Create, edit, design and export Apple Numbers, Keynote and Pages files. Verified and Arabic-safe.
Create, edit, format, theme and export Numbers, Keynote and Pages files from Claude or any AI agent.
Every write is backed up, checked and swapped in atomically, and any change can be undone with one call.
Install · What it can do · Safety · All 64 tools · For AI agents · Changelog
| Your app | Do this |
|---|---|
| Claude desktop app, one click (Mac) | Download iwork-studio-<version>.mcpb from the latest release, double-click it, pick the folders it may use |
| Claude desktop app (Mac, from Terminal) | Paste in Terminal: curl -LsSf https://raw.githubusercontent.com/Arkanji/iwork-studio/main/install.sh | sh, then quit Claude (Cmd-Q) and reopen |
| Claude Code, as a plugin (tools + skill) | /plugin marketplace add Arkanji/iwork-studio, then /plugin install iwork-studio@iwork-studio |
| Claude Code, tools only | claude mcp add iwork-studio -- uvx --from git+https://github.com/Arkanji/iwork-studio iwork-studio-mcp |
| Cursor, VS Code, Codex, any MCP client | uvx --from git+https://github.com/Arkanji/iwork-studio iwork-studio-mcp config, then paste the printed JSON into the client's MCP settings. Also listed in the MCP Registry as io.github.Arkanji/iwork-studio |
That's it. The installer sets up uv if needed, and uv brings its own Python.
… | sh -s -- --roots ~/Documents ~/Desktop limits it to those folders. Other clients: set IWORK_STUDIO_ROOTS (:-separated).IWORK_STUDIO_TOOLSETS=keynote,design (any of files, numbers, keynote, pages, design; default all). Fewer tools keep the AI focused and its context small. The Claude Desktop extension has a Toolsets field; in Claude Code: claude mcp add iwork-studio -e IWORK_STUDIO_TOOLSETS=keynote,design -- uvx --from git+https://github.com/Arkanji/iwork-studio iwork-studio-mcp. Capabilities, read, find, undo and the kit list always load.uvx --from git+https://github.com/Arkanji/iwork-studio iwork-studio-mcp uninstallAI agent setting this up for someone? Pick the row for their app, run it, then call
iwork_capabilities. Rules for using the tools are inAGENTS.md.
"Build a 6-slide pitch deck on programmable gift cards in the midnight kit, with speaker notes, and export it to PowerPoint."
"Turn sales.numbers into a board deck: chart the quarters, a table of the top regions, in our Resal kit."
"Take the fonts and colours from brand.key and save them as our Resal kit."
"Review pitch.key and fix anything that overflows or is too small to read."
"Make budget.numbers look professional with the banking kit — and show me a preview first."
"Turn sales.csv into a Numbers file, make the header bold on a teal fill, show column B as SAR with two decimals, and add a total row."
"In pitch.key, switch to the Gradient theme, make the title on slide 1 white at 60 pt, add a dissolve between every slide, and put logo.png on the last slide."
"Add a bar chart of revenue by quarter for 2025 and 2026 to slide 4."
"Duplicate slide 3, move the copy to the front and add presenter notes: ملاحظات المتحدث"
"Fill the Name and Date fields in offer-letter.pages, then export it as a password-protected PDF."
"In the invoice.pages table, set the quantity in B3 to 12 and make D9 the total of D2:D8."
"Find my Keynote decks from this week and export each one to PowerPoint."
"Undo the last change to budget.numbers."
| Numbers | Keynote | Pages | |
|---|---|---|---|
| Read | Every sheet, table, cell, formula and format | Every slide's text, notes, layout, theme, styling and charts | Body text, placeholders and tables |
| Create | From data or CSV ⚡ · from a built-in template · from your own file | A designed deck from an outline, with chart and table slides (straight from a Numbers table) · from a built-in theme · from your own deck | From a built-in template · from your own file |
| Edit content | Cells ⚡ · formulas · recalculate · insert/delete rows and columns ⚡ · add tables and sheets ⚡ · sort | Find/replace across the deck ⚡ · slide titles and bullets · add, duplicate, delete, move, hide slides · presenter notes · images · charts · tables | Replace text everywhere · replace the body · fill placeholders · table cells (text, numbers, formulas) |
| Design | Design kits ⚡ · your brand kit ⚡ · fonts, colours, fill, alignment, wrap ⚡ · currency, %, dates, decimals ⚡ · borders ⚡ · widths and heights ⚡ · headers ⚡ · merges ⚡ | Design kits · your brand kit · theme · slide layout · text font, size and colour · styled tables · transitions | — |
| Review | Design review of what Keynote draws: text off the slide or past its box, text Keynote had to shrink, overlaps, small text, crowded slides · any slide as an image | ||
| Export | PDF · Excel · CSV | PDF · PowerPoint · images · movie | PDF · Word · EPUB · text · RTF |
| Present | Start, stop, next, previous |
⚡ = works anywhere, no app needed (pure Python). Everything else drives the real app on a Mac with a logged-in session, classic iWork or the Creator Studio apps.
Every file type: preview any change before it's made (dry_run), look up metadata, pull the preview thumbnail, find files with Spotlight, check that a word is visibly rendered, check the rendered font/size/colour, list backups and undo.
On purpose, so it never breaks a file:
Six design kits turn a plain deck or table into something you'd present: a font pair (Latin + Arabic, all bundled with macOS — nothing to install), a restrained palette checked for WCAG contrast, and a type scale.
| Kit | Feel |
|---|---|
executive | Calm and corporate: slate neutrals, one blue accent |
banking | Trust and weight: deep navy, restrained gold |
classic | Formal reports and boards: serif headings, navy and amber |
teal | Fresh and confident: deep teal |
analytics | Data-forward: strong blue, amber highlights |
midnight | Dark stage: near-black slides, white titles, mint accent |
Build with one (keynote_build_deck(..., kit="midnight")), restyle anything (keynote_apply_design, numbers_apply_design), or bring your brand as colours and fonts — contrast is checked. Agents also get a design guide: one idea per slide, titles that state the takeaway, right-aligned numbers, restrained colour.
Your brand, once. Point iwork_extract_design_kit at a deck or table that already has your look: it reads the fonts (Latin and Arabic) and colours, and saves them as a named kit you can use anywhere a kit goes. Or save your colours and fonts directly with iwork_save_design_kit.
Numbers on slides. A slide in keynote_build_deck can carry a chart or a table, from data or straight from a Numbers table: the header row gives the columns, the first column the rows. Tables get the kit's header band, fonts, banding and right-aligned numbers, and every cell is read back.
It checks its own work. keynote_review_deck renders the deck through Keynote and compares every drawn line with its text box: text off the slide or running past its box is an error; text Keynote had to shrink to fit, overlapping boxes, text under 18 pt and crowded slides are warnings. keynote_slide_image hands a slide back as an image, so an agent can look before it says "done".
An iWork app will happily say "saved" about a file it just broke. Nothing here trusts "saved".
backup → change a scratch copy → re-open it and compare → atomic swap
↘ anything off: your file is untouched, the error says why
<file>.backups/.iwork_list_backups → iwork_restore_backup. The restore backs up the current version first, so undo can be undone too.dry_run=true. It runs the real change on a throwaway copy, with every check, and shows exactly what would change. Your file isn't touched.١٢٣), "$1,234.56" and =… text stay text. Pass a real number when you want a number.Writes are marked destructive and reads read-only, so clients can ask before writing. Every write that changes an existing file takes dry_run=true for a preview. Every tool has a title, every parameter a description, and every tool says when to use it instead of its siblings. Need fewer? Load only some toolsets (see Load less under Install).
| Tool | What it does |
|---|---|
iwork_capabilities | What this machine can do: apps, GUI session, which routes work |
iwork_read | Any .numbers / .key / .pages → JSON |
iwork_find | Find iWork files by kind and name (Spotlight on a Mac) |
iwork_metadata · iwork_thumbnail | Template, app builds, format version, slide count · the stored preview image |
iwork_create · iwork_create_from_template | New file from Apple's built-in templates · copy of your own file |
iwork_list_templates | Built-in templates (Numbers, Pages) and themes (Keynote) |
iwork_list_design_kits | Design kits: fonts, palettes, type scale — presets and your saved kits |
iwork_extract_design_kit | A kit from your own deck or table: its fonts and colours; save it by name |
iwork_save_design_kit · iwork_delete_design_kit | Keep your brand kit by name · remove one |
iwork_export | PDF, Excel, CSV, Word, EPUB, text, RTF, PowerPoint, slide images, movie; optional password |
iwork_verify_render · iwork_verify_format | Rendered PDF shows this text · with this font, size, colour, page size |
iwork_list_backups · iwork_restore_backup | Undo |
| Tool | What it does |
|---|---|
numbers_create · numbers_import_csv | New file from rows of data · from a CSV/TSV |
numbers_edit_cell | Set one cell |
numbers_set_formula | Put a formula in a cell; Numbers computes it |
numbers_recalculate | Have Numbers recompute every formula after edits made without it |
numbers_insert · numbers_delete | Rows or columns, anywhere |
numbers_add_table | New table on a sheet, or on a new sheet |
numbers_sort | Sort body rows by a column |
numbers_inspect_format | Widths, heights, headers, merges, and every cell's style, number format and borders |
numbers_set_cell_style | Font, size, bold/italic/underline/strike, colours, fill, alignment, wrap |
numbers_set_number_format | Number, currency (any ISO code), %, scientific, fraction, date, text; decimals, separators, negatives |
numbers_set_borders | All / outline / inner / one side; width, colour, style |
numbers_set_dimensions · numbers_set_headers · numbers_merge_cells | Column widths and row heights · header rows/columns · merges |
| Tool | What it does |
|---|---|
keynote_build_deck | A new deck from an outline: titles, bullets, notes, images, chart and table slides, transition, design kit |
keynote_review_deck | Design review of the rendered deck: off-slide and overflowing text, overlaps, small text, crowded slides |
keynote_slide_image | One slide as an image, to look at |
keynote_set_slide_text | Fill a slide's title and body |
keynote_apply_design | Restyle every slide from a design kit |
keynote_replace_text | Find/replace on every slide, formatting untouched |
keynote_list_slides | Every slide's text, notes, hidden state and chart count |
keynote_add_slide · keynote_duplicate_slide · keynote_delete_slide · keynote_move_slide · keynote_skip_slide | Slide operations |
keynote_set_presenter_notes | Presenter notes |
keynote_list_themes · keynote_inspect_style | Available themes · a deck's theme, layouts and text styling |
keynote_set_theme · keynote_set_slide_layout · keynote_format_text | Theme · one slide's layout · one text item's font, size, colour |
keynote_set_transition | Effect, duration, delay, auto-advance |
keynote_add_image | Place an image on a slide |
keynote_add_chart | Add a bar, line, area, pie or scatter chart from data |
keynote_add_table | Add a table, styled from a design kit; every cell is read back |
keynote_slideshow | Start, stop, next, previous |
| Tool | What it does |
|---|---|
pages_preflight | Checks Pages can answer (run once first) |
pages_replace_all · pages_set_body | Replace text everywhere · replace the whole body (resets its formatting) |
pages_list_placeholders · pages_fill_placeholders | Template fields like Name and Date |
pages_read_tables · pages_set_table_cells | Read every table · write text, numbers and formulas into an existing table |
Keynote slide, theme, transition and image tools refuse a deck that's open in Keynote (they never close a window that may hold unsaved work). To hide them all: IWORK_STUDIO_DISABLE_SLIDE_OPS=1.
Prompts. Clients that show MCP prompts get four ready-made workflows: Pitch deck from an outline, Report deck from a Numbers table, Restyle with my brand and Make this table look designed. Each writes to the design rules, builds in one call, previews before restyling, and runs the design review before it calls the job done.
AGENTS.md: setup and usage rules for any agent (Codex, Cursor, Copilot, Gemini; Claude Code reads it via CLAUDE.md).skill-pack/SKILL.md, auto-discovered by Claude Code in this repo, or bash skill-pack/install.sh for other skill-based agents. It includes CLI scripts with JSON output for agents without MCP.llms.txt: a short machine-readable summary.The contract: JSON in, JSON out. Errors are typed and say what to tell the user: ChartRefusalError, DocumentOpenError, PagesOutOfScopeError, AquaSessionError (no Mac GUI here) and so on. Don't retry a refused write with a trick.
pip install iwork-studio # Python 3.12
from iwork_studio import numbers_structure, numbers_format, numbers_io, keynote_io, keynote_slides, exporter, backups
from iwork_studio import keynote_deck, design, review
keynote_deck.build_deck("pitch.key", [{"title": "رسال", "body": "Programmable value"},
{"title": "Why now", "body": ["Trust", "Access"]},
{"title": "Riyadh leads growth", "chart": {"type": "bar", "from": "sales.numbers"}}],
kit="midnight") # macOS + Keynote
review.review_deck("pitch.key")["findings"] # macOS + Keynote
design.extract_kit("brand.numbers", name="Resal", save=True)
numbers_structure.import_csv("sales.csv", "sales.numbers")
design.apply_to_numbers("sales.numbers", "banking")
numbers_format.set_cell_style("sales.numbers", "A1:D1", bold=True, fill_color="#1A7F79", font_color="#FFFFFF")
numbers_format.set_number_format("sales.numbers", "B2:B99", "currency", currency_code="SAR", decimal_places=2)
numbers_io.edit_cell("sales.numbers", "B2", 2500)
keynote_io.edit_text("pitch.key", "2025", "2026")
keynote_slides.set_presenter_notes("pitch.key", 1, "ملاحظات") # macOS + Keynote
exporter.export("pitch.key", "pptx") # macOS + Keynote
backups.restore_backup("sales.numbers", backups.list_backups("sales.numbers")[0]["name"])
save in <path> is denied by the iWork sandbox. In-place save and export work. → sandbox-trap.mdtitle/body properties throw -1700. Use the text item's object text. → keynote-1700-defect.mdtcc-preflight.mdApplication("Numbers") drives the wrong app; names are resolved per call. → apps.pymake new slide and move slide … to before slide … work.-1700); layouts go through AppleScript.bodyText() is null), and most letter and flyer templates are page layout. Placeholders are filled and checked across every text box instead.open for files outside it; JavaScript open is allowed, so documents are opened that way and then found by their exact path.numbers_recalculate has Numbers recompute every formula..git.tell slide n to make new table works, while make new table at end of tables of slide n and deleting a table fail with -10000. A failed table add is undone by restoring the backup.More, each with its status: jxa-traps.md (including traps borrowed from reichenbach/iwork_mcp).
pure Python file parsers (headless, deterministic) → .numbers everything, .key text
the real app via AppleScript / JXA → .key slides & theming, .pages text & tables, formulas, sort, export, render checks
MCP server · CLI scripts · skill → thin wrappers over the same library and the same safety model
src/iwork_studio/ numbers_io · numbers_format · numbers_structure · keynote_io · keynote_slides · keynote_theme
keynote_deck · keynote_table · design · review · preview · pages_io · app_ops · exporter
helpers · format_check · render_verify · pdf · backups · apps · mcp_server
mcpb/ Claude Desktop extension manifest (scripts/build_mcpb.sh builds the .mcpb)
skill-pack/ SKILL.md · CLI scripts · references (capabilities, traps, pins); also the Claude Code plugin
.claude-plugin/ plugin marketplace (one plugin: skill-pack/)
tests/ headless suite (CI) · `pytest -m aqua` = live suite for a Mac with iWork
install.sh one-line setup for the Claude desktop app
git clone https://github.com/Arkanji/iwork-studio.git && cd iwork-studio
uv run --extra test pytest -m "not aqua" # headless suite, what CI runs
uv run --extra test pytest -m aqua # live suite: a Mac with Numbers, Keynote and Pages
scripts/live.sh # the same, unattended: logs to ~/.iwork-studio/probes, quits the apps it opened
iWork changes between releases. If something breaks, check the capabilities and traps, run the live suite, and pin what changed. New write routes must follow the safety model and come with tests that prove the rollback. Clone outside iCloud-synced folders.
MIT, traps included. Take them.
Source-derived launch command. Check the maintainer’s required arguments and credentials before running:
uvx iwork-studioMerge this template into ~/Library/Application Support/Claude/claude_desktop_config.json. Keep existing servers. Add any arguments, credentials, and permissions required by the maintainer; this template has not been install-tested.
{
"mcpServers": {
"io-github-arkanji-iwork-studio": {
"command": "uvx",
"args": [
"iwork-studio"
]
}
}
}Restart Claude Desktop completely for changes to take effect. Confirm the server appears connected in the client’s tool list, then try a read-only example from its documentation.
Claude Desktop setup referenceiwork-studiopypiiWork Studio works with any MCP-compatible client. Copy the config snippet from the Configuration section above and add it to the file shown for your client, then restart the application.
~/Library/Application Support/Claude/claude_desktop_config.jsonRestart Claude Desktop completely for changes to take effect.~/.cursor/mcp.jsonRestart Cursor for changes to take effect..vscode/mcp.jsonReload VS Code window for changes to take effect.~/.codeium/windsurf/mcp_config.jsonRestart Windsurf for changes to take effect..mcp.jsonSave at the project root, then start Claude Code in that project and review the MCP server approval prompt. Keep real credentials out of shared files.