Skip to main content
Glama
BEST_PRACTICES_EN.md6.09 kB
# BEST_PRACTICES.md > 🛠 **Objective**: Production-oriented FastMCP (SDK v1.10.1) server best practices. Clarify project structure, deployment recommendations, and bypass capabilities all at once to avoid the embarrassment of "runs but hard to maintain". ------ ## 1 · Transport Layer Selection | Scenario | Recommended Transport | Description | | ----------------------- | -------------------------- | ----------------------------------------------- | | Local CLI / IDE Debug | **stdio** | No ports, shortest path | | Web / Multi-client | **Streamable HTTP** | Best compatibility with LB / auth middleware; supports HTTP2 / H2C | | Long connection push | Streamable HTTP + built-in SSE | Auto-upgrade on same path, no additional /sse endpoint needed | ⚠️ Public deployments must implement Host validation or bind to `127.0.0.1` at gateway to prevent DNS rebinding attacks. ------ ## 2 · Directory Structure (Production Template) ```text mcp-server/ ├── server/ # Core Python package (import server) │ ├── __init__.py │ ├── main.py # FastMCP instance & app entry │ ├── config.py # Pydantic Settings / env parsing │ ├── resources/ # All @mcp.resource │ │ ├── __init__.py │ │ └── greeting.py │ ├── tools/ # All @mcp.tool │ │ ├── __init__.py │ │ └── math.py │ ├── prompts/ # All @mcp.prompt │ │ ├── __init__.py │ │ └── echo.py │ ├── routes/ # Bypass REST API │ │ ├── __init__.py │ │ ├── health.py │ │ └── convert.py │ └── static/ # Static resources directory (mounted by StaticFiles) ├── tests/ # pytest & httpx │ ├── __init__.py │ ├── conftest.py │ ├── unit/ # Pure function unit tests │ └── integration/ # End-to-end Streamable HTTP calls ├── scripts/ # Local ops scripts │ ├── start.sh # Unified entry (uvicorn / gunicorn) │ └── migrate.sh # DB / KV migration example ├── configs/ # Config & secret templates (not in Git) │ ├── logging.yml # Structured logging config │ └── .env.example # Environment variable example (.env ➜ docker-compose) ├── deploy/ # Unified deployment directory │ ├── docker/ # Containerization │ │ ├── Dockerfile │ │ └── entrypoint.sh │ ├── kubernetes/ # K8s / Helm Chart │ │ ├── deployment.yaml │ │ └── service.yaml │ └── ci/ # CI/CD (GitHub Actions / GitLab CI) │ └── github/ │ └── workflows/ │ └── ci.yml ├── pyproject.toml # Poetry / PEP 621; lock mcp==1.10.1 ├── README.md # Project overview & quick start └── docs/ # Development / ops documentation ├── QUICKSTART.md ├── BEST_PRACTICES.md └── API_REFERENCE.md ``` ### Directory Key Points | Directory | Purpose / Highlights | | ------------------- | ------------------------------------------------------------ | | **server/** | Code as protocol, layered by resources / tools / prompts; `config.py` unified loading of `os.environ`, avoiding scattered `os.getenv()` | | **routes/** | Only bypass HTTP; keep MCP core clean. | | **tests/** | Unit tests cover pure functions; integration tests directly connect `/mcp` Streamable HTTP, ensuring tools & resources are callable under real protocol. | | **deploy/** | Unified deployment directory containing all deployment configs including containerization, K8s, CI/CD. | | **deploy/docker/** | Independent of source code, any container changes don't pollute server package; `entrypoint.sh` reads `/configs/.env` ➜ generates final config. | | **deploy/kubernetes/** | Decoupled from CI, avoiding Helm over-coupling early projects; add Helm Chart in production. | | **docs/** | Separate **running (QUICKSTART)**, **development (BEST_PRACTICES)**, **interface (API_REFERENCE)** for targeted reading by newcomers. | > ✅ **Practice Rule**: All variable content unrelated to business logic (config / logs / secrets) should always be placed in `configs/` or external volumes. ------ ## 3 · Bypass Capabilities | Need | Approach | | --------------- | ------------------------------------------------------------ | | Health Check | `GET /health`: Return 200 & build sha | | RESTful API | `POST /api/v1/xxx`: Other RESTful API entries | | Static Files | `StaticFiles(directory=server.static)` ➜ `/static` | | Sub-microservice | `from fastapi import APIRouter`; mount `router` to `app.mount("/sub", sub_app)` | > **Naming Suggestion**: Unified bypass routes in `routes/`, filename consistent with HTTP path, search cost = 0. ------ ## 4 · Deployment Tips 1. **Process Model**: Uvicorn Worker ≥ *4* (`--worker-class=uvicorn.workers.UvicornWorker`); IO-intensive suggests 2 × CPU Core. 2. **Logging**: Unified structured JSON ➜ ELK / Loki; no `print()`. 3. **Version Locking**: `mcp==1.10.1`, `fastapi~=0.115.14`; regression test in staging before upgrade. 4. **Security**: - Streamable HTTP endpoint at `/mcp`, other custom APIs don't share cookies; - Public only expose 443 TLS, internal `ClusterIP` communication via H2C. 5. **Monitoring**: Prometheus + OpenTelemetry Exporter; key metrics: `tool_invocation_total`, `tool_latency_seconds`, `resource_hit_total`.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/WW-AI-Lab/Awesome-MCP-Scaffold'

If you have feedback or need assistance with the MCP directory API, please join our Discord server