关于 Adobe InDesign
面向需要创建、编辑、检查和导出 InDesign 文档的 Agent,借助本地桥接控制 Adobe InDesign。项目提供广泛的文档操作,并附带用于版面与制作任务的 AI 技能。
主要功能
- 01控制文本、图形、图像和表格
- 02管理文档、页面、样式和主页
- 03导出并预检多种格式
- 04使用 GREP 搜索和替换文本
- 05附带 10 项制作类 AI 技能
适用场景
- 01根据电子表格生成目录页面
- 02导入 Word 文件并制作书籍版面
- 03批量生成模板的不同版本
- 04印刷导出前检查字体和链接
MCP 相关
该 MCP 服务将 InDesign 文档操作作为工具和资源提供给 MCP 客户端。它通过 stdio 与 Agent 通信,并经由本地 WebSocket 桥接连接 InDesign。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
197收录的工具列表 · 更新于 1 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| slug | object | 否 | |
| slug.top | number | 否 | |
| slug.left | number | 否 | |
| slug.right | number | 否 | |
| slug.bottom | number | 否 | |
| bleed | object | 否 | |
| bleed.top | number | 否 | |
| bleed.left | number | 否 | |
| bleed.right | number | 否 | |
| bleed.bottom | number | 否 | |
| pages | integer | 否 | |
| width | number | 否 | |
| height | number | 否 | |
| margins | object | 否 | |
| margins.top | number | 否 | |
| margins.left | number | 否 | |
| margins.right | number | 否 | |
| margins.bottom | number | 否 | |
| document_id | any | 否 | 要操作的已打开文档:名称(参见 document_listOpen)或从 0 开始的索引。默认为最前面的文档。 |
| facingPages | boolean | 否 | |
| orientation | enum | 否 | portrait | landscape |
详细介绍
只需说“创建一个 5 页的 A4 文档,并在第 3 页添加一个红色圆形”——它就会帮你完成。
最全面的 Adobe InDesign MCP 服务。199 个工具。35 个处理程序。全面覆盖 DOM。
⚡ 点击观看快速演示 · v1.1.0 版本发布
已发布到 npm,包名为
indesign-nutria-mcp。 你的 Agent 使用npx -y indesign-nutria-mcp启动它——请参阅 快速开始。InDesign 仍在你的电脑上运行: MCP 服务通过本地桥接连接它,所有数据都保留在本机。
🚀 为什么要开发它
InDesign 自动化 20 年来一直问题重重。 ExtendScript 年久失修。CEP 面板过度复杂。UXP 脚本需要计算机科学学位。你只想让 AI 帮你完成排版。
这个 MCP 服务解决了这些问题。克隆它,将 Agent 指向它,InDesign 就能任你驱使,如同提线木偶。
🆚 MCP 与旧方法对比
| MCP(本项目) | ExtendScript | CEP 面板 | UXP 脚本 | 手动操作 | |
|---|---|---|---|---|---|
| 上手时间 | 30 秒 | 3 周 | 2 个月 | 1 个月 | 0(但速度慢) |
| 原生支持 AI | ✅ 任意 MCP Agent | ❌ | ❌ | ❌ | ❌ |
| 工具数量 | 199 | 不限(由你编写) | 通常为 5-20 个 | 通常为 5-20 个 | ∞(手动操作) |
| 错误消息 | 人类可读 | 含糊不清的崩溃信息 | 不一 | 更好 | 不适用 |
| 设置时间 | 5 分钟 | 10 分钟 | 2 小时 | 30 分钟 | 即时 |
| 撤销支持 | ✅ 内置 | ❌ | 不一 | ❌ | ✅ |
| 搜索文本 | text_search("pattern") | 编写 50 行代码 | 也许可以 | 也许可以 | Ctrl+F |
| 调试模式 | ✅ 堆栈跟踪 | ❌ | 不一 | 有限 | 不适用 |
| 远程控制 | ✅ 任何支持 STDIO 的环境 | ❌ 仅限 InDesign | ❌ | ❌ | 不适用 |
| 维护 | 零成本(我们维护 199 个工具) | 你负责编写和测试全部内容 | 脆弱易损 | 脆弱易损 | 不适用 |
✨ 它能做什么
📝 文本与排版(27 个工具)
创建文本框、设置内容、应用段落/字符样式、控制格式、使用 GREP 搜索、查找/替换、应用字体、设置分栏、内边距、自动调整大小、垂直对齐、首字下沉、保持选项、断字、制表位、段落线、文本绕排、基线、链接/取消链接。
🎨 形状与对象(20 个工具)
矩形、椭圆、多边形、线条、组、锚定对象——创建、修改、删除、列出、排列。
🖼️ 图像(5 个工具)
从磁盘置入、查询元数据、适合框架/按比例缩放、调整亮度/对比度、重新链接。
🎭 颜色与色板(6 个工具)
CMYK/RGB/LAB/专色,油墨列表、渐变,以及应用到填充/描边。
📄 页面与文档(15 个工具)
创建、打开、保存、关闭、getInfo、listOpen — 以及添加/删除/复制/移动页面、getInfo/listAll/applyMaster、版面分区。
📊 表格(20 个工具)
创建、设置单元格、添加/删除行列、合并/拆分、对齐、填充、描边、内边距、页眉/页脚、行列尺寸、表格样式、单元格样式。
🧬 样式(10 个工具)
段落、字符、对象样式 — 创建、列出、复制、删除、应用。
🏗️ 主页与书籍(10 个工具)
主页跨页 — 创建、复制、应用、删除、列出、getPages。书籍 — 列出、打开、getDocuments、同步。
📤 导出(9 个工具)
PDF、EPUB、HTML、JPG、PNG、打包 — 以及预检、字体/色板/表格列表,还有用于自定义 ExtendScript 的 script_run()。
🔍 查找与替换(5 个工具)
GREP 查找/替换、支持格式条件的查找/替换。
🔄 变换(5 个工具)
对齐、分布、旋转、缩放、翻转。
🔗 交互(5 个工具)
超链接、按钮、交叉引用锚点。
📚 参考内容(10 个工具)
脚注、尾注、交叉引用、索引条目/主题/生成。
📋 列表(6 个工具)
定义、应用到段落/选区、移除、重新开始编号。
🧩 XML 与数据合并(11 个工具)
XML 标签、导入/导出,以及使用 CSV/TSV/XML 数据源进行数据合并。
🔧 其他
图层、效果(投影、羽化、透明度)、目录、版面分区、撤销/重做、撤销组。
🧠 内置 AI 技能
仓库内置了十项技能;使用任何 AI Agent 时,技能会根据触发关键词自动加载:
| # | 技能 | 能为你做什么 |
|---|---|---|
| 1 | 审美偏好 | 在任何创意工作开始前询问 8 个问题 — 字体、配色、风格、页边距。并生成持久化的 JSON 配置文件。 |
| 2 | 版面可读性 | 在交付前检查叠加、对比度、孤行/寡行、层级、间距和溢出。 |
| 3 | 导出与验证 | 强制执行修改 → 导出 JPG → 分析像素 → 修复 → 重复的循环。 |
| 4 | 导入 Word | 导入 .docx,将 Word 样式映射到 InDesign 段落样式。 |
| 5 | 批量操作 | 在 N 个页面上应用相同的修改。 |
| 6 | 图像优化 | 置入、调整大小、检查 DPI、重新链接。提供印刷版(300dpi CMYK)与网页版(72dpi RGB)配置文件。 |
| 7 | 表格格式 | 创建并设置表格样式 — 列、行、边框、填充、合并单元格。 |
| 8 | 模板管理器 | 保存/加载可重复使用的页面模板。 |
| 9 | 批量导出 | 使用不同配置文件,将同一文档一次性导出为多种格式。 |
| 10 | 样式提取器 | 扫描 .indd 文件,将完整样式配置文件(字体、颜色、样式、主页、页边距)提取为 JSON,并在新布局中复现。 |
🏗️ 架构
┌─────────────────────┐ STDIO ┌──────────────────────┐ WebSocket ┌──────────────────┐
│ Any AI Agent │ ◄────────────────► │ indesign-nutria-mcp │ ◄───────────────► │ Adobe InDesign │
│ (Claude, OpenCode, │ │ (Node.js MCP Server) │ port 8120 │ + UXP Plugin │
│ Cursor, etc.) │ │ 35 handlers │ │ + ExtendScript │
└─────────────────────┘ │ 199 tools │ └──────────────────┘
│ 10 AI skills │
└──────────────────────┘
连接 InDesign 的两种方式
MCP 协议始终使用 stdio 通信。只有最后一跳有所不同;每个平台可选择其中一种:
| macOS | Windows | |
|---|---|---|
| 使用插件 | plugin/ 中的 UXP 面板 | plugin/ 中的 UXP 面板 |
| 不使用插件 | node bridge-proxy.mjs(JXA/osascript) | COM_BRIDGE_ENABLED=true(进程内 COM) |
两种方式均受支持。插件是功能更丰富的方案(还会发出变更事件);对于无法或不想加载 UXP 面板的配置,代理则可派上用场。Windows 桥接请参阅 WINDOWS.md,macOS 桥接请参阅 start-bridge.sh。
完整说明: macOS 上的四个进程、请求生命周期、错误约定和信任边界,请参阅 docs/architecture.md。
完整处理器目录
| 处理器 | 工具 | 主要功能 |
|---|---|---|
| AnchoredObject | 5 | create、getSettings、release、setPosition、setProperties |
| Book | 4 | list、open、getDocuments、synchronize |
| Changes | 1 | getStatus — 查看自 T? 以来的更改,不触碰 InDesign |
| Color | 6 | 色板 CRUD、油墨、渐变、应用 |
| DataMerge | 5 | selectDataSource、listFields、mergeRecords、export、removeDataSource |
| Document | 9 | create/open/save/close、getInfo、listOpen、getState、getPageStories、getStoryPages |
| Effect | 4 | 投影、羽化、透明度、渐变羽化 |
| Export | 11 | 多格式导出、打印打包、批量文件夹、印前检查、字体/色板/表格/主页/XML、executeScript、script_run |
| Font | 5 | list、find、change、缺失检查、字形插入 |
| Grep | 4 | find、replace、findFormat、replaceFormat |
| Image | 5 | place、info、adjust、fit、relink |
| Index | 4 | addEntry、createTopic、generate、listTopics |
| Interactive | 5 | 超链接、按钮、锚点 |
| Layer | 5 | create、delete、list、reorder、setProperties |
| List | 6 | define、apply、remove、重新开始编号 |
| Master | 6 | create、duplicate、apply、delete、list、getPages |
| Note | 4 | 脚注、尾注 |
| Object | 6 | 形状、组、图像链接 |
| Page | 7 | add、delete、duplicate、move、getInfo、listAll、applyMaster |
| Preview | 1 | document — 将页面渲染为 Agent 可查看的图像 |
| Recipe | 2 | 将已置入的文本故事流排至多个页面、使用命名 PDF 预设导出 — 每项操作各自作为一个撤销组 |
| Resources | 6 | 列出/更新/嵌入/取消嵌入链接、getLinkInfo |
| Section | 4 | create、list、setNumbering、delete |
| Shape | 6 | 创建矩形/椭圆/直线/多边形、删除、修改 |
| Style | 7 | 段落/字符/对象样式 CRUD |
| Table | 16 | 创建、单元格、行/列、合并/拆分、对齐、填充、描边、页眉/页脚 |
| TableStyle | 4 | tableStyle、cellStyle CRUD |
| Text | 7 | 文本框、内容、故事、findReplace、BOM 过滤、超时 |
| TextAdvanced | 20 | 分栏、文本绕排、链接、首字下沉、段落线、制表位、格式读取/写入、搜索 |
| Typography | 1 | 只读审查正在使用的字体、字号/行距组合、样式使用情况及覆盖 |
| Toc | 4 | createStyle、generate、update、listStyles |
| Transform | 5 | 对齐、分布、旋转、缩放、翻转 |
| Undo | 5 | undo、redo、history、beginGroup、endGroup |
| Xml | 6 | 标签 CRUD、标记/取消标记项目、导入/导出 |
| Xref | 3 | create、list、updateFormat |
| 199 | 35 个处理器,无重复项 |
tests/contract/toolInventory.test.ts 会锁定此数字,因此如果表格与代码不一致,CI 就会失败。
已在 InDesign 2026(21.3)上通过无插件 macOS 路径完成端到端验证: MCP stdio → WebSocket bridge → JXA proxy → InDesign,创建文档、 添加文本框、读取文本并关闭文档。
要从 Agent 关闭文档?
document_close默认使用saveOptions: "no"— 这是唯一不会弹出模态对话框的值。"ask"会打开保存提示;对于从未保存过的文档,"yes"会打开 Save As 对话框;两者都会阻塞脚本,直到桥接超时。请先使用document_save { filePath }保存,再关闭文档。
MCP 资源
| URI | 提供内容 |
|---|---|
mcp://session/status | 活动文档会话状态 |
mcp://bridge/status | WebSocket bridge 健康状况 + 队列深度 |
mcp://tools/inventory | 完整的 199 个工具目录,供 Agent 自行发现 |
mcp://document/active | 当前活动文档信息 |
🎯 使用场景
🏢 代理公司制作
“根据这个 CSV 创建一本 200 页的目录。产品名称使用 14pt Arial Bold,价格使用 12pt Arial Regular,描述使用 10pt。第 1、50、100、150 页添加红色的‘SALE’徽章。导出为 PDF。”
📚 图书出版
“导入这份 Word 文档。将 Heading 1 映射到「章标题」样式,将 Normal 映射到「正文」样式。添加包含页码的页眉。生成目录。导出为带裁切标记的 PDF。”
🎨 创意自动化
“使用这个 InDesign 模板,根据这份电子表格中的不同颜色和文本生成 50 个版本。将每个版本分别导出为 PDF。”
🏭 印刷制作
“检查全部 200 个文件,找出缺失的字体和失效的链接。修复它们。导出为 PDF/X-1a。”
🔄 持续出版
“每天早上 8 点,用 CMS 中的最新内容更新日报模板,执行印前检查,然后上传到 Web 服务。”
⚡ 快速开始(30 秒)
分为两部分:Agent 运行的服务——通过 npm 一行命令启动,无需克隆或构建;以及连接到这台机器上 InDesign 的桥接程序。
1️⃣ 连接 InDesign
服务会监听 127.0.0.1:8120;还需要有东西来驱动 InDesign。根据平台选择:
macOS — 使用 UXP 面板(也会发出更改事件)
- 打开 UXP Developer Tool
- 加载
plugin/目录——该目录随此仓库一同提供,因此只需克隆一次:git clone https://github.com/nutriandrea/adobe-indesign-mcp(无需构建) - 打开 MCP Bridge 面板——它会自动连接
macOS — 不使用面板
git clone https://github.com/nutriandrea/adobe-indesign-mcp
cd adobe-indesign-mcp
npm install # gives the proxy its `ws` dependency; nothing to build
./start-bridge.sh # launches InDesign, then the JXA proxy
Windows — 无需桥接进程。 COM 桥接程序会在 InDesign 进程内驱动 InDesign,因此 Windows 无需克隆仓库,也无需启动第二个进程;在第 2 步使用的配置中,通过环境变量启用它(参见
examples/claude-desktop.windows.json)。
详情和注意事项请参阅 WINDOWS.md。
2️⃣ 连接 AI Agent
两个宿主都会启动同一个已发布的软件包——无需克隆,也无需构建。
Claude Desktop:
{
"mcpServers": {
"indesign": {
"command": "npx",
"args": ["-y", "indesign-nutria-mcp"]
}
}
}
OpenCode(项目中的 opencode.json,或 ~/.config/opencode/opencode.json 中的相同配置块):
{
"mcp": {
"servers": {
"indesign": {
"type": "local",
"command": ["npx", "-y", "indesign-nutria-mcp"]
}
}
}
}
在 OpenCode 中,服务器配置位于 mcp.servers 下,而非 mcpServers,并且命令是一个数组——这是文档所述的 V2 格式。
Claude Desktop、Cursor 和 Claude Code 的现成配置文件(包括 Windows COM 版本)位于 examples/。每个文件都可直接复制粘贴。
3️⃣ 开始创作
🤖 "Create a landscape A3 document with 3 pages."
🤖 "Add a blue rectangle covering the top half of page 1."
🤖 "In the rectangle, add text 'Hello World' in white, Arial Bold 72pt."
🤖 "Export page 1 as JPG."
📝 MCP 客户端开发者须知
正在基于此服务构建自定义客户端(脚本、测试框架、测试运行器)?以下是实际集成中的两点经验:
| 陷阱 | 修复方法 |
|---|---|
大型响应会拆分到多个 stdout 数据块中。 preview_document 在 150ppi 下会返回约 100 KB 以上的 base64 数据,超过单个管道数据块的大小。对每个 data 事件使用 JSON.parse(chunk) 解析,会悄无声息地丢弃部分数据,并导致调用似乎永远卡住。 | 将 stdin 累积到缓冲区中,只对完整的、以换行符分隔的行调用 JSON.parse:buf += chunk; while ((i = buf.indexOf('\n')) >= 0) { parse(buf.slice(0, i)); buf = buf.slice(i + 1); } |
图像工具返回的是 image 内容,而非 text。 preview_document 会返回 { type: 'image', mimeType: 'image/png', data: '<base64>' }——读取 .text 会得到 undefined。 | 从 content[0].data 读取 base64 数据(检查 content[0].type)。 |
每条消息都是以 \n 结尾的单行 JSON-RPC 对象;除了换行符之外没有其他分帧方式。
🆕 v1.6.0 新内容
已修复
| ⚠️ | 编写脚本前请先阅读 |
|---|---|
| 布局技能提到了不存在的工具 | skills/indesign/indesign-mcp-layout/SKILL.md 声称工具前缀为 mcp_indesign_*,但注册表从未使用过这个前缀;它还将连通性检查指向 health_check 和 list_ai_skills,但没有任何处理程序注册这两个工具。技能是指令,因此提及无法解析的工具,会让模型在处理原有问题时再遭遇一次失败。 |
| 变更 | 对你的意义 |
|---|---|
| 技能现在使用真实工具名称 | 它指向注册表实际公开的裸工具名称,并记录了只读资源(mcp://bridge/status 等);这些资源不会触及 InDesign,也无需往返调用。 |
| 技能和指令一样受到检查 | tests/unit/skillGuidance.test.ts 会遍历 skills/ 和 marketplace/ 下的每个 SKILL.md,若其中包含注册表不认识的工具名称,或技能的 frontmatter name 与其文件夹名称不一致,就会报错。该测试已针对上述错误验证回归。 |
| 市场中的数量也会检查 | verify:tool-counts 现在会读取 marketplace/ 下的 Markdown,因此,提供给买家的数量会与 README、llms.txt 和软件包描述中的数量一并检查。 |
新增
| 变更 | 对你的意义 |
|---|---|
| 客户端配置 | examples/ 提供可直接复制粘贴的 Claude Desktop(macOS 和 Windows COM 版本)、Cursor 和 Claude Code 配置,以及 examples/README.md。 |
| 注册表和软件包元数据 | server.json 由 package.json 生成,并通过 verify:server-json 检查;另有 mcpb/manifest.json,因此可从同一版本发布到 MCP Registry 和 MCP Bundle。 |
| 发布自动化 | release.yml 会让标签依次通过 verify 和 verify:pack,以 provenance 发布到 npm、构建 .mcpb,并将其与 CHANGELOG 说明一起附加到 GitHub Release。publish-mcp-registry.yml 会在发布后接续运行,因此注册表绝不会宣传 npm 上尚未发布的版本。validate-release-tag.sh 会拒绝与 package.json 中的版本不一致或没有对应 CHANGELOG 章节的标签。 |
| 打包的配套技能 | marketplace/agensi/ 用于为第三方市场准备技能;npm run build:agensi 会验证审核方要求的归档结构:仅有一个顶层文件夹、根目录中有 SKILL.md,且只包含文本文件。与 mcpb/ 一样,它不会发布到 npm。 |
v1.5.0
### 面向 AI Agent| ⚠️ | 编写脚本前请阅读 |
|---|---|
传入 document_id——不要依赖当前标签页 | 每个工具都接受可选的 document_id:文档名称(document_listOpen 报告的名称)或从 0 开始的索引。打开多个文档时,当前标签页不一定是预期目标;如果调用落在错误的文档上,就会编辑错误的文件。调用 document_getState,然后在之后的所有调用中传入 document_id。 |
| 变更 | 对你的意义 |
|---|---|
每个工具都支持 document_id | 199 个工具均增加了一个可选参数。省略该参数时,工具会操作当前文档——与之前的行为完全相同,因此你现有的调用无需更改。 |
| 目标文档未打开时会明确报错 | 如果 document_id 为 'Gone.indd',且该文档未打开,则会报错:document_id 'Gone.indd' is not open. Open documents: A.indd, B.indd,错误分类为 document_not_found,并建议调用 document_listOpen。此前,脚本会静默编辑碰巧位于最前面的文档。 |
| 统一的解析器 | app.activeDocument 曾在 32 个处理器中的 197 处以内联方式编写;现在,每个脚本都会注入 __resolveDocument(),所有与文档相关的处理器都会通过它解析目标文档,因此整个调用期间目标文档都保持不变——即使脚本运行期间当前标签页发生变化也不例外。 |
| 从设计上确保安全 | document_id 会以 JSON 字符串字面量的形式传递给 InDesign,并按名称匹配,因此不会被执行。它通过 AsyncLocalStorage 按调用绑定,因此即使调用在分派前等待,也不会被并发调用劫持。 |
变更
| 变更 | 对你的意义 |
|---|---|
| “固定文档”的建议现在可以直接执行 | 连接时的约定过去要求主机询问要操作哪个文档。现在,它明确指定了 document_id 及其传递方式,随附的 indesign-mcp-layout 技能也指向了该说明。 |
v1.4.3
### 面向 AI Agent| ⚠️ | 编写脚本前请阅读 |
|---|---|
| 失败时会告诉你如何恢复 | 调用失败时会返回 JSON 封装 { ok: false, code, message, suggested_next_tool?, suggested_args? },而不是文本说明。请根据 code 分支处理;如果存在 suggested_next_tool,就调用它,不要猜测。 |
| 先获取状态,再执行操作 | document_getState 会在一次往返调用中返回前台文档的几何信息、索引、所有打开的文档、活动图层和选区数量。修改文档前请先调用它,而不是通过四个独立调用来拼凑状态。 |
| 配方只需调用一次,无需串联调用 | recipe_flowTextStory 会放置文本文件并将其排入多个页面;recipe_exportPreset 会应用指定的 PDF 预设并导出。实测中,排入文本的成本为 1 次调用 / 215 字节,而最接近的原子调用链需要 6 次调用 / 786 字节,且根本无法放置文本。 |
| 变更 | 对你的意义 |
|---|---|
| 结构化错误封装 | 共 16 种失败类型,每种都带有经过实时注册表检查的 suggested_next_tool(帧索引无效时建议调用 document_getInfo;超时时建议调用 document_listOpen)。ExtendScript 错误会附带 line、file 和 stack。 |
| 连接时提供工作流约定 | 服务会公布约 680 个 token 的 instructions,涵盖桥接初始化、先获取状态再执行操作、document_close 的保存陷阱、错误封装格式和撤销分组。 |
document_getState | 一次往返调用即可替代 document_getInfo + document_listOpen + 图层 + 选区这一调用序列。 |
preview_document 接受 documentIndex | 可渲染任意打开的文档,而不只是前台文档。导出文件上限为 4 MB;如果分辨率不合适,会先按适合的分辨率重新渲染一次,之后才报错 output_too_large。 |
| 新增两种配方 | recipe_flowTextStory 和 recipe_exportPreset,目录现有 197 种配方。 |
| 可选的成功封装 | RESPONSE_ENVELOPE_SUCCESS(或 responseEnvelope.success)会将成功结果封装为 { ok: true, ... },让成功和失败都使用同一个键来区分。默认关闭,因为它会改变响应格式。 |
| 更精简、正确的程序包 | 通过 files 允许列表取代 .npmignore 排除列表:解包后为 1.6 MB,低于原来的 4.4 MB;macOS 启动器执行的 bridge-proxy.mjs 现在也确实包含在程序包中。 |
变更
| 变更 | 对你的意义 |
|---|---|
| 错误响应为 JSON 文本 | 错误消息会原样保留在封装中;isError: true 保持不变。 |
document_close 的 saveOptions 默认为 "no" | "ask" 会弹出模态保存对话框,导致操作被阻塞,直到桥接超时,还可能使 InDesign 陷入无响应;"no" 不会弹出提示。想保留工作时,请先调用 document_save。 |
修复
| 修复 | 含义 |
|---|---|
调用 undo_beginGroup 后的每次调用都会失败 | wrapExtendScript 设置了 InDesign 中不存在的属性 app.scriptPreferences.undoMode。现在撤销分组通过 app.doScript(..., UndoModes.ENTIRE_SCRIPT) 执行。 |
每次调用 undo、redo 和 undo_history 都会抛出错误 | 它们读取了不属于 DOM 的 document.undoable / document.redoable。 |
| 服务将自身版本报告为 v1.0.0 | 在 v1.0.0 之后发布了四个版本,它仍在 initialize 时公布旧的硬编码版本号。现在 SERVER_VERSION 是唯一真实来源,并通过两道校验确保其准确。 |
v1.4.2
面向 AI Agent
| ⚠️ | 编写脚本前请阅读 |
|---|---|
| 优先使用带类型的工具 | export_executeScript 和 script_run 不支持取消。脚本卡住会使桥接持续处于忙碌状态,后续每次调用都会排队等待,直到宿主重启。循环、字体枚举和多项修改探测应使用带类型的工具;这些工具会校验参数并设置超时。请参阅 skills/indesign/indesign-mcp-layout。 |
v1.4.0
| 变更 | 对你的意义 |
|---|---|
Agent 视觉能力:preview_document | 将任意页面渲染为 Agent 实际可见的图像,让布局错误能在迭代过程中被发现,而不是等到导出后才发现。 |
批量导出 PDF:export_batchFolder | 一次调用即可将文件夹中的所有 .indd 导出为 PDF,并返回每个文件的结果。 |
| Windows COM 桥接 | 使用 COM_BRIDGE_ENABLED=true,无需任何插件即可运行。请参阅 WINDOWS.md。 |
| 加固文件路径 | 所有会操作文件的工具都会预先验证路径,在 InDesign 接触路径之前就会拒绝目录遍历尝试(..)和系统目录(现有 11 个受保护的调用点)。 |
v1.3.0
| 变更 | 对你的意义 |
|---|---|
| 适配 InDesign 2026 | 颜色和锚定对象工具可使用 2026 中重命名后的枚举,不再因升级而静默失败。 |
| 真正读取环境变量配置 | .env.example 中的所有设置现在都会生效:BRIDGE_PORT、HTTP_BRIDGE_ENABLED、LOG_LEVEL、……无效值不会阻止启动。 |
| 不再卡住 30 秒 | 如果插件未连接,工具调用会立即返回“Bridge is not connected”错误,而不是一直等到超时。 |
| 统一转义方式 | 所有处理程序共用一套经过充分验证的 ExtendScript 字符串转义器。 |
| 加固路径验证 | 文件路径检查现在使用真正的包含关系判断(不会因前缀冲突而绕过检查)。 |
| 状态如实反映连接情况 | getStatus().connected 会反映插件的实际连接状态,CI 也会强制执行覆盖率门槛。 |
v1.1.0 新增内容
| 功能 | 工具 | 解决的问题 | |---------|-------|----------------| | **读取文本格式** | `text_getFormatting` | 获取每个文本范围的字体、字号和样式。无需再编写自定义脚本。 | | **应用字符样式** | `text_applyCharStyle` | 通过一次调用应用到某个范围。 | | **应用字体** | `text_applyFont` | 将字体系列、样式和字号应用到某个范围。 | | **文本搜索** | `text_search`、`text_searchFormatting` | 支持 GREP 和格式感知搜索,并提供相对于段落的位置。 | | **故事→页面映射** | `document_getPageStories`、`document_getStoryPages` | 查看故事分别位于哪些页面。 | | **撤销分组** | `undo_beginGroup`、`undo_endGroup` | 将多个操作合并为一个撤销步骤。 | | **调试模式** | `script_run(code, debug=true)` | 提供完整的 ExtendScript 堆栈跟踪。 | | **BOM 过滤** | 文本读取 | 默认过滤 `\ufeff` 和 `\u0004`。 | | **超时/最大结果数** | `text_getStories` 等 | 为大型文档设置自定义限制。 | | **MCP 资源** | `mcp://tools/inventory` | Agent 自动发现所有工具。 |⚙️ 配置
所有设置都有默认值,无需进行任何配置。要自定义设置,请将 .env.example 复制为 .env,或传入 JSON 文件;环境变量的优先级高于文件:
BRIDGE_PORT=8120 # WebSocket port the UXP plugin connects to
HTTP_BRIDGE_ENABLED=false # optional REST fallback bridge
HTTP_BRIDGE_PORT=3000
SERVER_TRANSPORT=stdio # stdio | websocket
LOG_LEVEL=info # debug | info | warn | error
COM_BRIDGE_ENABLED=false # Windows only: drive InDesign over COM, no plugin
RESPONSE_ENVELOPE_SUCCESS=false # wrap successful results as { ok: true, ... }
无需插件的 macOS 代理使用独立的变量:
INDESIGN_APP="Adobe InDesign 2026" # matches your installed version
BRIDGE_WS_URL=ws://127.0.0.1:8120
BRIDGE_TIMEOUT_MS=120000 # a long export is not a hang
BRIDGE_RECONNECT_DELAY_MS=3000
优先级:环境变量 > JSON 配置文件 > 默认值。无效值会被忽略,不会导致程序终止。
🪟 Windows
在 Windows 上有两种运行方式:标准 UXP 插件流程(与 macOS 相同),或全新且可选启用的 COM bridge,完全无需插件。请参阅 WINDOWS.md。
📦 项目结构
├── src/
│ ├── server/ # MCP server (STDIO transport)
│ ├── bridge/ # WebSocket bridge, ScriptExecutor, protocol, COM executor
│ ├── handlers/ # 35 handler modules (199 tools)
│ ├── schemas/ # Zod parameter schemas
│ ├── core/ # Session tracking
│ ├── types/ # TypeScript definitions
│ └── utils/ # Config, logger, security, JSON polyfill
├── plugin/ # UXP panel (index.html, index.js, manifest.json)
├── examples/ # Copy-paste client configs (Claude Desktop, Cursor, Claude Code)
├── mcpb/ # MCP Bundle manifest (npm run build:mcpb packs the archive)
├── server.json # MCP Registry manifest (generated from package.json)
├── llms.txt # llms.txt index for agents and directories
├── bridge-proxy.mjs # Plugin-free macOS proxy (JXA/osascript)
├── jxa-driver.js # Runs one ExtendScript inside InDesign
├── start-bridge.sh # Launches InDesign + the proxy
├── skills/ # Agent-facing skills shipped with the server
├── marketplace/ # Store listings that package a skill for third-party channels
├── tests/ # 1131 tests (vitest)
├── .opencode/skills/ # 10 AI agent skills
├── docs/ # Documentation and fork audits
├── media/ # Social preview, hero images
├── dist/ # Compiled output
└── opencode.json # MCP configuration
📋 要求
| 要求 | 版本 |
|---|---|
| Adobe InDesign | 2022+(推荐使用 2024/2025/2026) |
| Node.js | 18+ |
| 操作系统 | macOS 或 Windows(Linux 可运行 MCP 服务,但目前没有适用于 Linux 的 InDesign 自动化方案) |
🧪 开发
npm test # Run 1131 tests
npm run test:watch # Watch mode
npm run build # TypeScript compile
npm run lint # ESLint
实时冒烟测试(macOS)
npm run smoke:macos
npm test 会测试处理程序、协议和启动流程,但无法检测无需插件的 macOS 流程中四个独立进程之间的衔接问题。这个问题并非假设:曾有一个构建版本在 965 项测试全部通过的情况下,桥接程序却从未监听其端口,导致所有工具调用在实际使用中都失败,却没有任何测试报错。
smoke:macos 会针对正在运行的 InDesign,驱动完整链路:MCP stdio → WebSocket bridge → JXA proxy → InDesign。它会创建文档、向文档写入内容、读回内容,然后关闭文档。它会创建一个未保存的文档,并在完成后清理。它需要桌面应用,因此不属于 npm test 的一部分,也不会在 CI 上运行;如果 InDesign 未打开,它会显示 SKIP 提示并以 0 退出。
发布涉及桥接程序、协议、代理或驱动程序的更改前,请手动运行此测试。
npm run smoke:recipes # the live gate for the two recipes
smoke:recipes 会执行单元测试无法完成的操作:使用 recipe_flowTextStory 流入一个长文本文件,检查文档增长量是否与工具报告的完全一致,调用一次 undo,确认整个流入操作合并为一个撤销步骤,然后测试 recipe_exportPreset 的两种预设路径。其他规则与上文相同——需要桌面应用;如果 InDesign 已关闭,则会显示 SKIP 提示并以 0 退出。
npm run smoke:target # the live gate for document_id
smoke:target 会打开两份文档,验证 document_id 的用途:指定非最前文档的调用会编辑那份文档,而不会影响最前面的文档。随后,它会检查索引定位是否有效;省略 document_id 时是否仍作用于最前面的文档(这是新增功能仍保证的行为);未打开的目标是否会返回一个 document_not_found 信封并建议使用 document_listOpen;以及恶意的 document_id 是否只会被忽略,而不会执行。它只会关闭自己创建的文档,从不保存文档,也不会影响任何已存在的文档。其他规则与上文相同——需要桌面应用;如果 InDesign 已关闭,则会显示 SKIP 提示并以 0 退出。
🗺️ 路线图
- InDesign Server — 为 CI/CD 流水线提供无头服务器支持
- 实时预览 — 将 InDesign 画布流式传输给 Agent
- 模板市场 — 分享和发现 InDesign 模板
- 自然语言 → 布局 — 描述一个页面,即可生成一个页面
- 批量 PDF 处理 — 在数百个文件中应用更改
- VSCode 扩展 — 从编辑器控制 InDesign
📚 深入了解
- 架构 — macOS 上的四进程路径、请求生命周期、错误约定
- 可用工具 — 每个工具的详细信息,由注册表生成
- 故障排除 — 模态窗口卡住、端口冲突、缺少字体、脚本被阻止
- 开发 — 构建、测试和实时冒烟测试
- 起源故事 — 本项目如何诞生
- 比较文档 — 深入比较 MCP、CEP 和 ExtendScript
- 发布帖 — 社交媒体发布内容
🤝 贡献
欢迎提交 PR!处理程序模式的设计力求简单:
- 创建
src/handlers/YourHandler.ts - 使用 Zod 模式定义工具
- 在
IndesignMcpServer.ts中注册 - 添加测试
详情请查看 CONTRIBUTING.md。
🙏 致谢
这个服务汇集了四位开发者在实际使用中发现的问题。每一项贡献都修复了真正损坏的功能,而非仅仅满足审美偏好。
-
@graydini —— 构建了本项目如今使用的 Windows COM 桥接:一个持久运行的
cscript进程,维持一个实时 COM 连接;使用NEVER_INTERACT,确保导出对话框绝不会阻塞;并在validateFilePath中加固了路径限制。 请参阅 PR #1 和 PR #21 的合并记录。 此外,他们还报告了 InDesign 2026 API 的不兼容问题,这些问题影响了官方 Windows 支持:ColorModel和AnchorPoint枚举已重命名且为只读,move()不再接受InsertionPoint目标。同一系列工作中的早期修复已合入main,包括样式列表中安全读取basedOn/pointSize、丰富的样式创建参数、将文本内容中的\n规范化为段落分隔符,以及无需eval且能通过 ExtendScript 清理器的 JSON polyfill。 他们的分支还包含特定于 COM 的运维经验——脚本挂起会导致 Windows 桥接卡死且无法恢复;fontFamily、italic和weight在 COM 下会抛出异常;InDesign 必须处于可见运行状态——这些内容现已记录在 WINDOWS.md 和布局技能中。逐文件审查尚未合并内容的报告见 docs/forks/graydini-windows-com-bridge-audit.md。 -
@advaitakelkar —— 在 PR #22 中诊断了 macOS 代理为何会返回无用内容。一份报告指出了三个真实问题:
osascript会将脚本结果发送到 stderr,因此每次成功调用都会被当成失败;脚本通过 shell 的-e引号传递,任何引号、反斜杠或换行符都会被破坏;应用名称被硬编码为“Adobe InDesign 2024”,因此其他所有版本都会失败。同一项工作还将连接握手移出了app.doScript,因为在那里它会被当作 ExtendScript 解析。相关改动已采纳并扩展——请参阅 v1.4.2 新功能。 -
@ijeetu —— 提出了两项容易被忽略但都切实有效的修复。MCP Bridge 面板现在会在打开时连接,而不是等待点击 Connect,因此服务器已在运行时,面板不会再显得毫无反应。此前,他们追查到 JSON polyfill 的解析失败是因为
sanitizeCode()将eval(改写成注释,导致括号无对应内容——已发布的wrapExtendScript已包含这项修复。
📄 许可证
MIT © Andrea Cacioppo
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。