Rightshold™ Sign up

Answers · agent safety

How do I log every tool call my AI agent makes, for audit?

Last updated

TL;DR: Log at the point where the agent calls tools, not inside each tool: one record per call with who (agent, session, user), what (tool name, server, call id, a hash or redacted copy of the arguments), when (start time and duration), and the outcome (success, error type, whether a human approved it). The MCP specification tells clients they SHOULD log tool usage for audit purposes. In Claude Code, PreToolUse, PostToolUse and PostToolUseFailure hooks fire on every tool call, MCP tools included, and its OpenTelemetry tool_result events record tool name, success, duration and decision without arguments unless you opt in. OpenTelemetry's GenAI conventions define an execute_tool span with gen_ai.tool.name and gen_ai.tool.call.id, and mark arguments and results as opt-in because they can hold sensitive data. Then make the log hard to rewrite: append-only storage, a write-only account for the logger, and a hash chain with signed checkpoints, so anyone can tell if an entry was later changed or deleted.

What should I check, step by step?

1. Pick the choke point: the agent's MCP client, framework callback or hook layer sees every call; logging inside individual tools misses the ones you didn't write.

  1. Record per call: timestamp, duration, agent and session id, tool name, MCP server and version, tool call id, result status and error type, and whether a person or policy approved it.
  2. Hash arguments and results by default; store full content only where you need it, redacted. OWASP says logs should not hold access tokens, passwords or session ids (hash session ids if you need to correlate).
  3. Claude Code: add PreToolUse and PostToolUse/PostToolUseFailure hooks (match mcp__.* for MCP tools) that append tool_name, tool_use_id, session_id, duration_ms and the outcome to your log; hooks also run in subagents and carry agent_id.
  4. Claude Code telemetry: claude_code.tool_result and tool_decision events give name, success, duration, sizes and accept/reject. Tool parameters and content are only exported when OTEL_LOG_TOOL_DETAILS or OTEL_LOG_TOOL_CONTENT is set.
  5. Other frameworks: emit an OpenTelemetry execute_tool span per call with gen_ai.operation.name, gen_ai.tool.name and gen_ai.tool.call.id, and leave gen_ai.tool.call.arguments and gen_ai.tool.call.result off unless you've decided to capture them. Don't create a second span if your MCP instrumentation already makes one.
  6. Make tampering visible: write to append-only storage from a write-only account, chain each entry to the hash of the one before, and commit the chain head somewhere you don't control on a schedule.
  7. Alert when logging stops, and treat tool output written into logs as untrusted input (strip CR/LF so a tool can't forge log lines).

What the standards actually say

MCP's tools specification (2025-11-25), under security considerations, says clients SHOULD prompt for confirmation on sensitive operations, show tool inputs to the user before calling the server, validate tool results, implement timeouts and log tool usage for audit purposes. Servers MUST validate inputs, implement access controls and rate limits, and sanitize outputs.

Why a hash chain beats a plain log file

An agent, a compromised host or an operator can edit a log file after an incident. If each entry includes the hash of the previous one and the latest hash is regularly committed to a place outside your control, any later edit or deletion breaks the chain at a visible point.

How do I ask Rightshold about this (free, no key)?

Add the MCP server https://www.rightshold.com/mcp to Claude, Cursor, ChatGPT, Grok or VS Code, then ask: “My agent keeps a signed, hash-chained log of every tool call. Commit today's head so I can prove later the log wasn't rewritten.”

One-click setup

{
  "tool": "recorder_checkpoint",
  "arguments": {
    "checkpoint": {
      "agent": "<RS number>",
      "seq": 1042,
      "head": "<sha256('rec:' + canonical(entry 1042))>",
      "at": "2026-10-30T12:00:00Z"
    },
    "signature": "<agent key's Ed25519 signature over canonical(checkpoint)>"
  }
}

Rightshold does not collect or store your agent's tool calls or arguments. It records the hash and count you commit and verifies excerpts you choose to disclose. Your logging pipeline, retention and redaction stay yours. Not legal advice.

What are the sources?

Related

Not legal advice. JSON · Markdown · All answers

Get a free API key in one call

No card and no email needed. 100 free credits; the license and policy checks stay free without a key.

curl -s -X POST https://www.rightshold.com/v1/accounts/signup -H "Content-Type: application/json" -d '{"accept_terms":true}'
export RIGHTSHOLD_API_KEY=rs_...   # the api_key from the reply (shown once)
curl -s https://www.rightshold.com/v1/licenses/check -H "Authorization: Bearer $RIGHTSHOLD_API_KEY" \
  -H "Content-Type: application/json" -d '{"license":"MIT","intended_use":{"commercial_use":true}}'