What Can It Do — Write the List Down and the Client Belongs to One Server
5 minPart 1 attached. Now it asks.
Two lines
final tools = await client.listTools();
stdout.writeln('tools: ${tools.map((t) => t.name).join(", ")}');
for (final t in tools) {
stdout.writeln(' ${t.name} — ${t.description}');
}
final resources = await client.listResources();
stdout.writeln('resources: ${resources.map((r) => r.uri).join(", ")}');tools: desk.admit
desk.admit — Admit a number of people from the queue
resources: ui://desk, desk://waitingWrite it down and it belongs to one server
You could write this instead.
// this server has desk.admit
await client.callTool('desk.admit', {'count': 1});It runs. And at that moment this client belongs to that server. One tool name in the code and it cannot stand in front of anything else.
Asking is different. The list arrives at runtime, so the client does not need to know what it attached to. Attach to a board and led.set comes back; attach to the desk and desk.admit does. Same code.
This is where the description gets used
listTools() does not return names alone. The description and input schema come with them.
desk.admit — Admit a number of people from the queueA human-facing client builds a button label and a tooltip from it. A model reads it to decide what to call. What server part 2 called "not a comment but running code" is consumed here.
Resources arrive as uris
resources: ui://desk, desk://waitingui:// is a screen and desk:// is a value. Not something the contract dictates — a naming rule the server chose. The client does not need to know it; in part 4 it just uses a uri from the list.
Verification — hardcoding fails
This piece claims the client asks rather than being told. So the check reads the client's code.
grep -q 'tools: .*desk.admit' captures/s2.txt || die "tools not discovered"
grep -q 'resources: .*ui://desk' captures/s2.txt || die "resources not discovered"
# The claim is that the client was not told; it asked.
grep -q "'desk.admit'" bin/step2.dart && die "the tool name is hardcoded in the client"One occurrence of the tool name in bin/step2.dart and it fails.
Run it yourself
dart run bin/step2.dart
bash verify.shWhat to take
listTools()andlistResources()— the surface arrives at runtime- Do not write names down — writing one makes it a single-server client
- A no-hardcoding check — stops this claim breaking quietly
Next
Call a tool. And learn that a refusal is not an exception.
Run the sample
cd course-client dart pub get dart run bin/step2.dart