Repository navigation
feat(cli): add tool calls and JSON output - #1088
Conversation
helpcodeai
left a comment
There was a problem hiding this comment.
Thanks @Coding-Professional, this is in good shape. I ran npm test, lint and build in packages/cli (10/10 pass). I also pointed the CLI at a fake server wired the way our backend is (stateless createMcpHandler, both SSE and JSON response modes). Inline/file/stdin --args, isError on stdout with --json and on stderr in text mode, input validation errors, non-text content, exit 3 on a bad key, and the destructive prompt on a real TTY (y, n, empty answer, Ctrl-D) all did what the README says. The key never showed up in stdout or stderr. Copilot didn't actually review this one (quota), so there's nothing from it to address.
Two things before merge:
client.callToolinsrc/index.ts:253runs with the SDK's default 60s request timeout. I tried a tool that takes 65s and got exit 4 with "Could not connect to the MCP server or complete the request" after 60s. That sends people looking at the network when the call was just slow, and our database engine alone allows 60s per statement plus connect time, so a slowsap_queryin CI can hit it. Please pass a longer timeout (a--timeout <seconds>flag with a default around 300 is fine) and catch the SDK'sREQUEST_TIMEOUTerror with its own message, something like "Tool call timed out after 300s", still exit 4.- The issue's acceptance criteria ask for one run against a local
docker compose upinstance. That needs no credentials, just a key you create in the UI. Please paste the commands and output (key redacted) into the PR description.
Smaller stuff, fine here or in a follow-up:
login --jsonputs the origin inurl(index.ts:179) butwhoami --jsonputs the full/mcp/<id>URL inurl(index.ts:195). I'd keep the instance URL inurlfor both and add the endpoint as a separate field if you want it, before scripts start relying on it.- The README lists the JSON shapes for stdout but not the error object on stderr (
{"error": ..., "exitCode": ...}). Worth one line. - The fake server in
cli.test.tsonly answers withapplication/json. Our backend defaults to SSE, so one SSE case would be good to have. listClientToolsinmcp.ts: with client 2.2,client.listTools()without a cursor already walks every page and returns nonextCursor, so the loop never gets past the first pass.return (await client.listTools()).toolsis enough.- Not from this PR: a refused connection (e.g. nothing on the port) still prints the generic message, because the error has no
cause.codethere (I getTypeError: fetch failedwith a cause that carries no code), so the ECONNREFUSED branch from part 1 never matches.
The branch is also behind main, so it needs an update before it can merge.
|
Thanks for the thorough review and testing. I'm addressing the timeout handling and the smaller improvements, and I'll add the local Docker Compose commands and redacted output to the PR description. I'll push the updates to this PR once verification is complete and keep the branch synced with main. |
helpcodeai
left a comment
There was a problem hiding this comment.
Thanks @Coding-Professional, both points are done.
--timeoutdefaults to 300s, validates its input and fails with "Tool call timed out after Ns" and exit 4.- The Compose run against 0.32.1 in the description is exactly what the issue asked for.
I re-ran it locally: npm test 11/11, including the slow SSE call and the paginated tool list, and npm run build is clean. Merging.
Summary
Developers can inspect and call connector tools from the terminal or CI without setting up another MCP client. This completes the CLI commands from #1009 after #1024 and targets
/mcp/<serverId>on both Cloud and self-hosted instances.Changes
tools describeandtools call, accepting an inline JSON object,@file.json, or stdin with--args -.--yesin non-interactive use.--jsonto every command, document stdout/stderr shapes, and preserve the tool'sisErrorresult with exit code 1.--timeout <seconds>and reportTool call timed out after <seconds>swith exit code 4.urlconsistent in login/whoami JSON, preserve base-path prefixes, and expose the MCPendpointseparately in whoami.Type
Testing
Commands run from the repository root unless stated otherwise:
npm test -w packages/cli: 11 passed, including a real 65-second SSE tool call that exceeds the SDK's former 60-second default, custom timeout success/failure, pagination, URL consistency, and existing credential-isolation tests.npm run lint -w packages/cli: passed.npm run build -w packages/cli: passed.npm test -w packages/backend -- --runInBand --testPathPatterns=adapters/catalog.spec.ts --silent: 7,717 passed.node scripts/validate-adapters.mjs: 438 passed, 0 failed; 1,458 existing non-blocking warnings.node scripts/adapter-count.mjs --check: passed (422 listed adapters, 19 keyless, 6,204 tools).git diff --check: passed.docker build .passed on the 0.30.0 base. Later upstream release syncs and this CLI-only update were not followed by another source image build. The Compose smoke run used the published 0.32.1 image.Local Docker Compose verification (15 October 2026)
Used a fresh isolated stack on ports 3300/4400 with the published 0.32.1 backend, a real PostgreSQL database, the keyless Hacker News connector, and a server-scoped per-user MCP key. The local account, connector and key were created through the same authenticated application API used by the dashboard; no database fixtures or fake MCP handler were used. Generated local secrets were kept in
.git/cli-review.envand were not committed.Image:
helpcodeai/anythingmcp@sha256:a0ef922cd0ef779fd8a2da289400bd20a1da55416c95ff30e4e0cba5cbdc6ea0The runner supplied the key and JSON stdin directly to the subprocess, never as command arguments. Inline, file and stdin calls all returned the real Hacker News item 1. The transcript also covers usage and authentication errors. The bad-key command temporarily used an intentionally invalid key.
CLI commands and redacted output
The test key was revoked and the stack was stopped afterward:
docker compose --env-file .git/cli-review.env -p amcp-cli-review -f docker-compose.quickstart.yml down # app and postgres stopped/removed; test network removedCloud live verification was not run because Cloud test credentials are unavailable. No Cloud-specific code or permissions were changed.
Checklist
Related Issues
Relates to #1009. Follows #1024.