MCP server logging best practices come down to five rules: record every tool call with who made it, what tool ran, a redacted summary of the arguments and the result status; write logs to stderr for stdio servers and never to stdout; keep secrets and personal data out of every log line; send everything to central, append-only storage; and alert on the patterns that signal abuse. The MCP specification sets several of these as requirements, and OWASP lists missing logs as its own risk, MCP08, lack of audit and telemetry. Without them, an incident leaves no trail to follow.
Why MCP servers need their own logging plan
An MCP server sits between a language model and real systems. When something goes wrong, the questions are always the same: which agent called which tool, with what arguments, on whose behalf, and what came back. Standard web server logs answer none of them, because a single HTTP request or stdio message can carry a tool call that reads a database or sends an email.
Microsoft's guide to MCP08 describes the failure plainly: a breach that runs for weeks because no logs show which tools ran or what data they touched. The research behind every malicious MCP server reported so far shows the same gap from the other side. Those attacks worked through tool calls that looked normal one at a time and only stood out as a pattern, which is only visible if the calls were recorded.
Logs also answer the questions that come after an incident. Customers and auditors will ask which of their records a tool touched, and when. Regulators may ask whether personal data left your systems. A server that cannot answer those questions turns a contained problem into a disclosure you have to make about everything it could have reached, rather than what it actually did. Following MCP server logging best practices from the first release is far cheaper than reconstructing that history later from API bills and guesswork.
What to log for every tool call
Treat each tool call as an audit event. At minimum, record a timestamp, a correlation ID, the client identity, the user or service the call acts for, the tool name, the authorization decision and scopes used, a redacted summary of the arguments, the result status, and how long it took. The MCP tools specification asks clients to log tool usage for audit purposes; servers should keep their own record rather than relying on whatever each client chooses to keep.
Log the events around the calls too. The specification's scope minimization guidance tells servers to log elevation events, meaning each time a client asks for more scope and what subset was granted, with correlation IDs. Add authentication failures, rejected inputs, rate limit hits, and any change to your tool list or tool descriptions, since a description that changes after approval is the signature of an MCP tool poisoning attack.
An example record that follows MCP server logging best practices
Here is one tool call written as a single structured line. It names the caller and the tool, records the decision and the outcome, and keeps the argument values out while still showing what kind of request it was.
{"ts":"2026-11-04T15:02:11Z","trace_id":"4bf92f3577b34da6","client":"cursor/1.7",
"user":"u_1842","tool":"query_orders","scopes":["orders:read"],"authz":"allow",
"args":{"customer_id":"sha256:9c1e...","limit":50},"status":"ok","rows":50,"ms":184} Every field earns its place. The trace ID joins this line to the client and to the database query it caused. The scopes and the authorization decision show whether the call was allowed for the right reason. The hashed customer ID lets you find every call about one customer without storing who that customer is. If your logs cannot answer who, what, on whose behalf and with what result for any call in the last few months, they do not yet meet MCP server logging best practices.
Where logs go: stderr, not stdout
For stdio servers the transport rules are strict. The server must not write anything to stdout that is not a valid MCP message, because stdout is the protocol channel and a stray log line corrupts it. The server may write UTF-8 strings to stderr for informational, debug and error messages. Clients may capture, forward or ignore stderr, and should not assume stderr output means an error. In other words, stderr is the right channel, but you cannot count on the client to keep what you write there.
So ship logs to a destination you control. For HTTP servers, that is the same pipeline as the rest of your services. For stdio servers distributed to users, document where logs go and keep any remote reporting opt-in, so you are not collecting a user's data without telling them.
The protocol logging feature is deprecated
Earlier versions of MCP included a Logging feature: servers declared a logging capability and sent notifications/message to the client, and clients could change the level with logging/setLevel. The 2026-07-28 specification deprecates it under SEP-2577. That revision removes logging/setLevel, moves the log level into a per-request _meta field, and suggests logging to stderr for stdio servers or using OpenTelemetry instead.
The same revision documents how to carry OpenTelemetry trace context in _meta, which makes it practical to follow one request from the client, through your MCP server, into the APIs behind it. For a new server, build on OpenTelemetry from the start and treat protocol log notifications as a convenience for developers, not your audit trail. Existing servers keep working during the deprecation window, which the SEP sets at a minimum of one year.
Redaction: what never goes in a log
A log that leaks secrets is worse than no log. The MCP logging specification says log messages must not contain credentials or secrets, personally identifying information, or internal system details that could aid an attack. It also says implementations should rate limit messages, validate data fields, control access to logs and monitor them for sensitive content.
Redact at the source, before the log line is written, rather than hoping a downstream filter catches it. Log the names and types of arguments and a hash or truncated form of values. Never log bearer tokens, API keys, or the contents of files a tool read. The authorization specification warns that tokens cached or logged on the server can be replayed by anyone who finds them. Microsoft's MCP08 guidance gives a practical summary: log redacted summaries, correlation IDs, tool names and authorization decisions, not raw payloads.
Retention, integrity and alerts
Keep logs long enough to investigate an incident you discover late, and store audit records in tamper-evident, append-only storage that the MCP server itself cannot delete. Restrict who can read them, since even redacted logs describe your systems.
Then make the logs work. The OWASP MCP Security Cheat Sheet recommends sending logs to a SIEM and alerting on tools being called for the first time, admin-level queries and abnormal call frequency. Microsoft adds off-hours activity, authentication failures, anonymous tool use and spikes in data access. A good first alert set is small: a new tool name, a tool description change, a burst of calls from one client, and any call that reaches data outside the user's usual scope.
Next step: apply MCP server logging best practices everywhere
MCP server logging best practices only help on the servers you know about. Logging is one part of running a server safely; our guide on how to secure MCP servers covers the rest, and MCP server authentication covers the identity your logs record. To find every MCP server your organization runs, including the ones nobody is logging, run a Discovery Scan.