Leverage latest MCP spec features from go-sdk v1.4.0#1955
Conversation
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
There was a problem hiding this comment.
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.PathEscapeorurl.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, "]", "\\]") |
There was a problem hiding this comment.
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 usingurl.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.
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
processMCPContentToolCallResult.Audios, matching the existing ImageContent pattern.[name](uri)) with proper escaping of]in names and)in URIs to prevent broken output.CallToolResult.StructuredContentfor tools that define anOutputSchema.Richer ToolAnnotations on MCP server
ReadOnlyHintcomputation withagentToolAnnotations()that inspects all agent tools to deriveDestructiveHint,IdempotentHint,OpenWorldHint, andTitle.*boolfields left nil when they match the spec default (true), explicitly set to false otherwise.Code quality
MediaContentbase type withImageContent/AudioContentas type aliases (no breaking changes at call sites).encodeMediaandoptionalBoolhelpers to reduce duplication.processMCPContenttest functions into one table-driven test.server_test.gowith table-driven tests foragentToolAnnotations.