Skip to content

Commit 3d7b845

Browse files
galkleinmannirgaclaude
authored
feat(mcp): add mcp official sdk instrumentation (#829)
Co-authored-by: Nir Gazit <nirga@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
1 parent 450ccd5 commit 3d7b845

File tree

21 files changed

+2074
-202
lines changed

21 files changed

+2074
-202
lines changed

packages/ai-semantic-conventions/src/SemanticAttributes.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ export const SpanAttributes = {
6060
TRACELOOP_ASSOCIATION_PROPERTIES: "traceloop.association.properties",
6161
TRACELOOP_ENTITY_INPUT: "traceloop.entity.input",
6262
TRACELOOP_ENTITY_OUTPUT: "traceloop.entity.output",
63+
64+
// MCP (Model Context Protocol)
65+
MCP_RESPONSE_VALUE: "mcp.response.value",
66+
MCP_REQUEST_ID: "mcp.request.id",
6367
};
6468

6569
export const Events = {
@@ -117,5 +121,6 @@ export enum TraceloopSpanKindValues {
117121
TASK = "task",
118122
AGENT = "agent",
119123
TOOL = "tool",
124+
SESSION = "session",
120125
UNKNOWN = "unknown",
121126
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
dist
2+
node_modules
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# OpenTelemetry MCP Instrumentation for Node.js
2+
3+
[![NPM Published Version][npm-img]][npm-url]
4+
[![Apache License][license-image]][license-image]
5+
6+
This library allows tracing of agentic workflows implemented with MCP (Model Context Protocol) framework using the [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk).
7+
8+
## Installation
9+
10+
```bash
11+
npm install --save @traceloop/instrumentation-mcp
12+
```
13+
14+
## Usage
15+
16+
```javascript
17+
const { McpInstrumentation } = require("@traceloop/instrumentation-mcp");
18+
const { registerInstrumentations } = require("@opentelemetry/instrumentation");
19+
20+
registerInstrumentations({
21+
instrumentations: [new McpInstrumentation()],
22+
});
23+
```
24+
25+
## Privacy
26+
27+
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.
28+
29+
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.
30+
31+
To disable logging, set the `traceContent` config option to `false`:
32+
33+
```javascript
34+
const { McpInstrumentation } = require("@traceloop/instrumentation-mcp");
35+
36+
const mcpInstrumentation = new McpInstrumentation({
37+
traceContent: false,
38+
});
39+
```
40+
41+
## Instrumented Operations
42+
43+
This instrumentation tracks the following MCP operations:
44+
45+
### Client Operations
46+
47+
- Session lifecycle management
48+
- Tool invocations
49+
- Resource access
50+
- Prompt templates
51+
- MCP protocol methods
52+
53+
### Server Operations
54+
55+
- Request handling
56+
- Tool execution
57+
- Resource serving
58+
- Server-side spans
59+
60+
## License
61+
62+
Apache 2.0 - See [LICENSE][license-url] for more information.
63+
64+
[npm-url]: https://www.npmjs.com/package/@traceloop/instrumentation-mcp
65+
[npm-img]: https://badge.fury.io/js/%40traceloop%2Finstrumentation-mcp.svg
66+
[license-url]: https://github.com/traceloop/openllmetry-js/blob/main/LICENSE
67+
[license-image]: https://img.shields.io/badge/license-Apache_2.0-green.svg?style=flat
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
const js = require("@eslint/js");
2+
const rootConfig = require("../../eslint.config.cjs");
3+
4+
const { FlatCompat } = require("@eslint/eslintrc");
5+
6+
const compat = new FlatCompat({
7+
baseDirectory: __dirname,
8+
recommendedConfig: js.configs.recommended,
9+
allConfig: js.configs.all,
10+
});
11+
12+
module.exports = [
13+
{
14+
ignores: ["!**/*", "**/node_modules", "dist/**/*"],
15+
},
16+
...rootConfig,
17+
{
18+
files: ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx"],
19+
rules: {},
20+
},
21+
{
22+
files: ["**/*.ts", "**/*.tsx"],
23+
rules: {},
24+
},
25+
{
26+
files: ["**/*.js", "**/*.jsx"],
27+
rules: {},
28+
},
29+
];
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
{
2+
"name": "@traceloop/instrumentation-mcp",
3+
"version": "0.20.2",
4+
"description": "MCP (Model Context Protocol) Instrumentation",
5+
"main": "dist/index.js",
6+
"module": "dist/index.mjs",
7+
"types": "dist/index.d.ts",
8+
"repository": "traceloop/openllmetry-js",
9+
"scripts": {
10+
"build": "rollup -c",
11+
"lint": "eslint .",
12+
"lint:fix": "eslint . --fix",
13+
"test": "ts-mocha -p tsconfig.json 'test/**/*.test.ts'"
14+
},
15+
"keywords": [
16+
"opentelemetry",
17+
"nodejs",
18+
"tracing",
19+
"mcp",
20+
"model-context-protocol"
21+
],
22+
"author": "Traceloop",
23+
"license": "Apache-2.0",
24+
"engines": {
25+
"node": ">=14"
26+
},
27+
"files": [
28+
"dist/**/*.js",
29+
"dist/**/*.mjs",
30+
"dist/**/*.js.map",
31+
"dist/**/*.d.ts",
32+
"doc",
33+
"LICENSE",
34+
"README.md",
35+
"package.json"
36+
],
37+
"publishConfig": {
38+
"access": "public"
39+
},
40+
"dependencies": {
41+
"@opentelemetry/api": "^1.9.0",
42+
"@opentelemetry/core": "^2.0.1",
43+
"@opentelemetry/instrumentation": "^0.203.0",
44+
"@opentelemetry/semantic-conventions": "^1.36.0",
45+
"@traceloop/ai-semantic-conventions": "workspace:*",
46+
"tslib": "^2.8.1"
47+
},
48+
"devDependencies": {
49+
"@modelcontextprotocol/sdk": "^1.0.4",
50+
"@opentelemetry/context-async-hooks": "^2.0.1",
51+
"@opentelemetry/sdk-trace-node": "^2.0.1",
52+
"@pollyjs/adapter-fetch": "^6.0.7",
53+
"@pollyjs/adapter-node-http": "^6.0.6",
54+
"@pollyjs/core": "^6.0.6",
55+
"@pollyjs/persister-fs": "^6.0.6",
56+
"@types/mocha": "^10.0.10",
57+
"ts-mocha": "^11.1.0",
58+
"zod": "^3.25.76"
59+
},
60+
"homepage": "https://github.com/traceloop/openllmetry-js/tree/main/packages/instrumentation-mcp"
61+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
const dts = require("rollup-plugin-dts");
2+
const typescript = require("@rollup/plugin-typescript");
3+
const json = require("@rollup/plugin-json");
4+
5+
const name = require("./package.json").main.replace(/\.js$/, "");
6+
7+
const bundle = (config) => ({
8+
...config,
9+
input: "src/index.ts",
10+
external: (id) => !/^[./]/.test(id),
11+
});
12+
13+
exports.default = [
14+
bundle({
15+
plugins: [
16+
typescript.default({ exclude: ["test/**/*", "tests/**/*"] }),
17+
json.default(),
18+
],
19+
output: [
20+
{
21+
file: `${name}.js`,
22+
format: "cjs",
23+
sourcemap: true,
24+
},
25+
{
26+
file: `${name}.mjs`,
27+
format: "es",
28+
sourcemap: true,
29+
},
30+
],
31+
}),
32+
bundle({
33+
plugins: [dts.default({ exclude: ["test/**/*", "tests/**/*"] })],
34+
output: {
35+
file: `${name}.d.ts`,
36+
format: "es",
37+
},
38+
}),
39+
];
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* Copyright Traceloop
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
export { McpInstrumentation } from "./instrumentation";
18+
export { McpInstrumentationConfig } from "./types";

0 commit comments

Comments
 (0)