Spaces:
Running
Running
Merge branch 'decorators' of https://github.com/jlowin/fastmcp into decorators
Browse files- docs/docs.json +1 -1
- pyproject.toml +3 -1
- src/fastmcp/client/transports.py +13 -4
- uv.lock +6 -1
docs/docs.json
CHANGED
|
@@ -12,7 +12,7 @@
|
|
| 12 |
"decoration": "windows"
|
| 13 |
},
|
| 14 |
"banner": {
|
| 15 |
-
"content": "FastMCP Cloud
|
| 16 |
},
|
| 17 |
"colors": {
|
| 18 |
"dark": "#f72585",
|
|
|
|
| 12 |
"decoration": "windows"
|
| 13 |
},
|
| 14 |
"banner": {
|
| 15 |
+
"content": "[FastMCP Cloud](https://fastmcp.link/x0Kyhy2) is coming!"
|
| 16 |
},
|
| 17 |
"colors": {
|
| 18 |
"dark": "#f72585",
|
pyproject.toml
CHANGED
|
@@ -11,7 +11,6 @@ dependencies = [
|
|
| 11 |
"openapi-pydantic>=0.5.1",
|
| 12 |
"rich>=13.9.4",
|
| 13 |
"typer>=0.15.2",
|
| 14 |
-
"websockets>=14.0",
|
| 15 |
"authlib>=1.5.2",
|
| 16 |
]
|
| 17 |
requires-python = ">=3.10"
|
|
@@ -67,6 +66,9 @@ Homepage = "https://gofastmcp.com"
|
|
| 67 |
Repository = "https://github.com/jlowin/fastmcp"
|
| 68 |
Documentation = "https://gofastmcp.com"
|
| 69 |
|
|
|
|
|
|
|
|
|
|
| 70 |
|
| 71 |
[build-system]
|
| 72 |
requires = ["hatchling", "uv-dynamic-versioning>=0.7.0"]
|
|
|
|
| 11 |
"openapi-pydantic>=0.5.1",
|
| 12 |
"rich>=13.9.4",
|
| 13 |
"typer>=0.15.2",
|
|
|
|
| 14 |
"authlib>=1.5.2",
|
| 15 |
]
|
| 16 |
requires-python = ">=3.10"
|
|
|
|
| 66 |
Repository = "https://github.com/jlowin/fastmcp"
|
| 67 |
Documentation = "https://gofastmcp.com"
|
| 68 |
|
| 69 |
+
[project.optional-dependencies]
|
| 70 |
+
websockets = ["websockets>=15.0.1"]
|
| 71 |
+
|
| 72 |
|
| 73 |
[build-system]
|
| 74 |
requires = ["hatchling", "uv-dynamic-versioning>=0.7.0"]
|
src/fastmcp/client/transports.py
CHANGED
|
@@ -27,10 +27,6 @@ from mcp.client.session import (
|
|
| 27 |
MessageHandlerFnT,
|
| 28 |
SamplingFnT,
|
| 29 |
)
|
| 30 |
-
from mcp.client.sse import sse_client
|
| 31 |
-
from mcp.client.stdio import stdio_client
|
| 32 |
-
from mcp.client.streamable_http import streamablehttp_client
|
| 33 |
-
from mcp.client.websocket import websocket_client
|
| 34 |
from mcp.server.fastmcp import FastMCP as FastMCP1Server
|
| 35 |
from mcp.shared.memory import create_connected_server_and_client_session
|
| 36 |
from pydantic import AnyUrl
|
|
@@ -141,6 +137,13 @@ class WSTransport(ClientTransport):
|
|
| 141 |
async def connect_session(
|
| 142 |
self, **session_kwargs: Unpack[SessionKwargs]
|
| 143 |
) -> AsyncIterator[ClientSession]:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 144 |
async with websocket_client(self.url) as transport:
|
| 145 |
read_stream, write_stream = transport
|
| 146 |
async with ClientSession(
|
|
@@ -188,6 +191,8 @@ class SSETransport(ClientTransport):
|
|
| 188 |
async def connect_session(
|
| 189 |
self, **session_kwargs: Unpack[SessionKwargs]
|
| 190 |
) -> AsyncIterator[ClientSession]:
|
|
|
|
|
|
|
| 191 |
client_kwargs: dict[str, Any] = {}
|
| 192 |
|
| 193 |
# load headers from an active HTTP request, if available. This will only be true
|
|
@@ -255,6 +260,8 @@ class StreamableHttpTransport(ClientTransport):
|
|
| 255 |
async def connect_session(
|
| 256 |
self, **session_kwargs: Unpack[SessionKwargs]
|
| 257 |
) -> AsyncIterator[ClientSession]:
|
|
|
|
|
|
|
| 258 |
client_kwargs: dict[str, Any] = {}
|
| 259 |
|
| 260 |
# load headers from an active HTTP request, if available. This will only be true
|
|
@@ -350,6 +357,8 @@ class StdioTransport(ClientTransport):
|
|
| 350 |
return
|
| 351 |
|
| 352 |
async def _connect_task():
|
|
|
|
|
|
|
| 353 |
async with contextlib.AsyncExitStack() as stack:
|
| 354 |
try:
|
| 355 |
server_params = StdioServerParameters(
|
|
|
|
| 27 |
MessageHandlerFnT,
|
| 28 |
SamplingFnT,
|
| 29 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
from mcp.server.fastmcp import FastMCP as FastMCP1Server
|
| 31 |
from mcp.shared.memory import create_connected_server_and_client_session
|
| 32 |
from pydantic import AnyUrl
|
|
|
|
| 137 |
async def connect_session(
|
| 138 |
self, **session_kwargs: Unpack[SessionKwargs]
|
| 139 |
) -> AsyncIterator[ClientSession]:
|
| 140 |
+
try:
|
| 141 |
+
from mcp.client.websocket import websocket_client
|
| 142 |
+
except ImportError:
|
| 143 |
+
raise ImportError(
|
| 144 |
+
"The websocket transport is not available. Please install fastmcp[websockets] or install the websockets package manually."
|
| 145 |
+
)
|
| 146 |
+
|
| 147 |
async with websocket_client(self.url) as transport:
|
| 148 |
read_stream, write_stream = transport
|
| 149 |
async with ClientSession(
|
|
|
|
| 191 |
async def connect_session(
|
| 192 |
self, **session_kwargs: Unpack[SessionKwargs]
|
| 193 |
) -> AsyncIterator[ClientSession]:
|
| 194 |
+
from mcp.client.sse import sse_client
|
| 195 |
+
|
| 196 |
client_kwargs: dict[str, Any] = {}
|
| 197 |
|
| 198 |
# load headers from an active HTTP request, if available. This will only be true
|
|
|
|
| 260 |
async def connect_session(
|
| 261 |
self, **session_kwargs: Unpack[SessionKwargs]
|
| 262 |
) -> AsyncIterator[ClientSession]:
|
| 263 |
+
from mcp.client.streamable_http import streamablehttp_client
|
| 264 |
+
|
| 265 |
client_kwargs: dict[str, Any] = {}
|
| 266 |
|
| 267 |
# load headers from an active HTTP request, if available. This will only be true
|
|
|
|
| 357 |
return
|
| 358 |
|
| 359 |
async def _connect_task():
|
| 360 |
+
from mcp.client.stdio import stdio_client
|
| 361 |
+
|
| 362 |
async with contextlib.AsyncExitStack() as stack:
|
| 363 |
try:
|
| 364 |
server_params = StdioServerParameters(
|
uv.lock
CHANGED
|
@@ -437,6 +437,10 @@ dependencies = [
|
|
| 437 |
{ name = "python-dotenv" },
|
| 438 |
{ name = "rich" },
|
| 439 |
{ name = "typer" },
|
|
|
|
|
|
|
|
|
|
|
|
|
| 440 |
{ name = "websockets" },
|
| 441 |
]
|
| 442 |
|
|
@@ -473,8 +477,9 @@ requires-dist = [
|
|
| 473 |
{ name = "python-dotenv", specifier = ">=1.1.0" },
|
| 474 |
{ name = "rich", specifier = ">=13.9.4" },
|
| 475 |
{ name = "typer", specifier = ">=0.15.2" },
|
| 476 |
-
{ name = "websockets", specifier = ">=
|
| 477 |
]
|
|
|
|
| 478 |
|
| 479 |
[package.metadata.requires-dev]
|
| 480 |
dev = [
|
|
|
|
| 437 |
{ name = "python-dotenv" },
|
| 438 |
{ name = "rich" },
|
| 439 |
{ name = "typer" },
|
| 440 |
+
]
|
| 441 |
+
|
| 442 |
+
[package.optional-dependencies]
|
| 443 |
+
websockets = [
|
| 444 |
{ name = "websockets" },
|
| 445 |
]
|
| 446 |
|
|
|
|
| 477 |
{ name = "python-dotenv", specifier = ">=1.1.0" },
|
| 478 |
{ name = "rich", specifier = ">=13.9.4" },
|
| 479 |
{ name = "typer", specifier = ">=0.15.2" },
|
| 480 |
+
{ name = "websockets", marker = "extra == 'websockets'", specifier = ">=15.0.1" },
|
| 481 |
]
|
| 482 |
+
provides-extras = ["websockets"]
|
| 483 |
|
| 484 |
[package.metadata.requires-dev]
|
| 485 |
dev = [
|