MCP Apps: Open created issue/PR link via host open-link capability#2593
Merged
Conversation
The success views for issue-write and pr-write rendered a plain anchor to the created/updated issue or PR. MCP Apps run in a sandboxed iframe where target="_blank" navigation may be blocked, so clicking the link did nothing in some hosts. Route the click through the host's ui/open-link capability (already exposed by useMcpApp as openLink), which asks the host to open the URL in the user's browser. The hook now also falls back to window.open when the host denies the request, in addition to the existing no-app fallback. The href is retained so right-click/copy and native fallback still work. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates the MCP App success-view links (issue-write / pr-write) to open the created/updated Issue/PR URL via the host’s ui/open-link capability (with a browser fallback), which is important for MCP Apps rendered in sandboxed iframes where plain anchor navigation can be blocked.
Changes:
- Route success-view link clicks through
useMcpApp().openLink(url)(preventing default anchor navigation). - Extend
useMcpApp.openLinkto fall back towindow.openwhen the host denies the open-link request (result.isError). - Keep
hrefattributes for copy-link / right-click behavior.
Show a summary per file
| File | Description |
|---|---|
| ui/src/hooks/useMcpApp.ts | Adds a fallback to window.open when app.openLink returns an error result. |
| ui/src/apps/pr-write/App.tsx | Wires openLink into the PR success link click handler to use host open-link capability. |
| ui/src/apps/issue-write/App.tsx | Wires openLink into the issue success link click handler to use host open-link capability. |
Copilot's findings
- Files reviewed: 3/3 changed files
- Comments generated: 2
When the success-view link URL was unavailable ("#"), the click handler
returned before calling e.preventDefault(), so the anchor's default
target="_blank" navigation still ran and could open a stray blank tab.
Call preventDefault() first, then no-op when the URL is unavailable.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment on lines
+109
to
115
| const result = await app.openLink({ url }); | ||
| // The host may deny the request (e.g. blocked domain or user cancelled). | ||
| // Fall back to a direct window.open so the link still works. | ||
| if (result?.isError) { | ||
| window.open(url, "_blank", "noopener,noreferrer"); | ||
| } | ||
| }, |
Contributor
Author
There was a problem hiding this comment.
I'm not sure if this is needed Copilot
omgitsads
approved these changes
Jun 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
When a user creates or updates an issue/PR via the MCP App form, the success view shows a link to the result. Clicking it now opens the URL in the user's browser via the host's
ui/open-linkcapability, instead of relying on a plaintarget="_blank"anchor.Why
MCP Apps render inside a sandboxed iframe, where ordinary
target="_blank"navigation can be blocked by the host. In those hosts, clicking the success link did nothing. The MCP Apps spec providesui/open-linkprecisely so an app can ask the host to open an external URL.How
issue-writeandpr-writenow callopenLink(url)on click (preventDefault+ host request).openLinkwas already exposed byuseMcpApp(sendsui/open-link).useMcpApp.openLinknow also falls back towindow.openwhen the host denies the request (result.isError), in addition to the existing fallback when no app connection is present.hrefis retained so right-click / copy-link and native fallback still work, and the handler no-ops when the URL is unavailable ("#").Notes
tsc --noEmit,npm run build). No UI test suite exists in this package.openLinkscapability for the in-browser open; otherwise thewindow.openfallback applies.