Skip to content

Usage auditing

Scanning tells you what could go wrong; auditing tells you what your agents actually did. The harness guards (Claude Code, OpenCode) append one record per MCP tool call to a local JSONL log — the ground truth for “which servers do we really use” and the paper trail when something looks like exfiltration.

{
"ts": "2026-07-26T14:03:11.402Z",
"org": "org_9f3k",
"harness": "claude-code",
"event": "pre",
"sessionId": "sess_01j9…",
"server": "github",
"tool": "create_issue",
"decision": "allow",
"rule": null,
"argsSha256": "9f2c8a41…",
"argsBytes": 412,
"args": null,
"cwd": "/work/acme-web",
"policyPath": "/work/acme-web/.ringzero/mcp-policy.json",
"policyMode": "warn"
}
FieldMeaning
eventpre (before the call, carries the decision) or post (after)
decisionallow · warn (policy violation, warn mode) · deny (blocked)
ruleThe matched rule: a dangerous-pattern id or unapproved-server
argsSha256 / argsBytesHash + size of the tool arguments — enough to correlate, nothing to leak
argsnull unless raw-args logging is opted into

Records never contain raw tool arguments by default — only a SHA-256 and a byte count. Two identical calls hash identically, so you can still spot repetition without storing content.

One file per day: ~/.ringzero/mcp-audit/YYYY-MM-DD.jsonl, append-only. Override with RINGZERO_MCP_AUDIT_DIR or policy audit.dir; disable with audit.enabled: false.

Terminal window
ringzero-mcp audit report --since 7d
RingZero MCP audit — 1284 records in /home/dev/.ringzero/mcp-audit
window: 2026-07-19T09:12:04.771Z → 2026-07-26T14:03:11.402Z
harnesses: claude-code, opencode
decisions: 1261 allow · 19 warn · 4 deny
matched rules:
unapproved-server: 17
curl-pipe-sh: 3
ssh-key-read: 3
calls by server:
github: 811 (create_issue×402, get_issue×301, …)
linear: 344 (…)
slack-mpc: 17 (post_message×17)

--json emits the same summary machine-readably; ringzero-mcp audit tail follows the log live.

  • Unapproved servers with real trafficslack-mpc: 17 above is the allowlist telling you shadow tooling is in active use, not just configured.
  • Dangerous-pattern warns — in warn mode these are dry-run denies. A curl-pipe-sh or env-exfil hit means an agent actually attempted that call; investigate the session before flipping to enforce.
  • Volume anomalies — a server whose call count or argsBytes profile jumps an order of magnitude is worth a scan and a look at its recent version history.
  • post events without matching pre — calls that bypassed the guard (e.g. OpenCode subagents; see the limitations).
Terminal window
ringzero-mcp audit sync --since 24h

Uploads records in batches of 500 to POST /v1/mcp/usage-events using RINGZERO_API_KEY (scope mcp:upload) — run it on a schedule to feed the org-wide view. Without a key it says so and exits 0: the log stays local, and local is a fully supported mode.