docs/cli-management-commands.md
This document describes the CLI commands for managing MCPProxy upstream servers and monitoring system health.
MCPProxy provides two command groups:
mcpproxy upstream - Server management (add, remove, list, logs, enable, disable, restart)mcpproxy doctor - Health checks and diagnosticsAll commands support both daemon mode (fast, via socket) and standalone mode (direct connection).
mcpproxy upstream listList all configured upstream servers with connection status.
Usage:
mcpproxy upstream list [flags]
Flags:
--output, -o - Output format (table, json) [default: table]--log-level, -l - Log level (trace, debug, info, warn, error) [default: warn]--config, -c - Path to config fileExamples:
# List servers with table output
mcpproxy upstream list
# JSON output for scripting
mcpproxy upstream list --output=json
# With debug logging
mcpproxy upstream list --log-level=debug
Output Fields:
Status Indicators:
Example Output:
NAME PROTOCOL TOOLS STATUS ACTION
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ github-server http 15 Connected (15 tools) -
❌ oauth-server http 0 Token expired auth login --server=oauth-server
⏸️ disabled-server stdio 0 Disabled by user upstream enable disabled-server
mcpproxy upstream addAdd a new upstream MCP server to the configuration.
Usage:
# HTTP server
mcpproxy upstream add <name> <url> [flags]
# Stdio server (use -- to separate command)
mcpproxy upstream add <name> -- <command> [args...] [flags]
Flags:
--header - HTTP header in 'Name: value' format (repeatable)--env - Environment variable in KEY=value format (repeatable)--working-dir - Working directory for stdio commands--transport - Transport type: http or stdio (auto-detected if not specified)--if-not-exists - Don't error if server already exists--no-quarantine - Don't quarantine the new server (use with caution)Examples:
# Add HTTP-based server
mcpproxy upstream add notion https://mcp.notion.com/sse
# Add with authentication header
mcpproxy upstream add weather https://api.weather.com/mcp \
--header "Authorization: Bearer my-token"
# Add stdio-based server using -- separator
mcpproxy upstream add fs -- npx -y @anthropic/mcp-server-filesystem /path/to/dir
# Add with environment variables and working directory
mcpproxy upstream add sqlite -- uvx mcp-server-sqlite --db mydb.db \
--env "DEBUG=true" \
--working-dir /home/user/projects
# Idempotent add (for scripts)
mcpproxy upstream add notion https://mcp.notion.com/sse --if-not-exists
Behavior:
Output:
✅ Added server 'notion'
⚠️ New servers are quarantined by default. Approve in the web UI.
mcpproxy upstream removeRemove an upstream MCP server from the configuration.
Usage:
mcpproxy upstream remove <name> [flags]
Flags:
--yes, -y - Skip confirmation prompt--if-exists - Don't error if server doesn't existExamples:
# Remove with confirmation prompt
mcpproxy upstream remove notion
# Skip confirmation (for scripts)
mcpproxy upstream remove notion --yes
mcpproxy upstream remove notion -y
# Idempotent remove (for scripts)
mcpproxy upstream remove notion --yes --if-exists
Interactive Confirmation:
$ mcpproxy upstream remove notion
Remove server 'notion'? [y/N]: y
✅ Removed server 'notion'
Behavior:
mcpproxy upstream add-jsonAdd an upstream server using a JSON configuration object.
Usage:
mcpproxy upstream add-json <name> '<json>'
JSON Fields:
url - Server URL (for HTTP transport)command - Command to run (for stdio transport)args - Command arguments (array)headers - HTTP headers (object)env - Environment variables (object)working_dir - Working directory (for stdio)protocol - Transport type (auto-detected if not specified)Examples:
# Add HTTP server with headers
mcpproxy upstream add-json weather '{"url":"https://api.weather.com/mcp","headers":{"Authorization":"Bearer token"}}'
# Add stdio server with environment
mcpproxy upstream add-json sqlite '{"command":"uvx","args":["mcp-server-sqlite","--db","mydb.db"],"env":{"DEBUG":"1"}}'
# Complex configuration
mcpproxy upstream add-json complex-server '{
"command": "node",
"args": ["./server.js"],
"env": {"NODE_ENV": "production", "PORT": "3000"},
"working_dir": "/opt/mcp-server"
}'
Behavior:
url (→ http) or command (→ stdio)mcpproxy upstream logs <name>Display recent log entries from a specific server.
Usage:
mcpproxy upstream logs <server-name> [flags]
mcpproxy upstream logs --server <server-name> [flags]
Flags:
--server, -s - Server name (alternative to positional argument)--tail, -n - Number of lines to show [default: 50]--follow, -f - Follow log output (requires daemon)--log-level, -l - Log level [default: warn]--config, -c - Path to config fileExamples:
# Show last 50 lines (either form works)
mcpproxy upstream logs github-server
mcpproxy upstream logs --server github-server
mcpproxy upstream logs -s github-server
# Show last 200 lines
mcpproxy upstream logs github-server --tail=200
# Follow logs (Ctrl+C to stop)
mcpproxy upstream logs github-server --follow
Behavior:
mcpproxy upstream enable <name|--all>Enable a disabled server or all disabled servers.
Usage:
mcpproxy upstream enable <server-name>
mcpproxy upstream enable --server <server-name>
mcpproxy upstream enable --all [--force]
Flags:
--server, -s - Server name (alternative to positional argument)--all - Enable all disabled servers--force - Skip confirmation prompt (for automation)Requirements:
Examples:
# Enable single server (either form works)
mcpproxy upstream enable github-server
mcpproxy upstream enable --server github-server
mcpproxy upstream enable -s github-server
# Enable all servers (interactive confirmation)
mcpproxy upstream enable --all
# Enable all servers (skip prompt)
mcpproxy upstream enable --all --force
Interactive Confirmation:
$ mcpproxy upstream enable --all
⚠️ This will enable 5 server(s). Continue? [y/N]: _
Non-interactive mode requires --force:
$ echo "y" | mcpproxy upstream enable --all
Error: --all requires --force flag in non-interactive mode
mcpproxy upstream disable <name|--all>Disable a server or all enabled servers.
Usage:
mcpproxy upstream disable <server-name>
mcpproxy upstream disable --server <server-name>
mcpproxy upstream disable --all [--force]
Flags:
--server, -s - Server name (alternative to positional argument)--all - Disable all enabled servers--force - Skip confirmation promptRequirements:
Examples:
# Disable single server (either form works)
mcpproxy upstream disable github-server
mcpproxy upstream disable --server github-server
mcpproxy upstream disable -s github-server
# Disable all servers (interactive confirmation)
mcpproxy upstream disable --all
# Disable all in script
mcpproxy upstream disable --all --force
mcpproxy upstream restart <name|--all>Restart a server or all enabled servers.
Usage:
mcpproxy upstream restart <server-name>
mcpproxy upstream restart --server <server-name>
mcpproxy upstream restart --all
Flags:
--server, -s - Server name (alternative to positional argument)--all - Restart all enabled serversRequirements:
Examples:
# Restart single server (either form works)
mcpproxy upstream restart github-server
mcpproxy upstream restart --server github-server
mcpproxy upstream restart -s github-server
# Restart all servers (no confirmation needed)
mcpproxy upstream restart --all
Note: Restart does not require confirmation as it's non-destructive.
Locally-launched HTTP/SSE upstreams: when a server is configured with both
command and an HTTP/SSE url (see docs/configuration.md),
restart stops the spawned child (SIGTERM → grace → SIGKILL) before
re-running Connect. The grace timeout is fixed at 5s today; the next start
won't begin until the previous child is fully reaped, so you can rely on the
port being free after the command returns. Stop ordering is: close MCP client
→ stop launched child → release per-server state.
mcpproxy doctorRun comprehensive health checks to identify issues.
Usage:
mcpproxy doctor [flags]
Flags:
--output, -o - Output format (pretty, json) [default: pretty]--log-level, -l - Log level [default: warn]--config, -c - Path to config file--server - Limit health checks to a single upstream server by name (Spec 044)Requirements:
Examples:
# Pretty output with issue categorization
mcpproxy doctor
# JSON output for scripting
mcpproxy doctor --output=json
# Only show issues for a single server
mcpproxy doctor --server=github
Health Checks:
Output:
mcpproxy doctor fix <CODE> (Spec 044)Run a registered diagnostics fixer for a specific (server, code) pair.
By default the fix runs as a non-destructive dry_run; pass --execute
to apply mutating changes.
Usage:
mcpproxy doctor fix <CODE> --server <name> [--execute] [--fixer-key <key>] [flags]
Flags:
--server - Upstream server name (required)--fixer-key - Override the auto-resolved fixer_key (rare; needed only
when a code defines multiple button-type fix steps)--execute - Apply the fix (default behaviour is dry_run)--output, -o - Output format (pretty, json) [default: pretty]Requirements:
Examples:
# Dry-run an OAuth re-login for the github server
mcpproxy doctor fix MCPX_OAUTH_REFRESH_EXPIRED --server github
# Actually re-run the OAuth flow (destructive)
mcpproxy doctor fix MCPX_OAUTH_REFRESH_EXPIRED --server github --execute
# JSON output for scripting / CI
mcpproxy doctor fix MCPX_STDIO_SPAWN_ENOENT --server my-stdio -o json
Error code reference: run mcpproxy doctor list-codes for the full
catalog with associated fix steps and fixer keys.
# 1. Run health check to see all issues
mcpproxy doctor
# 2. Check specific server status
mcpproxy upstream list
# 3. View logs for failing server
mcpproxy upstream logs failing-server --tail=100
# 4. Restart server
mcpproxy upstream restart failing-server
# 5. Verify fix
mcpproxy upstream list
# Follow logs in terminal 1
mcpproxy upstream logs github-server --follow
# In terminal 2, trigger operations
mcpproxy call tool --tool-name=github:get_user --json_args='{"username":"octocat"}'
# Watch logs update in real-time
# List all servers first
mcpproxy upstream list
# Disable all for maintenance
mcpproxy upstream disable --all --force
# Perform maintenance...
# Re-enable all
mcpproxy upstream enable --all --force
# Verify
mcpproxy upstream list
~/.mcpproxy/mcpproxy.sockmcpproxy serve running| Command | Daemon Mode | Standalone Mode | Notes |
|---|---|---|---|
upstream add | ✅ Via API | ✅ Config file | Both modes supported |
upstream remove | ✅ Via API | ✅ Config file | Both modes supported |
upstream add-json | ✅ Via API | ✅ Config file | Both modes supported |
upstream list | ✅ Full status | ✅ Config only | Standalone shows "unknown" |
upstream logs | ✅ Via API | ✅ File read | Follow requires daemon |
upstream enable | ✅ | ❌ | Requires daemon |
upstream disable | ✅ | ❌ | Requires daemon |
upstream restart | ✅ | ❌ | Requires daemon |
doctor | ✅ | ❌ | Requires daemon |
All servers added via upstream add or upstream add-json are quarantined by default:
# Add server (automatically quarantined)
mcpproxy upstream add notion https://mcp.notion.com/sse
# View quarantine status
mcpproxy upstream list
# 🔒 notion http 0 Pending approval Approve in Web UI
# Approve in web UI or via API:
curl -X POST "http://localhost:8080/api/v1/servers/notion/unquarantine" \
-H "X-API-Key: your-key"
⚠️ Safety Warning: Bulk Operations
The --all flag affects all servers simultaneously:
disable --all - Stops all upstream connections (reversible with enable --all)enable --all - Activates all servers (may trigger API calls, OAuth flows)restart --all - Reconnects all servers (may cause brief service disruption)Best practices:
upstream list first to see affected servers--all--force in automation only when appropriateConfirmation prompt shows count:
⚠️ This will disable 12 server(s). Continue? [y/N]:
Shows what will be affected before proceeding.
mcpproxy tools)Global view and per-tool enable/disable across all configured servers.
mcpproxy tools listList tools from upstream servers. Without --server, lists every tool across
all servers from the consolidated endpoint (requires daemon). With --server,
lists tools from that specific server only (daemon or standalone).
Usage:
mcpproxy tools list [flags]
Flags:
--server, -s - Server name (optional; omit for global list)--status - Filter by state: enabled, disabled, config-denied--risk - Filter by risk level: read, write, destructive--approval - Filter by approval: approved, pending, changed--output, -o - Output format: table, json, yaml--log-level, -l - Log level [default: info]--config, -c - Path to config file--timeout, -t - Connection timeout [default: 30s]--trace-transport - Enable HTTP/SSE frame-by-frame tracingExamples:
# Global list (all servers) — requires daemon
mcpproxy tools list
mcpproxy tools list -o json | jq '.[0]'
# Filtered list
mcpproxy tools list --status disabled
mcpproxy tools list --risk read
mcpproxy tools list --approval pending
# Server-scoped debug listing (daemon or standalone)
mcpproxy tools list --server=github-server
mcpproxy tools list --server=github-server --log-level=trace
Output Columns (global view):
mcpproxy tools enable <server:tool> [...]Enable one or more tools. Requires daemon.
Usage:
mcpproxy tools enable <server:tool> [<server:tool>...]
Examples:
mcpproxy tools enable github:create_issue
mcpproxy tools enable github:create_issue github:list_repos memory:create_entities
Behavior:
server:tool is parsed by splitting on the first : (tool names may contain :)OK <server:tool>: enabled or FAILED <server:tool>: <reason> per targetmcpproxy tools disable <server:tool> [...]Disable one or more tools. Requires daemon.
Usage:
mcpproxy tools disable <server:tool> [<server:tool>...]
Examples:
mcpproxy tools disable github:create_issue
mcpproxy tools disable everything:echo memory:foo
echo "exit: $?" # non-zero if any failed
Behavior:
tools enable0 - Success1 - Execution failure (API error, connection failure, user declined confirmation)2 - Invalid arguments or configuration (non-interactive without --force)cmd/mcpproxy/*_cmd.gointernal/cliclient/client.gointernal/httpapi/server.gocmd/mcpproxy/internal/cliclient/client.gocmd/mcpproxy/main.goAll commands support manual testing:
go build -o mcpproxy ./cmd/mcpproxy
./mcpproxy <command> [args]