Filesystem Go Ultra
FreeNot checkedHigh-performance MCP filesystem server in Go — 17 tools, pipeline system, audit logging, dashboard, WSL support. For Claude Desktop and Claude Code.
About
High-performance MCP filesystem server in Go — 17 tools, pipeline system, audit logging, dashboard, WSL support. For Claude Desktop and Claude Code.
README
v4.8.0 · Go 1.27.2 · MCP 2025-11-25 · stdio · 34 tools ultra / 19 agent / 18 strict
A Model Context Protocol filesystem server written in Go, designed for safe file editing by AI agents: automatic backups with step-through undo, optimistic concurrency to detect external file changes, an accidental-rewrite guard, strict path security, and risk assessment on every mutation. Built for Claude Desktop, Claude Code, and OpenCode, with support for large files, WSL/Windows interoperability, and token-efficient responses.
Legacy aliases (read_text_file, View, Edit, etc.) and the fs super-tool are disabled. Default --profile=ultra registers all 34 tools; --profile=agent is the 18-tool core plus git; --profile=strict registers the 18-tool core (includes backup for undo and security_policy; no analyze_code, no git, no context_pack, no github_issues, no gitlab_issues).
Transport is stdio only, using the MCP 2025-11-25 lifecycle (initialize, with optional client Roots). Protocol revision 2026-07-28 is not yet qualified for this application. The SDK has modern protocol primitives, but upgrading it alone does not establish application compatibility. CLI allowlists (--allowed-paths or positional directories) remain the recommended deployment configuration and work without client Roots. Dual-era stdio support requires separate lifecycle, error-code and message-limit tests before it can be advertised; HTTP transport is a separate concern.
Compared with the reference server
Against @modelcontextprotocol/server-filesystem. The reference column is its README plus open issue 3174. This column is what this tree does, not a promise about untested Windows edge cases.
| Reference server | filesystem-ultra | |
|---|---|---|
| Windows roots | Client roots replace the CLI list. file:///c%3A/temp is skipped as invalid (issue 3174, open). |
file:///c%3A/temp becomes c:\temp. file://server/share/dir becomes \\server\share\dir. --roots-mode=union keeps the CLI list and adds client roots. Reserved device names (CON, NUL, …) and NTFS ADS (file.txt:stream) are rejected. 8.3 short names are not expanded to their long form: the caller's own path segments are preserved and matched case-insensitively against the root base. |
| Search | search_files is a glob on names, not file contents. |
Content by default. Filename globs (*.go, Reports.*) stay names-only; a regex such as preview.*range searches content. Explicit include_content:false searches names. include and file_types intersect in all modes before pagination; invalid globs return VALIDATION. |
| Undo | No backup or undo tool. | backup(action:"undo_last") walks the chain. |
| Dry-run / diff | edit_file has dryRun and returns a diff. |
dry_run on edit and patch. Also diff_files and apply_patch. |
Claude Desktop extension (.mcpb)
scripts/pack-mcpb.ps1 builds a Windows bundle into dist/ (gitignored). Double-click the .mcpb in Claude Desktop. The install dialog asks for allowed directories; the server exits if none are set. The bundle is win32 only and starts with --profile=strict --compact-mode --roots-mode=union. Sending it to the extension directory is a manual step.
Quick start
Minimum configuration is the allowed paths. Every other flag still works and wins when you set it, but it is optional.
# Build
go build -ldflags="-s -w" -trimpath -o filesystem-ultra ./cmd/filesystem-ultra
# Configuration 0 — paths only
./filesystem-ultra C:\mi\proyecto
# or a paths file (one path per line; # comments and blank lines ignored)
./filesystem-ultra --allowed-paths-file=.mcp-paths
# or .env in the working directory (loaded only if the file exists)
# MCP_ALLOWED_PATHS=C:\proyecto,C:\otros
# MCP_PROFILE=strict
./filesystem-ultra
# Tests
go test ./core/ ./internal/mcpserver/ -count=1
--preset=minimal is the short form of --profile=strict --compact-mode --roots-mode=union when those flags are not set. See Configuration.
Features
Safety and correctness
- Automatic backups with step-through undo — every mutation is recoverable:
backup(action:"undo_last")walks the chain;restorereturns a file to its pre-edit bytes - Optimistic concurrency (OCC) —
content_hash/expected_hashchaining detects external file changes between read and edit;--auto-occwarns or blocks on stale edits. Mismatch returns a conflict report (changed_ranges, hashes); a bounded diff only ifinclude_diff:trueordetail:"full" - Accidental-rewrite guard (v4.5.10) — blocks
edit_filecalls that look like unintended full-file rewrites - Path security — symlink-resolved containment via
filepath.Rel, NTFS ADS blocking, RTLO/zero-width Unicode rejection, Windows reserved names, TOCTOU symlink defense - Risk assessment — mutations above configurable thresholds are flagged (20% change = MEDIUM, 75% = HIGH by default); HIGH/CRITICAL results include post-edit integrity verification. Path floors raise risk for
go.mod/go.sum, Dockerfiles, GitHub workflows, and*.csproj(never lower it; test files and docs do not raise it, andcmd//internal/package code raises to MEDIUM) - Failure Intelligence — errors are a JSON envelope with
code,retryable,suggestion, and typeddetails. Do not replay whenretryableis false (PATCH_FAILED,BUDGET_EXCEEDED,VALIDATION, …) - Unambiguous multi_edit rollback — every counted failure (including
ambiguous) appears in the diagnosis; the file is not written - Search pagination —
max_resultsis the page size;offsetcontinues. No hidden 10/20 presentation cap. Structuredcontinuationsays how to continue - Git destinations —
git(action:"remote")without--git-network; push/fetch print the effective URL (credentials redacted).--git-remote-allowis optional. Omit it: any configured remote is allowed. Set it only to extra-lock hosts (e.g.github.com,gitlab.com).force:truedoes not bypass. - Verifiable stats —
server_info(action:"stats")splits MCP calls vs internal ops, applied/rejected/simulated mutations, and process vs historical backups; ops/s is an interval delta; latency is avg/p50/p95 - Mutation budget —
--mutation-budget=N(default off) caps applied mutations per process; dry-run does not count - Explicit
detail—summary|normal|fullondirectory_tree,search_files,read_file(batch), andhelp(catalog). Defaultnormal. Compact-mode trims text;detailtrims structuredContent - Access control — fail-closed: at least one allowed path is required (positional,
--allowed-paths,.mcp-paths/--allowed-paths-file, orMCP_ALLOWED_PATHS). Also enforced in batch operations.--insecure-openis labs-only. - Plan mode — dry-run analysis with diff preview and risk report before applying changes
- Structured output —
outputSchema+structuredContenton read/write/edit/multi_edit plussearch_files,list_directory,batch_operations, andbackup. Status (applied/simulated/empty/partial), truncation, and hashes are machine-readable. Errors use a JSON envelope withretryable(do not auto-retry when false). Text fallbacks stay byte-identical. Handler-level sweep in CI. - Native tool inputs — arrays/objects for
paths,edits,patterns,request/pipeline/rename; legacy*_jsonstrings stay as adapters. Conflicting dual forms and invalid enums are rejected - Optional strict match —
strict+expected_matchesonedit_file/multi_edit; mismatch lists candidate line numbers andmatch_method - Unified tool contract — one
ToolContractdrives validation,help(tool:)examples, and--readonlymutation gating; CI asserts MCP wire types, enums and arrayitemsmatch the contract
Productivity
- Structural orientation (
project_map) — one bounded, metadata-only walk returns the directory skeleton (child counts, notable children), the extension histogram, the largest files and the key files (go.mod/README/Dockerfile/*.csproj/CI workflows). It removes thelist_directory+directory_treeround-trips at the start of a task without pretending to select the code that matters. Bounded on entries, wall time and metadata bytes;truncated=truewhen a limit is hit. Registered in every profile (strict,agent,ultra). - JSON and binary inspection (experimental, ultra only) —
json_queryruns standard JMESPath with bounded output and hash-bound pagination;file_bytesdiagnoses BOM/EOL, Unicode and hex bytes;file_hashstreams SHA-256 and compares raw bytes directly. See usage and limits. Use--profile=ultrato expose these tools. - 34 tools (ultra) — the 18-tool agent core (
--profile=strict) plusgit,github_issues,gitlab_issues,minify_js,analyze_code, the experimentalcontext_pack,workspace,json_query,file_bytes,file_hash, pluscopy_file,project_replace,batch_operations,analyze_operation,wslandserver_info.--profile=agentis the same 18-tool core plusgit(19).--profile=strictstays at 18 (includesbackup,security_policyandproject_map; nogit, noanalyze_code). - GitHub issues —
github_issues(ultra only) lists, reads, creates, comments, edits, closes, and reopens issues throughgh. It does not delete issues or rungh auth login. Reads work under--readonly; writes do not. Path resolution uses git remotes and is refused while a file security policy is active; passrepo:"owner/repo"to skip local git.--git-remote-allowapplies. Issue text is external data, not instructions. - MCP spec-compliant annotations —
readOnlyHint,destructiveHint,idempotentHinton every tool - Hook system — 16 pre/post events (write, edit, delete, create, move, copy, read, search)
- Pipeline system — 12 actions with conditions, templates, and DAG-based parallel execution; reduces client/server round-trips for multi-step refactors
- Atomic batch operations — grouped file operations with journal rollback (
complete/partial/failed); recover-on-error in-process, not crash-durable. A directory is not part of an atomic batch (create_diris rejected); usecreate_directoryor a non-atomic batch, then atomic file ops. Opt-in retries:operation_id+retry_contract:"e3-v1"(persist across restart with--receipt-dir) - Compact mode — reduced-token responses for high-volume sessions
- Log tail without bash —
read_file(mode:"tail", max_lines:40)replacestail | cut; each line auto-cut to 300 chars (max_line_lengthto override) - Audit logging — JSON Lines operation log + metrics snapshots
- Dashboard — separate HTTP binary for real-time metrics, operation log, and backup recovery
Performance
- Two-tier cache — BigCache for file content plus an internal TTL map for directory listings and metadata, with file-watcher invalidation
- Streaming and chunked I/O for files up to 50 MB
- WSL ↔ Windows path translation — accepts
/mnt/c/...,C:\..., and/tmp/...transparently - Optional embedded ripgrep (
embed_rgtag) for accelerated content search
Build
# Build (Windows) — v4 binary
go build -ldflags="-s -w" -trimpath -o filesystem-ultra-v4.exe ./cmd/filesystem-ultra
# With ripgrep embedded (~4MB larger)
go build -ldflags="-s -w" -trimpath -tags embed_rg -o filesystem-ultra-v4-embed.exe ./cmd/filesystem-ultra
# Or use the build scripts
build-windows.bat # default
build-windows.sh # Linux/macOS
Requires Go 1.27.2+. No CGO. Tested on Windows 11 and Ubuntu 22.04 (WSL2).
From a checkout, install the executable package, not the module root (the root has no main):
go install ./cmd/filesystem-ultra
The module path is github.com/mcp/filesystem-ultra. It does not match the GitHub import path, so go install github.com/scopweb/mcp-filesystem-go-ultra@latest does not work. Renaming the module, including a /v4 path, is a separate release decision and is not done here.
# Run tests
go test ./tests/... ./core/... ./internal/mcpserver/
# With race detector
go test -race ./...
# Security fuzzing
go test -fuzz=Fuzz ./tests/security
Configuration
Configuration 0
The server starts with allowed paths and nothing else. Sources are unioned (duplicates dropped; the first spelling wins). Scalar settings do not work that way: an explicit flag wins, then --preset, then the process environment, then .env, then the flag default.
| Source | Notes |
|---|---|
Positional args and --allowed-paths |
Never ignored. Both are kept. --allowed-paths is comma-separated. |
--allowed-paths-file or .mcp-paths |
One path per line. # comments and blank lines are ignored. Relative paths resolve against the process cwd. Auto-detects .mcp-paths only when the flag is omitted. A missing or unreadable file exits 2. |
MCP_ALLOWED_PATHS |
Environment or .env. Separated by comma or ;. |
| None of the above | Fail-closed (exit 2), unless --insecure-open. |
.env is loaded from the cwd when it exists. A missing default .env is not an error. Only MCP_* keys are read (MCP_ALLOWED_PATHS, MCP_PROFILE, MCP_ROOTS_MODE, MCP_COMPACT_MODE, MCP_READONLY, MCP_AUTO_OCC, MCP_LOG_LEVEL, MCP_BACKUP_DIR). Values are not expanded.
./filesystem-ultra --preset=minimal C:\mi\proyecto
Advanced configuration
Recommended flags for Claude Code / OpenCode
Keep this trio in the MCP args (and leave --readonly off so the agent can write):
--profile=strict --compact-mode --roots-mode=union
| Flag | Why |
|---|---|
--profile=strict |
Registers the 18-tool agent core (list_allowed_directories, project_map, directory_tree, read_file / write_file / edit_file / apply_patch, backup for undo, security_policy, …). Omits git, wsl, minify_js, analyze_code, batch_operations, copy_file, server_info, … so tools/list stays small. --profile=agent is that core plus git. Default is ultra (34 tools) so existing configs do not break. |
--compact-mode |
Short token-efficient responses (hashes, UNDO ids, no emoji walls). |
--response-mode=structured |
Opt-in. Brief text fallback; file bodies stay once in structuredContent. Default compat keeps the full text fallback. |
--roots-mode=union |
Default. MCP client Roots are added to the CLI allowlist. replace wipes the CLI list when the client sends Roots (OpenCode and Claude do). |
Do not pass --git-network unless the agent must git push / git fetch. Do not pass --readonly unless the session should be read-only.
Add to your claude_desktop_config.json:
{
"mcpServers": {
"filesystem": {
"command": "C:\\path\\to\\filesystem-ultra-v4.exe",
"args": [
"--profile", "strict",
"--compact-mode",
"--cache-size", "200MB",
"--parallel-ops", "8",
"--log-level", "error",
"--log-dir", "C:\\logs\\mcp-filesystem",
"--roots-mode", "union",
"C:\\your\\project\\"
]
}
}
}
Linux:
{
"mcpServers": {
"filesystem-ultra": {
"command": "/path/to/filesystem-ultra",
"args": [
"--profile", "strict",
"--compact-mode",
"--cache-size", "200MB",
"--parallel-ops", "8",
"--log-level", "error",
"--log-dir", "/home/user/.local/share/mcp-filesystem/logs",
"--roots-mode", "union",
"/home/user/projects/"
]
}
}
}
OpenCode
OpenCode does not read claude_desktop_config.json. Put this in the project opencode.json / opencode.jsonc, or globally in ~/.config/opencode/opencode.json (Windows: %USERPROFILE%\.config\opencode\opencode.json).
Differences vs Claude: key is mcp (not mcpServers), type is required, command is one array (binary + flags + paths), and timeout defaults to 5s — too short for tools/list. Set 30000. Recommended: --profile=strict --compact-mode --roots-mode=union (--readonly off).
Windows (opencode.json):
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"filesystem-ultra": {
"type": "local",
"command": [
"C:\\path\\to\\filesystem-ultra-v4.exe",
"--profile", "strict",
"--compact-mode",
"--cache-size", "200MB",
"--parallel-ops", "8",
"--log-level", "error",
"--log-dir", "C:\\logs\\mcp-filesystem",
"--roots-mode", "union",
"C:\\your\\project\\"
],
"enabled": true,
"timeout": 30000
}
}
}
Linux:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"filesystem-ultra": {
"type": "local",
"command": [
"/path/to/filesystem-ultra",
"--profile", "strict",
"--compact-mode",
"--cache-size", "200MB",
"--parallel-ops", "8",
"--log-level", "error",
"--log-dir", "/home/user/.local/share/mcp-filesystem/logs",
"--roots-mode", "union",
"/home/user/projects/"
],
"enabled": true,
"timeout": 30000
}
}
}
Quit and restart OpenCode after saving.
--roots-mode. Default is union: client Roots are added to the CLI list. replace keeps only the client list, so OpenCode or Claude will hide every other path. ignore keeps the CLI list only.
| Mode | Effect |
|---|---|
replace (default) |
Client Roots replace the CLI list. OpenCode → only the workspace. |
union |
CLI paths plus the workspace. Use this when the allowlist must survive. |
ignore |
CLI list only; client Roots are ignored. |
Allowed paths: positional args, or one --allowed-paths (comma-separated; do not repeat the flag — Go flag.String keeps the last value only), or --allowed-paths-file / .mcp-paths, or MCP_ALLOWED_PATHS. Those sources are unioned. At least one path is required since v4.6.0 (fail-closed, exit 2). Labs only: --insecure-open disables the sandbox (entire disk).
Key flags
| Flag | Default | Description |
|---|---|---|
--allowed-paths |
(required unless another path source is set) | Comma-separated allowed roots. Unioned with positional args, the paths file, and MCP_ALLOWED_PATHS |
--allowed-paths-file |
.mcp-paths if that file exists |
One root per line. Missing or unreadable exits 2 |
--env-file |
.env if that file exists |
MCP_* settings. Missing default is not an error; an explicit missing file exits 2 |
--preset |
(none) | minimal, agent, or full. Does not override flags you set explicitly |
--insecure-open |
off | Labs only: disable the sandbox (entire disk). Fail-closed by default since v4.6.0. |
--roots-mode |
union | How MCP client Roots combine with CLI paths: union (default, CLI plus client), replace (client list only), ignore (keep CLI). An empty Roots result does not open the disk. There is no intersect mode. |
--profile |
ultra | ultra = all 34 tools; agent = 19 (strict + git); strict = 18-tool core (includes backup and security_policy) |
--file-security-config |
empty | JSON policy layered on allowed-paths. Invalid file exits 2. Immutable until restart. See below. |
--git-network |
off | Enable git push/fetch. Off the critical path; ignored in strict |
--git-remote-allow |
empty (any destination) | Optional extra lock on push/fetch. See below. |
--readonly |
off | Reject mutating tools |
--mutation-budget |
0 (off) | Max applied mutations per process. Shared by all stdio clients. BUDGET_EXCEEDED when exceeded |
--allow-secrets |
off | Allow .env / keys (audited) |
--compact-mode |
off | Reduced-token responses |
--cache-size |
100MB | In-memory file cache limit |
--cache-ttl |
3m | File content cache life (Go duration). Retention only; freshness is size/mtime. Does not change directory-listing TTL. Get does not refresh BigCache life. |
--parallel-ops |
2×CPU (max 16) | Max concurrent operations |
--backup-dir |
system temp | Directory for automatic backups |
--backup-max-age |
7 | Maximum backup retention, in days |
--backup-max-count |
100 | Maximum number of backups to keep |
--risk-threshold-medium |
20 | % change flagged as medium risk |
--risk-threshold-high |
75 | % change flagged as high risk |
--hooks-enabled |
off | Enable pre/post operation hooks |
--hooks-config |
— | Path to hooks configuration JSON |
--log-dir |
— | Directory for audit logs and metrics (enables logging) |
--log-level |
info | Log level: debug, info, warn, error |
--debug |
off | Verbose debug logging |
File security policy
--file-security-config adds an owner-controlled layer on top of allowed-paths. Without the flag, behavior is unchanged. The file is loaded at startup and is immutable until the process restarts. A missing, malformed, or invalid file exits 2. The server does not continue without the policy.
{
"version": 1,
"rules": [
{ "pattern": ".env", "level": "hidden" },
{ "pattern": ".env.*", "level": "hidden" },
{ "pattern": "*.ini", "level": "protected" },
{ "pattern": "settings.json", "level": "read_only" },
{ "pattern": "**/secrets/**", "level": "hidden" }
]
}
filesystem-ultra.exe --allowed-paths C:\proj --file-security-config C:\proj\policy.json
| Level | List name | Read content | Mutate | Copy out |
|---|---|---|---|---|
normal |
yes | yes | yes | yes |
read_only |
yes | yes | no | yes |
protected |
name, type, level only | no | no | no |
hidden |
no | no (looks missing) | no | no |
The most restrictive matching rule wins (normal < read_only < protected < hidden). A directory rule is inherited by descendants; a child rule cannot weaken it. Patterns without / match the name at any depth. Patterns with separators are relative to each effective sandbox root (*, ?, **). \ is a separator. Absolute paths, .., $, ~, and character classes are rejected. Case follows the platform (\ means case-insensitive). --insecure-open plus a separator pattern is rejected.
security_policy is read-only and does not list patterns or paths. force, allow_rewrite, and dry_run do not bypass the policy. While a policy is active, git is unavailable, WSL sync and auto-sync are disabled, and .git trees are not readable through these tools (objects can hold historical bytes). The dashboard is a separate process: pass the same --file-security-config and --allowed-paths or it can still serve backup bytes.
This policy controls tools and processes that implement it. It is not an OS sandbox. Another shell, MCP, or program with filesystem permission can still read the files. Hard links, concurrent external changes, and OS case-sensitivity differences are not fully closed.
Git network (--git-network / --git-remote-allow)
--git-network (default off) is what enables push/fetch. git(action:"remote") works without it and prints the effective URL (credentials redacted). Push/fetch also print that URL — that is the default safety.
--git-remote-allow is optional. Do not set it unless you want an extra host lock.
| You pass | Push/fetch may go to |
|---|---|
| nothing (default) | Whatever origin (or pushurl) is. No extra check. |
github.com,gitlab.com |
Those two hosts only (typical GitHub + GitLab setup) |
github.com/scopweb |
Repos under that org/user only |
| a full repo URL | That repository only |
The name origin is never enough to authorize: the effective URL is matched (pushurl, insteadOf, multiple push URLs). force:true does not bypass. git(action:"remote") still works without --git-network.
Omit the flag if seeing the URL is enough.
Tool Discovery
Do not dump the full catalog at startup. Handshake instructions are short. First call list_allowed_directories, then project_map / directory_tree or help(tool:"X").
| Step | Call | When |
|---|---|---|
| 1 | list_allowed_directories |
Before the first read |
| 2 | project_map |
Cheap structural orientation of a project (metadata only) |
| 3 | directory_tree or help(tool:"X") |
Explore a tree, or look up one tool on demand |
| 4 | help() |
Only if you need the live registered list |
--profile=strict shrinks tools/list to the 18-tool agent core so lazy-loading clients see the useful set.
Using the skill
The skill ships in .claude/skills/filesystem-ultra-tools/. Same order: list_allowed_directories first, then project_map / directory_tree / help(tool:X).
Host filesystem vs runtime sandbox
filesystem-ultra:* tools operate on the host filesystem visible to the MCP server. A client may also expose native tools such as create_file, str_replace, or view; those can run in a separate sandbox even when passed a Windows-looking path.
For a host project, bind the whole task to the filesystem-ultra family. After every creation or edit, verify independently with get_file_info or list_directory, and use read_file when content matters. If a known file reports File not found, stop and audit recent operations made through the failing tool family before retrying or switching tools.
Subagentes y arneses
Copy examples/harness/ — do not guess flags. One MCP instance per workspace: --profile=strict --roots-mode=union --compact-mode. OpenCode timeout ≥ 30000. One role = one disk family (never mix native Read/Edit with ultra). Codex *** Begin Patch is not ultra apply_patch. Parent→child handoff: roots, path, content_hash, backup_id, profile; the child re-reads.
Available Tools
34 in --profile=ultra (default). --profile=agent is the 18-tool core plus git. --profile=strict is those 18, marked strict. server_info is not read-only: artifact/write can overwrite a file.
| Tool | Purpose | When to use |
|---|---|---|
list_allowed_directories |
Sandbox roots. Zero parameters. strict | Before the first read |
project_map |
Cheap structural orientation: skeleton with child counts, extension histogram, largest files, key files. Metadata only. Bounded (entries, time, metadata bytes). strict | Orient yourself in an unknown project without listing every file |
directory_tree |
Compact recursive tree. respect_ignore=true, max_depth=2, max_nodes=500. strict |
After roots, to explore. truncated + hidden_count in structured output |
diff_files |
Unified diff of two paths, or against:"backup". strict |
Preview before apply_patch or to compare two files |
apply_patch |
Unified diff. One file or in-process multi-file transaction. dry_run + expected_hash (single-file). Dest EOL wins. strict |
Surgical edit. If PATCH_FAILED: read_file and regenerate; do not retry the same patch |
read_file |
Full / range / head / tail / base64 / paths[]. Replaces bash cat/head/tail/cut. strict |
If a client asks for read_multiple_files or read_text_file, use this |
write_file |
Create or overwrite. mode:"append" skips rewrite-guard. strict |
New files or whole-file rewrite |
edit_file |
Exact / regex / range / insert. Backup + OCC. strict | Targeted edits (allow_rewrite not force for rewrite-guard) |
multi_edit |
Multiple replacements on one file. strict | Several anchors in the same file |
list_directory |
Directory listing. strict | Copy exact paths (case) before edits |
search_files |
Name or content. Gitignore ON. Default text is grouped path + line:text (context included). output_format:"text" is the legacy layout. strict |
Find, then edit. truncated + hidden_count + continuation |
get_file_info |
Size, dates, type. Batch paths[]. strict |
Verify after a host mutation |
create_directory |
mkdir -p. strict |
New folders |
move_file |
Move or rename. strict | Relocate |
delete_file |
Soft-delete default, files and directories; permanent:true hard. strict |
Remove |
help |
Live catalog; help(tool:"X") schema + examples. strict |
On demand — not at startup |
copy_file |
Recursive copy | ultra |
project_replace |
Token rename across a tree, or paths for an explicit list. preview:true dry-runs |
ultra |
batch_operations |
Atomic ops / pipelines / rename | ultra |
backup |
Undo / restore / trash. strict | After a bad edit: undo_last / restore / restore_trash |
analyze_operation |
Dry-run risk preview | ultra |
wsl |
WSL ↔ Windows sync | ultra |
git |
Local git. add + update:true is git add -u. remote is read-only (no --git-network). push/fetch need --git-network |
ultra |
minify_js |
Pure-Go JS minify (no Node) | ultra |
analyze_code |
Read-only symbols / lint / sec / impact. Symbols: Go AST; JS/TS/C#/SQL regex. Not a writer. | ultra — understand code; edit with apply_patch/edit_file. Do not use git grep or bash |
server_info |
Stats / static help / artifacts. Not read-only: artifact/write can overwrite a file |
ultra |
security_policy |
Read-only description of the file protection policy. Does not list rules | strict |
github_issues |
GitHub issues via gh. No delete, no gh auth login |
ultra |
gitlab_issues |
GitLab issues via its HTTP API. No delete | ultra |
context_pack |
Definition-centred task context: ranked files, exact line ranges, bounded snippets, explicit omissions. Experimental. doc | ultra |
workspace |
Experimental real git worktree for agent edits: begin/status/diff/export/discard | ultra |
json_query |
Standard JMESPath over JSON with bounded output and hash-bound pagination. Experimental. doc | ultra |
file_bytes |
BOM/EOL, Unicode and hex diagnostics. Experimental. doc | ultra |
file_hash |
Streaming SHA-256 of original bytes, with byte comparison. Experimental. doc | ultra |
Dashboard
Separate binary for real-time observability — reads audit logs and serves a web UI.
# Build
go build -ldflags="-s -w" -trimpath -o dashboard.exe ./cmd/dashboard/
# Run
dashboard.exe --log-dir=C:\logs\mcp-filesystem --backup-dir=C:\backups --port=9100
- No coupling with the MCP server (file-based communication only)
- Embedded web assets via
go:embed(single binary, no dependencies) - Real-time updates via SSE (Server-Sent Events)
- Pages: Dashboard (metrics), Operations (audit log), Backups (search and recovery), Statistics, Proxy/Tokens, Edit Analysis
MCP Proxy
Transparent stdio proxy that logs every tool call with timing and token estimates. Sits between Claude Desktop and the MCP server.
# Build
go build -ldflags="-s -w" -trimpath -o mcp-proxy.exe ./cmd/proxy/
# Claude Desktop config — wrap the MCP server with the proxy
# "command": "mcp-proxy.exe",
# "args": ["--model", "sonnet-4", "--log-dir", "C:\\logs\\mcp-proxy", "--", "filesystem-ultra-v4.exe", ...]
Point the dashboard at the proxy logs to see the Proxy / Tokens page:
dashboard.exe --log-dir=C:\logs\mcp-filesystem --proxy-log-dir=C:\logs\mcp-proxy --port=9100
The dashboard has no authentication. It binds 127.0.0.1 by default and only accepts loopback Host headers. Pass --file-security-config and --allowed-paths (the same values as the server) or it can still serve backup bytes that the server's policy hides.
Audit Logging
When --log-dir is set on the MCP server, it writes:
operations.jsonl— JSON Lines audit log (one entry per tool call, auto-rotates at 10MB)metrics.json— Performance metrics snapshot (updated every 30 seconds)
Architecture
cmd/
filesystem-ultra/
main.go Process entry point — calls mcpserver.Run()
proxy/
main.go Stdio proxy — logs tool calls, timing, token estimates
dashboard/
main.go HTTP dashboard for logs/metrics/backups
static/ Embedded web UI (go:embed)
internal/mcpserver/ MCP server: config, tool registration, stdio loop
(tests live here too, next to the code they drive)
run.go Run() — config, CLI flags, server startup
audit.go auditWrap — request normalization + audit logging
format.go Response formatters, parseSize, truncateContent, formatSize
help_content.go getHelpContent() — static help text for all topics
tools_core.go read_file, write_file, edit_file (the 3 core mutators)
tools_search.go list_directory, directory_tree, search_files, analyze_operation
tools_files.go create_directory, delete_file, move_file, copy_file, get_file_info
tools_batch.go multi_edit, batch_operations, backup, project_replace
tools_platform.go wsl, server_info
tools_discovery.go list_allowed_directories
tools_patch.go diff_files, apply_patch
tools_git.go git (12 local actions; push/fetch/pull need --git-network; remote is local)
tools_minify.go minify_js (pure-Go)
tools_aliases.go help (on-demand; legacy aliases disabled)
tools_analyze.go analyze_code (ultra only: symbols|lint|sec|impact)
tools_project_map.go project_map (metadata-only structural orientation)
tools_context.go context_pack (experimental)
tools_workspace.go workspace (experimental git worktree)
tools_inspect.go json_query, file_bytes, file_hash (experimental)
tools_github_issues.go github_issues (ultra only)
tools_gitlab_issues.go gitlab_issues (ultra only)
tools_security.go security_policy (read-only description of the file policy)
tools_diff.go diff_files
output_schemas.go outputSchema definitions for the structured tools
experimental.go experimental feature registry (one release cycle)
profile.go strict / agent / ultra catalog definition
core/
engine.go UltraFastEngine — central struct, cache, worker pool, metrics
edit_operations.go EditFile, MultiEdit — backup, risk assessment, hooks
file_operations.go Rename, SoftDelete, Copy, Move
streaming_operations.go StreamingWrite, ChunkedRead, SmartEdit
search_operations.go SmartSearch, AdvancedTextSearch
backup_manager.go Create, restore, compare, and clean backups
impact_analyzer.go Risk assessment (LOW / MEDIUM / HIGH / CRITICAL)
edit_safety_layer.go Context validation, stale-edit prevention
hooks.go Pre/post hook system (16 event types)
large_file_processor.go Line-by-line and chunk-based processing
regex_transformer.go Regex transformations with capture groups
pipeline.go Multi-step pipeline execution (sequential + parallel)
pipeline_types.go Pipeline types, validation
pipeline_conditions.go 9 condition types for conditional steps
pipeline_templates.go {{step_id.field}} template resolution
pipeline_scheduler.go DAG builder, topological sort, destructive step splitting
batch_operations.go Atomic batch operations with rollback
batch_rename.go Batch file renaming
audit_logger.go JSON Lines operation log + MetricsSnapshot writer
claude_optimizer.go Claude Desktop auto-optimization (small/large file strategy)
plan_mode.go Dry-run analysis (analyze_write, analyze_edit, analyze_delete)
path_converter.go WSL ↔ Windows path conversion
path_detector.go Path format detection and WSL distro lookup
path_security.go Path rejection rules (ADS, reserved names, control chars)
path_risk.go Path-aware risk floors
canonical.go Symlink-resolving canonical path for locking and OCC
secrets.go Secret-filename denylist
file_policy.go File security policy (levels and patterns)
file_policy_engine.go Policy enforcement across tools
osroot.go os.Root containment (per-root sandboxed I/O)
project_map.go Structural orientation (metadata only)
tool_contract.go ToolContract: schemas, enums, examples, mutation gating
mutation_budget.go Per-process applied-mutation budget
operation_retry.go e3-v1 retry receipts
wsl_sync.go WSL/Windows file synchronization
autosync_config.go Auto-sync configuration system
watcher.go File watcher for cache invalidation
mmap.go Memory-mapped file I/O (Windows fallback)
config.go Thresholds and constants
errors.go PathError, ValidationError, EditError, PipelineStepError, etc.
cache/
intelligent.go BigCache (files) + internal TTL map (dirs + metadata)
tests/ Black-box suite over the exported core API
mcp_functions_test.go Core MCP function tests
bug5_test.go–bug9_test.go Regression tests
edit_safety_test.go Edit safety validation tests
security/ Security & fuzzing tests
File size thresholds
| Class | Size | Strategy |
|---|---|---|
| Small | < 100 KB | Direct I/O |
| Medium | < 500 KB | Streaming |
| Large | < 5 MB | Chunking |
| Very large | < 50 MB | Special handling |
| Over limit | ≥ 50 MB | Edit rejected |
Security
IsPathAllowed()resolves symlinks viafilepath.EvalSymlinks()before the containment check — prevents symlink escape from allowed paths- Secret files denied by default — base name only, case-insensitive:
.envand.env.*,credentials.json,.npmrc,.pypirc,id_rsa*,id_ed25519*,id_ecdsa*, and the extensions.pem,.key,.p12,.pfx. Opt in with--allow-secrets(audited) - Search regex is Go RE2 —
search_filescompiles withregexp. Nested quantifiers stay linear; backreferences are rejected - Writes are temp + rename — crash-safe replace on every platform. NTFS file id, birthtime, and hardlinks are not preserved (same tradeoff the reference server kept on Windows)
- Allowed-path root protection (v4.2.1) —
delete_file,soft_delete, andmove_filereject the--allowed-pathsroot itself, preventingos.RemoveAll()from wiping an entire tree - Strict parameter validation — unknown params rejected, types enforced (
core/param_validator.go) - Temp files and backup IDs use
crypto/rand(not timestamps) - Backup IDs are sanitized to
[a-zA-Z0-9_-]to prevent path traversal - Temp files and backup metadata written with
0600permissions copyDirectory()skips symlinks- No
unsafepackage usage in the server (core/,internal/mcpserver/,cache/). The Windows-only proxy and the benchmark clock useunsafefor job objects andQueryPerformanceCounter
Dependencies
| Package | Version | Purpose |
|---|---|---|
github.com/mark3labs/mcp-go |
v1.3.0 | MCP server SDK |
github.com/allegro/bigcache/v3 |
v3.2.0 | File content cache |
github.com/jmespath/go-jmespath |
v0.4.0 | JMESPath engine behind json_query |
golang.org/x/sync |
v0.24.0 | singleflight read deduplication |
golang.org/x/sys |
v0.49.0 | Windows file locking and job objects |
modernc.org/sqlite |
v1.60.1 | Pure-Go SQLite reader used by the proxy (OpenCode metrics). No CGO |
Documentation
Full documentation at filesystem.scopweb.com.
For agent prompts: llms.txt states the guarantees this server actually keeps (OCC, apply_patch, CRLF dry-run artefacts, backups, paths, retryable) and the strict tool inventory, without promises the code does not back.
Per-tool usage and limits: https://filesystem.scopweb.com/tools/context-pack/ and https://filesystem.scopweb.com/tools/inspection-tools/.
Changelog
See CHANGELOG.md for the full version history (latest: v4.8.0).
License
MIT
Installing Filesystem Go Ultra
This server has no published package — it is built from source. Open the repository and follow its README.
▸ github.com/scopweb/mcp-filesystem-go-ultraFAQ
Is Filesystem Go Ultra MCP free?
Yes, Filesystem Go Ultra MCP is free — one-click install via Unyly at no cost.
Does Filesystem Go Ultra need an API key?
No, Filesystem Go Ultra runs without API keys or environment variables.
Is Filesystem Go Ultra hosted or self-hosted?
Self-hosted: the server runs locally on your machine via the install command above.
How do I install Filesystem Go Ultra in Claude Desktop, Claude Code or Cursor?
Open Filesystem Go Ultra on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
GitHub
PRs, issues, code search, CI status
by GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Unyly Deploy
Deploy sites and MCP servers to Unyly straight from your AI agent
by UnylyAmap Maps Mcp Server
MCP server for using the AMap Maps API
by duxiaohuiPayMCP
Lightweight payments layer for MCP servers: turn tools into paid endpoints with a two-line decorator. [PyPI](https://pypi.org/project/paymcp/) · [npm](https://w
by blustAIServer For Power BI
Enables exploring Microsoft Fabric / Power BI workspaces and semantic models, and executing ad-hoc DAX queries.
by Mitsubishi-FusoTemplate MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
by mcpdotdirectSupabase
Database, auth and storage
by SupabaseEverything
Reference / test server with prompts, resources, and tools.
Compare Filesystem Go Ultra with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All development MCPs
