mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-23 14:04:18 +02:00
Remove 3.x-era compatibility shims (#4661)
* Remove 3.x-era compatibility shims * Require response_type in ctx.elicit() * Name the utilities path for the two non-re-exported auth helpers * Point sampling handler migration at its submodule
This commit is contained in:
parent
1550eea886
commit
ea7fb8cb2e
28 changed files with 150 additions and 285 deletions
|
|
@ -178,9 +178,16 @@ The proxy, OpenAPI, and app integrations moved to their permanent homes, and the
|
|||
| `fastmcp.experimental.server.openapi` | `fastmcp.server.providers.openapi` |
|
||||
| `fastmcp.experimental.utilities.openapi` | `fastmcp.utilities.openapi` |
|
||||
| `fastmcp.server.apps`, `fastmcp.server.app` | `fastmcp.apps` (e.g. `AppConfig`) or `fastmcp` (`FastMCPApp`) |
|
||||
| `Tool` / `ToolResult` from `fastmcp.tools.tool` | `fastmcp.tools` |
|
||||
| `Resource` from `fastmcp.resources.resource` | `fastmcp.resources` |
|
||||
| `Prompt` / `Message` from `fastmcp.prompts.prompt` | `fastmcp.prompts` |
|
||||
| `FunctionTool` / `ParsedFunction` / `tool` from `fastmcp.tools.tool` | `fastmcp.tools.function_tool` |
|
||||
| `FunctionResource` / `resource` from `fastmcp.resources.resource` | `fastmcp.resources.function_resource` |
|
||||
| `FunctionPrompt` / `prompt` from `fastmcp.prompts.prompt` | `fastmcp.prompts.function_prompt` |
|
||||
| `OpenAISamplingHandler` from `fastmcp.experimental.sampling.handlers` | `fastmcp.client.sampling.handlers.openai` |
|
||||
| `AuthCheck` / `AuthContext` / `require_scopes` / `require_roles` / `restrict_tag` / `run_auth_checks` from `fastmcp.server.auth.authorization` | `fastmcp.server.auth` |
|
||||
| `run_auth_checks_with_shortfall` / `scope_requirements` from `fastmcp.server.auth.authorization` | `fastmcp.utilities.authorization` |
|
||||
| `SkillsProvider` | `SkillsDirectoryProvider` from `fastmcp.server.providers.skills` |
|
||||
|
||||
Two renames in the same family are worth calling out because they have no compatibility alias. The response-caching wrapper models lost a spelling typo — `CachableToolResult`, `CachablePromptResult`, and their siblings became `CacheableToolResult`, `CacheablePromptResult`, etc. — so an import of the old spelling from `fastmcp.server.middleware.caching` raises `ImportError`. And `PromptToolMiddleware` / `ResourceToolMiddleware` are gone in favor of the `PromptsAsTools` / `ResourcesAsTools` transforms from `fastmcp.server.transforms` (the `ToolInjectionMiddleware` base class is retained).
|
||||
|
||||
|
|
@ -204,14 +211,25 @@ Two of these replacements are not exact behavioral swaps. `create_proxy` takes i
|
|||
|
||||
`import_server` → `mount` is the one row here that is not a mechanical swap, because the two never had the same semantics. `import_server` took a **one-time static snapshot** — it copied the child's tools, resources, and prompts at call time, with no live link, and did not run the child's lifespan or middleware. `mount` is a **live composition** — it holds a live link to the child and runs the child's lifespan and middleware. After switching, later changes to the child become visible through the parent, the child's lifespan runs with the parent's (entered when the server starts, held until it stops — not per request), and the child's middleware runs on the operations delegated to it. If you depended on the frozen-copy behavior (a stable snapshot, no child lifecycle), there is no drop-in replacement: register the child's components on the parent directly instead of composing the two servers.
|
||||
|
||||
### Removed tool and decorator parameters
|
||||
### Removed parameters and settings
|
||||
|
||||
Two `@tool` parameters and two settings are gone:
|
||||
Several parameters and settings that warned in 3.x are gone:
|
||||
|
||||
- **Tool `serializer=`** is removed from `@tool` / `mcp.tool()`, `Tool.from_function`, `Tool.from_tool`, and the OpenAPI tool. Return a `ToolResult` from your tool for full control over serialization instead.
|
||||
- **Tool `exclude_args=`** is removed. Hide a parameter from the tool schema by injecting it instead: give it a `Depends(factory)` default (from `fastmcp.dependencies`), where `factory` is a callable returning the value the argument used to carry. An injected parameter never appears in the tool's schema, which is what `exclude_args` was for.
|
||||
- **The `decorator_mode` setting** (`FASTMCP_DECORATOR_MODE`) and its `"object"` mode are removed. Decorators always return your original function with metadata attached; reach the component object through the server (`await mcp.get_tool("name")`) rather than off the decorated function.
|
||||
- **`StreamableHttpTransport(sse_read_timeout=...)`** is removed — it was a no-op under the SDK v2 client. Set the read timeout through the public `Client(transport, timeout=...)` (a `timedelta` or float seconds), or reach for a custom `httpx_client_factory` when you need finer control. (`SSETransport` still accepts `sse_read_timeout`.)
|
||||
- **`ctx.elicit()` now requires `response_type`.** Omitting it (or passing `None`) has warned since 3.2 and now raises `TypeError`. The empty-object schema it produced gave clients nothing to render, and some showed an empty, non-functional form. Pass a type describing what you expect back — `bool` is the right answer for a confirmation:
|
||||
|
||||
```python
|
||||
# Before
|
||||
result = await ctx.elicit("Approve this action?")
|
||||
|
||||
# After
|
||||
result = await ctx.elicit("Approve this action?", response_type=bool)
|
||||
```
|
||||
|
||||
This is the server-authoring API only. Client elicitation handlers still receive `response_type=None` for URL requests and for empty schemas sent by other servers — that contract is unchanged.
|
||||
|
||||
## Behavior changes to verify
|
||||
|
||||
|
|
|
|||
|
|
@ -187,9 +187,9 @@ async def confirm_purchase(ctx: Context) -> str:
|
|||
|
||||
These arguments only apply when FastMCP is adding the wrapper. For structured responses (`BaseModel`, dataclass, `TypedDict`), set the metadata on the individual fields via `Field(title=..., description=...)` — passing `response_title` or `response_description` alongside a model type raises `TypeError`.
|
||||
|
||||
### Empty Responses
|
||||
### Confirmations
|
||||
|
||||
Passing `None` as the response type creates an empty-object schema and returns an accepted result with `data == {}`. This form is deprecated because some clients render empty forms poorly; prefer an explicit response type such as `bool` for confirmations.
|
||||
`response_type` is required. When all you want is a yes/no answer, ask for a `bool` rather than an empty schema — an empty schema gives the client nothing to render, and some clients show an empty, non-functional form.
|
||||
|
||||
```python
|
||||
@mcp.tool
|
||||
|
|
|
|||
|
|
@ -722,7 +722,7 @@ Schema generation works for most common types including basic types, collections
|
|||
For complete control over tool responses, return a `ToolResult` object. This gives you explicit control over all aspects of the tool's output: traditional content, structured data, and metadata.
|
||||
|
||||
```python
|
||||
from fastmcp.tools.tool import ToolResult
|
||||
from fastmcp.tools import ToolResult
|
||||
from mcp_types import TextContent
|
||||
|
||||
@mcp.tool
|
||||
|
|
@ -788,7 +788,7 @@ When you need custom serialization (like YAML, Markdown tables, or specialized f
|
|||
```python
|
||||
import yaml
|
||||
from fastmcp import FastMCP
|
||||
from fastmcp.tools.tool import ToolResult
|
||||
from fastmcp.tools import ToolResult
|
||||
|
||||
mcp = FastMCP("MyServer")
|
||||
|
||||
|
|
|
|||
|
|
@ -250,7 +250,7 @@ Here's a minimal example:
|
|||
from fastmcp.experimental.transforms.code_mode import CodeMode
|
||||
from fastmcp.experimental.transforms.code_mode import GetToolCatalog, GetSchemas
|
||||
from fastmcp.server.context import Context
|
||||
from fastmcp.tools.tool import Tool
|
||||
from fastmcp.tools import Tool
|
||||
|
||||
def list_all_tools(get_catalog: GetToolCatalog) -> Tool:
|
||||
async def list_tools(ctx: Context) -> str:
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ Create custom transforms by subclassing `Transform` and overriding the methods y
|
|||
```python
|
||||
from collections.abc import Sequence
|
||||
from fastmcp.server.transforms import Transform, GetToolNext
|
||||
from fastmcp.tools.tool import Tool
|
||||
from fastmcp.tools import Tool
|
||||
|
||||
class TagFilter(Transform):
|
||||
"""Filter tools to only those with specific tags."""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue