Operations & Gateways
MCP Audit Logs: Build Evidence for AI Agent Actions
By Ralph Duin··Updated

Useful MCP audit logs connect an authenticated actor to a requested action, the decision that allowed or denied it, and the outcome that was actually observed. A tool-call message alone cannot prove that a downstream change completed. An agent's narrative cannot prove authorization. Build evidence around the enforcement and execution boundaries, then test whether someone else can reconstruct the event.
This guide is for platform and security teams operating MCP tools. It provides a redacted event design, a reconstruction workflow, and failure checks. It is not a compliance certification or a claim that MCP defines a universal audit schema. Protocol notes use revision 2026-07-28, checked in October 2026.
Distinguish diagnostic messages, traces, and audit evidence
A diagnostic log helps explain an error. A trace helps connect work across components. An audit record supports an accountability question such as “which identity was permitted to change this record?” The same infrastructure may carry all three, but their required fields, access, completeness and retention can differ.
OpenTelemetry traces describe operations as spans connected within a trace. That is useful correlation, but a trace identifier does not itself identify a human or prove a policy decision. If traces are sampled, an absent span is not proof that an action never happened. Review the sampling configuration before depending on a trace store as your complete action history.
MCP's Logging utility is deprecated as of revision 2026-07-28; its guidance directs new implementations toward stderr for stdio or structured observability such as OpenTelemetry. Legacy protocol logging messages should not be presented as a required current audit solution. Your audit design still needs an explicit owner and collection path.
Define the questions before choosing fields
Start with a small set of questions your incident or operations team needs to answer. The OWASP Logging Cheat Sheet emphasizes purpose-driven event collection and distinguishes sources with different trust levels. Translate that into an evidence contract for your own tools rather than collecting everything because storage is available.
| Question | Useful evidence | Important limitation |
|---|---|---|
| Who requested the action? | Authenticated principal, client identifier, tenant or workspace | A model name is not an authenticated principal |
| What was requested? | Stable connection/tool identity and safe target reference | A tool display name can change or collide |
| Why was it permitted? | Decision, policy version and applicable approval reference | “Allowed” without the evaluated rule is hard to interpret later |
| Was execution attempted? | Attempt identifier, dispatch time, upstream correlation | A permitted decision may never reach the upstream |
| What happened? | Observed outcome, error category, downstream reference | A timeout can leave the actual side effect unknown |
| How complete is the record? | Event delivery status and known collection gaps | No result record does not establish success or denial |
For delegated work, retain the relationship between the initiating request and the identities that actually execute each step. Do not manufacture a human approver when a scheduled service identity triggered the action. Use access-control boundaries to decide where the identity and policy facts originate.
A redacted audit event example
The following is an illustrative application record for a fictional sandbox action. It is not an MCP wire message, a standard schema, or an export from MCP Beast. Identifiers and timestamps are invented; there is no live credential or customer payload.
{
"event_type": "tool_attempt_completed",
"event_id": "example-event-003",
"request_id": "example-request-41",
"attempt_id": "example-attempt-1",
"occurred_at": "2026-10-10T12:00:02Z",
"principal_id": "test-user-7",
"client_id": "test-client-2",
"workspace_id": "sandbox-workspace",
"connection_id": "sandbox-support",
"tool_name": "update_issue",
"target_reference": "test-issue-42",
"policy": {
"version": "example-policy-v3",
"decision": "allow",
"approval_reference": "test-approval-8"
},
"outcome": "confirmed_by_upstream_response",
"upstream_reference": "example-provider-request-93",
"payload_capture": "omitted"
}
An outcome label must have a defined meaning in your system. Here it means an upstream response confirmed completion, not that an independent investigator verified the provider's database. If the request timed out after dispatch, record an unknown outcome and reconcile it using the provider's safe lookup or idempotency mechanism. Do not relabel uncertainty as failure and blindly repeat a consequential action.
Store a denied decision without a completed-attempt event when nothing was dispatched. Separating decisions from attempts lets you distinguish “not permitted,” “permitted but never sent,” and “sent with an uncertain result.”
Capture enough context without copying secrets
Begin with an allowlist of fields serving the evidence questions. Tool arguments can include access tokens, document contents, personal information, or internal locations. Results can contain the same material plus raw provider errors. Even parameter names and target references may reveal more than intended in a particular system.
OpenTelemetry's sensitive-data guidance recommends minimizing collection and reviewing what instrumentation emits. Apply redaction before a record reaches its storage or exporter, then test downstream copies and support bundles. Removing a value from one dashboard does not remove it from the underlying event stream.
If a workflow needs protected payload evidence, define its purpose, authorized readers, retention and storage separately. Do not make verbatim recording the default for “high-risk” actions. A restricted reference may be sufficient; a hash alone may neither hide predictable data nor prove what was originally supplied. Review those tradeoffs against the actual investigation need. The credential isolation guide covers secret exposure paths around tool execution.
Reconstruct one action across the boundaries
A useful acceptance exercise begins with a safe sandbox change whose intended outcome is known. Give the reviewer a request identifier and access to the permitted evidence, without explaining the execution sequence. Ask them to reconstruct who requested it, what was approved, which attempt reached the provider, and what the system can honestly conclude about the result.
Use these fictional reconstruction cases to check whether the reviewer reaches a defensible conclusion. They reuse the illustrative event vocabulary above; they are not a second logging standard or observed test results.
| Case | Decision record | Attempt record | Downstream observation | Defensible conclusion | Next recovery step |
|---|---|---|---|---|---|
| Denial before dispatch | Correlated deny decision with policy version | Enforcement evidence confirms dispatch was blocked; no completed-attempt event is expected | Controlled sandbox observation agrees that this request did not reach the provider | This request was denied before dispatch on the tested path | Review the denial with the policy owner; change permissions only if authorized, then make a new request |
| Dispatch with confirmed response | Correlated allow decision and applicable approval reference | Dispatch record followed by tool_attempt_completed | Linked upstream response confirms completion | confirmed_by_upstream_response, within the response's stated meaning; not independent database verification | Close this attempt with its evidence reference; do not repeat it just to obtain another confirmation |
| Dispatch with missing response | Correlated allow decision and applicable approval reference | Dispatch recorded; local wait ends without a confirming response | No correlated completion evidence available yet | Outcome unknown: a timeout does not prove the side effect failed or succeeded | Reconcile through the provider's safe lookup or documented idempotency mechanism before retrying a consequential action |
A missing event cannot place a request in the denial row. An absent attempt or response may reflect sampling, delivery loss, incomplete access, or an uninstrumented path. Without positive evidence of the denial and dispatch boundary, preserve the gap and investigate collection as well as execution. A transport failure proven to occur before dispatch is also distinct from a policy rejection; record which boundary stopped the request.
Next, try a repeated request. Keep a stable initiating-request reference and distinct attempt identifiers so two attempts cannot be mistaken for two human approvals. Where the provider supports idempotency, record a safe reference to that control without assuming it guarantees the whole workflow exactly once. Link related evidence; do not rely on timestamp sorting alone across machines.
These are proposed checks, not results from an experiment performed for this article. They complement MCP monitoring and observability, which focuses on operational health rather than the completeness of an action history.
Test collection failures and evidence access
Audit collection is itself a system that can fail. Disconnect the exporter in a test environment, fill its bounded queue, deny storage access, and simulate an oversized or malformed event. Determine which failures are visible, how delivery resumes, and which records may be missing. Choose and document whether each sensitive operation should stop or continue when its required evidence cannot be recorded.
An append-only application interface is not the same as immutable storage. Identify which administrators, service accounts, retention jobs and backup operators can alter or delete records. If tamper evidence is required, verify the storage and verification procedure against the stated threat model; a product label or a hash field is insufficient proof.
Set retention through the responsible policy owner and the applicable obligations for the actual records. There is no universal MCP retention duration. Test authorized export and eventual deletion, including replicas and backups where applicable. Avoid claiming a framework is satisfied merely because records exist; the reviewer must be able to use the right records under the right controls.
Start with one tool and make the evidence usable
Choose a tool whose behavior and owner are clear. Agree on the event contract, record a permitted attempt and a denied request, exercise uncertain completion, and inspect every diagnostic path for a canary secret. Document gaps in the collection path before expanding to other tools and execution locations.
If you evaluate a gateway, require evidence from the exact runtime and plan you will deploy. Ask whether direct-to-server calls bypass its audit path and how those calls are accounted for. The gateway buyer guide provides a broader pilot scorecard.
For MCP Beast, use the security overview to frame that conversation. Do not infer append-only storage, cryptographic chaining, a particular export destination, or regulatory compliance from this article. The useful result is an evidence contract your team can test and operate, with known limits rather than unsupported guarantees.
Frequently Asked Questions
What should MCP audit logs capture?
Capture the authenticated actor, selected connection and tool, relevant policy decision, execution attempt and observed outcome, with safe correlation identifiers. Choose payload fields by evidence need and data sensitivity rather than logging complete requests by default.
Are MCP protocol logging messages an audit trail?
Not by themselves. They do not establish a complete authorization and execution history. The Logging utility is deprecated in MCP revision 2026-07-28; design application audit evidence independently of legacy diagnostic messages.
Should a timed-out tool call be logged as failed?
Record the observed timeout and whether dispatch occurred. If the downstream side effect is unknown, preserve that uncertainty and reconcile it before repeating a consequential operation.
How long should an organization retain MCP audit logs?
Set retention according to the purpose, data classification and applicable obligations for those records, with a named policy owner. MCP does not prescribe one universal duration or make a logging system compliant by default.
Related: MCP authentication, credential boundaries, and gateway evaluation.