skybridge 0.0.0-dev.e068fc7 → 0.0.0-dev.e08ace9

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 (84) hide show
  1. package/dist/cli/detect-port.d.ts +9 -0
  2. package/dist/cli/detect-port.js +22 -1
  3. package/dist/cli/detect-port.js.map +1 -1
  4. package/dist/cli/use-nodemon.d.ts +1 -0
  5. package/dist/cli/use-nodemon.js +10 -3
  6. package/dist/cli/use-nodemon.js.map +1 -1
  7. package/dist/commands/build.js +1 -1
  8. package/dist/commands/build.js.map +1 -1
  9. package/dist/commands/dev.js +8 -10
  10. package/dist/commands/dev.js.map +1 -1
  11. package/dist/commands/start.js +18 -14
  12. package/dist/commands/start.js.map +1 -1
  13. package/dist/server/express.js +3 -0
  14. package/dist/server/express.js.map +1 -1
  15. package/dist/server/index.d.ts +1 -0
  16. package/dist/server/index.js.map +1 -1
  17. package/dist/server/middleware.d.ts +96 -0
  18. package/dist/server/middleware.js +93 -0
  19. package/dist/server/middleware.js.map +1 -0
  20. package/dist/server/middleware.test-d.d.ts +1 -0
  21. package/dist/server/middleware.test-d.js +52 -0
  22. package/dist/server/middleware.test-d.js.map +1 -0
  23. package/dist/server/middleware.test.d.ts +1 -0
  24. package/dist/server/middleware.test.js +383 -0
  25. package/dist/server/middleware.test.js.map +1 -0
  26. package/dist/server/server.d.ts +34 -0
  27. package/dist/server/server.js +77 -16
  28. package/dist/server/server.js.map +1 -1
  29. package/dist/server/widgetsDevServer.js +2 -2
  30. package/dist/server/widgetsDevServer.js.map +1 -1
  31. package/dist/web/bridges/apps-sdk/adaptor.d.ts +4 -4
  32. package/dist/web/bridges/apps-sdk/adaptor.js +8 -13
  33. package/dist/web/bridges/apps-sdk/adaptor.js.map +1 -1
  34. package/dist/web/bridges/apps-sdk/bridge.d.ts +1 -1
  35. package/dist/web/bridges/apps-sdk/index.d.ts +1 -1
  36. package/dist/web/bridges/apps-sdk/index.js.map +1 -1
  37. package/dist/web/bridges/apps-sdk/types.d.ts +8 -5
  38. package/dist/web/bridges/apps-sdk/types.js.map +1 -1
  39. package/dist/web/bridges/mcp-app/adaptor.d.ts +6 -4
  40. package/dist/web/bridges/mcp-app/adaptor.js +33 -39
  41. package/dist/web/bridges/mcp-app/adaptor.js.map +1 -1
  42. package/dist/web/bridges/mcp-app/bridge.d.ts +16 -32
  43. package/dist/web/bridges/mcp-app/bridge.js +56 -204
  44. package/dist/web/bridges/mcp-app/bridge.js.map +1 -1
  45. package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +5 -3
  46. package/dist/web/bridges/mcp-app/use-mcp-app-context.js +2 -2
  47. package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -1
  48. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +2 -18
  49. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -1
  50. package/dist/web/bridges/types.d.ts +7 -3
  51. package/dist/web/create-store.test.js +4 -1
  52. package/dist/web/create-store.test.js.map +1 -1
  53. package/dist/web/data-llm.test.js +1 -1
  54. package/dist/web/data-llm.test.js.map +1 -1
  55. package/dist/web/hooks/index.d.ts +1 -1
  56. package/dist/web/hooks/index.js.map +1 -1
  57. package/dist/web/hooks/test/utils.js +4 -0
  58. package/dist/web/hooks/test/utils.js.map +1 -1
  59. package/dist/web/hooks/use-display-mode.d.ts +3 -3
  60. package/dist/web/hooks/use-display-mode.js.map +1 -1
  61. package/dist/web/hooks/use-display-mode.test-d.d.ts +1 -0
  62. package/dist/web/hooks/use-display-mode.test-d.js +8 -0
  63. package/dist/web/hooks/use-display-mode.test-d.js.map +1 -0
  64. package/dist/web/hooks/use-layout.test.js +2 -2
  65. package/dist/web/hooks/use-layout.test.js.map +1 -1
  66. package/dist/web/hooks/use-open-external.d.ts +3 -1
  67. package/dist/web/hooks/use-open-external.js +1 -1
  68. package/dist/web/hooks/use-open-external.js.map +1 -1
  69. package/dist/web/hooks/use-open-external.test.js +25 -10
  70. package/dist/web/hooks/use-open-external.test.js.map +1 -1
  71. package/dist/web/hooks/use-set-open-in-app-url.test.js +5 -11
  72. package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -1
  73. package/dist/web/hooks/use-widget-state.test.js +2 -0
  74. package/dist/web/hooks/use-widget-state.test.js.map +1 -1
  75. package/dist/web/plugin/plugin.js +8 -0
  76. package/dist/web/plugin/plugin.js.map +1 -1
  77. package/dist/web/plugin/validate-widget.d.ts +5 -0
  78. package/dist/web/plugin/validate-widget.js +27 -0
  79. package/dist/web/plugin/validate-widget.js.map +1 -0
  80. package/dist/web/plugin/validate-widget.test.d.ts +1 -0
  81. package/dist/web/plugin/validate-widget.test.js +42 -0
  82. package/dist/web/plugin/validate-widget.test.js.map +1 -0
  83. package/package.json +15 -12
  84. package/tsconfig.base.json +28 -0
@@ -0,0 +1,383 @@
1
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
+ import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
3
+ import { describe, expect, it, vi } from "vitest";
4
+ import { z } from "zod";
5
+ import { buildMiddlewareChain, getHandlerMaps, matchesFilter, } from "./middleware.js";
6
+ import { McpServer } from "./server.js";
7
+ // ---------------------------------------------------------------------------
8
+ // matchesFilter
9
+ // ---------------------------------------------------------------------------
10
+ describe("matchesFilter", () => {
11
+ it("matches exact method", () => {
12
+ expect(matchesFilter("tools/call", "tools/call", false)).toBe(true);
13
+ });
14
+ it("rejects non-matching exact method", () => {
15
+ expect(matchesFilter("tools/list", "tools/call", false)).toBe(false);
16
+ });
17
+ it("matches wildcard", () => {
18
+ expect(matchesFilter("tools/call", "tools/*", false)).toBe(true);
19
+ expect(matchesFilter("tools/list", "tools/*", false)).toBe(true);
20
+ });
21
+ it("rejects non-matching wildcard", () => {
22
+ expect(matchesFilter("resources/read", "tools/*", false)).toBe(false);
23
+ });
24
+ it('category "request" matches when isNotification=false', () => {
25
+ expect(matchesFilter("tools/call", "request", false)).toBe(true);
26
+ });
27
+ it('category "request" rejects when isNotification=true', () => {
28
+ expect(matchesFilter("notifications/initialized", "request", true)).toBe(false);
29
+ });
30
+ it('category "notification" matches when isNotification=true', () => {
31
+ expect(matchesFilter("notifications/initialized", "notification", true)).toBe(true);
32
+ });
33
+ it('category "notification" rejects when isNotification=false', () => {
34
+ expect(matchesFilter("tools/call", "notification", false)).toBe(false);
35
+ });
36
+ });
37
+ // ---------------------------------------------------------------------------
38
+ // buildMiddlewareChain
39
+ // ---------------------------------------------------------------------------
40
+ describe("buildMiddlewareChain", () => {
41
+ const fakeExtra = {};
42
+ const makeHandler = (returnValue) => vi.fn(async () => returnValue);
43
+ const makeEntry = (filter, handler) => ({ filter, handler });
44
+ it("returns original handler when no middleware applies", () => {
45
+ const original = makeHandler("result");
46
+ const chain = buildMiddlewareChain("tools/call", false, original, [
47
+ makeEntry("resources/*", async (_req, _extra, next) => next()),
48
+ ]);
49
+ expect(chain).toBe(original);
50
+ });
51
+ it("catch-all middleware runs for any method", async () => {
52
+ const original = makeHandler("ok");
53
+ const spy = vi.fn();
54
+ const chain = buildMiddlewareChain("tools/call", false, original, [
55
+ makeEntry(null, async (request, _extra, next) => {
56
+ spy(request.method);
57
+ return next();
58
+ }),
59
+ ]);
60
+ const result = await chain({ method: "tools/call", params: {} }, fakeExtra);
61
+ expect(spy).toHaveBeenCalledWith("tools/call");
62
+ expect(result).toBe("ok");
63
+ });
64
+ it("method-scoped middleware only runs for matching methods", async () => {
65
+ const original = makeHandler("ok");
66
+ const spy = vi.fn();
67
+ const entries = [
68
+ makeEntry("tools/call", async (_req, _extra, next) => {
69
+ spy("tools/call");
70
+ return next();
71
+ }),
72
+ ];
73
+ // Matching
74
+ const chain1 = buildMiddlewareChain("tools/call", false, original, entries);
75
+ await chain1({ method: "tools/call", params: {} }, fakeExtra);
76
+ expect(spy).toHaveBeenCalledTimes(1);
77
+ // Non-matching — returns original handler directly
78
+ const chain2 = buildMiddlewareChain("tools/list", false, original, entries);
79
+ expect(chain2).toBe(original);
80
+ });
81
+ it("executes middleware in registration order (onion model)", async () => {
82
+ const calls = [];
83
+ const original = makeHandler("result");
84
+ const chain = buildMiddlewareChain("tools/call", false, original, [
85
+ makeEntry(null, async (_req, _extra, next) => {
86
+ calls.push("A:before");
87
+ const result = await next();
88
+ calls.push("A:after");
89
+ return result;
90
+ }),
91
+ makeEntry(null, async (_req, _extra, next) => {
92
+ calls.push("B:before");
93
+ const result = await next();
94
+ calls.push("B:after");
95
+ return result;
96
+ }),
97
+ ]);
98
+ await chain({ method: "tools/call", params: {} }, fakeExtra);
99
+ expect(calls).toEqual(["A:before", "B:before", "B:after", "A:after"]);
100
+ });
101
+ it("short-circuit (no next() call) skips handler", async () => {
102
+ const original = makeHandler("original");
103
+ const chain = buildMiddlewareChain("tools/call", false, original, [
104
+ makeEntry(null, async () => "short-circuited"),
105
+ ]);
106
+ const result = await chain({ method: "tools/call", params: {} }, fakeExtra);
107
+ expect(result).toBe("short-circuited");
108
+ expect(original).not.toHaveBeenCalled();
109
+ });
110
+ it("middleware can modify result post-next()", async () => {
111
+ const original = makeHandler({ value: 1 });
112
+ const chain = buildMiddlewareChain("tools/call", false, original, [
113
+ makeEntry(null, async (_req, _extra, next) => {
114
+ const result = (await next());
115
+ return { value: result.value + 10 };
116
+ }),
117
+ ]);
118
+ const result = await chain({ method: "tools/call", params: {} }, fakeExtra);
119
+ expect(result).toEqual({ value: 11 });
120
+ });
121
+ it("throws on double next() call", async () => {
122
+ const original = makeHandler("ok");
123
+ const chain = buildMiddlewareChain("tools/call", false, original, [
124
+ makeEntry(null, async (_req, _extra, next) => {
125
+ await next();
126
+ return next(); // double call
127
+ }),
128
+ ]);
129
+ await expect(chain({ method: "tools/call", params: {} }, fakeExtra)).rejects.toThrow("next() called multiple times");
130
+ });
131
+ it("propagates errors from handler and middleware", async () => {
132
+ // Error from original handler bubbles through middleware
133
+ const failingHandler = vi.fn(async () => {
134
+ throw new Error("handler boom");
135
+ });
136
+ const chain1 = buildMiddlewareChain("tools/call", false, failingHandler, [
137
+ makeEntry(null, async (_req, _extra, next) => next()),
138
+ ]);
139
+ await expect(chain1({ method: "tools/call", params: {} }, fakeExtra)).rejects.toThrow("handler boom");
140
+ // Error thrown inside middleware propagates
141
+ const chain2 = buildMiddlewareChain("tools/call", false, makeHandler("ok"), [
142
+ makeEntry(null, async () => {
143
+ throw new Error("middleware boom");
144
+ }),
145
+ ]);
146
+ await expect(chain2({ method: "tools/call", params: {} }, fakeExtra)).rejects.toThrow("middleware boom");
147
+ });
148
+ it("passes extra as undefined for notifications (isNotification=true)", async () => {
149
+ const original = makeHandler(undefined);
150
+ let capturedExtra = {};
151
+ const chain = buildMiddlewareChain("notifications/initialized", true, original, [
152
+ makeEntry(null, async (_req, extra, next) => {
153
+ capturedExtra = extra;
154
+ return next();
155
+ }),
156
+ ]);
157
+ await chain({ method: "notifications/initialized" });
158
+ expect(capturedExtra).toBeUndefined();
159
+ });
160
+ it("defaults params to empty object when rawRequest has no params", async () => {
161
+ const original = makeHandler("ok");
162
+ let capturedParams;
163
+ const chain = buildMiddlewareChain("tools/call", false, original, [
164
+ makeEntry(null, async (request, _extra, next) => {
165
+ capturedParams = request.params;
166
+ return next();
167
+ }),
168
+ ]);
169
+ await chain({ method: "tools/call" }, fakeExtra);
170
+ expect(capturedParams).toEqual({});
171
+ });
172
+ it("propagates in-place param mutation to original handler", async () => {
173
+ let handlerReceivedName = "";
174
+ const original = vi.fn(async (rawReq) => {
175
+ handlerReceivedName = rawReq.params.name;
176
+ return "ok";
177
+ });
178
+ const chain = buildMiddlewareChain("tools/call", false, original, [
179
+ makeEntry(null, async (request, _extra, next) => {
180
+ request.params.name = "mutated";
181
+ return next();
182
+ }),
183
+ ]);
184
+ await chain({ params: { name: "original" } }, fakeExtra);
185
+ expect(handlerReceivedName).toBe("mutated");
186
+ });
187
+ it("propagates full param replacement to original handler", async () => {
188
+ let handlerReceivedParams = {};
189
+ const original = vi.fn(async (rawReq) => {
190
+ handlerReceivedParams = rawReq.params;
191
+ return "ok";
192
+ });
193
+ const chain = buildMiddlewareChain("tools/call", false, original, [
194
+ makeEntry(null, async (request, _extra, next) => {
195
+ request.params = { replaced: true };
196
+ return next();
197
+ }),
198
+ ]);
199
+ await chain({ params: { original: true } }, fakeExtra);
200
+ expect(handlerReceivedParams).toEqual({ replaced: true });
201
+ });
202
+ });
203
+ // ---------------------------------------------------------------------------
204
+ // McpServer.mcpMiddleware() integration tests
205
+ // ---------------------------------------------------------------------------
206
+ describe("McpServer.mcpMiddleware()", () => {
207
+ function createClient() {
208
+ return new Client({ name: "test-client", version: "1.0.0" });
209
+ }
210
+ it("returns this for chaining", () => {
211
+ const server = new McpServer({ name: "test", version: "1.0.0" });
212
+ const result = server.mcpMiddleware(async (_req, _extra, next) => next());
213
+ expect(result).toBe(server);
214
+ });
215
+ it("intercepts tools/call and exposes request params", async () => {
216
+ let capturedMethod = "";
217
+ let capturedParams = {};
218
+ const server = new McpServer({ name: "test", version: "1.0.0" });
219
+ server.registerTool("greet", {
220
+ description: "greet",
221
+ inputSchema: { name: z.string() },
222
+ }, (args) => ({
223
+ content: [{ type: "text", text: `hi ${args.name}` }],
224
+ }));
225
+ server.mcpMiddleware("tools/call", async (request, _extra, next) => {
226
+ capturedMethod = request.method;
227
+ capturedParams = request.params;
228
+ return next();
229
+ });
230
+ const client = createClient();
231
+ const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
232
+ await server.connect(serverTransport);
233
+ await client.connect(clientTransport);
234
+ const result = await client.callTool({
235
+ name: "greet",
236
+ arguments: { name: "World" },
237
+ });
238
+ expect(capturedMethod).toBe("tools/call");
239
+ expect(capturedParams).toMatchObject({
240
+ name: "greet",
241
+ arguments: { name: "World" },
242
+ });
243
+ expect(result.content).toEqual([{ type: "text", text: "hi World" }]);
244
+ await client.close();
245
+ await server.close();
246
+ });
247
+ it("array filter works", async () => {
248
+ const matchedMethods = [];
249
+ const server = new McpServer({ name: "test", version: "1.0.0" });
250
+ server.registerTool("t1", { description: "t1" }, () => ({
251
+ content: [{ type: "text", text: "ok" }],
252
+ }));
253
+ server.mcpMiddleware(["tools/call", "tools/list"], async (request, _extra, next) => {
254
+ matchedMethods.push(request.method);
255
+ return next();
256
+ });
257
+ const client = createClient();
258
+ const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
259
+ await server.connect(serverTransport);
260
+ await client.connect(clientTransport);
261
+ await client.listTools();
262
+ await client.callTool({ name: "t1" });
263
+ expect(matchedMethods).toEqual(["tools/list", "tools/call"]);
264
+ await client.close();
265
+ await server.close();
266
+ });
267
+ it("throws if registered after connect()", async () => {
268
+ const server = new McpServer({ name: "test", version: "1.0.0" });
269
+ const [_clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
270
+ await server.connect(serverTransport);
271
+ expect(() => server.mcpMiddleware(async (_req, _extra, next) => next())).toThrow("Cannot register MCP middleware after run() or connect()");
272
+ await server.close();
273
+ });
274
+ it("throws when filter provided without handler", () => {
275
+ const server = new McpServer({ name: "test", version: "1.0.0" });
276
+ expect(() =>
277
+ // @ts-expect-error intentionally passing filter without handler
278
+ server.mcpMiddleware("tools/call")).toThrow("mcpMiddleware requires a handler function");
279
+ });
280
+ it("catch-all middleware + filtered middleware stack correctly", async () => {
281
+ const calls = [];
282
+ const server = new McpServer({ name: "test", version: "1.0.0" });
283
+ server.registerTool("t1", { description: "t1" }, () => ({
284
+ content: [{ type: "text", text: "ok" }],
285
+ }));
286
+ server
287
+ .mcpMiddleware(async (request, _extra, next) => {
288
+ calls.push(`global:${request.method}`);
289
+ return next();
290
+ })
291
+ .mcpMiddleware("tools/call", async (_req, _extra, next) => {
292
+ calls.push("tools-only");
293
+ return next();
294
+ });
295
+ const client = createClient();
296
+ const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
297
+ await server.connect(serverTransport);
298
+ await client.connect(clientTransport);
299
+ await client.listTools();
300
+ await client.callTool({ name: "t1" });
301
+ // Catch-all also intercepts initialize + notifications/initialized from handshake.
302
+ // tools/list: only global middleware runs
303
+ // tools/call: global + tools-only both run
304
+ expect(calls).toContain("global:tools/list");
305
+ expect(calls).toContain("global:tools/call");
306
+ expect(calls).toContain("tools-only");
307
+ // "tools-only" must come right after "global:tools/call"
308
+ const toolsCallIdx = calls.indexOf("global:tools/call");
309
+ expect(calls[toolsCallIdx + 1]).toBe("tools-only");
310
+ await client.close();
311
+ await server.close();
312
+ });
313
+ it("notification middleware receives extra as undefined", async () => {
314
+ let capturedExtra = "sentinel";
315
+ const server = new McpServer({ name: "test", version: "1.0.0" });
316
+ server.registerTool("t1", { description: "t1" }, () => ({
317
+ content: [{ type: "text", text: "ok" }],
318
+ }));
319
+ server.mcpMiddleware("notification", async (_request, extra, next) => {
320
+ capturedExtra = extra;
321
+ return next();
322
+ });
323
+ const client = createClient();
324
+ const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
325
+ await server.connect(serverTransport);
326
+ await client.connect(clientTransport);
327
+ // The client sends notifications/initialized automatically on connect.
328
+ await client.listTools();
329
+ expect(capturedExtra).toBeUndefined();
330
+ await client.close();
331
+ await server.close();
332
+ });
333
+ it("category 'request' filter matches requests but not notifications", async () => {
334
+ const matchedMethods = [];
335
+ const server = new McpServer({ name: "test", version: "1.0.0" });
336
+ server.registerTool("t1", { description: "t1" }, () => ({
337
+ content: [{ type: "text", text: "ok" }],
338
+ }));
339
+ server.mcpMiddleware("request", async (request, _extra, next) => {
340
+ matchedMethods.push(request.method);
341
+ return next();
342
+ });
343
+ const client = createClient();
344
+ const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
345
+ await server.connect(serverTransport);
346
+ await client.connect(clientTransport);
347
+ await client.listTools();
348
+ await client.callTool({ name: "t1" });
349
+ expect(matchedMethods).toContain("tools/list");
350
+ expect(matchedMethods).toContain("tools/call");
351
+ expect(matchedMethods).not.toContain("notifications/initialized");
352
+ await client.close();
353
+ await server.close();
354
+ });
355
+ });
356
+ // ---------------------------------------------------------------------------
357
+ // getHandlerMaps
358
+ // ---------------------------------------------------------------------------
359
+ describe("getHandlerMaps", () => {
360
+ it("throws for incompatible server objects", () => {
361
+ // Empty object
362
+ expect(() => getHandlerMaps({})).toThrow("Incompatible MCP SDK version");
363
+ // Only _requestHandlers (missing _notificationHandlers)
364
+ expect(() => getHandlerMaps({ _requestHandlers: new Map() })).toThrow("Incompatible MCP SDK version");
365
+ // Non-Map values
366
+ expect(() => getHandlerMaps({
367
+ _requestHandlers: {},
368
+ _notificationHandlers: {},
369
+ })).toThrow("Incompatible MCP SDK version");
370
+ });
371
+ it("returns handler maps from valid server", () => {
372
+ const reqMap = new Map();
373
+ const notifMap = new Map();
374
+ const fake = {
375
+ _requestHandlers: reqMap,
376
+ _notificationHandlers: notifMap,
377
+ };
378
+ const result = getHandlerMaps(fake);
379
+ expect(result.requestHandlers).toBe(reqMap);
380
+ expect(result.notificationHandlers).toBe(notifMap);
381
+ });
382
+ });
383
+ //# sourceMappingURL=middleware.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.test.js","sourceRoot":"","sources":["../../src/server/middleware.test.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@ import type { AnySchema, SchemaOutput, ZodRawShapeCompat } from "@modelcontextpr
4
4
  import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
5
5
  import type { CallToolResult, Resource, ServerNotification, ServerRequest, ToolAnnotations } from "@modelcontextprotocol/sdk/types.js";
6
6
  import type { RequestHandler } from "express";
7
+ import type { McpExtra, McpMethodString, McpMiddlewareFilter, McpMiddlewareFn, McpTypedMiddlewareFn } from "./middleware.js";
7
8
  export type ToolDef<TInput = unknown, TOutput = unknown, TResponseMetadata = unknown> = {
8
9
  input: TInput;
9
10
  output: TOutput;
@@ -84,8 +85,41 @@ export declare class McpServer<TTools extends Record<string, ToolDef> = Record<n
84
85
  readonly $types: McpServerTypes<TTools>;
85
86
  private express?;
86
87
  private customMiddleware;
88
+ private mcpMiddlewareEntries;
89
+ private mcpMiddlewareApplied;
87
90
  use(...handlers: RequestHandler[]): this;
88
91
  use(path: string, ...handlers: RequestHandler[]): this;
92
+ /**
93
+ * Register MCP protocol-level middleware (catch-all).
94
+ */
95
+ mcpMiddleware(handler: McpMiddlewareFn): this;
96
+ /**
97
+ * Register MCP protocol-level middleware for all requests (`extra` is `McpExtra`).
98
+ */
99
+ mcpMiddleware(filter: "request", handler: (request: {
100
+ method: string;
101
+ params: Record<string, unknown>;
102
+ }, extra: McpExtra, next: () => Promise<unknown>) => Promise<unknown> | unknown): this;
103
+ /**
104
+ * Register MCP protocol-level middleware for all notifications (`extra` is `undefined`).
105
+ */
106
+ mcpMiddleware(filter: "notification", handler: (request: {
107
+ method: string;
108
+ params: Record<string, unknown>;
109
+ }, extra: undefined, next: () => Promise<unknown>) => Promise<unknown> | unknown): this;
110
+ /**
111
+ * Register MCP protocol-level middleware for an exact method.
112
+ * Narrows both `params` and `extra` based on the method string.
113
+ */
114
+ mcpMiddleware<M extends McpMethodString>(filter: M, handler: McpTypedMiddlewareFn<M>): this;
115
+ /**
116
+ * Register MCP protocol-level middleware with a method filter.
117
+ * Filter can be an exact method (`"tools/call"`), wildcard (`"tools/*"`),
118
+ * category (`"request"` | `"notification"`), or an array of those.
119
+ */
120
+ mcpMiddleware(filter: McpMiddlewareFilter, handler: McpMiddlewareFn): this;
121
+ private applyMcpMiddleware;
122
+ connect(transport: Parameters<typeof McpServerBase.prototype.connect>[0]): Promise<void>;
89
123
  run(): Promise<void>;
90
124
  registerWidget<TName extends string, TInput extends ZodRawShapeCompat, TReturn extends {
91
125
  content: CallToolResult["content"];
@@ -4,9 +4,10 @@ import http from "node:http";
4
4
  import path from "node:path";
5
5
  import { McpServer as McpServerBase, } from "@modelcontextprotocol/sdk/server/mcp.js";
6
6
  import { mergeWith, union } from "es-toolkit";
7
+ import { DEFAULT_HMR_PORT } from "./const.js";
7
8
  import { createServer } from "./express.js";
9
+ import { buildMiddlewareChain, getHandlerMaps } from "./middleware.js";
8
10
  import { templateHelper } from "./templateHelper.js";
9
- import { DEFAULT_HMR_PORT } from "./const.js";
10
11
  const mergeWithUnion = (target, source) => {
11
12
  return mergeWith(target, source, (targetVal, sourceVal) => {
12
13
  if (Array.isArray(targetVal) && Array.isArray(sourceVal)) {
@@ -17,6 +18,8 @@ const mergeWithUnion = (target, source) => {
17
18
  export class McpServer extends McpServerBase {
18
19
  express;
19
20
  customMiddleware = [];
21
+ mcpMiddlewareEntries = [];
22
+ mcpMiddlewareApplied = false;
20
23
  use(pathOrHandler, ...handlers) {
21
24
  if (typeof pathOrHandler === "string") {
22
25
  this.customMiddleware.push({
@@ -31,7 +34,57 @@ export class McpServer extends McpServerBase {
31
34
  }
32
35
  return this;
33
36
  }
37
+ mcpMiddleware(filterOrHandler,
38
+ // biome-ignore lint/suspicious/noExplicitAny: overloads narrow the handler type at call sites; implementation must accept all variants
39
+ maybeHandler) {
40
+ if (this.mcpMiddlewareApplied) {
41
+ throw new Error("Cannot register MCP middleware after run() or connect() has been called");
42
+ }
43
+ const handler = maybeHandler;
44
+ if (typeof filterOrHandler === "function") {
45
+ this.mcpMiddlewareEntries.push({
46
+ filter: null,
47
+ handler: filterOrHandler,
48
+ });
49
+ }
50
+ else if (handler) {
51
+ this.mcpMiddlewareEntries.push({
52
+ filter: filterOrHandler,
53
+ handler,
54
+ });
55
+ }
56
+ else {
57
+ throw new Error("mcpMiddleware requires a handler function when a filter is provided");
58
+ }
59
+ return this;
60
+ }
61
+ applyMcpMiddleware() {
62
+ if (this.mcpMiddlewareApplied) {
63
+ return;
64
+ }
65
+ this.mcpMiddlewareApplied = true;
66
+ if (this.mcpMiddlewareEntries.length === 0) {
67
+ return;
68
+ }
69
+ const { requestHandlers, notificationHandlers } = getHandlerMaps(this.server);
70
+ const entries = this.mcpMiddlewareEntries;
71
+ // Wrap existing handlers and proxy future .set() for lazy SDK registration
72
+ const instrumentMap = (map, isNotification) => {
73
+ for (const [method, handler] of map) {
74
+ map.set(method, buildMiddlewareChain(method, isNotification, handler, entries));
75
+ }
76
+ const originalSet = map.set.bind(map);
77
+ map.set = (method, handler) => originalSet(method, buildMiddlewareChain(method, isNotification, handler, entries));
78
+ };
79
+ instrumentMap(requestHandlers, false);
80
+ instrumentMap(notificationHandlers, true);
81
+ }
82
+ async connect(transport) {
83
+ this.applyMcpMiddleware();
84
+ return super.connect(transport);
85
+ }
34
86
  async run() {
87
+ this.applyMcpMiddleware();
35
88
  if (!this.express) {
36
89
  this.express = await createServer({
37
90
  server: this,
@@ -45,7 +98,7 @@ export class McpServer extends McpServerBase {
45
98
  console.error("Failed to start server:", error);
46
99
  reject(error);
47
100
  });
48
- const port = parseInt(process.env.SKYBRIDGE_PORT ?? "3000", 10);
101
+ const port = parseInt(process.env.__PORT ?? "3000", 10);
49
102
  server.listen(port, () => {
50
103
  resolve();
51
104
  });
@@ -61,7 +114,7 @@ export class McpServer extends McpServerBase {
61
114
  hostType: "apps-sdk",
62
115
  uri: `ui://widgets/apps-sdk/${name}.html`,
63
116
  mimeType: "text/html+skybridge",
64
- buildContentMeta: ({ resourceDomains, connectDomains, domain }) => {
117
+ buildContentMeta: ({ resourceDomains, connectDomains, domain }, overrides) => {
65
118
  const userUi = userMeta?.ui;
66
119
  const userCsp = userUi?.csp;
67
120
  const defaults = {
@@ -83,7 +136,7 @@ export class McpServer extends McpServerBase {
83
136
  "openai/widgetPrefersBorder": userUi?.prefersBorder,
84
137
  };
85
138
  const directOpenaiKeys = Object.fromEntries(Object.entries(userMeta ?? {}).filter(([key]) => key.startsWith("openai/")));
86
- return mergeWithUnion(mergeWithUnion(defaults, fromUi), directOpenaiKeys);
139
+ return mergeWithUnion(mergeWithUnion(mergeWithUnion(defaults, fromUi), directOpenaiKeys), { "openai/widgetDomain": overrides.domain });
87
140
  },
88
141
  };
89
142
  this.registerWidgetResource({
@@ -98,7 +151,7 @@ export class McpServer extends McpServerBase {
98
151
  hostType: "mcp-app",
99
152
  uri: `ui://widgets/ext-apps/${name}.html`,
100
153
  mimeType: "text/html;profile=mcp-app",
101
- buildContentMeta: ({ resourceDomains, connectDomains, domain }) => {
154
+ buildContentMeta: ({ resourceDomains, connectDomains, domain }, overrides) => {
102
155
  const defaults = {
103
156
  ui: {
104
157
  csp: {
@@ -108,7 +161,9 @@ export class McpServer extends McpServerBase {
108
161
  domain,
109
162
  },
110
163
  };
111
- return mergeWithUnion(defaults, { ui: userMeta?.ui });
164
+ return mergeWithUnion(defaults, {
165
+ ui: { ...userMeta?.ui, ...overrides },
166
+ });
112
167
  },
113
168
  };
114
169
  this.registerWidgetResource({
@@ -139,7 +194,7 @@ export class McpServer extends McpServerBase {
139
194
  const hostFromHeaders = extra?.requestInfo?.headers?.["x-forwarded-host"] ??
140
195
  extra?.requestInfo?.headers?.host;
141
196
  const useExternalHost = isProduction || useForwardedHost || isClaude;
142
- const devPort = process.env.SKYBRIDGE_PORT || "3000";
197
+ const devPort = process.env.__PORT || "3000";
143
198
  const serverUrl = useExternalHost
144
199
  ? `https://${hostFromHeaders}`
145
200
  : `http://localhost:${devPort}`;
@@ -158,22 +213,28 @@ export class McpServer extends McpServerBase {
158
213
  });
159
214
  const connectDomains = [serverUrl];
160
215
  if (!isProduction) {
161
- const hmrPort = process.env.SKYBRIDGE_HMR_PORT ?? DEFAULT_HMR_PORT;
216
+ const hmrPort = process.env.__SKYBRIDGE_HMR_PORT ?? DEFAULT_HMR_PORT;
162
217
  const VITE_HMR_WEBSOCKET_DEFAULT_URL = `ws://localhost:${hmrPort}`;
163
218
  connectDomains.push(VITE_HMR_WEBSOCKET_DEFAULT_URL);
164
219
  }
220
+ const pathname = extra?.requestInfo?.url?.pathname ?? "";
221
+ const url = `https://${hostFromHeaders}${pathname}`;
222
+ const hash = crypto
223
+ .createHash("sha256")
224
+ .update(url)
225
+ .digest("hex")
226
+ .slice(0, 32);
227
+ const contentMetaOverrides = isClaude
228
+ ? {
229
+ domain: `${hash}.claudemcpcontent.com`,
230
+ }
231
+ : {};
165
232
  const contentMeta = buildContentMeta({
166
233
  resourceDomains: [serverUrl],
167
234
  connectDomains,
168
- domain: isClaude
169
- ? `${crypto
170
- .createHash("sha256")
171
- .update(`https://${hostFromHeaders}/mcp`)
172
- .digest("hex")
173
- .slice(0, 32)}.claudemcpcontent.com`
174
- : serverUrl,
235
+ domain: serverUrl,
175
236
  baseUriDomains: [serverUrl],
176
- });
237
+ }, contentMetaOverrides);
177
238
  return {
178
239
  contents: [
179
240
  { uri: uri.href, mimeType, text: html, _meta: contentMeta },