[goose2] MCP Apps: hydrate and replay app payloads in Goose2#8632
[goose2] MCP Apps: hydrate and replay app payloads in Goose2#8632aharvard wants to merge 5 commits intocodex/translate-acp-host-capabilitiesfrom
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bce545c6cc
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
bce545c to
8a24b3c
Compare
7a3aad5 to
6a2c3c1
Compare
1ebb8db to
14d0b06
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 14d0b06d3a
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
6a2c3c1 to
058800e
Compare
14d0b06 to
4e7991e
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4e7991ea2f
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| let tools = self.get_all_tools_cached(session_id).await.map_err(|e| { | ||
| ErrorData::new( | ||
| ErrorCode::INTERNAL_ERROR, |
There was a problem hiding this comment.
Keep prefixed tool dispatch independent of tool listing failures
In resolve_tool, the new unconditional get_all_tools_cached(session_id) call can fail before the prefixed fallback branch runs, so a valid call like ext__tool now returns an internal error whenever tool listing fails (for example, due to an unrelated extension timing out). The previous behavior allowed prefixed tool calls to route directly to the owning client without requiring a successful global tool refresh, so this change makes dispatch reliability depend on list-tools health rather than call-tool availability.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
I don’t think this reproduces with the current implementation. resolve_tool now intentionally checks the listed tool set first so prefixed calls still respect available_tools filtering and preserve MCP app metadata. Also, fetch_all_tools() already degrades individual list_tools failures to warnings/empty results, so unrelated extension timeouts don’t usually cause get_all_tools_cached() to fail before the prefixed fallback runs. The remaining coupling is only on a true top-level internal cache/list failure, which is much narrower than the scenario described.
Signed-off-by: Andrew Harvard <aharvard@squareup.com>
Signed-off-by: Andrew Harvard <aharvard@squareup.com>
Signed-off-by: Andrew Harvard <aharvard@squareup.com>
Signed-off-by: Andrew Harvard <aharvard@squareup.com>
Signed-off-by: Andrew Harvard <aharvard@squareup.com>
4e7991e to
b62e2f1
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b62e2f1c6e
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| case "tool_call": { | ||
| const messageId = findStreamingMessageId(sessionId); | ||
| if (!messageId) break; | ||
| const messageId = ensureLiveAssistantMessage(sessionId, gooseSessionId); | ||
|
|
There was a problem hiding this comment.
Guard tool events behind an active streaming message
Using ensureLiveAssistantMessage(...) in the tool_call path now creates a new assistant message even when no stream is active. That regresses the previous behavior (which dropped tool events when streamingMessageId was null) and can surface ghost assistant bubbles if late tool notifications arrive after a stop/cancel race, because useChat clears streamingMessageId before backend events are fully drained. The same helper is used in tool_call_update, so both request/update events can be misattributed to a newly created message instead of being ignored.
Useful? React with 👍 / 👎.
Category: improvement
User Impact: Goose2 can now show a session-scoped MCP App payload in chat and replay that same payload when an older chat is reopened.
Stacked On: #8623
Problem: PR #8623 establishes the MCP Apps capability handshake and host identity, but Goose2 still needed a durable way to surface an app payload after an MCP tool call completes. Without that, Goose2 had no backend-owned, replayable representation of the MCP App resource associated with a completed tool interaction.
Solution: This PR introduces backend-owned MCP App association and resource hydration in Goose runtime. When an app-capable tool completes, Goose runtime reads the associated
ui://resource, stores the resulting snapshot ontool_result.meta.goose.mcpApp, and forwards that through ACPtool_call_update._meta.goosefor both live updates and replay. Goose2 now renders that payload throughMcpAppViewas structured JSON; the next step is replacing that payload view with the real HTML renderer and bridge.Sequence
sequenceDiagram participant UI as "Goose 2 (ACP client / MCP Apps host)" participant ACP as "goose serve (ACP server)" participant Runtime as "Goose runtime (MCP client)" participant MCP as "MCP server" UI->>ACP: prompt ACP->>Runtime: agent.reply(...) Runtime->>MCP: callTool(...) MCP-->>Runtime: CallToolResult Runtime->>MCP: readResource(sessionId, ui://...) MCP-->>Runtime: ReadResourceResult Runtime->>Runtime: attach tool_result.meta.goose.mcpApp Runtime-->>ACP: completed ToolResponse ACP-->>UI: tool_call_update + _meta.goose.mcpApp UI->>UI: build McpApp payload UI->>UI: render McpAppView (JSON for now) Note over UI,ACP: later, on session reload UI->>ACP: loadSession(...) ACP->>ACP: replay stored ToolResponse from thread history ACP-->>UI: replayed tool_call_update + _meta.goose.mcpApp UI->>UI: reconstruct McpAppView from replayWhat This PR Introduces
This is intentionally the "payload-first" step.
This PR is the first backend implementation of MCP App payload hydration and replay in Goose2. Its job is to create a stable, session-scoped payload at tool-completion time, persist that payload with the tool result, and let Goose2 reconstruct the same
MCP Appview later when a session is reopened.The current
McpAppViewis deliberately a structured payload view rather than the final HTML renderer. That keeps this PR focused on the data model, persistence, and replay path. The next PR can then build the real app surface on top of that payload with the iframe, proxy, and host bridge behavior.Other ACP Clients
Replayed MCP App payloads should remain part of session history even when an older Goose2-created session is later opened by another ACP client. Clients that do not render MCP Apps can ignore
_meta.goose.mcpApp, while the session-scoped capability advertisement from #8623 still matters for new prompts: it prevents Goose runtime from doing fresh MCP App resource reads for a client that does not currently advertise MCP Apps support.Reproduction Steps
https://mcp-app-bench.onrender.com/mcprun the app benchThis is part 2 of 3, tracked in #8591