8000 feat: add --dry-run to print a tool call's JSON-RPC request by readyagentsdev · Pull Request #113 · avelino/mcp · GitHub
[go: up one dir, main page]

Skip to content

feat: add --dry-run to print a tool call's JSON-RPC request - #113

Merged
avelino merged 1 commit into
avelino:mainfrom
readyagentsdev:feat/dry-run-tool-calls
Oct 7, 2026
Merged

avelino merged 1 commit into
avelino:mainfrom
readyagentsdev:feat/dry-run-tool-calls

Conversation

@readyagentsdev
Copy link
Copy Markdown
Contributor

Closes #1

What

This adds --dry-run for tool calls. mcp <server> <tool> [json] --dry-run prints the JSON-RPC tools/call request as pretty JSON and exits 0. It does not connect to the server.

$ mcp slack send_message '{"channel":"#general","text":"hello"}' --dry-run
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "arguments": {
      "channel": "#general",
      "text": "hello"
    },
    "name": "send_message"
  }
}

Why and how

The approach follows your review of the earlier attempt (#44):

  • The dry run is handled in main.rs right after the config loads, before the db pool, the audit logger, and any connection. It works when the backend is unreachable, and it never spawns a stdio server.
  • --dry-run with --list, --info, --health, a missing tool name, or a built-in subcommand (search, logs, serve, ...) now fails with --dry-run only applies to tool calls: mcp <server> <tool> [json] --dry-run. Before, the flag was silently ignored in those cases.
  • The server name must still exist in the config, with the same error as a normal call.
  • Arguments come from the command line or stdin, like a normal call.
  • The request is built from the same ToolCallParams / JsonRpcRequest types that McpClient::call_tool uses.

Limitations:

  • The id is always 1. In a live session the client assigns ids after the handshake.
  • The output shows the request for a direct call. When MCP_PROXY_URL is set, the proxy route would send the namespaced {server}__{tool} name instead.

I also added one line to mcp --help and one row to the README commands table.

Tests

  • New unit tests in src/cli/server.rs:
    • test_dry_run_request_is_tools_call: checks the full request for a tool with arguments.
    • test_dry_run_request_keeps_empty_arguments: checks the request with empty arguments.
    • test_dry_run_target_accepts_tool_call: accepts <server> <tool> with or without JSON.
    • test_dry_run_target_rejects_non_tool_calls: rejects --list, --info, --health, a server with no tool, top-level --list, and search / logs / serve.
  • With rustc 1.98.1: cargo fmt --check passes, cargo clippy -- -D warnings passes with no warnings, and cargo test gives 877 passed, 0 failed.
  • Manual check with a temporary MCP_CONFIG_DIR. The config has a stdio server whose command is sh -c "touch /tmp/spawned; sleep 5", and an HTTP server at http://127.0.0.1:9/mcp, where nothing listens:
    • A dry run against the stdio server prints the request and exits 0, and /tmp/spawned is not created. The same call without --dry-run does create it.
    • A dry run against the unreachable HTTP server prints the request and exits 0. It does the same with arguments piped on stdin.
    • fake --list --dry-run, down --health --dry-run, and search foo --dry-run exit 1 with the message above.
    • An unknown server exits 1 with server "nope" not found in config.
    • Invalid JSON exits 1 with tool arguments are not valid JSON: ....

The commit is signed off (DCO).

Signed-off-by: Agent G <326687097+readyagentsdev@users.noreply.github.com>
avelino commented Oct 7, 2026
Copy link
Copy Markdown
Owner

Thanks a lot for this, and sorry it sat here for so long. Really clean change: it exits before touching the db or spawning anything, rejects the non tool call cases, and the tests cover exactly what matters. This is going to help a lot when debugging servers. Merging. Hope to see more PRs from you!

@avelino
avelino merged commit a9ebe8f into avelino:main Oct 7, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support --dry-run flag for tool calls

2 participants

0