Heimdall is a transparent proxy that sits between your MCP client (Claude Desktop, OpenCode, Cursor…) and any MCP server — local or remote. It intercepts every JSON-RPC message, records it as an OpenTelemetry span, and persists it to the storage backend you choose: SQLite for local dev, Postgres or MySQL for shared teams.
Docs: https://stack.cardor.dev/heimdall
The schema is native OTel: Unix nanosecond timestamps stored, SpanKind and SpanStatusCode values, and resource_attributes populated via @opentelemetry/semantic-conventions (service.name, service.version, service.namespace). Add --otlp localhost/v1/traces to also export spans live to Jaeger or Grafana Tempo — additive to DB.
You use it as a one-line drop-in via mcp.json — no modifications to the target server, no opinions on security or policy, just pure observability.
// mcp.json — before
{ "mcpServers": { "my-server": { "command": "node", "args": ["server.js"] } } }
// mcp.json — after (Heimdall wrapping it)
{ "mcpServers": { "my-server": { "command": "heimdall", "args": ["--store", "sqlite://~/.heimdall/traces.db", "--", "node", "server.js"] } } }
That's it. Every tool call, resource read, and prompt fetch now has a trace record with timing, input, output, span context, and OTel resource metadata.
MCP servers are black boxes. When an agent misbehaves — calls the wrong tool, returns unexpected output, loops endlessly — you have no structured record of what happened. Server logs exist, but they're unstructured, per-server, and hard to correlate across a session. I wanted a single place to answer "what did this agent actually do, in what order, how long did each call take, and what did it return?" — the same question I'd answer with distributed tracing in a backend system.
Heimdall brings that pattern to the MCP layer: OpenTelemetry spans in native format, a queryable DB with OTel-native types, live OTLP export, and a library API for custom interceptors — all with zero changes to existing servers.
Link: https://github.com/enmanuelmag/heimdall-mcp
Would love to hear your thoughts — especially if you've hit the "what did my agent actually do?" problem and solved it differently!
No responses yet.