Skip to content

Commit 71aeb9a

Browse files
committed
add examples with notifications
1 parent b37a2e1 commit 71aeb9a

File tree

3 files changed

+113
-6
lines changed

3 files changed

+113
-6
lines changed

src/examples/client/simpleStreamableHttp.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import {
1010
GetPromptRequest,
1111
GetPromptResultSchema,
1212
ListResourcesRequest,
13-
ListResourcesResultSchema
13+
ListResourcesResultSchema,
14+
LoggingMessageNotificationSchema
1415
} from '../../types.js';
1516

1617
async function main(): Promise<void> {
@@ -19,12 +20,17 @@ async function main(): Promise<void> {
1920
name: 'example-client',
2021
version: '1.0.0'
2122
});
23+
2224
const transport = new StreamableHTTPClientTransport(
2325
new URL('http://localhost:3000/mcp')
2426
);
2527

2628
// Connect the client using the transport and initialize the server
2729
await client.connect(transport);
30+
client.setNotificationHandler(LoggingMessageNotificationSchema, (notification) => {
31+
console.log(`Notification received: ${notification.params.level} - ${notification.params.data}`);
32+
});
33+
2834

2935
console.log('Connected to MCP server');
3036
// List available tools
@@ -46,6 +52,23 @@ async function main(): Promise<void> {
4652
const greetResult = await client.request(greetRequest, CallToolResultSchema);
4753
console.log('Greeting result:', greetResult.content[0].text);
4854

55+
// Call the new 'multi-greet' tool
56+
console.log('\nCalling multi-greet tool (with notifications)...');
57+
const multiGreetRequest: CallToolRequest = {
58+
method: 'tools/call',
59+
params: {
60+
name: 'multi-greet',
61+
arguments: { name: 'MCP User' }
62+
}
63+
};
64+
const multiGreetResult = await client.request(multiGreetRequest, CallToolResultSchema);
65+
console.log('Multi-greet results:');
66+
multiGreetResult.content.forEach(item => {
67+
if (item.type === 'text') {
68+
console.log(`- ${item.text}`);
69+
}
70+
});
71+
4972
// List available prompts
5073
try {
5174
const promptsRequest: ListPromptsRequest = {

src/examples/server/jsonResponseStreamableHttp.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ import { CallToolResult } from '../../types.js';
99
const server = new McpServer({
1010
name: 'json-response-streamable-http-server',
1111
version: '1.0.0',
12+
}, {
13+
capabilities: {
14+
logging: {},
15+
}
1216
});
1317

1418
// Register a simple tool that returns a greeting
@@ -30,6 +34,46 @@ server.tool(
3034
}
3135
);
3236

37+
// Register a tool that sends multiple greetings with notifications
38+
server.tool(
39+
'multi-greet',
40+
'A tool that sends different greetings with delays between them',
41+
{
42+
name: z.string().describe('Name to greet'),
43+
},
44+
async ({ name }, { sendNotification }): Promise<CallToolResult> => {
45+
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
46+
47+
await sendNotification({
48+
method: "notifications/message",
49+
params: { level: "debug", data: `Starting multi-greet for ${name}` }
50+
});
51+
52+
await sleep(1000); // Wait 1 second before first greeting
53+
54+
await sendNotification({
55+
method: "notifications/message",
56+
params: { level: "info", data: `Sending first greeting to ${name}` }
57+
});
58+
59+
await sleep(1000); // Wait another second before second greeting
60+
61+
await sendNotification({
62+
method: "notifications/message",
63+
params: { level: "info", data: `Sending second greeting to ${name}` }
64+
});
65+
66+
return {
67+
content: [
68+
{
69+
type: 'text',
70+
text: `Good morning, ${name}!`,
71+
}
72+
],
73+
};
74+
}
75+
);
76+
3377
const app = express();
3478
app.use(express.json());
3579

src/examples/server/simpleStreamableHttp.ts

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { CallToolResult, GetPromptResult, ReadResourceResult } from '../../types
99
const server = new McpServer({
1010
name: 'simple-streamable-http-server',
1111
version: '1.0.0',
12-
});
12+
}, { capabilities: { logging: {} } });
1313

1414
// Register a simple tool that returns a greeting
1515
server.tool(
@@ -30,6 +30,46 @@ server.tool(
3030
}
3131
);
3232

33+
// Register a tool that sends multiple greetings with notifications
34+
server.tool(
35+
'multi-greet',
36+
'A tool that sends different greetings with delays between them',
37+
{
38+
name: z.string().describe('Name to greet'),
39+
},
40+
async ({ name }, { sendNotification }): Promise<CallToolResult> => {
41+
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
42+
43+
await sendNotification({
44+
method: "notifications/message",
45+
params: { level: "debug", data: `Starting multi-greet for ${name}` }
46+
});
47+
48+
await sleep(1000); // Wait 1 second before first greeting
49+
50+
await sendNotification({
51+
method: "notifications/message",
52+
params: { level: "info", data: `Sending first greeting to ${name}` }
53+
});
54+
55+
await sleep(1000); // Wait another second before second greeting
56+
57+
await sendNotification({
58+
method: "notifications/message",
59+
params: { level: "info", data: `Sending second greeting to ${name}` }
60+
});
61+
62+
return {
63+
content: [
64+
{
65+
type: 'text',
66+
text: `Good morning, ${name}!`,
67+
}
68+
],
69+
};
70+
}
71+
);
72+
3373
// Register a simple prompt
3474
server.prompt(
3575
'greeting-template',
@@ -81,7 +121,7 @@ app.post('/mcp', async (req: Request, res: Response) => {
81121
// Check for existing session ID
82122
const sessionId = req.headers['mcp-session-id'] as string | undefined;
83123
let transport: StreamableHTTPServerTransport;
84-
124+
85125
if (sessionId && transports[sessionId]) {
86126
// Reuse existing transport
87127
transport = transports[sessionId];
@@ -90,14 +130,14 @@ app.post('/mcp', async (req: Request, res: Response) => {
90130
transport = new StreamableHTTPServerTransport({
91131
sessionIdGenerator: () => randomUUID(),
92132
});
93-
133+
94134
// Connect the transport to the MCP server BEFORE handling the request
95135
// so responses can flow back through the same transport
96136
await server.connect(transport);
97-
137+
98138
// After handling the request, if we get a session ID back, store the transport
99139
await transport.handleRequest(req, res, req.body);
100-
140+
101141
// Store the transport by session ID for future requests
102142
if (transport.sessionId) {
103143
transports[transport.sessionId] = transport;

0 commit comments

Comments
 (0)