PhoenixKit.API.MCP.Names (phoenix_kit v2.64.1)

Copy Markdown View Source

Tool names on MCP.

Some model APIs accept only [a-zA-Z0-9_-] in tool names, so MCP shows every tool with _ where the name has a . (catalogue.set_prices is catalogue_set_prices). REST and OpenAPI keep the dotted name, and tools/call accepts both.

Two tools of one audience can map to the same MCP name (a.b_c and a_b.c). PhoenixKit.API.ToolLint.check_tools/1 reports that in a module's tests; at run time the first one in registry order wins, in dedupe/1 and in resolve/2. dedupe/1 works on the list the caller may see and resolve/2 ignores scopes, so when the two tools need different scopes a key that holds only the second one sees the second tool in tools/list, while tools/call with the underscore name reaches the first and is refused. The dotted name always reaches its own tool.

Summary

Functions

Drops every tool whose MCP name an earlier tool of the list already has.

The dotted name for name, which may be given in either form.

The MCP form of a tool name.

Functions

dedupe(tools)

@spec dedupe([PhoenixKit.API.Tool.t()]) :: [PhoenixKit.API.Tool.t()]

Drops every tool whose MCP name an earlier tool of the list already has.

resolve(name, audience)

The dotted name for name, which may be given in either form.

A name that has a . is returned as it is. An underscore name is mapped to the dotted name of a tool of audience: a live one, or one whose module is switched off (so that PhoenixKit.API.Executor can say module_disabled instead of not_found). That is decided by PhoenixKit.API.Registry.find/2, which looks at the audience, so the answer for a tool of the other audience, a tool hidden by api_disabled_tools, a tool of a module switched off in api_disabled_modules and a name nobody has is the same: the name comes back unchanged. An anonymous caller of the public endpoint can therefore not learn the dotted name of an admin tool, or that it exists.

Whether the tool is visible to the caller, permitted or enabled is the executor's answer.

to_mcp(name)

@spec to_mcp(String.t()) :: String.t()

The MCP form of a tool name.