mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-24 06:24:18 +02:00
Add FileSystemProvider for filesystem-based component discovery (#2823)
This commit is contained in:
parent
43811cc16b
commit
87f2edd9c0
14 changed files with 2419 additions and 4 deletions
39
examples/filesystem-provider/mcp/prompts/assistant.py
Normal file
39
examples/filesystem-provider/mcp/prompts/assistant.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
"""Assistant prompts."""
|
||||
|
||||
from fastmcp.fs import prompt
|
||||
|
||||
|
||||
@prompt
|
||||
def code_review(code: str, language: str = "python") -> str:
|
||||
"""Generate a code review prompt.
|
||||
|
||||
Args:
|
||||
code: The code to review.
|
||||
language: Programming language (default: python).
|
||||
"""
|
||||
return f"""Please review this {language} code:
|
||||
|
||||
```{language}
|
||||
{code}
|
||||
```
|
||||
|
||||
Focus on:
|
||||
- Code quality and readability
|
||||
- Potential bugs or issues
|
||||
- Performance considerations
|
||||
- Best practices"""
|
||||
|
||||
|
||||
@prompt(
|
||||
name="explain-concept",
|
||||
description="Generate a prompt to explain a technical concept.",
|
||||
tags={"education", "explanation"},
|
||||
)
|
||||
def explain(topic: str, audience: str = "developer") -> str:
|
||||
"""Generate an explanation prompt.
|
||||
|
||||
Args:
|
||||
topic: The concept to explain.
|
||||
audience: Target audience level.
|
||||
"""
|
||||
return f"Explain {topic} to a {audience}. Use clear examples and analogies."
|
||||
55
examples/filesystem-provider/mcp/resources/config.py
Normal file
55
examples/filesystem-provider/mcp/resources/config.py
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
"""Configuration resources - static and templated."""
|
||||
|
||||
import json
|
||||
|
||||
from fastmcp.fs import resource
|
||||
|
||||
|
||||
# Static resource - no parameters in URI
|
||||
@resource("config://app")
|
||||
def get_app_config() -> str:
|
||||
"""Get application configuration."""
|
||||
return json.dumps(
|
||||
{
|
||||
"name": "FilesystemDemo",
|
||||
"version": "1.0.0",
|
||||
"features": ["tools", "resources", "prompts"],
|
||||
},
|
||||
indent=2,
|
||||
)
|
||||
|
||||
|
||||
# Resource template - {env} is a parameter
|
||||
@resource("config://env/{env}")
|
||||
def get_env_config(env: str) -> str:
|
||||
"""Get environment-specific configuration.
|
||||
|
||||
Args:
|
||||
env: Environment name (dev, staging, prod).
|
||||
"""
|
||||
configs = {
|
||||
"dev": {"debug": True, "log_level": "DEBUG", "database": "localhost"},
|
||||
"staging": {"debug": True, "log_level": "INFO", "database": "staging-db"},
|
||||
"prod": {"debug": False, "log_level": "WARNING", "database": "prod-db"},
|
||||
}
|
||||
config = configs.get(env, {"error": f"Unknown environment: {env}"})
|
||||
return json.dumps(config, indent=2)
|
||||
|
||||
|
||||
# Resource with custom metadata
|
||||
@resource(
|
||||
"config://features",
|
||||
name="feature-flags",
|
||||
mime_type="application/json",
|
||||
tags={"config", "features"},
|
||||
)
|
||||
def get_feature_flags() -> str:
|
||||
"""Get feature flags configuration."""
|
||||
return json.dumps(
|
||||
{
|
||||
"dark_mode": True,
|
||||
"beta_features": False,
|
||||
"max_upload_size_mb": 100,
|
||||
},
|
||||
indent=2,
|
||||
)
|
||||
24
examples/filesystem-provider/mcp/tools/calculator.py
Normal file
24
examples/filesystem-provider/mcp/tools/calculator.py
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
"""Math tools with custom metadata."""
|
||||
|
||||
from fastmcp.fs import tool
|
||||
|
||||
|
||||
@tool(
|
||||
name="add-numbers", # Custom name (default would be "add")
|
||||
description="Add two numbers together.",
|
||||
tags={"math", "arithmetic"},
|
||||
)
|
||||
def add(a: float, b: float) -> float:
|
||||
"""Add two numbers."""
|
||||
return a + b
|
||||
|
||||
|
||||
@tool(tags={"math", "arithmetic"})
|
||||
def multiply(a: float, b: float) -> float:
|
||||
"""Multiply two numbers.
|
||||
|
||||
Args:
|
||||
a: First number.
|
||||
b: Second number.
|
||||
"""
|
||||
return a * b
|
||||
28
examples/filesystem-provider/mcp/tools/greeting.py
Normal file
28
examples/filesystem-provider/mcp/tools/greeting.py
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
"""Greeting tools - multiple tools in one file."""
|
||||
|
||||
from fastmcp.fs import tool
|
||||
|
||||
|
||||
@tool
|
||||
def greet(name: str) -> str:
|
||||
"""Greet someone by name.
|
||||
|
||||
Args:
|
||||
name: The person's name.
|
||||
"""
|
||||
return f"Hello, {name}!"
|
||||
|
||||
|
||||
@tool
|
||||
def farewell(name: str) -> str:
|
||||
"""Say goodbye to someone.
|
||||
|
||||
Args:
|
||||
name: The person's name.
|
||||
"""
|
||||
return f"Goodbye, {name}!"
|
||||
|
||||
|
||||
# Helper functions without decorators are ignored
|
||||
def _format_message(msg: str) -> str:
|
||||
return msg.strip().capitalize()
|
||||
29
examples/filesystem-provider/server.py
Normal file
29
examples/filesystem-provider/server.py
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
"""Filesystem-based MCP server using FileSystemProvider.
|
||||
|
||||
This example demonstrates how to use FileSystemProvider to automatically
|
||||
discover and register tools, resources, and prompts from the filesystem.
|
||||
|
||||
Run:
|
||||
fastmcp run examples/filesystem-provider/server.py
|
||||
|
||||
Inspect:
|
||||
fastmcp inspect examples/filesystem-provider/server.py
|
||||
|
||||
Dev mode (re-scan files on every request):
|
||||
Change reload=True below, then modify files while the server runs.
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from fastmcp import FastMCP
|
||||
from fastmcp.fs import FileSystemProvider
|
||||
|
||||
# The provider scans all .py files in the directory recursively.
|
||||
# Functions decorated with @tool, @resource, or @prompt are registered.
|
||||
# Directory structure is purely organizational - decorators determine type.
|
||||
provider = FileSystemProvider(
|
||||
root=Path(__file__).parent / "mcp",
|
||||
reload=True, # Set True for dev mode (re-scan on every request)
|
||||
)
|
||||
|
||||
mcp = FastMCP("FilesystemDemo", providers=[provider])
|
||||
Loading…
Add table
Add a link
Reference in a new issue