Skip to main content
Glama
bitfiction
by bitfiction

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
STATICBOT_API_KEYYesAuthenticates requests to Staticbot
STATICBOT_API_URLNoOverride only for a self-hosted or local APIhttps://app.staticbot.dev

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": true
}

Tools

Functions exposed to the LLM to take actions

NameDescription
get_account_statusA

START HERE. The first call of any Staticbot conversation, and the cheapest: it answers in one request who the credential belongs to, which integrations are connected, what the plan allows, and what is actually outstanding — so you never propose work whose prerequisites are missing. Read pendingAction and follow it, exactly as you would follow a migration's pendingAction: • CONNECT_SOURCE_CONTROL / CONNECT_DATABASE — nothing can start. Give the user the url and stop; do not propose a migration or a deployment until they have connected it and you have called this tool again. • CHOOSE_PATH — everything required is connected. Staticbot does two different things and the user's goal decides which: start_hosting (deploy the repository, keep building where they build today, nothing about the app's backend changes) and start_migration (move the app's database, auth, storage and functions onto infrastructure they own, leaving the builder's backend behind). ASK which one they want. Do not infer it from the fact that they asked about repositories, and do not default to migration. Each entry in nextActions carries available, blockedBy, blockedReason and the tool that begins it. A blocked entry is still listed on purpose — it is how you tell 'needs one more connection' apart from 'Staticbot cannot do this', and blockedReason is written to be shown to the user verbatim. Contains no secrets.

list_templatesA

List available templates (slim response: id, name, category, repoLink). Use get_template to see full details including config variables. Templates feed both hosting and migration. Reuse an exact repository match when one exists; otherwise create a new template from the repository resolved through list_source_repositories. Ask the user to choose only when multiple existing templates or repositories are plausible — and when two repositories share a name, show which account each is hosted in (sourceLabel) so the choice is meaningful.

get_templateA

Get details of a template including its backend-classified configuration variables. Each entry has key, configured (whether a value is set at all), and sanitized value. Staticbot never returns credential values, so read configured to tell "withheld" apart from "not set". For migrations, follow migrationAction, collectionStage, sensitivity, resolution, integration, and migrationHint; do not infer meaning or safety from prefixes. Include a configOverride only when migrationEditable=true. migrationBackendDerived=true means Staticbot derives the value from target state and user input cannot take precedence. SECURITY_REVIEW means stop and explain the client-exposure finding; REVIEW_CONFIGURATION means the variable needs an explicit template annotation. Never request either as a configOverride. CONFIGURE_INTEGRATION is follow-up work, not a migration-creation input.

create_templateA

Create a new template by scanning a source repository (GitHub or GitLab). Auto-detects platforms, env vars, and builders. Both public and private repositories are supported through the organization's connected Staticbot source-control integration. Before asking the user for a URL, call list_source_repositories and use an unambiguous repository match from the current client/project context, passing that repository's integrationInstanceId as sourceControlIntegrationInstanceId — with several accounts connected, only that one's token can read the repo, and omitting it makes a private repository look missing. If no source-control integration is connected, direct the user to https://app.staticbot.dev/integrations and retry after they connect it. Never claim the repository must be public. Staticbot also classifies the repository's hosting workload; inspect the returned hostingWorkload and isSsr fields instead of choosing AWS or Cloudflare from agent-side heuristics. A template is the shared starting point for BOTH Staticbot paths — hosting the repository and migrating the app off its builder — so creating one does not commit the user to a migration. Use it when no existing template from list_templates matches the repo. The name is optional — if omitted, it's derived from the repo name.

list_stacksA

List all infrastructure stacks. A stack groups one or more templates with a domain assignment. Each stack can have multiple deployments.

get_stackA

Get details of a stack including its templates and config overrides. Every override key is listed; values are returned for location-shaped keys (URLs, regions, names, branches) and "[REDACTED]" for credential-shaped ones.

create_stackA

Create a new infrastructure stack from a template. A stack ties a template to a domain and becomes deployable. Call list_templates first to find the right templateId. Staticbot analyzes the template's repository and owns the hosting decision: static sites route to the supported AWS static target, SSR/full-stack apps route to the supported Cloudflare Workers target. Report the returned hostingWorkload, deploymentTarget, and infrastructureOwnership fields to the user.

Never invent a provider or an account. Cloudflare alone accepts an account-placement default during stack creation because a customer Worker stack pins its connected integration and resolved zone. If the user wants that, call list_cloudflare_hosting_targets, let them choose, then preflight_cloudflare_hosting and pass the preflighted value as cloudflareChoice. Otherwise omit it for Staticbot hosting. For an AWS static site, create the stack first, then call list_aws_hosting_targets with its stackId and pass the selected value to create_deployment as targetAccountId. There is no AWS account field on create_stack.

For templates that use Supabase, pass supabaseIntegrationInstanceId + supabaseProjectRef. Staticbot fills and refreshes the declared Supabase configuration from the connected account; never ask the user for Supabase API keys.

list_deploymentsA

List all deployments. Optionally filter by stackId. Each deployment represents one execution of a stack's infrastructure.

create_deploymentA

Create a new deployment for a stack. This prepares the deployment but does NOT start it — call start_deployment next. Default type is APPLY (creates real resources). Use PLAN for a dry-run preview.

For an AWS-hosted stack, call list_aws_hosting_targets with the stackId first and pass the selected option's exact value as targetAccountId. That value DECIDES infrastructure ownership: the managed value means Staticbot-managed hosting and a customer account value means customer-managed hosting. Never invent an account id or send infrastructureOwnership.

Do not set cloudflareChoice or cloudflareHostname unless the user has chosen to host a Cloudflare Workers app in their OWN Cloudflare account: call list_cloudflare_hosting_targets, let the user pick, then preflight_cloudflare_hosting, and pass that choice plus the hostname. Omit both to use the stack's existing hosting, which is the normal case — Staticbot hosts it.

start_deploymentA

Start a deployment that was created with create_deployment. The deployment must be in CREATED status. Once started, Staticbot provisions the repository-derived target stored on the stack. Poll get_deployment to track progress.

get_deploymentA

Get the status of a deployment and the per-domain DNS state. Poll this for progress. Statuses: CREATED → PENDING → IN_PROGRESS → WAITING → COMPLETED (or FAILED).

Response fields you should always read:

  • status — pipeline state.

  • dns — per-domain DNS state, populated once Terraform emits a state snapshot. Present regardless of status; check it on every poll, not just on WAITING.

  • requiredAction — legacy; only set when status=WAITING and there are records to add. Prefer dns.

For each entry in dns, read action and behave as follows:

  • NO_ACTION — registrar NS already delegate to a zone Staticbot owns; nothing to ask the user. Celebrate.

  • MANUAL_RECORDS_AT_REGISTRAR — present records (cert CNAME + ALIAS/CNAME for the website) to the user, asking them to add them at whatever DNS provider currently serves their domain. Do NOT suggest changing nameservers — Staticbot intentionally does not recommend NS takeover as a default path.

  • OFFER_CLOUDFLARE_PUSH — domain is on Cloudflare and an integration is linked. Offer push_dns_to_cloudflare using this item's exact domainId; obtain authorization before the external DNS write. Manual records at the current provider remain the fallback.

  • OFFER_CLOUDFLARE_CONNECT — domain is on Cloudflare without an integration. Suggest connecting Cloudflare (direct the user to the integrations page) for the smoothest no-NS-change path.

  • REGISTER_DOMAIN_FIRST — domain is not registered. Block and ask the user to register it first.

Other fields per domain:

  • staticbotManaged — true when live registrar NS overlap our recorded Route53 zone NS for this apex. Useful for explaining 'your domain is already pointing at us'.

  • nsPointedAt — AWS_ROUTE53 | CLOUDFLARE | OTHER (where the live NS resolve to).

  • mailRecordsDetected — true when MX/TXT/SRV/CAA records exist on the apex. Treat as a hard block on any advice that involves changing nameservers — doing so would risk breaking the customer's mail.

  • cloudflareLinked — true when the domain is wired to a Cloudflare integration in Staticbot.

  • domainId — Staticbot DNS-domain ID; pass this exact value to push_dns_to_cloudflare.

  • records — flat list of {type, host, value, description} to surface to the user.

The response also includes failureSummary when a worker job is failing or has been retried. Surface its summary; when terminal=true, include the statusUrl so the user can inspect the full failure.

push_dns_to_cloudflareA

Push a deployment's certificate-validation and website-routing DNS records into the customer's linked Cloudflare zone. This is an external DNS write, although it is idempotent and never changes nameservers or mail records. First call get_deployment and select the exact dns item whose action is OFFER_CLOUDFLARE_PUSH; pass the deployment response's id as deploymentId and that DNS item's domainId as domainId. Present the intended action and obtain the user's authorization before calling. Do not infer a domain ID, use this for MANUAL_RECORDS_AT_REGISTRAR, or describe it as DNS delegation. Present the returned message and every per-record error. Manual records at the current provider remain the fallback.

recheck_dns_verificationA

Ask Cloudflare to retry custom-hostname domain-control validation for a Cloudflare Workers deployment, then return refreshed certificate and hostname-routing status. Call this after DNS records were published or when the user explicitly asks to recheck verification. This action does not write DNS records or change nameservers. A null result means the deployment has no applicable Cloudflare custom hostname. Surface verificationErrors and do not report the domain live unless both customHostnameStatus and hostnameStatus are active.

list_aws_hosting_targetsA

Use this when an existing stack's deploymentTarget is AWS_STATIC and you need to choose which AWS account will own its next deployment. Call it with that stack's stackId before create_deployment because managed-account eligibility and the current selection are stack-specific.

Render the response; do not derive or repair it:

  • managed is the Staticbot-hosted option. It can be null; when null, do not offer it.

  • customerOptions contains ready-to-render labels and opaque values for connected customer accounts.

  • notices explains why an option is absent or unusable. Surface every notice verbatim.

  • selectedValue is the stack's current account when stackId was supplied and is suitable as the default selection.

If one usable option exists, use it without asking. If several exist, present them and let the user decide. If none exist, show the notices and do not create a deployment. Pass only a returned option's exact value as create_deployment.targetAccountId. That value decides infrastructure ownership; never invent an account id or send infrastructureOwnership.

list_cloudflare_hosting_targetsA

List the Cloudflare accounts this app can be hosted in: Staticbot's managed account (the default) plus any Cloudflare account the user has connected. Call this before create_stack or create_deployment for a Cloudflare Workers / SSR app whenever the user has a connected Cloudflare account and might want the Worker deployed into it rather than hosted by Staticbot.

Read the response, do not compute from it:

  • managed is the Staticbot-hosted option. It is always present and always valid.

  • customerOptions lists the user's own accounts — each with a ready-to-render label and the value you pass back verbatim. Pass value through unchanged; never construct or edit one.

  • notices explains accounts that could not be offered (a revoked credential, a missing Workers permission). Show these to the user — they are the reason an account is missing from the list.

  • selectedValue / selectedHostname are the defaults when stackId was supplied.

Do not decide for the user. If customerOptionsAvailable is false, do not ask — Staticbot hosting is the only choice. If it is true, present the options (including the managed one) and let the user pick. Deploying into the user's own account means the Worker, its domain and its certificate live in their account, so it is their decision, not an inference from their setup.

Before creating anything with a customer choice, call preflight_cloudflare_hosting — it reports collisions that would otherwise fail the deployment.

preflight_cloudflare_hostingA

Check that a hosting choice and hostname can actually be deployed, before create_stack or create_deployment. Read-only: it never creates, deletes or takes over anything. It answers for the managed choice too, so call it the same way whichever option the user picked.

How to use the result:

  • ok: true — deployable. Report connectionLabel, and hostname / workerName when present. note may add useful context (for example that an apex hostname is supported).

  • ok: false — do not create anything. Show the user blockingMessage verbatim; it names the exact collision and what to fix in Cloudflare. Resolve it with the user, then call this again. warnings are non-blocking (a check that could not be run) — surface them, but they do not stop the deployment.

For a customer choice, hostname must be a domain that already lives in one of that account's zones. An autogenerated Staticbot subdomain cannot be used, and an apex such as example.com is supported. The answer can go stale — permissions and DNS can change — so call it again after any change the user makes, and never treat a previous result as permission.

get_auto_deploy_settingsB

Get the automatic-update flags for a deployment. autoDeployLatestWebsite controls whether a new website template version is deployed automatically; autoDeployLatestInfra is reserved for infrastructure updates.

update_auto_deploy_settingsA

Update automatic-update flags for a deployment. Omitted fields keep their current values. IMPORTANT: Confirm the requested settings with the user before calling this tool.

get_auto_deploy_infoA

Check whether Automatic Updates are available for a deployment and inspect its GitHub webhook state. Returns fields including available, webhookConfigured, canSetupWebhook, and isGithubRepo. Automatic Updates do not apply to preview stacks.

list_rollback_versionsA

List the recent commit-pinned website template versions that are valid rollback targets for a deployment, newest first. Use only a returned templateId with rollback_website; do not infer a target from a commit SHA or version label.

rollback_websiteA

Roll a static website back to a specific commit-pinned template version. Call list_rollback_versions first. IMPORTANT: Present the exact returned target version and commit to the user and get explicit confirmation before calling this tool. Never supply an inferred or unverified template ID. Returns the worker job ID; poll get_deployment to track progress.

redeploy_websiteA

Rebuild and redeploy the static website component. By default it redeploys the currently pinned template version; set useLatest=true to pull the latest version first. Returns the worker job ID; poll get_deployment to track progress.

list_migrationsA

List all migrations. Optionally filter by status. Migrations orchestrate moving a full project (database, auth, storage, edge functions) from a source platform (Lovable, Bolt, Firebase, Base44) to target Supabase infrastructure.

get_migrationA

Get the current status and phase breakdown of a migration. The response includes all migration phases (Discovery, DB Migration, Data Import, Edge Functions, Storage Buckets, Auth Config, Backend Switchover, Preview & Verify, Continuous Sync, Download, Follow-ups) with their individual statuses, plus sourceType (LOVABLE_SUPABASE / BOLT_SUPABASE / FIREBASE / BASE44_SUPABASE / BASE44_NATIVE), targetType (SUPABASE_CLOUD / SUPABASE_SELF_HOSTED), and packageAvailable (true once the downloadable zip is ready — fetch via download_package).

Self-navigating: the response includes a pendingAction field that tells you the next action to take. New pre-flight states are explicit: REVIEW_TARGET_CONFLICTS → present targetConflictReport, then either call clean_migration_target after destructive confirmation or call confirm_migration only after the user explicitly declines cleanup; WAIT_FOR_TARGET_CLEANUP → poll; RETRY_TARGET_CLEANUP → call retry_migration_job (never skip cleanup); CHOOSE_MIGRATION_STRATEGY → present preFlightGate.actions and consequences, then call confirm_migration with the selected gateChoice. RESUME → the migration is paused and waiting on a person: tell the user what it is waiting for and call resume_migration once they agree (never resume a migration they paused without asking). PROVIDE_BASE44_SECRETS → this gate takes the values of the customer's own third-party credentials, so it is resolved in a browser and NOT by a tool: endpoint is null, url is the migration page, and detail is written to be shown to the user verbatim. Give them the URL, keep polling, and do not ask for the secret values in the conversation — no tool accepts them and the API refuses them over this connection. Other types: CONFIRM, RETRY_OR_SKIP, RESOLVE_SCHEMA_GAP, CHOOSE_BACKEND_SWITCHOVER, CHOOSE_DATA_IMPORT_METHOD, CHOOSE_FRONTEND_DEPLOY, COMPLETE_MANUAL_JOB. When pendingAction is null, poll only while the status is flowing.

The response exposes preFlightGate with backend-authored labels, consequences, export files, and the accepted choice IDs. It also exposes targetConflictReport with conflicting objects, cleanup scopes, confirmationProjectRef, and endpoint paths. Present these fields instead of inventing or defaulting a choice.

The response also includes failureBanner with categorised error info (category, title, body, severity, actionable, followupNote, retryable) when a job has a categorised failure. Use this to present richer error feedback. When retryable=false, prefer skip_migration_job or an AI-assisted fix over repeating deterministic SQL that will fail again — but check the job's skipGuard first, because a guarded job breaks the migration if skipped and needs the user's explicit approval; retryable=null means the cause may be environmental.

The support field reports whether this migration is SELF_SERVICE, SUPPORTED, or SUPPORT_WINDOW_ENDED, together with available human-support contact details. consultationUrl is returned only for SUPPORTED migrations and books the optional consultation already included in that migration's existing support entitlement; it is never a purchase, checkout, or upgrade route. When support is active, use those routes for human escalation instead of implying the MCP itself provides human support. Purchase and operator-grant actions are intentionally unavailable through MCP.

Polling Phase 7 (Backend Switchover): the response also includes previewDeployment (null until Phase 7 provisions one) with its own independent status. Important: the migration itself can be marked COMPLETED while previewDeployment.status is still IN_PROGRESS — the preview Terraform applies in the background. When babysitting a migration toward 'live preview ready', also poll previewDeployment.status until it reaches COMPLETED. Treat anything other than COMPLETED/FAILED/ABORTED/DESTROYED/CLEANED_UP as 'still progressing'. Use previewDeployment.createdAt to compute elapsed time so you can give the user a sense of progress without spamming this endpoint — once-every-5s is plenty.

confirm_migrationA

Approve a migration after discovery, or resolve a pre-flight migration-strategy gate. Before calling, get the migration and present the discovery inventory. If preFlightGate is non-null, present every enabled action and its consequence verbatim, obtain the user's explicit choice, and pass that exact action ID as gateChoice. For USE_OFFICIAL_EXPORT, gateSelection may select an offered export file path; omit it to use the newest. Never infer a gate choice or bypass REVIEW_TARGET_CONFLICTS without discussing the detected target objects.

get_clean_target_planA

Inspect a destructive target cleanup BEFORE asking the user to authorize it. Always call this immediately before presenting cleanup, and never rely on the targetConflictReport from an earlier get_migration: that is a snapshot taken at discovery, while this is the current state of the target. Returns available (cleanup is only possible before execution starts, and only for Supabase Cloud targets) with unavailableReason when it is not, the exact confirmationProjectRef the user must approve, countsAvailable plus live per-scope rows describing what each of DATABASE, STORAGE and PROJECT would remove, and the cleanupEndpoint. Present the rows and the project ref verbatim, get explicit approval for one exact scope, then pass that ref to clean_migration_target unchanged. If available is false, tell the user the reason — do not call clean_migration_target to find out.

clean_migration_targetA

Destructively clean conflicting objects from a Supabase Cloud migration target before execution starts. Call get_clean_target_plan first and take confirmProjectRef from its response — it reports the live state and whether cleanup is even available. DATABASE deletes user-created database objects, Supabase migration history, and existing authentication users/sessions while preserving Storage. STORAGE empties and deletes every Storage bucket and file while preserving database/auth data. PROJECT performs both cleanups. This cannot be undone. Before calling, get the migration, present the exact scope consequences and targetConflictReport.confirmationProjectRef, and obtain explicit user confirmation for that exact project and scope. Copy the returned confirmationProjectRef into confirmProjectRef; never guess it. The migration remains paused after cleanup.

resume_migrationA

Resume a migration that is PAUSED_BY_USER or PAUSED_FOR_USER_ACTION. Use this after the user has completed the required manual step (e.g. DNS configuration, backend switchover review).

pause_migrationA

Pause a running migration. The current in-progress job will finish, but no new jobs will be started. Use resume_migration to continue later.

get_migration_jobsA

Get all jobs for a migration. Jobs are the individual work units within each phase (e.g. 'migrate_schema', 'import_data', 'deploy_edge_function_X'). Use this to understand what's happening at a granular level, diagnose failures, or find a jobId for retry/skip. For IN_PROGRESS long-running jobs (e.g. CALL_EXPORT_TO_TARGET on multi-table sources), each job's progressMessage field carries a human-readable subtitle like "Exporting table 'startups' (8/10)" so you can report concrete progress without waiting for completion. Each job also carries skipGuard: null means it is freely skippable, non-null means skipping it breaks the migration. Read it before offering a skip and relay consequence and alternative to the user rather than discovering the gate by triggering a 400.

retry_migration_jobA

Retry a failed migration job. The job must be in FAILED status. It will be reset to READY and picked up by the worker again. Use get_migration_jobs first to find the failed job's ID and error message.

skip_migration_jobA

Skip a migration job that is blocking progress. The job will be marked as SKIPPED and dependent jobs will proceed. Use this when a job is non-critical (e.g. an edge function that can be deployed manually later) or when retry won't help. FIRST check the job's skipGuard from get_migration_jobs. When it is non-null, skipping breaks the rest of the migration — present skipGuard.consequence and skipGuard.alternative to the user verbatim, get explicit approval, then call again with acknowledged=true. The jobs that deploy the Staticbot export function to the source project (MANUAL_SYNC_LOVABLE, MANUAL_SYNC_BASE44, LOVABLE_MCP_SYNC, AUTO_DEPLOY_EXPORT_FUNCTION) are the main case: that function is the only way to read the customer's data, so skipping it makes the data import fail with "function not found". The API re-checks whether the function is live and returns 400 if it is not. Never set acknowledged just to clear that 400.

get_migration_deploymentsA

List all AWS deployments associated with a migration's infrastructure stack. Migrations that deploy to AWS (self-hosted Supabase) create deployments for the infrastructure provisioning.

create_migrationA

Create a new migration. Starts a multi-phase pipeline: Discovery → DB Migration → Data Import → Edge Functions → Storage Buckets → Auth Config → Backend Switchover → Preview & Verify → Continuous Sync → Download → Follow-ups.

Two delivery modes via targetType: • SUPABASE_CLOUD (default) — Staticbot applies the migration end-to-end against a managed Supabase project you own. Requires targetSupabaseProjectRef plus the Supabase integration instance. • SUPABASE_SELF_HOSTED — Staticbot runs discovery + data export, then produces a downloadable AES-256-encrypted zip the user applies to their self-hosted Supabase (typically with Claude Code following the bundled CLAUDE.md). Skip target* params; once the GENERATE_PACKAGE job completes, call download_package to fetch the zip + password.

Source platforms via sourceType: • LOVABLE_SUPABASE (default) — Lovable-built apps on Supabase. • BOLT_SUPABASE — Bolt.new apps on Supabase (Phase 3 Lovable-specific steps are adjusted). • FIREBASE — supported by Staticbot, but NOT creatable through this connection: it needs a Google service-account private key, which no tool here accepts. Give the user https://app.staticbot.dev/migrations/new/firebase and stop. Never ask them for the key in the conversation and never accept it if offered. • BASE44_SUPABASE — Base44 apps backed by Supabase. If repository discovery cannot resolve the source, pass sourceDeployedUrl and Staticbot will inspect the deployed app server-side. Backend switchover updates Base44 platform secrets (not GitHub env vars). • BASE44_NATIVE — Base44 apps using @base44/sdk against Base44's managed backend (no source Supabase). Requires sourceIntegrationInstanceId (the Base44 integration) AND base44AppId (which app in it to migrate). Discovery hits Base44's REST API, DDL is synthesised from entity schemas, and data is imported directly.

BEFORE calling this tool, confirm the user actually wants a migration rather than hosting — get_account_status describes both — then follow these steps to gather the required parameters:

  1. Call get_account_status. If its pendingAction is CONNECT_SOURCE_CONTROL or CONNECT_DATABASE, stop and give the user the URL — a migration cannot be created without them. Then identify the source platform from the user's request and client context.

  2. Call list_source_repositories (no arguments) before asking for any repository URL, and match the current project/repository context against fullName or webUrl. It covers every connected GitHub and GitLab account, and private repositories are supported. Use one unambiguous match directly; when several are plausible, present them with their sourceLabel — the account each is hosted in — and let the user choose. Carry the chosen repository's integrationInstanceId into create_template. If the listing has no sources, direct the user to https://app.staticbot.dev/integrations to connect an account, then retry. Never claim that Staticbot requires a public repository.

  3. Ask the user whether the target is managed Supabase (SUPABASE_CLOUD) or their own self-hosted install (SUPABASE_SELF_HOSTED).

  4. From list_integration_instances, use type='supabase' as supabaseIntegrationInstanceId, the selected type='github' instance as githubIntegrationInstanceId, and type='base44' as sourceIntegrationInstanceId (for BASE44_NATIVE). For BASE44_NATIVE also call list_base44_apps with that Base44 instance and pass the chosen app's id as base44AppId — one Base44 token covers every app in the workspace, so the integration alone does not say which app to migrate. Ask the user which app when more than one comes back; never guess.

  5. Source Supabase metadata is discovered by Staticbot. For a BASE44_SUPABASE app whose repository contains placeholders, provide its deployed *.base44.app URL as sourceDeployedUrl. Never ask the user for Supabase API keys.

  6. For SUPABASE_CLOUD only: call list_supabase_projects with the Supabase integration instance. If the user wants an existing target, ask them to choose an ACTIVE project. If they want a new target, call list_supabase_organizations and list_supabase_regions, obtain explicit confirmation of the exact project name, organization, and region, then call create_supabase_project. Poll get_supabase_project_status until healthy=true before using its id as targetSupabaseProjectRef. Never create a second project merely because provisioning is slow or a status poll fails. Skip this step for SUPABASE_SELF_HOSTED.

  7. For templateId: either ask the user to pick from list_templates, or create a new template from the resolved repository using create_template.

IMPORTANT: Source and target Supabase projects must be different. Staticbot validates this after source discovery; if it reports a match, ask the user to choose another target.

After creation, the migration starts with a DISCOVERY job. Once discovery completes, it pauses (PAUSED_FOR_APPROVAL) — present the inventory to the user and call confirm_migration if they approve.

download_packageA

Fetch the downloadable migration package for a migration. Returns a presigned URL to the AES-256-encrypted zip plus the password to extract it.

Availability: • SUPABASE_SELF_HOSTED: this is the delivery mechanism. The user unzips with the password, runs Claude Code against the folder, and follows the bundled CLAUDE.md to apply the migration to their self-hosted Supabase. • SUPABASE_CLOUD: this is a portable backup of the applied migration (re-applicable to any Supabase later).

The package is ready once the GENERATE_PACKAGE job is COMPLETED — check via get_migration_jobs first. Calling before then returns 404. The download URL is time-limited; the password is shown only here, never logged.

complete_migration_jobA

Complete a manual job that requires user action. Used for jobs with type MANUAL_SYNC_LOVABLE, MANUAL_SYNC_BASE44, MANUAL_EXPORT_DATA, MANUAL_IMPORT_DATA, etc. The job must be in READY status. For MANUAL_SYNC_LOVABLE / MANUAL_SYNC_BASE44 you normally do NOT need this tool: ask the user to open their Lovable project and paste 'deploy staticbot edge function' into the Lovable AI chat (Base44: sync the project from GitHub). Staticbot detects the deployed function and completes the step by itself within about 15 seconds — poll get_migration, or call validate_function_url to check immediately (a reachable function completes the step in that same call). Use this tool for a sync step only when the function URL differs from the one in the job's inputData; calling it on a sync step that already completed returns ok. Format: https://{projectRef}.supabase.co/functions/v1/{functionName}. For MANUAL_REVIEW_SCHEMA (Firebase migrations): show the proposed DDL from the job's inputData, have the user review it, then pass their approved DDL as approvedSql — it is injected into the dependent APPLY_SQL job. Completing without approvedSql leaves APPLY_SQL with no schema to apply.

choose_data_import_methodA

Choose how to import data in Phase 3. Call this when a MANUAL_CHOOSE_DATA_IMPORT_METHOD job is READY. IMPORTANT: You MUST present these options to the user and ask them to choose before calling this tool:

  1. 'automated' (recommended) — Staticbot deploys an edge function, exports data, imports to target, copies storage, migrates secrets/cron/auth. Fully automated.

  2. 'manual' — User exports data from Lovable and imports via Supabase SQL editor themselves. Do NOT pick an option without asking the user first.

When the source check (PROBE_SOURCE) already deployed and verified the export function, Staticbot selects 'automated' by itself and get_migration never offers this gate as a pendingAction — only call this tool when pendingAction.type is CHOOSE_DATA_IMPORT_METHOD. If the gate was closed in the meantime, the call returns ok when your method matches the recorded one and HTTP 409 when it differs; the choice cannot be changed, so re-fetch the migration and follow its pendingAction instead of retrying.

choose_backend_switchoverA

Choose how to handle backend switchover in Phase 7. Call when MANUAL_CHOOSE_BACKEND_SWITCHOVER is READY. IMPORTANT: You MUST present these options to the user and ask them to choose before calling this tool. Four choice values are supported (use the literal string in your choice arg):

  1. 'switch-fully-to-supabase' (method='auto') — Staticbot opens a GitHub PR that replaces ALL Supabase env vars (URL, anon key) in the repo with the migrated target's values. After the PR is merged, BOTH the source platform's previews AND production use the new Supabase. This is the 'I'm leaving Lovable/Base44 for good' choice.

  2. 'source-preview-supabase-prod' (method='skip') — Production deployments read from the migrated Supabase backend; the source platform's preview environment keeps using its own managed Supabase as before. Good for gradual rollout where you keep developing in Lovable/Base44 but ship from the new Supabase. (Only shown to LOVABLE_SUPABASE and BASE44_SUPABASE customers — Bolt previews use WebContainer, not a separately-hosted Supabase.)

  3. 'source-primary-supabase-backup' (method='skip') — Nothing changes for now. The live app stays on the source platform's current setup; the migrated Supabase project is parked as a fallback the user can switch to later. (Same platform gating as #2.)

  4. 'handle-myself' (method='skip') — No automated changes. The user will update environment variables themselves whenever they're ready.

Historical aliases: the old lovable-preview-supabase-prod and lovable-primary-supabase-backup IDs are still accepted by the backend (it stores choice as an opaque label). Prefer the source-* names for new calls so analytics filters reflect the platform-agnostic semantic.

Platform-specific job creation under method='auto': • BASE44_SUPABASE — creates MANUAL_SWITCH_BASE44_SECRETS jobs (Base44 manages env vars on its platform, not in GitHub). The user updates secrets in Base44's UI. • BASE44_NATIVE — Phase 7 is fully automated (installs @bitfiction/base44-supabase-shim into the repo). No manual CHOOSE gate. • All other source types — rewrites env vars in the GitHub repo directly. Do NOT pick an option without asking the user first.

choose_frontend_deployA

Choose how to handle frontend deployment in Phase 8 (Next Steps). Call when MANUAL_CHOOSE_FRONTEND_DEPLOY is READY. IMPORTANT: You MUST present these options to the user and ask them to choose before calling this tool:

  1. 'continuous-sync' (method='continuous-sync', choice='setup-continuous-sync') — Sets up automatic GitHub-to-target sync. Every push to the repo automatically deploys to the new Supabase. Recommended for most users.

  2. 'staticbot' (method='staticbot', choice='deploy-with-staticbot') — Deploy the frontend with Staticbot. Staticbot analyzes the repository and selects the supported target and ownership model; do not promise AWS or Cloudflare before that analysis.

  3. 'skip' (method='skip') — Skip frontend deployment entirely. Do NOT pick an option without asking the user first.

validate_function_urlA

Check that the Staticbot export edge function is reachable, and COMPLETE its sync step when it is. Use after the user pasted 'deploy staticbot edge function' into the Lovable AI chat (Base44: synced from GitHub). The function URL is in the MANUAL_SYNC_LOVABLE / MANUAL_SYNC_BASE44 job's inputData (function_url), or derive it as https://{sourceProjectRef}.supabase.co/functions/v1/{functionName}. Returns {status: 'ok'|'error', message, completed}. completed=true means the step is done — by this call or because Staticbot already detected the deployment — so do NOT call complete_migration_job afterwards; re-fetch get_migration and follow its pendingAction. On status 'error' the function is not live yet: Staticbot keeps checking by itself, so waiting and polling get_migration every 15-30 seconds is enough.

list_integration_instancesA

List all connected integrations for the organization. Each instance has a 'type' field identifying whether it is 'supabase', 'github', 'base44', etc. Use the instance with type='supabase' as supabaseIntegrationInstanceId, type='github' as githubIntegrationInstanceId, and type='base44' as sourceIntegrationInstanceId (for BASE44_NATIVE migrations) when calling create_migration. To resolve a repository, call list_source_repositories instead — it covers every connected source-control account in one call and reports which account each repository is hosted in. Use this tool for the supabase/base44 instance IDs, and to check whether any source-control account is connected at all.

list_source_repositoriesA

List all public and private repositories accessible through the organization's connected Staticbot source-control integrations — GitHub and GitLab. Call this whenever a workflow needs a repository, with NO arguments: it covers every connected account in one call. An organization can connect several accounts on the same provider, and passing one instance ID narrows the listing to that account, which hides the others' repositories — only do that when the user has already chosen an account. The response is { sources[], repositories[] }. Each repository has fullName, webUrl, private, description, defaultBranch, plus provider, integrationInstanceId and sourceLabel — the account it is hosted in, e.g. "GitHub · octocat". Match the current client/project context against fullName or webUrl. If there is one unambiguous match, use its webUrl directly without asking the user to repeat it. When several are plausible — including the same name in two accounts — present the candidates WITH their sourceLabel and ask the user to choose, because the repositories are different. Listing repositories is not itself a decision to migrate: carry the chosen repository into whichever path get_account_status reported (start_hosting or start_migration), and ask the user which if they have not said. Whichever it is, pass the repository's integrationInstanceId back as sourceControlIntegrationInstanceId when calling create_template, so it is read with the account that can actually see it. A sources[] entry with an unavailableReason means that account's repositories are missing from the list and the user has to act — report it rather than concluding the repository does not exist. If there are no sources at all, direct the user to https://app.staticbot.dev/integrations to connect an account and then retry. Never claim that Staticbot requires a public repository.

list_github_repositoriesA

Deprecated — use list_source_repositories, which serves GitHub and GitLab through one tool. Lists the public and private GitHub repositories accessible through a connected Staticbot GitHub integration: call list_integration_instances first, then pass the selected GitHub instance ID here. Returns a flat array whose repository URL field is htmlUrl. Never claim that Staticbot requires a public repository.

list_supabase_projectsA

List all Supabase projects accessible through a connected Supabase integration instance. Returns project name, reference ID, region, and status. Use the project's id field as targetSupabaseProjectRef when creating a migration. Only ACTIVE_HEALTHY projects can be used as targets. Present the list and let the user choose an existing target, or offer to create a customer-owned project with create_supabase_project.

list_supabase_organizationsA

List the Supabase organizations accessible through a connected Supabase integration instance. Call this before create_supabase_project and present the organization names to the user. Use the selected organization's id unchanged as organizationId. Do not guess an organization when more than one is available.

list_supabase_regionsA

List the regions Staticbot supports when creating a customer-owned Supabase project. Call this before create_supabase_project and use the user's selected region id unchanged. When the user has not expressed a location preference, explain the available choices rather than silently choosing one.

create_supabase_projectA

Create a new project directly inside the customer's selected Supabase organization. This changes an external account, consumes a project slot, and may affect the customer's Supabase billing. Before calling, use list_supabase_organizations and list_supabase_regions, present the exact project name, organization, and region, and obtain the user's explicit confirmation. Staticbot generates and encrypts the database password; it is intentionally never returned through MCP. Provisioning is asynchronous: after creation, call get_supabase_project_status with the returned id until healthy=true. Do not call create_supabase_project again because provisioning is slow or a poll fails.

get_supabase_project_statusA

Read the lifecycle state of a Supabase project created or selected through Staticbot. After create_supabase_project, poll this tool until healthy=true before using the project as a migration target. A transitioning state means wait; it is not permission to create another project. Stop and report the returned state if unavailable=true.

list_base44_appsA

List the Base44 apps a connected Base44 integration can migrate. Call this before create_migration for any BASE44_NATIVE migration: a Base44 personal access token is scoped to a WORKSPACE and reaches every app in it, so the integration alone does not identify which app to migrate. Pass the chosen app's id as create_migration's base44AppId. Ask the user which app when more than one is returned — never guess, and never assume the first or the most recently edited one is meant. Migrating the wrong app is not cheaply reversible. An empty list means the token cannot see any apps: usually a token scoped to a single app that has since been deleted, or one created with Access limited to one app. A 400 means the integration still holds a legacy Base44 account API key, which cannot enumerate apps and stops working entirely on 2026-10-15 — tell the user to reconnect Base44 with a personal access token. Contains no secrets. NEVER ask the user to paste their Base44 personal access token into the conversation, and never accept one if they offer it — no Staticbot tool takes it, and there is nowhere for it to go. It is a long-lived, workspace-wide, full-access credential that can read and change every app in the workspace. A token pasted into chat is sent to the model, kept in the conversation transcript, and may be retained in client logs. The only correct handling is the browser: send the user to the integrations page and have them enter it there. If no Base44 integration exists yet, this tool and create_migration both return the exact connect URL in their error — give the user that URL verbatim.

list_connected_projectsA

List all connected projects. Connected projects sync changes from a GitHub repo to a target Supabase instance and optional Staticbot deployment. After a migration completes, enable continuous sync to keep the target up-to-date with Lovable, Bolt, Base44, or Firebase changes.

get_connected_projectA

Get details of a connected project including sync mode, webhook status, linked migration, and deployment.

list_connected_project_previewsA

List every tracked branch preview for a connected project, including the preview deployment ID, raw deployment status, preview URL, and dashboard status URL. Always use deploymentStatus to distinguish builds in progress from FAILED, ABORTED, or COMPLETED previews; hasPreview only means preview resources exist.

trigger_syncA

Trigger a manual sync for a connected project. Detects changes since the last sync (new database migrations, edge function updates, frontend changes) and applies them to the target Supabase instance and the project's Staticbot-selected deployment target.

list_sync_runsA

List sync run history for a connected project. Each sync run represents one execution of the sync pipeline — applying migrations, deploying edge functions, and rebuilding the frontend.

get_sync_runA

Get details of a specific sync run including status, source and target repository versions, summary of changes, and error information. Use the returned version fields when explaining or reviewing the diff; do not infer them. Statuses: PENDING → IN_PROGRESS → COMPLETED/FAILED. Destructive migrations cause PAUSED_FOR_REVIEW.

get_sync_run_jobsA

Get all jobs for a sync run. Jobs are the individual work units (e.g. apply_migration, deploy_edge_function, frontend_deploy). Use this to diagnose sync failures at the job level.

confirm_sync_runA

Confirm a sync run that is PAUSED_FOR_REVIEW. Destructive database migrations (DROP TABLE, ALTER COLUMN) pause the sync for review before applying. Optionally skip the destructive migrations instead of applying them. WARNING: skipDestructive is PERMANENT, not a deferral. The run still completes, so the next sync diffs from this run's commit and the skipped migrations are never re-applied — they stay in the repo, absent from the live database, and nothing reports the divergence. Later migrations that assume the change will fail with errors that look unrelated. The API returns 400 unless acknowledged is true; show the user the returned consequence and get explicit approval, then re-send. Never set acknowledged just to clear the error.

retry_sync_runA

Retry a connected-project sync run in FAILED status. Resets its failed jobs to PENDING and reopens the run. Use get_sync_run and get_sync_run_jobs first to explain the failure to the user.

skip_sync_runA

Skip all failed jobs in a connected-project sync run, marking them completed with skipped=true. The run must be FAILED. WARNING: this is PERMANENT, not a deferral. The run completes, so the next sync diffs from this run's commit and the skipped migrations are never re-detected — they stay in the repo, absent from the live database, and nothing reports the divergence afterwards. Prefer retry_sync_run: most sync failures are transient (expired token, upstream 5xx, timeout), and re-applying a migration that already landed is safe — it is detected as already-existing rather than failing. The API returns 400 unless acknowledged is true; show the user the returned consequence and get explicit approval, then re-send. Never set acknowledged just to clear the error.

get_sync_schema_gapsA

List SQL migrations that continuous sync was asked to apply to this project's live database and never applied — a run failed and was never retried, or the work was skipped — where the diff window has since moved past them, so no future sync will re-offer them. Each entry means the file exists in the repo and is missing from the database. An empty list is the healthy case. Report these to the user; do NOT try to re-apply them automatically — replaying months-old DDL against a live database is the user's decision.

set_connected_project_sync_modeA

Change a connected project's continuous-sync mode. AUTOMATIC syncs every push (and requires a Supabase backend), MANUAL syncs only when trigger_sync is called, PAUSED ignores pushes, and ARCHIVED stops syncing. IMPORTANT: Confirm the new mode with the user before calling this tool.

create_migration_previewA

Trigger (or retrieve) a preview deployment for a migration. The preview builds the migrated app on Staticbot's infrastructure so the customer can verify it works before finalising backend switchover. Optional mode: 'light' (fast, single SOFTWARE job) or 'full'.

resolve_schema_gapA

Resolve a MANUAL_REVIEW_SCHEMA_GAP gate. IMPORTANT: You MUST present these options to the user and ask them to choose before calling:

  1. 'recheck' — Re-check the source schema for drift.

  2. 'abort' — Skip the migration. Do NOT pick an option without asking the user first.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

A3.9/5.0

Scored across 63 tools

Disambiguation4/5

Almost every tool targets a distinct resource and action, and the descriptions are detailed enough to separate similar workflows. A few pairs could still be confused, though: get_deployment vs get_migration_deployments, get_auto_deploy_settings vs get_auto_deploy_info, and the deprecated list_github_repositories duplicating list_source_repositories.

Naming Consistency5/5

All tool names follow a consistent snake_case verb_noun pattern, such as list_migrations, create_deployment, retry_sync_run, and choose_frontend_deploy. Even the multi-word actions like push_dns_to_cloudflare and preflight_cloudflare_hosting fit the same predictable style, with no mixed casing or random verb choices.

Tool Count2/5

63 tools is far above the 25+ threshold and would overwhelm an agent even with good organization. The breadth is partly justified by the platform's dual hosting/migration scope, but this surface would be more appropriate split into separate servers for hosting, migrations, sync, and infrastructure management.

Completeness3/5

The core migration, deployment, and sync workflows are deeply covered with create/get/confirm/retry/skip/preview/download operations. However, there are notable lifecycle gaps: no delete or cancel tools for stacks, deployments, templates, migrations, or connected projects, and update operations are limited to auto-deploy settings and sync mode.

Maintenance

ActivityActive
ResponsivenessNo issues