Cairnloop.ToolRegistry (cairnloop v0.1.0)

Copy Markdown View Source

Manages registration and advisory filtering of host-injected governed tools.

Boot-time validation (validate_configured_tools!/0) ensures every declared tool implements Cairnloop.Tool and exposes a valid __tool_spec__/0. Call this from Cairnloop.Application.start/2 so a misconfigured tool fails fast at boot.

get_available_tools/2 is an advisory UX filter only — it applies scope/0 and authorize/2 as a convenience to hide unavailable tools from the UI. The authoritative gate is Cairnloop.Governance.validate/3 (D-28).

Summary

Functions

Resolves a string tool_ref to a module without using String.to_existing_atom/1 (D-19).

Retrieves available tools filtered by scope/0 and authorize/2 — advisory UX only. Cairnloop.Governance.validate/3 is the authoritative gate (D-28).

Returns all configured tools as {module, spec} tuples without any scope or authorization filtering. Used by the optional MCP seam (D17-08) to project the full tool registry for tools/list responses.

Called at application boot to validate that every tool in config implements the governed-tool contract and exposes a valid __tool_spec__/0. Raises ArgumentError if any tool fails validation (D-07).

Functions

find_tool_module(tool_ref)

@spec find_tool_module(String.t()) :: {:ok, module()} | {:error, :unknown_tool}

Resolves a string tool_ref to a module without using String.to_existing_atom/1 (D-19).

inspect(MyTool) and Atom.to_string(MyTool) both produce "Elixir.MyTool" — the string comparison is safe and does not create new atoms from untrusted input.

get_available_tools(actor_id, context)

@spec get_available_tools(Cairnloop.Tool.actor_id(), Cairnloop.Tool.context()) :: [
  module()
]

Retrieves available tools filtered by scope/0 and authorize/2 — advisory UX only. Cairnloop.Governance.validate/3 is the authoritative gate (D-28).

list_all_tools()

@spec list_all_tools() :: [{module(), Cairnloop.Tool.Spec.t()}]

Returns all configured tools as {module, spec} tuples without any scope or authorization filtering. Used by the optional MCP seam (D17-08) to project the full tool registry for tools/list responses.

Unlike get_available_tools/2 — which applies advisory scope/authorize filtering — this function returns every tool registered in :cairnloop, :tools config regardless of actor context. This is correct for MCP listing: the MCP client decides which tools to surface.

validate_configured_tools!()

Called at application boot to validate that every tool in config implements the governed-tool contract and exposes a valid __tool_spec__/0. Raises ArgumentError if any tool fails validation (D-07).