Official repo for spec & SDK of MCP Apps protocol - standard for UIs embedded AI chatbots, served by MCP servers
by modelcontextprotocolLast 12 weeks ยท 364 commits
5 of 6 standards met
Removes the duplicate entry from the union type in and regenerates the derived schema files. Motivation and Context The type listed twice (lines 61 and 67). This is a copy-paste error โ the stable spec () only lists it once. The duplicate has no runtime impact but makes the type definition inconsistent with the spec. How Has This Been Tested? โ all 85 unit tests pass โ all files pass formatting check โ schemas regenerated cleanly with no duplicate Breaking Changes None. Removing a duplicate union member does not change the set of valid values. Types of changes [x] Bug fix (non-breaking change which fixes an issue) [ ] New feature (non-breaking change which adds functionality) [ ] Breaking change (fix or feature that would cause existing functionality to change) [ ] Documentation update Checklist [x] I have read the MCP Documentation [x] My code follows the repository's style guidelines [x] New and existing tests pass locally [ ] I have added appropriate error handling [ ] I have added or updated documentation as needed Additional context The duplicate was in the text colors section of . The fix removes line 67 () and runs to update , , and .
My app performs a search and displays the results. Everything works correctly the first time because I receive the inputs through . However, when I refresh the page, the chat reloads and the app initializes again, but does not fire. Iโm not sure how to access the original tool input data after a refresh. Additional details: Iโm not relying on state persistence, I simply need to access the previous tool input Iโm using ChatGPT Am I missing something?
Repository: modelcontextprotocol/ext-apps. Description: Official repo for spec & SDK of MCP Apps protocol - standard for UIs embedded AI chatbots, served by MCP servers Stars: 1767, Forks: 208. Primary language: TypeScript. Languages: TypeScript (70.3%), MDX (25.5%), JavaScript (4.2%). Homepage: https://apps.extensions.modelcontextprotocol.io/ Topics: ai, apps, mcp, mcp-apps, modelcontextprotocol, ui. Latest release: v1.1.2 (1w ago). Open PRs: 65, open issues: 60. Last activity: 1d ago. Community health: 87%. Top contributors: ochafik, jonathanhefner, antonpk1, martinalong, localden, idosal, liady, jerome3o-anthropic, Avcharov, dependabot[bot] and others.
TypeScript
MCP Apps: AppBridge and Model get separate session IDs โ no way to correlate them I'm building an MCP server with an MCP App (AppBridge iframe). The App UI needs to know what the Model is doing - e.g. when the Model kicks off a tool call, the App should show live progress. The problem: Claude Desktop calls twice, once for the AppBridge and once for the Model - so they end up with different values. My server generates a session ID on each : Since fires twice, I get two UUIDs. Here's what the request log looks like: So when the Model calls a tool, the server stores state under . But the AppBridge queries using - it never finds it. I don't see a way in the spec to link these two sessions together. Is the dual- intentional? If so, is there a planned way to share a conversation-level or connection-level ID across both sub-connections? A previously working prototype also broke with this behavior, so this might be a recent change in Claude Desktop. Environment:** Claude Desktop/Claude Web
Describe the bug When you reload a ChatGPT window with existing MCP App widgets the tool input and tool result notifications do not happen as defined in section 3 of the overview. https://github.com/modelcontextprotocol/ext-apps/blob/30f79b9e3f2525a95a997fce2e5839ab0dd4da96/docs/overview.md#lifecycle To Reproduce Steps to reproduce the behavior: 1. Call a tool that renders a widget that uses tool-results from chatgpt 2. reload the page 3. chatgpt re-renders the widget iframe 4. is called, but and are not Expected behavior** The phase should happen after the phase every time
Problem When a host uses , the current API requires at construction time: This forces the host to call after . However, the iframe's inline script calls immediately on script load โ which happens before fires on the host. The result is a race condition where the iframe's first message is lost and the handshake never completes. Fix Add a method to that: 1. Can be called after to provide the target window 2. Flushes any outgoing messages that were queued while no target was set Both constructor parameters are now optional, making the change fully backward-compatible โ passing a target at construction still works identically. New deferred-target pattern This ensures the bridge is listening before the iframe loads, so is never missed. Changes โ make constructor params optional, add , add , update to queue when no target โ add deferred-target examples โ new test file covering backward compat, deferred flush, incoming message filtering, and close cleanup Tests All 93 tests pass (). The new tests cover: Messages sent immediately when target is provided at construction (backward compat) Messages queued before , flushed on call Messages sent directly after called for valid JSON-RPC messages Source filtering still works when is provided Queue cleared on Context This race condition was discovered while integrating MCP Apps into a host that renders iframes dynamically. The workaround required a custom class with its own message queue. This PR proposes adding that capability directly to the SDK's built-in transport. Made with Cursor