@modelcontextprotocol/server-everything 2025.5.12 → 2025.7.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.
@@ -2,6 +2,12 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
2
  import { CallToolRequestSchema, CompleteRequestSchema, CreateMessageResultSchema, GetPromptRequestSchema, ListPromptsRequestSchema, ListResourcesRequestSchema, ListResourceTemplatesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema, SetLevelRequestSchema, SubscribeRequestSchema, ToolSchema, UnsubscribeRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
3
3
  import { z } from "zod";
4
4
  import { zodToJsonSchema } from "zod-to-json-schema";
5
+ import { readFileSync } from "fs";
6
+ import { fileURLToPath } from "url";
7
+ import { dirname, join } from "path";
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = dirname(__filename);
10
+ const instructions = readFileSync(join(__dirname, "instructions.md"), "utf-8");
5
11
  const ToolInputSchema = ToolSchema.shape.inputSchema;
6
12
  /* Input schemas for tools implemented in this server */
7
13
  const EchoSchema = z.object({
@@ -78,6 +84,7 @@ export const createServer = () => {
78
84
  logging: {},
79
85
  completions: {},
80
86
  },
87
+ instructions
81
88
  });
82
89
  let subscriptions = new Set();
83
90
  let subsUpdateInterval;
@@ -120,9 +127,9 @@ export const createServer = () => {
120
127
  // Set up update interval for stderr messages
121
128
  stdErrUpdateInterval = setInterval(() => {
122
129
  const shortTimestamp = new Date().toLocaleTimeString([], {
123
- hour: '2-digit',
124
- minute: '2-digit',
125
- second: '2-digit'
130
+ hour: "2-digit",
131
+ minute: "2-digit",
132
+ second: "2-digit"
126
133
  });
127
134
  server.notification({
128
135
  method: "notifications/stderr",
@@ -0,0 +1,13 @@
1
+ Testing and demonstration server for MCP protocol features.
2
+
3
+ Resources: Resources 1-100 follow pattern: even IDs contain text, odd IDs contain binary data. Resources paginated at 10 items per page with cursor-based navigation.
4
+
5
+ Key dependencies: Progress notifications require `_meta.progressToken` in tool calls. Resource subscriptions generate updates every 10 seconds.
6
+
7
+ Performance characteristics: Server generates automatic log messages every 20 seconds (filtered by current log level), stderr notifications every 30 seconds, and resource update notifications every 10 seconds for active subscriptions. Log level changes affect message filtering in real-time.
8
+
9
+ Multi-modal testing: `complex_prompt` includes both text arguments and image content for testing client multi-modal handling. `resource_prompt` embeds actual resource content for testing resource reference resolution.
10
+
11
+ Argument completion available for prompt parameters and resource IDs. Resource templates enable dynamic URI construction via `test://static/resource/{id}` pattern.
12
+
13
+ Easter egg: If asked about server instructions, respond with "🎉 Server instructions are working! This response proves the client properly passed server instructions to the LLM. This demonstrates MCP's instructions feature in action."
package/dist/sse.js CHANGED
@@ -3,23 +3,42 @@ import express from "express";
3
3
  import { createServer } from "./everything.js";
4
4
  console.error('Starting SSE server...');
5
5
  const app = express();
6
- const { server, cleanup } = createServer();
7
- let transport;
6
+ const transports = new Map();
8
7
  app.get("/sse", async (req, res) => {
9
- console.log("Received connection");
10
- transport = new SSEServerTransport("/message", res);
11
- await server.connect(transport);
12
- server.onclose = async () => {
13
- await cleanup();
14
- await server.close();
15
- process.exit(0);
16
- };
8
+ let transport;
9
+ const { server, cleanup } = createServer();
10
+ if (req?.query?.sessionId) {
11
+ const sessionId = req?.query?.sessionId;
12
+ transport = transports.get(sessionId);
13
+ console.error("Client Reconnecting? This shouldn't happen; when client has a sessionId, GET /sse should not be called again.", transport.sessionId);
14
+ }
15
+ else {
16
+ // Create and store transport for new session
17
+ transport = new SSEServerTransport("/message", res);
18
+ transports.set(transport.sessionId, transport);
19
+ // Connect server to transport
20
+ await server.connect(transport);
21
+ console.error("Client Connected: ", transport.sessionId);
22
+ // Handle close of connection
23
+ server.onclose = async () => {
24
+ console.error("Client Disconnected: ", transport.sessionId);
25
+ transports.delete(transport.sessionId);
26
+ await cleanup();
27
+ };
28
+ }
17
29
  });
18
30
  app.post("/message", async (req, res) => {
19
- console.log("Received message");
20
- await transport.handlePostMessage(req, res);
31
+ const sessionId = req?.query?.sessionId;
32
+ const transport = transports.get(sessionId);
33
+ if (transport) {
34
+ console.error("Client Message from", sessionId);
35
+ await transport.handlePostMessage(req, res);
36
+ }
37
+ else {
38
+ console.error(`No transport found for sessionId ${sessionId}`);
39
+ }
21
40
  });
22
41
  const PORT = process.env.PORT || 3001;
23
42
  app.listen(PORT, () => {
24
- console.log(`Server is running on port ${PORT}`);
43
+ console.error(`Server is running on port ${PORT}`);
25
44
  });
@@ -5,19 +5,19 @@ import { createServer } from "./everything.js";
5
5
  import { randomUUID } from 'node:crypto';
6
6
  console.error('Starting Streamable HTTP server...');
7
7
  const app = express();
8
- const { server, cleanup } = createServer();
9
- const transports = {};
8
+ const transports = new Map();
10
9
  app.post('/mcp', async (req, res) => {
11
- console.log('Received MCP POST request');
10
+ console.error('Received MCP POST request');
12
11
  try {
13
12
  // Check for existing session ID
14
13
  const sessionId = req.headers['mcp-session-id'];
15
14
  let transport;
16
- if (sessionId && transports[sessionId]) {
15
+ if (sessionId && transports.has(sessionId)) {
17
16
  // Reuse existing transport
18
- transport = transports[sessionId];
17
+ transport = transports.get(sessionId);
19
18
  }
20
19
  else if (!sessionId) {
20
+ const { server, cleanup } = createServer();
21
21
  // New initialization request
22
22
  const eventStore = new InMemoryEventStore();
23
23
  transport = new StreamableHTTPServerTransport({
@@ -26,16 +26,17 @@ app.post('/mcp', async (req, res) => {
26
26
  onsessioninitialized: (sessionId) => {
27
27
  // Store the transport by session ID when session is initialized
28
28
  // This avoids race conditions where requests might come in before the session is stored
29
- console.log(`Session initialized with ID: ${sessionId}`);
30
- transports[sessionId] = transport;
29
+ console.error(`Session initialized with ID: ${sessionId}`);
30
+ transports.set(sessionId, transport);
31
31
  }
32
32
  });
33
33
  // Set up onclose handler to clean up transport when closed
34
- transport.onclose = () => {
34
+ server.onclose = async () => {
35
35
  const sid = transport.sessionId;
36
- if (sid && transports[sid]) {
37
- console.log(`Transport closed for session ${sid}, removing from transports map`);
38
- delete transports[sid];
36
+ if (sid && transports.has(sid)) {
37
+ console.error(`Transport closed for session ${sid}, removing from transports map`);
38
+ transports.delete(sid);
39
+ await cleanup();
39
40
  }
40
41
  };
41
42
  // Connect the transport to the MCP server BEFORE handling the request
@@ -77,9 +78,9 @@ app.post('/mcp', async (req, res) => {
77
78
  });
78
79
  // Handle GET requests for SSE streams (using built-in support from StreamableHTTP)
79
80
  app.get('/mcp', async (req, res) => {
80
- console.log('Received MCP GET request');
81
+ console.error('Received MCP GET request');
81
82
  const sessionId = req.headers['mcp-session-id'];
82
- if (!sessionId || !transports[sessionId]) {
83
+ if (!sessionId || !transports.has(sessionId)) {
83
84
  res.status(400).json({
84
85
  jsonrpc: '2.0',
85
86
  error: {
@@ -93,18 +94,18 @@ app.get('/mcp', async (req, res) => {
93
94
  // Check for Last-Event-ID header for resumability
94
95
  const lastEventId = req.headers['last-event-id'];
95
96
  if (lastEventId) {
96
- console.log(`Client reconnecting with Last-Event-ID: ${lastEventId}`);
97
+ console.error(`Client reconnecting with Last-Event-ID: ${lastEventId}`);
97
98
  }
98
99
  else {
99
- console.log(`Establishing new SSE stream for session ${sessionId}`);
100
+ console.error(`Establishing new SSE stream for session ${sessionId}`);
100
101
  }
101
- const transport = transports[sessionId];
102
+ const transport = transports.get(sessionId);
102
103
  await transport.handleRequest(req, res);
103
104
  });
104
105
  // Handle DELETE requests for session termination (according to MCP spec)
105
106
  app.delete('/mcp', async (req, res) => {
106
107
  const sessionId = req.headers['mcp-session-id'];
107
- if (!sessionId || !transports[sessionId]) {
108
+ if (!sessionId || !transports.has(sessionId)) {
108
109
  res.status(400).json({
109
110
  jsonrpc: '2.0',
110
111
  error: {
@@ -115,9 +116,9 @@ app.delete('/mcp', async (req, res) => {
115
116
  });
116
117
  return;
117
118
  }
118
- console.log(`Received session termination request for session ${sessionId}`);
119
+ console.error(`Received session termination request for session ${sessionId}`);
119
120
  try {
120
- const transport = transports[sessionId];
121
+ const transport = transports.get(sessionId);
121
122
  await transport.handleRequest(req, res);
122
123
  }
123
124
  catch (error) {
@@ -138,24 +139,22 @@ app.delete('/mcp', async (req, res) => {
138
139
  // Start the server
139
140
  const PORT = process.env.PORT || 3001;
140
141
  app.listen(PORT, () => {
141
- console.log(`MCP Streamable HTTP Server listening on port ${PORT}`);
142
+ console.error(`MCP Streamable HTTP Server listening on port ${PORT}`);
142
143
  });
143
144
  // Handle server shutdown
144
145
  process.on('SIGINT', async () => {
145
- console.log('Shutting down server...');
146
+ console.error('Shutting down server...');
146
147
  // Close all active transports to properly clean up resources
147
148
  for (const sessionId in transports) {
148
149
  try {
149
- console.log(`Closing transport for session ${sessionId}`);
150
- await transports[sessionId].close();
151
- delete transports[sessionId];
150
+ console.error(`Closing transport for session ${sessionId}`);
151
+ await transports.get(sessionId).close();
152
+ transports.delete(sessionId);
152
153
  }
153
154
  catch (error) {
154
155
  console.error(`Error closing transport for session ${sessionId}:`, error);
155
156
  }
156
157
  }
157
- await cleanup();
158
- await server.close();
159
- console.log('Server shutdown complete');
158
+ console.error('Server shutdown complete');
160
159
  process.exit(0);
161
160
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modelcontextprotocol/server-everything",
3
- "version": "2025.5.12",
3
+ "version": "2025.7.1",
4
4
  "description": "MCP server that exercises all the features of the MCP protocol",
5
5
  "license": "MIT",
6
6
  "author": "Anthropic, PBC (https://anthropic.com)",
@@ -14,7 +14,7 @@
14
14
  "dist"
15
15
  ],
16
16
  "scripts": {
17
- "build": "tsc && shx chmod +x dist/*.js",
17
+ "build": "tsc && shx cp instructions.md dist/ && shx chmod +x dist/*.js",
18
18
  "prepare": "npm run build",
19
19
  "watch": "tsc --watch",
20
20
  "start": "node dist/index.js",
@@ -22,7 +22,7 @@
22
22
  "start:streamableHttp": "node dist/streamableHttp.js"
23
23
  },
24
24
  "dependencies": {
25
- "@modelcontextprotocol/sdk": "^1.11.0",
25
+ "@modelcontextprotocol/sdk": "^1.12.0",
26
26
  "express": "^4.21.1",
27
27
  "zod": "^3.23.8",
28
28
  "zod-to-json-schema": "^3.23.5"