Logging

libtmux-mcp uses Python’s standard logging module under the libtmux_mcp.* namespace. FastMCP forwards server-side log records to connected MCP clients via the MCP logging capability. No manual wiring needed.

Logger hierarchy

All loggers are children of libtmux_mcp. The primary streams are:

  • libtmux_mcp.audit — one structured line per tool call, emitted by AuditMiddleware. Includes tool name, digest-redacted arguments, latency, and outcome. See Safety tiers for the argument-redaction rules. It does not record tool return values.

  • libtmux_mcp.retry — warnings from ReadonlyRetryMiddleware when a readonly tool retried after a transient LibTmuxException.

  • libtmux_mcp.server / libtmux_mcp.tools.* / etc. — ad-hoc warnings and debug messages from the codebase.

  • fastmcp.errors — one record per failed tool call, emitted by ToolErrorResultMiddleware.

Error levels

Tool failures are logged at a level matching who needs to act:

  • WARNING — expected, agent-correctable failures: unknown pane/window/session ids, invalid arguments, safety-tier denials, transient tmux errors. The calling agent receives the message and can correct course; operators don’t need to.

  • ERROR — operator faults and potential bugs: a missing tmux binary, or any unexpected exception escaping a tool.

A WARNING-heavy, ERROR-quiet log stream is therefore healthy — it means agents are probing and recovering. ERROR records are the ones worth alerting on.

Level control

Set the logger level via standard Python mechanisms — for local development, the simplest is an environment variable:

$ FASTMCP_LOG_LEVEL=DEBUG libtmux-mcp

FastMCP reads FASTMCP_LOG_LEVEL at startup and applies it to every fastmcp.* and libtmux_mcp.* logger.

What clients see

MCP clients render incoming notifications/message records in their log pane (e.g. Claude Desktop’s “MCP server logs” panel, or claude-cli’s --verbose output). The records include the server name (libtmux-mcp), level, and the log message — but not the Python logger name, which the protocol doesn’t model.

History controls stay observable

suppress_history and suppress_persistent_history affect shell-history behavior only. They do not disable audit logging and do not clear pane echo or scrollback. The audit logger still summarizes the call’s arguments and outcome, other library or application loggers keep their own behavior, and an MCP client can still retain the original request and response. See Safety tiers for every observation boundary that remains outside history suppression.

Tip

If a tool call has no user-visible error or side effect, the libtmux_mcp.audit log shows the invocation and whether it returned or raised, not the tool’s return value. Use the MCP response and current tmux state to determine what the tool returned or changed.

Further reading