Universal Dev MCP
Facilitates PHP package management via Composer, including installation and dependency handling.
Provides tools for managing Django projects, including running tests, managing packages, and executing framework-specific commands.
Enables Docker container management, including listing containers, viewing logs, and executing commands.
Offers a dedicated plugin for Frappe framework projects, allowing interaction with Frappe commands and project management.
Provides version control operations such as checking status, viewing logs, committing changes, and pushing.
Integrates with Laravel projects, supporting test execution, package management, and other framework tasks.
Supports Next.js projects with auto-detection and tools for development, testing, and deployment.
Enables installation and management of Node.js packages using npm with automatic detection.
Allows running Python tests using pytest, with automatic detection and execution.
Works with React projects, providing shell, file, and package management tools.
Allows managing Rust projects, including code compilation, testing, and package management.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Universal Dev MCPcheck git status and show recent commits"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Universal Dev MCP
A Model Context Protocol (MCP) server that gives Claude AI access to your own development environment — across any framework, any of your projects, from anywhere.
Connect Claude (via claude.ai web or Claude Code CLI) to your local machine and let it read files, run commands, manage Git, control browsers, switch between projects, and remember context across sessions.
Scope: This is a single-developer tool. It is designed for one person driving their own machine. Run it on your own trusted network — do not treat the OTP gate as multi-user access control. See Security Notes.
What It Does
90+ built-in tools — shell, file ops (edit/grep/tree/move), git (diff/branch/stash/pull), docker, background services, HTTP client, DB query, env, logs, ports, browser automation, desktop control
26 framework plugins — Frappe is a full integration (bench, API, doctype control); the rest (Vue, React, Flutter, Django, Next.js, Laravel, and more) are lighter helpers that mostly build/test and locate framework files
Multi-project workflow — register all your projects, switch by name ("ab Vue par kaam karo")
Persistent memory — Claude remembers decisions, errors, and context across sessions (SQLite)
OTP gate — a single-user token check on every tool call (one shared credential, not per-user accounts)
Public URL tunneling — Tailscale, Ngrok, or Cloudflare for claude.ai web access
Framework auto-detection — scans your project and detects framework automatically
Related MCP server: Orchestrator MCP Server
Requirements
Python 3.10 or higher
pip
Git
Docker (optional, for Frappe/container-based projects)
A public tunnel tool for claude.ai web: Tailscale, Ngrok, or Cloudflare
For browser tools: a Chromium download via
playwright install chromium(see Step 2 below)For desktop tools (Linux):
xdotooland a screenshot tool (scrotor ImageMagick), pluspython3-tk
Quick Start
Step 1 — Clone the repo
git clone <repo-url> universal-mcp
cd universal-mcpStep 2 — Run the setup wizard
python setup_wizard.pyThe wizard will guide you through (step by step):
Python version check
Install dependencies (
requirements.txt)Tunnel provider setup (Tailscale / Ngrok / Cloudflare / manual URL / CLI only)
Select framework plugins you need (Frappe, Vue, Flutter, etc.)
Register your projects (name + path — so you can switch by name later)
Optional email setup for OTP delivery
Setup creates ~/.universal-dev-mcp/config.json — you never need to run it again unless you add a new project.
After setup — install the extras the wizard does not:
playwright install chromium # required before any browser_* tool works pip install pillow # used by desktop screenshot tools # Linux desktop tools also need: sudo apt install xdotool scrot python3-tkSkip these if you don't use the browser/desktop tools.
Step 3 — Start the server
python main.py startServer starts on http://localhost:8080. You will see:
Local URL: http://localhost:8080/mcp
Remote URL: https://your-tunnel-url.ts.net/mcpStep 4 — Start your tunnel (if using claude.ai web)
Run this in a separate terminal and keep it open:
Provider | Command |
Tailscale |
|
Ngrok |
|
Cloudflare |
|
Note: claude.ai web only accepts HTTPS public URLs.
localhostwill be rejected. The tunnel must be running before you add the URL to claude.ai.
Step 5 — Add to Claude
Claude.ai web:
Go to
claude.ai→ Settings → IntegrationsClick Add Custom MCP
Enter:
https://your-tunnel-url/mcp
Claude Code CLI (local only):
claude mcp add universal-mcp http://localhost:8080/mcpFirst Use — Authentication
Every tool call requires an OTP token. This is a single-user gate — one OTP identity for the whole server, not separate developer accounts. On first use:
Call
verify_sessiontool with an empty code — this sends an OTPIf email is configured, check your inbox. Otherwise, the OTP prints in the server terminal
Call
verify_sessionagain with the 6-digit codeYou receive a session token — pass it to all subsequent tool calls
The token expires after 2 hours of inactivity (each use refreshes it); restarting the server clears all sessions
Folder Structure
universal-mcp/
│
├── main.py # CLI entry point — start, setup commands
├── server.py # MCP server core — 90+ tool definitions and dispatch
├── auth.py # OTP authentication and session management
├── config.py # Config file handling (~/.universal-dev-mcp/)
├── tunnel.py # Public URL tunnel management (CF, Tailscale, Ngrok)
├── setup_wizard.py # Interactive one-time setup wizard
├── requirements.txt # Python dependencies
├── .mcp-config.example.json # Per-project config template
│
├── core/ # Universal tool implementations
│ ├── project_detector.py # Framework auto-detection via file signatures
│ ├── project_context.py # Config loader + framework switch detection
│ ├── memory_manager.py # SQLite memory (4 types: project, decision, debug, semantic)
│ ├── agent_planner.py # Structured plan generator for Claude
│ ├── browser_automation.py # Playwright browser automation
│ ├── desktop_control.py # Desktop GUI automation (xdotool / XTEST + Pillow)
│ ├── shell_executor.py # Shell command runner (project cwd; best-effort blocklist)
│ ├── file_manager.py # Safe project-jailed file operations
│ ├── git_ops.py # Git status, log, diff, commit, push
│ ├── env_manager.py # .env reading with secret masking
│ ├── log_reader.py # Log file tailing and grep
│ ├── docker_ops.py # Docker container management
│ ├── test_runner.py # Auto-detect and run tests
│ ├── package_manager.py # pip / npm / composer install
│ └── port_manager.py # Port availability check
│
└── plugins/ # Framework-specific tool extensions
├── __init__.py # Plugin loader — maps names to modules
├── shared.py # Shared helpers (run_command, collect_files)
├── frappe/ # Frappe/ERPNext tools (9 files)
├── vue/ # Vue.js tools
├── flutter/ # Flutter mobile tools
├── react/ # React tools
├── django/ # Django tools
├── nextjs/ # Next.js tools
├── laravel/ # Laravel PHP tools
├── generic/ # Fallback tools (always loaded)
└── ... # 26 frameworks total (most are lightweight file-discovery helpers)Global Config Location
Everything is stored in ~/.universal-dev-mcp/:
File | Purpose |
| Global settings (tunnel, email, plugins, projects) |
| Default framework config overrides |
| SQLite database for Claude's persistent memory |
Per-Project Config
Create .mcp-config.json in your project root for project-specific settings:
{
"framework": "django",
"language": "python",
"db": "postgresql",
"env_file": ".env",
"django": {
"run_command": "python manage.py runserver",
"test_command": "pytest"
}
}See .mcp-config.example.json for all options. For Frappe multi-bench config, see plugins/frappe/README.md.
Available Tools
Core Tools (always available)
Tool | What it does |
| OTP login — must call first |
| Switch to a registered project by name |
| List all registered projects with active marker |
| Add a new project to registry at runtime |
| Load current project framework and config |
| Save framework to |
| Run any terminal command in project directory |
| Read a file (50KB limit) |
| Create or overwrite a file |
| List directory contents |
| Search text across project files |
| Git status / log / diff / branch |
| Stage all + commit (optional push) |
| Read .env file (secrets masked by key name — see Security Notes) |
| Tail or grep log files |
| Check which ports are listening |
| List Docker containers |
| View container logs |
| Auto-detect and run tests (pytest/jest/phpunit) |
| Install package (pip/npm/composer auto-detected) |
| Generate a structured action plan |
| Simple key-value memory per project |
| Per-project notes (scoped by a |
| Store and search past decisions |
| Track errors and resolutions |
| Tagged knowledge snippets |
| Start Playwright browser |
| Open URL |
| Click element by selector |
| Type text into input |
| Capture browser screenshot |
| Capture desktop screen |
| Open an application |
| Click at screen coordinates |
| Type text on desktop |
Daily-use tools
Tool | What it does |
| Replace an exact, unique substring in a file (no full rewrite) |
| Search text, returns |
| Read a file with line numbers + offset/limit range |
| Append text to a file (creates if missing) |
| Move/rename, delete (recursive opt-in), create directory |
| Recursive directory tree (skips node_modules/.git/etc.) |
| Working-tree diff, optionally one file |
| History / list branches / switch branch |
| Create + switch to a new branch |
| Stage paths / stash push-pop-list-drop / pull / push |
| Discard-or-unstage a file / view a file at a revision |
| Start a long-running command in the background (dev server, |
| Tail a service's output, or list all tracked services |
| Stop / restart a background service |
| HTTP client for testing local endpoints |
| Read-only SQL query (writes need |
| Run a command inside a container |
| Compose stack up / down (confirm) / restart one container |
| Kill the process bound to a port |
| Read one key from |
| Grep a log file for a pattern |
| List / uninstall dependencies |
| List / run a |
| Run |
Plugin Tools (loaded based on selected frameworks)
Framework | Added Tools |
Frappe |
|
Vue |
|
Flutter |
|
Django |
|
React |
|
Generic |
|
The frameworks above have curated tools. The remaining plugins (e.g.
aws,mongodb,springboot,cloud,angular,node) mostly expose file-discovery helpers — they locate config/source files rather than deeply drive the framework.genericis always loaded alongside whichever framework is active.
Switching Between Projects
Register projects during setup wizard, or at runtime:
User: "ab Vue par kaam karo"
AI calls: switch_project(name="vue")
User: "frappe mein kaam karo"
AI calls: switch_project(name="frappe")
User: "konse projects hain?"
AI calls: list_projects()Add a new project without re-running wizard:
AI calls: register_project(name="myapi", project_path="/workspace/my-fastapi-app")Adding a New Framework Plugin
Create
plugins/yourframework/directory with__init__.pyandyourframework_ops.pyIn
yourframework_ops.py:
import subprocess
def your_tool(project_path: str, some_arg: str = "") -> str:
result = subprocess.run(
["your-cli", some_arg], cwd=project_path,
capture_output=True, text=True, timeout=60
)
return result.stdout or result.stderr
TOOLS = {
"your_tool": {"fn": your_tool, "description": "What this tool does"},
}Register in
plugins/__init__.pyPLUGIN_MAP:
"yourframework": "plugins.yourframework",Add to
setup_wizard.pyALL_PLUGINSlist
Troubleshooting
"Couldn't reach the MCP server" in claude.ai
Verify the MCP server is running:
python main.py startVerify the tunnel is running in a separate terminal
Make sure the URL ends with
/mcp:https://your-url.ts.net/mcplocalhostURLs are always rejected by claude.ai web
OTP not received by email
Check
smtp_passwordin~/.universal-dev-mcp/config.jsonGmail requires an App Password (not your account password)
As fallback, the OTP always prints in the server terminal
Bench not running / Frappe site not accessible
Check Docker containers:
docker psEnsure MariaDB and Redis containers are running
Set auto-restart:
docker update --restart=unless-stopped <container-name>Start bench inside container:
docker exec <container> bash -lc "nohup bench start > /tmp/bench.log 2>&1 &"
Framework not detected correctly
Run
project_contexttool — Claude will scan and suggestConfirm with
confirm_framework(framework="vue")to save.mcp-config.json
Plugin tools not showing up
Check
active_pluginsin~/.universal-dev-mcp/config.jsonRe-run setup wizard to add missing plugins:
python setup_wizard.py
Session expired
Tokens expire after 2 hours of inactivity — call
verify_sessionagain to renew
browser_launch fails / "Executable doesn't exist"
Run
playwright install chromiumonce (the setup wizard does not do this)
desktop_* tools fail on Linux
Install
xdotool,scrot(or ImageMagick), andpython3-tk; ensurepillowis installed
Security Notes
Read this before exposing the server. This is a single-developer tool. Treat a running server as "whoever holds the token has a shell on my machine."
shell_runis effectively full shell access — not a sandbox. It runs your command withshell=Truein the project directory. The built-in blocklist catches only a few exact patterns (rm -rf /,mkfs,reboot, …) and is trivially bypassed (rm -fr /,find / -delete,bash -c '…'). Do not rely on it as a safety boundary.One shared credential. There is a single OTP identity for the whole server; anyone with the OTP (which prints to the server terminal) gets the same full access.
developer_nameis just a label.File tools are jailed to the project directory —
../and absolute-path traversal are blocked. Butshell_runis not jailed and can read/write anywhere your user can..envmasking is partial.env_readmasks values whose key name looks sensitive. It does not cover unusual key names, andfile_read(".env")/shell_run("cat .env")return everything unmasked.The server binds
127.0.0.1— it is only reachable remotely through the tunnel you start. Only run the tunnel on a network you trust, and stop it when you're done.Keep
"require_auth": true. Setfalseonly on a fully trusted, non-exposed local setup.
License
MIT
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/kallusuvaidyam/universal_mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server