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

**Short answer:** 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.

## Checklist
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.
2. 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.
3. 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).
4. 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.
5. 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.
6. 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.
7. 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.
8. 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.
- OpenTelemetry's GenAI semantic conventions (status: Development) name the span execute_tool {gen_ai.tool.name}, require gen_ai.operation.name and gen_ai.tool.name, conditionally require gen_ai.tool.call.id and error.type, and list tool arguments and results as opt-in because they may contain sensitive information.
- OWASP's Logging Cheat Sheet asks for when, where, who and what for each event, tamper detection, protection against modification and deletion, and a separate account that can only write to the log.

## 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.
- You keep the full log private and disclose only the stretch an auditor needs; they can check that it chains to a head you committed before the dispute began.

## Ask Rightshold (free, no key)
Add the MCP server https://www.rightshold.com/mcp to Claude, Cursor, ChatGPT, Grok or VS Code (one-click setup: https://www.rightshold.com/start?ref=seo), 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."

```json
{
  "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)>"
  }
}
```
- Needs an API key. Only the head hash and the entry count become public; your log entries stay with you.
- verify_recorder is free: give it the agent and a disclosed run of entries ({entry, signature}, each entry carrying seq and the prev hash) and it checks the signatures, that the entries follow one another and that they end at a committed head, and says when that head was committed.
- record_ai_run records a signed summary of one agent run (model, inputs and outputs by hash) that a reviewer can verify later with verify_ai_run.

_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._

## Sources
- [Model Context Protocol specification (2025-11-25): Tools, Security considerations](https://modelcontextprotocol.io/specification/2025-11-25/server/tools)
- [OpenTelemetry semantic conventions: GenAI spans (execute_tool)](https://github.com/open-telemetry/semantic-conventions-genai/blob/main/docs/gen-ai/gen-ai-spans.md)
- [Claude Code docs: Hooks reference (PreToolUse, PostToolUse, PostToolUseFailure)](https://code.claude.com/docs/en/hooks)
- [Claude Code docs: Monitoring (OpenTelemetry events)](https://code.claude.com/docs/en/monitoring-usage)
- [OWASP Logging Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html)

## Related
- [How to vet an MCP server before installing it](https://www.rightshold.com/answers/how-to-vet-an-mcp-server-before-installing-it)
- [How to scope OAuth tokens per task for AI agents](https://www.rightshold.com/answers/how-to-scope-oauth-tokens-per-task-for-ai-agents)
- [How to test that MCP tool errors don't leak secrets](https://www.rightshold.com/answers/how-to-test-that-mcp-tool-errors-dont-leak-secrets)
- [How to detect MCP tool description changes (rug pulls)](https://www.rightshold.com/answers/how-to-detect-mcp-tool-description-changes-rug-pull)

_Not legal advice. Updated 2026-10-30. JSON: https://www.rightshold.com/answers/how-to-log-every-ai-agent-tool-call-for-audit.json_