source-code
MCP-ecosystem CLI adapter — convert MCP servers into discoverable, scriptable CLI tools.
Install / Use
claude mcp add mcp2cli -- npx -y github:mcp2cli/source-codeIf the server publishes to npm under a different name, use that package instead — check the repo README.
MCP Server
Model Context Protocol server
Quality Score
Category
Development & EngineeringSupported Platforms
Tags
Skill content
View source on GitHubmcp2cli
Turn any MCP server into a native command-line application.
Server tools become verbs. Resources become nouns. Prompts become workflows. No MCP protocol knowledge required at the terminal.
# One binary. Any server. Real CLI commands.
email ls
email send --to user@example.com --subject "Hi" --body "Meeting at 3"
email get mail://inbox
staging deploy --version 2.1.0 --background
prod --json doctor | jq '.data.server'
Why mcp2cli?
MCP (Model Context Protocol) defines a powerful standard for servers to expose tools, resources, and prompts. But interacting with an MCP server requires JSON-RPC plumbing, session negotiation, and protocol-level knowledge — none of which belongs in a CLI.
mcp2cli bridges that gap:
| Problem | mcp2cli |
|---------|---------|
| MCP requires JSON-RPC plumbing | Auto-discovers capabilities → typed --flags from JSON Schema |
| Testing MCP servers needs custom client code | Point, shoot: mcp2cli --url http://localhost:3001/mcp ls |
| Each server needs its own CLI wrapper | One binary + config files = unlimited server bindings |
| AI agents can't easily call MCP tools from shell | --json output → structured envelopes for programmatic parsing |
| CI/CD can't orchestrate MCP operations | Exit codes, JSON output, pipes, --timeout, --background |
| Server tools have cryptic protocol names | Profile overlays rename, group, and hide commands |
Quick Start
Install
cargo install --path .
Option A: Ad-hoc — zero config
# HTTP server — just point and go
mcp2cli --url http://127.0.0.1:3001/mcp ls
mcp2cli --url http://127.0.0.1:3001/mcp echo --message hello
# Stdio server — just run
mcp2cli --stdio "npx @modelcontextprotocol/server-everything" ls
Option B: Named config + alias
# Create a config
mcp2cli config init --name email --app bridge \
--transport streamable_http --endpoint https://mcp.example.com/email
# Create a symlink alias
mcp2cli link create --name email
# Authenticate (the email server needs a bearer token)
email auth login
# Use it like a standalone app
email ls # Discover capabilities
email send --to user@example.com \
--subject "Hi" --body "Meeting at 3" # Call a tool
email search --query "from:boss" # Search the mailbox
email get mail://inbox # Read a resource
email doctor # Health check
Option C: Demo mode — no server needed
mcp2cli config init --name demo --app bridge \
--transport streamable_http --endpoint https://demo.invalid/mcp
mcp2cli use demo
mcp2cli ls
How It Works
mcp2cli discovers → builds manifest → generates CLI → parses input → executes MCP call
- Discovers the server's tools, resources, resource templates, and prompts
- Builds a command manifest — each capability becomes a typed command with flags derived from JSON Schema
- Generates a clap CLI tree — dotted names become nested subcommands, required fields become required flags
- Parses your input against the generated tree with full type validation
- Executes the MCP operation and renders the result
Schema-to-flag mapping
| JSON Schema | CLI flag | Example |
|-------------|----------|---------|
| string | --name <TEXT> | --message hello |
| integer | --count <INT> | --steps 5 |
| number | --rate <NUM> | --temperature 0.7 |
| boolean | --flag | --include-image |
| enum | --kind <A\|B\|C> | --level error |
| array | --tags <VAL,...> | --labels bug,urgent |
| Complex | --config <JSON> | --config '{"a":1}' |
Namespace grouping
Dotted tool names automatically become nested subcommands:
# Server tools: send, reply, draft.create
email send --to user@example.com --subject "Hi" --body "Hello"
email reply --thread-id 123 --body "Thanks"
email draft create --subject "New draft"
Features at a Glance
Core
- Discovery-driven CLI — server capabilities auto-generate typed CLI commands with
--flagsfrom JSON Schema - Named configs & aliases —
mcp2cli use <name>, symlink aliases (email,prod,staging), dispatch routing - Profile overlays — rename, hide, group, alias commands; rename flags; change resource verbs
- Ad-hoc connections —
--urland--stdiofor config-free, zero-setup usage - Fuzzy matching — "Did you mean?" suggestions for mistyped commands
Transports
- Streamable HTTP — JSON-RPC over HTTP with SSE streaming and session negotiation
- Stdio — spawn local subprocess servers, communicate via stdin/stdout
- Demo mode —
demo.invalidfile-backed backend for offline learning and testing
Protocol Coverage
Full dual-revision implementation of the Model Context Protocol — MCP 2026-07-28 (stateless, per-request _meta, server/discover, MRTR, the tasks extension) and MCP 2025-11-25 (initialize handshake, sessions). By default mcp2cli probes with server/discover and falls back to the legacy handshake automatically, exactly as the 2026-07-28 backward-compatibility rules describe; pin either revision with server.protocol_version. See the Protocol Coverage reference for per-feature, per-revision detail, source pointers, and CLI examples.
| Category | 2025-11-25 | 2026-07-28 | mcp2cli surface |
|---|---|---|---|
| Lifecycle | initialize + notifications/initialized, ping | stateless _meta on every request, server/discover | One handshake or probe per session; ping works in both (maps to server/discover on modern servers) |
| Discovery | tools/list, resources/list, resources/templates/list, prompts/list + notifications/*/list_changed | same lists + ttlMs/cacheScope freshness hints | ls populates a persistent cache; list-change notifications / TTL hints keep it fresh |
| Tool invocation | tools/call | tools/call + resultType, MRTR retries, x-mcp-header → Mcp-Param-* mirroring | Typed clap flags from JSON Schema; progress token attached automatically |
| Resources | resources/read, resources/subscribe/unsubscribe | resources/read (MRTR-capable), subscriptions/listen | get <URI> for concrete reads; subscribe verifies the era-appropriate subscription |
| Prompts | prompts/get | prompts/get (MRTR-capable) | Each prompt becomes a command with typed argument flags |
| Completions | completion/complete with ref.context | same | complete command with ref context (resource or prompt) |
| Logging | logging/setLevel, notifications/message | per-request _meta["…/logLevel"] | log <LEVEL> works in both; the level persists and is injected per-request on modern servers |
| Progress | notifications/progress + _meta.progressToken | same (request-scoped stream) | Progress tokens auto-attached; ticks rendered to stderr or event sinks |
| Cancellation | notifications/cancelled (bidirectional) | notifications/cancelled (stdio) / closing the response stream (HTTP) | Ctrl+C cancels the in-flight request |
| Server input (elicitation/sampling/roots) | server-initiated JSON-RPC requests | MRTR: resultType: "input_required" + retry with inputResponses | Same interactive terminal prompts in both revisions |
| Tasks | experimental core (_meta.task, tasks/get/result/cancel) | official io.modelcontextprotocol/tasks extension (resultType: "task", polled tasks/get, tasks/update) | --background creates a task; jobs show/wait/cancel/watch tracks it; unsolicited modern tasks are polled transparently |
Operations
- Authentication —
auth login/logout/statuswith file-backed token persistence - Event system — 5 sink types: stderr, HTTP webhook, Unix socket, SSE server, command exec
- Output formats —
--json,--output json|ndjson|human— every command supports structured output - Request timeouts — global default + per-command
--timeoutoverride - Daemon mode — keep MCP connections warm between invocations (Unix socket IPC)
- Doctor & Inspect — runtime health diagnostics, full capability dump
Multi-Server Workflow
Each alias routes to a different MCP server. Each feels like its own standalone application.
# Set up multiple servers
mcp2cli config init --name dev --transport stdio --stdio-command ./dev-server
mcp2cli config init --name staging --transport streamable_http --endpoint https://staging.api/mcp
mcp2cli config init --name prod --transport streamable_http --endpoint https://prod.api/mcp
# Create aliases
mcp2cli link create --name dev
mcp2cli link create --name staging
mcp2cli link create --name prod
# Each alias is its own CLI
dev ls # Local dev server
staging deploy --version 1.2.3 # Staging HTTP server
prod doctor # Production health check
JSON Output for Scripts & Agents
Every command supports structured JSON output:
# JSON envelope
email --json ls | jq '.data.items[].id'
# Tool result
email --json send --to user@example.com --subject "Hi" --body "Hello" | jq '.data.content[0].text'
# Health check data
email --json doctor | jq '.data.server'
# Machine-readable discovery
email --json ls --tools | jq '[.data.items[] | {id, kind, summary}]'
Consistent envelope format:
{
"app_id": "email",
"command": "invoke",
"summary": "called send",
"lines": ["..."],
"data": { "content": [...] }
}
Profile Overlays
Customize the CLI surface per-server — no server changes needed:
profile:
display_name: "Email CLI"
aliases:
long-running-operation: lro # Rename commands
echo: ping
hide:
- debug-tool # Hide from help/ls
groups:
mail: # Custom grouping
- send
- reply
- draft-create
flags:
echo:
message: msg # Rename flags
resource_verb: fetch # "fetch" instead of "get"
Config Model
Each named config is a YAML file. Minimal example:
schema_version: 1
server:
transport: streamable_http
endpoint: http://localhost:3001/mcp
Full example with all options:
schema_version: 1
app:
profile: bridge
server:
display_name: My MCP Server
transport: stdio # or streamable_http
endpoint: null # required for streamable_http
protocol_version: auto # auto | 2026-07-28 | 2025-11-25
stdio:
command: npx
args: ['@modelcontextprotocol/server-everything']
roots:
- uri: "file:///home/user/project"
name: "Project Root"
defaults:
output: human # human | json | ndjson
timeout_seconds: 120 # 0 = no timeout
logging:
level: warn
format: pretty
outputs:
- kind: stderr
auth:
browser_open_command: null
events:
enable_stdio_events: true
# http_endpoint: "http://127.0.0.1:9090/events"
# local_socket_path: "/tmp/mcp2cli-events.sock"
# sse_endpoint: "127.0.0.1:9091"
# command: "logger -t mcp2cli '${MCP_EVENT_MESSAGE}'"
prof
Truncated for display — read the full file on GitHub.
Related Skills
Agent-Reach
78.6kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu — one CLI, zero API fees.
ruflo
71.2k🌊 The original agent meta-harness. Deploy intelligent multi-player swarms, coordinate autonomous workflows, and build conversational AI systems. Features adaptive memory, self-learning intelligence, RAG integration, and native Claude Code / Codex / Hermes and many more Integrated
headroom
69.4kCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.
CowAgent
46.8kOpen-source super AI assistant & Agent Harness. Plans tasks, runs tools and skills, self-evolves with memory and knowledge. Multi-model, multi-channel. Lightweight, extensible, one-line install. (formerly chatgpt-on-wechat)
