CtrlK
BlogDocsLog inGet started
Tessl Logo
SkillPublic

fastmcp

Provides up-to-date FastMCP API patterns for tools, resources, prompts, server composition, authentication, and deployment. Use when the user asks to "create an MCP server", "build an MCP tool", "add an MCP resource", "define MCP prompts", "set up FastMCP", "run an MCP server", "expose tools via MCP", "mount MCP sub-servers", "configure MCP transport", "add authentication to MCP", "test an MCP server", "use the MCP client", or when writing any Python code that uses the fastmcp package. Does not cover the MCP protocol spec, the TypeScript MCP SDK, or configuring MCP servers in Claude Code settings.

75

Quality

94%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide
SecuritybySnyk

Passed

No findings from the security scan

SKILL.md
Quality
Evals
Security

FastMCP Server Development

This skill covers the core FastMCP API for building production-ready MCP servers.

Server Initialization

Install with uv add "fastmcp>=4" (or pip install "fastmcp>=4"); this skill targets fastmcp 4.x.

from fastmcp import FastMCP

mcp = FastMCP(
    name="MyServer",
    instructions="A helpful server for data processing",
    version="1.0.0",
)
  • name — display name for the server.
  • instructions — system-level guidance for the client connecting to this server.
  • version — semantic version string.

Tools

Tools are functions that the client can invoke. Decorate with @mcp.tool.

Basic tool

@mcp.tool
def add(a: int, b: int) -> int:
    """Add two numbers together."""
    return a + b

FastMCP auto-generates the JSON schema from the function signature and docstring. The docstring becomes the tool description shown to the client.

Async tool

import httpx

@mcp.tool
async def fetch_data(url: str) -> dict:
    """Fetch JSON data from a URL."""
    async with httpx.AsyncClient() as client:
        response = await client.get(url)
        return response.json()

Custom name and description

@mcp.tool(name="multiply", description="Multiply two numbers")
async def multiply_numbers(x: float, y: float) -> float:
    return x * y

Structured input with Pydantic

from pydantic import BaseModel

class SearchQuery(BaseModel):
    query: str
    max_results: int = 10
    include_metadata: bool = False

@mcp.tool
def search(params: SearchQuery) -> list[dict]:
    """Search with structured parameters."""
    return [{"result": f"Found for: {params.query}"}]

Use Pydantic models when a tool has more than 3-4 parameters or when validation is needed.

Context object

The Context parameter provides logging, progress reporting, and access to lifespan resources:

from fastmcp.server.context import Context

@mcp.tool
async def process_files(file_paths: list[str], ctx: Context) -> dict:
    """Process multiple files with progress reporting."""
    total = len(file_paths)
    await ctx.info(f"Starting to process {total} files")

    for i, path in enumerate(file_paths):
        await ctx.report_progress(i, total, f"Processing {path}")
        try:
            # process file...
            pass
        except Exception as e:
            await ctx.error(f"Failed to process {path}: {e}")

    await ctx.report_progress(total, total, "Complete")
    return {"processed": total}

Context methods:

  • ctx.info(msg), ctx.debug(msg), ctx.warning(msg), ctx.error(msg) — structured logging.
  • ctx.report_progress(progress, total, message) — progress updates.
  • ctx.lifespan_context — dict of resources from the lifespan handler.

Add ctx: Context as any parameter — FastMCP injects it automatically (it is not exposed to the client).

Resources

Resources expose data that the client can read. Decorate with @mcp.resource.

Static resource

@mcp.resource("config://settings")
def get_settings() -> str:
    """Return application settings."""
    return "debug=true\nlog_level=INFO"

JSON resource

@mcp.resource("data://report", mime_type="application/json")
def get_report() -> dict:
    """Return JSON data (automatically serialized)."""
    return {"users": 150, "active": 42}

Dynamic resource template

Use {parameter} in the URI for parameterized resources:

@mcp.resource("users://{user_id}/profile")
async def get_user_profile(user_id: str) -> dict:
    """Fetch user profile by ID."""
    return {"id": user_id, "name": f"User {user_id}"}

The client sees a URI template and can fill in the parameter to read specific resources.

Prompts

Prompts are reusable templates that guide AI interactions. Decorate with @mcp.prompt.

Simple prompt

@mcp.prompt
def greeting() -> str:
    """A friendly greeting prompt."""
    return "Hello! How can I help you today?"

Parameterized prompt

@mcp.prompt
def analyze_code(language: str, code: str) -> str:
    """Generate a code analysis prompt."""
    return f"Please analyze this {language} code and suggest improvements:\n\n```{language}\n{code}\n```"

Running the Server

stdio transport (default)

if __name__ == "__main__":
    mcp.run()

stdio is the default transport. Use for local integrations (e.g., Claude Desktop).

HTTP transport (Streamable HTTP)

if __name__ == "__main__":
    mcp.run(transport="http", host="0.0.0.0", port=8000)

Use HTTP for remote/deployed servers. The client connects to http://host:port/mcp.

Server Composition

Mount sub-servers to organize a large server into logical modules:

math_server = FastMCP("MathServer")
text_server = FastMCP("TextServer")

@math_server.tool
def add(a: int, b: int) -> int:
    return a + b

@text_server.tool
def uppercase(text: str) -> str:
    return text.upper()

# Main server mounts sub-servers
main = FastMCP("MainServer")
main.mount(math_server, namespace="math")   # tools: math_add
main.mount(text_server)                      # tools: uppercase (no prefix)
  • namespace — optional prefix added to all tool/resource names from the sub-server.
  • Keeps each module independently testable.

Common Patterns Quick Reference

PatternApproach
Simple function → tool@mcp.tool on a typed function
Complex inputPydantic model as parameter
Logging in toolsAdd ctx: Context parameter
Read-only data@mcp.resource with URI
Parameterized data@mcp.resource("scheme://{param}")
Reusable prompts@mcp.prompt with parameters
Modular servermain.mount(sub_server, namespace="ns")
Shared resources (DB, HTTP)Lifespan handler + ctx.lifespan_context
AuthJWTVerifier for JWTs, OAuthProxy/OIDCProxy for OAuth
Per-tool authorization@mcp.tool(auth=require_scopes("admin"))

Key Rules

  1. Always type-annotate tool parameters and return types — FastMCP generates the schema from them.
  2. Write clear docstrings — the docstring becomes the tool/resource/prompt description visible to the client.
  3. Use ctx: Context for logging and progress — do not use print().
  4. Prefer Pydantic models for tools with 4+ parameters or when input validation is needed.
  5. Use namespace when mounting sub-servers to avoid tool name collisions.
  6. Choose the right transport — stdio for local, HTTP for remote/deployed servers.

Additional Resources

Reference Files

For detailed API documentation and advanced patterns, consult:

  • references/api-reference.md — Tool decorator options, resource MIME types, prompt patterns, Context API, authentication (JWT/OAuth2), server configuration
  • references/patterns.md — Server composition, lifespan management, OpenAPI/FastAPI import, proxy servers, dependencies, error handling, deployment
Repository

provectus/awos-recruitment

Path

.claude/skills/fastmcp/SKILL.md

Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.