Mogollan Unveils Coatepec MCP Server to Cut Rails AI Agent Lag

I Didn't Get MCP, So I Built My Way Through It - Enrique Mogollan — Ruby on Rails

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)

中文简报

Mogollan推出Coatepec MCP服务器以减少Rails AI Agent延迟 AI编码Agent在被原始终端日志淹没时容易出错,这使得返回过滤后JSON的热框架Sidecar对于消除启动延迟并降低90%的Token消耗至关重要。 为了揭开AI Agent与工具通信方式的秘密,Enrique Mogollan原生使用Ruby构建了一个MCP检查器,用于检查跨stdio和Streamable HTTP传输的原始JSON-RPC消息。他将高维向量空间类比为童子军在夜间按星座导航,展示了嘈杂的CLI输出如何产生分散LLM注意力的“光污染”。为解决该问题,他开发了Coatepec,这是一款通过进程分叉保持Rails热进程运行的MCP Sidecar,使Agent能够在几毫秒内执行测试套件并检查模型,同时将Token消耗减少90%。最后,他还探讨了MCP Apps,该技术可将交互式HTML和JavaScript界面直接推送到AI聊天窗口中。 软件工程师Enrique Mogollan开发了Coatepec,这是一个运行Rails热Sidecar进程的MCP服务器,消除了AI Agent执行测试和模型检查时面临的8秒框架冷启动损耗。 (11:34) 通过剥离冗余的CLI杂质、废弃警告以及臃肿的JSON头部,Coatepec在各gem版本中将Token消耗降低了90%,防止了上下文窗口中出现LLM“光污染”。 (14:45) 基准测试显示,macOS上通过spawn创建进程的耗时与bin/rails冷启动延迟相当,因此必须改用fork才能实现毫秒级的响应时间。 (14:45) Model Context Protocol已通过MCP Apps超越了纯文本和原始JSON形式,能够在聊天窗口的iframe内渲染交互式HTML、CSS和JavaScript微型应用程序。 (18:05)

Reading summary

Enrique Mogollan argues that developers can demystify and optimize the Model Context Protocol (MCP) by inspecting raw JSON-RPC traffic and replacing noisy command-line executions with dedicated, context-efficient server sidecars. Drawing from his work building a native Ruby inspector and the Coatepec MCP server, he demonstrates how maintaining warm application processes resolves framework latency and context window bloat. Demystifying MCP Mechanics Through Native Inspection (4:20) To understand how agents bridge external data into large language model context windows, Mogollan built an MCP inspector in Ruby as an alternative to Anthropic's official Node.js tool. Beneath high-level abstractions, MCP relies on strict JSON-RPC message envelopes transmitted over two primary transport layers: `stdio` for local process communication and Streamable HTTP for remote streaming, which replaced the earlier Server-Sent Events (SSE) implementation. Communication follows a three-stage lifecycle: initializing the client-server handshake, listing capabilities against strict JSON schemas (covering tools, resources, and prompt templates), and executing remote calls. Raw inspection reveals that standard server implementations produce verbose metadata and headers alongside payload data, underscoring the need to scrutinize what travels across the wire. Context Windows and the Light Pollution Problem (7:09) Mogollan models LLM vector spaces through a celestial navigation metaphor: embedded tokens act as stars, attention mechanisms act as constellation lines connecting related concepts, and the visible night sky represents the finite context window. When autonomous agents run standard developer tooling, command-line interfaces flood the context window with package installation logs, deprecation notices, and stack traces. Mogollan terms this excess data "light pollution," which glares across the context window and prevents model attention from focusing on relevant error signals. Furthermore, executing standard terminal commands during repetitive developer workflows—such as running test suites 50 times a day during Rails upgrades—incurs severe latency, including eight-second cold-boot penalties just to initialize the framework environment before tests execute. Coatepec's Warm Sidecar and Process Architecture (11:34) To eliminate boot latency and context bloat, Mogollan developed Coatepec, an MCP server that maintains a warm, pre-loaded Rails environment in an in-memory background sidecar. Instead of exposing broad system access, Coatepec provides seven curated tools focused on specific developer tasks, including running targeted test paths (`rails_spec_run`), listing routes, and inspecting Active Record model schemas. When tested on macOS, Mogollan found that the default process creation mechanism (`spawn`) matched the sluggish latency of running raw CLI commands; replacing `spawn` with Ruby's `fork` enabled near-instantaneous execution. The server engine handles execution requests through a synchronized dispatch lock (`lock.synchronize`) and duplicates database connections per worker, allowing concurrent Coatepec instances to run safely across multiple Git worktrees. Token Optimization, Safety Guardrails, and Interactive UIs (14:45) Coatepec lowered context consumption by 90% across gem releases by stripping protocol headers and redundant trace paths, returning lean, hyper-focused JSON payloads that models like Claude can parse cleanly into structured tables without explicit prompting. Mogollan cautions that while assigning tasks to sub-agents isolates context, the baseline overhead of provisioning and configuring each sub-agent consumes substantial tokens upfront, making sub-agents impractical for constrained token budgets. To maintain application safety, Coatepec explicitly prohibits dynamic code evaluation (`eval`), interactive console sessions, and raw SQL queries, restricting its scope strictly to static inspection and test execution. Looking forward, Mogollan highlights MCP Apps, which extend the protocol beyond static JSON by streaming HTML, CSS, and JavaScript into sandboxed iframes, enabling bi-directional, stateful mini-applications directly inside chat interfaces. Mogollan concludes that mastering emerging protocols like MCP requires looking beneath software abstractions through deliberate, hands-on tool building. While purpose-built servers like Coatepec demonstrate that keeping warm processes and curated outputs dramatically speeds up agentic workflows, developers must continuously weigh token costs, process isolation, and security constraints when integrating AI agents into development environments.

Source quotes

[0:06] Enrique Mogollan: Roughly a year ago, MCP seemed to explode everywhere—showing up across editors, test harnesses, and chat interfaces. [4:20] Enrique Mogollan: Regardless of transport, every exchange adheres strictly to JSON-RPC conventions, giving every interaction an identical message envelope structure. [7:09] Enrique Mogollan: When a transformer ingests text, it projects each token into a dense, multi-dimensional vector spanning thousands of dimensions. [7:09] Enrique Mogollan: 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] Enrique Mogollan: Coatepec operates by maintaining a warm, pre-loaded Rails process in a background sidecar. [13:35] Enrique Mogollan: I didn't ask it to build a table. It just did it because the JSON was formatted in a right way. [14:45] Enrique Mogollan: Across successive gem releases, token consumption dropped by 90%. [14:45] Enrique Mogollan: Unless an engineer has an unlimited token budget, avoiding sub-agents is often more practical. [16:45] Enrique Mogollan: The gem is purposefully designed for static code and metadata inspection during development, not runtime debugging. [18:05] Enrique Mogollan: Rather than merely returning static text or JSON stars in isolation, an MCP App delivers an entire interface. [21:25] Enrique Mogollan: the sky is no longer the limit.

Original transcript

[0:06] [music] [0:11] Hello. [0:13] Who here has built an MCP server? [0:18] All right, there are a few hands. Who [0:21] here has built or saw how the RAM [0:24] messages between a server and a client [0:27] go? [0:29] All right, there are a few people, [0:33] but after today, everyone in this [0:36] audience will have seen that the [0:39] messages going back and forth between [0:40] the server and a client. [0:44] And [0:45] [snorts] [0:46] MCP a year ago was everywhere. It was in [0:50] my editor. It was in the harness. It was [0:53] in the chat. [0:55] And I could give you the oneline [0:58] definition. MCP is how an agent pulls [1:02] data from an external source into the [1:04] context window without you having to [1:06] type it or stuff it into the prompt. [1:10] But I really didn't get exactly how it [1:13] worked. I wasn't sure how it was [1:16] beneficial for me. So, I started doing [1:19] some things, experiments, ended up [1:22] building an MCP inspector, and I'm going [1:25] to tell you about it a little bit. [1:29] Hi again, my name is Enrique. I'm a [1:32] sovereign engineer at Handshake. In [1:35] Handshake, we help students and young [1:37] people land their first job. And we're [1:39] also helping the foundational labs to [1:42] train their models with the network or [1:43] students and people that we have. [1:47] I am also from Mexico. I'm originally [1:50] from a town called San Miguel deende. [1:53] It's in the heart of Mexico. [1:57] Thank you. Uh maybe you heard about this [2:00] town. It's uh one of the places that was [2:04] named by the travel magazine of one of [2:06] the place best places to live, best [2:08] places to see to travel and it's [2:11] cobblestone streets colonial [2:13] architecture. But something that the [2:16] magazines don't mention a lot is that [2:19] semi- desertic area that surrounds the [2:21] town. And after the semi- deserted area, [2:24] there's some mountains. [2:27] And I spent a lot of time during my [2:30] youth in the weekends over there hiking [2:34] and camping because I was a boy scout. [2:38] And one of the other things that I [2:40] enjoyed doing over there was this thing [2:44] called navigational challenges where [2:46] they give you a map. They put you in a [2:49] point and then they tell you go there, [2:51] find your place and you have to follow [2:54] the map. No GPS, no phone. And not [2:58] because it was forbidden. It was because [3:00] it didn't exist back then. [3:03] And the navigational challenges during [3:06] the day were easy, [3:09] more or less easy. You just have to find [3:11] a hill, a church, a radio tower, that [3:14] weird tree that everyone lo uses as a [3:17] marker, and then you once you find a [3:19] landmark, you start walking in that [3:21] direction or you move your map to match [3:24] it. [3:26] But then someone on the scouts came up [3:29] with the idea of doing navigational [3:31] challenges during the night. [3:33] And that was a little bit harder. It was [3:36] tricky. [3:37] I get lost constantly. [3:41] And the challenge was which cluster of [3:44] dots in the sky map to the ones that are [3:47] in my map. And we didn't get a compass [3:50] and did during the night. We just had [3:53] our constellation map and the landmark [3:55] map. [3:59] And I know this is a little bit random, [4:02] but that feeling of having to match [4:05] something that are dots with symbols on [4:08] a page is pretty much what MCP inspector [4:13] looks like. That's pretty much the same [4:15] feeling that I got when I saw the first [4:17] RAM message going through. [4:20] All right, so a year ago, I built an MCP [4:24] inspector in Ruby. There is one in nodes [4:26] that is maintained by entropic and has [4:29] hundreds of contributors. But I wanted [4:31] to build one in Ruby just to be able to [4:34] see what was this MCP thing. [4:38] And last year at this Ruby I gave a talk [4:40] about this and I'm not going to give you [4:43] the same talk but I'm going to tell you [4:45] two important things. One is that there [4:48] are two transfer methods. The first one [4:50] is stdio or standard input output and [4:53] that works very well for local [4:55] development or local MCP servers when [4:57] you can just connect them directly into [5:00] your local servers. And the other one is [5:02] a streamable HTTP which is a combination [5:05] of both standard HTTP and stream from [5:09] HTTP. In the past, this used to be HTTP [5:13] as server side event, but that has been [5:16] deprecated in favor of streamable HTTP. [5:21] The second thing that you need to know [5:22] about uh the inspector or MCP is that [5:27] all the messages are in JSON RPC. So, [5:30] every conversation in a way has the same [5:33] shape. [5:36] And I'm going to show you a demo of the [5:38] MCP inspector. First, we're going to [5:40] look at to how we set up the MCP server. [5:45] Then we're going to list the tools um [5:48] that remember there are for MCP there [5:51] are tools, resources, and prompts. And [5:55] finally, we're going to execute a call. [5:57] All right. So, we're here here seeing [6:00] the setup here. I'm showing you the [6:02] list. This is the file system MCP [6:04] server. So, it has a bunch of things and [6:07] I'm here. I'm actually executing one of [6:10] the requests. [6:12] And as you can see, at the top there's [6:14] prejson. At the bottom is the raw JSON. [6:18] And now everyone in the audience has [6:20] seen raw JSON going back and forth [6:22] between an MCP server and a client. [6:26] All right. So again, the inspector is [6:29] the initialize [6:31] and then you can list tools, resources, [6:33] and prompts. And then you can execute or [6:36] call uh each of these. [6:39] But one thing I want to highlight is [6:41] that the MCP server for profile system [6:44] has a bunch of things a a long list and [6:47] each of these items has a schema and the [6:51] schema is also JSON or how you you can [6:56] use it the tool [6:58] and then when you actually execute the [7:00] tool there's a lot of headers that come [7:03] back from the JSON [7:06] the JSON response. [7:09] All right. So, let's go back for a [7:12] moment to uh Mexico and the navigation [7:15] and challenges because I told you during [7:17] the day it was kind of easy, but during [7:21] the night it was more complicated [7:24] because all the things that you have is [7:26] just points in the sky. [7:29] And actually points in the sky is not a [7:33] bad representation of what is happening [7:36] with with LLM models when they use [7:39] transformers in the background because [7:41] what they do is they take a token and [7:44] make it a vector a multi-dimensional [7:47] vector that uses thousands of [7:50] dimensions. [7:52] But we as humans, it's very difficult [7:55] for us to imagine how this vector is [7:59] represented in multiple dimensions. So [8:01] today, we're going to flatten this [8:04] vector and we're going to have put it in [8:06] two dimensions. And because it's two [8:08] dimensions, we're just going to put it [8:11] into a little tiny dot. And today, [8:15] because it's a special day, because it's [8:17] Rails World, we're going to make it a [8:19] star. [8:22] So basically it's a vector a token is a [8:25] vector or a star in the sky [8:27] and then when you group stars [8:32] when you put them together it's token [8:34] that have similar similarities between [8:37] them for example ocean and tide are [8:41] together but ocean and tax return are [8:46] completely separated [8:48] and this is the mechanism this [8:51] distance is has some meaning and this is [8:54] the mechanism that is used to be able to [8:57] determine the the semantic significance [9:00] of things. And this is how you can find [9:02] an email by vaguely remembering [9:04] something random from 10 years ago. [9:10] And then when you put it together u [9:14] there's although there's like infinite [9:16] sky there's only a few portion of the [9:19] sky that you can see at time. So that's [9:21] your context window. [9:24] And then when we try to align the stars [9:28] to match a specific constellation, [9:31] that's our attention. [9:33] And that is important for us because we [9:36] want to find our path. And to in order [9:39] to be able to find our path, we have to [9:41] find Dubet and Morac to be able to find [9:44] the Polaris star. Find north. [9:50] So here's our map. Stars are tokens. The [9:54] sky is the context window and [9:56] constellations lines our attention and [9:59] MCP is how you put more stars into the [10:03] sky. [10:05] All right. So let's go back to uh [10:08] problem in real life. Here I am running [10:12] the test or I'm asking an agent to run [10:14] the test for Ruby event. I just uh [10:18] downloaded Ruby events run bundle [10:20] install and told the agent can you run [10:22] the test and as you can see there a lot [10:25] of things that are happening uh because [10:27] sometimes it has to bundle install first [10:30] sometimes it shows me the error one time [10:33] or it can also show me uh the warnings [10:36] of the things that are happening the [10:37] deprocations [10:39] so it's a lot of things that are [10:41] happening in one request [10:45] So this happened to me when I was [10:48] upgrading Rails at work. I was [10:51] constantly running the test suite 50 [10:54] times a day. And one of the things that [10:57] happened to me was that every time I run [10:59] the test, it took eight seconds for my [11:02] server to start just like Rails to boot [11:05] to be able to run a spec. [11:07] And then all the context that started [11:10] coming back [11:13] is like stars that were adding and [11:15] adding into my context. And I call it [11:19] light pollution that prevents me for me [11:22] see the stars in the sky. But that [11:25] doesn't mean that the stars are not [11:28] there. The stars are there. I just lost [11:30] my ability to find them. [11:34] So I I started questioning myself. do we [11:36] actually need all these context all [11:39] these data into the context [11:43] and I think the answer is no we we don't [11:45] need all that data we just need a [11:47] portion that is important to us so I [11:50] started working on something um [11:53] something that I call quatt [11:56] and quatc is an mcp server and this is [11:59] not a performance stock but is an mcp [12:02] server that is helping me do my work [12:04] faster [12:07] And it's the same protocol that we watch [12:09] in the inspectors, same tools, [12:12] resources, but the difference is what we [12:14] get back from the response. [12:18] So how does it work? So it works by [12:21] creating a sidecar process and it [12:24] creates a warm rails version of the my [12:27] rails process and then the agent just [12:30] talks to this quattex server and it [12:33] tells it oh can you run the test? Oh can [12:35] you give me the routes for this? Oh can [12:38] you tell me about the model user? [12:42] And instead of like taking eight seconds [12:44] to to boot uh drills, it just takes [12:49] milliseconds. [12:52] And how does it look in in the inspector [12:56] here? I have seven tools only seven [12:59] tools. The first one is uh rails [13:02] spectrum and the I think this is the [13:04] more the most important and the [13:07] parameters is just like which test you [13:10] want to execute. [13:12] And after we execute it, we get just a [13:14] small little portion of JSON. [13:19] So let me show you how it runs in an [13:22] agent. [13:24] Here I'm telling the agent to run the [13:26] same similar test in the Ruby events [13:29] app. Uh and it's thinking it called [13:32] squad the peg and I'm going to expand [13:35] the call there. And you can see it's [13:38] just a small JSON. And because it's very [13:42] small and very well uh formatted, uh [13:45] cloud determined that the best way for [13:48] me to see the data was to build a table. [13:51] I didn't ask it to build a table. It [13:52] just did it because the JSON was [13:54] formatted in a right way. [13:58] All right. So, how does MC MCP server [14:02] for quite a bit work? Here I'm showing [14:04] you the definition of the tool. It's [14:07] called Rails Specrun. And basically here [14:10] I'm calling a worker manager to run the [14:13] spec. [14:15] And inside run the spec there's a call [14:18] to dispatch and dispatch calls lock [14:21] synchronize. And this lock is to be able [14:24] to use work trees. So we can use [14:27] multiple times quatt [14:30] because every time you create a new [14:32] process in quadbec with quatbec for [14:35] rails it will it will duplicate the [14:38] database connection. So each process [14:40] gets its own database connection. [14:45] But one thing that I want you to notice [14:46] is that here it says client spam. And [14:50] this is because I work on a Mac computer [14:53] and Mac computers the prefer method to [14:55] start a new server or new process is [14:58] with spawn. However, spawn is is very uh [15:04] slow. It's as slow as using just being [15:06] rails directly. So instead of using [15:10] spawn, I switch it to use fork. [15:14] And at the top the orange line is bin [15:17] rails. the same as a spawn. But when I [15:20] switched to fork is when I started to [15:22] get performance gains. [15:25] Now I was not satisfied to just like [15:27] being faster. I also wanted to be better [15:31] and and to more token efficient. So over [15:34] different versions of the gem, I was [15:37] able to reduce the token consumption by [15:39] 90%. And just this is basically just [15:42] adjusting the JSON headers or not [15:45] sending the full uh path of the error [15:48] and just sending which test pass which [15:50] test fail [15:53] just trying making engineering work. [15:57] All right. I also tried to take [16:00] advantage of sub aents and I was [16:03] successful. My original idea was to [16:06] include the skill to tell it to always [16:08] use quat with a sub agent and that works [16:12] but it has a cav caveat. Uh and the [16:14] caveat is that yes you save tokens on [16:18] your main context window but on the [16:20] other hand every time you spawn a sub [16:23] agent you have to do some setup and that [16:26] setup is going to end up burning more [16:29] tokens at the end. So if you don't have [16:31] unlimited tokens, [16:34] it's better if you don't use agents. [16:37] And for me that was interesting. I [16:39] something that I didn't expect it to [16:41] find. [16:43] All right. So [16:45] one last graph of how it behaves. Um so [16:49] model and routes is just basically [16:52] instantaneous. You can talk to quat to [16:54] get data from rails. Uh and then when [16:57] you try to run the spec still faster [17:00] than just being rails [17:04] and yes the the main tools that are [17:07] available is the spec run that is mini [17:09] test compatible rails model and rails [17:12] route to just query and you can also in [17:15] include your rails engines if you have [17:18] ones [17:20] but one thing that I wanted to make sure [17:22] is that this has no eal no console [17:26] No raw SQL. You cannot start a console [17:30] from quatc. It's just for development. [17:33] It's not for debugging. [17:38] And one thing I want to mention is why [17:42] is the name of the gym is quatc? Well, [17:45] in Mexico there is the state of [17:47] Veraracruz. And in Veraracruz there is [17:49] this place called Catek. It's up in the [17:53] mountains and it has one of my favorite [17:55] coffees. So, I was just drinking coffee [17:58] when I thought about the gem. [18:02] All right. So, [18:05] we're going to back go back to [18:06] inspector, but it's not the Ruby [18:09] inspector. This is the node inspector, [18:12] the node MCP inspector. [18:15] And I want to show you something that is [18:18] different, something that is interesting [18:20] because now [18:22] they they ship something called MCP [18:25] apps. [18:27] And one thing that I want to highlight [18:29] is that it has like a new thing called [18:32] UI. [18:34] So basically what MCP apps or like the [18:38] future of MCP [18:40] based on this official first extension [18:43] is a tool that is tells you that is [18:46] something an interface available and [18:48] when the interface is available it sends [18:51] you back an HTML that you can put inside [18:54] an iframe and this iframe is will [18:58] contain the HTML will contain the styles [19:01] and it will contain JavaScript [19:03] and this iframe will have access to all [19:06] the tools that are available in the MCP [19:08] server. [19:12] So in another way to think about it is [19:15] you get the entire constellation back. [19:18] You don't get just one star, you get [19:21] everything. It's basically that their [19:23] MCP apps is giving you a map with uh [19:27] augmented reality that you can just put [19:29] in the put in the sky and it will tell [19:31] you oh yeah this is this is the [19:33] direction this is where you want to go. [19:35] So here I'm going to show you an [19:37] example. The good and cold valley card [19:40] is an iframe and every time I modify the [19:43] iframe, it's sending data to the MCP [19:45] server and the MCP server is even [19:48] sending back an animation. And I'm just [19:52] going to play it one more time uh [19:54] because I want to highlight that this uh [19:58] card of cold valley is the MCP app. This [20:02] is not coming from Rails. This is an MCP [20:05] app. Although I'm running it in a Rails [20:07] application, I'm just embedding [20:09] something that's coming from MCP. [20:13] And how am I doing that? Just basically [20:16] setting up my iframe allowing scripts. [20:20] And then I have an MCP client. And then [20:23] after the MCP client is set up, I I call [20:28] the tool get coffee place card. And then [20:31] inside this there is a resource that [20:34] comes from the text. So basically I'm [20:36] just calling an MCP server. And I know [20:40] what you're thinking. We have APIs. Why [20:44] why why do we need this? Or we can [20:46] access database directly. Well MCP is [20:50] built for agents. [20:52] So one of the advantages of using MCP [20:56] apps for example is that you can start [20:58] talking with an agent and it will do [21:01] something similar allow the MCP server [21:05] have the same interface here. I can [21:07] modify the rating I can modify my [21:09] favorite beverage and when I put the [21:14] five rating starts I get the animation [21:17] back and it's all in the chat window. [21:25] There's one more thing I would like to [21:28] share about my past. [21:32] I was terrible at navigation challenges. [21:36] I got lost. I ran out of water and I [21:41] also was a terrible leader in navigation [21:43] challenges. I got my team lost. I led [21:47] them through the hardest part multiple [21:49] times. [21:52] But eventually I got better. [21:55] I even learned trigonometry to be able [21:57] to read maps and be able to tell what [22:00] was happening and how long do we have to [22:02] walk. [22:04] And I think that the same skills that I [22:08] used back then are the same skills that [22:11] have led me to this stage today. It is [22:15] curiosity and my willingness to learn [22:17] from my mistakes. [22:21] It is my curiosity because we saw that I [22:26] was curious about the MCB inspector and [22:29] it was my willingness to learn from my [22:32] mistakes that led me to improve quite [22:35] the [22:38] curiosity what is telling me that I [22:42] should look into this thing called MCP [22:44] apps [22:46] but now now you all have this knowledge [22:50] Now I am curious to see what you're [22:54] going to build with all these tools and [22:56] all this knowledge that you have [22:59] because as we saw today [23:04] the sky is no longer the limit [23:09] and thank you [23:17] >> [music] [23:22] [music]