Phantom.App.CSP (phantom_mcp v0.5.0)

Copy Markdown View Source

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

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(opts)

@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(ui)

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

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

put_content_security_policy(conn, opts)

@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"]
)