Lesson 13 · Designing a reviewed tool surface
From cognokratos/tauros-revenue · docs/course/13-reviewed-tool-surface.md · pinned revision facbbc927eb4
Part IV: AI capability · Course map · Next: Lesson 14
Goal
Design what a model is offered: an exact list, bounded outputs, strict inputs, and money that never becomes a float.
Concept
Note
Book edition note. Precisely: JSON floats are refused anywhere in the arguments. JSON integers are exact and are accepted (
strict_arguments.ex). Amounts are still decimal strings.
Eight tools: four reads, four proposals. The list is exact and reviewed
(Tauros.Authority.mcp_tools/0). Outputs are chosen (select/load): no
customer email, no approver identities, no full history. Inputs are strict:
unknown arguments are errors, at the top level and inside input, and JSON
numbers are refused because they arrive as IEEE floats. Amounts are decimal
strings.
Code to inspect
lib/tauros/revenue.ex, thetoolsblock: descriptions say what each tool does not dolib/tauros_web/mcp/strict_arguments.ex: accepted names read from the published schematest/tauros/mcp_tools_test.exs: invariants A and B, and the schema contract
Run it
mix test test/tauros/mcp_tools_test.exs test/tauros_web/mcp/strict_arguments_test.exs test/tauros_web/mcp/tools_test.exs
Break it
Add a tool that is agent-safe but not reviewed, then run the allowlist test:
# lib/tauros/revenue.ex, inside `tools do`
tool :deactivate_payment_destination, PaymentDestination, :deactivate
Also send {"id": "…", "state": "approved"} to submit_invoice, and an amount
as a number (Exercise 10).
Why it fails
McpToolsTest compares the declared, routed and served tools with the
reviewed list for equality; inclusion in agent_safe is not enough.
StrictArguments answers "Unknown arguments for submit_invoice: state.
Accepted arguments: id" and refuses the float with its path. Remove the
tool afterwards.
What to remember
- The tool list is a review, enforced by an equality test.
- Bound what a model sees; refuse what you did not declare.
- Money crosses JSON as strings.