ARCHIVED: This repo has been superseded by agent-receipts/mcp-proxy, which combines beacon's governance features (policy engine, risk scoring, intent tracking) with cryptographic action receipts. See also agent-receipts/sdk-go.
They tell you WHO did WHAT. Beacon tells you WHY, and whether it matched what the human actually intended.
AI agents are making real decisions across enterprise tools — creating GitHub issues, sending Slack messages, running SQL queries, modifying infrastructure. Today, there is no way to:
- Audit what an agent actually did across multiple systems in a single view
- Trace actions back to intent — did the agent do what the human actually asked for?
- Catch risky actions before they happen — a bulk delete, a message sent to the wrong channel, a credential exposed
Existing MCP gateways (Runlayer, MintMCP) focus on access control and routing. They answer "who called what tool." Beacon answers the harder question: why, and did it match what was intended?
They tell you WHO did WHAT. Beacon tells you WHY, and whether it matched what the human actually intended.
| Capability | MCP Gateways | Beacon Proxy |
|---|---|---|
| Audit trail | Yes | Yes |
| Tool-level access control | Yes | Planned |
| Intent-to-action tracing | No | Yes |
| Cross-system action grouping | No | Yes |
| Outcome verification | No | Planned |
| Human-readable action narrative | No | Planned |
graph LR
Client["MCP Client<br/>(Claude, etc)"]
Proxy["beacon-proxy"]
Server["MCP Server<br/>(GitHub, etc)"]
DB[("SQLite<br/>Audit DB")]
Client -- "stdin/stdout" --> Proxy
Proxy -- "stdin/stdout" --> Server
Proxy -- "log" --> DB
subgraph Beacon
Proxy
DB
end
- Configure your MCP client to launch
beacon-proxyinstead of the real server beacon-proxyspawns the real MCP server as a child process- Every JSON-RPC message (both directions) passes through transparently
- Messages are parsed and logged to a local SQLite audit trail
The proxy is fully transparent — it does not modify, delay, or drop any messages. Zero config changes to your MCP servers.
go install github.com/ottojongerius/beacon/cmd/beacon-proxy@latestOr build from source:
git clone https://github.com/ottojongerius/beacon.git
cd beacon
make buildbeacon-proxy [flags] -- <server-command> [server-args...]
beacon-proxy verify [--db path]
| Flag | Default | Description |
|---|---|---|
--server-name |
unknown |
Label for this MCP server (used in audit trail) |
--db |
~/.beacon/audit.db |
Path to SQLite audit database |
--rules |
(built-in defaults) | Path to YAML policy rules file |
--port |
8080 |
HTTP port for approval endpoints |
--retention-days |
0 (keep forever) |
Auto-delete sessions older than N days on startup |
| Variable | Description |
|---|---|
BEACON_ENCRYPTION_KEY |
Passphrase for AES-256-GCM encryption of sensitive audit data. If unset, data is stored in plaintext (redaction still applies). |
beacon-proxy --server-name filesystem -- npx -y @modelcontextprotocol/server-filesystem /tmpBefore (direct connection):
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_TOKEN": "ghp_xxx" }
}
}
}After (with Beacon):
{
"mcpServers": {
"github": {
"command": "beacon-proxy",
"args": [
"--server-name", "github",
"--db", "~/.beacon/audit.db",
"--", "npx", "-y", "@modelcontextprotocol/server-github"
],
"env": { "GITHUB_TOKEN": "ghp_xxx" }
}
}
}Beacon includes a real-time web dashboard at http://localhost:8080 (configurable via --port).
- Live tool call stream — see every MCP action as it happens via SSE
- Session overview — browse sessions, see tool call counts and max risk per server
- Risk & policy views — filter by operation type, policy action, or risk level
- Intent chains — visualize temporal groupings of related tool calls
- Approve/deny — handle paused tool calls directly from the browser
- Hash chain verification — one-click integrity check of the entire audit trail
No build step — the dashboard is a single HTML file embedded in the binary.
One command to build, generate traffic, and open the dashboard:
make demoOr step-by-step:
go run ./cmd/beacon-traffic/ # populate with realistic sample data
open http://localhost:8080 # open dashboardCheck the integrity of the audit trail from the CLI:
beacon-proxy verify
beacon-proxy verify --db /path/to/audit.dbThe dashboard provides the primary UI. You can also query SQLite directly:
# List all sessions
sqlite3 ~/.beacon/audit.db "SELECT id, server_name, started_at FROM sessions"
# View tool calls for a session
sqlite3 ~/.beacon/audit.db "SELECT direction, method, jsonrpc_id FROM messages ORDER BY timestamp"- Credential redaction: sensitive data is automatically redacted before storage. Passwords, tokens, API keys, and other secrets are replaced with
[REDACTED]in the audit DB. Messages pass through to the MCP server unmodified — redaction only applies to stored data.- Key-based: JSON fields like
password,token,api_key,secret,credential,authorization,private_key, and others - Pattern-based: GitHub PATs (
ghp_,gho_), OpenAI/Anthropic keys (sk-), AWS access keys (AKIA), Bearer tokens, Slack tokens (xox), PEM private keys
- Key-based: JSON fields like
- Audit DB permissions: directory is
0700, DB file is0600— only the owning user can read the audit trail - Raw payload truncation: messages over 512KB are truncated in storage to prevent disk exhaustion from malicious servers
- Minimal stderr logging: error messages do not leak paths, session IDs, or message contents
- Encryption at rest: sensitive columns (
raw,arguments,result,error) are encrypted with AES-256-GCM when an encryption key is provided. Enable by setting theBEACON_ENCRYPTION_KEYenvironment variable. Without a key, data is stored in plaintext (redaction still applies). - Parameterized SQL: all database queries use parameterized statements — no SQL injection risk
- Tamper-evident hash chain: each audit message includes a SHA-256 hash chained to the previous message. Any modification, deletion, or reordering of existing records is detectable. Verify with
VerifyChain()— works offline against the DB file.
- The audit DB contains sensitive data. Raw MCP payloads may include file contents or PII. Enable encryption at rest via
BEACON_ENCRYPTION_KEYand treat~/.beacon/audit.dbas sensitive. - Beacon is a local tool, not a network boundary. It trusts the local user and the MCP client. If an attacker can modify
claude_desktop_config.json, they can bypass the proxy entirely. - DB size management. Use
--retention-days Nto auto-prune sessions older than N days on startup. Without this flag, data is kept indefinitely. - Tamper detection, not prevention. The hash chain detects modifications or deletions after the fact, but cannot prevent a local attacker with DB access from rewriting the entire chain. For stronger guarantees, consider external log shipping.
-
Transparent STDIO proxy with JSON-RPC logging
-
Security hardening (file permissions, payload truncation, safe logging)
-
Request/response pairing with duration tracking
-
Operation classification (read/write/delete/execute)
-
Risk scoring (0-100, additive factors)
-
Policy engine with flag / pause / block actions
-
YAML-configurable policy rules (with sensible defaults)
-
HTTP approval endpoints for paused tool calls
-
Temporal intent grouping (5s gap threshold)
-
Real-time web dashboard with live SSE stream
- Cross-system intent chains — one human request, multiple MCP servers, one narrative
- LLM-powered intent verification — "did the agent do what was asked?"
- Rollback suggestions — capture enough state to undo agent actions
- SIEM integration — stream audit events to Datadog, Splunk, etc.
See CONTRIBUTING.md for development setup and guidelines.
See docs/beacon-proxy-spec.md for the full technical spec.
Built by Otto Jongerius.