@smithery/sdk 1.5.5 → 1.5.6
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/index.d.ts +3 -0
- package/dist/server/index.js +3 -0
- package/dist/server/stateless.d.ts +35 -0
- package/dist/server/stateless.js +108 -0
- package/package.json +1 -1
|
@@ -0,0 +1,35 @@
|
|
|
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 stateless server instance
|
|
6
|
+
*/
|
|
7
|
+
export interface CreateStatelessServerArg<T = Record<string, unknown>> {
|
|
8
|
+
config: T;
|
|
9
|
+
}
|
|
10
|
+
export type CreateStatelessServerFn<T = Record<string, unknown>> = (arg: CreateStatelessServerArg<T>) => Server;
|
|
11
|
+
/**
|
|
12
|
+
* Configuration options for the stateless server
|
|
13
|
+
*/
|
|
14
|
+
export interface StatelessServerOptions<T = Record<string, unknown>> {
|
|
15
|
+
/**
|
|
16
|
+
* Zod schema for config validation
|
|
17
|
+
*/
|
|
18
|
+
schema?: z.ZodSchema<T>;
|
|
19
|
+
/**
|
|
20
|
+
* Express app instance to use (optional)
|
|
21
|
+
*/
|
|
22
|
+
app?: express.Application;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Creates a stateless server for handling MCP requests.
|
|
26
|
+
* Each request creates a new server instance - no session state is maintained.
|
|
27
|
+
* This is ideal for stateless API integrations and serverless environments.
|
|
28
|
+
*
|
|
29
|
+
* @param createMcpServer Function to create an MCP server
|
|
30
|
+
* @param options Configuration options including optional schema validation and Express app
|
|
31
|
+
* @returns Express app
|
|
32
|
+
*/
|
|
33
|
+
export declare function createStatelessServer<T = Record<string, unknown>>(createMcpServer: CreateStatelessServerFn<T>, options?: StatelessServerOptions<T>): {
|
|
34
|
+
app: express.Application;
|
|
35
|
+
};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
2
|
+
import express from "express";
|
|
3
|
+
import { parseAndValidateConfig } from "../shared/config.js";
|
|
4
|
+
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
5
|
+
/**
|
|
6
|
+
* Creates a stateless server for handling MCP requests.
|
|
7
|
+
* Each request creates a new server instance - no session state is maintained.
|
|
8
|
+
* This is ideal for stateless API integrations and serverless environments.
|
|
9
|
+
*
|
|
10
|
+
* @param createMcpServer Function to create an MCP server
|
|
11
|
+
* @param options Configuration options including optional schema validation and Express app
|
|
12
|
+
* @returns Express app
|
|
13
|
+
*/
|
|
14
|
+
export function createStatelessServer(createMcpServer, options) {
|
|
15
|
+
const app = options?.app ?? express();
|
|
16
|
+
app.use("/mcp", express.json());
|
|
17
|
+
// Handle POST requests for client-to-server communication
|
|
18
|
+
app.post("/mcp", async (req, res) => {
|
|
19
|
+
// In stateless mode, create a new instance of transport and server for each request
|
|
20
|
+
// to ensure complete isolation. A single instance would cause request ID collisions
|
|
21
|
+
// when multiple clients connect concurrently.
|
|
22
|
+
try {
|
|
23
|
+
// Validate config for all requests in stateless mode
|
|
24
|
+
const configResult = parseAndValidateConfig(req, options?.schema);
|
|
25
|
+
if (!configResult.ok) {
|
|
26
|
+
const status = configResult.error.status || 400;
|
|
27
|
+
res.status(status).json(configResult.error);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const config = configResult.value;
|
|
31
|
+
// Create a fresh server instance for each request
|
|
32
|
+
const server = createMcpServer({
|
|
33
|
+
config,
|
|
34
|
+
});
|
|
35
|
+
// Create a new transport for this request (no session management)
|
|
36
|
+
const transport = new StreamableHTTPServerTransport({
|
|
37
|
+
sessionIdGenerator: undefined,
|
|
38
|
+
});
|
|
39
|
+
// Clean up resources when request closes
|
|
40
|
+
res.on("close", () => {
|
|
41
|
+
transport.close();
|
|
42
|
+
server.close();
|
|
43
|
+
});
|
|
44
|
+
// Connect to the MCP server
|
|
45
|
+
await server.connect(transport);
|
|
46
|
+
// Handle the request directly
|
|
47
|
+
await transport.handleRequest(req, res, req.body);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
console.error("Error handling MCP request:", error);
|
|
51
|
+
if (!res.headersSent) {
|
|
52
|
+
res.status(500).json({
|
|
53
|
+
jsonrpc: "2.0",
|
|
54
|
+
error: {
|
|
55
|
+
code: -32603,
|
|
56
|
+
message: "Internal server error",
|
|
57
|
+
},
|
|
58
|
+
id: null,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
// SSE notifications not supported in stateless mode
|
|
64
|
+
app.get("/mcp", async (_req, res) => {
|
|
65
|
+
res.status(405).json({
|
|
66
|
+
jsonrpc: "2.0",
|
|
67
|
+
error: {
|
|
68
|
+
code: -32000,
|
|
69
|
+
message: "Method not allowed.",
|
|
70
|
+
},
|
|
71
|
+
id: null,
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
// Session termination not needed in stateless mode
|
|
75
|
+
app.delete("/mcp", async (_req, res) => {
|
|
76
|
+
res.status(405).json({
|
|
77
|
+
jsonrpc: "2.0",
|
|
78
|
+
error: {
|
|
79
|
+
code: -32000,
|
|
80
|
+
message: "Method not allowed.",
|
|
81
|
+
},
|
|
82
|
+
id: null,
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
// Add .well-known/mcp-config endpoint for configuration discovery
|
|
86
|
+
app.get("/.well-known/mcp-config", (req, res) => {
|
|
87
|
+
// Set proper content type for JSON Schema
|
|
88
|
+
res.set("Content-Type", "application/schema+json; charset=utf-8");
|
|
89
|
+
const baseSchema = options?.schema
|
|
90
|
+
? zodToJsonSchema(options.schema)
|
|
91
|
+
: {
|
|
92
|
+
type: "object",
|
|
93
|
+
properties: {},
|
|
94
|
+
required: [],
|
|
95
|
+
};
|
|
96
|
+
const configSchema = {
|
|
97
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
98
|
+
$id: `${req.protocol}://${req.get("host")}/.well-known/mcp-config`,
|
|
99
|
+
title: "MCP Session Configuration",
|
|
100
|
+
description: "Schema for the /mcp endpoint configuration",
|
|
101
|
+
"x-mcp-version": "1.0",
|
|
102
|
+
"x-query-style": "dot+bracket",
|
|
103
|
+
...baseSchema,
|
|
104
|
+
};
|
|
105
|
+
res.json(configSchema);
|
|
106
|
+
});
|
|
107
|
+
return { app };
|
|
108
|
+
}
|