$git clone https://github.com/knowsuchagency/mcp2climcp2cli 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.
| 1 | <p align="center"> |
| 2 | <img src="https://raw.githubusercontent.com/knowsuchagency/mcp2cli/main/assets/hero.png" alt="mcp2cli — one CLI for every API" width="700"> |
| 3 | </p> |
| 4 | |
| 5 | <h1 align="center">mcp2cli</h1> |
| 6 | |
| 7 | <p align="center"> |
| 8 | Turn any MCP server, OpenAPI spec, or GraphQL endpoint into a CLI — at runtime, with zero codegen.<br> |
| 9 | <strong>Save 96–99% of the tokens wasted on tool schemas every turn.</strong><br><br> |
| 10 | <a href="https://www.orangecountyai.com/blog/mcp2cli-one-cli-for-every-api-zero-wasted-tokens"><strong>Read the full writeup →</strong></a> |
| 11 | </p> |
| 12 | |
| 13 | ## Install |
| 14 | |
| 15 | ```bash |
| 16 | # Run directly without installing |
| 17 | uvx mcp2cli --help |
| 18 | |
| 19 | # Or install globally |
| 20 | uv tool install mcp2cli |
| 21 | ``` |
| 22 | |
| 23 | ## AI Agent Skill |
| 24 | |
| 25 | mcp2cli ships with an installable [skill](https://skills.sh) 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. |
| 26 | |
| 27 | ```bash |
| 28 | npx skills add knowsuchagency/mcp2cli --skill mcp2cli |
| 29 | ``` |
| 30 | |
| 31 | After installing, try prompts like: |
| 32 | - `mcp2cli --mcp https://mcp.example.com/sse` — interact with an MCP server |
| 33 | - `mcp2cli create a skill for https://api.example.com/openapi.json` — generate a skill from an API |
| 34 | |
| 35 | ## Usage |
| 36 | |
| 37 | ### MCP HTTP/SSE mode |
| 38 | |
| 39 | ```bash |
| 40 | # Connect to an MCP server over HTTP |
| 41 | mcp2cli --mcp https://mcp.example.com/sse --list |
| 42 | |
| 43 | # Call a tool |
| 44 | mcp2cli --mcp https://mcp.example.com/sse search --query "test" |
| 45 | |
| 46 | # With auth header |
| 47 | mcp2cli --mcp https://mcp.example.com/sse --auth-header "x-api-key:sk-..." \ |
| 48 | query --sql "SELECT 1" |
| 49 | |
| 50 | # Force a specific transport (skip streamable HTTP fallback dance) |
| 51 | mcp2cli --mcp https://mcp.example.com/sse --transport sse --list |
| 52 | |
| 53 | # Search tools by name or description (case-insensitive substring match) |
| 54 | mcp2cli --mcp https://mcp.example.com/sse --search "task" |
| 55 | ``` |
| 56 | |
| 57 | `--search` implies `--list` and works across all modes (`--mcp`, `--spec`, `--graphql`, `--mcp-stdio`). |
| 58 | |
| 59 | ### OAuth authentication |
| 60 | |
| 61 | APIs that require OAuth are supported out of the box — across MCP, OpenAPI, and GraphQL modes. |
| 62 | mcp2cli handles token acquisition, caching, and refresh automatically. |
| 63 | |
| 64 | ```bash |
| 65 | # Authorization code + PKCE flow (opens browser for login) |
| 66 | mcp2cli --mcp https://mcp.example.com/sse --oauth --list |
| 67 | mcp2cli --spec https://api.example.com/openapi.json --oauth --list |
| 68 | mcp2cli --graphql https://api.example.com/graphql --oauth --list |
| 69 | |
| 70 | # Client credentials flow (machine-to-machine, no browser) |
| 71 | mcp2cli --spec https://api.example.com/openapi.json \ |
| 72 | --oauth-client-id "my-client-id" \ |
| 73 | --oauth-client-secret "my-secret" \ |
| 74 | list-pets |
| 75 | |
| 76 | # With specific scopes |
| 77 | mcp2cli --graphql https://api.example.com/graphql --oauth --oauth-scope "read write" users |
| 78 | |
| 79 | # Local spec file — use --base-url for OAuth discovery |
| 80 | mcp2cli --spec ./openapi.json --base-url https://api.example.com --oauth --list |
| 81 | ``` |
| 82 | |
| 83 | Tokens are persisted in `~/.cache/mcp2cli/oauth/` so subsequent calls reuse existing tokens |
| 84 | and refresh automatically when they expire. |
| 85 | |
| 86 | ### Secrets from environment or files |
| 87 | |
| 88 | Sensitive values (`--auth-header` values, `--oauth-client-id`, `--oauth-client-secret`) support |
| 89 | `env:` and `file:` prefixes to avoid passing secrets as CLI arguments (which are visible in |
| 90 | process listings): |
| 91 | |
| 92 | ```bash |
| 93 | # Read from environment variable |
| 94 | mcp2cli --mcp https://mcp.example.com/sse \ |
| 95 | --auth-header "Authorization:env:MY_API_TOKEN" \ |
| 96 | --list |
| 97 | |
| 98 | # Read from file |
| 99 | mcp2cli --mcp https://mcp.example.com/sse \ |
| 100 | --oauth-client-secret "file:/run/secrets/client_secret" \ |
| 101 | --oauth-client-id "my-client-id" \ |
| 102 | --list |
| 103 | |
| 104 | # Works with secret managers that inject env vars |
| 105 | fnox exec -- mcp2cli --mcp https://mcp.example.com/sse \ |
| 106 | --oauth-client-id "env:OAUTH_CLIENT_ID" \ |
| 107 | --oauth-client-secret "env:OAUTH_CLIENT_SECRET" \ |
| 108 | --list |
| 109 | ``` |
| 110 | |
| 111 | ### MCP stdio mode |
| 112 | |
| 113 | ```bash |
| 114 | # List tools from an MCP server |
| 115 | mcp2cli --mcp-stdio "npx @modelcontextprotocol/server-filesystem /tmp" --list |
| 116 | |
| 117 | # Call a tool |
| 118 | mcp2cli --mcp-stdio "npx @modelcontextprotocol/server-filesystem /tmp" \ |
| 119 | rea |