fastmcp 2.14.4__py3-none-any.whl → 3.0.0b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fastmcp/_vendor/__init__.py +1 -0
- fastmcp/_vendor/docket_di/README.md +7 -0
- fastmcp/_vendor/docket_di/__init__.py +163 -0
- fastmcp/cli/cli.py +112 -28
- fastmcp/cli/install/claude_code.py +1 -5
- fastmcp/cli/install/claude_desktop.py +1 -5
- fastmcp/cli/install/cursor.py +1 -5
- fastmcp/cli/install/gemini_cli.py +1 -5
- fastmcp/cli/install/mcp_json.py +1 -6
- fastmcp/cli/run.py +146 -5
- fastmcp/client/__init__.py +7 -9
- fastmcp/client/auth/oauth.py +18 -17
- fastmcp/client/client.py +100 -870
- fastmcp/client/elicitation.py +1 -1
- fastmcp/client/mixins/__init__.py +13 -0
- fastmcp/client/mixins/prompts.py +295 -0
- fastmcp/client/mixins/resources.py +325 -0
- fastmcp/client/mixins/task_management.py +157 -0
- fastmcp/client/mixins/tools.py +397 -0
- fastmcp/client/sampling/handlers/anthropic.py +2 -2
- fastmcp/client/sampling/handlers/openai.py +1 -1
- fastmcp/client/tasks.py +3 -3
- fastmcp/client/telemetry.py +47 -0
- fastmcp/client/transports/__init__.py +38 -0
- fastmcp/client/transports/base.py +82 -0
- fastmcp/client/transports/config.py +170 -0
- fastmcp/client/transports/http.py +145 -0
- fastmcp/client/transports/inference.py +154 -0
- fastmcp/client/transports/memory.py +90 -0
- fastmcp/client/transports/sse.py +89 -0
- fastmcp/client/transports/stdio.py +543 -0
- fastmcp/contrib/component_manager/README.md +4 -10
- fastmcp/contrib/component_manager/__init__.py +1 -2
- fastmcp/contrib/component_manager/component_manager.py +95 -160
- fastmcp/contrib/component_manager/example.py +1 -1
- fastmcp/contrib/mcp_mixin/example.py +4 -4
- fastmcp/contrib/mcp_mixin/mcp_mixin.py +11 -4
- fastmcp/decorators.py +41 -0
- fastmcp/dependencies.py +12 -1
- fastmcp/exceptions.py +4 -0
- fastmcp/experimental/server/openapi/__init__.py +18 -15
- fastmcp/mcp_config.py +13 -4
- fastmcp/prompts/__init__.py +6 -3
- fastmcp/prompts/function_prompt.py +465 -0
- fastmcp/prompts/prompt.py +321 -271
- fastmcp/resources/__init__.py +5 -3
- fastmcp/resources/function_resource.py +335 -0
- fastmcp/resources/resource.py +325 -115
- fastmcp/resources/template.py +215 -43
- fastmcp/resources/types.py +27 -12
- fastmcp/server/__init__.py +2 -2
- fastmcp/server/auth/__init__.py +14 -0
- fastmcp/server/auth/auth.py +30 -10
- fastmcp/server/auth/authorization.py +190 -0
- fastmcp/server/auth/oauth_proxy/__init__.py +14 -0
- fastmcp/server/auth/oauth_proxy/consent.py +361 -0
- fastmcp/server/auth/oauth_proxy/models.py +178 -0
- fastmcp/server/auth/{oauth_proxy.py → oauth_proxy/proxy.py} +24 -778
- fastmcp/server/auth/oauth_proxy/ui.py +277 -0
- fastmcp/server/auth/oidc_proxy.py +2 -2
- fastmcp/server/auth/providers/auth0.py +24 -94
- fastmcp/server/auth/providers/aws.py +26 -95
- fastmcp/server/auth/providers/azure.py +41 -129
- fastmcp/server/auth/providers/descope.py +18 -49
- fastmcp/server/auth/providers/discord.py +25 -86
- fastmcp/server/auth/providers/github.py +23 -87
- fastmcp/server/auth/providers/google.py +24 -87
- fastmcp/server/auth/providers/introspection.py +60 -79
- fastmcp/server/auth/providers/jwt.py +30 -67
- fastmcp/server/auth/providers/oci.py +47 -110
- fastmcp/server/auth/providers/scalekit.py +23 -61
- fastmcp/server/auth/providers/supabase.py +18 -47
- fastmcp/server/auth/providers/workos.py +34 -127
- fastmcp/server/context.py +372 -419
- fastmcp/server/dependencies.py +541 -251
- fastmcp/server/elicitation.py +20 -18
- fastmcp/server/event_store.py +3 -3
- fastmcp/server/http.py +16 -6
- fastmcp/server/lifespan.py +198 -0
- fastmcp/server/low_level.py +92 -2
- fastmcp/server/middleware/__init__.py +5 -1
- fastmcp/server/middleware/authorization.py +312 -0
- fastmcp/server/middleware/caching.py +101 -54
- fastmcp/server/middleware/middleware.py +6 -9
- fastmcp/server/middleware/ping.py +70 -0
- fastmcp/server/middleware/tool_injection.py +2 -2
- fastmcp/server/mixins/__init__.py +7 -0
- fastmcp/server/mixins/lifespan.py +217 -0
- fastmcp/server/mixins/mcp_operations.py +392 -0
- fastmcp/server/mixins/transport.py +342 -0
- fastmcp/server/openapi/__init__.py +41 -21
- fastmcp/server/openapi/components.py +16 -339
- fastmcp/server/openapi/routing.py +34 -118
- fastmcp/server/openapi/server.py +67 -392
- fastmcp/server/providers/__init__.py +71 -0
- fastmcp/server/providers/aggregate.py +261 -0
- fastmcp/server/providers/base.py +578 -0
- fastmcp/server/providers/fastmcp_provider.py +674 -0
- fastmcp/server/providers/filesystem.py +226 -0
- fastmcp/server/providers/filesystem_discovery.py +327 -0
- fastmcp/server/providers/local_provider/__init__.py +11 -0
- fastmcp/server/providers/local_provider/decorators/__init__.py +15 -0
- fastmcp/server/providers/local_provider/decorators/prompts.py +256 -0
- fastmcp/server/providers/local_provider/decorators/resources.py +240 -0
- fastmcp/server/providers/local_provider/decorators/tools.py +315 -0
- fastmcp/server/providers/local_provider/local_provider.py +465 -0
- fastmcp/server/providers/openapi/__init__.py +39 -0
- fastmcp/server/providers/openapi/components.py +332 -0
- fastmcp/server/providers/openapi/provider.py +405 -0
- fastmcp/server/providers/openapi/routing.py +109 -0
- fastmcp/server/providers/proxy.py +867 -0
- fastmcp/server/providers/skills/__init__.py +59 -0
- fastmcp/server/providers/skills/_common.py +101 -0
- fastmcp/server/providers/skills/claude_provider.py +44 -0
- fastmcp/server/providers/skills/directory_provider.py +153 -0
- fastmcp/server/providers/skills/skill_provider.py +432 -0
- fastmcp/server/providers/skills/vendor_providers.py +142 -0
- fastmcp/server/providers/wrapped_provider.py +140 -0
- fastmcp/server/proxy.py +34 -700
- fastmcp/server/sampling/run.py +341 -2
- fastmcp/server/sampling/sampling_tool.py +4 -3
- fastmcp/server/server.py +1214 -2171
- fastmcp/server/tasks/__init__.py +2 -1
- fastmcp/server/tasks/capabilities.py +13 -1
- fastmcp/server/tasks/config.py +66 -3
- fastmcp/server/tasks/handlers.py +65 -273
- fastmcp/server/tasks/keys.py +4 -6
- fastmcp/server/tasks/requests.py +474 -0
- fastmcp/server/tasks/routing.py +76 -0
- fastmcp/server/tasks/subscriptions.py +20 -11
- fastmcp/server/telemetry.py +131 -0
- fastmcp/server/transforms/__init__.py +244 -0
- fastmcp/server/transforms/namespace.py +193 -0
- fastmcp/server/transforms/prompts_as_tools.py +175 -0
- fastmcp/server/transforms/resources_as_tools.py +190 -0
- fastmcp/server/transforms/tool_transform.py +96 -0
- fastmcp/server/transforms/version_filter.py +124 -0
- fastmcp/server/transforms/visibility.py +526 -0
- fastmcp/settings.py +34 -96
- fastmcp/telemetry.py +122 -0
- fastmcp/tools/__init__.py +10 -3
- fastmcp/tools/function_parsing.py +201 -0
- fastmcp/tools/function_tool.py +467 -0
- fastmcp/tools/tool.py +215 -362
- fastmcp/tools/tool_transform.py +38 -21
- fastmcp/utilities/async_utils.py +69 -0
- fastmcp/utilities/components.py +152 -91
- fastmcp/utilities/inspect.py +8 -20
- fastmcp/utilities/json_schema.py +12 -5
- fastmcp/utilities/json_schema_type.py +17 -15
- fastmcp/utilities/lifespan.py +56 -0
- fastmcp/utilities/logging.py +12 -4
- fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py +3 -3
- fastmcp/utilities/openapi/parser.py +3 -3
- fastmcp/utilities/pagination.py +80 -0
- fastmcp/utilities/skills.py +253 -0
- fastmcp/utilities/tests.py +0 -16
- fastmcp/utilities/timeout.py +47 -0
- fastmcp/utilities/types.py +1 -1
- fastmcp/utilities/versions.py +285 -0
- {fastmcp-2.14.4.dist-info → fastmcp-3.0.0b1.dist-info}/METADATA +8 -5
- fastmcp-3.0.0b1.dist-info/RECORD +228 -0
- fastmcp/client/transports.py +0 -1170
- fastmcp/contrib/component_manager/component_service.py +0 -209
- fastmcp/prompts/prompt_manager.py +0 -117
- fastmcp/resources/resource_manager.py +0 -338
- fastmcp/server/tasks/converters.py +0 -206
- fastmcp/server/tasks/protocol.py +0 -359
- fastmcp/tools/tool_manager.py +0 -170
- fastmcp/utilities/mcp_config.py +0 -56
- fastmcp-2.14.4.dist-info/RECORD +0 -161
- /fastmcp/server/{openapi → providers/openapi}/README.md +0 -0
- {fastmcp-2.14.4.dist-info → fastmcp-3.0.0b1.dist-info}/WHEEL +0 -0
- {fastmcp-2.14.4.dist-info → fastmcp-3.0.0b1.dist-info}/entry_points.txt +0 -0
- {fastmcp-2.14.4.dist-info → fastmcp-3.0.0b1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
"""Transport-related methods for FastMCP Server."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Awaitable, Callable
|
|
6
|
+
from functools import partial
|
|
7
|
+
from typing import TYPE_CHECKING, Any, Literal
|
|
8
|
+
|
|
9
|
+
import anyio
|
|
10
|
+
import uvicorn
|
|
11
|
+
from mcp.server.lowlevel.server import NotificationOptions
|
|
12
|
+
from mcp.server.stdio import stdio_server
|
|
13
|
+
from starlette.middleware import Middleware as ASGIMiddleware
|
|
14
|
+
from starlette.requests import Request
|
|
15
|
+
from starlette.responses import Response
|
|
16
|
+
from starlette.routing import BaseRoute, Route
|
|
17
|
+
|
|
18
|
+
import fastmcp
|
|
19
|
+
from fastmcp.server.event_store import EventStore
|
|
20
|
+
from fastmcp.server.http import (
|
|
21
|
+
StarletteWithLifespan,
|
|
22
|
+
create_sse_app,
|
|
23
|
+
create_streamable_http_app,
|
|
24
|
+
)
|
|
25
|
+
from fastmcp.utilities.cli import log_server_banner
|
|
26
|
+
from fastmcp.utilities.logging import get_logger, temporary_log_level
|
|
27
|
+
|
|
28
|
+
if TYPE_CHECKING:
|
|
29
|
+
from fastmcp.server.server import FastMCP, Transport
|
|
30
|
+
|
|
31
|
+
logger = get_logger(__name__)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class TransportMixin:
|
|
35
|
+
"""Mixin providing transport-related methods for FastMCP.
|
|
36
|
+
|
|
37
|
+
Includes HTTP/stdio/SSE transport handling and custom HTTP routes.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
async def run_async(
|
|
41
|
+
self: FastMCP,
|
|
42
|
+
transport: Transport | None = None,
|
|
43
|
+
show_banner: bool | None = None,
|
|
44
|
+
**transport_kwargs: Any,
|
|
45
|
+
) -> None:
|
|
46
|
+
"""Run the FastMCP server asynchronously.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
transport: Transport protocol to use ("stdio", "http", "sse", or "streamable-http")
|
|
50
|
+
show_banner: Whether to display the server banner. If None, uses the
|
|
51
|
+
FASTMCP_SHOW_SERVER_BANNER setting (default: True).
|
|
52
|
+
"""
|
|
53
|
+
if show_banner is None:
|
|
54
|
+
show_banner = fastmcp.settings.show_server_banner
|
|
55
|
+
if transport is None:
|
|
56
|
+
transport = "stdio"
|
|
57
|
+
if transport not in {"stdio", "http", "sse", "streamable-http"}:
|
|
58
|
+
raise ValueError(f"Unknown transport: {transport}")
|
|
59
|
+
|
|
60
|
+
if transport == "stdio":
|
|
61
|
+
await self.run_stdio_async(
|
|
62
|
+
show_banner=show_banner,
|
|
63
|
+
**transport_kwargs,
|
|
64
|
+
)
|
|
65
|
+
elif transport in {"http", "sse", "streamable-http"}:
|
|
66
|
+
await self.run_http_async(
|
|
67
|
+
transport=transport,
|
|
68
|
+
show_banner=show_banner,
|
|
69
|
+
**transport_kwargs,
|
|
70
|
+
)
|
|
71
|
+
else:
|
|
72
|
+
raise ValueError(f"Unknown transport: {transport}")
|
|
73
|
+
|
|
74
|
+
def run(
|
|
75
|
+
self: FastMCP,
|
|
76
|
+
transport: Transport | None = None,
|
|
77
|
+
show_banner: bool | None = None,
|
|
78
|
+
**transport_kwargs: Any,
|
|
79
|
+
) -> None:
|
|
80
|
+
"""Run the FastMCP server. Note this is a synchronous function.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
transport: Transport protocol to use ("http", "stdio", "sse", or "streamable-http")
|
|
84
|
+
show_banner: Whether to display the server banner. If None, uses the
|
|
85
|
+
FASTMCP_SHOW_SERVER_BANNER setting (default: True).
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
anyio.run(
|
|
89
|
+
partial(
|
|
90
|
+
self.run_async,
|
|
91
|
+
transport,
|
|
92
|
+
show_banner=show_banner,
|
|
93
|
+
**transport_kwargs,
|
|
94
|
+
)
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
def custom_route(
|
|
98
|
+
self: FastMCP,
|
|
99
|
+
path: str,
|
|
100
|
+
methods: list[str],
|
|
101
|
+
name: str | None = None,
|
|
102
|
+
include_in_schema: bool = True,
|
|
103
|
+
) -> Callable[
|
|
104
|
+
[Callable[[Request], Awaitable[Response]]],
|
|
105
|
+
Callable[[Request], Awaitable[Response]],
|
|
106
|
+
]:
|
|
107
|
+
"""
|
|
108
|
+
Decorator to register a custom HTTP route on the FastMCP server.
|
|
109
|
+
|
|
110
|
+
Allows adding arbitrary HTTP endpoints outside the standard MCP protocol,
|
|
111
|
+
which can be useful for OAuth callbacks, health checks, or admin APIs.
|
|
112
|
+
The handler function must be an async function that accepts a Starlette
|
|
113
|
+
Request and returns a Response.
|
|
114
|
+
|
|
115
|
+
Args:
|
|
116
|
+
path: URL path for the route (e.g., "/auth/callback")
|
|
117
|
+
methods: List of HTTP methods to support (e.g., ["GET", "POST"])
|
|
118
|
+
name: Optional name for the route (to reference this route with
|
|
119
|
+
Starlette's reverse URL lookup feature)
|
|
120
|
+
include_in_schema: Whether to include in OpenAPI schema, defaults to True
|
|
121
|
+
|
|
122
|
+
Example:
|
|
123
|
+
Register a custom HTTP route for a health check endpoint:
|
|
124
|
+
```python
|
|
125
|
+
@server.custom_route("/health", methods=["GET"])
|
|
126
|
+
async def health_check(request: Request) -> Response:
|
|
127
|
+
return JSONResponse({"status": "ok"})
|
|
128
|
+
```
|
|
129
|
+
"""
|
|
130
|
+
|
|
131
|
+
def decorator(
|
|
132
|
+
fn: Callable[[Request], Awaitable[Response]],
|
|
133
|
+
) -> Callable[[Request], Awaitable[Response]]:
|
|
134
|
+
self._additional_http_routes.append(
|
|
135
|
+
Route(
|
|
136
|
+
path,
|
|
137
|
+
endpoint=fn,
|
|
138
|
+
methods=methods,
|
|
139
|
+
name=name,
|
|
140
|
+
include_in_schema=include_in_schema,
|
|
141
|
+
)
|
|
142
|
+
)
|
|
143
|
+
return fn
|
|
144
|
+
|
|
145
|
+
return decorator
|
|
146
|
+
|
|
147
|
+
def _get_additional_http_routes(self: FastMCP) -> list[BaseRoute]:
|
|
148
|
+
"""Get all additional HTTP routes including from providers.
|
|
149
|
+
|
|
150
|
+
Returns a list of all custom HTTP routes from this server and
|
|
151
|
+
from all providers that have HTTP routes (e.g., FastMCPProvider).
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
List of Starlette BaseRoute objects
|
|
155
|
+
"""
|
|
156
|
+
return list(self._additional_http_routes)
|
|
157
|
+
|
|
158
|
+
async def run_stdio_async(
|
|
159
|
+
self: FastMCP,
|
|
160
|
+
show_banner: bool = True,
|
|
161
|
+
log_level: str | None = None,
|
|
162
|
+
stateless: bool = False,
|
|
163
|
+
) -> None:
|
|
164
|
+
"""Run the server using stdio transport.
|
|
165
|
+
|
|
166
|
+
Args:
|
|
167
|
+
show_banner: Whether to display the server banner
|
|
168
|
+
log_level: Log level for the server
|
|
169
|
+
stateless: Whether to run in stateless mode (no session initialization)
|
|
170
|
+
"""
|
|
171
|
+
from fastmcp.server.context import reset_transport, set_transport
|
|
172
|
+
|
|
173
|
+
# Display server banner
|
|
174
|
+
if show_banner:
|
|
175
|
+
log_server_banner(server=self)
|
|
176
|
+
|
|
177
|
+
token = set_transport("stdio")
|
|
178
|
+
try:
|
|
179
|
+
with temporary_log_level(log_level):
|
|
180
|
+
async with self._lifespan_manager():
|
|
181
|
+
async with stdio_server() as (read_stream, write_stream):
|
|
182
|
+
mode = " (stateless)" if stateless else ""
|
|
183
|
+
logger.info(
|
|
184
|
+
f"Starting MCP server {self.name!r} with transport 'stdio'{mode}"
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
await self._mcp_server.run(
|
|
188
|
+
read_stream,
|
|
189
|
+
write_stream,
|
|
190
|
+
self._mcp_server.create_initialization_options(
|
|
191
|
+
notification_options=NotificationOptions(
|
|
192
|
+
tools_changed=True
|
|
193
|
+
),
|
|
194
|
+
),
|
|
195
|
+
stateless=stateless,
|
|
196
|
+
)
|
|
197
|
+
finally:
|
|
198
|
+
reset_transport(token)
|
|
199
|
+
|
|
200
|
+
async def run_http_async(
|
|
201
|
+
self: FastMCP,
|
|
202
|
+
show_banner: bool = True,
|
|
203
|
+
transport: Literal["http", "streamable-http", "sse"] = "http",
|
|
204
|
+
host: str | None = None,
|
|
205
|
+
port: int | None = None,
|
|
206
|
+
log_level: str | None = None,
|
|
207
|
+
path: str | None = None,
|
|
208
|
+
uvicorn_config: dict[str, Any] | None = None,
|
|
209
|
+
middleware: list[ASGIMiddleware] | None = None,
|
|
210
|
+
json_response: bool | None = None,
|
|
211
|
+
stateless_http: bool | None = None,
|
|
212
|
+
stateless: bool | None = None,
|
|
213
|
+
) -> None:
|
|
214
|
+
"""Run the server using HTTP transport.
|
|
215
|
+
|
|
216
|
+
Args:
|
|
217
|
+
transport: Transport protocol to use - "http" (default), "streamable-http", or "sse"
|
|
218
|
+
host: Host address to bind to (defaults to settings.host)
|
|
219
|
+
port: Port to bind to (defaults to settings.port)
|
|
220
|
+
log_level: Log level for the server (defaults to settings.log_level)
|
|
221
|
+
path: Path for the endpoint (defaults to settings.streamable_http_path or settings.sse_path)
|
|
222
|
+
uvicorn_config: Additional configuration for the Uvicorn server
|
|
223
|
+
middleware: A list of middleware to apply to the app
|
|
224
|
+
json_response: Whether to use JSON response format (defaults to settings.json_response)
|
|
225
|
+
stateless_http: Whether to use stateless HTTP (defaults to settings.stateless_http)
|
|
226
|
+
stateless: Alias for stateless_http for CLI consistency
|
|
227
|
+
"""
|
|
228
|
+
# Allow stateless as alias for stateless_http
|
|
229
|
+
if stateless is not None and stateless_http is None:
|
|
230
|
+
stateless_http = stateless
|
|
231
|
+
|
|
232
|
+
# Resolve from settings/env var if not explicitly set
|
|
233
|
+
if stateless_http is None:
|
|
234
|
+
stateless_http = self._deprecated_settings.stateless_http
|
|
235
|
+
|
|
236
|
+
# SSE doesn't support stateless mode
|
|
237
|
+
if stateless_http and transport == "sse":
|
|
238
|
+
raise ValueError("SSE transport does not support stateless mode")
|
|
239
|
+
|
|
240
|
+
host = host or self._deprecated_settings.host
|
|
241
|
+
port = port or self._deprecated_settings.port
|
|
242
|
+
default_log_level_to_use = (
|
|
243
|
+
log_level or self._deprecated_settings.log_level
|
|
244
|
+
).lower()
|
|
245
|
+
|
|
246
|
+
app = self.http_app(
|
|
247
|
+
path=path,
|
|
248
|
+
transport=transport,
|
|
249
|
+
middleware=middleware,
|
|
250
|
+
json_response=json_response,
|
|
251
|
+
stateless_http=stateless_http,
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
# Display server banner
|
|
255
|
+
if show_banner:
|
|
256
|
+
log_server_banner(server=self)
|
|
257
|
+
uvicorn_config_from_user = uvicorn_config or {}
|
|
258
|
+
|
|
259
|
+
config_kwargs: dict[str, Any] = {
|
|
260
|
+
"timeout_graceful_shutdown": 0,
|
|
261
|
+
"lifespan": "on",
|
|
262
|
+
"ws": "websockets-sansio",
|
|
263
|
+
}
|
|
264
|
+
config_kwargs.update(uvicorn_config_from_user)
|
|
265
|
+
|
|
266
|
+
if "log_config" not in config_kwargs and "log_level" not in config_kwargs:
|
|
267
|
+
config_kwargs["log_level"] = default_log_level_to_use
|
|
268
|
+
|
|
269
|
+
with temporary_log_level(log_level):
|
|
270
|
+
async with self._lifespan_manager():
|
|
271
|
+
config = uvicorn.Config(app, host=host, port=port, **config_kwargs)
|
|
272
|
+
server = uvicorn.Server(config)
|
|
273
|
+
path = getattr(app.state, "path", "").lstrip("/")
|
|
274
|
+
mode = " (stateless)" if stateless_http else ""
|
|
275
|
+
logger.info(
|
|
276
|
+
f"Starting MCP server {self.name!r} with transport {transport!r}{mode} on http://{host}:{port}/{path}"
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
await server.serve()
|
|
280
|
+
|
|
281
|
+
def http_app(
|
|
282
|
+
self: FastMCP,
|
|
283
|
+
path: str | None = None,
|
|
284
|
+
middleware: list[ASGIMiddleware] | None = None,
|
|
285
|
+
json_response: bool | None = None,
|
|
286
|
+
stateless_http: bool | None = None,
|
|
287
|
+
transport: Literal["http", "streamable-http", "sse"] = "http",
|
|
288
|
+
event_store: EventStore | None = None,
|
|
289
|
+
retry_interval: int | None = None,
|
|
290
|
+
) -> StarletteWithLifespan:
|
|
291
|
+
"""Create a Starlette app using the specified HTTP transport.
|
|
292
|
+
|
|
293
|
+
Args:
|
|
294
|
+
path: The path for the HTTP endpoint
|
|
295
|
+
middleware: A list of middleware to apply to the app
|
|
296
|
+
json_response: Whether to use JSON response format
|
|
297
|
+
stateless_http: Whether to use stateless mode (new transport per request)
|
|
298
|
+
transport: Transport protocol to use - "http", "streamable-http", or "sse"
|
|
299
|
+
event_store: Optional event store for SSE polling/resumability. When set,
|
|
300
|
+
enables clients to reconnect and resume receiving events after
|
|
301
|
+
server-initiated disconnections. Only used with streamable-http transport.
|
|
302
|
+
retry_interval: Optional retry interval in milliseconds for SSE polling.
|
|
303
|
+
Controls how quickly clients should reconnect after server-initiated
|
|
304
|
+
disconnections. Requires event_store to be set. Only used with
|
|
305
|
+
streamable-http transport.
|
|
306
|
+
|
|
307
|
+
Returns:
|
|
308
|
+
A Starlette application configured with the specified transport
|
|
309
|
+
"""
|
|
310
|
+
|
|
311
|
+
if transport in ("streamable-http", "http"):
|
|
312
|
+
return create_streamable_http_app(
|
|
313
|
+
server=self,
|
|
314
|
+
streamable_http_path=path
|
|
315
|
+
or self._deprecated_settings.streamable_http_path,
|
|
316
|
+
event_store=event_store,
|
|
317
|
+
retry_interval=retry_interval,
|
|
318
|
+
auth=self.auth,
|
|
319
|
+
json_response=(
|
|
320
|
+
json_response
|
|
321
|
+
if json_response is not None
|
|
322
|
+
else self._deprecated_settings.json_response
|
|
323
|
+
),
|
|
324
|
+
stateless_http=(
|
|
325
|
+
stateless_http
|
|
326
|
+
if stateless_http is not None
|
|
327
|
+
else self._deprecated_settings.stateless_http
|
|
328
|
+
),
|
|
329
|
+
debug=self._deprecated_settings.debug,
|
|
330
|
+
middleware=middleware,
|
|
331
|
+
)
|
|
332
|
+
elif transport == "sse":
|
|
333
|
+
return create_sse_app(
|
|
334
|
+
server=self,
|
|
335
|
+
message_path=self._deprecated_settings.message_path,
|
|
336
|
+
sse_path=path or self._deprecated_settings.sse_path,
|
|
337
|
+
auth=self.auth,
|
|
338
|
+
debug=self._deprecated_settings.debug,
|
|
339
|
+
middleware=middleware,
|
|
340
|
+
)
|
|
341
|
+
else:
|
|
342
|
+
raise ValueError(f"Unknown transport: {transport}")
|
|
@@ -1,35 +1,55 @@
|
|
|
1
|
-
"""OpenAPI server implementation for FastMCP
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
from .server
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
"""OpenAPI server implementation for FastMCP.
|
|
2
|
+
|
|
3
|
+
.. deprecated::
|
|
4
|
+
This module is deprecated. Import from fastmcp.server.providers.openapi instead.
|
|
5
|
+
|
|
6
|
+
The recommended approach is to use OpenAPIProvider with FastMCP:
|
|
7
|
+
|
|
8
|
+
from fastmcp import FastMCP
|
|
9
|
+
from fastmcp.server.providers.openapi import OpenAPIProvider
|
|
10
|
+
import httpx
|
|
11
|
+
|
|
12
|
+
client = httpx.AsyncClient(base_url="https://api.example.com")
|
|
13
|
+
provider = OpenAPIProvider(openapi_spec=spec, client=client)
|
|
14
|
+
|
|
15
|
+
mcp = FastMCP("My API Server")
|
|
16
|
+
mcp.add_provider(provider)
|
|
17
|
+
|
|
18
|
+
FastMCPOpenAPI is still available but deprecated.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
import warnings
|
|
22
|
+
|
|
23
|
+
warnings.warn(
|
|
24
|
+
"fastmcp.server.openapi is deprecated. "
|
|
25
|
+
"Import from fastmcp.server.providers.openapi instead.",
|
|
26
|
+
DeprecationWarning,
|
|
27
|
+
stacklevel=2,
|
|
14
28
|
)
|
|
15
29
|
|
|
16
|
-
#
|
|
17
|
-
from .
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
30
|
+
# Re-export from new canonical location
|
|
31
|
+
from fastmcp.server.providers.openapi import ( # noqa: E402
|
|
32
|
+
ComponentFn as ComponentFn,
|
|
33
|
+
MCPType as MCPType,
|
|
34
|
+
OpenAPIProvider as OpenAPIProvider,
|
|
35
|
+
OpenAPIResource as OpenAPIResource,
|
|
36
|
+
OpenAPIResourceTemplate as OpenAPIResourceTemplate,
|
|
37
|
+
OpenAPITool as OpenAPITool,
|
|
38
|
+
RouteMap as RouteMap,
|
|
39
|
+
RouteMapFn as RouteMapFn,
|
|
21
40
|
)
|
|
22
41
|
|
|
23
|
-
#
|
|
42
|
+
# Keep FastMCPOpenAPI for backwards compat (it has its own deprecation warning)
|
|
43
|
+
from fastmcp.server.openapi.server import FastMCPOpenAPI as FastMCPOpenAPI # noqa: E402
|
|
44
|
+
|
|
24
45
|
__all__ = [
|
|
25
|
-
"DEFAULT_ROUTE_MAPPINGS",
|
|
26
46
|
"ComponentFn",
|
|
27
47
|
"FastMCPOpenAPI",
|
|
28
48
|
"MCPType",
|
|
49
|
+
"OpenAPIProvider",
|
|
29
50
|
"OpenAPIResource",
|
|
30
51
|
"OpenAPIResourceTemplate",
|
|
31
52
|
"OpenAPITool",
|
|
32
53
|
"RouteMap",
|
|
33
54
|
"RouteMapFn",
|
|
34
|
-
"_determine_route_type",
|
|
35
55
|
]
|