staff-mcp 1.0.10 → 1.0.14
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.
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
/**
|
|
3
3
|
* Starts an Express server that hosts the MCP server over Streamable HTTP.
|
|
4
|
+
*
|
|
5
|
+
* Transport lifecycle:
|
|
6
|
+
* - Each client session gets its own StreamableHTTPServerTransport instance.
|
|
7
|
+
* - When a session ends (DELETE, client disconnect, etc.), the transport fires
|
|
8
|
+
* its onclose callback, which schedules a reset via setTimeout(0).
|
|
9
|
+
* - The setTimeout deferral is critical: it lets Protocol._onclose() finish
|
|
10
|
+
* (setting _transport = undefined) before we call server.connect() again.
|
|
11
|
+
* - During the reset window, incoming requests receive 503 to trigger client retry.
|
|
4
12
|
*/
|
|
5
13
|
export declare function startHttpServer(server: McpServer, port: number, host?: string): Promise<void>;
|
|
@@ -4,33 +4,67 @@ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/
|
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
5
5
|
/**
|
|
6
6
|
* Starts an Express server that hosts the MCP server over Streamable HTTP.
|
|
7
|
+
*
|
|
8
|
+
* Transport lifecycle:
|
|
9
|
+
* - Each client session gets its own StreamableHTTPServerTransport instance.
|
|
10
|
+
* - When a session ends (DELETE, client disconnect, etc.), the transport fires
|
|
11
|
+
* its onclose callback, which schedules a reset via setTimeout(0).
|
|
12
|
+
* - The setTimeout deferral is critical: it lets Protocol._onclose() finish
|
|
13
|
+
* (setting _transport = undefined) before we call server.connect() again.
|
|
14
|
+
* - During the reset window, incoming requests receive 503 to trigger client retry.
|
|
7
15
|
*/
|
|
8
16
|
export async function startHttpServer(server, port, host = "0.0.0.0") {
|
|
9
17
|
const app = express();
|
|
10
18
|
// Enable CORS for all origins, including the MCP Inspector
|
|
11
19
|
app.use(cors());
|
|
12
20
|
// Necessary for processing JSON-RPC messages (POST)
|
|
13
|
-
// We use express.json() but also need to be careful not to consume the stream if transport needs it.
|
|
14
|
-
// However, StreamableHTTPServerTransport.handleRequest accepts parsedBody.
|
|
15
21
|
app.use(express.json());
|
|
16
|
-
//
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
// The currently active transport. Set to null during reset windows.
|
|
23
|
+
let transport = null;
|
|
24
|
+
/**
|
|
25
|
+
* Creates a fresh transport and connects it to the server.
|
|
26
|
+
* Must only be called when server has no active transport
|
|
27
|
+
* (i.e., after Protocol._onclose() has cleared _transport).
|
|
28
|
+
*/
|
|
29
|
+
async function setupTransport() {
|
|
30
|
+
// Mark transport as unavailable during the reset window so incoming
|
|
31
|
+
// requests get a clean 503 instead of hitting a closed transport.
|
|
32
|
+
transport = null;
|
|
33
|
+
const t = new StreamableHTTPServerTransport({
|
|
34
|
+
sessionIdGenerator: () => randomUUID(),
|
|
35
|
+
// Enable JSON responses for POST requests so the client receives
|
|
36
|
+
// tool lists / call results directly in the response body.
|
|
37
|
+
enableJsonResponse: true,
|
|
38
|
+
});
|
|
39
|
+
// Schedule a reset when this session ends.
|
|
40
|
+
// We use setTimeout(0) to defer past Protocol._onclose(), which
|
|
41
|
+
// clears _transport = undefined and makes connect() possible.
|
|
42
|
+
t.onclose = () => {
|
|
43
|
+
setTimeout(() => {
|
|
44
|
+
setupTransport().catch((err) => {
|
|
45
|
+
console.error("[MCP HTTP] Failed to reset transport:", err);
|
|
46
|
+
});
|
|
47
|
+
}, 0);
|
|
48
|
+
};
|
|
49
|
+
await server.connect(t);
|
|
50
|
+
transport = t;
|
|
51
|
+
console.error("[MCP HTTP] Transport ready for new sessions");
|
|
52
|
+
}
|
|
53
|
+
// Initial transport setup.
|
|
54
|
+
await setupTransport();
|
|
26
55
|
/**
|
|
27
56
|
* Unified handler for MCP requests.
|
|
28
57
|
* Handles GET (SSE) and POST (JSON-RPC).
|
|
29
58
|
*/
|
|
30
59
|
const mcpHandler = async (req, res) => {
|
|
60
|
+
const current = transport;
|
|
61
|
+
if (!current) {
|
|
62
|
+
// Transport is being reset — tell the client to retry.
|
|
63
|
+
res.status(503).json({ error: "Server is restarting session, please retry" });
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
31
66
|
try {
|
|
32
|
-
|
|
33
|
-
await transport.handleRequest(req, res, req.body);
|
|
67
|
+
await current.handleRequest(req, res, req.body);
|
|
34
68
|
}
|
|
35
69
|
catch (error) {
|
|
36
70
|
console.error("[MCP HTTP Error]:", error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/transports/http.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AACnG,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/transports/http.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED