fastmcp-server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@fastmcp-serverWhat tools do you have?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
fastmcp-server
Production-ready FastMCP server image with dynamic loading of tools, resources, prompts, and knowledge bases from multiple sources.
Run your own MCP server anywhere — Docker, Compose, Swarm, Kubernetes, or any container runtime. Define tools in Python, mount them, and your server is live.
Quick Start
# Create a tool
mkdir -p tools
cat > tools/hello.py << 'EOF'
def greet(name: str) -> str:
"""Greet someone by name."""
return f"Hello, {name}!"
EOF
# Run the server
docker run -d \
-p 8000:8000 \
-v $(pwd)/tools:/app/inline/tools \
docker.io/helmforge/fastmcp-server:0.4.0Your MCP server is now available at http://localhost:8000/mcp.
The built-in Web UI is at http://localhost:8000/ui.
Related MCP server: FastMCP Demo Server
How It Works
The server loads MCP components (tools, resources, prompts, knowledge) from a workspace directory. On startup, it syncs files from one or more sources into the workspace, registers everything with FastMCP, and exposes the server over HTTP.
Sources (Inline, S3, Git)
│
▼
/app/workspace/
├── tools/*.py → registered as MCP tools
├── resources/*.py → registered as MCP resources
├── prompts/*.py → registered as MCP prompts
└── knowledge/* → served as knowledge:// resources
│
▼
FastMCP Server (:8000/mcp)
├── /ui → Web dashboard
├── /healthz → Liveness probe
├── /readyz → Readiness probe
├── /startupz → Startup probe
├── /debug/info → Server diagnostics
├── /metrics → Prometheus metrics (opt-in)
└── /api/* → JSON API for UISources
The image supports three data sources with merge precedence (highest first):
Source | Best For | Limit |
Inline (volume mount at | Quick setup, small configs | Host filesystem |
S3 (AWS S3, MinIO, Cloudflare R2) | Teams, CI/CD pipelines, large knowledge bases | Unlimited |
Git (any HTTPS repo) | Version-controlled tools, collaboration | Repo size |
All sources can be combined. Inline always wins on conflicts.
Running with Docker Compose
services:
mcp-server:
image: docker.io/helmforge/fastmcp-server:0.4.0
ports:
- "8000:8000"
volumes:
- ./tools:/app/inline/tools
- ./resources:/app/inline/resources
- ./prompts:/app/inline/prompts
- ./knowledge:/app/inline/knowledge
environment:
MCP_SERVER_NAME: my-mcp-server
MCP_AUTH_TYPE: bearer
MCP_AUTH_TOKEN: ${MCP_AUTH_TOKEN}
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:8000/healthz"]
interval: 30s
timeout: 5s
retries: 3Running with S3 (MinIO example)
services:
mcp-server:
image: docker.io/helmforge/fastmcp-server:0.4.0
ports:
- "8000:8000"
environment:
SOURCE_S3_ENABLED: "true"
SOURCE_S3_ENDPOINT: http://minio:9000
SOURCE_S3_BUCKET: mcp-tools
SOURCE_S3_ACCESS_KEY: minioadmin
SOURCE_S3_SECRET_KEY: minioadmin
minio:
image: docker.io/minio/minio:RELEASE.2025-04-03T14-56-28Z
command: server /data --console-address ":9001"
ports:
- "9000:9000"
- "9001:9001"
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadminRunning with Git Source
docker run -d \
-p 8000:8000 \
-e SOURCE_GIT_ENABLED=true \
-e SOURCE_GIT_REPOSITORY=https://github.com/myorg/mcp-tools.git \
-e SOURCE_GIT_BRANCH=main \
docker.io/helmforge/fastmcp-server:0.4.0For private repos, set SOURCE_GIT_TOKEN with a personal access token.
Writing Tools
Create a .py file in tools/. By default, every public function defined in that module becomes an MCP tool:
def get_weather(city: str) -> str:
"""Get current weather for a city."""
import httpx
return httpx.get(f"https://wttr.in/{city}?format=3").text
def roll_dice(sides: int = 6) -> int:
"""Roll a die with the given number of sides."""
import random
return random.randint(1, sides)Utility modules are supported too. Files named like *_helpers.py are skipped by default. For any other utility module, keep helpers private (_helper) or disable auto-registration explicitly:
__mcp_auto_register__ = False
def evidence_true(data, *keys):
return TrueIf you want exact control over exports, declare a TOOLS allowlist:
TOOLS = ["deploy"]
def deploy(service: str, version: str) -> str:
"""Deploy a service."""
return f"Deployed {service}@{version}"
def helper() -> str:
return "not registered"Tool Metadata
Add optional module-level variables to control tool registration:
__tags__ = {"devops", "production"} # Categorization tags
__timeout__ = 30.0 # Execution timeout (seconds)
__annotations_mcp__ = { # MCP behavior hints
"destructiveHint": True,
"title": "Deploy Service"
}
def deploy(service: str, version: str) -> str:
"""Deploy a service to production."""
return f"Deployed {service}@{version}"Async Tools
Both async def and def functions work. Async is preferred for I/O-bound operations:
async def fetch_url(url: str) -> str:
"""Fetch content from a URL."""
import httpx
async with httpx.AsyncClient() as client:
response = await client.get(url)
return response.textStructured Output
Return ToolResult for full control over response format:
from fastmcp.tools.tool import ToolResult
def analyze(data: str) -> ToolResult:
"""Analyze data with structured output."""
return ToolResult(
content="Analysis complete",
structured_content={"word_count": len(data.split())},
meta={"version": "1.0"}
)Writing Resources
Create a .py file in resources/ with a RESOURCE_URI constant and a handler function:
import json
RESOURCE_URI = "config://app"
def get_config() -> str:
"""Application configuration."""
return json.dumps({"version": "1.0", "env": "production"}, indent=2)Important: Resource handlers must return
str,bytes, orlist[ResourceContent]. Returning adictdirectly will cause a serialization error.
Resource Templates
Use {param} placeholders in URIs for parameterized resources:
import json
RESOURCE_URI = "users://{user_id}/profile"
def get_profile(user_id: str) -> str:
"""Get user profile by ID."""
return json.dumps({"user_id": user_id, "name": f"User {user_id}"}, indent=2)Multiple Resources per File
Use a RESOURCES dict to register multiple resources from one file:
import json
RESOURCES = {
"status://health": "get_health",
"status://version": "get_version",
}
def get_health() -> str:
return json.dumps({"status": "ok"}, indent=2)
def get_version() -> str:
return "1.0.0"Writing Prompts
Create a .py file in prompts/. Every public function becomes an MCP prompt:
def summarize(text: str) -> str:
"""Summarize the provided text."""
return f"Please provide a concise summary of:\n\n{text}"Knowledge Base
Any file placed in knowledge/ is served as a knowledge:// resource. Supports text, markdown, JSON, YAML, or any UTF-8 file.
knowledge/
├── product-overview.md
├── api-reference.json
└── troubleshooting/
├── common-errors.md
└── faq.mdThese become accessible as knowledge://product-overview.md, knowledge://troubleshooting/common-errors.md, etc.
Authentication
Type | Variables | Use Case |
None |
| Development, internal networks |
Bearer |
| API keys, service accounts |
JWT |
| OAuth/OIDC, enterprise SSO |
Web UI
The embedded dashboard at /ui provides:
Dashboard — Server name, version, uptime, component counts, source status
Tools Explorer — All registered tools with descriptions, parameters, tags, timeout
Resources Explorer — Resources and templates with URIs, MIME types
Prompts Explorer — All prompts with descriptions
Auto-refreshes every 15 seconds. Disable with MCP_UI_ENABLED=false.
Observability
Health Endpoints
Endpoint | Purpose | When 200 |
| Liveness | Always (process is running) |
| Readiness | Sources synced + components loaded |
| Startup | Full initialization complete |
Diagnostics
GET /debug/info returns full server diagnostics: version, FastMCP version, uptime, component details, source status, auth type, and configuration.
Prometheus Metrics
Enable with MCP_METRICS_ENABLED=true. Exposes at /metrics:
mcp_tools_total— Number of registered toolsmcp_resources_total— Number of registered resourcesmcp_prompts_total— Number of registered promptsmcp_knowledge_total— Number of knowledge filesmcp_tool_calls_total{tool}— Tool invocation countermcp_tool_duration_seconds{tool}— Tool execution duration histogrammcp_tool_errors_total{tool}— Tool error countermcp_sources_sync_total{source,status}— Source sync operationsmcp_auth_requests_total{result}— Auth attempt counter
Structured Logging
Set LOG_FORMAT=json for JSON-structured logs compatible with Loki, ELK, CloudWatch, and Datadog:
{
"timestamp": "2026-04-05T10:30:00+00:00",
"level": "INFO",
"logger": "fastmcp-server.builder",
"message": "Registered tool: greet"
}Environment Variables
Server
Variable | Default | Description |
|
| Server display name |
|
| Listen address |
|
| Listen port |
|
| HTTP endpoint path |
|
| Workspace directory |
|
| Logging level |
|
| Log format: |
|
| Hide internal error details from clients |
|
| Duplicate handling: |
|
| Fail on boot if any tool/resource has errors |
|
| Enable built-in Web UI at |
|
| Enable Prometheus metrics at |
| Comma-separated pip packages to install at startup |
Authentication
Variable | Default | Description |
|
|
|
| Bearer token value | |
| JWT issuer | |
| JWT audience | |
| JWKS endpoint URL |
S3 Source
Variable | Default | Description |
|
| Enable S3 sync |
| S3-compatible endpoint URL | |
| Bucket name | |
|
| AWS region |
| Key prefix filter | |
| Access key ID | |
| Secret access key |
Git Source
Variable | Default | Description |
|
| Enable Git sync |
| Repository HTTPS URL | |
|
| Branch to clone |
| Subdirectory within the repo | |
| Auth token for private repos |
Init Container Pattern
For Kubernetes, separate source syncing from server startup using sync_only.py:
python /app/sync_only.pyThis script runs sync_sources() and exits. Use it as a Kubernetes init container to pre-populate the workspace volume before the main server starts.
Deployment Options
Method | Docs |
Docker / Docker Compose / Swarm | This README |
Kubernetes (Helm) |
Connecting MCP Clients
Once your FastMCP server is running and accessible, connect AI assistants to it as an MCP server.
Claude Code
Add the server to your Claude Code settings (~/.claude/settings.json or project .claude/settings.json):
{
"mcpServers": {
"my-mcp-server": {
"type": "streamable-http",
"url": "https://mcp.example.com/mcp"
}
}
}With bearer authentication:
{
"mcpServers": {
"my-mcp-server": {
"type": "streamable-http",
"url": "https://mcp.example.com/mcp",
"headers": {
"Authorization": "Bearer <your-token>"
}
}
}
}Codex (VS Code Extension)
Add to your Codex configuration file (~/.codex/config.toml):
[mcp_servers.my-mcp-server]
enabled = true
url = "https://mcp.example.com/mcp"
[mcp_servers.my-mcp-server.http_headers]
Authorization = "Bearer <your-token>"Without authentication (development):
[mcp_servers.my-mcp-server]
enabled = true
url = "https://mcp.example.com/mcp"Local Development
When running locally with Docker, use http://localhost:8000/mcp as the URL and omit authentication headers if MCP_AUTH_TYPE=none.
License
Apache-2.0 — see LICENSE.
This server cannot be deployed
Maintenance
Related MCP Connectors
MCP server for building and testing AI agents with multi-model experimentation and insights.
MCP server unifying ERPs, CRMs, APIs and knowledge base for Claude, ChatGPT and Gemini.
- UnifAPIOAuthcom.unifapi
Hosted MCP server for live public-data APIs and Skills for AI agents.
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
Related MCP Servers
- FlicenseNot gradedqualityFmaintenanceA production-ready MCP server built with FastAPI, providing an enhanced tool registry for creating, managing, and documenting AI tools for Large Language Models (LLMs).34-
- FlicenseAqualityDmaintenanceA production-ready MCP server that provides hackathon resources and reusable starter prompts. Built with FastMCP framework and includes comprehensive deployment options for development and production environments.1-
- FlicenseNot gradedqualityDmaintenanceA Model Context Protocol server built with FastMCP that features dynamic tool loading and modular management via a dedicated tool directory. It supports both stdio and HTTP transport modes, enabling efficient development and deployment of custom MCP tools.-
- FlicenseNot gradedqualityDmaintenanceA basic MCP server for deployment to Amazon Bedrock AgentCore Runtime, enabling tool integration via FastMCP with streamable HTTP transport.-