Bug
Widgets registered via registerWidget fail to render in Claude Web with an "Unable to reach [server]" error. The same widgets render correctly in Cursor and other MCP hosts.
Root cause
In registerWidgetResource (dist/server/server.js), the Claude-specific _meta.ui.domain hash is computed from the resource request URL, not the MCP connector URL:
const pathname = extra?.requestInfo?.url?.pathname ?? "";
const url = `https://${hostFromHeaders}${pathname}`;
const hash = crypto.createHash("sha256").update(url).digest("hex").slice(0, 32);
Claude Web expects domain to equal sha256(connectorUrl).slice(0,32) + ".claudemcpcontent.com", where connectorUrl is the URL the user entered when adding the MCP connector (e.g. https://mcp.fiji.so/mcp).
The pathname from extra.requestInfo.url.pathname is the path of the resource being fetched (typically "/"), not the /mcp endpoint path. So Skybridge hashes https://mcp.fiji.so/ instead of https://mcp.fiji.so/mcp, producing a different hash that Claude rejects.
Confirmed with hash comparison
https://mcp.fiji.so/ -> e33d66d6360c03b5787778d5d39cb0c6 (what Skybridge produces — rejected)
https://mcp.fiji.so/mcp -> 0a438b56404e81245c5485e96ce8e529 (what Claude expects — correct)
Suggested fix
Use the known MCP endpoint URL (from env var or server config) instead of the resource request path when computing the Claude domain hash. For example:
const url = process.env.MCP_SERVER_URL || `https://${hostFromHeaders}${extra?.requestInfo?.url?.pathname ?? ""}`;
Or better: derive the connector URL from the server's own configuration rather than relying on an env var.
Workaround
Using patch-package to apply the one-line fix above to dist/server/server.js.
Environment
- Skybridge v0.35.8
- Claude Web (claude.ai) as MCP host
- Connector URL:
https://mcp.fiji.so/mcp
Bug
Widgets registered via
registerWidgetfail to render in Claude Web with an "Unable to reach [server]" error. The same widgets render correctly in Cursor and other MCP hosts.Root cause
In
registerWidgetResource(dist/server/server.js), the Claude-specific_meta.ui.domainhash is computed from the resource request URL, not the MCP connector URL:Claude Web expects
domainto equalsha256(connectorUrl).slice(0,32) + ".claudemcpcontent.com", whereconnectorUrlis the URL the user entered when adding the MCP connector (e.g.https://mcp.fiji.so/mcp).The
pathnamefromextra.requestInfo.url.pathnameis the path of the resource being fetched (typically"/"), not the/mcpendpoint path. So Skybridge hasheshttps://mcp.fiji.so/instead ofhttps://mcp.fiji.so/mcp, producing a different hash that Claude rejects.Confirmed with hash comparison
Suggested fix
Use the known MCP endpoint URL (from env var or server config) instead of the resource request path when computing the Claude domain hash. For example:
Or better: derive the connector URL from the server's own configuration rather than relying on an env var.
Workaround
Using
patch-packageto apply the one-line fix above todist/server/server.js.Environment
https://mcp.fiji.so/mcp