Model or dataset
knowsuchagency/mcp2cli avatar
knowsuchagency/mcp2cli

mcp2cli: Turning MCP, OpenAPI and GraphQL Servers into a Runtime CLI

Turn any MCP, OpenAPI, or GraphQL server into a CLI — at runtime, with zero codegen

2,398 stars177 forksPythonMIT

At a glance

What is it?
mcp2cli generates a command line interface from an MCP server, an OpenAPI spec or a GraphQL endpoint without code generation. The approach is convenient and the token argument is plausible, but the README leaves several operational questions open.
Who is it for?
Adopt mcp2cli if you already run MCP servers over stdio or HTTP, or if you frequently need to poke at OpenAPI and GraphQL endpoints from a shell and want OAuth handled for you. Skip it if you need a stable, versioned command surface that you can document and test, because the command set is derived from whatever the remote server currently exposes.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem mcp2cli addresses

An MCP server exposes tools, but a shell has no native way to call them. The usual workaround is to write a small client, or to let an agent load every tool schema into its context on every turn. mcp2cli takes the second problem seriously: the README claims its approach saves 96 to 99 percent of the tokens spent on tool schemas each turn. That number comes from the project's own writeup, not from an independent measurement, so treat it as a stated design goal rather than a verified result. The audience is narrow and identifiable. It is engineers who already have an MCP server, an OpenAPI document or a GraphQL endpoint and want to call it from a terminal without generating and maintaining client code. It is also aimed at coding agents: the README describes an installable skill for Claude Code, Cursor and Codex, installed with npx skills add knowsuchagency/mcp2cli --skill mcp2cli, which lets the agent discover and call APIs through the same binary.

How the runtime CLI is built

There is no generated code and no build step. mcp2cli reads the interface description at call time and turns it into subcommands. In MCP mode it connects to the server, lists tools, and maps each tool name to a command, with tool arguments becoming flags. In OpenAPI mode it reads a spec, either a URL or a local file, and maps operations to commands, with --base-url supplying the host when the spec is local. In GraphQL mode it introspects the endpoint, discovers queries and mutations, and, according to the README, auto-generates a selection set which the --fields flag can override. That last detail matters: an auto-generated selection set is a guess about which fields you want, and --fields is the escape hatch when the guess is wrong. The same discovery model is reused for search. The --search flag does a case-insensitive substring match over tool names and descriptions, implies --list, and works across --mcp, --spec, --graphql and --mcp-stdio. For HTTP MCP servers, the README mentions a streamable HTTP fallback that --transport sse can skip when you already know the transport.

Installation and the four connection modes

The package is on PyPI and the README gives two install paths: uvx mcp2cli --help to run it without installing, or uv tool install mcp2cli for a global install. Four modes cover the supported inputs. HTTP MCP uses --mcp with a URL, stdio MCP uses --mcp-stdio with a command string such as "npx @modelcontextprotocol/server-filesystem /tmp", OpenAPI uses --spec with a URL or a path to JSON or YAML, and GraphQL uses --graphql with an endpoint. A call looks like mcp2cli --mcp https://mcp.example.com/sse search --query "test" or mcp2cli --spec ./openapi.json --base-url https://api.example.com list-pets --status available. For POST bodies, the README shows piping JSON into stdin with echo '{"name": "Fido", "tag": "dog"}' | mcp2cli --spec ./spec.json create-pet --stdin. Static credentials go through --auth-header, and the stdio mode accepts --env API_KEY=... for the child process. Two smaller options round out the surface: --root converts a path to a file:// URI for servers that scope operations to a workspace, and --complete takes a REF:ARG=PREFIX pair for prompt-argument or resource-template completion.

OAuth handling and the secret indirection

OAuth is supported across all three remote modes, and mcp2cli handles token acquisition, caching and refresh. The authorization-code flow with PKCE is the default and opens a browser. The client-credentials flow is for machine-to-machine use and takes --oauth-client-id and --oauth-client-secret. Scopes go in --oauth-scope. Tokens are persisted in ~/.cache/mcp2cli/oauth/, so later calls reuse them and refresh on expiry. The headless case is handled explicitly: the default flow starts a callback server on 127.0.0.1, which only works when the browser runs on the same machine, so on a VPS over SSH or in a container you add --oauth-manual-callback. The tool then prints the authorization URL and reads the redirect back from stdin. The README is honest that the page you land on will fail to load because nothing is listening on the loopback port, and that only the address matters since it carries the code and state parameters. Secrets can avoid the process listing through env: and file: prefixes, as in --auth-header "Authorization:env:MY_API_TOKEN" or --oauth-client-secret "file:/run/secrets/client_secret". The README also shows the pattern with a secret manager that injects environment variables, using fnox exec -- mcp2cli ... with env: references. Note the scope of this feature: the README lists --auth-header values, --oauth-client-id and --oauth-client-secret as the fields that accept the prefixes.

Where the runtime approach breaks down

The central trade-off is that the command surface is not yours. It is derived from a remote description, so a tool rename, a new required parameter or a changed selection set can alter the CLI between two invocations of the same command. There is no generated artifact to review in a pull request and no schema file to pin. If you need a stable interface that you can document, version and test, runtime derivation is the wrong model; a generated client or a hand-written wrapper is the better fit. The GraphQL selection set is a second soft spot. The README says mcp2cli auto-generates it and that --fields overrides it, which implies the default is a heuristic and that you should expect to pass --fields for any query where the fields matter. Authentication is a third limit. The README documents OAuth and static headers, and the env: and file: prefixes are limited to the three named options, so anything outside that set has to be handled by your shell or a wrapper. Finally, the README does not describe retry behaviour, rate limiting, output formatting or exit codes. Those are the details that decide whether a CLI is usable in a script, and their absence from the documentation is a real gap, not a stylistic one.

How this differs from generated clients and curl

The obvious alternative is an OpenAPI generator such as openapi-python-client or openapi-generator, which reads the same spec and emits typed client code. The difference is when the work happens. A generator produces a checked-in artifact that you can review, pin to a spec revision and test, at the cost of a regeneration step every time the API changes. mcp2cli does the opposite: it reads the description at invocation and produces commands on the fly, which means zero build step and always-current commands, but no artifact to review and no compile-time guarantee that a command still exists. For a one-off call against an unfamiliar API, mcp2cli is less work. For a service that must keep working when the upstream API changes, a generated client gives you a diff to look at. Plain curl sits at the other extreme: it is always available and always stable, but it knows nothing about the spec, so you supply the URL, the headers, the body and the OAuth token yourself. mcp2cli's value is that it reads the description for you and, in the OAuth case, manages the token lifecycle.

Licence and maintenance considerations

The project is MIT licensed, which permits commercial use, modification and redistribution provided the copyright notice and permission notice are included. That is the extent of what can be said here; whether the licence fits your organisation's policy is a question for your own review, not for this article. On maintenance, the repository is not archived, the default branch is main, and the last push recorded in the supplied material is 2026-09-09. No releases were retrieved, so there is no version history to reason about and no changelog to check for breaking changes. That is worth weighing: the tool depends on remote descriptions that can change without notice, and without a release history you cannot tell how often the CLI's own behaviour shifts. The token cache in ~/.cache/mcp2cli/oauth/ is a credential store on disk. If you run mcp2cli on a shared host, that directory is part of your secret management surface, and --oauth-manual-callback does not change that; it only changes how the code reaches the tool.

Editorial conclusion

Adopt mcp2cli if you already run MCP servers over stdio or HTTP, or if you frequently need to poke at OpenAPI and GraphQL endpoints from a shell and want OAuth handled for you. Skip it if you need a stable, versioned command surface that you can document and test, because the command set is derived from whatever the remote server currently exposes. Before rolling it out, run mcp2cli --mcp <url> --list against your actual server, then verify that --oauth-manual-callback works on your headless host and that the token cache under ~/.cache/mcp2cli/oauth/ lands on storage you are willing to treat as a credential store.

Official sources

  1. Issues
  2. knowsuchagency/mcp2cli on GitHub
  3. License: MIT
  4. Project website
  5. README
Community notes

Community notes