MCP Server for AWS Cost Explorer — query costs, analyze EC2, detect anomalies, and generate cost reports
Project description
🐍 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:
- Transport → Streamable HTTP
- URL →
http://mcp-server:8000/mcp(dentro de Docker usa el nombre del servicio) - Click Connect
- Ve a la pestaña Tools → List Tools
⚠️ Si corres el Inspector en el host (no en Docker), usa
http://localhost:8000/mcpcomo 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
- 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)
- Regístrala en
src/server.py:
from src.tools.mi_tool import register_mi_tools
# ...
register_mi_tools(mcp)
- 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.tooldecorators - ✅ 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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aws_cost_mcp-1.0.0.tar.gz.
File metadata
- Download URL: aws_cost_mcp-1.0.0.tar.gz
- Upload date:
- Size: 698.8 kB
- Tags: Source
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c1d50c566e595209c8a719565b16194c7ab2a4c3369816420be3eb671ba9c7a1
|
|
| MD5 |
6f40d2aacb17eb7f22684b323352ac4b
|
|
| BLAKE2b-256 |
a2c72f7bc4314f754d7fac910d87a068b2631547e817e05c0178419320ceaab9
|
File details
Details for the file aws_cost_mcp-1.0.0-py3-none-any.whl.
File metadata
- Download URL: aws_cost_mcp-1.0.0-py3-none-any.whl
- Upload date:
- Size: 26.2 kB
- Tags: Python 3
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9ac41b027eff23aeb9cb12b1530a27adf446d02e2338115425b15e9a7f92ae05
|
|
| MD5 |
3c64c178d5cb1368e9d5fa4ff5affd84
|
|
| BLAKE2b-256 |
80d9612f2d766a5269123f63030357dda17181140e768a880ff16655d7b58734
|