Register MCP App UI resources in shared server constructor#2570
Merged
SamMorrowDrums merged 1 commit intoMay 29, 2026
Conversation
The remote/HTTP server never called RegisterUIResources, so when the remote_mcp_ui_apps feature flag was enabled per-request, tools like issue_write and create_pull_request would advertise a ui:// resource URI in their _meta.ui block but the resource itself was not registered. The client's follow-up resources/read call then failed with -32002 'Resource not found' (the error surfaced as 'Error loading MCP App: MPC -32002: Resource not found' in VS Code). The stdio bootstrap also gated registration on featureChecker called with context.Background(), which can't see per-request flag overrides. Move RegisterUIResources into pkg/github.NewMCPServer (the shared constructor used by both stdio and HTTP), gated only on UIAssetsAvailable(). The resources are inert static HTML; the inventory still strips _meta.ui from tools per-request via stripMCPAppsMetadata, so the URI is only advertised to clients when the flag is on for that request. Fixes #2467 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes a remote/HTTP MCP server bug where tools could advertise ui://github-mcp-server/... MCP App resource URIs (via _meta.ui when remote_mcp_ui_apps is enabled per-request), but the corresponding UI resources were only registered in the stdio bootstrap—causing resources/read to fail with -32002 Resource not found in clients like VS Code.
Changes:
- Move
RegisterUIResourcesinto the sharedpkg/github.NewMCPServerconstructor (gated byUIAssetsAvailable()), so both stdio and HTTP servers register the UI resources. - Remove the stdio-only UI resource registration block from
internal/ghmcp/server.go. - Add regression tests that verify advertised
ui://URIs resolve viaresources/read, including an end-to-end in-memory client/server test throughNewMCPServer.
Show a summary per file
| File | Description |
|---|---|
| pkg/github/server.go | Registers embedded MCP App UI resources in the shared server constructor so HTTP/remote servers serve ui:// resources too. |
| internal/ghmcp/server.go | Removes stdio-only UI resource registration now that it’s handled in the shared constructor. |
| pkg/github/ui_resources_test.go | Adds regression coverage ensuring UI resource URIs are actually readable via resources/read, including through NewMCPServer. |
Copilot's findings
- Files reviewed: 3/3 changed files
- Comments generated: 1
Comment on lines
+113
to
+115
| if UIAssetsAvailable() { | ||
| RegisterUIResources(ghServer) | ||
| } |
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.
Fixes #2467
Bug
When the
remote_mcp_ui_appsfeature flag is enabled per-request on the remote/HTTP server (api.githubcopilot.com/mcp/), tools likeissue_writeandcreate_pull_requestadvertise aui://github-mcp-server/...resource URI in their_meta.uiblock and tell the model "click Submit in the form". The client then tries to load that resource viaresources/read, but the resource was never registered on the HTTP server —RegisterUIResourceswas only called from the stdio bootstrap ininternal/ghmcp/server.go. The read fails with-32002 Resource not found, which VS Code surfaces as:The stdio bootstrap was also subtly fragile: it gated registration on
featureChecker(context.Background(), MCPAppsFeatureFlag), which can't see per-request flag overrides (insiders URL,X-MCP-Featuresheader).Fix
Move the
RegisterUIResourcescall intopkg/github.NewMCPServer— the shared constructor used by both the stdio and HTTP paths — gated only onUIAssetsAvailable(). The resources are inert static HTML embedded at build time; the inventory still strips_meta.uifrom tools per-request viastripMCPAppsMetadata, so a client only sees the URI when the feature flag is actually on for that request.Tests
Added
pkg/github/ui_resources_test.gowith two tests that reproduce the user's bug without VS Code:TestRegisterUIResources_ReadableViaClient— registers the resources and confirms every advertised URI (get-me,issue-write,pr-write) resolves viaresources/read.TestNewMCPServer_RegistersUIResources— exercises the shared constructor that the HTTP handler uses and proves the URI is readable end-to-end through an in-memory MCP client.Both tests fail with the exact
calling "resources/read": Resource not founderror before this change and pass after. They skip whenscript/build-uihasn't been run, matching the existing pattern inmcp-diff.yml.script/lint,script/test, andscript/generate-docsall clean.