« Track Overview · Warmup · Hitchhiker's · Deep Dive · Principal Deep Dive · Core Contributor · Staff Notes

Phase 02 — MCP: The Tool Plane and the Bank's Tool Estate

Answers these JD lines: "Model Context Protocol (MCP) for agent-to-tool access" · "Engineer the platform's tool layer and MCP server estate, including tool packaging, versioning, capability advertisement, schema enforcement, and runtime tool discovery across Wholesale, Retail, and Group functions."

Why this phase exists

MCP is the easy half. It is a well-specified JSON-RPC protocol that you can implement in an afternoon, and doing so removes a real problem: without it, every agent framework integrates with every tool separately, and a bank with 12 agent teams and 60 systems has a combinatorial mess.

The hard half is what the protocol deliberately leaves out. MCP has no authorization model, no versioning story, no tenancy, and no governance. It tells you how to say "here are my tools" and "call this one." It says nothing about whose tools, which version, may you, or what happens when the schema changes underneath a running agent.

For a bank that is not a gap in the spec — it is the correct division of labour. A wire protocol should not encode your control model. But it does mean that "we use MCP" is not a tool strategy, and a candidate who says it as though it were will not pass this interview.

Five ideas carry the phase:

  1. The tool description is prompt surface. The model reads it to decide what to call. It is the most-read text in your platform, it is where selection accuracy comes from, and it is emphatically not the place for platform metadata.
  2. Discovery must be authorization-aware. tools/list is answered relative to a principal. A tool an agent may not call must not appear at all — its name and description are themselves information, and a model that can see a tool will eventually try it.
  3. Protocol errors and tool errors are different things. A schema violation is a JSON-RPC error that never reaches the tool. A downstream failure is a successful response carrying isError: true, so the model sees it and adapts. Collapsing the two either hides real failures or turns typos into outages.
  4. Versioning is about who breaks. Adding a required field breaks callers; removing one does not. Narrowing an enum breaks; widening does not. That asymmetry is the whole rule, and a registry that enforces it prevents the most common estate-wide outage.
  5. Every tool declares a side-effect class, and the platform derives retry policy from it. Retry is not a per-call-site decision made by whoever wrote the agent.

Concept map

  • JSON-RPC 2.0: request/response/notification, id semantics, the reserved error codes (-32700 parse, -32600 invalid request, -32601 method not found, -32602 invalid params, -32603 internal).
  • MCP shape: host → client (one per connection) → server. initialize and capability negotiation · tools/list · tools/call · resources/list and resources/read · prompts/list and prompts/get · notifications/tools/list_changed.
  • Tools vs resources vs prompts: model-controlled invocation · application-controlled reading · user-controlled templates. Three different trust levels.
  • Schema enforcement: a JSON Schema subset, all-errors-at-once, paths, and the deterministic repair loop that precedes asking the model again.
  • Versioning: semver, ^/~ constraints, the patch/minor/major classification rule, immutable publication, deprecation and retirement, and the change notification that makes a window work.
  • The estate: side-effect class, required scopes, data classification, owner, tenant visibility — the metadata that turns a pile of tools into a governed catalogue.
  • Authorization-aware discovery: filter before you list; an undiscoverable tool is indistinguishable from a nonexistent one.

The lab

LabYou buildProves you understand
01 — MCP Server, Client & the Tool Estatea JSON-RPC 2.0 MCP server and client with capability negotiation, tools/resources/prompts and change notifications; a JSON-Schema validator with a deterministic repair loop; a semver registry that classifies schema changes and refuses under-bumped breaking changes; and discovery filtered by scope, tenant, classification and lifecyclethat MCP is a transport for a catalogue you still have to govern — and that the governance is where the bank's risk actually is

Integrated scenario (how this shows up at work)

The Wholesale payments team owns payments.lookup. On a Tuesday they add a required as_of argument, because the compliance team wants point-in-time answers. They deploy it as version 1.1.0 — a minor bump, because they added one small field.

Four agent teams break within the hour. Their agents call payments.lookup without as_of, get a validation error every time, and either fail or loop. The Retail collections agent, which uses the tool for a completely unrelated purpose, is the loudest.

Nothing in MCP would have prevented this. The registry in this lab does, three ways: it classifies the change as major and refuses the 1.1.0 publish; it lets callers pin ^1.0.0 so the old contract stays resolvable through a deprecation window; and it emits notifications/tools/list_changed so caching clients re-list rather than calling a tool that moved underneath them.

Deliverables checklist

  • Lab 01 green under LAB_MODULE=solution pytest and under your own lab.py.
  • You can describe the MCP host/client/server relationship and the initialize handshake.
  • You can name what MCP does not provide, and where each of those belongs instead.
  • You can explain the difference between a protocol error and a tool error, and why it matters to the model.
  • You can state the patch/minor/major rule in one sentence about who breaks.
  • You can explain why tools/list must be answered relative to a principal.
  • You can name the four side-effect classes and the retry policy each implies.

Key takeaways

  • "We use MCP" is not a tool strategy. The protocol is the easy half; the estate is the job.
  • Filter before you list. Discovery is an authorization decision, and an unentitled tool must be invisible, not merely uncallable.
  • The description is read by the model. Treat it as the highest-leverage prompt in the platform, and keep platform metadata out of it.
  • A schema violation must not reach the tool; a tool failure must reach the model. Two different channels, deliberately.
  • Callers break when the contract gets stricter. Encode that rule in the registry, not in a wiki page.
  • Side-effect class is a required field, because retry policy is derived from it and thirty teams should not each decide.