How a Chat Message Becomes a GitHub API Call: Full Stack Trace
▶ Watch on YouTube & subscribe to The Stack Underflow
Most explanations of AI coding agents wave their hands at the moment things “just work.” This episode doesn’t. It picks one sentence — “Create a GitHub issue for this bug” — and refuses to look away until a real row exists in a real database.
The payoff is concrete: by the end you can name every node in the round trip, describe exactly what each one does, and stop treating any part of it as magic.
The one-sentence version: When you type a command to an AI editor, your text passes through eight distinct nodes — editor, model, MCP client, MCP server, and the target API — before any real-world effect happens, and the return trip follows the same path in reverse.
The eight nodes, named up front
Here is the full path for the GitHub issue example. Memorise the labels; the rest of the article is just filling them in.
You → Editor (MCP host) → Model → MCP Client
→ MCP Server → GitHub API → Your Repo
← (same path in reverse)
Eight nodes, one round trip. Each arrow is a real protocol boundary you can intercept and inspect.
The forward trip: sentence to side-effect
Step 1 — You type
Nothing happens yet. Your sentence sits in a text box. The editor (which, as covered in episode 2, is the MCP host) holds it in memory and waits for you to submit.
Step 2 — Editor calls the model
The editor packages your message together with the list of available tools — including create_issue from the GitHub MCP server — and sends the whole bundle to the model via the model API.
The model reads your sentence, scans the tool list, and decides which tool fits. It then emits a JSON tool call. Critically:
- The model produced text. Structured text, but still text.
- It did not execute anything.
- It does not have network access at this point.
The MCP client, sitting inside the editor process, catches that JSON output.
Step 3 — MCP client sends across the protocol boundary
The MCP client wraps the tool call as a JSON-RPC message and dispatches it to the GitHub MCP server — a separate process running on your machine. This is the moment the request leaves your editor’s process space.
Step 4 — The part most explanations skip
The MCP server holds a credential: a Personal Access Token (or OAuth token) that you supplied when you first configured the server. Notice what this means:
- The model never sees the token.
- The editor does not carry the token.
- The token lives exclusively on the MCP server.
The server attaches the token to a real HTTPS request and calls api.github.com. The same call you would make from curl:
curl -X POST https://api.github.com/repos/owner/repo/issues \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"title": "Bug: ...", "body": "..."}'
Step 5 — GitHub creates the issue
GitHub validates the token, creates the issue (issue #1234, say), and returns 201 Created plus the issue details. A real row now exists in a real database. The English sentence has become a real-world effect.
The return trip: result back to you
The path reverses, step by step:
| Direction | From | To | Payload |
|---|---|---|---|
| Return | GitHub API | MCP Server | HTTP 201 + issue JSON |
| Return | MCP Server | MCP Client | JSON-RPC result |
| Return | MCP Client | Model | Plain text message |
| Return | Model | Editor / You | Human-readable confirmation |
One subtlety at the “MCP client → Model” step: the client does not send the raw JSON-RPC blob back to the model. It presents the result as plain text in a new message. The model reads that text, decides the task is complete, and writes its final reply to you: “Issue #1234 created.”
Why credential isolation matters
Keeping the PAT on the MCP server rather than in the model context or editor config is not an accident — it’s a deliberate security boundary. If the model is ever fed adversarial content that attempts a prompt-injection attack, it still cannot leak credentials it never had access to. The MCP server acts as a narrow capability gate: it knows how to authenticate, but it only does so in response to well-defined JSON-RPC calls.
One call versus many
This trace covered a single tool call — one round trip. Real tasks are almost never one round trip. A typical coding agent session looks more like:
- Read a file
- Read another file for context
- Edit the first file
- Run tests
- Read the failure output
- Edit again
- Re-run tests
Each of those steps is the same trace repeated. The repetition has a name — the agent loop — and it is the subject of the next episode.
Common misconceptions
- “The model makes the API call.” It does not. The model emits JSON text that describes a tool call. The MCP client and server execute it. The model has no network socket.
- “The editor stores my API tokens.” For MCP-based integrations, tokens live on the MCP server process, not in the editor’s config or the model’s context window.
- “The model sees the full HTTP response.” It sees a plain-text representation prepared by the MCP client. Raw HTTP headers, status codes, and binary payloads are translated before they reach the model.
- “Eight nodes is unusually complex.” This is the minimal path for an authenticated third-party API call. Many real tasks involve more hops (multiple servers, chained tool calls, memory lookups).
Frequently asked questions
Why does the MCP server need to be a separate process? Process isolation is what keeps credentials out of the editor and model. It also lets the server be written in any language, updated independently, and restarted without touching the editor. The JSON-RPC protocol over stdio or HTTP is deliberately thin so the boundary stays clean.
Can I inspect the JSON-RPC messages in flight?
Yes. MCP servers typically log their stdio traffic, and many clients expose a debug panel. You can also run the MCP server manually and send hand-crafted JSON-RPC messages to it with curl or a tool like jq, exactly as you would debug any RPC service.
What happens if the GitHub token is expired or invalid?
GitHub returns a 401 Unauthorized HTTP response. The MCP server surfaces this as an error in the JSON-RPC result. The MCP client forwards the error to the model as a plain-text error message. The model reads it and typically tells you the credential needs refreshing — it cannot fix the credential itself.
Is this trace specific to GitHub, or does it generalise? The structure generalises to any MCP server. Swap GitHub for a Postgres MCP server, a filesystem server, or a Slack server and the eight-node path is identical. Only the tool names and the credential type change.
Where this fits in the series
This episode is the “put it all together” moment for the first three episodes of AI Agent Internals: How Coding Agents Really Work. Episode 1 introduced the model-produces-text / orchestrator-executes-tools split. Episode 2 mapped the MCP host–client–server topology. Here, you watched both layers run in sequence on a concrete example. The next episode zooms out to the agent loop — what happens when a task needs dozens of these round trips strung together. Browse all tutorials to follow the series in order.
Found this useful? The deep version lives on YouTube — new breakdowns of how AI dev tools actually work, weekly.
Subscribe on YouTube →