- 🔧
mcp-devtools
server offers a comprehensive suite of software development tools:- 🤖 Agentic editing (
ai_edit
) - 📁 File management (
read_file
,write_to_file
) - 🎋 Git management (
git_diff
,git_show
,git_stage_and_commit
,git_status
,git_log
) - 🖥️ Terminal integration (
execute_command
)
- 🤖 Agentic editing (
- Python 3.12, uv
- Installation: (🐧 Linux/macOS)
curl -LsSf https://astral.sh/uv/install.sh | sh
- Installation: (🪟 Windows)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
- Installation: (🐧 Linux/macOS)
- Aider (only needed for the
ai_edit
tool)-
Installation:
python -m pip install aider-install && aider-install
- Create or copy provided .aider.conf.yml into your home directory (🐧
~/.aider.conf.yml
) or your project repo root (make sure to double check if its.gitignore
d if you are going to keep API keys there, even though Aider should auto-ignore it on first run). - Adjust Aider options to your needs (model, provider, base url, API keys, etc.).
- Follow 📄 official Aider documentation for detailed descriptions of each available option.
The
ai_edit
tool provides a powerful way to make code changes using natural language. It no longer automatically commits changes. Instead, it applies them to your working directory and provides a structured report for you to review.- Delegate a Task: Call
ai_edit
with a clear instruction and the target files. - Receive a Report: The tool returns a report with:
- Aider's Plan: The approach the AI will take.
- Applied Changes (Diff): The exact changes made to your files.
- Next Steps: Instructions to manually review, stage, and commit the changes.
- Review and Commit: You are in full control. Review the diff, and if you approve, stage and commit the changes using the
git_stage_and_commit
tool.
Aider reads .aider.conf.yml itself. The MCP server does not override Aider configuration except enforcing chat history behavior based on the required continue_thread flag (passing --restore-chat-history or --no-restore-chat-history). Any additional options you pass via the ai_edit tool's options parameter are forwarded as-is.
Note on workspaces and Git worktrees (Experimental):
- Git worktrees are EXPERIMENTAL and disabled by default.
- Enable per-session worktrees by setting
MCP_EXPERIMENTAL_WORKTREES=1
(also acceptstrue
/yes
). - When enabled,
ai_edit
may create per-session worktrees under.mcp-devtools/workspaces/<session_id>
and purge them on success; stale worktrees are cleaned up opportunistically based on session TTL. - Diffs and snapshot artifacts are still computed from and stored under the root repository (e.g.,
.mcp-devtools/
), so user-facing behavior remains unchanged when disabled.
- Create or copy provided .aider.conf.yml into your home directory (🐧
-
uvx mcp-devtools -p 1337
git clone "https://github.com/daoch4n/mcp-devtools/"
cd mcp-devtools
./server.sh -p 1337
git clone "https://github.com/daoch4n/mcp-devtools/"
cd mcp-devtools
.\server.ps1 -p 1337
To integrate mcp-devtools
with your AI assistant, add the following configuration to your MCP settings file:
{
"mcpServers": {
"devtools": {
"url": "http://localhost:1337/sse"
}
}
}
vibe.flow.mp4
# ROLE AND DIRECTIVE
**You are a Senior Software Architect.** Your primary function is to architect software solutions by delegating all code implementation to a stateless coding agent via the `ai_edit` tool. Your expertise lies in meticulous planning, atomic delegation, and rigorous code review, not direct implementation.
---
# STANDARD OPERATING PROCEDURE (SOP)
You must adhere to the following five-step, iterative workflow:
1. **Analyze & Plan:** Thoroughly analyze the user's request and formulate a clear, high-level implementation plan. Break the problem down into the smallest possible, logical, and incremental steps.
2. **Delegate ONE Step:** Translate **only the very next step** of your plan into a precise, actionable, and fully self-contained prompt for the `ai_edit` tool. **Never bundle multiple steps into a single delegation.** Default to continue_thread = false. Set continue_thread = true only when you intentionally build on the immediately preceding Aider conversation (e.g., iterative refinement of the same change).
3. **Provide Full Context:** Because the agent is stateless, you must include all necessary context (e.g., file paths, relevant code snippets, class/function definitions) within your `ai_edit` prompt. (See "Agent Memory & Context Protocol" below). Always include file paths, the exact code blocks to modify, and relevant dependencies. This applies whether continue_thread is true or false.
4. **Review & Verify:** Critically evaluate the diff generated by `ai_edit` after every execution. This is a **mandatory code review**.
* Does the code correctly implement the single step you delegated?
* Is the code quality acceptable?
* Are there any errors or edge cases missed?
5. **Iterate & Guide:**
* **If Approved:** The step is complete. Proceed to delegate the *next* incremental step in your plan.
* **If Revision is Needed:** The implementation is flawed. Provide corrective feedback in a new `ai_edit` prompt, again ensuring all context is provided, to guide the agent to the correct solution for that specific step.
---
# AGENT MEMORY MODEL (CONDITIONAL STATELESSNESS)
- The coding agent can be stateless or continue prior conversation, controlled by ai_edit's required continue_thread flag.
- If continue_thread = false:
- Aider does not restore prior chat. Treat every call as a fresh agent with no memory.
- Always include all the immediate context the agent needs: full file paths, the exact function/class to touch, and any dependent snippets.
- If continue_thread = true:
- Aider restores prior chat history for continuity within the same repo/session.
- Still include critical context to make the agent robust. Chat history is best-effort and is not a substitute for explicit, precise context.
## Choosing continue_thread
- Set false:
- Switching features or tasks
- After significant repository changes
- When you want clean isolation between prompts
- Set true:
- Iterating immediately on the same feature or fix
- Correcting the previous Aider change
- Resuming a short-lived session in the same repo
---
# CONSTRAINTS & TOOL PROTOCOL
**Primary Constraint:**
* You are **strictly prohibited** from writing or modifying application code directly. All code implementation must be delegated.
* **Forbidden Tools for Coding:** `apply_diff`, `write_to_file`, and `{your_native_tool_slug}` must NOT be used to modify code.
**Permitted Exception:**
* You MAY use file editing tools to create or modify non-code assets, such as documentation.
**`ai_edit` Tool Usage Rules:**
* `repo_path`: Always pass the full, absolute path of the current working directory.
💬 But I'm too lazy to copy paste prompts myself!

😻 Prompt-Driven Dev Flow: inspired by pure vibes 🦘, optimized for Vibing human-out-of-loop
- Just connect Roo to
mcp-devtools
server and code as usual but use❓ Ask
mode instead of💻 Code
, AI will automatically use theai_edit
tool if available to apply all changes.
🙀 Spec-Driven Dev Flow: inspired by spooky vibes 👻, optimized for Agile human-in-the-loop
- To experience agile spec-driven flow, place the .kiroomodes file and .kiroo/ folder into your repo root and rename them to
.roomodes
and.roo/
:- Start writing Epic Specs and User Stories with
✒️ Agile Writer
- After your confirmation, it will auto-switch to
✏️ Agile Architect
and write Epic Design - After next confirmation, it will auto-switch to
🖊️ Agile Planner
and write Epic Tasks - After final comfirmation, it will auto-switch to
🖋️ Agile Dev
and orchestrate Epic Code writing, followed by Epic Review of each commit.
- Start writing Epic Specs and User Stories with
😼 Plan-Driven Dev Flow: inspired by minimal vibes ♾️, optimized for Waterfall human-out-of-loop
- To experience structured waterfall flow, place the .rooroomodes file and .rooroo/ folder into your repo root and rename them to
.roomodes
and.roo/
:🧭 Rooroo Navigator
agent is your Advanced Flow manager. Responsible for project coordination and task orchestration, lifecycles, delegation. Providescontext.md
files to tasks, either the ones generated by🗓️ Rooroo Planner
, or self-generated ones if Planner wasn't deemed neccessary for the task.👩🏻💻 Rooroo Developer
agent:
Delegates all code changes to subagent then reviews Aider work results, or just codes itself ifai_edit
tool unavailable.📊 Rooroo Analyzer
agent acts as a researcher and analyzes the code.🗓️ Rooroo Planner
agent decomposes complex goals requiring multi-expert coordination into clear, actionable sub-tasks for other agents to do. It is also the main supplier ofcontext.md
files for them.💡 Rooroo Idea Sparker
agent is your brainstorming copilot and innovation catalyst, talk to it if you'd like some creative thinking and assumption challenging done, or just explore something new with it.
- 🛡️ For automated workflows, always run MCP Servers in isolated environments (🐧Firejail or 🪟Sandboxie)
- 🗃️ Filesystem access boundaries are maintained via passing
repo_path
to every tool call, so AI assistant only has read/write access to files in the current workspace (relative to any path AI decides to pass asrepo_path
, make sure system prompt is solid on cwd use). ⚠️ execute_command
doesn't have strict access boundaries defined, while it does execute all commands with cwd set torepo_path
(relative to it), nothing is there to stop AI from passing full paths to other places it seems fit; reading, altering or deleting unintended data on your whole computer, so execise extreme caution with auto-allowingexecute_command
tool or at least don't leave AI assistant unattended while doing so. MCP server is not responsible for your AI assistant executing rm -rf * in your home folder.
Issue:
- 🔍 When using the
write_to_file
tool for direct code editing with languages like JavaScript that utilize template literals, you may encounter unexpected syntax errors. This issue stems from how the AI assistant generates thecontent
string, where backticks and dollar signs within template literals might be incorrectly escaped with extra backslashes (\
).
Mitigation:
- 🔨 The
write_to_file
tool is dynamically integrated withtsc
(TypeScript compiler) for conditional type checking of.js
,.mjs
, and.ts
files on edit. The output oftsc --noEmit --allowJs
is provided as part of the tool's response. AI assistants should parse this output to detect any compiler errors and should not proceed with further actions if errors are reported, indicating a problem with the written code.
Workarounds:
- 🤖 Instruct your AI assistant to delegate editing files to the
ai_edit
tool. It's more suitable for direct code manipulation thanwrite_to_file
.ai_edit
will apply the changes and return a diff for review. Your assistant can then orchestrate the review and commit process.
-
Description: Shows the current status of the Git working tree, including untracked, modified, and staged files.
-
Input Schema:
{ "type": "object", "properties": { "repo_path": { "type": "string", "description": "The absolute path to the Git repository's working directory." } }, "required": [ "repo_path" ] }
- Description: Shows differences in the working directory. By default (without target), shows worktree vs index like
git diff
. Pass target='HEAD' for previous 'all changes vs HEAD' behavior. - Input Schema:
{ "type": "object", "properties": { "repo_path": { "type": "string", "description": "The absolute path to the Git repository's working directory." }, "target": { "type": "string", "description": "Optional. If omitted, behaves like `git diff` (worktree vs index). Pass 'HEAD' or another ref to compare against a commit or branch." } }, "required": [ "repo_path" ] }
- Description: Stages specified files (or all changes if no files are specified) and then commits them to the repository with a given message. This creates a new commit in the Git history.
- Input Schema:
{ "type": "object", "properties": { "repo_path": { "type": "string", "description": "The absolute path to the Git repository's working directory." }, "message": { "type": "string", "description": "The commit message for the changes." }, "files": { "type": "array", "items": { "type": "string" }, "description": "An optional list of specific file paths (relative to the repository root) to stage before committing. If not provided, all changes will be staged." } }, "required": [ "repo_path", "message" ] }
- Description: Shows the commit history for the repository, listing recent commits with their hash, author, date, and message. The number of commits can be limited.
- Input Schema:
{ "type": "object", "properties": { "repo_path": { "type": "string", "description": "The absolute path to the Git repository's working directory." }, "max_count": { "type": "integer", "default": 10, "description": "The maximum number of commit entries to retrieve. Defaults to 10." } }, "required": [ "repo_path" ] }
- Description: Shows the metadata (author, date, message) and the diff of a specific commit or commit range (A..B or A...B). This allows inspection of changes introduced by a particular commit or range of commits. Optionally filter by path or show only metadata/diff.
- Input Schema:
{ "type": "object", "properties": { "repo_path": { "type": "string", "description": "The absolute path to the Git repository's working directory." }, "revision": { "type": "string", "description": "The commit hash, reference (e.g., 'HEAD', 'main', 'abc1234'), or range (A..B or A...B) to show details for." }, "path": { "type": "string", "description": "Optional. Filter the output to show only changes for the specified file path." }, "show_metadata_only": { "type": "boolean", "description": "Optional. If true, shows only the commit metadata (author, date, message) without the diff." }, "show_diff_only": { "type": "boolean", "description": "Optional. If true, shows only the diff without the commit metadata." } }, "required": [ "repo_path", "revision" ] }
- Description: Reads and returns the entire content of a specified file within the Git repository's working directory. The file path must be relative to the repository root.
- Input Schema:
{ "type": "object", "properties": { "repo_path": { "type": "string", "description": "The absolute path to the Git repository's working directory." }, "file_path": { "type": "string", "description": "The path to the file to read, relative to the repository's working directory." } }, "required": [ "repo_path", "file_path" ] }
- Description: Writes the provided content to a specified file within the repository. If the file does not exist, it will be created. If it exists, its content will be completely overwritten. Includes a check to ensure content was written correctly and generates a diff.
- Input Schema:
{ "type": "object", "properties": { "repo_path": { "type": "string", "description": "The absolute path to the Git repository's working directory." }, "file_path": { "type": "string", "description": "The path to the file to write to, relative to the repository's working directory. The file will be created if it doesn't exist, or overwritten if it does." }, "content": { "type": "string", "description": "The string content to write to the specified file." } }, "required": [ "repo_path", "file_path", "content" ] }
- Description: Executes an arbitrary shell command within the context of the specified repository's working directory. This tool can be used for tasks not covered by other specific Git tools, such as running build scripts, linters, or other system commands.
- Input Schema:
{ "type": "object", "properties": { "repo_path": { "type": "string", "description": "The absolute path to the directory where the command should be executed." }, "command": { "type": "string", "description": "The shell command string to execute (e.g., 'ls -l', 'npm install')." } }, "required": [ "repo_path", "command" ] }
-
Description: AI pair programming tool for making targeted code changes using Aider. This tool applies the requested changes directly to your working directory without committing them. After the tool runs, it returns a structured report containing:
- Aider's Plan: The approach Aider decided to take.
- Applied Changes (Diff): A diff of the modifications made to your files.
- Next Steps: Guidance on how to manually review, stage, and commit the changes.
- Thread Context Usage: Information about the approximate token count of the conversation history and guidance on keeping it under ~200k tokens.
Use this tool to:
- Implement new features or functionality in existing code
- Add tests to an existing codebase
- Fix bugs in code
- Refactor or improve existing code
IMPORTANT: This tool does NOT automatically commit changes. You are responsible for reviewing and committing the work.
-
Input Schema:
{ "type": "object", "properties": { "repo_path": { "type": "string", "description": "The absolute path to the Git repository's working directory where the AI edit should be performed." }, "message": { "type": "string", "description": "A detailed natural language message describing the code changes to make. Be specific about files, desired behavior, and any constraints." }, "files": { "type": "array", "items": { "type": "string" }, "description": "A list of file paths (relative to the repository root) that Aider should operate on. This argument is mandatory." }, "continue_thread": { "type": "boolean", "description": "Required. Whether to continue the Aider thread by restoring chat history. If true, passes --restore-chat-history; if false, passes --no-restore-chat-history. Clients must explicitly choose." }, "options": { "type": "array", "items": { "type": "string" }, "description": "Optional. A list of additional command-line options to pass directly to Aider. Each option should be a string." }, "edit_format": { "type": "string", "enum": [ "diff", "diff-fenced", "udiff", "whole" ], "default": "diff", "description": "Optional. The format Aider should use for edits. Defaults to 'diff'. Options: 'diff', 'diff-fenced', 'udiff', 'whole'." }, "prune": { "type": "boolean", "default": false, "description": "Optional. Whether to prune older chat history sessions before running. Defaults to false." }, "prune_mode": { "type": "string", "enum": [ "summarize", "truncate" ], "description": "Optional. The pruning mode to use when prune=true. 'summarize' creates a summary of older sessions, 'truncate' removes them. Defaults to 'summarize' if prune=true and prune_mode is not specified." } }, "required": [ "repo_path", "message", "files", "continue_thread" ] }
- Stateless (recommended):
- continue_thread: false
- Always include all context needed for the single step.
- With restored chat:
- continue_thread: true
- Still include critical context; do not rely solely on chat history.
- Use this to refine a change made in the immediately previous run.
Note: When
continue_thread
is false, the server prunes Aider chat memory by truncating.aider.chat.history.md
in the repository root before invoking Aider.
Also: After Aider completes, the server appends the last Aider reply from
.aider.chat.history.md
(last session only) to the tool output, with SEARCH/REPLACE noise removed for readability.
Pruning: When
prune
is true, older chat sessions are either summarized or truncated based onprune_mode
. By default, only the most recent session is kept (configurable viaMCP_PRUNE_KEEP_SESSIONS
environment variable).
- Description: Check the status of Aider and its environment. Use this to:
- Verify Aider is correctly installed
- Check API keys
- View the current configuration
- Diagnose connection or setup issues
- Input Schema:
{ "type": "object", "properties": { "repo_path": { "type": "string", "description": "The absolute path to the Git repository or working directory to check Aider's status within." }, "check_environment": { "type": "boolean", "default": true, "description": "If true, the tool will also check Aider's configuration, environment variables, and Git repository details. Defaults to true." } }, "required": [ "repo_path" ] }
- Description: List active AI editing sessions or get the status of a specific session. Can optionally run TTL cleanup to remove expired sessions when listing (cleanup=true).
- Input Schema:
{ "type": "object", "properties": { "repo_path": { "type": "string", "description": "The absolute path to the Git repository's working directory." }, "action": { "type": "string", "description": "The action to perform: 'list' sessions or get 'status' of a specific session.", "enum": [ "list", "status" ] }, "session_id": { "type": "string", "description": "Optional. The session ID to get status for. Required when action='status'." }, "cleanup": { "type": "boolean", "default": false, "description": "Optional. If true, runs TTL cleanup when listing sessions. Defaults to false." } }, "required": [ "repo_path", "action" ] }
- Example Usage:
// List sessions with cleanup {"repo_path": "/abs/path/to/repo", "action": "list", "cleanup": true} // Get status of a specific session {"repo_path": "/abs/path/to/repo", "action": "status", "session_id": "<session_id>"}
💬 But I'm too lazy to even read this all!