Purpose
mcp-audit is a plug-and-play security and observability proxy for MCP servers. It sits between an MCP client and any upstream MCP server, generates signed audit trails, redacts sensitive payloads, enforces allow/deny policies and per-tool rate limiting, and exposes a local read-only dashboard. It is not a domain-specific MCP server, but a transparent proxy that wraps any MCP server and audits the JSON-RPC traffic flowing through it. What is shown in the directory may be tools exposed by the upstream server, not tools implemented by mcp-audit itself.
The MCP 2026 roadmap sets out enterprise requirements for audit trails, gateway patterns, and operational visibility. mcp-audit fills this gap as a deployable sidecar or local wrapper: it sits between any MCP client and server, preserves protocol traffic, and records signed audit entries for tool calls, resource reads, prompt requests, and all other JSON-RPC methods.
Key capabilities
- Audit AI agent tool calls in regulated environments
- Detect accidental or dangerous MCP tool usage
- Retain signed JSONL or SQLite logs for incident review
- Redact sensitive fields before storing requests and responses
- Block disallowed tools and enforce per-tool rate limiting without modifying the upstream MCP server
Supported transports:
- stdio: suitable for local MCP clients such as Claude Desktop
- http: suitable for MCP servers exposed over HTTP
HTTP upstreams can use custom CA bundles, TLS server name overrides, and optional mTLS client certificates. Upstream retries are disabled by default; when enabled, they apply only to conservative, idempotent JSON-RPC methods; tools/call is not retried.
Audit entries include: ULID, timestamp, direction, transport, JSON-RPC method, tool name (if present), redacted arguments/results, JSON-RPC error (if present), duration, client/server identification, and an optional HMAC-SHA256 signature.
Policy enforcement: mcp-audit can enforce synchronous allow/deny rules before a tools/call reaches the upstream MCP server. Denied calls return a JSON-RPC error while still being written to the audit log. Rules are evaluated in order, empty fields and * match any value, so they can be used with deThe fault_action: deny and explicit allow rules are used for stricter deployments.
OTLP export: tools/call audit entries can be exported as OTLP/HTTP JSON spans to Jaeger, Tempo, Honeycomb, or any OTLP-compatible collector. The export uses current OpenTelemetry MCP and GenAI semantic conventions (such as mcp.method.name, jsonrpc.request.id, gen_ai.operation.name, gen_ai.tool.name, network.transport, network.protocol.name, rpc.response.status_code, error.type), while project-specific attributes remain link-oriented (such as mcp_audit.entry_id, mcp_audit.direction, mcp_audit.client_id, mcp_audit.server_id, mcp_audit.storage, mcp_audit.signature.present). By default, request parameters and tool results are not exported; signed JSONL or SQLite audit rows remain the evidence artifact, and OTLP provides correlation, latency, and operational visibility. Exporter health is visible through Prometheus metrics under the mcp_audit_otel_ prefix, including export requests, span results, dropped spans, queue depth, and queue capacity. Temporary OTLP failures are retried with bounded exponential backoff; retryable responses respect Retry-After, up to otel.retry.max_interval_ms.
Dashboard: shows recent entries, filters, expandable request/result JSON, top tools, today's calls, and error rate, refreshing every five seconds. By default it listens only on 127.0.0.1:9090. To expose it on other interfaces, explicitly configure dashboard.bind_address and enable authentication or place it behind a trusted access proxy. After configuring dashboard.auth.token, requests to /, /api/entries, and /api/stats must carry credentials; missing or invalid credentials return 401 Unauthorized and WWW-Authenticate: Bearer realm="mcp-audit-dashboard". Repeated authentication failures from the same remote address are rate-limited as 429 Too Many Requests. Dashboard JSON API responses include Cache-Control: no-store.
Prometheus metrics: mcp-audit exposes Prometheus metrics on a separate endpoint so platform teams can scrape operational data without exposing the dashboard. Application metrics use the mcp_audit_ prefix and avoid unbounded labels. Tool-level labels can be disabled via metrics.tool_labels: false to strictly control cardinality. Policy decisions are exposed as mcp_audit_policy_decisions_total{action="allow|deny"}.
Usage
Installation:
- Download the latest prebuilt binary and run it
- Run with Docker
- Install from source with Go
- To pin a specific release for reproducible installation, see INSTALL.md
Run:
- Run in stdio mode
- Generate a key on Windows PowerShell and set it as an environment variable
- Run in HTTP mode
- Run with Docker Compose
The default dashboard address is http://127.0.0.1:9090,Prometheus metrics are by default located at http://localhost:9091/metrics。
Configuration: By default, config.yaml is loaded from the current directory; CLI flags override configuration values, and AUDIT_SECRET overrides audit.secret.
Client configuration examples cover: Cursor stdio, Continue stdio, VS Code stdio, Claude Desktop stdio, Zed stdio. Claude Desktop can also be configured to launch mcp-audit instead of the upstream MCP server.
HTTP forwarding security: By default, hop-by-hop request headers and Authorization are stripped before forwarding to the upstream. To pass a bearer token to a trusted authenticated upstream, you must explicitly opt in. Forwarded headers (including secrets such as bearer tokens) are transmitted as-is to the upstream server; enable this only when you control or trust the upstream MCP server. Authorization is the only sensitive header that can be selectively forwarded, because some MCP HTTP servers require it for upstream authentication. Cookie, Set-Cookie, and Proxy-Authorization are always rejected; they represent state intended for other components (such as browser sessions or proxy chains) and have no legitimate use in MCP request forwarding. If an existing deployment relies on implicit Authorization forwarding, the corresponding configuration must be added.
Log rotation: JSONL rotation is disabled by default and supports size-based and UTC time-based triggers. Rotation archives use UTC timestamps, such as audit.jsonl.20260610T214605Z; multiple rotations within the same second add a numeric suffix. Archive timestamps reflect the wall-clock time of the rotation event, not the deadline that was crossed. Time-based rotation is append-driven: mcp-audit does not start a background timer, so if there are no writes for several days, the active file will not rotate after the deadline until the next append. Missed deadlines are not made up, and the next append creates at most one archive. max_age_days uses the rotation timestamp encoded in the archive filename, i.e. the age since rotation, not the age of the oldest entry in the archive. Age retention runs before max_files retention. Compression and SQLite archiving are not part of this release.
Use cases
- Auditing tool calls generated by AI agents in regulated environments
- Detecting accidental or dangerous MCP tool usage
- Retaining signed logs for incident review
- Redacting sensitive fields before storage
- Blocking disallowed tools and enforcing per-tool rate limits without modifying the upstream MCP server
- Exporting audit entries via OTLP to OTLP-compatible collectors such as Jaeger, Tempo, and Honeycomb for correlation, latency, and operational visibility
Limitations
- This release does not include compression and SQLite archiving
- Upstream retries are disabled by default and apply only to conservative idempotent JSON-RPC methods; tools/call is not retried
- OTLP does not export request parameters and tool results by default
- Time-based JSONL rotation is append-driven and does not make up missed deadlines
- The dashboard listens only on 127.0.0.1:9090 by default
- Cookie, Set-Cookie, and Proxy-Authorization are always rejected for forwarding
- Forwarded headers (including secrets such as bearer tokens) are transmitted as-is to the upstream; enable Authorization forwarding only when you control or trust the upstream MCP server
Other information
License: Apache-2.0, see LICENSE for details. For architecture notes, see ARCHITECTURE.md; for platform-specific installation and troubleshooting, see INSTALL.md; for stability guarantees, see STABILITY.md; for contribution guidelines, see CONTRIBUTING.md; for release history, see CHANGELOG.md; and for the security vulnerability reporting process, see SECURITY.md.