typer-mcp

typer-mcp

Automatically converts any CLI built with Python's Typer into an MCP server without changing code. Gives AI agents instant access to thousands of CLI tools.

Category
Visit Server

README

šŸš€ Typer-MCP

PyPI version Python Versions License: AGPLv3 or Commercial GitHub stars

Instantly convert any Typer CLI into an MCP Server – empower AI agents with your command‑line tools.

🧠 Core idea: Just as FastAPI-MCP lets your APIs talk to AI, Typer-MCP does the same for every CLI you build with Typer. Without changing your original code, your CLI tools become tools that large language models (Claude, Gemini, GPT, …) can call directly.


šŸ“‹ Table of Contents


✨ Features

  • Zero‑intrusion conversion – Turn any Typer CLI into an MCP server without modifying your existing code.
  • Full parameter support – str, int, float, bool, Optional, Enum, list, numeric ranges (min/max), regex patterns, minLength/maxLength, uniqueItems.
  • Nested commands (subgroups) – Fully recursive discovery of commands inside Typer groups.
  • Smart validation – Required/optional parameters, type checking, and JSON Schema generation.
  • Secure subprocess execution – Uses subprocess.Popen with real timeout and process termination (no zombie processes).
  • Environment variable filtering – Only a safe allowlist is exposed; PATH and dangerous vars are blocked by default.
  • Graceful shutdown – Responds to SIGINT/SIGTERM and exits cleanly.
  • Flexible variable naming – Works with any Typer instance name (not just app).
  • Timeout management – Global or per‑command timeout (default 30 seconds) with forced termination.
  • Debug mode – Detailed logs written to stderr for easy troubleshooting.
  • Lightweight – Only depends on typer>=0.12.0 (no extra SDKs).
  • MCP compliant – Implements initialize, tools/list, tools/call, and notifications/initialized.
  • Standalone CLI – Comes with run, list-tools, and version commands.

šŸ“¦ Installation

From PyPI (stable)

pip install typer-mcp

Note: The package does not depend on the official MCP SDK. The JSON‑RPC protocol is implemented natively, keeping the installation lean.

From source (latest)

git clone https://github.com/Darussalamnoor/typer-mcp.git
cd typer-mcp
pip install -e .

For development and testing

pip install -e ".[test,dev]"

šŸš€ Quick Start

  1. Create a normal Typer CLI (my_cli.py)
import typer

app = typer.Typer()

@app.command()
def greet(name: str, excited: bool = False):
    """Greet someone."""
    msg = f"Hello {name}!"
    if excited:
        msg = msg.upper() + "!!!"
    print(msg)

@app.command()
def add(a: float, b: float):
    """Add two numbers."""
    print(f"{a} + {b} = {a + b}")

if __name__ == "__main__":
    app()
  1. Run the MCP server (no code changes)
typer-mcp run --app my_cli:app
  1. Test with an MCP client (e.g., mcp-cli)
pip install mcp-cli
mcp-cli call --server "typer-mcp run --app my_cli:app" \
             --tool greet \
             --args '{"name": "World", "excited": true}'

Output:

HELLO, WORLD!!!!
  1. Connect to Claude Desktop

Edit your Claude Desktop configuration:

Ā· macOS: ~/Library/Application Support/Claude/claude_desktop_config.json Ā· Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "my-typer-cli": {
      "command": "typer-mcp",
      "args": ["run", "--app", "my_cli:app"],
      "env": {}
    }
  }
}

Restart Claude Desktop – your tools (greet, add) will be automatically available.


šŸ› ļø CLI Commands

Command Description Example run Start MCP server for a Typer app typer-mcp run --app my_cli:app list-tools List all discoverable tools without starting the server typer-mcp list-tools --app my_cli:app --format json version Show current version typer-mcp version

run options

Option Description Default --app (required) Import path to Typer instance (e.g., my_cli:app) – --debug / -d Enable debug logging to stderr False --timeout / -t Default tool execution timeout (seconds) 30.0

list-tools options

Option Description Default --app (required) Import path to Typer instance – --format / -f Output format: text or json text


šŸ“– API Documentation

TyperMCP class

The main programmatic entry point.

from typer_mcp import TyperMCP
import typer

app = typer.Typer()
# ... define commands ...

mcp = TyperMCP(app, debug=True, tool_timeout=60.0, app_var_name="app")
mcp.run()  # blocks, starts MCP server

Constructor parameters:

Ā· app (typer.Typer): Your Typer application. Ā· debug (bool, default False): Enable debug logging. Ā· tool_timeout (float, default 30.0): Default timeout for tools. Ā· app_var_name (str, default "app"): Name of the variable that holds the Typer instance. This is automatically extracted from the import path when using the CLI, so you rarely need to set it manually.

Methods:

Ā· run(block: bool = True): Start the MCP server. If block=True (default), it runs forever; if block=False, it runs in a background thread. Ā· get_tools() -> list[MCPTool]: Return a list of MCPTool objects derived from the Typer commands. Ā· version() -> str: Return the library version. Ā· close(): Stop the server gracefully (works only in non‑blocking mode).

Data types (typer_mcp.types)

Ā· ParameterType: Enum with "string", "integer", "number", "boolean", "array", "object", "null". Ā· MCPParameter: Parameter specification (name, type, description, required, default, enum, range, pattern, min/max length, array items, uniqueItems, is_positional). Ā· MCPTool: Contains name, description, and a tuple of MCPParameter. Provides to_schema() and validate_arguments(). Ā· MCPRequest / MCPResponse: JSON‑RPC models following the MCP protocol. Ā· ToolResult: Execution result (content, error flag, stdout, stderr, metadata).

Example:

from typer_mcp import MCPTool, MCPParameter, ParameterType

tool = MCPTool(
    name="calculate",
    description="Multiply two integers",
    parameters=(
        MCPParameter(name="x", type=ParameterType.INTEGER, required=True, minimum=0, maximum=100),
        MCPParameter(name="y", type=ParameterType.INTEGER, required=True),
    )
)
tool.validate_arguments({"x": 5, "y": 10})  # True

šŸ”¬ Advanced Examples

Complex parameters (Enum, list, numeric range)

from enum import Enum
import typer
from click import IntRange

class LogLevel(str, Enum):
    DEBUG = "debug"
    INFO = "info"
    ERROR = "error"

app = typer.Typer()

@app.command()
def process(
    level: LogLevel = typer.Option(LogLevel.INFO, help="Log level"),
    numbers: list[int] = typer.Argument(..., help="List of integers"),
    timeout: int = typer.Option(30, help="Timeout", clamp=IntRange(1, 120))
):
    """Process with advanced parameters."""
    print(f"Level: {level.value}, Numbers: {numbers}, Timeout: {timeout}")

After running typer-mcp run --app my_cli:app, the MCP tools will automatically include:

Ā· level with enum: ["debug", "info", "error"] Ā· numbers with type: "array" and items: {"type": "integer"} Ā· timeout with type: "integer", minimum: 1, maximum: 120

Nested commands (subgroups)

import typer

app = typer.Typer()
user_app = typer.Typer()
app.add_typer(user_app, name="user")

@user_app.command("create")
def user_create(name: str):
    """Create a new user."""
    print(f"User {name} created.")

@user_app.command("delete")
def user_delete(user_id: int):
    """Delete a user by ID."""
    print(f"User {user_id} deleted.")

Tools discovered: user_create and user_delete (with full parameter validation).

Adjust timeout

typer-mcp run --app my_cli:app --timeout 120.0

Debug mode

typer-mcp run --app my_cli:app --debug

Logs appear on stderr.


šŸ“‚ Project Structure

typer-mcp/
ā”œā”€ā”€ src/
│   └── typer_mcp/
│       ā”œā”€ā”€ __init__.py        # Main exports (TyperMCP, helpers)
│       ā”œā”€ā”€ core.py            # TyperMCP class (with non‑blocking support)
│       ā”œā”€ā”€ types.py           # Data models (ParameterType, MCPParameter, ...)
│       ā”œā”€ā”€ converter.py       # Convert Typer app to MCP tools (supports subgroups)
│       ā”œā”€ā”€ server.py          # MCP server (JSON‑RPC) with graceful shutdown
│       ā”œā”€ā”€ utils.py           # SecureProcess, environment sanitization, docstring extraction
│       └── cli.py             # typer-mcp command line tool
ā”œā”€ā”€ tests/                     # Unit tests (pytest)
ā”œā”€ā”€ examples/                  # Example CLI scripts
ā”œā”€ā”€ pyproject.toml             # Project configuration and dependencies
ā”œā”€ā”€ README.md                  # This file
ā”œā”€ā”€ LICENSE                    # Full AGPLv3 text
└── COMMERCIAL-LICENSE         # (Optional) brief explanation of commercial terms

šŸ›”ļø Security & Timeout Handling

Typer-MCP implements enterprise‑grade security measures:

Ā· Environment variable filtering: Only a safe allowlist (HOME, USER, LANG, TZ, TERM, SHELL) is passed to subprocesses. PATH and other dangerous variables are not exposed, preventing injection attacks. Ā· Command argument sanitization: Null bytes and shell metacharacters (;, &, |, ` , $, (, ), <, >) are rejected. Ā· Real timeout with process termination: Uses subprocess.Popen and a custom SecureProcess class. On timeout, the entire process tree is terminated (SIGTERM then SIGKILL), leaving no zombie processes. Ā· Graceful shutdown: The server responds to SIGINT/SIGTERM, finishes the current message, and exits cleanly.

These features make Typer-MCP suitable for production environments where reliability and security are critical.


🧪 Development & Contribution

We welcome contributions! Please follow these steps:

  1. Fork the repository.
  2. Create a feature/bugfix branch:
    git checkout -b feature/your-feature-name
    
  3. Make your changes. Follow PEP 8 and use type hints.
  4. Write tests and run them:
    pip install -e ".[test]"
    pytest tests/ -v
    
  5. Submit a Pull Request to the main branch.

Guidelines:

Ā· All code must pass mypy and ruff checks (config in pyproject.toml). Ā· New features must include tests and documentation. Ā· Use black for formatting.


šŸ› Troubleshooting

  1. ModuleNotFoundError: No module named 'typer_mcp'

Ā· Ensure the package is installed: pip install -e . (in development mode). Ā· Or add the src directory to your PYTHONPATH.

  1. Connection refused or Server not responding in Claude Desktop

Ā· Verify the command path in the Claude Desktop config (use which typer-mcp). Ā· Check Claude Desktop logs (usually ~/Library/Logs/Claude on macOS).

  1. Command times out

Ā· Increase the timeout with --timeout. Ā· If the command inherently takes long, redesign it to work incrementally.

  1. Output contains extra formatting (colors)

Ā· Typer produces colored output by default. To disable colors while running under MCP, set the environment variable NO_COLOR=1.

  1. Tool calls fail with ImportError: cannot import name 'app'

Ā· This means your Typer instance has a different variable name (e.g., cli instead of app). The CLI automatically extracts the correct name from the import path (e.g., my_cli:cli). If you are using the API directly, pass the app_var_name argument to TyperMCP.

For other issues, please open a GitHub Issue.


šŸ“„ Dual License

This project is released under a Dual Licensing model to support both the open‑source community and the author’s ability to earn a living.

  1. Free / Open‑Source License (Non‑commercial, educational, open‑source)

You may use, modify, and distribute the software under the terms of the GNU Affero General Public License version 3 (AGPLv3). The full license text is in the LICENSE file.

Key requirements of AGPLv3:

Ā· Any distribution (including network‑based provision, e.g., SaaS) requires you to release the full source code of your changes. Ā· If you run the software as a web service, end users have the right to receive the source code. Ā· This license is suitable for academic, educational, personal, and open‑source projects.

  1. Commercial License (For companies and closed‑source products)

If you wish to use this library in a commercial product, closed‑source software, or a cloud service where source code is not disclosed to users, you must purchase a separate commercial license from the author.

A commercial license allows you to:

Ā· Use the code in proprietary products without being required to release your source code. Ā· Be exempt from the AGPLv3 obligations (e.g., publishing server‑side source code). Ā· Receive priority support and updates.

To obtain a commercial license and for pricing information, please contact: šŸ“§ mg.gmqmw.rtrt@gmail.com (Please include ā€œCommercial License – Typer-MCPā€ in the subject line.)


šŸ’– Financial Support

We have released this project as free and open‑source for everyone around the world to help the developer community. However, due to unfair sanctions against our beloved country, Iran, common funding methods (such as PayPal, GitHub Sponsors, or Stripe) are not available to us.

If you benefit from this project and would like to support us, please consider one of the following options:

Ā· Send international gift cards (Amazon, Google Play, Apple App Store, Steam, or other gifts you prefer) to the email address below. Ā· Purchase a commercial license for your commercial projects (contact us via email). Ā· Spread the word about the project and star the repository on GitHub.

Email for support and commercial inquiries: šŸ“§ mg.gmqmw.rtrt@gmail.com Please mention the project name (Typer-MCP) and the type of support you wish to provide. We appreciate every contribution, even a small gift card, to continue development, fix bugs, and start new projects.

Thank you for your support ā¤ļø


⭐ If you find this project useful, please give it a star on GitHub!

https://img.shields.io/github/stars/Darussalamnoor/typer-mcp?style=social


Built by Darussalamnoor (sole author and developer)

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured