mcp2cli is a free, open source api development & testing project written in Python and released under MIT. It has 2,402 GitHub stars, 177 forks and 3 open issues, and was last pushed 6 days ago. On this registry it ranks #94 of 178 tracked projects in API Development & Testing, with 5 head-to-head comparisons available.

What is mcp2cli?

mcp2cli is a Python command-line tool that turns any MCP server, OpenAPI specification, or GraphQL endpoint into an immediately usable CLI at runtime with zero code generation, built for developers and AI coding agents that need to reach those APIs straight from a terminal.

What it is

mcp2cli is a runtime bridge that presents MCP servers, OpenAPI specifications, and GraphQL endpoints as ordinary command-line interfaces. It lives in the Python packaging ecosystem and is distributed on PyPI, with source carrying an MIT licence. Rather than generating client stubs ahead of time, it reads a server's or spec's tool and operation definitions at the moment of invocation and maps them onto subcommands, so the surface a user types is derived live from the remote description instead of checked in as generated code.

The concrete problem it solves is the token and setup cost of tool schemas. As the project frames it, mcp2cli saves 96 to 99 percent of the tokens wasted on tool schemas every turn, and it removes the codegen step that usually stands between a spec and a working client. Instead of hand-writing a wrapper or regenerating stubs whenever an API changes, a developer points mcp2cli at the endpoint and works with it directly. It replaces the ad-hoc per-API client that a team would otherwise build and maintain.

Key capabilities

  • Connects to MCP servers over HTTP and Server-Sent Events with --mcp, and enumerates available tools with --list.
  • Forces a chosen transport with --transport sse, skipping the streamable HTTP fallback negotiation.
  • Searches tools by name or description with --search, a case-insensitive substring match that implies --list and works across --mcp, --spec, --graphql, and --mcp-stdio modes.
  • Handles OAuth across MCP, OpenAPI, and GraphQL modes with --oauth, covering the authorization code plus PKCE flow and the client credentials flow through --oauth-client-id and --oauth-client-secret, with --oauth-scope for scoping.
  • Caches OAuth tokens under ~/.cache/mcp2cli/oauth/ and refreshes them automatically when they expire.
  • Supports headless authorization with --oauth-manual-callback, which prints the authorization URL and reads the redirect back from stdin for machines where no browser runs, such as a VPS over SSH or a container.
  • Accepts secrets through env: and file: prefixes for --auth-header, --oauth-client-id, and --oauth-client-secret, keeping values out of process listings and working with secret managers that inject environment variables, as shown with fnox exec.
  • Ships an installable agent skill through skills.sh that teaches Claude Code, Cursor, and Codex how to discover and call MCP servers and OpenAPI endpoints, and to generate new skills from APIs.

Who uses it and how

  • Developers working in a terminal who need to list and call tools on an MCP server, an OpenAPI-backed service, or a GraphQL endpoint without writing or regenerating a client.
  • AI coding agents such as Claude Code, Cursor, and Codex, after the skill is installed with npx skills add knowsuchagency/mcp2cli --skill mcp2cli, so the agent can discover and call APIs on its own.
  • Operators running mcp2cli on headless hosts, where --oauth-manual-callback lets a login complete by pasting a redirect URL from a browser on another machine.
  • Teams that keep credentials in environment variables or mounted secret files, wiring env: and file: prefixes so tokens never appear in CLI arguments.

Getting started

Run the tool without installing it with uvx mcp2cli --help, or install it globally with uv tool install mcp2cli.

How it compares

No comparable command-line tools are named in the available facts, so mcp2cli stands alone in this registry. Its distinguishing claim is runtime operation with zero codegen, rather than generating a typed client ahead of use.

When to use it — and when not to

A self-hoster must hold OAuth tokens on disk under ~/.cache/mcp2cli/oauth/ and supply credentials for protected endpoints, and OAuth discovery against a local spec file requires passing --base-url so the endpoint can be found. Teams that want a typed, generated client library checked into their repository, rather than an untyped runtime CLI, should look elsewhere. The README excerpt available here is truncated, with the MCP stdio section only partially shown, so some details are not documented on this page.

project readme (upstream, from github) — read inline

mcp2cli — one CLI for every API

mcp2cli

Turn any MCP server, OpenAPI spec, or GraphQL endpoint into a CLI — at runtime, with zero codegen.
Save 96–99% of the tokens wasted on tool schemas every turn.

Read the full writeup →

Install

# Run directly without installing
uvx mcp2cli --help

# Or install globally
uv tool install mcp2cli

AI Agent Skill

mcp2cli ships with an installable skill that teaches AI coding agents (Claude Code, Cursor, Codex) how to use it. Once installed, your agent can discover and call any MCP server or OpenAPI endpoint — and even generate new skills from APIs.

npx skills add knowsuchagency/mcp2cli --skill mcp2cli

After installing, try prompts like:

  • mcp2cli --mcp https://mcp.example.com/sse — interact with an MCP server
  • mcp2cli create a skill for https://api.example.com/openapi.json — generate a skill from an API

Usage

MCP HTTP/SSE mode

# Connect to an MCP server over HTTP
mcp2cli --mcp https://mcp.example.com/sse --list

# Call a tool
mcp2cli --mcp https://mcp.example.com/sse search --query "test"

# With auth header
mcp2cli --mcp https://mcp.example.com/sse --auth-header "x-api-key:sk-..." \
  query --sql "SELECT 1"

# Force a specific transport (skip streamable HTTP fallback dance)
mcp2cli --mcp https://mcp.example.com/sse --transport sse --list

# Search tools by name or description (case-insensitive substring match)
mcp2cli --mcp https://mcp.example.com/sse --search "task"

--search implies --list and works across all modes (--mcp, --spec, --graphql, --mcp-stdio).

OAuth authentication

APIs that require OAuth are supported out of the box — across MCP, OpenAPI, and GraphQL modes. mcp2cli handles token acquisition, caching, and refresh automatically.

# Authorization code + PKCE flow (opens browser for login)
mcp2cli --mcp https://mcp.example.com/sse --oauth --list
mcp2cli --spec https://api.example.com/openapi.json --oauth --list
mcp2cli --graphql https://api.example.com/graphql --oauth --list

# Client credentials flow (machine-to-machine, no browser)
mcp2cli --spec https://api.example.com/openapi.json \
  --oauth-client-id "my-client-id" \
  --oauth-client-secret "my-secret" \
  list-pets

# With specific scopes
mcp2cli --graphql https://api.example.com/graphql --oauth --oauth-scope "read write" users

# Local spec file — use --base-url for OAuth discovery
mcp2cli --spec ./openapi.json --base-url https://api.example.com --oauth --list

Tokens are persisted in ~/.cache/mcp2cli/oauth/ so subsequent calls reuse existing tokens and refresh automatically when they expire.

Headless hosts — no browser on the machine running mcp2cli

The default authorization-code flow starts a callback server on 127.0.0.1, which only works when the browser runs on the same machine. On a VPS over SSH or in a container, add --oauth-manual-callback: mcp2cli prints the authorization URL instead of opening a browser, and reads the redirect back from stdin.

mcp2cli --mcp https://mcp.linear.app/mcp --oauth --oauth-manual-callback --list

Open the printed URL in a browser on any machine, authorize, then paste the URL you land on. That page will fail to load — nothing is listening on the loopback port — which is expected; only its address matters, because it carries the code and state parameters. PKCE and state verification are unchanged, so paste the URL unmodified.

Secrets from environment or files

Sensitive values (--auth-header values, --oauth-client-id, --oauth-client-secret) support env: and file: prefixes to avoid passing secrets as CLI arguments (which are visible in process listings):

# Read from environment variable
mcp2cli --mcp https://mcp.example.com/sse \
  --auth-header "Authorization:env:MY_API_TOKEN" \
  --list

# Read from file
mcp2cli --mcp https://mcp.example.com/sse \
  --oauth-client-secret "file:/run/secrets/client_secret" \
  --oauth-client-id "my-client-id" \
  --list

# Works with secret managers that inject env vars
fnox exec -- mcp2cli --mcp https://mcp.example.com/sse \
  --oauth-client-id "env:OAUTH_CLIENT_ID" \
  --oauth-client-secret "env:OAUTH_CLIENT_SECRET" \
  --list

MCP stdio mode

# List tools from an MCP server
mcp2cli --mcp-stdio "npx @modelcontextprotocol/server-filesystem /tmp" --list

# Call a tool
mcp2cli --mcp-stdio "npx @modelcontextprotocol/server-filesystem /tmp" \
  read-file --path /tmp/hello.txt

# Pass environment variables to the server process
mcp2cli --mcp-stdio "node server.js" --env API_KEY=sk-... --env DEBUG=1 \
  search --query "test"

MCP roots and completion

Expose one or more filesystem roots when a server scopes operations to a workspace. Paths are converted to file:// URIs; explicit roots must also use the file:// scheme.

mcp2cli --mcp-stdio "npx @modelcontextprotocol/server-filesystem /tmp" \
  --root "$PWD" --root file:///var/shared --list

Request prompt-argument or resource-template completions with REF:ARG=PREFIX:

mcp2cli --mcp https://example.com/mcp \
  --complete "greeting:name=San"
mcp2cli --mcp https://example.com/mcp \
  --complete "file:///docs/{topic}:topic=api"

Both options work when starting a persistent session; roots are retained by the session daemon and completion requests can be sent through --session.

OpenAPI mode

# List all commands from a remote spec
mcp2cli --spec https://petstore3.swagger.io/api/v3/openapi.json --list

# Call an endpoint
mcp2cli --spec ./openapi.json --base-url https://api.example.com list-pets --status available

# With auth
mcp2cli --spec ./spec.json --auth-header "Authorization:Bearer tok_..." create-item --name "Test"

# POST with JSON body from stdin
echo '{"name": "Fido", "tag": "dog"}' | mcp2cli --spec ./spec.json create-pet --stdin

# Local YAML spec
mcp2cli --spec ./api.yaml --base-url http://localhost:8000 --list

GraphQL mode

# List all queries and mutations from a GraphQL endpoint
mcp2cli --graphql https://api.example.com/graphql --list

# Call a query
mcp2cli --graphql https://api.example.com/graphql users --limit 10

# Call a mutation
mcp2cli --graphql https://api.example.com/graphql create-user --name "Alice" --email "[email protected]"

# Override auto-generated selection set fields
mcp2cli --graphql https://api.example.com/graphql users --fields "id name email"

# With auth
mcp2cli --graphql https://api.example.com/graphql --auth-header "Authorization:Bearer tok_..." users

mcp2cli introspects the endpoint, discovers queries and mutations, auto-generates selection sets, and constructs parameterized queries with proper variable declarations. No SDL parsing, no code generation — just point and run.

Bake mode — save connection settings

Tired of repeating --spec/--mcp/--mcp-stdio plus auth flags on every invocation? Bake them into a named configuration:

# Create a baked tool from an OpenAPI spec
mcp2cli bake create petstore --spec https://api.example.com/spec.json \
  --exclude "delete-*,update-*" --methods GET,POST --cache-ttl 7200

# Create a baked tool from an MCP stdio server
mcp2cli bake create myfs --mcp-stdio "npx -y @modelcontextprotocol/server-filesystem /tmp" \
  --include "search-*,list-*" --exclude "list-allowed-*"

# Use a baked tool with @ prefix — no connection flags needed
mcp2cli @petstore --list
mcp2cli @petstore list-pets --limit 10
mcp2cli @myfs --list                      # search-files, list-directory, list-directory-with-sizes
mcp2cli @myfs search-files --path /tmp --pattern "**/*.md"   # pattern is a glob, relative to --path

# Manage baked tools
mcp2cli bake list                         # show all baked tools
mcp2cli bake show petstore                # show config (secrets masked)
mcp2cli bake update petstore --cache-ttl 3600
mcp2cli bake remove petstore
mcp2cli bake install petstore             # creates ~/.local/bin/petstore wrapper
mcp2cli bake install petstore --dir ./scripts/  # install wrapper to custom directory

Filtering options:

  • --include — comma-separated glob patterns to whitelist tools (e.g. "list-*,get-*")
  • --exclude — comma-separated glob patterns to blacklist tools (e.g. "delete-*")
  • --methods — comma-separated HTTP methods to allow (e.g. "GET,POST", OpenAPI only)

Configs are stored in ~/.config/mcp2cli/baked.json. Override with MCP2CLI_CONFIG_DIR.

bake show masks the credential values it knows about — the OAuth client secret and every --auth-header value — while leaving env:/file: references readable so the config stays diagnosable. Val

readme truncated — read the full docs on github

Frequently asked questions

Is mcp2cli free to use?

mcp2cli is open source under the MIT licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does mcp2cli do?

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

What is mcp2cli written in?

mcp2cli is primarily written in Python. Its source is publicly available at https://github.com/knowsuchagency/mcp2cli, and it has 2,402 GitHub stars.