Workspace/Lesson workspace
Loading progress
Grounding & reasoning40 min

Choose a transport and account for interrupted work

Lesson 2 of 3
How to study this lesson

Read one section, trace the worked example, and try the knowledge check. Bookmark saves a shortcut; notes appear in My notebook. Mark lesson complete is your own assessment and does not mark its lab passed.

By the end, you can

  • Compare stdio and Streamable HTTP operational boundaries.
  • Keep request identity separate from business idempotency.
  • Design integration tests around stream loss and version mismatch.

The transport determines an operational relationship

A local stdio deployment launches a server process and exchanges framed messages through its standard streams. A remote HTTP deployment connects to a service endpoint and introduces network intermediaries, transport authentication, and independent service lifecycles. Both can expose the same business tool, yet their deployment failure modes differ. Choose based on the trust boundary and operating model rather than assuming remote is more capable or local is automatically safe.

A local process may inherit sensitive environment variables or broad filesystem access. A remote service may receive private arguments and depend on proxies with their own timeouts. Document who launches or operates the server, which identity it runs under, where logs go, and which component can terminate work. These are concrete architectural responsibilities that the tool catalog cannot answer.

A pinned HTTP mapping

In MCP 2026-07-28, Streamable HTTP sends client messages as POST requests to one endpoint. A reply can be a JSON object or a request-scoped SSE stream. The revision requires protocol and method headers, plus a name header for relevant methods such as tools/call; header values must agree with their corresponding body fields. Consult the pinned transport specification for complete framing and encoding requirements.

The short example checks three plain ASCII header mappings for a stock lookup. This is a deliberate subset, not a conformance validator. It omits SSE parsing, custom parameter headers, non-ASCII encoding, error envelopes, and connection handling. The educational benefit is seeing why duplicated routing information must agree: an intermediary must not authorize tool A while the body executes tool B.

An interrupted response is not rollback

Consider a reservation that commits at time 120 milliseconds, starts its response at 130 milliseconds, and loses the connection at 140 milliseconds. The host knows that the response is incomplete; it does not know that the reservation failed. This is the same uncertainty encountered in the previous module, now inside a standardized integration protocol.

The pinned revision removes the earlier stream-resumption mechanism. Its changelog requires a new request with a new request ID when reissuing interrupted work. That does not supply application idempotency. Preserve a tool's documented business operation key when replay is appropriate, or query its operation status. If neither mechanism exists, stop short of repeating a mutation whose previous outcome is unknown and expose the uncertainty to the controlling application.

Bound waiting at several levels

Use a connection deadline, an operation deadline, and an overall workflow budget. A stream that emits progress forever should not consume the entire workbench. Progress is evidence that a component is active, not proof that the business operation is advancing. Distinguish cancellation requested from cancellation confirmed, especially when a side effect may already have committed.

Imagine the host budget is eight seconds, the tool budget is five, and a proxy closes idle streams after three. If a valid tool stays silent for four seconds, the proxy can fail before the tool deadline. Diagnose that mismatch through timestamps and explicit configuration. Increasing every timeout may hide the immediate symptom while making overload worse. Measure the longest legitimate silent interval and align the relevant layers deliberately.

Production evidence comes from fault scenarios

A useful integration suite covers a valid read, malformed arguments, insufficient scope, unsupported revision, mismatched headers, an unavailable endpoint, and a connection lost after an effect. For stdio, include a server process exit and accidental non-protocol output on its protocol stream. These cases expose boundary assumptions more efficiently than repeatedly testing a happy-path lookup.

Record selected revision, endpoint identity, method, attempt ID, duration, and classified result. Keep business keys separate so one intended action can be reconstructed across attempts. The mini project starts as an offline trace inspector because it is reproducible without credentials. Completing it with a real server requires a compatible maintained implementation and tests that prove the chosen transport behavior, not merely a screenshot showing that one tool call worked.

Work through the code

An offline subset validator normalizes header names and compares plain ASCII values to body fields. It detects a tool-name mismatch. It is not a full implementation of the transport specification or header encoding rules.

inspect_http_mapping.py
python
VERSION_KEY = "io.modelcontextprotocol/protocolVersion"
body = {
    "method": "tools/call",
    "params": {"name": "stock_lookup", "_meta": {VERSION_KEY: "2026-07-28"}},
}
headers = {
    "MCP-Protocol-Version": "2026-07-28",
    "Mcp-Method": "tools/call",
    "Mcp-Name": "stock_lookup",
}

def matches(headers, body):
    normalized = {key.lower(): value for key, value in headers.items()}
    expected = {
        "mcp-protocol-version": body["params"]["_meta"][VERSION_KEY],
        "mcp-method": body["method"],
        "mcp-name": body["params"]["name"],
    }
    return all(normalized.get(key) == value for key, value in expected.items())

print(matches(headers, body))
print(matches({**headers, "Mcp-Name": "reserve_stock"}, body))
EXPECTED / ILLUSTRATIVE OUTPUT
True
False

Run Python snippets locally with the prerequisites named above. The module coding lab runs directly in your browser.

Pause and reason

A reservation response stream disconnects after the server may have committed. The tool accepts operation_key. Describe the new attempt and a misleading metric to avoid.

Check your understanding

Which observation proves a reservation was rolled back?

Your notes

Explain the mechanism in your own words. Add a failure you want to test.

Saved notes appear in your notebook

Go deeper with primary sources

Practice this module