Skip to main content
OpenAI’s chat completion returns response.choices[0].message.tool_calls as a list of tool-call objects. Certior accepts that list in its native shape via verify_tool_calls() - no SDK migration, no proxy, no schema rewrite.
Runnable end-to-end demo: examples/openai_agent_demo.py. It runs live against OpenAI when OPENAI_API_KEY is set and replays a recorded sample of the tool-calls without a key, so it works keyless too. Every allow/block verdict is computed live by Z3.

The full loop

What verify_tool_calls returns

For every input tool call, you get a dict augmented with:

Per-call overrides

A call may carry its own required_capabilities / cost_cents keys that override the tool_specs map. Use this when one tool’s permission profile depends on its arguments.

Anthropic and MCP

The same verify_tool_calls() accepts Anthropic’s tool_use block list and MCP tool calls in their native shapes. The normalizer in certior.adapters.tool_use._normalize_tool_call handles each.

See also