Skip to content

Fix #26325: Sanitize MCP Tool Names for Bedrock Compatibility#26353

Open
david-fraley wants to merge 1 commit into
mainfrom
dfraley/fix-bedrock-mcp-tool-names
Open

Fix #26325: Sanitize MCP Tool Names for Bedrock Compatibility#26353
david-fraley wants to merge 1 commit into
mainfrom
dfraley/fix-bedrock-mcp-tool-names

Conversation

@david-fraley

Copy link
Copy Markdown
Collaborator

Problem

AWS Bedrock requires tool names to match the pattern ^[a-zA-Z0-9_-]{1,128}$. MCP tools often have names containing dots and other special characters that violate this requirement, causing HTTP 400 errors when tool names are sent to Bedrock, which breaks the agent turn.

Solution

Implement tool name sanitization by:

  1. Replacing invalid characters (especially dots) with underscores
  2. Truncating names exceeding 128 characters
  3. Maintaining a mapping from sanitized names back to original tool IDs
  4. Resolving sanitized names to original IDs when executing tools

Changes

aibridge/intercept/messages/base.go

  • Added sanitizedToolNames field to interceptionBase struct to track mapping
  • Updated injectTools() method to sanitize tool names before sending to Bedrock
  • Added sanitizeToolName() function that:
    • Replaces non-alphanumeric/non-underscore/non-hyphen characters with underscores
    • Truncates to 128 characters (Bedrock limit)
    • Returns "unknown_tool" for empty results
  • Added resolveToolID() method to resolve sanitized names back to original IDs

aibridge/intercept/messages/blocking.go

  • Updated tool lookup to use resolveToolID() before calling GetTool()
  • Two locations updated: tool presence check and tool execution loop

aibridge/intercept/messages/streaming.go

  • Updated 8 locations where tools are looked up to resolve sanitized names:
    • ContentBlockStart: block name resolution
    • ContentBlockDelta: lastToolName resolution
    • ContentBlockStop: lastToolName resolution
    • Message delta usage reporting
    • Tool name extraction from message content
    • Tool execution loop (name parameter iteration)
    • Non-injected tool tracking

aibridge/intercept/messages/base_internal_test.go

  • Added comprehensive unit tests for sanitizeToolName() covering:
    • Empty strings → "unknown_tool"
    • Dots converted to underscores
    • Hyphens preserved
    • Mixed special characters handled
    • 128-character truncation
    • Edge cases

Testing

✅ All new unit tests pass (8 test cases for sanitizeToolName)
✅ Existing tests continue to pass
✅ Code formatting verified with go fmt

Example

sanitizeToolName("awslabs.aws_documentation_mcp_server__read_documentation")
// Returns: "awslabs_aws_documentation_mcp_server__read_documentation"

sanitizeToolName("@#$invalid!tool")
// Returns: "___invalid_tool"

AWS Bedrock requires tool names to match the pattern ^[a-zA-Z0-9_-]{1,128}$.
MCP tools often have names with dots and other special characters that violate
this requirement, causing HTTP 400 errors when tool names are sent to Bedrock.

Changes:
- Added sanitizeToolName() function to replace invalid characters with underscores
  and truncate to 128 characters
- Added sanitizedToolNames field to interceptionBase struct to track mapping from
  sanitized names back to original MCP tool IDs
- Updated injectTools() in base.go to sanitize tool names before sending to Bedrock
- Added resolveToolID() method to resolve sanitized names back to original IDs when
  processing model responses
- Updated blocking.go and streaming.go to resolve tool IDs before looking up tools
  from the MCP proxy, ensuring we use the original tool ID for execution
- Added comprehensive unit tests for sanitizeToolName() covering edge cases

This ensures tool names sent to Bedrock are always valid, while maintaining
proper tool execution with the correct original MCP tool IDs.
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.

1 participant