Jeremiah Lowin commited on
Commit
411d72c
·
2 Parent(s): 8c95b712eb93f5

Merge branch 'decorators' of https://github.com/jlowin/fastmcp into decorators

Browse files
Files changed (4) hide show
  1. docs/docs.json +1 -1
  2. pyproject.toml +3 -1
  3. src/fastmcp/client/transports.py +13 -4
  4. uv.lock +6 -1
docs/docs.json CHANGED
@@ -12,7 +12,7 @@
12
  "decoration": "windows"
13
  },
14
  "banner": {
15
- "content": "FastMCP Cloud is coming. [Claim your server](https://fastmcp.link/x0Kyhy2) today!"
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 = ">=14.0" },
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 = [