Skip to content

Commit 2509265

Browse files
chore: Bump FastMCP to v3.x and make the necessary changes to support it (#425)
Co-authored-by: Oliver Meyer <42039965+olivermeyer@users.noreply.github.com>
1 parent d1f565e commit 2509265

5 files changed

Lines changed: 73 additions & 230 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ dependencies = [
125125
"truststore>=0.10.4,<1",
126126
"urllib3>=2.6.3,<3", # CVE-2026-21441 requires >= 2.6.3
127127
"wsidicom>=0.28.1,<1",
128+
"fastmcp>=3.0.0,<4",
128129
# Transitive overrides
129130
# WARNING: one cannot negate or downgrade a dependency required here. use override-dependencies for that.
130131
"rfc3987; sys_platform == 'never'", # GPLv3
@@ -138,7 +139,6 @@ dependencies = [
138139
"lxml>=6.0.2", # For python 3.14 pre-built wheels
139140
"filelock>=3.20.1", # CVE-2025-68146
140141
"marshmallow>=3.26.2", # CVE-2025-68480
141-
"fastmcp>=2.0.0,<3", # MCP server - Major version 3 is in beta as of 26/01/2026 and has not been released on PyPI. Upgrade once a stable release is out.
142142
]
143143

144144
[project.optional-dependencies]

src/aignostics/utils/_mcp.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def mcp_create_server(server_name: str = MCP_SERVER_NAME) -> FastMCP:
5454
5555
Creates a new FastMCP server instance and mounts all discovered MCP servers
5656
from the SDK and plugins. Each mounted server's tools are namespaced
57-
automatically using FastMCP's built-in prefix feature.
57+
automatically using FastMCP's built-in namespace feature.
5858
5959
Args:
6060
server_name: Human-readable name for the MCP server.
@@ -76,7 +76,7 @@ def mcp_create_server(server_name: str = MCP_SERVER_NAME) -> FastMCP:
7676
continue
7777
seen_names.add(server.name)
7878
logger.info(f"Mounting MCP server: {server.name}")
79-
mcp.mount(server, prefix=server.name)
79+
mcp.mount(server, namespace=server.name)
8080
count += 1
8181

8282
logger.info(f"Mounted {count} MCP servers")
@@ -115,7 +115,7 @@ def mcp_list_tools(server_name: str = MCP_SERVER_NAME) -> list[dict[str, Any]]:
115115
'name' and 'description' keys.
116116
"""
117117
server = mcp_create_server(server_name)
118-
# FastMCP's get_tools() is async because mounted servers may need to
118+
# FastMCP's list_tools() is async because mounted servers may need to
119119
# lazily initialize resources. We use asyncio.run() to bridge sync/async.
120-
tools = asyncio.run(server.get_tools())
121-
return [{"name": name, "description": tool.description or ""} for name, tool in tools.items()]
120+
tools = asyncio.run(server.list_tools())
121+
return [{"name": tool.name, "description": tool.description or ""} for tool in tools]

tests/aignostics/utils/mcp_test.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ def plugin2_tool() -> str:
9898
assert isinstance(server, FastMCP)
9999
assert server.name == MCP_SERVER_NAME
100100
# Verify exactly 2 tools from both plugins are mounted with namespacing
101-
tools = asyncio.run(server.get_tools())
102-
tool_names = list(tools.keys())
101+
tools = asyncio.run(server.list_tools())
102+
tool_names = [t.name for t in tools]
103103
assert len(tool_names) == 2
104104
# Verify namespacing: tools should be prefixed with server name
105105
plugin1_tools = [n for n in tool_names if "plugin1" in n]
@@ -139,8 +139,8 @@ def unique_tool() -> str:
139139
# Verify warning was logged for duplicate
140140
assert "Duplicate MCP server name 'duplicate_name'" in caplog.text
141141
# Verify only first duplicate and unique server were mounted (2 servers, not 3)
142-
tools = asyncio.run(server.get_tools())
143-
tool_names = list(tools.keys())
142+
tools = asyncio.run(server.list_tools())
143+
tool_names = [t.name for t in tools]
144144
assert len(tool_names) == 2
145145
# dup1_tool should be present (first occurrence)
146146
assert any("dup1_tool" in name for name in tool_names)

tests/resources/mcp_dummy_plugin/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ name = "mcp-dummy-plugin"
77
version = "0.0.1"
88
description = "Dummy MCP plugin for integration testing of plugin auto-discovery."
99
requires-python = ">=3.11"
10-
dependencies = ["fastmcp>=2.0.0,<3", "typer>=0.12", "aignostics"]
10+
dependencies = ["fastmcp>=3.0.0,<4", "typer>=0.12", "aignostics"]
1111

1212
[project.entry-points."aignostics.plugins"]
1313
mcp_dummy_plugin = "mcp_dummy_plugin"

0 commit comments

Comments
 (0)