Skip to content

Leverage latest MCP spec features from go-sdk v1.4.0#1955

Merged
dgageot merged 1 commit intodocker:mainfrom
dgageot:board/are-there-features-in-the-most-recent-mc-7866095f
Mar 6, 2026
Merged

Leverage latest MCP spec features from go-sdk v1.4.0#1955
dgageot merged 1 commit intodocker:mainfrom
dgageot:board/are-there-features-in-the-most-recent-mc-7866095f

Conversation

@dgageot
Copy link
Member

@dgageot dgageot commented Mar 6, 2026

Summary

Handle additional MCP content types and set richer tool annotations when exposing agents as MCP servers, leveraging features available in go-sdk v1.4.0.

Changes

New MCP content types in processMCPContent

  • AudioContent: Re-encode raw bytes to base64 and collect in ToolCallResult.Audios, matching the existing ImageContent pattern.
  • ResourceLink: Render as markdown links ([name](uri)) with proper escaping of ] in names and ) in URIs to prevent broken output.
  • StructuredContent: Pass through CallToolResult.StructuredContent for tools that define an OutputSchema.

Richer ToolAnnotations on MCP server

  • Replace the single ReadOnlyHint computation with agentToolAnnotations() that inspects all agent tools to derive DestructiveHint, IdempotentHint, OpenWorldHint, and Title.
  • Follows MCP spec defaults: *bool fields left nil when they match the spec default (true), explicitly set to false otherwise.

Code quality

  • Introduce MediaContent base type with ImageContent/AudioContent as type aliases (no breaking changes at call sites).
  • Extract encodeMedia and optionalBool helpers to reduce duplication.
  • Consolidate four separate processMCPContent test functions into one table-driven test.
  • Add new server_test.go with table-driven tests for agentToolAnnotations.

Handle AudioContent, ResourceLink, and StructuredContent in MCP tool
responses, and set richer ToolAnnotations (DestructiveHint, IdempotentHint,
OpenWorldHint, Title) when exposing agents as MCP tools.

- Add MediaContent type unifying ImageContent/AudioContent with type aliases
- Process AudioContent by re-encoding to base64, matching ImageContent pattern
- Surface ResourceLink as markdown text with escaped special characters
- Pass through StructuredContent from CallToolResult for tools with OutputSchema
- Compute aggregate ToolAnnotations from all agent tools instead of ReadOnlyHint only
- Extract encodeMedia and optionalBool helpers to reduce duplication
- Consolidate processMCPContent tests into a single table-driven test

Assisted-By: cagent
@dgageot dgageot requested a review from a team as a code owner March 6, 2026 06:37
Copy link

@docker-agent docker-agent bot left a comment

Choose a reason for hiding this comment

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

Review: COMMENT

Assessment: 🟡 NEEDS ATTENTION

Summary

This PR successfully adds support for richer MCP content types (Audio, ResourceLink, StructuredContent) and improved tool annotations. The code is generally well-structured with comprehensive test coverage.

However, there is one notable issue in the new ResourceLink handling code that should be addressed:

MEDIUM severity: The markdown escaping for resource links is incomplete and could produce broken markdown or malformed URIs.

Findings

[MEDIUM] pkg/tools/mcp/mcp.go:505 — Incomplete markdown escaping for ResourceLink

The ResourceLink handling only escapes ] in names and ) in URIs:

name := strings.ReplaceAll(c.Name, "]", "\\]")
uri := strings.ReplaceAll(c.URI, ")", "%29")
text += fmt.Sprintf("[%s](%s)", name, uri)

This escaping is insufficient:

  • URI: Only ) is escaped as %29. URIs with spaces, [, quotes, newlines, or other special characters will produce invalid markdown. Consider using proper URL encoding (e.g., url.PathEscape or url.QueryEscape).
  • Name: Only ] is escaped. Names containing markdown metacharacters like *, _, backticks, or [ could be misinterpreted by markdown parsers.

Recommendation: Use url.PathEscape() or similar for the entire URI, and consider escaping all markdown special characters in the name, or use a markdown escaping library.

case *mcp.ResourceLink:
if c.Name != "" {
// Escape ] in name and ) in URI to prevent broken markdown links.
name := strings.ReplaceAll(c.Name, "]", "\\]")
Copy link

Choose a reason for hiding this comment

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

MEDIUM: Incomplete markdown escaping for ResourceLink

The escaping only handles ] in names and ) in URIs. This is insufficient for robust markdown link generation:

  • URI escaping: Only )%29, but URIs with spaces, [, quotes, or newlines will break the markdown syntax. Consider using url.PathEscape() for proper URL encoding.
  • Name escaping: Only ] is handled, but names with *, _, `, or [ could trigger unintended markdown formatting.

Recommendation: Apply proper URL encoding to the entire URI and escape all markdown metacharacters in the name.

@dgageot dgageot merged commit c58fef0 into docker:main Mar 6, 2026
8 checks passed
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.

2 participants