Auto-wrap any Click/typer CLI as an MCP (Model Context Protocol) server.
⭐ Star this repo if you use MCP with Python CLIs — it helps others discover click-to-mcp!
Part of the DevForge developer tool ecosystem.
The problem: You have Python CLIs built with Click or typer. Your AI coding agent (Claude Code, Codex, Cursor) needs to call them — but MCP servers require writing boilerplate from scratch.
The old way:
- Create a new Python package for your MCP server
- Define JSON Schema for every tool manually
- Wire up stdio/HTTP transport
- Keep it in sync when your CLI changes
The click-to-mcp way:
pip install click-to-mcp
click-to-mcp serve your-cliOne command. Your CLI is now an MCP server. No boilerplate, no schema writing, no maintenance burden.
Real example: api-contract-guardian has 6 commands with 20+ options. Writing an MCP server for it would take 200+ lines of boilerplate. With click-to-mcp: click-to-mcp serve api-contract-guardian — done.
Works with DevForge CLI tools out of the box — wrap api-contract-guardian, json2sql, deploydiff, or configdrift as MCP servers with zero code changes.
Install directly from GitHub (PyPI coming soon):
pip install git+https://github.com/Coding-Dev-Tools/click-to-mcp.gitOr install via Homebrew (macOS/Linux):
brew tap Coding-Dev-Tools/tap
brew install click-to-mcpOr install via Scoop (Windows):
scoop bucket add Coding-Dev-Tools https://github.com/Coding-Dev-Tools/scoop-bucket
scoop install click-to-mcpFor HTTP+SSE transport (web-based MCP clients), install with the http extra:
pip install "click-to-mcp[http] @ git+https://github.com/Coding-Dev-Tools/click-to-mcp.git"# Discover all Click/typer CLIs installed in your environment
click-to-mcp discover
# List the MCP tools that would be exposed from a CLI (without starting a server)
click-to-mcp list-tools api-contract-guardian
click-to-mcp list-tools --all --json-output # all CLIs, JSON for CI
# Serve a specific CLI as an MCP server (stdio transport)
click-to-mcp serve api-contract-guardian
# Serve over HTTP+SSE (for web-based MCP clients)
click-to-mcp serve-http api-contract-guardian --port 8000
# Or serve the built-in demo
click-to-mcp demo # stdio
click-to-mcp demo-http # HTTP+SSE on port 8000
# Generate MCP client configuration (copy-paste ready JSON)
click-to-mcp config api-contract-guardian
click-to-mcp config api-contract-guardian --client cursor
click-to-mcp config api-contract-guardian --transport http --port 9000
click-to-mcp config --all --client vscodeThen configure your MCP client to connect via stdio or HTTP.
click-to-mcp introspects your Click/typer CLI at runtime and maps every command to an MCP tool:
| Click Concept | MCP Mapping |
|---|---|
@click.command() |
MCP tool |
@click.argument() |
Required input property |
@click.option() |
Optional input property with default |
click.Choice |
JSON Schema enum |
click.INT/FLOAT |
JSON Schema integer/number |
click.BOOL / is_flag |
JSON Schema boolean |
Nested click.Group |
Prefixed tools (e.g. config_show) |
No annotations, no decorators, no boilerplate. Your existing Click CLI is the MCP server.
This section shows how to integrate click-to-mcp with popular AI coding tools so your CLIs become first-class tools that AI agents can invoke directly.
Add your CLI as an MCP server in your project's .claude/settings.json:
{
"mcpServers": {
"api-contract-guardian": {
"command": "click-to-mcp",
"args": ["serve", "api-contract-guardian"]
},
"json2sql": {
"command": "click-to-mcp",
"args": ["serve", "json2sql"]
},
"deploydiff": {
"command": "click-to-mcp",
"args": ["serve", "deploydiff"]
}
}
}Now when you ask Claude Code to "validate my API contracts", it will automatically call the acg_validate MCP tool with the right arguments — no manual command-line invocation needed.
Add to your Cursor MCP settings (.cursor/mcp.json):
{
"mcpServers": {
"api-contract-guardian": {
"command": "click-to-mcp",
"args": ["serve", "api-contract-guardian"]
}
}
}Add to .vscode/mcp.json:
{
"servers": {
"api-contract-guardian": {
"command": "click-to-mcp",
"args": ["serve", "api-contract-guardian"]
}
}
}For CLIs that aren't installed as entry points, use the library API:
# my_mcp_server.py
from click_to_mcp import run
from my_cli import app # Your Click/typer CLI
run(app, prefix="my-cli", name="my-cli-mcp")Then reference the script directly:
{
"mcpServers": {
"my-cli": {
"command": "python",
"args": ["my_mcp_server.py"]
}
}
}When your MCP server is configured, the AI agent sees your CLI commands as native tools. For example, with api-contract-guardian:
Agent: "I need to validate the API contract against the staging server."
→ Calls MCP tool: acg_validate
Arguments: { "spec_file": "openapi.yaml", "base_url": "https://staging.api.com", "strict": true, "output_format": "json" }
← Result: "Validating openapi.yaml against https://staging.api.com...\n✓ All contracts pass"
The agent doesn't need to know shell syntax, argument flags, or command names. It just calls the tool with structured arguments, and click-to-mcp handles the rest.
import click
from click_to_mcp import run
@click.group()
def my_cli():
"""My awesome CLI tool."""
pass
@my_cli.command()
@click.argument("name")
@click.option("--loud", is_flag=True, help="Shout the greeting")
def hello(name: str, loud: bool):
"""Say hello to someone."""
msg = f"Hello, {name}!"
if loud:
msg = msg.upper()
click.echo(msg)
if __name__ == "__main__":
run(my_cli, prefix="my-cli", name="my-cli-mcp")See examples/quick_start.py for the full runnable example.
See examples/api_contract_guardian_mcp.py for a demo showing how to wrap API Contract Guardian as an MCP server with validate, extract, and monitor commands.
# List all installed Click/typer CLIs
click-to-mcp discover
# Serve a specific CLI as an MCP server over stdio
click-to-mcp serve <name>
# Serve over HTTP+SSE (requires pip install "click-to-mcp[http]")
click-to-mcp serve-http <name> --port 8000
# Serve the built-in demo
click-to-mcp demo # stdio
click-to-mcp demo-http # HTTP+SSE
# Version info
click-to-mcp --version# my_cli.py
import click
from click_to_mcp import serve_stdio
@click.group()
def cli():
"""My CLI tool."""
pass
@cli.command()
@click.argument("file")
@click.option("--verbose", is_flag=True)
def validate(file: str, verbose: bool) -> None:
"""Validate a file."""
click.echo(f"Validating {file}...")
# Run as MCP server
serve_stdio(cli, name="my-cli", description="My CLI as MCP server")from click_to_mcp import run
from my_cli import app
# Automatically detects Click/typer instances
run(app, prefix="my-cli")- Auto-discovery:
click-to-mcp discoverscansconsole_scriptsentry points for Click/typer CLIs - Tool preview:
click-to-mcp list-tools <name>shows MCP tools without starting a server (CI-friendly with--json-output) - Client config:
click-to-mcp config <name>generates ready-to-paste JSON for Claude Desktop, Cursor, VS Code, Windsurf, and Cline - Serve any CLI:
click-to-mcp serve <name>wraps any discovered CLI as an MCP server - HTTP+SSE transport:
click-to-mcp serve-http <name>serves over HTTP for web-based clients (v0.3.0+) - Supports both Click and Typer: Full compatibility with both frameworks
- Nested command groups: Handles subcommand groups recursively with prefixed tool names
- Parameter introspection: Correctly maps Click options, arguments, types, enums, defaults, and help text to JSON Schema
- Full MCP protocol: Implements
initialize,tools/list,tools/callover stdio and HTTP+SSE - Health endpoint: HTTP servers expose
/healthfor monitoring and load balancers
Best for local CLI-based MCP clients (Claude Code, Cursor, Cline). No extra dependencies needed.
click-to-mcp serve <name>Best for web-based MCP clients, remote access, and multi-user setups. Requires the [http] extra.
# Install HTTP dependencies
pip install "click-to-mcp[http]"
# Start an HTTP+SSE server
click-to-mcp serve-http <name> --host 127.0.0.1 --port 8000Endpoints:
| Endpoint | Method | Description |
|---|---|---|
/sse |
GET | SSE stream (server-to-client events) |
/messages |
POST | JSON-RPC message endpoint |
/health |
GET | Health check (JSON status) |
Configure your MCP client with the SSE URL:
{
"mcpServers": {
"my-cli": {
"url": "http://127.0.0.1:8000/sse"
}
}
}Click-to-MCP implements the standard MCP protocol with:
initialize— protocol handshake (returns server capabilities)tools/list— discover all CLI commands as MCP tools with JSON Schema inputstools/call— invoke a CLI command with typed arguments
Add an MCP server entry point to any Click/typer CLI:
# cli.py — add a subcommand to run as MCP server
import typer
from click_to_mcp import run
app = typer.Typer(...)
@app.command()
def mcp():
"""Run as an MCP server over stdio."""
from click_to_mcp import run
run(app)Then agents can use it as: your-cli mcp
git clone https://github.com/Coding-Dev-Tools/click-to-mcp
cd click-to-mcp
pip install -e ".[dev,http]"
python -m pytest tests/ -v # 23 tests (12 stdio + 11 HTTP)
click-to-mcp demo # starts MCP stdio server for demo CLI
click-to-mcp demo-http # starts MCP HTTP+SSE server on port 8000click-to-mcp is free and open source under Apache 2.0. No license key required, no rate limits, no telemetry.
It also works with any DevForge CLI tool — even on the free tier.
Apache 2.0
Part of DevForge — developer CLI tools built by autonomous AI agents.