Where DesktopCommanderMCP Stores Tool Call Logs: Audit Logging Across macOS, Linux, and Windows

DesktopCommanderMCP stores every tool invocation in a JSONL audit file at ~/.claude-server-commander/tool-history.jsonl, using os.homedir() to ensure the same logging mechanism works identically on macOS, Linux, and Windows.

DesktopCommanderMCP is a Model Context Protocol (MCP) server that provides desktop automation capabilities. Understanding where tool call logs are stored and how the audit logging system functions across different operating systems is essential for debugging and compliance. The implementation uses a platform-agnostic approach that writes to the user's home directory regardless of the underlying OS.

Audit Log Storage Location and File Format

The primary audit store is implemented in src/utils/toolHistory.ts.

The system constructs the log file path using Node.js's os.homedir() method:

import * as os from 'os';
import * as path from 'path';

const historyFile = path.join(os.homedir(), '.claude-server-commander', 'tool-history.jsonl');

Each entry is appended as a JSON object containing the timestamp, tool name, arguments, output, and optional duration. The file uses JSON Lines (JSONL) format, where each line represents a complete JSON record.

How the Audit Logging Mechanism Works

The ToolHistory class in src/utils/toolHistory.ts manages the audit trail through several key mechanisms.

The addCall Method

When a tool executes, the addCall method creates a ToolCallRecord and queues it for persistence:

import { toolHistory } from './utils/toolHistory';

// After tool execution
const result = await someTool.run(args);
toolHistory.addCall('someTool', args, result, Date.now() - start);

This method pushes the record into a bounded in-memory array (maximum 1,000 entries) and schedules an asynchronous disk flush via flushToDisk().

File Size Management

The audit system enforces storage limits to prevent unbounded growth:

  • Maximum file size: 5 MiB
  • Target size after trim: approximately 4 MiB

When the file exceeds the size cap, trimHistoryFileIfTooLarge() removes the oldest lines until the file shrinks to the target size. This rotation happens automatically during the flush cycle.

Asynchronous Write Queue

The flushToDisk routine checks the file size, trims if necessary, then appends new JSON lines using fs.appendFileSync. This design ensures that tool calls are recorded without blocking the main execution thread.

Cross-Platform Storage Paths

Because the log path derives from os.homedir(), the audit logging mechanism is platform-agnostic. The same code executes on all supported operating systems, with the OS determining the actual directory resolution.

Platform os.homedir() Resolution Final Audit File Location
macOS /Users/<username> /Users/<username>/.claude-server-commander/tool-history.jsonl
Linux /home/<username> /home/<username>/.claude-server-commander/tool-history.jsonl
Windows C:\Users\<username> C:\Users\<username>\.claude-server-commander\tool-history.jsonl

Secondary and Legacy Log Files

Beyond the primary JSONL audit store, DesktopCommanderMCP maintains additional logging infrastructure.

Legacy Plain-Text Logger

The older trackTools helper in src/utils/trackTools.ts writes plain-text logs to a different directory structure:


~/.claude-server-commander-logs/fuzzy-search.log

This logger rotates files when they reach approximately 10 MiB, compared to the 5 MiB cap used by the primary audit system.

Specialized Loggers

Additional components like src/utils/fuzzySearchLogger.ts implement domain-specific logging under the same home-directory scheme. These files complement the main audit trail but use different rotation strategies and formats.

Programmatic Access to Audit Logs

You can interact with the audit system directly through the toolHistory API.

Retrieving Recent Calls

To fetch formatted history entries with timezone conversion:

import { toolHistory } from './utils/toolHistory';

const recent = toolHistory.getRecentCallsFormatted({
  maxResults: 20,
  since: '2024-01-01T00:00:00Z',
});
console.log(recent);

Cleanup and Shutdown

For graceful shutdown or test cleanup:

await toolHistory.cleanup();   // Flushes pending writes and clears timers

Accessing the File Path Directly

To locate the audit file programmatically:

import { toolHistory } from './utils/toolHistory';
console.log('Audit file:', toolHistory.getStats().historyFile);

Summary

  • DesktopCommanderMCP stores tool call logs in ~/.claude-server-commander/tool-history.jsonl using a JSONL format.
  • The src/utils/toolHistory.ts module provides the primary audit logging implementation with a 5 MiB size cap and 1,000-entry memory buffer.
  • Cross-platform compatibility is achieved through os.homedir(), resulting in platform-specific paths on macOS (/Users/...), Linux (/home/...), and Windows (C:\Users\...).
  • Legacy logging in src/utils/trackTools.ts uses plain-text format with 10 MiB rotation under ~/.claude-server-commander-logs/.

Frequently Asked Questions

Where exactly is the tool call audit log stored on Windows?

On Windows, the audit log is stored at C:\Users\<username>\.claude-server-commander\tool-history.jsonl, where <username> is the current user's profile name. The path is constructed dynamically using Node.js's os.homedir() function, which resolves to the user's home directory regardless of Windows version.

What is the maximum size of the audit log file before rotation?

The primary audit file caps at 5 MiB, at which point the system trims oldest entries until the file reaches approximately 4 MiB. This is implemented in the trimHistoryFileIfTooLarge() function within src/utils/toolHistory.ts. Secondary log files used by the legacy trackTools system rotate at 10 MiB instead.

How can I programmatically retrieve recent tool call history?

Import the toolHistory singleton from src/utils/toolHistory.ts and call getRecentCallsFormatted(), passing optional parameters for maxResults and since timestamp. This returns the most recent entries with timestamps converted to the local timezone, formatted for display or further processing.

Does DesktopCommanderMCP support custom audit log directories?

Currently, the audit log directory is hardcoded to .claude-server-commander within the user's home directory as defined by os.homedir(). The path is constructed in src/utils/toolHistory.ts without configuration options, meaning you cannot specify custom locations without modifying the source code. Direct file access is possible by reading the JSONL file directly from the resolved home directory path.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →