mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-19 03:54:18 +02:00
61 lines
2.3 KiB
Markdown
61 lines
2.3 KiB
Markdown
# Consolidating Discovery Methods
|
|
|
|
This document captures the design decisions around component listing methods in FastMCP 3.0.
|
|
|
|
## Problem
|
|
|
|
The server had parallel implementations for listing components:
|
|
- `get_tools()` / `_list_tools()`
|
|
- `get_resources()` / `_list_resources()`
|
|
- `get_prompts()` / `_list_prompts()`
|
|
- `get_resource_templates()` / `_list_resource_templates()`
|
|
|
|
These were nearly identical but with subtle differences in dedup keys, logging, and return types. The `_list_*` methods were internal and used by the MCP protocol handlers, while `get_*` methods were the public API.
|
|
|
|
## Solution
|
|
|
|
The duplicate methods were consolidated into a single set of `list_*` methods. The old `get_*` plural methods and `_list_*` internal methods were both removed.
|
|
|
|
This happened in two phases:
|
|
|
|
1. **Consolidation** (Dec 2025): Merged `get_*` and `_list_*` into a single `get_*` method with an `apply_middleware` parameter.
|
|
2. **Rename** (Jan 2026): When `FastMCP` was refactored to inherit from `Provider`, the methods were renamed to `list_*` to align with the `Provider` interface. The `apply_middleware` parameter was renamed to `run_middleware` with a default of `True`.
|
|
|
|
```python
|
|
async def list_tools(self, *, run_middleware: bool = True) -> Sequence[Tool]:
|
|
"""Canonical method for listing tools."""
|
|
...
|
|
```
|
|
|
|
## Key Changes
|
|
|
|
### Return Type: dict → list
|
|
|
|
The dict return type was removed because the key was redundant—components already have `.name` or `.uri` attributes.
|
|
|
|
```python
|
|
# Before (v2.x)
|
|
tools = await server.get_tools()
|
|
tool = tools["my_tool"]
|
|
|
|
# After (v3.0)
|
|
tools = await server.list_tools()
|
|
tool = next(t for t in tools if t.name == "my_tool")
|
|
```
|
|
|
|
### Middleware via Parameter
|
|
|
|
The `run_middleware=True` parameter (default) applies the middleware chain. This replaces the separate `_list_*_middleware()` methods.
|
|
|
|
## Benefits
|
|
|
|
1. **Single source of truth** - One method, not two
|
|
2. **Consistent behavior** - Same dedup key, same visibility filtering
|
|
3. **Clearer API** - Public method with explicit middleware opt-in
|
|
4. **Provider alignment** - `FastMCP.list_tools()` overrides `Provider.list_tools()`
|
|
5. **Less code** - Deleted ~200 lines of duplicate implementation
|
|
|
|
## Implementation Files
|
|
|
|
- `src/fastmcp/server/server.py` - Canonical `list_*` methods
|
|
- `src/fastmcp/server/providers/` - Provider base class defines the interface
|