Server and asset origins
SetMCP_URL to your server’s public origin (OAuth resource URL, API calls, CSP connectDomains):
MCP_ASSETS_URL when view JS/CSS and public/ files are served from a different prefix (CDN, Supabase Storage):
MCP_ASSETS_URL is unset, assets use the same origin as MCP_URL (or the request origin behind a proxy).
At mcp-use build, MCP_ASSETS_URL rewrites manifest paths to full https:// URLs for static upload workflows.
Separate the UI origin from the MCP endpoint
Setview.domain to the dedicated HTTPS origin you want ChatGPT to use, such as
https://wavebyvento.com. The MCP endpoint is the URL clients connect to, such as
https://wave-by-vento.run.mcp-use.com/mcp. These values serve different purposes.
views/wave/view.tsx as described in MCP Apps.
On resources/read, mcp-use emits host-specific _meta.ui.domain:
Claude hashes the full endpoint, including
/mcp, not the website origin or
MCP_ASSETS_URL. This follows Claude’s domain handling contract.
ChatGPT expects a dedicated origin; openai/widgetDomain is a compatibility alias
for ui.domain, not a way to repair a conflicting value. See the
OpenAI resource metadata reference.
Endpoint resolution and migration
- An origin-only
MCP_URLcombines with the server’sbasePath(default/mcp). - For View domain resolution, an
MCP_URLwith a path is treated as the full endpoint and hashed verbatim, including a trailing slash or query. With OAuth, keepMCP_URLorigin-only: OAuth configuration separately requires an origin and appendsbasePath. - Without a valid
MCP_URL, View reads use the request path and query with the forwarded origin, or the request origin when forwarded headers are absent. ConfigureMCP_URLwhen a proxy hides or rewrites the public path; only trust forwarded headers set by your proxy. - Older HTTP(S)
view.domainvalues containing/mcpor another path are normalized to their origin. Set the intended UI origin explicitly when it differs from the endpoint origin. - Existing computed
*.claudemcpcontent.comvalues remain unchanged for compatibility. They are Claude-specific and unsuitable for ChatGPT. Replace them with an HTTPS UI origin to use automatic host conversion. - An omitted
view.domainkeeps the host default. If no HTTP request orMCP_URLis available, Claude falls back to hashing the authored domain; configure the public endpoint for that case.
Preserve generated resource metadata
Remove custom response helpers that overwrite_meta.ui.domain after next().
The SDK applies Claude’s conversion before response middleware receives the result;
a later overwrite replaces the generated value. Keep unrelated additions and preserve
existing ui fields when merging metadata.
Configure the domain through view.domain. Tool definition _meta and tool result
_meta do not configure the View resource domain. Generated View resources emit
ui.domain without an openai/widgetDomain alias. Manually registered resources and
custom middleware remain author-controlled; if you emit both keys for ChatGPT, keep
them consistent. Resource listings show the UI origin; Claude conversion happens on reads.
view.csp.frameDomains separately allows nested iframes inside the View. It does
not select the View’s sandbox origin, identify the MCP endpoint, or fix domain
validation. Declare it only when the View embeds another page. ChatGPT applies
additional review to nested frames.
CSP merge order
On eachresources/read, the framework merges CSP in this order (high → low priority):
- Author
view.cspon the bound tool CSP_*_DOMAINSenv vars (per category) or theCSP_URLSshortcut- MCP auto-append:
MCP_URL→connectDomains; assets origin →resourceDomains
CSP_URLS and per-category env vars rank above MCP auto-append. Duplicate origins keep the higher-priority entry’s position.
Add domains for one view
Declare CSP on the tool’sview: config:
connectDomains, resourceDomains, frameDomains, baseUriDomains.
Global CSP env vars
UseCSP_URLS when every view needs the same extra domains (shortcut for all four categories):
Static deployments
When assets live on static storage and the MCP server runs elsewhere:Verify CSP
The mcp-use Inspector provides a CSP Mode Toggle for testing:- Permissive: Relaxed CSP for debugging
- Widget-Declared: Enforces the view’s declared CSP (production-like)
Next Steps
- MCP Apps: View overview and routing
- Self hosted: Run an MCP server in Docker