@awarecorp/mcp-logger 0.0.2-dev.1 โ†’ 0.0.2-dev.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +16 -5
  2. package/dist/cli/cli.js +1 -84
  3. package/dist/cli/interceptor.js +1 -170
  4. package/dist/index.d.ts +110 -10
  5. package/dist/index.js +1 -21
  6. package/dist/sdk/index.js +1 -80
  7. package/dist/sdk/instrumentation.js +1 -99
  8. package/dist/sdk/types.d.ts +40 -11
  9. package/dist/shared/config.js +1 -18
  10. package/dist/shared/span-utils.js +1 -90
  11. package/dist/shared/telemetry.js +1 -91
  12. package/dist/shared/types.d.ts +6 -5
  13. package/package.json +11 -5
  14. package/dist/cli/cli.d.ts.map +0 -1
  15. package/dist/cli/cli.js.map +0 -1
  16. package/dist/cli/interceptor.d.ts.map +0 -1
  17. package/dist/cli/interceptor.js.map +0 -1
  18. package/dist/cli/types.d.ts.map +0 -1
  19. package/dist/cli/types.js +0 -5
  20. package/dist/cli/types.js.map +0 -1
  21. package/dist/index.d.ts.map +0 -1
  22. package/dist/index.js.map +0 -1
  23. package/dist/sdk/index.d.ts +0 -66
  24. package/dist/sdk/index.d.ts.map +0 -1
  25. package/dist/sdk/index.js.map +0 -1
  26. package/dist/sdk/instrumentation.d.ts +0 -11
  27. package/dist/sdk/instrumentation.d.ts.map +0 -1
  28. package/dist/sdk/instrumentation.js.map +0 -1
  29. package/dist/sdk/types.d.ts.map +0 -1
  30. package/dist/sdk/types.js +0 -5
  31. package/dist/sdk/types.js.map +0 -1
  32. package/dist/shared/config.d.ts +0 -18
  33. package/dist/shared/config.d.ts.map +0 -1
  34. package/dist/shared/config.js.map +0 -1
  35. package/dist/shared/span-utils.d.ts +0 -31
  36. package/dist/shared/span-utils.d.ts.map +0 -1
  37. package/dist/shared/span-utils.js.map +0 -1
  38. package/dist/shared/telemetry.d.ts +0 -25
  39. package/dist/shared/telemetry.d.ts.map +0 -1
  40. package/dist/shared/telemetry.js.map +0 -1
  41. package/dist/shared/types.d.ts.map +0 -1
  42. package/dist/shared/types.js +0 -5
  43. package/dist/shared/types.js.map +0 -1
package/README.md CHANGED
@@ -284,19 +284,30 @@ MIT
284
284
 
285
285
  ## ๐Ÿ“ฆ ๋ฐฐํฌ (Maintainers Only)
286
286
 
287
- ### Stable ๋ฒ„์ „ ๋ฐฐํฌ
287
+ **๊ถŒ์žฅ:** GitHub Actions๋ฅผ ์‚ฌ์šฉํ•œ ์ž๋™ ๋ฐฐํฌ
288
+
289
+ ### ์ž๋™ ๋ฐฐํฌ (GitHub Actions) โญ
288
290
  ```bash
289
- npm run version:patch # ๋˜๋Š” minor, major
290
- npm run publish:stable
291
+ # Dev ๋ฒ„์ „ (develop ๋ธŒ๋žœ์น˜)
292
+ git checkout develop
293
+ npm run version:dev
294
+ git push origin develop --tags
291
295
  ```
292
296
 
293
- ### Dev ๋ฒ„์ „ ๋ฐฐํฌ
297
+ ์ž์„ธํ•œ ๊ฐ€์ด๋“œ:
298
+ - [GITHUB_SETUP.md](./GITHUB_SETUP.md) - Repository ์ดˆ๊ธฐ ์„ค์ •
299
+ - [GITHUB_ACTIONS.md](./GITHUB_ACTIONS.md) - ์ž๋™ ๋ฐฐํฌ ์‚ฌ์šฉ๋ฒ•
300
+
301
+ ### ์ˆ˜๋™ ๋ฐฐํฌ (๋กœ์ปฌ)
294
302
  ```bash
303
+ # Dev ๋ฒ„์ „
295
304
  npm run version:dev
296
305
  npm run publish:dev
297
306
  ```
298
307
 
299
- ์ž์„ธํ•œ ๋‚ด์šฉ์€ [DEVELOPMENT.md](./DEVELOPMENT.md#๋ฐฐํฌ)๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.
308
+ **์ฐธ๊ณ :** Stable ๋ฒ„์ „์€ ์•„์ง ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
309
+
310
+ ์ž์„ธํ•œ ๊ฐœ๋ฐœ ๊ฐ€์ด๋“œ: [DEVELOPMENT.md](./DEVELOPMENT.md)
300
311
 
301
312
  ---
302
313
 
package/dist/cli/cli.js CHANGED
@@ -1,85 +1,2 @@
1
1
  #!/usr/bin/env node
2
- /**
3
- * MCP Logger CLI
4
- *
5
- * MCP ์„œ๋ฒ„๋ฅผ ๋ž˜ํ•‘ํ•˜์—ฌ ์ž๋™์œผ๋กœ observability๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
6
- */
7
- import { spawn } from 'child_process';
8
- import { program } from 'commander';
9
- import { initializeTelemetry, shutdownTelemetry } from '../shared/telemetry.js';
10
- import { MessageInterceptor } from './interceptor.js';
11
- program
12
- .name('mcp-logger')
13
- .description('Add observability to any MCP server without code changes')
14
- .version('1.0.0')
15
- .requiredOption('-k, --api-key <key>', 'Aware API key')
16
- .option('-s, --service-name <name>', 'Service name for identification')
17
- .option('-d, --debug', 'Enable debug logging', false)
18
- .option('-e, --endpoint <url>', 'Custom OTLP endpoint')
19
- .argument('<command...>', 'MCP server command to wrap')
20
- .action(async (command, options) => {
21
- try {
22
- // 1. Telemetry ์ดˆ๊ธฐํ™”
23
- initializeTelemetry(options);
24
- if (options.debug) {
25
- console.error('[MCP Logger CLI] Starting MCP server:', command.join(' '));
26
- }
27
- // 2. MCP ์„œ๋ฒ„ ์‹คํ–‰
28
- const [cmd, ...args] = command;
29
- const mcpServer = spawn(cmd, args, {
30
- stdio: ['pipe', 'pipe', 'inherit'], // stdin, stdout, stderr
31
- env: {
32
- ...process.env,
33
- // Trace context ์ „ํŒŒ (ํ–ฅํ›„ ์‚ฌ์šฉ)
34
- MCP_LOGGER_ENABLED: 'true',
35
- },
36
- });
37
- // 3. stdin ๊ฐ€๋กœ์ฑ„๊ธฐ (Claude โ†’ MCP Server)
38
- const requestInterceptor = new MessageInterceptor('request', options.debug);
39
- process.stdin.pipe(requestInterceptor).pipe(mcpServer.stdin);
40
- // 4. stdout ๊ฐ€๋กœ์ฑ„๊ธฐ (MCP Server โ†’ Claude)
41
- const responseInterceptor = new MessageInterceptor('response', options.debug);
42
- mcpServer.stdout.pipe(responseInterceptor).pipe(process.stdout);
43
- // 5. ์—๋Ÿฌ ์ฒ˜๋ฆฌ
44
- mcpServer.on('error', async (err) => {
45
- console.error('[MCP Logger CLI] Failed to start MCP server:', err);
46
- await shutdownTelemetry();
47
- process.exit(1);
48
- });
49
- mcpServer.on('exit', async (code, signal) => {
50
- if (options.debug) {
51
- console.error(`[MCP Logger CLI] MCP server exited with code ${code}, signal ${signal}`);
52
- }
53
- await shutdownTelemetry();
54
- process.exit(code || 0);
55
- });
56
- // 6. ์‹œ๊ทธ๋„ ์ฒ˜๋ฆฌ - ํ•œ ๋ฒˆ๋งŒ ์ฒ˜๋ฆฌ
57
- let isShuttingDown = false;
58
- const handleShutdown = async (signal) => {
59
- if (isShuttingDown)
60
- return;
61
- isShuttingDown = true;
62
- if (options.debug) {
63
- console.error(`[MCP Logger CLI] Received ${signal}, shutting down...`);
64
- }
65
- mcpServer.kill(signal);
66
- // MCP ์„œ๋ฒ„๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ (์ตœ๋Œ€ 5์ดˆ)
67
- await Promise.race([
68
- new Promise(resolve => mcpServer.once('exit', resolve)),
69
- new Promise(resolve => setTimeout(resolve, 5000))
70
- ]);
71
- await shutdownTelemetry();
72
- process.exit(0);
73
- };
74
- process.on('SIGTERM', () => handleShutdown('SIGTERM'));
75
- process.on('SIGINT', () => handleShutdown('SIGINT'));
76
- }
77
- catch (err) {
78
- console.error('[MCP Logger CLI] Fatal error:', err);
79
- await shutdownTelemetry();
80
- process.exit(1);
81
- }
82
- });
83
- // CLI ์‹คํ–‰
84
- program.parse();
85
- //# sourceMappingURL=cli.js.map
2
+ import{spawn as e}from"child_process";import{program as r}from"commander";import{NodeSDK as t}from"@opentelemetry/sdk-node";import{OTLPTraceExporter as o}from"@opentelemetry/exporter-trace-otlp-http";import{Resource as s}from"@opentelemetry/resources";import{trace as i,SpanStatusCode as n}from"@opentelemetry/api";import{Transform as c}from"stream";const a="https://aware.mcypher.com/v1/traces",p="1.0.0";let g=null,d=null,m=!1;function l(){return d}async function u(){if(g)try{await g.shutdown(),g=null,d=null,m=!1}catch(e){console.error("[MCP Logger] Error shutting down telemetry:",e)}}function h(e,r=1e4){try{const t=JSON.stringify(e);return t.length>r?t.slice(0,r)+"... (truncated)":t}catch(e){return null}}class f extends c{buffer="";direction;debug;constructor(e,r=!1){super(),this.direction=e,this.debug=r}_transform(e,r,t){try{this.push(e),this.buffer+=e.toString(),this.buffer.length>1e6&&(this.debug&&console.error("[MCP Logger CLI] Buffer size exceeded, clearing..."),this.buffer=""),this.tryParseMessages(),t()}catch(e){t(e)}}tryParseMessages(){const e=this.buffer.split("\n");this.buffer=e.pop()||"";for(const r of e){const e=r.trim();if(e)try{const r=JSON.parse(e);this.traceMessage(r).catch(e=>{this.debug&&console.error("[MCP Logger CLI] Trace error:",e)})}catch(r){this.debug&&console.error("[MCP Logger CLI] Failed to parse:",e)}}}async traceMessage(e){const r=l();if(!r)return void(this.debug&&console.error("[MCP Logger CLI] Tracer not initialized"));const t=e.method?`mcp.${e.method}`:void 0!==e.id?"mcp.response":"mcp.notification";return new Promise(o=>{r.startActiveSpan(t,r=>{try{if(function(e,r){for(const[t,o]of Object.entries(r))null!=o&&e.setAttribute(t,o)}(r,{"mcp.direction":this.direction,"mcp.jsonrpc":e.jsonrpc||"2.0"}),void 0!==e.id&&r.setAttribute("mcp.id",String(e.id)),e.method&&r.setAttribute("mcp.method",e.method),e.params){const t=h(e.params);t&&(r.setAttribute("mcp.params.size",t.length),t.length<1e3&&r.setAttribute("mcp.params",t))}const t=h(e);t&&function(e,r,t,o){try{t?e.addEvent(r,t):e.addEvent(r)}catch(e){o&&console.error("[MCP Logger] Failed to add span event:",e)}}(r,`mcp.${this.direction}`,{message:t,timestamp:Date.now()},this.debug),this.debug&&console.error(`[MCP Logger CLI] ${this.direction}:`,JSON.stringify(e,null,2)),e.error?(r.setAttribute("mcp.error",!0),r.setAttribute("mcp.error.code",e.error.code),r.setAttribute("mcp.error.message",e.error.message),r.setStatus({code:n.ERROR,message:e.error.message})):function(e){e.setStatus({code:n.OK})}(r)}catch(e){this.debug&&console.error("[MCP Logger CLI] Error in span:",e),r.setStatus({code:n.ERROR,message:String(e)})}finally{r.end(),o()}})})}_flush(e){try{if(this.buffer.trim())try{const e=JSON.parse(this.buffer);this.traceMessage(e).catch(e=>{this.debug&&console.error("[MCP Logger CLI] Trace error:",e)})}catch(e){this.debug&&console.error("[MCP Logger CLI] Failed to parse final buffer:",e)}e()}catch(r){e(r)}}}r.name("mcp-logger").description("Add observability to any MCP server without code changes").version("1.0.0").requiredOption("-k, --api-key <key>","Aware API key").option("-s, --service-name <name>","Service name for identification").option("-e, --endpoint <url>","Custom OTLP endpoint").argument("<command...>","MCP server command to wrap").action(async(r,n)=>{try{const c=!0;!function(e){if(m)return console.error("[MCP Logger] Telemetry already initialized, returning existing tracer"),d;const r=e.serviceName||`mcp-server-${Math.random().toString(36).slice(2,8)}`;console.error("[MCP Logger] Initializing telemetry..."),console.error(`[MCP Logger] Endpoint: ${e.endpoint||a}`),console.error(`[MCP Logger] Service: ${r}`),g=new t({resource:new s({"service.name":r,"service.version":p}),traceExporter:new o({url:e.endpoint||a,headers:{"x-api-key":e.apiKey}})}),g.start(),d=i.getTracer("mcp-logger",p),m=!0,console.error("[MCP Logger] Telemetry initialized successfully");const n=async()=>{console.error("[MCP Logger] Shutting down telemetry..."),await u()};process.once("SIGTERM",n),process.once("SIGINT",n)}({...n,debug:c}),console.error("[MCP Logger CLI] Starting MCP server:",r.join(" "));const[l,...h]=r,C=e(l,h,{stdio:["pipe","pipe","inherit"],env:{...process.env,MCP_LOGGER_ENABLED:"true"}}),y=new f("request",c);process.stdin.pipe(y).pipe(C.stdin);const L=new f("response",c);C.stdout.pipe(L).pipe(process.stdout),C.on("error",async e=>{console.error("[MCP Logger CLI] Failed to start MCP server:",e),await u(),process.exit(1)}),C.on("exit",async(e,r)=>{console.error(`[MCP Logger CLI] MCP server exited with code ${e}, signal ${r}`),await u(),process.exit(e||0)});let M=!1;const P=async e=>{M||(M=!0,console.error(`[MCP Logger CLI] Received ${e}, shutting down...`),C.kill(e),await Promise.race([new Promise(e=>C.once("exit",e)),new Promise(e=>setTimeout(e,5e3))]),await u(),process.exit(0))};process.on("SIGTERM",()=>P("SIGTERM")),process.on("SIGINT",()=>P("SIGINT"))}catch(e){console.error("[MCP Logger CLI] Fatal error:",e),await u(),process.exit(1)}}),r.parse();
@@ -1,170 +1 @@
1
- /**
2
- * JSON-RPC ๋ฉ”์‹œ์ง€ ๊ฐ€๋กœ์ฑ„๊ธฐ ๋ฐ ์ถ”์ 
3
- *
4
- * stdin/stdout์„ ํ†ต๊ณผํ•˜๋Š” JSON-RPC ๋ฉ”์‹œ์ง€๋ฅผ ํŒŒ์‹ฑํ•˜์—ฌ OpenTelemetry๋กœ ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค.
5
- */
6
- import { Transform } from 'stream';
7
- import { SpanStatusCode } from '@opentelemetry/api';
8
- import { getTracer } from '../shared/telemetry.js';
9
- import { setSpanAttributes, addSpanEvent, markSpanSuccess, safeStringify } from '../shared/span-utils.js';
10
- /**
11
- * JSON-RPC ๋ฉ”์‹œ์ง€ ํŒŒ์‹ฑ ๋ฐ ๋กœ๊น…์„ ์œ„ํ•œ Transform stream
12
- */
13
- export class MessageInterceptor extends Transform {
14
- buffer = '';
15
- direction;
16
- debug;
17
- constructor(direction, debug = false) {
18
- super();
19
- this.direction = direction;
20
- this.debug = debug;
21
- }
22
- _transform(chunk, encoding, callback) {
23
- try {
24
- // ์›๋ณธ ๋ฐ์ดํ„ฐ๋Š” ๊ทธ๋Œ€๋กœ ์ „๋‹ฌ
25
- this.push(chunk);
26
- // ๋กœ๊น…์„ ์œ„ํ•œ ํŒŒ์‹ฑ (๋น„๋™๊ธฐ)
27
- this.buffer += chunk.toString();
28
- // ๋ฒ„ํผ ํฌ๊ธฐ ์ œํ•œ (๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๋ฐฉ์ง€)
29
- if (this.buffer.length > 1_000_000) { // 1MB
30
- if (this.debug) {
31
- console.error('[MCP Logger CLI] Buffer size exceeded, clearing...');
32
- }
33
- this.buffer = '';
34
- }
35
- this.tryParseMessages();
36
- callback();
37
- }
38
- catch (err) {
39
- callback(err);
40
- }
41
- }
42
- /**
43
- * ๋ฒ„ํผ์—์„œ JSON-RPC ๋ฉ”์‹œ์ง€ ํŒŒ์‹ฑ ์‹œ๋„
44
- */
45
- tryParseMessages() {
46
- const lines = this.buffer.split('\n');
47
- // ๋งˆ์ง€๋ง‰ ๋ถˆ์™„์ „ํ•œ ๋ผ์ธ์€ ๋ฒ„ํผ์— ๋ณด๊ด€
48
- this.buffer = lines.pop() || '';
49
- for (const line of lines) {
50
- const trimmed = line.trim();
51
- if (!trimmed)
52
- continue;
53
- try {
54
- const message = JSON.parse(trimmed);
55
- // OpenTelemetry๋กœ ๋กœ๊น… (๋น„๋™๊ธฐ์ง€๋งŒ blockingํ•˜์ง€ ์•Š์Œ)
56
- this.traceMessage(message).catch(err => {
57
- if (this.debug) {
58
- console.error('[MCP Logger CLI] Trace error:', err);
59
- }
60
- });
61
- }
62
- catch (err) {
63
- // JSON ํŒŒ์‹ฑ ์‹คํŒจ๋Š” ๋ฌด์‹œ (MCP ๋ฉ”์‹œ์ง€๊ฐ€ ์•„๋‹ ์ˆ˜ ์žˆ์Œ)
64
- if (this.debug) {
65
- console.error('[MCP Logger CLI] Failed to parse:', trimmed);
66
- }
67
- }
68
- }
69
- }
70
- /**
71
- * ๋ฉ”์‹œ์ง€๋ฅผ OpenTelemetry span์œผ๋กœ ์ถ”์ 
72
- */
73
- async traceMessage(message) {
74
- const tracer = getTracer();
75
- if (!tracer) {
76
- if (this.debug) {
77
- console.error('[MCP Logger CLI] Tracer not initialized');
78
- }
79
- return;
80
- }
81
- const spanName = message.method
82
- ? `mcp.${message.method}`
83
- : message.id !== undefined
84
- ? 'mcp.response'
85
- : 'mcp.notification';
86
- return new Promise((resolve) => {
87
- tracer.startActiveSpan(spanName, (span) => {
88
- try {
89
- // ๊ธฐ๋ณธ ์†์„ฑ ์„ค์ •
90
- setSpanAttributes(span, {
91
- 'mcp.direction': this.direction,
92
- 'mcp.jsonrpc': message.jsonrpc || '2.0',
93
- });
94
- if (message.id !== undefined) {
95
- span.setAttribute('mcp.id', String(message.id));
96
- }
97
- if (message.method) {
98
- span.setAttribute('mcp.method', message.method);
99
- }
100
- // params ์ฒ˜๋ฆฌ
101
- if (message.params) {
102
- const paramsStr = safeStringify(message.params);
103
- if (paramsStr) {
104
- span.setAttribute('mcp.params.size', paramsStr.length);
105
- if (paramsStr.length < 1000) {
106
- span.setAttribute('mcp.params', paramsStr);
107
- }
108
- }
109
- }
110
- // ์ด๋ฒคํŠธ ๊ธฐ๋ก
111
- const messageStr = safeStringify(message);
112
- if (messageStr) {
113
- addSpanEvent(span, `mcp.${this.direction}`, {
114
- message: messageStr,
115
- timestamp: Date.now(),
116
- }, this.debug);
117
- }
118
- if (this.debug) {
119
- console.error(`[MCP Logger CLI] ${this.direction}:`, JSON.stringify(message, null, 2));
120
- }
121
- // ์—๋Ÿฌ ์ฒดํฌ
122
- if (message.error) {
123
- span.setAttribute('mcp.error', true);
124
- span.setAttribute('mcp.error.code', message.error.code);
125
- span.setAttribute('mcp.error.message', message.error.message);
126
- span.setStatus({ code: SpanStatusCode.ERROR, message: message.error.message });
127
- }
128
- else {
129
- markSpanSuccess(span);
130
- }
131
- }
132
- catch (err) {
133
- if (this.debug) {
134
- console.error('[MCP Logger CLI] Error in span:', err);
135
- }
136
- span.setStatus({ code: SpanStatusCode.ERROR, message: String(err) });
137
- }
138
- finally {
139
- span.end();
140
- resolve();
141
- }
142
- });
143
- });
144
- }
145
- _flush(callback) {
146
- try {
147
- // ๋‚จ์€ ๋ฒ„ํผ ์ฒ˜๋ฆฌ
148
- if (this.buffer.trim()) {
149
- try {
150
- const message = JSON.parse(this.buffer);
151
- this.traceMessage(message).catch(err => {
152
- if (this.debug) {
153
- console.error('[MCP Logger CLI] Trace error:', err);
154
- }
155
- });
156
- }
157
- catch (err) {
158
- if (this.debug) {
159
- console.error('[MCP Logger CLI] Failed to parse final buffer:', err);
160
- }
161
- }
162
- }
163
- callback();
164
- }
165
- catch (err) {
166
- callback(err);
167
- }
168
- }
169
- }
170
- //# sourceMappingURL=interceptor.js.map
1
+ import{Transform as e}from"stream";import"@opentelemetry/api";import"@opentelemetry/sdk-node";import"@opentelemetry/exporter-trace-otlp-http";import"@opentelemetry/resources";class r extends e{buffer="";direction;debug;constructor(e,r=!1){super(),this.direction=e,this.debug=r}_transform(e,r,t){try{this.push(e),this.buffer+=e.toString(),this.buffer.length>1e6&&(this.debug&&console.error("[MCP Logger CLI] Buffer size exceeded, clearing..."),this.buffer=""),this.tryParseMessages(),t()}catch(e){t(e)}}tryParseMessages(){const e=this.buffer.split("\n");this.buffer=e.pop()||"";for(const r of e){const e=r.trim();if(e)try{const r=JSON.parse(e);this.traceMessage(r).catch(e=>{this.debug&&console.error("[MCP Logger CLI] Trace error:",e)})}catch(r){this.debug&&console.error("[MCP Logger CLI] Failed to parse:",e)}}}async traceMessage(e){this.debug&&console.error("[MCP Logger CLI] Tracer not initialized")}_flush(e){try{if(this.buffer.trim())try{const e=JSON.parse(this.buffer);this.traceMessage(e).catch(e=>{this.debug&&console.error("[MCP Logger CLI] Trace error:",e)})}catch(e){this.debug&&console.error("[MCP Logger CLI] Failed to parse final buffer:",e)}e()}catch(r){e(r)}}}export{r as MessageInterceptor};
package/dist/index.d.ts CHANGED
@@ -1,15 +1,115 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+
1
3
  /**
2
- * @awarecorp/mcp-logger
4
+ * ๊ณตํ†ต ํƒ€์ž… ์ •์˜
5
+ */
6
+ /**
7
+ * ํ…”๋ ˆ๋ฉ”ํŠธ๋ฆฌ ์ดˆ๊ธฐํ™” ์˜ต์…˜
8
+ */
9
+ interface TelemetryOptions {
10
+ /**
11
+ * API Key for authentication (ํ•„์ˆ˜)
12
+ */
13
+ apiKey: string;
14
+ /**
15
+ * ์„œ๋น„์Šค ์ด๋ฆ„ (์˜ต์…˜)
16
+ * ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ์ž๋™์œผ๋กœ 'mcp-server-{random}' ํ˜•์‹์œผ๋กœ ์ƒ์„ฑ
17
+ */
18
+ serviceName?: string;
19
+ /**
20
+ * ์ปค์Šคํ…€ OTLP ์—”๋“œํฌ์ธํŠธ (์˜ต์…˜)
21
+ * ๊ธฐ๋ณธ๊ฐ’: CONFIG.ENDPOINT
22
+ */
23
+ endpoint?: string;
24
+ /**
25
+ * ๋””๋ฒ„๊ทธ ๋กœ๊ทธ ํ™œ์„ฑํ™” (์˜ต์…˜)
26
+ */
27
+ debug?: boolean;
28
+ }
29
+
30
+ /**
31
+ * SDK ํƒ€์ž… ์ •์˜
32
+ */
33
+
34
+ /**
35
+ * SDK ์ดˆ๊ธฐํ™” ์˜ต์…˜ (TelemetryOptions ํ™•์žฅ)
36
+ */
37
+ interface SDKInitOptions extends TelemetryOptions {
38
+ }
39
+ /**
40
+ * MCP Server ํƒ€์ž… (์žฌexport)
41
+ */
42
+ type MCPServer = Server;
43
+
44
+ /**
45
+ * ๊ณตํ†ต ํ…”๋ ˆ๋ฉ”ํŠธ๋ฆฌ ๋ ˆ์ด์–ด
46
+ *
47
+ * OpenTelemetry SDK ์ดˆ๊ธฐํ™” ๋ฐ ๊ด€๋ฆฌ๋ฅผ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.
48
+ * SDK์™€ CLI ์–‘์ชฝ์—์„œ ๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
49
+ */
50
+
51
+ /**
52
+ * Telemetry ์ข…๋ฃŒ
53
+ */
54
+ declare function shutdownTelemetry(): Promise<void>;
55
+
56
+ /**
57
+ * MCP Logger SDK
58
+ *
59
+ * MCP ์„œ๋ฒ„์— ์ž๋™ ๊ด€์ธก์„ฑ(Observability)์„ ์ถ”๊ฐ€ํ•˜๋Š” SDK์ž…๋‹ˆ๋‹ค.
60
+ */
61
+
62
+ /**
63
+ * MCP ์„œ๋ฒ„์— ์ž๋™ ๊ณ„์ธก์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
64
+ *
65
+ * ์ด ํ•จ์ˆ˜๋Š” MCP ์„œ๋ฒ„์˜ ๋ชจ๋“  ์š”์ฒญ/์‘๋‹ต์„ ์ž๋™์œผ๋กœ ๋กœ๊น…ํ•˜๊ณ  ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค.
66
+ * OpenTelemetry๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ traces๋ฅผ ์ˆ˜์ง‘ํ•˜๋ฉฐ, ์„ค์ •๋œ ์—”๋“œํฌ์ธํŠธ๋กœ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.
67
+ *
68
+ * @param server - MCP Server ์ธ์Šคํ„ด์Šค
69
+ * @param options - ์ดˆ๊ธฐํ™” ์˜ต์…˜
70
+ *
71
+ * @throws {Error} apiKey๊ฐ€ ์ œ๊ณต๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ
72
+ * @throws {Error} server ์ธ์Šคํ„ด์Šค๊ฐ€ ์ œ๊ณต๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ
73
+ *
74
+ * @example
75
+ * TypeScript ์‚ฌ์šฉ ์˜ˆ์‹œ:
76
+ * ```typescript
77
+ * import { Server } from '@modelcontextprotocol/sdk/server/index.js';
78
+ * import { initMCPLogger } from '@awarecorp/mcp-logger';
79
+ *
80
+ * const server = new Server({ name: 'my-server', version: '1.0.0' }, {
81
+ * capabilities: { tools: {} }
82
+ * });
83
+ *
84
+ * initMCPLogger(server, {
85
+ * apiKey: 'your-api-key',
86
+ * serviceName: 'my-mcp-server',
87
+ * debug: true,
88
+ * });
89
+ *
90
+ * server.setRequestHandler('tools/call', async (request) => {
91
+ * // ์ด ํ•ธ๋“ค๋Ÿฌ๋Š” ์ž๋™์œผ๋กœ ๋กœ๊น…๋ฉ๋‹ˆ๋‹ค
92
+ * return { result: 'success' };
93
+ * });
94
+ * ```
3
95
  *
4
- * Unified MCP observability solution
96
+ * @example
97
+ * JavaScript ์‚ฌ์šฉ ์˜ˆ์‹œ:
98
+ * ```javascript
99
+ * const { Server } = require('@modelcontextprotocol/sdk/server/index.js');
100
+ * const { initMCPLogger } = require('@awarecorp/mcp-logger');
5
101
  *
6
- * This package provides:
7
- * 1. SDK: For programmatic integration into MCP servers
8
- * 2. CLI: For wrapping existing MCP servers without code changes
102
+ * const server = new Server({ name: 'my-server', version: '1.0.0' }, {
103
+ * capabilities: { tools: {} }
104
+ * });
9
105
  *
10
- * NOTE: This entry point ONLY exports the SDK.
11
- * CLI functionality is available through the `mcp-logger` binary.
106
+ * initMCPLogger(server, {
107
+ * apiKey: process.env.API_KEY,
108
+ * serviceName: 'my-mcp-server',
109
+ * });
110
+ * ```
12
111
  */
13
- export { initMCPLogger, shutdown } from './sdk/index.js';
14
- export type { SDKInitOptions, MCPServer } from './sdk/types.js';
15
- //# sourceMappingURL=index.d.ts.map
112
+ declare function initMCPLogger(server: MCPServer, options: SDKInitOptions): void;
113
+
114
+ export { initMCPLogger, shutdownTelemetry as shutdown };
115
+ export type { MCPServer, SDKInitOptions };
package/dist/index.js CHANGED
@@ -1,21 +1 @@
1
- /**
2
- * @awarecorp/mcp-logger
3
- *
4
- * Unified MCP observability solution
5
- *
6
- * This package provides:
7
- * 1. SDK: For programmatic integration into MCP servers
8
- * 2. CLI: For wrapping existing MCP servers without code changes
9
- *
10
- * NOTE: This entry point ONLY exports the SDK.
11
- * CLI functionality is available through the `mcp-logger` binary.
12
- */
13
- // ============================================================================
14
- // SDK Exports (PUBLIC API)
15
- // ============================================================================
16
- export { initMCPLogger, shutdown } from './sdk/index.js';
17
- // ============================================================================
18
- // CLI is NOT exported here
19
- // Access via: npx @awarecorp/mcp-logger --api-key xxx -- <command>
20
- // ============================================================================
21
- //# sourceMappingURL=index.js.map
1
+ import{NodeSDK as e}from"@opentelemetry/sdk-node";import{OTLPTraceExporter as r}from"@opentelemetry/exporter-trace-otlp-http";import{Resource as t}from"@opentelemetry/resources";import{trace as o,SpanStatusCode as n}from"@opentelemetry/api";const s="https://aware.mcypher.com/v1/traces",c="1.0.0";let i=null,a=null,l=!1;function u(){return a}async function g(){if(i)try{await i.shutdown(),i=null,a=null,l=!1}catch(e){console.error("[MCP Logger] Error shutting down telemetry:",e)}}function m(e,r){for(const[t,o]of Object.entries(r))null!=o&&e.setAttribute(t,o)}function p(e,r,t,o){try{t?e.addEvent(r,t):e.addEvent(r)}catch(e){o&&console.error("[MCP Logger] Failed to add span event:",e)}}function d(e,r=1e4){try{const t=JSON.stringify(e);return t.length>r?t.slice(0,r)+"... (truncated)":t}catch(e){return null}}function h(h,f){if(!f.apiKey)throw new Error("[MCP Logger SDK] apiKey is required");if(!h)throw new Error("[MCP Logger SDK] server instance is required");!function(n){if(l)return n.debug&&console.error("[MCP Logger] Telemetry already initialized, returning existing tracer"),a;const u=n.serviceName||`mcp-server-${Math.random().toString(36).slice(2,8)}`;n.debug&&(console.error("[MCP Logger] Initializing telemetry..."),console.error(`[MCP Logger] Endpoint: ${n.endpoint||s}`),console.error(`[MCP Logger] Service: ${u}`)),i=new e({resource:new t({"service.name":u,"service.version":c}),traceExporter:new r({url:n.endpoint||s,headers:{"x-api-key":n.apiKey}})}),i.start(),a=o.getTracer("mcp-logger",c),l=!0,n.debug&&console.error("[MCP Logger] Telemetry initialized successfully");const m=async()=>{n.debug&&console.error("[MCP Logger] Shutting down telemetry..."),await g()};process.once("SIGTERM",m),process.once("SIGINT",m)}(f),function(e,r=!1){const t=u();if(!t)throw new Error("[MCP Logger SDK] Tracer not initialized. Call initMCPLogger first.");const o=e.setRequestHandler.bind(e);e.setRequestHandler=function(e,s){const c=e.shape?.method,i=c?._def?.value||"unknown";return r&&console.log(`[MCP Logger SDK] Instrumenting handler: ${i}`),o(e,async(e,o)=>{const c=`mcp.${i}`;return await t.startActiveSpan(c,{attributes:{"mcp.method":i,"mcp.request.method":e.method}},async t=>{const c=Date.now();try{const i=d(e.params||{});m(t,{"mcp.request.id":"unknown","mcp.request.params.size":i?.length}),i&&i.length<1e3&&t.setAttribute("mcp.request.params",i),p(t,"mcp.request.received",{"request.method":e.method,"request.timestamp":c},r),r&&console.log("[MCP Logger SDK] Request received:",{method:e.method,params:e.params});const a=await s(e,o),l=Date.now(),u=l-c,g=d(a);return m(t,{"mcp.duration_ms":u,"mcp.response.size":g?.length}),g&&g.length<1e3&&t.setAttribute("mcp.response.result",g),p(t,"mcp.response.sent",{"response.timestamp":l,"response.duration_ms":u},r),function(e){e.setStatus({code:n.OK})}(t),r&&console.log(`[MCP Logger SDK] Response sent (${u}ms):`,a),a}catch(e){throw function(e,r,t){const o=r instanceof Error?r.message:"Unknown error",s=r instanceof Error?r.constructor.name:"Error";r instanceof Error&&e.recordException(r),e.setStatus({code:n.ERROR,message:o}),e.setAttribute("error",!0),e.setAttribute("error.type",s),e.setAttribute("error.message",o),t&&console.error("[MCP Logger] Error recorded in span:",r)}(t,e,r),r&&console.error("[MCP Logger SDK] Error occurred:",e),e}finally{t.end()}})})},r&&console.log("[MCP Logger SDK] Server instrumentation complete")}(h,f.debug),f.debug&&console.log("[MCP Logger SDK] โœ“ Initialization complete")}export{h as initMCPLogger,g as shutdown};
package/dist/sdk/index.js CHANGED
@@ -1,80 +1 @@
1
- /**
2
- * MCP Logger SDK
3
- *
4
- * MCP ์„œ๋ฒ„์— ์ž๋™ ๊ด€์ธก์„ฑ(Observability)์„ ์ถ”๊ฐ€ํ•˜๋Š” SDK์ž…๋‹ˆ๋‹ค.
5
- */
6
- import { initializeTelemetry } from '../shared/telemetry.js';
7
- import { instrumentMCPServer } from './instrumentation.js';
8
- /**
9
- * MCP ์„œ๋ฒ„์— ์ž๋™ ๊ณ„์ธก์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
10
- *
11
- * ์ด ํ•จ์ˆ˜๋Š” MCP ์„œ๋ฒ„์˜ ๋ชจ๋“  ์š”์ฒญ/์‘๋‹ต์„ ์ž๋™์œผ๋กœ ๋กœ๊น…ํ•˜๊ณ  ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค.
12
- * OpenTelemetry๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ traces๋ฅผ ์ˆ˜์ง‘ํ•˜๋ฉฐ, ์„ค์ •๋œ ์—”๋“œํฌ์ธํŠธ๋กœ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.
13
- *
14
- * @param server - MCP Server ์ธ์Šคํ„ด์Šค
15
- * @param options - ์ดˆ๊ธฐํ™” ์˜ต์…˜
16
- *
17
- * @throws {Error} apiKey๊ฐ€ ์ œ๊ณต๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ
18
- * @throws {Error} server ์ธ์Šคํ„ด์Šค๊ฐ€ ์ œ๊ณต๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ
19
- *
20
- * @example
21
- * TypeScript ์‚ฌ์šฉ ์˜ˆ์‹œ:
22
- * ```typescript
23
- * import { Server } from '@modelcontextprotocol/sdk/server/index.js';
24
- * import { initMCPLogger } from '@awarecorp/mcp-logger';
25
- *
26
- * const server = new Server({ name: 'my-server', version: '1.0.0' }, {
27
- * capabilities: { tools: {} }
28
- * });
29
- *
30
- * initMCPLogger(server, {
31
- * apiKey: 'your-api-key',
32
- * serviceName: 'my-mcp-server',
33
- * debug: true,
34
- * });
35
- *
36
- * server.setRequestHandler('tools/call', async (request) => {
37
- * // ์ด ํ•ธ๋“ค๋Ÿฌ๋Š” ์ž๋™์œผ๋กœ ๋กœ๊น…๋ฉ๋‹ˆ๋‹ค
38
- * return { result: 'success' };
39
- * });
40
- * ```
41
- *
42
- * @example
43
- * JavaScript ์‚ฌ์šฉ ์˜ˆ์‹œ:
44
- * ```javascript
45
- * const { Server } = require('@modelcontextprotocol/sdk/server/index.js');
46
- * const { initMCPLogger } = require('@awarecorp/mcp-logger');
47
- *
48
- * const server = new Server({ name: 'my-server', version: '1.0.0' }, {
49
- * capabilities: { tools: {} }
50
- * });
51
- *
52
- * initMCPLogger(server, {
53
- * apiKey: process.env.API_KEY,
54
- * serviceName: 'my-mcp-server',
55
- * });
56
- * ```
57
- */
58
- export function initMCPLogger(server, options) {
59
- if (!options.apiKey) {
60
- throw new Error('[MCP Logger SDK] apiKey is required');
61
- }
62
- if (!server) {
63
- throw new Error('[MCP Logger SDK] server instance is required');
64
- }
65
- // 1. OpenTelemetry SDK ์ดˆ๊ธฐํ™”
66
- initializeTelemetry(options);
67
- // 2. MCP Server ๊ณ„์ธก
68
- instrumentMCPServer(server, options.debug);
69
- if (options.debug) {
70
- console.log('[MCP Logger SDK] โœ“ Initialization complete');
71
- }
72
- }
73
- /**
74
- * SDK๋ฅผ ์ข…๋ฃŒํ•˜๊ณ  ๋ชจ๋“  pending traces๋ฅผ flushํ•ฉ๋‹ˆ๋‹ค.
75
- *
76
- * ์ผ๋ฐ˜์ ์œผ๋กœ ๋ช…์‹œ์ ์œผ๋กœ ํ˜ธ์ถœํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค.
77
- * ํ”„๋กœ์„ธ์Šค ์ข…๋ฃŒ ์‹œ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.
78
- */
79
- export { shutdownTelemetry as shutdown } from '../shared/telemetry.js';
80
- //# sourceMappingURL=index.js.map
1
+ import{NodeSDK as e}from"@opentelemetry/sdk-node";import{OTLPTraceExporter as r}from"@opentelemetry/exporter-trace-otlp-http";import{Resource as t}from"@opentelemetry/resources";import{trace as o,SpanStatusCode as n}from"@opentelemetry/api";const s="https://aware.mcypher.com/v1/traces",c="1.0.0";let i=null,a=null,l=!1;function u(){return a}async function g(){if(i)try{await i.shutdown(),i=null,a=null,l=!1}catch(e){console.error("[MCP Logger] Error shutting down telemetry:",e)}}function m(e,r){for(const[t,o]of Object.entries(r))null!=o&&e.setAttribute(t,o)}function p(e,r,t,o){try{t?e.addEvent(r,t):e.addEvent(r)}catch(e){o&&console.error("[MCP Logger] Failed to add span event:",e)}}function d(e,r=1e4){try{const t=JSON.stringify(e);return t.length>r?t.slice(0,r)+"... (truncated)":t}catch(e){return null}}function h(h,f){if(!f.apiKey)throw new Error("[MCP Logger SDK] apiKey is required");if(!h)throw new Error("[MCP Logger SDK] server instance is required");!function(n){if(l)return n.debug&&console.error("[MCP Logger] Telemetry already initialized, returning existing tracer"),a;const u=n.serviceName||`mcp-server-${Math.random().toString(36).slice(2,8)}`;n.debug&&(console.error("[MCP Logger] Initializing telemetry..."),console.error(`[MCP Logger] Endpoint: ${n.endpoint||s}`),console.error(`[MCP Logger] Service: ${u}`)),i=new e({resource:new t({"service.name":u,"service.version":c}),traceExporter:new r({url:n.endpoint||s,headers:{"x-api-key":n.apiKey}})}),i.start(),a=o.getTracer("mcp-logger",c),l=!0,n.debug&&console.error("[MCP Logger] Telemetry initialized successfully");const m=async()=>{n.debug&&console.error("[MCP Logger] Shutting down telemetry..."),await g()};process.once("SIGTERM",m),process.once("SIGINT",m)}(f),function(e,r=!1){const t=u();if(!t)throw new Error("[MCP Logger SDK] Tracer not initialized. Call initMCPLogger first.");const o=e.setRequestHandler.bind(e);e.setRequestHandler=function(e,s){const c=e.shape?.method,i=c?._def?.value||"unknown";return r&&console.log(`[MCP Logger SDK] Instrumenting handler: ${i}`),o(e,async(e,o)=>{const c=`mcp.${i}`;return await t.startActiveSpan(c,{attributes:{"mcp.method":i,"mcp.request.method":e.method}},async t=>{const c=Date.now();try{const i=d(e.params||{});m(t,{"mcp.request.id":"unknown","mcp.request.params.size":i?.length}),i&&i.length<1e3&&t.setAttribute("mcp.request.params",i),p(t,"mcp.request.received",{"request.method":e.method,"request.timestamp":c},r),r&&console.log("[MCP Logger SDK] Request received:",{method:e.method,params:e.params});const a=await s(e,o),l=Date.now(),u=l-c,g=d(a);return m(t,{"mcp.duration_ms":u,"mcp.response.size":g?.length}),g&&g.length<1e3&&t.setAttribute("mcp.response.result",g),p(t,"mcp.response.sent",{"response.timestamp":l,"response.duration_ms":u},r),function(e){e.setStatus({code:n.OK})}(t),r&&console.log(`[MCP Logger SDK] Response sent (${u}ms):`,a),a}catch(e){throw function(e,r,t){const o=r instanceof Error?r.message:"Unknown error",s=r instanceof Error?r.constructor.name:"Error";r instanceof Error&&e.recordException(r),e.setStatus({code:n.ERROR,message:o}),e.setAttribute("error",!0),e.setAttribute("error.type",s),e.setAttribute("error.message",o),t&&console.error("[MCP Logger] Error recorded in span:",r)}(t,e,r),r&&console.error("[MCP Logger SDK] Error occurred:",e),e}finally{t.end()}})})},r&&console.log("[MCP Logger SDK] Server instrumentation complete")}(h,f.debug),f.debug&&console.log("[MCP Logger SDK] โœ“ Initialization complete")}export{h as initMCPLogger,g as shutdown};
@@ -1,99 +1 @@
1
- /**
2
- * MCP Server ์ž๋™ ๊ณ„์ธก
3
- *
4
- * setRequestHandler๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜์—ฌ ๋ชจ๋“  ์š”์ฒญ/์‘๋‹ต์„ ์ž๋™์œผ๋กœ ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค.
5
- */
6
- import { getTracer } from '../shared/telemetry.js';
7
- import { setSpanAttributes, addSpanEvent, recordSpanError, markSpanSuccess, safeStringify } from '../shared/span-utils.js';
8
- /**
9
- * MCP Server์— ์ž๋™ ๊ณ„์ธก ์ ์šฉ
10
- */
11
- export function instrumentMCPServer(server, debug = false) {
12
- const tracer = getTracer();
13
- if (!tracer) {
14
- throw new Error('[MCP Logger SDK] Tracer not initialized. Call initMCPLogger first.');
15
- }
16
- // ์›๋ณธ setRequestHandler ์ €์žฅ
17
- const originalSetRequestHandler = server.setRequestHandler.bind(server);
18
- // setRequestHandler ์˜ค๋ฒ„๋ผ์ด๋“œ
19
- server.setRequestHandler = function (requestSchema, handler) {
20
- // requestSchema์—์„œ method ์ถ”์ถœ
21
- const methodLiteral = requestSchema.shape?.method;
22
- const method = methodLiteral?._def?.value || 'unknown';
23
- if (debug) {
24
- console.log(`[MCP Logger SDK] Instrumenting handler: ${method}`);
25
- }
26
- // ๋ž˜ํ•‘๋œ ํ•ธ๋“ค๋Ÿฌ ์ƒ์„ฑ
27
- const wrappedHandler = async (request, extra) => {
28
- const spanName = `mcp.${method}`;
29
- return await tracer.startActiveSpan(spanName, {
30
- attributes: {
31
- 'mcp.method': method,
32
- 'mcp.request.method': request.method,
33
- },
34
- }, async (span) => {
35
- const startTime = Date.now();
36
- try {
37
- // Request ๋กœ๊น…
38
- const paramsStr = safeStringify(request.params || {});
39
- setSpanAttributes(span, {
40
- 'mcp.request.id': 'unknown', // MCPRequest์— id๊ฐ€ ์—†์œผ๋ฏ€๋กœ 'unknown'์œผ๋กœ ์„ค์ •
41
- 'mcp.request.params.size': paramsStr?.length,
42
- });
43
- if (paramsStr && paramsStr.length < 1000) {
44
- span.setAttribute('mcp.request.params', paramsStr);
45
- }
46
- addSpanEvent(span, 'mcp.request.received', {
47
- 'request.method': request.method,
48
- 'request.timestamp': startTime,
49
- }, debug);
50
- if (debug) {
51
- console.log(`[MCP Logger SDK] Request received:`, {
52
- method: request.method,
53
- params: request.params,
54
- });
55
- }
56
- // ์›๋ณธ ํ•ธ๋“ค๋Ÿฌ ์‹คํ–‰
57
- const result = await handler(request, extra);
58
- const endTime = Date.now();
59
- const duration = endTime - startTime;
60
- // Response ๋กœ๊น…
61
- const resultStr = safeStringify(result);
62
- setSpanAttributes(span, {
63
- 'mcp.duration_ms': duration,
64
- 'mcp.response.size': resultStr?.length,
65
- });
66
- if (resultStr && resultStr.length < 1000) {
67
- span.setAttribute('mcp.response.result', resultStr);
68
- }
69
- addSpanEvent(span, 'mcp.response.sent', {
70
- 'response.timestamp': endTime,
71
- 'response.duration_ms': duration,
72
- }, debug);
73
- markSpanSuccess(span);
74
- if (debug) {
75
- console.log(`[MCP Logger SDK] Response sent (${duration}ms):`, result);
76
- }
77
- return result;
78
- }
79
- catch (error) {
80
- // Error ๋กœ๊น…
81
- recordSpanError(span, error, debug);
82
- if (debug) {
83
- console.error(`[MCP Logger SDK] Error occurred:`, error);
84
- }
85
- throw error;
86
- }
87
- finally {
88
- span.end();
89
- }
90
- });
91
- };
92
- // ๋ž˜ํ•‘๋œ ํ•ธ๋“ค๋Ÿฌ๋กœ ๋“ฑ๋ก
93
- return originalSetRequestHandler(requestSchema, wrappedHandler);
94
- };
95
- if (debug) {
96
- console.log('[MCP Logger SDK] Server instrumentation complete');
97
- }
98
- }
99
- //# sourceMappingURL=instrumentation.js.map
1
+ import"@opentelemetry/sdk-node";import"@opentelemetry/exporter-trace-otlp-http";import"@opentelemetry/resources";import"@opentelemetry/api";function e(e,t=!1){throw new Error("[MCP Logger SDK] Tracer not initialized. Call initMCPLogger first.")}export{e as instrumentMCPServer};