Spaces:
Running
Running
zzstoatzz commited on
Commit ·
bb7d65e
1
Parent(s): bd2f8d9
fix a couple parsing issues
Browse files
docs/python-sdk/fastmcp-server-server.mdx
CHANGED
|
@@ -10,7 +10,7 @@ FastMCP - A more ergonomic interface for MCP servers.
|
|
| 10 |
|
| 11 |
## Functions
|
| 12 |
|
| 13 |
-
### `add_resource_prefix` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#
|
| 14 |
|
| 15 |
```python
|
| 16 |
add_resource_prefix(uri: str, prefix: str, prefix_format: Literal['protocol', 'path'] | None = None) -> str
|
|
@@ -28,18 +28,27 @@ Add a prefix to a resource URI.
|
|
| 28 |
|
| 29 |
**Examples:**
|
| 30 |
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
"
|
| 35 |
-
|
| 36 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
|
| 38 |
**Raises:**
|
| 39 |
- `ValueError`: If the URI doesn't match the expected protocol\://path format
|
| 40 |
|
| 41 |
|
| 42 |
-
### `remove_resource_prefix` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#
|
| 43 |
|
| 44 |
```python
|
| 45 |
remove_resource_prefix(uri: str, prefix: str, prefix_format: Literal['protocol', 'path'] | None = None) -> str
|
|
@@ -58,18 +67,27 @@ Returns:
|
|
| 58 |
|
| 59 |
**Examples:**
|
| 60 |
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
"resource://path/to/resource"
|
| 65 |
-
|
| 66 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
|
| 68 |
**Raises:**
|
| 69 |
- `ValueError`: If the URI doesn't match the expected protocol\://path format
|
| 70 |
|
| 71 |
|
| 72 |
-
### `has_resource_prefix` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#
|
| 73 |
|
| 74 |
```python
|
| 75 |
has_resource_prefix(uri: str, prefix: str, prefix_format: Literal['protocol', 'path'] | None = None) -> bool
|
|
@@ -87,12 +105,21 @@ Check if a resource URI has a specific prefix.
|
|
| 87 |
|
| 88 |
**Examples:**
|
| 89 |
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
True
|
| 94 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 95 |
False
|
|
|
|
| 96 |
|
| 97 |
**Raises:**
|
| 98 |
- `ValueError`: If the URI doesn't match the expected protocol\://path format
|
|
@@ -140,7 +167,7 @@ Run the FastMCP server. Note this is a synchronous function.
|
|
| 140 |
add_middleware(self, middleware: Middleware) -> None
|
| 141 |
```
|
| 142 |
|
| 143 |
-
#### `custom_route` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#
|
| 144 |
|
| 145 |
```python
|
| 146 |
custom_route(self, path: str, methods: list[str], name: str | None = None, include_in_schema: bool = True)
|
|
@@ -161,7 +188,7 @@ Starlette's reverse URL lookup feature)
|
|
| 161 |
- `include_in_schema`: Whether to include in OpenAPI schema, defaults to True
|
| 162 |
|
| 163 |
|
| 164 |
-
#### `add_tool` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#
|
| 165 |
|
| 166 |
```python
|
| 167 |
add_tool(self, tool: Tool) -> None
|
|
@@ -176,7 +203,7 @@ with the Context type annotation. See the @tool decorator for examples.
|
|
| 176 |
- `tool`: The Tool instance to register
|
| 177 |
|
| 178 |
|
| 179 |
-
#### `remove_tool` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#
|
| 180 |
|
| 181 |
```python
|
| 182 |
remove_tool(self, name: str) -> None
|
|
@@ -191,19 +218,19 @@ Remove a tool from the server.
|
|
| 191 |
- `NotFoundError`: If the tool is not found
|
| 192 |
|
| 193 |
|
| 194 |
-
#### `tool` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#
|
| 195 |
|
| 196 |
```python
|
| 197 |
tool(self, name_or_fn: AnyFunction) -> FunctionTool
|
| 198 |
```
|
| 199 |
|
| 200 |
-
#### `tool` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#
|
| 201 |
|
| 202 |
```python
|
| 203 |
tool(self, name_or_fn: str | None = None) -> Callable[[AnyFunction], FunctionTool]
|
| 204 |
```
|
| 205 |
|
| 206 |
-
#### `tool` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#
|
| 207 |
|
| 208 |
```python
|
| 209 |
tool(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionTool] | FunctionTool
|
|
@@ -227,12 +254,37 @@ This decorator supports multiple calling patterns:
|
|
| 227 |
- `name`: Optional name for the tool (keyword-only, alternative to name_or_fn)
|
| 228 |
- `description`: Optional description of what the tool does
|
| 229 |
- `tags`: Optional set of tags for categorizing the tool
|
| 230 |
-
- `annotations`: Optional annotations about the tool's behavior
|
| 231 |
- `exclude_args`: Optional list of argument names to exclude from the tool schema
|
| 232 |
- `enabled`: Optional boolean to enable or disable the tool
|
| 233 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 234 |
|
| 235 |
-
#### `add_resource` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#
|
| 236 |
|
| 237 |
```python
|
| 238 |
add_resource(self, resource: Resource) -> None
|
|
@@ -244,7 +296,7 @@ Add a resource to the server.
|
|
| 244 |
- `resource`: A Resource instance to add
|
| 245 |
|
| 246 |
|
| 247 |
-
#### `add_template` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#
|
| 248 |
|
| 249 |
```python
|
| 250 |
add_template(self, template: ResourceTemplate) -> None
|
|
@@ -256,7 +308,7 @@ Add a resource template to the server.
|
|
| 256 |
- `template`: A ResourceTemplate instance to add
|
| 257 |
|
| 258 |
|
| 259 |
-
#### `add_resource_fn` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#
|
| 260 |
|
| 261 |
```python
|
| 262 |
add_resource_fn(self, fn: AnyFunction, uri: str, name: str | None = None, description: str | None = None, mime_type: str | None = None, tags: set[str] | None = None) -> None
|
|
@@ -276,7 +328,7 @@ has parameters, it will be registered as a template resource.
|
|
| 276 |
- `tags`: Optional set of tags for categorizing the resource
|
| 277 |
|
| 278 |
|
| 279 |
-
#### `resource` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#
|
| 280 |
|
| 281 |
```python
|
| 282 |
resource(self, uri: str) -> Callable[[AnyFunction], Resource | ResourceTemplate]
|
|
@@ -305,8 +357,36 @@ has parameters, it will be registered as a template resource.
|
|
| 305 |
- `tags`: Optional set of tags for categorizing the resource
|
| 306 |
- `enabled`: Optional boolean to enable or disable the resource
|
| 307 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 308 |
|
| 309 |
-
|
|
|
|
| 310 |
|
| 311 |
```python
|
| 312 |
add_prompt(self, prompt: Prompt) -> None
|
|
@@ -318,19 +398,19 @@ Add a prompt to the server.
|
|
| 318 |
- `prompt`: A Prompt instance to add
|
| 319 |
|
| 320 |
|
| 321 |
-
#### `prompt` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#
|
| 322 |
|
| 323 |
```python
|
| 324 |
prompt(self, name_or_fn: AnyFunction) -> FunctionPrompt
|
| 325 |
```
|
| 326 |
|
| 327 |
-
#### `prompt` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#
|
| 328 |
|
| 329 |
```python
|
| 330 |
prompt(self, name_or_fn: str | None = None) -> Callable[[AnyFunction], FunctionPrompt]
|
| 331 |
```
|
| 332 |
|
| 333 |
-
#### `prompt` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#
|
| 334 |
|
| 335 |
```python
|
| 336 |
prompt(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt
|
|
@@ -356,9 +436,11 @@ Decorator to register a prompt.
|
|
| 356 |
tags: Optional set of tags for categorizing the prompt
|
| 357 |
enabled: Optional boolean to enable or disable the prompt
|
| 358 |
|
| 359 |
-
|
|
|
|
|
|
|
| 360 |
@server.prompt
|
| 361 |
-
def analyze_table(table_name: str) -> list
|
| 362 |
schema = read_table_schema(table_name)
|
| 363 |
return [
|
| 364 |
{
|
|
@@ -369,7 +451,7 @@ Decorator to register a prompt.
|
|
| 369 |
]
|
| 370 |
|
| 371 |
@server.prompt()
|
| 372 |
-
def analyze_with_context(table_name: str, ctx: Context) -> list
|
| 373 |
ctx.info(f"Analyzing table {table_name}")
|
| 374 |
schema = read_table_schema(table_name)
|
| 375 |
return [
|
|
@@ -381,7 +463,7 @@ Decorator to register a prompt.
|
|
| 381 |
]
|
| 382 |
|
| 383 |
@server.prompt("custom_name")
|
| 384 |
-
def analyze_file(path: str) -> list
|
| 385 |
content = await read_file(path)
|
| 386 |
return [
|
| 387 |
{
|
|
@@ -397,14 +479,15 @@ Decorator to register a prompt.
|
|
| 397 |
]
|
| 398 |
|
| 399 |
@server.prompt(name="custom_name")
|
| 400 |
-
def another_prompt(data: str) -> list
|
| 401 |
return [{"role": "user", "content": data}]
|
| 402 |
|
| 403 |
# Direct function call
|
| 404 |
server.prompt(my_function, name="custom_name")
|
|
|
|
| 405 |
|
| 406 |
|
| 407 |
-
#### `sse_app` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#
|
| 408 |
|
| 409 |
```python
|
| 410 |
sse_app(self, path: str | None = None, message_path: str | None = None, middleware: list[ASGIMiddleware] | None = None) -> StarletteWithLifespan
|
|
@@ -418,7 +501,7 @@ Create a Starlette app for the SSE server.
|
|
| 418 |
- `middleware`: A list of middleware to apply to the app
|
| 419 |
|
| 420 |
|
| 421 |
-
#### `streamable_http_app` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#
|
| 422 |
|
| 423 |
```python
|
| 424 |
streamable_http_app(self, path: str | None = None, middleware: list[ASGIMiddleware] | None = None) -> StarletteWithLifespan
|
|
@@ -431,7 +514,7 @@ Create a Starlette app for the StreamableHTTP server.
|
|
| 431 |
- `middleware`: A list of middleware to apply to the app
|
| 432 |
|
| 433 |
|
| 434 |
-
#### `http_app` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#
|
| 435 |
|
| 436 |
```python
|
| 437 |
http_app(self, path: str | None = None, middleware: list[ASGIMiddleware] | None = None, json_response: bool | None = None, stateless_http: bool | None = None, transport: Literal['http', 'streamable-http', 'sse'] = 'http') -> StarletteWithLifespan
|
|
@@ -448,7 +531,7 @@ Create a Starlette app using the specified HTTP transport.
|
|
| 448 |
- A Starlette application configured with the specified transport
|
| 449 |
|
| 450 |
|
| 451 |
-
#### `mount` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#
|
| 452 |
|
| 453 |
```python
|
| 454 |
mount(self, server: FastMCP[LifespanResultT], prefix: str | None = None, as_proxy: bool | None = None) -> None
|
|
@@ -502,7 +585,7 @@ automatically determined based on whether the server has a custom lifespan
|
|
| 502 |
- `prompt_separator`: Deprecated. Separator character for prompt names.
|
| 503 |
|
| 504 |
|
| 505 |
-
#### `from_openapi` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#
|
| 506 |
|
| 507 |
```python
|
| 508 |
from_openapi(cls, openapi_spec: dict[str, Any], client: httpx.AsyncClient, route_maps: list[RouteMap] | None = None, route_map_fn: OpenAPIRouteMapFn | None = None, mcp_component_fn: OpenAPIComponentFn | None = None, mcp_names: dict[str, str] | None = None, tags: set[str] | None = None, **settings: Any) -> FastMCPOpenAPI
|
|
@@ -511,7 +594,7 @@ from_openapi(cls, openapi_spec: dict[str, Any], client: httpx.AsyncClient, route
|
|
| 511 |
Create a FastMCP server from an OpenAPI specification.
|
| 512 |
|
| 513 |
|
| 514 |
-
#### `from_fastapi` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#
|
| 515 |
|
| 516 |
```python
|
| 517 |
from_fastapi(cls, app: Any, name: str | None = None, route_maps: list[RouteMap] | None = None, route_map_fn: OpenAPIRouteMapFn | None = None, mcp_component_fn: OpenAPIComponentFn | None = None, mcp_names: dict[str, str] | None = None, httpx_client_kwargs: dict[str, Any] | None = None, tags: set[str] | None = None, **settings: Any) -> FastMCPOpenAPI
|
|
@@ -520,7 +603,7 @@ from_fastapi(cls, app: Any, name: str | None = None, route_maps: list[RouteMap]
|
|
| 520 |
Create a FastMCP server from a FastAPI application.
|
| 521 |
|
| 522 |
|
| 523 |
-
#### `as_proxy` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#
|
| 524 |
|
| 525 |
```python
|
| 526 |
as_proxy(cls, backend: Client[ClientTransportT] | ClientTransport | FastMCP[Any] | AnyUrl | Path | MCPConfig | dict[str, Any] | str, **settings: Any) -> FastMCPProxy
|
|
@@ -528,13 +611,13 @@ as_proxy(cls, backend: Client[ClientTransportT] | ClientTransport | FastMCP[Any]
|
|
| 528 |
|
| 529 |
Create a FastMCP proxy server for the given backend.
|
| 530 |
|
| 531 |
-
The `
|
| 532 |
-
instance or any value accepted as the `
|
| 533 |
-
|
| 534 |
-
`
|
| 535 |
|
| 536 |
|
| 537 |
-
#### `from_client` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#
|
| 538 |
|
| 539 |
```python
|
| 540 |
from_client(cls, client: Client[ClientTransportT], **settings: Any) -> FastMCPProxy
|
|
@@ -543,4 +626,4 @@ from_client(cls, client: Client[ClientTransportT], **settings: Any) -> FastMCPPr
|
|
| 543 |
Create a FastMCP proxy server from a FastMCP client.
|
| 544 |
|
| 545 |
|
| 546 |
-
### `MountedServer` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#
|
|
|
|
| 10 |
|
| 11 |
## Functions
|
| 12 |
|
| 13 |
+
### `add_resource_prefix` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L1879"><Icon icon="github" size="14" /></a></sup>
|
| 14 |
|
| 15 |
```python
|
| 16 |
add_resource_prefix(uri: str, prefix: str, prefix_format: Literal['protocol', 'path'] | None = None) -> str
|
|
|
|
| 28 |
|
| 29 |
**Examples:**
|
| 30 |
|
| 31 |
+
With new style:
|
| 32 |
+
```python
|
| 33 |
+
add_resource_prefix("resource://path/to/resource", "prefix")
|
| 34 |
+
"resource://prefix/path/to/resource"
|
| 35 |
+
```
|
| 36 |
+
With legacy style:
|
| 37 |
+
```python
|
| 38 |
+
add_resource_prefix("resource://path/to/resource", "prefix")
|
| 39 |
+
"prefix+resource://path/to/resource"
|
| 40 |
+
```
|
| 41 |
+
With absolute path:
|
| 42 |
+
```python
|
| 43 |
+
add_resource_prefix("resource:///absolute/path", "prefix")
|
| 44 |
+
"resource://prefix//absolute/path"
|
| 45 |
+
```
|
| 46 |
|
| 47 |
**Raises:**
|
| 48 |
- `ValueError`: If the URI doesn't match the expected protocol\://path format
|
| 49 |
|
| 50 |
|
| 51 |
+
### `remove_resource_prefix` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L1939"><Icon icon="github" size="14" /></a></sup>
|
| 52 |
|
| 53 |
```python
|
| 54 |
remove_resource_prefix(uri: str, prefix: str, prefix_format: Literal['protocol', 'path'] | None = None) -> str
|
|
|
|
| 67 |
|
| 68 |
**Examples:**
|
| 69 |
|
| 70 |
+
With new style:
|
| 71 |
+
```python
|
| 72 |
+
remove_resource_prefix("resource://prefix/path/to/resource", "prefix")
|
| 73 |
+
"resource://path/to/resource"
|
| 74 |
+
```
|
| 75 |
+
With legacy style:
|
| 76 |
+
```python
|
| 77 |
+
remove_resource_prefix("prefix+resource://path/to/resource", "prefix")
|
| 78 |
+
"resource://path/to/resource"
|
| 79 |
+
```
|
| 80 |
+
With absolute path:
|
| 81 |
+
```python
|
| 82 |
+
remove_resource_prefix("resource://prefix//absolute/path", "prefix")
|
| 83 |
+
"resource:///absolute/path"
|
| 84 |
+
```
|
| 85 |
|
| 86 |
**Raises:**
|
| 87 |
- `ValueError`: If the URI doesn't match the expected protocol\://path format
|
| 88 |
|
| 89 |
|
| 90 |
+
### `has_resource_prefix` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L2006"><Icon icon="github" size="14" /></a></sup>
|
| 91 |
|
| 92 |
```python
|
| 93 |
has_resource_prefix(uri: str, prefix: str, prefix_format: Literal['protocol', 'path'] | None = None) -> bool
|
|
|
|
| 105 |
|
| 106 |
**Examples:**
|
| 107 |
|
| 108 |
+
With new style:
|
| 109 |
+
```python
|
| 110 |
+
has_resource_prefix("resource://prefix/path/to/resource", "prefix")
|
| 111 |
+
True
|
| 112 |
+
```
|
| 113 |
+
With legacy style:
|
| 114 |
+
```python
|
| 115 |
+
has_resource_prefix("prefix+resource://path/to/resource", "prefix")
|
| 116 |
+
True
|
| 117 |
+
```
|
| 118 |
+
With other path:
|
| 119 |
+
```python
|
| 120 |
+
has_resource_prefix("resource://other/path/to/resource", "prefix")
|
| 121 |
False
|
| 122 |
+
```
|
| 123 |
|
| 124 |
**Raises:**
|
| 125 |
- `ValueError`: If the URI doesn't match the expected protocol\://path format
|
|
|
|
| 167 |
add_middleware(self, middleware: Middleware) -> None
|
| 168 |
```
|
| 169 |
|
| 170 |
+
#### `custom_route` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L384"><Icon icon="github" size="14" /></a></sup>
|
| 171 |
|
| 172 |
```python
|
| 173 |
custom_route(self, path: str, methods: list[str], name: str | None = None, include_in_schema: bool = True)
|
|
|
|
| 188 |
- `include_in_schema`: Whether to include in OpenAPI schema, defaults to True
|
| 189 |
|
| 190 |
|
| 191 |
+
#### `add_tool` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L742"><Icon icon="github" size="14" /></a></sup>
|
| 192 |
|
| 193 |
```python
|
| 194 |
add_tool(self, tool: Tool) -> None
|
|
|
|
| 203 |
- `tool`: The Tool instance to register
|
| 204 |
|
| 205 |
|
| 206 |
+
#### `remove_tool` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L754"><Icon icon="github" size="14" /></a></sup>
|
| 207 |
|
| 208 |
```python
|
| 209 |
remove_tool(self, name: str) -> None
|
|
|
|
| 218 |
- `NotFoundError`: If the tool is not found
|
| 219 |
|
| 220 |
|
| 221 |
+
#### `tool` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L767"><Icon icon="github" size="14" /></a></sup>
|
| 222 |
|
| 223 |
```python
|
| 224 |
tool(self, name_or_fn: AnyFunction) -> FunctionTool
|
| 225 |
```
|
| 226 |
|
| 227 |
+
#### `tool` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L780"><Icon icon="github" size="14" /></a></sup>
|
| 228 |
|
| 229 |
```python
|
| 230 |
tool(self, name_or_fn: str | None = None) -> Callable[[AnyFunction], FunctionTool]
|
| 231 |
```
|
| 232 |
|
| 233 |
+
#### `tool` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L792"><Icon icon="github" size="14" /></a></sup>
|
| 234 |
|
| 235 |
```python
|
| 236 |
tool(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionTool] | FunctionTool
|
|
|
|
| 254 |
- `name`: Optional name for the tool (keyword-only, alternative to name_or_fn)
|
| 255 |
- `description`: Optional description of what the tool does
|
| 256 |
- `tags`: Optional set of tags for categorizing the tool
|
| 257 |
+
- `annotations`: Optional annotations about the tool's behavior
|
| 258 |
- `exclude_args`: Optional list of argument names to exclude from the tool schema
|
| 259 |
- `enabled`: Optional boolean to enable or disable the tool
|
| 260 |
|
| 261 |
+
**Examples:**
|
| 262 |
+
|
| 263 |
+
Register a tool with a custom name:
|
| 264 |
+
```python
|
| 265 |
+
@server.tool
|
| 266 |
+
def my_tool(x: int) -> str:
|
| 267 |
+
return str(x)
|
| 268 |
+
|
| 269 |
+
# Register a tool with a custom name
|
| 270 |
+
@server.tool
|
| 271 |
+
def my_tool(x: int) -> str:
|
| 272 |
+
return str(x)
|
| 273 |
+
|
| 274 |
+
@server.tool("custom_name")
|
| 275 |
+
def my_tool(x: int) -> str:
|
| 276 |
+
return str(x)
|
| 277 |
+
|
| 278 |
+
@server.tool(name="custom_name")
|
| 279 |
+
def my_tool(x: int) -> str:
|
| 280 |
+
return str(x)
|
| 281 |
+
|
| 282 |
+
# Direct function call
|
| 283 |
+
server.tool(my_function, name="custom_name")
|
| 284 |
+
```
|
| 285 |
+
|
| 286 |
|
| 287 |
+
#### `add_resource` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L912"><Icon icon="github" size="14" /></a></sup>
|
| 288 |
|
| 289 |
```python
|
| 290 |
add_resource(self, resource: Resource) -> None
|
|
|
|
| 296 |
- `resource`: A Resource instance to add
|
| 297 |
|
| 298 |
|
| 299 |
+
#### `add_template` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L922"><Icon icon="github" size="14" /></a></sup>
|
| 300 |
|
| 301 |
```python
|
| 302 |
add_template(self, template: ResourceTemplate) -> None
|
|
|
|
| 308 |
- `template`: A ResourceTemplate instance to add
|
| 309 |
|
| 310 |
|
| 311 |
+
#### `add_resource_fn` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L930"><Icon icon="github" size="14" /></a></sup>
|
| 312 |
|
| 313 |
```python
|
| 314 |
add_resource_fn(self, fn: AnyFunction, uri: str, name: str | None = None, description: str | None = None, mime_type: str | None = None, tags: set[str] | None = None) -> None
|
|
|
|
| 328 |
- `tags`: Optional set of tags for categorizing the resource
|
| 329 |
|
| 330 |
|
| 331 |
+
#### `resource` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L969"><Icon icon="github" size="14" /></a></sup>
|
| 332 |
|
| 333 |
```python
|
| 334 |
resource(self, uri: str) -> Callable[[AnyFunction], Resource | ResourceTemplate]
|
|
|
|
| 357 |
- `tags`: Optional set of tags for categorizing the resource
|
| 358 |
- `enabled`: Optional boolean to enable or disable the resource
|
| 359 |
|
| 360 |
+
**Examples:**
|
| 361 |
+
|
| 362 |
+
Register a resource with a custom name:
|
| 363 |
+
```python
|
| 364 |
+
@server.resource("resource://my-resource")
|
| 365 |
+
def get_data() -> str:
|
| 366 |
+
return "Hello, world!"
|
| 367 |
+
|
| 368 |
+
@server.resource("resource://my-resource")
|
| 369 |
+
async get_data() -> str:
|
| 370 |
+
data = await fetch_data()
|
| 371 |
+
return f"Hello, world! {data}"
|
| 372 |
+
|
| 373 |
+
@server.resource("resource://{city}/weather")
|
| 374 |
+
def get_weather(city: str) -> str:
|
| 375 |
+
return f"Weather for {city}"
|
| 376 |
+
|
| 377 |
+
@server.resource("resource://{city}/weather")
|
| 378 |
+
def get_weather_with_context(city: str, ctx: Context) -> str:
|
| 379 |
+
ctx.info(f"Fetching weather for {city}")
|
| 380 |
+
return f"Weather for {city}"
|
| 381 |
+
|
| 382 |
+
@server.resource("resource://{city}/weather")
|
| 383 |
+
async def get_weather(city: str) -> str:
|
| 384 |
+
data = await fetch_weather(city)
|
| 385 |
+
return f"Weather for {city}: {data}"
|
| 386 |
+
```
|
| 387 |
|
| 388 |
+
|
| 389 |
+
#### `add_prompt` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L1092"><Icon icon="github" size="14" /></a></sup>
|
| 390 |
|
| 391 |
```python
|
| 392 |
add_prompt(self, prompt: Prompt) -> None
|
|
|
|
| 398 |
- `prompt`: A Prompt instance to add
|
| 399 |
|
| 400 |
|
| 401 |
+
#### `prompt` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L1102"><Icon icon="github" size="14" /></a></sup>
|
| 402 |
|
| 403 |
```python
|
| 404 |
prompt(self, name_or_fn: AnyFunction) -> FunctionPrompt
|
| 405 |
```
|
| 406 |
|
| 407 |
+
#### `prompt` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L1113"><Icon icon="github" size="14" /></a></sup>
|
| 408 |
|
| 409 |
```python
|
| 410 |
prompt(self, name_or_fn: str | None = None) -> Callable[[AnyFunction], FunctionPrompt]
|
| 411 |
```
|
| 412 |
|
| 413 |
+
#### `prompt` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L1123"><Icon icon="github" size="14" /></a></sup>
|
| 414 |
|
| 415 |
```python
|
| 416 |
prompt(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt
|
|
|
|
| 436 |
tags: Optional set of tags for categorizing the prompt
|
| 437 |
enabled: Optional boolean to enable or disable the prompt
|
| 438 |
|
| 439 |
+
Examples:
|
| 440 |
+
|
| 441 |
+
```python
|
| 442 |
@server.prompt
|
| 443 |
+
def analyze_table(table_name: str) -> list[Message]:
|
| 444 |
schema = read_table_schema(table_name)
|
| 445 |
return [
|
| 446 |
{
|
|
|
|
| 451 |
]
|
| 452 |
|
| 453 |
@server.prompt()
|
| 454 |
+
def analyze_with_context(table_name: str, ctx: Context) -> list[Message]:
|
| 455 |
ctx.info(f"Analyzing table {table_name}")
|
| 456 |
schema = read_table_schema(table_name)
|
| 457 |
return [
|
|
|
|
| 463 |
]
|
| 464 |
|
| 465 |
@server.prompt("custom_name")
|
| 466 |
+
def analyze_file(path: str) -> list[Message]:
|
| 467 |
content = await read_file(path)
|
| 468 |
return [
|
| 469 |
{
|
|
|
|
| 479 |
]
|
| 480 |
|
| 481 |
@server.prompt(name="custom_name")
|
| 482 |
+
def another_prompt(data: str) -> list[Message]:
|
| 483 |
return [{"role": "user", "content": data}]
|
| 484 |
|
| 485 |
# Direct function call
|
| 486 |
server.prompt(my_function, name="custom_name")
|
| 487 |
+
```
|
| 488 |
|
| 489 |
|
| 490 |
+
#### `sse_app` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L1344"><Icon icon="github" size="14" /></a></sup>
|
| 491 |
|
| 492 |
```python
|
| 493 |
sse_app(self, path: str | None = None, message_path: str | None = None, middleware: list[ASGIMiddleware] | None = None) -> StarletteWithLifespan
|
|
|
|
| 501 |
- `middleware`: A list of middleware to apply to the app
|
| 502 |
|
| 503 |
|
| 504 |
+
#### `streamable_http_app` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L1375"><Icon icon="github" size="14" /></a></sup>
|
| 505 |
|
| 506 |
```python
|
| 507 |
streamable_http_app(self, path: str | None = None, middleware: list[ASGIMiddleware] | None = None) -> StarletteWithLifespan
|
|
|
|
| 514 |
- `middleware`: A list of middleware to apply to the app
|
| 515 |
|
| 516 |
|
| 517 |
+
#### `http_app` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L1396"><Icon icon="github" size="14" /></a></sup>
|
| 518 |
|
| 519 |
```python
|
| 520 |
http_app(self, path: str | None = None, middleware: list[ASGIMiddleware] | None = None, json_response: bool | None = None, stateless_http: bool | None = None, transport: Literal['http', 'streamable-http', 'sse'] = 'http') -> StarletteWithLifespan
|
|
|
|
| 531 |
- A Starlette application configured with the specified transport
|
| 532 |
|
| 533 |
|
| 534 |
+
#### `mount` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L1470"><Icon icon="github" size="14" /></a></sup>
|
| 535 |
|
| 536 |
```python
|
| 537 |
mount(self, server: FastMCP[LifespanResultT], prefix: str | None = None, as_proxy: bool | None = None) -> None
|
|
|
|
| 585 |
- `prompt_separator`: Deprecated. Separator character for prompt names.
|
| 586 |
|
| 587 |
|
| 588 |
+
#### `from_openapi` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L1720"><Icon icon="github" size="14" /></a></sup>
|
| 589 |
|
| 590 |
```python
|
| 591 |
from_openapi(cls, openapi_spec: dict[str, Any], client: httpx.AsyncClient, route_maps: list[RouteMap] | None = None, route_map_fn: OpenAPIRouteMapFn | None = None, mcp_component_fn: OpenAPIComponentFn | None = None, mcp_names: dict[str, str] | None = None, tags: set[str] | None = None, **settings: Any) -> FastMCPOpenAPI
|
|
|
|
| 594 |
Create a FastMCP server from an OpenAPI specification.
|
| 595 |
|
| 596 |
|
| 597 |
+
#### `from_fastapi` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L1748"><Icon icon="github" size="14" /></a></sup>
|
| 598 |
|
| 599 |
```python
|
| 600 |
from_fastapi(cls, app: Any, name: str | None = None, route_maps: list[RouteMap] | None = None, route_map_fn: OpenAPIRouteMapFn | None = None, mcp_component_fn: OpenAPIComponentFn | None = None, mcp_names: dict[str, str] | None = None, httpx_client_kwargs: dict[str, Any] | None = None, tags: set[str] | None = None, **settings: Any) -> FastMCPOpenAPI
|
|
|
|
| 603 |
Create a FastMCP server from a FastAPI application.
|
| 604 |
|
| 605 |
|
| 606 |
+
#### `as_proxy` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L1790"><Icon icon="github" size="14" /></a></sup>
|
| 607 |
|
| 608 |
```python
|
| 609 |
as_proxy(cls, backend: Client[ClientTransportT] | ClientTransport | FastMCP[Any] | AnyUrl | Path | MCPConfig | dict[str, Any] | str, **settings: Any) -> FastMCPProxy
|
|
|
|
| 611 |
|
| 612 |
Create a FastMCP proxy server for the given backend.
|
| 613 |
|
| 614 |
+
The `backend` argument can be either an existing `fastmcp.client.Client`
|
| 615 |
+
instance or any value accepted as the `transport` argument of
|
| 616 |
+
`fastmcp.client.Client`. This mirrors the convenience of the
|
| 617 |
+
`fastmcp.client.Client` constructor.
|
| 618 |
|
| 619 |
|
| 620 |
+
#### `from_client` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L1820"><Icon icon="github" size="14" /></a></sup>
|
| 621 |
|
| 622 |
```python
|
| 623 |
from_client(cls, client: Client[ClientTransportT], **settings: Any) -> FastMCPProxy
|
|
|
|
| 626 |
Create a FastMCP proxy server from a FastMCP client.
|
| 627 |
|
| 628 |
|
| 629 |
+
### `MountedServer` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L1873"><Icon icon="github" size="14" /></a></sup>
|
docs/python-sdk/fastmcp-tools-tool_transform.mdx
CHANGED
|
@@ -18,38 +18,58 @@ descriptions, add default values, or hide them from clients while passing consta
|
|
| 18 |
|
| 19 |
**Examples:**
|
| 20 |
|
| 21 |
-
|
|
|
|
| 22 |
ArgTransform(name="new_name")
|
|
|
|
| 23 |
|
| 24 |
-
|
|
|
|
| 25 |
ArgTransform(description="Updated description")
|
|
|
|
| 26 |
|
| 27 |
-
|
|
|
|
| 28 |
ArgTransform(default=42)
|
|
|
|
| 29 |
|
| 30 |
-
|
|
|
|
| 31 |
ArgTransform(default_factory=lambda: time.time())
|
|
|
|
| 32 |
|
| 33 |
-
|
|
|
|
| 34 |
ArgTransform(type=str)
|
|
|
|
| 35 |
|
| 36 |
-
|
|
|
|
| 37 |
ArgTransform(hide=True)
|
|
|
|
| 38 |
|
| 39 |
-
|
|
|
|
| 40 |
ArgTransform(hide=True, default="constant_value")
|
|
|
|
| 41 |
|
| 42 |
-
|
|
|
|
| 43 |
ArgTransform(hide=True, default_factory=lambda: uuid.uuid4().hex)
|
|
|
|
| 44 |
|
| 45 |
-
|
|
|
|
| 46 |
ArgTransform(required=True)
|
|
|
|
| 47 |
|
| 48 |
-
|
|
|
|
| 49 |
ArgTransform(name="new_name", description="New desc", default=None, type=int)
|
|
|
|
| 50 |
|
| 51 |
|
| 52 |
-
### `TransformedTool` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/tools/tool_transform.py#
|
| 53 |
|
| 54 |
|
| 55 |
A tool that is transformed from another tool.
|
|
@@ -65,7 +85,7 @@ with transformed arguments.
|
|
| 65 |
|
| 66 |
**Methods:**
|
| 67 |
|
| 68 |
-
#### `from_tool` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/tools/tool_transform.py#
|
| 69 |
|
| 70 |
```python
|
| 71 |
from_tool(cls, tool: Tool, name: str | None = None, description: str | None = None, tags: set[str] | None = None, transform_fn: Callable[..., Any] | None = None, transform_args: dict[str, ArgTransform] | None = None, annotations: ToolAnnotations | None = None, serializer: Callable[[Any], str] | None = None, enabled: bool | None = None) -> TransformedTool
|
|
@@ -81,9 +101,9 @@ argument names.
|
|
| 81 |
- `name`: New name for the tool. Defaults to parent tool's name.
|
| 82 |
- `transform_args`: Optional transformations for parent tool arguments.
|
| 83 |
Only specified arguments are transformed, others pass through unchanged\:
|
| 84 |
-
-
|
| 85 |
-
-
|
| 86 |
-
-
|
| 87 |
- `description`: New description. Defaults to parent's description.
|
| 88 |
- `tags`: New tags. Defaults to parent's tags.
|
| 89 |
- `annotations`: New annotations. Defaults to parent's annotations.
|
|
@@ -92,17 +112,28 @@ Only specified arguments are transformed, others pass through unchanged\:
|
|
| 92 |
**Returns:**
|
| 93 |
- TransformedTool with the specified transformations.
|
| 94 |
|
| 95 |
-
Examples:
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
result = await forward(
|
| 106 |
-
return f"
|
| 107 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
|
|
|
|
| 18 |
|
| 19 |
**Examples:**
|
| 20 |
|
| 21 |
+
Rename argument 'old_name' to 'new_name'
|
| 22 |
+
```python
|
| 23 |
ArgTransform(name="new_name")
|
| 24 |
+
```
|
| 25 |
|
| 26 |
+
Change description only
|
| 27 |
+
```python
|
| 28 |
ArgTransform(description="Updated description")
|
| 29 |
+
```
|
| 30 |
|
| 31 |
+
Add a default value (makes argument optional)
|
| 32 |
+
```python
|
| 33 |
ArgTransform(default=42)
|
| 34 |
+
```
|
| 35 |
|
| 36 |
+
Add a default factory (makes argument optional)
|
| 37 |
+
```python
|
| 38 |
ArgTransform(default_factory=lambda: time.time())
|
| 39 |
+
```
|
| 40 |
|
| 41 |
+
Change the type
|
| 42 |
+
```python
|
| 43 |
ArgTransform(type=str)
|
| 44 |
+
```
|
| 45 |
|
| 46 |
+
Hide the argument entirely from clients
|
| 47 |
+
```python
|
| 48 |
ArgTransform(hide=True)
|
| 49 |
+
```
|
| 50 |
|
| 51 |
+
Hide argument but pass a constant value to parent
|
| 52 |
+
```python
|
| 53 |
ArgTransform(hide=True, default="constant_value")
|
| 54 |
+
```
|
| 55 |
|
| 56 |
+
Hide argument but pass a factory-generated value to parent
|
| 57 |
+
```python
|
| 58 |
ArgTransform(hide=True, default_factory=lambda: uuid.uuid4().hex)
|
| 59 |
+
```
|
| 60 |
|
| 61 |
+
Make an optional parameter required (removes any default)
|
| 62 |
+
```python
|
| 63 |
ArgTransform(required=True)
|
| 64 |
+
```
|
| 65 |
|
| 66 |
+
Combine multiple transformations
|
| 67 |
+
```python
|
| 68 |
ArgTransform(name="new_name", description="New desc", default=None, type=int)
|
| 69 |
+
```
|
| 70 |
|
| 71 |
|
| 72 |
+
### `TransformedTool` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/tools/tool_transform.py#L199"><Icon icon="github" size="14" /></a></sup>
|
| 73 |
|
| 74 |
|
| 75 |
A tool that is transformed from another tool.
|
|
|
|
| 85 |
|
| 86 |
**Methods:**
|
| 87 |
|
| 88 |
+
#### `from_tool` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/tools/tool_transform.py#L280"><Icon icon="github" size="14" /></a></sup>
|
| 89 |
|
| 90 |
```python
|
| 91 |
from_tool(cls, tool: Tool, name: str | None = None, description: str | None = None, tags: set[str] | None = None, transform_fn: Callable[..., Any] | None = None, transform_args: dict[str, ArgTransform] | None = None, annotations: ToolAnnotations | None = None, serializer: Callable[[Any], str] | None = None, enabled: bool | None = None) -> TransformedTool
|
|
|
|
| 101 |
- `name`: New name for the tool. Defaults to parent tool's name.
|
| 102 |
- `transform_args`: Optional transformations for parent tool arguments.
|
| 103 |
Only specified arguments are transformed, others pass through unchanged\:
|
| 104 |
+
- Simple rename (str)
|
| 105 |
+
- Complex transformation (rename/description/default/drop) (ArgTransform)
|
| 106 |
+
- Drop the argument (None)
|
| 107 |
- `description`: New description. Defaults to parent's description.
|
| 108 |
- `tags`: New tags. Defaults to parent's tags.
|
| 109 |
- `annotations`: New annotations. Defaults to parent's annotations.
|
|
|
|
| 112 |
**Returns:**
|
| 113 |
- TransformedTool with the specified transformations.
|
| 114 |
|
| 115 |
+
**Examples:**
|
| 116 |
+
|
| 117 |
+
# Transform specific arguments only
|
| 118 |
+
```python
|
| 119 |
+
Tool.from_tool(parent, transform_args={"old": "new"}) # Others unchanged
|
| 120 |
+
```
|
| 121 |
+
|
| 122 |
+
# Custom function with partial transforms
|
| 123 |
+
```python
|
| 124 |
+
async def custom(x: int, y: int) -> str:
|
| 125 |
+
result = await forward(x=x, y=y)
|
| 126 |
+
return f"Custom: {result}"
|
| 127 |
+
|
| 128 |
+
Tool.from_tool(parent, transform_fn=custom, transform_args={"a": "x", "b": "y"})
|
| 129 |
+
```
|
| 130 |
+
|
| 131 |
+
# Using **kwargs (gets all args, transformed and untransformed)
|
| 132 |
+
```python
|
| 133 |
+
async def flexible(**kwargs) -> str:
|
| 134 |
+
result = await forward(**kwargs)
|
| 135 |
+
return f"Got: {kwargs}"
|
| 136 |
+
|
| 137 |
+
Tool.from_tool(parent, transform_fn=flexible, transform_args={"a": "x"})
|
| 138 |
+
```
|
| 139 |
|
src/fastmcp/server/server.py
CHANGED
|
@@ -363,6 +363,7 @@ class FastMCP(Generic[LifespanResultT]):
|
|
| 363 |
return await self._resource_manager.get_resource_templates()
|
| 364 |
|
| 365 |
async def get_resource_template(self, key: str) -> ResourceTemplate:
|
|
|
|
| 366 |
templates = await self.get_resource_templates()
|
| 367 |
if key not in templates:
|
| 368 |
raise NotFoundError(f"Unknown resource template: {key}")
|
|
@@ -403,9 +404,12 @@ class FastMCP(Generic[LifespanResultT]):
|
|
| 403 |
include_in_schema: Whether to include in OpenAPI schema, defaults to True
|
| 404 |
|
| 405 |
Example:
|
|
|
|
|
|
|
| 406 |
@server.custom_route("/health", methods=["GET"])
|
| 407 |
async def health_check(request: Request) -> Response:
|
| 408 |
return JSONResponse({"status": "ok"})
|
|
|
|
| 409 |
"""
|
| 410 |
|
| 411 |
def decorator(
|
|
@@ -814,15 +818,18 @@ class FastMCP(Generic[LifespanResultT]):
|
|
| 814 |
name: Optional name for the tool (keyword-only, alternative to name_or_fn)
|
| 815 |
description: Optional description of what the tool does
|
| 816 |
tags: Optional set of tags for categorizing the tool
|
| 817 |
-
annotations: Optional annotations about the tool's behavior
|
| 818 |
exclude_args: Optional list of argument names to exclude from the tool schema
|
| 819 |
enabled: Optional boolean to enable or disable the tool
|
| 820 |
|
| 821 |
-
|
|
|
|
|
|
|
| 822 |
@server.tool
|
| 823 |
def my_tool(x: int) -> str:
|
| 824 |
return str(x)
|
| 825 |
|
|
|
|
| 826 |
@server.tool
|
| 827 |
def my_tool(x: int) -> str:
|
| 828 |
return str(x)
|
|
@@ -837,6 +844,7 @@ class FastMCP(Generic[LifespanResultT]):
|
|
| 837 |
|
| 838 |
# Direct function call
|
| 839 |
server.tool(my_function, name="custom_name")
|
|
|
|
| 840 |
"""
|
| 841 |
if isinstance(annotations, dict):
|
| 842 |
annotations = ToolAnnotations(**annotations)
|
|
@@ -991,7 +999,9 @@ class FastMCP(Generic[LifespanResultT]):
|
|
| 991 |
tags: Optional set of tags for categorizing the resource
|
| 992 |
enabled: Optional boolean to enable or disable the resource
|
| 993 |
|
| 994 |
-
|
|
|
|
|
|
|
| 995 |
@server.resource("resource://my-resource")
|
| 996 |
def get_data() -> str:
|
| 997 |
return "Hello, world!"
|
|
@@ -1014,6 +1024,7 @@ class FastMCP(Generic[LifespanResultT]):
|
|
| 1014 |
async def get_weather(city: str) -> str:
|
| 1015 |
data = await fetch_weather(city)
|
| 1016 |
return f"Weather for {city}: {data}"
|
|
|
|
| 1017 |
"""
|
| 1018 |
# Check if user passed function directly instead of calling decorator
|
| 1019 |
if inspect.isroutine(uri):
|
|
@@ -1138,7 +1149,9 @@ class FastMCP(Generic[LifespanResultT]):
|
|
| 1138 |
tags: Optional set of tags for categorizing the prompt
|
| 1139 |
enabled: Optional boolean to enable or disable the prompt
|
| 1140 |
|
| 1141 |
-
|
|
|
|
|
|
|
| 1142 |
@server.prompt
|
| 1143 |
def analyze_table(table_name: str) -> list[Message]:
|
| 1144 |
schema = read_table_schema(table_name)
|
|
@@ -1182,6 +1195,7 @@ class FastMCP(Generic[LifespanResultT]):
|
|
| 1182 |
|
| 1183 |
# Direct function call
|
| 1184 |
server.prompt(my_function, name="custom_name")
|
|
|
|
| 1185 |
"""
|
| 1186 |
|
| 1187 |
if isinstance(name_or_fn, classmethod):
|
|
@@ -1787,10 +1801,10 @@ class FastMCP(Generic[LifespanResultT]):
|
|
| 1787 |
) -> FastMCPProxy:
|
| 1788 |
"""Create a FastMCP proxy server for the given backend.
|
| 1789 |
|
| 1790 |
-
The `
|
| 1791 |
-
instance or any value accepted as the `
|
| 1792 |
-
|
| 1793 |
-
`
|
| 1794 |
"""
|
| 1795 |
from fastmcp.client.client import Client
|
| 1796 |
from fastmcp.server.proxy import FastMCPProxy
|
|
@@ -1827,14 +1841,14 @@ class FastMCP(Generic[LifespanResultT]):
|
|
| 1827 |
Given a component, determine if it should be enabled. Returns True if it should be enabled; False if it should not.
|
| 1828 |
|
| 1829 |
Rules:
|
| 1830 |
-
|
| 1831 |
-
|
| 1832 |
-
|
| 1833 |
- If the exclude tag is a string, it must be present in the input tags to exclude.
|
| 1834 |
-
|
| 1835 |
- If the include tag is a string, it must be present in the input tags to include.
|
| 1836 |
-
|
| 1837 |
-
|
| 1838 |
"""
|
| 1839 |
if not component.enabled:
|
| 1840 |
return False
|
|
@@ -1875,12 +1889,21 @@ def add_resource_prefix(
|
|
| 1875 |
The resource URI with the prefix added
|
| 1876 |
|
| 1877 |
Examples:
|
| 1878 |
-
|
| 1879 |
-
|
| 1880 |
-
|
| 1881 |
-
"
|
| 1882 |
-
|
| 1883 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1884 |
|
| 1885 |
Raises:
|
| 1886 |
ValueError: If the URI doesn't match the expected protocol://path format
|
|
@@ -1926,12 +1949,21 @@ def remove_resource_prefix(
|
|
| 1926 |
The resource URI with the prefix removed
|
| 1927 |
|
| 1928 |
Examples:
|
| 1929 |
-
|
| 1930 |
-
|
| 1931 |
-
|
| 1932 |
-
"resource://path/to/resource"
|
| 1933 |
-
|
| 1934 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1935 |
|
| 1936 |
Raises:
|
| 1937 |
ValueError: If the URI doesn't match the expected protocol://path format
|
|
@@ -1984,12 +2016,21 @@ def has_resource_prefix(
|
|
| 1984 |
True if the URI has the specified prefix, False otherwise
|
| 1985 |
|
| 1986 |
Examples:
|
| 1987 |
-
|
| 1988 |
-
|
| 1989 |
-
|
| 1990 |
-
True
|
| 1991 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1992 |
False
|
|
|
|
| 1993 |
|
| 1994 |
Raises:
|
| 1995 |
ValueError: If the URI doesn't match the expected protocol://path format
|
|
|
|
| 363 |
return await self._resource_manager.get_resource_templates()
|
| 364 |
|
| 365 |
async def get_resource_template(self, key: str) -> ResourceTemplate:
|
| 366 |
+
"""Get a registered resource template by key."""
|
| 367 |
templates = await self.get_resource_templates()
|
| 368 |
if key not in templates:
|
| 369 |
raise NotFoundError(f"Unknown resource template: {key}")
|
|
|
|
| 404 |
include_in_schema: Whether to include in OpenAPI schema, defaults to True
|
| 405 |
|
| 406 |
Example:
|
| 407 |
+
Register a custom HTTP route for a health check endpoint:
|
| 408 |
+
```python
|
| 409 |
@server.custom_route("/health", methods=["GET"])
|
| 410 |
async def health_check(request: Request) -> Response:
|
| 411 |
return JSONResponse({"status": "ok"})
|
| 412 |
+
```
|
| 413 |
"""
|
| 414 |
|
| 415 |
def decorator(
|
|
|
|
| 818 |
name: Optional name for the tool (keyword-only, alternative to name_or_fn)
|
| 819 |
description: Optional description of what the tool does
|
| 820 |
tags: Optional set of tags for categorizing the tool
|
| 821 |
+
annotations: Optional annotations about the tool's behavior
|
| 822 |
exclude_args: Optional list of argument names to exclude from the tool schema
|
| 823 |
enabled: Optional boolean to enable or disable the tool
|
| 824 |
|
| 825 |
+
Examples:
|
| 826 |
+
Register a tool with a custom name:
|
| 827 |
+
```python
|
| 828 |
@server.tool
|
| 829 |
def my_tool(x: int) -> str:
|
| 830 |
return str(x)
|
| 831 |
|
| 832 |
+
# Register a tool with a custom name
|
| 833 |
@server.tool
|
| 834 |
def my_tool(x: int) -> str:
|
| 835 |
return str(x)
|
|
|
|
| 844 |
|
| 845 |
# Direct function call
|
| 846 |
server.tool(my_function, name="custom_name")
|
| 847 |
+
```
|
| 848 |
"""
|
| 849 |
if isinstance(annotations, dict):
|
| 850 |
annotations = ToolAnnotations(**annotations)
|
|
|
|
| 999 |
tags: Optional set of tags for categorizing the resource
|
| 1000 |
enabled: Optional boolean to enable or disable the resource
|
| 1001 |
|
| 1002 |
+
Examples:
|
| 1003 |
+
Register a resource with a custom name:
|
| 1004 |
+
```python
|
| 1005 |
@server.resource("resource://my-resource")
|
| 1006 |
def get_data() -> str:
|
| 1007 |
return "Hello, world!"
|
|
|
|
| 1024 |
async def get_weather(city: str) -> str:
|
| 1025 |
data = await fetch_weather(city)
|
| 1026 |
return f"Weather for {city}: {data}"
|
| 1027 |
+
```
|
| 1028 |
"""
|
| 1029 |
# Check if user passed function directly instead of calling decorator
|
| 1030 |
if inspect.isroutine(uri):
|
|
|
|
| 1149 |
tags: Optional set of tags for categorizing the prompt
|
| 1150 |
enabled: Optional boolean to enable or disable the prompt
|
| 1151 |
|
| 1152 |
+
Examples:
|
| 1153 |
+
|
| 1154 |
+
```python
|
| 1155 |
@server.prompt
|
| 1156 |
def analyze_table(table_name: str) -> list[Message]:
|
| 1157 |
schema = read_table_schema(table_name)
|
|
|
|
| 1195 |
|
| 1196 |
# Direct function call
|
| 1197 |
server.prompt(my_function, name="custom_name")
|
| 1198 |
+
```
|
| 1199 |
"""
|
| 1200 |
|
| 1201 |
if isinstance(name_or_fn, classmethod):
|
|
|
|
| 1801 |
) -> FastMCPProxy:
|
| 1802 |
"""Create a FastMCP proxy server for the given backend.
|
| 1803 |
|
| 1804 |
+
The `backend` argument can be either an existing `fastmcp.client.Client`
|
| 1805 |
+
instance or any value accepted as the `transport` argument of
|
| 1806 |
+
`fastmcp.client.Client`. This mirrors the convenience of the
|
| 1807 |
+
`fastmcp.client.Client` constructor.
|
| 1808 |
"""
|
| 1809 |
from fastmcp.client.client import Client
|
| 1810 |
from fastmcp.server.proxy import FastMCPProxy
|
|
|
|
| 1841 |
Given a component, determine if it should be enabled. Returns True if it should be enabled; False if it should not.
|
| 1842 |
|
| 1843 |
Rules:
|
| 1844 |
+
- If the component's enabled property is False, always return False.
|
| 1845 |
+
- If both include_tags and exclude_tags are None, return True.
|
| 1846 |
+
- If exclude_tags is provided, check each exclude tag:
|
| 1847 |
- If the exclude tag is a string, it must be present in the input tags to exclude.
|
| 1848 |
+
- If include_tags is provided, check each include tag:
|
| 1849 |
- If the include tag is a string, it must be present in the input tags to include.
|
| 1850 |
+
- If include_tags is provided and none of the include tags match, return False.
|
| 1851 |
+
- If include_tags is not provided, return True.
|
| 1852 |
"""
|
| 1853 |
if not component.enabled:
|
| 1854 |
return False
|
|
|
|
| 1889 |
The resource URI with the prefix added
|
| 1890 |
|
| 1891 |
Examples:
|
| 1892 |
+
With new style:
|
| 1893 |
+
```python
|
| 1894 |
+
add_resource_prefix("resource://path/to/resource", "prefix")
|
| 1895 |
+
"resource://prefix/path/to/resource"
|
| 1896 |
+
```
|
| 1897 |
+
With legacy style:
|
| 1898 |
+
```python
|
| 1899 |
+
add_resource_prefix("resource://path/to/resource", "prefix")
|
| 1900 |
+
"prefix+resource://path/to/resource"
|
| 1901 |
+
```
|
| 1902 |
+
With absolute path:
|
| 1903 |
+
```python
|
| 1904 |
+
add_resource_prefix("resource:///absolute/path", "prefix")
|
| 1905 |
+
"resource://prefix//absolute/path"
|
| 1906 |
+
```
|
| 1907 |
|
| 1908 |
Raises:
|
| 1909 |
ValueError: If the URI doesn't match the expected protocol://path format
|
|
|
|
| 1949 |
The resource URI with the prefix removed
|
| 1950 |
|
| 1951 |
Examples:
|
| 1952 |
+
With new style:
|
| 1953 |
+
```python
|
| 1954 |
+
remove_resource_prefix("resource://prefix/path/to/resource", "prefix")
|
| 1955 |
+
"resource://path/to/resource"
|
| 1956 |
+
```
|
| 1957 |
+
With legacy style:
|
| 1958 |
+
```python
|
| 1959 |
+
remove_resource_prefix("prefix+resource://path/to/resource", "prefix")
|
| 1960 |
+
"resource://path/to/resource"
|
| 1961 |
+
```
|
| 1962 |
+
With absolute path:
|
| 1963 |
+
```python
|
| 1964 |
+
remove_resource_prefix("resource://prefix//absolute/path", "prefix")
|
| 1965 |
+
"resource:///absolute/path"
|
| 1966 |
+
```
|
| 1967 |
|
| 1968 |
Raises:
|
| 1969 |
ValueError: If the URI doesn't match the expected protocol://path format
|
|
|
|
| 2016 |
True if the URI has the specified prefix, False otherwise
|
| 2017 |
|
| 2018 |
Examples:
|
| 2019 |
+
With new style:
|
| 2020 |
+
```python
|
| 2021 |
+
has_resource_prefix("resource://prefix/path/to/resource", "prefix")
|
| 2022 |
+
True
|
| 2023 |
+
```
|
| 2024 |
+
With legacy style:
|
| 2025 |
+
```python
|
| 2026 |
+
has_resource_prefix("prefix+resource://path/to/resource", "prefix")
|
| 2027 |
+
True
|
| 2028 |
+
```
|
| 2029 |
+
With other path:
|
| 2030 |
+
```python
|
| 2031 |
+
has_resource_prefix("resource://other/path/to/resource", "prefix")
|
| 2032 |
False
|
| 2033 |
+
```
|
| 2034 |
|
| 2035 |
Raises:
|
| 2036 |
ValueError: If the URI doesn't match the expected protocol://path format
|
src/fastmcp/tools/tool_transform.py
CHANGED
|
@@ -100,35 +100,55 @@ class ArgTransform:
|
|
| 100 |
examples: Examples for the argument. Use ... for no change.
|
| 101 |
|
| 102 |
Examples:
|
| 103 |
-
|
|
|
|
| 104 |
ArgTransform(name="new_name")
|
|
|
|
| 105 |
|
| 106 |
-
|
|
|
|
| 107 |
ArgTransform(description="Updated description")
|
|
|
|
| 108 |
|
| 109 |
-
|
|
|
|
| 110 |
ArgTransform(default=42)
|
|
|
|
| 111 |
|
| 112 |
-
|
|
|
|
| 113 |
ArgTransform(default_factory=lambda: time.time())
|
|
|
|
| 114 |
|
| 115 |
-
|
|
|
|
| 116 |
ArgTransform(type=str)
|
|
|
|
| 117 |
|
| 118 |
-
|
|
|
|
| 119 |
ArgTransform(hide=True)
|
|
|
|
| 120 |
|
| 121 |
-
|
|
|
|
| 122 |
ArgTransform(hide=True, default="constant_value")
|
|
|
|
| 123 |
|
| 124 |
-
|
|
|
|
| 125 |
ArgTransform(hide=True, default_factory=lambda: uuid.uuid4().hex)
|
|
|
|
| 126 |
|
| 127 |
-
|
|
|
|
| 128 |
ArgTransform(required=True)
|
|
|
|
| 129 |
|
| 130 |
-
|
|
|
|
| 131 |
ArgTransform(name="new_name", description="New desc", default=None, type=int)
|
|
|
|
| 132 |
"""
|
| 133 |
|
| 134 |
name: str | EllipsisType = NotSet
|
|
@@ -279,9 +299,9 @@ class TransformedTool(Tool):
|
|
| 279 |
name: New name for the tool. Defaults to parent tool's name.
|
| 280 |
transform_args: Optional transformations for parent tool arguments.
|
| 281 |
Only specified arguments are transformed, others pass through unchanged:
|
| 282 |
-
-
|
| 283 |
-
-
|
| 284 |
-
-
|
| 285 |
description: New description. Defaults to parent's description.
|
| 286 |
tags: New tags. Defaults to parent's tags.
|
| 287 |
annotations: New annotations. Defaults to parent's annotations.
|
|
@@ -290,23 +310,29 @@ class TransformedTool(Tool):
|
|
| 290 |
Returns:
|
| 291 |
TransformedTool with the specified transformations.
|
| 292 |
|
| 293 |
-
|
| 294 |
# Transform specific arguments only
|
|
|
|
| 295 |
Tool.from_tool(parent, transform_args={"old": "new"}) # Others unchanged
|
|
|
|
| 296 |
|
| 297 |
# Custom function with partial transforms
|
|
|
|
| 298 |
async def custom(x: int, y: int) -> str:
|
| 299 |
result = await forward(x=x, y=y)
|
| 300 |
return f"Custom: {result}"
|
| 301 |
|
| 302 |
Tool.from_tool(parent, transform_fn=custom, transform_args={"a": "x", "b": "y"})
|
|
|
|
| 303 |
|
| 304 |
# Using **kwargs (gets all args, transformed and untransformed)
|
|
|
|
| 305 |
async def flexible(**kwargs) -> str:
|
| 306 |
result = await forward(**kwargs)
|
| 307 |
return f"Got: {kwargs}"
|
| 308 |
|
| 309 |
Tool.from_tool(parent, transform_fn=flexible, transform_args={"a": "x"})
|
|
|
|
| 310 |
"""
|
| 311 |
transform_args = transform_args or {}
|
| 312 |
|
|
@@ -423,8 +449,8 @@ class TransformedTool(Tool):
|
|
| 423 |
|
| 424 |
Returns:
|
| 425 |
A tuple containing:
|
| 426 |
-
-
|
| 427 |
-
-
|
| 428 |
"""
|
| 429 |
|
| 430 |
# Build transformed schema and mapping
|
|
|
|
| 100 |
examples: Examples for the argument. Use ... for no change.
|
| 101 |
|
| 102 |
Examples:
|
| 103 |
+
Rename argument 'old_name' to 'new_name'
|
| 104 |
+
```python
|
| 105 |
ArgTransform(name="new_name")
|
| 106 |
+
```
|
| 107 |
|
| 108 |
+
Change description only
|
| 109 |
+
```python
|
| 110 |
ArgTransform(description="Updated description")
|
| 111 |
+
```
|
| 112 |
|
| 113 |
+
Add a default value (makes argument optional)
|
| 114 |
+
```python
|
| 115 |
ArgTransform(default=42)
|
| 116 |
+
```
|
| 117 |
|
| 118 |
+
Add a default factory (makes argument optional)
|
| 119 |
+
```python
|
| 120 |
ArgTransform(default_factory=lambda: time.time())
|
| 121 |
+
```
|
| 122 |
|
| 123 |
+
Change the type
|
| 124 |
+
```python
|
| 125 |
ArgTransform(type=str)
|
| 126 |
+
```
|
| 127 |
|
| 128 |
+
Hide the argument entirely from clients
|
| 129 |
+
```python
|
| 130 |
ArgTransform(hide=True)
|
| 131 |
+
```
|
| 132 |
|
| 133 |
+
Hide argument but pass a constant value to parent
|
| 134 |
+
```python
|
| 135 |
ArgTransform(hide=True, default="constant_value")
|
| 136 |
+
```
|
| 137 |
|
| 138 |
+
Hide argument but pass a factory-generated value to parent
|
| 139 |
+
```python
|
| 140 |
ArgTransform(hide=True, default_factory=lambda: uuid.uuid4().hex)
|
| 141 |
+
```
|
| 142 |
|
| 143 |
+
Make an optional parameter required (removes any default)
|
| 144 |
+
```python
|
| 145 |
ArgTransform(required=True)
|
| 146 |
+
```
|
| 147 |
|
| 148 |
+
Combine multiple transformations
|
| 149 |
+
```python
|
| 150 |
ArgTransform(name="new_name", description="New desc", default=None, type=int)
|
| 151 |
+
```
|
| 152 |
"""
|
| 153 |
|
| 154 |
name: str | EllipsisType = NotSet
|
|
|
|
| 299 |
name: New name for the tool. Defaults to parent tool's name.
|
| 300 |
transform_args: Optional transformations for parent tool arguments.
|
| 301 |
Only specified arguments are transformed, others pass through unchanged:
|
| 302 |
+
- Simple rename (str)
|
| 303 |
+
- Complex transformation (rename/description/default/drop) (ArgTransform)
|
| 304 |
+
- Drop the argument (None)
|
| 305 |
description: New description. Defaults to parent's description.
|
| 306 |
tags: New tags. Defaults to parent's tags.
|
| 307 |
annotations: New annotations. Defaults to parent's annotations.
|
|
|
|
| 310 |
Returns:
|
| 311 |
TransformedTool with the specified transformations.
|
| 312 |
|
| 313 |
+
Examples:
|
| 314 |
# Transform specific arguments only
|
| 315 |
+
```python
|
| 316 |
Tool.from_tool(parent, transform_args={"old": "new"}) # Others unchanged
|
| 317 |
+
```
|
| 318 |
|
| 319 |
# Custom function with partial transforms
|
| 320 |
+
```python
|
| 321 |
async def custom(x: int, y: int) -> str:
|
| 322 |
result = await forward(x=x, y=y)
|
| 323 |
return f"Custom: {result}"
|
| 324 |
|
| 325 |
Tool.from_tool(parent, transform_fn=custom, transform_args={"a": "x", "b": "y"})
|
| 326 |
+
```
|
| 327 |
|
| 328 |
# Using **kwargs (gets all args, transformed and untransformed)
|
| 329 |
+
```python
|
| 330 |
async def flexible(**kwargs) -> str:
|
| 331 |
result = await forward(**kwargs)
|
| 332 |
return f"Got: {kwargs}"
|
| 333 |
|
| 334 |
Tool.from_tool(parent, transform_fn=flexible, transform_args={"a": "x"})
|
| 335 |
+
```
|
| 336 |
"""
|
| 337 |
transform_args = transform_args or {}
|
| 338 |
|
|
|
|
| 449 |
|
| 450 |
Returns:
|
| 451 |
A tuple containing:
|
| 452 |
+
- The new JSON schema for the transformed tool as a dictionary
|
| 453 |
+
- Async function that validates and forwards calls to the parent tool
|
| 454 |
"""
|
| 455 |
|
| 456 |
# Build transformed schema and mapping
|