Ruby on Rails
AI coding agents fail when flooded with raw terminal logs, making warm framework sidecars that return filtered JSON essential to eliminating boot delays and cutting token consumption by 90%.
AI-assisted summary of I Didn't Get MCP, So I Built My Way Through It - Enrique Mogollan — original source. Check the original for full context.
Source published:
Key ideas
- Software engineer Enrique Mogollan created Coatepec, an MCP server running a warm Rails sidecar process that eliminates the 8-second framework cold-boot penalty for AI agents executing tests and model inspections. (11:34)
- By stripping out CLI cruft, deprecation warnings, and bloated JSON headers, Coatepec reduced token consumption across gem releases by 90%, preventing LLM 'light pollution' in the context window. (14:45)
- Benchmarking revealed macOS process creation via spawn matched bin/rails cold-boot delays, requiring a switch to fork to achieve millisecond response times. (14:45)
- The Model Context Protocol has evolved beyond text and raw JSON through MCP Apps, which render interactive HTML, CSS, and JavaScript mini-applications inside chat window iframes. (18:05)
Detailed notes
## Background Published on YouTube by the official Ruby on Rails channel on October 1, 2026, this conference presentation features Enrique Mogollan, a software engineer at Handshake. The session explores how Model Context Protocol (MCP) works under the hood by examining raw wire messages, introducing Coatepec—an MCP server maintaining a warm Rails process for sub-second test runs and model inspections—and demonstrating interactive MCP Apps.
## TL;DR To demystify how AI agents communicate with tools, Enrique Mogollan built an MCP inspector natively in Ruby to inspect raw JSON-RPC messages across stdio and Streamable HTTP transports. Drawing an analogy between high-dimensional vector spaces and nighttime Boy Scout constellation navigation, he demonstrates how noisy CLI outputs create 'light pollution' that distracts LLM attention. To solve this, he developed Coatepec, an MCP sidecar that keeps a warm Rails process running via process forking, enabling agents to execute test suites and inspect models in milliseconds while cutting token usage by 90%. He concludes by exploring MCP Apps, which push interactive HTML and JavaScript interfaces directly into AI chat windows.
## Atmosphere & style The presentation blends pragmatic systems engineering with reflective, personal storytelling, opening with nostalgic recollections of navigating the mountains of San Miguel de Allende using paper maps and stars. Mogollan's delivery is humble and deliberate, demystifying cutting-edge AI protocols through relatable metaphors of light pollution and compass headings rather than marketing buzzwords. Watching the talk feels like sitting around a developer campfire, observing an engineer candidly recount his mistakes, trial-and-error experiments, and breakthroughs while inspiring the audience to explore uncharted technical terrain.
## Bulletin - [11:34](https://www.youtube.com/watch?v=km2hEx-HEME&t=694s) Software engineer Enrique Mogollan created Coatepec, an MCP server running a warm Rails sidecar process that eliminates the 8-second framework cold-boot penalty for AI agents executing tests and model inspections. - [14:45](https://www.youtube.com/watch?v=km2hEx-HEME&t=885s) By stripping out CLI cruft, deprecation warnings, and bloated JSON headers, Coatepec reduced token consumption across gem releases by 90%, preventing LLM 'light pollution' in the context window. - [14:45](https://www.youtube.com/watch?v=km2hEx-HEME&t=885s) Benchmarking revealed macOS process creation via spawn matched bin/rails cold-boot delays, requiring a switch to fork to achieve millisecond response times. - [18:05](https://www.youtube.com/watch?v=km2hEx-HEME&t=1085s) The Model Context Protocol has evolved beyond text and raw JSON through MCP Apps, which render interactive HTML, CSS, and JavaScript mini-applications inside chat window iframes.
## Key takeaways - [00:06](https://www.youtube.com/watch?v=km2hEx-HEME&t=6s) MCP provides a standardized protocol for AI agents to pull external data into an LLM's context window without manual copy-pasting or prompt stuffing. - [04:20](https://www.youtube.com/watch?v=km2hEx-HEME&t=260s) MCP communications rely on two primary transport mechanisms: stdio for local processes and Streamable HTTP for remote streaming, with SSE now deprecated. - [04:20](https://www.youtube.com/watch?v=km2hEx-HEME&t=260s) All MCP interactions follow JSON-RPC conventions across a three-stage lifecycle: initialize, list capabilities, and execute tool or resource calls. - [07:09](https://www.youtube.com/watch?v=km2hEx-HEME&t=429s) LLM vector spaces can be conceptualized as a night sky where tokens are stars, the visible sky represents the context window, and attention mechanisms act as constellation lines connecting related concepts. - [07:09](https://www.youtube.com/watch?v=km2hEx-HEME&t=429s) Verbose CLI output, bundler banners, and multi-line error traces introduce 'light pollution' that overwhelms the model's attention mechanism and obscures the target solution. - [11:34](https://www.youtube.com/watch?v=km2hEx-HEME&t=694s) Coatepec maintains a persistent, warm Rails environment in a background sidecar so agents can inspect models, check routes, and run tests in milliseconds instead of waiting for Rails to boot. - [11:34](https://www.youtube.com/watch?v=km2hEx-HEME&t=694s) Curating an MCP server down to a small set of focused tools (Coatepec provides only seven) prevents agents from being distracted by noisy, low-value capabilities. - [13:35](https://www.youtube.com/watch?v=km2hEx-HEME&t=815s) Returning minimal, clean JSON payloads prompts LLM chat interfaces like Claude to automatically format data into readable UI tables without explicit prompting. - [13:35](https://www.youtube.com/watch?v=km2hEx-HEME&t=815s) Coatepec supports concurrent Git worktrees by wrapping spec execution in synchronization locks and duplicating database connections across isolated worker processes. - [14:45](https://www.youtube.com/watch?v=km2hEx-HEME&t=885s) Switching Ruby process creation from macOS spawn to fork was essential to eliminate execution lag when running specs against the warm Rails sidecar. - [14:45](https://www.youtube.com/watch?v=km2hEx-HEME&t=885s) Refining tool output and pruning JSON headers reduced token usage by 90% across releases, substantially improving agent focus and lowering API costs. - [14:45](https://www.youtube.com/watch?v=km2hEx-HEME&t=885s) Sub-agents introduce significant token setup overhead; unless an application has an unlimited token budget, single-agent architectures with lean tools are often more practical. - [16:45](https://www.youtube.com/watch?v=km2hEx-HEME&t=1005s) To ensure safety, Coatepec strictly disallows eval, interactive rails console sessions, and raw SQL execution, restricting its role to static code and metadata inspection. - [18:05](https://www.youtube.com/watch?v=km2hEx-HEME&t=1085s) MCP Apps allow servers to deliver sandboxed iframe interfaces that communicate directly back to MCP server tools, enabling dynamic mini-applications within chat feeds.
## Detailed walkthrough ### [00:06](https://www.youtube.com/watch?v=km2hEx-HEME&t=6s) Demystifying MCP and the Boy Scout Analogy
Enrique Mogollan begins his talk by asking the audience two questions: who has built an MCP (Model Context Protocol) server, and who has actually seen the raw messages traveling back and forth between a server and a client. While only a few hands go up, he promises that by the end of the session, everyone present will have witnessed those raw wire messages. Roughly a year ago, MCP seemed to explode everywhere—showing up across editors, test harnesses, and chat interfaces. While a simple one-line definition describes MCP as the mechanism an agent uses to pull external data into an LLM's context window without human manual copy-pasting or prompt stuffing, its inner workings and practical utility were initially far from obvious. To understand what was actually happening beneath the abstractions, Enrique built an MCP inspector in Ruby.
Introducing himself, Enrique notes that he is a software engineer at Handshake, a platform dedicated to helping students and early-career talent secure their first jobs, as well as collaborating with foundational AI labs to train models using their student network. Originally from San Miguel de Allende in the heart of Mexico—a colonial town with cobblestone architecture celebrated by travel publications—he recalls the semi-arid, mountainous terrain surrounding the area. During his youth as a Boy Scout, Enrique spent weekends hiking, camping, and participating in navigational challenges. Equipped with only a paper map, participants had to navigate from point A to point B without GPS or smartphones simply because those technologies did not exist yet.
Daytime navigation was fairly straightforward: travelers oriented themselves against visible terrain markers like a hill, a church tower, a radio antenna, or a well-known tree used as a waypoint. However, the Scout leaders eventually introduced nighttime navigational challenges, which proved drastically harder. Without a compass in the dark, navigators had to correlate clusters of faint pinpricks in the night sky with constellation charts and topographical landmarks. Enrique compares that exact feeling—staring at faint points of light and attempting to map them to paper symbols—to the experience of inspecting raw messages passing through an MCP inspector for the first time.
[04:20](https://www.youtube.com/watch?v=km2hEx-HEME&t=260s) How MCP Works: Transports, JSON-RPC, and the Ruby Inspector
Enrique explains that while Anthropic maintains an official MCP inspector written in Node.js with hundreds of contributors, he wanted to construct one natively in Ruby to truly grasp the mechanics. From an architectural perspective, MCP relies on two core transport mechanisms. The first is `stdio` (standard input/output), which is ideal for local development because local MCP servers can connect directly to parent processes via standard streams. The second is Streamable HTTP, which blends standard HTTP request-response patterns with streaming. He notes that while earlier implementations utilized HTTP Server-Sent Events (SSE), SSE has since been deprecated in favor of Streamable HTTP. Regardless of transport, every exchange adheres strictly to JSON-RPC conventions, giving every interaction an identical message envelope structure.
```mermaid flowchart LR accTitle: MCP Client to Server Communication Architecture accDescr: Diagram illustrating how an MCP client connects to an MCP server via stdio or Streamable HTTP using JSON-RPC messages.
subgraph ClientLayer["Client Side"] Client["MCP Client / Agent"] end
subgraph TransportLayer["Transport Layer"] STDIO["stdio (Local Dev)"] StreamHTTP["Streamable HTTP (Remote)"] end
subgraph ServerLayer["Server Side"] Server["MCP Server"] Schema["JSON Schemas<br/>(Tools, Resources, Prompts)"] end
Client -->|"JSON-RPC"| STDIO Client -->|"JSON-RPC"| StreamHTTP STDIO --> Server StreamHTTP --> Server Server --- Schema ```
To demonstrate, Enrique walks through the Ruby MCP inspector against a standard filesystem MCP server. The lifecycle breaks down into three sequential stages: 1. **Initialize**: Setting up the server connection and establishing communication. 2. **List Capabilities**: Querying the server to discover its available tools, resources, and prompt templates. 3. **Execute / Call**: Issuing a remote call against a chosen tool or resource with specific arguments.
In the inspector UI, the interface displays both human-formatted output on top and the underlying raw JSON at the bottom. When inspecting a file system server, the tool list is extensive, with each capability accompanied by a strict JSON schema detailing its invocation format. Executing a tool yields verbose responses packed with protocol headers and structural metadata alongside the tool's actual output.
[07:09](https://www.youtube.com/watch?v=km2hEx-HEME&t=429s) The Celestial Vector Space: Tokens, Context, and Light Pollution
Returning to the night navigation metaphor, Enrique links constellation matching directly to the mathematical machinery of transformer-based LLMs. When a transformer ingests text, it projects each token into a dense, multi-dimensional vector spanning thousands of dimensions. Because high-dimensional space is impossible for human intuition to picture, he suggests flattening the vector space down to two dimensions, turning each token into a tiny dot—or, in honor of Rails World, a star in the sky.
Tokens that share semantic proximity cluster tightly together: for instance, "ocean" and "tide" will sit adjacent to one another in vector space, whereas "ocean" and "tax return" are located light-years apart. This mathematical distance governs semantic meaning, enabling an LLM (or a search engine) to locate an old email based on vague 10-year-old memories. From this perspective, the celestial elements map directly to core LLM components:
- **Stars**: Individual tokens embedded as vectors. - **The Visible Sky**: The finite context window; though the celestial sphere is vast, you can only observe a fixed window at any given moment. - **Constellation Lines**: Attention mechanisms that selectively connect relevant tokens to establish meaning. - **Finding North**: Navigating via key pointer stars (such as Dubhe and Merak in Ursa Major guiding the eye to Polaris) to resolve the prompt's objective. - **MCP**: The mechanism that injects new stars into that visible sky.
This model reveals a significant downside when agents run raw developer tooling. Enrique demonstrates asking an AI agent to execute tests on a project called `ruby_events`. In standard workflows, running tests via terminal commands forces the agent to handle `bundle install` output, multi-line error traces, deprecation warnings, and runtime banners. When Enrique worked on upgrading Rails versions at his day job, he found himself executing test suites 50 times a day. Each invocation incurred an 8-second cold-boot delay just for the Rails environment to start before RSpec could even begin. More critically, the massive dump of standard output produced "light pollution"—a blinding flood of irrelevant tokens that overwhelmed the context window. The vital clues were still technically in the sky, but the glare of low-value context made it impossible for the model's attention mechanism to lock onto the north star.
[11:34](https://www.youtube.com/watch?v=km2hEx-HEME&t=694s) Introducing Coatepec: Warm Rails via an MCP Sidecar
To solve the twin problems of slow boot times and context bloat, Enrique built an MCP server named Coatepec (spelled phonetically in talk captions as "quatc" / "quatc server"). While clarifying that his presentation is not strictly a performance talk, he explains that Coatepec dramatically accelerates developer agent loops by fundamentally changing what gets sent back across the wire.
```mermaid flowchart TD accTitle: Coatepec MCP Server Architecture accDescr: Flow diagram showing an agent interacting with the Coatepec MCP server sidecar maintaining a warm Rails process.
Agent["AI Agent / LLM Client"]
subgraph CoatepecMCP["Coatepec (MCP Server)"] Tools["Curated Tools (7 total)<br/>• rails_spec_run<br/>• routes<br/>• inspect_model"] Sidecar["Warm Rails Sidecar Process"] end
App["Rails Application Environment"]
Agent -->|"MCP JSON-RPC Request"| Tools Tools -->|"Runs in-memory"| Sidecar Sidecar --- App Sidecar -->|"Lean, filtered JSON response"| Agent ```
Coatepec operates by maintaining a warm, pre-loaded Rails process in a background sidecar. Instead of triggering a cold CLI command that pays the 8-second framework boot penalty every time, the agent talks directly to Coatepec over standard MCP interfaces. Coatepec provides focused capabilities tailored to common agent queries: - Running specific test files or examples (`rails_spec_run`) - Inspecting application route definitions - Inspecting database and Active Record model schemas (e.g., querying details on a `User` model)
Because the Rails environment remains hot in memory, requests execute in milliseconds rather than seconds. Just as importantly, Coatepec strictly curates its tool interface. Rather than exposing dozens of noisy options, it presents only seven tools. When running tests through `rails_spec_run`, the tool takes the targeted test path, runs it against the warm process, and filters out CLI cruft, deprecation warnings, and stack traces—returning only a tiny, hyper-focused JSON payload containing the exact pass/fail results. Enrique initiates a live demonstration showing an agent querying the `ruby_events` test suite through Coatepec, where the agent triggers the warm tool call and awaits its concise response.
[13:35](https://www.youtube.com/watch?v=km2hEx-HEME&t=815s) Formatting Tool Output and Coatepec Server Architecture
When an MCP tool responds with clean, minimal JSON, AI clients like Claude interpret it far more effectively. In Enrique's demo, because the output JSON is concise and well-structured, Claude decides on its own to display the data as a clean table without any explicit prompting: "I didn't ask it to build a table. It just did it because the JSON was formatted in a right way."
Beneath the hood of Coatepec, the tool definition—such as `rails_spec_run`—relies on an internal worker manager to execute specs. The execution flows through a `dispatch` call guarded by `lock.synchronize`. This locking mechanism is essential for supporting Git worktrees, allowing multiple instances of Coatepec to run concurrently. Each spawned Rails worker duplicates its database connection so that every worker process retains isolated access without collisions.
```mermaid flowchart TD accTitle: Coatepec Spec Execution Flow accDescr: Diagram illustrating how the MCP client calls rails_spec_run through a worker manager to fork isolated processes.
subgraph MCPClient ["Agent / Client"] A["Tool Call: rails_spec_run"] end
subgraph CoatepecEngine ["Coatepec Server"] B["Worker Manager"] C["dispatch (lock.synchronize)"] end
subgraph Execution ["Rails Process Lifecycle"] D["Fork Warm Rails Process"] E["Duplicate DB Connection"] F["Execute Spec / Query"] end
A --> B B --> C C --> D D --> E E --> F ```
[14:45](https://www.youtube.com/watch?v=km2hEx-HEME&t=885s) Overcoming macOS Spawn Latency and Optimizing Tokens
Achieving true speed required solving a macOS process creation bottleneck. On macOS, the default mechanism for creating processes is `spawn`. However, using `spawn` in Ruby proved just as slow as invoking `bin/rails` from scratch. The breakthrough came when Enrique switched the implementation from `spawn` to `fork`. In performance benchmarks, the initial `spawn` approach (matching raw `bin/rails` execution times) dropped dramatically once `fork` was used, yielding immediate responsiveness.
Beyond raw latency gains, Enrique focused heavily on token efficiency: - Across successive gem releases, token consumption dropped by 90%. - Savings were achieved by trimming bloated JSON headers and omitting redundant trace paths, sending only pass/fail statuses and essential test metadata. - Sub-agents were tested to isolate tasks, but Enrique uncovered a surprising trade-off: while a sub-agent prevents clutter in the primary context window, the overhead of spinning up and configuring each sub-agent consumes a substantial baseline of tokens upfront. Unless an engineer has an unlimited token budget, avoiding sub-agents is often more practical.
[16:45](https://www.youtube.com/watch?v=km2hEx-HEME&t=1005s) Tooling Scope, Safety Guardrails, and the Coatepec Name
Inspecting models and routes through Coatepec is essentially instantaneous, and running test suites remains significantly faster than running standard CLI test commands. The gem exposes core development tools—such as `spec_run` (which is Minitest compatible), `rails_model`, and `rails_route`—and fully supports querying Rails engines.
Enrique deliberately excluded arbitrary execution features to maintain strict safety: - No `eval` - No interactive console sessions (`rails console` cannot be started via Coatepec) - No raw SQL execution - The gem is purposefully designed for static code and metadata inspection during development, not runtime debugging.
Closing out the discussion on the gem itself, Enrique shares the origin of the name: Coatepec is a town nestled in the mountains of Veracruz, Mexico, renowned for producing some of his favorite coffee. He was drinking that very coffee when he conceived the idea for the gem.
[18:05](https://www.youtube.com/watch?v=km2hEx-HEME&t=1085s) MCP Apps: Interactive UI in Chat Windows
Turning back to the official Node-based MCP Inspector, Enrique highlights a major evolution in the protocol: MCP Apps and interactive UI capabilities. Rather than merely returning static text or JSON stars in isolation, an MCP App delivers an entire interface. When an interface is available, the tool returns HTML, CSS, and JavaScript packaged for an `<iframe>`. The rendered iframe retains full direct communication back to the tools declared on the MCP server.
```mermaid flowchart LR accTitle: MCP App Embedding Flow accDescr: Flow diagram showing how the MCP Server returns HTML UI to render in an iframe that triggers tool actions.
subgraph ChatAgent ["Chat / Host Window"] Client["MCP Client"] IframeUI["Embedded Iframe (HTML / CSS / JS)"] end
subgraph MCPServer ["MCP Server"] ToolCard["Tool: get_coffee_place_card"] ActionHandler["State Handler / Tool Dispatch"] end
Client -->|"Call tool"| ToolCard ToolCard -->|"Returns markup payload"| IframeUI IframeUI -->|"User rating update / events"| ActionHandler ActionHandler -->|"Server push: animation / state"| IframeUI ```
Enrique illustrates this by rendering a "Cold Valley" coffee card within a Rails application. The card is not a Rails view partial; it is an MCP App running inside an iframe configured to allow scripts. When a user updates the beverage rating on the card to five stars, the iframe posts an event to the MCP server, and the server pushes back an interactive animation right inside the chat UI. While traditional web apps already use APIs and direct database connections, MCP Apps provide a standardized way for agents to surface full visual mini-applications dynamically inside chat streams.
[21:25](https://www.youtube.com/watch?v=km2hEx-HEME&t=1285s) Navigating the Unknown: Curiosity and Mistakes
Enrique connects his engineering journey back to a personal story about wilderness navigation. Early on, he struggled severely in navigation challenges: getting lost, running out of water, and leading teams through the most arduous terrain. To conquer the challenge, he taught himself trigonometry to read topographical maps accurately and plot his path.
Those same principles—relentless curiosity and a willingness to learn from failures—drove him to understand MCP by building an inspector in Ruby, optimizing Coatepec through trial and error, and exploring bleeding-edge features like MCP Apps. He concludes by challenging the audience to take this knowledge and build novel agent workflows: "the sky is no longer the limit."
## Notable quotes > [00:06](https://www.youtube.com/watch?v=km2hEx-HEME&t=6s) Roughly a year ago, MCP seemed to explode everywhere—showing up across editors, test harnesses, and chat interfaces. — Enrique Mogollan
> [04:20](https://www.youtube.com/watch?v=km2hEx-HEME&t=260s) Regardless of transport, every exchange adheres strictly to JSON-RPC conventions, giving every interaction an identical message envelope structure. — Enrique Mogollan
> [07:09](https://www.youtube.com/watch?v=km2hEx-HEME&t=429s) When a transformer ingests text, it projects each token into a dense, multi-dimensional vector spanning thousands of dimensions. — Enrique Mogollan
> [07:09](https://www.youtube.com/watch?v=km2hEx-HEME&t=429s) The vital clues were still technically in the sky, but the glare of low-value context made it impossible for the model's attention mechanism to lock onto the north star. — Enrique Mogollan
> [11:34](https://www.youtube.com/watch?v=km2hEx-HEME&t=694s) Coatepec operates by maintaining a warm, pre-loaded Rails process in a background sidecar. — Enrique Mogollan
> [13:35](https://www.youtube.com/watch?v=km2hEx-HEME&t=815s) I didn't ask it to build a table. It just did it because the JSON was formatted in a right way. — Enrique Mogollan
> [14:45](https://www.youtube.com/watch?v=km2hEx-HEME&t=885s) Across successive gem releases, token consumption dropped by 90%. — Enrique Mogollan
> [14:45](https://www.youtube.com/watch?v=km2hEx-HEME&t=885s) Unless an engineer has an unlimited token budget, avoiding sub-agents is often more practical. — Enrique Mogollan
> [16:45](https://www.youtube.com/watch?v=km2hEx-HEME&t=1005s) The gem is purposefully designed for static code and metadata inspection during development, not runtime debugging. — Enrique Mogollan
> [18:05](https://www.youtube.com/watch?v=km2hEx-HEME&t=1085s) Rather than merely returning static text or JSON stars in isolation, an MCP App delivers an entire interface. — Enrique Mogollan
> [21:25](https://www.youtube.com/watch?v=km2hEx-HEME&t=1285s) the sky is no longer the limit. — Enrique Mogollan
## Mentioned Enrique Mogollan, Model Context Protocol (MCP), Handshake, San Miguel de Allende, Anthropic, Node.js, Ruby, Streamable HTTP, Server-Sent Events (SSE), JSON-RPC, Ruby on Rails, Rails World, RSpec, Minitest, Coatepec, Claude, Git, macOS, Veracruz, Shopify
## Video description MCP was everywhere, but what actually happens between an agent and a server? Enrique Mogollan, a software engineer at Handshake, set out to find out by building an MCP inspector in Ruby. In this talk he shows the raw messages that flow between client and server, then introduces Coatepec, an MCP server that keeps a warm Rails process running so agents can run tests, list routes and inspect models in milliseconds instead of waiting for Rails to boot. He also explains why returning less context helps agents focus, and closes with a look at MCP apps that render interactive UI in the chat window.
***
Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/
[Source](https://www.youtube.com/watch?v=km2hEx-HEME)