From 44f14b1f7be16ce35ba55f16ff2d0f3aa775606a Mon Sep 17 00:00:00 2001 From: Jeremiah Lowin <153965+jlowin@users.noreply.github.com> Date: Sun, 22 Jun 2025 20:59:53 -0400 Subject: [PATCH] Clean up parameter documentation --- docs/.cursor/rules/mintlify.mdc | 364 ++++++++++++++++++++++++++++++++ docs/clients/logging.mdx | 31 ++- docs/clients/progress.mdx | 31 ++- docs/clients/sampling.mdx | 95 +++++++-- docs/servers/auth/bearer.mdx | 89 ++++++-- docs/servers/prompts.mdx | 57 +++-- docs/servers/resources.mdx | 53 +++-- docs/servers/server.mdx | 58 ++++- docs/servers/tools.mdx | 85 +++++--- 9 files changed, 736 insertions(+), 127 deletions(-) create mode 100644 docs/.cursor/rules/mintlify.mdc diff --git a/docs/.cursor/rules/mintlify.mdc b/docs/.cursor/rules/mintlify.mdc new file mode 100644 index 000000000..503fe1647 --- /dev/null +++ b/docs/.cursor/rules/mintlify.mdc @@ -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 + + +Supplementary information that supports the main content without interrupting flow + + +#### Tip - Best practices and pro tips + + +Expert advice, shortcuts, or best practices that enhance user success + + +#### Warning - Important cautions + + +Critical information about potential issues, breaking changes, or destructive actions + + +#### Info - Neutral contextual information + + +Background information, context, or neutral announcements + + +#### Check - Success confirmations + + +Positive confirmations, successful completions, or achievement indicators + + +### 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 + + +```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' +``` + + +#### Request/Response examples + + +```bash cURL +curl -X POST 'https://api.example.com/users' \ + -H 'Content-Type: application/json' \ + -d '{"name": "John Doe", "email": "john@example.com"}' +``` + + + +```json Success +{ + "id": "user_123", + "name": "John Doe", + "email": "john@example.com", + "created_at": "2024-01-15T10:30:00Z" +} +``` + + +### Structural components + +#### Steps for procedures + + + + Run `npm install` to install required packages. + + + Verify installation by running `npm list`. + + + + + Create a `.env` file with your API credentials. + + ```bash + API_KEY=your_api_key_here + ``` + + + Never commit API keys to version control. + + + + +#### Tabs for alternative content + + + + ```bash + brew install node + npm install -g package-name + ``` + + + + ```powershell + choco install nodejs + npm install -g package-name + ``` + + + + ```bash + sudo apt install nodejs npm + npm install -g package-name + ``` + + + +#### Accordions for collapsible content + + + + - **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 + + + + ```javascript + const config = { + performance: { cache: true, timeout: 30000 }, + security: { encryption: 'AES-256' } + }; + ``` + + + +### API documentation components + +#### Parameter fields + + +Unique identifier for the user. Must be a valid UUID v4 format. + + + +User's email address. Must be valid and unique within the system. + + + +Maximum number of results to return. Range: 1-100. + + + +Bearer token for API authentication. Format: `Bearer YOUR_API_KEY` + + +#### Response fields + + +Unique identifier assigned to the newly created user. + + + +ISO 8601 formatted timestamp of when the user was created. + + + +List of permission strings assigned to this user. + + +#### Expandable nested fields + + +Complete user object with all associated data. + + + + User profile information including personal details. + + + + User's first name as entered during registration. + + + + URL to user's profile picture. Returns null if no avatar is set. + + + + + + +### Interactive components + +#### Cards for navigation + + +Complete walkthrough from installation to your first API call in under 10 minutes. + + + + + Learn how to authenticate requests using API keys or JWT tokens. + + + + Understand rate limits and best practices for high-volume usage. + + + +### Media and advanced components + +#### Frames for images + +Wrap all images in frames. + + +Main dashboard showing analytics overview + + + +Analytics dashboard with charts + + +#### Tooltips and updates + + +API + + + +## 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 + + +## 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 \ No newline at end of file diff --git a/docs/clients/logging.mdx b/docs/clients/logging.mdx index 9c28a5d25..f9cc9fcf5 100644 --- a/docs/clients/logging.mdx +++ b/docs/clients/logging.mdx @@ -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. -## Setting Up Log Handling +## Log Handler 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") -- **`logger`**: Logger name (optional, may be None) -- **`data`**: The actual log message content + + + + + The log level + + + + The logger name (optional, may be None) + + + + The actual log message content + + + + ```python async def detailed_log_handler(message: LogMessage): @@ -51,13 +65,12 @@ async def detailed_log_handler(message: LogMessage): ## 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 -# Without custom handler - uses default DEBUG logging client = Client("my_mcp_server.py") 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") ``` \ No newline at end of file diff --git a/docs/clients/progress.mdx b/docs/clients/progress.mdx index bd500fa26..ff3e0aa85 100644 --- a/docs/clients/progress.mdx +++ b/docs/clients/progress.mdx @@ -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. -## Setting Up Progress Handling +## Progress Handler Set a progress handler when creating the client: @@ -35,6 +35,26 @@ client = Client( ) ``` +### Handler Parameters + +The progress handler receives three parameters: + + + + + Current progress value + + + + Expected total value (may be None) + + + + Optional status message (may be None) + + + + ## Per-Call Progress Handler Override the progress handler for specific tool calls: @@ -48,12 +68,3 @@ async with client: 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) - diff --git a/docs/clients/sampling.mdx b/docs/clients/sampling.mdx index 25d035478..0483a59b3 100644 --- a/docs/clients/sampling.mdx +++ b/docs/clients/sampling.mdx @@ -5,13 +5,13 @@ description: Handle server-initiated LLM sampling requests. icon: robot --- -import { VersionBadge } from '/snippets/version-badge.mdx' +import { VersionBadge } from "/snippets/version-badge.mdx"; 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: @@ -38,26 +38,88 @@ client = Client( ) ``` -## Handler Parameters +### Handler Parameters The sampling handler receives three parameters: -### SamplingMessage + + + + + The role of the message. + -- **`role`**: Message role (e.g., "user", "assistant", "system") -- **`content`**: Message content (usually has `.text` attribute) + + The content of the message. -### SamplingParams + TextContent is most common, and has a `.text` attribute. + -- **`systemPrompt`**: System prompt string (optional) -- **`maxTokens`**: Maximum tokens to generate (optional) -- **`temperature`**: Sampling temperature (optional) -- **`topP`**: Top-p sampling parameter (optional) -- **`stopSequences`**: List of stop sequences (optional) + + + + + + The messages to sample from + -### RequestContext + + The server's preferences for which model to select. The client MAY ignore + these preferences. + + + The hints to use for model selection. + -- **`request_id`**: Unique identifier for the sampling request + + The cost priority for model selection. + + + + The speed priority for model selection. + + + + The intelligence priority for model selection. + + + + + + An optional system prompt the server wants to use for sampling. + + + + A request to include context from one or more MCP servers (including the caller), to + be attached to the prompt. + + + + The sampling temperature. + + + + The maximum number of tokens to sample. + + + + The stop sequences to use for sampling. + + + + Optional metadata to pass through to the LLM provider. + + + + + + + + Unique identifier for the MCP request + + + + ## Basic Example @@ -75,10 +137,10 @@ async def basic_sampling_handler( for message in messages: content = message.content.text if hasattr(message.content, 'text') else str(message.content) conversation.append(f"{message.role}: {content}") - + # Use the system prompt if provided system_prompt = params.systemPrompt or "You are a helpful assistant." - + # Here you would integrate with your preferred LLM service # This is just a placeholder response return f"Response based on conversation: {' | '.join(conversation)}" @@ -88,4 +150,3 @@ client = Client( sampling_handler=basic_sampling_handler ) ``` - diff --git a/docs/servers/auth/bearer.mdx b/docs/servers/auth/bearer.mdx index 74344a02e..15df171f6 100644 --- a/docs/servers/auth/bearer.mdx +++ b/docs/servers/auth/bearer.mdx @@ -61,13 +61,27 @@ mcp = FastMCP(name="My MCP Server", auth=auth) ### Configuration Parameters -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `public_key` | `str` | If `jwks_uri` is not provided | RSA public key in PEM format for static key validation | -| `jwks_uri` | `str` | If `public_key` is not provided | URL for JSON Web Key Set endpoint | -| `issuer` | `str` | No | Expected JWT `iss` claim value | -| `audience` | `str` | No | Expected JWT `aud` claim value | -| `required_scopes` | `list[str]` | No | Global scopes required for all requests | + + + RSA public key in PEM format for static key validation. Required if `jwks_uri` is not provided + + + + URL for JSON Web Key Set endpoint. Required if `public_key` is not provided + + + + Expected JWT `iss` claim value + + + + Expected JWT `aud` claim value + + + + Global scopes required for all requests + + #### Public Key @@ -141,15 +155,35 @@ print(f"Test token: {token}") The `create_token()` method accepts these parameters: -| Parameter | Type | Default | Description | -|-----------|------|---------|-------------| -| `subject` | `str` | `"fastmcp-user"` | JWT subject claim (usually user ID) | -| `issuer` | `str` | `"https://fastmcp.example.com"` | JWT issuer claim | -| `audience` | `str` | `None` | JWT audience claim | -| `scopes` | `list[str]` | `None` | OAuth scopes to include | -| `expires_in_seconds` | `int` | `3600` | Token expiration time | -| `additional_claims` | `dict` | `None` | Extra claims to include | -| `kid` | `str` | `None` | Key ID for JWKS lookup | + + + JWT subject claim (usually user ID) + + + + JWT issuer claim + + + + JWT audience claim + + + + OAuth scopes to include + + + + Token expiration time in seconds + + + + Extra claims to include in the token + + + + Key ID for JWKS lookup + + ## Accessing Token Claims @@ -179,10 +213,21 @@ async def get_my_data(ctx: Context) -> dict: ### AccessToken Properties -| Property | Type | Description | -|----------|------|-------------| -| `token` | `str` | The raw JWT string | -| `client_id` | `str` | Authenticated principal identifier | -| `scopes` | `list[str]` | Granted scopes | -| `expires_at` | `datetime \| None` | Token expiration timestamp | + + + The raw JWT string + + + + Authenticated principal identifier + + + + Granted scopes + + + + Token expiration timestamp + + diff --git a/docs/servers/prompts.mdx b/docs/servers/prompts.mdx index 80c799781..f296cb74e 100644 --- a/docs/servers/prompts.mdx +++ b/docs/servers/prompts.mdx @@ -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. +#### 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}." +``` + + + + Sets the explicit prompt name exposed via MCP. If not provided, uses the function name + + + + Provides the description exposed via MCP. If set, the function's docstring is ignored for this purpose + + + + A set of strings used to categorize the prompt. Clients might use tags to filter or group available prompts + + + + A boolean to enable or disable the prompt. See [Disabling Prompts](#disabling-prompts) for more information + + ### Argument Types @@ -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. -### 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 diff --git a/docs/servers/resources.mdx b/docs/servers/resources.mdx index f38834980..127f70805 100644 --- a/docs/servers/resources.mdx +++ b/docs/servers/resources.mdx @@ -58,18 +58,9 @@ def get_config() -> dict: * Resource Name: Taken from the function name (`get_greeting`). * 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: - -- **`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: +You can customize the resource's properties using arguments in the `@mcp.resource` decorator: ```python from fastmcp import FastMCP @@ -89,12 +80,40 @@ def get_application_status() -> dict: return {"status": "ok", "uptime": 12345, "version": mcp.settings.version} # Example usage ``` -- **`uri`**: The unique identifier for the resource (required). -- **`name`**: A human-readable name (defaults to function name). -- **`description`**: Explanation of the resource (defaults to docstring). -- **`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). -- **`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. + + + The unique identifier for the resource + + + + A human-readable name. If not provided, defaults to function name + + + + Explanation of the resource. If not provided, defaults to docstring + + + + Specifies the content type. FastMCP often infers a default like `text/plain` or `application/json`, but explicit is better for non-text types + + + + A set of strings for categorization, potentially used by clients for filtering + + + + A boolean to enable or disable the resource. See [Disabling Resources](#disabling-resources) for more information + + + +### 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 diff --git a/docs/servers/server.mdx b/docs/servers/server.mdx index f8c4eda21..df3dfd2b0 100644 --- a/docs/servers/server.mdx +++ b/docs/servers/server.mdx @@ -31,13 +31,31 @@ mcp_with_instructions = FastMCP( The `FastMCP` constructor accepts several arguments: -* `name`: (Optional) A human-readable name for your server. Defaults to "FastMCP". -* `instructions`: (Optional) Description of how to interact with this server. These instructions help clients understand the server's purpose and available functionality. -* `lifespan`: (Optional) An async context manager function for server startup and shutdown logic. -* `tags`: (Optional) A set of strings to tag the server itself. -* `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 + + + A human-readable name for your server + + + Description of how to interact with this server. These instructions help clients understand the server's purpose and available functionality + + + + An async context manager function for server startup and shutdown logic + + + + A set of strings to tag the server itself + + + + 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 + + + + Keyword arguments corresponding to additional `ServerSettings` configuration + + ## Components FastMCP servers expose several types of components to the client: @@ -235,6 +253,34 @@ mcp = FastMCP( ) ``` +### Constructor Parameters + + + + Optional server dependencies list with package specifications + + + + Only expose components with at least one matching tag + + + + Hide components with any matching tag + + + + How to handle duplicate tool registrations + + + + How to handle duplicate resource registrations + + + + How to handle duplicate prompt registrations + + + ### Global Settings Global settings affect all FastMCP servers and can be configured via environment variables (prefixed with `FASTMCP_`) or in a `.env` file: diff --git a/docs/servers/tools.mdx b/docs/servers/tools.mdx index 300a6c7dd..b136e9702 100644 --- a/docs/servers/tools.mdx +++ b/docs/servers/tools.mdx @@ -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. -### 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"}] +``` + + + + Sets the explicit tool name exposed via MCP. If not provided, uses the function name + + + + Provides the description exposed via MCP. If set, the function's docstring is ignored for this purpose + + + + A set of strings to categorize the tool. Clients might use tags to filter or group available tools + + + + A boolean to enable or disable the tool. See [Disabling Tools](#disabling-tools) for more information + + + + A list of argument names to exclude from the tool schema shown to the LLM. See [Excluding Arguments](#excluding-arguments) for more information + + + + An optional `ToolAnnotations` object or dictionary to add additional metadata about the tool. + + + A human-readable title for the tool. + + + If true, the tool does not modify its environment. + + + If true, the tool may perform destructive updates to its environment. + + + If true, calling the tool repeatedly with the same arguments will have no additional effect on the its environment. + + + If true, this tool may interact with an "open world" of external entities. If false, the tool's domain of interaction is closed. + + + + +### Tool Parameters + +#### Type Annotations Type annotations for parameters are essential for proper tool functionality. They: 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. -### 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