iWork Studio MCP Server
<div align="center">
<!-- mcp-name: io.github.Arkanji/iwork-studio -->
<img src="https://raw.githubusercontent.com/Arkanji/iwork-studio/main/assets/banner.svg" alt="iWork Studio — read and edit Apple Numbers, Keynote and Pages with Python" width="100%">
[](https://github.com/Arkanji/iwork-studio/blob/main/.github/workflows/ci.yml)
[](https://pypi.org/project/iwork-studio/)
[](https://github.com/Arkanji/iwork-studio/tree/main/LICENSE)
[](#what-it-can-do)
[](#all-64-tools)
[](#arabic--rtl)
[](#the-safety-model)
### 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.<br>
Every write is backed up, checked and swapped in atomically, and any change can be undone with one call.
[**Install**](#install) · [What it can do](#what-it-can-do) · [Safety](#the-safety-model) · [All 64 tools](#all-64-tools) · [For AI agents](#for-ai-agents) · [Changelog](https://github.com/Arkanji/iwork-studio/blob/main/CHANGELOG.md)
<br>
<a href="https://arkanji.com/images/posts/iwork-studio-film-v3.mp4">
<img src="https://raw.githubusercontent.com/Arkanji/iwork-studio/main/assets/iwork-studio-film.webp" alt="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" width="100%">
</a>
<sub>▶ <a href="https://arkanji.com/images/posts/iwork-studio-film-v3.mp4"><b>Watch the film with sound</b></a> (46s) · <a href="https://arkanji.com/posts/iwork-studio-launch/">Read the launch story</a></sub>
</div>
---
## Install
| Your app | Do this |
|---|---|
| **Claude desktop app, one click** (Mac) | Download `iwork-studio-<version>.mcpb` from the [latest release](https://github.com/Arkanji/iwork-studio/releases/latest), 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](https://registry.modelcontextprotocol.io) as `io.github.Arkanji/iwork-studio` |
That's it. The installer sets up [`uv`](https://docs.astral.sh/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`](https://github.com/Arkanji/iwork-studio/blob/main/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](https://github.com/Arkanji/iwork-studio/blob/main/skill-pack/references/design-guide.md): 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](#install)).
<details open>
<summary><b>Any file</b> (17)</summary>
| 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 |
</details>
<details>
<summary><b>Numbers</b> (17)</summary>
| 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 |
</details>
<details>
<summary><b>Keynote</b> (23)</summary>
| 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 |
</details>
<details>
<summary><b>Pages</b> (7)</summary>
| 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 |
</details>
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`](https://github.com/Arkanji/iwork-studio/blob/main/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`](https://github.com/Arkanji/iwork-studio/blob/main/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`](https://github.com/Arkanji/iwork-studio/blob/main/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
```bash
pip install iwork-studio # Python 3.12
```
```python
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"])
```
<details>
<summary><b>Traps we mapped so your agent doesn't hit them</b></summary>
1. **`save in <path>` is denied by the iWork sandbox.** In-place `save` and `export` work. → [`sandbox-trap.md`](https://github.com/Arkanji/iwork-studio/blob/main/skill-pack/references/sandbox-trap.md)
2. **Keynote's slide `title`/`body` properties throw `-1700`.** Use the text item's `object text`. → [`keynote-1700-defect.md`](https://github.com/Arkanji/iwork-studio/blob/main/skill-pack/references/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`](https://github.com/Arkanji/iwork-studio/blob/main/skill-pack/references/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`](https://github.com/Arkanji/iwork-studio/blob/main/src/iwork_studio/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`](https://github.com/Arkanji/iwork-studio/blob/main/skill-pack/references/jxa-traps.md) (including traps borrowed from [reichenbach/iwork_mcp](https://github.com/reichenbach/iwork_mcp)).
</details>
<details>
<summary><b>How it's built</b></summary>
```
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
```
</details>
## Contributing
```bash
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](https://github.com/Arkanji/iwork-studio/blob/main/skill-pack/references/capability-matrix.md) and [traps](https://github.com/Arkanji/iwork-studio/blob/main/skill-pack/references/jxa-traps.md), 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](https://github.com/Arkanji/iwork-studio/tree/main/LICENSE), traps included. Take them.
TDQS
Scored across 64 tools
Tools are extensively documented with cross-references and explicit 'use X instead' guidance, but the sheer number (64) and overlapping categories (e.g., multiple create, verify, and design tools) create some risk of misselection. Most tools have distinct purposes, but a few pairs (e.g., iwork_verify_format vs iwork_verify_render, numbers_apply_design vs numbers_set_cell_style) require careful reading to distinguish.
Consistent snake_case with clear app prefixes (iwork_, numbers_, pages_, keynote_) and mostly verb_noun patterns (list_*, set_*, add_*, delete_*). No mixing of conventions. Minor deviations like iwork_capabilities (noun) are acceptable given its special role.
64 tools is excessive for a single MCP server. While the domain (three iWork apps plus design, backup, and verification) is broad, many highly specific tools (e.g., numbers_set_borders, numbers_merge_cells) could be consolidated with parameters, making the set unwieldy for an agent. This exceeds the 25+ threshold for 'too many'.
The surface is remarkably complete for iWork automation: CRUD for Numbers/Keynote/Pages, formatting, verification, backup/restore, design kit management, and export. Minor gaps (e.g., no Numbers chart creation, no Pages image insertion) are either app limitations or out of scope, but core workflows are fully covered.