mcp-template

2

Batteries-included Python template. One codebase ships as a CLI, an MCP server, and an HTTP API over a shared service registry.

Key FeaturesArchitectureQuick StartCLI UsageAdding CommandsConfigurationDeployCredits

Deploy on Railway   Deploy to Render

Project Version Python Version GitHub repo size GitHub Actions Workflow Status


Agent Prompt

Copy and paste this into your AI coding agent (Claude Code, Cursor, Copilot, etc.) to install:

Install the CLI and download the usage skill:

pip install mcp-template

curl -fsSL https://raw.githubusercontent.com/Miyamura80/MCP-Template/main/scripts/install-skills.sh -o install-skills.sh
bash install-skills.sh && rm install-skills.sh

App Distribution

  • MCP server with OAuth
  • Claude and ChatGPT connectors
  • APIs and SDKs
  • Chat interfaces like iMessage and WhatsApp
  • A dashboard that uses the same MCP layer
  • Open source

Key Features

Feature Stack
CLI (auto-discovery commands, global flags, shell completions, self-update) Typer
MCP server (streamable HTTP at /mcp, services auto-registered as tools; stdio supported for local dev) FastMCP
HTTP API server (also hosts /mcp) FastAPI + Uvicorn
Auth WorkOS + API keys
Payments Stripe
Database + migrations SQLAlchemy + Alembic
Config (YAML + .env) Pydantic-settings
LLM inference + observability DSPY + LiteLLM + LangFuse
Testing pytest + TestTemplate
Lint / type / dead-code Ruff + Vulture + ty + import-linter
Pre-commit (folder size, ai-writing, agent-config sync) prek
Agent loop Ralph Wiggum
Telemetry Anonymous, opt-out

Architecture

One codebase, three interfaces. Write business logic once in services/ and it ships as a CLI subcommand, an MCP tool, and an HTTP route - same Pydantic input/output contract everywhere.

┌──────────────┐  ┌──────────────┐  ┌──────────────┐
│ src/cli/app  │  │ mcp_server/  │  │ api_server/  │   transport / interface
│  (Typer)     │  │ (FastMCP)    │  │ (FastAPI)    │
└──────┬───────┘  └──────┬───────┘  └──────┬───────┘
       │                 │                 │
       └─────────────────┼─────────────────┘
                         ▼
                 ┌───────────────┐
                 │  services/    │   pure @service functions
                 │  @service     │   (transport-agnostic)
                 └───────┬───────┘
                         ▼
                 ┌───────────────┐
                 │  models/      │   Pydantic I/O contracts
                 └───────┬───────┘
                         ▼
        ┌────────────┬───────┬────────────┬─────────────┐
        │ common/    │ db/   │ utils/llm/ │ src/utils/  │   shared infra
        │ (config)   │ (ORM) │ (DSPY)     │ (logs/theme)│
        └────────────┴───────┴────────────┴─────────────┘

MCP UI (optional)

Need elicitation, image output, or an iframe dashboard for an MCP tool? Add an opt-in enhancer in mcp_server/enhancers/. Enhancers wrap a service for the MCP transport only - the pure service stays untouched and CLI/API consumers are unaffected.

See mcp_server/MCP_UI_ARCHITECTURE.md for the full design.

Quick Start

make onboard              # interactive setup (rename, deps, env, hooks)
uv sync                   # install deps
uv run mymcp --help       # see all CLI commands
uv run mymcp greet Alice  # run a command
uv run mymcp init my_command  # scaffold a new command

uv run mymcp-serve        # start the server (HTTP API + MCP at /mcp on one port)
uv run mymcp-mcp          # legacy: stdio MCP only, for local Claude Desktop / dev

Deploy

One-click deploy to Railway or Render (backend + managed Postgres, migrations run automatically). See deployment docs for the per-platform setup, the Railway template variable map, and OAuth/secret wiring.

CLI Usage

Global flags go before the subcommand:

Flag Short Description
--verbose -v Increase output verbosity
--quiet -q Suppress non-essential output
--debug Show full tracebacks on error
--format -f Output format: table, json, plain
--dry-run Preview actions without executing
--version -V Print version and exit
uv run mymcp --format json config show     # JSON output
uv run mymcp --dry-run greet Bob           # preview without executing
uv run mymcp --verbose greet Alice         # detailed output

Adding Commands

Drop a Python file in src/cli/commands/ and it is auto-discovered.

Single command - export a main() function:

# src/cli/commands/hello.py
from typing import Annotated
import typer

def main(name: Annotated[str, typer.Argument(help="Who to greet.")]) -> None:
    """Say hello."""
    typer.echo(f"Hello, {name}!")
uv run mymcp hello World   # Hello, World!

Subcommand group - export app = typer.Typer():

# src/cli/commands/db.py
import typer

app = typer.Typer()

@app.command()
def migrate() -> None:
    """Run migrations."""
    ...
uv run mymcp db migrate

Or scaffold with: uv run mymcp init my_command --desc "Does something".

Configuration

from common import global_config

# Access config values from common/global_config.yaml
global_config.example_parent.example_child

# Access secrets from .env
global_config.OPENAI_API_KEY

CLI config inspection:

uv run mymcp config show                           # full config
uv run mymcp config get llm_config.cache_enabled   # single value
uv run mymcp config set logging.verbose false      # write override

Full configuration docs

Credits

This software uses the following tools:

About the Core Contributors

Made with contrib.rocks.