Skip to content

Repository files navigation

run-mcp

A thin MCP client for humans and agents — test the server you're building without touching a config file.

CI npm license

Change your Model Context Protocol server's code and test it immediately — no editing mcp.json, no restarting your agent, no publishing to npm first. run-mcp spawns the server, calls its tools, shows you its stderr when it crashes, and restarts it on demand.

run-mcp provides three interfaces for interacting with MCP servers:

  1. Agent MCP Server (run-mcp) — An MCP server that exposes tools (connect_to_mcp, call_mcp_primitive, reconnect_to_mcp) so AI agents can dynamically connect to and test local MCP projects without hardcoding them in configuration files. This is the default mode when you run npx -y run-mcp.
  2. Interactive REPL (run-mcp -- node server.js) — A human-friendly CLI for developers to manually test and explore MCP servers using short, memorable commands (tools/call, status, etc.).
  3. Headless CLI (run-mcp call, run-mcp list-tools, etc.) — Single-shot subcommands that output clean JSON to stdout for CI/CD pipelines, shell scripts, and jq workflows.

Interception Rules (Agent Server & REPL)

To protect the CLI and parent agents from large payloads, run-mcp automatically applies the following rules:

  • Saving images to disk instead of passing multi-MB base64 strings through
  • Enforcing timeouts so a hung tool call doesn't block forever
  • Spilling huge text to disk: oversized responses are saved in full, and the truncated reply carries a result id — page through the rest with the read_result tool (or just open the file)

For humans, the REPL mode provides a quick way to test any MCP server without writing client code.

Installation

npm install
npm run build

To install globally (makes run-mcp available system-wide):

npm install -g .

Quick Start

REPL Mode — Test an MCP server interactively

# Start a REPL session with any MCP server
run-mcp -- node path/to/my-mcp-server.js

# Or use npx without installing globally
npx . -- node path/to/my-mcp-server.js

# Or start it without arguments to run the Agent Server mode!
run-mcp

You'll see an interactive prompt:

⟳ Connecting to target MCP server...
  Command: node path/to/my-mcp-server.js
✓ Connected (PID: 12345)
  5 tool(s) available. Type help for commands.

>

Usage

run-mcp [options] [target_command...]

Option Description
-V, --version output the version number
-o, --out-dir <path> Directory to save intercepted images and audio
-t, --timeout <ms> Default tool call timeout in milliseconds (default: 300000) (Agent Mode only)
--max-text <chars> Max text response length before truncation (default: 50000) (Agent Mode only)
-m, --media-threshold <kb> Media size threshold in KB to save to disk (0 to always save, -1 to keep inline)
--mcp Force start Agent Server mode even if run interactively without arguments
-s, --script <file> Read commands from a file instead of stdin (REPL Mode only)
--color <mode> Color output mode: always, never, auto (default: auto)
--open-media Automatically open intercepted images and audio files using the host OS viewer
--scan Scan the current workspace and parent directories for any JSON files containing mcpServers
--transport <mode> Transport for http(s) targets: auto (default), http (Streamable HTTP), sse
-w, --watch Watch the current directory for file changes and auto-reconnect (REPL Mode only)
-h, --help display help for command

Examples: $ run-mcp # Test harness (agent mode) $ run-mcp -- node my-server.js # Interactive testing (human REPL mode) $ run-mcp -s test.txt -- node my-server.js # Run a script in REPL mode $ run-mcp -- npx -y some-mcp-server # Test an npx server $ run-mcp --out-dir ./test-output # Agent mode with options $ run-mcp --out-dir ./screenshots -- node srv.js # REPL mode with options

Watch Mode

When developing an MCP server, use --watch (or -w) to automatically reconnect whenever your source files change. This eliminates the manual reconnect step from your edit-test loop:

run-mcp -w -- node my-server.js

On each file change, run-mcp will:

  1. Detect the changed files (debounced to 500ms to batch rapid saves)
  2. Disconnect from the current server process
  3. Reconnect to a fresh instance
  4. Show a diff of what primitives changed (tools added/removed/modified, resources, prompts)

Common directories like node_modules, .git, dist, and build are automatically ignored.

Headless Mode (Single-Shot CI/CD)

For CI/CD pipelines, shell scripts, or parsing via jq, run-mcp exposes a suite of headless subcommands that pipe clean JSON to stdout and isolate standard errors and progress updates to stderr.

⚠️ Double-Dash -- Separator

To prevent argument parsing conflicts between run-mcp and the target server, you should separate the target command with a double-dash -- when the target command itself contains flags or options.

  • Required when the target command has options/flags:
    run-mcp list-tools -- node my-server.js --verbose
    (Must use -- so --verbose is passed to your server, not parsed as an option for run-mcp.)
  • Optional when the target command has no options/flags:
    run-mcp list-tools node my-server.js
    (Runs successfully without --.)

⚡ HTTPie-Style Shorthand Arguments

Instead of escaping complex JSON strings on the command line, you can provide arguments using simple key-value shorthand notation:

  • key=value -> evaluated as a string
  • key:=json_val -> parsed as a JSON primitive (boolean, number, array, object, null)

Example:

# Call a tool using shorthand arguments
run-mcp call greet name=Alice count:=5 -- node my-server.js

🔄 Stateful/Persistent CLI Sessions

Normally, every headless command spawns a fresh process of the target server, which is slow and discards connection state. By passing --session <name>, run-mcp will spawn a persistent background daemon on the first call. Subsequent commands will dynamically attach to the same running session:

# Spawns a background session daemon & launches a browser
run-mcp call browser_launch headless:=true --session main -- node browser-server.js

# Navigates the browser on the active running session (no target command needed!)
run-mcp call browser_navigate url=https://google.com --session main

# Closes the session and stops the background target server
run-mcp close-session main

Available Headless Subcommands

  • call [options] <tool> [json_args] [target_command...]
  • list-tools [options] [target_command...]
  • list-resources [options] [target_command...]
  • list-prompts [options] [target_command...]
  • read [options] <uri> [target_command...]
  • describe [options] <tool> [target_command...]
  • get-prompt [options] <name> [json_args] [target_command...]
  • daemon <session_name> [target_command...]
  • close-session <session_name>
  • validate [options] [target_command...]

Use run-mcp <subcommand> --help for specific command options.

Agent Use Cases

Dynamic Testing

When an AI agent is actively developing an MCP server, it needs to test it. Standard MCP clients require updating a configuration file (mcp.json) and restarting the agent session entirely.

run-mcp solves this by giving the agent a suite of tools to dynamically spawn, inspect, and test local MCP servers on the fly.

How to use: Add run-mcp to your agent's MCP configuration using npx:

{
  "mcpServers": {
    "run-mcp": {
      "command": "npx",
      "args": ["-y", "run-mcp"]
    }
  }
}

Then use these tools from your agent:

Tool Description
connect_to_mcp Spawn and connect (use include to get tools/resources/prompts)
call_mcp_primitive Call a tool, read a resource, or get a prompt (auto-connects)
list_mcp_primitives List tools, resources, and/or prompts
get_server_notifications Inspect notifications the target emitted (list_changed, updates, logs)
subscribe_to_resource Exercise a server's resource-subscription support
reconnect_to_mcp Restart the target after a code edit and diff what changed
read_result Page through an oversized result spilled to disk
disconnect_from_mcp Tear down and reconnect after changes
mcp_server_status Check connection status
get_mcp_server_stderr View target server stderr output
validate_mcp_server Validate an MCP server command and collect diagnostics
list_available_mcp_servers List local MCP servers found in config files

REPL Mode Commands

Once connected via run-mcp <command>, the following shorthand commands are available:

Command Description
tools/list List all available tools
tools/describe <name> Show a tool's input schema
tools/call <name> [json] [opts] Call a tool (interactive if no json)
tools/scaffold <name> Generate argument template for a tool
resources/list List all available resources
resources/read <uri> Read a resource by URI
resources/templates List resource templates
resources/subscribe <uri> Subscribe to resource changes
resources/unsubscribe <uri> Unsubscribe from resource changes
prompts/list List all available prompts
prompts/get <name> [json_args] Get a prompt with arguments
ping Verify connection, show round-trip time
log-level <level> Set server logging verbosity
`history [count clear]`
`notifications [count clear]`
roots/list Show configured client roots
roots/add <uri> [name] Add a root directory
roots/remove <uri> Remove a root directory
!! / last Re-run the last command
reconnect Disconnect and reconnect
timing Show tool call performance stats
status Show target server status

Examples

# List available tools
> tools/list

# Inspect a tool's schema
> tools/describe screenshot

# Call a tool with arguments
> tools/call screenshot {"target": "#loginBtn"}

# Call with a custom timeout (5 seconds)
> tools/call long_running_tool {} --timeout 5000

# Arguments with spaces work fine
> tools/call send_message {"text": "hello world", "channel": "general"}

Direct Inline Tool Calls & Shorthand Arguments

Instead of prefixing every tool call with tools/call, you can invoke any target server tool directly by name, and provide arguments in shorthand key-value form:

# Direct inline tool execution with HTTPie shorthand parameters
> greet name=Bob count:=3

Interactive Wizard & Argument Memory

If you invoke a tool without JSON arguments, run-mcp will guide you through an interactive scaffolding wizard:

> tools/call send_message
✔ text (string) Message text to send: Hello World!
✔ Select optional arguments to provide: channel
✔ channel (string) The Slack channel: general
✔ Execute? Yes
  Calling send_message...

run-mcp actively remembers your inputs across identical interactive calls, scaffolding defaults based on your last execution! Use tools/forget or --clear if you need a clean slate.

Script Mode

You can automate REPL commands by writing them to a file:

# commands.txt
tools/list
tools/call get_status {}
tools/call screenshot {"save_path": "/tmp/test.png"}
run-mcp -s commands.txt -- node my-server.js
  • Lines starting with # are treated as comments
  • Exits with code 0 on success, 1 on first error

Testing your server's client-facing behavior

Some MCP features depend on what the client provides. run-mcp exposes these so an agent can exercise them:

  • Roots — pass roots to connect_to_mcp (or reconnect_to_mcp) and your server's roots/list calls get a real answer. run-mcp advertises the roots capability, so without this your server correctly sees an empty list. Roots persist across reconnects.
  • Log level — pass log_level to raise your server's logging verbosity.
  • Notificationsget_server_notifications shows what your server emitted (tools/list_changed, resources/updated, log messages). These travel outside the request/response flow, so a tool result will never reveal them.
  • Subscriptionssubscribe_to_resource, then trigger a change and confirm with get_server_notifications(method='resources/updated').

Agent Server Mode — How It Works

Run with no target command (or --mcp), run-mcp is itself an MCP server that exposes tools (connect_to_mcp, call_mcp_primitive, reconnect_to_mcp, …) so an agent can dynamically spawn and test local MCP servers. Tool-call responses are processed through the interceptor pipeline:

Feature Behavior
Image extraction type: "image" responses with base64 data are saved to disk. Replaced with [Image saved to /path/to/img.png (24KB)]
Audio extraction type: "audio" responses with base64 data are saved to disk. Replaced with [Audio saved to /path/to/audio.wav (12KB)]
Base64 detection Text responses that are entirely base64-encoded (1000+ chars) are also saved as images
Timeouts Tool calls are wrapped in a configurable timeout (default 5 minutes, use --timeout to change)
Truncation Text exceeding the limit (default 50K chars, --max-text to change) is saved in full to disk; the reply keeps the head plus a result id, navigable via the read_result tool

Architecture

For the detailed system architecture diagram and source module directory map, please refer to AGENTS.md.

Development

# Install dependencies
npm install

# Build (one-time)
npm run build

# Watch mode (rebuild on changes)
npm run dev

# Run directly
node dist/index.js -- <target_command...>

License

MIT

About

A thin MCP client for humans and agents — run any Model Context Protocol server, call its tools, read its stderr, and reconnect after each edit. REPL, headless CLI, or an MCP server your agent drives. No client config edits, no restarts.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages