-
Notifications
You must be signed in to change notification settings - Fork 4
task: Changes required for FastMCP v3.x #425
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Prepare the MCP integration code for FastMCP v3.x API changes (mount namespacing and async tool listing) ahead of switching the dependency in pyproject.toml.
Changes:
- Update
mcp.mount(..., prefix=...)tomcp.mount(..., namespace=...). - Replace
get_tools()(dict) withlist_tools()(list) and adjust tool formatting output. - Update docstrings/comments to reflect the new FastMCP API terminology.
| seen_names.add(server.name) | ||
| logger.info(f"Mounting MCP server: {server.name}") | ||
| mcp.mount(server, prefix=server.name) | ||
| mcp.mount(server, namespace=server.name) |
Copilot
AI
Feb 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
namespace on mount() and list_tools() are FastMCP v3.x API calls; if this PR lands before the dependency is bumped to v3.x, this will raise at runtime (unexpected keyword argument / missing attribute). To make this change safe (and keep CI green) until pyproject.toml is updated, consider supporting both APIs via capability detection (e.g., try namespace then fallback to prefix, and try list_tools() then fallback to get_tools()).
| # lazily initialize resources. We use asyncio.run() to bridge sync/async. | ||
| tools = asyncio.run(server.get_tools()) | ||
| return [{"name": name, "description": tool.description or ""} for name, tool in tools.items()] | ||
| tools = asyncio.run(server.list_tools()) |
Copilot
AI
Feb 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
namespace on mount() and list_tools() are FastMCP v3.x API calls; if this PR lands before the dependency is bumped to v3.x, this will raise at runtime (unexpected keyword argument / missing attribute). To make this change safe (and keep CI green) until pyproject.toml is updated, consider supporting both APIs via capability detection (e.g., try namespace then fallback to prefix, and try list_tools() then fallback to get_tools()).
| tools = asyncio.run(server.get_tools()) | ||
| return [{"name": name, "description": tool.description or ""} for name, tool in tools.items()] | ||
| tools = asyncio.run(server.list_tools()) | ||
| return [{"name": tool.name, "description": tool.description or ""} for tool in tools] |
Copilot
AI
Feb 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
list_tools() returning a list can make output ordering depend on server/tool registration order, which may be non-deterministic across environments and can cause flaky CLI output/tests. Consider sorting the returned tools by tool.name before formatting the list so mcp_list_tools() has stable output.
| return [{"name": tool.name, "description": tool.description or ""} for tool in tools] | |
| # Sort tools by name to ensure deterministic output order across environments | |
| sorted_tools = sorted(tools, key=lambda tool: tool.name) | |
| return [{"name": tool.name, "description": tool.description or ""} for tool in sorted_tools] |
| tools = asyncio.run(server.list_tools()) | ||
| return [{"name": tool.name, "description": tool.description or ""} for tool in tools] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Tests in mcp_test.py use the outdated FastMCP v2 API (get_tools()), while production code uses the new v3 API (list_tools()), guaranteeing future test failures.
Severity: CRITICAL
Suggested Fix
Update the test file tests/aignostics/utils/mcp_test.py to use the new FastMCP v3.x API. Replace calls to server.get_tools() with server.list_tools(). Update the test logic to handle a list of Tool objects instead of a dictionary, accessing tool names via the tool.name attribute.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: src/aignostics/utils/_mcp.py#L120-L121
Potential issue: The production code was updated to use the FastMCP v3.x API,
specifically changing from `server.get_tools()` to `server.list_tools()`. However, the
corresponding test file, `tests/aignostics/utils/mcp_test.py`, was not updated. It still
calls the old `get_tools()` method and expects a dictionary, while the new
`list_tools()` method returns a list of `Tool` objects. When the FastMCP dependency is
updated to v3.x as intended for this pull request, the tests will fail with an
`AttributeError`, blocking deployment.
Did we get this right? 👍 / 👎 to inform future reviews.
❌ 6 Tests Failed:
View the full list of 6 ❄️ flaky test(s)
To view more test analytics, go to the Test Analytics Dashboard |
|



Merge when FastMCP releases a v3.x to PyPI and we switch to that in the
pyproject.toml