@modelcontextprotocol/server-everything 2025.1.14 → 2025.4.8

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 CHANGED
@@ -45,6 +45,33 @@ This MCP server attempts to exercise all the features of the MCP protocol. It is
45
45
  - No inputs required
46
46
  - Returns: JSON string of all environment variables
47
47
 
48
+ 7. `annotatedMessage`
49
+ - Demonstrates how annotations can be used to provide metadata about content
50
+ - Inputs:
51
+ - `messageType` (enum: "error" | "success" | "debug"): Type of message to demonstrate different annotation patterns
52
+ - `includeImage` (boolean, default: false): Whether to include an example image
53
+ - Returns: Content with varying annotations:
54
+ - Error messages: High priority (1.0), visible to both user and assistant
55
+ - Success messages: Medium priority (0.7), user-focused
56
+ - Debug messages: Low priority (0.3), assistant-focused
57
+ - Optional image: Medium priority (0.5), user-focused
58
+ - Example annotations:
59
+ ```json
60
+ {
61
+ "priority": 1.0,
62
+ "audience": ["user", "assistant"]
63
+ }
64
+ ```
65
+
66
+ 8. `getResourceReference`
67
+ - Returns a resource reference that can be used by MCP clients
68
+ - Inputs:
69
+ - `resourceId` (number, 1-100): ID of the resource to reference
70
+ - Returns: A resource reference with:
71
+ - Text introduction
72
+ - Embedded resource with `type: "resource"`
73
+ - Text instruction for using the resource URI
74
+
48
75
  ### Resources
49
76
 
50
77
  The server provides 100 test resources in two formats:
@@ -78,6 +105,27 @@ Resource features:
78
105
  - `style` (string): Output style preference
79
106
  - Returns: Multi-turn conversation with images
80
107
 
108
+ 3. `resource_prompt`
109
+ - Demonstrates embedding resource references in prompts
110
+ - Required arguments:
111
+ - `resourceId` (number): ID of the resource to embed (1-100)
112
+ - Returns: Multi-turn conversation with an embedded resource reference
113
+ - Shows how to include resources directly in prompt messages
114
+
115
+ ### Logging
116
+
117
+ The server sends random-leveled log messages every 15 seconds, e.g.:
118
+
119
+ ```json
120
+ {
121
+ "method": "notifications/message",
122
+ "params": {
123
+ "level": "info",
124
+ "data": "Info-level message"
125
+ }
126
+ }
127
+ ```
128
+
81
129
  ## Usage with Claude Desktop
82
130
 
83
131
  Add to your `claude_desktop_config.json`:
@@ -33,6 +33,22 @@ const EXAMPLE_COMPLETIONS = {
33
33
  resourceId: ["1", "2", "3", "4", "5"],
34
34
  };
35
35
  const GetTinyImageSchema = z.object({});
36
+ const AnnotatedMessageSchema = z.object({
37
+ messageType: z
38
+ .enum(["error", "success", "debug"])
39
+ .describe("Type of message to demonstrate different annotation patterns"),
40
+ includeImage: z
41
+ .boolean()
42
+ .default(false)
43
+ .describe("Whether to include an example image"),
44
+ });
45
+ const GetResourceReferenceSchema = z.object({
46
+ resourceId: z
47
+ .number()
48
+ .min(1)
49
+ .max(100)
50
+ .describe("ID of the resource to reference (1-100)"),
51
+ });
36
52
  var ToolName;
37
53
  (function (ToolName) {
38
54
  ToolName["ECHO"] = "echo";
@@ -41,11 +57,14 @@ var ToolName;
41
57
  ToolName["PRINT_ENV"] = "printEnv";
42
58
  ToolName["SAMPLE_LLM"] = "sampleLLM";
43
59
  ToolName["GET_TINY_IMAGE"] = "getTinyImage";
60
+ ToolName["ANNOTATED_MESSAGE"] = "annotatedMessage";
61
+ ToolName["GET_RESOURCE_REFERENCE"] = "getResourceReference";
44
62
  })(ToolName || (ToolName = {}));
45
63
  var PromptName;
46
64
  (function (PromptName) {
47
65
  PromptName["SIMPLE"] = "simple_prompt";
48
66
  PromptName["COMPLEX"] = "complex_prompt";
67
+ PromptName["RESOURCE"] = "resource_prompt";
49
68
  })(PromptName || (PromptName = {}));
50
69
  export const createServer = () => {
51
70
  const server = new Server({
@@ -60,9 +79,9 @@ export const createServer = () => {
60
79
  },
61
80
  });
62
81
  let subscriptions = new Set();
63
- let updateInterval;
82
+ let subsUpdateInterval;
64
83
  // Set up update interval for subscribed resources
65
- updateInterval = setInterval(() => {
84
+ subsUpdateInterval = setInterval(() => {
66
85
  for (const uri of subscriptions) {
67
86
  server.notification({
68
87
  method: "notifications/resources/updated",
@@ -70,6 +89,32 @@ export const createServer = () => {
70
89
  });
71
90
  }
72
91
  }, 5000);
92
+ let logLevel = "debug";
93
+ let logsUpdateInterval;
94
+ const messages = [
95
+ { level: "debug", data: "Debug-level message" },
96
+ { level: "info", data: "Info-level message" },
97
+ { level: "notice", data: "Notice-level message" },
98
+ { level: "warning", data: "Warning-level message" },
99
+ { level: "error", data: "Error-level message" },
100
+ { level: "critical", data: "Critical-level message" },
101
+ { level: "alert", data: "Alert level-message" },
102
+ { level: "emergency", data: "Emergency-level message" },
103
+ ];
104
+ const isMessageIgnored = (level) => {
105
+ const currentLevel = messages.findIndex((msg) => logLevel === msg.level);
106
+ const messageLevel = messages.findIndex((msg) => level === msg.level);
107
+ return messageLevel < currentLevel;
108
+ };
109
+ // Set up update interval for random log messages
110
+ logsUpdateInterval = setInterval(() => {
111
+ let message = {
112
+ method: "notifications/message",
113
+ params: messages[Math.floor(Math.random() * messages.length)],
114
+ };
115
+ if (!isMessageIgnored(message.params.level))
116
+ server.notification(message);
117
+ }, 15000);
73
118
  // Helper method to request sampling from client
74
119
  const requestSampling = async (context, uri, maxTokens = 100) => {
75
120
  const request = {
@@ -191,6 +236,17 @@ export const createServer = () => {
191
236
  },
192
237
  ],
193
238
  },
239
+ {
240
+ name: PromptName.RESOURCE,
241
+ description: "A prompt that includes an embedded resource reference",
242
+ arguments: [
243
+ {
244
+ name: "resourceId",
245
+ description: "Resource ID to include (1-100)",
246
+ required: true,
247
+ },
248
+ ],
249
+ },
194
250
  ],
195
251
  };
196
252
  });
@@ -237,6 +293,32 @@ export const createServer = () => {
237
293
  ],
238
294
  };
239
295
  }
296
+ if (name === PromptName.RESOURCE) {
297
+ const resourceId = parseInt(args?.resourceId, 10);
298
+ if (isNaN(resourceId) || resourceId < 1 || resourceId > 100) {
299
+ throw new Error(`Invalid resourceId: ${args?.resourceId}. Must be a number between 1 and 100.`);
300
+ }
301
+ const resourceIndex = resourceId - 1;
302
+ const resource = ALL_RESOURCES[resourceIndex];
303
+ return {
304
+ messages: [
305
+ {
306
+ role: "user",
307
+ content: {
308
+ type: "text",
309
+ text: `This prompt includes Resource ${resourceId}. Please analyze the following resource:`,
310
+ },
311
+ },
312
+ {
313
+ role: "user",
314
+ content: {
315
+ type: "resource",
316
+ resource: resource,
317
+ },
318
+ },
319
+ ],
320
+ };
321
+ }
240
322
  throw new Error(`Unknown prompt: ${name}`);
241
323
  });
242
324
  server.setRequestHandler(ListToolsRequestSchema, async () => {
@@ -271,6 +353,16 @@ export const createServer = () => {
271
353
  description: "Returns the MCP_TINY_IMAGE",
272
354
  inputSchema: zodToJsonSchema(GetTinyImageSchema),
273
355
  },
356
+ {
357
+ name: ToolName.ANNOTATED_MESSAGE,
358
+ description: "Demonstrates how annotations can be used to provide metadata about content",
359
+ inputSchema: zodToJsonSchema(AnnotatedMessageSchema),
360
+ },
361
+ {
362
+ name: ToolName.GET_RESOURCE_REFERENCE,
363
+ description: "Returns a resource reference that can be used by MCP clients",
364
+ inputSchema: zodToJsonSchema(GetResourceReferenceSchema),
365
+ },
274
366
  ];
275
367
  return { tools };
276
368
  });
@@ -336,7 +428,9 @@ export const createServer = () => {
336
428
  const { prompt, maxTokens } = validatedArgs;
337
429
  const result = await requestSampling(prompt, ToolName.SAMPLE_LLM, maxTokens);
338
430
  return {
339
- content: [{ type: "text", text: `LLM sampling result: ${result.content.text}` }],
431
+ content: [
432
+ { type: "text", text: `LLM sampling result: ${result.content.text}` },
433
+ ],
340
434
  };
341
435
  }
342
436
  if (name === ToolName.GET_TINY_IMAGE) {
@@ -359,6 +453,79 @@ export const createServer = () => {
359
453
  ],
360
454
  };
361
455
  }
456
+ if (name === ToolName.GET_RESOURCE_REFERENCE) {
457
+ const validatedArgs = GetResourceReferenceSchema.parse(args);
458
+ const resourceId = validatedArgs.resourceId;
459
+ const resourceIndex = resourceId - 1;
460
+ if (resourceIndex < 0 || resourceIndex >= ALL_RESOURCES.length) {
461
+ throw new Error(`Resource with ID ${resourceId} does not exist`);
462
+ }
463
+ const resource = ALL_RESOURCES[resourceIndex];
464
+ return {
465
+ content: [
466
+ {
467
+ type: "text",
468
+ text: `Returning resource reference for Resource ${resourceId}:`,
469
+ },
470
+ {
471
+ type: "resource",
472
+ resource: resource,
473
+ },
474
+ {
475
+ type: "text",
476
+ text: `You can access this resource using the URI: ${resource.uri}`,
477
+ },
478
+ ],
479
+ };
480
+ }
481
+ if (name === ToolName.ANNOTATED_MESSAGE) {
482
+ const { messageType, includeImage } = AnnotatedMessageSchema.parse(args);
483
+ const content = [];
484
+ // Main message with different priorities/audiences based on type
485
+ if (messageType === "error") {
486
+ content.push({
487
+ type: "text",
488
+ text: "Error: Operation failed",
489
+ annotations: {
490
+ priority: 1.0, // Errors are highest priority
491
+ audience: ["user", "assistant"], // Both need to know about errors
492
+ },
493
+ });
494
+ }
495
+ else if (messageType === "success") {
496
+ content.push({
497
+ type: "text",
498
+ text: "Operation completed successfully",
499
+ annotations: {
500
+ priority: 0.7, // Success messages are important but not critical
501
+ audience: ["user"], // Success mainly for user consumption
502
+ },
503
+ });
504
+ }
505
+ else if (messageType === "debug") {
506
+ content.push({
507
+ type: "text",
508
+ text: "Debug: Cache hit ratio 0.95, latency 150ms",
509
+ annotations: {
510
+ priority: 0.3, // Debug info is low priority
511
+ audience: ["assistant"], // Technical details for assistant
512
+ },
513
+ });
514
+ }
515
+ // Optional image with its own annotations
516
+ if (includeImage) {
517
+ content.push({
518
+ type: "image",
519
+ data: MCP_TINY_IMAGE,
520
+ mimeType: "image/png",
521
+ annotations: {
522
+ priority: 0.5,
523
+ audience: ["user"], // Images primarily for user visualization
524
+ },
525
+ });
526
+ }
527
+ return { content };
528
+ }
362
529
  throw new Error(`Unknown tool: ${name}`);
363
530
  });
364
531
  server.setRequestHandler(CompleteRequestSchema, async (request) => {
@@ -368,7 +535,7 @@ export const createServer = () => {
368
535
  if (!resourceId)
369
536
  return { completion: { values: [] } };
370
537
  // Filter resource IDs that start with the input value
371
- const values = EXAMPLE_COMPLETIONS.resourceId.filter(id => id.startsWith(argument.value));
538
+ const values = EXAMPLE_COMPLETIONS.resourceId.filter((id) => id.startsWith(argument.value));
372
539
  return { completion: { values, hasMore: false, total: values.length } };
373
540
  }
374
541
  if (ref.type === "ref/prompt") {
@@ -376,28 +543,30 @@ export const createServer = () => {
376
543
  const completions = EXAMPLE_COMPLETIONS[argument.name];
377
544
  if (!completions)
378
545
  return { completion: { values: [] } };
379
- const values = completions.filter(value => value.startsWith(argument.value));
546
+ const values = completions.filter((value) => value.startsWith(argument.value));
380
547
  return { completion: { values, hasMore: false, total: values.length } };
381
548
  }
382
549
  throw new Error(`Unknown reference type`);
383
550
  });
384
551
  server.setRequestHandler(SetLevelRequestSchema, async (request) => {
385
552
  const { level } = request.params;
553
+ logLevel = level;
386
554
  // Demonstrate different log levels
387
555
  await server.notification({
388
556
  method: "notifications/message",
389
557
  params: {
390
558
  level: "debug",
391
559
  logger: "test-server",
392
- data: `Logging level set to: ${level}`,
560
+ data: `Logging level set to: ${logLevel}`,
393
561
  },
394
562
  });
395
563
  return {};
396
564
  });
397
565
  const cleanup = async () => {
398
- if (updateInterval) {
399
- clearInterval(updateInterval);
400
- }
566
+ if (subsUpdateInterval)
567
+ clearInterval(subsUpdateInterval);
568
+ if (logsUpdateInterval)
569
+ clearInterval(logsUpdateInterval);
401
570
  };
402
571
  return { server, cleanup };
403
572
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modelcontextprotocol/server-everything",
3
- "version": "2025.1.14",
3
+ "version": "2025.4.8",
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)",
@@ -16,7 +16,9 @@
16
16
  "scripts": {
17
17
  "build": "tsc && shx chmod +x dist/*.js",
18
18
  "prepare": "npm run build",
19
- "watch": "tsc --watch"
19
+ "watch": "tsc --watch",
20
+ "start": "node dist/index.js",
21
+ "start:sse": "node dist/sse.js"
20
22
  },
21
23
  "dependencies": {
22
24
  "@modelcontextprotocol/sdk": "1.0.1",