@excalimate/mcp-server 0.1.0 → 0.3.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.
Files changed (64) hide show
  1. package/README.md +176 -16
  2. package/dist/checkpoint-store.d.ts +1 -0
  3. package/dist/checkpoint-store.d.ts.map +1 -1
  4. package/dist/checkpoint-store.js +23 -2
  5. package/dist/checkpoint-store.js.map +1 -1
  6. package/dist/httpServer.d.ts +4 -0
  7. package/dist/httpServer.d.ts.map +1 -0
  8. package/dist/httpServer.js +199 -0
  9. package/dist/httpServer.js.map +1 -0
  10. package/dist/index.d.ts +0 -7
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +35 -177
  13. package/dist/index.js.map +1 -1
  14. package/dist/server/animationTools.d.ts +9 -0
  15. package/dist/server/animationTools.d.ts.map +1 -0
  16. package/dist/server/animationTools.js +254 -0
  17. package/dist/server/animationTools.js.map +1 -0
  18. package/dist/server/checkpointTools.d.ts +5 -0
  19. package/dist/server/checkpointTools.d.ts.map +1 -0
  20. package/dist/server/checkpointTools.js +22 -0
  21. package/dist/server/checkpointTools.js.map +1 -0
  22. package/dist/server/elementNormalizer.d.ts +3 -0
  23. package/dist/server/elementNormalizer.d.ts.map +1 -0
  24. package/dist/server/elementNormalizer.js +52 -0
  25. package/dist/server/elementNormalizer.js.map +1 -0
  26. package/dist/server/geometry.d.ts +24 -0
  27. package/dist/server/geometry.d.ts.map +1 -0
  28. package/dist/server/geometry.js +102 -0
  29. package/dist/server/geometry.js.map +1 -0
  30. package/dist/server/queryTools.d.ts +28 -0
  31. package/dist/server/queryTools.d.ts.map +1 -0
  32. package/dist/server/queryTools.js +107 -0
  33. package/dist/server/queryTools.js.map +1 -0
  34. package/dist/server/referenceText.d.ts +3 -0
  35. package/dist/server/referenceText.d.ts.map +1 -0
  36. package/dist/server/referenceText.js +268 -0
  37. package/dist/server/referenceText.js.map +1 -0
  38. package/dist/server/sceneTools.d.ts +4 -0
  39. package/dist/server/sceneTools.d.ts.map +1 -0
  40. package/dist/server/sceneTools.js +86 -0
  41. package/dist/server/sceneTools.js.map +1 -0
  42. package/dist/server/shareTools.d.ts +11 -0
  43. package/dist/server/shareTools.d.ts.map +1 -0
  44. package/dist/server/shareTools.js +81 -0
  45. package/dist/server/shareTools.js.map +1 -0
  46. package/dist/server/stateContext.d.ts +21 -0
  47. package/dist/server/stateContext.d.ts.map +1 -0
  48. package/dist/server/stateContext.js +85 -0
  49. package/dist/server/stateContext.js.map +1 -0
  50. package/dist/server.d.ts +5 -10
  51. package/dist/server.d.ts.map +1 -1
  52. package/dist/server.js +24 -891
  53. package/dist/server.js.map +1 -1
  54. package/dist/shareRoutes.d.ts +4 -0
  55. package/dist/shareRoutes.d.ts.map +1 -0
  56. package/dist/shareRoutes.js +44 -0
  57. package/dist/shareRoutes.js.map +1 -0
  58. package/dist/stdioServer.d.ts +3 -0
  59. package/dist/stdioServer.d.ts.map +1 -0
  60. package/dist/stdioServer.js +5 -0
  61. package/dist/stdioServer.js.map +1 -0
  62. package/package.json +6 -2
  63. package/SKILL.md +0 -110
  64. package/references/REFERENCE.md +0 -192
package/README.md CHANGED
@@ -2,47 +2,199 @@
2
2
 
3
3
  Excalimate MCP server for creating Excalidraw designs and animating them with keyframes. Designed for AI agent integration (Claude Desktop, Copilot CLI, etc.).
4
4
 
5
+ **Pair with [excalimate.com](https://excalimate.com) for real-time live preview** — the AI creates and animates, you watch it happen in your browser.
6
+
7
+ ## Getting Started with excalimate.com
8
+
9
+ The fastest way to use Excalimate with AI is to combine the deployed web app with this npm package. No cloning, no building — just install and go.
10
+
11
+ ### Step 1: Start the MCP server
12
+
13
+ ```bash
14
+ npx @excalimate/mcp-server
15
+ # → Listening on http://localhost:3001/mcp
16
+ # → Live preview SSE at http://localhost:3001/live
17
+
18
+ # Custom port:
19
+ npx @excalimate/mcp-server --port 4000
20
+ ```
21
+
22
+ Port priority: CLI arg (`--port` / `-p`) > `PORT` env var > default `3001`.
23
+ Also supports `--port=4000` syntax.
24
+
25
+ Or install globally:
26
+
27
+ ```bash
28
+ npm install -g @excalimate/mcp-server
29
+ excalimate-mcp
30
+ ```
31
+
32
+ ### Step 2: Open the web app
33
+
34
+ Go to [excalimate.com](https://excalimate.com) in your browser and click **📡 Live** in the toolbar. The app connects to `localhost:3001` automatically.
35
+
36
+ You can configure the MCP server URL in **File → Preferences**. The app persists this setting in localStorage, shows connection progress (progress bar + notifications), provides smart error dialogs, and warns about HTTPS→HTTP mixed-content connections.
37
+
38
+ ### Step 3: Connect your AI
39
+
40
+ Point your AI tool to `http://localhost:3001/mcp` as an MCP server. Then ask it to create a diagram and animate it — you'll see elements appear and animate in your browser in real-time.
41
+
42
+ **That's it.** The AI draws and animates, you see it live, and you can edit alongside it.
43
+
5
44
  ## Features
6
45
 
7
- - **22 tools** for scene creation, animation, camera control, export, and checkpointing
46
+ - **23 tools** for scene creation, animation, camera control, export, checkpointing, and sharing
8
47
  - **Dual transport**: stdio (Claude Desktop) + Streamable HTTP (cloud deployment)
48
+ - **Live preview**: Real-time updates in [excalimate.com](https://excalimate.com) via SSE
9
49
  - **Sequence reveal**: Staggered element reveal animations in one tool call
10
50
  - **Camera animation**: Pan/zoom keyframes for cinematic effects
11
51
  - **Checkpoint persistence**: Save/load complete scene + animation state
52
+ - **Runtime versioning**: Server version is read from `package.json`
53
+
54
+ ## Installation & Usage
12
55
 
13
- ## Quick Start
56
+ ### HTTP mode (recommended — enables live preview)
14
57
 
15
58
  ```bash
16
- # Install
17
- cd mcp-server
18
- npm install
59
+ npx @excalimate/mcp-server
60
+ # → http://localhost:3001/mcp
19
61
 
20
- # Build
21
- npm run build
62
+ # Custom port:
63
+ npx @excalimate/mcp-server -p 4000
64
+ ```
22
65
 
23
- # Run (stdio for Claude Desktop)
24
- node dist/index.js --stdio
66
+ Open [excalimate.com](https://excalimate.com) and click **📡 Live**, then configure your AI tool below.
25
67
 
26
- # Run (HTTP for cloud)
27
- node dist/index.js
28
- # → http://localhost:3001/mcp
68
+ ### Configure your AI tool
69
+
70
+ <details>
71
+ <summary><strong>VS Code (GitHub Copilot) — ✅ live preview</strong></summary>
72
+
73
+ Add to your VS Code MCP config (`.vscode/mcp.json` or user-level `mcp.json`):
74
+
75
+ **HTTP mode (recommended — live preview works):**
76
+
77
+ ```jsonc
78
+ {
79
+ "servers": {
80
+ "excalimate": {
81
+ "type": "http",
82
+ "url": "http://localhost:3001/mcp"
83
+ }
84
+ }
85
+ }
29
86
  ```
30
87
 
31
- ## Claude Desktop Configuration
88
+ Start the MCP server first (`npx @excalimate/mcp-server`), open [excalimate.com](https://excalimate.com), click **📡 Live**, then ask Copilot to create a diagram. You'll see it appear in real-time.
32
89
 
33
- Add to `claude_desktop_config.json`:
90
+ **stdio mode (no live preview):**
91
+
92
+ ```jsonc
93
+ {
94
+ "servers": {
95
+ "excalimate": {
96
+ "type": "stdio",
97
+ "command": "npx",
98
+ "args": ["@excalimate/mcp-server", "--stdio"]
99
+ }
100
+ }
101
+ }
102
+ ```
103
+
104
+ </details>
105
+
106
+ <details>
107
+ <summary><strong>Claude Desktop — stdio only (no live preview)</strong></summary>
108
+
109
+ Add to your `claude_desktop_config.json`:
34
110
 
35
111
  ```json
36
112
  {
37
113
  "mcpServers": {
38
114
  "excalimate": {
39
- "command": "node",
40
- "args": ["/path/to/mcp-server/dist/index.js", "--stdio"]
115
+ "command": "npx",
116
+ "args": ["@excalimate/mcp-server", "--stdio"]
41
117
  }
42
118
  }
43
119
  }
44
120
  ```
45
121
 
122
+ Claude Desktop uses stdio transport, so there's no live preview. The AI creates scenes and animations, then use `save_checkpoint` to save state and load it in [excalimate.com](https://excalimate.com) via the **MCP** button in the toolbar.
123
+
124
+ </details>
125
+
126
+ <details>
127
+ <summary><strong>Claude Code (CLI) — ✅ live preview</strong></summary>
128
+
129
+ Claude Code supports HTTP MCP servers. Start the server first, then add it:
130
+
131
+ ```bash
132
+ npx @excalimate/mcp-server &
133
+ claude mcp add excalimate http://localhost:3001/mcp
134
+ ```
135
+
136
+ Open [excalimate.com](https://excalimate.com) and click **📡 Live** — you'll see the AI's changes in real-time.
137
+
138
+ </details>
139
+
140
+ <details>
141
+ <summary><strong>Cursor — ✅ live preview</strong></summary>
142
+
143
+ In Cursor settings, go to **MCP Servers** and add:
144
+
145
+ - **Name:** `excalimate`
146
+ - **Type:** `http`
147
+ - **URL:** `http://localhost:3001/mcp`
148
+
149
+ Start the MCP server (`npx @excalimate/mcp-server`), open [excalimate.com](https://excalimate.com), click **📡 Live**, then use Cursor's agent to create diagrams with live preview.
150
+
151
+ </details>
152
+
153
+ <details>
154
+ <summary><strong>Windsurf — ✅ live preview</strong></summary>
155
+
156
+ Add to your Windsurf MCP config:
157
+
158
+ ```json
159
+ {
160
+ "mcpServers": {
161
+ "excalimate": {
162
+ "serverUrl": "http://localhost:3001/mcp"
163
+ }
164
+ }
165
+ }
166
+ ```
167
+
168
+ Start the MCP server, open [excalimate.com](https://excalimate.com), click **📡 Live**, and use Cascade to create animated diagrams in real-time.
169
+
170
+ </details>
171
+
172
+ <details>
173
+ <summary><strong>Any HTTP-compatible MCP client — ✅ live preview</strong></summary>
174
+
175
+ Point your MCP client to:
176
+
177
+ ```
178
+ http://localhost:3001/mcp
179
+ ```
180
+
181
+ Start the server with `npx @excalimate/mcp-server`, open [excalimate.com](https://excalimate.com), and click **📡 Live**. Any tool that supports Streamable HTTP MCP transport will work with live preview.
182
+
183
+ </details>
184
+
185
+ > **Tip:** HTTP mode (the default) is always preferred — it enables live preview so you can watch the AI build your animation in real-time. stdio mode is only needed for tools that don't support HTTP transport (like Claude Desktop).
186
+
187
+ ### From source (for development)
188
+
189
+ ```bash
190
+ cd mcp-server
191
+ npm install
192
+ npm run build
193
+ node dist/index.js # HTTP mode
194
+ node dist/index.js --port 4000
195
+ node dist/index.js --stdio # stdio mode
196
+ ```
197
+
46
198
  ## Tools
47
199
 
48
200
  ### Scene Tools
@@ -84,6 +236,13 @@ Add to `claude_desktop_config.json`:
84
236
  | `items_visible_in_camera` | Report visibility of items at a given time |
85
237
  | `animations_of_item` | Describe all animations of an element |
86
238
 
239
+ ### Sharing Tools
240
+ | Tool | Description |
241
+ |------|-------------|
242
+ | `share_project` | Create E2E encrypted share URL for the current project |
243
+
244
+ `share_project` accepts `{ baseUrl?: string }` and defaults to `https://excalimate.com`, returning URLs like `https://excalimate.com/#share=ID,KEY`.
245
+
87
246
  ### Checkpoint Tools
88
247
  | Tool | Description |
89
248
  |------|-------------|
@@ -105,4 +264,5 @@ Add to `claude_desktop_config.json`:
105
264
  }
106
265
  4. set_clip_range {0, 5000} → Set 5-second export window
107
266
  5. save_checkpoint {id: "demo"} → Save for web app preview
267
+ or share_project {baseUrl: "https://excalimate.com"} → Generate E2E encrypted share URL
108
268
  ```
@@ -13,6 +13,7 @@ export declare class FileCheckpointStore implements CheckpointStore {
13
13
  save(id: string, data: ServerState): Promise<void>;
14
14
  load(id: string): Promise<ServerState | null>;
15
15
  list(): Promise<string[]>;
16
+ private _pruning;
16
17
  private prune;
17
18
  }
18
19
  export declare class MemoryCheckpointStore implements CheckpointStore {
@@ -1 +1 @@
1
- {"version":3,"file":"checkpoint-store.d.ts","sourceRoot":"","sources":["../src/checkpoint-store.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAW9C,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAC9C,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CAC3B;AAED,qBAAa,mBAAoB,YAAW,eAAe;IACzD,OAAO,CAAC,GAAG,CAAS;;IAOd,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAclD,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAc7C,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YASjB,KAAK;CAgBpB;AAED,qBAAa,qBAAsB,YAAW,eAAe;IAC3D,OAAO,CAAC,KAAK,CAA6B;IAEpC,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAWlD,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAO7C,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;CAGhC"}
1
+ {"version":3,"file":"checkpoint-store.d.ts","sourceRoot":"","sources":["../src/checkpoint-store.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAW9C,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAC9C,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CAC3B;AAED,qBAAa,mBAAoB,YAAW,eAAe;IACzD,OAAO,CAAC,GAAG,CAAS;;IAOd,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAclD,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAc7C,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAS/B,OAAO,CAAC,QAAQ,CAAS;YAEX,KAAK;CAiCpB;AAED,qBAAa,qBAAsB,YAAW,eAAe;IAC3D,OAAO,CAAC,KAAK,CAA6B;IAEpC,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAWlD,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAO7C,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;CAGhC"}
@@ -53,7 +53,12 @@ export class FileCheckpointStore {
53
53
  return [];
54
54
  }
55
55
  }
56
+ _pruning = false;
56
57
  async prune() {
58
+ // Serialize prune operations to avoid concurrent filesystem races
59
+ if (this._pruning)
60
+ return;
61
+ this._pruning = true;
57
62
  try {
58
63
  const entries = await fs.promises.readdir(this.dir);
59
64
  const jsonFiles = entries.filter(f => f.endsWith('.json'));
@@ -65,9 +70,25 @@ export class FileCheckpointStore {
65
70
  })));
66
71
  stats.sort((a, b) => a.mtime - b.mtime);
67
72
  const toRemove = stats.slice(0, stats.length - MAX_CHECKPOINTS);
68
- await Promise.all(toRemove.map(f => fs.promises.unlink(path.join(this.dir, f.name)).catch(() => { })));
73
+ await Promise.all(toRemove.map(async (f) => {
74
+ try {
75
+ await fs.promises.unlink(path.join(this.dir, f.name));
76
+ }
77
+ catch (err) {
78
+ const code = err.code;
79
+ // ENOENT is expected (concurrent delete) — log anything else
80
+ if (code !== 'ENOENT') {
81
+ console.warn(`[checkpoint] Failed to prune ${f.name}:`, err);
82
+ }
83
+ }
84
+ }));
85
+ }
86
+ catch (err) {
87
+ console.warn('[checkpoint] Prune scan failed:', err);
88
+ }
89
+ finally {
90
+ this._pruning = false;
69
91
  }
70
- catch { /* best-effort */ }
71
92
  }
72
93
  }
73
94
  export class MemoryCheckpointStore {
@@ -1 +1 @@
1
- {"version":3,"file":"checkpoint-store.js","sourceRoot":"","sources":["../src/checkpoint-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"checkpoint-store.js","sourceRoot":"","sources":["../src/checkpoint-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { Response } from 'express';
3
+ export declare function startHTTPServer(factoryWithSSE: (sseClients: Set<Response>, broadcastSSE: (data: string) => void, port: number) => McpServer, portOverride?: number): Promise<void>;
4
+ //# sourceMappingURL=httpServer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"httpServer.d.ts","sourceRoot":"","sources":["../src/httpServer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOzE,OAAO,KAAK,EAAW,QAAQ,EAAE,MAAM,SAAS,CAAC;AAwCjD,wBAAsB,eAAe,CACnC,cAAc,EAAE,CAAC,UAAU,EAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,EAAE,IAAI,EAAE,MAAM,KAAK,SAAS,EAC5G,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAoLf"}
@@ -0,0 +1,199 @@
1
+ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
2
+ import cors from 'cors';
3
+ import crypto from 'node:crypto';
4
+ import express from 'express';
5
+ import helmet from 'helmet';
6
+ import rateLimit from 'express-rate-limit';
7
+ import { getSharedState } from './server.js';
8
+ import { registerShareRoutes } from './shareRoutes.js';
9
+ function getCorsOrigin() {
10
+ const raw = process.env.CORS_ORIGIN;
11
+ // No CORS origin configured: allow local dev + production domains
12
+ if (!raw || !raw.trim()) {
13
+ return ['http://localhost:5173', 'https://excalimate.com', 'https://www.excalimate.com'];
14
+ }
15
+ const origins = raw
16
+ .split(',')
17
+ .map((o) => o.trim())
18
+ .filter((o) => o.length > 0);
19
+ if (origins.length === 0) {
20
+ return ['http://localhost:5173', 'https://excalimate.com', 'https://www.excalimate.com'];
21
+ }
22
+ if (origins.length === 1) {
23
+ return origins[0];
24
+ }
25
+ // Multiple allowed origins: validate incoming origin against the list
26
+ return (origin, callback) => {
27
+ // Allow requests without an Origin header (e.g., same-origin or non-browser clients)
28
+ if (!origin) {
29
+ return callback(null, true);
30
+ }
31
+ if (origins.includes(origin)) {
32
+ return callback(null, true);
33
+ }
34
+ return callback(new Error('Not allowed by CORS'), false);
35
+ };
36
+ }
37
+ export async function startHTTPServer(factoryWithSSE, portOverride) {
38
+ const port = portOverride ?? parseInt(process.env.PORT ?? '3001', 10);
39
+ const app = express();
40
+ app.use(helmet()); // Security headers
41
+ app.use(cors({
42
+ origin: getCorsOrigin(),
43
+ }));
44
+ // Rate limiting
45
+ const limiter = rateLimit({
46
+ windowMs: 60 * 1000, // 1 minute
47
+ max: 200, // 200 requests per minute
48
+ standardHeaders: true,
49
+ legacyHeaders: false,
50
+ });
51
+ app.use(limiter);
52
+ // Stricter rate limit for share uploads
53
+ const shareLimiter = rateLimit({
54
+ windowMs: 60 * 1000,
55
+ max: 10, // 10 shares per minute
56
+ standardHeaders: true,
57
+ legacyHeaders: false,
58
+ });
59
+ const jsonMiddleware = express.json();
60
+ // Parse JSON only for non-share routes (share uses raw binary)
61
+ app.use((req, res, next) => {
62
+ if (req.path === '/share' && req.method === 'POST') {
63
+ next();
64
+ }
65
+ else {
66
+ jsonMiddleware(req, res, next);
67
+ }
68
+ });
69
+ // SSE clients for live state broadcasting
70
+ const sseClients = new Set();
71
+ /** Safely broadcast to all SSE clients, removing dead ones on failure. */
72
+ function broadcastSSE(data) {
73
+ for (const client of sseClients) {
74
+ try {
75
+ client.write(`data: ${data}\n\n`);
76
+ }
77
+ catch {
78
+ sseClients.delete(client);
79
+ }
80
+ }
81
+ }
82
+ // Factory that wires SSE broadcasting
83
+ const factory = () => factoryWithSSE(sseClients, broadcastSSE, port);
84
+ // Session map: keep server + transport alive across requests
85
+ const sessions = new Map();
86
+ // Periodically clean up stale sessions (no activity for 30 minutes)
87
+ const SESSION_TTL_MS = 30 * 60 * 1000;
88
+ const sessionCleanupTimer = setInterval(() => {
89
+ const now = Date.now();
90
+ for (const [sid, session] of sessions) {
91
+ if (now - session.lastActivity > SESSION_TTL_MS) {
92
+ sessions.delete(sid);
93
+ }
94
+ }
95
+ }, 60 * 1000);
96
+ sessionCleanupTimer.unref();
97
+ app.all('/mcp', async (req, res) => {
98
+ const sessionId = req.headers['mcp-session-id'];
99
+ // Route to existing session
100
+ if (sessionId && sessions.has(sessionId)) {
101
+ const session = sessions.get(sessionId);
102
+ session.lastActivity = Date.now();
103
+ try {
104
+ await session.transport.handleRequest(req, res, req.body);
105
+ }
106
+ catch (error) {
107
+ console.error('MCP session error:', error);
108
+ if (!res.headersSent) {
109
+ res.status(500).json({
110
+ jsonrpc: '2.0',
111
+ error: { code: -32603, message: 'Internal server error' },
112
+ id: null,
113
+ });
114
+ }
115
+ }
116
+ return;
117
+ }
118
+ // New session
119
+ const server = factory();
120
+ const transport = new StreamableHTTPServerTransport({
121
+ sessionIdGenerator: () => crypto.randomUUID(),
122
+ });
123
+ transport.onclose = () => {
124
+ const sid = transport.sessionId;
125
+ if (sid)
126
+ sessions.delete(sid);
127
+ // Don't call server.close() here — it would call transport.close()
128
+ // again, causing infinite recursion. The SDK handles cleanup internally.
129
+ };
130
+ try {
131
+ await server.connect(transport);
132
+ await transport.handleRequest(req, res, req.body);
133
+ // Store session after first successful request (session ID is now set)
134
+ const sid = transport.sessionId;
135
+ if (sid) {
136
+ sessions.set(sid, { server, transport, lastActivity: Date.now() });
137
+ }
138
+ }
139
+ catch (error) {
140
+ console.error('MCP error:', error);
141
+ if (!res.headersSent) {
142
+ res.status(500).json({
143
+ jsonrpc: '2.0',
144
+ error: { code: -32603, message: 'Internal server error' },
145
+ id: null,
146
+ });
147
+ }
148
+ }
149
+ });
150
+ // SSE endpoint — web app connects here to receive live state updates
151
+ app.get('/live', (req, res) => {
152
+ res.writeHead(200, {
153
+ 'Content-Type': 'text/event-stream',
154
+ 'Cache-Control': 'no-cache',
155
+ Connection: 'keep-alive',
156
+ 'Access-Control-Allow-Origin': '*',
157
+ });
158
+ res.write('data: {"type":"connected"}\n\n');
159
+ sseClients.add(res);
160
+ req.on('close', () => sseClients.delete(res));
161
+ });
162
+ // Current state endpoint
163
+ app.get('/state', (_req, res) => {
164
+ res.json(getSharedState());
165
+ });
166
+ // ── E2E Encrypted Sharing ──────────────────────────────────────
167
+ // The server only stores encrypted blobs. It never sees the encryption key.
168
+ registerShareRoutes(app, shareLimiter);
169
+ const httpServer = app.listen(port, () => {
170
+ console.log(`Excalimate MCP server listening on http://localhost:${port}/mcp`);
171
+ console.log(`Live preview SSE at http://localhost:${port}/live`);
172
+ });
173
+ let shuttingDown = false;
174
+ const shutdown = async () => {
175
+ if (shuttingDown)
176
+ return;
177
+ shuttingDown = true;
178
+ console.log('\nGraceful shutdown started...');
179
+ // 1. Stop accepting new connections
180
+ httpServer.close();
181
+ // 2. Stop the session cleanup timer
182
+ clearInterval(sessionCleanupTimer);
183
+ // 3. Close all SSE clients
184
+ for (const client of sseClients) {
185
+ try {
186
+ client.end();
187
+ }
188
+ catch { /* best-effort */ }
189
+ }
190
+ sseClients.clear();
191
+ // 4. Clear MCP sessions
192
+ sessions.clear();
193
+ console.log('Shutdown complete.');
194
+ process.exit(0);
195
+ };
196
+ process.on('SIGINT', shutdown);
197
+ process.on('SIGTERM', shutdown);
198
+ }
199
+ //# sourceMappingURL=httpServer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"httpServer.js","sourceRoot":"","sources":["../src/httpServer.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,10 +1,3 @@
1
1
  #!/usr/bin/env node
2
- /**
3
- * Excalimate MCP Server — Entry Point
4
- *
5
- * Supports two transports:
6
- * --stdio : For Claude Desktop / Copilot CLI
7
- * (default) : Streamable HTTP on port 3001
8
- */
9
2
  export {};
10
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;GAMG"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}