Skip to content

Rename _fastmcp metadata namespace to fastmcp and make non-optional#2895

Merged
jlowin merged 5 commits intomainfrom
rename-fastmcp-meta-namespace
Jan 17, 2026
Merged

Rename _fastmcp metadata namespace to fastmcp and make non-optional#2895
jlowin merged 5 commits intomainfrom
rename-fastmcp-meta-namespace

Conversation

@jlowin
Copy link
Copy Markdown
Member

@jlowin jlowin commented Jan 17, 2026

Component metadata now uses a cleaner fastmcp namespace (instead of _fastmcp) and is always included in responses.

Changes:

  • meta._fastmcp.tagsmeta.fastmcp.tags
  • meta.fastmcp.version now included when component has a version
  • Removed include_fastmcp_meta setting/parameter (metadata always present)
# Accessing component metadata
tools = await client.list_tools()
for tool in tools:
    tags = tool.meta.get("fastmcp", {}).get("tags", [])
    version = tool.meta.get("fastmcp", {}).get("version")

- Rename meta namespace from `_fastmcp` to `fastmcp`
- Always include fastmcp metadata (remove `include_fastmcp_meta` setting)
- Add component version to metadata when available
@marvin-context-protocol marvin-context-protocol Bot added breaking change Breaks backward compatibility. Requires minor version bump. Critical for maintainer attention. enhancement Improvement to existing functionality. For issues and smaller PR improvements. labels Jan 17, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 17, 2026

Walkthrough

This pull request removes the include_fastmcp_meta parameter from the FastMCP public API and renames the metadata namespace from _fastmcp to fastmcp. The get_meta() method in component utilities is updated to always emit fastmcp metadata instead of conditionally based on a runtime flag. A new get_fastmcp_metadata() helper function is introduced to extract fastmcp metadata from component dictionaries. The FastMCPMeta type is extended with a version field. All tool, resource, template, and prompt conversion methods (to_mcp_*) are modified to remove the include_fastmcp_meta parameter. Documentation is updated across multiple files to reference the new namespace and reflect the removal of the parameter.

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Description check ❓ Inconclusive The description clearly explains what changed and provides a practical code example, but the Contributors Checklist and Review Checklist items are not checked off, and the description lacks detail on testing and documentation updates. Check off the appropriate checklist items (especially 'I have tested my changes' and 'I have performed all required documentation updates') to confirm compliance with the contribution workflow.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately captures the main changes: renaming the _fastmcp namespace to fastmcp and making it non-optional. It is concise and directly reflects the core purpose of the pull request.
Docstring Coverage ✅ Passed Docstring coverage is 93.75% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (5)
docs/clients/prompts.mdx (1)

45-50: Consider simplifying redundant dictionary access.

The filter logic calls prompt.meta.get('fastmcp', {}) twice on the same object. This is slightly inefficient and harder to read.

♻️ Suggested improvement
     analysis_prompts = [
         prompt for prompt in prompts 
-        if prompt.meta and
-           prompt.meta.get('fastmcp', {}) and
-           'analysis' in prompt.meta.get('fastmcp', {}).get('tags', [])
+        if prompt.meta
+        and 'analysis' in prompt.meta.get('fastmcp', {}).get('tags', [])
     ]

The intermediate check prompt.meta.get('fastmcp', {}) is unnecessary since the final .get('tags', []) already handles the empty dict case gracefully.

docs/clients/resources.mdx (1)

73-78: Same redundant access pattern as in prompts.mdx.

The filter logic duplicates the .get('fastmcp', {}) call unnecessarily.

♻️ Suggested improvement
     config_resources = [
         resource for resource in resources 
-        if resource.meta and
-           resource.meta.get('fastmcp', {}) and
-           'config' in resource.meta.get('fastmcp', {}).get('tags', [])
+        if resource.meta
+        and 'config' in resource.meta.get('fastmcp', {}).get('tags', [])
     ]
docs/clients/tools.mdx (1)

45-50: Same redundant access pattern.

Consider simplifying to match the suggested pattern from other client docs for consistency.

♻️ Suggested improvement
     analysis_tools = [
         tool for tool in tools 
-        if tool.meta and
-           tool.meta.get('fastmcp', {}) and
-           'analysis' in tool.meta.get('fastmcp', {}).get('tags', [])
+        if tool.meta
+        and 'analysis' in tool.meta.get('fastmcp', {}).get('tags', [])
     ]
docs/development/upgrade-guide.mdx (1)

11-15: Consider adding a version badge to indicate which version introduces this change.

Other sections in this upgrade guide are organized by version (e.g., "## v3.0.0", "## v2.14.0"). This new section lacks a version indicator, which may confuse users trying to determine when they need to apply this migration.

♻️ Suggested structure

Either add a version heading:

-## FastMCP Metadata Namespace Change
+## v2.X.X (or appropriate version)
+
+### FastMCP Metadata Namespace Change

Or add a VersionBadge component:

 ## FastMCP Metadata Namespace Change
+
+<VersionBadge version="2.X.X" />
 
 ### Metadata Namespace Renamed
src/fastmcp/resources/resource.py (1)

372-374: Avoid eager get_meta() evaluation when _meta is overridden.

overrides.get("_meta", self.get_meta()) always evaluates self.get_meta(), even when _meta is supplied, which can mutate self.meta and do extra work. Consider lazy evaluation.

♻️ Proposed tweak
-            _meta=overrides.get(  # type: ignore[call-arg]  # _meta is Pydantic alias for meta field
-                "_meta", self.get_meta()
-            ),
+            _meta=(
+                overrides["_meta"]
+                if "_meta" in overrides
+                else self.get_meta()
+            ),  # type: ignore[call-arg]  # _meta is Pydantic alias for meta field

Comment thread src/fastmcp/utilities/components.py Outdated
- Add get_fastmcp_metadata() helper with fallback to legacy _fastmcp namespace
- Update proxy.py to use helper for compatibility with older servers
- Update get_meta() return type to dict[str, Any] (always returns dict)
- Regenerate python-sdk API docs
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/fastmcp/utilities/components.py (1)

140-158: Type validation concern for meta["fastmcp"] remains unaddressed.

If a caller sets meta["fastmcp"] to a non-mapping value, the | operator on line 155 will raise a TypeError. This was flagged in a previous review.

🛡️ Suggested guard
-        if upstream_meta := meta.get("fastmcp"):
-            fastmcp_meta = upstream_meta | fastmcp_meta
+        if (upstream_meta := meta.get("fastmcp")) is not None:
+            if not isinstance(upstream_meta, dict):
+                raise TypeError("meta['fastmcp'] must be a mapping")
+            fastmcp_meta = upstream_meta | fastmcp_meta
🧹 Nitpick comments (2)
docs/python-sdk/fastmcp-server-middleware-authorization.mdx (1)

14-29: Split alternative examples and add expected outcome/error handling.

Lines 14-29 combine two alternative configurations in one snippet, which makes the example less runnable and harder to follow. Consider using Tabs (global vs tag-based) and add a brief expected-outcome note plus minimal auth-failure handling to meet the MDX example requirements. As per coding guidelines.

docs/python-sdk/fastmcp-resources-resource.mdx (1)

169-172: Add a short description/returns for get_span_attributes.

The section is signature-only; add a docstring in src/fastmcp/resources/resource.py so generated docs explain purpose and expected keys/values. As per coding guidelines, API docs should document parameters and return values.

Comment on lines +1 to +4
---
title: authorization
sidebarTitle: authorization
---
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add required description in frontmatter (update generator).

Line 1-4 is missing description, which is required for MDX pages. Since docs/python-sdk/** is auto-generated, please update the doc generator/template and regenerate the file rather than editing it manually. As per coding guidelines.

🛠️ Suggested frontmatter output
 ---
 title: authorization
 sidebarTitle: authorization
+description: Authorization middleware for FastMCP servers.
 ---

@jlowin jlowin added the v3 Targeted for FastMCP 3 label Jan 17, 2026
@jlowin jlowin merged commit 53e220a into main Jan 17, 2026
13 checks passed
@jlowin jlowin deleted the rename-fastmcp-meta-namespace branch January 17, 2026 02:35
@jlowin jlowin removed the breaking change Breaks backward compatibility. Requires minor version bump. Critical for maintainer attention. label Jan 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Improvement to existing functionality. For issues and smaller PR improvements. v3 Targeted for FastMCP 3

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant