Update dependencies to latest versions with upper bounds#60
Update dependencies to latest versions with upper bounds#60druvv wants to merge 1 commit intopunitarani:mainfrom
Conversation
Pin all dependencies with upper bounds to prevent breaking major version upgrades. Upgrade fastmcp from >=0.1.0 to >=3.0.0,<4 and remove the custom FliMCP subclass that relied on fastmcp internals (_tool_manager, _mcp_server) which no longer exist in v3. The native FastMCP 3.x API supports tool annotations and prompt decorators directly, so the subclass was replaced with plain FastMCP usage. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
| "curl-cffi>=0.13.0,<1", | ||
| "fastapi>=0.116.0,<1", | ||
| "fastmcp>=3.0.0,<4", | ||
| "httpx>=0.28.1,<1", | ||
| "pandas>=2.3.0,<3", | ||
| "plotext>=5.3.2,<6", | ||
| "pydantic>=2.11.0,<3", | ||
| "python-dotenv>=1.1.0,<2", | ||
| "ratelimit>=2.2.1,<3", | ||
| "tenacity>=9.1.0,<10", | ||
| "typer>=0.16.0,<1", | ||
| "uvicorn>=0.35.0,<1", |
There was a problem hiding this comment.
<1 upper bounds don't protect against within-0.x breaking changes
Several dependencies are still in the 0.x release series (fastapi, uvicorn, typer, httpx, curl-cffi). Per SemVer convention, pre-1.0 packages may introduce breaking changes between minor versions (e.g. 0.116.0 → 0.200.0). The <1 upper bound prevents an upgrade to 1.x, but it still allows any future 0.x release, which could carry breaking changes — the same class of problem this PR is trying to prevent.
The stated motivation is preventing breakage like fastmcp 0.x → 3.x, where <1 would indeed have caught it. For fastapi, uvicorn, typer, etc. however, a stricter compatible-release constraint (e.g. ~=0.116.0 or >=0.116.0,<0.117.0) would fully close that gap. Alternatively, this tradeoff is acceptable if the intent is only to guard against major-series jumps — worth a note in the PR description for future maintainers.
| dependencies = [ | ||
| "curl-cffi>=0.7.4", | ||
| "fastapi>=0.115.6", | ||
| "fastmcp>=0.1.0", | ||
| "httpx>=0.28.1", | ||
| "pandas>=2.2.3", | ||
| "plotext>=5.3.2", | ||
| "pydantic>=2.10.4", | ||
| "python-dotenv>=1.0.1", | ||
| "ratelimit>=2.2.1", | ||
| "tenacity>=9.0.0", | ||
| "typer>=0.15.1", | ||
| "uvicorn>=0.34.0", | ||
| "curl-cffi>=0.13.0,<1", | ||
| "fastapi>=0.116.0,<1", | ||
| "fastmcp>=3.0.0,<4", | ||
| "httpx>=0.28.1,<1", | ||
| "pandas>=2.3.0,<3", | ||
| "plotext>=5.3.2,<6", | ||
| "pydantic>=2.11.0,<3", | ||
| "python-dotenv>=1.1.0,<2", | ||
| "ratelimit>=2.2.1,<3", | ||
| "tenacity>=9.1.0,<10", | ||
| "typer>=0.16.0,<1", | ||
| "uvicorn>=0.35.0,<1", | ||
| ] |
There was a problem hiding this comment.
pydantic-settings used directly but not declared as a dependency
fli/mcp/server.py line 15 imports directly from pydantic_settings:
from pydantic_settings import BaseSettings, SettingsConfigDictHowever, pydantic-settings is not listed in the [project.dependencies] table. It is currently available as a transitive dependency (pulled in by fastmcp), but relying on transitive deps is fragile — if fastmcp ever stops depending on it, this import will fail at runtime without any change to pyproject.toml.
| dependencies = [ | |
| "curl-cffi>=0.7.4", | |
| "fastapi>=0.115.6", | |
| "fastmcp>=0.1.0", | |
| "httpx>=0.28.1", | |
| "pandas>=2.2.3", | |
| "plotext>=5.3.2", | |
| "pydantic>=2.10.4", | |
| "python-dotenv>=1.0.1", | |
| "ratelimit>=2.2.1", | |
| "tenacity>=9.0.0", | |
| "typer>=0.15.1", | |
| "uvicorn>=0.34.0", | |
| "curl-cffi>=0.13.0,<1", | |
| "fastapi>=0.116.0,<1", | |
| "fastmcp>=3.0.0,<4", | |
| "httpx>=0.28.1,<1", | |
| "pandas>=2.3.0,<3", | |
| "plotext>=5.3.2,<6", | |
| "pydantic>=2.11.0,<3", | |
| "python-dotenv>=1.1.0,<2", | |
| "ratelimit>=2.2.1,<3", | |
| "tenacity>=9.1.0,<10", | |
| "typer>=0.16.0,<1", | |
| "uvicorn>=0.35.0,<1", | |
| ] | |
| "curl-cffi>=0.13.0,<1", | |
| "fastapi>=0.116.0,<1", | |
| "fastmcp>=3.0.0,<4", | |
| "httpx>=0.28.1,<1", | |
| "pandas>=2.3.0,<3", | |
| "plotext>=5.3.2,<6", | |
| "pydantic>=2.11.0,<3", | |
| "pydantic-settings>=2.0.0,<3", | |
| "python-dotenv>=1.1.0,<2", | |
| "ratelimit>=2.2.1,<3", | |
| "tenacity>=9.1.0,<10", | |
| "typer>=0.16.0,<1", | |
| "uvicorn>=0.35.0,<1", |
|
potentially a copy of #66 |
Summary
fastmcp>=3.0.0,<4instead offastmcp>=0.1.0)FliMCPsubclass that relied on fastmcp internals (_tool_manager,_mcp_server) which no longer exist in v3@mcp.prompt()decorators insteadMotivation
Running
pip install flightsand thenfli-mcpfails because the loosefastmcp>=0.1.0pin resolves to v3.x, but the MCP server code uses v2 internal APIs (_tool_manager.add_tool,_tool_manager.list_tools) that were removed. Adding upper bounds on all deps prevents similar breakage in the future.Test plan
fli-mcpstarts and responds toinitializeJSON-RPCtools/listreturns bothsearch_flightsandsearch_dateswith annotationsprompts/listreturns bothsearch-direct-flightandfind-budget-windowsearch_flightstool executes a real flight search successfullyGreptile Summary
This PR fixes a real install-time breakage: the loose
fastmcp>=0.1.0pin was silently resolving to v3.x, butFliMCPused removed v2 internals (_tool_manager,_mcp_server). The fix is two-pronged — add explicit upper bounds to all dependencies and rewrite the MCP server to use FastMCP 3.x native decorators (@mcp.tool(annotations=...),@mcp.prompt()), removing the now-unnecessaryFliMCPsubclass entirely.Key changes:
FliMCPsubclass removed; plainFastMCPis used, eliminating all fragile internal-API access@mcp.tool(annotations={...}), which FastMCP 3.x accepts nativelystr(FastMCP 3.x wraps it automatically) instead of constructinglist[PromptMessage]manuallyfastmcpis pinned to>=3.0.0,<4Findings:
pydantic-settingsis imported directly inserver.pybut is not listed as an explicit dependency — it's currently available as a transitive dep offastmcp, but this is fragilefastapi,uvicorn,typer,httpx,curl-cffi) use<1as the upper bound, which does not protect against breaking changes between0.xminor versions[project.optional-dependencies] devgroup have no upper bounds, inconsistent with the PR's stated goalConfidence Score: 5/5
Safe to merge — the core FastMCP v2 → v3 migration is correct and all remaining findings are P2 style/best-practice suggestions that do not block functionality.
The critical breakage (missing v2 internal APIs) is fully resolved by the migration to FastMCP 3.x native decorators. All three findings are P2: one missing transitive dep declaration, one note about the completeness of the <1 upper-bound strategy for 0.x packages, and an inconsistency in dev deps. None of these affect runtime correctness of the MCP server.
pyproject.toml — missing pydantic-settings direct dep and incomplete upper-bound coverage for pre-1.0 packages
Important Files Changed
Sequence Diagram
sequenceDiagram participant Client as MCP Client participant Server as FastMCP Server participant Tool as @mcp.tool() participant Search as SearchFlights/SearchDates participant Prompt as @mcp.prompt() Client->>Server: tools/list Server-->>Client: [search_flights, search_dates] + ToolAnnotations Client->>Server: tools/call search_flights(params) Server->>Tool: search_flights(origin, dest, date, ...) Tool->>Search: _execute_flight_search(FlightSearchParams) Search-->>Tool: list[FlightResult] Tool-->>Server: dict[str, Any] Server-->>Client: JSON result Client->>Server: prompts/list Server-->>Client: [search-direct-flight, find-budget-window] Client->>Server: prompts/get search-direct-flight(args) Server->>Prompt: search_direct_flight_prompt(origin, dest, date, ...) Prompt-->>Server: str (FastMCP wraps into PromptMessage) Server-->>Client: GetPromptResultComments Outside Diff (1)
pyproject.toml, line 41-50 (link)The
[project.optional-dependencies] devgroup still has no upper bounds on any of its packages, which is inconsistent with the goal stated in the PR. While dev deps don't affect end-users, a futurepytestmajor bump (for example) could silently break the CI test suite in the same wayfastmcp 3.xbroke the MCP server. Consider applying the same<NEXT_MAJORbound pattern here for consistency.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Reviews (1): Last reviewed commit: "Update dependencies to latest versions w..." | Re-trigger Greptile
(2/5) Greptile learns from your feedback when you react with thumbs up/down!