Seeing MCP From the Inside: An Inspector, a Warm Rails Process, and the Problem of Too Much Context
Ruby on RailsEnrique Mogollan, a software engineer at Handshake, says that a year ago MCP seemed to be everywhere: in the editor, in the agent harness, in the chat. They could recite the one-line definition: MCP is how an agent pulls data from an external source into the context window without you typing it or stuffing it into the prompt. But they admit they didn't really understand how it worked or how it would benefit them. Their answer was to build things. First came an MCP inspector written in Ruby. Then came an MCP server for Rails called Coatepec. Most recently they began exploring MCP apps. Running through the talk is one argument: what you return to an agent matters as much as whether you can return it, and less context often works better.
Night Navigation as a Framing Device
Mogollan opens with a story from home. They grew up in San Miguel de Allende, in central Mexico. Travel magazines praise its cobblestone streets and colonial architecture, but they rarely mention the semi-desert and mountains that surround it. Mogollan spent weekends there as a Boy Scout, and one activity was the navigational challenge. Scouts were dropped at a point with a map and told to reach a destination with no GPS and no phone. That wasn't a rule, they note; those things just didn't exist yet.
During the day the challenges were manageable. You found a landmark such as a hill, a church, a radio tower, or the odd tree everyone used as a marker, and you oriented the map to it. Then someone proposed doing the challenges at night, without a compass, using only a constellation map and the landmark map. Mogollan says they got lost constantly. The hard part was working out which cluster of dots in the sky matched the dots on the page. That feeling of matching dots to symbols is how they describe their first look at raw MCP messages going through an inspector, and the metaphor comes back throughout the talk.
Building an MCP Inspector in Ruby
Anthropic maintains an MCP inspector in Node with hundreds of contributors. Mogollan built one in Ruby anyway, simply to see what this MCP thing was. They had given a talk on it the previous year, and here they pull out two points from that work.
The first is transport. MCP has two transport methods. Standard input/output (stdio) works well for local development and local servers that you connect directly. Streamable HTTP combines standard HTTP with streaming over HTTP. It replaces the earlier HTTP-with-server-sent-events approach, which has been deprecated.
The second is that every message is JSON-RPC. As a result, every conversation between client and server has the same basic shape.
The demo follows the inspector's flow against a filesystem MCP server. The client initializes the connection, lists what the server offers (tools, resources, and prompts are MCP's three primitives), and then calls one. The inspector shows the request as pretty-printed JSON on top and the raw JSON underneath. Mogollan's point, delivered as a joke, is that everyone in the room has now seen raw messages pass between an MCP server and client.
They also highlight how much data is involved. The filesystem server exposes a long list of items, and each comes with a JSON schema describing how to use it. When you execute a tool, the JSON response returns a lot of headers along with the result.
Tokens as Stars, Context as Sky
Back to the night sky. Mogollan argues that points of light are a reasonable picture of how transformer-based models represent language. Each token becomes a vector with thousands of dimensions, which people can't picture. So they flatten it to two dimensions, draw it as a dot, and, "because it's Rails World," make it a star.
In this picture, related tokens cluster together. "Ocean" and "tide" sit close; "ocean" and "tax return" sit far apart. The distance carries meaning, and that mechanism is what lets you find an email from a vague memory of something written ten years ago. The sky is infinite, but you only see part of it at a time; that part is the context window. Lining stars up into a constellation is attention, which you need to find your way: locate Dubhe and Merak to find Polaris, and you have north. Their map of the analogy: stars are tokens, the visible sky is the context window, constellation lines are attention, and MCP is how you put more stars into the sky.
The Real Problem: Slow Boots and Light Pollution
The practical motivation came from a Rails upgrade at work, where Mogollan ran the test suite around 50 times a day. They show a reproduction. They downloaded the RubyEvents app, ran bundle install, and asked an agent to run the tests. One request produces a lot of output. Sometimes the agent has to bundle install first. Sometimes it shows an error, and sometimes it prints deprecation warnings and other noise.
Two problems stood out. First, every test run spent about eight seconds just booting Rails before a single spec ran. Second, all the output kept flowing into the agent's context. Mogollan calls this "light pollution": the stars are still there, but you can no longer pick them out. That led them to ask whether the agent needed all of that data in its context. Their conclusion was no; it needs only the part that matters.
Coatepec: A Warm Rails Sidecar
The result is Coatepec, an MCP server that Mogollan says helps them work faster. They are careful to say this isn't a performance talk. It uses the same protocol, tools, and resources seen in the inspector. What differs is what comes back in the responses.
Coatepec runs as a sidecar process that keeps a warm instance of the Rails app. The agent talks to the Coatepec server with requests like "run this test," "give me the routes," or "tell me about the User model." Because Rails is already loaded, these return in milliseconds instead of waiting the eight-second boot.
In the inspector, Coatepec exposes only seven tools. The one Mogollan considers most important runs specs. Its only parameter is which test to execute, and it returns a small piece of JSON. In an agent demo, they ask for a similar test run on RubyEvents. The agent calls Coatepec, and the expanded call shows a compact JSON result. Mogollan points out that because the response was small and well formatted, Claude chose on its own to present the results as a table. They hadn't asked for one.
Inside the Implementation: Locks, Worktrees, and Fork vs. Spawn
Mogollan walks through the code. The spec-running tool calls a worker manager, which dispatches the run, and dispatch goes through a lock's synchronize. The lock exists to support worktrees, so Coatepec can run several times in parallel. Each new Coatepec process duplicates the database connection, so every process has its own.
The bigger lesson involved process creation. Mogollan works on a Mac, where, as they describe it, the preferred way to start a new process is spawn. They found spawn as slow as running bin/rails directly. A chart shows the spawn approach tracking the bin/rails baseline. The performance gains only appeared after they switched to fork.
Cutting Tokens by 90%
Speed alone didn't satisfy Mogollan. They also wanted the output to be better and more token-efficient. Across several versions of the gem, they report reducing token consumption by 90%. They describe the method as ordinary engineering work: trimming the JSON headers, dropping full error paths, and reporting just which tests passed and which failed.
The Sub-Agent Experiment
They also tried using sub-agents. The plan was to ship a skill telling the agent to always run Coatepec through a sub-agent. It worked, but with a caveat. You do save tokens in the main context window. Each sub-agent, though, needs setup, and that setup ends up burning more tokens overall. Mogollan's takeaway is that unless you have unlimited tokens, you're better off not using sub-agents for this. They say they didn't expect that result.
What Coatepec Does and Deliberately Doesn't Do
A final chart compares operations. Model and route lookups are, in Mogollan's words, basically instantaneous. Spec runs take longer but remain faster than going through bin/rails. The main tools are a Minitest-compatible spec runner, a model inspection tool, and a routes query tool, and Rails engines can be included.
They stress the limits too. Coatepec has no eval, no console, and no raw SQL, and you cannot open a console through it. It is intended for development, not debugging.
The name comes from Coatepec, a mountain town in the Mexican state of Veracruz that grows one of Mogollan's favorite coffees. They were drinking it when they came up with the idea for the gem.
MCP Apps: Getting the Whole Constellation
The last section returns to an inspector, this time Anthropic's Node version, which now supports MCP apps. Mogollan points to a new UI element. As they explain it, MCP apps, which they describe as the first official MCP extension and the direction MCP is heading, let a tool declare that an interface is available. When it is, the server returns HTML meant to be placed in an iframe. That HTML includes styles and JavaScript, and the iframe can access all the tools the MCP server provides.
In their metaphor, you no longer get one star; you get the whole constellation. An MCP app is like an augmented-reality map you hold up to the sky that shows you which way to go.
The demo is a card for a coffee place. Each time Mogollan changes something in the card, it sends data to the MCP server, and the server can send back an animation. They emphasize that although the page is a Rails application, the card is not rendered by Rails. It is an MCP app embedded in the page. The setup is short: an iframe that allows scripts, an MCP client, and a call to a tool called "get coffee place card," whose returned resource supplies the content.
Mogollan anticipates the objection: we already have APIs and direct database access, so why do we need this? Their answer is that MCP is built for agents. They show the same interface working inside an agent chat. They change the rating and their favorite beverage, and a five-star rating triggers the animation, all within the chat window.
Curiosity and Learning From Mistakes
Mogollan ends by returning to the scouts. They were bad at navigation challenges: they got lost, ran out of water, and as a leader took their team the wrong way, through the hardest terrain, more than once. Over time they improved, and even learned trigonometry to read maps and estimate how far the team still had to walk.
They see the same two traits behind the work in this talk. Curiosity led to the MCP inspector. A willingness to learn from mistakes drove the iterations on Coatepec. That same curiosity is now pushing them toward MCP apps, which they present as the next thing to explore rather than a finished project. They close by saying they're curious to see what the audience will build with these tools, because "the sky is no longer the limit."
Hello. Who here has built an MCP server? All right, there are a few hands. Who here has built or saw how the raw messages between a server and a client go? All right, there are a few people, but after today, everyone in this audience will have seen the messages going back and forth between the server and a client.
MCP a year ago was everywhere. It was in my editor. It was in the harness. It was in the chat. And I could give you the one-line definition: MCP is how an agent pulls data from an external source into the context window without you having to type it or stuff it into the prompt. But I really didn't get exactly how it worked. I wasn't sure how it was beneficial for me. So I started doing some things, experiments, ended up building an MCP inspector, and I'm going to tell you about it a little bit.
Hi again, my name is Enrique. I'm a software engineer at Handshake. In Handshake, we help students and young people land their first job. And we're also helping the foundational labs to train their models with the network of students and people that we have.
I am also from Mexico. I'm originally from a town called San Miguel de Allende. It's in the heart of Mexico. Thank you. Maybe you heard about this town. It's one of the places that was named by the travel magazine as one of the best places to live, best places to see, to travel, and it's cobblestone streets, colonial architecture. But something that the magazines don't mention a lot is that semi-desert area that surrounds the town. And after the semi-desert area, there's some mountains.
And I spent a lot of time during my youth on the weekends over there hiking and camping because I was a Boy Scout. And one of the other things that I enjoyed doing over there was this thing called navigational challenges, where they give you a map. They put you in a point and then they tell you, go there, find your place, and you have to follow the map. No GPS, no phone. And not because it was forbidden. It was because it didn't exist back then.
And the navigational challenges during the day were easy, more or less easy. You just have to find a hill, a church, a radio tower, that weird tree that everyone uses as a marker, and then once you find a landmark, you start walking in that direction or you move your map to match it.
But then someone in the Scouts came up with the idea of doing navigational challenges during the night. And that was a little bit harder. It was tricky. I get lost constantly. And the challenge was which cluster of dots in the sky map to the ones that are in my map. And we didn't get a compass during the night. We just had our constellation map and the landmark map.
And I know this is a little bit random, but that feeling of having to match something that are dots with symbols on a page is pretty much what MCP inspector looks like. That's pretty much the same feeling that I got when I saw the first raw message going through.
All right, so a year ago, I built an MCP inspector in Ruby. There is one in Node that is maintained by Anthropic and has hundreds of contributors. But I wanted to build one in Ruby just to be able to see what was this MCP thing. And last year at this Ruby, I gave a talk about this, and I'm not going to give you the same talk, but I'm going to tell you two important things.
One is that there are two transport methods. The first one is stdio, or standard input/output, and that works very well for local development or local MCP servers when you can just connect them directly into your local servers. And the other one is Streamable HTTP, which is a combination of both standard HTTP and stream from HTTP. In the past, this used to be HTTP as server-sent events, but that has been deprecated in favor of Streamable HTTP.
The second thing that you need to know about the inspector or MCP is that all the messages are in JSON-RPC. So every conversation, in a way, has the same shape.
And I'm going to show you a demo of the MCP inspector. First, we're going to look at how we set up the MCP server. Then we're going to list the tools. Remember, for MCP there are tools, resources, and prompts. And finally, we're going to execute a call.
All right. So we're here seeing the setup. I'm showing you the list. This is the filesystem MCP server. So it has a bunch of things, and I'm here. I'm actually executing one of the requests. And as you can see, at the top there's pretty JSON. At the bottom is the raw JSON. And now everyone in the audience has seen raw JSON going back and forth between an MCP server and a client.
All right. So again, the inspector is the initialize, and then you can list tools, resources, and prompts. And then you can execute or call each of these. But one thing I want to highlight is that the MCP server for filesystem has a bunch of things, a long list, and each of these items has a schema. And the schema is also JSON, or how you can use the tool. And then when you actually execute the tool, there's a lot of headers that come back from the JSON response.
All right. So let's go back for a moment to Mexico and the navigational challenges, because I told you during the day it was kind of easy, but during the night it was more complicated because all the things that you have is just points in the sky.
And actually, points in the sky is not a bad representation of what is happening with LLM models when they use transformers in the background, because what they do is they take a token and make it a vector, a multidimensional vector that uses thousands of dimensions.
But we as humans, it's very difficult for us to imagine how this vector is represented in multiple dimensions. So today, we're going to flatten this vector, and we're going to put it in two dimensions. And because it's two dimensions, we're just going to put it into a little tiny dot. And today, because it's a special day, because it's Rails World, we're going to make it a star.
So basically, a token is a vector or a star in the sky. And then when you group stars, when you put them together, it's tokens that have similarities between them. For example, ocean and tide are together, but ocean and tax return are completely separated. And this distance has some meaning, and this is the mechanism that is used to be able to determine the semantic significance of things. And this is how you can find an email by vaguely remembering something random from 10 years ago.
And then when you put it together, although there's infinite sky, there's only a few portions of the sky that you can see at a time. So that's your context window. And then when we try to align the stars to match a specific constellation, that's our attention. And that is important for us because we want to find our path. And in order to be able to find our path, we have to find Dubhe and Merak to be able to find the Polaris star, find north.
So here's our map. Stars are tokens. The sky is the context window, and constellation lines are attention, and MCP is how you put more stars into the sky.
All right. So let's go back to a problem in real life. Here I am running the tests, or I'm asking an agent to run the tests for RubyEvents. I just downloaded RubyEvents, ran bundle install, and told the agent, can you run the tests? And as you can see, there are a lot of things that are happening, because sometimes it has to bundle install first. Sometimes it shows me the error one time, or it can also show me the warnings of the things that are happening, the deprecations. So it's a lot of things that are happening in one request.
So this happened to me when I was upgrading Rails at work. I was constantly running the test suite 50 times a day. And one of the things that happened to me was that every time I ran the tests, it took eight seconds for my server to start, just Rails to boot to be able to run a spec.
And then all the context that started coming back is like stars that were adding and adding into my context. And I call it light pollution that prevents me from seeing the stars in the sky. But that doesn't mean that the stars are not there. The stars are there. I just lost my ability to find them.
So I started questioning myself: do we actually need all this context, all this data into the context? And I think the answer is no. We don't need all that data. We just need a portion that is important to us. So I started working on something, something that I call Coatepec. And Coatepec is an MCP server. And this is not a performance talk, but it's an MCP server that is helping me do my work faster.
And it's the same protocol that we watched in the inspector, same tools, resources, but the difference is what we get back from the response.
So how does it work? It works by creating a sidecar process, and it creates a warm Rails version of my Rails process. And then the agent just talks to this Coatepec server, and it tells it, can you run the tests? Can you give me the routes for this? Can you tell me about the model User? And instead of taking eight seconds to boot Rails, it just takes milliseconds.
And how does it look in the inspector? Here I have seven tools, only seven tools. The first one is Rails Spec Run, and I think this is the most important. And the parameters are just which test you want to execute. And after we execute it, we get just a small little portion of JSON.
So let me show you how it runs in an agent. Here I'm telling the agent to run the same similar test in the RubyEvents app. And it's thinking. It called Coatepec, and I'm going to expand the call there. And you can see it's just a small JSON. And because it's very small and very well formatted, Claude determined that the best way for me to see the data was to build a table. I didn't ask it to build a table. It just did it because the JSON was formatted in the right way.
All right. So how does the MCP server for Coatepec work? Here I'm showing you the definition of the tool. It's called Rails Spec Run. And basically here I'm calling a worker manager to run the spec. And inside run the spec, there's a call to dispatch, and dispatch calls lock synchronize. And this lock is to be able to use worktrees. So we can use Coatepec multiple times, because every time you create a new process with Coatepec for Rails, it will duplicate the database connection. So each process gets its own database connection.
But one thing that I want you to notice is that here it says client spawn. And this is because I work on a Mac computer, and on Mac computers the preferred method to start a new server or new process is with spawn. However, spawn is very slow. It's as slow as using just bin/rails directly. So instead of using spawn, I switched it to use fork. And at the top, the orange line is bin/rails, the same as spawn. But when I switched to fork is when I started to get performance gains.
Now I was not satisfied to just be faster. I also wanted to be better and more token efficient. So over different versions of the gem, I was able to reduce the token consumption by 90%. And this is basically just adjusting the JSON headers or not sending the full path of the error and just sending which tests pass, which tests fail, just trying, making engineering work.
All right. I also tried to take advantage of subagents, and I was successful. My original idea was to include the skill to tell it to always use Coatepec with a subagent, and that works, but it has a caveat. And the caveat is that, yes, you save tokens on your main context window, but on the other hand, every time you spawn a subagent, you have to do some setup, and that setup is going to end up burning more tokens at the end. So if you don't have unlimited tokens, it's better if you don't use agents. And for me that was interesting, something that I didn't expect to find.
All right. So one last graph of how it behaves. Model and routes is just basically instantaneous. You can talk to Coatepec to get data from Rails. And then when you try to run the spec, it's still faster than just bin/rails.
And yes, the main tools that are available are the Spec Run that is Minitest compatible, Rails Model and Rails Route to just query. And you can also include your Rails engines if you have ones. But one thing that I wanted to make sure is that this has no eval, no console, no raw SQL. You cannot start a console from Coatepec. It's just for development. It's not for debugging.
And one thing I want to mention is why is the name of the gem Coatepec? Well, in Mexico there is the state of Veracruz. And in Veracruz there is this place called Coatepec. It's up in the mountains, and it has one of my favorite coffees. So I was just drinking coffee when I thought about the gem.
All right. So we're going to go back to the inspector, but it's not the Ruby inspector. This is the Node inspector, the Node MCP inspector. And I want to show you something that is different, something that is interesting, because now they ship something called MCP apps. And one thing that I want to highlight is that it has a new thing called UI.
So basically, what MCP apps, or the future of MCP based on this official first extension, is a tool that tells you that there's an interface available. And when the interface is available, it sends you back an HTML that you can put inside an iframe. And this iframe will contain the HTML, will contain the styles, and it will contain JavaScript. And this iframe will have access to all the tools that are available in the MCP server.
So another way to think about it is you get the entire constellation back. You don't get just one star, you get everything. It's basically that MCP apps is giving you a map with augmented reality that you can just put in the sky, and it will tell you, oh yeah, this is the direction, this is where you want to go.
So here I'm going to show you an example. The good and cold valley card is an iframe, and every time I modify the iframe, it's sending data to the MCP server, and the MCP server is even sending back an animation. And I'm just going to play it one more time because I want to highlight that this card of cold valley is the MCP app. This is not coming from Rails. This is an MCP app. Although I'm running it in a Rails application, I'm just embedding something that's coming from MCP.
And how am I doing that? Just basically setting up my iframe, allowing scripts. And then I have an MCP client. And then after the MCP client is set up, I call the tool get coffee place card. And then inside this, there is a resource that comes from the text. So basically I'm just calling an MCP server. And I know what you're thinking. We have APIs. Why do we need this? Or we can access the database directly. Well, MCP is built for agents.
So one of the advantages of using MCP apps, for example, is that you can start talking with an agent, and it will do something similar, allow the MCP server to have the same interface here. I can modify the rating. I can modify my favorite beverage. And when I put the five rating stars, I get the animation back, and it's all in the chat window.
There's one more thing I would like to share about my past. I was terrible at navigation challenges. I got lost. I ran out of water, and I also was a terrible leader in navigation challenges. I got my team lost. I led them through the hardest part multiple times. But eventually I got better. I even learned trigonometry to be able to read maps and be able to tell what was happening and how long do we have to walk.
And I think that the same skills that I used back then are the same skills that have led me to this stage today. It is curiosity and my willingness to learn from my mistakes. It is my curiosity, because we saw that I was curious about the MCP inspector, and it was my willingness to learn from my mistakes that led me to improve Coatepec. Curiosity was telling me that I should look into this thing called MCP apps.
But now you all have this knowledge. Now I am curious to see what you're going to build with all these tools and all this knowledge that you have, because as we saw today, the sky is no longer the limit. And thank you.
Article published · Updated
