# How to Analyze Fuzzy Search Logs for Debugging in DesktopCommanderMCP

> Debug DesktopCommanderMCP fuzzy search issues by analyzing tab-separated logs. Query logs programmatically or with Unix tools to diagnose failures and performance.

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

---

**DesktopCommanderMCP records every fuzzy-search operation to a tab-separated log file that you can query programmatically or inspect with standard Unix tools to diagnose matching failures and performance issues.**

The `wonderwhy-er/DesktopCommanderMCP` repository includes a dedicated telemetry system for its fuzzy-search capabilities. When you need to analyze fuzzy search logs for debugging in DesktopCommanderMCP, you interact with the singleton logger defined in [`src/utils/fuzzySearchLogger.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/fuzzySearchLogger.ts) and consumed by [`src/tools/edit.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/edit.ts) after each search execution.

## Log File Location and Format

The logger persists data to a hidden directory in the user’s home folder:

```

<HOME>/.claude-server-commander-logs/fuzzy-search.log

```

The file is created lazily on first write. If it does not exist, the logger initializes it with a tab-separated header row (lines 47–64 of [`fuzzySearchLogger.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/fuzzySearchLogger.ts)). Each subsequent entry appends a single line containing 16 tab-delimited fields:

- **timestamp** – ISO-8601 time the search finished
- **searchText** – Raw query string (newlines and tabs escaped)
- **foundText** – Matched text (escaped)
- **similarity** – Numeric similarity score (0–1)
- **executionTime** – Duration in milliseconds
- **exactMatchCount** – Number of exact-match characters
- **expectedReplacements** – Expected fuzzy replacements
- **fuzzyThreshold** – Configured threshold for matching
- **belowThreshold** – `true` if similarity fell below threshold
- **diff** – Diff view between query and result (escaped)
- **searchLength** – Length of query string
- **foundLength** – Length of found string
- **fileExtension** – Extension of source file
- **characterCodes** – Unique character codes observed
- **uniqueCharacterCount** – Count of distinct characters
- **diffLength** – Length of diff string

Because the format is plain-text TSV, you can open it with spreadsheet applications, `awk`, `csvkit`, or standard text editors.

## Programmatic Access Methods

The `fuzzySearchLogger` singleton exposes three async methods for log inspection:

- **`getLogPath()`** – Returns the absolute path string (useful for UI display or external tooling).
- **`getRecentLogs(count?)`** – Reads the file, strips the header, and returns the last *N* records as an array of strings.
- **`clearLog()`** – Re-creates the log file containing only the header row.

All methods first invoke `ensureLogFile()` to guarantee the directory and file exist.

## Step-by-Step Debugging Workflow

1. **Reproduce the issue.** Run the search operation that misbehaves; [`src/tools/edit.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/edit.ts) automatically calls `await fuzzySearchLogger.log(logEntry)` after every fuzzy search.

2. **Retrieve recent entries.** Fetch the last 20 records to verify the search was captured:

```typescript
const recent = await fuzzySearchLogger.getRecentLogs(20);
console.log('Last 20 fuzzy-search logs:', recent);

```

3. **Filter for threshold violations.** Inspect the 9th column (index 8) to find searches that fell below the configured threshold:

```typescript
const below = recent.filter(line => line.split('\t')[8] === 'true');
console.log('Below-threshold searches:', below);

```

4. **Inspect performance metrics.** Check the 5th column (index 4) for execution times exceeding your SLA:

```typescript
const slow = recent.filter(line => Number(line.split('\t')[4]) > 100);
console.log('Searches > 100ms:', slow);

```

5. **Access the raw file.** Retrieve the absolute path for deeper analysis with external tools:

```typescript
const logPath = await fuzzySearchLogger.getLogPath();
console.log('Full log location:', logPath);

```

6. **Reset for clean testing.** Clear the log before a new debugging session:

```typescript
await fuzzySearchLogger.clearLog();

```

## Practical Code Examples

### Manually log a custom search entry

Useful for scripts testing edge cases without invoking the full tool chain:

```typescript
import { fuzzySearchLogger, type FuzzySearchLogEntry } from './utils/fuzzySearchLogger.js';

async function logCustomSearch() {
  const entry: FuzzySearchLogEntry = {
    timestamp: new Date(),
    searchText: 'HelloWorld',
    foundText: 'Hello_World',
    similarity: 0.85,
    executionTime: 12,
    exactMatchCount: 5,
    expectedReplacements: 2,
    fuzzyThreshold: 0.8,
    belowThreshold: false,
    diff: '-HelloWorld\n+Hello_World',
    searchLength: 10,
    foundLength: 11,
    fileExtension: '.txt',
    characterCodes: 'H e l o W r d',
    uniqueCharacterCount: 8,
    diffLength: 24,
  };

  await fuzzySearchLogger.log(entry);
}

```

### Identify file-specific matching issues

Filter logs by file extension to see if certain document types produce unexpected results:

```typescript
async function findExtensionIssues(ext: string) {
  const logs = await fuzzySearchLogger.getRecentLogs(100);
  const matches = logs.filter(line => line.split('\t')[12] === ext);
  console.log(`Found ${matches.length} searches for ${ext}`);
  return matches;
}

```

### Monitor threshold tuning effectiveness

After adjusting `fuzzyThreshold` in your configuration, verify the impact on match quality:

```typescript
async function analyzeThreshold(threshold: number) {
  const logs = await fuzzySearchLogger.getRecentLogs(50);
  const violations = logs.filter(line => {
    const cols = line.split('\t');
    return Number(cols[3]) < threshold; // similarity column
  });
  console.log(`${violations.length} searches below new threshold`);
}

```

## Summary

- Logs reside at `~/.claude-server-commander-logs/fuzzy-search.log` as tab-separated values.
- The `fuzzySearchLogger` singleton in [`src/utils/fuzzySearchLogger.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/fuzzySearchLogger.ts) provides `getRecentLogs()`, `getLogPath()`, and `clearLog()` for programmatic access.
- Each log entry contains 16 fields including `executionTime`, `belowThreshold`, and `diff` for comprehensive debugging.
- Filter the 9th column (index 8) to find threshold violations, and the 5th column (index 4) to diagnose performance bottlenecks.
- The TSV format enables analysis with standard Unix tools (`awk`, `grep`) or spreadsheet software without requiring custom parsers.

## Frequently Asked Questions

### Where does DesktopCommanderMCP store fuzzy-search telemetry?

The logger writes to a hidden directory in your home folder at `~/.claude-server-commander-logs/fuzzy-search.log`. This path is generated dynamically and can be retrieved programmatically via `await fuzzySearchLogger.getLogPath()`.

### How can I view the last few fuzzy-search operations without opening the file manually?

Call `await fuzzySearchLogger.getRecentLogs(10)` to receive the last 10 entries as an array of strings. Each string is a tab-separated line that you can split on `\t` to access individual fields like `similarity` or `executionTime`.

### What does the `belowThreshold` field indicate in the logs?

The `belowThreshold` column (9th field) is a boolean flag set to `true` when the calculated similarity score falls below the configured `fuzzyThreshold`. Monitoring this field helps identify searches that are too strict or queries that fail to match intended targets.

### Can I clear the log file to start a fresh debugging session?

Yes. Invoke `await fuzzySearchLogger.clearLog()` to truncate the file and rewrite only the TSV header. This is useful when you want to isolate logs for a specific reproduction scenario without historical noise from previous operations.