@smithery/sdk 1.4.3 → 1.5.1
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/server/stateful.js +26 -0
- package/package.json +1 -1
- package/dist/server/stateless.d.ts +0 -24
- package/dist/server/stateless.js +0 -80
package/dist/server/stateful.js
CHANGED
|
@@ -3,6 +3,7 @@ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/
|
|
|
3
3
|
import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
|
|
4
4
|
import express from "express";
|
|
5
5
|
import { parseAndValidateConfig } from "../shared/config.js";
|
|
6
|
+
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
6
7
|
import { createLRUStore } from "./session.js";
|
|
7
8
|
/**
|
|
8
9
|
* Creates a stateful server for handling MCP requests.
|
|
@@ -85,6 +86,31 @@ export function createStatefulServer(createMcpServer, options) {
|
|
|
85
86
|
// Handle the request
|
|
86
87
|
await transport.handleRequest(req, res, req.body);
|
|
87
88
|
});
|
|
89
|
+
// Add .well-known/mcp-config endpoint for configuration discovery
|
|
90
|
+
app.get("/.well-known/mcp/config.json", (req, res) => {
|
|
91
|
+
// Set proper content type for JSON Schema
|
|
92
|
+
res.set("Content-Type", "application/schema+json; charset=utf-8");
|
|
93
|
+
const baseSchema = options?.schema
|
|
94
|
+
? zodToJsonSchema(options.schema, {
|
|
95
|
+
name: "SessionConfig",
|
|
96
|
+
$refStrategy: "none",
|
|
97
|
+
})
|
|
98
|
+
: {
|
|
99
|
+
type: "object",
|
|
100
|
+
properties: {},
|
|
101
|
+
required: [],
|
|
102
|
+
};
|
|
103
|
+
const configSchema = {
|
|
104
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
105
|
+
$id: `${req.protocol}://${req.get("host")}/.well-known/mcp/config.json`,
|
|
106
|
+
title: "MCP Session Configuration",
|
|
107
|
+
description: "Schema for the /mcp endpoint configuration",
|
|
108
|
+
"x-mcp-version": "1.0",
|
|
109
|
+
"x-query-style": "dot+bracket",
|
|
110
|
+
...baseSchema,
|
|
111
|
+
};
|
|
112
|
+
res.json(configSchema);
|
|
113
|
+
});
|
|
88
114
|
// Reusable handler for GET and DELETE requests
|
|
89
115
|
const handleSessionRequest = async (req, res) => {
|
|
90
116
|
const sessionId = req.headers["mcp-session-id"];
|
package/package.json
CHANGED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import express from "express";
|
|
2
|
-
import type { z } from "zod";
|
|
3
|
-
import type { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
4
|
-
/**
|
|
5
|
-
* Arguments when we create a new instance of your server
|
|
6
|
-
*/
|
|
7
|
-
export interface CreateServerArg<T = Record<string, unknown>> {
|
|
8
|
-
config: T;
|
|
9
|
-
}
|
|
10
|
-
export type CreateServerFn<T = Record<string, unknown>> = (arg: CreateServerArg<T>) => Server;
|
|
11
|
-
export interface CreateStatelessServerOptions<T> {
|
|
12
|
-
schema?: z.ZodSchema<T>;
|
|
13
|
-
app?: express.Application;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Creates a stateless server for handling MCP requests
|
|
17
|
-
* In stateless mode, each request creates a new server and transport instance
|
|
18
|
-
* @param createMcpServer Function to create an MCP server
|
|
19
|
-
* @param options Optional configuration including Zod schema for validation
|
|
20
|
-
* @returns Express app
|
|
21
|
-
*/
|
|
22
|
-
export declare function createStatelessServer<T = Record<string, unknown>>(createMcpServer: CreateServerFn<T>, options?: CreateStatelessServerOptions<T>): {
|
|
23
|
-
app: express.Application;
|
|
24
|
-
};
|
package/dist/server/stateless.js
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import express from "express";
|
|
2
|
-
import { parseAndValidateConfig } from "../shared/config.js";
|
|
3
|
-
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
4
|
-
/**
|
|
5
|
-
* Creates a stateless server for handling MCP requests
|
|
6
|
-
* In stateless mode, each request creates a new server and transport instance
|
|
7
|
-
* @param createMcpServer Function to create an MCP server
|
|
8
|
-
* @param options Optional configuration including Zod schema for validation
|
|
9
|
-
* @returns Express app
|
|
10
|
-
*/
|
|
11
|
-
export function createStatelessServer(createMcpServer, options) {
|
|
12
|
-
const app = options?.app ?? express();
|
|
13
|
-
app.use("/mcp", express.json());
|
|
14
|
-
app.post("/mcp", async (req, res) => {
|
|
15
|
-
// In stateless mode, create a new instance of transport and server for each request
|
|
16
|
-
// to ensure complete isolation. A single instance would cause request ID collisions
|
|
17
|
-
// when multiple clients connect concurrently.
|
|
18
|
-
try {
|
|
19
|
-
// Parse and validate config
|
|
20
|
-
const configResult = parseAndValidateConfig(req, options?.schema);
|
|
21
|
-
if (!configResult.ok) {
|
|
22
|
-
const status = configResult.error.status;
|
|
23
|
-
res.status(status).json(configResult.error);
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
const config = configResult.value;
|
|
27
|
-
// Create a new server instance with config
|
|
28
|
-
const server = createMcpServer({ config: config });
|
|
29
|
-
// Create a new transport instance
|
|
30
|
-
const transport = new StreamableHTTPServerTransport({
|
|
31
|
-
sessionIdGenerator: undefined,
|
|
32
|
-
});
|
|
33
|
-
// Clean up resources when the request ends
|
|
34
|
-
res.on("close", () => {
|
|
35
|
-
transport.close();
|
|
36
|
-
server.close();
|
|
37
|
-
});
|
|
38
|
-
// Connect the server to the transport
|
|
39
|
-
await server.connect(transport);
|
|
40
|
-
// Handle the incoming request
|
|
41
|
-
await transport.handleRequest(req, res, req.body);
|
|
42
|
-
}
|
|
43
|
-
catch (error) {
|
|
44
|
-
console.error("Error handling MCP request:", error);
|
|
45
|
-
if (!res.headersSent) {
|
|
46
|
-
res.status(500).json({
|
|
47
|
-
jsonrpc: "2.0",
|
|
48
|
-
error: {
|
|
49
|
-
code: -32603,
|
|
50
|
-
message: "Internal server error",
|
|
51
|
-
},
|
|
52
|
-
id: null,
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
app.get("/mcp", async (req, res) => {
|
|
58
|
-
console.log("Received GET MCP request");
|
|
59
|
-
res.writeHead(405).end(JSON.stringify({
|
|
60
|
-
jsonrpc: "2.0",
|
|
61
|
-
error: {
|
|
62
|
-
code: -32000,
|
|
63
|
-
message: "Method not allowed in stateless mode",
|
|
64
|
-
},
|
|
65
|
-
id: null,
|
|
66
|
-
}));
|
|
67
|
-
});
|
|
68
|
-
app.delete("/mcp", async (req, res) => {
|
|
69
|
-
console.log("Received DELETE MCP request");
|
|
70
|
-
res.writeHead(405).end(JSON.stringify({
|
|
71
|
-
jsonrpc: "2.0",
|
|
72
|
-
error: {
|
|
73
|
-
code: -32000,
|
|
74
|
-
message: "Method not allowed in stateless mode",
|
|
75
|
-
},
|
|
76
|
-
id: null,
|
|
77
|
-
}));
|
|
78
|
-
});
|
|
79
|
-
return { app };
|
|
80
|
-
}
|