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
- // Use a single transport instance for the lifetime of the HTTP server.
17
- const transport = new StreamableHTTPServerTransport({
18
- sessionIdGenerator: () => randomUUID(),
19
- // VERY IMPORTANT: Enable JSON responses for POST requests.
20
- // This allows the client to receive tool lists and call results directly in the POST response,
21
- // which is what the Anthropic Inspector and many other clients expect.
22
- enableJsonResponse: true,
23
- });
24
- // Connect the MCP server instance to this transport.
25
- await server.connect(transport);
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
- // In Streamable HTTP, handleRequest handles the full lifecycle based on method.
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;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAAiB,EAAE,IAAY,EAAE,OAAe,SAAS;IAC7F,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;IAEtB,2DAA2D;IAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IAEhB,oDAAoD;IACpD,qGAAqG;IACrG,2EAA2E;IAC3E,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAExB,uEAAuE;IACvE,MAAM,SAAS,GAAG,IAAI,6BAA6B,CAAC;QAClD,kBAAkB,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE;QACtC,4DAA4D;QAC5D,+FAA+F;QAC/F,uEAAuE;QACvE,kBAAkB,EAAE,IAAI;KACzB,CAAC,CAAC;IAEH,qDAAqD;IACrD,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC;;;OAGG;IACH,MAAM,UAAU,GAAG,KAAK,EAAE,GAAoB,EAAE,GAAqB,EAAE,EAAE;QACvE,IAAI,CAAC;YACH,gFAAgF;YAChF,MAAM,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QACpD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;YAC1C,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;gBACrB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBACnB,KAAK,EAAE,uBAAuB;oBAC9B,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAChE,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IAEF,kCAAkC;IAClC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAE5B,qBAAqB;IACrB,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC5B,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAElC,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QACnC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;YAC1B,OAAO,CAAC,KAAK,CAAC,yCAAyC,IAAI,IAAI,IAAI,MAAM,CAAC,CAAC;YAC3E,OAAO,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;YACxD,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/transports/http.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,10 @@
1
1
  {
2
2
  "name": "staff-mcp",
3
- "version": "1.0.10",
3
+ "version": "1.0.14",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://github.com/ChineseAStar/staff-mcp.git"
7
+ },
4
8
  "type": "module",
5
9
  "main": "dist/src/index.js",
6
10
  "bin": {