Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/ai-semantic-conventions/src/SemanticAttributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ export const SpanAttributes = {
TRACELOOP_ASSOCIATION_PROPERTIES: "traceloop.association.properties",
TRACELOOP_ENTITY_INPUT: "traceloop.entity.input",
TRACELOOP_ENTITY_OUTPUT: "traceloop.entity.output",

// MCP (Model Context Protocol)
MCP_RESPONSE_VALUE: "mcp.response.value",
MCP_REQUEST_ID: "mcp.request.id",
};

export const Events = {
Expand Down Expand Up @@ -117,5 +121,6 @@ export enum TraceloopSpanKindValues {
TASK = "task",
AGENT = "agent",
TOOL = "tool",
SESSION = "session",
UNKNOWN = "unknown",
}
2 changes: 2 additions & 0 deletions packages/instrumentation-mcp/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dist
node_modules
67 changes: 67 additions & 0 deletions packages/instrumentation-mcp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# OpenTelemetry MCP Instrumentation for Node.js

[![NPM Published Version][npm-img]][npm-url]
[![Apache License][license-image]][license-image]
Comment on lines +3 to +4
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix license badge link to point at LICENSE URL

The Apache license badge currently links to the image itself instead of the LICENSE page:

[![Apache License][license-image]][license-image]

Consider updating it to use the defined license-url reference:

-[![Apache License][license-image]][license-image]
+[![Apache License][license-image]][license-url]
🤖 Prompt for AI Agents
In packages/instrumentation-mcp/README.md around lines 3-4, the Apache license
badge is linking to the image reference itself rather than the LICENSE page;
update the badge link target to use the defined license-url reference (e.g.,
change the trailing reference from [license-image] to [license-url]) so the
badge points to the LICENSE page instead of the image file.


This library allows tracing of agentic workflows implemented with MCP (Model Context Protocol) framework using the [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk).

## Installation

```bash
npm install --save @traceloop/instrumentation-mcp
```

## Usage

```javascript
const { McpInstrumentation } = require("@traceloop/instrumentation-mcp");
const { registerInstrumentations } = require("@opentelemetry/instrumentation");

registerInstrumentations({
instrumentations: [new McpInstrumentation()],
});
```

## Privacy

By default, this instrumentation logs prompts, completions, and embeddings to span attributes. This gives you a clear visibility into how your LLM application is working, and can make it easy to debug and evaluate the quality of the outputs.

However, you may want to disable this logging for privacy reasons, as they may contain highly sensitive data from your users. You may also want to disable this logging to reduce the size of your traces.

To disable logging, set the `traceContent` config option to `false`:

```javascript
const { McpInstrumentation } = require("@traceloop/instrumentation-mcp");

const mcpInstrumentation = new McpInstrumentation({
traceContent: false,
});
```

## Instrumented Operations

This instrumentation tracks the following MCP operations:

### Client Operations

- Session lifecycle management
- Tool invocations
- Resource access
- Prompt templates
- MCP protocol methods

### Server Operations

- Request handling
- Tool execution
- Resource serving
- Server-side spans

## License

Apache 2.0 - See [LICENSE][license-url] for more information.

[npm-url]: https://www.npmjs.com/package/@traceloop/instrumentation-mcp
[npm-img]: https://badge.fury.io/js/%40traceloop%2Finstrumentation-mcp.svg
[license-url]: https://github.com/traceloop/openllmetry-js/blob/main/LICENSE
[license-image]: https://img.shields.io/badge/license-Apache_2.0-green.svg?style=flat
29 changes: 29 additions & 0 deletions packages/instrumentation-mcp/eslint.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const js = require("@eslint/js");
const rootConfig = require("../../eslint.config.cjs");

const { FlatCompat } = require("@eslint/eslintrc");

const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all,
});

module.exports = [
{
ignores: ["!**/*", "**/node_modules", "dist/**/*"],
},
...rootConfig,
{
files: ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx"],
rules: {},
},
{
files: ["**/*.ts", "**/*.tsx"],
rules: {},
},
{
files: ["**/*.js", "**/*.jsx"],
rules: {},
},
];
61 changes: 61 additions & 0 deletions packages/instrumentation-mcp/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"name": "@traceloop/instrumentation-mcp",
"version": "0.20.0",
"description": "MCP (Model Context Protocol) Instrumentation",
"main": "dist/index.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"repository": "traceloop/openllmetry-js",
"scripts": {
"build": "rollup -c",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"test": "ts-mocha -p tsconfig.json 'test/**/*.test.ts'"
},
"keywords": [
"opentelemetry",
"nodejs",
"tracing",
"mcp",
"model-context-protocol"
],
"author": "Traceloop",
"license": "Apache-2.0",
"engines": {
"node": ">=14"
},
"files": [
"dist/**/*.js",
"dist/**/*.mjs",
"dist/**/*.js.map",
"dist/**/*.d.ts",
"doc",
"LICENSE",
"README.md",
"package.json"
],
"publishConfig": {
"access": "public"
},
"dependencies": {
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/core": "^2.0.1",
"@opentelemetry/instrumentation": "^0.203.0",
"@opentelemetry/semantic-conventions": "^1.36.0",
"@traceloop/ai-semantic-conventions": "workspace:*",
"tslib": "^2.8.1"
},
"devDependencies": {
"@modelcontextprotocol/sdk": "^1.0.4",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

Verify MCP SDK version compatibility.

Ensure that version ^1.0.4 of @modelcontextprotocol/sdk is the latest stable version and compatible with the instrumentation implementation.


🌐 Web query:

What is the latest stable version of @modelcontextprotocol/sdk npm package?

💡 Result:

The latest stable version is 1.22.0 (released Nov 13, 2025). [1][2]

Sources:
[1] GitHub releases for modelcontextprotocol/typescript-sdk.
[2] ReleaseAlert listing for @modelcontextprotocol/sdk.


🌐 Web query:

@modelcontextprotocol/sdk breaking changes between version 1.0.4 and 1.22.0 migration guide

💡 Result:

Summary of notable breaking or migration-relevant changes from @modelcontextprotocol/sdk v1.0.4 → v1.22.0 and migration steps

Key changes you must review and adapt for:

  • registerTool now accepts ZodType for input/output schemas (may change typings and how you pass schemas). [1]
  • Decoupled request payloads & removal of passthrough iteration (SEP-1319) — request/response shapes and iteration behavior were refactored; check code that relied on passthrough semantics. [1]
  • Default values for elicitation schemas (SEP-1034) and compatibility updates (SEP-1330) — elicitation schema handling may now inject defaults; validate your elicitation handlers. [1]
  • New formal format rules for tool names (SEP-986) — tool name validation/format stricter; update existing tool names if they violate the new format. [1]
  • Auth / scope handling changes (alignment with SEP-835 and related fixes) — authorization flows and scope parsing/management have been adjusted; confirm your auth integrations and 401/403 handling. [1]
  • Node LTS and runtime changes — SDK now targets a newer Node LTS; update your Node runtime if necessary. [1]
  • Typecheck / typing fixes and request payload typing changes — TypeScript consumers may need small code changes to satisfy stricter typechecks. [1]
  • Zod-related updates (zod v4 support in later beta; v3 compatibility notes) — if you use zod schemas, check peer/required zod versions and adjust imports/usage accordingly. [1]
  • Client APIs: small feature additions to ClientSessionGroup (Python SDK example: pass-through/expose additional params to call_tool / connect_to_server) — verify any advanced client session uses. [3]

Practical migration steps

  1. Read the full changelog/compare between your v1.0.4 tag and v1.22.0; scan SEP numbers referenced above for relevant protocol semantics. Start with the SDK releases page. [1]
  2. Update TypeScript typings and compiles: run tsc/tests and fix any type errors introduced by the decoupling/typecheck fixes. [1]
  3. Review all registerTool calls and tool-name strings; migrate schema arguments to ZodType where appropriate. [1]
  4. Re-run auth flows and tests that exercise 401/403 and scope escalation; adjust code that parsed WWW-Authenticate scope or relied on passthrough iteration. [1]
  5. If you use zod, check/upgrade zod to the required peer version (v3.25+ or v4 for beta features) and test schema behavior. [1]
  6. Upgrade Node to the LTS version required by the newer SDK and run integration tests (SSE/stdio transports, elicitation flows). [1]
  7. For Python consumers (if applicable), review the Python SDK v1.22.0 release notes for ClientSessionGroup changes. [3]

References

  • modelcontextprotocol/typescript-sdk releases (includes v1.22.0 changelog and SEPs mentioned). [1]
  • @modelcontextprotocol/sdk v1.0.4 package info (npm). [2]
  • modelcontextprotocol/python-sdk v1.22.0 release notes (ClientSessionGroup notes). [3]

If you want, I can:

  • produce a line-by-line diff of breaking API changes by comparing your code usage to the SDK’s public types (I can fetch the compare URL and parse relevant commits), or
  • fetch the full commit/PR list between 1.0.4 and 1.22.0 and extract exact code-level changes you’ll need to make. Which do you prefer?


---

🏁 Script executed:

```shell
#!/bin/bash
# Find instrumentation-mcp source files and examine SDK usage
find packages/instrumentation-mcp -type f \( -name "*.ts" -o -name "*.js" \) ! -path "*/node_modules/*" ! -path "*/dist/*" | head -20

Length of output: 239


🏁 Script executed:

#!/bin/bash
# Search for MCP SDK imports and API usage in instrumentation-mcp
rg "@modelcontextprotocol/sdk|registerTool|Client|Server|Tool" packages/instrumentation-mcp -n -C3 --type ts --type js

Length of output: 27425


🏁 Script executed:

#!/bin/bash
# Check the main entry point and structure of instrumentation-mcp
cat packages/instrumentation-mcp/package.json | grep -A5 -B5 '"main"\|"exports"'

Length of output: 305


🏁 Script executed:

#!/bin/bash
# Examine the instrumentation-mcp implementation files
ls -la packages/instrumentation-mcp/src/ 2>/dev/null || echo "src directory not found, checking structure:"
find packages/instrumentation-mcp -maxdepth 3 -type f -name "*.ts" -o -name "*.js" | grep -v node_modules | head -15

Length of output: 540


🏁 Script executed:

#!/bin/bash
# Look for any version constraints or compatibility notes in the package
cat packages/instrumentation-mcp/package.json

Length of output: 1633


Update @modelcontextprotocol/sdk devDependency to a more recent version.

The registerTool ZodType support added in v1.22.0 is backwards-compatible with existing plain-object schema definitions, so the current test code remains compatible. However, the pinned version ^1.0.4 in devDependencies is significantly outdated. Version 1.22.0 (released Nov 13, 2025) includes multiple improvements including request payload decoupling, TypeScript typecheck fixes, and stricter tool name format validation. While the instrumentation's version constraint (>=1.0.0) remains broad, updating to ^1.22.0 or a recent stable version will ensure tests run against the latest SDK with latest bugfixes and features. No code changes are required since the test patterns using registerTool with plain descriptive objects remain compatible.

🤖 Prompt for AI Agents
In packages/instrumentation-mcp/package.json around line 49, the devDependency
"@modelcontextprotocol/sdk" is pinned to the outdated version "^1.0.4"; update
the version string to a recent release that includes registerTool ZodType
support and fixes (for example "^1.22.0"), then reinstall dependencies
(npm/yarn/pnpm install) and commit the updated package.json and lockfile so
CI/tests run against the newer SDK.

"@opentelemetry/context-async-hooks": "^2.0.1",
"@opentelemetry/sdk-trace-node": "^2.0.1",
"@pollyjs/adapter-fetch": "^6.0.7",
"@pollyjs/adapter-node-http": "^6.0.6",
"@pollyjs/core": "^6.0.6",
"@pollyjs/persister-fs": "^6.0.6",
"@types/mocha": "^10.0.10",
"ts-mocha": "^11.1.0",
"zod": "^3.25.76"
},
"homepage": "https://github.com/traceloop/openllmetry-js/tree/main/packages/instrumentation-mcp"
}
39 changes: 39 additions & 0 deletions packages/instrumentation-mcp/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const dts = require("rollup-plugin-dts");
const typescript = require("@rollup/plugin-typescript");
const json = require("@rollup/plugin-json");

const name = require("./package.json").main.replace(/\.js$/, "");

const bundle = (config) => ({
...config,
input: "src/index.ts",
external: (id) => !/^[./]/.test(id),
});

exports.default = [
bundle({
plugins: [
typescript.default({ exclude: ["test/**/*", "tests/**/*"] }),
json.default(),
],
output: [
{
file: `${name}.js`,
format: "cjs",
sourcemap: true,
},
{
file: `${name}.mjs`,
format: "es",
sourcemap: true,
},
],
}),
bundle({
plugins: [dts.default({ exclude: ["test/**/*", "tests/**/*"] })],
output: {
file: `${name}.d.ts`,
format: "es",
},
}),
];
18 changes: 18 additions & 0 deletions packages/instrumentation-mcp/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright Traceloop
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

export { McpInstrumentation } from "./instrumentation";
export { McpInstrumentationConfig } from "./types";
Loading
Loading