mcp-template
Batteries-included Python template. One codebase ships as a CLI, an MCP server, and an HTTP API over a shared service registry.
Key Features • Architecture • Quick Start • CLI Usage • Adding Commands • Configuration • Deploy • Credits
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
Credits
This software uses the following tools:
- Cursor: The AI Code Editor
- uv
- Typer: CLI framework
- Rich: Terminal formatting
- prek: Rust-based pre-commit framework
- DSPY: Pytorch for LLM Inference
- LangFuse: LLM Observability Tool
About the Core Contributors
Made with contrib.rocks.