Skip to content

Conversation

@calvingiles
Copy link

OpenAI's ChatGPT apps SDK uses _meta in resource content to pass widget domain information to clients (see https://developers.openai.com/apps-sdk/build/mcp-server/). FastMCP resources support metadata via the meta parameter, but this wasn't being included in the content returned to clients.

The MCP specification defines a _meta field on ResourceContents for this purpose. FastMCP now populates this field with the resource's metadata when serving content, and ensures resources created from templates inherit the template's metadata.

Description

Contributors Checklist

  • My change closes #(issue number)
  • I have followed the repository's development workflow
  • I have tested my changes manually and by adding relevant tests
  • I have performed all required documentation updates

Review Checklist

  • I have self-reviewed my changes
  • My Pull Request is ready for review

OpenAI's ChatGPT apps SDK uses _meta in resource content to pass widget domain information to clients (see https://developers.openai.com/apps-sdk/build/mcp-server/). FastMCP resources support metadata via the meta parameter, but this wasn't being included in the content returned to clients.

The MCP specification defines a _meta field on ResourceContents for this purpose. FastMCP now populates this field with the resource's metadata when serving content, and ensures resources created from templates inherit the template's metadata.
@marvin-context-protocol marvin-context-protocol bot added bug Something isn't working. Reports of errors, unexpected behavior, or broken functionality. server Related to FastMCP server implementation or server-side functionality. labels Nov 18, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 18, 2025

Walkthrough

The pull request extends metadata support throughout the resource management system. The Resource.from_function method signature now accepts optional parameters for title, icons, annotations, and meta fields, enabling richer metadata initialization. The resource template implementation passes these new fields when creating Resource instances. Additionally, a new _setup_read_resource_handler method is introduced to the FastMCP server class that wraps the existing resource reading handler, augmenting both text and binary resource contents with metadata information and registering it directly on the MCP server's request handlers.

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Description check ❓ Inconclusive The description explains the motivation, changes, and context well, but all contributor and review checklist items remain unchecked, indicating incomplete preparation for review. Complete the contributor and review checklists by checking off items as applicable, particularly confirming testing, documentation updates, self-review, and readiness for review.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding _meta support to resource content responses, which is the primary objective of the PR.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


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
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: 0

🧹 Nitpick comments (1)
src/fastmcp/server/server.py (1)

471-524: Refine exception handling and add match default case.

Two improvement opportunities:

  1. Line 491: The bare except Exception is too broad. Since get_resource can raise NotFoundError (and potentially other specific exceptions), catch those explicitly to avoid masking unexpected errors:
 # Get the resource to access its meta
 try:
     resource = await self._resource_manager.get_resource(uri)
     resource_meta = resource.get_meta(
         include_fastmcp_meta=self.include_fastmcp_meta
     )
-except Exception:
+except (NotFoundError, ValueError):
     resource_meta = None
  1. Lines 495-514: The match statement lacks a default case. If content_item.content is neither str nor bytes, it will be silently skipped, which could mask bugs:
 for content_item in result:
     match content_item.content:
         case str() as data:
             contents_list.append(
                 mcp.types.TextResourceContents(
                     uri=uri,
                     text=data,
                     mimeType=content_item.mime_type or "text/plain",
                     _meta=resource_meta,
                 )
             )
         case bytes() as data:
             contents_list.append(
                 mcp.types.BlobResourceContents(
                     uri=uri,
                     blob=base64.b64encode(data).decode(),
                     mimeType=content_item.mime_type
                     or "application/octet-stream",
                     _meta=resource_meta,
                 )
             )
+        case _:
+            logger.warning(f"Unexpected content type for resource {uri}: {type(content_item.content)}")
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dd876b5 and 76e3d4a.

⛔ Files ignored due to path filters (1)
  • tests/resources/test_resource_content_meta.py is excluded by none and included by none
📒 Files selected for processing (2)
  • src/fastmcp/resources/template.py (1 hunks)
  • src/fastmcp/server/server.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/fastmcp/server/server.py (2)
src/fastmcp/resources/resource_manager.py (1)
  • get_resource (244-287)
src/fastmcp/utilities/components.py (1)
  • get_meta (75-97)
src/fastmcp/resources/template.py (1)
src/fastmcp/server/server.py (1)
  • icons (380-384)
🪛 Ruff (0.14.5)
src/fastmcp/server/server.py

491-491: Do not catch blind exception: Exception

(BLE001)

⏰ 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). (1)
  • GitHub Check: Run tests: Python 3.10 on windows-latest
🔇 Additional comments (2)
src/fastmcp/resources/template.py (1)

183-195: LGTM! Metadata propagation implemented correctly.

The template now properly forwards metadata fields (title, icons, annotations, meta) when creating resource instances. This enables resources instantiated from templates to inherit the template's metadata, which will then be included in the _meta field of resource content responses.

src/fastmcp/server/server.py (1)

523-523: Approach confirmed valid and appropriate.

Direct programmatic registration is recommended when you need full control over request/response shaping and low-level protocol handling. The direct dictionary assignment at line 523 is the correct pattern for this use case, particularly when implementing custom response transformation as done here. No changes needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working. Reports of errors, unexpected behavior, or broken functionality. server Related to FastMCP server implementation or server-side functionality.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants