| name | mcpmu |
| disable-model-invocation | true |
| description | Install, set up, and manage MCP servers using the mcpmu CLI. Use when the user wants to install mcpmu, register it as an MCP server, add/remove/list MCP servers, manage namespaces, set tool permissions, manage server-level denied tools, or expose servers via serve mode. |
| allowed-tools | Bash(mcpmu *), Bash(brew *), Bash(go install *), Bash(claude mcp *), Bash(codex mcp *), Bash(which mcpmu), Bash(command -v mcpmu) |
mcpmu — MCP Server Manager
mcpmu is a multiplexing MCP server manager. You configure MCP servers once in mcpmu, then expose them as a single unified MCP endpoint to any agent (Claude Code, Codex, Cursor, Windsurf, etc.).
Installing mcpmu
First check if mcpmu is already installed:
which mcpmu
If not installed, install via Homebrew (preferred) or Go:
Homebrew (macOS/Linux):
brew tap Bigsy/tap && brew install mcpmu
From source (requires Go):
go install github.com/Bigsy/mcpmu/cmd/mcpmu@latest
Registering mcpmu as an MCP Server
After installing mcpmu, register it so your agent can use all mcpmu-managed servers through a single endpoint.
Claude Code:
claude mcp add mcpmu -- mcpmu serve --stdio
Codex:
codex mcp add mcpmu -- mcpmu serve --stdio
OpenCode (global config ~/.config/opencode/config.json, or project-level opencode.json):
{
"mcp": {
"mcpmu": {
"type": "local",
"command": ["mcpmu", "serve", "--stdio"]
}
}
}
Any MCP config JSON (Cursor, Windsurf, etc.):
{
"mcpmu": {
"command": "mcpmu",
"args": ["serve", "--stdio"]
}
}
With a specific namespace:
claude mcp add work -- mcpmu serve --stdio --namespace work
codex mcp add work -- mcpmu serve --stdio --namespace work
OpenCode (namespace-specific):
{
"mcp": {
"work": {
"type": "local",
"command": ["mcpmu", "serve", "--stdio", "--namespace", "work"]
}
}
}
With management tools (lets the agent add/remove servers via MCP):
claude mcp add mcpmu -- mcpmu serve --stdio --expose-manager-tools
You can verify the registration:
claude mcp list
codex mcp list
opencode mcp list
To remove mcpmu from an agent:
claude mcp remove mcpmu
codex mcp remove mcpmu
For OpenCode, remove the entry from the config JSON file.
Scoped registration (Claude Code)
Claude Code supports different scopes for MCP server registration:
claude mcp add mcpmu --scope user -- mcpmu serve --stdio
claude mcp add mcpmu --scope project -- mcpmu serve --stdio
Full Setup Walkthrough
To go from zero to a working mcpmu setup:
- Install mcpmu:
brew tap Bigsy/tap && brew install mcpmu
- Add some MCP servers:
mcpmu add context7 -- npx -y @upstash/context7-mcp
- Optionally create a namespace:
mcpmu namespace add work --description "Work tools"
- Assign servers to it:
mcpmu namespace assign work context7
- Register with your agent:
- Claude Code:
claude mcp add mcpmu -- mcpmu serve --stdio
- Codex:
codex mcp add mcpmu -- mcpmu serve --stdio
- OpenCode: add to
~/.config/opencode/config.json (global) or opencode.json (project)
- Others: add the JSON config entry shown above
- Restart your agent — all mcpmu-managed tools are now available
Adding Servers
Stdio servers (local processes)
mcpmu add <name> -- <command> [args...]
Examples:
mcpmu add context7 -- npx -y @upstash/context7-mcp
mcpmu add filesystem -- npx -y @modelcontextprotocol/server-filesystem /tmp
mcpmu add my-server --env FOO=bar --cwd /path -- ./server --flag
mcpmu add auto-server --autostart -- ./server
HTTP servers (remote endpoints)
mcpmu add <name> <url> [flags]
Examples:
mcpmu add atlassian https://mcp.atlassian.com/mcp --scopes read,write
mcpmu add figma https://mcp.figma.com/mcp --bearer-env FIGMA_TOKEN
mcpmu add slack https://mcp.slack.com/mcp --oauth-client-id 1601185624273.8899143856786 --oauth-callback-port 3118
mcpmu add searxng https://searxng-mcp.example.com/mcp \
--header "CF-Access-Client-Id: <id>" \
--env-header "CF-Access-Client-Secret: CF_ACCESS_CLIENT_SECRET"
Flags for HTTP servers:
--scopes — OAuth scopes (comma-separated; auto-discovered from server if omitted)
--bearer-env — env var containing bearer token
--oauth-client-id — pre-registered OAuth client ID (skips dynamic registration)
--oauth-callback-port — OAuth callback port (1-65535)
--header — custom HTTP header in Name: Value form, repeatable. Sent on every request. Stored verbatim in config.
--env-header — HTTP header sourced from an env var, Name: ENV_VAR form, repeatable. Value read at request time — use this for secrets so they stay out of the config file.
General flags (stdio and HTTP):
--autostart — start server automatically on app launch
--startup-timeout — startup timeout in seconds (default: 10)
--tool-timeout — tool call timeout in seconds (default: 60)
Note: --bearer-env and OAuth flags (--oauth-client-id, --scopes, --oauth-callback-port) are mutually exclusive.
Note: --header / --env-header are orthogonal to auth mode — they stack on top of bearer or OAuth, useful for gateways like Cloudflare Access. A header name cannot appear in both flags.
Note: Most OAuth servers advertise supported scopes via metadata — --scopes is only needed when the server doesn't or you want to restrict the requested set.
OAuth login (for HTTP servers that need it)
mcpmu mcp login <server>
mcpmu mcp login atlassian --scopes read,write
mcpmu mcp login slack
mcpmu mcp logout <server>
Listing and Managing Servers
mcpmu list
mcpmu list --json
mcpmu remove <name>
mcpmu remove <name> --yes
mcpmu rename <old> <new>
Namespaces
Namespaces group servers into profiles — e.g. work, personal, minimal. The namespace subcommand can also be shortened to ns.
mcpmu namespace add <name> --description "desc"
mcpmu namespace list [--json]
mcpmu namespace remove <name> [--yes]
mcpmu namespace assign <namespace> <server>
mcpmu namespace unassign <namespace> <server>
mcpmu namespace default <name>
mcpmu namespace rename <old> <new>
mcpmu namespace set-deny-default <namespace> <true|false>
Common namespace patterns
Create separate profiles:
mcpmu namespace add work --description "Work servers"
mcpmu namespace add personal --description "Personal projects"
mcpmu namespace assign work atlassian
mcpmu namespace assign work context7
mcpmu namespace assign personal context7
Create a minimal namespace that denies all tools by default, then allowlist:
mcpmu namespace add minimal --description "Lean toolset"
mcpmu namespace set-deny-default minimal true
mcpmu permission set minimal context7 resolve allow
Tool Permissions
Control which tools each server exposes per namespace:
mcpmu permission list <namespace> [--json]
mcpmu permission set <namespace> <server> <tool> <allow|deny>
mcpmu permission unset <namespace> <server> <tool>
Examples:
mcpmu permission set work atlassian jira_search allow
mcpmu permission set work atlassian confluence_delete deny
Server-level global deny list
For defense-in-depth, deny tools at the server level. Globally denied tools are blocked regardless of namespace permissions — even a namespace explicit allow cannot override a server global deny:
mcpmu server deny-tool <server> <tool> [<tool>...]
mcpmu server allow-tool <server> <tool> [<tool>...]
mcpmu server denied-tools <server> [--json]
Examples:
mcpmu server deny-tool filesystem delete_file move_file
mcpmu server allow-tool filesystem move_file
mcpmu server denied-tools filesystem
Permission resolution order: server global deny > explicit tool permission > server default > namespace default > allow.
In the TUI, press p on the server detail pane to open an interactive deny list editor.
Serve Mode
Expose managed servers as a single MCP endpoint:
mcpmu serve --stdio
mcpmu serve --stdio --namespace work
mcpmu serve --stdio -n work --eager
mcpmu serve --stdio --expose-manager-tools
mcpmu serve --stdio --log-level debug
mcpmu serve --stdio --isolated
Flags:
-n, --namespace — namespace to expose
--eager — pre-start all servers (default: lazy/on-demand)
--expose-manager-tools — include mcpmu.* tools in tools/list
-l, --log-level — debug, info, warn, error
--isolated — bypass the shared daemon for this serve process
Shared daemon behavior
On Unix, concurrent serves for the same config share one daemon and one
instance of each upstream server by default. Windows stays embedded. Set
top-level "daemonMode": false to disable the daemon globally, or use
--isolated for one private serve.
The daemon inherits the first spawner's working directory and environment, so
prefer absolute server cwd values and explicit env config. Shared servers
also share login state and upstream rate limits. Stateful servers such as
browser automation, REPLs, and interpreter sessions should use
"shared": false in that server's config; they then get one instance per
connected serve session.
mcpmu.servers_stop stops a shared instance for every connected client and
the next use starts it again. For shared: false, manager start/stop/restart
actions affect only the caller's instance.
Daemon diagnostics are available when needed:
mcpmu daemon status
mcpmu daemon stop
Connecting mcpmu to Other Agents
For Claude Code registration, see "Registering mcpmu as an MCP Server" above.
For other agents:
Codex:
codex mcp add mcpmu -- mcpmu serve --stdio
OpenCode (global ~/.config/opencode/config.json or project opencode.json):
{
"mcp": {
"mcpmu": {
"type": "local",
"command": ["mcpmu", "serve", "--stdio"]
}
}
}
Any MCP config JSON (Cursor, Windsurf, etc.):
{
"mcpmu": {
"command": "mcpmu",
"args": ["serve", "--stdio"]
}
}
For a namespace-specific entry:
Codex:
codex mcp add work -- mcpmu serve --stdio --namespace work
OpenCode:
{
"mcp": {
"work": {
"type": "local",
"command": ["mcpmu", "serve", "--stdio", "--namespace", "work"]
}
}
}
Cursor, Windsurf, etc.:
{
"work": {
"command": "mcpmu",
"args": ["serve", "--stdio", "--namespace", "work"]
}
}
Interactive TUI
Run mcpmu with no arguments to open the terminal UI for visual server management, log monitoring, and namespace switching.
Config
Config lives at ~/.config/mcpmu/config.json. All commands support --config / -c to use a custom config path.
Shell Completions
mcpmu completion zsh > "$(brew --prefix)/share/zsh/site-functions/_mcpmu"
mcpmu completion bash > /etc/bash_completion.d/mcpmu
mcpmu completion fish > ~/.config/fish/completions/mcpmu.fish