Claude Tool Use: Requests, Execution and Results
A client tool is a function your application executes. Claude proposes a tool name and structured arguments; the server decides whether the operation is allowed. Provider-managed server tools have a different execution boundary.
#Define one narrow tool
This tool declaration is a request fragment. It describes a read-only lookup in a fictional order dataset.
json{ "name": "lookup_demo_order", "description": "Read shipping status for a fictional demo order. Does not change orders.", "input_schema": { "type": "object", "properties": {"order_id": {"type": "string", "enum": ["DEMO-104"]}}, "required": ["order_id"], "additionalProperties": false } }
A schema helps the model form arguments. It does not replace server-side validation, identity checks or authorization.
#Complete the loop
- Send the user task and allowed tool definitions.
- Receive the assistant response and retain its content blocks unchanged.
- For each
tool_useblock, validate its name and input, then execute the allowed function. - Add a user message containing a
tool_resultwith the matchingtool_use_id. - Request the next response, stopping at a final answer or a strict step/time budget.
Example result fragment, with an illustrative identifier to be replaced by the actual returned tool ID:
json{ "role": "user", "content": [{ "type": "tool_result", "tool_use_id": "RETURNED_TOOL_USE_ID", "content": "{\"order_id\":\"DEMO-104\",\"status\":\"packed\",\"data_type\":\"fictional_fixture\"}" }] }
If several tools are requested, match every result to its own ID. For a failed tool, return an appropriate error result rather than fabricating success. Treat returned web text and documents as untrusted data.
#Guard side effects
Use an allowlist; reject unknown tool names. Never evaluate arbitrary expressions with eval. Keep file operations within an approved workspace. Writes, payments and messages need authorization checks and idempotency at the execution layer. A second model instruction is not an access-control system.
Test the handler with local fixtures first: invalid order ID, missing arguments, timeout, duplicate invocation and unauthorized identity. Model calls are not required to test these boundaries.