Skip to main content

FastMCP server template with mcp-refcache and Langfuse tracing

Project description

FastMCP Template

A production-ready FastMCP server template with mcp-refcache integration for building AI agent tools that handle large data efficiently.

Using This Template

Create Your Project

  1. Use as GitHub Template (recommended):

    • Click "Use this template" → "Create a new repository"
    • Or use GitHub CLI: gh repo create my-mcp-server --template l4b4r4b4b4/fastmcp-template
  2. Or clone directly:

    git clone https://github.com/l4b4r4b4b4/fastmcp-template my-mcp-server
    cd my-mcp-server
    rm -rf .git && git init
    

Rename the Project

After creating your project, rename it from fastmcp-template to your project name:

1. Update pyproject.toml

[project]
name = "my-mcp-server"  # Your project name
version = "0.0.1"
description = "Your project description"
authors = [{ name = "Your Name", email = "you@example.com" }]

[project.scripts]
my-mcp-server = "app.__main__:app"  # Your CLI command

2. Update Docker images in docker-compose.yml

services:
  my-mcp-server:
    image: ghcr.io/your-org/my-mcp-server:latest

3. Update docker/Dockerfile.base labels

LABEL org.opencontainers.image.source="https://github.com/your-org/my-mcp-server"

4. Update app/server.py

mcp = FastMCP(
    name="My MCP Server",  # Your server name
    instructions="Your server description...",
)

_cache = RefCache(
    name="my-mcp-server",  # Your cache namespace
    ...
)

5. Update GitHub workflows

In .github/workflows/release.yml:

env:
  APP_IMAGE_NAME: ${{ github.repository_owner }}/my-mcp-server
  BASE_IMAGE_NAME: ${{ github.repository_owner }}/my-mcp-base

6. Update Zed/Editor settings

In .zed/settings.json, update the context server name and command.

Add Your Tools

Create new tool modules in app/tools/:

# app/tools/my_feature.py
from pydantic import BaseModel, Field

class MyInput(BaseModel):
    """Input for my tool."""
    query: str = Field(description="The query to process")

async def my_tool(query: str) -> dict:
    """Process a query and return results."""
    # Your business logic here
    return {"result": f"Processed: {query}"}

Then register in app/tools/__init__.py and app/server.py:

# app/tools/__init__.py
from app.tools.my_feature import MyInput, my_tool
__all__ = [..., "MyInput", "my_tool"]

# app/server.py
from app.tools import my_tool
mcp.tool(my_tool)

Configure PyPI Publishing

  1. Go to PyPI Trusted Publishers
  2. Add a new pending publisher:
    • Project name: my-mcp-server
    • Owner: your-github-username
    • Repository: my-mcp-server
    • Workflow: publish.yml
    • Environment: pypi

Features

  • Reference-Based Caching - Return references instead of large data, reducing context window usage
  • Preview Generation - Automatic previews for large results (sample, truncate, paginate strategies)
  • Pagination - Navigate large datasets without loading everything at once
  • Access Control - Separate user and agent permissions for sensitive data
  • Private Computation - Let agents compute with values they cannot see
  • Docker Ready - Production-ready containers with Python slim base image
  • Optional Langfuse Tracing - Built-in observability integration

Quick Start

Prerequisites

  • Python 3.12+
  • uv (recommended) or pip

Installation

# Clone the template
git clone https://github.com/l4b4r4b4b4/fastmcp-template
cd fastmcp-template

# Install dependencies
uv sync

# Run the server (stdio mode for Claude Desktop)
uv run fastmcp-template

# Run the server (SSE/HTTP mode for deployment)
uv run fastmcp-template --transport sse --port 8000

Install from PyPI

# Run directly with uvx (no install needed)
uvx fastmcp-template stdio

# Or install globally
uv tool install fastmcp-template
fastmcp-template --help

Docker Deployment

# Pull and run from GHCR
docker pull ghcr.io/l4b4r4b4b4/fastmcp-template:latest
docker run -p 8000:8000 ghcr.io/l4b4r4b4b4/fastmcp-template:latest

# Or build locally with Docker Compose
docker compose up

# Build images manually
docker compose --profile build build base
docker compose build

Using with Claude Desktop

Add to your claude_desktop_config.json:

{
  "mcpServers": {
    "fastmcp-template": {
      "command": "uv",
      "args": ["run", "fastmcp-template"],
      "cwd": "/path/to/fastmcp-template"
    }
  }
}

Using with Zed

The template includes .zed/settings.json pre-configured for MCP context servers.

Example Tools

The template includes several example tools demonstrating different patterns:

Simple Tool (No Caching)

@mcp.tool
def hello(name: str = "World") -> dict[str, Any]:
    """Say hello to someone."""
    return {"message": f"Hello, {name}!"}

Cached Tool (Public Namespace)

@mcp.tool
@cache.cached(namespace="public")
async def generate_items(count: int = 10, prefix: str = "item") -> list[dict]:
    """Generate items with automatic caching for large results."""
    return [{"id": i, "name": f"{prefix}_{i}"} for i in range(count)]

Private Computation (EXECUTE Permission)

@mcp.tool
def store_secret(name: str, value: float) -> dict[str, Any]:
    """Store a secret that agents can use but not read."""
    secret_policy = AccessPolicy(
        user_permissions=Permission.FULL,
        agent_permissions=Permission.EXECUTE,  # Can use, cannot see
    )
    ref = cache.set(key=f"secret_{name}", value=value, policy=secret_policy)
    return {"ref_id": ref.ref_id}

@mcp.tool
def compute_with_secret(secret_ref: str, multiplier: float = 1.0) -> dict[str, Any]:
    """Compute using a secret without revealing it."""
    secret = cache.resolve(secret_ref, actor=DefaultActor.system())
    return {"result": secret * multiplier}

Project Structure

fastmcp-template/
├── app/                     # Application code (flat structure for containers)
│   ├── __init__.py          # Version export
│   ├── server.py            # Main server with example tools
│   └── tools/               # Additional tool modules
├── docker/
│   ├── Dockerfile.base      # Python slim base image with dependencies
│   ├── Dockerfile           # Production image (extends base)
│   └── Dockerfile.dev       # Development with hot reload
├── tests/
│   ├── conftest.py          # Pytest fixtures
│   └── test_server.py       # Server tests
├── .github/
│   └── workflows/
│       ├── ci.yml           # CI pipeline (lint, test, security)
│       ├── publish.yml      # PyPI trusted publisher
│       └── release.yml      # Docker build & publish to GHCR
├── docker-compose.yml       # Local development & production
├── pyproject.toml           # Project config
├── flake.nix                # Nix dev shell
└── .rules                   # AI assistant guidelines

Development

Setup

# Install dependencies
uv sync

# Install pre-commit and pre-push hooks (configured in .pre-commit-config.yaml)
uv run pre-commit install --install-hooks
uv run pre-commit install --hook-type pre-push

Running Tests

uv run pytest
uv run pytest --cov  # With coverage

Linting and Formatting

uv run ruff check . --fix
uv run ruff format .

Type Checking

uv run mypy app/

Docker Development

# Run development container with hot reload
docker compose --profile dev up

# Build base image (for publishing)
docker compose --profile build build base

# Build all images
docker compose build

Using Nix (Optional)

nix develop  # Enter dev shell with all tools

Customization

  1. Rename the project: Update pyproject.toml, app/, and imports
  2. Add your tools: Create new tools in app/server.py or add modules to app/tools/
  3. Configure caching: Adjust RefCache settings in app/server.py
  4. Add Langfuse: Install with uv add langfuse and configure environment variables
  5. Extend base image: Use FROM ghcr.io/l4b4r4b4b4/fastmcp-base:latest in your Dockerfile

Configuration

Environment Variables

Variable Description Default
LANGFUSE_PUBLIC_KEY Langfuse public key -
LANGFUSE_SECRET_KEY Langfuse secret key -
LANGFUSE_HOST Langfuse host URL https://cloud.langfuse.com

CLI Commands

uvx fastmcp-template --help

Commands:
  stdio             Start server in stdio mode (for Claude Desktop and local CLI)
  sse               Start server in SSE mode (Server-Sent Events)
  streamable-http   Start server in streamable HTTP mode (recommended for remote/Docker)

# Examples:
uvx fastmcp-template stdio                          # Local CLI mode
uvx fastmcp-template sse --port 8000                # SSE on port 8000
uvx fastmcp-template streamable-http --host 0.0.0.0 # Docker/remote mode

Test Prompts

Use these prompts in a fresh chat session to verify the MCP server is working correctly. Each prompt demonstrates different capabilities of mcp-refcache.

🟢 Basic: Hello World

Prompt: "Say hello to 'MCP Developer' using the fastmcp-template tools"

Expected: The assistant calls hello with name="MCP Developer" and returns a greeting.


🟢 Basic: Health Check

Prompt: "Check if the fastmcp-template server is healthy"

Expected: The assistant calls health_check and reports server status.


🟡 Intermediate: Generate & Explore Items

Prompt: "Generate 50 widgets and tell me about the first and last items"

Expected: The assistant calls generate_items(count=50, prefix="widget") and describes widget_0 and widget_49.


🟡 Intermediate: Salary Calculator (Private Computation)

Prompt: "I want to calculate a 5% raise on my salary, but I don't want you to know my actual salary. Store $75,000 as a secret called 'current_salary', then calculate what it would be with a 5% raise."

Expected:

  1. Assistant calls store_secret(name="current_salary", value=75000)
  2. Assistant calls compute_with_secret(secret_ref="...", multiplier=1.05)
  3. Assistant reports the result ($78,750) without ever seeing the original value

🔴 Advanced: Multi-Step Private Computation

Prompt: "Help me compare two investment options without seeing my principal. Store $10,000 as 'principal'. Then calculate returns for: Option A (8% return) and Option B (12% return). Which is better?"

Expected:

  1. Assistant stores the secret principal
  2. Assistant computes both options using the same secret reference
  3. Assistant compares results ($10,800 vs $11,200) and recommends Option B
  4. The actual principal value is never revealed to the assistant

🔴 Advanced: Access Control Verification

Prompt: "Store my API key hash as a secret (use value 12345), then try to read it back directly using get_cached_result"

Expected:

  1. Assistant stores the secret successfully
  2. When attempting to read with get_cached_result, it gets "access denied"
  3. Assistant explains that secrets have EXECUTE-only permission for agents

🔴 Advanced: Admin Tool Verification

Prompt: "Show me the cache statistics using admin_get_cache_stats"

Expected: Assistant receives "Admin access required" error and explains that admin tools are permission-gated.


Test Coverage Summary

Feature Prompt Level Tools Used
Basic greeting 🟢 Basic hello
Server health 🟢 Basic health_check
Item generation 🟡 Intermediate generate_items
Secret storage 🟡 Intermediate store_secret
Private computation 🟡 Intermediate compute_with_secret
Access control 🔴 Advanced get_cached_result
Admin gating 🔴 Advanced admin_* tools

License

MIT License - see LICENSE for details.

Contributing

See CONTRIBUTING.md for development guidelines.

Related Projects

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastmcp_template-0.0.3.tar.gz (182.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fastmcp_template-0.0.3-py3-none-any.whl (27.8 kB view details)

Uploaded Python 3

File details

Details for the file fastmcp_template-0.0.3.tar.gz.

File metadata

  • Download URL: fastmcp_template-0.0.3.tar.gz
  • Upload date:
  • Size: 182.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fastmcp_template-0.0.3.tar.gz
Algorithm Hash digest
SHA256 f36da049d6dd8f7759931707792766887e5c3b154ab81f8809a5200c11499c55
MD5 e0718ab2ba3b4d2917ab3f382d687cb8
BLAKE2b-256 fe1d010dd8eb48ca6638f23737b73928de1ca6bec4bc187b9d3db91ccf2216d1

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastmcp_template-0.0.3.tar.gz:

Publisher: publish.yml on l4b4r4b4b4/fastmcp-template

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastmcp_template-0.0.3-py3-none-any.whl.

File metadata

File hashes

Hashes for fastmcp_template-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 a17c8453e0bbd36c51ba104c42157f9743827a9ff659ccb827cbc0dfba2639ee
MD5 826f9f6d3645c45fe9a3c8dd37945c71
BLAKE2b-256 daf670285b8a7dd68e84806cf232e5ae9a560d01fc2cf7bc083e832dc815338e

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastmcp_template-0.0.3-py3-none-any.whl:

Publisher: publish.yml on l4b4r4b4b4/fastmcp-template

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page