Swap public/private method naming in Provider#2902
Conversation
…ce_templates methods
WalkthroughThis PR renames and rebinds provider and server list/get methods between public and underscore-prefixed forms across the provider stack (base, aggregate, fastmcp_provider, filesystem, local, openapi, proxy, server). Authorization middleware was updated to call the FastMCP public getters ( Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
src/fastmcp/server/providers/base.py (1)
12-26: Docstring example uses old naming convention.The example shows overriding
list_toolsandget_tool(public methods), but after this PR, providers should override_list_toolsand_get_tool(private methods). The public methods in the base class now apply transforms, so overriding them would bypass the transform chain.📝 Suggested fix
class DatabaseProvider(Provider): def __init__(self, db_url: str): super().__init__() self.db = Database(db_url) - async def list_tools(self) -> list[Tool]: + async def _list_tools(self) -> list[Tool]: rows = await self.db.fetch("SELECT * FROM tools") return [self._make_tool(row) for row in rows] - async def get_tool(self, name: str) -> Tool | None: + async def _get_tool(self, name: str) -> Tool | None: row = await self.db.fetchone("SELECT * FROM tools WHERE name = ?", name) return self._make_tool(row) if row else Nonesrc/fastmcp/server/server.py (3)
1226-1277: Minor: Comment at line 1277 appears reversed.The comment says
_get_resource is inherited from Provider - wraps get_resource() with transforms, but the relationship is the opposite:get_resource()(public) wraps_get_resource()(private) with transforms.📝 Suggested fix
- # _get_resource is inherited from Provider - wraps get_resource() with transforms + # get_resource is inherited from Provider - wraps _get_resource() with transforms
1327-1378: Minor: Comment at line 1378 appears reversed.Same issue as line 1277 - the public method wraps the private method, not vice versa.
📝 Suggested fix
- # _get_resource_template is inherited from Provider - wraps get_resource_template() with transforms + # get_resource_template is inherited from Provider - wraps _get_resource_template() with transforms
1424-1475: Minor: Comment at line 1475 appears reversed.Same issue - the public method wraps the private method.
📝 Suggested fix
- # _get_prompt is inherited from Provider - wraps get_prompt() with transforms + # get_prompt is inherited from Provider - wraps _get_prompt() with transforms
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
src/fastmcp/server/server.py (3)
1557-1564: Update stale comment to reference get_tool.The inline note still mentions _get_tool, but get_tool is now the transform-aware entry point.
✏️ Proposed comment fix
- # Use _get_tool to apply transforms (including visibility) + # Use get_tool to apply transforms (including visibility)
1668-1691: Update comment to match get_resource usage.The comment references _get_resource, but the code now calls get_resource.
✏️ Proposed comment fix
- # Try concrete resources first (transforms + auth via _get_resource) + # Try concrete resources first (transforms + auth via get_resource)
1789-1796: Update comment to reference get_prompt.The note still points to _get_prompt after the API swap.
✏️ Proposed comment fix
- # Use _get_prompt to apply transforms (including visibility) + # Use get_prompt to apply transforms (including visibility)
Test Failure AnalysisSummary: The test Root Cause: The authorization middleware was changed to call the public Impact:
The test
But now it sees:
Suggested Solution: Revert the authorization middleware changes to call the private methods ( Update Detailed AnalysisTest Failure LogThe test configured rate limiting with Code EvidenceFrom async def _get_tool(
self, name: str, version: VersionSpec | None = None
) -> Tool | None:
tools = await self._list_tools() # ← This triggers list_tools through middleware!
matching = [t for t in tools if t.name == name]
...When authorization middleware calls the public Other Tests Show Awareness of list_tools CallsLine 400 comment in the same test file: burst_capacity=4, # init + list_tools + call + list_tools = 4, so 2nd call failsThis shows developers were already accounting for extra Related Files
|
This reverses the public/private naming convention for Provider methods to match user expectations:
Before: Public methods (
list_tools,get_tool) were overridden by providers; private methods (_list_tools,_get_tool) applied transforms.After: Private methods are overridden by providers to supply raw components; public methods apply transforms and are what users call.
This makes far more sense ergonomically—users call
provider.list_tools()and get transforms applied automatically. Provider implementers override_list_tools()to supply raw data.The call chain is now:
Provider.list_tools()→ builds transform chain →_list_tools()FastMCP._list_tools()→ aggregates viap.list_tools()on sub-providerslist_tools()→ transforms →_list_tools()