Skip to main content
Glama
bitfiction
by bitfiction

create_migration

Creates an end-to-end migration from Lovable, Bolt, Base44, or Firebase to Supabase, handling discovery, database, data, storage, auth, and backend switchover.

Instructions

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.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
nameYesHuman-readable name for this migration
sourceTypeNoSource platform. Defaults to LOVABLE_SUPABASE.
targetTypeNoTarget delivery mode. SUPABASE_CLOUD (default) for managed Supabase; SUPABASE_SELF_HOSTED produces a downloadable package instead of applying to a target project.
templateIdNoTemplate ID for the target infrastructure (from list_templates). Required for every source type reachable from here.
base44AppIdNoBase44 app id (24-char hex) to migrate, from list_base44_apps. Required for BASE44_NATIVE: a Base44 personal access token is scoped to a workspace and reaches every app in it, so the integration does not identify the app. Omit for other source types.
descriptionNoOptional human-readable migration description
packageOptionsNoOptional self-hosted package build options for BASE44_NATIVE migrations.
configOverridesNoOptional non-secret creation-time values. Call get_template and include only keys where the backend reports migrationEditable=true and migrationAction is REQUIRED_INPUT or OPTIONAL_OVERRIDE. Never send CONFIGURE_INTEGRATION, SECURITY_REVIEW, or migrationBackendDerived entries. Staticbot derives target aliases from the selected target, and connected integrations or later lifecycle steps handle credentials. Secret-looking keys are REJECTED, not ignored — this connection cannot carry credential values.
targetSchemaNameNoOptional target Postgres schema name
sourceDeployedUrlNoDeployed *.base44.app URL used only for legacy BASE44_SUPABASE source discovery. Staticbot extracts source metadata server-side and never returns keys.
targetSupabaseProjectRefNoTarget Supabase project reference (the subdomain part of the URL). Required for SUPABASE_CLOUD; omit for SUPABASE_SELF_HOSTED.
githubIntegrationInstanceIdNoGitHub integration instance ID for repo access
sourceIntegrationInstanceIdNoSource integration instance ID. Required for BASE44_NATIVE (the Base44 integration from list_integration_instances). Omit for other source types.
supabaseIntegrationInstanceIdNoSupabase integration instance ID (from list_integration_instances). Required for SUPABASE_CLOUD; omit for SUPABASE_SELF_HOSTED.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYesParsed JSON response from the Staticbot public API

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv1.8.1

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only say readOnlyHint=false, openWorldHint=false, destructiveHint=false, which is minimal. The description compensates by disclosing the multi-phase pipeline, the pause after DISCOVERY (PAUSED_FOR_APPROVAL), the requirement that source and target Supabase projects must differ, and the fact that FIREBASE cannot be created through this connection. It also warns that secret-looking configOverrides keys are REJECTED, not ignored. It does not explicitly state that the tool is non-destructive, but the annotations already cover that; the description adds substantial behavioral context beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long, but every section earns its place: the pipeline overview, delivery modes, source platform matrix, pre-call workflow, and post-creation behavior are all necessary for correct invocation. The numbered steps and bolded mode names make it scannable. It loses one point because the length is substantial and some information (e.g., the full pipeline list) could be condensed without losing meaning, but it is well-structured and front-loaded with the most important facts.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (14 parameters, 5 source types, 2 target modes, multi-phase pipeline), the description is remarkably complete. It covers prerequisites, parameter sourcing, error/stop conditions, the FIREBASE exclusion, the source/target project difference validation, and the post-creation pause. The output schema exists, so return values need not be described. An agent has everything needed to invoke this tool correctly and to route the user appropriately.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds meaningful semantics beyond the schema: it explains when to omit target* params (SUPABASE_SELF_HOSTED), when base44AppId is required and why (a Base44 token covers every app in the workspace), and when sourceDeployedUrl is needed (legacy BASE44_SUPABASE with placeholders). It also clarifies that templateId is required for every source type reachable from here, which is not obvious from the schema alone. This pushes it above baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a clear verb and resource ('Create a new migration') and immediately distinguishes the tool from siblings by outlining the multi-phase pipeline and the two delivery modes. It also names the source platforms it supports and explicitly says FIREBASE is NOT creatable through this connection, which prevents a wrong invocation. This is a specific, well-scoped definition that an agent can act on without ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides an explicit, numbered pre-call workflow: call get_account_status first, stop if pendingAction is CONNECT_SOURCE_CONTROL or CONNECT_DATABASE, use list_source_repositories before asking for a repository URL, and choose between SUPABASE_CLOUD and SUPABASE_SELF_HOSTED. It also names alternatives (list_supabase_projects, list_supabase_organizations, create_supabase_project, list_templates, create_template) and gives clear conditions for when to use each. This is exemplary usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.