Skip to content

Commit 961f13d

Browse files
authored
test: Skipped mcp streaming tests on @modelcontextprotocol/sdk 1.26.0+ (newrelic#3728)
1 parent 15b82c2 commit 961f13d

File tree

1 file changed

+134
-131
lines changed

1 file changed

+134
-131
lines changed

test/versioned/mcp-sdk/client-streaming.test.js

Lines changed: 134 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -5,166 +5,169 @@
55

66
'use strict'
77

8-
const test = require('node:test')
8+
const { describe, test } = require('node:test')
99
const assert = require('node:assert')
10+
const semver = require('semver')
1011

1112
const { removeModules } = require('../../lib/cache-buster')
1213
const helper = require('../../lib/agent_helper')
1314
const { assertPackageMetrics, assertSegments, assertSpanKind } = require('../../lib/custom-assertions')
1415
const {
1516
MCP
1617
} = require('../../../lib/metrics/names')
18+
const version = helper.readPackageVersion(__dirname, '@modelcontextprotocol/sdk')
19+
20+
describe('MCP streaming tests', { skip: semver.gte(version, '1.26.0') }, () => {
21+
test.beforeEach(async (ctx) => {
22+
ctx.nr = {}
23+
ctx.nr.agent = helper.instrumentMockedAgent({
24+
ai_monitoring: {
25+
enabled: ctx.name.includes('disabled') ? false : true
26+
}
27+
})
1728

18-
test.beforeEach(async (ctx) => {
19-
ctx.nr = {}
20-
ctx.nr.agent = helper.instrumentMockedAgent({
21-
ai_monitoring: {
22-
enabled: ctx.name.includes('disabled') ? false : true
23-
}
29+
const { Client } = require('@modelcontextprotocol/sdk/client/index.js')
30+
const { StreamableHTTPClientTransport } = require('@modelcontextprotocol/sdk/client/streamableHttp.js')
31+
// Set up server
32+
const McpTestServer = require('./streaming-server')
33+
ctx.nr.mcpServer = new McpTestServer()
34+
const port = await ctx.nr.mcpServer.start()
35+
36+
// Set up client
37+
ctx.nr.transport = new StreamableHTTPClientTransport(
38+
new URL(`http://localhost:${port}/mcp`)
39+
)
40+
ctx.nr.client = new Client(
41+
{
42+
name: 'test-client',
43+
version: '1.0.0'
44+
}
45+
)
46+
await ctx.nr.client.connect(ctx.nr.transport)
2447
})
2548

26-
const { Client } = require('@modelcontextprotocol/sdk/client/index.js')
27-
const { StreamableHTTPClientTransport } = require('@modelcontextprotocol/sdk/client/streamableHttp.js')
28-
// Set up server
29-
const McpTestServer = require('./streaming-server')
30-
ctx.nr.mcpServer = new McpTestServer()
31-
const port = await ctx.nr.mcpServer.start()
32-
33-
// Set up client
34-
ctx.nr.transport = new StreamableHTTPClientTransport(
35-
new URL(`http://localhost:${port}/mcp`)
36-
)
37-
ctx.nr.client = new Client(
38-
{
39-
name: 'test-client',
40-
version: '1.0.0'
41-
}
42-
)
43-
await ctx.nr.client.connect(ctx.nr.transport)
44-
})
45-
46-
test.afterEach(async (ctx) => {
47-
await ctx.nr.client.close()
48-
await ctx.nr.transport.close()
49-
await ctx.nr.mcpServer.stop()
50-
helper.unloadAgent(ctx.nr.agent)
51-
removeModules([
52-
'@modelcontextprotocol/sdk/client/index.js',
53-
'@modelcontextprotocol/sdk/client/streamableHttp.js'
54-
])
55-
})
56-
57-
test('should log package tracking metrics', (t) => {
58-
const { agent } = t.nr
59-
const version = helper.readPackageVersion(__dirname, '@modelcontextprotocol/sdk')
60-
assertPackageMetrics({
61-
agent,
62-
pkg: '@modelcontextprotocol/sdk',
63-
version,
64-
subscriberType: true
49+
test.afterEach(async (ctx) => {
50+
await ctx.nr.client.close()
51+
await ctx.nr.transport.close()
52+
await ctx.nr.mcpServer.stop()
53+
helper.unloadAgent(ctx.nr.agent)
54+
removeModules([
55+
'@modelcontextprotocol/sdk/client/index.js',
56+
'@modelcontextprotocol/sdk/client/streamableHttp.js'
57+
])
6558
})
66-
})
6759

68-
test('should create span for callTool', (t, end) => {
69-
const { agent, client } = t.nr
70-
helper.runInTransaction(agent, async (tx) => {
71-
const result = await client.callTool({
72-
name: 'echo',
73-
arguments: {
74-
message: 'example message'
75-
}
76-
})
77-
assert.ok(result, 'should return a result from the tool call')
78-
const name = `${MCP.TOOL}/callTool/echo`
79-
assertSegments(tx.trace, tx.trace.root, [name], { exact: false })
80-
tx.end()
81-
assertSpanKind({
60+
test('should log package tracking metrics', (t) => {
61+
const { agent } = t.nr
62+
assertPackageMetrics({
8263
agent,
83-
segments: [
84-
{ name, kind: 'internal' }
85-
]
64+
pkg: '@modelcontextprotocol/sdk',
65+
version,
66+
subscriberType: true
8667
})
87-
88-
end()
8968
})
90-
})
91-
92-
test('should create span for readResource', (t, end) => {
93-
const { agent, client } = t.nr
94-
helper.runInTransaction(agent, async (tx) => {
95-
const resource = await client.readResource({
96-
uri: 'echo://hello-world',
97-
})
98-
99-
assert.ok(resource, 'should return a resource from readResource')
10069

101-
const name = `${MCP.RESOURCE}/readResource/echo`
102-
assertSegments(tx.trace, tx.trace.root, [name], { exact: false })
103-
104-
tx.end()
105-
assertSpanKind({
106-
agent,
107-
segments: [
108-
{ name, kind: 'internal' }
109-
]
70+
test('should create span for callTool', (t, end) => {
71+
const { agent, client } = t.nr
72+
helper.runInTransaction(agent, async (tx) => {
73+
const result = await client.callTool({
74+
name: 'echo',
75+
arguments: {
76+
message: 'example message'
77+
}
78+
})
79+
assert.ok(result, 'should return a result from the tool call')
80+
const name = `${MCP.TOOL}/callTool/echo`
81+
assertSegments(tx.trace, tx.trace.root, [name], { exact: false })
82+
tx.end()
83+
assertSpanKind({
84+
agent,
85+
segments: [
86+
{ name, kind: 'internal' }
87+
]
88+
})
89+
90+
end()
11091
})
111-
112-
end()
11392
})
114-
})
11593

116-
test('should create span for getPrompt', (t, end) => {
117-
const { agent, client } = t.nr
118-
helper.runInTransaction(agent, async (tx) => {
119-
const prompt = await client.getPrompt({
120-
name: 'echo',
121-
arguments: {
122-
message: 'example message'
123-
}
124-
})
94+
test('should create span for readResource', (t, end) => {
95+
const { agent, client } = t.nr
96+
helper.runInTransaction(agent, async (tx) => {
97+
const resource = await client.readResource({
98+
uri: 'echo://hello-world',
99+
})
125100

126-
assert.ok(prompt, 'should return a prompt from getPrompt')
101+
assert.ok(resource, 'should return a resource from readResource')
127102

128-
const name = `${MCP.PROMPT}/getPrompt/echo`
129-
assertSegments(tx.trace, tx.trace.root, [name], { exact: false })
103+
const name = `${MCP.RESOURCE}/readResource/echo`
104+
assertSegments(tx.trace, tx.trace.root, [name], { exact: false })
130105

131-
tx.end()
132-
assertSpanKind({
133-
agent,
134-
segments: [
135-
{ name, kind: 'internal' }
136-
]
137-
})
106+
tx.end()
107+
assertSpanKind({
108+
agent,
109+
segments: [
110+
{ name, kind: 'internal' }
111+
]
112+
})
138113

139-
end()
114+
end()
115+
})
140116
})
141-
})
142117

143-
test('should not instrument if ai_monitoring is disabled', (t, end) => {
144-
const { agent, client } = t.nr
145-
146-
helper.runInTransaction(agent, async (tx) => {
147-
const result = await client.callTool({
148-
name: 'echo',
149-
arguments: {
150-
message: 'example message'
151-
}
118+
test('should create span for getPrompt', (t, end) => {
119+
const { agent, client } = t.nr
120+
helper.runInTransaction(agent, async (tx) => {
121+
const prompt = await client.getPrompt({
122+
name: 'echo',
123+
arguments: {
124+
message: 'example message'
125+
}
126+
})
127+
128+
assert.ok(prompt, 'should return a prompt from getPrompt')
129+
130+
const name = `${MCP.PROMPT}/getPrompt/echo`
131+
assertSegments(tx.trace, tx.trace.root, [name], { exact: false })
132+
133+
tx.end()
134+
assertSpanKind({
135+
agent,
136+
segments: [
137+
{ name, kind: 'internal' }
138+
]
139+
})
140+
141+
end()
152142
})
143+
})
153144

154-
assert.ok(result, 'should still return a result from the tool call')
155-
156-
const name = `${MCP.TOOL}/callTool/echo`
157-
const root = tx?.trace?.segments?.root
158-
assert.ok(root)
159-
function assertNoMcpSegment(node) {
160-
assert.notEqual(node?.segment?.name, name, 'should not create MCP segment')
161-
for (const child of node?.children) {
162-
assertNoMcpSegment(child)
145+
test('should not instrument if ai_monitoring is disabled', (t, end) => {
146+
const { agent, client } = t.nr
147+
148+
helper.runInTransaction(agent, async (tx) => {
149+
const result = await client.callTool({
150+
name: 'echo',
151+
arguments: {
152+
message: 'example message'
153+
}
154+
})
155+
156+
assert.ok(result, 'should still return a result from the tool call')
157+
158+
const name = `${MCP.TOOL}/callTool/echo`
159+
const root = tx?.trace?.segments?.root
160+
assert.ok(root)
161+
function assertNoMcpSegment(node) {
162+
assert.notEqual(node?.segment?.name, name, 'should not create MCP segment')
163+
for (const child of node?.children) {
164+
assertNoMcpSegment(child)
165+
}
163166
}
164-
}
165-
assertNoMcpSegment(root)
167+
assertNoMcpSegment(root)
166168

167-
tx.end()
168-
end()
169+
tx.end()
170+
end()
171+
})
169172
})
170173
})

0 commit comments

Comments
 (0)