mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-22 21:44:18 +02:00
Merge pull request #539 from jlowin/codex/add-support-for-fastmcp-1.0-server
Add FastMCP 1.0 server support for in-memory Client / Testing
This commit is contained in:
commit
e0b84186ed
4 changed files with 35 additions and 14 deletions
|
|
@ -37,7 +37,7 @@ Clients must be initialized with a `transport`. You can either provide an alread
|
|||
The following inference rules are used to determine the appropriate `ClientTransport` based on the input type:
|
||||
|
||||
1. **`ClientTransport` Instance**: If you provide an already instantiated transport object, it's used directly.
|
||||
2. **`FastMCP` Instance**: Creates a `FastMCPTransport` for efficient in-memory communication (ideal for testing).
|
||||
2. **`FastMCP` Instance**: Creates a `FastMCPTransport` for efficient in-memory communication (ideal for testing). This also works with a **FastMCP 1.0 server** created via `mcp.server.fastmcp.FastMCP`.
|
||||
3. **`Path` or `str` pointing to an existing file**:
|
||||
* If it ends with `.py`: Creates a `PythonStdioTransport` to run the script using `python`.
|
||||
* If it ends with `.js`: Creates a `NodeStdioTransport` to run the script using `node`.
|
||||
|
|
|
|||
|
|
@ -290,8 +290,8 @@ asyncio.run(main())
|
|||
### FastMCP Transport
|
||||
|
||||
- **Class:** `fastmcp.client.transports.FastMCPTransport`
|
||||
- **Inferred From:** An instance of `fastmcp.server.FastMCP`
|
||||
- **Use Case:** Connecting directly to a `FastMCP` server instance in the same Python process
|
||||
- **Inferred From:** An instance of `fastmcp.server.FastMCP` or a **FastMCP 1.0 server** (`mcp.server.fastmcp.FastMCP`)
|
||||
- **Use Case:** Connecting directly to a FastMCP server instance in the same Python process
|
||||
|
||||
This is extremely useful for testing your FastMCP servers.
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ from mcp.client.sse import sse_client
|
|||
from mcp.client.stdio import stdio_client
|
||||
from mcp.client.streamable_http import streamablehttp_client
|
||||
from mcp.client.websocket import websocket_client
|
||||
from mcp.server.fastmcp import FastMCP as FastMCP1Server
|
||||
from mcp.shared.memory import create_connected_server_and_client_session
|
||||
from pydantic import AnyUrl
|
||||
from typing_extensions import Unpack
|
||||
|
|
@ -448,15 +449,21 @@ class NpxStdioTransport(StdioTransport):
|
|||
|
||||
|
||||
class FastMCPTransport(ClientTransport):
|
||||
"""
|
||||
Special transport for in-memory connections to an MCP server.
|
||||
"""In-memory transport for FastMCP servers.
|
||||
|
||||
This is particularly useful for testing or when client and server
|
||||
are in the same process.
|
||||
This transport connects directly to a FastMCP server instance in the same
|
||||
Python process. It works with both FastMCP 2.x servers and FastMCP 1.0
|
||||
servers from the low-level MCP SDK. This is particularly useful for unit
|
||||
tests or scenarios where client and server run in the same runtime.
|
||||
"""
|
||||
|
||||
def __init__(self, mcp: FastMCPServer):
|
||||
self.server = mcp # Can be FastMCP or MCPServer
|
||||
def __init__(self, mcp: FastMCPServer | FastMCP1Server):
|
||||
"""Initialize a FastMCPTransport from a FastMCP server instance."""
|
||||
|
||||
# Accept both FastMCP 2.x and FastMCP 1.0 servers. Both expose a
|
||||
# ``_mcp_server`` attribute pointing to the underlying MCP server
|
||||
# implementation, so we can treat them identically.
|
||||
self.server = mcp
|
||||
|
||||
@contextlib.asynccontextmanager
|
||||
async def connect_session(
|
||||
|
|
@ -558,6 +565,7 @@ class MCPConfigTransport(ClientTransport):
|
|||
def infer_transport(
|
||||
transport: ClientTransport
|
||||
| FastMCPServer
|
||||
| FastMCP1Server
|
||||
| AnyUrl
|
||||
| Path
|
||||
| MCPConfig
|
||||
|
|
@ -573,7 +581,7 @@ def infer_transport(
|
|||
|
||||
The function supports these input types:
|
||||
- ClientTransport: Used directly without modification
|
||||
- FastMCPServer: Creates an in-memory FastMCPTransport
|
||||
- FastMCPServer or FastMCP1Server: Creates an in-memory FastMCPTransport
|
||||
- Path or str (file path): Creates PythonStdioTransport (.py) or NodeStdioTransport (.js)
|
||||
- AnyUrl or str (URL): Creates StreamableHttpTransport (default) or SSETransport (for /sse endpoints)
|
||||
- MCPConfig or dict: Creates MCPConfigTransport, potentially connecting to multiple servers
|
||||
|
|
@ -610,8 +618,8 @@ def infer_transport(
|
|||
if isinstance(transport, ClientTransport):
|
||||
return transport
|
||||
|
||||
# the transport is a FastMCP server
|
||||
elif isinstance(transport, FastMCPServer):
|
||||
# the transport is a FastMCP server (2.x or 1.0)
|
||||
elif isinstance(transport, FastMCPServer | FastMCP1Server):
|
||||
inferred_transport = FastMCPTransport(mcp=transport)
|
||||
|
||||
# the transport is a path to a script
|
||||
|
|
|
|||
|
|
@ -673,7 +673,7 @@ class TestInferTransport:
|
|||
assert transport.transport.command == "echo"
|
||||
assert transport.transport.args == ["hello"]
|
||||
|
||||
def test_infer_composite_client(config):
|
||||
def test_infer_composite_client(self):
|
||||
config = {
|
||||
"mcpServers": {
|
||||
"local": {
|
||||
|
|
@ -689,4 +689,17 @@ class TestInferTransport:
|
|||
transport = infer_transport(config)
|
||||
assert isinstance(transport, MCPConfigTransport)
|
||||
assert isinstance(transport.transport, FastMCPTransport)
|
||||
assert len(transport.transport.server._mounted_servers) == 2
|
||||
assert len(cast(FastMCP, transport.transport.server)._mounted_servers) == 2
|
||||
|
||||
def test_infer_fastmcp_server(self, fastmcp_server):
|
||||
"""FastMCP server instances should infer to FastMCPTransport."""
|
||||
transport = infer_transport(fastmcp_server)
|
||||
assert isinstance(transport, FastMCPTransport)
|
||||
|
||||
def test_infer_fastmcp_v1_server(self):
|
||||
"""FastMCP 1.0 server instances should infer to FastMCPTransport."""
|
||||
from mcp.server.fastmcp import FastMCP as FastMCP1
|
||||
|
||||
server = FastMCP1()
|
||||
transport = infer_transport(server)
|
||||
assert isinstance(transport, FastMCPTransport)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue