MCP Apps: Give the Model Data, Give the User a UI - Dustin Mihalik, Indeed

Building effective MCP apps requires designing around data exposure to the model first, keeping model context in sync with UI, and separating data processing...

By Sean Weldon

MCP Apps: Give the Model Data, Give the User a UI

Abstract

The emergence of Model Context Protocol (MCP) apps - tool integrations that return interactive user interface components rather than plain text - introduces a design problem largely absent from conventional API integration: the language model and the rendered interface can diverge, producing redundant narration, blind spots in model reasoning, and prematurely truncated exploration. Drawing on practitioner experience from Indeed's implementation of MCP apps, this synthesis consolidates three design rules: data displayed to the user must simultaneously be supplied as structured data to the model, user interactions with rendered components must be propagated back into model context, and data-retrieval tools must be architecturally separated from UI-rendering tools. The evidence indicates that failure to separate retrieval from rendering suppresses the model's multi-query exploration behavior. The recommended pattern favors small, composable tools in which rendering is a byproduct of data exploration rather than its starting point.

1. Introduction

Tool-calling integrations for large language models have historically returned text. Text responses are portable and legible to the model, but they impose costs on organizations exposing them: responses carry no branding, and links back to the originating service appear inconsistently. Practitioners report that inducing assistants such as Claude or ChatGPT to reliably link out to external content required substantial prompt engineering and evaluation effort, with fragile results even after significant investment.

MCP apps address this limitation by permitting a tool to return a rendered interface - buttons, detail modals, cards, widgets - that the host application displays inline. The provider regains control over presentation, calls-to-action such as "apply" or "add to cart," and user retention within the conversational environment. This capability, however, introduces a dual-consumer problem: a tool result now has two audiences, the human user who sees rendered pixels and the model that sees tokens. When these two representations desynchronize, the system degrades in predictable ways - the model narrates redundantly, misses information visible to the user, or halts exploration prematurely.

This synthesis argues that effective MCP app design requires three ordered commitments: exposing data to the model before or alongside exposing it to the user, keeping model context synchronized with subsequent UI interactions, and structurally separating the tools that fetch data from the tools that render it. Section 2 situates these commitments within the MCP app specification and adjacent industry guidance. Section 3 analyzes each rule in turn, with particular attention to the third, which the source material identifies as superseding the others. Section 4 distills implementation guidance, and Section 5 discusses broader implications for tool-calling system design.

2. Background and Related Work

The MCP app specification defines the return contract for a UI-producing tool. A compliant response comprises two elements: structured content, a machine-readable payload consumed by the model, and a resource URI pointing to the HTML artifact rendered for the user. The requirement that both be returned is not incidental - it encodes the assumption that model-visible and user-visible representations must remain in correspondence. A second protocol primitive, the update model context method, provides a channel for post-render communication, accepting a single string injected into the model's context to report events occurring after the initial tool result was produced.

The architectural guidance analyzed here draws directly on the OpenAI Apps SDK documentation, from which the phrase "separate your data processing from your UI rendering" is explicitly adopted. Two recurring design patterns emerge: the data/render tool split and the small composable tool pattern, both of which contrast with the monolithic "call the existing API and inject HTML" approach that naive ports of REST services tend to produce.

3. Core Analysis

3.1 Rule 1 - Supply Data to the Model, Not Only to the UI

The most common implementation error treats an MCP app as a rendering shim over an existing API: the tool invokes a backend, transforms the response into HTML, and returns only the markup. This produces a "black box" in which the model cannot see what the user sees. The corrective principle is direct: "anything that you show to the user also needs to be provided as data to the model." In practice this means returning structured content alongside the resource URI, per the MCP app spec, and maintaining synchronization between the two as the tool evolves.

A secondary complication surfaces even after this rule is satisfied: the model may still redundantly re-describe results in text, duplicating what the UI already displays. This is addressed not through data changes but through tool description changes - explicitly stating that "results were automatically displayed to the user as UI components" measurably reduces redundant textual output. This finding indicates that model behavior in MCP app contexts is governed as much by descriptive metadata as by the underlying data payload.

3.2 Rule 2 - Track User Interactions with UI

Interactive elements such as "view details" buttons generate state changes that the model has no visibility into by default. The update model context method addresses this by allowing the UI to pass interaction data back to the model as a string. Because the mechanism accepts only a single string, tracking multiple events over time requires appending to that string rather than replacing it - a constraint with direct implementation consequences for any UI that accumulates state, such as a shopping cart. In the cart example, each added item and its cost are appended to the context string so that the model can subsequently answer questions about cart contents without re-querying the backend. This rule demonstrates that UI state and model state are not automatically reconciled by the protocol; reconciliation is an explicit engineering responsibility.

3.3 Rule 3 - Separate Data Processing from UI Rendering

This rule is identified as superseding all others. The underlying mechanism is behavioral: when results are automatically displayed via UI, the model ceases the deep, multi-query exploration it would otherwise perform in a text-only mode. Once a widget renders, the model appears to treat the task as complete, even when the rendered subset represents a small fraction of a larger, unexplored dataset.

The remedy is architectural rather than descriptive: split a single tool into a data tool (e.g., "search jobs," which returns no UI) and a render tool (e.g., "render jobs widget," which accepts a list of IDs). This separation allows the model to explore a large result set - the example given is on the order of 100 jobs - before selecting a filtered subset, such as 5, to render. Tool descriptions must explicitly specify tool call ordering, instructing the model to invoke the data tool before the render tool. The pattern generalizes beyond job search to e-commerce product listings, map and address rendering, and any domain where a large candidate set must be narrowed before presentation.

An extension of this pattern allows render tools to accept additional model-generated fields - a "reason why this is a good fit," or highlighted text spans - enabling the model to inject qualitative judgment into the UI rather than confining its contribution to raw filtering.

4. Technical Insights

Several implementation-level conclusions follow from the analysis above:

A notable trade-off is that this architecture assumes the model can reliably follow explicit sequencing instructions in tool descriptions; the source material does not report failure rates or edge cases where this ordering breaks down, representing a gap for further empirical evaluation.

5. Discussion

These findings point toward a broader principle in tool-calling system design: rendering surfaces should not be treated as terminal outputs but as one possible byproduct of a reasoning process the model is otherwise free to continue. The observation that auto-rendered UI suppresses multi-query exploration is significant because it implies that UI presence itself, independent of its content, functions as an implicit signal of task completion to the model. This has implications beyond MCP apps for any system that mixes structured tool output with rendered artifacts.

The emphasis on tool description wording as a primary lever - rather than changes to data schemas or protocol mechanics - suggests that prompt-adjacent engineering remains a first-class design activity even within structured protocols like MCP. This aligns with the broader industry pattern in which small, composable tools with narrow, well-described responsibilities outperform monolithic tools with broad scope, a pattern echoed in the source's framing: complex reasoning ("hard problems") should be left to the model, while tools should handle narrow, well-defined data or rendering responsibilities.

Open questions remain regarding scalability of the append-only context string as interaction histories grow, and regarding how these rules generalize to multi-turn sessions involving several distinct render tools operating on overlapping datasets.

6. Conclusion

This synthesis identifies three design rules for MCP apps - supplying data to the model, propagating UI interactions back into context, and separating data retrieval from rendering - with the third identified as foundational. The practical takeaway is that MCP app design should begin with data modeling and tool decomposition rather than interface design, treating UI rendering as an optional final step in a chain the model itself controls. Organizations building MCP apps should prioritize small, composable tools with explicit, ordering-aware descriptions, and should anticipate that render tools can be productively extended with model-generated qualitative annotations without compromising the underlying separation principle.


Sources


About the Author

Sean Weldon is an AI engineer and systems architect specializing in autonomous systems, agentic workflows, and applied machine learning. He builds production AI systems that automate complex business operations.

LinkedIn | Website | GitHub