After getting frustrated not knowing what was actually happening inside MCP servers — which tools were slow, which failed silently, what inputs Claude was sending.
The idea: a transparent proxy that sits between your MCP client (Claude Desktop, OpenCode, Cursor) and any MCP server, captures every JSON-RPC message as an OpenTelemetry span, and persists it to a storage backend you configure.
No modifications to the target server required. You just wrap it in mcp.json:
"command": "heimdall-mcp",
"args": ["--store", "sqlite://~/.heimdall/traces.db", "--", "node", "my-server.js"]
For remote servers (HTTP/SSE):
"command": "heimdall-mcp",
"args": ["--store", "postgres://...", "--target", "http://remote-server/sse"]
Storage options: SQLite (local WASM, no native deps), Postgres, MySQL, or any OTLP-compatible backend.
Also ships as a TypeScript library with a fluent builder API if you want to embed it directly.
Why I think this is useful:
- LLM agents are increasingly orchestrating MCP tools, but observability tooling hasn't caught up
- IBM's ContextForge does something similar but it's a heavy Python gateway — this is meant to be a lightweight npm package
Still early (v0.1), but the core proxy + SQLite store is working. Looking for feedback on the interceptor API design and whether the OTel semantic conventions mapping makes sense.
Website: https://stack.cardor.dev/heimdall
GitHub: https://github.com/enmanuelmag/heimdall-mcp
Check the repo for more feature planned on roadmap 🚀
Top comments (0)