Calling MCP tools from the terminal with mcp-bin
TL;DR mcp-bin turns the tools of MCP servers into normal CLI commands. You describe the servers in a config file, and every tool becomes a command with flags generated from its schema. Then you can compile everything into a single binary that doesn’t need the config anymore. Install with
brew install volodymyrsmirnov/tap/mcp-bin.
MCP servers are made for AI clients. A lot of useful services have one now, but to use their tools you need an app that speaks MCP. Being a human with a terminal is apparently not enough.
Ideally, I want the following:
- Call any MCP tool from the terminal, like a normal command.
- Use the same commands from shell scripts and from AI agents that can run CLI tools.
- Ship a set of servers as one file, without a config next to it.
How it works
The config lists the servers. A server can be local, started as a process with a command and arguments, or remote with a URL and headers. Values like ${API_KEY} are taken from the environment.
servers:
fetch:
description: "Fetch web content"
command: uvx
args:
- mcp-server-fetch
my-api:
description: "Internal API"
url: https://mcp.example.com
headers:
Authorization: "Bearer ${API_TOKEN}"
notion:
description: "Notion workspace via OAuth2"
url: https://mcp.notion.com/mcp
mcp-bin run --config config.yaml fetch --help
mcp-bin run --config config.yaml fetch fetch --url https://example.com
mcp-bin connects to the server, reads the list of tools and turns each input schema into flags. Strings, numbers and booleans become normal flags, and objects and arrays are passed as JSON. --help works on every level, and --json returns the raw MCP response.
The compile command collects the tool schemas from all servers and packs the config, the tool list and any files you want to embed into a zip archive. The archive is appended to a copy of the mcp-bin binary itself, so the result is one file that works without --config:
mcp-bin compile --config config.yaml --output my-tools
./my-tools fetch fetch --url https://example.com
Environment variables are resolved at compile time, but can still be overridden when the binary runs.
There is also a skill command that generates a Markdown document with all servers, tools and their flags, made for an AI agent to read. With that, an agent can use the compiled binary as a set of CLI tools. So the tools that were made for AI agents become CLI commands, and then get documented back for AI agents. I’m aware of the irony.
OAuth
Some remote MCP servers need OAuth, like Notion, so instead of an API key you get the full browser dance. mcp-bin finds the authorization endpoints from the server itself, opens the browser, runs the flow with PKCE and keeps the tokens in the system keychain (Keychain on macOS, Secret Service on Linux). Expired tokens are refreshed automatically. If the server supports dynamic client registration, the URL is enough, otherwise you add a client ID and secret to the config.
For remote servers, mcp-bin tries the newer Streamable HTTP transport first and falls back to SSE for servers that haven’t moved on yet.
The code is on GitHub.