1. Conduid
  2. Data
  3. Trace Js
MCP server · Data

Trace Js

Tracing middleware for MCP servers in TypeScript. Logs all requests, tool calls, and responses to file, DB, or cloud with adapters for OTLP, Supabase, PostgreSQL, and Contexa.

Unclaimed last commit 11 months ago data
51Fair

Scored 8 days ago · breakdown

About Trace Js

Trace Js is an MCP server published by SynqedAI in the Data category: tracing middleware for MCP servers in TypeScript. Logs all requests, tool calls, and responses to file, DB, or cloud with adapters for OTLP, Supabase, PostgreSQL, and Contexa.

The repository has 22 stars and 1 forks, with the last commit 11 months ago. Six months or more without a commit doesn't mean the server is broken, but check the open issues before depending on it in production.

Install

From source
git clone https://github.com/SynqedAI/mcp-trace-js

This server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.

Ask AI

✦

Ask AI about Trace Js

Powered by Claude · Grounded in docs

I know everything about Trace Js. Ask me about installation, configuration, usage, or troubleshooting.

Security checks

Static checks derived from the repository yesterday. Heuristics on the source, not an audit.

  • ✓README presentThe repository ships documentation.
  • !License declaredNo license file. Legally you have no right to use it in a product.
  • !Tests presentNo tests found. Behaviour changes may go unnoticed between versions.
  • ✓Dependencies pinnedA lockfile pins dependency versions.
  • ✓No dynamic code executionSource scan found no eval, dynamic Function, or shell execution.
  • !Scoped permissionsDoesn't declare a permission scope. Assume it can do anything its process can.

Releases

v0.2.0v0.2.0 · 29 Oct 2025What's Changed feat(trace): remove express dependency, ensure full MCP SDK compatibi… by @mybytecode in https://github.com/ContexaAI/mcp-trace-js/pull/1 chore: update version to 0.1.9 and add express dependency back to pac… by @mybytecode…

README

mcp-trace

Flexible, pluggable tracing middleware for Model Context Protocol (MCP) servers in JavaScript/TypeScript. Log every request, tool call, and response to local files, PostgreSQL, Supabase, Contexa, console, OTLP, or your own backend—with full control over what gets logged.


Node.js Package

Table of Contents


Features

  • 📦 Plug-and-play: Add tracing to any MCP server in seconds
  • 🗃️ Pluggable adapters: Log to file, PostgreSQL, Supabase, Contexa, console, OTLP, or your own
  • 🛠️ Configurable logging: Enable/disable fields (tool args, responses, client ID, etc.)
  • 🧩 Composable: Use multiple adapters at once
  • 📝 Schema-first: All traces stored as JSON for easy querying
  • 🔒 Privacy-aware: Control exactly what gets logged
  • ⚡ TypeScript support: Full type safety and IntelliSense
  • 🛡️ Production-ready: Comprehensive error handling and memory management
  • 🔧 Robust validation: Configuration validation with descriptive error messages
  • 🧹 Automatic cleanup: Prevents memory leaks with timeout management
  • 🌐 OpenTelemetry support: Native OTLP integration for observability platforms

Quickstart

Installation

npm install mcp-trace

Minimal Example

import { TraceMiddleware, FileAdapter } from "mcp-trace-js";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";

// Create your MCP server
const server = new McpServer({ name: "my-server", version: "1.0.0" });

// Set up tracing
const traceAdapter = new FileAdapter("trace.log");
const traceMiddleware = new TraceMiddleware({ adapter: traceAdapter });

// Initialize tracing with your server
traceMiddleware.init(server);

// Your server is now fully traced!

Basic Usage

Streamable HTTP Server

See example/streamable-http-server.ts for a complete MCP server using Streamable HTTP transport with tracing.

npm run example:streamable-http

This example demonstrates:

  • Setting up an MCP server with Streamable HTTP transport
  • Registering tools with tracing integration
  • Handling HTTP requests with proper tracing
  • Graceful shutdown with trace flushing

The server includes:

  • Addition tool: Adds two numbers
  • Search tool: Simulates search functionality
  • Health check endpoint: /health
  • MCP endpoint: /mcp (GET and POST)
  • Tracing: All requests and tool calls are traced to streamable-http-trace.log

Feature Usage

Configurable Logging

Control exactly which fields are logged by passing a logFields dictionary to TraceMiddleware. By default, all fields are logged unless set to false.

Available fields:

  • type, method, timestamp, session_id, request_id, client_id, duration
  • tool_name, tool_arguments, tool_response, tool_response_structured

Example: Only log tool name and response, hide arguments and client ID:

const traceMiddleware = new TraceMiddleware({
  adapter: traceAdapter,
  logFields: {
    tool_name: true,
    tool_response: true,
    tool_arguments: false, // disables tool arguments
    client_id: false, // disables client_id
    // ...add more as needed
  },
});

Request-Level Control

Skip tracing for specific requests by adding the X-Ignore-Traces header:

# Skip tracing for this request
curl -H "X-Ignore-Traces: true" http://localhost:8080/mcp

Supported header formats:

  • X-Ignore-Traces: true
  • x-ignore-traces: true

When this header is present, the middleware will skip all tracing logic and continue to the next middleware without any performance overhead.

PII Redaction

Protect sensitive data by providing a custom redaction function that processes all trace data before it's sent to adapters.

const redactPII = (data: any) => {
  // Redact sensitive fields
  if (typeof data === "object" && data !== null) {
    const redacted = { ...data };

    // Redact common PII fields
    if (redacted.email) redacted.email = "[REDACTED]";
    if (redacted.password) redacted.password = "[REDACTED]";
    if (redacted.apiKey) redacted.apiKey = "[REDACTED]";
    if (redacted.token) redacted.token = "[REDACTED]";

    // Redact nested objects
    if (redacted.arguments && typeof redacted.arguments === "object") {
      redacted.arguments = redactPII(redacted.arguments);
    }

    return redacted;
  }

  return data;
};

const traceMiddleware = new TraceMiddleware({
  adapter: traceAdapter,
  redact: redactPII,
});

User Identification

Automatically extract user information from request headers for better trace context and analytics.

const extractUser = (
  headers: Record<string, string | string[] | undefined>
) => {
  // Extract user info from headers (e.g., JWT token, custom headers)
  const authHeader = headers.authorization || headers.Authorization;

  if (typeof authHeader === "string" && authHeader.startsWith("Bearer ")) {
    const token = authHeader.substring(7);
    // Decode JWT or extract user info from token
    const userInfo = decodeJWT(token); // Your JWT decoding logic

    return {
      user_id: userInfo.sub,
      user_name: userInfo.name,
      user_email: userInfo.email,
    };
  }

  // Alternative: Extract from custom headers
  const userId = headers["x-user-id"];
  const userName = headers["x-user-name"];
  const userEmail = headers["x-user-email"];

  if (userId && userName && userEmail) {
    return {
      user_id: Array.isArray(userId) ? userId[0] : userId,
      user_name: Array.isArray(userName) ? userName[0] : userName,
      user_email: Array.isArray(userEmail) ? userEmail[0] : userEmail,
    };
  }

  return undefined;
};

const traceMiddleware = new TraceMiddleware({
  adapter: traceAdapter,
  identifyUser: extractUser,
});

Production-Ready Features

Error Handling & Resilience

The middleware includes comprehensive error handling to ensure your MCP server continues running even if tracing fails:

  • Graceful degradation: If tracing fails, the original MCP flow continues uninterrupted
  • Structured error logging: All errors are logged with context for easy debugging
  • Transport-level safety: Errors in message handlers don't break the transport layer

Configuration Validation

The middleware validates your configuration at startup:

// This will throw a descriptive error if the adapter is invalid
const traceMiddleware = new TraceMiddleware({
  adapter: invalidAdapter, // ❌ Will throw: "TraceAdapter is required"
});

Memory Management

Automatic cleanup prevents memory leaks:

  • Request timeout handling: Pending requests are automatically cleaned up after 5 minutes
  • Proper shutdown: All resources are cleaned up when shutdown() is called
  • Timeout management: All timeouts are tracked and cleared on shutdown

Type Safety

Full TypeScript support with proper type guards:

  • Message type validation: Automatic detection of JSON-RPC requests, responses, and notifications
  • Type-safe handlers: All message handlers use proper TypeScript types
  • IntelliSense support: Full autocomplete and type checking

Contexa Adapter

Send traces to Contexa for cloud-based trace storage and analytics.

Requirements:

  • Contexa API key (CONTEXA_API_KEY)
  • Contexa Server ID (CONTEXA_SERVER_ID)

Usage:

import { TraceMiddleware, ContexaTraceAdapter } from "mcp-trace-js";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";

const server = new McpServer({ name: "my-server", version: "1.0.0" });

// Option 1: Set environment variables
// process.env.CONTEXA_API_KEY = 'your-api-key';
// process.env.CONTEXA_SERVER_ID = 'your-server-id';
// const contexaAdapter = new ContexaTraceAdapter();

// Option 2: Pass directly
const contexaAdapter = new ContexaTraceAdapter({
  apiKey: "your-api-key",
  serverId: "your-server-id",
  // Optional: apiUrl, bufferSize, flushInterval, maxRetries, retryDelay
});

const traceMiddleware = new TraceMiddleware({ adapter: contexaAdapter });
traceMiddleware.init(server);

// On shutdown, ensure all events are sent:
await contexaAdapter.flush(5000);
await contexaAdapter.shutdown();

Other Adapters

File Adapter

Logs each trace as a JSON line to a file.

import { TraceMiddleware, FileAdapter } from "mcp-trace-js";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";

const server = new McpServer({ name: "my-server", version: "1.0.0" });
const traceAdapter = new FileAdapter("trace.log");
const traceMiddleware = new TraceMiddleware({ adapter: traceAdapter });

traceMiddleware.init(server);

Console Adapter

Logs each trace to the console in a human-readable format (with colors).

import { TraceMiddleware, ConsoleAdapter } from "mcp-trace-js";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";

const server = new McpServer({ name: "my-server", version: "1.0.0" });
const traceAdapter = new ConsoleAdapter();
const traceMiddleware = new TraceMiddleware({ adapter: traceAdapter });

traceMiddleware.init(server);

PostgreSQL Adapter

Store traces in a PostgreSQL table for easy querying and analytics.

Table schema:

CREATE TABLE IF NOT EXISTS trace_events (
  id SERIAL PRIMARY KEY,
  timestamp TIMESTAMPTZ NOT NULL,
  type TEXT NOT NULL,
  method TEXT,
  session_id TEXT NOT NULL,
  client_id TEXT,
  duration INTEGER,
  entity_name TEXT,
  arguments JSONB,
  response TEXT,
  error TEXT
);

Usage:

import { TraceMiddleware, PostgresTraceAdapter } from "mcp-trace-js";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";

const server = new McpServer({ name: "my-server", version: "1.0.0" });
const psqlAdapter = new PostgresTraceAdapter({
  dsn: "postgresql://user:pass@host:port/dbname",
  // Optional: tableName
});
const traceMiddleware = new TraceMiddleware({ adapter: psqlAdapter });

traceMiddleware.init(server);

Supabase Adapter

Log traces to Supabase (PostgreSQL as a service).

Table schema: (same as PostgreSQL above)

Install:

npm install @supabase/supabase-js

Usage:

import { createClient } from "@supabase/supabase-js";
import { TraceMiddleware, SupabaseTraceAdapter } from "mcp-trace-js";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";

const server = new McpServer({ name: "my-server", version: "1.0.0" });
const supabase = createClient(SUPABASE_URL, SUPABASE_KEY);
const supabaseAdapter = new SupabaseTraceAdapter({ supabaseClient: supabase });
const traceMiddleware = new TraceMiddleware({ adapter: supabaseAdapter });

traceMiddleware.init(server);

OTLP Adapter

Send traces to OpenTelemetry-compatible observability platforms (Jaeger, Zipkin, DataDog, etc.) using the OTLP protocol.

Install:

npm install @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/exporter-trace-otlp-http

Usage:

import { TraceMiddleware, OTLPAdapter } from "mcp-trace-js";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";

const server = new McpServer({ name: "my-server", version: "1.0.0" });

const otlpAdapter = new OTLPAdapter({
  endpoint: "http://localhost:4318/v1/traces", // OTLP HTTP endpoint
  // Optional: headers, timeout, retryDelay, maxRetries
});

const traceMiddleware = new TraceMiddleware({ adapter: otlpAdapter });
traceMiddleware.init(server);

Configuration options:

const otlpAdapter = new OTLPAdapter({
  endpoint: "http://localhost:4318/v1/traces",
  headers: {
    Authorization: "Bearer your-token",
  },
  timeout: 5000,
  retryDelay: 1000,
  maxRetries: 3,
});

Multi-Adapter Example

Send traces to multiple backends at once:

import {
  TraceMiddleware,
  FileAdapter,
  PostgresTraceAdapter,
  SupabaseTraceAdapter,
  OTLPAdapter,
  MultiAdapter,
} from "mcp-trace-js";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";

const server = new McpServer({ name: "my-server", version: "1.0.0" });
const fileAdapter = new FileAdapter("trace.log");
const psqlAdapter = new PostgresTraceAdapter({
  dsn: "postgresql://user:pass@host:port/dbname",
});
const supabaseAdapter = new SupabaseTraceAdapter({ supabaseClient: supabase });
const otlpAdapter = new OTLPAdapter({
  endpoint: "http://localhost:4318/v1/traces",
});

const multiAdapter = new MultiAdapter(
  fileAdapter,
  psqlAdapter,
  supabaseAdapter,
  otlpAdapter
);
const traceMiddleware = new TraceMiddleware({ adapter: multiAdapter });

traceMiddleware.init(server);

Requirements

  • Node.js 16+
  • TypeScript 4.5+ (for TypeScript projects)
  • @modelcontextprotocol/sdk (for MCP server integration)
  • pg (for PostgreSQL adapter)
  • @supabase/supabase-js (for Supabase adapter)
  • @opentelemetry/api, @opentelemetry/sdk-node, @opentelemetry/exporter-trace-otlp-http (for OTLP adapter)

Contributing

We love contributions! Please open issues for bugs or feature requests, and submit pull requests for improvements.


License

MIT


Links & Acknowledgements

README fetched from the repository yesterday. The original is authoritative.

Questions

About Trace Js

How do I install Trace Js?

No package has been published for this server, so install it from source: clone the repository and follow its README.

Is Trace Js safe to use with an AI agent?

Its trust score is 51 out of 100 (fair). It passes 3 of the 6 static security checks run so far; the failures are listed above. It has no ConduID identity yet, so agent calls to it are not receipted.

Is Trace Js still maintained?

The last commit was 11 months ago. That's long enough that you should check whether the maintainer is responding to issues before depending on it.