Levr
All articles
Agentic Development

Build MCP Apps with Data-First UI Design

MCP apps combine Model Context Protocol tools with interactive interfaces inside chat clients, but a useful interface must not hide state from the coding agent. Every result, selection, and detail exposed in a widget needs an equivalent structured representation that the model can reason over. The s

MMichael SwindellSeptember 11, 202618 min read

MCP apps combine Model Context Protocol tools with interactive interfaces inside chat clients, but a useful interface must not hide state from the coding agent. Every result, selection, and detail exposed in a widget needs an equivalent structured representation that the model can reason over. The stronger design separates exploration from presentation: data tools support repeated searching, filtering, and comparison, while focused render tools display the final choices. This approach prevents a polished widget from reducing agent capability. An agent-first control plane such as Levr applies the same idea to engineering work by keeping issues, acceptance criteria, tests, and workflow state available to both people and agents.

At a Glance

A practical architecture for MCP apps that improves both UI quality and model reasoning.

  • Shared state: Anything a user sees in an MCP app should also be available to the model as structured data.
  • Clear instructions: Tool descriptions must explain when a UI renders results so the model does not duplicate the interface in text.
  • Interaction context: Selections, opened details, and other user actions need to return to the model context.
  • Tool separation: Keep retrieval and reasoning tools separate from rendering tools so the model can explore before it presents.
  • Composable design: Small, focused tools give models more flexibility than a single large UI-driven tool.

Why can an MCP app UI make an agent less useful?

An MCP app can reduce agent quality when rendering results causes the model to stop searching, filtering, or comparing options. A UI should improve presentation without replacing the agent’s reasoning process. The model still needs access to the underlying data and freedom to call retrieval tools repeatedly.

Interactive UI is valuable in chat applications. It can present branded results, make primary actions obvious, and keep important details within the conversation rather than forcing users to navigate elsewhere. A job result, product listing, support case, or engineering task becomes easier to scan when it has buttons, cards, summaries, and drill-down views.

But a rendered widget can accidentally signal that the task is complete. If a search tool both finds records and immediately presents a carousel, the model may call it once, notice that results are on screen, and stop. That behavior is acceptable for a simple lookup. It fails when the real request requires broad exploration, filtering, ranking, or synthesis.

For example, a request for a new job may require searches across multiple locations, exclusion of certain industries, compensation comparison, and a final shortlist. A plain data tool can support all of that work. A single UI-returning search tool can prematurely narrow the agent’s behavior to one result set.

The key distinction is simple: rendering is not reasoning. The UI should show the outcome of a reasoning process, not constrain that process.

What data must the model receive when a widget displays results?

The model should receive the same meaningful facts that the widget displays, including identifiers, labels, attributes, rankings, and available actions. Without that shared representation, the UI becomes a black box and the model cannot answer follow-up questions accurately or act on what is shown.

Consider a search result card that displays a title, company, location, salary range, short description, and link. If those fields are fetched only by the embedded UI, the model does not necessarily know which results appeared or what each record contains.

That gap becomes visible as soon as a user asks a follow-up:

  • “Tell me more about the first result.”
  • “Which option has the highest pay?”
  • “Compare the companies in this list.”
  • “Draft a cover letter for the role I opened.”
  • “Show only results that match my earlier criteria.”

A model cannot reliably answer these requests if the information lives only inside a client-side component or behind an API call that occurred outside its context. It may hallucinate, ask the user to repeat details, or make a fresh search that does not match what is on screen.

The practical pattern is to return two coordinated outputs: structured content for model reasoning and a UI resource for presentation. The structured payload should include the data needed for natural-language follow-ups, while the UI resource provides the visual experience. The two must remain synchronized as the product changes.

This is consistent with the Model Context Protocol’s tool model, which is designed for tools to return structured content alongside other response content. Review the Model Context Protocol tools specification when designing return schemas and tool contracts.

How should tool descriptions handle rendered UI?

Tool descriptions should explicitly tell the model that an interface renders results for the user. This instruction prevents unnecessary text duplication and gives the model a clear division of labor: the widget presents detailed results, while the response adds concise context, decisions, or next actions.

Without this guidance, a model behaves as it normally would after a successful tool call. It may summarize every result beneath the widget, recreate a table that the UI already displays, or repeat links and details that are easier to inspect in the rendered interface.

The result is not necessarily wrong, but it is noisy. It can also crowd out the useful part of the assistant response, such as an explanation of why certain options were selected or a question needed to refine the search.

Descriptions should establish three expectations:

  • What is rendered: State whether search results, a selected record, a map, a cart, or another interface appears automatically.
  • What the model should say: Tell the model whether to provide a brief summary, a recommendation, or no duplicate listing at all.
  • What comes next: Explain which retrieval tools must be called before a rendering tool and what data shape the renderer expects.

A short instruction can cover a large portion of the problem. For instance, a tool description can state that the results are already displayed in UI components and that the model should summarize its decision rather than reproduce the full list. Good descriptions are not documentation for humans alone. They are behavioral controls for the model.

How do you keep the model aware of user interactions?

User interactions must be added back into model context whenever they affect a possible follow-up request. If someone opens a record, changes a selection, updates a cart, or chooses a filter, the agent needs that state to answer correctly and continue the task without guessing.

Rendered interfaces often fetch details on demand. That is a sensible UI optimization, but it creates a context problem. Suppose a widget displays ten job cards and someone opens the detailed description for one of them. The app knows which card was opened. The model may not.

The same issue appears in many domains:

  • Commerce: A user adds products to a cart, adjusts quantities, or selects a shipping option.
  • Maps: A user clicks a location, opens directions, or chooses among nearby addresses.
  • Support: A user expands a case, selects an account, or chooses a recommended resolution.
  • Engineering: A developer opens an issue, selects a test failure, or approves a proposed implementation plan.

MCP apps provide a mechanism for updating model context from the UI. The context update is a string, so applications that need to preserve multiple events should establish a disciplined format for appending state. Include enough detail to identify the action and record involved, but avoid dumping unrelated UI data into the context. Persisting these interactions across turns is exactly the state-management problem covered in advanced MCP app patterns for bidirectional state.

A useful interaction update includes the selected object’s stable ID, the action taken, a compact summary of relevant fields, and any state that affects permitted next steps. For example, “Selected job ID 1842, opened detailed description, location Austin, role barista” gives the model a concrete reference for later requests.

Why should data processing and UI rendering be separate tools?

Separate tools let the model search, filter, rank, and compare data as deeply as needed before choosing what to display. Retrieval tools provide reasoning flexibility, while rendering tools create a focused interface from selected records. Combining both jobs in one tool often limits exploration.

This is the most important architectural decision for an MCP app. A model handles complex requests well when it can make multiple data calls, inspect the outputs, revise its plan, and eventually present a carefully selected result set.

A job-search architecture illustrates the pattern:

  • Search jobs: Returns matching jobs as structured data, with no UI.
  • Get job details: Retrieves complete information for a specific job when needed.
  • Render job list: Takes a selected list of job IDs and displays a concise result widget.
  • Render job highlight: Displays one recommended job with relevant context and action controls.

The model can now run many searches across cities or criteria, process a large result set, identify five relevant records, and render only those five. The user gets a focused interface. The model retains the ability to do difficult work before the UI appears.

This separation also makes tools easier to test. You can evaluate retrieval quality independently from UI selection and rendering behavior. When a result looks wrong, the team can determine whether the problem came from search, filtering, ranking, tool instructions, or presentation. This separation is the same discipline covered in tool binding and runtime control in AI coding agents.

OpenAI’s Apps SDK documentation similarly emphasizes separating data processing from interface rendering. Treat that separation as a product architecture rule, not a cosmetic implementation choice.

Give coding agents shared project state, not disconnected prompts.

Levr keeps issues, acceptance criteria, test results, workflow gates, and attribution in a shared control plane that humans and coding agents can update together.

Explore agent-first project workflows

How can render tools improve a result instead of only displaying it?

Render tools can accept model-generated rationale alongside record IDs, allowing the UI to show why an option was selected or which detail matters most. This keeps the model’s synthesis connected to the interface while preserving a structured and reviewable rendering contract.

A render tool does not need to be a passive display function. It can take controlled, typed inputs that enrich the user experience without moving business logic into opaque UI code.

For a shortlist of jobs, products, documents, or incidents, a renderer might accept:

  • A stable record ID.
  • A concise explanation of relevance.
  • A highlighted requirement, attribute, or excerpt.
  • A ranking position or recommendation category.
  • A suggested next action, such as opening details or applying a filter.

This lets the model add judgment where it has value. A result card can explain that a role was chosen because it meets the location preference, avoids excluded industries, and offers competitive compensation. A map card can note why a location fits a route constraint. An engineering issue card can explain why a failing test likely blocks a release.

Keep the input contract narrow. The model should not be allowed to inject arbitrary markup or invent facts that the UI treats as trusted data. Store model-authored rationale separately from canonical record fields, label it clearly, and preserve the source record ID so the reasoning can be traced to the facts that supported it.

What does a composable MCP toolset look like in practice?

A composable MCP toolset uses small tools with clear responsibilities, rather than one broad tool that retrieves, reasons, mutates state, and renders a complete UI. This gives the model more valid paths through a task while making tool descriptions, evaluations, permissions, and failures easier to manage.

Large all-in-one tools are tempting because they look convenient. A tool named searchAndDisplayJobs may appear easier to build than several focused capabilities. Yet it forces one interaction pattern and makes it difficult for the model to handle requests that do not fit that pattern.

A composable design usually separates tools by intent:

  • Discovery tools: Search, list, retrieve, or inspect available data.
  • Reasoning support tools: Compare records, validate constraints, or retrieve deeper details.
  • State tools: Record a selection, update a preference, or save a draft.
  • Rendering tools: Present a chosen list, a record detail, a map, or an action panel.

Each tool should have a narrowly defined input schema and an accurate description of what it returns. Small tools reduce prompt complexity because the model does not need to infer numerous modes from one overloaded interface. They also produce cleaner evaluations because each tool can be tested against a specific job.

Composability does not mean creating a separate tool for every UI pixel. The goal is to expose meaningful operations that map to user goals and agent reasoning steps.

How do you apply data-first MCP design to engineering workflows?

Apply data-first MCP design by exposing work items, acceptance criteria, tests, code changes, and workflow status as shared structured objects before rendering dashboards or task interfaces. Coding agents can then investigate and act on the same project state that developers and engineering managers inspect.

The same problem appears when coding agents work from isolated prompts. A dashboard might show sprint health, blocked issues, test failures, and pull request status, while an agent sees only a short task description. That creates two versions of reality: one for the team and another for automation.

A better engineering workflow gives the agent structured access to:

  • Issue descriptions and acceptance criteria.
  • Related defects, dependencies, and prior decisions.
  • Test suites, run results, and failing cases.
  • Pull request and CI/CD status connected to the work item.
  • Workflow gates that define what must happen before completion.

One way to handle this in Levr’s agent-first features is to keep the issue, tests, execution results, and activity history in the same shared graph. A coding agent can read the task contract, work against it, record relevant test evidence, and update the same item the team reviews.

This model supports varied autonomy levels. A person can define the intent, let an agent implement the work, use automated verification as a gate, and retain final approval. The workflow stays coherent because the project context is not trapped in a dashboard, a chat thread, or a local agent session.

Structured Data, Verified by the Agent Loop

The Levr Dashboard exposes issues, acceptance criteria, and linked test results as structured objects an agent can act on directly. Workflow gates confirm each change before it merges, keeping the same data both the coding agent and your team see in sync.

Agentic Software Development | Control Plane | Manual & Automatic Verification Issue Tracking |Levr

Levr Dashboard: structured project data an agent can query and act on.

What MCP app mistakes should teams avoid?

The most common MCP app mistakes are hiding displayed data from the model, combining discovery with rendering, failing to return interaction state, and relying on vague tool descriptions. These mistakes produce polished interfaces that cannot support robust follow-up questions, multi-step reasoning, or reliable agent behavior.

  • Building a UI-only widget: Do not treat an embedded interface as the source of truth. Return equivalent structured data to the model.
  • Rendering too early: Avoid tools that automatically display the first search result when a task requires comparison across many possibilities.
  • Duplicating output: Tell the model that a UI is present and specify what, if anything, should be restated in text.
  • Losing selections: Send context updates after meaningful interaction events so follow-up requests refer to the right record.
  • Overloading one tool: Break complex, multi-purpose tools into retrieval, state, and rendering operations with focused schemas.
  • Ignoring evaluations: Test simple lookup behavior and difficult multi-step requests separately. The latter often exposes architecture flaws.

Teams should also resist optimizing for a single impressive demo. A widget that handles one linear path may fail as soon as users ask comparative, contextual, or open-ended questions. Test the app with the hard requests that justify using an agent in the first place.

Technical Deep Dive FAQ

What is an MCP app?

An MCP app is an interactive application experience connected to a Model Context Protocol server and surfaced within a compatible chat client. It combines tools that let a model access data or take actions with UI components that present results in a structured visual format. A strong MCP app does not treat the interface as separate from the model. It keeps the relevant data and interaction state available to the model so conversation, tool calls, and UI actions remain coordinated. MCP apps are one expression of the broader shift toward agentic software development.

What is the difference between MCP tools and MCP apps?

MCP tools expose operations a model can call, such as searching records, retrieving details, or starting a workflow. MCP apps add an interactive visual layer for displaying information and collecting user interaction within the chat environment. Tools remain the operational and data interface for the model. The app layer improves presentation, but it should not conceal the records, state, or decisions required for the model to answer follow-up questions and complete multi-step tasks.

Why must MCP app UI data also be sent to the model?

UI-only data creates an information gap between the user and the model. If a widget fetches and displays ten results but the model receives none of their details, it cannot accurately compare them, explain a selection, or respond to questions about a particular displayed item. Returning equivalent structured data lets the model reason about the same facts visible in the interface. It also reduces hallucination risk because follow-up answers can refer to stable records and attributes.

How do MCP apps update model context after a user clicks something?

An MCP app can use its model context update capability to send interaction state back to the host. The update should identify what changed in a compact, consistent format, such as a selected record ID, action type, and essential fields needed for the next turn. Because context updates are text-based, teams should define conventions for accumulating events without creating noisy or contradictory state. Only send events that could materially affect the model’s next response or tool call.

Should an MCP search tool render results automatically?

A search tool should render automatically only when a single search result is enough to satisfy the typical request. For complex work, separate the search from the renderer. Let the model call search tools repeatedly, inspect and filter the structured outputs, then invoke a render tool with the selected IDs. This design supports broad exploration without filling the conversation with several redundant widgets. It also gives the model a deliberate point at which to decide what deserves presentation.

What should a render tool accept as input?

A render tool should accept stable record references and only the additional context required to display them well. Common inputs include an ordered list of IDs, a display mode, concise model-authored rationales, and optional highlight fields. Avoid making the renderer repeat full retrieval logic or accept unbounded content that the client will treat as trusted. A narrow schema creates predictable rendering behavior and preserves a clear boundary between canonical data, model judgment, and presentation details.

How do tool descriptions change model behavior in MCP apps?

Tool descriptions tell the model what a tool does, when it should be used, what data it needs, and what happens after it returns. In an MCP app, descriptions should explicitly state when a UI displays results so the model does not repeat a full textual rendering. They should also describe dependencies, such as requiring a search or detail tool before rendering selected records. Clear descriptions reduce redundant output and guide the model through the intended tool sequence.

How should teams evaluate an MCP app?

Evaluate an MCP app with both UI and reasoning scenarios. Test simple queries, then test difficult requests requiring repeated searches, filtering, ranking, and contextual follow-ups after interaction. Verify that the model knows what the UI showed, which item was selected, and why a rendered shortlist was chosen. Test descriptions separately for duplicate narration. Finally, test error states, incomplete records, stale selections, and unavailable tools, because these cases reveal whether state boundaries are genuinely well defined.

How does a shared control plane help coding agents?

A shared control plane gives coding agents access to the same structured project objects that guide the human team, including issues, acceptance criteria, tests, workflow states, and historical activity. This reduces the risk that an agent works from stale or incomplete prompt context. In Levr, teams can connect agents to shared issues and quality gates over MCP, allowing task progress and verification evidence to stay associated with the underlying work rather than scattered across chats and local sessions.

Can multiple coding agents work from the same project context?

Yes. A shared project context makes it possible for multiple coding agents to work on different tasks while referring to the same issues, tests, workflow rules, and activity history. The important design requirement is attribution and coordination. Each action should be connected to the agent or person that performed it, and dependent work should be expressed through shared objects rather than copied prompts. This provides an audit trail and helps agents avoid operating from conflicting assumptions.

At a Glance

Data-first MCP apps keep interactive UI and agent reasoning aligned.

  • Expose the facts: Every meaningful UI result needs a structured representation the model can inspect.
  • Return interaction state: Context updates keep selections and user actions visible to the model.
  • Separate responsibilities: Retrieval supports exploration, while rendering presents selected outcomes.
  • Design for hard tasks: Test multi-step requests, not only single-query demonstrations.

The best MCP interface is one that makes the user experience clearer without making the model less informed.

Further reading

Ship at agent speed

Give your coding agents a control plane, not just a prompt.

Levr connects your coding agents, including Claude Code, Cursor, Codex, and Copilot, to shared project context with issues, gates, test suites, and memory. Free access is available during beta.

Levr provides agent message bus capabilities, shared memory, and cross-agent context so work, verification, and accountability stay connected.

Get early access, it’s free

No credit card required during beta.