Skip to content
Scalpels home

Scalpels is officially launching on October 31, 2026. Special early adopter pricing is available now.

← All documentation

Documentation

Capstan

Artifact hosting

Updated

Artifact hosting turns a page of HTML into a link you can share. Your tool posts the HTML to Capstan; Capstan stores it privately in your bucket and returns a link. Opening the link shows a page on your app's hostname containing a sandboxed frame, and the frame loads the HTML from a second hostname under a strict content security policy.

Why there are two hostnames

Capstan does not try to clean AI-generated HTML. It contains it instead:

  • The HTML is served only from the render hostname, which never receives your login cookie. Requests to it carry no session, and Capstan strips any cookie from its responses.
  • The render hostname serves nothing except artifact content and the /up health check. Every other path on it is a 404.
  • The viewer page is served only from the app hostname, and artifact content only from the render hostname. Each refuses the other's requests.
  • The frame is sandboxed to allow scripts and nothing more, and the content policy blocks network requests, form submission and base-URL changes. Only your app's own origin may frame the content.

Using one hostname for both is not possible. Without a custom domain, the app and render origins are the same, so Capstan serves no artifacts at all rather than give up the separation. The rest of Capstan continues to work.

Switch it on

  1. Add your custom app domain. Follow Use your own domain, wait until Laravel Cloud says Connected, and redeploy. Your custom domain becomes Capstan's app origin. Scalpels enables artifact intent during installation and automatically keeps the environment's existing laravel.cloud address as the isolated render origin; do not add a second custom domain or set either value yourself.
  2. Keep SESSION_DOMAIN unset. If both hostnames sit under one parent domain, a shared session domain would send your login cookie to the render hostname.

If you put a CDN or proxy in front of the render hostname, it must not rewrite HTML. Capstan sends Cache-Control: no-transform, which Cloudflare honours.

Publish an artifact

Publishing needs a token for the capstan.artifact.ingest purpose and your actor id. API tokens explains how to get both.

curl -X POST https://capstan.example.com/api/v1/artifacts \
  -H "Authorization: Bearer $CAPSTAN_TOKEN" \
  -H "X-Capstan-Actor-ID: 1" \
  -H "Content-Type: application/json" \
  -d '{
        "content": "<!doctype html><title>Hello</title><p>Hello from Capstan.</p>",
        "content_type": "text/html",
        "visibility": "signed_url"
      }'

The fields are:

  • content: the HTML. Required, and no larger than CAPSTAN_ARTIFACT_MAX_CONTENT_BYTES (1 MB by default).
  • content_type: text/html or application/xhtml+xml. Required.
  • visibility: org_auth (the default) or signed_url. See below.
  • expires_at: an ISO-8601 time in the future. After it, the artifact returns 404.

A success is 201. The response carries the artifact (id, actor_id, visibility, expires_at, content_type, size_bytes, content_hash, created_at) and a share_url. Agents connected through MCP can do the same with the create_artifact_share tool; see Use Capstan from your agent.

Who can open a link

  • org_auth: anyone signed in to this Capstan can open the link. Someone who is not signed in is refused.
  • signed_url: anyone holding the link can open it, signed in or not. The link's signature expires at the artifact's expires_at, or one hour after it was issued if you did not set one. After that the link is refused, so set expires_at when you need a public link that lasts longer than an hour.

Either way, the frame inside the viewer loads the HTML from a separate content link that is valid for at most five minutes. Copy the viewer link, not the frame's address.

What artifact HTML can do

By default the content policy allows inline scripts, inline styles and inline data: images, and nothing from the network: no external scripts, stylesheets, fonts or images, and no fetch or XHR calls. Make your artifacts self-contained.

If your organisation decides a trusted source should be allowed, add it to the matching allowlist (CAPSTAN_ARTIFACT_CSP_SCRIPT_SRC, _STYLE_SRC, _FONT_SRC or _IMG_SRC) as a comma-separated list and redeploy. Network calls from artifact HTML stay blocked whatever you add.

Finding and removing artifacts

There is no screen listing artifacts in this release, and no API or tool to delete one. Keep the share_url your tool receives, and use expires_at for anything that should stop being reachable.