mcp-to-cli
v0.5.3
Published
Connect to remote MCP servers from the command line
Readme
mcp-to-cli
MCP servers are great for universal compatibility with agents, but for every coding agent you use, you have to re-connect to each server. Also, if your coding agent doesn't have a good harness for tool search, your MCP servers can unnecessarily eat up a ton of context.
mcp-to-cli fixes this. It's a fully local command-line client that saves named connections to remote MCP servers in one place (~/.mcp-to-cli/). Connect once, use everywhere — any tool that can shell out to a CLI can call MCP tools through it.
Quick start
Run directly with npx:
npx mcp-to-cli@latestOr install as a skill:
npx skills add smithery-ai/mcp-to-cli
claude "use /mcp-cli to connect to https://mcp.deepwiki.com/mcp and tell me about browserbase/stagehand"Use direct CLI
# Install globally
npm i -g mcp-to-cli
# Connect to a server
# (opens browser for OAuth, or ngrok URL for remote setups like OpenClaw)
mcp connect https://mcp.deepwiki.com/mcp --name deepwiki --ngrok
# List what tools are available
mcp deepwiki tools list
# Call a tool (args are validated locally with Zod before sending)
mcp deepwiki tools call ask_question --args '{"repoName":"browserbase/stagehand", "question": "What does this do?"}'What it does
- Connects to remote MCP servers over Streamable HTTP, with SSE fallback.
- Stores named connections locally so you can address a server by name.
- Supports OAuth browser authorization flows for protected servers.
- Lists tool, resource, and prompt capabilities exposed by a server.
- Validates tool arguments locally against each tool's input schema before sending the call.
- Calls tools interactively or with JSON arguments from the command line.
- MCP URLs can be safely guessed via run.tools shortcuts (requires a Smithery account), i.e.
mcp connect notion->mcp connect https://notion.run.tools
Requirements
- Bun 1.3+
- A reachable MCP server URL
NGROK_AUTHTOKENin your environment when using--ngrok
Install
bun installLocal development
bun startWatch mode:
bun devQuality checks
The repository uses Oxc tooling for linting and formatting:
bun fmtformats the codebase withoxfmtand applies autofixableoxlintchanges.bun checkverifies formatting, fails on lint warnings, and runs TypeScript type-checking.
Useful individual commands:
bun run lint
bun run fmt:check
bun run typecheckRelease
This repo now uses release-please to infer version bumps and changelog entries from Conventional Commit messages.
Use release-worthy commit prefixes on changes that should ship:
fix:for patch releasesfeat:for minor releasesfeat!:orfix!:for major releases
On every push to main, GitHub Actions runs release-please and either:
- open or update a release pull request that bumps versions and regenerates
CHANGELOG.md - create a GitHub release and publish to npm after that release pull request is merged
If you need to force a specific version, release-please also supports a Release-As: x.y.z footer in the commit body.
To dry-run the publish locally:
bun install
npm run release:dry-runTo publish manually from an authenticated machine:
npm run releaseRepository setup required:
- add the
NPM_TOKENGitHub Actions secret - use Conventional Commit messages on merge commits or squash commit titles
CLI usage
Top-level help:
bun start --helpSave a connection
mcp connect https://example.com/mcp --name exampleYou can also pass a bare service name instead of a full URL. The CLI resolves it to https://<name>.run.tools (Smithery):
mcp connect linear # → https://linear.run.tools
mcp connect notion # → https://notion.run.toolsPrint the OAuth URL instead of opening a browser:
mcp connect https://example.com/mcp --name example --no-openUse ngrok for OAuth callbacks (useful for OpenClaw/remote setups):
mcp connect https://example.com/mcp --name example --ngrokEquivalent command:
mcp connections add https://example.com/mcp --name example [--no-open]If --name is omitted, the CLI derives a name from the server hostname.
List saved connections
mcp connections listRemove a saved connection
mcp connections remove exampleProfiles
Profiles let you maintain separate sets of connections and credentials. For example, keep work and personal MCP servers isolated, or split staging from production.
Create a profile
mcp profile create work
mcp profile create acme/staging
mcp profile create acme/prodProfiles can be nested — acme/staging and acme/prod are children of acme.
Use a profile
Either pass --profile (or -p) to any command:
mcp --profile work connect https://linear.run.tools
mcp --profile work connections list
mcp -p work linear tools listOr set the MCP_CLI_PROFILE environment variable:
export MCP_CLI_PROFILE=work
mcp connect https://linear.run.tools
mcp connections listResolution order: --profile flag > MCP_CLI_PROFILE env > "default".
List profiles
mcp profile listRemove a profile
mcp profile remove work
mcp profile rm acme --recursiveRemoving a profile deletes its saved connections and auth for that profile. If the profile has child profiles, pass --recursive to remove the whole subtree.
Profile inheritance
Child profiles inherit connections and auth from their parents. For profile acme/staging, the lookup chain is:
default → acme → acme/stagingConnections are merged (child overrides parent for the same name). Auth is resolved from most specific to least specific — if acme/staging doesn't have auth for a connection, it checks acme, then default.
Writes (adding connections, saving auth) always target the current profile only.
Working with a saved server
After a server is saved, address it by connection name:
mcp <connection> <category> <command>Supported categories:
toolsresourcesprompts
Tools
List available tools:
mcp example tools listPaginate and show full descriptions:
mcp example tools list --offset 0 --limit 10 --full-descriptionInspect a tool schema:
mcp example tools get search_docsCall a tool interactively:
mcp example tools call search_docsCall a tool with JSON arguments:
mcp example tools call search_docs --args '{"query":"oauth"}'Return raw JSON output:
mcp example tools call search_docs --args '{"query":"oauth"}' --jsonResources
List resources:
mcp example resources listRead a resource:
mcp example resources get file:///docs/intro.mdPrompts
List prompts:
mcp example prompts listRender a prompt:
mcp example prompts get summarize_releaseOAuth flow
For servers that require OAuth:
- The CLI opens the system browser (or prints the URL if
--no-openwas used). - It listens on a shared local callback server at
http://localhost:8912/<connection>/callback. - If the connection was created with
--ngrok, the redirect URI uses the ngrok URL for that same callback path instead of localhost. - After approval, tokens are stored for the saved connection and reused on future requests.
- Both
--ngrokand--no-openpreferences are saved with the connection and applied automatically on future requests.
Local data
Saved connection metadata and auth state are stored under:
~/.mcp-to-cli/
profiles/
default/
connections.json
auth-<name>.json
work/
connections.json
auth-<name>.json
acme/
staging/
connections.json
auth-<name>.jsonEach profile has its own directory containing:
connections.jsonfor saved serversauth-<name>.jsonfor per-connection OAuth state
Project structure
src/cli.ts Command parsing and user-facing CLI flows
src/client.ts MCP client creation, transport fallback, auth retry logic
src/auth.ts OAuth provider and local callback server
src/config.ts Local storage for saved connections and auth state
index.ts Re-exports for library-style importsContinuous integration
GitHub Actions runs the same checks used locally on pushes and pull requests to main:
- formatting check
- lint with warnings treated as failures
- TypeScript type-checking
