{"name":"io.github.Arkanji/iwork-studio","slug":"arkanji-iwork-studio","title":"iWork Studio","description":"Create, edit, design and export Apple Numbers, Keynote and Pages files. Verified and Arabic-safe.","url":"https://mcp.market/server/arkanji-iwork-studio","rating":null,"grade":"A","score":92,"certified":false,"status":"active","category":"media","tags":["media"],"presence":{"score":30,"stars":2,"forks":0,"downloads_week":149,"last_push_at":"2026-10-13T09:22:49.000Z","license":"MIT"},"uptime":null,"claimed":false,"transport":"pypi","callable_via_gateway":false,"default_price_micros":0,"repository":"https://github.com/Arkanji/iwork-studio","website":null,"version":"2.6.1","remotes":[],"packages":[{"registryType":"pypi","identifier":"iwork-studio","version":"2.6.1","runtimeHint":"uvx","transport":{"type":"stdio"},"environmentVariables":[{"description":"Folders the server may touch, separated by ':' (recommended)","format":"string","name":"IWORK_STUDIO_ROOTS"},{"description":"Load only some tools: comma-separated files, numbers, keynote, pages, design (default all)","format":"string","name":"IWORK_STUDIO_TOOLSETS"}]}],"tools":[{"name":"iwork_capabilities","description":"What this machine can do right now: routes, GUI session, installed apps, Keynote slide-op status. Call first when unsure.","write_action":false,"price_micros":0,"input_schema":null},{"name":"iwork_create","description":"New .numbers / .key / .pages from Apple's built-in templates (Keynote: themes); names from iwork_list_templates. Omit template for Blank / Basic White. Refuses to overwrite. Needs macOS + the app.","write_action":true,"price_micros":0,"input_schema":null},{"name":"iwork_create_from_template","description":"Start a new document from one of the user's own files (any .numbers / .key / .pages): copies it to `path` and checks it opens. Refuses to overwrite.","write_action":true,"price_micros":0,"input_schema":null},{"name":"iwork_delete_design_kit","description":"Delete a saved design kit (presets can't be deleted). Returns the kit's contents, so it can be saved again with iwork_save_design_kit.","write_action":true,"price_micros":0,"input_schema":null},{"name":"iwork_export","description":"Export to another format. Numbers: pdf | xlsx | csv. Pages: pdf | docx | epub | txt | rtf. Keynote: pdf | pptx | images | movie. Optional password (+hint) for pdf/xlsx/docx/pptx, image_quality (good|better|best), image_format for slide images (jpeg|png|tiff). Default output sits next to the source. The export is checked against the source with a second tool and the source is verified unchanged. Ne","write_action":false,"price_micros":0,"input_schema":null},{"name":"iwork_extract_design_kit","description":"Make a design kit from the user's own deck or table: heading and body fonts (Latin and Arabic) and the title, body and brand colours. .numbers reads the table's header and body styles (no app); .key reads every slide's title and body (needs macOS + Keynote). Parts the file doesn't show come from the nearest preset and are listed in notes. save=true with a name keeps it for reuse by name (contrast","write_action":false,"price_micros":0,"input_schema":null},{"name":"iwork_find","description":"Find Numbers / Keynote / Pages files (newest first). kind: numbers | keynote | pages; name: part of the file name. Searches `folder`, else the allowed folders, else Documents/Desktop/Downloads. Uses Spotlight on macOS.","write_action":false,"price_micros":0,"input_schema":null},{"name":"iwork_list_backups","description":"List the versioned backups (newest first) every write left for this file, plus the Keynote write manifest.","write_action":false,"price_micros":0,"input_schema":null},{"name":"iwork_list_design_kits","description":"Design kits for good-looking decks and tables: font pairs (Latin + Arabic, bundled with macOS), contrast-checked palettes and a type scale. Lists the presets and the kits you saved (saved: true). Use with keynote_build_deck(kit=…), keynote_apply_design, numbers_apply_design. Custom kits: pass {\"fonts\": {...}, \"colors\": {...}}.","write_action":false,"price_micros":0,"input_schema":null},{"name":"iwork_list_templates","description":"Built-in templates for Numbers or Pages, or themes for Keynote (app: numbers | pages | keynote). Needs macOS + the app.","write_action":false,"price_micros":0,"input_schema":null},{"name":"iwork_metadata","description":"What a file says about itself, without the app: kind, size, modified, template it was made from, app builds that saved it, file format version, slide count (Keynote), embedded media count.","write_action":false,"price_micros":0,"input_schema":null},{"name":"iwork_read","description":"Read a .numbers, .key or .pages file into JSON (.pages needs the Pages app and a GUI session).","write_action":false,"price_micros":0,"input_schema":null},{"name":"iwork_restore_backup","description":"Undo: atomically restore a backup (a name from iwork_list_backups). The current version is backed up first.","write_action":false,"price_micros":0,"input_schema":null},{"name":"iwork_samples","description":"Copy sample files (sample-sales.numbers with English and Arabic sheets of synthetic sales data, and sample-outline.md for a deck) into a folder, so a first try needs none of the user's own files. Never overwrites. Returns try-it prompts.","write_action":false,"price_micros":0,"input_schema":null},{"name":"iwork_save_design_kit","description":"Save a design kit by name for reuse anywhere a kit is accepted. kit = {\"fonts\": {...}, \"colors\": {...}, \"theme\": \"...\", \"background\": \"#RRGGBB\"} (missing parts come from the \"executive\" preset, or from \"base\": \"<preset>\"), or a preset name to copy. Contrast is checked (4.5:1). Never replaces a saved kit unless overwrite=true; can't reuse a preset's name.","write_action":false,"price_micros":0,"input_schema":null},{"name":"iwork_thumbnail","description":"Extract the preview image stored in the file (first page/slide) to a JPEG and return its path — a quick look without opening the app. Reflects the app's last save.","write_action":false,"price_micros":0,"input_schema":null},{"name":"iwork_verify_format","description":"Independent check of formatting: export a PDF through the app and confirm `text` is drawn with the given font (name contains), size (pt), color (#RRGGBB), bold, and page size (pt). Needs macOS + the app.","write_action":false,"price_micros":0,"input_schema":null},{"name":"iwork_verify_render","description":"Export the file to PDF through its app and assert `assert_text` is visibly rendered. For Arabic, use one word.","write_action":false,"price_micros":0,"input_schema":null},{"name":"keynote_add_chart","description":"Add a chart to a slide from data. rows = series names, columns = category names, data = one list of numbers per row (rows × columns). type: bar | stacked_bar | horizontal_bar | stacked_horizontal_bar | line | area | stacked_area | pie | scatter (or *_3d). group_by: row | column. Text and other charts are verified untouched. dry_run=true previews the change on a copy without touching the file.","write_action":false,"price_micros":0,"input_schema":null},{"name":"keynote_add_image","description":"Place an image file (png, jpg, heic, pdf…) on a slide; optional x/y position and width in points. All text verified untouched. dry_run=true previews the change on a copy without touching the file.","write_action":false,"price_micros":0,"input_schema":null},{"name":"keynote_add_slide","description":"Insert a slide after slide number `after` (0 = first, omit = end). Every other slide is verified unchanged. dry_run=true previews the change on a copy without touching the file.","write_action":true,"price_micros":0,"input_schema":null},{"name":"keynote_add_table","description":"Add a table to a slide (1-based). rows = [[\"Region\", \"Q1\"], [\"Riyadh\", 1200], …]: text, numbers, or null; text starting with \"=\" is a formula. kit (iwork_list_design_kits name or your own) styles it: header band, fonts (Arabic-aware), banding, numbers right-aligned. Optional x, y (points from top-left) and width. Every cell, font and colour is read back; other slides and tables are checked untouch","write_action":false,"price_micros":0,"input_schema":null},{"name":"keynote_apply_design","description":"Make a deck look designed: the kit's theme (optional), then every slide's title and body fonts (Arabic-aware), sizes from a type scale, and colours from a contrast-checked palette. kit = a name from iwork_list_design_kits or your own {\"fonts\": {...}, \"colors\": {...}}. Text is verified unchanged. dry_run=true previews the change on a copy without touching the file.","write_action":false,"price_micros":0,"input_schema":null},{"name":"keynote_build_deck","description":"Build a new Keynote deck from an outline. slides = [{\"title\": \"…\", \"body\": [\"bullet\", \"bullet\"], \"layout\": \"Title & Bullets\", \"notes\": \"…\", \"image\": \"/path/pic.png\"}, …]; the first slide defaults to a title layout, the rest to Title & Bullets. theme from keynote_list_themes; optional transition for every slide (e.g. dissolve). Every slide is read back and checked; on any mismatch the new file is r","write_action":false,"price_micros":0,"input_schema":null},{"name":"keynote_delete_slide","description":"Delete slide number `slide` (1-based). Recoverable with iwork_restore_backup. dry_run=true previews the change on a copy without touching the file.","write_action":true,"price_micros":0,"input_schema":null},{"name":"keynote_duplicate_slide","description":"Duplicate slide number `slide` (1-based); the copy lands right after it. dry_run=true previews the change on a copy without touching the file.","write_action":false,"price_micros":0,"input_schema":null},{"name":"keynote_format_text","description":"Font (PostScript name, e.g. \"HelveticaNeue-Bold\"), size (pt) and/or colour (\"#RRGGBB\") of one text item on a slide — pick it by item index (from keynote_inspect_style) or by a unique piece of its text (match). Alignment and shape fill are not scriptable. dry_run=true previews the change on a copy without touching the file.","write_action":false,"price_micros":0,"input_schema":null},{"name":"keynote_inspect_style","description":"A deck's styling: current theme, available slide layouts, and per slide its layout plus each text item's text, font, size and colour. Read this before theming.","write_action":false,"price_micros":0,"input_schema":null},{"name":"keynote_list_slides","description":"Every slide with its text, presenter notes and whether it is hidden (via Keynote). Use slide numbers from here for slide operations.","write_action":false,"price_micros":0,"input_schema":null},{"name":"keynote_list_themes","description":"Themes available in Keynote on this Mac (names to pass to keynote_set_theme).","write_action":false,"price_micros":0,"input_schema":null},{"name":"keynote_move_slide","description":"Move slide number `slide` so it ends up at position `to` (both 1-based). dry_run=true previews the change on a copy without touching the file.","write_action":false,"price_micros":0,"input_schema":null},{"name":"keynote_replace_text","description":"Find/replace text across every slide of a .key deck (literal unless regex=true). Formatting and structure are verified unchanged. dry_run=true previews the change on a copy without touching the file.","write_action":false,"price_micros":0,"input_schema":null},{"name":"keynote_review_deck","description":"Design review of a deck as Keynote actually draws it: renders to PDF and reports, per slide, text drawn off the slide or past the bottom of its box (errors), text boxes drawn on top of each other, text under 18 pt, and slides that are too dense (warnings). Run it after building or restyling a deck, fix the errors, then look at a flagged slide with keynote_slide_image. The file isn't changed. Needs","write_action":false,"price_micros":0,"input_schema":null},{"name":"keynote_set_presenter_notes","description":"Set the presenter notes of slide number `slide` (1-based). Arabic-safe. dry_run=true previews the change on a copy without touching the file.","write_action":false,"price_micros":0,"input_schema":null},{"name":"keynote_set_slide_layout","description":"Change one slide's layout (master), e.g. \"Title & Bullets\". Other slides are verified untouched. dry_run=true previews the change on a copy without touching the file.","write_action":false,"price_micros":0,"input_schema":null},{"name":"keynote_set_slide_text","description":"Fill a slide's title and/or body box (body may be a list of bullet lines). The title box is the top-most text box, the body the largest other one. Other slides and text boxes are verified untouched. dry_run=true previews the change on a copy without touching the file.","write_action":false,"price_micros":0,"input_schema":null},{"name":"keynote_set_theme","description":"Apply a different Keynote theme to the whole deck. Rolled back if any slide loses text. dry_run=true previews the change on a copy without touching the file.","write_action":false,"price_micros":0,"input_schema":null},{"name":"keynote_set_transition","description":"Transition into a slide: effect such as dissolve, push, wipe, magic move, cube, flip, move in, reveal, \"none\"; duration/delay in seconds; automatic=true advances on its own. Other slides verified untouched. dry_run=true previews the change on a copy without touching the file.","write_action":false,"price_micros":0,"input_schema":null},{"name":"keynote_skip_slide","description":"Hide (skipped=true) or show a slide in the slideshow. dry_run=true previews the change on a copy without touching the file.","write_action":false,"price_micros":0,"input_schema":null},{"name":"keynote_slide_image","description":"One slide as an image (JPEG, `width` px wide), exported by Keynote, so you can look at the design yourself. Skipped slides aren't exported. The file isn't changed. Needs macOS + Keynote.","write_action":false,"price_micros":0,"input_schema":null},{"name":"keynote_slideshow","description":"Present: action = start (needs path; from_slide 1-based) | stop | next | previous. Doesn't change the file. Needs macOS + Keynote.","write_action":false,"price_micros":0,"input_schema":null},{"name":"numbers_add_table","description":"Add a table with data to an existing sheet (`sheet`, default the first) or to a new sheet (`new_sheet`). Every existing table is verified unchanged. dry_run=true previews the change on a copy without touching the file.","write_action":false,"price_micros":0,"input_schema":null},{"name":"numbers_apply_design","description":"Style a whole table from a design kit: header band (fill, bold, contrast-checked text), body font and colour (Arabic cells get the Arabic font), alternate-row banding, number columns right-aligned. Values never change; every other table is verified untouched. No app needed. dry_run=true previews the change on a copy without touching the file.","write_action":false,"price_micros":0,"input_schema":null},{"name":"numbers_create","description":"Create a new .numbers file from data. sheets = [{\"name\": \"Sales\", \"tables\": [{\"name\": \"Q1\", \"rows\": [[\"Region\", \"Revenue\"], [\"Riyadh\", 1200]], \"header_rows\": 1}]}]. Numbers stay numbers, text stays text exactly (Arabic included). Refuses to overwrite. No app needed.","write_action":true,"price_micros":0,"input_schema":null},{"name":"numbers_delete","description":"Delete `count` rows or columns (what = rows | columns) starting at 1-based position `at`. Remaining cells are verified. Refused in tables with formulas or merged cells. Undo with iwork_restore_backup. dry_run=true previews the change on a copy without touching the file.","write_action":true,"price_micros":0,"input_schema":null},{"name":"numbers_edit_cell","description":"Set one cell (e.g. ref \"B2\") in a .numbers file. Backed up, verified, atomic; every other cell is checked unchanged. dry_run=true previews the change on a copy without touching the file.","write_action":false,"price_micros":0,"input_schema":null},{"name":"numbers_import_csv","description":"Turn a CSV/TSV into a new .numbers file (UTF-8, delimiter auto-detected). Plain numbers become numbers (numbers=false keeps everything as text); dates, \"$1,234\" and Arabic-Indic digits stay text exactly as written. Refuses to overwrite.","write_action":false,"price_micros":0,"input_schema":null},{"name":"numbers_insert","description":"Insert rows or columns (what = rows | columns) before 1-based position `at`; omit `at` to append. Optional `values`: one list per new row (or column). Every existing cell is verified at its new position. In tables with formulas, only appending is allowed (shifting would break references). dry_run=true previews the change on a copy without touching the file.","write_action":true,"price_micros":0,"input_schema":null},{"name":"numbers_inspect_format","description":"Current formatting of a Numbers table: column widths, row heights, header rows/cols, merges, and per-cell font/colour/fill/alignment, number format (shown_as) and borders. Read this before formatting.","write_action":false,"price_micros":0,"input_schema":null},{"name":"numbers_merge_cells","description":"Merge a rectangular range (\"A1:C1\"). Refused if any cell other than the top-left holds data (it would be hidden) or the range crosses the header edge. dry_run=true previews the change on a copy without touching the file.","write_action":false,"price_micros":0,"input_schema":null},{"name":"numbers_recalculate","description":"Make Numbers recompute every formula from the current values. Numbers keeps showing a formula's old result after edits made without it (numbers_edit_cell, numbers_insert…), so run this after those when the file has formulas — their result says so (formulas_need_recalc). Formulas and inputs are verified unchanged. Needs macOS + Numbers, file closed. dry_run=true previews the change on a copy withou","write_action":false,"price_micros":0,"input_schema":null},{"name":"numbers_set_borders","description":"Cell borders on a range: sides = all | outline | inner | top | right | bottom | left; width in points; color \"#RRGGBB\"; style = solid | dashes | dots | none. dry_run=true previews the change on a copy without touching the file.","write_action":false,"price_micros":0,"input_schema":null},{"name":"numbers_set_cell_style","description":"Style a range (\"A1:D1\"): font_name, font_size, bold, italic, underline, strikethrough, font_color / fill_color as \"#RRGGBB\", align (left|center|right|justify|auto), valign (top|middle|bottom), wrap. Only the attributes you pass change; every other cell is verified untouched. dry_run=true previews the change on a copy without touching the file.","write_action":false,"price_micros":0,"input_schema":null},{"name":"numbers_set_dimensions","description":"Set column widths and/or row heights in points, e.g. columns={\"A\": 160, \"C\": 90}, rows={\"1\": 32} (rows are 1-based). Nothing else changes. dry_run=true previews the change on a copy without touching the file.","write_action":false,"price_micros":0,"input_schema":null},{"name":"numbers_set_formula","description":"Put a formula in one cell, e.g. ref \"D10\", formula \"=SUM(D2:D9)\"; Numbers computes it and the result is returned. Every other cell's input is verified unchanged. Needs macOS + Numbers, file closed. dry_run=true previews the change on a copy without touching the file.","write_action":true,"price_micros":0,"input_schema":null},{"name":"numbers_set_headers","description":"Set how many header rows / header columns a table has (0–5). dry_run=true previews the change on a copy without touching the file.","write_action":false,"price_micros":0,"input_schema":null},{"name":"numbers_set_number_format","description":"How numbers display in a range (\"B2:B9\"): format = number | currency | percentage | scientific | fraction | datetime | text. Options: decimal_places, thousands_separator, negative_style (minus|red|parentheses|red_parentheses), currency_code (ISO, e.g. SAR, USD), accounting, date_format (e.g. \"d MMM yyyy\"). Values are not changed; the result shows how each cell now displays. dry_run=true previews t","write_action":false,"price_micros":0,"input_schema":null},{"name":"numbers_sort","description":"Sort a table's body rows by a column letter (header rows stay on top). Verified as a pure reorder. A table whose formulas read other rows (e.g. =B2*0.1 below a base-figure row) is refused, because Numbers' sort would break them; for it, to_new_table=true leaves the table, its formulas and its charts as they are and puts a sorted copy of its values (no formulas) in a new table on the same sheet (na","write_action":false,"price_micros":0,"input_schema":null},{"name":"pages_fill_placeholders","description":"Fill template placeholders by tag, e.g. {\"Name\": \"Sara\", \"Date\": \"3 October\"}. Formatting is kept; the body is verified to change only there. Needs macOS + Pages. dry_run=true previews the change on a copy without touching the file.","write_action":false,"price_micros":0,"input_schema":null},{"name":"pages_list_placeholders","description":"Template placeholders in a .pages document (tag + current text), e.g. a letter's \"Name\" or \"Date\" fields. Needs macOS + Pages.","write_action":false,"price_micros":0,"input_schema":null},{"name":"pages_preflight","description":"Check Pages can answer AppleEvents. Run once before any Pages op; never loop on failure.","write_action":false,"price_micros":0,"input_schema":null},{"name":"pages_read_tables","description":"Every table in a .pages document: name, size, and each cell's value, shown text and formula. Needs macOS + Pages.","write_action":false,"price_micros":0,"input_schema":null},{"name":"pages_replace_all","description":"Replace every occurrence of `find` in a .pages body (needs Pages + GUI session). Rolled back if the readback disagrees. dry_run=true previews the change on a copy without touching the file.","write_action":false,"price_micros":0,"input_schema":null},{"name":"pages_set_body","description":"Replace the entire body text of a .pages document (needs Pages + GUI session). Body formatting is reset. dry_run=true previews the change on a copy without touching the file.","write_action":false,"price_micros":0,"input_schema":null},{"name":"pages_set_table_cells","description":"Write cells of an existing table in a .pages document. table = its name or number (from pages_read_tables); cells = {\"B2\": 1200, \"C3\": \"تم\", \"D9\": \"=SUM(D2:D8)\"} — numbers stay numbers, \"=…\" makes a formula, null clears. Every other cell and the body text are verified unchanged. New tables can't be created (Pages 15 doesn't script it). Needs macOS + Pages, document closed. dry_run=true previews th","write_action":true,"price_micros":0,"input_schema":null}],"scan":{"score":92,"grade":"A","scanned_at":"2026-10-13T14:39:57.822Z","report":{"scannerVersion":"0.1.10","scannedAt":"2026-10-13T14:39:57.771Z","components":{"code":{"score":25,"max":25,"notes":["29 source files scanned"]},"reliability":{"score":-1,"max":20,"notes":["no gateway calls yet and no remote to probe"]},"poisoning":{"score":-1,"max":15,"notes":["tools not inspected (local package is not executed); not counted"]},"auth":{"score":12,"max":15,"notes":["local package, no credentials required"]},"maintenance":{"score":15,"max":15,"notes":["last push 0 days ago"]},"identity":{"score":8,"max":10,"notes":["registry namespace matches repository owner","GitHub account older than a year"]}},"findings":[],"inputs":{"packages":[{"registryType":"pypi","identifier":"iwork-studio","version":"2.6.1","found":true,"weeklyDownloads":149,"license":"MIT","dependencyCount":9,"publishedAt":"2026-10-13T07:42:12.250014Z","repositoryUrl":"https://github.com/Arkanji/iwork-studio"}],"repo":{"found":true,"owner":"Arkanji","repo":"iwork-studio","archived":false,"pushedAt":"2026-10-13T09:22:49Z","stars":2,"forks":0,"openIssues":0,"ownerType":"User","ownerAvatarUrl":"https://avatars.githubusercontent.com/u/9057709?v=4","ownerCreatedAt":"2014-10-07T19:41:23Z","license":"MIT"},"icon":{"url":"https://avatars.githubusercontent.com/u/9057709?v=4&s=128","source":"github"},"presence":{"stars":2,"forks":0,"downloadsWeek":149,"license":"MIT","lastPushAt":"2026-10-13T09:22:49.000Z","score":30}}}},"grade_history":[],"reviews":[]}