# `Phantom.App.CSP`
[🔗](https://github.com/dbernheisel/phantom_mcp/blob/main/lib/phantom/app/csp.ex#L1)

Content Security Policy plug for MCP App resources.

When used inside a `Phantom.App` module, this plug:
1. Sets the `Content-Security-Policy` response header
2. Stores UI metadata in `conn.private[:phantom_ui]` for the MCP `_meta.ui` response

## Usage in a Phantom.App module

    defmodule MyApp.DashboardApp do
      use Phantom.App,
        permissions: [:clipboard_write],
        prefers_border: true

      plug Phantom.App.CSP,
        connect_domains: ["https://api.example.com"],
        resource_domains: ["https://cdn.example.com"],

      def mount(assigns), do: ...
      def render(assigns), do: ...
    end

## Usage in a Phoenix pipeline

    import Phantom.App.CSP

    pipeline :mcp_apps do
      plug :put_content_security_policy,
        connect_domains: ["https://api.example.com"]
    end

## Options

  * `:connect_domains` - Origins allowed for fetch/XHR/WebSocket
  * `:resource_domains` - Origins for scripts, images, styles, fonts, media
  * `:frame_domains` - Origins for nested iframes
  * `:base_uri_domains` - Origins for document base-uri
  * `:permissions` - Sandbox permissions (`:camera`, `:microphone`, `:geolocation`, `:clipboard_write`)
  * `:domain` - Dedicated sandbox origin hint
  * `:prefers_border` - Whether the app prefers a visible border

# `build`

```elixir
@spec build(Keyword.t()) :: String.t()
```

Build a CSP header string from domain options.

Returns a policy string following the MCP Apps spec defaults.

# `build_from_ui`

```elixir
@spec build_from_ui(Phantom.UI.t() | nil) :: String.t()
```

Build a CSP header string from a `Phantom.UI` struct.

# `put_content_security_policy`

```elixir
@spec put_content_security_policy(Plug.Conn.t(), Keyword.t()) :: Plug.Conn.t()
```

Set the `Content-Security-Policy` response header.

    conn
    |> put_content_security_policy(
      connect_domains: ["https://api.example.com"],
      resource_domains: ["https://cdn.example.com"]
    )

---

*Consult [api-reference.md](api-reference.md) for complete listing*
