fastmcp 2.3.4__py3-none-any.whl → 2.3.5__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastmcp
3
- Version: 2.3.4
3
+ Version: 2.3.5
4
4
  Summary: The fast, Pythonic way to build MCP servers.
5
5
  Project-URL: Homepage, https://gofastmcp.com
6
6
  Project-URL: Repository, https://github.com/jlowin/fastmcp
@@ -19,7 +19,7 @@ Classifier: Typing :: Typed
19
19
  Requires-Python: >=3.10
20
20
  Requires-Dist: exceptiongroup>=1.2.2
21
21
  Requires-Dist: httpx>=0.28.1
22
- Requires-Dist: mcp<2.0.0,>=1.8.1
22
+ Requires-Dist: mcp<2.0.0,>=1.9.0
23
23
  Requires-Dist: openapi-pydantic>=0.5.1
24
24
  Requires-Dist: python-dotenv>=1.1.0
25
25
  Requires-Dist: rich>=13.9.4
@@ -290,7 +290,7 @@ FastMCP introduces powerful ways to structure and deploy your MCP applications.
290
290
 
291
291
  ### Proxy Servers
292
292
 
293
- Create a FastMCP server that acts as an intermediary for another local or remote MCP server using `FastMCP.from_client()`. This is especially useful for bridging transports (e.g., remote SSE to local Stdio) or adding a layer of logic to a server you don't control.
293
+ Create a FastMCP server that acts as an intermediary for another local or remote MCP server using `FastMCP.as_proxy()`. This is especially useful for bridging transports (e.g., remote SSE to local Stdio) or adding a layer of logic to a server you don't control.
294
294
 
295
295
  Learn more in the [**Proxying Documentation**](https://gofastmcp.com/patterns/proxy).
296
296
 
@@ -4,14 +4,16 @@ fastmcp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  fastmcp/settings.py,sha256=Slo7sRSbXblgmTQcRSee6ns6CsW2yW-TvBY--kAhJqg,3856
5
5
  fastmcp/cli/__init__.py,sha256=Ii284TNoG5lxTP40ETMGhHEq3lQZWxu9m9JuU57kUpQ,87
6
6
  fastmcp/cli/claude.py,sha256=IAlcZ4qZKBBj09jZUMEx7EANZE_IR3vcu7zOBJmMOuU,4567
7
- fastmcp/cli/cli.py,sha256=Tb-WiIXFZiq4nqlZ6LMXN2iYY30clC4Om_gP89HbJcE,15641
7
+ fastmcp/cli/cli.py,sha256=eRZ4tpne7dj_rhjREwiNRN5i9A1T8-ptxg1lYaHfS5o,12401
8
+ fastmcp/cli/run.py,sha256=o7Ge6JZKXYwlY2vYdMNoVX8agBchAaeU_73iPndojIM,5351
8
9
  fastmcp/client/__init__.py,sha256=Ri8GFHolIKOZnXaMzIc3VpkLcEqAmOoYGCKgmSk6NnE,550
9
10
  fastmcp/client/base.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- fastmcp/client/client.py,sha256=EOS6_2zd9zWxhCN_cY6cAiqGmCSWMX1t3g6PxemjTtw,17982
11
- fastmcp/client/logging.py,sha256=Q8jYcZj4KA15Yiz3RP8tBXj8sd9IxL3VThF_Y0O4Upc,356
11
+ fastmcp/client/client.py,sha256=qUbL3sbZOzSOTyKo7inKX6XbZaZQtEYBR8e7pHfBdhQ,19675
12
+ fastmcp/client/logging.py,sha256=GbI2_BIQgITR1YmqDzHnEJ4s3vFu_oe4Mva22N0RXO4,542
13
+ fastmcp/client/progress.py,sha256=WjLLDbUKMsx8DK-fqO7AGsXb83ak-6BMrLvzzznGmcI,1043
12
14
  fastmcp/client/roots.py,sha256=IxI_bHwHTmg6c2H-s1av1ZgrRnNDieHtYwdGFbzXT5c,2471
13
15
  fastmcp/client/sampling.py,sha256=UlDHxnd6k_HoU8RA3ob0g8-e6haJBc9u27N_v291QoI,1698
14
- fastmcp/client/transports.py,sha256=30SubI-fgrqVknyPlySVJ7sGkOMAjm8CP-Owrb8gu58,19704
16
+ fastmcp/client/transports.py,sha256=w2ELDN9UO3c1yC3Vuzq0WI9syLUc20u389-XMwUoX5Y,19320
15
17
  fastmcp/contrib/README.md,sha256=rKknYSI1T192UvSszqwwDlQ2eYQpxywrNTLoj177SYU,878
16
18
  fastmcp/contrib/bulk_tool_caller/README.md,sha256=5aUUY1TSFKtz1pvTLSDqkUCkGkuqMfMZNsLeaNqEgAc,1960
17
19
  fastmcp/contrib/bulk_tool_caller/__init__.py,sha256=xvGSSaUXTQrc31erBoi1Gh7BikgOliETDiYVTP3rLxY,75
@@ -23,7 +25,6 @@ fastmcp/contrib/mcp_mixin/example.py,sha256=GnunkXmtG5hLLTUsM8aW5ZURU52Z8vI4tNLl
23
25
  fastmcp/contrib/mcp_mixin/mcp_mixin.py,sha256=cfIRbnSxsVzglTD-auyTE0izVQeHP7Oz18qzYoBZJgg,7899
24
26
  fastmcp/low_level/README.md,sha256=IRvElvOOc_RLLsqbUm7e6VOEwrKHPJeox0pV7JVKHWw,106
25
27
  fastmcp/low_level/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
- fastmcp/low_level/sse_server_transport.py,sha256=pUG3AL4Wjf9LgH9fj1l3emGEjFDFDhmKcDfgiiFJcuQ,4448
27
28
  fastmcp/prompts/__init__.py,sha256=An8uMBUh9Hrb7qqcn_5_Hent7IOeSh7EA2IUVsIrtHc,179
28
29
  fastmcp/prompts/prompt.py,sha256=CGu11NbOvO0b79F3EDCG7YbajGslpoPu59VOEzanIp0,7968
29
30
  fastmcp/prompts/prompt_manager.py,sha256=9VcioLE-AoUKe1e9SynNQME9SvWy0q1QAvO1ewIWVmI,3126
@@ -33,12 +34,12 @@ fastmcp/resources/resource_manager.py,sha256=aJFbn1-Rc-oMahp3SSWNJXJEu8Nxu-gc24i
33
34
  fastmcp/resources/template.py,sha256=ex1s2kBQmGUU1zQ-b__egyJoNlNNKI42JALO0uxxAaE,7408
34
35
  fastmcp/resources/types.py,sha256=5fUFvzRlekNjtfihtq8S-fT0alKoNfclzrugqeM5JRE,6366
35
36
  fastmcp/server/__init__.py,sha256=bMD4aQD4yJqLz7-mudoNsyeV8UgQfRAg3PRwPvwTEds,119
36
- fastmcp/server/context.py,sha256=ykitQygA7zT5prbFTLCuYlnAzuljf_9ErUT0FYBPv3E,8135
37
+ fastmcp/server/context.py,sha256=obOTozUq6xwe2oNn6VQ6F4mwWGEonF5A0emi7jo1J8k,8231
37
38
  fastmcp/server/dependencies.py,sha256=1utkxFsV37HZcWBwI69JyngVN2ppGO_PEgxUlUHHy_Q,742
38
- fastmcp/server/http.py,sha256=utl7vJkMvKUnKIflCptVWk1oqOi7_sJJHqUl22g4JC8,10473
39
+ fastmcp/server/http.py,sha256=q0oATZ7TBN11DqFT_AoyH5gvgAvz4COXDlf73t3rcb4,11317
39
40
  fastmcp/server/openapi.py,sha256=_7U0XtPk4wCkGOBfYx3J3ujA9iqQtnsc0scA4sCsIT0,24170
40
41
  fastmcp/server/proxy.py,sha256=mt3eM6TQWfnZD5XehmTXisskZ4CBbsWyjRPjprlTjBY,9653
41
- fastmcp/server/server.py,sha256=EM5BqwXRlG73sMZg6186yMVKfXYGn5gT4qqAxfNa8lU,45454
42
+ fastmcp/server/server.py,sha256=LM5zb6as2DT_lFY1tB4b89rNAbyv-tQiU2xNeDC8f4E,46933
42
43
  fastmcp/tools/__init__.py,sha256=ocw-SFTtN6vQ8fgnlF8iNAOflRmh79xS1xdO0Bc3QPE,96
43
44
  fastmcp/tools/tool.py,sha256=k7awnrPoId_1XJHFce7X3mAEgBsJyr2v5kuuxXrE5Ww,7602
44
45
  fastmcp/tools/tool_manager.py,sha256=v4Ur-JXDPXUxHqHJxA52IIcZfSiCBOnoFFLOmmJR1A8,4157
@@ -51,8 +52,8 @@ fastmcp/utilities/logging.py,sha256=n4P7P-aFDCuUFz8O-ykzUOj2sXl789HtWI_pX3ynGaY,
51
52
  fastmcp/utilities/openapi.py,sha256=V3hANT6KcD_Bloq9uHDVkVJRcGaZIq8GH5ZZ7bKVmXY,56943
52
53
  fastmcp/utilities/tests.py,sha256=mAV2EjDeCbm9V9NsVIUjcmzf93MgDjfj8kMvHpf4vgo,3224
53
54
  fastmcp/utilities/types.py,sha256=6CcqAQ1QqCO2HGSFlPS6FO5JRWnacjCcO2-EhyEnZV0,4400
54
- fastmcp-2.3.4.dist-info/METADATA,sha256=9uZJ9YUNRVnoD6oFmDatjuiaQn8GAWt9XKzqagsngyQ,15754
55
- fastmcp-2.3.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
56
- fastmcp-2.3.4.dist-info/entry_points.txt,sha256=ff8bMtKX1JvXyurMibAacMSKbJEPmac9ffAKU9mLnM8,44
57
- fastmcp-2.3.4.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
58
- fastmcp-2.3.4.dist-info/RECORD,,
55
+ fastmcp-2.3.5.dist-info/METADATA,sha256=G6eYJAsY7YIpIq6EOmjP1bihF3evF9Tb5wy9ZncSxRg,15751
56
+ fastmcp-2.3.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
57
+ fastmcp-2.3.5.dist-info/entry_points.txt,sha256=ff8bMtKX1JvXyurMibAacMSKbJEPmac9ffAKU9mLnM8,44
58
+ fastmcp-2.3.5.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
59
+ fastmcp-2.3.5.dist-info/RECORD,,
@@ -1,104 +0,0 @@
1
- import logging
2
- from contextlib import asynccontextmanager
3
- from typing import Any
4
- from urllib.parse import quote
5
- from uuid import uuid4
6
-
7
- import anyio
8
- from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream
9
- from mcp.server.sse import SseServerTransport as LowLevelSSEServerTransport
10
- from mcp.shared.message import SessionMessage
11
- from sse_starlette import EventSourceResponse
12
- from starlette.types import Receive, Scope, Send
13
-
14
- logger = logging.getLogger(__name__)
15
-
16
-
17
- class SseServerTransport(LowLevelSSEServerTransport):
18
- """
19
- Patched SSE server transport
20
- """
21
-
22
- @asynccontextmanager
23
- async def connect_sse(self, scope: Scope, receive: Receive, send: Send):
24
- """
25
- See https://github.com/modelcontextprotocol/python-sdk/pull/659/
26
- """
27
- if scope["type"] != "http":
28
- logger.error("connect_sse received non-HTTP request")
29
- raise ValueError("connect_sse can only handle HTTP requests")
30
-
31
- logger.debug("Setting up SSE connection")
32
- read_stream: MemoryObjectReceiveStream[SessionMessage | Exception]
33
- read_stream_writer: MemoryObjectSendStream[SessionMessage | Exception]
34
-
35
- write_stream: MemoryObjectSendStream[SessionMessage]
36
- write_stream_reader: MemoryObjectReceiveStream[SessionMessage]
37
-
38
- read_stream_writer, read_stream = anyio.create_memory_object_stream(0)
39
- write_stream, write_stream_reader = anyio.create_memory_object_stream(0)
40
-
41
- session_id = uuid4()
42
- self._read_stream_writers[session_id] = read_stream_writer
43
- logger.debug(f"Created new session with ID: {session_id}")
44
-
45
- # Determine the full path for the message endpoint to be sent to the client.
46
- # scope['root_path'] is the prefix where the current Starlette app
47
- # instance is mounted.
48
- # e.g., "" if top-level, or "/api_prefix" if mounted under "/api_prefix".
49
- root_path = scope.get("root_path", "")
50
-
51
- # self._endpoint is the path *within* this app, e.g., "/messages".
52
- # Concatenating them gives the full absolute path from the server root.
53
- # e.g., "" + "/messages" -> "/messages"
54
- # e.g., "/api_prefix" + "/messages" -> "/api_prefix/messages"
55
- full_message_path_for_client = root_path.rstrip("/") + self._endpoint
56
-
57
- # This is the URI (path + query) the client will use to POST messages.
58
- client_post_uri_data = (
59
- f"{quote(full_message_path_for_client)}?session_id={session_id.hex}"
60
- )
61
-
62
- sse_stream_writer, sse_stream_reader = anyio.create_memory_object_stream[
63
- dict[str, Any]
64
- ](0)
65
-
66
- async def sse_writer():
67
- logger.debug("Starting SSE writer")
68
- async with sse_stream_writer, write_stream_reader:
69
- await sse_stream_writer.send(
70
- {"event": "endpoint", "data": client_post_uri_data}
71
- )
72
- logger.debug(f"Sent endpoint event: {client_post_uri_data}")
73
-
74
- async for session_message in write_stream_reader:
75
- logger.debug(f"Sending message via SSE: {session_message}")
76
- await sse_stream_writer.send(
77
- {
78
- "event": "message",
79
- "data": session_message.message.model_dump_json(
80
- by_alias=True, exclude_none=True
81
- ),
82
- }
83
- )
84
-
85
- async with anyio.create_task_group() as tg:
86
-
87
- async def response_wrapper(scope: Scope, receive: Receive, send: Send):
88
- """
89
- The EventSourceResponse returning signals a client close / disconnect.
90
- In this case we close our side of the streams to signal the client that
91
- the connection has been closed.
92
- """
93
- await EventSourceResponse(
94
- content=sse_stream_reader, data_sender_callable=sse_writer
95
- )(scope, receive, send)
96
- await read_stream_writer.aclose()
97
- await write_stream_reader.aclose()
98
- logging.debug(f"Client session disconnected {session_id}")
99
-
100
- logger.debug("Starting SSE response task")
101
- tg.start_soon(response_wrapper, scope, receive, send)
102
-
103
- logger.debug("Yielding read and write streams")
104
- yield (read_stream, write_stream)