Skip to content

Commit 1afb158

Browse files
committed
ref(core): adopt published MCP result conventions
1 parent a19fe12 commit 1afb158

4 files changed

Lines changed: 49 additions & 24 deletions

File tree

‎packages/core/src/integrations/mcp-server/attributeExtraction.ts‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ export function getNotificationAttributes(
9494
attributes[MCP_RESOURCE_URI] = String(params.uri);
9595
const urlObject = parseStringToURLObject(String(params.uri));
9696
if (urlObject && !isURLObjectRelative(urlObject)) {
97-
// oxlint-disable-next-line typescript/no-deprecated -- Keep the resource URI scheme distinct from the network protocol.
9897
attributes[MCP_RESOURCE_PROTOCOL] = urlObject.protocol.replace(':', '');
9998
}
10099
}

‎packages/core/src/integrations/mcp-server/attributes.ts‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
1-
/** Prefix for tool result attributes that contain sensitive content */
2-
export const MCP_TOOL_RESULT_PREFIX = 'mcp.tool.result';
3-
4-
/** Prefix for prompt result attributes that contain sensitive content */
5-
export const MCP_PROMPT_RESULT_PREFIX = 'mcp.prompt.result';
6-
71
/** Sentry origin value for MCP function spans */
82
export const MCP_FUNCTION_ORIGIN_VALUE = 'auto.function.mcp_server';
93

‎packages/core/src/integrations/mcp-server/resultExtraction.ts‎

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,33 @@
66

77
import {
88
MCP_PROMPT_RESULT_DESCRIPTION,
9+
MCP_PROMPT_RESULT_KEY_CONTENT,
10+
MCP_PROMPT_RESULT_KEY_ROLE,
911
MCP_PROMPT_RESULT_MESSAGE_CONTENT,
1012
MCP_PROMPT_RESULT_MESSAGE_COUNT,
1113
MCP_PROMPT_RESULT_MESSAGE_ROLE,
1214
MCP_TOOL_RESULT_CONTENT,
1315
MCP_TOOL_RESULT_CONTENT_COUNT,
16+
MCP_TOOL_RESULT_CONTENT_TYPE,
17+
MCP_TOOL_RESULT_DATA_SIZE,
1418
MCP_TOOL_RESULT_IS_ERROR,
19+
MCP_TOOL_RESULT_KEY_CONTENT,
20+
MCP_TOOL_RESULT_KEY_CONTENT_TYPE,
21+
MCP_TOOL_RESULT_KEY_DATA_SIZE,
22+
MCP_TOOL_RESULT_KEY_MIME_TYPE,
23+
MCP_TOOL_RESULT_KEY_NAME,
24+
MCP_TOOL_RESULT_KEY_RESOURCE_MIME_TYPE,
25+
MCP_TOOL_RESULT_KEY_RESOURCE_URI,
26+
MCP_TOOL_RESULT_KEY_URI,
27+
MCP_TOOL_RESULT_MIME_TYPE,
28+
MCP_TOOL_RESULT_NAME,
29+
MCP_TOOL_RESULT_RESOURCE_MIME_TYPE,
30+
MCP_TOOL_RESULT_RESOURCE_URI,
31+
MCP_TOOL_RESULT_URI,
1532
} from '@sentry/conventions/attributes';
16-
import { MCP_TOOL_RESULT_PREFIX, MCP_PROMPT_RESULT_PREFIX } from './attributes';
1733
import { isValidContentItem } from './validation';
1834

35+
/* oxlint-disable typescript/no-deprecated -- Preserve the legacy result attributes for existing consumers. */
1936
/**
2037
* Build attributes for tool result content items
2138
* @param content - Array of content items from tool result
@@ -35,43 +52,55 @@ function buildAllContentItemAttributes(
3552
continue;
3653
}
3754

38-
const prefix = content.length === 1 ? MCP_TOOL_RESULT_PREFIX : `${MCP_TOOL_RESULT_PREFIX}.${i}`;
55+
const single = content.length === 1;
56+
const index = String(i);
3957

4058
if (typeof item.type === 'string') {
41-
attributes[`${prefix}.content_type`] = item.type;
59+
const key = single ? MCP_TOOL_RESULT_CONTENT_TYPE : MCP_TOOL_RESULT_KEY_CONTENT_TYPE.replace('<key>', index);
60+
attributes[key] = item.type;
4261
}
4362

4463
if (includeContent) {
4564
const safeSet = (key: string, value: unknown): void => {
4665
if (typeof value === 'string') {
47-
attributes[`${prefix}.${key}`] = value;
66+
attributes[key] = value;
4867
}
4968
};
5069

51-
safeSet('mime_type', item.mimeType);
52-
safeSet('uri', item.uri);
53-
safeSet('name', item.name);
70+
safeSet(
71+
single ? MCP_TOOL_RESULT_MIME_TYPE : MCP_TOOL_RESULT_KEY_MIME_TYPE.replace('<key>', index),
72+
item.mimeType,
73+
);
74+
safeSet(single ? MCP_TOOL_RESULT_URI : MCP_TOOL_RESULT_KEY_URI.replace('<key>', index), item.uri);
75+
safeSet(single ? MCP_TOOL_RESULT_NAME : MCP_TOOL_RESULT_KEY_NAME.replace('<key>', index), item.name);
5476

5577
if (typeof item.text === 'string') {
56-
// oxlint-disable-next-line typescript/no-deprecated -- Preserve the legacy content attribute for existing consumers.
57-
const attrName = content.length === 1 ? MCP_TOOL_RESULT_CONTENT : `${prefix}.content`;
78+
const attrName = single ? MCP_TOOL_RESULT_CONTENT : MCP_TOOL_RESULT_KEY_CONTENT.replace('<key>', index);
5879
attributes[attrName] = item.text;
5980
}
6081

6182
if (typeof item.data === 'string') {
62-
attributes[`${prefix}.data_size`] = item.data.length;
83+
const key = single ? MCP_TOOL_RESULT_DATA_SIZE : MCP_TOOL_RESULT_KEY_DATA_SIZE.replace('<key>', index);
84+
attributes[key] = item.data.length;
6385
}
6486

6587
const resource = item.resource;
6688
if (isValidContentItem(resource)) {
67-
safeSet('resource_uri', resource.uri);
68-
safeSet('resource_mime_type', resource.mimeType);
89+
safeSet(
90+
single ? MCP_TOOL_RESULT_RESOURCE_URI : MCP_TOOL_RESULT_KEY_RESOURCE_URI.replace('<key>', index),
91+
resource.uri,
92+
);
93+
safeSet(
94+
single ? MCP_TOOL_RESULT_RESOURCE_MIME_TYPE : MCP_TOOL_RESULT_KEY_RESOURCE_MIME_TYPE.replace('<key>', index),
95+
resource.mimeType,
96+
);
6997
}
7098
}
7199
}
72100

73101
return attributes;
74102
}
103+
/* oxlint-enable typescript/no-deprecated */
75104

76105
/**
77106
* Extract tool result attributes for span instrumentation
@@ -126,17 +155,21 @@ export function extractPromptResultAttributes(
126155
continue;
127156
}
128157

129-
const prefix = messages.length === 1 ? MCP_PROMPT_RESULT_PREFIX : `${MCP_PROMPT_RESULT_PREFIX}.${i}`;
130-
131158
if (typeof message.role === 'string') {
132-
const attrName = messages.length === 1 ? MCP_PROMPT_RESULT_MESSAGE_ROLE : `${prefix}.role`;
159+
const attrName =
160+
messages.length === 1
161+
? MCP_PROMPT_RESULT_MESSAGE_ROLE
162+
: MCP_PROMPT_RESULT_KEY_ROLE.replace('<key>', String(i));
133163
attributes[attrName] = message.role;
134164
}
135165

136166
if (isValidContentItem(message.content)) {
137167
const content = message.content;
138168
if (typeof content.text === 'string') {
139-
const attrName = messages.length === 1 ? MCP_PROMPT_RESULT_MESSAGE_CONTENT : `${prefix}.content`;
169+
const attrName =
170+
messages.length === 1
171+
? MCP_PROMPT_RESULT_MESSAGE_CONTENT
172+
: MCP_PROMPT_RESULT_KEY_CONTENT.replace('<key>', String(i));
140173
attributes[attrName] = content.text;
141174
}
142175
}

‎packages/core/src/integrations/mcp-server/sessionExtraction.ts‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,6 @@ export function buildTransportAttributes(
294294
...(sessionId && { [MCP_SESSION_ID]: sessionId }),
295295
...(clientInfo.address && { [CLIENT_ADDRESS]: clientInfo.address }),
296296
...(clientInfo.port && { [CLIENT_PORT]: clientInfo.port }),
297-
// oxlint-disable-next-line typescript/no-deprecated -- Keep the transport implementation name distinct from the network transport.
298297
[MCP_TRANSPORT]: mcpTransport,
299298
[NETWORK_TRANSPORT]: networkTransport,
300299
[NETWORK_PROTOCOL_VERSION]: '2.0',

0 commit comments

Comments
 (0)