Skip to content

🎃 Build an amcp CLI (MVP): log in with an API key, list and call tools #1009

Open

Description

@helpcodeai

Part of the October Challenge #997.

Why

Developers want to test a connector's tools from the terminal or a CI job ("does sap_query still answer after the upgrade?") without opening the UI or wiring up an MCP client. A small CLI that talks to the MCP endpoint we already expose is enough, and it works the same against AnythingMCP Cloud and any self-hosted instance. Comparable tools: mcp-cli, the MCP Inspector CLI mode, Composio's CLI.

Self-hosted vs Cloud

  • Self-hosted: works with per-user MCP API keys (mcp_…) and with the instance-wide MCP_API_KEY / MCP_BEARER_TOKEN used in legacy auth mode.
  • Cloud (DEPLOYMENT_MODE=cloud): works with per-user MCP API keys. Important difference: on Cloud the bare /mcp URL serves a fixed set of 8 meta-tools (anythingmcp_search_tools, anythingmcp_run_read_tool, …, see shared-toolset.ts:26 and :52), not the workspace's tools. The CLI must therefore always target a server URL /mcp/<serverId>, which exposes that server's tools directly on both deployments.
  • Who can use it: any member who can create an MCP API key. The backend already scopes everything: the key resolves to a user and organization, the per-server endpoint checks org membership (mcp-endpoint.controller.ts:837–871) and the user's MCP role limits which tools are listed and callable. The CLI adds no permissions of its own.

What to build

New workspace package packages/cli (@anythingmcp/cli, "bin": { "amcp": "dist/index.js" }, TypeScript, Node ≥ 22.12 like the root engines).

  1. Transport: @modelcontextprotocol/client v2 (already used by the backend) with StreamableHTTPClientTransport, header X-API-Key: <key>. One small dependency for argument parsing (commander or Node's built-in util.parseArgs); nothing else.
  2. Commands:
    • amcp login --url https://cloud.anythingmcp.com --server <serverId> — reads the key from a hidden prompt or --key-stdin (never as a plain argument, it would land in shell history), calls tools/list once to verify, saves a profile to ~/.config/amcp/config.json ($XDG_CONFIG_HOME respected, file mode 0600). --profile <name> for several instances.
    • amcp logout, amcp whoami (URL, server id, key prefix mcp_ab12… only).
    • amcp tools ls [--filter <text>] — name, read-only/destructive hint (from tool annotations), first line of description.
    • amcp tools describe <name> — description + input JSON schema.
    • amcp tools call <name> --args '<json>' (or --args @file.json, or - for stdin). Prints text content; if a tool annotation says destructiveHint: true and stdin is a TTY, ask for confirmation unless --yes.
    • Global --json (machine-readable output for every command), --profile, --url/--server/AMCP_URL/AMCP_API_KEY/AMCP_SERVER env overrides for CI.
  3. Exit codes: 0 ok, 1 tool returned isError, 2 usage/invalid JSON, 3 auth (401/403), 4 network/server error. Errors to stderr; never print the key or full request headers, even with --verbose.
  4. Workspace wiring: add packages/cli to root package.json workspaces; give it build, lint and test scripts. The Docker build runs npm ci with only the backend/frontend package.json copied (Dockerfile:26–32); verify docker build . still works and adjust the COPY lines if needed. The CLI must not end up in the server image.

Where to look

  • package.json (root) — workspaces, engines, test/lint scripts.
  • docs/api-reference.md:3 — the REST API under /api/* requires a JWT, not an MCP API key; :286 MCP API keys.
  • packages/backend/src/auth/mcp-combined-auth.guard.ts:61–85 — how X-API-Key (mcp_… or static key) is accepted.
  • packages/backend/src/mcp-server/mcp-endpoint.controller.ts:222 (bare /mcp), :676 (/mcp/:serverId).
  • packages/backend/src/mcp-server/shared-toolset.ts:52 — sharedEndpointMode(), why bare /mcp differs on Cloud.
  • packages/backend/src/connectors/engines/mcp-client.engine.ts:46 — existing StreamableHTTPClientTransport usage with custom headers.
  • packages/frontend/src/app/mcp-server/[id]/page.tsx:270, :297 — where users find the server URL and the X-API-Key header; add a "CLI" snippet there in a follow-up.
  • packages/backend/prisma/schema.prisma:344 — McpApiKey (optionally bound to one mcpServerId).

Acceptance criteria

  • Tests with node --test (or jest like the backend) against an in-process fake MCP server (@modelcontextprotocol/server): tools ls, tools call success, isError, 401, invalid --args JSON, --json output shape.
  • Config file is created 0600; the key never appears in stdout/stderr (test it).
  • Manually verified against a local docker compose up instance and against Cloud (put the commands/output, key redacted, in the PR).
  • The backend and frontend tests and lint still pass; docker build . still passes.
  • Docs: packages/cli/README.md + a "CLI" section in docs/api-reference.md.

Out of scope

  • amcp servers ls / connector management: there is no endpoint that lists MCP servers for an API key (/api/mcp-servers is JWT-only, mcp-servers.controller.ts:92). Follow-up: a maintainer-designed read-only endpoint, then the command.
  • OAuth device-flow / browser login, email+password login.
  • Publishing to npm, Homebrew, standalone binaries.
  • Resources and prompts (resources/list, prompts/get), interactive REPL, shell completions.

Size

L (several days, may be split: package skeleton + login/tools ls first, tools call + --json second).

How to claim

Comment "I'd like to work on this" and we'll assign you. Rules in #997.

Activity

  1. helpcodeai commented on Oct 10, 2026

    @helpcodeai
    ContributorAuthor

    @Coding-Professional this is the new issue for the one you are working on, and it is still yours. Leave a short comment here so GitHub lets us assign it to you again. The notes from before, for reference:

    Assigned, thanks, and nice to see you back after MOCO. It's a big one, so feel free to split it like the issue says: package skeleton with login and tools ls first, tools call and --json in a second PR. Two spots where people usually trip: always target /mcp/<serverId> (bare /mcp on Cloud only has the 8 meta-tools), and run docker build . once packages/cli is in the workspaces, because the Dockerfile copies the package.json files one by one. If the in-process fake MCP server for the tests gives you trouble, ask here.

  2. Coding-Professional commented on Oct 11, 2026

    @Coding-Professional
    Contributor

    I'd like to work on this.

  3. helpcodeai commented on Oct 11, 2026

    @helpcodeai
    ContributorAuthor

    @Coding-Professional thanks, it's yours (GitHub won't let me set the assignee field right now, so this comment counts). I've seen #1024, review coming shortly.

  4. Coding-Professional commented on Oct 11, 2026

    @Coding-Professional
    Contributor

    @helpcodeai

    Thanks for assigning this to me! I have raised the PR.

    Looking forward to your feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthacktoberfestGood for Hacktoberfest contributorshelp wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions