Skip to main content

🐍 MCP Server Starter — Python / FastMCP

Plantilla lista para desarrollar servidores MCP en Python usando FastMCP, con soporte completo para probarlos localmente con MCP Inspector — ya sea via Docker o directamente en tu máquina.


📁 Estructura del proyecto

mcp-python-starter/
├── src/
│   ├── server.py              # Entry point — inicia el servidor (stdio o HTTP)
│   ├── constants.py           # Constantes globales (puerto, URL base, etc.)
│   ├── tools/
│   │   ├── hello.py           # Tools de ejemplo: hello_world, echo
│   │   └── calculator.py      # Tool de ejemplo: calculator
│   └── services/
│       └── api_client.py      # Cliente HTTP asíncrono reutilizable
├── Dockerfile                 # Imagen del servidor MCP
├── docker-compose.yml         # Servidor MCP + MCP Inspector (todo en Docker)
├── docker-compose.dev.yml     # Solo servidor con hot-reload
├── mcp.json                   # Config para MCP Inspector CLI y Claude Code
├── .env.example               # Variables de entorno de ejemplo
└── pyproject.toml             # Dependencias del proyecto

🚀 Inicio rápido

Opción A — Todo en Docker (recomendado para probar rápido)

Levanta el servidor MCP y el MCP Inspector en un solo comando:

cp .env.example .env
docker compose up --build

Luego abre http://localhost:6274 en el browser.

En el Inspector:

  1. Transport → Streamable HTTP
  2. URL → http://mcp-server:8000/mcp (dentro de Docker usa el nombre del servicio)
  3. Click Connect
  4. Ve a la pestaña Tools → List Tools

⚠️ Si corres el Inspector en el host (no en Docker), usa http://localhost:8000/mcp como URL.


Opción B — Servidor en Docker + Inspector en el host

# Terminal 1 — levantar solo el servidor
docker compose -f docker-compose.dev.yml up --build

# Terminal 2 — abrir el Inspector en tu máquina (abre browser automáticamente)
npx @modelcontextprotocol/inspector

En el Inspector: Transport → Streamable HTTP → URL → http://localhost:8000/mcp


Opción C — Sin Docker (virtualenv local)

# Crear entorno virtual e instalar dependencias
python -m venv .venv
source .venv/bin/activate      # Windows: .venv\Scripts\activate
pip install -e .

# Modo HTTP (para MCP Inspector)
TRANSPORT=http python -m src.server

# En otra terminal — abrir el Inspector
npx @modelcontextprotocol/inspector
# → Connect: Streamable HTTP → http://localhost:8000/mcp

🧪 Probar con MCP Inspector CLI

Sin browser, desde la terminal:

# Listar todas las tools disponibles
npx @modelcontextprotocol/inspector --cli \
  --config mcp.json --server my-mcp-server-stdio \
  --method tools/list

# Llamar hello_world
npx @modelcontextprotocol/inspector --cli \
  --config mcp.json --server my-mcp-server-stdio \
  --method tools/call --tool-name hello_world \
  --tool-arg 'params={"name": "Mundo", "language": "es"}'

# Llamar calculator
npx @modelcontextprotocol/inspector --cli \
  --config mcp.json --server my-mcp-server-stdio \
  --method tools/call --tool-name calculator \
  --tool-arg 'params={"a": 10, "b": 3, "operation": "divide"}'

➕ Agregar una nueva tool

  1. Crea src/tools/mi_tool.py:
import json
from mcp.server.fastmcp import Context, FastMCP
from pydantic import BaseModel, ConfigDict, Field

class MiInput(BaseModel):
    model_config = ConfigDict(extra="forbid")
    param: str = Field(..., description="Descripción del parámetro")

def register_mi_tools(mcp: FastMCP) -> None:
    @mcp.tool(
        name="mi_tool",
        annotations={
            "title": "Mi Tool",
            "readOnlyHint": True,
            "destructiveHint": False,
            "idempotentHint": True,
            "openWorldHint": False,
        },
    )
    async def mi_tool(params: MiInput, ctx: Context) -> str:
        """Descripción de la tool — FastMCP la usa como 'description'.

        Args:
            params (MiInput):
                - param (str): Descripción del parámetro

        Returns:
            str: Resultado de la operación.
        """
        await ctx.log_info("mi_tool llamado", {"param": params.param})
        result = {"resultado": f"Procesado: {params.param}"}
        return json.dumps(result, ensure_ascii=False, indent=2)
  1. Regístrala en src/server.py:
from src.tools.mi_tool import register_mi_tools
# ...
register_mi_tools(mcp)
  1. Prueba sin reconstruir (hot-reload activo con docker-compose.dev.yml).

🔌 Transportes disponibles

Transporte Cómo activar Cuándo usar
stdio TRANSPORT=stdio python -m src.server Claude Code, Cursor, integración local
HTTP TRANSPORT=http python -m src.server MCP Inspector web, servidores remotos

🔗 Conectar a Claude Code

# Agregar el servidor (modo stdio)
claude mcp add my-mcp-server python -m src.server

# O editar ~/.claude/mcp.json con la entrada de mcp.json de este repo

⚙️ Variables de entorno

Variable Default Descripción
TRANSPORT stdio stdio o http
PORT 8000 Puerto del servidor HTTP
API_BASE_URL https://api.example.com URL base de tu API
API_TOKEN (vacío) Token Bearer para tu API

🛠️ Características del starter

  • ✅ FastMCP con @mcp.tool decorators
  • ✅ Pydantic v2 para validación de inputs
  • ✅ async/await en todas las tools (con httpx.AsyncClient)
  • ✅ Context injection para logging y progress reporting
  • ✅ Lifespan management para recursos compartidos (DB, caché, etc.)
  • ✅ Doble transporte: stdio y Streamable HTTP
  • ✅ Docker con multi-stage build
  • ✅ Hot-reload en modo desarrollo
  • ✅ MCP Inspector integrado en Docker Compose

📚 Referencias

Metadata

Release files for aws-cost-mcp 1.0.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 aws-cost-mcp 1.0.0
File Size Uploaded
aws_cost_mcp-1.0.0.tar.gz 698.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for aws-cost-mcp 1.0.0
File Interpreter ABI Platform
aws_cost_mcp-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 725.1 kB

Release files / aws_cost_mcp-1.0.0.tar.gz

Download URL aws_cost_mcp-1.0.0.tar.gz
Size 698.8 kB
Tags Source
SHA-256 checksum
How to use checksums
c1d50c566e595209c8a719565b16194c7ab2a4c3369816420be3eb671ba9c7a1
BLAKE2b-256 checksum
How to use checksums
a2c72f7bc4314f754d7fac910d87a068b2631547e817e05c0178419320ceaab9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / aws_cost_mcp-1.0.0-py3-none-any.whl

Download URL aws_cost_mcp-1.0.0-py3-none-any.whl
Size 26.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9ac41b027eff23aeb9cb12b1530a27adf446d02e2338115425b15e9a7f92ae05
BLAKE2b-256 checksum
How to use checksums
80d9612f2d766a5269123f63030357dda17181140e768a880ff16655d7b58734
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

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