> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mcp-use.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Content Security Policy

> Configure CSP for MCP Apps and ChatGPT Apps SDK widgets

Content Security Policy (CSP) controls which domains your widgets can fetch from, load scripts/styles from, and embed. Widgets run in sandboxed iframes, so CSP must explicitly allow any external resources.

## Automatic Configuration

When `baseUrl` is set (via `MCPServer` constructor or `MCP_URL` environment variable), mcp-use automatically configures CSP:

```typescript theme={null}
const server = new MCPServer({
  name: "my-server",
  version: "1.0.0",
  baseUrl: process.env.MCP_URL, // Required for production
});
```

This ensures:

* Widget URLs use the correct domain
* CSP includes your server domain
* Works behind proxies and custom domains

The server origin is auto-injected into each widget's `connectDomains`, `resourceDomains`, and `baseUriDomains` - you don't need to add it manually.

## Per-Widget Configuration

For widgets that need additional domains (APIs, CDNs, etc.), configure CSP in your widget metadata.

### MCP Apps (all compatible clients, ChatGPT, Claude etc..)

With `type: "mcpApps"`, use camelCase in `metadata.csp`:

```typescript theme={null}
export const widgetMetadata: WidgetMetadata = {
  description: "Display weather",
  props: propSchema,
  metadata: {
    csp: {
      connectDomains: ["https://api.weather.com"],
      resourceDomains: ["https://cdn.weather.com"],
      baseUriDomains: ["https://myserver.com"],
      frameDomains: ["https://trusted-embed.com"],
      redirectDomains: ["https://oauth.provider.com"],
    },
  },
};
```

### Apps SDK Format (ChatGPT only - DEPRECATED)

With `type: "appsSdk"`, use snake\_case in `appsSdkMetadata["openai/widgetCSP"]`:

```typescript theme={null}
export const appsSdkMetadata = {
  "openai/widgetCSP": {
    connect_domains: ["https://api.weather.com"],
    resource_domains: ["https://cdn.weather.com"],
    frame_domains: ["https://trusted-embed.com"],
    redirect_domains: ["https://oauth.provider.com"],
  },
};
```

### Field Reference

| MCP Apps (camelCase) | Apps SDK (snake\_case) | Description                                                               |
| -------------------- | ---------------------- | ------------------------------------------------------------------------- |
| `connectDomains`     | `connect_domains`      | Domains for fetch, XHR, WebSocket                                         |
| `resourceDomains`    | `resource_domains`     | Domains for scripts, styles, images                                       |
| `baseUriDomains`     | `base_uri_domains`     | Domains for base URI (MCP Apps)                                           |
| `frameDomains`       | `frame_domains`        | Domains for iframe embeds                                                 |
| `redirectDomains`    | `redirect_domains`     | Domains for redirects (ChatGPT-specific)                                  |
| `scriptDirectives`   | `script_directives`    | Custom script CSP directives, not all clients support this (e.g. ChatGPT) |
| `styleDirectives`    | `style_directives`     | Custom style CSP directives                                               |

<Note>
  Your CSP domains are merged with your server's base URL automatically. For ChatGPT, OpenAI's required domains (`*.oaistatic.com`, etc.) are also added. For MCP Apps clients, only the domains you declare are used.
</Note>

## Environment Variables

```env theme={null}
# Base URL  -  auto-included in widget CSP
MCP_URL=https://myserver.com

# Additional domains (comma-separated)  -  appended to widget CSP
CSP_URLS=https://api.example.com,https://cdn.example.com
```

* **MCP\_URL**: Base URL for widget assets and public files. Also used by the server to configure CSP.
* **CSP\_URLS**: (Optional) Additional domains to whitelist. Supports comma-separated list. Required for static deployments where widget assets are served from different domains.

## Static Deployments

When widgets are served from static storage (e.g., Supabase Storage) while the MCP server runs elsewhere, set:

* **MCP\_URL**: Where widget assets are stored
* **MCP\_SERVER\_URL**: Where the MCP server runs (for API calls)
* **CSP\_URLS**: Domains for storage and API access (e.g., `https://YOUR_PROJECT.supabase.co`)

See [Supabase deployment](./deployment/supabase) for a complete setup.

<Tip>
  **Alternative**: Instead of the global `CSP_URLS` environment variable, configure CSP per-widget in `metadata.csp`
</Tip>

## Inspector Debugging

The mcp-use Inspector provides a **CSP Mode Toggle** for testing:

* **Permissive**  -  Relaxed CSP for debugging
* **Widget-Declared**  -  Enforces the widget's declared CSP (production-like)

<Warning>
  CSP violations are logged in the console. Use Widget-Declared mode to catch CSP issues before production deployment.
</Warning>

See [Debugging ChatGPT Apps](/inspector/debugging-chatgpt-apps) for details.

## Next Steps

* [MCP Apps](./mcp-apps)  -  Unified metadata format for both protocols
* [ChatGPT Apps SDK](./mcp-apps)  -  Widget metadata and registration
* [Supabase Deployment](./deployment/supabase)  -  Static deployment with CSP
* [Debugging Widgets](/inspector/debugging-chatgpt-apps)  -  Test CSP in the Inspector
