Skip to content

resource

Chapter 13 Plan: External Tools with MCP

Read the planned learning contract for external tools with MCP in Chapter 13. Review prerequisites and proposed tasks; completed notebooks and solutions are not available yet.

Planned construction brief. The complete lesson, runnable notebooks and checkpoint are not available yet.

Status: PLANNED. This is the construction brief for a dedicated protocol lesson. Its complete manuscript, learner implementation, two runnable notebooks and checkpoint remain to be authored. The current Chapter 14 retains the existing MCP construction alongside containment until the protocol material is expanded and separated without losing teaching content.

Why Lucy needs this chapter

The dispatcher can already call a Python function. Now a useful text-analysis tool runs in another process maintained independently. We need an agreed request/response format and a bounded connection, while preserving the application's own tool permissions. A server advertising a tool cannot grant itself permission to run it.

This chapter follows worker recovery and precedes tool isolation. MCP supplies a protocol boundary; the next chapter supplies a separately configured operating-system boundary. Starting an MCP child executable does not sandbox it.

Goals and prerequisites

Bring JSON values, exceptions, time budgets, the typed dispatcher and worker ownership from preceding chapters. No JSON-RPC, subprocess, standard-stream or MCP knowledge is assumed. Start with a dictionary and a child process that echoes one controlled response before introducing the full exchange.

By the end you will be able to:

  1. Explain how request IDs associate a response with a particular outstanding call.
  2. Exchange newline-framed JSON between a parent and a controlled child process without mixing logs into protocol output.
  3. Construct initialization, explicit supported-version negotiation, tool discovery and one allowed invocation.
  4. Validate discovered schemas and returned messages before exposing their content to the model.
  5. Enforce byte, time and tool-allowlist limits, then clean up the child on success and failure.
  6. Explain exactly what the narrow stdio client supports and why protocol success proves neither authorization nor containment.

Concepts introduced before their use

JSON-RPC gives a request a method, parameters and an identity so a reply can refer to it. A notification has no request identity and expects no response. The lesson begins with printed request/reply dictionaries and deliberately swaps two IDs before using a subprocess.

A child process has stdin, stdout and stderr streams. The parent writes protocol input to stdin and reads protocol output from stdout; diagnostic logs belong on stderr. Framing separates one message from the next in a byte stream. Explain text encoding, the newline boundary and buffering with one short exchange before adding asynchronous reading or deadline enforcement.

Initialization establishes the supported protocol and capabilities before ordinary operations. Discovery describes available tools. Local authorization chooses which discovered tools our application may invoke. The adapter must not collapse those three decisions into “the server responded, therefore execute anything it lists.”

The initial scope is the pinned MCP 2025-06-18 stdio transport. The transport specification also defines Streamable HTTP; implementing stdio is not a claim to implement that transport or every MCP feature. Unknown or unsupported version/capability combinations must produce a clear refusal. No new runtime SDK is necessary for the controlled teaching server.

Build, fail and repair

StepBuildPredict or break
1Author one request/reply pair as JSON valuesA reply for a different ID must not satisfy the request
2Start a controlled child and exchange one framed messageMissing flush or missing newline exposes the need for a deadline
3Separate protocol output from diagnosticsA log line on stdout is a malformed protocol message
4Implement initialization and supported-version checksAn unsupported server must not reach tool invocation
5Discover a bounded set of tool descriptionsDiscovery alone leaves local permission unchanged
6Register one validated, explicitly allowed toolA second advertised but forbidden tool remains uncallable
7Invoke through the learner's typed dispatcherReturned evidence must be associated with the correct request
8Bound frames, elapsed time and child lifetimeWrong IDs, oversized output and hanging children leave no success result

Use an independently scripted server with known responses. Later replace it with the optional ZeoCore word-count adapter to compare the same protocol boundary with a maintained implementation. ZeoCore remains an optional separate environment; it must not become a prerequisite for building or understanding this client.

Ownership and handoff interfaces

The learner owns the transport framing, request-ID tracking, initializer, discovery validator and bounded call adapter. The minimal conceptual interface is initialize(), list_tools() and call_tool(name, arguments) with explicit configuration for executable, deadline, frame limit and allowed tool names. Do not implement these by importing the finished sovereign_agent.mcp_client client.

The caller supplies a trusted executable configuration. The model may select an allowed tool name and typed arguments; it cannot select a new executable or extend the allowlist. The dispatcher retains application permission and the caller retains work ownership. A late response after timeout is not allowed to revive a completed request or authorize new effects.

Chapter 14 consumes this bounded adapter and adds container enforcement for generated code. Keep process lifecycle responsibilities explicit: the client reaps the child it started, bounds diagnostic collection and explains the limits of its cleanup mechanism. Environment-specific process-tree guarantees need measured evidence rather than a successful wait() on the immediate child alone.

Unit A — Construct and connect, 90 minutes

MinutesDedicated workSaved evidence
0–10Match printed requests and responses by identityWritten associations
10–25Exchange one JSON line with a controlled subprocessCaptured protocol trace
25–40Introduce initialization and version/capability checksSuccessful and refused handshakes
40–55Discover and validate one tool descriptionTyped local registration
55–75Connect one permitted call through the learner dispatcherInput-to-observation trace
75–85Advertise a second forbidden tool and prove no invocationIndependent server call log
85–90Explain protocol versus permissionRecall response

Unit B — Diagnose and transfer, 90 minutes

MinutesDedicated workSaved evidence
0–10Predict wrong-ID, oversized and hung-child outcomesFailure table
10–25Reproduce a client that accepts the wrong responseFailing independent observation
25–45Repair association and frame validationPassing adversarial traces
45–60Add timeout and cleanup with a controlled hanging serverDeadline and process-exit evidence
60–75Transfer to another tool schema and noisy stderrCorrect result without log confusion
75–85Remove learner allowlist checking and prove the integrated checker failsNegative-control result
85–90State supported features and containment limitsWritten interface contract

Independent acceptance examples

Given and actionExpected observation
Server initializes with the supported pinned versionReady for discovery only after the complete handshake
Server returns an unsupported versionClear refusal; zero tool calls
Request 41 receives a result labeled 42No successful observation accepted for request 41
Server advertises word_count and forbidden purchaseOnly configured word_count can enter local dispatch
Invoke word_count on vanilla stock needs reviewIndependently authored result: four words
Server sends a frame beyond the configured boundRefusal before parsing an unbounded payload into the model path
Server never completes the expected responseBounded failure and recorded cleanup of the controlled child
Server writes a diagnostic on stderrDiagnostic remains separate from valid protocol output
Learner authorization is bypassedIndependent server log exposes the forbidden invocation and the test fails

Completion requires the dedicated chapter, both notebook/Markdown pairs, worked answers, educator guide and learner-owned checkpoint. Existing protocol teaching is then relocated from Chapter 14, whose opening and prerequisites must be rewritten to assume this explicit construction.

Continue to Chapter 14: isolation. Exercise Book · Solutions Book · Textbook contents.

Keep building with Prof Rod

Found this material through a colleague, classroom or shared download? Get the complete book at profrod.ai/book and join the Prof Rod learner community. Bring one result, one question or one failure you learned from. Share this resource with another learner and keep its source links with it so they can find the full course and future updates.

SOURCE PROVENANCE

Derived from github.com/profrodai/sovereign-agent/blob/5b825f3a58461bce8aba1173acf0b6d175c44b64/book/textbook/ch13/profrod-sovereign-agent-ch13-mcp-tools-chapter.md