Skip to main content
    All shows

    Thursday, October 29 · 29 min

    Tool Design & MCP Integration

    0:00-:--
    Speed

    Transcript

    Koko: Here is the single question that unlocks Domain Two: when you look at a tool your agent can use, what are you actually evaluating? Not what it can do — what it should do, who should hold it, what it costs to run, and what happens when it breaks. That four-part lens is the whole domain.

    Chris: So the exam is testing whether you think about tools as controlled things with specific purposes and failure modes, not just as capabilities you bolt on.

    Koko: Exactly. And Domain Two is about eighteen percent of the exam — just under a fifth — so it is worth taking seriously. The core problem it covers is: how do you give a model the ability to reach outside its own knowledge safely? Web search, a data API, a file read, a scraper — all of that.

    Chris: And the word 'safely' is doing real work there. It is not just 'can the model call a tool,' it is 'should this agent have this tool at all, and what guardrails are around it.'

    Koko: Right. Now, there are two ideas that genuinely surprise people when they first hit this domain. The first one sounds almost obvious once you hear it, but it trips up a lot of candidates. Ready?

    Chris: Go ahead.

    Koko: The words that describe a tool matter more than its plumbing. A model decides which tool to reach for entirely from your description. Not from the code underneath, not from the function signature — from the text you wrote explaining what the tool does.

    Chris: Which means a perfectly functional tool is useless if it is described badly, because the model will either skip it or misapply it.

    Koko: Exactly. Think of it like a menu at a restaurant. The kitchen can make anything, but if the menu says 'item seven' and nothing else, nobody orders it. The description is the interface, full stop.

    Chris: And the trap the exam sets is probably an answer where someone has a well-implemented tool but a vague or generic description, and it looks fine on the surface.

    Koko: Precisely — the trap is assuming that implementation quality is what makes a tool good. It is not. Description quality is what makes a tool usable. The exam will show you a tool that works perfectly in isolation and ask why it is underperforming in an agent, and the answer is almost always the description.

    Chris: What is the second surprising idea?

    Koko: MCP — the Model Context Protocol — is a standard, not a product. Newcomers treat it like a specific piece of software you install. It is actually a protocol: a shared agreement about how tools and models talk to each other. That distinction matters on the exam.

    Chris: So questions about MCP are really questions about the protocol's rules and boundaries, not about a particular vendor's implementation.

    Koko: Correct. And we will go deep on MCP mechanics in a later module. For now, the one instinct to carry through everything: when a question shows you a tool, ask four things. Is it well-described? Is it least-privilege — does only the agent that needs it have it? Are tools tried in order of cost, cheapest first? And does it fail gracefully into a structured result rather than crash? Purpose, privileges, cost order, graceful failure. That is the lens the exam rewards, and we are going to test every concept in this domain against it.

    Koko: So the first thing the exam hammers on is tool descriptions, and the mental model shift is this: a tool description is not documentation for a human. It is operational input to the model. The model decides which tool to call entirely from that text.

    Chris: Right — so if the description is vague, the behavior is vague. It's not that the model ignores a bad description, it's that it obeys it faithfully and the result is unpredictable.

    Koko: Exactly. Think about handing a contractor a drill and walking off versus saying 'you are the researcher; when you need current facts, use the search tool; trace every claim to a source.' Same tool, completely different outcomes.

    Chris: And a concrete constraint like 'at most two searches' in the description actually shapes how the model plans its work.

    Koko: That's the instinct the exam rewards: a good description states the purpose, the when-to-call, the when-not-to-call, and at least one concrete constraint. It reads like prompt copy, not a README.

    Chris: What about the case where two tools could plausibly handle the same request? Say a lookup tool and a search tool — how does the description fix that?

    Koko: Their descriptions have to draw the line between them. Something like 'use lookup when the answer is in the local database; use search only when you need information not in the database.' If both descriptions are silent on the boundary, the model picks arbitrarily.

    Chris: So the description is doing the disambiguation work that the model can't do on its own.

    Koko: Perfectly put. The trap here is thinking a longer or more technical description is automatically better. A crisp 'use this when X, not when Y' beats a paragraph of prose every time.

    Koko: Now separate from the prose description, there's the structured definition — the name, the type, and crucially, usage limits like a max-uses cap. If the description is the story of the tool, the definition object is the wiring, with a built-in fuse.

    Chris: So a cap of five on a search tool means the model physically cannot call it a sixth time, regardless of what it wants to do.

    Koko: Right. It cannot loop forever and run up the bill. The cap is in the structure, not in the prose.

    Chris: And you only attach a tool to the agents that actually need it. An agent whose job is purely synthesis gets no search tool passed to it at all.

    Koko: That's the instinct: restraint is a limit you set, not a personality you request. The trap here — and this one shows up constantly — is 'give the model the tool and hope it uses it sparingly.' Hoping is not an architecture. The usage cap and withholding the tool entirely are the architecture.

    Chris: So 'please use search judiciously' in a system prompt is just a polite suggestion, and the exam knows the difference.

    Koko: The exam absolutely knows the difference.

    Koko: Last concept in this section: tool choice. By default the model decides whether and which tool to call. Tool choice lets you override that — let it choose freely, require that it calls some tool, require a specific named tool, or forbid tools entirely for that turn.

    Chris: So it's a dial from 'driver's discretion' all the way to 'take this exact exit' or 'no stopping.'

    Koko: Perfect analogy. In an extraction step on a supported model, you name the extraction tool so the request always routes there. For a pure conversational reply with no side effects, you forbid tools.

    Chris: You said 'on a supported model' — what's the constraint there?

    Koko: Good catch. Some current models reject forced selection outright. On those, the workaround is: leave it on auto, use a strict schema, state clearly in the prompt when the tool is required, and then verify in your application that the call actually arrived.

    Chris: And there's a scope boundary too — tool choice only controls which tool gets requested. Your application still has to authorize, validate, and execute it.

    Koko: Exactly, and strict mode — not tool choice — is what constrains the inputs. Those are four separate jobs: selection, schema conformance, authorization, execution. The exam will try to collapse them. The instinct is to keep them separate and use each control for its own job.

    Chris: The option sitting next to the right answer will say 'leave tool choice on auto and the model will figure it out.' That works until correctness actually depends on a specific tool being called or not called.

    Koko: And at that point auto with no check has reintroduced exactly the variability you needed to remove. That's the trap. Know when 'usually' has to become 'must,' and reach for the right dial.

    Koko: So we have tools, we have agents — now the question is who gets what. And the answer is: deliberately, minimally, and written down somewhere explicit. Think of several specialists sharing one office. You do not hand all of them the master key ring just because it would be convenient.

    Chris: Right — default to none, then grant up by job description. So in that five-agent example from the notes, four agents are pure reasoning over text the user pastes in, so they get zero external tools, and only the web researcher is in the allow-set for the search tool.

    Koko: Exactly. And that allow-set lives in one centralized mapping — not scattered across each agent's config — so it cannot drift.

    Chris: The same logic applies to the dangerous tools too. Delete-records or send-email goes only to the one agent whose job actually requires it, and the power to spawn other agents stays with the orchestrator alone.

    Koko: That's it. The instinct the exam rewards is: distribute by need, default to none, keep the mapping explicit and centralized. Two payoffs — least privilege shrinks the blast radius of any single misfire, and it sharpens the audit trail because you can see exactly who had access to what.

    Chris: The discriminator I'd want to nail down: what specifically makes the centralized-list part load-bearing? Because you could imagine each agent just declaring its own tools.

    Koko: Good question. If each agent declares its own tools the mapping drifts — someone adds a tool locally, no one notices, and you have lost the audit trail. One explicit list means one place to review, one place to tighten. The trap the exam sets is the argument that giving every agent every tool is simpler and more flexible. It sounds reasonable, but it is an over-grant: any agent can now take any action, which is a security risk, and agents start calling tools they have no business calling, which is also a cost risk.

    Chris: Moving to external services — the pattern I read in the notes is wrap each provider behind a uniform interface and try them in order: cheap-and-deterministic first, expensive-and-model-driven last.

    Koko: Yes. The analogy is calling the reliable supplier first. Only when everyone else is out of stock do you phone the premium concierge. In code that means: try the cheap deterministic API, then a second one, then the model's own web search as the expensive last resort — each layer returns the result or null so the next layer gets its turn.

    Chris: The null return is what makes the chain composable. If any provider threw instead of returning null, the whole fallback collapses.

    Koko: Exactly — and every external call is time-bounded, so a slow provider does not stall the chain indefinitely. Now here is the part that catches people: a scraper that suddenly fails because a site is blocking it. The instinct is to treat that as a configuration problem.

    Chris: Switch the render engine to one whose egress addresses are not blocked, adjust the headers or timeouts — not rewrite the logic. Changing the route before rebuilding the truck, as you put it.

    Koko: Right. The trap is the opposite ordering on both counts. The option next to it on the exam will say: reach for the most powerful flexible tool first, and when a scrape is blocked, re-engineer the code. Both invert the actual hierarchy — cost ladder inverted, and what is really a configuration fix gets treated as a logic bug.

    Chris: The error design section — the core rule is that a tool should never throw and take the whole run down. It returns a structured result or a logged skip, because partial success is a first-class outcome.

    Koko: That is a really good way to put it. The analogy I like: one jammed printer on a floor of twenty reports 'I am out of toner.' It does not trip the building's main breaker. A fetcher pulling twenty independent datasets per company returns null and logs for the one endpoint that fails, stores the other nineteen, and reports a per-dataset tally.

    Chris: And the errors have to be distinguishable. The notes give the example of an access gate returning one code for 'server misconfigured' versus a different code for 'wrong secret' — because those require completely different responses from the caller.

    Koko: Exactly. The model is the caller that has to reason about the error, so you hand it an in-band structured signal — a status field, a tally, a distinguishable code — not a raw stack trace. Retry the transient case, fix the validation case, escalate the permission case. Distinguishable failure signals beat a generic crash.

    Chris: The trap here being the instinct that throwing makes the problem more visible.

    Koko: Right — and the trap sounds principled, which is why it is dangerous. One throwing sub-call takes down the entire run and loses every dataset that did work. Visibility through throwing is not worth destroying partial success. The exam rewards the instinct that failure is data, not an exception.

    Koko: So the input schema is a contract — the model has to satisfy it, which means if you design it badly, you are essentially forcing the model into a corner. The classic bad design is everything required, every enum closed. No escape hatches.

    Chris: And a closed enum with nothing required to be absent — if the model encounters a case that does not fit any option, it has nowhere to put it. It has to pick the closest wrong answer.

    Koko: Exactly. That is the trap — everything required plus closed enums manufactures hallucinations. The model is not misbehaving; you built a schema that gives it no honest exit. Think of a paper form that has no N/A box and no 'other' line. Someone has to write something in every blank, so they guess.

    Chris: So the fix is: genuinely optional fields get marked nullable, so the model can express 'this was absent,' and enums get an escape — an 'other' member or a companion free-text field.

    Koko: That is it. The instinct the exam rewards is: design once for inputs you have not seen yet. Nullable optionals, extensible enums. An extraction schema that does this lets the model report missing data honestly and file an unforeseen category without inventing one that fits.

    Chris: The option sitting next to it on the exam will say something like 'mark all fields required to enforce completeness' — which sounds rigorous but actually just pushes fabrication downstream.

    Koko: Right. Rigor at the schema level, hallucination at the output level. Not the trade you want.

    Koko: Alright, MCP. First thing: MCP is a standard, not a product. That distinction matters more than it sounds.

    Chris: It is the Model Context Protocol — a common interface for exposing tools and data so any MCP-speaking client can talk to any MCP server without custom wiring. USB for AI is how I think about it. One connector shape, works everywhere.

    Koko: Perfect analogy. Integrate a capability once, reuse it with any client. The trap is treating MCP as a specific app you install — or, and this one is equally dangerous, conflating it with agent-to-agent messaging. MCP is the protocol between an agent and its tools and data. Two agents talking to each other is a different layer entirely.

    Chris: So the exam question that frames MCP as 'the protocol for agents coordinating with each other' is a distractor.

    Koko: Hard distractor, yes. Now, configuration scope — three levels. Walk me through them.

    Chris: Project-scoped config lives with the repo, shared with everyone on it. User-scoped is personal, spans all your projects. And local — the default — is personal and applies to one project only.

    Koko: Good. And secrets?

    Chris: Environment variables or a secret store referenced by config. Never hard-coded into the shared project file, because that commits the credential to the repo.

    Koko: The instinct: keep server secrets in env, not shared config. The trap there is subtle — it is not 'ignore secrets,' it is 'put them somewhere that looks reasonable but travels with the repo.'

    Koko: Last piece: MCP servers expose two distinct things — tools and resources — and mixing them up is a design error, not just a naming choice.

    Chris: A tool is an action the model invokes, potentially with side effects. A resource is readable content — a document, a record, a catalog entry — that the model pulls into context as reference material.

    Koko: Power tool versus reference binder. One acts on the world, one you read. What does the example look like in practice?

    Chris: Reference documents are exposed as resources. Something like 'submit an order' is a tool. That keeps the tool list to genuine actions only.

    Koko: And that matters because the action surface is what you lock down for least-privilege. If read-only reference is dressed up as a tool, you have cluttered that surface and blurred the boundary. The trap is modeling everything as a tool — it feels simpler until you are trying to audit what has side effects.

    Chris: So the instinct is: if it does something, tool. If you are reading it for context, resource.

    Koko: That is the whole discriminator. Action with side effects — tool. Readable reference — resource. Hold that line and your action surface stays clean and auditable.

    Koko: Let's run some scenarios. Here's one that shows up on the exam in different costumes: an agent has two similar tools — one checks order status, one starts a refund — and it keeps initiating refunds when the user just asked where their package is. What's the first thing you look at?

    Chris: The tool descriptions. If the model is picking the wrong one, the boundary between the two tools isn't drawn clearly enough in the descriptions.

    Koko: Exactly. And here's where the exam is sneaky — the trap answer is 'add more technical detail to the descriptions.' More detail sounds rigorous. But technical detail isn't the fix.

    Chris: Right, because the model isn't confused about how the refund works — it's confused about when to use it versus when not to.

    Koko: That's the whole thing. The model selects almost entirely from the description, so the description has to state purpose and, critically, when to use this tool and when not to. You need the boundary made explicit — something like 'use this for status checks, do not use this if any action on the order is required.'

    Chris: And on models that support it, you can go further and force or forbid a specific tool for a given step — so the status-checking step literally cannot call the refund tool.

    Koko: Yes — forced selection controls which tool gets requested. The application still authorizes and executes it, that distinction matters. But there's a second layer here even before you get to forced selection. What's the least-privilege answer?

    Chris: The refund tool shouldn't be in the allow-set for a status-checking agent at all. If that agent's job is checking status, it has no business seeing a refund tool.

    Koko: Perfect. Scoping the allow-set means a status question can't reach the refund tool even if the description is imperfect. Defense in depth.

    Koko: Second scenario. An agent needs data from an external source, but one provider is expensive, one is a scraper that gets blocked, and right now one failing endpoint is throwing an exception and taking the entire run down. Three problems layered on top of each other. Where do you start?

    Chris: The architecture. You want a single clean interface that abstracts all the providers, ordered by cost and reliability — cheapest and most deterministic goes first, something like the model's own web search as an expensive last resort.

    Koko: Good. Each provider fails to null so the next one runs — the interface handles the fallback, not the caller. Now the scraper getting blocked — what kind of problem is that?

    Chris: A configuration problem first. Before you touch any logic, you try switching the render engine or the headers. Most blocking is fingerprint-based, not a fundamental barrier.

    Koko: The exam will offer 'rewrite the scraping logic' as the adjacent option. That's a code change when a config change is the right move. Now — the throwing endpoint that crashes the whole run. That's the one I want to land carefully.

    Chris: Each provider needs to return a structured error, not throw. So if one endpoint fails, it logs a skip and the run continues with whatever did succeed.

    Koko: And the run reports a tally — three sources tried, two succeeded, one skipped. Partial success is a first-class outcome. The trap the exam sets is treating anything less than full success as a crash condition — failing closed when the data you did get is still useful.

    Chris: So the instinct is: structured errors over exceptions, fallback chains over brittle single sources, and partial results over all-or-nothing.

    Koko: That's the whole scenario in one sentence. Keep that.

    Koko: So let's do the thing where we actually compress all of this into exam-ready instincts — because when you're staring at a question under time pressure, you don't want to reconstruct the reasoning from scratch. You want the reflex.

    Chris: Right. And the one I keep coming back to is the description instinct. The description is the selection mechanism. Not documentation, not a label — it's prompt copy that tells the model when to reach for this tool and, critically, when not to.

    Koko: Exactly. And that when-not is what disambiguates overlapping tools. If you have two tools that could plausibly apply, the description is the only thing doing the routing. Get that wrong and the model guesses.

    Chris: Then restraint — enforced, not requested. Usage caps, withhold the tool entirely. The exam will have an option that says something like 'instruct the model to use the tool sparingly.' That's the soft version.

    Koko: And the exam rewards the hard version. You don't ask for restraint, you build it in structurally. Same logic with tool choice — it turns a tendency into a guarantee, but only where the model supports it. Name the tool when one must be called, or exclude tools entirely for a clean text reply.

    Chris: And the trap there — I've seen this framing in practice questions — is assuming tool choice is how you constrain the schema. It's not. Strict inputs constrain the schema. Tool choice controls which tool fires.

    Koko: Sharp distinction. Keep those two separate in your head. Now, least privilege.

    Chris: Default none. Each agent gets only what its job requires. And the mapping is centralized — one place tracks who has what.

    Koko: Good. And when you're wrapping external services — order the fallback cheap to expensive. Try the local cache before the paid API. Each leg fails to null, not to an exception. And here's the one people miss: if a service is blocked, treat that as configuration first, not a code problem.

    Chris: That framing really clicked for me. A block means someone made a policy decision — figure out what it is before you try to route around it.

    Koko: Exactly. Then graceful failure — structured, in-band errors. The tool returns a result, even if that result is 'this failed and here is why.' It does not throw and take down the run.

    Chris: And schemas — nullable and extensible so the model can say 'absent' rather than inventing a value. Required fields without a null option are an invitation to hallucinate.

    Koko: That's the one that connects directly to reliability in production. Okay, MCP — one sentence.

    Chris: Open standard, agent-to-tool plug format. Tools are for actions, resources are readable reference data. Secrets come from environment variables, never shared config.

    Koko: That's it. So the through-line for the whole domain — when two answers are competing, ask: which one describes the tool clearly, hands it only where it's needed, tries cheap before expensive, and fails into a result rather than a crash? That answer wins. Every time.

    Chris: Purpose, privilege, cost order, graceful failure. I'm writing that on the back of my hand.

    Koko: The goal isn't to prevent every misfire. The goal is to design so a single misfire stays small. Keep drilling with the flashcards and the quiz at KokoAI Academy — koko knows dot A I. Domain two is eighteen percent. That's worth owning.

    Koko: Alright, final stretch. Let's lock in the handful of things that separate a pass from a near-miss on Domain Two.

    Chris: I want to start with tool descriptions because that one comes up constantly. The rule is: the description is the primary signal the model uses to pick a tool. So vague descriptions mean misrouting.

    Koko: Exactly. Think of a description like a job posting. If it just says 'does data stuff,' every candidate applies. You need input formats, example queries, edge cases, and crucially — when to use this one versus the similar one sitting next to it.

    Chris: And the fix when a generic tool's contract is too fuzzy is to split it into purpose-specific tools with clear contracts. But the exam will also test the flip side — don't split when operations are closely related. Those stay on one tool with an action parameter.

    Koko: Right. Split on purpose, not on verb. The trap is splitting 'create order' and 'update order' into two tools when they belong together. Fix the description or the schema — that's the recurring right answer on this domain.

    Chris: On errors: the structured error shape has an isError flag, an errorCategory — transient, validation, business, or permission — an isRetryable boolean, and a human-readable description. The discriminator I always remind myself of is: an access failure is retryable, but a valid empty result is not an error at all.

    Koko: That distinction will absolutely be on the exam. An empty search result is not a failure. Mark it as one and you've misled the agent. Now, tool count — what's the instinct there?

    Chris: Scope each agent to its role. Eighteen tools on one agent degrades selection. Four or five focused tools is the target.

    Koko: And when you need to steer selection, you use tool_choice — auto, any, a named tool, or none to forbid tools for that turn entirely. One thing the exam likes to test: who actually authorizes and executes the call?

    Chris: The application, not tool_choice. Tool_choice controls what the model requests. Authorization and execution live in the application layer.

    Koko: Good. MCP config — the two files have distinct scopes. Dot-mcp-dot-json is project-scoped and committed for shared team tooling. User-scoped personal servers live in tilde-slash-dot-claude-dot-json. And secrets go in as environment-variable expansion — dollar-sign curly brace GITHUB_TOKEN curly brace — nothing committed in plaintext.

    Chris: MCP resources expose content catalogs, which cuts down exploratory tool calls. That's the efficiency angle.

    Koko: Exactly. And the built-in tools each have a lane: Grep searches file contents, Glob matches file paths, Read and Write handle full files, Edit does targeted changes. When Edit's anchor isn't unique, add surrounding context — or fall back to Read plus Write.

    Chris: The trap on Edit is reaching for it when the anchor is ambiguous and not adding context. The option next to the right answer will say just run Edit anyway.

    Koko: And the right answer is always least privilege, clear contracts, structured errors, and fix the description. Those four instincts cover most of Domain Two. You've done the work — carry those in and trust them. Keep drilling with the flashcards and the practice quiz at KokoAI Academy, that's koko-knows-dot-A-I. You've got this.