Skip to main content
Glama
Geofflew

Conversation as an App

by Geofflew

This is an example repo, not a library. It exists to show an engineering idea, rebuilt over synthetic data so the idea can be read and run. It is not maintained as a dependency or hardened for production. Study the concepts; code reuse requires permission.

Turn a conversational answer into something people can inspect

A host invokes a spending tool; its structured result and registered HTML view form an app. Clicking a category calls a second tool through the host and returns the contributing records.

Situation

Someone asks, “How much did we spend in September?” A total and category breakdown answer the first question. Then they want to understand the travel amount: which records contributed to it?

Conversation is a useful way to ask for the summary. Once it appears, selecting a category is a more direct way to explore it than describing that category in another message.

Related MCP server: Expense Tracker MCP

Complication

A chart alone does not provide that interaction. It needs data with stable category names, a way to request contributing records, and a host that connects the interface to the server. Recalculating the summary inside the browser would also create a second source of truth.

The important connection is question → tool result → interactive view → follow-up tool call → underlying records. The view should help the person explore the answer while keeping its calculations and evidence together.

Our Answer

A genuine MCP Apps integration connects two tools and one HTML resource. The included local host makes a fixed initial call so the full flow runs without a language model, API key, or external account.

Give the host both an answer and a view

summarize_spending calculates totals from 18 seeded synthetic expenses. Its response includes structuredContent for the app and ordinary text for hosts that show only text. Both come from the same calculation, in integer cents.

The tool's _meta.ui.resourceUri names a registered ui:// resource containing the bundled HTML and JavaScript. An app-capable host reads that resource, loads the view, and delivers the result. Registering HTML does not make every MCP client an app host; the host needs MCP Apps support.

The official TypeScript MCP SDK implements tool discovery, resource reads, and tool calls. The official MCP Apps extension implements the app-to-host bridge. A small esbuild bundle puts the view and its dependencies in one HTML resource without runtime CDN requests.

Server registration · Calculations and fixture · Build

Make a click continue the same investigation

The view renders category buttons with proportional bars. Selecting Travel requests inspect_category({category:"Travel"}) through the host. The host forwards that request to the MCP server; the server validates the category and returns its actual contributing records.

In the generated dataset, the summary shows $439.35 for Travel. Selecting it returns six records totaling $439.35. The view checks that the detail total agrees with the selected summary before displaying it. It uses the returned record IDs and amounts rather than inventing detail from the chart.

inspect_category is marked app-visible in tool metadata. The local host also restricts the view to that tool. Metadata communicates intended visibility to hosts; the server independently validates arguments. Both tools are read-only.

Interactive view · Local host bridge

Keep the interaction's state understandable

Changing categories clears the previous rows and shows a loading message. If someone clicks again before the first request finishes, a sequence counter prevents the slower response from overwriting the newer selection. Errors stay visible in the status area instead of leaving old records under a new heading.

The local preview uses a sandboxed iframe and the official AppBridge. Its small HTTP adapter forwards browser requests to an actual MCP client connected over stdio to the server. It is a learning host for this bundled app, not a general-purpose host for untrusted extensions.

Preview adapter · Protocol tests

Benefits

People can move from a summary to its evidence without repeatedly restating what they want. The category, amount, and contributing records stay in one view, making a surprising total easier to inspect.

The same result remains readable as text. The interface adds a convenient way to explore the answer while the server retains responsibility for its data and calculations.

Run and connect it · Mechanisms and tradeoffs · Blog draft

Copyright © 2026 Geoffrey Lew. All rights reserved.

Available Tools

2 tools
inspect_categoryInspect category recordsC
Read-onlyIdempotent

Return the records contributing to one synthetic category total.

ParametersJSON Schema
NameRequiredDescriptionDefault
categoryYes

TDQS

C2.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so safety is covered. The description adds only that it returns contributing records rather than aggregates, but does not explain what 'synthetic' means, whether records are ordered or truncated, or what the caller should expect beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single efficient sentence with the action front-loaded and no filler. However, the unexplained term 'synthetic category total' reduces clarity despite the brevity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description should clarify what the returned records look like and what 'synthetic' means. Annotations cover the safety profile, but the description leaves the agent without enough context to interpret the result or know when this tool is appropriate versus summarize_spending.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description does not explain the category parameter beyond the vague phrase 'synthetic category total'. The enum values are visible in the schema, but the description does not add meaning about how the category maps to underlying records.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a verb and resource ('Return the records') and scopes it to a category, but 'synthetic category total' is unexplained jargon. It does not distinguish this tool from the sibling summarize_spending, leaving the agent unsure which to choose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus summarize_spending. The description implies a drill-down use case but never states the condition that selects it over the sibling.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

summarize_spendingSummarize synthetic spendingB
Read-onlyIdempotent

Return September synthetic spending by category with an interactive view.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint=false and destructiveHint=false, so the safety profile is fully covered. The description adds that the period is fixed to September (relevant given zero parameters) but the phrase 'interactive view' is unexplained and ambiguous about what actually comes back.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no padding. The one questionable element is 'with an interactive view', which spends words on a concept it does not define rather than on useful routing information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and no parameters, the description should carry the burden of saying what is returned (chart versus raw category totals, granularity, ordering). It only gestures at 'spending by category' and an undefined 'interactive view', leaving the agent guessing about the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes no parameters, so there is nothing for the description to disambiguate; the baseline for a zero-parameter tool applies. The fixed September scope is the only semantic constraint and it is at least mentioned.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Return) and resource (September synthetic spending by category), which is clear enough for an agent to know what it produces. However, it never distinguishes itself from the sibling inspect_category, and 'by category' could be read as covering all categories while the sibling implies per-category drill-down. Clear but undifferentiated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no statement of when to use this tool versus inspect_category, nor any exclusion or precondition. The agent must infer the relationship between the two tools from their names alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updatesv1.0.0
    • First observedinspect_category
    • First observedsummarize_spending

TDQS

B3.2/5.0

Scored across 2 tools

Disambiguation5/5

The two tools have clearly distinct roles: summarize_spending provides an aggregate view by category, while inspect_category drills down into one category's records. There is no overlap or ambiguity in when to use each.

Naming Consistency5/5

Both tools follow a consistent snake_case verb_noun pattern (summarize_spending, inspect_category), making the naming predictable and easy to parse.

Tool Count3/5

Two tools is thin for a server, though it may be sufficient for a narrowly scoped spending exploration surface. The set lacks any additional operations that would make it feel more robust.

Completeness4/5

The pair covers the core workflow of viewing a summary and then inspecting category details. Minor gaps exist, such as no way to filter by date range or search across records, but the essential exploration loop is present.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Persistent expense tracker backed by Neon Postgres with SQL tools for adding, editing, deleting, and analyzing expenses via natural language.
    -
  • F
    license
    C
    quality
    D
    maintenance
    Enables logging, querying, and summarizing personal expenses via natural language, with tools for adding, listing, and aggregating spending by category.
    3
    -
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables AI assistants to add, retrieve, and categorize expense records through structured MCP tools, with data stored in SQLite and deployable remotely for natural-language expense management.
    -
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables users to ask plain-English questions about their expenses, query and compare spending, add categorized transactions, forecast future spending, and detect anomalies through natural language.
    -