Turning React’s Fiber Tree into an Queryable MCP Tool: Notes from Building vite-react-mcp
Notes from building vite-react-mcp: connecting MCP ideas with React internals to expose runtime state as an LLM-queryable tool.
This post is a snapshot of my thinking while building vite-react-mcp — less a polished showcase and more a technical diary for my future self. It documents how I connected Model Context Protocol (MCP) ideas with React internals to expose runtime state as an LLM-queryable tool.
The Spark: MCP as Structured Tool Invocation
I was initially drawn to MCP because of its promise: a standardized way for LLMs to call tools. After digging in, I realized something important:
At its core, MCP isn’t magic. It’s still prompting an LLM to invoke structured tool calls. The innovation is in standardization and ergonomics, not in changing the fundamental nature of LLM interaction.
That realization reframed MCP for me. Instead of seeing it as a new paradigm, I started seeing it as a clean interface layer that lets us design richer agent workflows.
MCP vs RAG: Dynamic Context Beats Static Retrieval
What excited me more was how MCP compares to traditional RAG systems.
RAG tends to preload or retrieve static context. MCP, by contrast, lets an LLM dynamically load context at the moment it needs it via tool calls. This shifts the architecture from:
“Here’s a big chunk of context, hope it’s enough”
to:
“Ask for exactly what you need, when you need it”
That subtle shift is powerful. It encourages designing systems where runtime state is exposed as queryable capabilities. The question then became:
What high-value runtime context could I expose?
React Internals as a Context Source
Having previously studied React’s source code, I knew how much information lives inside the Fiber tree. The Fiber architecture encodes:
- Component hierarchy
- State and props
- Hooks and internal bookkeeping
- Render scheduling information
For an LLM trying to reason about a running React app, this is gold. If an agent could query the Fiber tree, it could understand the UI’s actual runtime structure instead of guessing from source code alone.
So the idea was simple:
Expose React’s internal runtime state as MCP tools.
Bridging Fiber to Tool Calls
The main architectural challenge was bridging two worlds:
- React’s internal Fiber representation
- MCP’s structured, queryable tool interface
Fortunately, React DevTools had already solved a large part of this problem. If you’ve used React DevTools, you know it can introspect and manipulate React’s internal state in impressive ways.
The catch: React DevTools is built as a browser extension, not as a public API.
To reuse its capabilities, I needed to effectively hijack the DevTools bridge — turning what was meant for an extension UI into a programmatic interface that an MCP server could expose.
This reframed the architecture:
- Hook into the same internals React DevTools uses
- Capture Fiber data and state snapshots
- Normalize that data into a stable schema
- Expose it as MCP tools that an LLM can query
Standing on Bippy’s Shoulders
I didn’t have to start from scratch. The project at https://github.com/aidenybai/bippy provided a crucial foundation.
Bippy already explores instrumentation and introspection around React internals. It offered a practical starting point for tapping into the DevTools communication layer and experimenting with Fiber extraction.
Instead of reinventing the plumbing, I could focus on:
- Designing MCP-friendly schemas
- Building a Vite integration workflow
- Ensuring the exposed data is useful for agent reasoning
Architectural Shape of vite-react-mcp
At a high level, vite-react-mcp looks like this:
React App
↓
DevTools Hook / Bippy Instrumentation
↓
Fiber Extraction & Normalization Layer
↓
MCP Server Interface
↓
LLM Tool Calls
Each layer has a clear responsibility:
- Instrumentation: Tap into React internals safely
- Extraction: Convert Fiber structures into serializable data
- Normalization: Present stable, queryable schemas
- MCP Interface: Expose tools with predictable semantics
The key design constraint was stability. React internals are not public APIs and can change. So the normalization layer acts as a buffer, insulating the MCP interface from raw internal churn.
Lessons and Pitfalls
A few things stood out during development:
1. Internal APIs Are Moving Targets
Anything built on React internals must assume breakage. Defensive coding and version awareness are not optional.
2. Schema Design Matters More Than Extraction
Extracting data is easy compared to designing a schema that an LLM can reason about effectively. The shape of the tool response heavily influences how useful it is in agent workflows.
3. Observability vs Overhead
Hooking into runtime internals introduces performance considerations. The system needs to balance observability with minimal impact on the app.
4. Agent-First Thinking Changes Architecture
Designing for LLM consumption forces you to think differently. Instead of optimizing for human UI, you optimize for machine query patterns and composable tool semantics.
Why This Matters (to Future Me)
The deeper takeaway isn’t just about React or MCP.
It’s about a pattern:
Expose rich runtime systems as structured, queryable interfaces for agents.
React Fiber is just one example. The same idea applies to databases, build systems, CI pipelines, and developer tooling in general.
vite-react-mcp is a small experiment in that direction — a prototype of how developer environments can become agent-native.
And if I revisit this months or years later, I hope I remember that the real value wasn’t the code itself, but the architectural intuition it helped sharpen.
If you want, I can tune the tone (more casual vs more academic), add diagrams, or expand any section into deeper technical detail.