@hybridlabor-api/aos 4.0.2 → 4.1.0
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.
- package/.claude/agents/database-reviewer.md +109 -0
- package/.claude/agents/go-build-resolver.md +112 -0
- package/.claude/agents/opensource-forker.md +216 -0
- package/.claude/agents/opensource-sanitizer.md +206 -0
- package/.claude/agents/security-reviewer.md +126 -0
- package/.claude/agents/silent-failure-hunter.md +68 -0
- package/CLAUDE.md +15 -0
- package/README.md +0 -13
- package/THIRD_PARTY_NOTICES.md +133 -0
- package/package.json +4 -2
- package/skills/basic/bdbmediastorm/SKILL.md +7 -1
- package/skills/basic/startcycle/SKILL.md +2 -0
- package/skills/bdbrainstorm/SKILL.md +1 -0
- package/skills/global_config/plan-canvas/SKILL.md +233 -0
- package/skills/global_config/plan-canvas/scripts/lib/loopback-guard.js +59 -0
- package/skills/global_config/plan-canvas/scripts/lib/plan-canvas/markdown.js +301 -0
- package/skills/global_config/plan-canvas/scripts/lib/plan-canvas/sdk.js +239 -0
- package/skills/global_config/plan-canvas/scripts/lib/plan-canvas/server.js +636 -0
- package/skills/global_config/plan-canvas/scripts/lib/plan-canvas/sessions.js +271 -0
- package/skills/global_config/plan-canvas/scripts/lib/plan-canvas/ui.js +630 -0
- package/skills/global_config/plan-canvas/scripts/plan-canvas.js +419 -0
- package/.agents/skills/firecrawl/SKILL.md +0 -149
- package/.agents/skills/firecrawl/rules/install.md +0 -82
- package/.agents/skills/firecrawl/rules/security.md +0 -26
- package/.agents/skills/firecrawl-agent/SKILL.md +0 -58
- package/.agents/skills/firecrawl-build/SKILL.md +0 -39
- package/.agents/skills/firecrawl-build-interact/SKILL.md +0 -68
- package/.agents/skills/firecrawl-build-onboarding/SKILL.md +0 -103
- package/.agents/skills/firecrawl-build-onboarding/references/auth-flow.md +0 -39
- package/.agents/skills/firecrawl-build-onboarding/references/project-setup.md +0 -20
- package/.agents/skills/firecrawl-build-onboarding/references/sdk-installation.md +0 -17
- package/.agents/skills/firecrawl-build-scrape/SKILL.md +0 -69
- package/.agents/skills/firecrawl-build-search/SKILL.md +0 -69
- package/.agents/skills/firecrawl-crawl/SKILL.md +0 -59
- package/.agents/skills/firecrawl-download/SKILL.md +0 -70
- package/.agents/skills/firecrawl-interact/SKILL.md +0 -84
- package/.agents/skills/firecrawl-map/SKILL.md +0 -51
- package/.agents/skills/firecrawl-scrape/SKILL.md +0 -69
- package/.agents/skills/firecrawl-search/SKILL.md +0 -60
- package/docs/sessions/AUDIT-HANDOVER-2026-08-28.md +0 -169
- package/docs/sessions/BDB_REMOTEOS_MCP_HANDOVER.md +0 -130
- package/docs/sessions/SESSION-HANDOVER-v3.13.md +0 -249
- package/mcps/RhinoMCP/cc-plugin/.claude/settings.json +0 -10
- package/mcps/after-effects-mcp/build/index.js +0 -840
- package/mcps/after-effects-mcp/build/scripts/applyEffect.jsx +0 -153
- package/mcps/after-effects-mcp/build/scripts/applyEffectTemplate.jsx +0 -218
- package/mcps/after-effects-mcp/build/scripts/createComposition.jsx +0 -71
- package/mcps/after-effects-mcp/build/scripts/createShapeLayer.jsx +0 -147
- package/mcps/after-effects-mcp/build/scripts/createSolidLayer.jsx +0 -114
- package/mcps/after-effects-mcp/build/scripts/createTextLayer.jsx +0 -115
- package/mcps/after-effects-mcp/build/scripts/getLayerInfo.jsx +0 -192
- package/mcps/after-effects-mcp/build/scripts/getProjectInfo.jsx +0 -90
- package/mcps/after-effects-mcp/build/scripts/listCompositions.jsx +0 -50
- package/mcps/after-effects-mcp/build/scripts/mcp-bridge-auto.jsx +0 -1773
- package/mcps/after-effects-mcp/build/scripts/setLayerProperties.jsx +0 -160
- package/mcps/bdb-remoteos-mcp/queue.db +0 -0
- package/mcps/bdb-remoteos-mcp/src/bdb_remoteos_mcp/__pycache__/__init__.cpython-312.pyc +0 -0
- package/mcps/bdb-remoteos-mcp/src/bdb_remoteos_mcp/__pycache__/incus_client.cpython-312.pyc +0 -0
- package/mcps/bdb-remoteos-mcp/src/bdb_remoteos_mcp/__pycache__/main.cpython-312.pyc +0 -0
- package/mcps/bdb-remoteos-mcp/src/bdb_remoteos_mcp/__pycache__/queue.cpython-312.pyc +0 -0
- package/mcps/bdb-remoteos-mcp/src/bdb_remoteos_mcp/__pycache__/schemas.cpython-312.pyc +0 -0
- package/mcps/bdb-remoteos-mcp/src/bdb_remoteos_mcp/__pycache__/server.cpython-312.pyc +0 -0
- package/mcps/bdb-remoteos-mcp/src/bdb_remoteos_mcp/__pycache__/webhook.cpython-312.pyc +0 -0
- package/mcps/bdb-remoteos-mcp/tests/__pycache__/__init__.cpython-312.pyc +0 -0
- package/mcps/bdb-remoteos-mcp/tests/__pycache__/mock_incus.cpython-312.pyc +0 -0
- package/mcps/bdb-remoteos-mcp/tests/__pycache__/test_mcp_server.cpython-312-pytest-9.1.1.pyc +0 -0
- package/mcps/bdb-remoteos-mcp/tests/__pycache__/test_security_redteam.cpython-312-pytest-9.1.1.pyc +0 -0
- package/mcps/bdb-remoteos-mcp/tests/__pycache__/test_webhook.cpython-312-pytest-9.1.1.pyc +0 -0
- package/mcps/computer-use-mcp/dist/client.d.ts +0 -150
- package/mcps/computer-use-mcp/dist/client.js +0 -136
- package/mcps/computer-use-mcp/dist/entrypoint.d.ts +0 -16
- package/mcps/computer-use-mcp/dist/entrypoint.js +0 -26
- package/mcps/computer-use-mcp/dist/native.d.ts +0 -212
- package/mcps/computer-use-mcp/dist/native.js +0 -50
- package/mcps/computer-use-mcp/dist/server.d.ts +0 -32
- package/mcps/computer-use-mcp/dist/server.js +0 -342
- package/mcps/computer-use-mcp/dist/session.d.ts +0 -101
- package/mcps/computer-use-mcp/dist/session.js +0 -2372
- package/skills/bdbsaastraining/scripts/__pycache__/build_profile.cpython-314.pyc +0 -0
|
@@ -1,840 +0,0 @@
|
|
|
1
|
-
// src/index.ts
|
|
2
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
-
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
-
import * as fs from "fs";
|
|
5
|
-
import * as os from "os";
|
|
6
|
-
import * as path from "path";
|
|
7
|
-
import { z } from "zod";
|
|
8
|
-
import { fileURLToPath } from "url";
|
|
9
|
-
var server = new McpServer({
|
|
10
|
-
name: "AfterEffectsServer",
|
|
11
|
-
version: "1.0.0"
|
|
12
|
-
});
|
|
13
|
-
var __filename = fileURLToPath(import.meta.url);
|
|
14
|
-
var __dirname = path.dirname(__filename);
|
|
15
|
-
var SCRIPTS_DIR = path.join(__dirname, "scripts");
|
|
16
|
-
var TEMP_DIR = path.join(__dirname, "temp");
|
|
17
|
-
function getAETempDir() {
|
|
18
|
-
const homeDir = os.homedir();
|
|
19
|
-
const bridgeDir = path.join(homeDir, "Documents", "ae-mcp-bridge");
|
|
20
|
-
if (!fs.existsSync(bridgeDir)) {
|
|
21
|
-
fs.mkdirSync(bridgeDir, { recursive: true });
|
|
22
|
-
}
|
|
23
|
-
return bridgeDir;
|
|
24
|
-
}
|
|
25
|
-
function readResultsFromTempFile() {
|
|
26
|
-
try {
|
|
27
|
-
const tempFilePath = path.join(getAETempDir(), "ae_mcp_result.json");
|
|
28
|
-
console.error(`Checking for results at: ${tempFilePath}`);
|
|
29
|
-
if (fs.existsSync(tempFilePath)) {
|
|
30
|
-
const stats = fs.statSync(tempFilePath);
|
|
31
|
-
console.error(`Result file exists, last modified: ${stats.mtime.toISOString()}`);
|
|
32
|
-
const content = fs.readFileSync(tempFilePath, "utf8");
|
|
33
|
-
console.error(`Result file content length: ${content.length} bytes`);
|
|
34
|
-
const thirtySecondsAgo = new Date(Date.now() - 30 * 1e3);
|
|
35
|
-
if (stats.mtime < thirtySecondsAgo) {
|
|
36
|
-
console.error(`WARNING: Result file is older than 30 seconds. After Effects may not be updating results.`);
|
|
37
|
-
return JSON.stringify({
|
|
38
|
-
warning: "Result file appears to be stale (not recently updated).",
|
|
39
|
-
message: "This could indicate After Effects is not properly writing results or the MCP Bridge Auto panel isn't running.",
|
|
40
|
-
lastModified: stats.mtime.toISOString(),
|
|
41
|
-
originalContent: content
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
return content;
|
|
45
|
-
} else {
|
|
46
|
-
console.error(`Result file not found at: ${tempFilePath}`);
|
|
47
|
-
return JSON.stringify({ error: "No results file found. Please run a script in After Effects first." });
|
|
48
|
-
}
|
|
49
|
-
} catch (error) {
|
|
50
|
-
console.error("Error reading results file:", error);
|
|
51
|
-
return JSON.stringify({ error: `Failed to read results: ${String(error)}` });
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
async function waitForBridgeResult(expectedCommand, timeoutMs = 5e3, pollMs = 250) {
|
|
55
|
-
const start = Date.now();
|
|
56
|
-
const resultPath = path.join(getAETempDir(), "ae_mcp_result.json");
|
|
57
|
-
let lastSize = -1;
|
|
58
|
-
while (Date.now() - start < timeoutMs) {
|
|
59
|
-
if (fs.existsSync(resultPath)) {
|
|
60
|
-
try {
|
|
61
|
-
const content = fs.readFileSync(resultPath, "utf8");
|
|
62
|
-
if (content && content.length > 0 && content.length !== lastSize) {
|
|
63
|
-
lastSize = content.length;
|
|
64
|
-
try {
|
|
65
|
-
const parsed = JSON.parse(content);
|
|
66
|
-
if (!expectedCommand || parsed._commandExecuted === expectedCommand) {
|
|
67
|
-
return content;
|
|
68
|
-
}
|
|
69
|
-
} catch {
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
} catch {
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
await new Promise((r) => setTimeout(r, pollMs));
|
|
76
|
-
}
|
|
77
|
-
return JSON.stringify({ error: `Timed out waiting for bridge result${expectedCommand ? ` for command '${expectedCommand}'` : ""}.` });
|
|
78
|
-
}
|
|
79
|
-
function writeCommandFile(command, args = {}) {
|
|
80
|
-
try {
|
|
81
|
-
const commandFile = path.join(getAETempDir(), "ae_command.json");
|
|
82
|
-
const commandData = {
|
|
83
|
-
command,
|
|
84
|
-
args,
|
|
85
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
86
|
-
status: "pending"
|
|
87
|
-
// pending, running, completed, error
|
|
88
|
-
};
|
|
89
|
-
fs.writeFileSync(commandFile, JSON.stringify(commandData, null, 2));
|
|
90
|
-
console.error(`Command "${command}" written to ${commandFile}`);
|
|
91
|
-
} catch (error) {
|
|
92
|
-
console.error("Error writing command file:", error);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
function clearResultsFile() {
|
|
96
|
-
try {
|
|
97
|
-
const resultFile = path.join(getAETempDir(), "ae_mcp_result.json");
|
|
98
|
-
const resetData = {
|
|
99
|
-
status: "waiting",
|
|
100
|
-
message: "Waiting for new result from After Effects...",
|
|
101
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
102
|
-
};
|
|
103
|
-
fs.writeFileSync(resultFile, JSON.stringify(resetData, null, 2));
|
|
104
|
-
console.error(`Results file cleared at ${resultFile}`);
|
|
105
|
-
} catch (error) {
|
|
106
|
-
console.error("Error clearing results file:", error);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
server.resource(
|
|
110
|
-
"compositions",
|
|
111
|
-
"aftereffects://compositions",
|
|
112
|
-
async (uri) => {
|
|
113
|
-
clearResultsFile();
|
|
114
|
-
writeCommandFile("listCompositions", {});
|
|
115
|
-
const result = await waitForBridgeResult("listCompositions", 6e3, 250);
|
|
116
|
-
return {
|
|
117
|
-
contents: [{
|
|
118
|
-
uri: uri.href,
|
|
119
|
-
mimeType: "application/json",
|
|
120
|
-
text: result
|
|
121
|
-
}]
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
);
|
|
125
|
-
server.tool(
|
|
126
|
-
"run-script",
|
|
127
|
-
"Run a read-only script in After Effects",
|
|
128
|
-
{
|
|
129
|
-
script: z.string().describe("Name of the predefined script to run"),
|
|
130
|
-
parameters: z.record(z.string(), z.unknown()).optional().describe("Optional parameters for the script")
|
|
131
|
-
},
|
|
132
|
-
async ({ script, parameters = {} }) => {
|
|
133
|
-
const allowedScripts = [
|
|
134
|
-
"listCompositions",
|
|
135
|
-
"getProjectInfo",
|
|
136
|
-
"getLayerInfo",
|
|
137
|
-
"createComposition",
|
|
138
|
-
"createTextLayer",
|
|
139
|
-
"createShapeLayer",
|
|
140
|
-
"createSolidLayer",
|
|
141
|
-
"setLayerProperties",
|
|
142
|
-
"setLayerKeyframe",
|
|
143
|
-
"setLayerExpression",
|
|
144
|
-
"applyEffect",
|
|
145
|
-
"applyEffectTemplate",
|
|
146
|
-
"test-animation",
|
|
147
|
-
"bridgeTestEffects",
|
|
148
|
-
"createCamera",
|
|
149
|
-
"batchSetLayerProperties",
|
|
150
|
-
"setCompositionProperties",
|
|
151
|
-
"duplicateLayer",
|
|
152
|
-
"deleteLayer",
|
|
153
|
-
"setLayerMask"
|
|
154
|
-
];
|
|
155
|
-
if (!allowedScripts.includes(script)) {
|
|
156
|
-
return {
|
|
157
|
-
content: [
|
|
158
|
-
{
|
|
159
|
-
type: "text",
|
|
160
|
-
text: `Error: Script "${script}" is not allowed. Allowed scripts are: ${allowedScripts.join(", ")}`
|
|
161
|
-
}
|
|
162
|
-
],
|
|
163
|
-
isError: true
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
try {
|
|
167
|
-
clearResultsFile();
|
|
168
|
-
writeCommandFile(script, parameters);
|
|
169
|
-
return {
|
|
170
|
-
content: [
|
|
171
|
-
{
|
|
172
|
-
type: "text",
|
|
173
|
-
text: `Command to run "${script}" has been queued.
|
|
174
|
-
Please ensure the "MCP Bridge Auto" panel is open in After Effects.
|
|
175
|
-
Use the "get-results" tool after a few seconds to check for results.`
|
|
176
|
-
}
|
|
177
|
-
]
|
|
178
|
-
};
|
|
179
|
-
} catch (error) {
|
|
180
|
-
return {
|
|
181
|
-
content: [
|
|
182
|
-
{
|
|
183
|
-
type: "text",
|
|
184
|
-
text: `Error queuing command: ${String(error)}`
|
|
185
|
-
}
|
|
186
|
-
],
|
|
187
|
-
isError: true
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
);
|
|
192
|
-
server.tool(
|
|
193
|
-
"get-results",
|
|
194
|
-
"Get results from the last script executed in After Effects",
|
|
195
|
-
{},
|
|
196
|
-
async () => {
|
|
197
|
-
try {
|
|
198
|
-
const result = readResultsFromTempFile();
|
|
199
|
-
return {
|
|
200
|
-
content: [
|
|
201
|
-
{
|
|
202
|
-
type: "text",
|
|
203
|
-
text: result
|
|
204
|
-
}
|
|
205
|
-
]
|
|
206
|
-
};
|
|
207
|
-
} catch (error) {
|
|
208
|
-
return {
|
|
209
|
-
content: [
|
|
210
|
-
{
|
|
211
|
-
type: "text",
|
|
212
|
-
text: `Error getting results: ${String(error)}`
|
|
213
|
-
}
|
|
214
|
-
],
|
|
215
|
-
isError: true
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
);
|
|
220
|
-
server.prompt(
|
|
221
|
-
"list-compositions",
|
|
222
|
-
"List compositions in the current After Effects project",
|
|
223
|
-
() => {
|
|
224
|
-
return {
|
|
225
|
-
messages: [{
|
|
226
|
-
role: "user",
|
|
227
|
-
content: {
|
|
228
|
-
type: "text",
|
|
229
|
-
text: "Please list all compositions in the current After Effects project."
|
|
230
|
-
}
|
|
231
|
-
}]
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
);
|
|
235
|
-
server.prompt(
|
|
236
|
-
"analyze-composition",
|
|
237
|
-
{
|
|
238
|
-
compositionName: z.string().describe("Name of the composition to analyze")
|
|
239
|
-
},
|
|
240
|
-
(args) => {
|
|
241
|
-
return {
|
|
242
|
-
messages: [{
|
|
243
|
-
role: "user",
|
|
244
|
-
content: {
|
|
245
|
-
type: "text",
|
|
246
|
-
text: `Please analyze the composition named "${args.compositionName}" in the current After Effects project. Provide details about its duration, frame rate, resolution, and layers.`
|
|
247
|
-
}
|
|
248
|
-
}]
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
);
|
|
252
|
-
server.prompt(
|
|
253
|
-
"create-composition",
|
|
254
|
-
"Create a new composition with specified settings",
|
|
255
|
-
() => {
|
|
256
|
-
return {
|
|
257
|
-
messages: [{
|
|
258
|
-
role: "user",
|
|
259
|
-
content: {
|
|
260
|
-
type: "text",
|
|
261
|
-
text: `Please create a new composition with custom settings. You can specify parameters like name, width, height, frame rate, etc.`
|
|
262
|
-
}
|
|
263
|
-
}]
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
);
|
|
267
|
-
server.tool(
|
|
268
|
-
"get-help",
|
|
269
|
-
"Get help on using the After Effects MCP integration",
|
|
270
|
-
{},
|
|
271
|
-
async () => {
|
|
272
|
-
return {
|
|
273
|
-
content: [
|
|
274
|
-
{
|
|
275
|
-
type: "text",
|
|
276
|
-
text: `# After Effects MCP Integration Help
|
|
277
|
-
|
|
278
|
-
To use this integration with After Effects, follow these steps:
|
|
279
|
-
|
|
280
|
-
1. **Install the scripts in After Effects**
|
|
281
|
-
- Run \`node install-bridge.js\` with administrator privileges
|
|
282
|
-
- This copies the necessary scripts to your After Effects installation
|
|
283
|
-
|
|
284
|
-
2. **Open After Effects**
|
|
285
|
-
- Launch Adobe After Effects
|
|
286
|
-
- Open a project that you want to work with
|
|
287
|
-
|
|
288
|
-
3. **Open the MCP Bridge Auto panel**
|
|
289
|
-
- In After Effects, go to Window > mcp-bridge-auto.jsx
|
|
290
|
-
- The panel will automatically check for commands every few seconds
|
|
291
|
-
|
|
292
|
-
4. **Run scripts through MCP**
|
|
293
|
-
- Use the \`run-script\` tool to queue a command
|
|
294
|
-
- The Auto panel will detect and run the command automatically
|
|
295
|
-
- Results will be saved to a temp file
|
|
296
|
-
|
|
297
|
-
5. **Get results through MCP**
|
|
298
|
-
- After a command is executed, use the \`get-results\` tool
|
|
299
|
-
- This will retrieve the results from After Effects
|
|
300
|
-
|
|
301
|
-
Available scripts:
|
|
302
|
-
- getProjectInfo: Information about the current project
|
|
303
|
-
- listCompositions: List all compositions in the project
|
|
304
|
-
- getLayerInfo: Information about layers in the active composition
|
|
305
|
-
- createComposition: Create a new composition
|
|
306
|
-
- createTextLayer: Create a new text layer
|
|
307
|
-
- createShapeLayer: Create a new shape layer
|
|
308
|
-
- createSolidLayer: Create a new solid layer
|
|
309
|
-
- setLayerProperties: Set properties for a layer
|
|
310
|
-
- setLayerKeyframe: Set a keyframe for a layer property
|
|
311
|
-
- setLayerExpression: Set an expression for a layer property
|
|
312
|
-
- applyEffect: Apply an effect to a layer
|
|
313
|
-
- applyEffectTemplate: Apply a predefined effect template to a layer
|
|
314
|
-
|
|
315
|
-
Effect Templates:
|
|
316
|
-
- gaussian-blur: Simple Gaussian blur effect
|
|
317
|
-
- directional-blur: Motion blur in a specific direction
|
|
318
|
-
- color-balance: Adjust hue, lightness, and saturation
|
|
319
|
-
- brightness-contrast: Basic brightness and contrast adjustment
|
|
320
|
-
- curves: Advanced color adjustment using curves
|
|
321
|
-
- glow: Add a glow effect to elements
|
|
322
|
-
- drop-shadow: Add a customizable drop shadow
|
|
323
|
-
- cinematic-look: Combination of effects for a cinematic appearance
|
|
324
|
-
- text-pop: Effects to make text stand out (glow and shadow)
|
|
325
|
-
|
|
326
|
-
Note: The auto-running panel can be left open in After Effects to continuously listen for commands from external applications.`
|
|
327
|
-
}
|
|
328
|
-
]
|
|
329
|
-
};
|
|
330
|
-
}
|
|
331
|
-
);
|
|
332
|
-
server.tool(
|
|
333
|
-
"create-composition",
|
|
334
|
-
"Create a new composition in After Effects with specified parameters",
|
|
335
|
-
{
|
|
336
|
-
name: z.string().describe("Name of the composition"),
|
|
337
|
-
width: z.number().int().positive().describe("Width of the composition in pixels"),
|
|
338
|
-
height: z.number().int().positive().describe("Height of the composition in pixels"),
|
|
339
|
-
pixelAspect: z.number().positive().optional().describe("Pixel aspect ratio (default: 1.0)"),
|
|
340
|
-
duration: z.number().positive().optional().describe("Duration in seconds (default: 10.0)"),
|
|
341
|
-
frameRate: z.number().positive().optional().describe("Frame rate in frames per second (default: 30.0)"),
|
|
342
|
-
backgroundColor: z.object({
|
|
343
|
-
r: z.number().int().min(0).max(255),
|
|
344
|
-
g: z.number().int().min(0).max(255),
|
|
345
|
-
b: z.number().int().min(0).max(255)
|
|
346
|
-
}).optional().describe("Background color of the composition (RGB values 0-255)")
|
|
347
|
-
},
|
|
348
|
-
async (params) => {
|
|
349
|
-
try {
|
|
350
|
-
writeCommandFile("createComposition", params);
|
|
351
|
-
return {
|
|
352
|
-
content: [
|
|
353
|
-
{
|
|
354
|
-
type: "text",
|
|
355
|
-
text: `Command to create composition "${params.name}" has been queued.
|
|
356
|
-
Please ensure the "MCP Bridge Auto" panel is open in After Effects.
|
|
357
|
-
Use the "get-results" tool after a few seconds to check for results.`
|
|
358
|
-
}
|
|
359
|
-
]
|
|
360
|
-
};
|
|
361
|
-
} catch (error) {
|
|
362
|
-
return {
|
|
363
|
-
content: [
|
|
364
|
-
{
|
|
365
|
-
type: "text",
|
|
366
|
-
text: `Error queuing composition creation: ${String(error)}`
|
|
367
|
-
}
|
|
368
|
-
],
|
|
369
|
-
isError: true
|
|
370
|
-
};
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
);
|
|
374
|
-
var LayerIdentifierSchema = {
|
|
375
|
-
compIndex: z.number().int().positive().describe("1-based index of the target composition in the project panel."),
|
|
376
|
-
layerIndex: z.number().int().positive().describe("1-based index of the target layer within the composition.")
|
|
377
|
-
};
|
|
378
|
-
var KeyframeValueSchema = z.unknown().describe("The value for the keyframe (e.g., [x,y] for Position, [w,h] for Scale, angle for Rotation, percentage for Opacity)");
|
|
379
|
-
server.tool(
|
|
380
|
-
"setLayerKeyframe",
|
|
381
|
-
// Corresponds to the function name in ExtendScript
|
|
382
|
-
"Set a keyframe for a specific layer property at a given time.",
|
|
383
|
-
{
|
|
384
|
-
...LayerIdentifierSchema,
|
|
385
|
-
// Reuse common identifiers
|
|
386
|
-
propertyName: z.string().describe("Name of the property to keyframe (e.g., 'Position', 'Scale', 'Rotation', 'Opacity')."),
|
|
387
|
-
timeInSeconds: z.number().describe("The time (in seconds) for the keyframe."),
|
|
388
|
-
value: KeyframeValueSchema
|
|
389
|
-
},
|
|
390
|
-
async (parameters) => {
|
|
391
|
-
try {
|
|
392
|
-
writeCommandFile("setLayerKeyframe", parameters);
|
|
393
|
-
return {
|
|
394
|
-
content: [
|
|
395
|
-
{
|
|
396
|
-
type: "text",
|
|
397
|
-
text: `Command to set keyframe for "${parameters.propertyName}" on layer ${parameters.layerIndex} in comp ${parameters.compIndex} has been queued.
|
|
398
|
-
Use the "get-results" tool after a few seconds to check for confirmation.`
|
|
399
|
-
}
|
|
400
|
-
]
|
|
401
|
-
};
|
|
402
|
-
} catch (error) {
|
|
403
|
-
return {
|
|
404
|
-
content: [
|
|
405
|
-
{
|
|
406
|
-
type: "text",
|
|
407
|
-
text: `Error queuing setLayerKeyframe command: ${String(error)}`
|
|
408
|
-
}
|
|
409
|
-
],
|
|
410
|
-
isError: true
|
|
411
|
-
};
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
);
|
|
415
|
-
server.tool(
|
|
416
|
-
"setLayerExpression",
|
|
417
|
-
// Corresponds to the function name in ExtendScript
|
|
418
|
-
"Set or remove an expression for a specific layer property.",
|
|
419
|
-
{
|
|
420
|
-
...LayerIdentifierSchema,
|
|
421
|
-
// Reuse common identifiers
|
|
422
|
-
propertyName: z.string().describe("Name of the property to apply the expression to (e.g., 'Position', 'Scale', 'Rotation', 'Opacity')."),
|
|
423
|
-
expressionString: z.string().describe('The JavaScript expression string. Provide an empty string ("") to remove the expression.')
|
|
424
|
-
},
|
|
425
|
-
async (parameters) => {
|
|
426
|
-
try {
|
|
427
|
-
writeCommandFile("setLayerExpression", parameters);
|
|
428
|
-
return {
|
|
429
|
-
content: [
|
|
430
|
-
{
|
|
431
|
-
type: "text",
|
|
432
|
-
text: `Command to set expression for "${parameters.propertyName}" on layer ${parameters.layerIndex} in comp ${parameters.compIndex} has been queued.
|
|
433
|
-
Use the "get-results" tool after a few seconds to check for confirmation.`
|
|
434
|
-
}
|
|
435
|
-
]
|
|
436
|
-
};
|
|
437
|
-
} catch (error) {
|
|
438
|
-
return {
|
|
439
|
-
content: [
|
|
440
|
-
{
|
|
441
|
-
type: "text",
|
|
442
|
-
text: `Error queuing setLayerExpression command: ${String(error)}`
|
|
443
|
-
}
|
|
444
|
-
],
|
|
445
|
-
isError: true
|
|
446
|
-
};
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
);
|
|
450
|
-
server.tool(
|
|
451
|
-
"test-animation",
|
|
452
|
-
"Test animation functionality in After Effects",
|
|
453
|
-
{
|
|
454
|
-
operation: z.enum(["keyframe", "expression"]).describe("The animation operation to test"),
|
|
455
|
-
compIndex: z.number().int().positive().describe("Composition index (usually 1)"),
|
|
456
|
-
layerIndex: z.number().int().positive().describe("Layer index (usually 1)")
|
|
457
|
-
},
|
|
458
|
-
async (params) => {
|
|
459
|
-
try {
|
|
460
|
-
const timestamp = (/* @__PURE__ */ new Date()).getTime();
|
|
461
|
-
const tempFile = path.join(process.env.TEMP || process.env.TMP || os.tmpdir(), `ae_test_${timestamp}.jsx`);
|
|
462
|
-
let scriptContent = "";
|
|
463
|
-
if (params.operation === "keyframe") {
|
|
464
|
-
scriptContent = `
|
|
465
|
-
// Direct keyframe test script
|
|
466
|
-
try {
|
|
467
|
-
var comp = app.project.items[${params.compIndex}];
|
|
468
|
-
var layer = comp.layers[${params.layerIndex}];
|
|
469
|
-
var prop = layer.property("Transform").property("Opacity");
|
|
470
|
-
var time = 1; // 1 second
|
|
471
|
-
var value = 25; // 25% opacity
|
|
472
|
-
|
|
473
|
-
// Set a keyframe
|
|
474
|
-
prop.setValueAtTime(time, value);
|
|
475
|
-
|
|
476
|
-
// Write direct result
|
|
477
|
-
var resultFile = new File("${path.join(process.env.TEMP || process.env.TMP || os.tmpdir(), "ae_test_result.txt").replace(/\\/g, "\\\\")}");
|
|
478
|
-
resultFile.open("w");
|
|
479
|
-
resultFile.write("SUCCESS: Added keyframe at time " + time + " with value " + value);
|
|
480
|
-
resultFile.close();
|
|
481
|
-
|
|
482
|
-
// Visual feedback
|
|
483
|
-
alert("Test successful: Added opacity keyframe at " + time + "s with value " + value + "%");
|
|
484
|
-
} catch (e) {
|
|
485
|
-
var errorFile = new File("${path.join(process.env.TEMP || process.env.TMP || os.tmpdir(), "ae_test_error.txt").replace(/\\/g, "\\\\")}");
|
|
486
|
-
errorFile.open("w");
|
|
487
|
-
errorFile.write("ERROR: " + e.toString());
|
|
488
|
-
errorFile.close();
|
|
489
|
-
|
|
490
|
-
alert("Test failed: " + e.toString());
|
|
491
|
-
}
|
|
492
|
-
`;
|
|
493
|
-
} else if (params.operation === "expression") {
|
|
494
|
-
scriptContent = `
|
|
495
|
-
// Direct expression test script
|
|
496
|
-
try {
|
|
497
|
-
var comp = app.project.items[${params.compIndex}];
|
|
498
|
-
var layer = comp.layers[${params.layerIndex}];
|
|
499
|
-
var prop = layer.property("Transform").property("Position");
|
|
500
|
-
var expression = "wiggle(3, 30)";
|
|
501
|
-
|
|
502
|
-
// Set the expression
|
|
503
|
-
prop.expression = expression;
|
|
504
|
-
|
|
505
|
-
// Write direct result
|
|
506
|
-
var resultFile = new File("${path.join(process.env.TEMP || process.env.TMP || os.tmpdir(), "ae_test_result.txt").replace(/\\/g, "\\\\")}");
|
|
507
|
-
resultFile.open("w");
|
|
508
|
-
resultFile.write("SUCCESS: Added expression: " + expression);
|
|
509
|
-
resultFile.close();
|
|
510
|
-
|
|
511
|
-
// Visual feedback
|
|
512
|
-
alert("Test successful: Added position expression: " + expression);
|
|
513
|
-
} catch (e) {
|
|
514
|
-
var errorFile = new File("${path.join(process.env.TEMP || process.env.TMP || os.tmpdir(), "ae_test_error.txt").replace(/\\/g, "\\\\")}");
|
|
515
|
-
errorFile.open("w");
|
|
516
|
-
errorFile.write("ERROR: " + e.toString());
|
|
517
|
-
errorFile.close();
|
|
518
|
-
|
|
519
|
-
alert("Test failed: " + e.toString());
|
|
520
|
-
}
|
|
521
|
-
`;
|
|
522
|
-
}
|
|
523
|
-
fs.writeFileSync(tempFile, scriptContent);
|
|
524
|
-
console.error(`Written test script to: ${tempFile}`);
|
|
525
|
-
return {
|
|
526
|
-
content: [
|
|
527
|
-
{
|
|
528
|
-
type: "text",
|
|
529
|
-
text: `I've created a direct test script for the ${params.operation} operation.
|
|
530
|
-
|
|
531
|
-
Please run this script manually in After Effects:
|
|
532
|
-
1. In After Effects, go to File > Scripts > Run Script File...
|
|
533
|
-
2. Navigate to: ${tempFile}
|
|
534
|
-
3. You should see an alert confirming the result.
|
|
535
|
-
|
|
536
|
-
This bypasses the MCP Bridge Auto panel and will directly modify the specified layer.`
|
|
537
|
-
}
|
|
538
|
-
]
|
|
539
|
-
};
|
|
540
|
-
} catch (error) {
|
|
541
|
-
return {
|
|
542
|
-
content: [
|
|
543
|
-
{
|
|
544
|
-
type: "text",
|
|
545
|
-
text: `Error creating test script: ${String(error)}`
|
|
546
|
-
}
|
|
547
|
-
],
|
|
548
|
-
isError: true
|
|
549
|
-
};
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
);
|
|
553
|
-
server.tool(
|
|
554
|
-
"apply-effect",
|
|
555
|
-
"Apply an effect to a layer in After Effects",
|
|
556
|
-
{
|
|
557
|
-
compIndex: z.number().int().positive().describe("1-based index of the target composition in the project panel."),
|
|
558
|
-
layerIndex: z.number().int().positive().describe("1-based index of the target layer within the composition."),
|
|
559
|
-
effectName: z.string().optional().describe("Display name of the effect to apply (e.g., 'Gaussian Blur')."),
|
|
560
|
-
effectMatchName: z.string().optional().describe("After Effects internal name for the effect (more reliable, e.g., 'ADBE Gaussian Blur 2')."),
|
|
561
|
-
effectCategory: z.string().optional().describe("Optional category for filtering effects."),
|
|
562
|
-
presetPath: z.string().optional().describe("Optional path to an effect preset file (.ffx)."),
|
|
563
|
-
effectSettings: z.record(z.string(), z.unknown()).optional().describe("Optional parameters for the effect (e.g., { 'Blurriness': 25 }).")
|
|
564
|
-
},
|
|
565
|
-
async (parameters) => {
|
|
566
|
-
try {
|
|
567
|
-
writeCommandFile("applyEffect", parameters);
|
|
568
|
-
return {
|
|
569
|
-
content: [
|
|
570
|
-
{
|
|
571
|
-
type: "text",
|
|
572
|
-
text: `Command to apply effect to layer ${parameters.layerIndex} in composition ${parameters.compIndex} has been queued.
|
|
573
|
-
Use the "get-results" tool after a few seconds to check for confirmation.`
|
|
574
|
-
}
|
|
575
|
-
]
|
|
576
|
-
};
|
|
577
|
-
} catch (error) {
|
|
578
|
-
return {
|
|
579
|
-
content: [
|
|
580
|
-
{
|
|
581
|
-
type: "text",
|
|
582
|
-
text: `Error queuing apply-effect command: ${String(error)}`
|
|
583
|
-
}
|
|
584
|
-
],
|
|
585
|
-
isError: true
|
|
586
|
-
};
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
);
|
|
590
|
-
server.tool(
|
|
591
|
-
"apply-effect-template",
|
|
592
|
-
"Apply a predefined effect template to a layer in After Effects",
|
|
593
|
-
{
|
|
594
|
-
compIndex: z.number().int().positive().describe("1-based index of the target composition in the project panel."),
|
|
595
|
-
layerIndex: z.number().int().positive().describe("1-based index of the target layer within the composition."),
|
|
596
|
-
templateName: z.enum([
|
|
597
|
-
"gaussian-blur",
|
|
598
|
-
"directional-blur",
|
|
599
|
-
"color-balance",
|
|
600
|
-
"brightness-contrast",
|
|
601
|
-
"curves",
|
|
602
|
-
"glow",
|
|
603
|
-
"drop-shadow",
|
|
604
|
-
"cinematic-look",
|
|
605
|
-
"text-pop"
|
|
606
|
-
]).describe("Name of the effect template to apply."),
|
|
607
|
-
customSettings: z.record(z.string(), z.unknown()).optional().describe("Optional custom settings to override defaults.")
|
|
608
|
-
},
|
|
609
|
-
async (parameters) => {
|
|
610
|
-
try {
|
|
611
|
-
writeCommandFile("applyEffectTemplate", parameters);
|
|
612
|
-
return {
|
|
613
|
-
content: [
|
|
614
|
-
{
|
|
615
|
-
type: "text",
|
|
616
|
-
text: `Command to apply effect template '${parameters.templateName}' to layer ${parameters.layerIndex} in composition ${parameters.compIndex} has been queued.
|
|
617
|
-
Use the "get-results" tool after a few seconds to check for confirmation.`
|
|
618
|
-
}
|
|
619
|
-
]
|
|
620
|
-
};
|
|
621
|
-
} catch (error) {
|
|
622
|
-
return {
|
|
623
|
-
content: [
|
|
624
|
-
{
|
|
625
|
-
type: "text",
|
|
626
|
-
text: `Error queuing apply-effect-template command: ${String(error)}`
|
|
627
|
-
}
|
|
628
|
-
],
|
|
629
|
-
isError: true
|
|
630
|
-
};
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
);
|
|
634
|
-
server.tool(
|
|
635
|
-
"mcp_aftereffects_applyEffect",
|
|
636
|
-
"Apply an effect to a layer in After Effects",
|
|
637
|
-
{
|
|
638
|
-
compIndex: z.number().int().positive().describe("1-based index of the target composition in the project panel."),
|
|
639
|
-
layerIndex: z.number().int().positive().describe("1-based index of the target layer within the composition."),
|
|
640
|
-
effectName: z.string().optional().describe("Display name of the effect to apply (e.g., 'Gaussian Blur')."),
|
|
641
|
-
effectMatchName: z.string().optional().describe("After Effects internal name for the effect (more reliable, e.g., 'ADBE Gaussian Blur 2')."),
|
|
642
|
-
effectSettings: z.record(z.string(), z.unknown()).optional().describe("Optional parameters for the effect (e.g., { 'Blurriness': 25 }).")
|
|
643
|
-
},
|
|
644
|
-
async (parameters) => {
|
|
645
|
-
try {
|
|
646
|
-
writeCommandFile("applyEffect", parameters);
|
|
647
|
-
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
648
|
-
const result = readResultsFromTempFile();
|
|
649
|
-
return {
|
|
650
|
-
content: [
|
|
651
|
-
{
|
|
652
|
-
type: "text",
|
|
653
|
-
text: result
|
|
654
|
-
}
|
|
655
|
-
]
|
|
656
|
-
};
|
|
657
|
-
} catch (error) {
|
|
658
|
-
return {
|
|
659
|
-
content: [
|
|
660
|
-
{
|
|
661
|
-
type: "text",
|
|
662
|
-
text: `Error applying effect: ${String(error)}`
|
|
663
|
-
}
|
|
664
|
-
],
|
|
665
|
-
isError: true
|
|
666
|
-
};
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
);
|
|
670
|
-
server.tool(
|
|
671
|
-
"mcp_aftereffects_applyEffectTemplate",
|
|
672
|
-
"Apply a predefined effect template to a layer in After Effects",
|
|
673
|
-
{
|
|
674
|
-
compIndex: z.number().int().positive().describe("1-based index of the target composition in the project panel."),
|
|
675
|
-
layerIndex: z.number().int().positive().describe("1-based index of the target layer within the composition."),
|
|
676
|
-
templateName: z.enum([
|
|
677
|
-
"gaussian-blur",
|
|
678
|
-
"directional-blur",
|
|
679
|
-
"color-balance",
|
|
680
|
-
"brightness-contrast",
|
|
681
|
-
"curves",
|
|
682
|
-
"glow",
|
|
683
|
-
"drop-shadow",
|
|
684
|
-
"cinematic-look",
|
|
685
|
-
"text-pop"
|
|
686
|
-
]).describe("Name of the effect template to apply."),
|
|
687
|
-
customSettings: z.record(z.string(), z.unknown()).optional().describe("Optional custom settings to override defaults.")
|
|
688
|
-
},
|
|
689
|
-
async (parameters) => {
|
|
690
|
-
try {
|
|
691
|
-
writeCommandFile("applyEffectTemplate", parameters);
|
|
692
|
-
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
693
|
-
const result = readResultsFromTempFile();
|
|
694
|
-
return {
|
|
695
|
-
content: [
|
|
696
|
-
{
|
|
697
|
-
type: "text",
|
|
698
|
-
text: result
|
|
699
|
-
}
|
|
700
|
-
]
|
|
701
|
-
};
|
|
702
|
-
} catch (error) {
|
|
703
|
-
return {
|
|
704
|
-
content: [
|
|
705
|
-
{
|
|
706
|
-
type: "text",
|
|
707
|
-
text: `Error applying effect template: ${String(error)}`
|
|
708
|
-
}
|
|
709
|
-
],
|
|
710
|
-
isError: true
|
|
711
|
-
};
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
);
|
|
715
|
-
server.tool(
|
|
716
|
-
"mcp_aftereffects_get_effects_help",
|
|
717
|
-
"Get help on using After Effects effects",
|
|
718
|
-
{},
|
|
719
|
-
async () => {
|
|
720
|
-
return {
|
|
721
|
-
content: [
|
|
722
|
-
{
|
|
723
|
-
type: "text",
|
|
724
|
-
text: `# After Effects Effects Help
|
|
725
|
-
|
|
726
|
-
## Common Effect Match Names
|
|
727
|
-
These are internal names used by After Effects that can be used with the \`effectMatchName\` parameter:
|
|
728
|
-
|
|
729
|
-
### Blur & Sharpen
|
|
730
|
-
- Gaussian Blur: "ADBE Gaussian Blur 2"
|
|
731
|
-
- Camera Lens Blur: "ADBE Camera Lens Blur"
|
|
732
|
-
- Directional Blur: "ADBE Directional Blur"
|
|
733
|
-
- Radial Blur: "ADBE Radial Blur"
|
|
734
|
-
- Smart Blur: "ADBE Smart Blur"
|
|
735
|
-
- Unsharp Mask: "ADBE Unsharp Mask"
|
|
736
|
-
|
|
737
|
-
### Color Correction
|
|
738
|
-
- Brightness & Contrast: "ADBE Brightness & Contrast 2"
|
|
739
|
-
- Color Balance: "ADBE Color Balance (HLS)"
|
|
740
|
-
- Color Balance (RGB): "ADBE Pro Levels2"
|
|
741
|
-
- Curves: "ADBE CurvesCustom"
|
|
742
|
-
- Exposure: "ADBE Exposure2"
|
|
743
|
-
- Hue/Saturation: "ADBE HUE SATURATION"
|
|
744
|
-
- Levels: "ADBE Pro Levels2"
|
|
745
|
-
- Vibrance: "ADBE Vibrance"
|
|
746
|
-
|
|
747
|
-
### Stylistic
|
|
748
|
-
- Glow: "ADBE Glow"
|
|
749
|
-
- Drop Shadow: "ADBE Drop Shadow"
|
|
750
|
-
- Bevel Alpha: "ADBE Bevel Alpha"
|
|
751
|
-
- Noise: "ADBE Noise"
|
|
752
|
-
- Fractal Noise: "ADBE Fractal Noise"
|
|
753
|
-
- CC Particle World: "CC Particle World"
|
|
754
|
-
- CC Light Sweep: "CC Light Sweep"
|
|
755
|
-
|
|
756
|
-
## Effect Templates
|
|
757
|
-
The following predefined effect templates are available:
|
|
758
|
-
|
|
759
|
-
- \`gaussian-blur\`: Simple Gaussian blur effect
|
|
760
|
-
- \`directional-blur\`: Motion blur in a specific direction
|
|
761
|
-
- \`color-balance\`: Adjust hue, lightness, and saturation
|
|
762
|
-
- \`brightness-contrast\`: Basic brightness and contrast adjustment
|
|
763
|
-
- \`curves\`: Advanced color adjustment using curves
|
|
764
|
-
- \`glow\`: Add a glow effect to elements
|
|
765
|
-
- \`drop-shadow\`: Add a customizable drop shadow
|
|
766
|
-
- \`cinematic-look\`: Combination of effects for a cinematic appearance
|
|
767
|
-
- \`text-pop\`: Effects to make text stand out (glow and shadow)
|
|
768
|
-
|
|
769
|
-
## Example Usage
|
|
770
|
-
To apply a Gaussian blur effect:
|
|
771
|
-
|
|
772
|
-
\`\`\`json
|
|
773
|
-
{
|
|
774
|
-
"compIndex": 1,
|
|
775
|
-
"layerIndex": 1,
|
|
776
|
-
"effectMatchName": "ADBE Gaussian Blur 2",
|
|
777
|
-
"effectSettings": {
|
|
778
|
-
"Blurriness": 25
|
|
779
|
-
}
|
|
780
|
-
}
|
|
781
|
-
\`\`\`
|
|
782
|
-
|
|
783
|
-
To apply the "cinematic-look" template:
|
|
784
|
-
|
|
785
|
-
\`\`\`json
|
|
786
|
-
{
|
|
787
|
-
"compIndex": 1,
|
|
788
|
-
"layerIndex": 1,
|
|
789
|
-
"templateName": "cinematic-look"
|
|
790
|
-
}
|
|
791
|
-
\`\`\`
|
|
792
|
-
`
|
|
793
|
-
}
|
|
794
|
-
]
|
|
795
|
-
};
|
|
796
|
-
}
|
|
797
|
-
);
|
|
798
|
-
server.tool(
|
|
799
|
-
"run-bridge-test",
|
|
800
|
-
"Run the bridge test effects script to verify communication and apply test effects",
|
|
801
|
-
{},
|
|
802
|
-
async () => {
|
|
803
|
-
try {
|
|
804
|
-
clearResultsFile();
|
|
805
|
-
writeCommandFile("bridgeTestEffects", {});
|
|
806
|
-
return {
|
|
807
|
-
content: [
|
|
808
|
-
{
|
|
809
|
-
type: "text",
|
|
810
|
-
text: `Bridge test effects command has been queued.
|
|
811
|
-
Please ensure the "MCP Bridge Auto" panel is open in After Effects.
|
|
812
|
-
Use the "get-results" tool after a few seconds to check for the test results.`
|
|
813
|
-
}
|
|
814
|
-
]
|
|
815
|
-
};
|
|
816
|
-
} catch (error) {
|
|
817
|
-
return {
|
|
818
|
-
content: [
|
|
819
|
-
{
|
|
820
|
-
type: "text",
|
|
821
|
-
text: `Error queuing bridge test command: ${String(error)}`
|
|
822
|
-
}
|
|
823
|
-
],
|
|
824
|
-
isError: true
|
|
825
|
-
};
|
|
826
|
-
}
|
|
827
|
-
}
|
|
828
|
-
);
|
|
829
|
-
async function main() {
|
|
830
|
-
console.error("After Effects MCP Server starting...");
|
|
831
|
-
console.error(`Scripts directory: ${SCRIPTS_DIR}`);
|
|
832
|
-
console.error(`Temp directory: ${TEMP_DIR}`);
|
|
833
|
-
const transport = new StdioServerTransport();
|
|
834
|
-
await server.connect(transport);
|
|
835
|
-
console.error("After Effects MCP Server running...");
|
|
836
|
-
}
|
|
837
|
-
main().catch((error) => {
|
|
838
|
-
console.error("Fatal error:", error);
|
|
839
|
-
process.exit(1);
|
|
840
|
-
});
|