mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-23 05:54:19 +02:00
Add empty parens to docs
This commit is contained in:
parent
38f5da1a61
commit
b3f80c5374
21 changed files with 82 additions and 82 deletions
10
README.md
10
README.md
|
|
@ -31,7 +31,7 @@ from fastmcp import FastMCP
|
|||
|
||||
mcp = FastMCP("Demo 🚀")
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def add(a: int, b: int) -> int:
|
||||
"""Add two numbers"""
|
||||
return a + b
|
||||
|
|
@ -144,7 +144,7 @@ Learn more in the [**FastMCP Server Documentation**](https://gofastmcp.com/serve
|
|||
Tools allow LLMs to perform actions by executing your Python functions (sync or async). Ideal for computations, API calls, or side effects (like `POST`/`PUT`). FastMCP handles schema generation from type hints and docstrings. Tools can return various types, including text, JSON-serializable objects, and even images using the [`fastmcp.Image`](https://gofastmcp.com/servers/tools#return-values) helper.
|
||||
|
||||
```python
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def multiply(a: float, b: float) -> float:
|
||||
"""Multiplies two numbers."""
|
||||
return a * b
|
||||
|
|
@ -176,7 +176,7 @@ Learn more in the [**Resources & Templates Documentation**](https://gofastmcp.co
|
|||
Prompts define reusable message templates to guide LLM interactions. Decorate functions with `@mcp.prompt`. Return strings or `Message` objects.
|
||||
|
||||
```python
|
||||
@mcp.prompt
|
||||
@mcp.prompt()
|
||||
def summarize_request(text: str) -> str:
|
||||
"""Generate a prompt asking for a summary."""
|
||||
return f"Please summarize the following text:\n\n{text}"
|
||||
|
|
@ -201,7 +201,7 @@ from fastmcp import FastMCP, Context
|
|||
|
||||
mcp = FastMCP("My MCP Server")
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
async def process_data(uri: str, ctx: Context):
|
||||
# Log a message to the client
|
||||
await ctx.info(f"Processing {uri}...")
|
||||
|
|
@ -321,7 +321,7 @@ from fastmcp import FastMCP
|
|||
|
||||
mcp = FastMCP("Demo 🚀")
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def hello(name: str) -> str:
|
||||
return f"Hello, {name}!"
|
||||
|
||||
|
|
|
|||
|
|
@ -359,7 +359,7 @@ import asyncio
|
|||
# 1. Create your FastMCP server instance
|
||||
server = FastMCP(name="InMemoryServer")
|
||||
|
||||
@server.tool
|
||||
@server.tool()
|
||||
def ping():
|
||||
return "pong"
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ from fastmcp import FastMCP
|
|||
|
||||
mcp = FastMCP("MyServer")
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def hello(name: str) -> str:
|
||||
return f"Hello, {name}!"
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ from fastmcp import FastMCP
|
|||
|
||||
mcp = FastMCP(name="MyServer")
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def hello(name: str) -> str:
|
||||
return f"Hello, {name}!"
|
||||
|
||||
|
|
@ -244,7 +244,7 @@ import asyncio
|
|||
|
||||
mcp = FastMCP(name="MyServer")
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def hello(name: str) -> str:
|
||||
return f"Hello, {name}!"
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ from fastmcp import FastMCP
|
|||
|
||||
mcp = FastMCP("My MCP Server")
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def greet(name: str) -> str:
|
||||
return f"Hello, {name}!"
|
||||
```
|
||||
|
|
@ -49,7 +49,7 @@ from fastmcp import FastMCP, Client
|
|||
|
||||
mcp = FastMCP("My MCP Server")
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def greet(name: str) -> str:
|
||||
return f"Hello, {name}!"
|
||||
|
||||
|
|
@ -76,7 +76,7 @@ from fastmcp import FastMCP
|
|||
|
||||
mcp = FastMCP("My MCP Server")
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def greet(name: str) -> str:
|
||||
return f"Hello, {name}!"
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ from fastmcp import FastMCP
|
|||
|
||||
mcp = FastMCP("Demo 🚀")
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def add(a: int, b: int) -> int:
|
||||
"""Add two numbers"""
|
||||
return a + b
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ from fastmcp import FastMCP
|
|||
|
||||
mcp = FastMCP(name="Dice Roller")
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def roll_dice(n_dice: int) -> list[int]:
|
||||
"""Roll `n_dice` 6-sided dice and return the results."""
|
||||
return [random.randint(1, 6) for _ in range(n_dice)]
|
||||
|
|
@ -170,7 +170,7 @@ auth = BearerAuthProvider(
|
|||
|
||||
mcp = FastMCP(name="Dice Roller", auth=auth)
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def roll_dice(n_dice: int) -> list[int]:
|
||||
"""Roll `n_dice` 6-sided dice and return the results."""
|
||||
return [random.randint(1, 6) for _ in range(n_dice)]
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ from fastmcp import FastMCP
|
|||
|
||||
mcp = FastMCP(name="Dice Roller")
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def roll_dice(n_dice: int) -> list[int]:
|
||||
"""Roll `n_dice` 6-sided dice and return the results."""
|
||||
return [random.randint(1, 6) for _ in range(n_dice)]
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ from fastmcp import FastMCP
|
|||
|
||||
mcp = FastMCP(name="Dice Roller")
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def roll_dice(n_dice: int) -> list[int]:
|
||||
"""Roll `n_dice` 6-sided dice and return the results."""
|
||||
return [random.randint(1, 6) for _ in range(n_dice)]
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ from fastmcp import FastMCP
|
|||
|
||||
mcp = FastMCP(name="Dice Roller")
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def roll_dice(n_dice: int) -> list[int]:
|
||||
"""Roll `n_dice` 6-sided dice and return the results."""
|
||||
return [random.randint(1, 6) for _ in range(n_dice)]
|
||||
|
|
@ -165,7 +165,7 @@ auth = BearerAuthProvider(
|
|||
|
||||
mcp = FastMCP(name="Dice Roller", auth=auth)
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def roll_dice(n_dice: int) -> list[int]:
|
||||
"""Roll `n_dice` 6-sided dice and return the results."""
|
||||
return [random.randint(1, 6) for _ in range(n_dice)]
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ from fastmcp import FastMCP
|
|||
|
||||
mcp = FastMCP("MyServer")
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def hello(name: str) -> str:
|
||||
return f"Hello, {name}!"
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ from fastmcp import FastMCP
|
|||
mcp = FastMCP()
|
||||
|
||||
class MyClass:
|
||||
@mcp.tool # This won't work correctly
|
||||
@mcp.tool() # This won't work correctly
|
||||
def add(self, x, y):
|
||||
return x + y
|
||||
|
||||
|
|
@ -83,7 +83,7 @@ mcp = FastMCP()
|
|||
|
||||
class MyClass:
|
||||
@classmethod
|
||||
@mcp.tool # This won't work correctly
|
||||
@mcp.tool() # This won't work correctly
|
||||
def from_string(cls, s):
|
||||
return cls(s)
|
||||
```
|
||||
|
|
@ -122,7 +122,7 @@ mcp = FastMCP()
|
|||
|
||||
class MyClass:
|
||||
@staticmethod
|
||||
@mcp.tool # This works!
|
||||
@mcp.tool() # This works!
|
||||
def utility(x, y):
|
||||
return x + y
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ from starlette.requests import Request
|
|||
|
||||
mcp = FastMCP(name="HTTP Request Demo")
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
async def user_agent_info() -> dict:
|
||||
"""Return information about the user agent."""
|
||||
# Get the HTTP request
|
||||
|
|
@ -58,7 +58,7 @@ from fastmcp.server.dependencies import get_http_headers
|
|||
|
||||
mcp = FastMCP(name="Headers Demo")
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
async def safe_header_info() -> dict:
|
||||
"""Safely get header information without raising errors."""
|
||||
# Get headers (returns empty dict if no request context)
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ from fastmcp import FastMCP, Client
|
|||
def mcp_server():
|
||||
server = FastMCP("TestServer")
|
||||
|
||||
@server.tool
|
||||
@server.tool()
|
||||
def greet(name: str) -> str:
|
||||
return f"Hello, {name}!"
|
||||
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ Once authenticated, your tools, resources, or prompts can access token informati
|
|||
from fastmcp import FastMCP, Context, ToolError
|
||||
from fastmcp.server.dependencies import get_access_token, AccessToken
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
async def get_my_data(ctx: Context) -> dict:
|
||||
access_token: AccessToken = get_access_token()
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ import asyncio
|
|||
# Define subservers
|
||||
weather_mcp = FastMCP(name="WeatherService")
|
||||
|
||||
@weather_mcp.tool
|
||||
@weather_mcp.tool()
|
||||
def get_forecast(city: str) -> dict:
|
||||
"""Get weather forecast."""
|
||||
return {"city": city, "forecast": "Sunny"}
|
||||
|
|
@ -102,7 +102,7 @@ from fastmcp import FastMCP, Client
|
|||
# Define subserver
|
||||
dynamic_mcp = FastMCP(name="DynamicService")
|
||||
|
||||
@dynamic_mcp.tool
|
||||
@dynamic_mcp.tool()
|
||||
def initial_tool():
|
||||
"""Initial tool demonstration."""
|
||||
return "Initial Tool Exists"
|
||||
|
|
@ -112,7 +112,7 @@ main_mcp = FastMCP(name="MainAppLive")
|
|||
main_mcp.mount("dynamic", dynamic_mcp)
|
||||
|
||||
# Add a tool AFTER mounting - it will be accessible through main_mcp
|
||||
@dynamic_mcp.tool
|
||||
@dynamic_mcp.tool()
|
||||
def added_later():
|
||||
"""Tool added after mounting."""
|
||||
return "Tool Added Dynamically!"
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ from fastmcp import FastMCP, Context
|
|||
|
||||
mcp = FastMCP(name="ContextDemo")
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
async def process_file(file_uri: str, ctx: Context) -> str:
|
||||
"""Processes a file, using context for logging and resource access."""
|
||||
# Context is available as the ctx parameter
|
||||
|
|
@ -71,7 +71,7 @@ async def get_user_profile(user_id: str, ctx: Context) -> dict:
|
|||
<VersionBadge version="2.2.5" />
|
||||
|
||||
```python
|
||||
@mcp.prompt
|
||||
@mcp.prompt()
|
||||
async def data_analysis_request(dataset: str, ctx: Context) -> str:
|
||||
"""Generate a request to analyze data with contextual information."""
|
||||
# Context is available as the ctx parameter
|
||||
|
|
@ -99,7 +99,7 @@ async def process_data(data: list[float]) -> dict:
|
|||
ctx = get_context()
|
||||
await ctx.info(f"Processing {len(data)} data points")
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
async def analyze_dataset(dataset_name: str) -> dict:
|
||||
# Call utility function that uses context internally
|
||||
data = load_data(dataset_name)
|
||||
|
|
@ -118,7 +118,7 @@ async def analyze_dataset(dataset_name: str) -> dict:
|
|||
Send log messages back to the MCP client. This is useful for debugging and providing visibility into function execution during a request.
|
||||
|
||||
```python
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
async def analyze_data(data: list[float], ctx: Context) -> dict:
|
||||
"""Analyze numerical data with logging."""
|
||||
await ctx.debug("Starting analysis of numerical data")
|
||||
|
|
@ -149,7 +149,7 @@ async def analyze_data(data: list[float], ctx: Context) -> dict:
|
|||
For long-running operations, notify the client about the progress. This allows clients to display progress indicators and provide a better user experience.
|
||||
|
||||
```python
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
async def process_items(items: list[str], ctx: Context) -> dict:
|
||||
"""Process a list of items with progress updates."""
|
||||
total = len(items)
|
||||
|
|
@ -182,7 +182,7 @@ Progress reporting requires the client to have sent a `progressToken` in the ini
|
|||
Read data from resources registered with your FastMCP server. This allows functions to access files, configuration, or dynamically generated content.
|
||||
|
||||
```python
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
async def summarize_document(document_uri: str, ctx: Context) -> str:
|
||||
"""Summarize a document by its resource URI."""
|
||||
# Read the document content
|
||||
|
|
@ -222,7 +222,7 @@ The returned content is typically accessed via `content_list[0].content` and can
|
|||
Request the client's LLM to generate text based on provided messages. This is useful when your function needs to leverage the LLM's capabilities to process data or generate responses.
|
||||
|
||||
```python
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
async def analyze_sentiment(text: str, ctx: Context) -> dict:
|
||||
"""Analyze the sentiment of a text using the client's LLM."""
|
||||
# Create a sampling prompt asking for sentiment analysis
|
||||
|
|
@ -258,7 +258,7 @@ async def analyze_sentiment(text: str, ctx: Context) -> dict:
|
|||
When providing a simple string, it's treated as a user message. For more complex scenarios, you can provide a list of messages with different roles.
|
||||
|
||||
```python
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
async def generate_example(concept: str, ctx: Context) -> str:
|
||||
"""Generate a Python code example for a given concept."""
|
||||
# Using a system prompt and a user message
|
||||
|
|
@ -280,7 +280,7 @@ See [Client Sampling](/clients/client#llm-sampling) for more details on how clie
|
|||
Access metadata about the current request and client.
|
||||
|
||||
```python
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
async def request_info(ctx: Context) -> dict:
|
||||
"""Return information about the current request."""
|
||||
return {
|
||||
|
|
@ -300,7 +300,7 @@ async def request_info(ctx: Context) -> dict:
|
|||
#### FastMCP Server and Sessions
|
||||
|
||||
```python
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
async def advanced_tool(ctx: Context) -> str:
|
||||
"""Demonstrate advanced context access."""
|
||||
# Access the FastMCP server instance
|
||||
|
|
@ -326,7 +326,7 @@ See the [HTTP Requests pattern](/patterns/http-requests) for more details.
|
|||
For web applications, you can access the underlying HTTP request:
|
||||
|
||||
```python
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
async def handle_web_request(ctx: Context) -> dict:
|
||||
"""Access HTTP request information from the Starlette request."""
|
||||
request = ctx.get_http_request()
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ FastMCP servers expose several types of components to the client:
|
|||
Tools are functions that the client can call to perform actions or access external systems.
|
||||
|
||||
```python
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def multiply(a: float, b: float) -> float:
|
||||
"""Multiplies two numbers together."""
|
||||
return a * b
|
||||
|
|
@ -87,7 +87,7 @@ See [Resources & Templates](/servers/resources) for detailed documentation.
|
|||
Prompts are reusable message templates for guiding the LLM.
|
||||
|
||||
```python
|
||||
@mcp.prompt
|
||||
@mcp.prompt()
|
||||
def analyze_data(data_points: list[float]) -> str:
|
||||
"""Creates a prompt asking for analysis of numerical data."""
|
||||
formatted_data = ", ".join(str(point) for point in data_points)
|
||||
|
|
@ -106,7 +106,7 @@ from fastmcp import FastMCP
|
|||
|
||||
mcp = FastMCP(name="MyServer")
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def greet(name: str) -> str:
|
||||
"""Greet a user by name."""
|
||||
return f"Hello, {name}!"
|
||||
|
|
@ -145,7 +145,7 @@ import asyncio
|
|||
main = FastMCP(name="Main")
|
||||
sub = FastMCP(name="Sub")
|
||||
|
||||
@sub.tool
|
||||
@sub.tool()
|
||||
def hello():
|
||||
return "hi"
|
||||
|
||||
|
|
@ -216,7 +216,7 @@ def yaml_serializer(data):
|
|||
# Create a server with the custom serializer
|
||||
mcp = FastMCP(name="MyServer", tool_serializer=yaml_serializer)
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def get_config():
|
||||
"""Returns configuration in YAML format."""
|
||||
return {"api_key": "abc123", "debug": True, "rate_limit": 100}
|
||||
|
|
|
|||
|
|
@ -33,13 +33,13 @@ from fastmcp.prompts.prompt import Message, PromptMessage, TextContent
|
|||
mcp = FastMCP(name="PromptServer")
|
||||
|
||||
# Basic prompt returning a string (converted to user message automatically)
|
||||
@mcp.prompt
|
||||
@mcp.prompt()
|
||||
def ask_about_topic(topic: str) -> str:
|
||||
"""Generates a user message asking for an explanation of a topic."""
|
||||
return f"Can you please explain the concept of '{topic}'?"
|
||||
|
||||
# Prompt returning a specific message type
|
||||
@mcp.prompt
|
||||
@mcp.prompt()
|
||||
def generate_code_request(language: str, task_description: str) -> PromptMessage:
|
||||
"""Generates a user message requesting code generation."""
|
||||
content = f"Write a {language} function that performs the following task: {task_description}"
|
||||
|
|
@ -69,7 +69,7 @@ FastMCP intelligently handles different return types from your prompt function:
|
|||
```python
|
||||
from fastmcp.prompts.prompt import Message
|
||||
|
||||
@mcp.prompt
|
||||
@mcp.prompt()
|
||||
def roleplay_scenario(character: str, situation: str) -> list[Message]:
|
||||
"""Sets up a roleplaying scenario with initial messages."""
|
||||
return [
|
||||
|
|
@ -89,7 +89,7 @@ Type annotations are important for prompts. They:
|
|||
from pydantic import Field
|
||||
from typing import Literal, Optional
|
||||
|
||||
@mcp.prompt
|
||||
@mcp.prompt()
|
||||
def generate_content_request(
|
||||
topic: str = Field(description="The main subject to cover"),
|
||||
format: Literal["blog", "email", "social"] = "blog",
|
||||
|
|
@ -111,7 +111,7 @@ def generate_content_request(
|
|||
Parameters in your function signature are considered **required** unless they have a default value.
|
||||
|
||||
```python
|
||||
@mcp.prompt
|
||||
@mcp.prompt()
|
||||
def data_analysis_prompt(
|
||||
data_uri: str, # Required - no default value
|
||||
analysis_type: str = "summary", # Optional - has default value
|
||||
|
|
@ -154,13 +154,13 @@ FastMCP seamlessly supports both standard (`def`) and asynchronous (`async def`)
|
|||
|
||||
```python
|
||||
# Synchronous prompt
|
||||
@mcp.prompt
|
||||
@mcp.prompt()
|
||||
def simple_question(question: str) -> str:
|
||||
"""Generates a simple question to ask the LLM."""
|
||||
return f"Question: {question}"
|
||||
|
||||
# Asynchronous prompt
|
||||
@mcp.prompt
|
||||
@mcp.prompt()
|
||||
async def data_based_prompt(data_id: str) -> str:
|
||||
"""Generates a prompt based on data that needs to be fetched."""
|
||||
# In a real scenario, you might fetch data from a database or API
|
||||
|
|
@ -183,7 +183,7 @@ from fastmcp import FastMCP, Context
|
|||
|
||||
mcp = FastMCP(name="PromptServer")
|
||||
|
||||
@mcp.prompt
|
||||
@mcp.prompt()
|
||||
async def generate_report_request(report_type: str, ctx: Context) -> str:
|
||||
"""Generates a request for a report."""
|
||||
return f"Please create a {report_type} report. Request ID: {ctx.request_id}"
|
||||
|
|
@ -207,7 +207,7 @@ mcp = FastMCP(
|
|||
on_duplicate_prompts="error" # Raise an error if a prompt name is duplicated
|
||||
)
|
||||
|
||||
@mcp.prompt
|
||||
@mcp.prompt()
|
||||
def greeting(): return "Hello, how can I help you today?"
|
||||
|
||||
# This registration attempt will raise a ValueError because
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ from fastmcp import FastMCP
|
|||
# Original server
|
||||
original_server = FastMCP(name="Original")
|
||||
|
||||
@original_server.tool
|
||||
@original_server.tool()
|
||||
def tool_a() -> str:
|
||||
return "A"
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ from fastmcp import FastMCP
|
|||
|
||||
mcp = FastMCP(name="CalculatorServer")
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def add(a: int, b: int) -> int:
|
||||
"""Adds two integer numbers together."""
|
||||
return a + b
|
||||
|
|
@ -61,7 +61,7 @@ Type annotations for parameters are essential for proper tool functionality. The
|
|||
Use standard Python type annotations for parameters:
|
||||
|
||||
```python
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def analyze_text(
|
||||
text: str,
|
||||
max_tokens: int = 100,
|
||||
|
|
@ -79,7 +79,7 @@ You can provide additional metadata about parameters using Pydantic's `Field` cl
|
|||
from typing import Annotated
|
||||
from pydantic import Field
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def process_image(
|
||||
image_url: Annotated[str, Field(description="URL of the image to process")],
|
||||
resize: Annotated[bool, Field(description="Whether to resize the image")] = False,
|
||||
|
|
@ -97,7 +97,7 @@ def process_image(
|
|||
You can also use the Field as a default value, though the Annotated approach is preferred:
|
||||
|
||||
```python
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def search_database(
|
||||
query: str = Field(description="Search query string"),
|
||||
limit: int = Field(10, description="Maximum number of results", ge=1, le=100)
|
||||
|
|
@ -137,7 +137,7 @@ For additional type annotations not listed here, see the [Parameter Types](#para
|
|||
FastMCP follows Python's standard function parameter conventions. Parameters without default values are required, while those with default values are optional.
|
||||
|
||||
```python
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def search_products(
|
||||
query: str, # Required - no default value
|
||||
max_results: int = 10, # Optional - has default value
|
||||
|
|
@ -197,14 +197,14 @@ FastMCP seamlessly supports both standard (`def`) and asynchronous (`async def`)
|
|||
|
||||
```python
|
||||
# Synchronous tool (suitable for CPU-bound or quick tasks)
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def calculate_distance(lat1: float, lon1: float, lat2: float, lon2: float) -> float:
|
||||
"""Calculate the distance between two coordinates."""
|
||||
# Implementation...
|
||||
return 42.5
|
||||
|
||||
# Asynchronous tool (ideal for I/O-bound operations)
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
async def fetch_weather(city: str) -> dict:
|
||||
"""Retrieve current weather conditions for a city."""
|
||||
# Use 'async def' for operations involving network calls, file I/O, etc.
|
||||
|
|
@ -244,7 +244,7 @@ except ImportError:
|
|||
|
||||
mcp = FastMCP("Image Demo")
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def generate_image(width: int, height: int, color: str) -> Image:
|
||||
"""Generates a solid color image."""
|
||||
# Create image using Pillow
|
||||
|
|
@ -258,7 +258,7 @@ def generate_image(width: int, height: int, color: str) -> Image:
|
|||
# Return using FastMCP's Image helper
|
||||
return Image(data=img_bytes, format="png")
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def do_nothing() -> None:
|
||||
"""This tool performs an action but returns no data."""
|
||||
print("Performing a side effect...")
|
||||
|
|
@ -285,7 +285,7 @@ mcp = FastMCP(name="SecureServer", mask_error_details=True)
|
|||
from fastmcp import FastMCP
|
||||
from fastmcp.exceptions import ToolError
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def divide(a: float, b: float) -> float:
|
||||
"""Divide a by b."""
|
||||
|
||||
|
|
@ -351,7 +351,7 @@ from fastmcp import FastMCP, Context
|
|||
|
||||
mcp = FastMCP(name="ContextDemo")
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
async def process_data(data_uri: str, ctx: Context) -> dict:
|
||||
"""Process data from a resource with progress reporting."""
|
||||
await ctx.info(f"Processing data from {data_uri}")
|
||||
|
|
@ -396,7 +396,7 @@ FastMCP supports **type coercion** when possible. This means that if a client se
|
|||
The most common parameter types are Python's built-in scalar types:
|
||||
|
||||
```python
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def process_values(
|
||||
name: str, # Text data
|
||||
count: int, # Integer numbers
|
||||
|
|
@ -416,7 +416,7 @@ FastMCP supports various date and time types from the `datetime` module:
|
|||
```python
|
||||
from datetime import datetime, date, timedelta
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def process_date_time(
|
||||
event_date: date, # ISO format date string or date object
|
||||
event_time: datetime, # ISO format datetime string or datetime object
|
||||
|
|
@ -440,7 +440,7 @@ def process_date_time(
|
|||
FastMCP supports all standard Python collection types:
|
||||
|
||||
```python
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def analyze_data(
|
||||
values: list[float], # List of numbers
|
||||
properties: dict[str, str], # Dictionary with string keys and values
|
||||
|
|
@ -465,7 +465,7 @@ Collection types can be nested and combined to represent complex data structures
|
|||
For parameters that can accept multiple types or may be omitted:
|
||||
|
||||
```python
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def flexible_search(
|
||||
query: str | int, # Can be either string or integer
|
||||
filters: dict[str, str] | None = None, # Optional dictionary
|
||||
|
|
@ -488,7 +488,7 @@ Literals constrain parameters to a specific set of values:
|
|||
```python
|
||||
from typing import Literal
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def sort_data(
|
||||
data: list[float],
|
||||
order: Literal["ascending", "descending"] = "ascending",
|
||||
|
|
@ -516,7 +516,7 @@ class Color(Enum):
|
|||
GREEN = "green"
|
||||
BLUE = "blue"
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def process_image(
|
||||
image_path: str,
|
||||
color_filter: Color = Color.RED
|
||||
|
|
@ -539,7 +539,7 @@ There are two approaches to handling binary data in tool parameters:
|
|||
#### Bytes
|
||||
|
||||
```python
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def process_binary(data: bytes):
|
||||
"""Process binary data directly.
|
||||
|
||||
|
|
@ -563,7 +563,7 @@ FastMCP does not automatically decode base64-encoded strings for bytes parameter
|
|||
from typing import Annotated
|
||||
from pydantic import Field
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def process_image_data(
|
||||
image_data: Annotated[str, Field(description="Base64-encoded image data")]
|
||||
):
|
||||
|
|
@ -587,7 +587,7 @@ The `Path` type from the `pathlib` module can be used for file system paths:
|
|||
```python
|
||||
from pathlib import Path
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def process_file(path: Path) -> str:
|
||||
"""Process a file at the given path."""
|
||||
assert isinstance(path, Path) # Path is properly converted
|
||||
|
|
@ -603,7 +603,7 @@ The `UUID` type from the `uuid` module can be used for unique identifiers:
|
|||
```python
|
||||
import uuid
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def process_item(
|
||||
item_id: uuid.UUID # String UUID or UUID object
|
||||
) -> str:
|
||||
|
|
@ -628,7 +628,7 @@ class User(BaseModel):
|
|||
age: int | None = None
|
||||
is_active: bool = True
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def create_user(user: User):
|
||||
"""Create a new user in the system."""
|
||||
# The input is automatically validated against the User model
|
||||
|
|
@ -657,7 +657,7 @@ Note that fields can be used *outside* Pydantic models to provide metadata and v
|
|||
from typing import Annotated
|
||||
from pydantic import Field
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def analyze_metrics(
|
||||
# Numbers with range constraints
|
||||
count: Annotated[int, Field(ge=0, le=100)], # 0 <= count <= 100
|
||||
|
|
@ -682,7 +682,7 @@ def analyze_metrics(
|
|||
You can also use `Field` as a default value, though the `Annotated` approach is preferred:
|
||||
|
||||
```python
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def validate_data(
|
||||
# Value constraints
|
||||
age: int = Field(ge=0, lt=120), # 0 <= age < 120
|
||||
|
|
@ -727,7 +727,7 @@ mcp = FastMCP(
|
|||
on_duplicate_tools="error"
|
||||
)
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def my_tool(): return "Version 1"
|
||||
|
||||
# This will now raise a ValueError because 'my_tool' already exists
|
||||
|
|
@ -754,7 +754,7 @@ from fastmcp import FastMCP
|
|||
|
||||
mcp = FastMCP(name="DynamicToolServer")
|
||||
|
||||
@mcp.tool
|
||||
@mcp.tool()
|
||||
def calculate_sum(a: int, b: int) -> int:
|
||||
"""Add two numbers together."""
|
||||
return a + b
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue