@excalimate/mcp-server 0.2.0 → 0.3.5
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/README.md +22 -1
- package/dist/checkpoint-store.d.ts +1 -0
- package/dist/checkpoint-store.d.ts.map +1 -1
- package/dist/checkpoint-store.js +23 -2
- package/dist/checkpoint-store.js.map +1 -1
- package/dist/httpServer.d.ts +4 -0
- package/dist/httpServer.d.ts.map +1 -0
- package/dist/httpServer.js +179 -0
- package/dist/httpServer.js.map +1 -0
- package/dist/index.d.ts +0 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -197
- package/dist/index.js.map +1 -1
- package/dist/server/animationTools.d.ts +9 -0
- package/dist/server/animationTools.d.ts.map +1 -0
- package/dist/server/animationTools.js +254 -0
- package/dist/server/animationTools.js.map +1 -0
- package/dist/server/checkpointTools.d.ts +5 -0
- package/dist/server/checkpointTools.d.ts.map +1 -0
- package/dist/server/checkpointTools.js +22 -0
- package/dist/server/checkpointTools.js.map +1 -0
- package/dist/server/elementNormalizer.d.ts +3 -0
- package/dist/server/elementNormalizer.d.ts.map +1 -0
- package/dist/server/elementNormalizer.js +52 -0
- package/dist/server/elementNormalizer.js.map +1 -0
- package/dist/server/geometry.d.ts +24 -0
- package/dist/server/geometry.d.ts.map +1 -0
- package/dist/server/geometry.js +102 -0
- package/dist/server/geometry.js.map +1 -0
- package/dist/server/queryTools.d.ts +28 -0
- package/dist/server/queryTools.d.ts.map +1 -0
- package/dist/server/queryTools.js +107 -0
- package/dist/server/queryTools.js.map +1 -0
- package/dist/server/referenceText.d.ts +3 -0
- package/dist/server/referenceText.d.ts.map +1 -0
- package/dist/server/referenceText.js +268 -0
- package/dist/server/referenceText.js.map +1 -0
- package/dist/server/sceneTools.d.ts +4 -0
- package/dist/server/sceneTools.d.ts.map +1 -0
- package/dist/server/sceneTools.js +86 -0
- package/dist/server/sceneTools.js.map +1 -0
- package/dist/server/shareTools.d.ts +14 -0
- package/dist/server/shareTools.d.ts.map +1 -0
- package/dist/server/shareTools.js +81 -0
- package/dist/server/shareTools.js.map +1 -0
- package/dist/server/stateContext.d.ts +21 -0
- package/dist/server/stateContext.d.ts.map +1 -0
- package/dist/server/stateContext.js +85 -0
- package/dist/server/stateContext.js.map +1 -0
- package/dist/server.d.ts +4 -9
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +23 -906
- package/dist/server.js.map +1 -1
- package/dist/stdioServer.d.ts +3 -0
- package/dist/stdioServer.d.ts.map +1 -0
- package/dist/stdioServer.js +5 -0
- package/dist/stdioServer.js.map +1 -0
- package/package.json +3 -2
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
/**
|
|
3
|
+
* MCP tool: share_project
|
|
4
|
+
*
|
|
5
|
+
* Creates an E2E encrypted share URL containing the complete project state.
|
|
6
|
+
* Uploads to the Excalimate cloud share service (Cloudflare Worker + R2)
|
|
7
|
+
* so links persist even after the MCP server restarts.
|
|
8
|
+
*
|
|
9
|
+
* Uses AES-256-GCM encryption — the key is returned in the URL hash
|
|
10
|
+
* fragment and never stored on any server.
|
|
11
|
+
*/
|
|
12
|
+
import crypto from 'node:crypto';
|
|
13
|
+
import { z } from 'zod';
|
|
14
|
+
import { promisify } from 'node:util';
|
|
15
|
+
import { gzip } from 'node:zlib';
|
|
16
|
+
const gzipAsync = promisify(gzip);
|
|
17
|
+
const DEFAULT_SHARE_API = 'https://share.excalimate.com';
|
|
18
|
+
/**
|
|
19
|
+
* Encrypt data with AES-256-GCM.
|
|
20
|
+
* Returns: [IV (12 bytes)] [ciphertext + GCM auth tag]
|
|
21
|
+
*/
|
|
22
|
+
function encrypt(plaintext) {
|
|
23
|
+
const key = crypto.randomBytes(32);
|
|
24
|
+
const iv = crypto.randomBytes(12);
|
|
25
|
+
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
|
|
26
|
+
const enc = Buffer.concat([cipher.update(plaintext), cipher.final()]);
|
|
27
|
+
const tag = cipher.getAuthTag();
|
|
28
|
+
const result = Buffer.concat([iv, enc, tag]);
|
|
29
|
+
const keyBase64url = key.toString('base64url');
|
|
30
|
+
return { encrypted: result, keyBase64url };
|
|
31
|
+
}
|
|
32
|
+
export function registerShareTools(server, ctx) {
|
|
33
|
+
server.tool('share_project', 'Create an E2E encrypted share URL for the current project. Uploads to the Excalimate cloud share service so links persist permanently (30 days). The encryption key is in the URL hash fragment (never sent to any server). Returns the shareable URL.', {
|
|
34
|
+
baseUrl: z.string().optional().describe('Base URL for the share link (default: https://excalimate.com)'),
|
|
35
|
+
shareApi: z.string().optional().describe('Share service API URL (default: https://share.excalimate.com)'),
|
|
36
|
+
}, async ({ baseUrl, shareApi }) => {
|
|
37
|
+
const state = ctx.getState();
|
|
38
|
+
if (!state.scene.elements || state.scene.elements.length === 0) {
|
|
39
|
+
return { content: [{ type: 'text', text: 'Error: No elements in the scene. Create a scene first.' }] };
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
const payload = JSON.stringify({
|
|
43
|
+
scene: state.scene,
|
|
44
|
+
timeline: state.timeline,
|
|
45
|
+
clipStart: state.clipStart,
|
|
46
|
+
clipEnd: state.clipEnd,
|
|
47
|
+
cameraFrame: state.cameraFrame,
|
|
48
|
+
});
|
|
49
|
+
const compressed = await gzipAsync(Buffer.from(payload, 'utf-8'));
|
|
50
|
+
const { encrypted, keyBase64url } = encrypt(compressed);
|
|
51
|
+
// Upload to the cloud share service (persists across MCP server restarts)
|
|
52
|
+
const apiUrl = shareApi ?? process.env.EXCALIMATE_SHARE_API ?? DEFAULT_SHARE_API;
|
|
53
|
+
const response = await fetch(`${apiUrl}/share`, {
|
|
54
|
+
method: 'POST',
|
|
55
|
+
headers: { 'Content-Type': 'application/octet-stream' },
|
|
56
|
+
body: new Uint8Array(encrypted),
|
|
57
|
+
});
|
|
58
|
+
if (!response.ok) {
|
|
59
|
+
const err = await response.text();
|
|
60
|
+
return { content: [{ type: 'text', text: `Error uploading share: ${err}` }] };
|
|
61
|
+
}
|
|
62
|
+
const { id } = await response.json();
|
|
63
|
+
const appBase = baseUrl ?? 'https://excalimate.com';
|
|
64
|
+
const fullUrl = `${appBase}/#share=${id},${keyBase64url}`;
|
|
65
|
+
return {
|
|
66
|
+
content: [{
|
|
67
|
+
type: 'text',
|
|
68
|
+
text: `Share URL created:\n${fullUrl}\n\n` +
|
|
69
|
+
`Elements: ${state.scene.elements.length}, ` +
|
|
70
|
+
`Tracks: ${state.timeline.tracks.length}, ` +
|
|
71
|
+
`Encrypted size: ${(encrypted.length / 1024).toFixed(1)} KB\n\n` +
|
|
72
|
+
`Link is valid for 30 days. The encryption key is in the URL hash — no server can read the content.`,
|
|
73
|
+
}],
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
catch (e) {
|
|
77
|
+
return { content: [{ type: 'text', text: `Error creating share: ${e}` }] };
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=shareTools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shareTools.js","sourceRoot":"","sources":["../../src/server/shareTools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { ServerState } from '../types.js';
|
|
3
|
+
export type StateChangeListener = (delta: Partial<ServerState>) => void;
|
|
4
|
+
export declare function getSharedState(): ServerState;
|
|
5
|
+
export interface StateContext {
|
|
6
|
+
getState: () => ServerState;
|
|
7
|
+
updateState: (newState: ServerState) => void;
|
|
8
|
+
emitChange: () => void;
|
|
9
|
+
/** Mark a state area as dirty for delta broadcasting. */
|
|
10
|
+
markDirty: (area: 'scene' | 'timeline' | 'clip' | 'cameraFrame' | 'all') => void;
|
|
11
|
+
mutatingTool: (name: string, description: string, schema: any, handler: (args: any) => Promise<{
|
|
12
|
+
content: {
|
|
13
|
+
type: 'text';
|
|
14
|
+
text: string;
|
|
15
|
+
}[];
|
|
16
|
+
}>,
|
|
17
|
+
/** Which state areas this tool modifies (for delta broadcasting). Defaults to 'all'. */
|
|
18
|
+
dirtyAreas?: Array<'scene' | 'timeline' | 'clip' | 'cameraFrame'>) => void;
|
|
19
|
+
}
|
|
20
|
+
export declare function createStateContext(serverId: string, server: McpServer, onStateChange?: StateChangeListener): StateContext;
|
|
21
|
+
//# sourceMappingURL=stateContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stateContext.d.ts","sourceRoot":"","sources":["../../src/server/stateContext.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;AAKxE,wBAAgB,cAAc,IAAI,WAAW,CAAyB;AAEtE,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,WAAW,CAAC;IAC5B,WAAW,EAAE,CAAC,QAAQ,EAAE,WAAW,KAAK,IAAI,CAAC;IAC7C,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,yDAAyD;IACzD,SAAS,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,aAAa,GAAG,KAAK,KAAK,IAAI,CAAC;IACjF,YAAY,EAAE,CACZ,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,GAAG,EACX,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,EAAE,CAAA;KAAE,CAAC;IAC9E,wFAAwF;IACxF,UAAU,CAAC,EAAE,KAAK,CAAC,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,aAAa,CAAC,KAC9D,IAAI,CAAC;CACX;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,EACjB,aAAa,CAAC,EAAE,mBAAmB,GAClC,YAAY,CAgFd"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { createDefaultState } from '../state.js';
|
|
2
|
+
let _activeState = createDefaultState();
|
|
3
|
+
let _activeServerId = null;
|
|
4
|
+
export function getSharedState() { return _activeState; }
|
|
5
|
+
export function createStateContext(serverId, server, onStateChange) {
|
|
6
|
+
if (_activeServerId !== null) {
|
|
7
|
+
console.warn(`[excalimate] New server ${serverId} replacing active server ${_activeServerId}. ` +
|
|
8
|
+
'Concurrent MCP sessions share the same state (single-tenant design).');
|
|
9
|
+
}
|
|
10
|
+
_activeServerId = serverId;
|
|
11
|
+
// ── Delta broadcasting with debounce ───────────────────────────
|
|
12
|
+
// Track which top-level state areas are dirty via flags set by tools.
|
|
13
|
+
// When the debounced emit fires, only serialize and broadcast the
|
|
14
|
+
// dirty fields. This avoids serializing the entire scene+timeline
|
|
15
|
+
// on every keyframe addition.
|
|
16
|
+
let _emitTimer = null;
|
|
17
|
+
const _dirty = { scene: false, timeline: false, clip: false, cameraFrame: false };
|
|
18
|
+
/** Mark a state area as dirty so it's included in the next broadcast. */
|
|
19
|
+
function markDirty(area) {
|
|
20
|
+
if (area === 'all') {
|
|
21
|
+
_dirty.scene = _dirty.timeline = _dirty.clip = _dirty.cameraFrame = true;
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
_dirty[area] = true;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const emitChange = () => {
|
|
28
|
+
// Default: mark everything dirty (tools that don't specify get full broadcast).
|
|
29
|
+
// Specific tools can call markDirty() before emitChange() for fine-grained deltas.
|
|
30
|
+
if (!_dirty.scene && !_dirty.timeline && !_dirty.clip && !_dirty.cameraFrame) {
|
|
31
|
+
markDirty('all');
|
|
32
|
+
}
|
|
33
|
+
if (_emitTimer)
|
|
34
|
+
clearTimeout(_emitTimer);
|
|
35
|
+
_emitTimer = setTimeout(() => {
|
|
36
|
+
_emitTimer = null;
|
|
37
|
+
try {
|
|
38
|
+
if (!onStateChange)
|
|
39
|
+
return;
|
|
40
|
+
const delta = {};
|
|
41
|
+
if (_dirty.scene)
|
|
42
|
+
delta.scene = _activeState.scene;
|
|
43
|
+
if (_dirty.timeline)
|
|
44
|
+
delta.timeline = _activeState.timeline;
|
|
45
|
+
if (_dirty.clip) {
|
|
46
|
+
delta.clipStart = _activeState.clipStart;
|
|
47
|
+
delta.clipEnd = _activeState.clipEnd;
|
|
48
|
+
}
|
|
49
|
+
if (_dirty.cameraFrame)
|
|
50
|
+
delta.cameraFrame = _activeState.cameraFrame;
|
|
51
|
+
// Reset dirty flags
|
|
52
|
+
_dirty.scene = _dirty.timeline = _dirty.clip = _dirty.cameraFrame = false;
|
|
53
|
+
if (Object.keys(delta).length === 0)
|
|
54
|
+
return;
|
|
55
|
+
onStateChange(delta);
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
console.error('emitChange failed:', err);
|
|
59
|
+
}
|
|
60
|
+
}, 50);
|
|
61
|
+
};
|
|
62
|
+
server.__getState = () => _activeState;
|
|
63
|
+
const updateState = (newState) => {
|
|
64
|
+
_activeState = newState;
|
|
65
|
+
};
|
|
66
|
+
const mutatingTool = (name, description, schema, handler, dirtyAreas) => {
|
|
67
|
+
server.tool(name, description, schema, async (args) => {
|
|
68
|
+
const result = await handler(args);
|
|
69
|
+
if (dirtyAreas) {
|
|
70
|
+
for (const area of dirtyAreas)
|
|
71
|
+
markDirty(area);
|
|
72
|
+
}
|
|
73
|
+
emitChange();
|
|
74
|
+
return result;
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
return {
|
|
78
|
+
getState: () => _activeState,
|
|
79
|
+
updateState,
|
|
80
|
+
emitChange,
|
|
81
|
+
markDirty,
|
|
82
|
+
mutatingTool,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=stateContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stateContext.js","sourceRoot":"","sources":["../../src/server/stateContext.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Excalimate MCP Server
|
|
3
|
-
*
|
|
4
|
-
* Provides tools for creating Excalidraw scenes, animating them with keyframes,
|
|
5
|
-
* and exporting the results. Designed for AI agent integration via MCP.
|
|
6
|
-
*/
|
|
7
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
8
2
|
import type { CheckpointStore } from './checkpoint-store.js';
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
export
|
|
3
|
+
import { getSharedState } from './server/stateContext.js';
|
|
4
|
+
import type { StateChangeListener } from './server/stateContext.js';
|
|
5
|
+
export { getSharedState };
|
|
6
|
+
export type { StateChangeListener } from './server/stateContext.js';
|
|
12
7
|
export declare function createServer(store: CheckpointStore, onStateChange?: StateChangeListener): McpServer;
|
|
13
8
|
//# sourceMappingURL=server.d.ts.map
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAa7D,OAAO,EAAsB,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEpE,OAAO,EAAE,cAAc,EAAE,CAAC;AAC1B,YAAY,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEpE,wBAAgB,YAAY,CAC1B,KAAK,EAAE,eAAe,EACtB,aAAa,CAAC,EAAE,mBAAmB,GAClC,SAAS,CAyBX"}
|