fix(core): accept 128-character tool names (#51207)

This commit is contained in:
Aiden Cline
2026-09-24 14:59:57 -05:00
committed by GitHub
parent 8118690839
commit 03be7f385b
3 changed files with 25 additions and 4 deletions
+1 -1
View File
@@ -308,7 +308,7 @@ function registrationError(tool: Tool.Info) {
if (error) return error
}
const name = normalizedName(tool)
if (!/^[A-Za-z0-9_-]{1,64}$/.test(name)) return new RegistrationError({ name, message: `Invalid tool name: ${name}` })
if (!/^[A-Za-z0-9_-]{1,128}$/.test(name)) return new RegistrationError({ name, message: `Invalid tool name: ${name}` })
const id = effectiveName(tool)
if (tool.options?.codemode === false && id === "execute")
return new RegistrationError({ name: id, message: 'Tool name "execute" is reserved for CodeMode' })
+2 -2
View File
@@ -2117,7 +2117,7 @@ testEffect(Layer.empty).live("isolates invalid MCP tools and preserves plugin tr
}) satisfies Mcp.Tool
const healthy = [tool("demo", "search"), tool("other", "lookup")]
const namespace = tool("x".repeat(65), "lookup")
const catalog = yield* Ref.make([tool("demo", "x".repeat(65)), ...healthy, namespace])
const catalog = yield* Ref.make([tool("demo", "x".repeat(129)), ...healthy, namespace])
yield* Effect.gen(function* () {
const registry = yield* Tool.Service
@@ -2146,7 +2146,7 @@ testEffect(Layer.empty).live("isolates invalid MCP tools and preserves plugin tr
editor.remove("repaired_lookup")
})
yield* Ref.set(catalog, [tool("demo", "y".repeat(65)), ...healthy, tool("demo", "added"), namespace])
yield* Ref.set(catalog, [tool("demo", "y".repeat(129)), ...healthy, tool("demo", "added"), namespace])
yield* bus.publish(McpEvent.ToolsChanged, { server: "demo" })
yield* waitForTool(registry, "demo_added")
expect((yield* toolDefinitions(registry)).map((tool) => tool.name)).toEqual([
+22 -1
View File
@@ -329,7 +329,7 @@ describe("Tool", () => {
{
before: make(),
"": make(),
["x".repeat(65)]: make(),
["x".repeat(129)]: make(),
"echo.tool": constant("first"),
echo_tool: constant("last"),
execute: make(),
@@ -346,6 +346,27 @@ describe("Tool", () => {
}),
)
it.effect("registers 128-character MCP tool names in Code Mode", () =>
Effect.gen(function* () {
const service = yield* Tool.Service
const name = "x".repeat(128)
yield* transform(service, { [name]: make(), ["x".repeat(129)]: make() }, { namespace: "cloudflare" })
const snapshot = yield* service.snapshot()
expect(codeModeListings(snapshot.codeModeCatalog!).map((tool) => tool.path)).toEqual([`cloudflare.${name}`])
const result = yield* snapshot.execute({
...call("execute"),
call: {
type: "tool-call",
id: "call-long-mcp-name",
name: "execute",
input: { code: `return (await tools.cloudflare[${JSON.stringify(name)}]({ text: "hello" })).text` },
},
})
expect(result.content).toEqual([{ type: "text", text: "hello" }])
}),
)
it.effect("executes native tools without requiring letter-leading names or namespace segments", () =>
Effect.gen(function* () {
const service = yield* Tool.Service