forked from modelcontextprotocol/typescript-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmultipleClientsParallel.ts
More file actions
157 lines (136 loc) · 5.17 KB
/
multipleClientsParallel.ts
File metadata and controls
157 lines (136 loc) · 5.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import type { CallToolRequest, CallToolResult } from '@modelcontextprotocol/client';
import { CallToolResultSchema, Client, StreamableHTTPClientTransport } from '@modelcontextprotocol/client';
/**
* Multiple Clients MCP Example
*
* This client demonstrates how to:
* 1. Create multiple MCP clients in parallel
* 2. Each client calls a single tool
* 3. Track notifications from each client independently
*/
// Command line args processing
const args = process.argv.slice(2);
const serverUrl = args[0] || 'http://localhost:3000/mcp';
interface ClientConfig {
id: string;
name: string;
toolName: string;
toolArguments: Record<string, string | number | boolean>;
}
async function createAndRunClient(config: ClientConfig): Promise<{ id: string; result: CallToolResult }> {
console.log(`[${config.id}] Creating client: ${config.name}`);
const client = new Client({
name: config.name,
version: '1.0.0'
});
const transport = new StreamableHTTPClientTransport(new URL(serverUrl));
// Set up client-specific error handler
client.onerror = error => {
console.error(`[${config.id}] Client error:`, error);
};
// Set up client-specific notification handler
client.setNotificationHandler('notifications/message', notification => {
console.log(`[${config.id}] Notification: ${notification.params.data}`);
});
try {
// Connect to the server
await client.connect(transport);
console.log(`[${config.id}] Connected to MCP server`);
// Call the specified tool
console.log(`[${config.id}] Calling tool: ${config.toolName}`);
const toolRequest: CallToolRequest = {
method: 'tools/call',
params: {
name: config.toolName,
arguments: {
...config.toolArguments,
// Add client ID to arguments for identification in notifications
caller: config.id
}
}
};
const result = await client.request(toolRequest, CallToolResultSchema);
console.log(`[${config.id}] Tool call completed`);
// Keep the connection open for a bit to receive notifications
await new Promise(resolve => setTimeout(resolve, 5000));
// Disconnect
await transport.close();
console.log(`[${config.id}] Disconnected from MCP server`);
return { id: config.id, result };
} catch (error) {
console.error(`[${config.id}] Error:`, error);
throw error;
}
}
async function main(): Promise<void> {
console.log('MCP Multiple Clients Example');
console.log('============================');
console.log(`Server URL: ${serverUrl}`);
console.log('');
try {
// Define client configurations
const clientConfigs: ClientConfig[] = [
{
id: 'client1',
name: 'basic-client-1',
toolName: 'start-notification-stream',
toolArguments: {
interval: 3, // 1 second between notifications
count: 5 // Send 5 notifications
}
},
{
id: 'client2',
name: 'basic-client-2',
toolName: 'start-notification-stream',
toolArguments: {
interval: 2, // 2 seconds between notifications
count: 3 // Send 3 notifications
}
},
{
id: 'client3',
name: 'basic-client-3',
toolName: 'start-notification-stream',
toolArguments: {
interval: 1, // 0.5 second between notifications
count: 8 // Send 8 notifications
}
}
];
// Start all clients in parallel
console.log(`Starting ${clientConfigs.length} clients in parallel...`);
console.log('');
const clientPromises = clientConfigs.map(config => createAndRunClient(config));
const results = await Promise.all(clientPromises);
// Display results from all clients
console.log('\n=== Final Results ===');
for (const { id, result } of results) {
console.log(`\n[${id}] Tool result:`);
if (Array.isArray(result.content)) {
for (const item of result.content) {
if (item.type === 'text' && item.text) {
console.log(` ${item.text}`);
} else {
console.log(` ${item.type} content:`, item);
}
}
} else {
console.log(` Unexpected result format:`, result);
}
}
console.log('\n=== All clients completed successfully ===');
} catch (error) {
console.error('Error running multiple clients:', error);
// eslint-disable-next-line unicorn/no-process-exit
process.exit(1);
}
}
// Start the example
try {
await main();
} catch (error) {
console.error('Error running multiple clients:', error);
// eslint-disable-next-line unicorn/no-process-exit
process.exit(1);
}