UNPKG

@sentry/core

Version:
123 lines (106 loc) 4.16 kB
import { DEBUG_BUILD } from './debug-build.js'; import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_OP } from './semanticAttributes.js'; import './tracing/errors.js'; import './utils-hoist/debug-build.js'; import { logger } from './utils-hoist/logger.js'; import './utils-hoist/time.js'; import './utils-hoist/syncpromise.js'; import { startSpan } from './tracing/trace.js'; const wrappedMcpServerInstances = new WeakSet(); /** * Wraps a MCP Server instance from the `@modelcontextprotocol/sdk` package with Sentry instrumentation. * * Compatible with versions `^1.9.0` of the `@modelcontextprotocol/sdk` package. */ // We are exposing this API for non-node runtimes that cannot rely on auto-instrumentation. function wrapMcpServerWithSentry(mcpServerInstance) { if (wrappedMcpServerInstances.has(mcpServerInstance)) { return mcpServerInstance; } if (!isMcpServerInstance(mcpServerInstance)) { DEBUG_BUILD && logger.warn('Did not patch MCP server. Interface is incompatible.'); return mcpServerInstance; } mcpServerInstance.resource = new Proxy(mcpServerInstance.resource, { apply(target, thisArg, argArray) { const resourceName = argArray[0]; const resourceHandler = argArray[argArray.length - 1]; if (typeof resourceName !== 'string' || typeof resourceHandler !== 'function') { return target.apply(thisArg, argArray); } return startSpan( { name: `mcp-server/resource:${resourceName}`, forceTransaction: true, attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'auto.function.mcp-server', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.mcp-server', [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route', 'mcp_server.resource': resourceName, }, }, () => target.apply(thisArg, argArray), ); }, }); mcpServerInstance.tool = new Proxy(mcpServerInstance.tool, { apply(target, thisArg, argArray) { const toolName = argArray[0]; const toolHandler = argArray[argArray.length - 1]; if (typeof toolName !== 'string' || typeof toolHandler !== 'function') { return target.apply(thisArg, argArray); } return startSpan( { name: `mcp-server/tool:${toolName}`, forceTransaction: true, attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'auto.function.mcp-server', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.mcp-server', [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route', 'mcp_server.tool': toolName, }, }, () => target.apply(thisArg, argArray), ); }, }); mcpServerInstance.prompt = new Proxy(mcpServerInstance.prompt, { apply(target, thisArg, argArray) { const promptName = argArray[0]; const promptHandler = argArray[argArray.length - 1]; if (typeof promptName !== 'string' || typeof promptHandler !== 'function') { return target.apply(thisArg, argArray); } return startSpan( { name: `mcp-server/resource:${promptName}`, forceTransaction: true, attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'auto.function.mcp-server', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.mcp-server', [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route', 'mcp_server.prompt': promptName, }, }, () => target.apply(thisArg, argArray), ); }, }); wrappedMcpServerInstances.add(mcpServerInstance); return mcpServerInstance ; } function isMcpServerInstance(mcpServerInstance) { return ( typeof mcpServerInstance === 'object' && mcpServerInstance !== null && 'resource' in mcpServerInstance && typeof mcpServerInstance.resource === 'function' && 'tool' in mcpServerInstance && typeof mcpServerInstance.tool === 'function' && 'prompt' in mcpServerInstance && typeof mcpServerInstance.prompt === 'function' ); } export { wrapMcpServerWithSentry }; //# sourceMappingURL=mcp-server.js.map