@powerhousedao/reactor-mcp 6.0.0-dev.112 → 6.0.0-dev.114
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/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp-routes.d.ts +19 -0
- package/dist/src/mcp-routes.d.ts.map +1 -0
- package/dist/src/mcp-routes.js +50 -0
- package/dist/src/mcp-routes.js.map +1 -0
- package/dist/test/setup-mcp-server.test.d.ts +10 -0
- package/dist/test/setup-mcp-server.test.d.ts.map +1 -0
- package/dist/test/setup-mcp-server.test.js +172 -0
- package/dist/test/setup-mcp-server.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -10
- package/dist/src/express.d.ts +0 -9
- package/dist/src/express.d.ts.map +0 -1
- package/dist/src/express.js +0 -59
- package/dist/src/express.js.map +0 -1
package/dist/src/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { setupMcpServer, type SetupMcpServerOptions } from "./
|
|
1
|
+
export { setupMcpServer, type SetupMcpServerOptions } from "./mcp-routes.js";
|
|
2
2
|
export { createServer, type CreateServerOptions } from "./server.js";
|
|
3
3
|
export * from "./tools/index.js";
|
|
4
4
|
export * from "./tools/types.js";
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACrE,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC"}
|
package/dist/src/index.js
CHANGED
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAA8B,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAA8B,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EAAE,YAAY,EAA4B,MAAM,aAAa,CAAC;AACrE,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
3
|
+
import type { IReactorClient, ISyncManager } from "@powerhousedao/reactor";
|
|
4
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
5
|
+
/** Minimal interface for an HTTP adapter that supports Node.js-style route handlers. */
|
|
6
|
+
interface NodeRouteAdapter {
|
|
7
|
+
mountNodeRoute(method: "DELETE" | "GET" | "POST", path: string, handler: (req: IncomingMessage, res: ServerResponse, body?: unknown) => void): void;
|
|
8
|
+
}
|
|
9
|
+
export interface SetupMcpServerOptions {
|
|
10
|
+
client: IReactorClient;
|
|
11
|
+
syncManager?: ISyncManager;
|
|
12
|
+
}
|
|
13
|
+
/** @internal Injected in tests to avoid relying on constructor mock semantics. */
|
|
14
|
+
type TransportFactory = (opts: {
|
|
15
|
+
sessionIdGenerator: undefined;
|
|
16
|
+
}) => InstanceType<typeof StreamableHTTPServerTransport>;
|
|
17
|
+
export declare function setupMcpServer(options: SetupMcpServerOptions, httpAdapter: NodeRouteAdapter, createTransport?: TransportFactory): Promise<McpServer>;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=mcp-routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-routes.d.ts","sourceRoot":"","sources":["../../src/mcp-routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AACnG,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3E,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEjE,wFAAwF;AACxF,UAAU,gBAAgB;IACxB,cAAc,CACZ,MAAM,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,EACjC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,CACP,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,IAAI,CAAC,EAAE,OAAO,KACX,IAAI,GACR,IAAI,CAAC;CACT;AAID,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,cAAc,CAAC;IACvB,WAAW,CAAC,EAAE,YAAY,CAAC;CAC5B;AAQD,kFAAkF;AAClF,KAAK,gBAAgB,GAAG,CAAC,IAAI,EAAE;IAC7B,kBAAkB,EAAE,SAAS,CAAC;CAC/B,KAAK,YAAY,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEzD,wBAAsB,cAAc,CAClC,OAAO,EAAE,qBAAqB,EAC9B,WAAW,EAAE,gBAAgB,EAG7B,eAAe,GAAE,gBACwB,GACxC,OAAO,CAAC,SAAS,CAAC,CAsDpB"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
2
|
+
import { logger } from "./logger.js";
|
|
3
|
+
import { createServer } from "./server.js";
|
|
4
|
+
const METHOD_NOT_ALLOWED = JSON.stringify({
|
|
5
|
+
jsonrpc: "2.0",
|
|
6
|
+
error: { code: -32000, message: "Method not allowed." },
|
|
7
|
+
id: null,
|
|
8
|
+
});
|
|
9
|
+
export async function setupMcpServer(options, httpAdapter,
|
|
10
|
+
// Allow tests to inject a factory function instead of relying on `new vi.fn()`
|
|
11
|
+
// constructor semantics, which differ between macOS and Linux environments.
|
|
12
|
+
createTransport = (opts) => new StreamableHTTPServerTransport(opts)) {
|
|
13
|
+
const server = await createServer(options);
|
|
14
|
+
httpAdapter.mountNodeRoute("POST", "/mcp", (req, res, body) => {
|
|
15
|
+
// In stateless mode, create a new instance of transport and server for each
|
|
16
|
+
// request to ensure complete isolation. A single instance would cause request
|
|
17
|
+
// ID collisions when multiple clients connect concurrently.
|
|
18
|
+
try {
|
|
19
|
+
const transport = createTransport({
|
|
20
|
+
sessionIdGenerator: undefined,
|
|
21
|
+
});
|
|
22
|
+
res.on("close", () => {
|
|
23
|
+
void transport.close();
|
|
24
|
+
void server.close();
|
|
25
|
+
});
|
|
26
|
+
void server.connect(transport);
|
|
27
|
+
void transport.handleRequest(req, res, body);
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
logger.error("Error handling MCP request:", error);
|
|
31
|
+
if (!res.headersSent) {
|
|
32
|
+
res.writeHead(500, { "Content-Type": "application/json" }).end(JSON.stringify({
|
|
33
|
+
jsonrpc: "2.0",
|
|
34
|
+
error: { code: -32603, message: "Internal server error" },
|
|
35
|
+
id: null,
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
// SSE notifications not supported in stateless mode
|
|
41
|
+
httpAdapter.mountNodeRoute("GET", "/mcp", (_req, res) => {
|
|
42
|
+
res.writeHead(405).end(METHOD_NOT_ALLOWED);
|
|
43
|
+
});
|
|
44
|
+
// Session termination not needed in stateless mode
|
|
45
|
+
httpAdapter.mountNodeRoute("DELETE", "/mcp", (_req, res) => {
|
|
46
|
+
res.writeHead(405).end(METHOD_NOT_ALLOWED);
|
|
47
|
+
});
|
|
48
|
+
return server;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=mcp-routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-routes.js","sourceRoot":"","sources":["../../src/mcp-routes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AAgBnG,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAO3C,MAAM,kBAAkB,GAAG,IAAI,CAAC,SAAS,CAAC;IACxC,OAAO,EAAE,KAAK;IACd,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,qBAAqB,EAAE;IACvD,EAAE,EAAE,IAAI;CACT,CAAC,CAAC;AAOH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAA8B,EAC9B,WAA6B;AAC7B,+EAA+E;AAC/E,4EAA4E;AAC5E,kBAAoC,CAAC,IAAI,EAAE,EAAE,CAC3C,IAAI,6BAA6B,CAAC,IAAI,CAAC;IAEzC,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;IAE3C,WAAW,CAAC,cAAc,CACxB,MAAM,EACN,MAAM,EACN,CAAC,GAAoB,EAAE,GAAmB,EAAE,IAAc,EAAE,EAAE;QAC5D,4EAA4E;QAC5E,8EAA8E;QAC9E,4DAA4D;QAC5D,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,eAAe,CAAC;gBAChC,kBAAkB,EAAE,SAAS;aAC9B,CAAC,CAAC;YACH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBACnB,KAAK,SAAS,CAAC,KAAK,EAAE,CAAC;gBACvB,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC;YACtB,CAAC,CAAC,CAAC;YACH,KAAK,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YAC/B,KAAK,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QAC/C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;YACnD,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;gBACrB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC,GAAG,CAC5D,IAAI,CAAC,SAAS,CAAC;oBACb,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,uBAAuB,EAAE;oBACzD,EAAE,EAAE,IAAI;iBACT,CAAC,CACH,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC,CACF,CAAC;IAEF,oDAAoD;IACpD,WAAW,CAAC,cAAc,CACxB,KAAK,EACL,MAAM,EACN,CAAC,IAAqB,EAAE,GAAmB,EAAE,EAAE;QAC7C,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAC7C,CAAC,CACF,CAAC;IAEF,mDAAmD;IACnD,WAAW,CAAC,cAAc,CACxB,QAAQ,EACR,MAAM,EACN,CAAC,IAAqB,EAAE,GAAmB,EAAE,EAAE;QAC7C,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAC7C,CAAC,CACF,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for setupMcpServer (packages/reactor-mcp/src/mcp-routes.ts).
|
|
3
|
+
*
|
|
4
|
+
* Verifies that:
|
|
5
|
+
* - mountNodeRoute is called for POST, GET, and DELETE on /mcp
|
|
6
|
+
* - The GET and DELETE handlers return 405 Method Not Allowed
|
|
7
|
+
* - The POST handler delegates to the MCP transport (via a mock McpServer)
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=setup-mcp-server.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-mcp-server.test.d.ts","sourceRoot":"","sources":["../../test/setup-mcp-server.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for setupMcpServer (packages/reactor-mcp/src/mcp-routes.ts).
|
|
3
|
+
*
|
|
4
|
+
* Verifies that:
|
|
5
|
+
* - mountNodeRoute is called for POST, GET, and DELETE on /mcp
|
|
6
|
+
* - The GET and DELETE handlers return 405 Method Not Allowed
|
|
7
|
+
* - The POST handler delegates to the MCP transport (via a mock McpServer)
|
|
8
|
+
*/
|
|
9
|
+
import { EventEmitter } from "node:events";
|
|
10
|
+
import { describe, expect, it, vi } from "vitest";
|
|
11
|
+
// ── mock createServer so we don't spin up real MCP tool registrations ─────────
|
|
12
|
+
vi.mock("../src/server.js", () => ({
|
|
13
|
+
createServer: vi.fn().mockResolvedValue({
|
|
14
|
+
connect: vi.fn().mockResolvedValue(undefined),
|
|
15
|
+
close: vi.fn().mockResolvedValue(undefined),
|
|
16
|
+
}),
|
|
17
|
+
}));
|
|
18
|
+
// Static import — vi.mock() is hoisted so the mock above is applied first.
|
|
19
|
+
import { setupMcpServer } from "../src/mcp-routes.js";
|
|
20
|
+
function makeMockAdapter() {
|
|
21
|
+
const routes = [];
|
|
22
|
+
const adapter = {
|
|
23
|
+
mountNodeRoute: vi.fn((method, path, handler) => {
|
|
24
|
+
routes.push({ method, path, handler });
|
|
25
|
+
}),
|
|
26
|
+
};
|
|
27
|
+
return { adapter, routes };
|
|
28
|
+
}
|
|
29
|
+
function makeMockResponse() {
|
|
30
|
+
const res = new EventEmitter();
|
|
31
|
+
const written = {
|
|
32
|
+
status: 0,
|
|
33
|
+
headers: {},
|
|
34
|
+
body: "",
|
|
35
|
+
};
|
|
36
|
+
res.writeHead = vi.fn((status, headers) => {
|
|
37
|
+
written.status = status;
|
|
38
|
+
if (headers)
|
|
39
|
+
Object.assign(written.headers, headers);
|
|
40
|
+
return res;
|
|
41
|
+
});
|
|
42
|
+
res.end = vi.fn((chunk) => {
|
|
43
|
+
if (typeof chunk === "string")
|
|
44
|
+
written.body = chunk;
|
|
45
|
+
return res;
|
|
46
|
+
});
|
|
47
|
+
return { res, written };
|
|
48
|
+
}
|
|
49
|
+
/** Returns a fresh transport factory mock for each POST-handler test. */
|
|
50
|
+
function makeTransportMock() {
|
|
51
|
+
const handleRequest = vi.fn().mockResolvedValue(undefined);
|
|
52
|
+
const close = vi.fn().mockResolvedValue(undefined);
|
|
53
|
+
// Use a plain factory function (not a constructor) to avoid `new vi.fn()`
|
|
54
|
+
// constructor semantics that differ between macOS and Linux/CI environments.
|
|
55
|
+
const createTransport = vi.fn().mockReturnValue({ handleRequest, close });
|
|
56
|
+
return {
|
|
57
|
+
Transport: createTransport,
|
|
58
|
+
handleRequest,
|
|
59
|
+
close,
|
|
60
|
+
createTransport,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
const mockClient = {};
|
|
64
|
+
const mockSyncManager = {};
|
|
65
|
+
// ── tests ─────────────────────────────────────────────────────────────────────
|
|
66
|
+
describe("setupMcpServer", () => {
|
|
67
|
+
it("registers routes for POST, GET, and DELETE on /mcp", async () => {
|
|
68
|
+
const { adapter, routes } = makeMockAdapter();
|
|
69
|
+
await setupMcpServer({ client: mockClient, syncManager: mockSyncManager }, adapter);
|
|
70
|
+
expect(adapter.mountNodeRoute).toHaveBeenCalledTimes(3);
|
|
71
|
+
const methods = routes.map((r) => r.method);
|
|
72
|
+
expect(methods).toContain("POST");
|
|
73
|
+
expect(methods).toContain("GET");
|
|
74
|
+
expect(methods).toContain("DELETE");
|
|
75
|
+
});
|
|
76
|
+
it("registers all routes at /mcp", async () => {
|
|
77
|
+
const { adapter, routes } = makeMockAdapter();
|
|
78
|
+
await setupMcpServer({ client: mockClient }, adapter);
|
|
79
|
+
for (const route of routes) {
|
|
80
|
+
expect(route.path).toBe("/mcp");
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
it("GET /mcp handler responds with 405", async () => {
|
|
84
|
+
const { adapter, routes } = makeMockAdapter();
|
|
85
|
+
await setupMcpServer({ client: mockClient }, adapter);
|
|
86
|
+
const getRoute = routes.find((r) => r.method === "GET");
|
|
87
|
+
expect(getRoute).toBeDefined();
|
|
88
|
+
const fakeReq = {};
|
|
89
|
+
const { res, written } = makeMockResponse();
|
|
90
|
+
getRoute.handler(fakeReq, res);
|
|
91
|
+
expect(written.status).toBe(405);
|
|
92
|
+
});
|
|
93
|
+
it("DELETE /mcp handler responds with 405", async () => {
|
|
94
|
+
const { adapter, routes } = makeMockAdapter();
|
|
95
|
+
await setupMcpServer({ client: mockClient }, adapter);
|
|
96
|
+
const deleteRoute = routes.find((r) => r.method === "DELETE");
|
|
97
|
+
expect(deleteRoute).toBeDefined();
|
|
98
|
+
const fakeReq = {};
|
|
99
|
+
const { res, written } = makeMockResponse();
|
|
100
|
+
deleteRoute.handler(fakeReq, res);
|
|
101
|
+
expect(written.status).toBe(405);
|
|
102
|
+
});
|
|
103
|
+
it("GET and DELETE response bodies contain a JSON-RPC error", async () => {
|
|
104
|
+
const { adapter, routes } = makeMockAdapter();
|
|
105
|
+
await setupMcpServer({ client: mockClient }, adapter);
|
|
106
|
+
for (const method of ["GET", "DELETE"]) {
|
|
107
|
+
const route = routes.find((r) => r.method === method);
|
|
108
|
+
const { res, written } = makeMockResponse();
|
|
109
|
+
route.handler({}, res);
|
|
110
|
+
const body = JSON.parse(written.body);
|
|
111
|
+
expect(body.error.message).toBeTruthy();
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
it("returns the McpServer instance", async () => {
|
|
115
|
+
const { adapter } = makeMockAdapter();
|
|
116
|
+
const result = await setupMcpServer({ client: mockClient }, adapter);
|
|
117
|
+
expect(result).toBeDefined();
|
|
118
|
+
expect(typeof result.connect).toBe("function");
|
|
119
|
+
});
|
|
120
|
+
// ── POST /mcp handler ───────────────────────────────────────────────────────
|
|
121
|
+
describe("POST /mcp handler", () => {
|
|
122
|
+
/** Run a POST handler invocation and wait for async fire-and-forget calls. */
|
|
123
|
+
async function invokePost(routes, body) {
|
|
124
|
+
const postRoute = routes.find((r) => r.method === "POST");
|
|
125
|
+
const fakeReq = {};
|
|
126
|
+
const { res } = makeMockResponse();
|
|
127
|
+
postRoute.handler(fakeReq, res, body);
|
|
128
|
+
// transport.handleRequest and server.connect are void-called (fire-and-forget)
|
|
129
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
130
|
+
return { req: fakeReq, res };
|
|
131
|
+
}
|
|
132
|
+
it("calls transport.handleRequest with (req, res, body)", async () => {
|
|
133
|
+
const { Transport, handleRequest } = makeTransportMock();
|
|
134
|
+
const { adapter, routes } = makeMockAdapter();
|
|
135
|
+
await setupMcpServer({ client: mockClient }, adapter, Transport);
|
|
136
|
+
const body = { jsonrpc: "2.0", method: "initialize", id: 1 };
|
|
137
|
+
const { req, res } = await invokePost(routes, body);
|
|
138
|
+
expect(handleRequest).toHaveBeenCalledOnce();
|
|
139
|
+
expect(handleRequest).toHaveBeenCalledWith(req, res, body);
|
|
140
|
+
});
|
|
141
|
+
it("creates a fresh transport per request for stateless isolation", async () => {
|
|
142
|
+
const { Transport, handleRequest } = makeTransportMock();
|
|
143
|
+
const { adapter, routes } = makeMockAdapter();
|
|
144
|
+
await setupMcpServer({ client: mockClient }, adapter, Transport);
|
|
145
|
+
await invokePost(routes);
|
|
146
|
+
await invokePost(routes);
|
|
147
|
+
expect(Transport).toHaveBeenCalledTimes(2);
|
|
148
|
+
expect(handleRequest).toHaveBeenCalledTimes(2);
|
|
149
|
+
});
|
|
150
|
+
it("connects the server to the new transport before handling the request", async () => {
|
|
151
|
+
const { Transport } = makeTransportMock();
|
|
152
|
+
const { adapter, routes } = makeMockAdapter();
|
|
153
|
+
const server = await setupMcpServer({ client: mockClient }, adapter, Transport);
|
|
154
|
+
await invokePost(routes);
|
|
155
|
+
const rawTransport = Transport.mock.results[0]?.value;
|
|
156
|
+
expect(server.connect).toHaveBeenCalledWith(rawTransport);
|
|
157
|
+
});
|
|
158
|
+
it("closes the transport when the response 'close' event fires", async () => {
|
|
159
|
+
const { Transport, close } = makeTransportMock();
|
|
160
|
+
const { adapter, routes } = makeMockAdapter();
|
|
161
|
+
await setupMcpServer({ client: mockClient }, adapter, Transport);
|
|
162
|
+
const postRoute = routes.find((r) => r.method === "POST");
|
|
163
|
+
const { res } = makeMockResponse();
|
|
164
|
+
postRoute.handler({}, res);
|
|
165
|
+
// Simulate connection drop / response finish
|
|
166
|
+
res.emit("close");
|
|
167
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
168
|
+
expect(close).toHaveBeenCalled();
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
//# sourceMappingURL=setup-mcp-server.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-mcp-server.test.js","sourceRoot":"","sources":["../../test/setup-mcp-server.test.ts"],"names":[],"mappings":"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"}
|