# dimitar-grigorov/mcp-file-tools [Health: Active]

**Category:** 📂 File Systems  
**Repository:** https://github.com/dimitar-grigorov/mcp-file-tools  
**GitHub Stars:** 20  
**Views:** 1  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/dimitar-grigorov-mcp-file-tools

## Description
Filesystem server for legacy, non-UTF-8 files. Auto-detects and converts 24 encodings (CP1251, CP1252, ISO-8859-x, KOI8-R/U, GBK/GB18030), keeps each file's original encoding on write, and manages BOM and line endings. Encoding-aware grep, partial reads with offset/limit for large files, and allowed-directory confinement. Single Go binary, no runtime dependencies.

## Claude Desktop Quick Installation
Install path detected from listing signals. Uses `npx` (confidence: high):

```json
"mcpServers": {
  "mcp-file-tools": {
    "command": "npx",
    "args": ["-y","@modelcontextprotocol/inspector"]
  }
}
```

## Documentation & README

# MCP File Tools

[![Go Report Card](https://goreportcard.com/badge/github.com/dimitar-grigorov/mcp-file-tools)](https://goreportcard.com/report/github.com/dimitar-grigorov/mcp-file-tools)
[![Release](https://img.shields.io/github/v/release/dimitar-grigorov/mcp-file-tools)](https://github.com/dimitar-grigorov/mcp-file-tools/releases/latest)
[![License: GPL-3.0](https://img.shields.io/github/license/dimitar-grigorov/mcp-file-tools)](LICENSE)
[![MCP Registry](https://img.shields.io/badge/MCP-Registry-blue)](https://registry.modelcontextprotocol.io/?search=mcp-file-tools)
[![Test](https://github.com/dimitar-grigorov/mcp-file-tools/actions/workflows/test.yml/badge.svg)](https://github.com/dimitar-grigorov/mcp-file-tools/actions/workflows/test.yml)

Claude sees `Настройки` — not `????` or `Íàñòðîéêè`.

MCP server for file operations on text that isn't UTF-8. It detects the encoding from the
file's bytes rather than its extension, hands the model UTF-8, and writes back in the
original encoding — BOM and CRLF/LF intact, still byte-compatible with whatever legacy
tool owns the file.

- **24 encodings, read and write** — Cyrillic (CP1251, KOI8-R/U, CP866), Windows-125x, ISO-8859-x, UTF-16 LE/BE, GBK/GB18030 ([full list](#supported-encodings))
- **Encoding-aware across the whole tool set** — not just read and write: `edit_file`, `grep_text_files` and `search_files` decode the same way
- **Detection you can inspect** — `detect_encoding` reports the charset, a confidence score and any BOM, so garbled text becomes diagnosable instead of mysterious
- **BOM and line endings are first-class** — add or strip a BOM, convert CRLF↔LF, and do it correctly on UTF-16, where a naive byte-level rewrite corrupts the file
- **Sandboxed** — every path, including symlink and junction targets, is resolved and checked against the directories you allowed

**Perfect for:** Delphi/Pascal projects, legacy VB6 apps, old PHP/HTML sites, config and data files whose encoding you can't tell from the filename.

> **PRs welcome and merged fast** — no CLA, no style review, one-line fixes count. Forked this to fix something? Please [send it back](#contributing) instead.

## What It Does

Provides 20 tools for file operations with automatic encoding conversion:
- [`read_text_file`](TOOLS.md#read_text_file) - Read files with encoding auto-detection and conversion
- [`read_multiple_files`](TOOLS.md#read_multiple_files) - Read multiple files concurrently with encoding support
- [`write_file`](TOOLS.md#write_file) - Write files in specific encodings
- [`edit_file`](TOOLS.md#edit_file) - Line-based edits with diff preview and whitespace-flexible matching
- [`copy_file`](TOOLS.md#copy_file) - Copy a file to a new location
- [`delete_file`](TOOLS.md#delete_file) - Delete a file
- [`list_directory`](TOOLS.md#list_directory) - Browse directories with pattern filtering
- [`tree`](TOOLS.md#tree) - Compact indented tree view (85% fewer tokens than JSON)
- [`search_files`](TOOLS.md#search_files) - Recursively search for files matching glob patterns
- [`grep_text_files`](TOOLS.md#grep_text_files) - Regex search in file contents with encoding support
- [`detect_encoding`](TOOLS.md#detect_encoding) - Auto-detect file encoding with confidence score
- [`convert_encoding`](TOOLS.md#convert_encoding) - Convert file between encodings
- [`manage_line_endings`](TOOLS.md#manage_line_endings) - Detect or convert line endings (CRLF/LF/mixed)
- [`manage_bom`](TOOLS.md#manage_bom) - Detect, strip, or add Unicode BOM
- [`list_encodings`](TOOLS.md#list_encodings) - Show all supported encodings
- [`get_file_info`](TOOLS.md#get_file_info) - Get file/directory metadata
- [`create_directory`](TOOLS.md#create_directory) - Create directories recursively (mkdir -p)
- [`move_file`](TOOLS.md#move_file) - Move or rename files and directories
- [`list_allowed_directories`](TOOLS.md#list_allowed_directories) - Show accessible directories
- [`check_for_updates`](TOOLS.md#check_for_updates) - Check whether a newer release is available

Plus three [prompts](TOOLS.md#prompts) — `audit_encodings`, `fix_mojibake`,
`migrate_to_utf8` — surfaced by clients as user commands.

See [TOOLS.md](TOOLS.md) for detailed parameters and examples.

**Out of scope:** binary/media reading (`read_media_file`). This is a *text*
tool; agents read images with their built-in tools.

### Supported encodings

24 encodings, each usable for both reading and writing. Any of them can be named
explicitly via the `encoding` parameter, or left to auto-detection.

| Script / region | Encodings |
|---|---|
| Unicode | UTF-8, UTF-16 LE, UTF-16 BE |
| Cyrillic | Windows-1251, KOI8-R, KOI8-U, CP866, ISO-8859-5 |
| Western European | Windows-1252, ISO-8859-1, ISO-8859-15 |
| Central European | Windows-1250, ISO-8859-2 |
| Greek | Windows-1253, ISO-8859-7 |
| Turkish | Windows-1254, ISO-8859-9 |
| Chinese Simplified | GBK, GB18030 |
| Hebrew, Arabic, Baltic, Vietnamese, Thai | Windows-1255, 1256, 1257, 1258, 874 |

Common aliases are accepted (`cp1251`, `latin1`, `gb2312`, `tis-620`, …) —
[`list_encodings`](TOOLS.md#list_encodings) prints the whole table with aliases.

UTF-32 is partially supported: LE and BE BOMs are detected, and
[`manage_bom`](TOOLS.md#manage_bom) can add or strip them, but transcoding to or from
UTF-32 is not implemented and [`manage_line_endings`](TOOLS.md#manage_line_endings)
refuses UTF-32 files rather than corrupting their 4-byte alignment.

**Security:** All operations restricted to allowed directories only. Paths are resolved
before the check, so a symlink or Windows junction pointing outside an allowed directory
is rejected rather than followed.

> **Upgrading to 2.0.0?** `write_file` now defaults **new** files to `utf-8` instead of
> `cp1251`. Existing files keep their detected encoding and are unaffected. See the
> [CHANGELOG](CHANGELOG.md) for the migration path.

## Installation

### Claude Code plugin (recommended)

The simplest way to use this with Claude Code:

```
/plugin marketplace add dimitar-grigorov/mcp-file-tools
/plugin install mcp-file-tools
```

**Requires [Node.js](https://nodejs.org) 18+ on your PATH** — the launcher is a Node
script. Claude Code ships as a standalone binary and does not bundle Node, so
`node --version` can fail on an otherwise working install; the server then shows as
*not connected* in `/mcp`.

On first launch the plugin downloads the right binary for your OS, verifies its
SHA-256, caches it, and keeps it pinned to a known version. The server is
automatically scoped to the folder you have open (via the MCP roots protocol), so
there is nothing to configure.

The plugin only accesses your current workspace. Without Node, or to grant access to
directories outside the workspace, use a manual install (below).

**Already added the server the manual way?** Remove the old `claude mcp add` entry so
you are not running two copies:

```
claude mcp remove file-tools
```

### Updating the plugin

```
claude plugin marketplace update mcp-file-tools
claude plugin update mcp-file-tools@mcp-file-tools
```

Use the full `plugin@marketplace` id, not the bare name. Or enable auto-update in
`/plugin` → **Marketplaces**.

### MCP Registry

This server is listed in the [Official MCP Registry](https://registry.modelcontextprotocol.io/?search=mcp-file-tools) for discovery by any MCP client.

### Manual install (other MCP clients, or access outside your workspace)

Download the binary for your platform, then register it with the directories it may access.

| Platform | Release asset | Suggested path |
|----------|---------------|----------------|
| Windows x64 | `mcp-file-tools_windows_amd64.exe` | `%LOCALAPPDATA%\Programs\mcp-file-tools\mcp-file-tools.exe` |
| Linux x64 | `mcp-file-tools_linux_amd64` | `~/.local/bin/mcp-file-tools` |
| macOS ARM64 | `mcp-file-tools_darwin_arm64` | `~/.local/bin/mcp-file-tools` |

Windows (PowerShell, not CMD):

```powershell
mkdir -Force "$env:LOCALAPPDATA\Programs\mcp-file-tools"
iwr "https://github.com/dimitar-grigorov/mcp-file-tools/releases/latest/download/mcp-file-tools_windows_amd64.exe" -OutFile "$env:LOCALAPPDATA\Programs\mcp-file-tools\mcp-file-tools.exe"
claude mcp add --scope user file-tools -- "$env:LOCALAPPDATA\Programs\mcp-file-tools\mcp-file-tools.exe" "D:\Projects"
```

Linux / macOS (swap the asset name from the table for your platform):

```bash
mkdir -p ~/.local/bin
curl -L "https://github.com/dimitar-grigorov/mcp-file-tools/releases/latest/download/mcp-file-tools_linux_amd64" -o ~/.local/bin/mcp-file-tools
chmod +x ~/.local/bin/mcp-file-tools
claude mcp add --scope user file-tools -- ~/.local/bin/mcp-file-tools ~/Projects
```

### Go install (all platforms)

```bash
# Requires Go 1.26+
go install github.com/dimitar-grigorov/mcp-file-tools/cmd/mcp-file-tools@latest
# Linux / macOS
claude mcp add --scope user file-tools -- $(go env GOPATH)/bin/mcp-file-tools ~/Projects
```

```powershell
# Windows PowerShell
claude mcp add --scope user file-tools -- "$(go env GOPATH)\bin\mcp-file-tools.exe" "D:\Projects"
```

### Other Clients

For Claude Desktop, VSCode, or Cursor, use the downloaded binary path in your config:

**Claude Desktop** (`%APPDATA%\Claude\claude_desktop_config.json` on Windows, `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):

Windows:
```json
{
  "mcpServers": {
    "file-tools": {
      "command": "C:\\Users\\YOUR_NAME\\AppData\\Local\\Programs\\mcp-file-tools\\mcp-file-tools.exe",
      "args": ["D:\\Projects", "C:\\Users\\YOUR_NAME\\Documents"]
    }
  }
}
```

macOS / Linux:
```json
{
  "mcpServers": {
    "file-tools": {
      "command": "/Users/YOUR_NAME/.local/bin/mcp-file-tools",
      "args": ["/Users/YOUR_NAME/Projects", "/Users/YOUR_NAME/Documents"]
    }
  }
}
```

The `args` array specifies allowed directories the server can access. Add as many directories as you need.

**VSCode / Cursor (Claude Code extension)**

If you already ran `claude mcp add --scope user` from the installation steps above, the server is already available in VSCode — no extra config needed.

To configure separately for VSCode only:
```powershell
claude mcp add --scope user file-tools -- "%LOCALAPPDATA%\Programs\mcp-file-tools\mcp-file-tools.exe" "D:\Projects"
```

Alternatively, create a **per-project config** by adding `.mcp.json` to your project root:
```json
{
  "mcpServers": {
    "file-tools": {
      "type": "stdio",
      "command": "C:\\Users\\YOUR_NAME\\AppData\\Local\\Programs\\mcp-file-tools\\mcp-file-tools.exe",
      "args": ["D:\\Projects", "D:\\Other\\Directory"]
    }
  }
}
```

**Note:** The `type: "stdio"` field is required. The `args` array specifies allowed directories — the VSCode extension does not automatically add the workspace directory, so you must list all directories you want to access. To add more directories later, re-run the `claude mcp add` command with all directories listed (it overwrites the previous config).

### OpenAI Codex CLI

For this server, the Codex equivalent is a direct MCP command; no manual TOML editing
is needed.

Windows (PowerShell):
```powershell
mkdir -Force "$env:LOCALAPPDATA\Programs\mcp-file-tools"
iwr "https://github.com/dimitar-grigorov/mcp-file-tools/releases/latest/download/mcp-file-tools_windows_amd64.exe" -OutFile "$env:LOCALAPPDATA\Programs\mcp-file-tools\mcp-file-tools.exe"
codex mcp add file-tools -- "$env:LOCALAPPDATA\Programs\mcp-file-tools\mcp-file-tools.exe" "D:\Projects"
```

Run `codex mcp list` to verify it, then start a new Codex session. Add more directory
arguments to grant access outside the current project.

### Auto-approve tools (Claude Code)

To skip the permission prompts, add to `.claude/settings.local.json` in your project root:

```json
{ "permissions": { "allow": ["mcp__file-tools__*"] } }
```

The plugin install uses a different prefix, and keeping `delete_file` / `move_file` behind
a prompt takes one more rule — see [docs/extra.md](docs/extra.md#auto-approving-tools-in-claude-code).

### Update

The server checks for updates automatically and notifies you through tool responses when a
newer version is available; the notice carries the steps for your install. Plugin installs
update through [Updating the plugin](#updating-the-plugin) — a re-downloaded binary is
ignored there. For a manual install:

1. Close all Claude Code sessions (the binary is locked while running)
2. Re-download the binary:

```powershell
iwr "https://github.com/dimitar-grigorov/mcp-file-tools/releases/latest/download/mcp-file-tools_windows_amd64.exe" `
    -OutFile "$env:LOCALAPPDATA\Programs\mcp-file-tools\mcp-file-tools.exe"
```

To disable update checks, set the environment variable `MCP_NO_UPDATE_CHECK=1`.

### Verify & Uninstall

```bash
# Check which file-tools server is connected (plugin or manual)
claude mcp list

# Remove a manual install
claude mcp remove file-tools

# Remove the plugin
claude plugin uninstall mcp-file-tools
```

## How to Use

Once installed, just ask Claude:
- "List all .pas files in this directory"
- "Read config.ini and detect its encoding"
- "Show all supported encodings"
- "Read MainForm.dfm using CP1251 encoding"

**Security:** The server only accesses directories you explicitly allow:
- **Automatic:** Claude Desktop/Code provide workspace directories automatically
- **Manual:** Specify directories in config `args: ["/path/to/project"]`

## Configuration

The server can be configured via environment variables:

| Variable | Description | Default |
|----------|-------------|---------|
| `MCP_DEFAULT_ENCODING` | Default encoding for `write_file` on **new** files when none specified. Existing files keep their detected encoding. Set to `cp1251` to restore the pre-2.0.0 default. | `utf-8` |
| `MCP_DEFAULT_LINE_ENDINGS` | Line endings for `write_file` on **new** files (`crlf`/`lf`). Existing files keep their own style regardless. | unset (write unchanged) |
| `MCP_MEMORY_THRESHOLD` | Memory threshold in bytes. Files smaller are loaded into memory for faster I/O; larger files use streaming. Also affects encoding detection mode. | `67108864` (64MB) |

To override, set environment variables in your config (Claude Desktop example):
```json
{
  "mcpServers": {
    "file-tools": {
      "command": "C:\\Users\\YOUR_NAME\\AppData\\Local\\Programs\\mcp-file-tools\\mcp-file-tools.exe",
      "args": ["D:\\Projects"],
      "env": {
        "MCP_DEFAULT_ENCODING": "utf-8"
      }
    }
  }
}
```

### Legacy teams (pre-2.0.0 behaviour)

Before 2.0.0 new files defaulted to `cp1251`. Existing files are unaffected by the
change — their encoding is detected and preserved — so this only matters if your team
**creates** new non-UTF-8 files (e.g. new Delphi units with Cyrillic literals). To keep
the old behaviour everywhere, set it once per machine:

```json
"env": { "MCP_DEFAULT_ENCODING": "cp1251" }
```

Per-project instead of per-machine: commit an `.mcp.json` with that `env` block to the
legacy repo, so anyone working in it gets the right default without local setup.

## Use Cases

### Legacy Codebases

Many legacy projects use non-UTF-8 encodings that AI assistants can't handle natively:

- **Delphi/Pascal** (Windows-1251): Source files with Cyrillic UI text
- **Visual Basic 6** (Windows-1252): Forms and config files with Western European characters
- **Legacy PHP/HTML** (CP1251, ISO-8859-1): Web apps with localized content
- **Old config files** (Various): INI, properties, registry files with legacy encodings

**How it works:**
```
User: Read config.ini and change the title to "Настройки"
Assistant: [read_text_file with cp1251] → [modify UTF-8] → [write_file with cp1251]
```

The original encoding is preserved - files remain compatible with legacy tools.

## Development

**Prerequisites:** Go 1.26+

```bash
# Run tests
go test ./...

# Build
go build -o mcp-file-tools ./cmd/mcp-file-tools
```

`test_server.go` is an end-to-end smoke test over every tool, run by CI on each push:

```bash
go run test_server.go
```

### Debugging

[MCP Inspector](https://github.com/modelcontextprotocol/inspector) gives a web UI for calling tools and inspecting responses (needs Node.js 18+):

```bash
npx @modelcontextprotocol/inspector go run ./cmd/mcp-file-tools -- /path/to/allowed/dir
```

Or pipe JSON-RPC straight to stdin:

```bash
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | go run ./cmd/mcp-file-tools /path/to/project
```

## Contributing

**If it fits the scope and works, it gets merged.** Don't ask first — just send the PR.

- No CLA, no style review. `make test` and `make lint` passing is enough; tests are welcome, never required.
- One-line fixes and half-finished features behind a flag are both fine.
- Pushed back on (with a comment, not a close): out of scope, or breaking tool contracts other people's agents rely on.
- Don't want to write the fix? [Open an issue](https://github.com/dimitar-grigorov/mcp-file-tools/issues) with the file, its encoding, and what the tool did.

Details in [CONTRIBUTING.md](CONTRIBUTING.md).

## Forking

Forking is fine. That's what GPL-3.0 is for. Taking the project over is not.

**GPL-3.0 is a license, not a preference.** Distribute your fork in any form (public repo, release binary, registry listing, product you ship to customers) and you must:

- **Keep GPL-3.0** and [LICENSE](LICENSE), copyright notice intact (§4, §5c)
- **Say what you changed** and when, prominently (§5a)
- **Give the source** to everyone you gave the binary to (§6)

> [!WARNING]
> Deleting the license or the notice, relicensing as MIT or proprietary, or shipping
> only a binary is a **license violation**, and §8 ends your rights the moment you do it.

**It will be enforced,** in this order: a request to comply, then a DMCA takedown plus
delisting from whichever registry or marketplace carries it, then legal action as the
copyright holder. Complying costs one license file, one notice, one source link, so none
of this needs to happen. Unsure whether what you ship complies?
[Ask in an issue](https://github.com/dimitar-grigorov/mcp-file-tools/issues), that's a
normal question and a cheaper one.

**The rest is asked, not enforced:**

- **Leave the credit in.** `Copyright (C) 2026 Dimitar Grigorov` in `LICENSE` and the source headers is the legal minimum. One line near the top of your README, *"Fork of [dimitar-grigorov/mcp-file-tools](https://github.com/dimitar-grigorov/mcp-file-tools)"*, is what actually tells a reader where this came from, and costs you nothing.
- **Give your fork its own name.** A rebranded fork in a public registry (MCP Registry, plugin marketplaces, Smithery) under this product name with the author swapped reads as if the original project moved. People install it believing it's this one, then file its bugs here.
- **Try upstream first.** A PR beats carrying merge conflicts forever, and puts your name on the commit rather than in a credits list. Maintaining a long-running fork? Open an issue about upstreaming the parts that fit.

## Credits

Ideas that started in someone else's fork and were reimplemented here:

- [@skyispainted](https://github.com/skyispainted) - GBK/GB18030, JSON-string array args, `edit_file` retry hint
- [@haobiao](https://github.com/haobiao) - GBK/GB18030, independently
- [Hugo Rosário](https://github.com/WTC-ZoneSoft) - merging MCP roots with CLI allowed dirs
- [@zoster81](https://github.com/zoster81) - UTF-16 line endings and grep, path containment fixes, write durability, BOM policy, ordered concurrency

A PR gets your name on the commit instead of this list.

## License

GPL-3.0 - see [LICENSE](LICENSE)

Copyright (C) 2026 Dimitar Grigorov. Free software, distributed WITHOUT ANY WARRANTY.

