Skip to content

McpServer: no first-class support for MCP Apps (SEP-1865 / interactive UI resources) #6353

Open

Description

@guillempuche

The effect/unstable/ai/McpServer module has no first-class implementation of SEP-1865 (MCP Apps — Interactive UIs for MCP).

What exists today

  • McpServer.ts pins LATEST_PROTOCOL_VERSION = "2025-06-18" (pre-1865).
  • McpSchema.ts ships _meta: Record<string, Json> on every relevant schema — spec-mandated passthrough.
  • Tool.Meta (Tool.ts:1635) is a generic Record<string, unknown> annotation; its docstring example happens to show { ui: { resourceUri: "ui://example/calculator-ui" } }, but Effect doesn't act on it.

What's missing

  • No handling of the ui:// URI scheme.
  • No HTML / widget / Skybridge resource-content variant beyond TextResourceContents / BlobResourceContents.
  • No McpServer.uiResource(...) (or equivalent) helper.
  • No typed annotations for SEP-1865 / OpenAI Apps SDK keys (openai/outputTemplate, widgetAccessible, widgetDescription, widgetPrefersBorder, etc.).
  • No content-type negotiation or rendering hooks.

Grep across the repo for sep-1865, mcp-app, mcpui, mcp-ui, skybridge, outputTemplate, widgetAccessible returns 0 hits; ui:// appears once, in the Tool.Meta docstring.

Ask

First-class SEP-1865 support: ui:// resource kind, typed Tool.Meta keys for the well-known fields, and bumping LATEST_PROTOCOL_VERSION once 1865 is part of a dated spec.

References

Activity

  1. lloydrichards commented on May 18, 2026

    @lloydrichards
    Contributor

    I've actually built several mcp servers using Effect that can support Mcp App

    https://github.com/lloydrichards/edu_mcp-apps

    There are some prs from back in Feb/Mar that opened this up Effect-TS/effect-smol#1440 and Effect-TS/effect-smol#1653

    Since Mcp App is part of the extension ecosystem for the mcp spec and with effect not have an McpClient implementation I would probably just stick o using the helpers from https://github.com/modelcontextprotocol/ext-apps to build on top of what you can expose from an Effect McpServer

  2. lloydrichards commented on May 18, 2026

    @lloydrichards
    Contributor

    https://www.lloydrichards.dev/labs/059-generative-data-viz <- and some of my thoughts and process from when I was working on this

  3. guillempuche commented on May 19, 2026

    @guillempuche
    Author

    @lloydrichards great work in Effect-TS/effect-smol#1440 and then your guide, wonderful!

    I'm curious about your comment at the end of the guide, "Bundle size: the widgets are around ~1MB each, mostly from React. While this is fine for a demo, I'll explore Web Components to reduce this in the future"

  4. lloydrichards commented on May 19, 2026

    @lloydrichards
    Contributor

    In the repo I was building for the article, I used vite + react instead of lit (web components) for building up the ui:/// resource which meant that each widget came bundled with react in a sort of mini SPA. There might have been ways to cut back the bundle size a bit, but generally its a lot of minified JS thats being stringified and send over http.

    It would depend a bit on what you're building but for short-lived widgets I thinks its better to use something like web components that don't rely no too much JS and can render quickly without too much code. In the edu_mcp-apps repo I was starting to explore this in the lit-lab package but hadn't figured out a good dx yet for building the components seperate from the mcp-server

  5. lloydrichards commented on May 19, 2026

    @lloydrichards
    Contributor

    This might help, but I was also using these helpers:

    UiResource.ts

    Which would be reused across widgets:

    import { LineChartWidgetPayload } from "@repo/domain/Chart";
    import { Effect } from "effect";
    import {
      makeUiRenderTool,
      makeUiResource,
      readPublicAsset,
    } from "../../UiResource";
    
    const LineChartWidgetResourceUri = "ui://line-chart";
    
    const LineChartWidgetHtml = readPublicAsset({
      importMetaDir: import.meta.dir,
      sourceSuffix: "src/widget/line-chart",
      sourcePath: "../../../public/widgets/widget-line-chart.html",
      distPath: "public/widgets/widget-line-chart.html",
    });
    
    export const LineChartWidgetResourceLayer = makeUiResource(
      LineChartWidgetResourceUri,
      {
        name: "Line Chart",
        description: "Line chart widget UI",
        html: LineChartWidgetHtml,
        meta: {
          prefersBorder: false,
        },
      },
    );
    
    export const RenderLineChartWidgetTool = makeUiRenderTool(
      LineChartWidgetResourceUri,
      {
        name: "render_line_chart_widget",
        title: "Line Chart",
        description: "Render the line chart widget UI",
        parameters: LineChartWidgetPayload,
        success: LineChartWidgetPayload,
      },
    );
    
    export const renderLineChartWidgetHandler = (
      payload: typeof LineChartWidgetPayload.Type,
    ) => Effect.succeed(payload);
  6. guillempuche commented on May 21, 2026

    @guillempuche
    Author

    Uaauuu Lloyd, thanks for the help!

  7. self-assigned this
    on Jul 14, 2026
  8. lloydrichards commented on Jul 28, 2026

    @lloydrichards
    Contributor

    @guillempuche i finally convinced my work to open up my lab project repo: https://github.com/interactivethings/interactivethings-data-viz-mcp-lab

    feel free to explore/fork the code, though its a couple months old now

  9. guillempuche commented on Jul 28, 2026

    @guillempuche
    Author

    uaauuu! Cool jobs Lloyd!

  10. lloydrichards commented on Oct 9, 2026

    @lloydrichards
    Contributor

    lloydrichards/edu_mcp-apps@5ff417d

    Just did some upgrading to get this working on v4 and the new McpServer so far everything looks to be working the same as before. McpJam has greatly improved their diagnostics so its easier to prototype the components now and check compatibility with other harnesses.

    I want to first get the Task expension in (#8631) to figure out some erganomics around what first-class support means, but I think if there isn't too much pushback about adding these sorts of modules then I can look into an McpApp version of it too

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions