Imp.ACP.ToolKind (Imp v0.5.0)

Copy Markdown View Source

Derives an ACP tool kind from the MCP tool annotations a server declares.

An MCP server declares what each tool does to the world: ToolAnnotations carries readOnlyHint, destructiveHint, idempotentHint and openWorldHint, and those hints travel on the wire in tools/list. The kind is computed from that declaration, so a tool a host has never heard of is still classified.

The rule

The MCP specification's own defaults apply when a hint is absent: readOnlyHint defaults to false, destructiveHint to true, and openWorldHint to true. Those defaults are consulted only when the tool declared some hint; a tool that declares none is undeclared, and this module answers nil rather than guessing.

readOnlyHint: true,  openWorldHint: true    -> "read"
readOnlyHint: true,  openWorldHint: false   -> "think"
write, destructiveHint: true                -> "delete"
write, not destructive, openWorldHint: true -> "execute"
write, not destructive, openWorldHint: false-> "edit"
no annotations, or no hints in them         -> nil

The hints answer the safety-relevant questions: does the tool change anything, and can the change be destructive. The finer ACP kinds (search versus read, edit versus execute) are presentational; a host that wants a different card declares the kind by name in :tool_kinds, which takes precedence over anything derived here. Nothing safety-relevant depends on that override.

"think" is the kind for a read that declares openWorldHint: false, a tool that touches nothing outside the process.

Summary

Functions

Derives one ACP tool kind, or nil when the tool declares no annotation hints at all.

Derives a name-to-kind map from a name-to-annotations map, dropping every tool that declares nothing to derive from.

Functions

derive(annotations)

@spec derive(map() | nil) :: String.t() | nil

Derives one ACP tool kind, or nil when the tool declares no annotation hints at all.

derive_all(annotations)

@spec derive_all(%{optional(String.t()) => map()}) :: %{
  optional(String.t()) => String.t()
}

Derives a name-to-kind map from a name-to-annotations map, dropping every tool that declares nothing to derive from.