Clean up parameter documentation

This commit is contained in:
Jeremiah Lowin 2025-06-22 20:59:53 -04:00
commit 44f14b1f7b
9 changed files with 742 additions and 133 deletions

View file

@ -0,0 +1,364 @@
---
description:
globs: *.mdx
alwaysApply: false
---
# Mintlify technical writing assistant
You are an AI writing assistant specialized in creating exceptional technical documentation using Mintlify components and following industry-leading technical writing practices.
## Core writing principles
### Language and style requirements
- Use clear, direct language appropriate for technical audiences
- Write in second person ("you") for instructions and procedures
- Use active voice over passive voice
- Employ present tense for current states, future tense for outcomes
- Maintain consistent terminology throughout all documentation
- Keep sentences concise while providing necessary context
- Use parallel structure in lists, headings, and procedures
### Content organization standards
- Lead with the most important information (inverted pyramid structure)
- Use progressive disclosure: basic concepts before advanced ones
- Break complex procedures into numbered steps
- Include prerequisites and context before instructions
- Provide expected outcomes for each major step
- End sections with next steps or related information
- Use descriptive, keyword-rich headings for navigation and SEO
### User-centered approach
- Focus on user goals and outcomes rather than system features
- Anticipate common questions and address them proactively
- Include troubleshooting for likely failure points
- Provide multiple pathways when appropriate (beginner vs advanced), but offer an opinionated path for people to follow to avoid overwhelming with options
## Mintlify component reference
### Callout components
#### Note - Additional helpful information
<Note>
Supplementary information that supports the main content without interrupting flow
</Note>
#### Tip - Best practices and pro tips
<Tip>
Expert advice, shortcuts, or best practices that enhance user success
</Tip>
#### Warning - Important cautions
<Warning>
Critical information about potential issues, breaking changes, or destructive actions
</Warning>
#### Info - Neutral contextual information
<Info>
Background information, context, or neutral announcements
</Info>
#### Check - Success confirmations
<Check>
Positive confirmations, successful completions, or achievement indicators
</Check>
### Code components
#### Single code block
```javascript config.js
const apiConfig = {
baseURL: 'https://api.example.com',
timeout: 5000,
headers: {
'Authorization': `Bearer ${process.env.API_TOKEN}`
}
};
```
#### Code group with multiple languages
<CodeGroup>
```javascript Node.js
const response = await fetch('/api/endpoint', {
headers: { Authorization: `Bearer ${apiKey}` }
});
```
```python Python
import requests
response = requests.get('/api/endpoint',
headers={'Authorization': f'Bearer {api_key}'})
```
```curl cURL
curl -X GET '/api/endpoint' \
-H 'Authorization: Bearer YOUR_API_KEY'
```
</CodeGroup>
#### Request/Response examples
<RequestExample>
```bash cURL
curl -X POST 'https://api.example.com/users' \
-H 'Content-Type: application/json' \
-d '{"name": "John Doe", "email": "john@example.com"}'
```
</RequestExample>
<ResponseExample>
```json Success
{
"id": "user_123",
"name": "John Doe",
"email": "john@example.com",
"created_at": "2024-01-15T10:30:00Z"
}
```
</ResponseExample>
### Structural components
#### Steps for procedures
<Steps>
<Step title="Install dependencies">
Run `npm install` to install required packages.
<Check>
Verify installation by running `npm list`.
</Check>
</Step>
<Step title="Configure environment">
Create a `.env` file with your API credentials.
```bash
API_KEY=your_api_key_here
```
<Warning>
Never commit API keys to version control.
</Warning>
</Step>
</Steps>
#### Tabs for alternative content
<Tabs>
<Tab title="macOS">
```bash
brew install node
npm install -g package-name
```
</Tab>
<Tab title="Windows">
```powershell
choco install nodejs
npm install -g package-name
```
</Tab>
<Tab title="Linux">
```bash
sudo apt install nodejs npm
npm install -g package-name
```
</Tab>
</Tabs>
#### Accordions for collapsible content
<AccordionGroup>
<Accordion title="Troubleshooting connection issues">
- **Firewall blocking**: Ensure ports 80 and 443 are open
- **Proxy configuration**: Set HTTP_PROXY environment variable
- **DNS resolution**: Try using 8.8.8.8 as DNS server
</Accordion>
<Accordion title="Advanced configuration">
```javascript
const config = {
performance: { cache: true, timeout: 30000 },
security: { encryption: 'AES-256' }
};
```
</Accordion>
</AccordionGroup>
### API documentation components
#### Parameter fields
<ParamField path="user_id" type="string" required>
Unique identifier for the user. Must be a valid UUID v4 format.
</ParamField>
<ParamField body="email" type="string" required>
User's email address. Must be valid and unique within the system.
</ParamField>
<ParamField query="limit" type="integer" default="10">
Maximum number of results to return. Range: 1-100.
</ParamField>
<ParamField header="Authorization" type="string" required>
Bearer token for API authentication. Format: `Bearer YOUR_API_KEY`
</ParamField>
#### Response fields
<ResponseField name="user_id" type="string" required>
Unique identifier assigned to the newly created user.
</ResponseField>
<ResponseField name="created_at" type="timestamp">
ISO 8601 formatted timestamp of when the user was created.
</ResponseField>
<ResponseField name="permissions" type="array">
List of permission strings assigned to this user.
</ResponseField>
#### Expandable nested fields
<ResponseField name="user" type="object">
Complete user object with all associated data.
<Expandable title="User properties">
<ResponseField name="profile" type="object">
User profile information including personal details.
<Expandable title="Profile details">
<ResponseField name="first_name" type="string">
User's first name as entered during registration.
</ResponseField>
<ResponseField name="avatar_url" type="string | null">
URL to user's profile picture. Returns null if no avatar is set.
</ResponseField>
</Expandable>
</ResponseField>
</Expandable>
</ResponseField>
### Interactive components
#### Cards for navigation
<Card title="Getting started guide" icon="rocket" href="/quickstart">
Complete walkthrough from installation to your first API call in under 10 minutes.
</Card>
<CardGroup cols={2}>
<Card title="Authentication" icon="key" href="/auth">
Learn how to authenticate requests using API keys or JWT tokens.
</Card>
<Card title="Rate limiting" icon="clock" href="/rate-limits">
Understand rate limits and best practices for high-volume usage.
</Card>
</CardGroup>
### Media and advanced components
#### Frames for images
Wrap all images in frames.
<Frame>
<img src="/images/dashboard.png" alt="Main dashboard showing analytics overview" />
</Frame>
<Frame caption="The analytics dashboard provides real-time insights">
<img src="/images/analytics.png" alt="Analytics dashboard with charts" />
</Frame>
#### Tooltips and updates
<Tooltip tip="Application Programming Interface - protocols for building software">
API
</Tooltip>
<Update label="Version 2.1.0" description="Released March 15, 2024">
## New features
- Added bulk user import functionality
- Improved error messages with actionable suggestions
## Bug fixes
- Fixed pagination issue with large datasets
- Resolved authentication timeout problems
</Update>
## Required page structure
Every documentation page must begin with YAML frontmatter:
```yaml
---
title: "Clear, specific, keyword-rich title"
description: "Concise description explaining page purpose and value"
---
```
## Content quality standards
### Code examples requirements
- Always include complete, runnable examples that users can copy and execute
- Show proper error handling and edge case management
- Use realistic data instead of placeholder values
- Include expected outputs and results for verification
- Test all code examples thoroughly before publishing
- Specify language and include filename when relevant
- Add explanatory comments for complex logic
### API documentation requirements
- Document all parameters including optional ones with clear descriptions
- Show both success and error response examples with realistic data
- Include rate limiting information with specific limits
- Provide authentication examples showing proper format
- Explain all HTTP status codes and error handling
- Cover complete request/response cycles
### Accessibility requirements
- Include descriptive alt text for all images and diagrams
- Use specific, actionable link text instead of "click here"
- Ensure proper heading hierarchy starting with H2
- Provide keyboard navigation considerations
- Use sufficient color contrast in examples and visuals
- Structure content for easy scanning with headers and lists
## AI assistant instructions
### Component selection logic
- Use **Steps** for procedures, tutorials, setup guides, and sequential instructions
- Use **Tabs** for platform-specific content or alternative approaches
- Use **CodeGroup** when showing the same concept in multiple languages
- Use **Accordions** for supplementary information that might interrupt flow
- Use **Cards and CardGroup** for navigation, feature overviews, and related resources
- Use **RequestExample/ResponseExample** specifically for API endpoint documentation
- Use **ParamField** for API parameters, **ResponseField** for API responses
- Use **Expandable** for nested object properties or hierarchical information
### Quality assurance checklist
- Verify all code examples are syntactically correct and executable
- Test all links to ensure they are functional and lead to relevant content
- Validate Mintlify component syntax with all required properties
- Confirm proper heading hierarchy with H2 for main sections, H3 for subsections
- Ensure content flows logically from basic concepts to advanced topics
- Check for consistency in terminology, formatting, and component usage
### Error prevention strategies
- Always include realistic error handling in code examples
- Provide dedicated troubleshooting sections for complex procedures
- Explain prerequisites clearly before beginning instructions
- Include verification and testing steps with expected outcomes
- Add appropriate warnings for destructive or security-sensitive actions
- Validate all technical information through testing before publication

View file

@ -11,7 +11,7 @@ import { VersionBadge } from '/snippets/version-badge.mdx'
MCP servers can emit log messages to clients. The client can handle these logs through a log handler callback. MCP servers can emit log messages to clients. The client can handle these logs through a log handler callback.
## Setting Up Log Handling ## Log Handler
Provide a `log_handler` function when creating the client: Provide a `log_handler` function when creating the client:
@ -31,13 +31,27 @@ client = Client(
) )
``` ```
## LogMessage Structure ### Handler Parameters
The `log_handler` receives a `LogMessage` object with: The `log_handler` is called every time a log message is received. It receives a `LogMessage` object:
- **`level`**: Log level (e.g., "debug", "info", "warning", "error") <Card icon="code" title="Log Handler Parameters">
- **`logger`**: Logger name (optional, may be None) <ResponseField name="LogMessage" type="Log Message Object">
- **`data`**: The actual log message content <Expandable title="attributes">
<ResponseField name="level" type='Literal["debug", "info", "notice", "warning", "error", "critical", "alert", "emergency"]'>
The log level
</ResponseField>
<ResponseField name="logger" type="str | None">
The logger name (optional, may be None)
</ResponseField>
<ResponseField name="data" type="Any">
The actual log message content
</ResponseField>
</Expandable>
</ResponseField>
</Card>
```python ```python
async def detailed_log_handler(message: LogMessage): async def detailed_log_handler(message: LogMessage):
@ -51,13 +65,12 @@ async def detailed_log_handler(message: LogMessage):
## Default Log Handling ## Default Log Handling
If you don't provide a custom `log_handler`, FastMCP uses a default handler that emits DEBUG level logs: If you don't provide a custom `log_handler`, FastMCP uses a default handler that emits a DEBUG-level FastMCP log for every log message received from the server, which is useful for visibility without polluting your own logs.
```python ```python
# Without custom handler - uses default DEBUG logging
client = Client("my_mcp_server.py") client = Client("my_mcp_server.py")
async with client: async with client:
# Server logs will be emitted at DEBUG level # Server logs will be emitted at DEBUG level automatically
await client.call_tool("some_tool") await client.call_tool("some_tool")
``` ```

View file

@ -11,7 +11,7 @@ import { VersionBadge } from '/snippets/version-badge.mdx'
MCP servers can report progress during long-running operations. The client can receive these updates through a progress handler. MCP servers can report progress during long-running operations. The client can receive these updates through a progress handler.
## Setting Up Progress Handling ## Progress Handler
Set a progress handler when creating the client: Set a progress handler when creating the client:
@ -35,6 +35,26 @@ client = Client(
) )
``` ```
### Handler Parameters
The progress handler receives three parameters:
<Card icon="code" title="Progress Handler Parameters">
<ResponseField name="progress" type="float">
Current progress value
</ResponseField>
<ResponseField name="total" type="float | None">
Expected total value (may be None)
</ResponseField>
<ResponseField name="message" type="str | None">
Optional status message (may be None)
</ResponseField>
</Card>
## Per-Call Progress Handler ## Per-Call Progress Handler
Override the progress handler for specific tool calls: Override the progress handler for specific tool calls:
@ -48,12 +68,3 @@ async with client:
progress_handler=my_progress_handler progress_handler=my_progress_handler
) )
``` ```
## Handler Parameters
The progress handler receives:
- **`progress`** (float): Current progress value
- **`total`** (float | None): Expected total value (may be None)
- **`message`** (str | None): Optional status message (may be None)

View file

@ -5,13 +5,13 @@ description: Handle server-initiated LLM sampling requests.
icon: robot icon: robot
--- ---
import { VersionBadge } from '/snippets/version-badge.mdx' import { VersionBadge } from "/snippets/version-badge.mdx";
<VersionBadge version="2.0.0" /> <VersionBadge version="2.0.0" />
MCP servers can request LLM completions from clients. The client handles these requests through a sampling handler callback. MCP servers can request LLM completions from clients. The client handles these requests through a sampling handler callback.
## Setting Up Sampling Handling ## Sampling Handler
Provide a `sampling_handler` function when creating the client: Provide a `sampling_handler` function when creating the client:
@ -38,26 +38,88 @@ client = Client(
) )
``` ```
## Handler Parameters ### Handler Parameters
The sampling handler receives three parameters: The sampling handler receives three parameters:
### SamplingMessage <Card icon="code" title="Sampling Handler Parameters">
<ResponseField name="SamplingMessage" type="Sampling Message Object">
<Expandable title="attributes">
<ResponseField name="role" type='Literal["user", "assistant"]'>
The role of the message.
</ResponseField>
- **`role`**: Message role (e.g., "user", "assistant", "system") <ResponseField name="content" type="TextContent | ImageContent | AudioContent">
- **`content`**: Message content (usually has `.text` attribute) The content of the message.
### SamplingParams TextContent is most common, and has a `.text` attribute.
</ResponseField>
- **`systemPrompt`**: System prompt string (optional) </Expandable>
- **`maxTokens`**: Maximum tokens to generate (optional) </ResponseField>
- **`temperature`**: Sampling temperature (optional) <ResponseField name="SamplingParams" type="Sampling Parameters Object">
- **`topP`**: Top-p sampling parameter (optional) <Expandable title="attributes">
- **`stopSequences`**: List of stop sequences (optional) <ResponseField name="messages" type="list[SamplingMessage]">
The messages to sample from
</ResponseField>
### RequestContext <ResponseField name="modelPreferences" type="ModelPreferences | None">
The server's preferences for which model to select. The client MAY ignore
these preferences.
<Expandable title="attributes">
<ResponseField name="hints" type="list[ModelHint] | None">
The hints to use for model selection.
</ResponseField>
- **`request_id`**: Unique identifier for the sampling request <ResponseField name="costPriority" type="float | None">
The cost priority for model selection.
</ResponseField>
<ResponseField name="speedPriority" type="float | None">
The speed priority for model selection.
</ResponseField>
<ResponseField name="intelligencePriority" type="float | None">
The intelligence priority for model selection.
</ResponseField>
</Expandable>
</ResponseField>
<ResponseField name="systemPrompt" type="str | None">
An optional system prompt the server wants to use for sampling.
</ResponseField>
<ResponseField name="includeContext" type="IncludeContext | None">
A request to include context from one or more MCP servers (including the caller), to
be attached to the prompt.
</ResponseField>
<ResponseField name="temperature" type="float | None">
The sampling temperature.
</ResponseField>
<ResponseField name="maxTokens" type="int">
The maximum number of tokens to sample.
</ResponseField>
<ResponseField name="stopSequences" type="list[str] | None">
The stop sequences to use for sampling.
</ResponseField>
<ResponseField name="metadata" type="dict[str, Any] | None">
Optional metadata to pass through to the LLM provider.
</ResponseField>
</Expandable>
</ResponseField>
<ResponseField name="RequestContext" type="Request Context Object">
<Expandable title="attributes">
<ResponseField name="request_id" type="RequestId">
Unique identifier for the MCP request
</ResponseField>
</Expandable>
</ResponseField>
</Card>
## Basic Example ## Basic Example
@ -75,10 +137,10 @@ async def basic_sampling_handler(
for message in messages: for message in messages:
content = message.content.text if hasattr(message.content, 'text') else str(message.content) content = message.content.text if hasattr(message.content, 'text') else str(message.content)
conversation.append(f"{message.role}: {content}") conversation.append(f"{message.role}: {content}")
# Use the system prompt if provided # Use the system prompt if provided
system_prompt = params.systemPrompt or "You are a helpful assistant." system_prompt = params.systemPrompt or "You are a helpful assistant."
# Here you would integrate with your preferred LLM service # Here you would integrate with your preferred LLM service
# This is just a placeholder response # This is just a placeholder response
return f"Response based on conversation: {' | '.join(conversation)}" return f"Response based on conversation: {' | '.join(conversation)}"
@ -88,4 +150,3 @@ client = Client(
sampling_handler=basic_sampling_handler sampling_handler=basic_sampling_handler
) )
``` ```

View file

@ -61,13 +61,27 @@ mcp = FastMCP(name="My MCP Server", auth=auth)
### Configuration Parameters ### Configuration Parameters
| Parameter | Type | Required | Description | <Card icon="code" title="BearerAuthProvider Configuration">
|-----------|------|----------|-------------| <ParamField body="public_key" type="str">
| `public_key` | `str` | If `jwks_uri` is not provided | RSA public key in PEM format for static key validation | RSA public key in PEM format for static key validation. Required if `jwks_uri` is not provided
| `jwks_uri` | `str` | If `public_key` is not provided | URL for JSON Web Key Set endpoint | </ParamField>
| `issuer` | `str` | No | Expected JWT `iss` claim value |
| `audience` | `str` | No | Expected JWT `aud` claim value | <ParamField body="jwks_uri" type="str">
| `required_scopes` | `list[str]` | No | Global scopes required for all requests | URL for JSON Web Key Set endpoint. Required if `public_key` is not provided
</ParamField>
<ParamField body="issuer" type="str | None">
Expected JWT `iss` claim value
</ParamField>
<ParamField body="audience" type="str | None">
Expected JWT `aud` claim value
</ParamField>
<ParamField body="required_scopes" type="list[str] | None">
Global scopes required for all requests
</ParamField>
</Card>
#### Public Key #### Public Key
@ -141,15 +155,35 @@ print(f"Test token: {token}")
The `create_token()` method accepts these parameters: The `create_token()` method accepts these parameters:
| Parameter | Type | Default | Description | <Card icon="code" title="create_token() Parameters">
|-----------|------|---------|-------------| <ParamField body="subject" type="str" default="fastmcp-user">
| `subject` | `str` | `"fastmcp-user"` | JWT subject claim (usually user ID) | JWT subject claim (usually user ID)
| `issuer` | `str` | `"https://fastmcp.example.com"` | JWT issuer claim | </ParamField>
| `audience` | `str` | `None` | JWT audience claim |
| `scopes` | `list[str]` | `None` | OAuth scopes to include | <ParamField body="issuer" type="str" default="https://fastmcp.example.com">
| `expires_in_seconds` | `int` | `3600` | Token expiration time | JWT issuer claim
| `additional_claims` | `dict` | `None` | Extra claims to include | </ParamField>
| `kid` | `str` | `None` | Key ID for JWKS lookup |
<ParamField body="audience" type="str | None">
JWT audience claim
</ParamField>
<ParamField body="scopes" type="list[str] | None">
OAuth scopes to include
</ParamField>
<ParamField body="expires_in_seconds" type="int" default="3600">
Token expiration time in seconds
</ParamField>
<ParamField body="additional_claims" type="dict | None">
Extra claims to include in the token
</ParamField>
<ParamField body="kid" type="str | None">
Key ID for JWKS lookup
</ParamField>
</Card>
## Accessing Token Claims ## Accessing Token Claims
@ -179,10 +213,21 @@ async def get_my_data(ctx: Context) -> dict:
### AccessToken Properties ### AccessToken Properties
| Property | Type | Description | <Card icon="code" title="AccessToken Properties">
|----------|------|-------------| <ParamField body="token" type="str">
| `token` | `str` | The raw JWT string | The raw JWT string
| `client_id` | `str` | Authenticated principal identifier | </ParamField>
| `scopes` | `list[str]` | Granted scopes |
| `expires_at` | `datetime \| None` | Token expiration timestamp | <ParamField body="client_id" type="str">
Authenticated principal identifier
</ParamField>
<ParamField body="scopes" type="list[str]">
Granted scopes
</ParamField>
<ParamField body="expires_at" type="datetime | None">
Token expiration timestamp
</ParamField>
</Card>

View file

@ -57,6 +57,41 @@ def generate_code_request(language: str, task_description: str) -> PromptMessage
Functions with `*args` or `**kwargs` are not supported as prompts. This restriction exists because FastMCP needs to generate a complete parameter schema for the MCP protocol, which isn't possible with variable argument lists. Functions with `*args` or `**kwargs` are not supported as prompts. This restriction exists because FastMCP needs to generate a complete parameter schema for the MCP protocol, which isn't possible with variable argument lists.
</Tip> </Tip>
#### Decorator Arguments
While FastMCP infers the name and description from your function, you can override these and add additional metadata using arguments to the `@mcp.prompt` decorator:
```python
@mcp.prompt(
name="analyze_data_request", # Custom prompt name
description="Creates a request to analyze data with specific parameters", # Custom description
tags={"analysis", "data"} # Optional categorization tags
)
def data_analysis_prompt(
data_uri: str = Field(description="The URI of the resource containing the data."),
analysis_type: str = Field(default="summary", description="Type of analysis.")
) -> str:
"""This docstring is ignored when description is provided."""
return f"Please perform a '{analysis_type}' analysis on the data found at {data_uri}."
```
<Card icon="code" title="@prompt Decorator Arguments">
<ParamField body="name" type="str | None">
Sets the explicit prompt name exposed via MCP. If not provided, uses the function name
</ParamField>
<ParamField body="description" type="str | None">
Provides the description exposed via MCP. If set, the function's docstring is ignored for this purpose
</ParamField>
<ParamField body="tags" type="set[str] | None">
A set of strings used to categorize the prompt. Clients might use tags to filter or group available prompts
</ParamField>
<ParamField body="enabled" type="bool" default="True">
A boolean to enable or disable the prompt. See [Disabling Prompts](#disabling-prompts) for more information
</ParamField>
</Card>
### Argument Types ### Argument Types
<VersionBadge version="2.9.0" /> <VersionBadge version="2.9.0" />
@ -177,28 +212,6 @@ def data_analysis_prompt(
In this example, the client *must* provide `data_uri`. If `analysis_type` or `include_charts` are omitted, their default values will be used. In this example, the client *must* provide `data_uri`. If `analysis_type` or `include_charts` are omitted, their default values will be used.
### Prompt Metadata
While FastMCP infers the name and description from your function, you can override these and add tags using arguments to the `@mcp.prompt` decorator:
```python
@mcp.prompt(
name="analyze_data_request", # Custom prompt name
description="Creates a request to analyze data with specific parameters", # Custom description
tags={"analysis", "data"} # Optional categorization tags
)
def data_analysis_prompt(
data_uri: str = Field(description="The URI of the resource containing the data."),
analysis_type: str = Field(default="summary", description="Type of analysis.")
) -> str:
"""This docstring is ignored when description is provided."""
return f"Please perform a '{analysis_type}' analysis on the data found at {data_uri}."
```
- **`name`**: Sets the explicit prompt name exposed via MCP.
- **`description`**: Provides the description exposed via MCP. If set, the function's docstring is ignored for this purpose.
- **`tags`**: A set of strings used to categorize the prompt. Clients *might* use tags to filter or group available prompts.
- **`enabled`**: A boolean to enable or disable the prompt (defaults to `True`). See [Disabling Prompts](#disabling-prompts) for more information.
### Disabling Prompts ### Disabling Prompts
<VersionBadge version="2.8.0" /> <VersionBadge version="2.8.0" />

View file

@ -58,18 +58,9 @@ def get_config() -> dict:
* Resource Name: Taken from the function name (`get_greeting`). * Resource Name: Taken from the function name (`get_greeting`).
* Resource Description: Taken from the function's docstring. * Resource Description: Taken from the function's docstring.
### Return Values #### Decorator Arguments
FastMCP automatically converts your function's return value into the appropriate MCP resource content: You can customize the resource's properties using arguments in the `@mcp.resource` decorator:
- **`str`**: Sent as `TextResourceContents` (with `mime_type="text/plain"` by default).
- **`dict`, `list`, `pydantic.BaseModel`**: Automatically serialized to a JSON string and sent as `TextResourceContents` (with `mime_type="application/json"` by default).
- **`bytes`**: Base64 encoded and sent as `BlobResourceContents`. You should specify an appropriate `mime_type` (e.g., `"image/png"`, `"application/octet-stream"`).
- **`None`**: Results in an empty resource content list being returned.
### Resource Metadata
You can customize the resource's properties using arguments in the decorator:
```python ```python
from fastmcp import FastMCP from fastmcp import FastMCP
@ -89,12 +80,40 @@ def get_application_status() -> dict:
return {"status": "ok", "uptime": 12345, "version": mcp.settings.version} # Example usage return {"status": "ok", "uptime": 12345, "version": mcp.settings.version} # Example usage
``` ```
- **`uri`**: The unique identifier for the resource (required). <Card icon="code" title="@resource Decorator Arguments">
- **`name`**: A human-readable name (defaults to function name). <ParamField body="uri" type="str" required>
- **`description`**: Explanation of the resource (defaults to docstring). The unique identifier for the resource
- **`mime_type`**: Specifies the content type (FastMCP often infers a default like `text/plain` or `application/json`, but explicit is better for non-text types). </ParamField>
- **`tags`**: A set of strings for categorization, potentially used by clients for filtering.
- **`enabled`**: A boolean to enable or disable the resource (defaults to `True`). See [Disabling Resources](#disabling-resources) for more information. <ParamField body="name" type="str | None">
A human-readable name. If not provided, defaults to function name
</ParamField>
<ParamField body="description" type="str | None">
Explanation of the resource. If not provided, defaults to docstring
</ParamField>
<ParamField body="mime_type" type="str | None">
Specifies the content type. FastMCP often infers a default like `text/plain` or `application/json`, but explicit is better for non-text types
</ParamField>
<ParamField body="tags" type="set[str] | None">
A set of strings for categorization, potentially used by clients for filtering
</ParamField>
<ParamField body="enabled" type="bool" default="True">
A boolean to enable or disable the resource. See [Disabling Resources](#disabling-resources) for more information
</ParamField>
</Card>
### Return Values
FastMCP automatically converts your function's return value into the appropriate MCP resource content:
- **`str`**: Sent as `TextResourceContents` (with `mime_type="text/plain"` by default).
- **`dict`, `list`, `pydantic.BaseModel`**: Automatically serialized to a JSON string and sent as `TextResourceContents` (with `mime_type="application/json"` by default).
- **`bytes`**: Base64 encoded and sent as `BlobResourceContents`. You should specify an appropriate `mime_type` (e.g., `"image/png"`, `"application/octet-stream"`).
- **`None`**: Results in an empty resource content list being returned.
### Disabling Resources ### Disabling Resources

View file

@ -31,13 +31,31 @@ mcp_with_instructions = FastMCP(
The `FastMCP` constructor accepts several arguments: The `FastMCP` constructor accepts several arguments:
* `name`: (Optional) A human-readable name for your server. Defaults to "FastMCP". <Card icon="code" title="FastMCP Constructor Parameters">
* `instructions`: (Optional) Description of how to interact with this server. These instructions help clients understand the server's purpose and available functionality. <ParamField body="name" type="str" default="FastMCP">
* `lifespan`: (Optional) An async context manager function for server startup and shutdown logic. A human-readable name for your server
* `tags`: (Optional) A set of strings to tag the server itself. </ParamField>
* `tools`: (Optional) A list of tools (or functions to convert to tools) to add to the server. In some cases, providing tools programmatically may be more convenient than using the `@mcp.tool` decorator.
* `**settings`: Keyword arguments corresponding to additional `ServerSettings` configuration
<ParamField body="instructions" type="str | None">
Description of how to interact with this server. These instructions help clients understand the server's purpose and available functionality
</ParamField>
<ParamField body="lifespan" type="AsyncContextManager | None">
An async context manager function for server startup and shutdown logic
</ParamField>
<ParamField body="tags" type="set[str] | None">
A set of strings to tag the server itself
</ParamField>
<ParamField body="tools" type="list[Tool | Callable] | None">
A list of tools (or functions to convert to tools) to add to the server. In some cases, providing tools programmatically may be more convenient than using the `@mcp.tool` decorator
</ParamField>
<ParamField body="**settings" type="Any">
Keyword arguments corresponding to additional `ServerSettings` configuration
</ParamField>
</Card>
## Components ## Components
FastMCP servers expose several types of components to the client: FastMCP servers expose several types of components to the client:
@ -235,6 +253,34 @@ mcp = FastMCP(
) )
``` ```
### Constructor Parameters
<Card icon="code" title="AdditionalFastMCP Constructor Parameters">
<ParamField body="dependencies" type="list[str] | None">
Optional server dependencies list with package specifications
</ParamField>
<ParamField body="include_tags" type="set[str] | None">
Only expose components with at least one matching tag
</ParamField>
<ParamField body="exclude_tags" type="set[str] | None">
Hide components with any matching tag
</ParamField>
<ParamField body="on_duplicate_tools" type='Literal["error", "warn", "replace"]' default="error">
How to handle duplicate tool registrations
</ParamField>
<ParamField body="on_duplicate_resources" type='Literal["error", "warn", "replace"]' default="warn">
How to handle duplicate resource registrations
</ParamField>
<ParamField body="on_duplicate_prompts" type='Literal["error", "warn", "replace"]' default="replace">
How to handle duplicate prompt registrations
</ParamField>
</Card>
### Global Settings ### Global Settings
Global settings affect all FastMCP servers and can be configured via environment variables (prefixed with `FASTMCP_`) or in a `.env` file: Global settings affect all FastMCP servers and can be configured via environment variables (prefixed with `FASTMCP_`) or in a `.env` file:

View file

@ -49,9 +49,68 @@ The way you define your Python function dictates how the tool appears and behave
Functions with `*args` or `**kwargs` are not supported as tools. This restriction exists because FastMCP needs to generate a complete parameter schema for the MCP protocol, which isn't possible with variable argument lists. Functions with `*args` or `**kwargs` are not supported as tools. This restriction exists because FastMCP needs to generate a complete parameter schema for the MCP protocol, which isn't possible with variable argument lists.
</Tip> </Tip>
### Parameters #### Decorator Arguments
#### Annotations While FastMCP infers the name and description from your function, you can override these and add additional metadata using arguments to the `@mcp.tool` decorator:
```python
@mcp.tool(
name="find_products", # Custom tool name for the LLM
description="Search the product catalog with optional category filtering.", # Custom description
tags={"catalog", "search"}, # Optional tags for organization/filtering
)
def search_products_implementation(query: str, category: str | None = None) -> list[dict]:
"""Internal function description (ignored if description is provided above)."""
# Implementation...
print(f"Searching for '{query}' in category '{category}'")
return [{"id": 2, "name": "Another Product"}]
```
<Card icon="code" title="@tool Decorator Arguments">
<ParamField body="name" type="str | None">
Sets the explicit tool name exposed via MCP. If not provided, uses the function name
</ParamField>
<ParamField body="description" type="str | None">
Provides the description exposed via MCP. If set, the function's docstring is ignored for this purpose
</ParamField>
<ParamField body="tags" type="set[str] | None">
A set of strings to categorize the tool. Clients might use tags to filter or group available tools
</ParamField>
<ParamField body="enabled" type="bool" default="True">
A boolean to enable or disable the tool. See [Disabling Tools](#disabling-tools) for more information
</ParamField>
<ParamField body="exclude_args" type="list[str] | None">
A list of argument names to exclude from the tool schema shown to the LLM. See [Excluding Arguments](#excluding-arguments) for more information
</ParamField>
<ParamField body="annotations" type="ToolAnnotations | dict | None">
An optional `ToolAnnotations` object or dictionary to add additional metadata about the tool.
<Expandable title="ToolAnnotations attributes">
<ParamField body="title" type="str | None">
A human-readable title for the tool.
</ParamField>
<ParamField body="readOnlyHint" type="bool | None">
If true, the tool does not modify its environment.
</ParamField>
<ParamField body="destructiveHint" type="bool | None">
If true, the tool may perform destructive updates to its environment.
</ParamField>
<ParamField body="idempotentHint" type="bool | None">
If true, calling the tool repeatedly with the same arguments will have no additional effect on the its environment.
</ParamField>
<ParamField body="openWorldHint" type="bool | None">
If true, this tool may interact with an "open world" of external entities. If false, the tool's domain of interaction is closed.
</ParamField>
</Expandable>
</ParamField>
</Card>
### Tool Parameters
#### Type Annotations
Type annotations for parameters are essential for proper tool functionality. They: Type annotations for parameters are essential for proper tool functionality. They:
1. Inform the LLM about the expected data types for each parameter 1. Inform the LLM about the expected data types for each parameter
@ -150,28 +209,6 @@ def search_products(
In this example, the LLM must provide a `query` parameter, while `max_results`, `sort_by`, and `category` will use their default values if not explicitly provided. In this example, the LLM must provide a `query` parameter, while `max_results`, `sort_by`, and `category` will use their default values if not explicitly provided.
### Metadata
While FastMCP infers the name and description from your function, you can override these and add tags using arguments to the `@mcp.tool` decorator:
```python
@mcp.tool(
name="find_products", # Custom tool name for the LLM
description="Search the product catalog with optional category filtering.", # Custom description
tags={"catalog", "search"}, # Optional tags for organization/filtering
)
def search_products_implementation(query: str, category: str | None = None) -> list[dict]:
"""Internal function description (ignored if description is provided above)."""
# Implementation...
print(f"Searching for '{query}' in category '{category}'")
return [{"id": 2, "name": "Another Product"}]
```
- **`name`**: Sets the explicit tool name exposed via MCP.
- **`description`**: Provides the description exposed via MCP. If set, the function's docstring is ignored for this purpose.
- **`tags`**: A set of strings to categorize the tool. Clients *might* use tags to filter or group available tools.
- **`enabled`**: A boolean to enable or disable the tool (defaults to `True`). See [Disabling Tools](#disabling-tools) for more information.
- **`exclude_args`**: A list of argument names to exclude from the tool schema shown to the LLM. See [Excluding Arguments](#excluding-arguments) for more information.
### Excluding Arguments ### Excluding Arguments