@modelcontextprotocol/server-everything 2025.12.18 → 2026.1.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.
- package/README.md +9 -158
- package/dist/docs/architecture.md +44 -0
- package/dist/docs/extension.md +23 -0
- package/dist/docs/features.md +52 -0
- package/dist/docs/how-it-works.md +45 -0
- package/dist/docs/instructions.md +28 -0
- package/dist/docs/startup.md +73 -0
- package/dist/docs/structure.md +182 -0
- package/dist/index.js +19 -14
- package/dist/prompts/args.js +34 -0
- package/dist/prompts/completions.js +52 -0
- package/dist/prompts/index.js +15 -0
- package/dist/prompts/resource.js +60 -0
- package/dist/prompts/simple.js +23 -0
- package/dist/resources/files.js +83 -0
- package/dist/resources/index.js +33 -0
- package/dist/resources/session.js +44 -0
- package/dist/resources/subscriptions.js +125 -0
- package/dist/resources/templates.js +171 -0
- package/dist/server/index.js +73 -0
- package/dist/server/logging.js +64 -0
- package/dist/server/roots.js +69 -0
- package/dist/tools/echo.js +29 -0
- package/dist/tools/get-annotated-message.js +81 -0
- package/dist/tools/get-env.js +28 -0
- package/dist/tools/get-resource-links.js +62 -0
- package/dist/tools/get-resource-reference.js +74 -0
- package/dist/tools/get-roots-list.js +71 -0
- package/dist/tools/get-structured-content.js +72 -0
- package/dist/tools/get-sum.js +40 -0
- package/dist/tools/get-tiny-image.js +41 -0
- package/dist/tools/gzip-file-as-resource.js +182 -0
- package/dist/tools/index.js +42 -0
- package/dist/tools/toggle-simulated-logging.js +41 -0
- package/dist/tools/toggle-subscriber-updates.js +44 -0
- package/dist/tools/trigger-elicitation-request.js +210 -0
- package/dist/tools/trigger-long-running-operation.js +59 -0
- package/dist/tools/trigger-sampling-request.js +71 -0
- package/dist/{sse.js → transports/sse.js} +25 -17
- package/dist/transports/stdio.js +27 -0
- package/dist/{streamableHttp.js → transports/streamableHttp.js} +68 -57
- package/package.json +10 -7
- package/dist/everything.js +0 -978
- package/dist/instructions.md +0 -23
- package/dist/stdio.js +0 -23
|
@@ -1,71 +1,68 @@
|
|
|
1
1
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
2
|
-
import { InMemoryEventStore } from
|
|
2
|
+
import { InMemoryEventStore } from "@modelcontextprotocol/sdk/examples/shared/inMemoryEventStore.js";
|
|
3
3
|
import express from "express";
|
|
4
|
-
import { createServer } from "
|
|
5
|
-
import { randomUUID } from
|
|
6
|
-
import cors from
|
|
7
|
-
console.
|
|
4
|
+
import { createServer } from "../server/index.js";
|
|
5
|
+
import { randomUUID } from "node:crypto";
|
|
6
|
+
import cors from "cors";
|
|
7
|
+
console.log("Starting Streamable HTTP server...");
|
|
8
|
+
// Express app with permissive CORS for testing with Inspector direct connect mode
|
|
8
9
|
const app = express();
|
|
9
10
|
app.use(cors({
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
'mcp-protocol-version'
|
|
18
|
-
]
|
|
19
|
-
})); // Enable CORS for all routes so Inspector can connect
|
|
11
|
+
origin: "*", // use "*" with caution in production
|
|
12
|
+
methods: "GET,POST,DELETE",
|
|
13
|
+
preflightContinue: false,
|
|
14
|
+
optionsSuccessStatus: 204,
|
|
15
|
+
exposedHeaders: ["mcp-session-id", "last-event-id", "mcp-protocol-version"],
|
|
16
|
+
}));
|
|
17
|
+
// Map sessionId to server transport for each client
|
|
20
18
|
const transports = new Map();
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
// Handle POST requests for client messages
|
|
20
|
+
app.post("/mcp", async (req, res) => {
|
|
21
|
+
console.log("Received MCP POST request");
|
|
23
22
|
try {
|
|
24
23
|
// Check for existing session ID
|
|
25
|
-
const sessionId = req.headers[
|
|
24
|
+
const sessionId = req.headers["mcp-session-id"];
|
|
26
25
|
let transport;
|
|
27
26
|
if (sessionId && transports.has(sessionId)) {
|
|
28
27
|
// Reuse existing transport
|
|
29
28
|
transport = transports.get(sessionId);
|
|
30
29
|
}
|
|
31
30
|
else if (!sessionId) {
|
|
32
|
-
const { server, cleanup
|
|
31
|
+
const { server, cleanup } = createServer();
|
|
33
32
|
// New initialization request
|
|
34
33
|
const eventStore = new InMemoryEventStore();
|
|
35
34
|
transport = new StreamableHTTPServerTransport({
|
|
36
35
|
sessionIdGenerator: () => randomUUID(),
|
|
37
36
|
eventStore, // Enable resumability
|
|
38
37
|
onsessioninitialized: (sessionId) => {
|
|
39
|
-
// Store the transport by session ID when session is initialized
|
|
38
|
+
// Store the transport by session ID when a session is initialized
|
|
40
39
|
// This avoids race conditions where requests might come in before the session is stored
|
|
41
|
-
console.
|
|
40
|
+
console.log(`Session initialized with ID: ${sessionId}`);
|
|
42
41
|
transports.set(sessionId, transport);
|
|
43
|
-
}
|
|
42
|
+
},
|
|
44
43
|
});
|
|
45
44
|
// Set up onclose handler to clean up transport when closed
|
|
46
|
-
server.onclose = async () => {
|
|
45
|
+
server.server.onclose = async () => {
|
|
47
46
|
const sid = transport.sessionId;
|
|
48
47
|
if (sid && transports.has(sid)) {
|
|
49
|
-
console.
|
|
48
|
+
console.log(`Transport closed for session ${sid}, removing from transports map`);
|
|
50
49
|
transports.delete(sid);
|
|
51
|
-
|
|
50
|
+
cleanup(sid);
|
|
52
51
|
}
|
|
53
52
|
};
|
|
54
53
|
// Connect the transport to the MCP server BEFORE handling the request
|
|
55
54
|
// so responses can flow back through the same transport
|
|
56
55
|
await server.connect(transport);
|
|
57
56
|
await transport.handleRequest(req, res);
|
|
58
|
-
|
|
59
|
-
startNotificationIntervals(transport.sessionId);
|
|
60
|
-
return; // Already handled
|
|
57
|
+
return;
|
|
61
58
|
}
|
|
62
59
|
else {
|
|
63
60
|
// Invalid request - no session ID or not initialization request
|
|
64
61
|
res.status(400).json({
|
|
65
|
-
jsonrpc:
|
|
62
|
+
jsonrpc: "2.0",
|
|
66
63
|
error: {
|
|
67
64
|
code: -32000,
|
|
68
|
-
message:
|
|
65
|
+
message: "Bad Request: No valid session ID provided",
|
|
69
66
|
},
|
|
70
67
|
id: req?.body?.id,
|
|
71
68
|
});
|
|
@@ -76,13 +73,13 @@ app.post('/mcp', async (req, res) => {
|
|
|
76
73
|
await transport.handleRequest(req, res);
|
|
77
74
|
}
|
|
78
75
|
catch (error) {
|
|
79
|
-
console.
|
|
76
|
+
console.log("Error handling MCP request:", error);
|
|
80
77
|
if (!res.headersSent) {
|
|
81
78
|
res.status(500).json({
|
|
82
|
-
jsonrpc:
|
|
79
|
+
jsonrpc: "2.0",
|
|
83
80
|
error: {
|
|
84
81
|
code: -32603,
|
|
85
|
-
message:
|
|
82
|
+
message: "Internal server error",
|
|
86
83
|
},
|
|
87
84
|
id: req?.body?.id,
|
|
88
85
|
});
|
|
@@ -90,59 +87,59 @@ app.post('/mcp', async (req, res) => {
|
|
|
90
87
|
}
|
|
91
88
|
}
|
|
92
89
|
});
|
|
93
|
-
// Handle GET requests for SSE streams
|
|
94
|
-
app.get(
|
|
95
|
-
console.
|
|
96
|
-
const sessionId = req.headers[
|
|
90
|
+
// Handle GET requests for SSE streams
|
|
91
|
+
app.get("/mcp", async (req, res) => {
|
|
92
|
+
console.log("Received MCP GET request");
|
|
93
|
+
const sessionId = req.headers["mcp-session-id"];
|
|
97
94
|
if (!sessionId || !transports.has(sessionId)) {
|
|
98
95
|
res.status(400).json({
|
|
99
|
-
jsonrpc:
|
|
96
|
+
jsonrpc: "2.0",
|
|
100
97
|
error: {
|
|
101
98
|
code: -32000,
|
|
102
|
-
message:
|
|
99
|
+
message: "Bad Request: No valid session ID provided",
|
|
103
100
|
},
|
|
104
101
|
id: req?.body?.id,
|
|
105
102
|
});
|
|
106
103
|
return;
|
|
107
104
|
}
|
|
108
105
|
// Check for Last-Event-ID header for resumability
|
|
109
|
-
const lastEventId = req.headers[
|
|
106
|
+
const lastEventId = req.headers["last-event-id"];
|
|
110
107
|
if (lastEventId) {
|
|
111
|
-
console.
|
|
108
|
+
console.log(`Client reconnecting with Last-Event-ID: ${lastEventId}`);
|
|
112
109
|
}
|
|
113
110
|
else {
|
|
114
|
-
console.
|
|
111
|
+
console.log(`Establishing new SSE stream for session ${sessionId}`);
|
|
115
112
|
}
|
|
116
113
|
const transport = transports.get(sessionId);
|
|
117
114
|
await transport.handleRequest(req, res);
|
|
118
115
|
});
|
|
119
|
-
// Handle DELETE requests for session termination
|
|
120
|
-
app.delete(
|
|
121
|
-
const sessionId = req.headers[
|
|
116
|
+
// Handle DELETE requests for session termination
|
|
117
|
+
app.delete("/mcp", async (req, res) => {
|
|
118
|
+
const sessionId = req.headers["mcp-session-id"];
|
|
122
119
|
if (!sessionId || !transports.has(sessionId)) {
|
|
123
120
|
res.status(400).json({
|
|
124
|
-
jsonrpc:
|
|
121
|
+
jsonrpc: "2.0",
|
|
125
122
|
error: {
|
|
126
123
|
code: -32000,
|
|
127
|
-
message:
|
|
124
|
+
message: "Bad Request: No valid session ID provided",
|
|
128
125
|
},
|
|
129
126
|
id: req?.body?.id,
|
|
130
127
|
});
|
|
131
128
|
return;
|
|
132
129
|
}
|
|
133
|
-
console.
|
|
130
|
+
console.log(`Received session termination request for session ${sessionId}`);
|
|
134
131
|
try {
|
|
135
132
|
const transport = transports.get(sessionId);
|
|
136
133
|
await transport.handleRequest(req, res);
|
|
137
134
|
}
|
|
138
135
|
catch (error) {
|
|
139
|
-
console.
|
|
136
|
+
console.log("Error handling session termination:", error);
|
|
140
137
|
if (!res.headersSent) {
|
|
141
138
|
res.status(500).json({
|
|
142
|
-
jsonrpc:
|
|
139
|
+
jsonrpc: "2.0",
|
|
143
140
|
error: {
|
|
144
141
|
code: -32603,
|
|
145
|
-
message:
|
|
142
|
+
message: "Error handling session termination",
|
|
146
143
|
},
|
|
147
144
|
id: req?.body?.id,
|
|
148
145
|
});
|
|
@@ -152,23 +149,37 @@ app.delete('/mcp', async (req, res) => {
|
|
|
152
149
|
});
|
|
153
150
|
// Start the server
|
|
154
151
|
const PORT = process.env.PORT || 3001;
|
|
155
|
-
app.listen(PORT, () => {
|
|
152
|
+
const server = app.listen(PORT, () => {
|
|
156
153
|
console.error(`MCP Streamable HTTP Server listening on port ${PORT}`);
|
|
157
154
|
});
|
|
155
|
+
// Handle server errors
|
|
156
|
+
server.on("error", (err) => {
|
|
157
|
+
const code = typeof err === "object" && err !== null && "code" in err
|
|
158
|
+
? err.code
|
|
159
|
+
: undefined;
|
|
160
|
+
if (code === "EADDRINUSE") {
|
|
161
|
+
console.error(`Failed to start: Port ${PORT} is already in use. Set PORT to a free port or stop the conflicting process.`);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
console.error("HTTP server encountered an error while starting:", err);
|
|
165
|
+
}
|
|
166
|
+
// Ensure a non-zero exit so npm reports the failure instead of silently exiting
|
|
167
|
+
process.exit(1);
|
|
168
|
+
});
|
|
158
169
|
// Handle server shutdown
|
|
159
|
-
process.on(
|
|
160
|
-
console.
|
|
170
|
+
process.on("SIGINT", async () => {
|
|
171
|
+
console.log("Shutting down server...");
|
|
161
172
|
// Close all active transports to properly clean up resources
|
|
162
173
|
for (const sessionId in transports) {
|
|
163
174
|
try {
|
|
164
|
-
console.
|
|
175
|
+
console.log(`Closing transport for session ${sessionId}`);
|
|
165
176
|
await transports.get(sessionId).close();
|
|
166
177
|
transports.delete(sessionId);
|
|
167
178
|
}
|
|
168
179
|
catch (error) {
|
|
169
|
-
console.
|
|
180
|
+
console.log(`Error closing transport for session ${sessionId}:`, error);
|
|
170
181
|
}
|
|
171
182
|
}
|
|
172
|
-
console.
|
|
183
|
+
console.log("Server shutdown complete");
|
|
173
184
|
process.exit(0);
|
|
174
185
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@modelcontextprotocol/server-everything",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2026.1.14",
|
|
4
4
|
"description": "MCP server that exercises all the features of the MCP protocol",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"mcpName": "io.github.modelcontextprotocol/server-everything",
|
|
@@ -19,15 +19,17 @@
|
|
|
19
19
|
"dist"
|
|
20
20
|
],
|
|
21
21
|
"scripts": {
|
|
22
|
-
"build": "tsc && shx cp
|
|
22
|
+
"build": "tsc && shx cp -r docs dist/ && shx chmod +x dist/*.js",
|
|
23
23
|
"prepare": "npm run build",
|
|
24
24
|
"watch": "tsc --watch",
|
|
25
|
-
"start": "node dist/index.js",
|
|
26
|
-
"start:sse": "node dist/
|
|
27
|
-
"start:streamableHttp": "node dist/
|
|
25
|
+
"start:stdio": "node dist/index.js stdio",
|
|
26
|
+
"start:sse": "node dist/index.js sse",
|
|
27
|
+
"start:streamableHttp": "node dist/index.js streamableHttp",
|
|
28
|
+
"prettier:fix": "prettier --write .",
|
|
29
|
+
"prettier:check": "prettier --check ."
|
|
28
30
|
},
|
|
29
31
|
"dependencies": {
|
|
30
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
32
|
+
"@modelcontextprotocol/sdk": "^1.25.2",
|
|
31
33
|
"cors": "^2.8.5",
|
|
32
34
|
"express": "^5.2.1",
|
|
33
35
|
"jszip": "^3.10.1",
|
|
@@ -38,6 +40,7 @@
|
|
|
38
40
|
"@types/cors": "^2.8.19",
|
|
39
41
|
"@types/express": "^5.0.6",
|
|
40
42
|
"shx": "^0.3.4",
|
|
41
|
-
"typescript": "^5.6.2"
|
|
43
|
+
"typescript": "^5.6.2",
|
|
44
|
+
"prettier": "^2.8.8"
|
|
42
45
|
}
|
|
43
46
|
}
|