Module 1.1 traced a tool call all the way from config block to result and labeled every layer it crossed. One box stayed closed: the transport — “how the bytes actually move.” This module opens it. The answer will feel mechanical at first, but its consequence is structural: the choice of transport determines whether auth is required, who can connect, and what the deployment lifecycle looks like. Module 1.3 follows directly from this module because remote transport introduces a problem this module names but does not solve.
Local stdio — the default mode
The @runsnative/mcp-server you connected in the Pre-Course Setup runs over local stdio by default. The config block you pasted tells the host exactly what to do: launch an npx process, wire its stdin and stdout to the client, and speak MCP JSON-RPC over that pipe. The server entry point is runsnative/packages/mcp-server/src/index.ts; the last two lines confirm the transport:
const transport = new StdioServerTransport()
await server.connect(transport)
What this means in practice:
- The host spawns the server as a child process when the session starts, on demand.
- The server runs on the same machine as the host. No network, no ports, no firewall.
- The server gets filesystem and process access from whatever user account launched the host. This is why stdio servers can read local files, run local scripts, or query local databases — they inherit the operator’s context.
- No install beyond the config. The
npx -y @runsnative/mcp-servercommand fetches and runs the server on first use; no separate install step. - Per-machine deployment. Every person who wants this server connected has to add the config block to their own host. There is no shared instance.
The runbook confirms the current production posture: “the live desktop config is all stdio” (mukadra/docs/operations/mcp-server-build-and-install-runbook.md §7). For the course artifact and for most locally-hosted capabilities, stdio is the default and the proven path.
Remote Streamable HTTP — the URL model
The other transport family is remote Streamable HTTP: instead of spawning a process, the host’s client connects to a URL. The server runs somewhere else — on a cloud service, behind a gateway, or on another machine — and the client speaks MCP JSON-RPC over HTTP POST.
The Mukadra portfolio has production examples of this today. The deployed mukadra-mcp-gateway Cloudflare Worker (mukadra/infrastructure/cloudflare/mcp-gateway/src/index.ts) accepts MCP JSON-RPC at /mcp over HTTPS. Claude.ai reaches pm-synth and CKO through that Worker, not by spawning local processes. The pm-synth MCP server (port 8150 per the Mukadra port registry) and the CKO edge (port 8303) each speak Streamable HTTP; the gateway brokers between them and the client.
What this model changes:
- No local process. The host connects to a URL. No
npx, no spawn, no per-machine binary. - No filesystem access. The server runs in its own environment. It cannot read the user’s local files unless explicitly designed to do so.
- Centrally updated. Deploy a new version of the server, and every connected client sees the change without any client-side action.
- Multi-client. One server instance can serve many clients simultaneously. The gateway Worker handles multiple claude.ai sessions concurrently.
- Needs auth. This is the structural consequence. A local stdio server is protected by the local OS’s process model — only the user who launched the host can reach it. A remote server is accessible to anyone who can reach the URL. Authentication is not optional; it is the price of the URL model. Module 1.3 covers exactly this.
The legacy transport: SSE
A third transport exists and you will encounter it in the wild: Server-Sent Events (SSE). It predates Streamable HTTP in the MCP ecosystem and some production servers still use it. Within the Mukadra portfolio, the Radar General MCP server runs SSE on port 8210 (per the root KUKAMANGA/CLAUDE.md port registry). The distinction that matters for you as a consumer: if a remote server gives you an SSE endpoint rather than a streamable-HTTP one, your MCP client config uses a different transport type field. Recognize it; do not build new servers on it. Streamable HTTP supersedes SSE for new work.
The decision framework
The outline’s framing holds: local stdio = filesystem/process access, zero hosting cost, per-machine deployment; remote HTTP = no local install, centrally updated, multi-client, auth required. Choose based on what the server actually needs to do:
- A server that needs to read the user’s local repository, run local scripts, or access local databases → local stdio. The
@runsnative/mcp-serverin its development mode (withRUNSNATIVE_CONTENT_ROOTset) is an example: local content, local process. - A server that serves a shared capability — a production tool surface, a knowledge base, a shared API — at scale to multiple users → remote Streamable HTTP. The
mukadra-mcp-gatewayWorker is an example: one URL, all claude.ai users reach it. - A server that serves a shared capability but whose users are always on a trusted machine with access to a shared network → either works; the deployment model drives the choice more than the transport itself.
Notice what the framework does not say: it does not say “MCP over HTTP for modern clients, stdio for legacy.” Both transports are actively used for good reasons. The client-support landscape is a snapshot in time — as of 2026-06-12 (volatile, non-load-bearing): Claude Desktop and Claude Code support local stdio servers natively; claude.ai (web/mobile) reaches servers only through a remote gateway. Client support is volatile; this claim should be re-verified if you are making architecture decisions. The course teaches both transports regardless.
Lab: trace your stdio connection and sketch the HTTP alternative
This lab has two parts. Both run in your own agent session.
Part 1 — trace the transport you are using:
Ask your agent to call list_exercises on @runsnative/mcp-server. While it does, account for the transport layer:
- Where is the server process running? (On your machine, as a child of the host.)
- What carries the JSON-RPC messages? (stdin/stdout of that process.)
- What would need to change for this to be a URL instead of a process? (A running HTTP service at a URL the host can reach; auth credentials for that service.)
Part 2 — sketch the HTTP topology using a real example:
Read the gateway worker’s route table (mukadra/infrastructure/cloudflare/mcp-gateway/src/index.ts, the route comment at the top). Draw — on paper or in your notes — the path from a claude.ai session to pm-synth:
claude.ai session → Cloudflare Worker (/mcp) → pm-synth (port 8150, Streamable HTTP)
Label where auth is enforced (the Worker’s authenticate() function, between the client and the backend). This is the topology Module 1.3 unpacks.
You know it worked when: you can say, for your current @runsnative/mcp-server connection, which transport it uses, why, and what single requirement would be added if it moved to a URL. If you can answer that question, you understand the structural difference between the two transport families and you are ready for Module 1.3.