Heimdall
Open Source Observability Platform for MCP Servers & Apps
Installation
npx heimdallAsk AI about Heimdall
Powered by Claude Β· Grounded in docs
I know everything about Heimdall. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
Overview
Heimdall is a comprehensive observability platform designed for monitoring Model Context Protocol (MCP) servers and AI/LLM applications. Built on OpenTelemetry standards, it provides real-time tracing, metrics, and insights into your AI infrastructure.
Key Features
- π Real-time Tracing - Track every tool call, resource access, and prompt execution
- π Dashboard Analytics - Visualize latency, error rates, and usage patterns
- π Easy Integration - Simple SDK decorators for Python and JavaScript/TypeScript
- π Self-hosted - Run entirely on your own infrastructure
- π OpenTelemetry Native - Built on industry-standard observability protocols
TODO
- Track Users - Associate traces with user identities for user-level analytics (currently all requests are shown as anonymous).
- Evaluate - LLM evaluation and quality scoring, including human annotation.
- Add Cloud Host Server - Managed cloud deployment.
Architecture
Currently we only support self-hosted deployment. The architecture is as follows:
βββββββββββββββββββ OTLP/HTTP βββββββββββββββββββ
β MCP Server β βββββββββββββββββββΆβ Heimdall β
β + SDK β Port 4318 β Backend β
βββββββββββββββββββ ββββββββββ¬βββββββββ
β
β REST API
β
ββββββββββΌβββββββββ
β Heimdall β
β Frontend β
β Port 5173 β
βββββββββββββββββββ
Quick Start
π For detailed setup instructions, see QUICKSTART.md
Prerequisites
- Node.js 18+
- Python 3.9+ (for Python SDK)
1. Start the Backend
cd backend
npm install
npm run dev
2. Start the Frontend
cd frontend
npm install
npm run dev
3. Create Organization and Project
- Navigate to http://localhost:5173
- Create an account with your email and password
- Create an Organization - this groups your projects together
- Create a Project - each project has a unique ID for trace collection
4. Get Your Configuration
After creating your organization and project, go to Settings to find:
- Organization ID - Your organization identifier
- Project ID - Your project identifier
You'll need these IDs to configure the SDK.
SDK Integration
Heimdall provides SDKs for instrumenting your MCP servers:
| SDK | Package | Installation |
|---|---|---|
| Python | hmdl | pip install hmdl |
| JavaScript/TypeScript | hmdl | npm install hmdl |
Python Example
from hmdl import HeimdallClient, trace_mcp_tool
# Initialize client with your organization and project IDs
client = HeimdallClient(
endpoint="http://localhost:4318",
org_id="your-org-id", # From Settings page
project_id="your-project-id", # From Settings page
service_name="my-mcp-server",
environment="development"
)
@trace_mcp_tool()
def search_tool(query: str, limit: int = 10) -> dict:
return {"results": [], "query": query, "limit": limit}
result = search_tool("test", limit=5)
client.flush()
Note: Python SDK automatically captures parameter names using introspection. Inputs are displayed as named objects:
{"query": "test", "limit": 5}.
JavaScript/TypeScript Example
import { HeimdallClient, traceMCPTool } from 'hmdl';
// Initialize client with your organization and project IDs
const client = new HeimdallClient({
endpoint: "http://localhost:4318",
orgId: "your-org-id", // From Settings page
projectId: "your-project-id", // From Settings page
serviceName: "my-mcp-server",
environment: "development"
});
const searchTool = traceMCPTool(
async (query: string, limit: number = 10) => ({ results: [], query, limit }),
{ name: "search-tool", paramNames: ["query", "limit"] }
);
await searchTool("test", 5);
await client.flush();
Note: Use the
paramNamesoption to display inputs as named objects (e.g.,{"query": "test", "limit": 5}) instead of arrays (["test", 5]).
Using Environment Variables
You can also configure the SDK using environment variables:
export HEIMDALL_ENDPOINT="http://localhost:4318"
export HEIMDALL_ORG_ID="your-org-id"
export HEIMDALL_PROJECT_ID="your-project-id"
export HEIMDALL_SERVICE_NAME="my-mcp-server"
export HEIMDALL_ENVIRONMENT="development"
export HEIMDALL_ENABLED="true"
Then simply initialize the client without arguments:
# Python
client = HeimdallClient()
// JavaScript/TypeScript
const client = new HeimdallClient();
Configuration
Environment Variables
| Variable | Description | Default |
|---|---|---|
HEIMDALL_ENDPOINT | Backend OTLP endpoint | http://localhost:4318 |
HEIMDALL_ORG_ID | Organization ID from dashboard | default |
HEIMDALL_PROJECT_ID | Project ID for trace grouping | default |
HEIMDALL_SERVICE_NAME | Service name in traces | mcp-server |
HEIMDALL_ENVIRONMENT | Environment tag | development |
HEIMDALL_ENABLED | Enable/disable tracing | true |
HEIMDALL_API_KEY | API key for authentication | - |
HEIMDALL_DEBUG | Enable debug logging | false |
HEIMDALL_BATCH_SIZE | Number of spans to batch | 100 |
HEIMDALL_FLUSH_INTERVAL_MS | Flush interval in ms | 5000 |
Client Configuration Options
| Option | Python | JavaScript | Description |
|---|---|---|---|
| Endpoint | endpoint | endpoint | Heimdall backend URL |
| Organization ID | org_id | orgId | Your organization ID |
| Project ID | project_id | projectId | Your project ID |
| Service Name | service_name | serviceName | Name of your service |
| Environment | environment | environment | Deployment environment |
| API Key | api_key | apiKey | Optional API key |
| Debug | debug | debug | Enable debug logging |
Wrapper/Decorator Options
trace_mcp_tool / traceMCPTool
| Option | Python | JavaScript | Description |
|---|---|---|---|
| Name | name (arg) | name | Custom span name (defaults to function name) |
| Parameter Names | N/A (automatic) | paramNames | Array of parameter names for input display |
| Capture Input | N/A | captureInput | Whether to capture input arguments (default: true) |
| Capture Output | N/A | captureOutput | Whether to capture return value (default: true) |
observe (general-purpose)
| Option | Python | JavaScript | Description |
|---|---|---|---|
| Name | name | name | Custom span name (defaults to function name) |
| Capture Input | capture_input | captureInput | Whether to capture input arguments (default: true) |
| Capture Output | capture_output | captureOutput | Whether to capture return value (default: true) |
Project Structure
heimdall/
βββ backend/ # OTLP receiver and API server
βββ frontend/ # React dashboard
βββ tests/ # SDK integration tests
βββ QUICKSTART.md # Detailed setup guide
βββ README.md # This file
heimdall-python/ # Python SDK
heimdall-js/ # JavaScript/TypeScript SDK
Running Tests
Test the SDK integration with the backend:
# Python SDK test
cd tests
source .venv/bin/activate
python test_python_sdk.py
# JavaScript SDK test
cd tests
npm run test:js
Documentation
- π Full Documentation - Comprehensive guides and API reference
- π Quick Start Guide - Get up and running in 5 minutes
- π Python SDK - Python SDK on PyPI
- π¦ JavaScript SDK - JavaScript/TypeScript SDK on npm
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Support & Contact
- π§ Email: founder@tryheimdall.com
- π Website: tryheimdall.com
- π Documentation: docs.tryheimdall.com
- π Issues: GitHub Issues
License
This project is licensed under the MIT License - see the LICENSE file for details.
