Skip to content

Commit e193118

Browse files
committed
refactor(mcp-server): method configuration and argument extraction for improved instrumentation
1 parent ec3cb6f commit e193118

File tree

2 files changed

+75
-43
lines changed

2 files changed

+75
-43
lines changed

packages/core/src/utils/mcp-server/types.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22
* types for MCP server instrumentation
33
*/
44

5+
6+
/** Method configuration type */
7+
export type MethodConfig = {
8+
targetField: string;
9+
targetAttribute: string;
10+
captureArguments?: boolean;
11+
argumentsField?: string;
12+
captureUri?: boolean;
13+
captureName?: boolean;
14+
};
15+
516
/**
617
* JSON-RPC 2.0 request object
718
*/
@@ -121,5 +132,6 @@ export interface McpSpanConfig {
121132
callback: () => unknown;
122133
}
123134

135+
124136
export type SessionId = string;
125137
export type RequestId = string | number;

packages/core/src/utils/mcp-server/utils.ts

Lines changed: 63 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,18 @@ import {
1818
MCP_NOTIFICATION_CLIENT_TO_SERVER_OP_VALUE,
1919
MCP_NOTIFICATION_ORIGIN_VALUE,
2020
MCP_NOTIFICATION_SERVER_TO_CLIENT_OP_VALUE,
21+
MCP_PROMPT_NAME_ATTRIBUTE,
2122
MCP_REQUEST_ID_ATTRIBUTE,
23+
MCP_RESOURCE_URI_ATTRIBUTE,
2224
MCP_ROUTE_SOURCE_VALUE,
2325
MCP_SERVER_OP_VALUE,
2426
MCP_SESSION_ID_ATTRIBUTE,
27+
MCP_TOOL_NAME_ATTRIBUTE,
2528
MCP_TRANSPORT_ATTRIBUTE,
2629
NETWORK_PROTOCOL_VERSION_ATTRIBUTE,
2730
NETWORK_TRANSPORT_ATTRIBUTE,
2831
} from './attributes';
29-
import type { ExtraHandlerData, JsonRpcNotification, JsonRpcRequest, McpSpanConfig, MCPTransport } from './types';
32+
import type { ExtraHandlerData, JsonRpcNotification, JsonRpcRequest, McpSpanConfig, MCPTransport, MethodConfig } from './types';
3033

3134
/** Validates if a message is a JSON-RPC request */
3235
export function isJsonRpcRequest(message: unknown): message is JsonRpcRequest {
@@ -68,65 +71,82 @@ export function validateMcpServerInstance(instance: unknown): boolean {
6871
return false;
6972
}
7073

74+
/** Configuration for MCP methods to extract targets and arguments */
75+
const METHOD_CONFIGS: Record<string, MethodConfig> = {
76+
'tools/call': {
77+
targetField: 'name',
78+
targetAttribute: MCP_TOOL_NAME_ATTRIBUTE,
79+
captureArguments: true,
80+
argumentsField: 'arguments',
81+
},
82+
'resources/read': {
83+
targetField: 'uri',
84+
targetAttribute: MCP_RESOURCE_URI_ATTRIBUTE,
85+
captureUri: true,
86+
},
87+
'resources/subscribe': {
88+
targetField: 'uri',
89+
targetAttribute: MCP_RESOURCE_URI_ATTRIBUTE,
90+
},
91+
'resources/unsubscribe': {
92+
targetField: 'uri',
93+
targetAttribute: MCP_RESOURCE_URI_ATTRIBUTE,
94+
},
95+
'prompts/get': {
96+
targetField: 'name',
97+
targetAttribute: MCP_PROMPT_NAME_ATTRIBUTE,
98+
captureName: true,
99+
captureArguments: true,
100+
argumentsField: 'arguments',
101+
},
102+
};
103+
71104
/** Extracts target info from method and params based on method type */
72105
function extractTargetInfo(method: string, params: Record<string, unknown>): {
73106
target?: string;
74107
attributes: Record<string, string>
75108
} {
76-
let target: string | undefined;
77-
let attributeKey: string | undefined;
78-
79-
switch (method) {
80-
case 'tools/call':
81-
target = typeof params?.name === 'string' ? params.name : undefined;
82-
attributeKey = 'mcp.tool.name';
83-
break;
84-
case 'resources/read':
85-
case 'resources/subscribe':
86-
case 'resources/unsubscribe':
87-
target = typeof params?.uri === 'string' ? params.uri : undefined;
88-
attributeKey = 'mcp.resource.uri';
89-
break;
90-
case 'prompts/get':
91-
target = typeof params?.name === 'string' ? params.name : undefined;
92-
attributeKey = 'mcp.prompt.name';
93-
break;
109+
const config = METHOD_CONFIGS[method as keyof typeof METHOD_CONFIGS];
110+
if (!config) {
111+
return { attributes: {} };
94112
}
95113

114+
const target = config.targetField && typeof params?.[config.targetField] === 'string'
115+
? params[config.targetField] as string
116+
: undefined;
117+
96118
return {
97119
target,
98-
attributes: target && attributeKey ? { [attributeKey]: target } : {}
120+
attributes: target && config.targetAttribute ? { [config.targetAttribute]: target } : {}
99121
};
100122
}
101123

102124
/** Extracts request arguments based on method type */
103125
function getRequestArguments(method: string, params: Record<string, unknown>): Record<string, string> {
104126
const args: Record<string, string> = {};
127+
const config = METHOD_CONFIGS[method as keyof typeof METHOD_CONFIGS];
128+
129+
if (!config) {
130+
return args;
131+
}
105132

106-
// Argument capture for different methods
107-
switch (method) {
108-
case 'tools/call':
109-
if (params?.arguments && typeof params.arguments === 'object') {
110-
for (const [key, value] of Object.entries(params.arguments as Record<string, unknown>)) {
111-
args[`mcp.request.argument.${key.toLowerCase()}`] = JSON.stringify(value);
112-
}
133+
// Capture arguments from the configured field
134+
if (config.captureArguments && config.argumentsField && params?.[config.argumentsField]) {
135+
const argumentsObj = params[config.argumentsField];
136+
if (typeof argumentsObj === 'object' && argumentsObj !== null) {
137+
for (const [key, value] of Object.entries(argumentsObj as Record<string, unknown>)) {
138+
args[`mcp.request.argument.${key.toLowerCase()}`] = JSON.stringify(value);
113139
}
114-
break;
115-
case 'resources/read':
116-
if (params?.uri) {
117-
args['mcp.request.argument.uri'] = JSON.stringify(params.uri);
118-
}
119-
break;
120-
case 'prompts/get':
121-
if (params?.name) {
122-
args['mcp.request.argument.name'] = JSON.stringify(params.name);
123-
}
124-
if (params?.arguments && typeof params.arguments === 'object') {
125-
for (const [key, value] of Object.entries(params.arguments as Record<string, unknown>)) {
126-
args[`mcp.request.argument.${key.toLowerCase()}`] = JSON.stringify(value);
127-
}
128-
}
129-
break;
140+
}
141+
}
142+
143+
// Capture specific fields as arguments
144+
if (config.captureUri && params?.uri) {
145+
args['mcp.request.argument.uri'] = JSON.stringify(params.uri);
146+
}
147+
148+
if (config.captureName && params?.name) {
149+
args['mcp.request.argument.name'] = JSON.stringify(params.name);
130150
}
131151

132152
return args;

0 commit comments

Comments
 (0)