Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions src/utils/__tests__/mcp-name.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,24 @@ describe("mcp-name utilities", () => {
expect(sanitizeMcpName("test#$%^&*()")).toBe("test")
})

it("should keep valid characters (alphanumeric, underscore, dot, colon, dash)", () => {
it("should keep valid characters (alphanumeric, underscore, dash)", () => {
expect(sanitizeMcpName("server_name")).toBe("server_name")
expect(sanitizeMcpName("server.name")).toBe("server.name")
expect(sanitizeMcpName("server:name")).toBe("server:name")
expect(sanitizeMcpName("server-name")).toBe("server-name")
expect(sanitizeMcpName("Server123")).toBe("Server123")
})

it("should remove dots and colons for AWS Bedrock compatibility", () => {
// Dots and colons are NOT allowed due to AWS Bedrock restrictions
expect(sanitizeMcpName("server.name")).toBe("servername")
expect(sanitizeMcpName("server:name")).toBe("servername")
expect(sanitizeMcpName("awslabs.aws-documentation-mcp-server")).toBe("awslabsaws-documentation-mcp-server")
})

it("should prepend underscore if name starts with non-letter/underscore", () => {
expect(sanitizeMcpName("123server")).toBe("_123server")
expect(sanitizeMcpName("-server")).toBe("_-server")
expect(sanitizeMcpName(".server")).toBe("_.server")
// Dots are removed, so ".server" becomes "server" which starts with a letter
expect(sanitizeMcpName(".server")).toBe("server")
})

it("should not modify names that start with letter or underscore", () => {
Expand Down
13 changes: 4 additions & 9 deletions src/utils/mcp-name.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
/**
* Utilities for sanitizing MCP server and tool names to conform to
* API function name requirements (e.g., Gemini's restrictions).
*
* Gemini function name requirements:
* - Must start with a letter or an underscore
* - Must be alphanumeric (a-z, A-Z, 0-9), underscores (_), dots (.), colons (:), or dashes (-)
* - Maximum length of 64 characters
* API function name requirements across all providers.
*/

/**
* Separator used between MCP prefix, server name, and tool name.
* We use "--" (double hyphen) because:
* 1. It's allowed by Gemini (dashes are permitted in function names)
* 1. It's allowed by all providers (dashes are permitted in function names)
* 2. It won't conflict with underscores in sanitized server/tool names
* 3. It's unique enough to be a reliable delimiter for parsing
*/
Expand Down Expand Up @@ -40,8 +35,8 @@ export function sanitizeMcpName(name: string): string {
// Replace spaces with underscores first
let sanitized = name.replace(/\s+/g, "_")

// Remove any characters that are not alphanumeric, underscores, dots, colons, or dashes
sanitized = sanitized.replace(/[^a-zA-Z0-9_.\-:]/g, "")
// Only allow alphanumeric, underscores, and dashes
sanitized = sanitized.replace(/[^a-zA-Z0-9_\-]/g, "")

// Replace any double-hyphen sequences with single hyphen to avoid separator conflicts
sanitized = sanitized.replace(/--+/g, "-")
Expand Down
Loading