skybridge 0.0.0-dev.a13daa8 → 0.0.0-dev.a16f3dc
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -5
- package/dist/commands/dev.d.ts +0 -1
- package/dist/commands/dev.js +0 -6
- package/dist/commands/dev.js.map +1 -1
- package/dist/server/express.d.ts +3 -1
- package/dist/server/express.js +2 -2
- package/dist/server/express.js.map +1 -1
- package/dist/server/express.test.js +7 -1
- package/dist/server/express.test.js.map +1 -1
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/middleware.d.ts +124 -0
- package/dist/server/middleware.js +93 -0
- package/dist/server/middleware.js.map +1 -0
- package/dist/server/middleware.test-d.d.ts +1 -0
- package/dist/server/middleware.test-d.js +75 -0
- package/dist/server/middleware.test-d.js.map +1 -0
- package/dist/server/middleware.test.d.ts +1 -0
- package/dist/server/middleware.test.js +383 -0
- package/dist/server/middleware.test.js.map +1 -0
- package/dist/server/server.d.ts +43 -1
- package/dist/server/server.js +64 -13
- package/dist/server/server.js.map +1 -1
- package/dist/server/widgetsDevServer.d.ts +2 -1
- package/dist/server/widgetsDevServer.js +2 -8
- package/dist/server/widgetsDevServer.js.map +1 -1
- package/dist/test/widget.test.js +11 -10
- package/dist/test/widget.test.js.map +1 -1
- package/dist/web/bridges/mcp-app/adaptor.d.ts +4 -2
- package/dist/web/bridges/mcp-app/adaptor.js +29 -35
- package/dist/web/bridges/mcp-app/adaptor.js.map +1 -1
- package/dist/web/bridges/mcp-app/bridge.d.ts +13 -30
- package/dist/web/bridges/mcp-app/bridge.js +43 -201
- package/dist/web/bridges/mcp-app/bridge.js.map +1 -1
- package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +5 -3
- package/dist/web/bridges/mcp-app/use-mcp-app-context.js +2 -2
- 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 +1 -41
- package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -1
- package/dist/web/create-store.test.js +3 -1
- package/dist/web/create-store.test.js.map +1 -1
- package/dist/web/data-llm.test.js +1 -0
- package/dist/web/data-llm.test.js.map +1 -1
- package/dist/web/hooks/test/utils.js +4 -0
- package/dist/web/hooks/test/utils.js.map +1 -1
- package/dist/web/hooks/use-layout.test.js +3 -3
- package/dist/web/hooks/use-layout.test.js.map +1 -1
- package/dist/web/hooks/use-open-external.test.js +15 -10
- package/dist/web/hooks/use-open-external.test.js.map +1 -1
- package/dist/web/hooks/use-tool-info.test.js +1 -1
- package/dist/web/hooks/use-tool-info.test.js.map +1 -1
- package/dist/web/hooks/use-user.test.js +1 -1
- package/dist/web/hooks/use-user.test.js.map +1 -1
- package/package.json +9 -9
- package/dist/server/const.d.ts +0 -1
- package/dist/server/const.js +0 -2
- package/dist/server/const.js.map +0 -1
package/README.md
CHANGED
|
@@ -120,11 +120,15 @@ Explore production-ready examples:
|
|
|
120
120
|
|
|
121
121
|
| Example | Description | Demo | Code |
|
|
122
122
|
|------------------------|----------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------------------------------|
|
|
123
|
-
| **Capitals Explorer**
|
|
124
|
-
| **Ecommerce Carousel**
|
|
125
|
-
| **Everything**
|
|
126
|
-
| **
|
|
127
|
-
| **
|
|
123
|
+
| **Capitals Explorer** | Interactive world map with geolocation and Wikipedia integration | [Try Demo](https://capitals.skybridge.tech/try) | [View Code](https://github.com/alpic-ai/skybridge/tree/main/examples/capitals) |
|
|
124
|
+
| **Ecommerce Carousel** | Product carousel with cart, localization, and modals | [Try Demo](https://ecommerce.skybridge.tech/try) | [View Code](https://github.com/alpic-ai/skybridge/tree/main/examples/ecom-carousel) |
|
|
125
|
+
| **Everything** | Comprehensive playground showcasing all hooks and features | [Try Demo](https://everything.skybridge.tech/try) | [View Code](https://github.com/alpic-ai/skybridge/tree/main/examples/everything) |
|
|
126
|
+
| **Investigation Game** | Interactive murder mystery game with multi-screen gameplay and dynamic story progression | [Try Demo](https://investigation-game.skybridge.tech/try) | [View Code](https://github.com/alpic-ai/skybridge/tree/main/examples/investigation-game) |
|
|
127
|
+
| **Productivity** | Data visualization dashboard demonstrating Skybridge capabilities for MCP Apps | [Try Demo](https://productivity.skybridge.tech/try) | [View Code](https://github.com/alpic-ai/skybridge/tree/main/examples/productivity) |
|
|
128
|
+
| **Time's Up** | Word-guessing party game where the user gives hints and the AI tries to guess the secret word | [Try Demo](https://times-up.skybridge.tech/try) | [View Code](https://github.com/alpic-ai/skybridge/tree/main/examples/times-up) |
|
|
129
|
+
| **Auth — Clerk** | Full OAuth authentication with Clerk and personalized coffee shop search | — | [View Code](https://github.com/alpic-ai/skybridge/tree/main/examples/auth-clerk) |
|
|
130
|
+
| **Auth — WorkOS AuthKit** | Full OAuth authentication with WorkOS AuthKit and personalized coffee shop search | — | [View Code](https://github.com/alpic-ai/skybridge/tree/main/examples/auth-workos) |
|
|
131
|
+
| **Manifest Starter** | Starter app with Manifest UI agentic components out-of-the-box | [Try Demo](https://manifest-ui.skybridge.tech/try) | [View Code](https://github.com/alpic-ai/skybridge/tree/main/examples/manifest-ui) |
|
|
128
132
|
|
|
129
133
|
See all examples in the [Showcase](https://docs.skybridge.tech/showcase) or browse the [examples/](examples/) directory.
|
|
130
134
|
|
package/dist/commands/dev.d.ts
CHANGED
|
@@ -4,7 +4,6 @@ export default class Dev extends Command {
|
|
|
4
4
|
static examples: string[];
|
|
5
5
|
static flags: {
|
|
6
6
|
port: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
-
"use-forwarded-host": import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
7
|
};
|
|
9
8
|
run(): Promise<void>;
|
|
10
9
|
}
|
package/dist/commands/dev.js
CHANGED
|
@@ -14,9 +14,6 @@ export default class Dev extends Command {
|
|
|
14
14
|
description: "Port to run the server on",
|
|
15
15
|
min: 1,
|
|
16
16
|
}),
|
|
17
|
-
"use-forwarded-host": Flags.boolean({
|
|
18
|
-
description: "Uses the forwarded host header to construct widget URLs instead of localhost, useful when accessing the dev server through a tunnel (e.g., ngrok)",
|
|
19
|
-
}),
|
|
20
17
|
};
|
|
21
18
|
async run() {
|
|
22
19
|
const { flags } = await this.parse(Dev);
|
|
@@ -27,9 +24,6 @@ export default class Dev extends Command {
|
|
|
27
24
|
const env = {
|
|
28
25
|
...process.env,
|
|
29
26
|
__PORT: String(port),
|
|
30
|
-
...(flags["use-forwarded-host"]
|
|
31
|
-
? { SKYBRIDGE_USE_FORWARDED_HOST: "true" }
|
|
32
|
-
: {}),
|
|
33
27
|
};
|
|
34
28
|
const App = () => {
|
|
35
29
|
const tsErrors = useTypeScriptCheck();
|
package/dist/commands/dev.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEpE,MAAM,CAAC,OAAO,OAAO,GAAI,SAAQ,OAAO;IACtC,MAAM,CAAU,WAAW,GAAG,0BAA0B,CAAC;IACzD,MAAM,CAAU,QAAQ,GAAG,CAAC,WAAW,CAAC,CAAC;IACzC,MAAM,CAAU,KAAK,GAAG;QACtB,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC;YAClB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,2BAA2B;YACxC,GAAG,EAAE,CAAC;SACP,CAAC;
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.tsx"],"names":[],"mappings":"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"}
|
package/dist/server/express.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import type http from "node:http";
|
|
1
2
|
import express from "express";
|
|
2
3
|
import type { McpServer } from "./server";
|
|
3
|
-
export declare function createServer({ server, customMiddleware, }: {
|
|
4
|
+
export declare function createServer({ server, httpServer, customMiddleware, }: {
|
|
4
5
|
server: McpServer;
|
|
6
|
+
httpServer: http.Server;
|
|
5
7
|
customMiddleware?: {
|
|
6
8
|
path?: string;
|
|
7
9
|
handlers: express.RequestHandler[];
|
package/dist/server/express.js
CHANGED
|
@@ -2,7 +2,7 @@ import path from "node:path";
|
|
|
2
2
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
3
3
|
import cors from "cors";
|
|
4
4
|
import express from "express";
|
|
5
|
-
export async function createServer({ server, customMiddleware = [], }) {
|
|
5
|
+
export async function createServer({ server, httpServer, customMiddleware = [], }) {
|
|
6
6
|
const app = express();
|
|
7
7
|
app.use(express.json());
|
|
8
8
|
const env = process.env.NODE_ENV || "development";
|
|
@@ -18,7 +18,7 @@ export async function createServer({ server, customMiddleware = [], }) {
|
|
|
18
18
|
const { devtoolsStaticServer } = await import("@skybridge/devtools");
|
|
19
19
|
app.use(await devtoolsStaticServer());
|
|
20
20
|
const { widgetsDevServer } = await import("./widgetsDevServer.js");
|
|
21
|
-
app.use(await widgetsDevServer());
|
|
21
|
+
app.use(await widgetsDevServer(httpServer));
|
|
22
22
|
}
|
|
23
23
|
if (env === "production") {
|
|
24
24
|
const assetsPath = path.join(process.cwd(), "dist", "assets");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express.js","sourceRoot":"","sources":["../../src/server/express.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"express.js","sourceRoot":"","sources":["../../src/server/express.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ vi.mock("@skybridge/devtools", () => ({
|
|
|
4
4
|
devtoolsStaticServer: () => ((_req, _res, next) => next()),
|
|
5
5
|
}));
|
|
6
6
|
vi.mock("./widgetsDevServer.js", () => ({
|
|
7
|
-
widgetsDevServer: () => ((_req, _res, next) => next()),
|
|
7
|
+
widgetsDevServer: (_httpServer) => ((_req, _res, next) => next()),
|
|
8
8
|
}));
|
|
9
9
|
const fakeServer = {};
|
|
10
10
|
async function listen(app) {
|
|
@@ -30,8 +30,10 @@ describe("createServer", () => {
|
|
|
30
30
|
calls.push("custom");
|
|
31
31
|
next();
|
|
32
32
|
};
|
|
33
|
+
const httpServer = http.createServer();
|
|
33
34
|
const app = await createServer({
|
|
34
35
|
server: fakeServer,
|
|
36
|
+
httpServer,
|
|
35
37
|
customMiddleware: [{ handlers: [mw] }],
|
|
36
38
|
});
|
|
37
39
|
const { port, server } = await listen(app);
|
|
@@ -46,8 +48,10 @@ describe("createServer", () => {
|
|
|
46
48
|
calls.push("auth");
|
|
47
49
|
next();
|
|
48
50
|
};
|
|
51
|
+
const httpServer = http.createServer();
|
|
49
52
|
const app = await createServer({
|
|
50
53
|
server: fakeServer,
|
|
54
|
+
httpServer,
|
|
51
55
|
customMiddleware: [{ path: "/mcp", handlers: [mw] }],
|
|
52
56
|
});
|
|
53
57
|
const { port, server } = await listen(app);
|
|
@@ -60,8 +64,10 @@ describe("createServer", () => {
|
|
|
60
64
|
const reject = (_req, res) => {
|
|
61
65
|
res.status(401).json({ error: "Unauthorized" });
|
|
62
66
|
};
|
|
67
|
+
const httpServer = http.createServer();
|
|
63
68
|
const app = await createServer({
|
|
64
69
|
server: fakeServer,
|
|
70
|
+
httpServer,
|
|
65
71
|
customMiddleware: [{ path: "/mcp", handlers: [reject] }],
|
|
66
72
|
});
|
|
67
73
|
const { port, server } = await listen(app);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express.test.js","sourceRoot":"","sources":["../../src/server/express.test.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAG7D,EAAE,CAAC,IAAI,CAAC,qBAAqB,EAAE,GAAG,EAAE,CAAC,CAAC;IACpC,oBAAoB,EAAE,GAAG,EAAE,CACzB,CAAC,CAAC,IAAa,EAAE,IAAa,EAAE,IAAgB,EAAE,EAAE,CAClD,IAAI,EAAE,CAAmB;CAC9B,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,uBAAuB,EAAE,GAAG,EAAE,CAAC,CAAC;IACtC,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"express.test.js","sourceRoot":"","sources":["../../src/server/express.test.ts"],"names":[],"mappings":"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"}
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export type { AnyToolRegistry, InferTools, ToolInput, ToolNames, ToolOutput, ToolResponseMetadata, } from "./inferUtilityTypes.js";
|
|
2
|
+
export type { McpExtra, McpMethodString, McpMiddlewareFilter, McpMiddlewareFn, McpResultFor, McpTypedMiddlewareFn, McpWildcard, } from "./middleware.js";
|
|
2
3
|
export type { McpServerTypes, ToolDef, WidgetHostType } from "./server.js";
|
|
3
4
|
export { McpServer } from "./server.js";
|
|
4
5
|
export { widgetsDevServer } from "./widgetsDevServer.js";
|
package/dist/server/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import type { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
2
|
+
import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
|
|
3
|
+
import type { CallToolResult, CancelTaskResult, ClientNotification, ClientRequest, CompleteResult, EmptyResult, GetPromptResult, GetTaskPayloadResult, GetTaskResult, InitializeResult, ListPromptsResult, ListResourcesResult, ListResourceTemplatesResult, ListTasksResult, ListToolsResult, ReadResourceResult, ServerNotification, ServerRequest, ServerResult } from "@modelcontextprotocol/sdk/types.js";
|
|
4
|
+
/**
|
|
5
|
+
* The `extra` context object provided by the MCP SDK to request handlers.
|
|
6
|
+
*/
|
|
7
|
+
export type McpExtra = RequestHandlerExtra<ServerRequest, ServerNotification>;
|
|
8
|
+
/**
|
|
9
|
+
* A single MCP middleware function following the onion model.
|
|
10
|
+
* Call `next()` to invoke the next middleware or the final handler.
|
|
11
|
+
* For notifications, `extra` is `undefined` (SDK does not provide extra context)
|
|
12
|
+
* and `next()` resolves to `undefined`.
|
|
13
|
+
*/
|
|
14
|
+
export type McpMiddlewareFn = (request: {
|
|
15
|
+
method: string;
|
|
16
|
+
params: Record<string, unknown>;
|
|
17
|
+
}, extra: McpExtra | undefined, next: () => Promise<unknown>) => Promise<unknown> | unknown;
|
|
18
|
+
/**
|
|
19
|
+
* MCP methods the server handles (incoming from client).
|
|
20
|
+
*/
|
|
21
|
+
export type McpMethodString = ClientRequest["method"] | ClientNotification["method"];
|
|
22
|
+
/** Extract params type for a specific MCP method from SDK unions. */
|
|
23
|
+
export type McpRequestParams<M extends string> = Extract<ClientRequest, {
|
|
24
|
+
method: M;
|
|
25
|
+
}> extends {
|
|
26
|
+
params: infer P;
|
|
27
|
+
} ? P : Extract<ClientNotification, {
|
|
28
|
+
method: M;
|
|
29
|
+
}> extends {
|
|
30
|
+
params: infer P;
|
|
31
|
+
} ? P : Record<string, unknown>;
|
|
32
|
+
/** Resolve extra type: McpExtra for requests, undefined for notifications. */
|
|
33
|
+
export type McpExtraFor<M extends string> = M extends ClientRequest["method"] ? McpExtra : M extends ClientNotification["method"] ? undefined : McpExtra | undefined;
|
|
34
|
+
/** Maps each MCP request method to its SDK result type. */
|
|
35
|
+
interface McpResultMap {
|
|
36
|
+
ping: EmptyResult;
|
|
37
|
+
initialize: InitializeResult;
|
|
38
|
+
"tools/list": ListToolsResult;
|
|
39
|
+
"tools/call": CallToolResult;
|
|
40
|
+
"resources/list": ListResourcesResult;
|
|
41
|
+
"resources/templates/list": ListResourceTemplatesResult;
|
|
42
|
+
"resources/read": ReadResourceResult;
|
|
43
|
+
"resources/subscribe": EmptyResult;
|
|
44
|
+
"resources/unsubscribe": EmptyResult;
|
|
45
|
+
"prompts/list": ListPromptsResult;
|
|
46
|
+
"prompts/get": GetPromptResult;
|
|
47
|
+
"completion/complete": CompleteResult;
|
|
48
|
+
"logging/setLevel": EmptyResult;
|
|
49
|
+
"tasks/get": GetTaskResult;
|
|
50
|
+
"tasks/result": GetTaskPayloadResult;
|
|
51
|
+
"tasks/list": ListTasksResult;
|
|
52
|
+
"tasks/cancel": CancelTaskResult;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Map an MCP method string to its corresponding result type.
|
|
56
|
+
* For request methods, resolves to the specific SDK result type.
|
|
57
|
+
* For wildcard patterns (e.g. `"tools/*"`), resolves to the union of matching result types.
|
|
58
|
+
* For notification methods, resolves to `undefined`.
|
|
59
|
+
* For unknown/unmatched methods, falls back to `ServerResult`.
|
|
60
|
+
*/
|
|
61
|
+
export type McpResultFor<M extends string> = M extends keyof McpResultMap ? McpResultMap[M] : M extends `${infer Prefix}/*` ? [McpResultMap[keyof McpResultMap & `${Prefix}/${string}`]] extends [never] ? M extends ToWildcard<ClientNotification["method"]> ? undefined : ServerResult : McpResultMap[keyof McpResultMap & `${Prefix}/${string}`] : M extends ClientNotification["method"] ? undefined : ServerResult;
|
|
62
|
+
/** Typed middleware fn for a specific method — narrows params, extra, and next() result. */
|
|
63
|
+
export type McpTypedMiddlewareFn<M extends string> = (request: {
|
|
64
|
+
method: M;
|
|
65
|
+
params: McpRequestParams<M>;
|
|
66
|
+
}, extra: McpExtraFor<M>, next: () => Promise<McpResultFor<M>>) => Promise<unknown> | unknown;
|
|
67
|
+
/** Extracts `"prefix/*"` from `"prefix/anything"` — distributive over unions. */
|
|
68
|
+
type ToWildcard<T extends string> = T extends `${infer Prefix}/${string}` ? `${Prefix}/*` : never;
|
|
69
|
+
/** Wildcard prefixes derived from method strings (e.g. `"tools/*"` from `"tools/call"`). */
|
|
70
|
+
export type McpWildcard = ToWildcard<McpMethodString>;
|
|
71
|
+
/** Category keywords matching all requests or all notifications. */
|
|
72
|
+
type McpCategory = "request" | "notification";
|
|
73
|
+
/**
|
|
74
|
+
* A single filter pattern for MCP middleware:
|
|
75
|
+
* - Exact method: `"tools/call"`
|
|
76
|
+
* - Wildcard: `"tools/*"`
|
|
77
|
+
* - Category: `"request"` | `"notification"`
|
|
78
|
+
* - Escape hatch: arbitrary string via `string & {}`
|
|
79
|
+
*/
|
|
80
|
+
type McpMiddlewareFilterPattern = McpMethodString | McpWildcard | McpCategory | (string & {});
|
|
81
|
+
/**
|
|
82
|
+
* Filter determining which MCP methods a middleware applies to.
|
|
83
|
+
* A single pattern or an array of patterns (OR logic).
|
|
84
|
+
*/
|
|
85
|
+
export type McpMiddlewareFilter = McpMiddlewareFilterPattern | McpMiddlewareFilterPattern[];
|
|
86
|
+
/**
|
|
87
|
+
* Internal entry stored for each registered middleware.
|
|
88
|
+
* `filter: null` means catch-all (matches everything).
|
|
89
|
+
*/
|
|
90
|
+
export type McpMiddlewareEntry = {
|
|
91
|
+
filter: McpMiddlewareFilter | null;
|
|
92
|
+
handler: McpMiddlewareFn;
|
|
93
|
+
};
|
|
94
|
+
type HandlerMap = Map<string, (...args: unknown[]) => Promise<unknown>>;
|
|
95
|
+
/**
|
|
96
|
+
* Extract the TS-private `_requestHandlers` and `_notificationHandlers` maps
|
|
97
|
+
* from the SDK's `Server` (extends `Protocol`). These are runtime-accessible
|
|
98
|
+
* but declared `private` in TypeScript.
|
|
99
|
+
*
|
|
100
|
+
* Validates with `instanceof Map` so an incompatible SDK version fails fast
|
|
101
|
+
* instead of silently breaking.
|
|
102
|
+
*/
|
|
103
|
+
export declare function getHandlerMaps(server: Server): {
|
|
104
|
+
requestHandlers: HandlerMap;
|
|
105
|
+
notificationHandlers: HandlerMap;
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* Check if a single filter pattern matches a given method.
|
|
109
|
+
*
|
|
110
|
+
* - Exact: `"tools/call"` matches only `"tools/call"`
|
|
111
|
+
* - Wildcard: `"tools/*"` matches any method starting with `"tools/"`
|
|
112
|
+
* - Category `"request"`: matches when `isNotification` is false
|
|
113
|
+
* - Category `"notification"`: matches when `isNotification` is true
|
|
114
|
+
*/
|
|
115
|
+
export declare function matchesFilter(method: string, filter: string, isNotification: boolean): boolean;
|
|
116
|
+
/**
|
|
117
|
+
* Build an onion-model middleware chain for a specific method.
|
|
118
|
+
*
|
|
119
|
+
* Filters `entries` to those matching `method`, then composes them
|
|
120
|
+
* so the first registered middleware is the outermost layer.
|
|
121
|
+
* `next()` is guarded against multiple calls within a single middleware.
|
|
122
|
+
*/
|
|
123
|
+
export declare function buildMiddlewareChain(method: string, isNotification: boolean, originalHandler: (...args: unknown[]) => Promise<unknown>, entries: McpMiddlewareEntry[]): (...args: unknown[]) => Promise<unknown>;
|
|
124
|
+
export {};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract the TS-private `_requestHandlers` and `_notificationHandlers` maps
|
|
3
|
+
* from the SDK's `Server` (extends `Protocol`). These are runtime-accessible
|
|
4
|
+
* but declared `private` in TypeScript.
|
|
5
|
+
*
|
|
6
|
+
* Validates with `instanceof Map` so an incompatible SDK version fails fast
|
|
7
|
+
* instead of silently breaking.
|
|
8
|
+
*/
|
|
9
|
+
export function getHandlerMaps(server) {
|
|
10
|
+
const obj = server;
|
|
11
|
+
if (!("_requestHandlers" in obj && obj._requestHandlers instanceof Map) ||
|
|
12
|
+
!("_notificationHandlers" in obj && obj._notificationHandlers instanceof Map)) {
|
|
13
|
+
throw new Error("Incompatible MCP SDK version: expected _requestHandlers and _notificationHandlers on Server");
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
requestHandlers: obj._requestHandlers,
|
|
17
|
+
notificationHandlers: obj._notificationHandlers,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Check if a single filter pattern matches a given method.
|
|
22
|
+
*
|
|
23
|
+
* - Exact: `"tools/call"` matches only `"tools/call"`
|
|
24
|
+
* - Wildcard: `"tools/*"` matches any method starting with `"tools/"`
|
|
25
|
+
* - Category `"request"`: matches when `isNotification` is false
|
|
26
|
+
* - Category `"notification"`: matches when `isNotification` is true
|
|
27
|
+
*/
|
|
28
|
+
export function matchesFilter(method, filter, isNotification) {
|
|
29
|
+
if (filter === "request") {
|
|
30
|
+
return !isNotification;
|
|
31
|
+
}
|
|
32
|
+
if (filter === "notification") {
|
|
33
|
+
return isNotification;
|
|
34
|
+
}
|
|
35
|
+
if (filter.endsWith("/*")) {
|
|
36
|
+
const prefix = filter.slice(0, -1); // "tools/*" → "tools/"
|
|
37
|
+
return method.startsWith(prefix);
|
|
38
|
+
}
|
|
39
|
+
return method === filter;
|
|
40
|
+
}
|
|
41
|
+
function matchesAnyFilter(method, filter, isNotification) {
|
|
42
|
+
if (filter === null) {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
if (typeof filter === "string") {
|
|
46
|
+
return matchesFilter(method, filter, isNotification);
|
|
47
|
+
}
|
|
48
|
+
return filter.some((pattern) => matchesFilter(method, pattern, isNotification));
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Build an onion-model middleware chain for a specific method.
|
|
52
|
+
*
|
|
53
|
+
* Filters `entries` to those matching `method`, then composes them
|
|
54
|
+
* so the first registered middleware is the outermost layer.
|
|
55
|
+
* `next()` is guarded against multiple calls within a single middleware.
|
|
56
|
+
*/
|
|
57
|
+
export function buildMiddlewareChain(method, isNotification, originalHandler, entries) {
|
|
58
|
+
const applicable = entries.filter((entry) => matchesAnyFilter(method, entry.filter, isNotification));
|
|
59
|
+
if (applicable.length === 0) {
|
|
60
|
+
return originalHandler;
|
|
61
|
+
}
|
|
62
|
+
return (...args) => {
|
|
63
|
+
const rawRequest = args[0];
|
|
64
|
+
// SDK calls request handlers as handler(request, extra) but
|
|
65
|
+
// notification handlers as handler(notification) — no extra arg.
|
|
66
|
+
const extra = isNotification ? undefined : args[1];
|
|
67
|
+
const mcpRequest = {
|
|
68
|
+
method,
|
|
69
|
+
params: rawRequest?.params ?? {},
|
|
70
|
+
};
|
|
71
|
+
let index = 0;
|
|
72
|
+
const executeLayer = () => {
|
|
73
|
+
const entry = applicable[index++];
|
|
74
|
+
if (!entry) {
|
|
75
|
+
if (rawRequest) {
|
|
76
|
+
rawRequest.params = mcpRequest.params;
|
|
77
|
+
}
|
|
78
|
+
return originalHandler(...args);
|
|
79
|
+
}
|
|
80
|
+
let nextCalled = false;
|
|
81
|
+
const next = () => {
|
|
82
|
+
if (nextCalled) {
|
|
83
|
+
throw new Error(`next() called multiple times in middleware for "${method}"`);
|
|
84
|
+
}
|
|
85
|
+
nextCalled = true;
|
|
86
|
+
return executeLayer();
|
|
87
|
+
};
|
|
88
|
+
return Promise.resolve(entry.handler(mcpRequest, extra, next));
|
|
89
|
+
};
|
|
90
|
+
return executeLayer();
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/server/middleware.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { expectTypeOf, test } from "vitest";
|
|
2
|
+
const server = null;
|
|
3
|
+
test("request category narrows extra and next() result", () => {
|
|
4
|
+
server.mcpMiddleware("request", async (_request, extra, next) => {
|
|
5
|
+
expectTypeOf(extra).toEqualTypeOf();
|
|
6
|
+
extra.signal;
|
|
7
|
+
const result = await next();
|
|
8
|
+
expectTypeOf(result).toEqualTypeOf();
|
|
9
|
+
return result;
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
test("notification category narrows extra and next() result", () => {
|
|
13
|
+
server.mcpMiddleware("notification", async (_request, extra, next) => {
|
|
14
|
+
expectTypeOf(extra).toEqualTypeOf();
|
|
15
|
+
// @ts-expect-error extra is undefined, cannot access .signal
|
|
16
|
+
extra.signal;
|
|
17
|
+
const result = await next();
|
|
18
|
+
expectTypeOf(result).toEqualTypeOf();
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
test("exact method tools/call narrows params, extra, and next() result", () => {
|
|
22
|
+
server.mcpMiddleware("tools/call", async (request, extra, next) => {
|
|
23
|
+
expectTypeOf(request.params.name).toBeString();
|
|
24
|
+
expectTypeOf(extra).toEqualTypeOf();
|
|
25
|
+
const result = await next();
|
|
26
|
+
expectTypeOf(result).toEqualTypeOf();
|
|
27
|
+
return result;
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
test("exact method tools/list narrows next() to ListToolsResult", () => {
|
|
31
|
+
server.mcpMiddleware("tools/list", async (_request, _extra, next) => {
|
|
32
|
+
const result = await next();
|
|
33
|
+
expectTypeOf(result).toEqualTypeOf();
|
|
34
|
+
return result;
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
test("exact notification method narrows extra and next() result", () => {
|
|
38
|
+
server.mcpMiddleware("notifications/initialized", async (_request, extra, next) => {
|
|
39
|
+
expectTypeOf(extra).toEqualTypeOf();
|
|
40
|
+
// @ts-expect-error extra is undefined
|
|
41
|
+
extra.signal;
|
|
42
|
+
const result = await next();
|
|
43
|
+
expectTypeOf(result).toEqualTypeOf();
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
test("McpTypedMiddlewareFn narrows params, extra, and next() per method", () => {
|
|
47
|
+
expectTypeOf().toBeString();
|
|
48
|
+
expectTypeOf().toEqualTypeOf();
|
|
49
|
+
expectTypeOf().toEqualTypeOf();
|
|
50
|
+
expectTypeOf().toEqualTypeOf();
|
|
51
|
+
expectTypeOf().toEqualTypeOf();
|
|
52
|
+
});
|
|
53
|
+
test("McpResultFor maps methods to correct result types", () => {
|
|
54
|
+
expectTypeOf().toEqualTypeOf();
|
|
55
|
+
expectTypeOf().toEqualTypeOf();
|
|
56
|
+
expectTypeOf().toEqualTypeOf();
|
|
57
|
+
});
|
|
58
|
+
test("wildcard tools/* narrows next() to union of tools result types", () => {
|
|
59
|
+
server.mcpMiddleware("tools/*", async (_request, _extra, next) => {
|
|
60
|
+
const result = await next();
|
|
61
|
+
expectTypeOf(result).toEqualTypeOf();
|
|
62
|
+
return result;
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
test("McpResultFor resolves wildcards to union of matching result types", () => {
|
|
66
|
+
expectTypeOf().toEqualTypeOf();
|
|
67
|
+
});
|
|
68
|
+
test("catch-all middleware has no narrowing on extra or params", () => {
|
|
69
|
+
server.mcpMiddleware((_request, extra, next) => {
|
|
70
|
+
expectTypeOf(extra).toEqualTypeOf();
|
|
71
|
+
expectTypeOf(_request.params).toEqualTypeOf();
|
|
72
|
+
return next();
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
//# sourceMappingURL=middleware.test-d.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.test-d.js","sourceRoot":"","sources":["../../src/server/middleware.test-d.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAQ5C,MAAM,MAAM,GAAG,IAA4B,CAAC;AAE5C,IAAI,CAAC,kDAAkD,EAAE,GAAG,EAAE;IAC5D,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAC9D,YAAY,CAAC,KAAK,CAAC,CAAC,aAAa,EAAY,CAAC;QAC9C,KAAK,CAAC,MAAM,CAAC;QACb,MAAM,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;QAC5B,YAAY,CAAC,MAAM,CAAC,CAAC,aAAa,EAAgB,CAAC;QACnD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,uDAAuD,EAAE,GAAG,EAAE;IACjE,MAAM,CAAC,aAAa,CAAC,cAAc,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACnE,YAAY,CAAC,KAAK,CAAC,CAAC,aAAa,EAAa,CAAC;QAC/C,6DAA6D;QAC7D,KAAK,CAAC,MAAM,CAAC;QACb,MAAM,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;QAC5B,YAAY,CAAC,MAAM,CAAC,CAAC,aAAa,EAAa,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kEAAkE,EAAE,GAAG,EAAE;IAC5E,MAAM,CAAC,aAAa,CAAC,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAChE,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;QAC/C,YAAY,CAAC,KAAK,CAAC,CAAC,aAAa,EAAY,CAAC;QAC9C,MAAM,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;QAC5B,YAAY,CAAC,MAAM,CAAC,CAAC,aAAa,EAAkB,CAAC;QACrD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,2DAA2D,EAAE,GAAG,EAAE;IACrE,MAAM,CAAC,aAAa,CAAC,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;QAClE,MAAM,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;QAC5B,YAAY,CAAC,MAAM,CAAC,CAAC,aAAa,EAAmB,CAAC;QACtD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,2DAA2D,EAAE,GAAG,EAAE;IACrE,MAAM,CAAC,aAAa,CAClB,2BAA2B,EAC3B,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAC9B,YAAY,CAAC,KAAK,CAAC,CAAC,aAAa,EAAa,CAAC;QAC/C,sCAAsC;QACtC,KAAK,CAAC,MAAM,CAAC;QACb,MAAM,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;QAC5B,YAAY,CAAC,MAAM,CAAC,CAAC,aAAa,EAAa,CAAC;IAClD,CAAC,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,mEAAmE,EAAE,GAAG,EAAE;IAC7E,YAAY,EAET,CAAC,UAAU,EAAE,CAAC;IACjB,YAAY,EAET,CAAC,aAAa,EAAY,CAAC;IAC9B,YAAY,EAET,CAAC,aAAa,EAAa,CAAC;IAC/B,YAAY,EAET,CAAC,aAAa,EAA4B,CAAC;IAC9C,YAAY,EAET,CAAC,aAAa,EAAsB,CAAC;AAC1C,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,mDAAmD,EAAE,GAAG,EAAE;IAC7D,YAAY,EAA8B,CAAC,aAAa,EAAmB,CAAC;IAC5E,YAAY,EAA8B,CAAC,aAAa,EAAkB,CAAC;IAC3E,YAAY,EAET,CAAC,aAAa,EAAa,CAAC;AACjC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,gEAAgE,EAAE,GAAG,EAAE;IAC1E,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;QAC/D,MAAM,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;QAC5B,YAAY,CAAC,MAAM,CAAC,CAAC,aAAa,EAAoC,CAAC;QACvE,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,mEAAmE,EAAE,GAAG,EAAE;IAC7E,YAAY,EAA2B,CAAC,aAAa,EAElD,CAAC;AACN,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,0DAA0D,EAAE,GAAG,EAAE;IACpE,MAAM,CAAC,aAAa,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAC7C,YAAY,CAAC,KAAK,CAAC,CAAC,aAAa,EAAwB,CAAC;QAC1D,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,aAAa,EAA2B,CAAC;QACvE,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|