AI Assistants

Claude Desktop Logs

Overview

Claude Desktop writes a set of text logs to ~/Library/Logs/Claude/. They are the best source for a timeline of the application itself: when it started and quit, when it updated, when users signed in, when MCP servers started and stopped, and when Cowork virtual machines and remote sessions came up. Logs rotate, so older entries survive only in numbered files or in backups.

The main trap is time. Different logs use different clocks, and the most important one carries no time zone.

File Locations

All paths are under ~/Library/Logs/Claude/.

FileContents
main.log, main1.log ... main3.logMain-process log (electron-log), rotated
mcp.log, mcp[0-9].logMCP manager log
mcp-server-<name>.logOne log per MCP server
claude.ai-web*.log, main-window.log, unknown-window.logRenderer console output
cowork_vm_node.log, cowork_vm_swift.log, swift.log, coworkd.log, vzgvisor.logCowork virtual machine components
cowork_host_loop_debug.logCowork host agent loop
ssh.log, remote-control.log, in-app-browser.logSSH, remote control, in-app browser

Updater logs are elsewhere: ~/Library/Caches/com.anthropic.claudefordesktop.ShipIt/ShipIt_stderr.log*.

Main Log Format

main.log follows the electron-log default:

2026-07-14 09:02:11 [info][Updater] Checking for update
2026-07-14 09:02:12 [warn][Window] Example warning text
    continuation line with no prefix
PartMeaning
YYYY-MM-DD HH:MM:SSTime of the entry
[level]info, warn, error, debug
[Component]Subsystem that wrote it
messageFree text

Lines without a prefix are continuations of the previous entry (stack traces, wrapped JSON) and must be joined to it.

Local Time With No Zone

The timestamps in main.log are local time with no time-zone offset. electron-log formats them with the host's local clock at the moment of writing and does not record the zone. Reading these as UTC will be wrong by the host's offset, and the error changes with daylight saving.

To place an entry on a UTC timeline you need the host's zone at that time:

  1. Take the zone from the evidence: system time zone settings (see System Info).
  2. Cross-check against a source that records zone or UTC: sentry/scope_v3.json (timezone and app start time), UTC-stamped MCP log lines, or a Cowork audit event written close in time.
  3. Watch for daylight saving transitions and for a user who travelled or changed the zone setting. A zone that is correct for the image may be wrong for a past log line. During the repeated hour at the end of daylight saving, a local time is ambiguous.

macfor emits both a normalised timestamp and the original timestamp_raw. When the zone could not be determined from the evidence it uses UTC and sets timezone_assumed: "UTC", so check that field before relying on a time. Treat the conversion as inferred.

MCP Logs

Format

mcp-server-<name>.log lines use an ISO 8601 UTC time:

2026-07-14T09:02:11.481Z [example-files] [info] Initializing server...
2026-07-14T09:02:11.902Z [example-files] [info] Server started and connected successfully
2026-07-14T09:02:12.010Z [example-files] [info] Message from client: {"method":"initialize","id":0}

mcp.log puts the level first. Unlike main.log, these timestamps carry a Z and are in UTC, so use them as the time anchor when reconciling the clocks.

What to Extract

EventMeaning
Initializing, connectedServer launch and handshake: the server really ran, and when
Transport closedServer exit
Message from client / Message from serverJSON-RPC traffic: method, request ID, and (in some builds) parameters
stderr linesServer output, including errors and sometimes paths and credentials

The file name carries the server name from the config (see MCP and Extensions). A server that is configured but has no log was never started under that name.

Older Verbose Builds

Early builds (late 2024) logged full JSON-RPC payloads: the tool name, its arguments, and the results the server returned. Where those logs survive they can show exactly what a tool was called with and what came back, which makes them valuable.

Current builds log metadata only (method, ID, direction) and omit the parameters. Which version made the change has not been established, so do not conclude from missing arguments that no tool was called. Check the version and look at the audit log and transcripts for the arguments.

Other Logs

  • Renderer logs (claude.ai-web*.log, main-window.log) record console output from the web interface, including errors and navigation. Useful for sign-in and network failures.
  • Cowork VM logs (cowork_vm_*.log, coworkd.log, vzgvisor.log) record the Cowork virtual machine and its host loop. Some use a different logger (logrus-style) from electron-log, so check the time format in each file rather than assuming one.
  • ssh.log, remote-control.log show remote sessions. Entries here indicate the app was used remotely, which matters for attribution. Pair with bridge-state.json in State and Storage.

Investigation Notes

  • Build a timeline. Combine main.log, updater logs, config.json (first launch, last quit), and Sentry start times. Convert main.log carefully.
  • Detect gaps. A gap in a rotated log may reflect rotation limits, not inactivity.
  • Sign-ins. Look for account and login messages in main.log. Match the account UUID with the conversation and session paths.
  • Secrets. MCP stderr and renderer logs can hold tokens and personal data. Collect logs as evidence, and redact secrets in any derived report.
  • Corroborate. An MCP log line proving a tool call is stronger when matched to an audit event in the same minute.

What macfor Collects

The ai.claudedesktop plugin emits claude_log_entry for the main and other logs (with log_file) and claude_mcp_log_entry for the MCP logs. Records carry timestamp, timestamp_raw, timezone_assumed, level, and component. MCP records add server, direction, method, rpc_id, and event (initializing, connected, transport_closed, message, stderr, other). The log files are copied byte-for-byte as original evidence.

{
  "type": "claude_log_entry",
  "log_file": "main.log",
  "line": 42,
  "timestamp": "2026-07-14T09:02:11Z",
  "timestamp_raw": "2026-07-14 19:02:11",
  "timezone_assumed": "",
  "level": "info",
  "component": "Updater",
  "message": "Checking for update"
}

All values above are illustrative.

References