Content Security Policy plug for MCP App resources.
When used inside a Phantom.App module, this plug:
- Sets the
Content-Security-Policyresponse header - Stores UI metadata in
conn.private[:phantom_ui]for the MCP_meta.uiresponse
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: ...
endUsage in a Phoenix pipeline
import Phantom.App.CSP
pipeline :mcp_apps do
plug :put_content_security_policy,
connect_domains: ["https://api.example.com"]
endOptions
: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
Summary
Functions
Build a CSP header string from domain options.
Build a CSP header string from a Phantom.UI struct.
Set the Content-Security-Policy response header.
Functions
Build a CSP header string from domain options.
Returns a policy string following the MCP Apps spec defaults.
@spec build_from_ui(Phantom.UI.t() | nil) :: String.t()
Build a CSP header string from a Phantom.UI struct.
@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"]
)