Update classes to inherit from FastMCPBaseModel instead of BaseModel#2739
Update classes to inherit from FastMCPBaseModel instead of BaseModel#2739
Conversation
Replace pydantic.BaseModel with FastMCPBaseModel for FastMCP classes to ensure extra='forbid' by default, preventing silent acceptance of incorrect initialization kwargs. Updated classes: - Deployment, MCPServerConfig (config classes) - ToolResult (tool classes) - SamplingTool (sampling classes, preserves arbitrary_types_allowed) - CachableResourceContent, CachableResourceResult, CachableToolResult, ResponseCachingStatistics (caching classes) - EventEntry, StreamEventList (event store classes) - ResourceContent, ResourceResult (resource classes)
WalkthroughThis PR removes **kwargs from several constructor signatures (Message, PromptResult, ResourceContent, ResourceResult) to enforce strict parameter validation. It replaces Pydantic BaseModel with FastMCPBaseModel across multiple data model classes (EventEntry, StreamEventList, and various cachable wrappers). The caching layer is enhanced with wrap/unwrap helper methods for converting between cached and uncached representations, new meta fields, and additional statistics tracking. The FunctionPrompt.add_to_docket method is updated to unpack arguments as keyword arguments rather than passing them as a single positional parameter. Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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 |
- Remove **kwargs from ResourceContent, ResourceResult, Message, PromptResult, ToolResult __init__ methods (custom __init__ already prevents extra kwargs) - Revert these classes to pydantic.BaseModel (FastMCPBaseModel not needed) - Fix CachableMessage and CachablePromptResult to use FastMCPBaseModel (were broken after BaseModel import removal)
Test Failure AnalysisSummary: The workflow run #20515579176 failed due to a test timeout on Windows, which is a known flaky test issue unrelated to the PR changes. Root Cause: The test This is a flaky test that occasionally times out on Windows runners, likely due to disk I/O performance issues or SQLite locking on Windows. Resolution: ✅ The issue has already been resolved - subsequent workflow runs have passed successfully:
This timeout is not caused by the PR changes (which update classes to inherit from Detailed AnalysisFailed Test
Failure Type
Stack TraceThe timeout occurred while initializing File "oauth_proxy.py", line 821
key_value=DiskStore(directory=settings.home / "oauth-proxy")
File "diskcache/core.py", line 623
con = self._local.con = sqlite3.connect(...)
+++ Timeout +++Why This Is Not PR-Related
Flaky Test PatternThis test has timed out before on Windows runners. It's a known issue with:
Related Files
Updated: 2025-12-26 - Workflow run #20515579176 analysis |
These classes use model_dump/reconstruction patterns that conflict with extra='forbid' when aliased fields like schema_ are involved.
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 (1)
src/fastmcp/server/sampling/sampling_tool.py (1)
16-44:model_configoverride losesextra="forbid"fromFastMCPBaseModel.When
SamplingTooloverridesmodel_configwith onlyarbitrary_types_allowed=True, it replaces the entireConfigDictinherited fromFastMCPBaseModel, losing theextra="forbid"setting. This defeats the purpose of the base class migration.🔎 Proposed fix
- model_config = ConfigDict(arbitrary_types_allowed=True) + model_config = ConfigDict(extra="forbid", arbitrary_types_allowed=True)
🧹 Nitpick comments (1)
src/fastmcp/server/middleware/caching.py (1)
100-104: Consider usingLiteral["user", "assistant"]for therolefield.The
Messageclass usesLiteral["user", "assistant"]for itsrolefield, butCachableMessageusesstr. Using the same type would provide better type safety and consistency.🔎 Proposed fix
+from typing import Any, Literal, TypedDict + class CachableMessage(FastMCPBaseModel): """A wrapper for Message that can be cached.""" - role: str + role: Literal["user", "assistant"] content: mcp.types.TextContent | mcp.types.EmbeddedResource
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
src/fastmcp/prompts/prompt.pysrc/fastmcp/resources/resource.pysrc/fastmcp/server/event_store.pysrc/fastmcp/server/middleware/caching.pysrc/fastmcp/server/sampling/sampling_tool.pysrc/fastmcp/tools/tool.py
🧰 Additional context used
📓 Path-based instructions (1)
src/fastmcp/**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
src/fastmcp/**/*.py: Python ≥ 3.10 with full type annotations required
Prioritize readable, understandable code - clarity over cleverness. Avoid obfuscated or confusing patterns even if shorter
Follow existing patterns and maintain consistency in code implementation
Be intentional about re-exports - don't blindly re-export everything to parent namespaces. Core types defining a module's purpose should be exported. Specialized features can live in submodules. Only re-export to fastmcp.* for most fundamental types
Never use bare except - be specific with exception types
Files:
src/fastmcp/server/event_store.pysrc/fastmcp/server/sampling/sampling_tool.pysrc/fastmcp/server/middleware/caching.pysrc/fastmcp/tools/tool.pysrc/fastmcp/prompts/prompt.pysrc/fastmcp/resources/resource.py
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
Repo: jlowin/fastmcp PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-25T15:53:07.646Z
Learning: Applies to src/fastmcp/**/*.py : Python ≥ 3.10 with full type annotations required
Learnt from: CR
Repo: jlowin/fastmcp PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-25T15:53:07.646Z
Learning: Applies to src/fastmcp/**/*.py : Follow existing patterns and maintain consistency in code implementation
📚 Learning: 2025-12-25T15:53:07.646Z
Learnt from: CR
Repo: jlowin/fastmcp PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-25T15:53:07.646Z
Learning: Applies to src/fastmcp/**/*.py : Python ≥ 3.10 with full type annotations required
Applied to files:
src/fastmcp/server/event_store.pysrc/fastmcp/server/sampling/sampling_tool.pysrc/fastmcp/server/middleware/caching.py
📚 Learning: 2025-12-25T15:53:07.646Z
Learnt from: CR
Repo: jlowin/fastmcp PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-25T15:53:07.646Z
Learning: Applies to src/fastmcp/**/*.py : Follow existing patterns and maintain consistency in code implementation
Applied to files:
src/fastmcp/server/sampling/sampling_tool.py
🧬 Code graph analysis (1)
src/fastmcp/server/sampling/sampling_tool.py (1)
src/fastmcp/utilities/types.py (1)
FastMCPBaseModel(38-41)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Run tests: Python 3.10 on windows-latest
- GitHub Check: Run tests: Python 3.13 on ubuntu-latest
- GitHub Check: Run tests: Python 3.10 on ubuntu-latest
- GitHub Check: Run tests with lowest-direct dependencies
🔇 Additional comments (11)
src/fastmcp/tools/tool.py (1)
119-121: LGTM!Formatting change consolidates the
super().__init__()call to a single line. No functional impact.src/fastmcp/prompts/prompt.py (3)
90-90: LGTM!Removal of
**kwargspassthrough enforces stricter parameter validation, preventing unknown kwargs from being silently accepted.
159-159: LGTM!Consistent with the PR objective of enforcing explicit parameter handling by removing
**kwargspassthrough.
561-584: LGTM!The change to splat
argumentsas**kwargsaligns with the docstring and mirrors the pattern inFunctionTool.add_to_docket. Theor {}safely handlesNonearguments.src/fastmcp/server/event_store.py (1)
21-37: LGTM!Clean migration of
EventEntryandStreamEventListtoFastMCPBaseModel. Both are simple data models with nomodel_configoverrides, so they correctly inheritextra="forbid".src/fastmcp/resources/resource.py (2)
88-88: LGTM!Removal of
**kwargspassthrough enforces stricter parameter validation forResourceContent.
168-168: LGTM!Consistent with the PR objective of removing
**kwargspassthrough fromResourceResult.src/fastmcp/server/middleware/caching.py (4)
38-76: LGTM!Clean migration to
FastMCPBaseModelwith well-structuredwrap/unwraphelpers for converting between domain and cachable representations.
79-97: LGTM!
CachableToolResultproperly migrated withwrap/unwraphelpers that delegate toToolResult's constructor.
107-135: LGTM!
CachablePromptResultproperly migrated with comprehensivewrap/unwraphelpers that handledescriptionandmetafields.
172-178: LGTM!
ResponseCachingStatisticsproperly migrated toFastMCPBaseModelwith expanded fields for comprehensive cache statistics tracking.
Replace
pydantic.BaseModelwithFastMCPBaseModelfor FastMCP classes to ensureextra='forbid'by default, preventing silent acceptance of incorrect initialization kwargs.Changes
Updated 12 classes across 6 files to inherit from
FastMCPBaseModel:Deployment,MCPServerConfigToolResultSamplingTool(preservesarbitrary_types_allowed=True)CachableResourceContent,CachableResourceResult,CachableToolResult,ResponseCachingStatisticsEventEntry,StreamEventListResourceContent,ResourceResultBenefits
This change ensures that these classes will reject unknown kwargs, helping catch typos and invalid parameters early: