anthropics / anthropics/claude-ai-mcp

[BUG] Claude.ai ignores frameDomains (and other CSP fields) declared in MCP Apps _meta.ui.csp — iframe blocked by hardcoded frame-src

Đang mở
#40 31 bình luận 57 reaction 0 người được giao Xem trên GitHub
bug mcp-apps
Ngôn ngữ chính
Không có dữ liệu ngôn ngữ
Star
471
Fork
76
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Mô tả

### What happened?

## Summary

Claude.ai's MCP Apps sandbox does not respect the `frameDomains`, `connectDomains`, or `resourceDomains` fields declared in a UI resource's `_meta.ui.csp` object. Instead, a hardcoded CSP of `frame-src 'self' blob: data:` is enforced, blocking any nested iframes from declared origins. This violates the MCP Apps specification (SEP-1865, section 5), which states:

> "The Sandbox MUST… If `frameDomains` is provided, allow nested iframes from declared origins."

The same MCP server works correctly on other hosts (ChatGPT, MCP-Jam) that properly respect the declared CSP fields.

## Environment

- **Host:** Claude.ai (web interface, claude.ai)
- **Browser:** Brave 144 / Chromium-based (macOS 26.2.0, ARM64)
- **MCP Server:** Revieve Skincare Advisor (`https://add-mcp-server--revieve-platform-mcp-server.netlify.app`)

## Resource `_meta.ui.csp` Declaration

The MCP server correctly declares CSP requirements in the UI resource metadata:

```typescript
{
uri: resourceUri,
mimeType: RESOURCE_MIME_TYPE,
text: pageHTML,
_meta: {
ui: {
csp: {
resourceDomains: [
"https://cdn.revieve.com/",
"https://www.googletagmanager.com/",
"https://d38knilzwtuys1.cloudfront.net",
"http://localhost:3000/",
"https://add-mcp-server--revieve-platform-plugin.netlify.app/",
ASTRO_DEV_URL,
],
connectDomains: [
"https://cdn.revieve.com/",
"https://partner-test.revieve.com",
"https://d38knilzwtuys1.cloudfront.net",
"https://sst.revieve.com",
],
frameDomains: [
"https://cdn.revieve.com",
"https://d38knilzwtuys1.cloudfront.net",
],
baseUriDomains: ["https://cdn.revieve.com/"],
},
},
},
}
```

## Observed Behavior

Claude.ai enforces the following CSP on the sandbox iframe, **completely ignoring** all declared domains:

```
frame-src 'self' blob: data:
connect-src 'self' https://cdn.revieve.com https://partner-test.revieve.com https://d38knilzwtuys1.cloudfront.net
```

### Console Errors

**1. `frame-src` violation — nested iframe blocked:**

```
Framing 'https://d38knilzwtuys1.cloudfront.net/' violates the following Content Security Policy
directive: "frame-src 'self' blob: data:". The request has been blocked.
```

**2. `connect-src` violation — analytics/telemetry blocked:**

```
Connecting to 'https://sst.revieve.com/g/collect?...' violates the following Content Security Policy
directive: "connect-src 'self' https://cdn.revieve.com https://partner-test.revieve.com
https://d38knilzwtuys1.cloudfront.net". The action has been blocked.
```

```
Fetch API cannot load https://sst.revieve.com/g/collect?...
Refused to connect because it violates the document's Content Security Policy.
```

### What did you expect to happen?

## Expected Behavior

Per the MCP Apps specification (SEP-1865), the host sandbox **must** read `_meta.ui.csp` and dynamically apply the declared domains to the corresponding CSP directives:

- `frameDomains` → should be added to `frame-src`
- `connectDomains` → should be added to `connect-src`
- `resourceDomains` → should be added to relevant resource directives (`script-src`, `img-src`, etc.)

The expected enforced CSP should include at minimum:

```
frame-src 'self' blob: data: https://cdn.revieve.com https://d38knilzwtuys1.cloudfront.net
connect-src 'self' https://cdn.revieve.com https://partner-test.revieve.com https://d38knilzwtuys1.cloudfront.net https://sst.revieve.com
```

### Steps to reproduce

## Steps to Reproduce

1. Go to Claude.ai
2. Connect the Revieve Skincare Advisor MCP server
3. Trigger any tool that returns a UI resource (e.g., `Show me the skincare advisor widget`)
4. Open browser DevTools → Console
5. Observe `frame-src` and `connect-src` CSP violation errors
6. The widget fails to render its iframe content

### Area

Resource Handling

### MCP Server (if applicable)

Revieve Skincare Advisor (`https://add-mcp-server--revieve-platform-mcp-server.netlify.app/api/mcp`)

### Error messages or logs

```shell
Framing 'https://d38knilzwtuys1.cloudfront.net/' violates the following Content Security Policy directive: "frame-src 'self' blob: data:". The request has been blocked.

js?id=G-VBZ5XNENGP:213 Connecting to 'https://sst.revieve.com/g/collect?v=2&tid=G-VBZ5XNENGP>m=45je6221v892154687za200zd892154687&_p=1770218131389&gcs=G111&gcd=13t3tPt2t5l1&npa=0&dma_cps=syphamo&dma=1&cid=715284458.1770131200&ul=en-us&sr=1512x982&_fplc=0&uaa=arm&uab=64&uafvl=Not(A%253ABrand%3B8.0.0.0%7CChromium%3B144.0.0.0%7CBrave%3B144.0.0.0&uamb=0&uam=&uap=macOS&uapv=26.2.0&uaw=0&frm=2&pscdl=noapi&_eu=AAAAAAQ&_s=1&tag_exp=103116026~103200004~104527907~104528501~104684208~104684211~115616985~115938466~115938469~116185181~116185182~116988315...ilzwtuys1.cloudfront.net%26resource-src%3Dhttps%253A%252F%252Fcdn.revieve.com%252F%2Bhttps%253A%252F%252Fwww.googletagmanager.com%252F%2Bhttps%253A%252F%252Fd38knilzwtuys1.cloudfront.net%2Bhttp%253A%252F%252Flocalhost%253A3000%252F%2Bhttps%253A%252F%252Fadd-mcp-server--revieve-platform-plugin.netlify.app%252F%2Bhttps%253A%252F%252Fadd-mcp-server--revieve-platform-mcp-server.netlify.app%2Bhttps%253A%252F%252Fassets.claude.ai&dt=-&_tu=RA&en=page_view&_ss=1&_ee=1&ep.identifier=Revieve%20skincaredemo&tfd=1380' violates the following Content Security Policy directive: "connect-src 'self' https://cdn.revieve.com https://partner-test.revieve.com https://d38knilzwtuys1.cloudfront.net". The action has been blocked.
fd @ js?id=G-VBZ5XNENGP:213
js?id=G-VBZ5XNENGP:213 Fetch API cannot load https://sst.revieve.com/g/collect?v=2&tid=G-VBZ5XNENGP>m=45je6221v892154687za200zd892154687&_p=1770218131389&gcs=G111&gcd=13t3tPt2t5l1&npa=0&dma_cps=syphamo&dma=1&cid=715284458.1770131200&ul=en-us&sr=1512x982&_fplc=0&uaa=arm&uab=64&uafvl=Not(A%253ABrand%3B8.0.0.0%7CChromium%3B144.0.0.0%7CBrave%3B144.0.0.0&uamb=0&uam=&uap=macOS&uapv=26.2.0&uaw=0&frm=2&pscdl=noapi&_eu=AAAAAAQ&_s=1&tag_exp=103116026~103200004~104527907~104528501~104684208~104684211~115616985~115938466~115938469~116185181~116185182~116988315...ilzwtuys1.cloudfront.net%26resource-src%3Dhttps%253A%252F%252Fcdn.revieve.com%252F%2Bhttps%253A%252F%252Fwww.googletagmanager.com%252F%2Bhttps%253A%252F%252Fd38knilzwtuys1.cloudfront.net%2Bhttp%253A%252F%252Flocalhost%253A3000%252F%2Bhttps%253A%252F%252Fadd-mcp-server--revieve-platform-plugin.netlify.app%252F%2Bhttps%253A%252F%252Fadd-mcp-server--revieve-platform-mcp-server.netlify.app%2Bhttps%253A%252F%252Fassets.claude.ai&dt=-&_tu=RA&en=page_view&_ss=1&_ee=1&ep.identifier=Revieve%20skincaredemo&tfd=1380. Refused to connect because it violates the document's Content Security Policy.
fd @ js?id=G-VBZ5XNENGP:213
js?id=G-VBZ5XNENGP:213 Connecting to 'https://sst.revieve.com/g/collect?v=2&tid=G-VBZ5XNENGP>m=45je6221v892154687za200zd892154687&_p=1770218131389&gcs=G111&gcd=13t3tPt2t5l1&npa=0&dma_cps=syphamo&dma=1&cid=715284458.1770131200&ul=en-us&sr=1512x982&_fplc=0&uaa=arm&uab=64&uafvl=Not(A%253ABrand%3B8.0.0.0%7CChromium%3B144.0.0.0%7CBrave%3B144.0.0.0&uamb=0&uam=&uap=macOS&uapv=26.2.0&uaw=0&frm=2&pscdl=noapi&_eu=AEAAAAQ&_s=2&tag_exp=103116026~103200004~104527907~104528501~104684208~104684211~115616985~115938466~115938469~116185181~116185182~116988315....cloudfront.net%26resource-src%3Dhttps%253A%252F%252Fcdn.revieve.com%252F%2Bhttps%253A%252F%252Fwww.googletagmanager.com%252F%2Bhttps%253A%252F%252Fd38knilzwtuys1.cloudfront.net%2Bhttp%253A%252F%252Flocalhost%253A3000%252F%2Bhttps%253A%252F%252Fadd-mcp-server--revieve-platform-plugin.netlify.app%252F%2Bhttps%253A%252F%252Fadd-mcp-server--revieve-platform-mcp-server.netlify.app%2Bhttps%253A%252F%252Fassets.claude.ai&dt=-&_tu=RA&en=scroll&ep.identifier=Revieve%20skincaredemo&epn.percent_scrolled=90&tfd=6831' violates the following Content Security Policy directive: "connect-src 'self' https://cdn.revieve.com https://partner-test.revieve.com https://d38knilzwtuys1.cloudfront.net". The action has been blocked.
fd @ js?id=G-VBZ5XNENGP:213
js?id=G-VBZ5XNENGP:213 Fetch API cannot load https://sst.revieve.com/g/collect?v=2&tid=G-VBZ5XNENGP>m=45je6221v892154687za200zd892154687&_p=1770218131389&gcs=G111&gcd=13t3tPt2t5l1&npa=0&dma_cps=syphamo&dma=1&cid=715284458.1770131200&ul=en-us&sr=1512x982&_fplc=0&uaa=arm&uab=64&uafvl=Not(A%253ABrand%3B8.0.0.0%7CChromium%3B144.0.0.0%7CBrave%3B144.0.0.0&uamb=0&uam=&uap=macOS&uapv=26.2.0&uaw=0&frm=2&pscdl=noapi&_eu=AEAAAAQ&_s=2&tag_exp=103116026~103200004~104527907~104528501~104684208~104684211~115616985~115938466~115938469~116185181~116185182~116988315....cloudfront.net%26resource-src%3Dhttps%253A%252F%252Fcdn.revieve.com%252F%2Bhttps%253A%252F%252Fwww.googletagmanager.com%252F%2Bhttps%253A%252F%252Fd38knilzwtuys1.cloudfront.net%2Bhttp%253A%252F%252Flocalhost%253A3000%252F%2Bhttps%253A%252F%252Fadd-mcp-server--revieve-platform-plugin.netlify.app%252F%2Bhttps%253A%252F%252Fadd-mcp-server--revieve-platform-mcp-server.netlify.app%2Bhttps%253A%252F%252Fassets.claude.ai&dt=-&_tu=RA&en=scroll&ep.identifier=Revieve%20skincaredemo&epn.percent_scrolled=90&tfd=6831. Refused to connect because it violates the document's Content Security Policy.
```

### Additional context

## Cross-Host Comparison

| Host | `frameDomains` Respected? | Widget Renders? |
|------|--------------------------|-----------------|
| Claude.ai | ❌ No — hardcoded `frame-src 'self' blob: data:` | ❌ Blocked |
| ChatGPT | ✅ Yes | ✅ Works |
| MCP-Jam | ✅ Yes | ✅ Works |

## Impact

This is a **spec compliance issue** that breaks any MCP App relying on nested iframes from external origins — a common pattern for widget-based integrations (embedded dashboards, third-party UI components, etc.). It effectively makes `frameDomains` non-functional on Claude.ai.

## Suggested Fix

Claude.ai's MCP Apps sandbox renderer should:

1. Read the `_meta.ui.csp` object from the UI resource
2. Dynamically merge `frameDomains` into the sandbox's `frame-src` directive
3. Dynamically merge `connectDomains` into `connect-src`
4. Dynamically merge `resourceDomains` into the appropriate resource directives

This is likely a small change in how the sandbox iframe's CSP header/meta tag is constructed before rendering.

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.