Build

One Tool — the Description Matters More Than the Code

By makemind · Feb 6, 2026

The server from part 1 could do nothing. Attach one tool.

Four pieces

server.addTool(
  name: 'desk.count',
  description: 'How many people are waiting at the desk right now',
  inputSchema: const {'type': 'object', 'properties': {}},
  handler: (args) async =>
      CallToolResult(content: [TextContent(text: '{"waiting":3}')]),
);

And declare the capability on.

capabilities: ServerCapabilities(tools: ToolsCapability(listChanged: true))

Three of them we never read

Of the four, only handler is read by our code. The other three are all read by whoever calls.

Ask tools/list and this goes out.

{
 "tools": [
  {
   "name": "desk.count",
   "description": "How many people are waiting at the desk right now",
   "inputSchema": {
    "type": "object",
    "properties": {}
   }
  }
 ]
}

A human-written client draws a button from this list. A model decides which tool to call from it. The basis of that decision is one line of description.

So that line is not a comment. It is running code.

Naming

Use dotted names like desk.count. What it is about, then what it does.

desk.count      counts who is waiting
desk.admit      admits people from the queue
camera.settings reads the camera's settings

With three tools it looks like it does not matter. At twenty, the absence of a rule shows. And a name cannot be changed once it ships — it is embedded in the caller's code.

This content requires Developer or above

Sign in and upgrade your plan to continue reading.

View Plans
Twitter