InDesign UXP MCP Server
A Model Context Protocol (MCP) server that gives AI assistants direct, native control over Adobe InDesign via a UXP plugin bridge, with ~130 tools covering documents, pages, text, graphics, styles, master spreads, books, and export.
README
InDesign UXP MCP Server
Forked from zachshallbetter/indesign-mcp-server — rewritten to use Adobe's UXP plugin platform instead of AppleScript.
A Model Context Protocol (MCP) server that gives AI assistants direct, native control over Adobe InDesign via a UXP plugin bridge. ~130 tools covering the full InDesign feature set — documents, pages, text, graphics, styles, master spreads, books, and export.
Why UXP vs AppleScript
This server is a ground-up rewrite of the AppleScript-based indesign-mcp-server. The execution model is fundamentally different.
| AppleScript (original) | UXP (this fork) | |
|---|---|---|
| Platform | macOS only | macOS + Windows |
| Execution path | Node → temp JSX file → AppleScript → InDesign | Node → HTTP → WebSocket → InDesign plugin |
| Speed | Slow — 3 hops, disk write per call | Fast — direct in-process call |
| Reliability | Flaky — breaks if InDesign loses focus or system dialogs appear | Stable — not affected by focus or system state |
| Return values | Strings only (last evaluated expression) | Full structured JSON objects |
| JS version | ExtendScript (ES3 — no const, arrow functions, or async/await) |
Modern JS (ES2015+ — async/await, destructuring, arrow functions) |
| Error messages | Cryptic AppleScript/OSA errors | Structured JSON with clear error strings |
| String handling | Manual escapeJsxString() for every value |
JSON.stringify() throughout — safe and simple |
| Enums | Magic strings like 'PDF_TYPE' |
Typed enums via require('indesign').ExportFormat.pdfType |
| Async support | Not supported — synchronous only | Native await (e.g. await doc.filePath) |
| Permissions | macOS Automation + Accessibility in System Settings | None beyond InDesign plugin install |
| Future-proofing | ❌ Adobe is deprecating ExtendScript/CEP | ✅ UXP is Adobe's official modern platform |
The short version: The AppleScript version puppets InDesign from the outside via macOS automation, writing temp files and hoping nothing interrupts the chain. This version runs inside InDesign as a first-class plugin — faster, more reliable, cross-platform, and built on the platform Adobe is investing in going forward.
How It Works
Claude / MCP Client
│
▼
MCP Server (Node.js)
│ POST /execute
▼
Bridge HTTP Server (port 3000)
│ WebSocket
▼
UXP Plugin (inside InDesign)
│ runs as async IIFE with `app` in scope
▼
InDesign DOM
The UXP plugin maintains a persistent WebSocket connection to the bridge. When a tool is called, the handler sends a JS code string to the bridge, which forwards it to the plugin. The plugin runs it as new Function('app', 'return (async () => { CODE })()') and returns the result as JSON.
Prerequisites
- Adobe InDesign 2024+ (UXP plugin support required)
- Node.js 18+
- macOS or Windows
Setup
1. Install the UXP Plugin
Load the plugin via the UXP Developer Tool or InDesign's plugin manager:
plugin/
├── index.js # Plugin entry point + WebSocket client
└── manifest.json # Plugin manifest
2. Start the Bridge
# Kill any existing bridge processes
lsof -ti:3001 | xargs kill 2>/dev/null
lsof -ti:3000 | xargs kill 2>/dev/null
# Start the bridge
cd bridge && node server.js
3. Connect the Plugin
In InDesign: Window → Plugins → InDesign Bridge
The panel should show: Connected to bridge ✓
4. Start the MCP Server
npm install
npm start
5. Configure Claude
Add to ~/.claude.json (or your MCP client config):
{
"mcpServers": {
"indesign": {
"command": "node",
"args": ["/path/to/indesign-uxp-server/src/index.js"]
}
}
}
Testing
# Quick sanity check (4 core tools)
node tests/test-uxp-handlers.js
# Full suite (27 tests across all handler categories)
node tests/test-all-handlers.js
Current status: 27/27 passing across all handler categories.
Tools
Documents
create_document open_document save_document close_document get_document_info get_document_preferences set_document_preferences get_document_elements get_document_styles get_document_colors get_document_layers get_document_stories get_document_hyperlinks create_document_hyperlink get_document_sections create_document_section get_document_grid_settings set_document_grid_settings get_document_layout_preferences set_document_layout_preferences get_document_xml_structure export_document_xml preflight_document validate_document cleanup_document data_merge save_document_to_cloud open_cloud_document view_document
Pages & Spreads
add_page delete_page duplicate_page move_page get_page_info set_page_properties adjust_page_layout resize_page reframe_page navigate_to_page select_page zoom_to_page set_page_background create_page_guides place_file_on_page place_xml_on_page get_page_content_summary snapshot_page_layout delete_page_layout_snapshot delete_all_page_layout_snapshots list_spreads get_spread_info duplicate_spread move_spread delete_spread set_spread_properties create_spread_guides place_file_on_spread place_xml_on_spread select_spread get_spread_content_summary
Text & Tables
create_text_frame edit_text_frame create_table populate_table find_replace_text find_text_in_document
Styles & Colors
create_paragraph_style apply_paragraph_style create_character_style list_styles create_color_swatch list_color_swatches apply_color create_object_style list_object_styles apply_object_style
Graphics & Shapes
place_image get_image_info create_rectangle create_ellipse create_polygon
Layers
create_layer set_active_layer list_layers organize_document_layers
Page Items
get_page_item_info select_page_item move_page_item resize_page_item set_page_item_properties duplicate_page_item delete_page_item list_page_items
Groups
create_group create_group_from_items ungroup get_group_info add_item_to_group remove_item_from_group list_groups set_group_properties
Master Spreads
create_master_spread list_master_spreads delete_master_spread duplicate_master_spread apply_master_spread get_master_spread_info create_master_text_frame create_master_rectangle create_master_guides detach_master_items remove_master_override
Export & Output
export_pdf export_images export_epub package_document
Books
create_book open_book list_books add_document_to_book synchronize_book repaginate_book export_book package_book preflight_book print_book get_book_info set_book_properties update_all_cross_references update_all_numbers update_chapter_and_paragraph_numbers
Utility
execute_indesign_code get_session_info clear_session help
Architecture
src/
├── core/
│ ├── InDesignMCPServer.js # MCP server, tool registration
│ ├── scriptExecutor.js # executeViaUXP() — POSTs to bridge
│ └── sessionManager.js # Page dimension tracking, smart positioning
├── handlers/
│ ├── documentHandlers.js
│ ├── pageHandlers.js
│ ├── textHandlers.js
│ ├── styleHandlers.js
│ ├── graphicsHandlers.js
│ ├── masterSpreadHandlers.js
│ ├── pageItemHandlers.js
│ ├── groupHandlers.js
│ ├── bookHandlers.js
│ ├── exportHandlers.js
│ └── utilityHandlers.js
├── types/ # MCP tool schema definitions
└── utils/stringUtils.js
bridge/
└── server.js # HTTP (port 3000) + WebSocket (port 3001) bridge
plugin/
├── index.js # UXP plugin — runs code inside InDesign
└── manifest.json
tests/
├── test-uxp-handlers.js # 4 core handler tests
└── test-all-handlers.js # 27-test comprehensive suite
Key UXP API Notes
- InDesign collections require
.item(n)— bracket access[n]returns undefined doc.filePathis async — alwaysawaitit in UXP codeexportFile(format, path)— format arg is first (same as ExtendScript)- Enums via
require('indesign'):ExportFormat.pdfType,ColorModel.process, etc. - Path strings work directly for
place()andexportFile()— no UXP storage API needed - Code runs as
async IIFE— usereturnto return values,awaitworks natively
License
MIT
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.