mcp-flow
A safe, local MCP server that lets Claude drive a controlled software-development loop (inspect, read, plan, patch, apply, check, analyze, fix, summarize) on a project, using deterministic tools and real diffs/test runs.
README
mcp-flow
A safe, local MCP server that lets Claude (or any MCP client) drive a controlled software-development loop on a project on your machine:
inspect → read → plan → patch → apply → check → analyze → fix-loop → summarize
The goal is simple: after every model turn, the code stays understandable, tested, reviewed, and corrected — through real diffs, real test/lint/typecheck runs, and an iterative fix loop, all behind hard safety rails.
- SDK:
@modelcontextprotocol/sdk^1.29.0 - Runtime: Node.js ≥ 18 (developed and tested on Node 22)
- Language: TypeScript (strict), ESM
- Transport: stdio (works with Claude Desktop, Cursor, and any standard MCP client)
1. What it does
mcp-flow exposes 10 tools:
| Tool | Purpose | Writes to disk? |
|---|---|---|
inspect_project |
Analyze structure: tree, stack(s), package manager, scripts, tests, linter/typechecker, config files. | No |
read_relevant_files |
Read only the files relevant to a task (explicit list or lexical ranking), truncated & secret-masked. | No |
create_change_plan |
Assemble a structured plan (likely files, steps, risks, checks to run) from deterministic context. | No |
generate_patch |
Turn concrete edits into a guaranteed-valid unified diff. Without edits, returns a generation brief. |
No |
apply_patch |
Apply a unified diff. Dry-run by default, path-confined, mass-deletion-guarded, backups before writing. | Yes (only when dryRun:false) |
run_project_checks |
Auto-detect and run test / lint / typecheck / build using allowlisted commands with timeouts. |
No |
analyze_check_failures |
Parse compiler/linter/test output into structured issues (file, line, code, priority) + fix guidance. | No |
fix_loop |
Controlled verify→analyze→fix loop, up to maxIterations. Closes the loop when the client supports sampling. |
Yes (only when allowApply:true) |
git_status |
Branch, staged/modified/untracked files, last commit, clean/dirty. | No |
summarize_changes |
User + technical summary, suggested conventional-commit message, checks performed, limitations. | No |
How the "thinking" tools work (important)
An MCP server is not a language model. So mcp-flow is deliberately honest
about the split of work:
- Deterministic tools do real work locally: scan the filesystem, build and apply diffs, run checks, parse errors, read git. These never need an LLM.
create_change_plan,generate_patch(brief mode),analyze_check_failures,summarize_changesassemble precise, structured context and hand the reasoning back to the calling model (Claude). They never fabricate code from a non-existent embedded model.generate_patchbecomes fully deterministic the moment you give itedits: it converts your intended changes into a clean unified diff thatapply_patchis guaranteed to accept.fix_loopruns the deterministic verify/analyze cycle. If the connected client supports the optional MCP sampling capability (sampling/createMessage), it asks the client's own model for corrective edits and applies them automatically. If the client does not support sampling (some desktop clients don't),fix_loopreturns a precise advisory with the next actions, and the orchestrating assistant drives the loop by calling the other tools — which Claude does naturally.
This design means the server is safe, deterministic where it matters, and never lies about having capabilities it doesn't.
2. What it does not do
- It does not run arbitrary shell commands. Only an allowlist of base
executables (npm/pnpm/yarn/bun/npx/node, tsc/vitest/jest/eslint/biome/prettier,
python/pytest/ruff/mypy, git) can ever be spawned, with
shell: false. - It does not touch anything outside the
projectPathyou give it. - It does not run destructive commands (
rm -rf,sudo,chmod -R,curl | bash,git push --force,git reset --hard, fork bombs, …). - It does not read
.envand other sensitive files unless you explicitly passallowSensitive: true. - It does not apply patches by default —
apply_patchis dry-run unless you setdryRun: false. - It does not embed or call any external LLM on its own.
3. Install
git clone <your-fork-or-path> "mcp flow"
cd "mcp flow"
npm install
4. Build
npm run build # compiles src/ -> dist/ with tsc
npm run typecheck # tsc --noEmit (strict)
npm test # vitest run (unit tests)
Quick manual run (it speaks MCP over stdio and waits for a client):
npm start # node dist/index.js
# or, without building, for development:
npm run dev # tsx src/index.ts
5. Add it to Claude Desktop
Build first (npm run build), then edit your Claude Desktop config:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Add an entry (see claude_desktop_config.example.json):
{
"mcpServers": {
"mcp-flow": {
"command": "node",
"args": ["/absolute/path/to/mcp flow/dist/index.js"]
}
}
}
Restart Claude Desktop. You should see the mcp-flow tools appear.
Cursor / other MCP clients
Any client that supports stdio MCP servers works. Point it at
node /absolute/path/to/mcp flow/dist/index.js. Clients that implement the
sampling capability unlock fully-autonomous fix_loop; others use it in
advisory mode.
6. Example prompts
Once connected, talk to Claude normally — it will pick the right tools:
- “Analyse ce projet et dis-moi comment il est structuré.”
→
inspect_project - “Ajoute une route API pour créer un utilisateur, puis lance les tests.”
→
create_change_plan→read_relevant_files→generate_patch→apply_patch→run_project_checks - “Corrige les erreurs TypeScript jusqu’à ce que le typecheck passe.”
→
run_project_checks(typecheck) →analyze_check_failures→fix_loop - “Implémente cette fonctionnalité, applique le patch, lance lint et tests,
puis résume les changements.”
→ full chain ending in
summarize_changes - “Fais une revue du diff actuel et propose un patch correctif.”
→
git_status→analyze_check_failures→generate_patch
A typical safe sequence Claude follows:
inspect_project(projectPath)
read_relevant_files(projectPath, taskDescription)
create_change_plan(projectPath, taskDescription)
generate_patch(projectPath, taskDescription, edits=[…]) # real unified diff
apply_patch(projectPath, patch, dryRun=true) # validate
apply_patch(projectPath, patch, dryRun=false) # apply + backup
run_project_checks(projectPath, checks=["test","lint","typecheck"])
analyze_check_failures(projectPath, checkResults=…) # if anything failed
# …iterate generate_patch/apply_patch until green…
summarize_changes(projectPath, checkResults=…)
7. Security rules (enforced in code)
All of these live in src/core/security.ts and are
covered by tests in tests/security.test.ts:
- Path confinement: every path is normalized and must resolve inside
projectPath. Traversal (../…), absolute escapes, and symlink escapes are rejected with a clear error. - Command allowlist: only known base executables run; everything else is
refused. Commands run with
shell: false(no interpolation), and arguments containing shell metacharacters (; & | \$ > <` …) are rejected. - Dangerous-command blocklist:
rm -rf,sudo, recursivechmod/chown,mkfs,dd if=,curl|bash, force-push, hard-reset, fork bombs, etc. - Mass-deletion guard: a patch that removes a huge number of lines while adding none, or deletes many files at once, is refused.
- Backups:
apply_patchcopies every touched file into.mcp-flow-backups/<timestamp>/before writing (unlesscreateBackup:false). - Sensitive files:
.env, keys,credentials,secrets.*are skipped unlessallowSensitive:true..env.example/.sample/.templateare allowed. - Secret masking: output is scrubbed for
KEY=…secrets, provider tokens (sk-…,ghp_…, AWSAKIA…, GoogleAIza…), JWTs, and PEM private keys. - Bounded everything: per-file read size, aggregate read budget, per-stream output size, and per-command timeout are all capped.
- No crashes: every tool catches its errors and returns a clean error result instead of taking the server down.
8. Known limitations
- Reasoning lives in the client.
mcp-flowstructures and validates work; it does not invent code by itself. Patch quality depends on the model driving it. - Autonomous
fix_looprequires client sampling support. Without it, the loop runs deterministically and returns precise next actions for the assistant to execute. (Claude follows these naturally.) - Check detection is heuristic. It covers common Node and Python setups well;
Rust/Go/PHP are detected but only get a
build/testmapping where obvious. You can always pass an explicitpackageManagerorcheckslist. apply_patchuses exact-context matching. If a file changed since the diff was generated, application fails with a clear message rather than guessing.- Patches are content-based, not git-blob-based: renames are modeled as delete + create.
9. Roadmap
- Optional
outputSchema/structuredContentfor clients that prefer it. - Resource endpoints (expose the scan / last diff as MCP resources).
- Smarter relevance ranking (symbol/import graph instead of lexical only).
- Configurable allowlist and limits via env vars.
- Rename/move detection in
generate_patch. - Pluggable check adapters for more ecosystems (Rust
cargo, Gogo test, etc.).
Project layout
src/
index.ts # MCP entrypoint: registers all 11 tools over stdio
types.ts # shared result/structure types
core/
security.ts # path confinement, allowlist, masking, limits
walk.ts # bounded, ignore-aware directory walking
projectScanner.ts # stack / pm / scripts / tests / config detection
fileReader.ts # task-aware, bounded, masked file reading
patchManager.ts # unified-diff build + safe apply (backups, guards)
commandRunner.ts # safe spawn (no shell, timeout, bounded output)
checkDetector.ts # map test/lint/typecheck/build -> concrete commands
failureAnalyzer.ts # parse tsc/eslint/ruff/mypy/pytest output
git.ts # read-only git status & diff
sampling.ts # optional MCP sampling for autonomous fix_loop
toolResult.ts # uniform ok()/fail() result helpers
tools/ # one file per tool, each exports register<Tool>()
tests/ # vitest unit tests (+ helpers)
License
MIT
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。