Skip to content

Conversation

@aharvard
Copy link
Collaborator

@aharvard aharvard commented Jan 13, 2026

Summary

Adds support for the _meta.ui.prefersBorder option in MCP App resources. When an MCP App returns prefersBorder: false in its resource metadata, the UI wrapper border and rounded corners are removed, allowing the app to render edge-to-edge.

Changes

  • Read prefersBorder from _meta.ui in the resource response (defaults to true)
  • Conditionally apply border/rounded styling based on this preference
  • Refactored resource state into a single ResourceData object for cleaner code

Usage

MCP Apps can now specify border preference in their resource response:

{
  "uri": "ui://widget/example.html",
  "mimeType": "text/html;profile=mcp-app",
  "_meta": {
    "ui": {
      "prefersBorder": false
    }
  },
  "text": "<!doctype html>..."
}

Before / After

Before After
image image

Before: MCP App with default border and rounded corners
After: MCP App with prefersBorder: false - no wrapper border

Copilot AI review requested due to automatic review settings January 13, 2026 14:26
@aharvard aharvard marked this pull request as draft January 13, 2026 14:27
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds support for the prefersBorder option in MCP App resource metadata, allowing apps to control whether they render with or without a UI wrapper border.

Changes:

  • Introduced ResourceData interface to consolidate resource state (html, csp, prefersBorder)
  • Read prefersBorder from _meta.ui in resource responses with proper fallback to true
  • Conditionally apply border and rounded corner styling based on preference

@aharvard aharvard marked this pull request as ready for review January 13, 2026 14:37
}

if (!resourceHtml) {
if (!resource.html) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider unifying the effective two arms of the if now that the payload is growing, i.e.

const toRender = resource.html ? <iframe> : "Loading MCP app..."

resource.prefersBorder ? 'border border-borderSubtle rounded-lg' : 'my-6'
)}
>
{resource.html && proxyUrl ? (
Copy link
Collaborator Author

@aharvard aharvard Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DOsinga PTAL

I unified resource.html and proxyUrl as we don't need a discrete state for proxyUrl loading

Also, leaving this inline instead of extracting as a const. I noticed a hard-to-reproduce issue where the iframe ref might have gotten lost or something... the rendered mcp app would be sitting there w/ no messages being sent down. Maybe a closure issue? Not sure. But I think what I got works.

@aharvard aharvard merged commit 1a2bc48 into main Jan 13, 2026
24 of 25 checks passed
@aharvard aharvard deleted the mcp-app-prefers-border branch January 13, 2026 17:17
wpfleger96 added a commit that referenced this pull request Jan 13, 2026
* main: (41 commits)
  Allow customizing the new line keybinding in the CLI (#5956)
  Ask for permission in the CLI (#6475)
  docs: add Ralph Loop tutorial for multi-model iterative development (#6455)
  Remove gitignore fallback from gooseignore docs (#6480)
  fix: clean up result recording for code mode (#6343)
  fix(code_execution): handle model quirks with tool calls (#6352)
  feat(ui): support prefersBorder option for MCP Apps (#6465)
  fixed line breaks (#6459)
  Use Intl.NumberFormat for token formatting in SessionsInsights (#6466)
  feat(ui): format large and small token counts for readability (#6449)
  fix: apply subrecipes when using slash commands (#6460)
  Fix: exclude platform_schedule_tool in CLI (#6442)
  Fix: Small update in how ML-based prompt injection determines final result (#6439)
  docs: remove SSE transport and rename to Streamable HTTP (#6319)
  fix: correct Cloudinary extension command and env variable (#6453)
  fix: add gap between buttons in MacDesktopInstallButtons.js (#6452)
  refactor: include hidden dotfiles folders in file picker search (#6315)
  upgraded safe npm packages (#6450)
  chore(deps): bump react-router and react-router-dom in /ui/desktop (#6408)
  chore(deps): bump lru from 0.12.5 to 0.16.3 (#6379)
  ...
lifeizhou-ap added a commit that referenced this pull request Jan 14, 2026
* main:
  fix: require auth when running goose on non loopback address (#6478)
  chore(deps): bump hono from 4.11.3 to 4.11.4 in /ui/desktop (#6485)
  feat(cli): graceful fallback for keyring failures (#5808)
  fix: support global .gooseignore and negation patterns (#6157)
  docs: manual config for jetbrains (#6490)
  fix: Recipe slash command doesn't work with single optional parameter (#6235)
  fix(openrouter): Handle Gemini thoughtSignature for tool calls (#6370)
  docs: fix extensions page (#6484)
  Allow customizing the new line keybinding in the CLI (#5956)
  Ask for permission in the CLI (#6475)
  docs: add Ralph Loop tutorial for multi-model iterative development (#6455)
  Remove gitignore fallback from gooseignore docs (#6480)
  fix: clean up result recording for code mode (#6343)
  fix(code_execution): handle model quirks with tool calls (#6352)
  feat(ui): support prefersBorder option for MCP Apps (#6465)
  fixed line breaks (#6459)
  Use Intl.NumberFormat for token formatting in SessionsInsights (#6466)
  feat(ui): format large and small token counts for readability (#6449)
  fix: apply subrecipes when using slash commands (#6460)
ThanhNguyxn pushed a commit to ThanhNguyxn/goose that referenced this pull request Jan 14, 2026
zanesq added a commit that referenced this pull request Jan 14, 2026
…ased

* 'main' of github.com:block/goose:
  fix(code_execution): serialize record_result output as JSON (#6495)
  perf(google): avoid accumulating thoughtSignatures across conversation history (#6462)
  fix(openai): make tool_call arguments optional and fix silent stream termination (#6309)
  fix: Improve error messages for invalid tool calls (#6483)
  fix: require auth when running goose on non loopback address (#6478)
  chore(deps): bump hono from 4.11.3 to 4.11.4 in /ui/desktop (#6485)
  feat(cli): graceful fallback for keyring failures (#5808)
  fix: support global .gooseignore and negation patterns (#6157)
  docs: manual config for jetbrains (#6490)
  fix: Recipe slash command doesn't work with single optional parameter (#6235)
  fix(openrouter): Handle Gemini thoughtSignature for tool calls (#6370)
  docs: fix extensions page (#6484)
  Allow customizing the new line keybinding in the CLI (#5956)
  Ask for permission in the CLI (#6475)
  docs: add Ralph Loop tutorial for multi-model iterative development (#6455)
  Remove gitignore fallback from gooseignore docs (#6480)
  fix: clean up result recording for code mode (#6343)
  fix(code_execution): handle model quirks with tool calls (#6352)
  feat(ui): support prefersBorder option for MCP Apps (#6465)
  fixed line breaks (#6459)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants