Try this first

Look at the tool from Lesson 1.7 again, and count the parts:

{
    "name": "read_file",
    "description": "Read a text file from the current folder and return its contents.",
    "input_schema": {
        "type": "object",
        "properties": {
            "path": {"type": "string", "description": "The name of the file"}
        },
        "required": ["path"],
    },
}

Three things go to the model: a name, a description, and a schema.

A fourth thing does not go to the model at all: your read_file function. The model never
sees it. It has no idea how the tool works, only what you said it does.

The split that matters

Part Who reads it What it decides
name The model How it refers to the tool
description The model Whether to use it at all
input_schema The model What arguments to send
Your function Only your code What actually happens

The model is choosing from a menu written by you, in English, with no way to test anything.
It cannot call the tool to see what it does. It cannot read your source. It reads the
description and decides.

That is why this module is mostly about writing.

What the schema is for

input_schema is JSON Schema. You are describing the shape of the arguments.

"input_schema": {
    "type": "object",
    "properties": {
        "path": {
            "type": "string",
            "description": "The file to read, for example notes.txt",
        },
        "max_lines": {
            "type": "integer",
            "description": "Stop after this many lines. Leave out to read the whole file.",
        },
    },
    "required": ["path"],
}

Two habits to start now.

Describe every property. A property with no description is a guess. max_lines without
a description could mean lines from the start, lines from the end, or a page size.

Mark only what is truly required. Everything in required must be sent every time. If a
sensible default exists, leave the property optional and apply the default in your function.

enum is the strongest tool you have

When a parameter has a fixed set of valid values, say so:

"sort_by": {
    "type": "string",
    "enum": ["name", "size", "modified"],
    "description": "Which field to sort the file list by.",
}

This does more than document. It removes a whole class of failure, because the model now has
three options rather than an open field. Whenever you catch yourself writing “must be one of”
in a description, that is an enum.

The model chooses a tool by reading a sentence you wrote. Everything else in this module
follows from that.

Try this before the next lesson

Take your read_file tool and add an optional max_lines parameter, with a description.
Implement it in the function.

Then ask Rover: “Show me the first two lines of notes.txt.” Watch whether it sends
max_lines. You did not tell it to. It read the schema and worked out that the parameter
matched the request.