Skip to content

Commit d553b09

Browse files
authored
Merge branch 'main' into paddle
2 parents eb013df + fc5e6f4 commit d553b09

File tree

6 files changed

+201
-42
lines changed

6 files changed

+201
-42
lines changed

README.md

Lines changed: 15 additions & 1 deletion
Large diffs are not rendered by default.

src/everything/CLAUDE.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# MCP "Everything" Server - Development Guidelines
2+
3+
## Build, Test & Run Commands
4+
- Build: `npm run build` - Compiles TypeScript to JavaScript
5+
- Watch mode: `npm run watch` - Watches for changes and rebuilds automatically
6+
- Run server: `npm run start` - Starts the MCP server using stdio transport
7+
- Run SSE server: `npm run start:sse` - Starts the MCP server with SSE transport
8+
- Prepare release: `npm run prepare` - Builds the project for publishing
9+
10+
## Code Style Guidelines
11+
- Use ES modules with `.js` extension in import paths
12+
- Strictly type all functions and variables with TypeScript
13+
- Follow zod schema patterns for tool input validation
14+
- Prefer async/await over callbacks and Promise chains
15+
- Place all imports at top of file, grouped by external then internal
16+
- Use descriptive variable names that clearly indicate purpose
17+
- Implement proper cleanup for timers and resources in server shutdown
18+
- Follow camelCase for variables/functions, PascalCase for types/classes, UPPER_CASE for constants
19+
- Handle errors with try/catch blocks and provide clear error messages
20+
- Use consistent indentation (2 spaces) and trailing commas in multi-line objects

src/everything/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,15 @@ This MCP server attempts to exercise all the features of the MCP protocol. It is
6363
}
6464
```
6565

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+
6675
### Resources
6776

6877
The server provides 100 test resources in two formats:
@@ -96,6 +105,13 @@ Resource features:
96105
- `style` (string): Output style preference
97106
- Returns: Multi-turn conversation with images
98107

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+
99115
### Logging
100116

101117
The server sends random-leveled log messages every 15 seconds, e.g.:

src/everything/everything.ts

Lines changed: 132 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,21 @@ const EXAMPLE_COMPLETIONS = {
6262
const GetTinyImageSchema = z.object({});
6363

6464
const AnnotatedMessageSchema = z.object({
65-
messageType: z.enum(["error", "success", "debug"])
65+
messageType: z
66+
.enum(["error", "success", "debug"])
6667
.describe("Type of message to demonstrate different annotation patterns"),
67-
includeImage: z.boolean().default(false)
68-
.describe("Whether to include an example image")
68+
includeImage: z
69+
.boolean()
70+
.default(false)
71+
.describe("Whether to include an example image"),
72+
});
73+
74+
const GetResourceReferenceSchema = z.object({
75+
resourceId: z
76+
.number()
77+
.min(1)
78+
.max(100)
79+
.describe("ID of the resource to reference (1-100)"),
6980
});
7081

7182
enum ToolName {
@@ -76,11 +87,13 @@ enum ToolName {
7687
SAMPLE_LLM = "sampleLLM",
7788
GET_TINY_IMAGE = "getTinyImage",
7889
ANNOTATED_MESSAGE = "annotatedMessage",
90+
GET_RESOURCE_REFERENCE = "getResourceReference",
7991
}
8092

8193
enum PromptName {
8294
SIMPLE = "simple_prompt",
8395
COMPLEX = "complex_prompt",
96+
RESOURCE = "resource_prompt",
8497
}
8598

8699
export const createServer = () => {
@@ -96,7 +109,7 @@ export const createServer = () => {
96109
tools: {},
97110
logging: {},
98111
},
99-
},
112+
}
100113
);
101114

102115
let subscriptions: Set<string> = new Set();
@@ -115,36 +128,37 @@ export const createServer = () => {
115128
let logLevel: LoggingLevel = "debug";
116129
let logsUpdateInterval: NodeJS.Timeout | undefined;
117130
const messages = [
118-
{level: "debug", data: "Debug-level message"},
119-
{level: "info", data: "Info-level message"},
120-
{level: "notice", data: "Notice-level message"},
121-
{level: "warning", data: "Warning-level message"},
122-
{level: "error", data: "Error-level message"},
123-
{level: "critical", data: "Critical-level message"},
124-
{level: "alert", data: "Alert level-message"},
125-
{level: "emergency", data: "Emergency-level message"}
126-
]
127-
128-
const isMessageIgnored = (level:LoggingLevel):boolean => {
131+
{ level: "debug", data: "Debug-level message" },
132+
{ level: "info", data: "Info-level message" },
133+
{ level: "notice", data: "Notice-level message" },
134+
{ level: "warning", data: "Warning-level message" },
135+
{ level: "error", data: "Error-level message" },
136+
{ level: "critical", data: "Critical-level message" },
137+
{ level: "alert", data: "Alert level-message" },
138+
{ level: "emergency", data: "Emergency-level message" },
139+
];
140+
141+
const isMessageIgnored = (level: LoggingLevel): boolean => {
129142
const currentLevel = messages.findIndex((msg) => logLevel === msg.level);
130-
const messageLevel = messages.findIndex((msg) => level === msg.level);
143+
const messageLevel = messages.findIndex((msg) => level === msg.level);
131144
return messageLevel < currentLevel;
132-
}
145+
};
133146

134147
// Set up update interval for random log messages
135148
logsUpdateInterval = setInterval(() => {
136149
let message = {
137150
method: "notifications/message",
138151
params: messages[Math.floor(Math.random() * messages.length)],
139-
}
140-
if (!isMessageIgnored(message.params.level as LoggingLevel)) server.notification(message);
152+
};
153+
if (!isMessageIgnored(message.params.level as LoggingLevel))
154+
server.notification(message);
141155
}, 15000);
142156

143157
// Helper method to request sampling from client
144158
const requestSampling = async (
145159
context: string,
146160
uri: string,
147-
maxTokens: number = 100,
161+
maxTokens: number = 100
148162
) => {
149163
const request: CreateMessageRequest = {
150164
method: "sampling/createMessage",
@@ -280,6 +294,17 @@ export const createServer = () => {
280294
},
281295
],
282296
},
297+
{
298+
name: PromptName.RESOURCE,
299+
description: "A prompt that includes an embedded resource reference",
300+
arguments: [
301+
{
302+
name: "resourceId",
303+
description: "Resource ID to include (1-100)",
304+
required: true,
305+
},
306+
],
307+
},
283308
],
284309
};
285310
});
@@ -330,6 +355,37 @@ export const createServer = () => {
330355
};
331356
}
332357

358+
if (name === PromptName.RESOURCE) {
359+
const resourceId = parseInt(args?.resourceId as string, 10);
360+
if (isNaN(resourceId) || resourceId < 1 || resourceId > 100) {
361+
throw new Error(
362+
`Invalid resourceId: ${args?.resourceId}. Must be a number between 1 and 100.`
363+
);
364+
}
365+
366+
const resourceIndex = resourceId - 1;
367+
const resource = ALL_RESOURCES[resourceIndex];
368+
369+
return {
370+
messages: [
371+
{
372+
role: "user",
373+
content: {
374+
type: "text",
375+
text: `This prompt includes Resource ${resourceId}. Please analyze the following resource:`,
376+
},
377+
},
378+
{
379+
role: "user",
380+
content: {
381+
type: "resource",
382+
resource: resource,
383+
},
384+
},
385+
],
386+
};
387+
}
388+
333389
throw new Error(`Unknown prompt: ${name}`);
334390
});
335391

@@ -347,7 +403,8 @@ export const createServer = () => {
347403
},
348404
{
349405
name: ToolName.PRINT_ENV,
350-
description: "Prints all environment variables, helpful for debugging MCP server configuration",
406+
description:
407+
"Prints all environment variables, helpful for debugging MCP server configuration",
351408
inputSchema: zodToJsonSchema(PrintEnvSchema) as ToolInput,
352409
},
353410
{
@@ -368,9 +425,16 @@ export const createServer = () => {
368425
},
369426
{
370427
name: ToolName.ANNOTATED_MESSAGE,
371-
description: "Demonstrates how annotations can be used to provide metadata about content",
428+
description:
429+
"Demonstrates how annotations can be used to provide metadata about content",
372430
inputSchema: zodToJsonSchema(AnnotatedMessageSchema) as ToolInput,
373431
},
432+
{
433+
name: ToolName.GET_RESOURCE_REFERENCE,
434+
description:
435+
"Returns a resource reference that can be used by MCP clients",
436+
inputSchema: zodToJsonSchema(GetResourceReferenceSchema) as ToolInput,
437+
},
374438
];
375439

376440
return { tools };
@@ -407,7 +471,7 @@ export const createServer = () => {
407471

408472
for (let i = 1; i < steps + 1; i++) {
409473
await new Promise((resolve) =>
410-
setTimeout(resolve, stepDuration * 1000),
474+
setTimeout(resolve, stepDuration * 1000)
411475
);
412476

413477
if (progressToken !== undefined) {
@@ -450,10 +514,12 @@ export const createServer = () => {
450514
const result = await requestSampling(
451515
prompt,
452516
ToolName.SAMPLE_LLM,
453-
maxTokens,
517+
maxTokens
454518
);
455519
return {
456-
content: [{ type: "text", text: `LLM sampling result: ${result.content.text}` }],
520+
content: [
521+
{ type: "text", text: `LLM sampling result: ${result.content.text}` },
522+
],
457523
};
458524
}
459525

@@ -478,6 +544,35 @@ export const createServer = () => {
478544
};
479545
}
480546

547+
if (name === ToolName.GET_RESOURCE_REFERENCE) {
548+
const validatedArgs = GetResourceReferenceSchema.parse(args);
549+
const resourceId = validatedArgs.resourceId;
550+
551+
const resourceIndex = resourceId - 1;
552+
if (resourceIndex < 0 || resourceIndex >= ALL_RESOURCES.length) {
553+
throw new Error(`Resource with ID ${resourceId} does not exist`);
554+
}
555+
556+
const resource = ALL_RESOURCES[resourceIndex];
557+
558+
return {
559+
content: [
560+
{
561+
type: "text",
562+
text: `Returning resource reference for Resource ${resourceId}:`,
563+
},
564+
{
565+
type: "resource",
566+
resource: resource,
567+
},
568+
{
569+
type: "text",
570+
text: `You can access this resource using the URI: ${resource.uri}`,
571+
},
572+
],
573+
};
574+
}
575+
481576
if (name === ToolName.ANNOTATED_MESSAGE) {
482577
const { messageType, includeImage } = AnnotatedMessageSchema.parse(args);
483578

@@ -490,26 +585,26 @@ export const createServer = () => {
490585
text: "Error: Operation failed",
491586
annotations: {
492587
priority: 1.0, // Errors are highest priority
493-
audience: ["user", "assistant"] // Both need to know about errors
494-
}
588+
audience: ["user", "assistant"], // Both need to know about errors
589+
},
495590
});
496591
} else if (messageType === "success") {
497592
content.push({
498593
type: "text",
499594
text: "Operation completed successfully",
500595
annotations: {
501596
priority: 0.7, // Success messages are important but not critical
502-
audience: ["user"] // Success mainly for user consumption
503-
}
597+
audience: ["user"], // Success mainly for user consumption
598+
},
504599
});
505600
} else if (messageType === "debug") {
506601
content.push({
507602
type: "text",
508603
text: "Debug: Cache hit ratio 0.95, latency 150ms",
509604
annotations: {
510605
priority: 0.3, // Debug info is low priority
511-
audience: ["assistant"] // Technical details for assistant
512-
}
606+
audience: ["assistant"], // Technical details for assistant
607+
},
513608
});
514609
}
515610

@@ -521,8 +616,8 @@ export const createServer = () => {
521616
mimeType: "image/png",
522617
annotations: {
523618
priority: 0.5,
524-
audience: ["user"] // Images primarily for user visualization
525-
}
619+
audience: ["user"], // Images primarily for user visualization
620+
},
526621
});
527622
}
528623

@@ -540,18 +635,19 @@ export const createServer = () => {
540635
if (!resourceId) return { completion: { values: [] } };
541636

542637
// Filter resource IDs that start with the input value
543-
const values = EXAMPLE_COMPLETIONS.resourceId.filter(id =>
638+
const values = EXAMPLE_COMPLETIONS.resourceId.filter((id) =>
544639
id.startsWith(argument.value)
545640
);
546641
return { completion: { values, hasMore: false, total: values.length } };
547642
}
548643

549644
if (ref.type === "ref/prompt") {
550645
// Handle completion for prompt arguments
551-
const completions = EXAMPLE_COMPLETIONS[argument.name as keyof typeof EXAMPLE_COMPLETIONS];
646+
const completions =
647+
EXAMPLE_COMPLETIONS[argument.name as keyof typeof EXAMPLE_COMPLETIONS];
552648
if (!completions) return { completion: { values: [] } };
553649

554-
const values = completions.filter(value =>
650+
const values = completions.filter((value) =>
555651
value.startsWith(argument.value)
556652
);
557653
return { completion: { values, hasMore: false, total: values.length } };

src/github/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# GitHub MCP Server
22

3+
**Deprecation Notice:** Development for this project has been moved to GitHub in the http://github.com/github/github-mcp-server repo.
4+
5+
---
6+
37
MCP Server for the GitHub API, enabling file operations, repository management, search functionality, and more.
48

59
### Features

0 commit comments

Comments
 (0)