Tools: how they get called

The model decides when to use a tool. The host makes the call and hands the result back.

  1. 1You ask “What is 48213 + 97356?”. The host sends your message plus the tool list to the model.
  2. 2The add tool’s description matches, and a tool gets the arithmetic exactly right. The model replies with a request to call it, with arguments that fit the schema.
  3. 3The host asks you to approve the call, then sends tools/call to the server.
  4. 4The result goes back to the model, which writes the final answer.

Annotations are hints, not guarantees

Annotations like readOnlyHint and destructiveHint help the host decide whether to ask for your approval before running a tool. Nothing enforces them: a tool marked read-only can still delete data, so if you write the server, make sure each tool's code matches its hints.
host → server: tools/calljson
{  "jsonrpc": "2.0", "id": 2,  "method": "tools/call",  "params": {    "name": "add",    "arguments": { "a": 48213, "b": 97356 }  }}
server → host: resultjson
{  "jsonrpc": "2.0", "id": 2,  "result": {    "content": [{ "type": "text", "text": "145569" }],    "structuredContent": { "result": 145569 },    "isError": false  }}
content
What the model reads: text, images, audio or resource links
structuredContent
Optional typed JSON that matches the tool’s outputSchema
isError
true when the tool failed, so the model can retry or explain

8 / 28