Your App Should Ship an MCP Server

mooreds1 pts0 comments

Your App Should Ship an MCP Server

Skip to content<br>On this page<br>The Problem: GUI Apps Are Opaque to AI Agents<br>The Solution: Make the App Speak MCP<br>1. The In-App MCP Server<br>2. The Lifecycle Wrapper<br>The SDLC Loop<br>What Tools Does the Server Expose?<br>What This Actually Enables<br>AI-Driven Iteration and Verification<br>Structured Test Authoring<br>The "Rebuild" Pattern<br>The Broader Principle

Your App Should Ship an MCP Server<br>By Justin Poehnelt · May 1, 2026 Markdown<br>svg]:pointer-events-none [&>svg]:size-3 bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90 border-transparent not-prose no-underline hover:no-underline" aria-label="Tag: ai">#ai svg]:pointer-events-none [&>svg]:size-3 bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90 border-transparent not-prose no-underline hover:no-underline" aria-label="Tag: mcp">#mcp svg]:pointer-events-none [&>svg]:size-3 bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90 border-transparent not-prose no-underline hover:no-underline" aria-label="Tag: rust">#rust svg]:pointer-events-none [&>svg]:size-3 bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90 border-transparent not-prose no-underline hover:no-underline" aria-label="Tag: agents">#agents svg]:pointer-events-none [&>svg]:size-3 bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90 border-transparent not-prose no-underline hover:no-underline" aria-label="Tag: code">#code svg]:pointer-events-none [&>svg]:size-3 bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90 border-transparent not-prose no-underline hover:no-underline" aria-label="Tag: native">#native svg]:pointer-events-none [&>svg]:size-3 bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90 border-transparent not-prose no-underline hover:no-underline" aria-label="Tag: gpui">#gpui

I’m building a native desktop editor for fiction writers. It’s written in Rust on top of gpui, by the Zed team. Under the hood, it generates a fiction specific AST, runs ~120 prose-craft analyzers and uses a multi-task ONNX transformer model against your manuscript in real time, surfacing things like show-don’t-tell violations, passive voice, pacing issues, and much more.<br>I started out using gpui-component, but the available Input component was not sufficient for building the complex UI I wanted with a CRDT backing, so I ended up with my own buffer based system and building the entire text editing UX from scratch. This is not recommended!<br>To solve for this complexity, I embedded a full MCP server directly inside the application binary. It has since become the single most impactful architectural decision I’ve made on this project, not for users, but for how I Claude builds the product itself.<br>Here’s the case for why your application should do the same.<br>The Problem: GUI Apps Are Opaque to AI Agents<br>If you’re building a native desktop application in 2026, you’ve probably noticed a gap. Your AI coding assistant can read your source code, run your tests, and even propose edits. However, your AI cannot always see your running application. It can’t click a button, type into a text field, verify that a diagnostic tooltip rendered correctly, or confirm that a scrollbar stopped at the right position.<br>For web apps, this is a solved problem with headless browsers, Playwright, Chrome MCP, etc. For native apps, especially those built on GPU-accelerated frameworks like gpui, you’re largely on your own. There’s no DOM to query. There’s no accessibility tree you can trivially script against. The rendered output is just a texture.<br>I spent too long in a loop that looked like this:<br>Read the source code<br>Make a change<br>cargo build<br>Manually launch the app<br>Manually paste in test prose<br>Squint at the screen<br>Screenshot it myself<br>Paste the screenshot into the AI interface<br>Repeat<br>Steps 4 through 8 are the bottleneck, and no amount of faster builds fixes that. The feedback loop is human-gated.

The Solution: Make the App Speak MCP<br>The Model Context Protocol is essentially a standardized JSON-RPC interface that AI agents already know how to speak. If your app exposes MCP tools, any MCP-compatible client can drive your application programmatically.<br>My implementation has two pieces:<br>1. The In-App MCP Server<br>When launched with --mcp, the app starts a background thread that reads newline-delimited JSON-RPC from stdin and writes responses to stdout. Commands are dispatched into the gpui event loop.<br>This is ~200 lines of Rust. No external dependencies beyond serde_json. The protocol surface is minimal: initialize, tools/list, and tools/call. That’s it (for now).<br>2. The Lifecycle Wrapper<br>This is a separate binary that manages the app process. It:<br>Builds the app from source on startup<br>Launches it with --mcp<br>Proxies all JSON-RPC between the MCP client and the app<br>Intercepts a special rebuild tool call to stop the app, run cargo build, and relaunch, without dropping the MCP connection<br>The wrapper feels like a hack and there is probably a...

secondary hover underline text prose server

Related Articles