Skip to main content
iWork Studio — read and edit Apple Numbers, Keynote and Pages with Python

CI Version License: MIT iWork MCP server Arabic safe Undo

Give your AI the keys to Apple iWork.

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


iWork Studio in action: an AI agent edits a Numbers cell and keeps its formula, updates every Keynote slide without touching the formatting, and writes an Arabic letter in Pages

▶ Watch the film with sound (46s) · Read the launch story


Install

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.

  • Fence it (recommended): … | sh -s -- --roots ~/Documents ~/Desktop limits it to those folders. Other clients: set IWORK_STUDIO_ROOTS (:-separated).
  • Load less (optional): only work in Keynote? Set 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.
  • First run: macOS asks once whether Claude may control Keynote / Pages / Numbers. Click OK. (Missed it? System Settings → Privacy & Security → Automation.)
  • Check it: ask "what can iwork-studio do on this Mac?".
  • Remove: uvx --from git+https://github.com/Arkanji/iwork-studio iwork-studio-mcp uninstall

AI agent setting this up for someone? Pick the row for their app, run it, then call iwork_capabilities. Rules for using the tools are in AGENTS.md.

Just ask, in English or Arabic

"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."

What it can do

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.

What it won't do

On purpose, so it never breaks a file:

  • Files with charts are refused by the tools that work without the app: their rewrite can silently break a chart's link to its data. The app-driven tools (Keynote slides, theming, transitions, images; Numbers formulas and sort) work on them and check every chart is still there.
  • Charts in Numbers and Pages can't be created: Apple doesn't make them scriptable. Keynote charts can be added. To chart sorted data without touching a Numbers chart, sort into a new table (numbers_sort with to_new_table) and build a Keynote chart slide from it.
  • Pages is limited to text and existing tables: replace, set body, placeholders and table cells. New tables can't be created (Pages 15 doesn't script it), and page-layout documents, like most letter templates, have no body text. There is no Pages file format parser anywhere, so it doesn't fake one.
  • Formulas and row shifts: in a table that has formulas, rows and columns can only be appended without the app. Inserting in the middle would leave references pointing at the wrong cells.
  • Not scriptable by Apple, so not offered: Numbers table styles, Keynote shape fill and text alignment, deleting a Keynote table, editing a theme's master slides. Page margins and page setup are planned.

Designed, not just edited

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".

The safety model

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
  • Backup first, versioned, next to the file in <file>.backups/.
  • Re-read and compared: exactly the requested change happened, and nothing else did. A cell edit checks every other cell. A row insert checks every cell at its new position. A slide op checks every other slide. A sort checks it's a pure reorder, and refuses up front when the table's formulas read other rows (Numbers' own sort would break them). On files with charts, every chart is counted before and after; on decks with tables, every table's cells are compared. An export is read back with a second, independent tool.
  • Atomic swap: the file is replaced in one step, so a crash can't leave half a file.
  • The app's "ok" is never trusted. App-driven writes are re-read from disk, and a write that "succeeded" but didn't land is rolled back.
  • Undo is one call: iwork_list_backups → iwork_restore_backup. The restore backs up the current version first, so undo can be undone too.
  • Preview first: every write takes 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.
  • New files never overwrite an existing one.
  • Refuse, don't mangle. The worst case is a clear "no", never a broken file.

Arabic & RTL

  • Arabic text round-trips exactly in all three apps, including presenter notes, Pages placeholders and Pages table cells.
  • Paragraph direction is checked in Pages. A replace that flips a right-to-left paragraph to left-to-right is rolled back. Pages writes new paragraphs left-to-right, even Arabic ones, and scripting can't change that, so those are flagged: set the direction in Pages (Format › Text).
  • Values are kept as typed: Arabic-Indic digits (١٢٣), "$1,234.56" and =… text stay text. Pass a real number when you want a number.
  • When checking a rendered PDF, assert one Arabic word. PDF text layers reorder multi-word RTL text.

All 64 tools

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).

Any file (17)
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
Numbers (17)
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. A table whose formulas read other rows is refused, since Numbers' sort would break them; to_new_table puts a sorted copy of its values in a new table and leaves the original, its formulas and its charts alone
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
Keynote (23)
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
Pages (7)
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.

For AI agents

  • AGENTS.md: setup and usage rules for any agent (Codex, Cursor, Copilot, Gemini; Claude Code reads it via CLAUDE.md).
  • MCP instructions: the server sends its rules on connect, so the model has them even without this repo.
  • Skill: 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.

Python

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"])
Traps we mapped so your agent doesn't hit them
  1. save in <path> is denied by the iWork sandbox. In-place save and export work. → sandbox-trap.md
  2. Keynote's slide title/body properties throw -1700. Use the text item's object text. → keynote-1700-defect.md
  3. Chart files corrupt quietly when the file-level libraries rewrite them, so those routes refuse them. When the app makes the edit it keeps its own charts linked, so app-driven routes allow them and count every chart before and after.
  4. Byte-equal saves don't exist in iWork's format. The real bar is semantic: it reopens, and the full model matches.
  5. First-run permission and template-chooser dialogs block every script call. A preflight turns the hang into one clear prompt. → tcc-preflight.md
  6. "Creator Studio" apps have different names. A hardcoded Application("Numbers") drives the wrong app; names are resolved per call. → apps.py
  7. stdout is the MCP wire. Import-time warnings from libraries would corrupt it, so they go to stderr.
  8. Keynote's JavaScript insert and move are broken; AppleScript make new slide and move slide … to before slide … work.
  9. Keynote master slides can't be reached from JavaScript (-1700); layouts go through AppleScript.
  10. numbers-parser doesn't save in-place style edits. Styles are registered first, then applied.
  11. numbers-parser stored 12 as 12.000000000000002. Decimals are now encoded exactly.
  12. numbers-parser doesn't update formula references when rows move, so mid-table inserts in formula tables are refused.
  13. Keynote colours are 0–65535 per channel, not 0–255 or 0–1.
  14. Pages page-layout documents have no body text (bodyText() is null), and most letter and flyer templates are page layout. Placeholders are filled and checked across every text box instead.
  15. Pages tables are invisible to JavaScript scripting but readable and writable from AppleScript; creating tables is broken in Pages 15, so only existing tables are offered.
  16. The Pages sandbox refuses AppleScript open for files outside it; JavaScript open is allowed, so documents are opened that way and then found by their exact path.
  17. numbers-parser can break formulas on re-save (an upstream report). Every no-app write compares every formula, so a broken one is caught and nothing changes.
  18. Numbers doesn't recalculate formulas when it opens a file changed without it: a total keeps its old result. Edits made without the app say so, and numbers_recalculate has Numbers recompute every formula.
  19. A rounding library used by numbers-parser wipes every warning filter in the process on each save. It's wrapped so it stays quiet without touching anyone else's settings.
  20. Don't keep the repo in iCloud Drive. Sync creates "main 2" copies inside .git.
  21. Keynote creates tables only one way: 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).

How it's built
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

Contributing

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.

License

MIT, traps included. Take them.

Metadata

Release files for iwork-studio 2.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for iwork-studio 2.6.0
File Size Uploaded
iwork_studio-2.6.0.tar.gz 200.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for iwork-studio 2.6.0
File Interpreter ABI Platform
iwork_studio-2.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 355.4 kB

Release files / iwork_studio-2.6.0.tar.gz

Download URL iwork_studio-2.6.0.tar.gz
Size 200.0 kB
Tags Source
SHA-256 checksum
How to use checksums
75cc30c4cf4805c68e6266b39c5dbbbc7b4e8b69e79e13fca8b1e86c26a1c874
BLAKE2b-256 checksum
How to use checksums
a6ebccd4e1112f32dffcfcb5a635c824ea898a371f99bf13fcc06ae065b24694
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Release files / iwork_studio-2.6.0-py3-none-any.whl

Download URL iwork_studio-2.6.0-py3-none-any.whl
Size 155.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a959715e2886ccf13e2feecf23a51f6d05c6c622a6486d51da738c1ef7713ef1
BLAKE2b-256 checksum
How to use checksums
f77d4a77314d125ec3d834e8720b49d406187fe358034420d2f0ce5339c3a87f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

2.6.0 This release

2 release files

2.5.0

2 release files

2.4.1

2 release files

2.4.0

2 release files

2.3.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page