indesign-cli 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cli_anything/indesign/README.md +32 -0
- cli_anything/indesign/__init__.py +1 -0
- cli_anything/indesign/__main__.py +5 -0
- cli_anything/indesign/core/artifacts.py +57 -0
- cli_anything/indesign/core/catalog.py +405 -0
- cli_anything/indesign/core/domains.py +178 -0
- cli_anything/indesign/core/envelope.py +65 -0
- cli_anything/indesign/core/errors.py +30 -0
- cli_anything/indesign/core/health.py +46 -0
- cli_anything/indesign/core/hidden_backend.py +116 -0
- cli_anything/indesign/core/hidden_handler_schemas.py +223 -0
- cli_anything/indesign/core/mcp_backend.py +152 -0
- cli_anything/indesign/core/node_setup.py +35 -0
- cli_anything/indesign/core/paths.py +41 -0
- cli_anything/indesign/core/plugins/__init__.py +2 -0
- cli_anything/indesign/core/plugins/backend.py +90 -0
- cli_anything/indesign/core/plugins/discovery.py +69 -0
- cli_anything/indesign/core/plugins/host_actions.py +76 -0
- cli_anything/indesign/core/plugins/install.py +38 -0
- cli_anything/indesign/core/plugins/manifest.py +279 -0
- cli_anything/indesign/core/plugins/validate.py +181 -0
- cli_anything/indesign/core/router.py +217 -0
- cli_anything/indesign/core/runtime.py +59 -0
- cli_anything/indesign/core/scripts.py +44 -0
- cli_anything/indesign/core/session.py +68 -0
- cli_anything/indesign/indesign_cli.py +320 -0
- cli_anything/indesign/node/hidden_handler_bridge.mjs +111 -0
- cli_anything/indesign/server/package-lock.json +168 -0
- cli_anything/indesign/server/package.json +45 -0
- cli_anything/indesign/server/src/advanced/index.js +76 -0
- cli_anything/indesign/server/src/core/InDesignMCPServer.js +273 -0
- cli_anything/indesign/server/src/core/scriptExecutor.js +271 -0
- cli_anything/indesign/server/src/core/sessionManager.js +545 -0
- cli_anything/indesign/server/src/handlers/advancedTemplateHandlers.js +1072 -0
- cli_anything/indesign/server/src/handlers/bookHandlers.js +490 -0
- cli_anything/indesign/server/src/handlers/documentHandlers.js +1472 -0
- cli_anything/indesign/server/src/handlers/exportHandlers.js +208 -0
- cli_anything/indesign/server/src/handlers/graphicsHandlers.js +605 -0
- cli_anything/indesign/server/src/handlers/groupHandlers.js +358 -0
- cli_anything/indesign/server/src/handlers/helpHandlers.js +347 -0
- cli_anything/indesign/server/src/handlers/index.js +77 -0
- cli_anything/indesign/server/src/handlers/layerHandlers.js +75 -0
- cli_anything/indesign/server/src/handlers/masterSpreadHandlers.js +451 -0
- cli_anything/indesign/server/src/handlers/pageHandlers.js +698 -0
- cli_anything/indesign/server/src/handlers/pageItemHandlers.js +704 -0
- cli_anything/indesign/server/src/handlers/presentationHandlers.js +220 -0
- cli_anything/indesign/server/src/handlers/spreadHandlers.js +348 -0
- cli_anything/indesign/server/src/handlers/styleHandlers.js +458 -0
- cli_anything/indesign/server/src/handlers/textHandlers.js +431 -0
- cli_anything/indesign/server/src/handlers/utilityHandlers.js +83 -0
- cli_anything/indesign/server/src/index.js +17 -0
- cli_anything/indesign/server/src/types/index.js +106 -0
- cli_anything/indesign/server/src/types/toolDefinitionsAdvancedTemplates.js +144 -0
- cli_anything/indesign/server/src/types/toolDefinitionsBook.js +224 -0
- cli_anything/indesign/server/src/types/toolDefinitionsContent.js +353 -0
- cli_anything/indesign/server/src/types/toolDefinitionsDocument.js +409 -0
- cli_anything/indesign/server/src/types/toolDefinitionsExport.js +65 -0
- cli_anything/indesign/server/src/types/toolDefinitionsLayer.js +40 -0
- cli_anything/indesign/server/src/types/toolDefinitionsMasterSpread.js +160 -0
- cli_anything/indesign/server/src/types/toolDefinitionsPage.js +271 -0
- cli_anything/indesign/server/src/types/toolDefinitionsPageItemGroup.js +437 -0
- cli_anything/indesign/server/src/types/toolDefinitionsPresentation.js +83 -0
- cli_anything/indesign/server/src/types/toolDefinitionsSpread.js +158 -0
- cli_anything/indesign/server/src/types/toolDefinitionsUtility.js +40 -0
- cli_anything/indesign/server/src/utils/stringUtils.js +107 -0
- cli_anything/indesign/skills/SKILL.md +198 -0
- indesign_cli-0.2.0.dist-info/METADATA +267 -0
- indesign_cli-0.2.0.dist-info/RECORD +72 -0
- indesign_cli-0.2.0.dist-info/WHEEL +5 -0
- indesign_cli-0.2.0.dist-info/entry_points.txt +3 -0
- indesign_cli-0.2.0.dist-info/licenses/LICENSE +21 -0
- indesign_cli-0.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
2
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
+
import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
4
|
+
import { advancedTemplateToolDefinitions } from '../types/toolDefinitionsAdvancedTemplates.js';
|
|
5
|
+
import { AdvancedTemplateHandlers } from '../handlers/advancedTemplateHandlers.js';
|
|
6
|
+
import { formatErrorResponse } from '../utils/stringUtils.js';
|
|
7
|
+
|
|
8
|
+
const TOOL_MAP = {
|
|
9
|
+
list_template_blueprints: AdvancedTemplateHandlers.listTemplateBlueprints,
|
|
10
|
+
inspect_template_blueprint: AdvancedTemplateHandlers.inspectTemplate,
|
|
11
|
+
create_page_with_template: AdvancedTemplateHandlers.createPageWithTemplate,
|
|
12
|
+
get_page_information: AdvancedTemplateHandlers.getPageInformation,
|
|
13
|
+
populate_template_slots: AdvancedTemplateHandlers.fillTemplateFromSlots,
|
|
14
|
+
run_jsx_file: AdvancedTemplateHandlers.runJsxFile,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
class AdvancedTemplateServer {
|
|
18
|
+
constructor() {
|
|
19
|
+
this.server = new Server(
|
|
20
|
+
{
|
|
21
|
+
name: 'indesign-template-orchestrator',
|
|
22
|
+
version: '0.1.0'
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
capabilities: {
|
|
26
|
+
tools: {}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
32
|
+
tools: advancedTemplateToolDefinitions.map((tool) => ({
|
|
33
|
+
name: tool.name,
|
|
34
|
+
description: tool.description,
|
|
35
|
+
inputSchema: tool.inputSchema
|
|
36
|
+
}))
|
|
37
|
+
}));
|
|
38
|
+
|
|
39
|
+
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
40
|
+
const { name, arguments: args } = request.params;
|
|
41
|
+
const handler = TOOL_MAP[name];
|
|
42
|
+
if (!handler) {
|
|
43
|
+
const payload = formatErrorResponse(`Tool not found: ${name}`, 'Advanced Template Tool Call');
|
|
44
|
+
return {
|
|
45
|
+
content: [{ type: 'text', text: JSON.stringify(payload, null, 2) }]
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const result = await handler(args || {});
|
|
50
|
+
return {
|
|
51
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]
|
|
52
|
+
};
|
|
53
|
+
} catch (error) {
|
|
54
|
+
const payload = formatErrorResponse(error.message, `Advanced Template Tool '${name}'`);
|
|
55
|
+
return {
|
|
56
|
+
content: [{ type: 'text', text: JSON.stringify(payload, null, 2) }]
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async run() {
|
|
63
|
+
const transport = new StdioServerTransport();
|
|
64
|
+
await this.server.connect(transport);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function main() {
|
|
69
|
+
const server = new AdvancedTemplateServer();
|
|
70
|
+
await server.run();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
main().catch((error) => {
|
|
74
|
+
console.error('Failed to start advanced template server:', error);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
});
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main InDesign MCP Server class
|
|
3
|
+
*/
|
|
4
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
5
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
6
|
+
import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
7
|
+
import { allToolDefinitions } from '../types/index.js';
|
|
8
|
+
import {
|
|
9
|
+
BookHandlers,
|
|
10
|
+
DocumentHandlers,
|
|
11
|
+
ExportHandlers,
|
|
12
|
+
GraphicsHandlers,
|
|
13
|
+
GroupHandlers,
|
|
14
|
+
HelpHandlers,
|
|
15
|
+
MasterSpreadHandlers,
|
|
16
|
+
SpreadHandlers,
|
|
17
|
+
LayerHandlers,
|
|
18
|
+
PageHandlers,
|
|
19
|
+
PageItemHandlers,
|
|
20
|
+
StyleHandlers,
|
|
21
|
+
TextHandlers,
|
|
22
|
+
UtilityHandlers,
|
|
23
|
+
PresentationHandlers
|
|
24
|
+
} from '../handlers/index.js';
|
|
25
|
+
import { formatErrorResponse } from '../utils/stringUtils.js';
|
|
26
|
+
|
|
27
|
+
export class InDesignMCPServer {
|
|
28
|
+
constructor() {
|
|
29
|
+
this.server = new Server(
|
|
30
|
+
{
|
|
31
|
+
name: 'indesign-server-complete',
|
|
32
|
+
version: '1.0.0',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
capabilities: {
|
|
36
|
+
tools: {},
|
|
37
|
+
},
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
this.setupToolHandlers();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
setupToolHandlers() {
|
|
45
|
+
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
46
|
+
tools: allToolDefinitions,
|
|
47
|
+
}));
|
|
48
|
+
|
|
49
|
+
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
50
|
+
const { name, arguments: args } = request.params;
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
const result = await this.handleToolCall(name, args);
|
|
54
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
55
|
+
} catch (error) {
|
|
56
|
+
return { content: [{ type: 'text', text: `Error: ${error.message}` }] };
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async handleToolCall(name, args) {
|
|
62
|
+
// Document Management
|
|
63
|
+
switch (name) {
|
|
64
|
+
case 'get_document_info': return await DocumentHandlers.getDocumentInfo();
|
|
65
|
+
case 'create_document': return await DocumentHandlers.createDocument(args);
|
|
66
|
+
case 'open_document': return await DocumentHandlers.openDocument(args);
|
|
67
|
+
case 'save_document': return await DocumentHandlers.saveDocument(args);
|
|
68
|
+
case 'close_document': return await DocumentHandlers.closeDocument();
|
|
69
|
+
|
|
70
|
+
// Document Advanced Tools
|
|
71
|
+
case 'preflight_document': return await DocumentHandlers.preflightDocument(args);
|
|
72
|
+
case 'zoom_to_page': return await DocumentHandlers.zoomToPage(args);
|
|
73
|
+
case 'data_merge': return await DocumentHandlers.dataMerge(args);
|
|
74
|
+
|
|
75
|
+
// Document Elements & Styles
|
|
76
|
+
case 'get_document_elements': return await DocumentHandlers.getDocumentElements(args);
|
|
77
|
+
case 'get_document_styles': return await DocumentHandlers.getDocumentStyles(args);
|
|
78
|
+
case 'get_document_colors': return await DocumentHandlers.getDocumentColors(args);
|
|
79
|
+
|
|
80
|
+
// Document Preferences
|
|
81
|
+
case 'get_document_preferences': return await DocumentHandlers.getDocumentPreferences(args);
|
|
82
|
+
case 'set_document_preferences': return await DocumentHandlers.setDocumentPreferences(args);
|
|
83
|
+
|
|
84
|
+
// Document Stories & Text
|
|
85
|
+
case 'get_document_stories': return await DocumentHandlers.getDocumentStories(args);
|
|
86
|
+
case 'find_text_in_document': return await DocumentHandlers.findTextInDocument(args);
|
|
87
|
+
|
|
88
|
+
// Document Layers & Organization
|
|
89
|
+
case 'get_document_layers': return await DocumentHandlers.getDocumentLayers(args);
|
|
90
|
+
case 'organize_document_layers': return await DocumentHandlers.organizeDocumentLayers(args);
|
|
91
|
+
|
|
92
|
+
// Document Hyperlinks & Interactivity
|
|
93
|
+
case 'get_document_hyperlinks': return await DocumentHandlers.getDocumentHyperlinks(args);
|
|
94
|
+
case 'create_document_hyperlink': return await DocumentHandlers.createDocumentHyperlink(args);
|
|
95
|
+
|
|
96
|
+
// Document Sections & Numbering
|
|
97
|
+
case 'get_document_sections': return await DocumentHandlers.getDocumentSections();
|
|
98
|
+
case 'create_document_section': return await DocumentHandlers.createDocumentSection(args);
|
|
99
|
+
|
|
100
|
+
// Document XML & Structure
|
|
101
|
+
case 'get_document_xml_structure': return await DocumentHandlers.getDocumentXmlStructure(args);
|
|
102
|
+
case 'export_document_xml': return await DocumentHandlers.exportDocumentXml(args);
|
|
103
|
+
|
|
104
|
+
// Document Cloud & Collaboration
|
|
105
|
+
case 'save_document_to_cloud': return await DocumentHandlers.saveDocumentToCloud(args);
|
|
106
|
+
case 'open_cloud_document': return await DocumentHandlers.openCloudDocument(args);
|
|
107
|
+
|
|
108
|
+
// Document Grid & Layout
|
|
109
|
+
case 'get_document_grid_settings': return await DocumentHandlers.getDocumentGridSettings();
|
|
110
|
+
case 'set_document_grid_settings': return await DocumentHandlers.setDocumentGridSettings(args);
|
|
111
|
+
case 'get_document_layout_preferences': return await DocumentHandlers.getDocumentLayoutPreferences();
|
|
112
|
+
case 'set_document_layout_preferences': return await DocumentHandlers.setDocumentLayoutPreferences(args);
|
|
113
|
+
|
|
114
|
+
// Document Validation & Cleanup
|
|
115
|
+
case 'validate_document': return await DocumentHandlers.validateDocument(args);
|
|
116
|
+
case 'cleanup_document': return await DocumentHandlers.cleanupDocument(args);
|
|
117
|
+
|
|
118
|
+
// Page Management
|
|
119
|
+
case 'add_page': return await PageHandlers.addPage(args);
|
|
120
|
+
case 'get_page_info': return await PageHandlers.getPageInfo(args);
|
|
121
|
+
case 'navigate_to_page': return await PageHandlers.navigateToPage(args);
|
|
122
|
+
|
|
123
|
+
// Advanced Page Management
|
|
124
|
+
case 'duplicate_page': return await PageHandlers.duplicatePage(args);
|
|
125
|
+
case 'move_page': return await PageHandlers.movePage(args);
|
|
126
|
+
case 'delete_page': return await PageHandlers.deletePage(args);
|
|
127
|
+
case 'set_page_properties': return await PageHandlers.setPageProperties(args);
|
|
128
|
+
case 'set_page_background': return await PageHandlers.setPageBackground(args);
|
|
129
|
+
case 'adjust_page_layout': return await PageHandlers.adjustPageLayout(args);
|
|
130
|
+
case 'resize_page': return await PageHandlers.resizePage(args);
|
|
131
|
+
case 'create_page_guides': return await PageHandlers.createPageGuides(args);
|
|
132
|
+
case 'place_file_on_page': return await PageHandlers.placeFileOnPage(args);
|
|
133
|
+
case 'place_xml_on_page': return await PageHandlers.placeXmlOnPage(args);
|
|
134
|
+
case 'snapshot_page_layout': return await PageHandlers.snapshotPageLayout(args);
|
|
135
|
+
case 'delete_page_layout_snapshot': return await PageHandlers.deletePageLayoutSnapshot(args);
|
|
136
|
+
case 'delete_all_page_layout_snapshots': return await PageHandlers.deleteAllPageLayoutSnapshots(args);
|
|
137
|
+
case 'reframe_page': return await PageHandlers.reframePage(args);
|
|
138
|
+
case 'select_page': return await PageHandlers.selectPage(args);
|
|
139
|
+
case 'get_page_content_summary': return await PageHandlers.getPageContentSummary(args);
|
|
140
|
+
|
|
141
|
+
// Text Management
|
|
142
|
+
case 'create_text_frame': return await TextHandlers.createTextFrame(args);
|
|
143
|
+
case 'edit_text_frame': return await TextHandlers.editTextFrame(args);
|
|
144
|
+
case 'create_table': return await TextHandlers.createTable(args);
|
|
145
|
+
case 'populate_table': return await TextHandlers.populateTable(args);
|
|
146
|
+
case 'find_replace_text': return await TextHandlers.findReplaceText(args);
|
|
147
|
+
|
|
148
|
+
// Graphics Management
|
|
149
|
+
case 'create_rectangle': return await GraphicsHandlers.createRectangle(args);
|
|
150
|
+
case 'create_ellipse': return await GraphicsHandlers.createEllipse(args);
|
|
151
|
+
case 'create_polygon': return await GraphicsHandlers.createPolygon(args);
|
|
152
|
+
case 'place_image': return await GraphicsHandlers.placeImage(args);
|
|
153
|
+
case 'create_object_style': return await GraphicsHandlers.createObjectStyle(args);
|
|
154
|
+
case 'list_object_styles': return await GraphicsHandlers.listObjectStyles();
|
|
155
|
+
case 'apply_object_style': return await GraphicsHandlers.applyObjectStyle(args);
|
|
156
|
+
case 'get_image_info': return await GraphicsHandlers.getImageInfo(args);
|
|
157
|
+
|
|
158
|
+
// Style Management
|
|
159
|
+
case 'create_paragraph_style': return await StyleHandlers.createParagraphStyle(args);
|
|
160
|
+
case 'create_character_style': return await StyleHandlers.createCharacterStyle(args);
|
|
161
|
+
case 'apply_paragraph_style': return await StyleHandlers.applyParagraphStyle(args);
|
|
162
|
+
case 'apply_character_style': return await StyleHandlers.applyCharacterStyle(args);
|
|
163
|
+
case 'apply_color': return await StyleHandlers.applyColor(args);
|
|
164
|
+
case 'create_color_swatch': return await StyleHandlers.createColorSwatch(args);
|
|
165
|
+
case 'list_styles': return await StyleHandlers.listStyles(args);
|
|
166
|
+
case 'list_color_swatches': return await StyleHandlers.listColorSwatches();
|
|
167
|
+
|
|
168
|
+
// Export Functions
|
|
169
|
+
case 'export_pdf': return await ExportHandlers.exportPDF(args);
|
|
170
|
+
case 'export_images': return await ExportHandlers.exportImages(args);
|
|
171
|
+
case 'package_document': return await ExportHandlers.packageDocument(args);
|
|
172
|
+
case 'export_epub': return await ExportHandlers.exportEPUB(args);
|
|
173
|
+
|
|
174
|
+
// Master Spread Management
|
|
175
|
+
case 'create_master_spread': return await MasterSpreadHandlers.createMasterSpread(args);
|
|
176
|
+
case 'list_master_spreads': return await MasterSpreadHandlers.listMasterSpreads(args);
|
|
177
|
+
case 'delete_master_spread': return await MasterSpreadHandlers.deleteMasterSpread(args);
|
|
178
|
+
case 'duplicate_master_spread': return await MasterSpreadHandlers.duplicateMasterSpread(args);
|
|
179
|
+
case 'apply_master_spread': return await MasterSpreadHandlers.applyMasterSpread(args);
|
|
180
|
+
case 'create_master_text_frame': return await MasterSpreadHandlers.createMasterTextFrame(args);
|
|
181
|
+
case 'create_master_rectangle': return await MasterSpreadHandlers.createMasterRectangle(args);
|
|
182
|
+
case 'create_master_guides': return await MasterSpreadHandlers.createMasterGuides(args);
|
|
183
|
+
case 'get_master_spread_info': return await MasterSpreadHandlers.getMasterSpreadInfo(args);
|
|
184
|
+
case 'detach_master_items': return await MasterSpreadHandlers.detachMasterItems(args);
|
|
185
|
+
case 'remove_master_override': return await MasterSpreadHandlers.removeMasterOverride(args);
|
|
186
|
+
|
|
187
|
+
// Spread Management
|
|
188
|
+
case 'list_spreads': return await SpreadHandlers.listSpreads(args);
|
|
189
|
+
case 'get_spread_info': return await SpreadHandlers.getSpreadInfo(args);
|
|
190
|
+
case 'duplicate_spread': return await SpreadHandlers.duplicateSpread(args);
|
|
191
|
+
case 'move_spread': return await SpreadHandlers.moveSpread(args);
|
|
192
|
+
case 'delete_spread': return await SpreadHandlers.deleteSpread(args);
|
|
193
|
+
case 'set_spread_properties': return await SpreadHandlers.setSpreadProperties(args);
|
|
194
|
+
case 'create_spread_guides': return await SpreadHandlers.createSpreadGuides(args);
|
|
195
|
+
case 'place_file_on_spread': return await SpreadHandlers.placeFileOnSpread(args);
|
|
196
|
+
case 'place_xml_on_spread': return await SpreadHandlers.placeXmlOnSpread(args);
|
|
197
|
+
case 'select_spread': return await SpreadHandlers.selectSpread(args);
|
|
198
|
+
case 'get_spread_content_summary': return await SpreadHandlers.getSpreadContentSummary(args);
|
|
199
|
+
|
|
200
|
+
// Layer Management
|
|
201
|
+
case 'create_layer': return await LayerHandlers.createLayer(args);
|
|
202
|
+
case 'set_active_layer': return await LayerHandlers.setActiveLayer(args);
|
|
203
|
+
case 'list_layers': return await LayerHandlers.listLayers(args);
|
|
204
|
+
|
|
205
|
+
// Book Management
|
|
206
|
+
case 'create_book': return await BookHandlers.createBook(args);
|
|
207
|
+
case 'open_book': return await BookHandlers.openBook(args);
|
|
208
|
+
case 'list_books': return await BookHandlers.listBooks(args);
|
|
209
|
+
case 'add_document_to_book': return await BookHandlers.addDocumentToBook(args);
|
|
210
|
+
case 'synchronize_book': return await BookHandlers.synchronizeBook(args);
|
|
211
|
+
case 'repaginate_book': return await BookHandlers.repaginateBook(args);
|
|
212
|
+
case 'update_all_cross_references': return await BookHandlers.updateAllCrossReferences(args);
|
|
213
|
+
case 'update_all_numbers': return await BookHandlers.updateAllNumbers(args);
|
|
214
|
+
case 'update_chapter_and_paragraph_numbers': return await BookHandlers.updateChapterAndParagraphNumbers(args);
|
|
215
|
+
case 'export_book': return await BookHandlers.exportBook(args);
|
|
216
|
+
case 'package_book': return await BookHandlers.packageBook(args);
|
|
217
|
+
case 'preflight_book': return await BookHandlers.preflightBook(args);
|
|
218
|
+
case 'print_book': return await BookHandlers.printBook(args);
|
|
219
|
+
case 'get_book_info': return await BookHandlers.getBookInfo(args);
|
|
220
|
+
case 'set_book_properties': return await BookHandlers.setBookProperties(args);
|
|
221
|
+
|
|
222
|
+
// PageItem Management
|
|
223
|
+
case 'get_page_item_info': return await PageItemHandlers.getPageItemInfo(args);
|
|
224
|
+
case 'select_page_item': return await PageItemHandlers.selectPageItem(args);
|
|
225
|
+
case 'move_page_item': return await PageItemHandlers.movePageItem(args);
|
|
226
|
+
case 'resize_page_item': return await PageItemHandlers.resizePageItem(args);
|
|
227
|
+
case 'set_page_item_properties': return await PageItemHandlers.setPageItemProperties(args);
|
|
228
|
+
case 'duplicate_page_item': return await PageItemHandlers.duplicatePageItem(args);
|
|
229
|
+
case 'delete_page_item': return await PageItemHandlers.deletePageItem(args);
|
|
230
|
+
case 'get_page_item_script_labels': return await PageItemHandlers.getPageItemScriptLabels(args);
|
|
231
|
+
case 'set_page_item_script_label': return await PageItemHandlers.setPageItemScriptLabel(args);
|
|
232
|
+
case 'list_page_items': return await PageItemHandlers.listPageItems(args);
|
|
233
|
+
|
|
234
|
+
// Group Management
|
|
235
|
+
case 'create_group': return await GroupHandlers.createGroup(args);
|
|
236
|
+
case 'create_group_from_items': return await GroupHandlers.createGroupFromItems(args);
|
|
237
|
+
case 'ungroup': return await GroupHandlers.ungroup(args);
|
|
238
|
+
case 'get_group_info': return await GroupHandlers.getGroupInfo(args);
|
|
239
|
+
case 'add_item_to_group': return await GroupHandlers.addItemToGroup(args);
|
|
240
|
+
case 'remove_item_from_group': return await GroupHandlers.removeItemFromGroup(args);
|
|
241
|
+
case 'list_groups': return await GroupHandlers.listGroups(args);
|
|
242
|
+
case 'set_group_properties': return await GroupHandlers.setGroupProperties(args);
|
|
243
|
+
|
|
244
|
+
// Utility Functions
|
|
245
|
+
case 'execute_indesign_code': return await UtilityHandlers.executeInDesignCode(args);
|
|
246
|
+
case 'view_document': return await UtilityHandlers.viewDocument();
|
|
247
|
+
case 'get_session_info': return await UtilityHandlers.getSessionInfo();
|
|
248
|
+
case 'clear_session': return await UtilityHandlers.clearSession();
|
|
249
|
+
|
|
250
|
+
// Presentation (Architecture report deck)
|
|
251
|
+
case 'create_presentation_document': return await PresentationHandlers.createPresentationDocument(args);
|
|
252
|
+
case 'add_cover_page': return await PresentationHandlers.addCoverPage(args);
|
|
253
|
+
case 'add_section_page': return await PresentationHandlers.addSectionPage(args);
|
|
254
|
+
case 'add_full_bleed_image': return await PresentationHandlers.addFullBleedImage(args);
|
|
255
|
+
case 'add_image_grid': return await PresentationHandlers.addImageGrid(args);
|
|
256
|
+
case 'export_presentation_pdf': return await PresentationHandlers.exportPresentationPDF(args);
|
|
257
|
+
|
|
258
|
+
// Help System
|
|
259
|
+
case 'help': return await HelpHandlers.getHelp(args);
|
|
260
|
+
|
|
261
|
+
// Add more handlers as we create them
|
|
262
|
+
default:
|
|
263
|
+
return formatErrorResponse(`Tool '${name}' not found or not implemented. Use 'help' to see available tools.`, "Tool Call");
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
async run() {
|
|
268
|
+
const transport = new StdioServerTransport();
|
|
269
|
+
await this.server.connect(transport);
|
|
270
|
+
// Don't log to stdout as it interferes with MCP protocol
|
|
271
|
+
// console.log('InDesign MCP Server started');
|
|
272
|
+
}
|
|
273
|
+
}
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core script execution functionality (macOS AppleScript + Windows COM)
|
|
3
|
+
*/
|
|
4
|
+
import { execFileSync } from 'child_process';
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import os from 'os';
|
|
8
|
+
import { fileURLToPath } from 'url';
|
|
9
|
+
import { createRequire } from 'module';
|
|
10
|
+
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
+
const __dirname = path.dirname(__filename);
|
|
13
|
+
|
|
14
|
+
const EXTENDSCRIPT_RUNTIME_SNIPPET = `
|
|
15
|
+
if (typeof JSON === "undefined") { JSON = {}; }
|
|
16
|
+
function __mcpJsonSeenContains(arr, value) {
|
|
17
|
+
for (var i = 0; i < arr.length; i++) {
|
|
18
|
+
if (arr[i] === value) return true;
|
|
19
|
+
}
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
function __mcpJsonEscapeString(str) {
|
|
23
|
+
if (str === null || str === undefined) return "";
|
|
24
|
+
var result = "";
|
|
25
|
+
var backslash = String.fromCharCode(92);
|
|
26
|
+
for (var i = 0; i < str.length; i++) {
|
|
27
|
+
var ch = str.charAt(i);
|
|
28
|
+
var code = str.charCodeAt(i);
|
|
29
|
+
if (code === 34) {
|
|
30
|
+
result += backslash + '"';
|
|
31
|
+
} else if (code === 92) {
|
|
32
|
+
result += backslash + backslash;
|
|
33
|
+
} else if (code === 8) {
|
|
34
|
+
result += backslash + "b";
|
|
35
|
+
} else if (code === 9) {
|
|
36
|
+
result += backslash + "t";
|
|
37
|
+
} else if (code === 10) {
|
|
38
|
+
result += backslash + "n";
|
|
39
|
+
} else if (code === 12) {
|
|
40
|
+
result += backslash + "f";
|
|
41
|
+
} else if (code === 13) {
|
|
42
|
+
result += backslash + "r";
|
|
43
|
+
} else if (code === 0x2028 || code === 0x2029) {
|
|
44
|
+
result += backslash + "u" + code.toString(16);
|
|
45
|
+
} else if (code < 32) {
|
|
46
|
+
var hex = code.toString(16);
|
|
47
|
+
result += backslash + "u" + ("0000" + hex).slice(-4);
|
|
48
|
+
} else {
|
|
49
|
+
result += ch;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
function __mcpJsonSerialize(value) {
|
|
55
|
+
var seen = [];
|
|
56
|
+
function serialize(v) {
|
|
57
|
+
if (v === null) return "null";
|
|
58
|
+
var t = typeof v;
|
|
59
|
+
if (t === "number" || t === "boolean") return String(v);
|
|
60
|
+
if (t === "string") return '"' + __mcpJsonEscapeString(v) + '"';
|
|
61
|
+
if (v instanceof Array) {
|
|
62
|
+
var arr = [];
|
|
63
|
+
for (var i = 0; i < v.length; i++) arr.push(serialize(v[i]));
|
|
64
|
+
return "[" + arr.join(",") + "]";
|
|
65
|
+
}
|
|
66
|
+
if (t === "object") {
|
|
67
|
+
if (__mcpJsonSeenContains(seen, v)) return '"[Circular]"';
|
|
68
|
+
seen.push(v);
|
|
69
|
+
var props = [];
|
|
70
|
+
for (var key in v) {
|
|
71
|
+
if (!v.hasOwnProperty(key)) continue;
|
|
72
|
+
props.push('"' + __mcpJsonEscapeString(key) + '":' + serialize(v[key]));
|
|
73
|
+
}
|
|
74
|
+
seen.pop();
|
|
75
|
+
return "{" + props.join(",") + "}";
|
|
76
|
+
}
|
|
77
|
+
return "null";
|
|
78
|
+
}
|
|
79
|
+
return serialize(value);
|
|
80
|
+
}
|
|
81
|
+
if (typeof JSON.stringify !== "function") {
|
|
82
|
+
JSON.stringify = function(value) { return __mcpJsonSerialize(value); };
|
|
83
|
+
}
|
|
84
|
+
if (typeof JSON.parse !== "function") {
|
|
85
|
+
JSON.parse = function(text) { return eval("(" + text + ")"); };
|
|
86
|
+
}
|
|
87
|
+
`;
|
|
88
|
+
|
|
89
|
+
export class ScriptExecutor {
|
|
90
|
+
// Cache a COM Application instance for Windows to avoid repeated activation
|
|
91
|
+
static _winApp = null;
|
|
92
|
+
|
|
93
|
+
static isWindows() {
|
|
94
|
+
return process.platform === 'win32';
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Execute AppleScript command (macOS only)
|
|
99
|
+
* @param {string} script - The AppleScript to execute
|
|
100
|
+
* @returns {string} The result of the AppleScript execution
|
|
101
|
+
*/
|
|
102
|
+
static async executeAppleScript(script) {
|
|
103
|
+
try {
|
|
104
|
+
const result = execFileSync('osascript', ['-e', script], { encoding: 'utf8' });
|
|
105
|
+
return result.trim();
|
|
106
|
+
} catch (error) {
|
|
107
|
+
throw new Error(`AppleScript execution failed: ${error.message}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Resolve a Windows COM InDesign.Application object via winax
|
|
113
|
+
* Tries multiple ProgIDs to maximize compatibility across versions.
|
|
114
|
+
*/
|
|
115
|
+
static _getWindowsInDesignApp() {
|
|
116
|
+
if (!this.isWindows()) {
|
|
117
|
+
throw new Error('Windows COM is only available on Windows');
|
|
118
|
+
}
|
|
119
|
+
if (this._winApp) return this._winApp;
|
|
120
|
+
|
|
121
|
+
// Lazy-require winax to avoid issues on non-Windows platforms
|
|
122
|
+
const requireCjs = createRequire(import.meta.url);
|
|
123
|
+
let WinaxObject;
|
|
124
|
+
try {
|
|
125
|
+
const winax = requireCjs('winax');
|
|
126
|
+
// winax provides constructor as winax.Object and also sets global.ActiveXObject in CJS
|
|
127
|
+
WinaxObject = winax.Object || global.ActiveXObject;
|
|
128
|
+
} catch (e) {
|
|
129
|
+
throw new Error("Missing dependency 'winax'. Please run: npm install winax");
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Prefer explicit recent desktop ProgIDs, then generic, then older versions
|
|
133
|
+
const progIDs = [
|
|
134
|
+
// Newer/future first
|
|
135
|
+
'InDesign.Application.2026',
|
|
136
|
+
'InDesign.Application.CC.2026',
|
|
137
|
+
// Current
|
|
138
|
+
'InDesign.Application.2025',
|
|
139
|
+
'InDesign.Application.CC.2025',
|
|
140
|
+
// Generic
|
|
141
|
+
'InDesign.Application',
|
|
142
|
+
// Recent past
|
|
143
|
+
'InDesign.Application.2024',
|
|
144
|
+
'InDesign.Application.CC.2024',
|
|
145
|
+
'InDesign.Application.2023',
|
|
146
|
+
'InDesign.Application.CC.2023',
|
|
147
|
+
'InDesign.Application.2022',
|
|
148
|
+
'InDesign.Application.CC.2022',
|
|
149
|
+
// InDesign Server fallbacks (least preferred)
|
|
150
|
+
'InDesignServer.Application.2025',
|
|
151
|
+
'InDesignServer.Application.2024',
|
|
152
|
+
'InDesignServer.Application',
|
|
153
|
+
];
|
|
154
|
+
|
|
155
|
+
let lastError;
|
|
156
|
+
for (const id of progIDs) {
|
|
157
|
+
try {
|
|
158
|
+
const app = new WinaxObject(id);
|
|
159
|
+
this._winApp = app;
|
|
160
|
+
return app;
|
|
161
|
+
} catch (err) {
|
|
162
|
+
lastError = err;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
throw new Error(
|
|
166
|
+
`Could not create InDesign COM object. Tried: ${progIDs.join(', ')}. ` +
|
|
167
|
+
`Last error: ${lastError?.message || lastError}. ` +
|
|
168
|
+
`Tips: Ensure Adobe InDesign desktop is installed and has been launched at least once, ` +
|
|
169
|
+
`and that COM registration is available. If installation is fresh, try restarting or running once as administrator.`
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Execute InDesign ExtendScript/JavaScript code
|
|
175
|
+
* - On Windows: Use COM DoScript via winax
|
|
176
|
+
* - On macOS: Use AppleScript to run the temp JSX file
|
|
177
|
+
* @param {string} script - The ExtendScript to execute
|
|
178
|
+
* @returns {string} The result of the script execution
|
|
179
|
+
*/
|
|
180
|
+
static async executeInDesignScript(script) {
|
|
181
|
+
if (this.isWindows()) {
|
|
182
|
+
return await this._executeInDesignScriptWindows(script);
|
|
183
|
+
}
|
|
184
|
+
// macOS path (AppleScript + temp JSX file)
|
|
185
|
+
let tempDir;
|
|
186
|
+
let tempScriptPath;
|
|
187
|
+
try {
|
|
188
|
+
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'indesign-mcp-'));
|
|
189
|
+
tempScriptPath = path.join(tempDir, 'script.jsx');
|
|
190
|
+
|
|
191
|
+
// Force non-interactive (headless) execution where possible
|
|
192
|
+
const wrapped = [
|
|
193
|
+
'try {',
|
|
194
|
+
' app.scriptPreferences.userInteractionLevel = UserInteractionLevels.NEVER_INTERACT;',
|
|
195
|
+
EXTENDSCRIPT_RUNTIME_SNIPPET,
|
|
196
|
+
script,
|
|
197
|
+
'} catch (e) {',
|
|
198
|
+
' "Error: " + e.message;',
|
|
199
|
+
'}'
|
|
200
|
+
].join('\n');
|
|
201
|
+
fs.writeFileSync(tempScriptPath, wrapped, { encoding: 'utf8' });
|
|
202
|
+
|
|
203
|
+
const escapedScriptPath = tempScriptPath.replace(/"/g, '\\"');
|
|
204
|
+
const appleScript = `
|
|
205
|
+
tell application "Adobe InDesign 2025"
|
|
206
|
+
do script POSIX file "${escapedScriptPath}" language javascript
|
|
207
|
+
end tell
|
|
208
|
+
`;
|
|
209
|
+
|
|
210
|
+
const result = await this.executeAppleScript(appleScript);
|
|
211
|
+
|
|
212
|
+
return result;
|
|
213
|
+
} catch (error) {
|
|
214
|
+
throw new Error(`Error executing tool (macOS): ${error.message}`);
|
|
215
|
+
} finally {
|
|
216
|
+
if (tempDir) {
|
|
217
|
+
try { fs.rmSync(tempDir, { recursive: true, force: true }); } catch {}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Execute a JSX file directly so $.fileName, relative #include, etc. behave correctly.
|
|
224
|
+
* @param {string} filePath - Absolute or relative path to the JSX file.
|
|
225
|
+
* @returns {string} The result of the script execution.
|
|
226
|
+
*/
|
|
227
|
+
static async executeInDesignScriptFile(filePath) {
|
|
228
|
+
if (!filePath || typeof filePath !== 'string') {
|
|
229
|
+
throw new Error('filePath must be a string');
|
|
230
|
+
}
|
|
231
|
+
const resolved = path.resolve(filePath);
|
|
232
|
+
const escaped = resolved.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
233
|
+
const wrapper = [
|
|
234
|
+
'var __mcpResult = "";',
|
|
235
|
+
'try {',
|
|
236
|
+
` var __mcpFile = File("${escaped}");`,
|
|
237
|
+
' if (!__mcpFile.exists) { throw new Error("JSX 文件不存在: " + __mcpFile.fsName); }',
|
|
238
|
+
' __mcpResult = app.doScript(__mcpFile, ScriptLanguage.JAVASCRIPT);',
|
|
239
|
+
'} catch (e) {',
|
|
240
|
+
' __mcpResult = "Error: " + (e && e.message ? e.message : e);',
|
|
241
|
+
'}',
|
|
242
|
+
'__mcpResult;'
|
|
243
|
+
].join('\n');
|
|
244
|
+
return await this.executeInDesignScript(wrapper);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Windows: Execute via COM DoScript
|
|
249
|
+
*/
|
|
250
|
+
static async _executeInDesignScriptWindows(script) {
|
|
251
|
+
try {
|
|
252
|
+
const app = this._getWindowsInDesignApp();
|
|
253
|
+
// Wrap to enforce non-interactive mode and basic error capture
|
|
254
|
+
const wrapped = [
|
|
255
|
+
'try {',
|
|
256
|
+
' app.scriptPreferences.userInteractionLevel = UserInteractionLevels.NEVER_INTERACT;',
|
|
257
|
+
EXTENDSCRIPT_RUNTIME_SNIPPET,
|
|
258
|
+
script,
|
|
259
|
+
'} catch (e) {',
|
|
260
|
+
' "Error: " + e.message;',
|
|
261
|
+
'}'
|
|
262
|
+
].join('\n');
|
|
263
|
+
// ScriptLanguage.JAVASCRIPT (numeric enum for COM environments)
|
|
264
|
+
const ScriptLanguage_JAVASCRIPT = 1246973031;
|
|
265
|
+
const result = app.DoScript(wrapped, ScriptLanguage_JAVASCRIPT);
|
|
266
|
+
return (result === undefined || result === null) ? '' : String(result);
|
|
267
|
+
} catch (error) {
|
|
268
|
+
throw new Error(`Windows COM execution failed: ${error.message}`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|