-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Expand file tree
/
Copy pathmcp.test.ts
More file actions
128 lines (108 loc) · 5.08 KB
/
mcp.test.ts
File metadata and controls
128 lines (108 loc) · 5.08 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
import { expect, test } from '@playwright/test';
import { waitForTransaction } from '@sentry-internal/test-utils';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
test('Should record transactions for mcp handlers', async ({ baseURL }) => {
const transport = new SSEClientTransport(new URL(`${baseURL}/sse`));
const client = new Client({
name: 'test-client',
version: '1.0.0',
});
const initializeTransactionPromise = waitForTransaction('node-express', transactionEvent => {
return transactionEvent.transaction === 'initialize';
});
await client.connect(transport);
await test.step('initialize handshake', async () => {
const initializeTransaction = await initializeTransactionPromise;
expect(initializeTransaction).toBeDefined();
expect(initializeTransaction.contexts?.trace?.op).toEqual('mcp.server');
expect(initializeTransaction.contexts?.trace?.data?.['mcp.method.name']).toEqual('initialize');
expect(initializeTransaction.contexts?.trace?.data?.['mcp.client.name']).toEqual('test-client');
expect(initializeTransaction.contexts?.trace?.data?.['mcp.server.name']).toEqual('Echo');
});
await test.step('tool handler', async () => {
const postTransactionPromise = waitForTransaction('node-express', transactionEvent => {
return transactionEvent.transaction === 'POST /messages';
});
const toolTransactionPromise = waitForTransaction('node-express', transactionEvent => {
return transactionEvent.transaction === 'tools/call echo';
});
const toolResult = await client.callTool({
name: 'echo',
arguments: {
message: 'foobar',
},
});
expect(toolResult).toMatchObject({
content: [
{
text: 'Tool echo: foobar',
type: 'text',
},
],
});
const postTransaction = await postTransactionPromise;
expect(postTransaction).toBeDefined();
expect(postTransaction.contexts?.trace?.op).toEqual('http.server');
const toolTransaction = await toolTransactionPromise;
expect(toolTransaction).toBeDefined();
expect(toolTransaction.contexts?.trace?.op).toEqual('mcp.server');
expect(toolTransaction.contexts?.trace?.data?.['mcp.method.name']).toEqual('tools/call');
// TODO: When https://github.com/modelcontextprotocol/typescript-sdk/pull/358 is released check for trace id equality between the post transaction and the handler transaction
});
await test.step('resource handler', async () => {
const postTransactionPromise = waitForTransaction('node-express', transactionEvent => {
return transactionEvent.transaction === 'POST /messages';
});
const resourceTransactionPromise = waitForTransaction('node-express', transactionEvent => {
return transactionEvent.transaction === 'resources/read echo://foobar';
});
const resourceResult = await client.readResource({
uri: 'echo://foobar',
});
expect(resourceResult).toMatchObject({
contents: [{ text: 'Resource echo: foobar', uri: 'echo://foobar' }],
});
const postTransaction = await postTransactionPromise;
expect(postTransaction).toBeDefined();
expect(postTransaction.contexts?.trace?.op).toEqual('http.server');
const resourceTransaction = await resourceTransactionPromise;
expect(resourceTransaction).toBeDefined();
expect(resourceTransaction.contexts?.trace?.op).toEqual('mcp.server');
expect(resourceTransaction.contexts?.trace?.data?.['mcp.method.name']).toEqual('resources/read');
// TODO: When https://github.com/modelcontextprotocol/typescript-sdk/pull/358 is released check for trace id equality between the post transaction and the handler transaction
});
await test.step('prompt handler', async () => {
const postTransactionPromise = waitForTransaction('node-express', transactionEvent => {
return transactionEvent.transaction === 'POST /messages';
});
const promptTransactionPromise = waitForTransaction('node-express', transactionEvent => {
return transactionEvent.transaction === 'prompts/get echo';
});
const promptResult = await client.getPrompt({
name: 'echo',
arguments: {
message: 'foobar',
},
});
expect(promptResult).toMatchObject({
messages: [
{
content: {
text: 'Please process this message: foobar',
type: 'text',
},
role: 'user',
},
],
});
const postTransaction = await postTransactionPromise;
expect(postTransaction).toBeDefined();
expect(postTransaction.contexts?.trace?.op).toEqual('http.server');
const promptTransaction = await promptTransactionPromise;
expect(promptTransaction).toBeDefined();
expect(promptTransaction.contexts?.trace?.op).toEqual('mcp.server');
expect(promptTransaction.contexts?.trace?.data?.['mcp.method.name']).toEqual('prompts/get');
// TODO: When https://github.com/modelcontextprotocol/typescript-sdk/pull/358 is released check for trace id equality between the post transaction and the handler transaction
});
});