Skip to content

feat(adapters): support MCP structured content, output schema, and new content types#142

Merged
dgenio merged 10 commits intomainfrom
feat/mcp-structured-content-output-schema
Mar 7, 2026
Merged

feat(adapters): support MCP structured content, output schema, and new content types#142
dgenio merged 10 commits intomainfrom
feat/mcp-structured-content-output-schema

Conversation

@dgenio
Copy link
Owner

@dgenio dgenio commented Mar 6, 2026

What changed

Extends the MCP adapter to handle all content types from the MCP spec (revision 2025-06-18). Closes #102.

SelectableItem (types.py)

  • Added output_schema: dict[str, Any] | None = None field with to_dict()/from_dict() support

mcp_tool_to_selectable() (adapters/mcp.py)

  • Maps outputSchema from MCP tool definition to SelectableItem.output_schema

mcp_result_to_envelope() (adapters/mcp.py)

  • audio content type: base64-decoded, stored as binary artifact (same pattern as image)
  • resource_link content type: URI stored as ArtifactRef with size_bytes=0
  • structuredContent (top-level): serialized as application/json artifact, top-level keys extracted as facts
  • Content-part annotations: audience and priority collected into provenance["content_annotations"]

Documentation (docs/integration_mcp.md)

  • Added supported content types table
  • Added structured content and content-part annotations sections with examples

Tests (tests/test_adapters.py)

  • 16 new tests covering: outputSchema mapping, audio (valid + invalid base64), resource_link (with/without name), structuredContent (with content + standalone), content-part annotations (present + absent), mixed content types coexistence, SelectableItem.output_schema round-trip

Why

Issue #102 identified that the MCP adapter silently dropped structuredContent, audio, resource_link, outputSchema, and content-part annotations — all features added in the MCP 2025-06-18 revision.

How verified

ruff format --check src/ tests/ examples/  →  79 files already formatted
ruff check src/ tests/ examples/           →  All checks passed!
mypy src/                                  →  Success: no issues found in 41 source files
pytest -q                                  →  515 passed in 16.61s

Tradeoffs / risks

  • resource_link stores the URI as raw bytes in binaries for caller resolution — no automatic fetch
  • structuredContent fact extraction is limited to top-level keys with short string representations (<200 chars)

Scope notes

  • Changes limited to MCP adapter, SelectableItem type, tests, docs, and changelog
  • No changes to A2A adapter or context pipeline
  • AI instruction files (AGENTS.md, CLAUDE.md, .github/copilot-instructions.md) reviewed — no updates needed (they don't list individual field names)

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Extends the MCP adapter to support additional MCP (2025-06-18) features—structured content, output schemas, and new result content types—so MCP integrations don’t silently drop important data.

Changes:

  • Add SelectableItem.output_schema with to_dict() / from_dict() support.
  • Extend mcp_tool_to_selectable() to map MCP outputSchema.
  • Extend mcp_result_to_envelope() to handle audio, resource_link, top-level structuredContent, and per-part annotations, plus add tests/docs/changelog entries.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
tests/test_adapters.py Adds coverage for new MCP content types, annotations, and output_schema round-tripping.
src/contextweaver/types.py Introduces SelectableItem.output_schema and serialisation support.
src/contextweaver/adapters/mcp.py Implements MCP outputSchema mapping and new result parsing behaviors (audio/resource_link/structuredContent/annotations).
docs/integration_mcp.md Documents new MCP behaviors and supported content types.
CHANGELOG.md Records the newly supported MCP features.

You can also share your feedback on Copilot code review. Take the survey.

@dgenio
Copy link
Owner Author

dgenio commented Mar 7, 2026

Good point — the image and audio blocks were near-identical, and the module was at 324 lines (above the 300-line target). Extracted a _decode_binary_part() helper that both branches now call, reducing duplication and making future binary types trivial to add. Committed in 0645acf.

@dgenio
Copy link
Owner Author

dgenio commented Mar 7, 2026

Great catch — the binaries entry for resource_link was declaring the linked resource's MIME type (e.g., text/csv), but the actual payload is a URI string, not CSV content. A consumer trusting that MIME would misinterpret the data.

Fixed by using text/uri-list (RFC 2483) for the binaries entry, which accurately describes what the payload contains. The resource's declared MIME type is preserved in ArtifactRef.media_type so consumers still know what the linked resource is.

Added an explicit assertion in the test to lock this in. Committed in 21f5314.

@dgenio
Copy link
Owner Author

dgenio commented Mar 7, 2026

Thanks for the thorough review! All three items have been addressed:

  1. structured_content type annotation — Widened from dict[str, Any] | None to Any with inline comment explaining why (bb54a3f).
  2. Image/audio handler duplication — Extracted _decode_binary_part() private helper that both branches now call (0645acf).
  3. resource_link MIME semantics — Binaries entry now uses text/uri-list (RFC 2483) to reflect the actual payload; resource's declared MIME stays on ArtifactRef.media_type (21f5314).

All 63 adapter tests pass, lint and type checks are clean. Ready for re-review when you get a chance!

dgenio added 10 commits March 7, 2026 07:34
…w content types

Handle all MCP spec (2025-06-18) content types in the MCP adapter:

- Add output_schema field to SelectableItem; map outputSchema from
  MCP tool definitions in mcp_tool_to_selectable()
- Handle audio content type (base64-decoded binary artifact)
- Handle resource_link content type (URI reference as ArtifactRef)
- Handle top-level structuredContent (stored as application/json
  artifact with fact extraction from top-level keys)
- Collect per-part annotations (audience, priority) into
  provenance["content_annotations"]
- Update MCP integration docs with new content type reference
- Add 16 tests covering all new content types and round-trip

Closes #102
@dgenio dgenio force-pushed the feat/mcp-structured-content-output-schema branch from 21f5314 to 04b1a86 Compare March 7, 2026 07:37
@dgenio dgenio merged commit 9892e5d into main Mar 7, 2026
3 checks passed
@dgenio dgenio deleted the feat/mcp-structured-content-output-schema branch March 7, 2026 07:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[adapters] Support MCP structured content, output schema, and new content types

2 participants