Skip to main content

click2mcp

click2mcp turns a Click CLI into a typed MCP server. At startup it walks the command tree and creates one MCP tool per leaf command, using the command's parameter names, types, defaults, and allowed values.

The JSON Schema comes from a function signature. MCPServer.add_tool and Tool.from_function build it with pydantic and do not accept a hand-written inputSchema, so click2mcp gives each command a function whose __signature__ and __annotations__ are the Click parameters themselves.

Install

pip install click2mcp

Quickstart

Add an adapter module to your CLI package:

# src/mycli/mcp/server.py
from click2mcp import ClickMCP
from mycli.main import main as cli

bridge = ClickMCP(app="mycli", cli=cli, module="mycli.main")
mcp = bridge.server


def main() -> None:
    bridge.run()

Expose it as a console script and an optional dependency:

[project.scripts]
mycli-mcp = "mycli.mcp.server:main"

[project.optional-dependencies]
mcp = ["click2mcp>=0.1.0"]

Install the extra, register the server with an MCP client, and run it over stdio. For Claude Code:

claude mcp add mycli -- mycli-mcp

cli can also be a zero-argument callable that returns the root group or None. It is resolved once. If it raises, the server still starts with only the escape hatches. module="mycli.main" is the fallback launcher used when no installed mycli executable can be found.

Configuration

Parameter Default Meaning
app required CLI executable name, tool-name prefix ({app}_{path}), MCP server name, and {app}-mcp program name.
cli required Root click.Group, zero-arg callable returning one, or None.
module None Module passed to python -m when no executable is found. Required if app is not installed and no launcher is given.
instructions generic template MCP server instructions; used verbatim when supplied.
exclude frozenset() Command paths omitted from the typed tools and refused by {app}_run.
include None Command path prefixes to expose; None exposes every leaf outside exclude.
escape_hatches True Register {app}_help and {app}_run.
help_description generic Description override for {app}_help.
run_description generic Description override for {app}_run.
inherit_group_options True Expose options declared on ancestor groups on every leaf tool below them.
launcher None Explicit argv prefix used to run the CLI.
env None Extra child environment variables, merged over the defaults.
invoke None Custom (tokens) -> CompletedProcess[str] runner; shared by typed tools and escape hatches.

The launcher is resolved once, in this order: launcher verbatim, the console script next to the running interpreter, shutil.which(app), then [sys.executable, "-m", module]. If none of them exist, construction raises RuntimeError. The child process gets NO_COLOR=1, TERM=dumb, and PYTHONIOENCODING=utf-8, merged over os.environ and then over env.

Behavior notes

Tool generation. Every leaf command becomes one tool. Spaces and hyphens in the command path turn into _, so mycli browse following users is mycli_browse_following_users, and the description ends with the exact CLI spelling. --groups restricts the typed tools to the named subtrees, written with dots or spaces. An empty entry is rejected.

Escape hatches and inherited options. {app}_help(path) runs --help, and {app}_run(args) runs an arbitrary command line. Set escape_hatches=False to omit both. Only ToolError text reaches the client. Typed tools also expose the options of their ancestor groups, and the generated argv puts each option before the subcommand it belongs to: {app} --verbose sub --profile=x run -- n. A leaf parameter shadows a group option with the same name, the innermost group wins over outer ones, and eager options such as --help and --version are skipped. Set inherit_group_options=False to disable the inheritance.

Prompts and failures. An option declared with prompt= is exposed as required, because the child's stdin is /dev/null and a prompt can never be answered over MCP, even when Click does not mark the option required. A leaf whose parameters cannot be turned into a signature, or whose tool name collides with another command's, is logged and skipped. The rest of the server still starts.

Runtime and exclusions. A call returns when the child exits. There is no server-side timeout, and the child's stdin is /dev/null, so it cannot read the JSON-RPC stream; deciding when to give up is the MCP client's job. Options are passed as one token, --long=value, never --long value, and repeated options are repeated. Positionals follow an end-of-options -- in declaration order, so values that begin with - survive. Full-screen TUIs and endless streams cannot work over MCP. List them in exclude, because nothing here kills a subprocess and {app}_run refuses excluded paths before spawning.

License

MIT

Metadata

Release files for click2mcp 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for click2mcp 0.1.0
File Size Uploaded Provenance Actions
click2mcp-0.1.0.tar.gz 28.3 kB With provenance Details for click2mcp-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for click2mcp 0.1.0
File Interpreter ABI Platform Actions
click2mcp-0.1.0-py3-none-any.whl Python 3 none any Details for click2mcp-0.1.0-py3-none-any.whl

Total release size: 49.3 kB

Release files / click2mcp-0.1.0.tar.gz

Download URL click2mcp-0.1.0.tar.gz
Size 28.3 kB
Tags Source
SHA-256 checksum
How to use checksums
60f4982d0d9d7dc9e89bfa6f2738ba7504a8b6f89103e20da53973111d72d994
BLAKE2b-256 checksum
How to use checksums
982a82d718c3650024cac26fe65905c31bdd9af96a35d3e1623548502e210e81
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.

Transparency log

Release files / click2mcp-0.1.0-py3-none-any.whl

Download URL click2mcp-0.1.0-py3-none-any.whl
Size 20.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
57c4ad2e0a5806d95ef842687964f0473b4aa88012540e619f3e16745cc36fe0
BLAKE2b-256 checksum
How to use checksums
afd6f082842a8dab21bed70c8a33dd8aa67d94206d1a7d094fc976d9d84606da
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.

Transparency log

Security for click2mcp 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for click2mcp-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page