Skip to main content
Glama
srmcguirt

FastMCP Python Boilerplate

by srmcguirt

FastMCP Python Boilerplate

Production-ready FastMCP Python boilerplate for building MCP servers that work with Claude, GPT, Cursor, and any MCP-compatible agent.

What's included

  • FastMCP server setup with proper tool schemas

  • Pydantic v2 config validation — reads from .env, never hardcodes secrets

  • Token-bucket rate limiter — thread-safe, per-client windows

  • structlog to stderr — structured logging that doesn't break MCP protocol framing

  • pytest suite, 36 tests — config, rate limiter, tools, and a subprocess-level check that stdout never carries anything but JSON-RPC

Docker packaging, CI, pre-commit, and the Claude Desktop config ship with the full package.

Related MCP server: MCP Server Template (Python)

The stdout/stderr gotcha

MCP uses stdout for JSON-RPC frames. Any print() that lands on stdout corrupts the protocol — the client sees malformed JSON and either drops the message or errors out. All logging goes to stderr.

This boilerplate has it wired by default:

import structlog, sys
structlog.configure(logger_factory=structlog.PrintLoggerFactory(file=sys.stderr))

Quick start

git clone https://github.com/srmcguirt/fastmcp-python-boilerplate
cd fastmcp-python-boilerplate
cp .env.example .env
pip install -r requirements.txt
python server.py

Structure

fastmcp-python-boilerplate/
├── mcp_server/
│   ├── __main__.py        # Entrypoint: python -m mcp_server
│   ├── server.py          # FastMCP server + example tools
│   ├── config.py          # Pydantic v2 settings (reads from .env)
│   ├── logger.py          # structlog wired to stderr
│   └── rate_limiter.py    # Thread-safe token bucket
├── tests/
│   ├── test_config.py
│   ├── test_rate_limiter.py
│   ├── test_server.py
│   └── test_logging_stdout_purity.py   # proves stdout stays JSON-RPC only
├── .env.example
├── pyproject.toml
└── LICENSE

Everything above is MIT licensed and runs as-is. pytest passes 36 tests, including a suite that spawns a subprocess and asserts at the file-descriptor level that no log output ever reaches stdout.

Get the Full Boilerplate

The free core above is a working server with the patterns wired up.

The full $35 package adds the deployment layer:

  • Multi-stage Dockerfile with health check, non-root user

  • Docker Compose with env file support

  • Three real tool implementations beyond the examples here

  • Per-tool rate limits with configurable burst

  • Request ID tracing through the structlog pipeline

  • Integration tests against a mocked MCP client

  • Pre-commit hooks (ruff, mypy)

  • GitHub Actions CI workflow

  • Claude Desktop + Claude Code config

  • Deployment guide with troubleshooting

-> Get FastMCP Python Boilerplate — $35

Full lineup: srmcguirt.dev

License

MIT — use it in production, keep it if you never buy anything.

Available Tools

2 tools
calculateA

Safely evaluate a simple arithmetic expression and return the result.

Supported: +, -, *, /, //, %, ** and parentheses. No function calls, variables, or imports are allowed.

Examples: "2 + 2" → 4.0 "10 / 3" → 3.3333... "(3 + 4) * 2" → 14.0 "2 ** 8" → 256.0

ParametersJSON Schema
NameRequiredDescriptionDefault
expressionYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It explicitly states the operation is safe, enumerates supported operators, and prohibits function calls, variables, and imports, effectively communicating that no arbitrary code execution occurs. It does not cover error behavior or division-by-zero handling, but the core safety behavior is well disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded with the purpose, follows with supported operations and restrictions, and uses examples to clarify expected behavior. Every sentence contributes useful information without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter calculator with an output schema, the description is sufficiently complete: it defines valid inputs, supported operations, restrictions, and example outputs. No critical information is missing for an agent to select and invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema provides only a string type with no description, so the description must compensate. It does so thoroughly by defining what the 'expression' parameter must be, supported operators, syntax rules, and concrete examples. This is exactly the meaning the schema lacks.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific verb ('evaluate') and resource ('simple arithmetic expression') and indicates the result is returned. It differentiates from sibling tool 'echo' by emphasizing evaluation rather than echoing, and lists supported operations to remove ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear boundaries for what expressions are valid (arithmetic only, no function calls, variables, or imports), so the intended use is implied. However, it does not explicitly mention when to prefer this tool over the sibling 'echo' or what types of tasks should not use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

echoA

Return text unchanged — useful for round-trip testing.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden of behavioral disclosure. It clearly states the tool returns the input unchanged, implying a pure, side-effect-free operation. It does not discuss error behavior or formatting, but for an echo tool the core behavior is fully disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence says exactly what the tool does and why it is useful. There is no redundancy or extraneous information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter echo tool with an output schema present, the description covers the core behavior and intended use case adequately. No additional context about return values is needed because the behavior is fully implied by 'unchanged' and the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has no property descriptions, so the description must compensate. The phrase 'Return *text* unchanged' implicitly references the 'text' parameter and conveys that it is echoed back, but it does not add explicit details like examples, constraints, or formatting. The single, self-explanatory parameter reduces the need for more.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Return') and resource ('text'), clearly stating the behavior is to return the input unchanged. It also names the use case (round-trip testing), making it easy to distinguish from the sibling tool 'calculate'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'useful for round-trip testing' gives an implied use case, but it does not explicitly state when to choose this tool over 'calculate' or when not to use it. There is minimal routing guidance, just enough to hint at its purpose.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

TDQS

A4.2/5.0
Disambiguation5/5

echo and calculate have entirely distinct purposes—one returns text unchanged and the other evaluates arithmetic expressions. There is no overlap or possibility of confusion between them.

Naming Consistency5/5

Both tools use simple, lowercase imperative verb names (echo, calculate), creating a consistent naming style. While there is no verb_noun pattern, the convention is uniform across the set.

Tool Count3/5

With only two tools, the server feels thin and provides minimal functionality. This is borderline but acceptable for a boilerplate template meant to demonstrate basic MCP tool patterns.

Completeness4/5

For the server's apparent purpose as a Python MCP boilerplate, the tool surface covers round-trip testing and simple computation with no obvious gaps. A few more demonstration tools could improve coverage, but nothing essential is missing.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Production-ready API server template integrating FastAPI with Model Context Protocol (MCP) for LLM integration, structured logging, and comprehensive testing.
    2
  • A
    license
    Not graded
    quality
    D
    maintenance
    A minimal, well-structured starter template for building Model Context Protocol (MCP) servers using Python and the FastMCP framework. It includes boilerplate for tools, testing setup, and modern Python packaging to accelerate server development.
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    A production-ready foundation for building secure, observable MCP servers with built-in authentication, rate limiting, and reference tools like database-query and semantic-search.
    15
    37
    MIT

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/srmcguirt/fastmcp-python-boilerplate'

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