Build

A Button Names a Tool and Stops There

By makemind · Jun 10, 2026

Part 3 brought values onto the screen. The other direction is left.

There is no code in onTap

{ "type": "button", "label": "Call next", "onTap": { "type": "tool", "tool": "queue.next" } },
{ "type": "button", "label": "Take a ticket", "onTap": { "type": "tool", "tool": "queue.take" } }

onTap is { type, tool }. "Pressing this calls a tool named queue.next" is the whole of it; what that tool does is not written down.

It could not be. This file came from the server built in the server course, and that is where the work happens.

The receiving side

rt.buildUI(
  context: c,
  // The name arrives here. The host does not know what it means.
  onToolCall: (tool, params) async => fired.add(tool),
)

This is the slot left as an empty function in part 1. In a real app it holds one line from client part 3.

onToolCall: (tool, params) async {
  // The name came off the screen. It is passed straight through.
  final r = await client.callTool(tool, params);
  final state = jsonDecode((r.content.first as TextContent).text)
      as Map<String, dynamic>;
  state.forEach(rt.stateManager.set);
},

tool is passed straight through. There is no if (tool == 'queue.next') — put one in and the host needs editing every time the server grows a tool.

This content requires Developer or above

Sign in and upgrade your plan to continue reading.

View Plans
Twitter