skybridge 0.36.1 → 0.36.3
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/dist/cli/detect-port.js.map +1 -1
- package/dist/cli/header.js.map +1 -1
- package/dist/cli/run-command.js.map +1 -1
- package/dist/cli/telemetry.js.map +1 -1
- package/dist/cli/tunnel-control-server.d.ts +9 -0
- package/dist/cli/tunnel-control-server.js +31 -0
- package/dist/cli/tunnel-control-server.js.map +1 -0
- package/dist/cli/tunnel-control-server.test.d.ts +1 -0
- package/dist/cli/tunnel-control-server.test.js +39 -0
- package/dist/cli/tunnel-control-server.test.js.map +1 -0
- package/dist/cli/tunnel-handler.d.ts +3 -0
- package/dist/cli/tunnel-handler.js +48 -0
- package/dist/cli/tunnel-handler.js.map +1 -0
- package/dist/cli/tunnel-handler.test.d.ts +1 -0
- package/dist/cli/tunnel-handler.test.js +105 -0
- package/dist/cli/tunnel-handler.test.js.map +1 -0
- package/dist/cli/tunnel.d.ts +57 -0
- package/dist/cli/tunnel.js +154 -0
- package/dist/cli/tunnel.js.map +1 -0
- package/dist/cli/tunnel.test.d.ts +1 -0
- package/dist/cli/tunnel.test.js +190 -0
- package/dist/cli/tunnel.test.js.map +1 -0
- package/dist/cli/types.js.map +1 -1
- package/dist/cli/use-execute-steps.js.map +1 -1
- package/dist/cli/use-messages.js.map +1 -1
- package/dist/cli/use-nodemon.js +11 -2
- package/dist/cli/use-nodemon.js.map +1 -1
- package/dist/cli/use-open-browser.d.ts +1 -0
- package/dist/cli/use-open-browser.js +44 -0
- package/dist/cli/use-open-browser.js.map +1 -0
- package/dist/cli/use-tunnel.d.ts +1 -1
- package/dist/cli/use-tunnel.js +102 -68
- package/dist/cli/use-tunnel.js.map +1 -1
- package/dist/cli/use-typescript-check.js.map +1 -1
- package/dist/commands/build.js +36 -1
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/dev.d.ts +1 -0
- package/dist/commands/dev.js +33 -2
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/start.js.map +1 -1
- package/dist/commands/telemetry/disable.js.map +1 -1
- package/dist/commands/telemetry/enable.js.map +1 -1
- package/dist/commands/telemetry/status.js.map +1 -1
- package/dist/server/asset-base-url-transform-plugin.js.map +1 -1
- package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -1
- package/dist/server/content-helpers.js.map +1 -1
- package/dist/server/content-helpers.test.js.map +1 -1
- package/dist/server/express.d.ts +1 -5
- package/dist/server/express.js +31 -7
- package/dist/server/express.js.map +1 -1
- package/dist/server/express.test.js +210 -69
- package/dist/server/express.test.js.map +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/inferUtilityTypes.js.map +1 -1
- package/dist/server/metric.js.map +1 -1
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/middleware.test-d.js.map +1 -1
- package/dist/server/middleware.test.js.map +1 -1
- package/dist/server/server.d.ts +27 -4
- package/dist/server/server.js +49 -17
- package/dist/server/server.js.map +1 -1
- package/dist/server/templateHelper.d.ts +0 -2
- package/dist/server/templateHelper.js +3 -22
- package/dist/server/templateHelper.js.map +1 -1
- package/dist/server/templates.generated.d.ts +4 -0
- package/dist/server/templates.generated.js +47 -0
- package/dist/server/templates.generated.js.map +1 -0
- package/dist/server/tunnel-proxy-router.d.ts +7 -0
- package/dist/server/tunnel-proxy-router.js +110 -0
- package/dist/server/tunnel-proxy-router.js.map +1 -0
- package/dist/server/tunnel-proxy-router.test.d.ts +1 -0
- package/dist/server/tunnel-proxy-router.test.js +229 -0
- package/dist/server/tunnel-proxy-router.test.js.map +1 -0
- package/dist/server/viewsDevServer.js.map +1 -1
- package/dist/test/utils.js.map +1 -1
- package/dist/test/view.test.js.map +1 -1
- package/dist/version.js +1 -3
- package/dist/version.js.map +1 -1
- package/dist/web/bridges/apps-sdk/adaptor.d.ts +4 -2
- package/dist/web/bridges/apps-sdk/adaptor.js +11 -2
- package/dist/web/bridges/apps-sdk/adaptor.js.map +1 -1
- package/dist/web/bridges/apps-sdk/bridge.js.map +1 -1
- package/dist/web/bridges/apps-sdk/index.js.map +1 -1
- package/dist/web/bridges/apps-sdk/types.d.ts +8 -1
- package/dist/web/bridges/apps-sdk/types.js.map +1 -1
- package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -1
- package/dist/web/bridges/get-adaptor.js.map +1 -1
- package/dist/web/bridges/index.js.map +1 -1
- package/dist/web/bridges/mcp-app/adaptor.d.ts +4 -2
- package/dist/web/bridges/mcp-app/adaptor.js +9 -6
- package/dist/web/bridges/mcp-app/adaptor.js.map +1 -1
- package/dist/web/bridges/mcp-app/bridge.js.map +1 -1
- package/dist/web/bridges/mcp-app/index.js.map +1 -1
- package/dist/web/bridges/mcp-app/types.js.map +1 -1
- package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -1
- package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -1
- package/dist/web/bridges/types.d.ts +10 -2
- package/dist/web/bridges/types.js.map +1 -1
- package/dist/web/bridges/use-host-context.js.map +1 -1
- package/dist/web/components/modal-provider.js.map +1 -1
- package/dist/web/create-store.js.map +1 -1
- package/dist/web/create-store.test.js.map +1 -1
- package/dist/web/data-llm.js.map +1 -1
- package/dist/web/data-llm.test.js.map +1 -1
- package/dist/web/generate-helpers.js.map +1 -1
- package/dist/web/generate-helpers.test-d.js.map +1 -1
- package/dist/web/generate-helpers.test.js.map +1 -1
- package/dist/web/helpers/state.js.map +1 -1
- package/dist/web/helpers/state.test.js.map +1 -1
- package/dist/web/hooks/index.d.ts +2 -0
- package/dist/web/hooks/index.js +2 -0
- package/dist/web/hooks/index.js.map +1 -1
- package/dist/web/hooks/test/utils.js.map +1 -1
- package/dist/web/hooks/use-call-tool.js.map +1 -1
- package/dist/web/hooks/use-call-tool.test-d.js.map +1 -1
- package/dist/web/hooks/use-call-tool.test.js +0 -4
- package/dist/web/hooks/use-call-tool.test.js.map +1 -1
- package/dist/web/hooks/use-display-mode.js.map +1 -1
- package/dist/web/hooks/use-display-mode.test-d.js.map +1 -1
- package/dist/web/hooks/use-display-mode.test.js.map +1 -1
- package/dist/web/hooks/use-files.js.map +1 -1
- package/dist/web/hooks/use-files.test.js.map +1 -1
- package/dist/web/hooks/use-layout.js.map +1 -1
- package/dist/web/hooks/use-layout.test.js.map +1 -1
- package/dist/web/hooks/use-open-external.js.map +1 -1
- package/dist/web/hooks/use-open-external.test.js.map +1 -1
- package/dist/web/hooks/use-request-close.d.ts +2 -0
- package/dist/web/hooks/use-request-close.js +8 -0
- package/dist/web/hooks/use-request-close.js.map +1 -0
- package/dist/web/hooks/use-request-close.test.d.ts +1 -0
- package/dist/web/hooks/use-request-close.test.js +52 -0
- package/dist/web/hooks/use-request-close.test.js.map +1 -0
- package/dist/web/hooks/use-request-modal.js.map +1 -1
- package/dist/web/hooks/use-request-modal.test.js.map +1 -1
- package/dist/web/hooks/use-request-size.d.ts +3 -0
- package/dist/web/hooks/use-request-size.js +8 -0
- package/dist/web/hooks/use-request-size.js.map +1 -0
- package/dist/web/hooks/use-request-size.test.d.ts +1 -0
- package/dist/web/hooks/use-request-size.test.js +65 -0
- package/dist/web/hooks/use-request-size.test.js.map +1 -0
- package/dist/web/hooks/use-send-follow-up-message.d.ts +2 -1
- package/dist/web/hooks/use-send-follow-up-message.js +2 -2
- package/dist/web/hooks/use-send-follow-up-message.js.map +1 -1
- package/dist/web/hooks/use-set-open-in-app-url.js.map +1 -1
- package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -1
- package/dist/web/hooks/use-tool-info.js.map +1 -1
- package/dist/web/hooks/use-tool-info.test-d.js.map +1 -1
- package/dist/web/hooks/use-tool-info.test.js.map +1 -1
- package/dist/web/hooks/use-user.js.map +1 -1
- package/dist/web/hooks/use-user.test.js.map +1 -1
- package/dist/web/hooks/use-view-state.js.map +1 -1
- package/dist/web/hooks/use-view-state.test.js.map +1 -1
- package/dist/web/index.js.map +1 -1
- package/dist/web/mount-view.js.map +1 -1
- package/dist/web/plugin/data-llm.test.js.map +1 -1
- package/dist/web/plugin/plugin.js +2 -9
- package/dist/web/plugin/plugin.js.map +1 -1
- package/dist/web/plugin/scan-views.js.map +1 -1
- package/dist/web/plugin/scan-views.test.js.map +1 -1
- package/dist/web/plugin/transform-data-llm.js.map +1 -1
- package/dist/web/plugin/transform-data-llm.test.js.map +1 -1
- package/dist/web/plugin/validate-view.js.map +1 -1
- package/dist/web/plugin/validate-view.test.js.map +1 -1
- package/dist/web/proxy.js.map +1 -1
- package/dist/web/types.js.map +1 -1
- package/package.json +8 -6
- package/dist/server/templates/development.hbs +0 -12
- package/dist/server/templates/production.hbs +0 -6
|
@@ -7,7 +7,6 @@ vi.mock("@skybridge/devtools", () => ({
|
|
|
7
7
|
vi.mock("./viewsDevServer.js", () => ({
|
|
8
8
|
viewsDevServer: (_httpServer) => ((_req, _res, next) => next()),
|
|
9
9
|
}));
|
|
10
|
-
const fakeServer = {};
|
|
11
10
|
async function listen(app) {
|
|
12
11
|
const server = http.createServer(app);
|
|
13
12
|
await new Promise((resolve) => server.listen(0, resolve));
|
|
@@ -26,6 +25,94 @@ async function postMcp(port) {
|
|
|
26
25
|
async function postApi(port) {
|
|
27
26
|
return fetch(`http://localhost:${port}/api/test`, { method: "POST" });
|
|
28
27
|
}
|
|
28
|
+
describe("McpServer.express", () => {
|
|
29
|
+
it("exposes a ready Express app immediately after construction", () => {
|
|
30
|
+
const server = new McpServer({ name: "t", version: "0.0.0" });
|
|
31
|
+
expect(server.express).toBeDefined();
|
|
32
|
+
expect(typeof server.express.use).toBe("function");
|
|
33
|
+
expect(typeof server.express.get).toBe("function");
|
|
34
|
+
});
|
|
35
|
+
it("server.express.get registers a route reachable alongside /mcp", async () => {
|
|
36
|
+
const { createApp } = await import("./express.js");
|
|
37
|
+
const server = new McpServer({ name: "t", version: "0.0.0" });
|
|
38
|
+
server.express.get("/health", (_req, res) => {
|
|
39
|
+
res.json({ status: "ok" });
|
|
40
|
+
});
|
|
41
|
+
const httpServer = http.createServer();
|
|
42
|
+
await createApp({ mcpServer: server, httpServer });
|
|
43
|
+
const { port, server: listening } = await listen(server.express);
|
|
44
|
+
openServer = listening;
|
|
45
|
+
const health = await fetch(`http://localhost:${port}/health`);
|
|
46
|
+
expect(health.status).toBe(200);
|
|
47
|
+
expect(await health.json()).toEqual({ status: "ok" });
|
|
48
|
+
// /mcp still works (POST returns 200/4xx, not 404)
|
|
49
|
+
const mcp = await postMcp(port);
|
|
50
|
+
expect(mcp.status).not.toBe(404);
|
|
51
|
+
});
|
|
52
|
+
it("server.use and server.express.use produce the same registration order", async () => {
|
|
53
|
+
const { createApp } = await import("./express.js");
|
|
54
|
+
const callsA = [];
|
|
55
|
+
const callsB = [];
|
|
56
|
+
const buildServer = () => new McpServer({ name: "t", version: "0.0.0" });
|
|
57
|
+
const sA = buildServer();
|
|
58
|
+
sA.use((_req, _res, next) => {
|
|
59
|
+
callsA.push("first");
|
|
60
|
+
next();
|
|
61
|
+
});
|
|
62
|
+
sA.express.use((_req, _res, next) => {
|
|
63
|
+
callsA.push("second");
|
|
64
|
+
next();
|
|
65
|
+
});
|
|
66
|
+
const sB = buildServer();
|
|
67
|
+
sB.express.use((_req, _res, next) => {
|
|
68
|
+
callsB.push("first");
|
|
69
|
+
next();
|
|
70
|
+
});
|
|
71
|
+
sB.use((_req, _res, next) => {
|
|
72
|
+
callsB.push("second");
|
|
73
|
+
next();
|
|
74
|
+
});
|
|
75
|
+
for (const s of [sA, sB]) {
|
|
76
|
+
s.express.get("/probe", (_req, res) => res.json({ ok: true }));
|
|
77
|
+
const httpServer = http.createServer();
|
|
78
|
+
await createApp({ mcpServer: s, httpServer });
|
|
79
|
+
const { port, server: listening } = await listen(s.express);
|
|
80
|
+
openServer = listening;
|
|
81
|
+
await fetch(`http://localhost:${port}/probe`);
|
|
82
|
+
listening.close();
|
|
83
|
+
}
|
|
84
|
+
expect(callsA).toEqual(["first", "second"]);
|
|
85
|
+
expect(callsB).toEqual(["first", "second"]);
|
|
86
|
+
});
|
|
87
|
+
it("useOnError still wraps thrown /mcp errors after the route is mounted", async () => {
|
|
88
|
+
const { createApp } = await import("./express.js");
|
|
89
|
+
const server = new McpServer({ name: "t", version: "0.0.0" });
|
|
90
|
+
// Register the error handler BEFORE createApp — useOnError should still
|
|
91
|
+
// apply it after /mcp, so /mcp errors hit it.
|
|
92
|
+
const seen = [];
|
|
93
|
+
server.useOnError((_err, _req, res, _next) => {
|
|
94
|
+
seen.push("useOnError");
|
|
95
|
+
res.status(503).json({ from: "useOnError" });
|
|
96
|
+
});
|
|
97
|
+
// Force the /mcp handler to throw so the error pipeline runs.
|
|
98
|
+
vi.spyOn(server, "connectStatelessTransport").mockRejectedValue(new Error("boom"));
|
|
99
|
+
const httpServer = http.createServer();
|
|
100
|
+
await createApp({
|
|
101
|
+
mcpServer: server,
|
|
102
|
+
httpServer,
|
|
103
|
+
// Mirror what run() does: forward the McpServer's useOnError handlers
|
|
104
|
+
// to createApp so they get applied after /mcp.
|
|
105
|
+
// biome-ignore lint/complexity/useLiteralKeys: test mirrors run() internals to verify useOnError ordering
|
|
106
|
+
errorMiddleware: server["customErrorMiddleware"],
|
|
107
|
+
});
|
|
108
|
+
const { port, server: listening } = await listen(server.express);
|
|
109
|
+
openServer = listening;
|
|
110
|
+
const res = await postMcp(port);
|
|
111
|
+
expect(seen).toEqual(["useOnError"]);
|
|
112
|
+
expect(res.status).toBe(503);
|
|
113
|
+
expect(await res.json()).toEqual({ from: "useOnError" });
|
|
114
|
+
});
|
|
115
|
+
});
|
|
29
116
|
describe("createApp", () => {
|
|
30
117
|
it("runs global custom middleware before the /mcp handler", async () => {
|
|
31
118
|
const { createApp } = await import("./express.js");
|
|
@@ -34,14 +121,12 @@ describe("createApp", () => {
|
|
|
34
121
|
calls.push("custom");
|
|
35
122
|
next();
|
|
36
123
|
};
|
|
124
|
+
const server = new McpServer({ name: "t", version: "0.0.0" });
|
|
125
|
+
server.use(mw);
|
|
37
126
|
const httpServer = http.createServer();
|
|
38
|
-
const app = await createApp({
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
customMiddleware: [{ handlers: [mw] }],
|
|
42
|
-
});
|
|
43
|
-
const { port, server } = await listen(app);
|
|
44
|
-
openServer = server;
|
|
127
|
+
const app = await createApp({ mcpServer: server, httpServer });
|
|
128
|
+
const { port, server: httpListening } = await listen(app);
|
|
129
|
+
openServer = httpListening;
|
|
45
130
|
await postMcp(port);
|
|
46
131
|
expect(calls).toEqual(["custom"]);
|
|
47
132
|
});
|
|
@@ -52,14 +137,12 @@ describe("createApp", () => {
|
|
|
52
137
|
calls.push("auth");
|
|
53
138
|
next();
|
|
54
139
|
};
|
|
140
|
+
const server = new McpServer({ name: "t", version: "0.0.0" });
|
|
141
|
+
server.use("/mcp", mw);
|
|
55
142
|
const httpServer = http.createServer();
|
|
56
|
-
const app = await createApp({
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
customMiddleware: [{ path: "/mcp", handlers: [mw] }],
|
|
60
|
-
});
|
|
61
|
-
const { port, server } = await listen(app);
|
|
62
|
-
openServer = server;
|
|
143
|
+
const app = await createApp({ mcpServer: server, httpServer });
|
|
144
|
+
const { port, server: httpListening } = await listen(app);
|
|
145
|
+
openServer = httpListening;
|
|
63
146
|
await postMcp(port);
|
|
64
147
|
expect(calls).toEqual(["auth"]);
|
|
65
148
|
});
|
|
@@ -70,14 +153,12 @@ describe("createApp", () => {
|
|
|
70
153
|
calls.push("reject");
|
|
71
154
|
res.status(401).json({ error: "Unauthorized" });
|
|
72
155
|
};
|
|
156
|
+
const server = new McpServer({ name: "t", version: "0.0.0" });
|
|
157
|
+
server.use("/mcp", reject);
|
|
73
158
|
const httpServer = http.createServer();
|
|
74
|
-
const app = await createApp({
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
customMiddleware: [{ path: "/mcp", handlers: [reject] }],
|
|
78
|
-
});
|
|
79
|
-
const { port, server } = await listen(app);
|
|
80
|
-
openServer = server;
|
|
159
|
+
const app = await createApp({ mcpServer: server, httpServer });
|
|
160
|
+
const { port, server: httpListening } = await listen(app);
|
|
161
|
+
openServer = httpListening;
|
|
81
162
|
const res = await postMcp(port);
|
|
82
163
|
expect(calls).toEqual(["reject"]);
|
|
83
164
|
expect(res.status).toBe(401);
|
|
@@ -94,14 +175,13 @@ describe("createApp", () => {
|
|
|
94
175
|
calls.push("B");
|
|
95
176
|
next();
|
|
96
177
|
};
|
|
178
|
+
const server = new McpServer({ name: "t", version: "0.0.0" });
|
|
179
|
+
server.use(mwA);
|
|
180
|
+
server.use(mwB);
|
|
97
181
|
const httpServer = http.createServer();
|
|
98
|
-
const app = await createApp({
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
customMiddleware: [{ handlers: [mwA] }, { handlers: [mwB] }],
|
|
102
|
-
});
|
|
103
|
-
const { port, server } = await listen(app);
|
|
104
|
-
openServer = server;
|
|
182
|
+
const app = await createApp({ mcpServer: server, httpServer });
|
|
183
|
+
const { port, server: httpListening } = await listen(app);
|
|
184
|
+
openServer = httpListening;
|
|
105
185
|
await postMcp(port);
|
|
106
186
|
expect(calls).toEqual(["A", "B"]);
|
|
107
187
|
});
|
|
@@ -112,14 +192,12 @@ describe("createApp", () => {
|
|
|
112
192
|
calls.push("api");
|
|
113
193
|
next();
|
|
114
194
|
};
|
|
195
|
+
const server = new McpServer({ name: "t", version: "0.0.0" });
|
|
196
|
+
server.use("/api", apiMw);
|
|
115
197
|
const httpServer = http.createServer();
|
|
116
|
-
const app = await createApp({
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
customMiddleware: [{ path: "/api", handlers: [apiMw] }],
|
|
120
|
-
});
|
|
121
|
-
const { port, server } = await listen(app);
|
|
122
|
-
openServer = server;
|
|
198
|
+
const app = await createApp({ mcpServer: server, httpServer });
|
|
199
|
+
const { port, server: httpListening } = await listen(app);
|
|
200
|
+
openServer = httpListening;
|
|
123
201
|
// Hit /mcp — the /api middleware should NOT fire
|
|
124
202
|
await postMcp(port);
|
|
125
203
|
expect(calls).toEqual([]);
|
|
@@ -131,14 +209,12 @@ describe("createApp", () => {
|
|
|
131
209
|
router.get("/health", (_req, res) => {
|
|
132
210
|
res.json({ status: "ok" });
|
|
133
211
|
});
|
|
212
|
+
const server = new McpServer({ name: "t", version: "0.0.0" });
|
|
213
|
+
server.use(router);
|
|
134
214
|
const httpServer = http.createServer();
|
|
135
|
-
const app = await createApp({
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
customMiddleware: [{ handlers: [router] }],
|
|
139
|
-
});
|
|
140
|
-
const { port, server } = await listen(app);
|
|
141
|
-
openServer = server;
|
|
215
|
+
const app = await createApp({ mcpServer: server, httpServer });
|
|
216
|
+
const { port, server: httpListening } = await listen(app);
|
|
217
|
+
openServer = httpListening;
|
|
142
218
|
const res = await fetch(`http://localhost:${port}/health`);
|
|
143
219
|
expect(res.status).toBe(200);
|
|
144
220
|
expect(await res.json()).toEqual({ status: "ok" });
|
|
@@ -150,16 +226,12 @@ describe("createApp", () => {
|
|
|
150
226
|
router.get("/data", (_req, res) => {
|
|
151
227
|
res.json({ value: 42 });
|
|
152
228
|
});
|
|
229
|
+
const server = new McpServer({ name: "t", version: "0.0.0" });
|
|
230
|
+
server.use("/api", router);
|
|
153
231
|
const httpServer = http.createServer();
|
|
154
|
-
const app = await createApp({
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
customMiddleware: [
|
|
158
|
-
{ path: "/api", handlers: [router] },
|
|
159
|
-
],
|
|
160
|
-
});
|
|
161
|
-
const { port, server } = await listen(app);
|
|
162
|
-
openServer = server;
|
|
232
|
+
const app = await createApp({ mcpServer: server, httpServer });
|
|
233
|
+
const { port, server: httpListening } = await listen(app);
|
|
234
|
+
openServer = httpListening;
|
|
163
235
|
const res = await fetch(`http://localhost:${port}/api/data`);
|
|
164
236
|
expect(res.status).toBe(200);
|
|
165
237
|
expect(await res.json()).toEqual({ value: 42 });
|
|
@@ -169,14 +241,12 @@ describe("createApp", () => {
|
|
|
169
241
|
const throwing = () => {
|
|
170
242
|
throw new Error("boom");
|
|
171
243
|
};
|
|
244
|
+
const server = new McpServer({ name: "t", version: "0.0.0" });
|
|
245
|
+
server.use("/explode", throwing);
|
|
172
246
|
const httpServer = http.createServer();
|
|
173
|
-
const app = await createApp({
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
customMiddleware: [{ path: "/explode", handlers: [throwing] }],
|
|
177
|
-
});
|
|
178
|
-
const { port, server } = await listen(app);
|
|
179
|
-
openServer = server;
|
|
247
|
+
const app = await createApp({ mcpServer: server, httpServer });
|
|
248
|
+
const { port, server: httpListening } = await listen(app);
|
|
249
|
+
openServer = httpListening;
|
|
180
250
|
const res = await fetch(`http://localhost:${port}/explode`);
|
|
181
251
|
expect(res.status).toBe(500);
|
|
182
252
|
// Server process did not crash — it still accepts connections
|
|
@@ -186,10 +256,15 @@ describe("createApp", () => {
|
|
|
186
256
|
it("returns 500 JSON-RPC error when the MCP handler throws and no error middleware is registered", async () => {
|
|
187
257
|
const { createApp } = await import("./express.js");
|
|
188
258
|
const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
|
|
259
|
+
const mcpServer = new McpServer({ name: "t", version: "0.0.0" });
|
|
260
|
+
// Force the express-level error path: make connectStatelessTransport
|
|
261
|
+
// reject so the request handler hits its try/catch and calls next(error),
|
|
262
|
+
// which lands in the default /mcp error handler.
|
|
263
|
+
vi.spyOn(mcpServer, "connectStatelessTransport").mockRejectedValue(new Error("boom"));
|
|
189
264
|
const httpServer = http.createServer();
|
|
190
|
-
const app = await createApp({ mcpServer
|
|
191
|
-
const { port, server } = await listen(app);
|
|
192
|
-
openServer =
|
|
265
|
+
const app = await createApp({ mcpServer, httpServer });
|
|
266
|
+
const { port, server: httpListening } = await listen(app);
|
|
267
|
+
openServer = httpListening;
|
|
193
268
|
const res = await postMcp(port);
|
|
194
269
|
expect(res.status).toBe(500);
|
|
195
270
|
expect(await res.json()).toEqual({
|
|
@@ -207,14 +282,16 @@ describe("createApp", () => {
|
|
|
207
282
|
calls.push("error-handler");
|
|
208
283
|
res.status(503).json({ custom: true });
|
|
209
284
|
};
|
|
285
|
+
const mcpServer = new McpServer({ name: "t", version: "0.0.0" });
|
|
286
|
+
vi.spyOn(mcpServer, "connectStatelessTransport").mockRejectedValue(new Error("boom"));
|
|
210
287
|
const httpServer = http.createServer();
|
|
211
288
|
const app = await createApp({
|
|
212
|
-
mcpServer
|
|
289
|
+
mcpServer,
|
|
213
290
|
httpServer,
|
|
214
291
|
errorMiddleware: [{ handlers: [errorHandler] }],
|
|
215
292
|
});
|
|
216
|
-
const { port, server } = await listen(app);
|
|
217
|
-
openServer =
|
|
293
|
+
const { port, server: httpListening } = await listen(app);
|
|
294
|
+
openServer = httpListening;
|
|
218
295
|
const res = await postMcp(port);
|
|
219
296
|
expect(calls).toEqual(["error-handler"]);
|
|
220
297
|
expect(res.status).toBe(503);
|
|
@@ -230,15 +307,17 @@ describe("createApp", () => {
|
|
|
230
307
|
const throwingApiRoute = (_req, _res, next) => {
|
|
231
308
|
next(new Error("api error"));
|
|
232
309
|
};
|
|
310
|
+
const mcpServer = new McpServer({ name: "t", version: "0.0.0" });
|
|
311
|
+
vi.spyOn(mcpServer, "connectStatelessTransport").mockRejectedValue(new Error("boom"));
|
|
312
|
+
mcpServer.use("/api/test", throwingApiRoute);
|
|
233
313
|
const httpServer = http.createServer();
|
|
234
314
|
const app = await createApp({
|
|
235
|
-
mcpServer
|
|
315
|
+
mcpServer,
|
|
236
316
|
httpServer,
|
|
237
|
-
customMiddleware: [{ path: "/api/test", handlers: [throwingApiRoute] }],
|
|
238
317
|
errorMiddleware: [{ path: "/mcp", handlers: [mcpErrorHandler] }],
|
|
239
318
|
});
|
|
240
|
-
const { port, server } = await listen(app);
|
|
241
|
-
openServer =
|
|
319
|
+
const { port, server: httpListening } = await listen(app);
|
|
320
|
+
openServer = httpListening;
|
|
242
321
|
const mcpRes = await postMcp(port);
|
|
243
322
|
expect(calls).toEqual(["mcp-error-handler"]);
|
|
244
323
|
expect(mcpRes.status).toBe(503);
|
|
@@ -286,4 +365,66 @@ describe("createApp", () => {
|
|
|
286
365
|
consoleSpy.mockRestore();
|
|
287
366
|
});
|
|
288
367
|
});
|
|
368
|
+
describe("createApp tunnel routes", () => {
|
|
369
|
+
it("proxies POST /__skybridge/tunnel to the cli control server in dev mode", async () => {
|
|
370
|
+
// Stand up a fake control listener that returns a known JSON body.
|
|
371
|
+
const control = http.createServer((_req, res) => {
|
|
372
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
373
|
+
res.end('{"status":"idle"}');
|
|
374
|
+
});
|
|
375
|
+
await new Promise((resolve) => control.listen(0, "127.0.0.1", resolve));
|
|
376
|
+
const controlAddr = control.address();
|
|
377
|
+
if (typeof controlAddr === "string" || controlAddr === null) {
|
|
378
|
+
control.close();
|
|
379
|
+
throw new Error("control server has no address");
|
|
380
|
+
}
|
|
381
|
+
const controlPort = controlAddr.port;
|
|
382
|
+
const prev = process.env.__TUNNEL_CONTROL_PORT;
|
|
383
|
+
process.env.__TUNNEL_CONTROL_PORT = String(controlPort);
|
|
384
|
+
try {
|
|
385
|
+
const { createApp } = await import("./express.js");
|
|
386
|
+
const mcpServer = new McpServer({ name: "t", version: "0.0.0" });
|
|
387
|
+
const httpServer = http.createServer();
|
|
388
|
+
const app = await createApp({ mcpServer, httpServer });
|
|
389
|
+
const { port, server } = await listen(app);
|
|
390
|
+
openServer = server;
|
|
391
|
+
const res = await fetch(`http://localhost:${port}/__skybridge/tunnel`, {
|
|
392
|
+
method: "POST",
|
|
393
|
+
});
|
|
394
|
+
expect(res.status).toBe(200);
|
|
395
|
+
expect(await res.json()).toEqual({ status: "idle" });
|
|
396
|
+
}
|
|
397
|
+
finally {
|
|
398
|
+
if (prev === undefined) {
|
|
399
|
+
delete process.env.__TUNNEL_CONTROL_PORT;
|
|
400
|
+
}
|
|
401
|
+
else {
|
|
402
|
+
process.env.__TUNNEL_CONTROL_PORT = prev;
|
|
403
|
+
}
|
|
404
|
+
await new Promise((resolve) => control.close(() => resolve()));
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
it("does not expose /__skybridge/tunnel in production mode", async () => {
|
|
408
|
+
const prevEnv = process.env.NODE_ENV;
|
|
409
|
+
process.env.NODE_ENV = "production";
|
|
410
|
+
try {
|
|
411
|
+
vi.resetModules();
|
|
412
|
+
const { createApp } = await import("./express.js");
|
|
413
|
+
const { McpServer: ReloadedMcpServer } = await import("./server.js");
|
|
414
|
+
const mcpServer = new ReloadedMcpServer({ name: "t", version: "0.0.0" });
|
|
415
|
+
const httpServer = http.createServer();
|
|
416
|
+
const app = await createApp({ mcpServer, httpServer });
|
|
417
|
+
const { port, server } = await listen(app);
|
|
418
|
+
openServer = server;
|
|
419
|
+
const res = await fetch(`http://localhost:${port}/__skybridge/tunnel`, {
|
|
420
|
+
method: "POST",
|
|
421
|
+
});
|
|
422
|
+
expect(res.status).toBe(404);
|
|
423
|
+
}
|
|
424
|
+
finally {
|
|
425
|
+
process.env.NODE_ENV = prevEnv;
|
|
426
|
+
vi.resetModules();
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
});
|
|
289
430
|
//# sourceMappingURL=express.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express.test.js","sourceRoot":"","sources":["../../src/server/express.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"express.test.js","sourceRoot":"","sources":["../../src/server/express.test.ts"],"names":[],"mappings":"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","sourcesContent":["import http from \"node:http\";\nimport type { ErrorRequestHandler, RequestHandler } from \"express\";\nimport { afterEach, describe, expect, it, vi } from \"vitest\";\nimport { McpServer } from \"./server.js\";\n\nvi.mock(\"@skybridge/devtools\", () => ({\n devtoolsStaticServer: () =>\n ((_req: unknown, _res: unknown, next: () => void) =>\n next()) as RequestHandler,\n}));\n\nvi.mock(\"./viewsDevServer.js\", () => ({\n viewsDevServer: (_httpServer: unknown) =>\n ((_req: unknown, _res: unknown, next: () => void) =>\n next()) as RequestHandler,\n}));\n\nasync function listen(app: Parameters<typeof http.createServer>[1]) {\n const server = http.createServer(app);\n await new Promise<void>((resolve) => server.listen(0, resolve));\n const port = (server.address() as { port: number }).port;\n return { port, server };\n}\n\nlet openServer: http.Server | undefined;\nafterEach(() => openServer?.close());\n\nasync function postMcp(port: number) {\n return fetch(`http://localhost:${port}/mcp`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ jsonrpc: \"2.0\", method: \"initialize\", id: 1 }),\n });\n}\n\nasync function postApi(port: number) {\n return fetch(`http://localhost:${port}/api/test`, { method: \"POST\" });\n}\n\ndescribe(\"McpServer.express\", () => {\n it(\"exposes a ready Express app immediately after construction\", () => {\n const server = new McpServer({ name: \"t\", version: \"0.0.0\" });\n expect(server.express).toBeDefined();\n expect(typeof server.express.use).toBe(\"function\");\n expect(typeof server.express.get).toBe(\"function\");\n });\n\n it(\"server.express.get registers a route reachable alongside /mcp\", async () => {\n const { createApp } = await import(\"./express.js\");\n const server = new McpServer({ name: \"t\", version: \"0.0.0\" });\n server.express.get(\"/health\", (_req, res) => {\n res.json({ status: \"ok\" });\n });\n\n const httpServer = http.createServer();\n await createApp({ mcpServer: server, httpServer });\n const { port, server: listening } = await listen(server.express);\n openServer = listening;\n\n const health = await fetch(`http://localhost:${port}/health`);\n expect(health.status).toBe(200);\n expect(await health.json()).toEqual({ status: \"ok\" });\n\n // /mcp still works (POST returns 200/4xx, not 404)\n const mcp = await postMcp(port);\n expect(mcp.status).not.toBe(404);\n });\n\n it(\"server.use and server.express.use produce the same registration order\", async () => {\n const { createApp } = await import(\"./express.js\");\n const callsA: string[] = [];\n const callsB: string[] = [];\n\n const buildServer = () => new McpServer({ name: \"t\", version: \"0.0.0\" });\n\n const sA = buildServer();\n sA.use((_req, _res, next) => {\n callsA.push(\"first\");\n next();\n });\n sA.express.use((_req, _res, next) => {\n callsA.push(\"second\");\n next();\n });\n\n const sB = buildServer();\n sB.express.use((_req, _res, next) => {\n callsB.push(\"first\");\n next();\n });\n sB.use((_req, _res, next) => {\n callsB.push(\"second\");\n next();\n });\n\n for (const s of [sA, sB]) {\n s.express.get(\"/probe\", (_req, res) => res.json({ ok: true }));\n const httpServer = http.createServer();\n await createApp({ mcpServer: s, httpServer });\n const { port, server: listening } = await listen(s.express);\n openServer = listening;\n await fetch(`http://localhost:${port}/probe`);\n listening.close();\n }\n\n expect(callsA).toEqual([\"first\", \"second\"]);\n expect(callsB).toEqual([\"first\", \"second\"]);\n });\n\n it(\"useOnError still wraps thrown /mcp errors after the route is mounted\", async () => {\n const { createApp } = await import(\"./express.js\");\n const server = new McpServer({ name: \"t\", version: \"0.0.0\" });\n // Register the error handler BEFORE createApp — useOnError should still\n // apply it after /mcp, so /mcp errors hit it.\n const seen: string[] = [];\n server.useOnError((_err, _req, res, _next) => {\n seen.push(\"useOnError\");\n res.status(503).json({ from: \"useOnError\" });\n });\n\n // Force the /mcp handler to throw so the error pipeline runs.\n vi.spyOn(server, \"connectStatelessTransport\").mockRejectedValue(\n new Error(\"boom\"),\n );\n\n const httpServer = http.createServer();\n await createApp({\n mcpServer: server,\n httpServer,\n // Mirror what run() does: forward the McpServer's useOnError handlers\n // to createApp so they get applied after /mcp.\n // biome-ignore lint/complexity/useLiteralKeys: test mirrors run() internals to verify useOnError ordering\n errorMiddleware: server[\"customErrorMiddleware\"],\n });\n const { port, server: listening } = await listen(server.express);\n openServer = listening;\n\n const res = await postMcp(port);\n expect(seen).toEqual([\"useOnError\"]);\n expect(res.status).toBe(503);\n expect(await res.json()).toEqual({ from: \"useOnError\" });\n });\n});\n\ndescribe(\"createApp\", () => {\n it(\"runs global custom middleware before the /mcp handler\", async () => {\n const { createApp } = await import(\"./express.js\");\n const calls: string[] = [];\n\n const mw: RequestHandler = (_req, _res, next) => {\n calls.push(\"custom\");\n next();\n };\n\n const server = new McpServer({ name: \"t\", version: \"0.0.0\" });\n server.use(mw);\n\n const httpServer = http.createServer();\n const app = await createApp({ mcpServer: server, httpServer });\n\n const { port, server: httpListening } = await listen(app);\n openServer = httpListening;\n\n await postMcp(port);\n expect(calls).toEqual([\"custom\"]);\n });\n\n it(\"runs path-scoped middleware on /mcp\", async () => {\n const { createApp } = await import(\"./express.js\");\n const calls: string[] = [];\n\n const mw: RequestHandler = (_req, _res, next) => {\n calls.push(\"auth\");\n next();\n };\n\n const server = new McpServer({ name: \"t\", version: \"0.0.0\" });\n server.use(\"/mcp\", mw);\n\n const httpServer = http.createServer();\n const app = await createApp({ mcpServer: server, httpServer });\n\n const { port, server: httpListening } = await listen(app);\n openServer = httpListening;\n\n await postMcp(port);\n expect(calls).toEqual([\"auth\"]);\n });\n\n it(\"allows middleware to short-circuit with 401\", async () => {\n const { createApp } = await import(\"./express.js\");\n const calls: string[] = [];\n\n const reject: RequestHandler = (_req, res) => {\n calls.push(\"reject\");\n res.status(401).json({ error: \"Unauthorized\" });\n };\n\n const server = new McpServer({ name: \"t\", version: \"0.0.0\" });\n server.use(\"/mcp\", reject);\n\n const httpServer = http.createServer();\n const app = await createApp({ mcpServer: server, httpServer });\n\n const { port, server: httpListening } = await listen(app);\n openServer = httpListening;\n\n const res = await postMcp(port);\n expect(calls).toEqual([\"reject\"]);\n expect(res.status).toBe(401);\n expect(await res.json()).toEqual({ error: \"Unauthorized\" });\n });\n\n it(\"runs multiple global middleware in registration order\", async () => {\n const { createApp } = await import(\"./express.js\");\n const calls: string[] = [];\n\n const mwA: RequestHandler = (_req, _res, next) => {\n calls.push(\"A\");\n next();\n };\n const mwB: RequestHandler = (_req, _res, next) => {\n calls.push(\"B\");\n next();\n };\n\n const server = new McpServer({ name: \"t\", version: \"0.0.0\" });\n server.use(mwA);\n server.use(mwB);\n\n const httpServer = http.createServer();\n const app = await createApp({ mcpServer: server, httpServer });\n\n const { port, server: httpListening } = await listen(app);\n openServer = httpListening;\n\n await postMcp(port);\n expect(calls).toEqual([\"A\", \"B\"]);\n });\n\n it(\"path-scoped middleware does not run on non-matching paths\", async () => {\n const { createApp } = await import(\"./express.js\");\n const calls: string[] = [];\n\n const apiMw: RequestHandler = (_req, _res, next) => {\n calls.push(\"api\");\n next();\n };\n\n const server = new McpServer({ name: \"t\", version: \"0.0.0\" });\n server.use(\"/api\", apiMw);\n\n const httpServer = http.createServer();\n const app = await createApp({ mcpServer: server, httpServer });\n\n const { port, server: httpListening } = await listen(app);\n openServer = httpListening;\n\n // Hit /mcp — the /api middleware should NOT fire\n await postMcp(port);\n expect(calls).toEqual([]);\n });\n\n it(\"supports Express Router via custom middleware\", async () => {\n const { createApp } = await import(\"./express.js\");\n const { Router } = await import(\"express\");\n\n const router = Router();\n router.get(\"/health\", (_req, res) => {\n res.json({ status: \"ok\" });\n });\n\n const server = new McpServer({ name: \"t\", version: \"0.0.0\" });\n server.use(router as RequestHandler);\n\n const httpServer = http.createServer();\n const app = await createApp({ mcpServer: server, httpServer });\n\n const { port, server: httpListening } = await listen(app);\n openServer = httpListening;\n\n const res = await fetch(`http://localhost:${port}/health`);\n expect(res.status).toBe(200);\n expect(await res.json()).toEqual({ status: \"ok\" });\n });\n\n it(\"supports path-prefixed Router\", async () => {\n const { createApp } = await import(\"./express.js\");\n const { Router } = await import(\"express\");\n\n const router = Router();\n router.get(\"/data\", (_req, res) => {\n res.json({ value: 42 });\n });\n\n const server = new McpServer({ name: \"t\", version: \"0.0.0\" });\n server.use(\"/api\", router as RequestHandler);\n\n const httpServer = http.createServer();\n const app = await createApp({ mcpServer: server, httpServer });\n\n const { port, server: httpListening } = await listen(app);\n openServer = httpListening;\n\n const res = await fetch(`http://localhost:${port}/api/data`);\n expect(res.status).toBe(200);\n expect(await res.json()).toEqual({ value: 42 });\n });\n\n it(\"server survives middleware errors without crashing\", async () => {\n const { createApp } = await import(\"./express.js\");\n\n const throwing: RequestHandler = () => {\n throw new Error(\"boom\");\n };\n\n const server = new McpServer({ name: \"t\", version: \"0.0.0\" });\n server.use(\"/explode\", throwing);\n\n const httpServer = http.createServer();\n const app = await createApp({ mcpServer: server, httpServer });\n\n const { port, server: httpListening } = await listen(app);\n openServer = httpListening;\n\n const res = await fetch(`http://localhost:${port}/explode`);\n expect(res.status).toBe(500);\n\n // Server process did not crash — it still accepts connections\n const followUp = await fetch(`http://localhost:${port}/explode`);\n expect(followUp.status).toBe(500);\n });\n\n it(\"returns 500 JSON-RPC error when the MCP handler throws and no error middleware is registered\", async () => {\n const { createApp } = await import(\"./express.js\");\n const consoleSpy = vi.spyOn(console, \"error\").mockImplementation(() => {});\n\n const mcpServer = new McpServer({ name: \"t\", version: \"0.0.0\" });\n // Force the express-level error path: make connectStatelessTransport\n // reject so the request handler hits its try/catch and calls next(error),\n // which lands in the default /mcp error handler.\n vi.spyOn(mcpServer, \"connectStatelessTransport\").mockRejectedValue(\n new Error(\"boom\"),\n );\n\n const httpServer = http.createServer();\n const app = await createApp({ mcpServer, httpServer });\n const { port, server: httpListening } = await listen(app);\n openServer = httpListening;\n\n const res = await postMcp(port);\n expect(res.status).toBe(500);\n expect(await res.json()).toEqual({\n jsonrpc: \"2.0\",\n error: { code: -32603, message: \"Internal server error\" },\n id: null,\n });\n expect(consoleSpy).toHaveBeenCalledWith(\n \"Error handling MCP request:\",\n expect.any(Error),\n );\n consoleSpy.mockRestore();\n });\n\n it(\"invokes a custom error handler when the MCP handler throws\", async () => {\n const { createApp } = await import(\"./express.js\");\n const calls: string[] = [];\n\n const errorHandler: ErrorRequestHandler = (_err, _req, res, _next) => {\n calls.push(\"error-handler\");\n res.status(503).json({ custom: true });\n };\n\n const mcpServer = new McpServer({ name: \"t\", version: \"0.0.0\" });\n vi.spyOn(mcpServer, \"connectStatelessTransport\").mockRejectedValue(\n new Error(\"boom\"),\n );\n\n const httpServer = http.createServer();\n const app = await createApp({\n mcpServer,\n httpServer,\n errorMiddleware: [{ handlers: [errorHandler] }],\n });\n const { port, server: httpListening } = await listen(app);\n openServer = httpListening;\n\n const res = await postMcp(port);\n expect(calls).toEqual([\"error-handler\"]);\n expect(res.status).toBe(503);\n expect(await res.json()).toEqual({ custom: true });\n });\n\n it(\"invokes a path-scoped error handler only for matching routes\", async () => {\n const { createApp } = await import(\"./express.js\");\n const calls: string[] = [];\n\n const mcpErrorHandler: ErrorRequestHandler = (_err, _req, res, _next) => {\n calls.push(\"mcp-error-handler\");\n res.status(503).json({ from: \"mcp-error-handler\" });\n };\n\n const throwingApiRoute: RequestHandler = (_req, _res, next) => {\n next(new Error(\"api error\"));\n };\n\n const mcpServer = new McpServer({ name: \"t\", version: \"0.0.0\" });\n vi.spyOn(mcpServer, \"connectStatelessTransport\").mockRejectedValue(\n new Error(\"boom\"),\n );\n mcpServer.use(\"/api/test\", throwingApiRoute);\n\n const httpServer = http.createServer();\n const app = await createApp({\n mcpServer,\n httpServer,\n errorMiddleware: [{ path: \"/mcp\", handlers: [mcpErrorHandler] }],\n });\n const { port, server: httpListening } = await listen(app);\n openServer = httpListening;\n\n const mcpRes = await postMcp(port);\n expect(calls).toEqual([\"mcp-error-handler\"]);\n expect(mcpRes.status).toBe(503);\n expect(await mcpRes.json()).toEqual({ from: \"mcp-error-handler\" });\n\n const consoleSpy = vi.spyOn(console, \"error\").mockImplementation(() => {});\n const apiRes = await postApi(port);\n expect(calls).toEqual([\"mcp-error-handler\"]);\n expect(apiRes.status).toBe(500);\n consoleSpy.mockRestore();\n });\n\n it(\"handles concurrent /mcp requests without 'Already connected to a transport'\", async () => {\n const { createApp } = await import(\"./express.js\");\n\n const mcpServer = new McpServer({\n name: \"concurrent-test\",\n version: \"0.0.0\",\n });\n // Slow tool: keeps the underlying transport bound long enough to overlap\n // with concurrent requests, exposing the shared-McpServer race.\n mcpServer.registerTool({ name: \"slow\", description: \"slow\" }, async () => {\n await new Promise((r) => setTimeout(r, 50));\n return { content: [{ type: \"text\" as const, text: \"done\" }] };\n });\n\n const consoleSpy = vi.spyOn(console, \"error\").mockImplementation(() => {});\n\n const httpServer = http.createServer();\n const app = await createApp({ mcpServer, httpServer });\n const { port, server } = await listen(app);\n openServer = server;\n\n const callBody = (id: number) =>\n JSON.stringify({\n jsonrpc: \"2.0\",\n method: \"tools/call\",\n id,\n params: { name: \"slow\", arguments: {} },\n });\n\n const N = 10;\n const responses = await Promise.all(\n Array.from({ length: N }, (_, i) =>\n fetch(`http://localhost:${port}/mcp`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json, text/event-stream\",\n },\n body: callBody(i + 1),\n }),\n ),\n );\n\n expect(responses.map((r) => r.status)).toEqual(Array(N).fill(200));\n expect(consoleSpy).not.toHaveBeenCalledWith(\n \"Error handling MCP request:\",\n expect.any(Error),\n );\n consoleSpy.mockRestore();\n });\n});\n\ndescribe(\"createApp tunnel routes\", () => {\n it(\"proxies POST /__skybridge/tunnel to the cli control server in dev mode\", async () => {\n // Stand up a fake control listener that returns a known JSON body.\n const control = http.createServer((_req, res) => {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end('{\"status\":\"idle\"}');\n });\n await new Promise<void>((resolve) =>\n control.listen(0, \"127.0.0.1\", resolve),\n );\n const controlAddr = control.address();\n if (typeof controlAddr === \"string\" || controlAddr === null) {\n control.close();\n throw new Error(\"control server has no address\");\n }\n const controlPort = controlAddr.port;\n\n const prev = process.env.__TUNNEL_CONTROL_PORT;\n process.env.__TUNNEL_CONTROL_PORT = String(controlPort);\n try {\n const { createApp } = await import(\"./express.js\");\n const mcpServer = new McpServer({ name: \"t\", version: \"0.0.0\" });\n const httpServer = http.createServer();\n const app = await createApp({ mcpServer, httpServer });\n const { port, server } = await listen(app);\n openServer = server;\n\n const res = await fetch(`http://localhost:${port}/__skybridge/tunnel`, {\n method: \"POST\",\n });\n expect(res.status).toBe(200);\n expect(await res.json()).toEqual({ status: \"idle\" });\n } finally {\n if (prev === undefined) {\n delete process.env.__TUNNEL_CONTROL_PORT;\n } else {\n process.env.__TUNNEL_CONTROL_PORT = prev;\n }\n await new Promise<void>((resolve) => control.close(() => resolve()));\n }\n });\n\n it(\"does not expose /__skybridge/tunnel in production mode\", async () => {\n const prevEnv = process.env.NODE_ENV;\n process.env.NODE_ENV = \"production\";\n try {\n vi.resetModules();\n const { createApp } = await import(\"./express.js\");\n const { McpServer: ReloadedMcpServer } = await import(\"./server.js\");\n const mcpServer = new ReloadedMcpServer({ name: \"t\", version: \"0.0.0\" });\n const httpServer = http.createServer();\n const app = await createApp({ mcpServer, httpServer });\n const { port, server } = await listen(app);\n openServer = server;\n\n const res = await fetch(`http://localhost:${port}/__skybridge/tunnel`, {\n method: \"POST\",\n });\n expect(res.status).toBe(404);\n } finally {\n process.env.NODE_ENV = prevEnv;\n vi.resetModules();\n }\n });\n});\n"]}
|
package/dist/server/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EACL,gBAAgB,EAChB,KAAK,EACL,YAAY,EACZ,IAAI,GACL,MAAM,sBAAsB,CAAC;AA8B9B,OAAO,EACL,SAAS,EACT,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EACL,gBAAgB,EAChB,KAAK,EACL,YAAY,EACZ,IAAI,GACL,MAAM,sBAAsB,CAAC;AA8B9B,OAAO,EACL,SAAS,EACT,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC","sourcesContent":["export {\n audio,\n embeddedResource,\n image,\n resourceLink,\n text,\n} from \"./content-helpers.js\";\nexport type {\n AnyToolRegistry,\n InferTools,\n ToolInput,\n ToolNames,\n ToolOutput,\n ToolResponseMetadata,\n} from \"./inferUtilityTypes.js\";\nexport type {\n McpExtra,\n McpMethodString,\n McpMiddlewareFilter,\n McpMiddlewareFn,\n McpResultFor,\n McpTypedMiddlewareFn,\n McpWildcard,\n} from \"./middleware.js\";\nexport type {\n HandlerContent,\n KnownToolMeta,\n McpServerTypes,\n ToolDef,\n ToolMeta,\n ViewConfig,\n ViewCsp,\n ViewHostType,\n ViewName,\n ViewNameRegistry,\n} from \"./server.js\";\nexport {\n McpServer,\n normalizeContent,\n} from \"./server.js\";\nexport { viewsDevServer } from \"./viewsDevServer.js\";\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inferUtilityTypes.js","sourceRoot":"","sources":["../../src/server/inferUtilityTypes.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"inferUtilityTypes.js","sourceRoot":"","sources":["../../src/server/inferUtilityTypes.ts"],"names":[],"mappings":"","sourcesContent":["import type { McpServerTypes, ToolDef } from \"./server.js\";\n\n/**\n * Any tool registry shape (includes both views and regular tools).\n * Used as a constraint for type parameters that accept tool registries.\n */\nexport type AnyToolRegistry = Record<string, ToolDef>;\n\n/**\n * Extract the tool registry type from an McpServer instance.\n * This includes both views (registered via view()) and regular tools (registered via registerTool()).\n *\n * Uses the `$types` property pattern for cross-package type inference.\n * This works across package boundaries because TypeScript uses structural typing\n * on the shape of `$types`, rather than nominal typing on the McpServer class itself.\n *\n * @example\n * ```ts\n * type MyTools = InferTools<MyServer>;\n * // { \"search\": ToolDef<...>, \"calculate\": ToolDef<...> }\n * ```\n */\nexport type InferTools<ServerType> = ServerType extends {\n $types: McpServerTypes<infer W>;\n}\n ? W\n : never;\ntype ExtractTool<\n ServerType,\n K extends ToolNames<ServerType>,\n> = InferTools<ServerType>[K];\n\n/**\n * Get a union of all tool names from an McpServer instance.\n * This includes both views and regular tools.\n *\n * @example\n * ```ts\n * type Names = ToolNames<MyServer>;\n * // \"search\" | \"calculate\" | \"details\"\n * ```\n */\nexport type ToolNames<ServerType> = keyof InferTools<ServerType> & string;\n\n/**\n * Get the input type for a specific tool (view or regular tool).\n *\n * @example\n * ```ts\n * type SearchInput = ToolInput<MyServer, \"search\">;\n * ```\n */\nexport type ToolInput<\n ServerType,\n ToolName extends ToolNames<ServerType>,\n> = ExtractTool<ServerType, ToolName>[\"input\"];\n\n/**\n * Get the output type for a specific tool (view or regular tool).\n *\n * @example\n * ```ts\n * type SearchOutput = ToolOutput<MyServer, \"search\">;\n * ```\n */\nexport type ToolOutput<\n ServerType,\n ToolName extends ToolNames<ServerType>,\n> = ExtractTool<ServerType, ToolName>[\"output\"];\n\n/**\n * Get the responseMetadata type for a specific tool (view or regular tool).\n * This is inferred from the `_meta` property of the tool callback's return value.\n *\n * @example\n * ```ts\n * type SearchMeta = ToolResponseMetadata<MyServer, \"search\">;\n * ```\n */\nexport type ToolResponseMetadata<\n ServerType,\n ToolName extends ToolNames<ServerType>,\n> = ExtractTool<ServerType, ToolName>[\"responseMetadata\"];\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metric.js","sourceRoot":"","sources":["../../src/server/metric.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAGxC,SAAS,eAAe,CAAC,OAAe;IACtC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AACnC,CAAC;AAED,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACvC,MAAM,UAAU,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;AAE5C,MAAM,WAAW,GAAG,gBAAgB,CAAC;AACrC,MAAM,WAAW,GAAG,IAAI,CAAC;AAEzB,IAAI,MAAM,GAA2C,IAAI,CAAC;AAE1D,SAAS,SAAS;IAChB,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9B,MAAM,CAAC,KAAK,EAAE,CAAC;IACjB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,UAAU,CAAC,MAAc;IAChC,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO;IACT,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpC,SAAS,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,EAAE;QACvD,qDAAqD;IACvD,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,qBAAqB;IACnC,IAAI,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAoB,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;QAC5D,2EAA2E;QAC3E,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;YACjB,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAED,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,EAAE,CAAC;QACtB,CAAC;gBAAS,CAAC;YACT,UAAU,CAAC,yBAAyB,UAAU,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC;AAC3C,CAAC"}
|
|
1
|
+
{"version":3,"file":"metric.js","sourceRoot":"","sources":["../../src/server/metric.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAGxC,SAAS,eAAe,CAAC,OAAe;IACtC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AACnC,CAAC;AAED,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACvC,MAAM,UAAU,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;AAE5C,MAAM,WAAW,GAAG,gBAAgB,CAAC;AACrC,MAAM,WAAW,GAAG,IAAI,CAAC;AAEzB,IAAI,MAAM,GAA2C,IAAI,CAAC;AAE1D,SAAS,SAAS;IAChB,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9B,MAAM,CAAC,KAAK,EAAE,CAAC;IACjB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,UAAU,CAAC,MAAc;IAChC,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO;IACT,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpC,SAAS,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,EAAE;QACvD,qDAAqD;IACvD,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,qBAAqB;IACnC,IAAI,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAoB,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;QAC5D,2EAA2E;QAC3E,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;YACjB,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAED,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,EAAE,CAAC;QACtB,CAAC;gBAAS,CAAC;YACT,UAAU,CAAC,yBAAyB,UAAU,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC;AAC3C,CAAC","sourcesContent":["import { createSocket } from \"node:dgram\";\nimport { isEnabled } from \"../cli/telemetry.js\";\nimport { VERSION } from \"../version.js\";\nimport type { McpMiddlewareEntry, McpMiddlewareFn } from \"./middleware.js\";\n\nfunction parseMajorMinor(version: string): string | null {\n const parts = version.split(\".\");\n if (parts.length < 2) {\n return null;\n }\n return `${parts[0]}.${parts[1]}`;\n}\n\nconst isDev = VERSION.includes(\"-dev\");\nconst versionTag = parseMajorMinor(VERSION);\n\nconst STATSD_HOST = \"18.208.242.161\";\nconst STATSD_PORT = 8125;\n\nlet socket: ReturnType<typeof createSocket> | null = null;\n\nfunction getSocket() {\n if (!socket) {\n socket = createSocket(\"udp4\");\n socket.unref();\n }\n return socket;\n}\n\nfunction sendMetric(metric: string): void {\n if (!STATSD_HOST) {\n return;\n }\n const payload = Buffer.from(metric);\n getSocket().send(payload, STATSD_PORT, STATSD_HOST, () => {\n // fire-and-forget: errors are intentionally silenced\n });\n}\n\n/**\n * Returns an internal MCP middleware entry that emits a DogStatsD counter over UDP\n * for every tool call. Enabled by default; respects the existing telemetry\n * opt-out (SKYBRIDGE_TELEMETRY_DISABLED, DO_NOT_TRACK, or `skybridge telemetry disable`).\n *\n * Returns `null` when the version string contains \"-dev\" (e.g. development\n * builds) or when the version cannot be parsed into major.minor, so that\n * malformed data does not pollute production metrics.\n *\n * Metric (DogStatsD counter format with tags):\n * Requests:1|c|#version:<major>.<minor> — every tools/call\n */\nexport function createMiddlewareEntry(): McpMiddlewareEntry | null {\n if (isDev || !versionTag) {\n return null;\n }\n\n const handler: McpMiddlewareFn = async (_req, _extra, next) => {\n // Check on every call so opt-out takes effect immediately without restart.\n if (!isEnabled()) {\n return next();\n }\n\n try {\n return await next();\n } finally {\n sendMetric(`Requests:1|c|#version:${versionTag}`);\n }\n };\n\n return { filter: \"tools/call\", handler };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/server/middleware.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/server/middleware.ts"],"names":[],"mappings":"AAyJA;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,MAAM,GAAG,GAAW,MAAM,CAAC;IAE3B,IACE,CAAC,CAAC,kBAAkB,IAAI,GAAG,IAAI,GAAG,CAAC,gBAAgB,YAAY,GAAG,CAAC;QACnE,CAAC,CACC,uBAAuB,IAAI,GAAG,IAAI,GAAG,CAAC,qBAAqB,YAAY,GAAG,CAC3E,EACD,CAAC;QACD,MAAM,IAAI,KAAK,CACb,6FAA6F,CAC9F,CAAC;IACJ,CAAC;IAED,OAAO;QACL,eAAe,EAAE,GAAG,CAAC,gBAA8B;QACnD,oBAAoB,EAAE,GAAG,CAAC,qBAAmC;KAC9D,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAC3B,MAAc,EACd,MAAc,EACd,cAAuB;IAEvB,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,CAAC,cAAc,CAAC;IACzB,CAAC;IACD,IAAI,MAAM,KAAK,cAAc,EAAE,CAAC;QAC9B,OAAO,cAAc,CAAC;IACxB,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,uBAAuB;QAC3D,OAAO,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,MAAM,KAAK,MAAM,CAAC;AAC3B,CAAC;AAED,SAAS,gBAAgB,CACvB,MAAc,EACd,MAAkC,EAClC,cAAuB;IAEvB,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAC7B,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,cAAc,CAAC,CAC/C,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAAc,EACd,cAAuB,EACvB,eAAyD,EACzD,OAA6B;IAE7B,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAC1C,gBAAgB,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,cAAc,CAAC,CACvD,CAAC;IAEF,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,OAAO,CAAC,GAAG,IAAe,EAAE,EAAE;QAC5B,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAwC,CAAC;QAClE,4DAA4D;QAC5D,iEAAiE;QACjE,MAAM,KAAK,GAAG,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAE,IAAI,CAAC,CAAC,CAAc,CAAC;QACjE,MAAM,UAAU,GAAG;YACjB,MAAM;YACN,MAAM,EAAG,UAAU,EAAE,MAAkC,IAAI,EAAE;SAC9D,CAAC;QAEF,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,MAAM,YAAY,GAAG,GAAqB,EAAE;YAC1C,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;YAClC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,IAAI,UAAU,EAAE,CAAC;oBACf,UAAU,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;gBACxC,CAAC;gBACD,OAAO,eAAe,CAAC,GAAG,IAAI,CAAC,CAAC;YAClC,CAAC;YAED,IAAI,UAAU,GAAG,KAAK,CAAC;YAEvB,MAAM,IAAI,GAAG,GAAqB,EAAE;gBAClC,IAAI,UAAU,EAAE,CAAC;oBACf,MAAM,IAAI,KAAK,CACb,mDAAmD,MAAM,GAAG,CAC7D,CAAC;gBACJ,CAAC;gBACD,UAAU,GAAG,IAAI,CAAC;gBAClB,OAAO,YAAY,EAAE,CAAC;YACxB,CAAC,CAAC;YAEF,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;QACjE,CAAC,CAAC;QAEF,OAAO,YAAY,EAAE,CAAC;IACxB,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport type { RequestHandlerExtra } from \"@modelcontextprotocol/sdk/shared/protocol.js\";\nimport type {\n CallToolResult,\n CancelTaskResult,\n ClientNotification,\n ClientRequest,\n CompleteResult,\n EmptyResult,\n GetPromptResult,\n GetTaskPayloadResult,\n GetTaskResult,\n InitializeResult,\n ListPromptsResult,\n ListResourcesResult,\n ListResourceTemplatesResult,\n ListTasksResult,\n ListToolsResult,\n ReadResourceResult,\n ServerNotification,\n ServerRequest,\n ServerResult,\n} from \"@modelcontextprotocol/sdk/types.js\";\n\n/**\n * The `extra` context object provided by the MCP SDK to request handlers.\n */\nexport type McpExtra = RequestHandlerExtra<ServerRequest, ServerNotification>;\n\n/**\n * A single MCP middleware function following the onion model.\n * Call `next()` to invoke the next middleware or the final handler.\n * For notifications, `extra` is `undefined` (SDK does not provide extra context)\n * and `next()` resolves to `undefined`.\n */\nexport type McpMiddlewareFn = (\n request: { method: string; params: Record<string, unknown> },\n extra: McpExtra | undefined,\n next: () => Promise<unknown>,\n) => Promise<unknown> | unknown;\n\n/**\n * MCP methods the server handles (incoming from client).\n */\nexport type McpMethodString =\n | ClientRequest[\"method\"]\n | ClientNotification[\"method\"];\n\n/** Extract params type for a specific MCP method from SDK unions. */\nexport type McpRequestParams<M extends string> =\n Extract<ClientRequest, { method: M }> extends { params: infer P }\n ? P\n : Extract<ClientNotification, { method: M }> extends { params: infer P }\n ? P\n : Record<string, unknown>;\n\n/** Resolve extra type: McpExtra for requests, undefined for notifications. */\nexport type McpExtraFor<M extends string> = M extends ClientRequest[\"method\"]\n ? McpExtra\n : M extends ClientNotification[\"method\"]\n ? undefined\n : McpExtra | undefined;\n\n/** Maps each MCP request method to its SDK result type. */\ninterface McpResultMap {\n ping: EmptyResult;\n initialize: InitializeResult;\n \"tools/list\": ListToolsResult;\n \"tools/call\": CallToolResult;\n \"resources/list\": ListResourcesResult;\n \"resources/templates/list\": ListResourceTemplatesResult;\n \"resources/read\": ReadResourceResult;\n \"resources/subscribe\": EmptyResult;\n \"resources/unsubscribe\": EmptyResult;\n \"prompts/list\": ListPromptsResult;\n \"prompts/get\": GetPromptResult;\n \"completion/complete\": CompleteResult;\n \"logging/setLevel\": EmptyResult;\n \"tasks/get\": GetTaskResult;\n \"tasks/result\": GetTaskPayloadResult;\n \"tasks/list\": ListTasksResult;\n \"tasks/cancel\": CancelTaskResult;\n}\n\n/**\n * Map an MCP method string to its corresponding result type.\n * For request methods, resolves to the specific SDK result type.\n * For wildcard patterns (e.g. `\"tools/*\"`), resolves to the union of matching result types.\n * For notification methods, resolves to `undefined`.\n * For unknown/unmatched methods, falls back to `ServerResult`.\n */\nexport type McpResultFor<M extends string> = M extends keyof McpResultMap\n ? McpResultMap[M]\n : M extends `${infer Prefix}/*`\n ? [McpResultMap[keyof McpResultMap & `${Prefix}/${string}`]] extends [never]\n ? M extends ToWildcard<ClientNotification[\"method\"]>\n ? undefined\n : ServerResult\n : McpResultMap[keyof McpResultMap & `${Prefix}/${string}`]\n : M extends ClientNotification[\"method\"]\n ? undefined\n : ServerResult;\n\n/** Typed middleware fn for a specific method — narrows params, extra, and next() result. */\nexport type McpTypedMiddlewareFn<M extends string> = (\n request: { method: M; params: McpRequestParams<M> },\n extra: McpExtraFor<M>,\n next: () => Promise<McpResultFor<M>>,\n) => Promise<unknown> | unknown;\n\n/** Extracts `\"prefix/*\"` from `\"prefix/anything\"` — distributive over unions. */\ntype ToWildcard<T extends string> = T extends `${infer Prefix}/${string}`\n ? `${Prefix}/*`\n : never;\n\n/** Wildcard prefixes derived from method strings (e.g. `\"tools/*\"` from `\"tools/call\"`). */\nexport type McpWildcard = ToWildcard<McpMethodString>;\n\n/** Category keywords matching all requests or all notifications. */\ntype McpCategory = \"request\" | \"notification\";\n\n/**\n * A single filter pattern for MCP middleware:\n * - Exact method: `\"tools/call\"`\n * - Wildcard: `\"tools/*\"`\n * - Category: `\"request\"` | `\"notification\"`\n * - Escape hatch: arbitrary string via `string & {}`\n */\ntype McpMiddlewareFilterPattern =\n | McpMethodString\n | McpWildcard\n | McpCategory\n | (string & {});\n\n/**\n * Filter determining which MCP methods a middleware applies to.\n * A single pattern or an array of patterns (OR logic).\n */\nexport type McpMiddlewareFilter =\n | McpMiddlewareFilterPattern\n | McpMiddlewareFilterPattern[];\n\n/**\n * Internal entry stored for each registered middleware.\n * `filter: null` means catch-all (matches everything).\n */\nexport type McpMiddlewareEntry = {\n filter: McpMiddlewareFilter | null;\n handler: McpMiddlewareFn;\n};\n\ntype HandlerMap = Map<string, (...args: unknown[]) => Promise<unknown>>;\n\n/**\n * Extract the TS-private `_requestHandlers` and `_notificationHandlers` maps\n * from the SDK's `Server` (extends `Protocol`). These are runtime-accessible\n * but declared `private` in TypeScript.\n *\n * Validates with `instanceof Map` so an incompatible SDK version fails fast\n * instead of silently breaking.\n */\nexport function getHandlerMaps(server: Server) {\n const obj: object = server;\n\n if (\n !(\"_requestHandlers\" in obj && obj._requestHandlers instanceof Map) ||\n !(\n \"_notificationHandlers\" in obj && obj._notificationHandlers instanceof Map\n )\n ) {\n throw new Error(\n \"Incompatible MCP SDK version: expected _requestHandlers and _notificationHandlers on Server\",\n );\n }\n\n return {\n requestHandlers: obj._requestHandlers as HandlerMap,\n notificationHandlers: obj._notificationHandlers as HandlerMap,\n };\n}\n\n/**\n * Check if a single filter pattern matches a given method.\n *\n * - Exact: `\"tools/call\"` matches only `\"tools/call\"`\n * - Wildcard: `\"tools/*\"` matches any method starting with `\"tools/\"`\n * - Category `\"request\"`: matches when `isNotification` is false\n * - Category `\"notification\"`: matches when `isNotification` is true\n */\nexport function matchesFilter(\n method: string,\n filter: string,\n isNotification: boolean,\n): boolean {\n if (filter === \"request\") {\n return !isNotification;\n }\n if (filter === \"notification\") {\n return isNotification;\n }\n if (filter.endsWith(\"/*\")) {\n const prefix = filter.slice(0, -1); // \"tools/*\" → \"tools/\"\n return method.startsWith(prefix);\n }\n return method === filter;\n}\n\nfunction matchesAnyFilter(\n method: string,\n filter: McpMiddlewareFilter | null,\n isNotification: boolean,\n): boolean {\n if (filter === null) {\n return true;\n }\n if (typeof filter === \"string\") {\n return matchesFilter(method, filter, isNotification);\n }\n return filter.some((pattern) =>\n matchesFilter(method, pattern, isNotification),\n );\n}\n\n/**\n * Build an onion-model middleware chain for a specific method.\n *\n * Filters `entries` to those matching `method`, then composes them\n * so the first registered middleware is the outermost layer.\n * `next()` is guarded against multiple calls within a single middleware.\n */\nexport function buildMiddlewareChain(\n method: string,\n isNotification: boolean,\n originalHandler: (...args: unknown[]) => Promise<unknown>,\n entries: McpMiddlewareEntry[],\n) {\n const applicable = entries.filter((entry) =>\n matchesAnyFilter(method, entry.filter, isNotification),\n );\n\n if (applicable.length === 0) {\n return originalHandler;\n }\n\n return (...args: unknown[]) => {\n const rawRequest = args[0] as Record<string, unknown> | undefined;\n // SDK calls request handlers as handler(request, extra) but\n // notification handlers as handler(notification) — no extra arg.\n const extra = isNotification ? undefined : (args[1] as McpExtra);\n const mcpRequest = {\n method,\n params: (rawRequest?.params as Record<string, unknown>) ?? {},\n };\n\n let index = 0;\n\n const executeLayer = (): Promise<unknown> => {\n const entry = applicable[index++];\n if (!entry) {\n if (rawRequest) {\n rawRequest.params = mcpRequest.params;\n }\n return originalHandler(...args);\n }\n\n let nextCalled = false;\n\n const next = (): Promise<unknown> => {\n if (nextCalled) {\n throw new Error(\n `next() called multiple times in middleware for \"${method}\"`,\n );\n }\n nextCalled = true;\n return executeLayer();\n };\n\n return Promise.resolve(entry.handler(mcpRequest, extra, next));\n };\n\n return executeLayer();\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.test-d.js","sourceRoot":"","sources":["../../src/server/middleware.test-d.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"middleware.test-d.js","sourceRoot":"","sources":["../../src/server/middleware.test-d.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n CallToolResult,\n ListToolsResult,\n ServerResult,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { expectTypeOf, test } from \"vitest\";\nimport type {\n McpExtra,\n McpResultFor,\n McpTypedMiddlewareFn,\n} from \"./middleware.js\";\nimport type { McpServer } from \"./server.js\";\n\nconst server = null as unknown as McpServer;\n\ntest(\"request category narrows extra and next() result\", () => {\n server.mcpMiddleware(\"request\", async (_request, extra, next) => {\n expectTypeOf(extra).toEqualTypeOf<McpExtra>();\n extra.signal;\n const result = await next();\n expectTypeOf(result).toEqualTypeOf<ServerResult>();\n return result;\n });\n});\n\ntest(\"notification category narrows extra and next() result\", () => {\n server.mcpMiddleware(\"notification\", async (_request, extra, next) => {\n expectTypeOf(extra).toEqualTypeOf<undefined>();\n // @ts-expect-error extra is undefined, cannot access .signal\n extra.signal;\n const result = await next();\n expectTypeOf(result).toEqualTypeOf<undefined>();\n });\n});\n\ntest(\"exact method tools/call narrows params, extra, and next() result\", () => {\n server.mcpMiddleware(\"tools/call\", async (request, extra, next) => {\n expectTypeOf(request.params.name).toBeString();\n expectTypeOf(extra).toEqualTypeOf<McpExtra>();\n const result = await next();\n expectTypeOf(result).toEqualTypeOf<CallToolResult>();\n return result;\n });\n});\n\ntest(\"exact method tools/list narrows next() to ListToolsResult\", () => {\n server.mcpMiddleware(\"tools/list\", async (_request, _extra, next) => {\n const result = await next();\n expectTypeOf(result).toEqualTypeOf<ListToolsResult>();\n return result;\n });\n});\n\ntest(\"exact notification method narrows extra and next() result\", () => {\n server.mcpMiddleware(\n \"notifications/initialized\",\n async (_request, extra, next) => {\n expectTypeOf(extra).toEqualTypeOf<undefined>();\n // @ts-expect-error extra is undefined\n extra.signal;\n const result = await next();\n expectTypeOf(result).toEqualTypeOf<undefined>();\n },\n );\n});\n\ntest(\"McpTypedMiddlewareFn narrows params, extra, and next() per method\", () => {\n expectTypeOf<\n Parameters<McpTypedMiddlewareFn<\"tools/call\">>[0][\"params\"][\"name\"]\n >().toBeString();\n expectTypeOf<\n Parameters<McpTypedMiddlewareFn<\"tools/call\">>[1]\n >().toEqualTypeOf<McpExtra>();\n expectTypeOf<\n Parameters<McpTypedMiddlewareFn<\"notifications/initialized\">>[1]\n >().toEqualTypeOf<undefined>();\n expectTypeOf<\n ReturnType<Parameters<McpTypedMiddlewareFn<\"tools/list\">>[2]>\n >().toEqualTypeOf<Promise<ListToolsResult>>();\n expectTypeOf<\n ReturnType<Parameters<McpTypedMiddlewareFn<\"notifications/initialized\">>[2]>\n >().toEqualTypeOf<Promise<undefined>>();\n});\n\ntest(\"McpResultFor maps methods to correct result types\", () => {\n expectTypeOf<McpResultFor<\"tools/list\">>().toEqualTypeOf<ListToolsResult>();\n expectTypeOf<McpResultFor<\"tools/call\">>().toEqualTypeOf<CallToolResult>();\n expectTypeOf<\n McpResultFor<\"notifications/initialized\">\n >().toEqualTypeOf<undefined>();\n});\n\ntest(\"wildcard tools/* narrows next() to union of tools result types\", () => {\n server.mcpMiddleware(\"tools/*\", async (_request, _extra, next) => {\n const result = await next();\n expectTypeOf(result).toEqualTypeOf<ListToolsResult | CallToolResult>();\n return result;\n });\n});\n\ntest(\"McpResultFor resolves wildcards to union of matching result types\", () => {\n expectTypeOf<McpResultFor<\"tools/*\">>().toEqualTypeOf<\n ListToolsResult | CallToolResult\n >();\n});\n\ntest(\"catch-all middleware has no narrowing on extra or params\", () => {\n server.mcpMiddleware((_request, extra, next) => {\n expectTypeOf(extra).toEqualTypeOf<McpExtra | undefined>();\n expectTypeOf(_request.params).toEqualTypeOf<Record<string, unknown>>();\n return next();\n });\n});\n"]}
|