# Desktop Commander MCP Audit Logging: How Tool Call Tracking Works

> Discover how Desktop Commander MCP audit logging tracks tool calls, storing logs in `~/.claude-server-commander/claude_tool_call.log` with rotation and JSON history.

- Repository: [Eduard Ruzga/DesktopCommanderMCP](https://github.com/wonderwhy-er/DesktopCommanderMCP)
- Tags: how-to-guide
- Published: 2026-08-03

---

**Desktop Commander MCP records every tool invocation to `~/.claude-server-commander/claude_tool_call.log` with automatic 10 MB rotation, plus an optional bounded JSON-Lines history for UI inspection.**

The audit logging mechanism in Desktop Commander MCP provides forensic visibility into every tool interaction. According to the `wonderwhy-er/DesktopCommanderMCP` source code, the system uses a dual-track approach: a raw append-only text log for debugging and a structured history file for quick UI access.

## Log File Location and Configuration

All audit logs reside in a dedicated configuration directory under the user home folder.

In [`src/config.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config.ts), the following constants define the primary audit log:

```ts
export const TOOL_CALL_FILE = path.join(CONFIG_DIR, 'claude_tool_call.log');
export const TOOL_CALL_FILE_MAX_SIZE = 1024 * 1024 * 10; // 10 MB

```

The `CONFIG_DIR` expands to `~/.claude-server-commander` on Linux/macOS or the equivalent path on Windows. Therefore, the canonical audit log location is:

```

$HOME/.claude-server-commander/claude_tool_call.log

```

## How the Audit Logger Writes Entries

The core audit function lives in [`src/utils/trackTools.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/trackTools.ts). The `trackToolCall(toolName, args?)` function handles every logged invocation:

```ts
export async function trackToolCall(toolName: string, args?: unknown): Promise<void> {
  const timestamp = new Date().toISOString();
  const logEntry = `${timestamp} | ${toolName.padEnd(20, ' ')}${args ? `\t| Arguments: ${JSON.stringify(args)}` : ''}\n`;
  // …size check & rotation…
  await fs.promises.appendFile(TOOL_CALL_FILE, logEntry, 'utf8');
}

```

Each entry contains:
- **ISO-8601 timestamp** for precise temporal ordering
- **Tool name** padded to 20 characters for columnar alignment
- **JSON-encoded arguments** (optional, when provided)

### Log Rotation Behavior

Before writing, `trackToolCall` checks if the current log exceeds **10 MB**. If so, it performs rotation:

1. Renames `claude_tool_call.log` to `claude_tool_call_YYYY-MM-DD_HH-MM-SS.log`
2. Creates a fresh empty log file
3. Continues appending new entries

This prevents unbounded growth while preserving historical audit data.

### Failure-Resilient Design

Errors during logging never block primary operations. If `appendFile` throws, the error is reported via telemetry and silently ignored—tool execution continues uninterrupted.

## Tool Call History for UI Inspection

A separate system in [`src/utils/toolHistory.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/toolHistory.ts) maintains `tool-history.jsonl` in the same directory. This JSON-Lines store keeps approximately **1,000 recent entries** with full call metadata including results.

| File | Purpose | Format |
|------|---------|--------|
| `claude_tool_call.log` | Authoritative audit trail for debugging | Plain text, append-only |
| `tool-history.jsonl` | Bounded history for UI display | JSON-Lines, ~1000 entries |

The history file serves the Desktop Commander UI; the raw audit log remains the source of truth for forensic analysis.

## Working with Audit Logs Programmatically

### Logging a Tool Call from Custom Code

```ts
import { trackToolCall } from './utils/trackTools.js';

await trackToolCall('read_file', { path: '/tmp/example.txt' });

```

### Reading the Current Audit Log

```ts
import { TOOL_CALL_FILE } from './config.js';
import { readFile } from 'fs/promises';

async function showAuditLog() {
  const content = await readFile(TOOL_CALL_FILE, 'utf-8');
  console.log(content);
}

```

### Forcing Log Rotation for Testing

```ts
import { TOOL_CALL_FILE_MAX_SIZE, TOOL_CALL_FILE } from './config.js';
import { rename, stat, appendFile } from 'fs/promises';
import path from 'path';

async function forceRotation() {
  const dir = path.dirname(TOOL_CALL_FILE);
  const base = path.basename(TOOL_CALL_FILE, '.log');
  const now = new Date();
  const ts = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}_${String(now.getHours()).padStart(2, '0')}-${String(now.getMinutes()).padStart(2, '0')}-${String(now.getSeconds()).padStart(2, '0')}`;
  const rotated = path.join(dir, `${base}_${ts}.log`);
  await rename(TOOL_CALL_FILE, rotated);
  await appendFile(TOOL_CALL_FILE, '', 'utf8');
}

```

## Summary

- **Primary audit log**: `~/.claude-server-commander/claude_tool_call.log` (10 MB rotation)
- **Core implementation**: `trackToolCall()` in [`src/utils/trackTools.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/trackTools.ts)
- **Configuration**: [`src/config.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config.ts) defines paths and size limits
- **Secondary history**: `tool-history.jsonl` for UI access to ~1,000 recent calls
- **Design priorities**: Non-blocking writes, automatic rotation, failure resilience

## Frequently Asked Questions

### Where exactly are Desktop Commander MCP tool call logs stored?

The audit log resides at `$HOME/.claude-server-commander/claude_tool_call.log`. On Windows, this maps to `%USERPROFILE%\.claude-server-commander\claude_tool_call.log`. A separate UI-oriented history file exists at `tool-history.jsonl` in the same directory.

### What happens when the audit log reaches 10 MB?

The `trackToolCall` function automatically rotates the file. It renames the current log with a timestamp suffix (e.g., `claude_tool_call_2024-11-03_14-27-55.log`) and starts a fresh empty log. This prevents disk exhaustion while preserving prior audit data.

### Can audit logging be disabled?

The source code in `wonderwhy-er/DesktopCommanderMCP` does not expose a configuration flag to disable `trackToolCall`. Since errors are caught and ignored, logging fails gracefully without affecting operations. To effectively disable, you would need to modify [`src/utils/trackTools.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/trackTools.ts) or redirect `TOOL_CALL_FILE` to `/dev/null`.

### How does the tool history differ from the audit log?

The tool history (`tool-history.jsonl`) is a structured JSON-Lines file with a ~1,000 entry limit used by the Desktop Commander UI. The audit log (`claude_tool_call.log`) is an unlimited, human-readable text file designed for forensic debugging and compliance tracing.