# StaticX Full LLM Context StaticX helps users create, upload, deploy, version, roll back, automate, and operate static websites. The product exposes a visual dashboard plus API, CLI, and MCP tooling for automation and AI agents. ## Canonical machine-readable files - `/llms.txt`: concise LLM index. - `/llms-full.txt`: this expanded context file. - `/openapi.json`: canonical OpenAPI 3.1 contract. - `/api/v1/openapi.json`: byte-identical alias of `/openapi.json`. - Append `.md` to any product page URL for a Markdown version (e.g. `/react-hosting.md`). ## Authentication StaticX uses scoped API tokens. Pass the token as a bearer token: ```http Authorization: Bearer STATICX_API_TOKEN Accept: application/json ``` Token values are secrets. Do not print them, log them, commit them, or include them in generated documentation. Shared examples should use placeholders such as `sx_replace_with_your_token`. ## Token scopes - Global tokens can operate across the account when the selected abilities allow it. - Workspace tokens stay inside one workspace. - Site tokens stay inside one site and are best for CI or one-agent deployment jobs. - Tokens can expire and can be revoked from StaticX settings. ## Required deployment shape - Static archives should place the published files at the archive root. - The root must contain `index.html` or `index.htm`. - The root must contain `404.html`. - Use `/projects/{project}/files` to upload files, queue ZIP archive imports, or queue URL imports. - ZIP and URL imports return `202` with `status=queued`; poll `/projects/{project}/imports/status` until `state=completed` before publishing. - Use `DELETE /projects/{project}/files` to delete workspace files or folders only after explicit user confirmation. - Use `/projects/{project}/deployments` to publish. - `versioned_history` creates a new immutable deployment per publish. - `baseline_only` updates the first/baseline release and keeps analytics/forms attached without growing history. ## Indexing (SpeedyIndex) StaticX can submit and check site URLs against search engines through SpeedyIndex. The SpeedyIndex API key belongs to the account OWNER (the site owner), is stored encrypted, is set in Settings -> Indexing, and is NEVER returned by the API. A workspace member acting on a shared site uses the owner's key and balance. Engine asymmetry (enforced server-side): - indexer: google, yandex (bing has NO indexer). - checker: google, yandex, bing. Endpoints: - `GET /indexing/balance`: the token user's SpeedyIndex balance as `{ "data": { "tokens", "indexer", "checker" } }`. No key -> 401 with error_code=no_key. - `GET /indexing/pages?engine=&status=&site=&workspace=&page=`: account-wide page inventory for every site the token can access, for one engine. Defaults: engine=google, status=unchecked. status=all returns all statuses. Response: `{ engine, status, rows[], metrics{}, trend[], pagination{} }`. Statuses: unchecked, not_indexed, pending, indexed, error, requested, not_requested. - `POST /projects/{project}/indexing/submit`: body `{ "engine": "google", "type": "indexer", "urls": ["https://..."] }`. Omit `urls` to submit the sitemap-diff set. Idempotent. Returns `{ "data": { "created", "submitted", "est_tokens" } }`. - `POST /projects/{project}/indexing/check`: body `{ "engine": "google", "urls": [...] }`. Omit `urls` to check the full site inventory. Repeatable. Returns `{ "data": { "created", "submitted" } }`. - `GET /projects/{project}/indexing/tasks`: recent tasks as `{ "data": [ ... ] }`. - `GET /projects/{project}/indexing/tasks/{task}`: one task plus its lazily fetched per-URL report. Indexing error codes (the JSON body always carries a machine-readable `error_code`): - `no_key` (HTTP 401): no SpeedyIndex key is connected. Recover: connect a key in Settings -> Indexing. - `insufficient_balance` (HTTP 402): the owner's SpeedyIndex balance is too low. Recover: top up SpeedyIndex credits. - `engine_unsupported` (HTTP 422): the engine/type combination is invalid (for example bing + indexer). Recover: choose a supported engine/type. - `rate_limited` (HTTP 429): SpeedyIndex rate limit reached. Recover: wait and retry. - `server` (HTTP 502): SpeedyIndex returned an upstream error. Recover: retry later. Authorization: indexing reads need `projects.read`; submit/check need `projects.write`. A project outside the token scope returns 403/404 like every other project route. The key is never present in any response or log. ## Plan limits and quota behavior - Free plan: 1 site, 500 MB total account storage, 500 MB maximum upload, 1,000 stored form entries, 1 team seat, last 5 rollback versions. - Plus plan: 15 sites, 10 GB storage, 50 GB maximum upload, 20,000 stored form entries, 5 team seats, last 10 rollback versions. - Pro plan: 100 sites, 20 GB storage, 50 GB maximum upload, 100,000 stored form entries, 10 team seats, last 50 rollback versions. - Unlimited plan: custom sites, storage, form entries, team seats, and rollback history, with 50 GB maximum upload. - Limits are enforced for dashboard uploads, API uploads, CLI/MCP uploads, URL imports, and hosted form submissions. - If an API response has `error_code=PLAN_QUOTA_EXCEEDED`, stop. Return the exact message and suggest cleaning up storage, deleting form entries, or upgrading. ## Golden deploy prompt Use this prompt when handing a static site deployment to an AI agent: ```text Use StaticX to deploy this static website. Before publishing: - inspect the project structure - build the site if a build step exists - confirm the publish root contains index.html or index.htm - confirm the publish root contains 404.html - explain exactly what files will be uploaded Then: - upload the build output to StaticX - if the upload response says `status=queued`, poll `/projects/{project}/imports/status` until `state=completed` before publishing - publish the site - if the user wants rollback history, keep `versioning_enabled=true` - if the user asks to avoid version history, send `versioning_enabled=false` when creating the site or deploying so StaticX keeps one baseline release only - return the live URL, deployment mode, deployment id, and any warnings Safety: - never print or log STATICX_API_TOKEN - do not delete files, rollback, or remove deployments without asking - when deleting workspace files, use DELETE /projects/{project}/files with the exact file_keys the user approved - if the API returns PLAN_QUOTA_EXCEEDED, stop and report the exact quota error - if import status becomes failed or stalled, stop and report the exact import message - if anything else fails, stop and report the exact API error ``` ## Exact curl examples Set these variables first: ```bash export STATICX_API_BASE_URL="https://staticx.site/api/v1" export STATICX_API_TOKEN="sx_replace_with_your_token" export STATICX_PROJECT_ID="123" ``` Upload a ZIP archive: ```bash curl -X POST "$STATICX_API_BASE_URL/projects/$STATICX_PROJECT_ID/files" \ -H "Authorization: Bearer $STATICX_API_TOKEN" \ -H "Accept: application/json" \ -F "mode=zip" \ -F "path=" \ -F "archive=@dist.zip" ``` Poll ZIP import status before deploy: ```bash curl -X GET "$STATICX_API_BASE_URL/projects/$STATICX_PROJECT_ID/imports/status" \ -H "Authorization: Bearer $STATICX_API_TOKEN" \ -H "Accept: application/json" ``` Upload individual files: ```bash curl -X POST "$STATICX_API_BASE_URL/projects/$STATICX_PROJECT_ID/files" \ -H "Authorization: Bearer $STATICX_API_TOKEN" \ -H "Accept: application/json" \ -F "mode=files" \ -F "path=" \ -F "files[]=@index.html" \ -F "files[]=@404.html" ``` Delete workspace files: ```bash curl -X DELETE "$STATICX_API_BASE_URL/projects/$STATICX_PROJECT_ID/files" \ -H "Authorization: Bearer $STATICX_API_TOKEN" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{"file_keys":["assets/old.xml","assets/unused-folder"]}' ``` Publish a deployment version: ```bash curl -X POST "$STATICX_API_BASE_URL/projects/$STATICX_PROJECT_ID/deployments" \ -H "Authorization: Bearer $STATICX_API_TOKEN" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{}' ``` The publish runs in the background. Poll the deployment until it finishes: ```bash curl "$STATICX_API_BASE_URL/projects/$STATICX_PROJECT_ID/deployments/{deployment}" \ -H "Authorization: Bearer $STATICX_API_TOKEN" \ -H "Accept: application/json" ``` Disable deployment history and publish the baseline release only: ```bash curl -X POST "$STATICX_API_BASE_URL/projects/$STATICX_PROJECT_ID/deployments" \ -H "Authorization: Bearer $STATICX_API_TOKEN" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{"versioning_enabled":false}' ``` Re-enable deployment history for future publishes: ```bash curl -X PATCH "$STATICX_API_BASE_URL/projects/$STATICX_PROJECT_ID" \ -H "Authorization: Bearer $STATICX_API_TOKEN" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{"versioning_enabled":true}' ``` Read deployment history: ```bash curl "$STATICX_API_BASE_URL/projects/$STATICX_PROJECT_ID/deployments" \ -H "Authorization: Bearer $STATICX_API_TOKEN" \ -H "Accept: application/json" ``` Start manual custom domain setup: ```bash curl -X POST "$STATICX_API_BASE_URL/projects/$STATICX_PROJECT_ID/domain" \ -H "Authorization: Bearer $STATICX_API_TOKEN" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{"domain":"app.example.com"}' ``` Check custom domain status: ```bash curl "$STATICX_API_BASE_URL/projects/$STATICX_PROJECT_ID/domain" \ -H "Authorization: Bearer $STATICX_API_TOKEN" \ -H "Accept: application/json" ``` Domain workflow notes: - The API domain endpoint returns manual DNS instructions. - CLI command: `staticx domain --site-id SITE_ID --domain app.example.com`. - MCP tool: `staticx_connect_custom_domain`. - DNS Connect is dashboard-only because the domain owner must approve access in a browser. - If the user asks for DNS automation, tell them to open Site Settings → Domain or Settings → Publishing domain and approve DNS Connect. - If the user asks to move a generated free subdomain onto an account publishing domain, tell them to use Site Settings → Domain in the dashboard. The suffix selector is dashboard-only until a public API route exists. - Generated subdomain labels are unique per suffix, so `launch.staticx.store` and `launch.example.com` can coexist, but duplicate `launch.example.com` cannot. ## Static form rules - Add `data-staticx-form` to the `
` element. - Use `data-staticx-form-id` only to share one collection across pages. - Keep the form as normal HTML. - Do not set a custom backend action for StaticX forms. - Do not manually inject the StaticX script. - StaticX injects the submit action, honeypot, and same-page script. - If a hosted form returns a plan limit error, do not bypass StaticX Forms. Tell the user to delete entries or upgrade. - Optional attributes: - `data-staticx-success-message` - `data-staticx-error-message` - `data-staticx-redirect` ## API route summary - `GET /user`: Read authenticated user and current token context. - `GET /domains`: List visible custom domains and generated StaticX addresses. - `GET /workspaces`: List workspaces visible to the token. - `POST /workspaces`: Create a workspace. - `GET /workspaces/{workspace}`: Read one workspace with members and project count. - `DELETE /workspaces/{workspace}`: Delete a workspace and either move or delete its sites. - `GET /projects`: List sites visible to the token. - `POST /projects`: Create a site from metadata, a ZIP archive, or a source URL. - `GET /projects/{project}`: Read one site. - `PATCH /projects/{project}`: Update site metadata. - `PUT /projects/{project}`: Update site metadata with a full update request. - `DELETE /projects/{project}`: Delete a site. - `GET /projects/{project}/domain`: Read custom domain setup, DNS instructions, and activation status. - `POST /projects/{project}/domain`: Start manual custom domain setup and return the single DNS record to create. - `POST /projects/{project}/domain/cloudflare-dns`: Provision (or reconcile) the managed CNAME for an already-connected custom domain, without changing the host. - `GET /projects/{project}/files`: List files and folders in a project workspace. - `POST /projects/{project}/files`: Upload files, queue a ZIP archive import, or queue a URL import. - `DELETE /projects/{project}/files`: Delete one or more project workspace files or folders. - `GET /projects/{project}/imports/status`: Read the latest ZIP or URL import status for a project. - `POST /projects/{project}/builds`: Run a compatibility build check. - `GET /projects/{project}/builds/{build}`: Read one compatibility build check. - `GET /projects/{project}/deployments`: List immutable deployment versions for a site. - `POST /projects/{project}/deployments`: Publish the current project workspace as an immutable deployment version. Asynchronous: responds immediately with the deployment in `running` status; poll GET /projects/{project}/deployments/{deployment} until `status` is `succeeded` or `failed`. - `DELETE /projects/{project}/deployments/delete-selected`: Delete multiple inactive deployment versions. - `GET /projects/{project}/deployments/{deployment}`: Read one deployment version. - `DELETE /projects/{project}/deployments/{deployment}`: Delete one inactive deployment version. - `POST /projects/{project}/deployments/{deployment}/rollback`: Make a previous successful deployment live. - `GET /projects/{project}/environment-variables`: List project environment variables. - `POST /projects/{project}/environment-variables`: Create or update one environment variable. - `PUT /projects/{project}/environment-variables`: Replace/sync project environment variables. - `DELETE /projects/{project}/environment-variables/{environmentVariable}`: Delete one environment variable. - `GET /projects/{project}/logs`: Read recent project activity logs. - `GET /indexing/balance`: Read the SpeedyIndex balance for the token user (the account owner). - `GET /indexing/pages`: List account-wide page inventory for the selected engine across every site the token can access. - `POST /projects/{project}/indexing/submit`: Submit site URLs to SpeedyIndex (indexer by default; sitemap-diff when urls is omitted). - `POST /projects/{project}/indexing/check`: Create a SpeedyIndex checker task for the given urls, or the site inventory when omitted. - `GET /projects/{project}/indexing/tasks`: List a site indexing and checker tasks, most recent first. - `GET /projects/{project}/indexing/tasks/{task}`: Read one indexing task with its lazily fetched per-URL report. ## MCP setup: generic stdio Use the public MCP server when an AI agent supports MCP stdio: ```json { "mcpServers": { "staticx": { "command": "npx", "args": [ "-y", "staticx-mcp-server" ], "env": { "STATICX_API_TOKEN": "sx_replace_with_your_token", "STATICX_API_BASE_URL": "https://staticx.site/api/v1", "STATICX_PROJECT_ID": "optional_site_id" } } } } ``` ## MCP client examples ### Cursor - Location: `~/.cursor/mcp.json` - Note: Open Cursor settings, add an MCP server, then paste this JSON. ```json { "mcpServers": { "staticx": { "command": "npx", "args": [ "-y", "staticx-mcp-server" ], "env": { "STATICX_API_TOKEN": "sx_replace_with_your_token", "STATICX_API_BASE_URL": "https://staticx.site/api/v1", "STATICX_PROJECT_ID": "optional_site_id" } } } } ``` ### Claude Desktop - Location: `claude_desktop_config.json` - Note: Add the `staticx` server under `mcpServers`, then restart Claude Desktop. ```json { "mcpServers": { "staticx": { "command": "npx", "args": [ "-y", "staticx-mcp-server" ], "env": { "STATICX_API_TOKEN": "sx_replace_with_your_token", "STATICX_API_BASE_URL": "https://staticx.site/api/v1", "STATICX_PROJECT_ID": "optional_site_id" } } } } ``` ### Claude Code - Location: `Terminal` - Note: Run `claude mcp list` afterward to confirm the server is available. ```bash claude mcp add staticx --scope user \ --env STATICX_API_TOKEN=sx_replace_with_your_token \ --env STATICX_API_BASE_URL=https://staticx.site/api/v1 \ --env STATICX_PROJECT_ID=optional_site_id \ -- npx -y staticx-mcp-server ``` ### Windsurf - Location: `~/.codeium/windsurf/mcp_config.json` - Note: Paste the config into the Windsurf MCP config file and reload Windsurf. ```json { "mcpServers": { "staticx": { "command": "npx", "args": [ "-y", "staticx-mcp-server" ], "env": { "STATICX_API_TOKEN": "sx_replace_with_your_token", "STATICX_API_BASE_URL": "https://staticx.site/api/v1", "STATICX_PROJECT_ID": "optional_site_id" } } } } ``` ### Cline - Location: `Cline MCP Servers settings` - Note: Use the Cline MCP Servers UI, add a server named `staticx`, and paste the JSON. ```json { "mcpServers": { "staticx": { "command": "npx", "args": [ "-y", "staticx-mcp-server" ], "env": { "STATICX_API_TOKEN": "sx_replace_with_your_token", "STATICX_API_BASE_URL": "https://staticx.site/api/v1", "STATICX_PROJECT_ID": "optional_site_id" } } } } ``` ## MCP tools - `staticx_config` - `staticx_auth_check` - `staticx_list_workspaces` - `staticx_create_workspace` - `staticx_list_projects` - `staticx_get_project` - `staticx_create_project` - `staticx_connect_custom_domain` - `staticx_get_custom_domain_status` - `staticx_upload_zip` - `staticx_import_url` - `staticx_deploy_project` - `staticx_deploy_zip` - `staticx_list_deployments` - `staticx_rollback_deployment` - `staticx_delete_deployment` - `staticx_set_environment_variables` - `staticx_get_logs` - `staticx_agent_guide` ## Safe agent workflow 1. Inspect the project and identify the static build output. 2. Build locally if the project has a build step. 3. Confirm `index.html` or `index.htm` and `404.html` exist at the published root. 4. Create or select a StaticX site. 5. Upload files or ZIP through the API or MCP tool. 6. Publish a deployment. 7. Return the live URL, version name, and any warnings. 8. Do not roll back or delete without explicit user confirmation. ## Common errors - `401`: the API token is missing or invalid. - `403`: the token is valid but lacks the required ability or scope. - `404`: the resource does not exist or is outside token scope. - `422`: validation failed, missing required files, invalid domain, invalid ZIP, or deployment failed. - `429`: hosted form entry limit reached. - `PLAN_QUOTA_EXCEEDED`: upload or storage limit reached. Stop and return the exact API message. ## Human documentation - Overview: https://staticx.site/documentation - API: https://staticx.site/documentation/api - CLI: https://staticx.site/documentation/cli - MCP quick start: https://staticx.site/documentation/mcp - MCP authentication: https://staticx.site/documentation/mcp-authentication - MCP clients: https://staticx.site/documentation/mcp-clients - MCP tools: https://staticx.site/documentation/mcp-tools - MCP recipes: https://staticx.site/documentation/mcp-recipes - Troubleshooting: https://staticx.site/documentation/mcp-troubleshooting