MainSDK
Search⌘K
Interfaces

Developer experience

Adopt an existing app

adopt

Bring a Next.js or Node app, including one from Lovable, Bolt or v0, onto MainSDK one module and one pull request at a time, with its behaviour locked first.

Building for 0.5ships as a beta APIPhase 1 · Core, public betaSpec migration-skillFree in your app, Apache-2.0

Status Status is where the work is: Planned (in a milestone, not started), Building (tickets in progress), Preview (usable, may change), then the stability it ships at.

Stability The promise an interface ships with.

  • Stable Follows semantic versioning; breaking changes need a new major, 12 months of overlap and a codemod.
  • Beta Usable in production; may change before it becomes stable.
  • Experimental May change or go away; needs an explicit opt-in in main.yaml.
Stability levels
Updated 2026-10-28

mainsdk adopt moves an existing app onto MainSDK without a rewrite. It scans the app, ranks the gaps, locks the flows that must keep working, then changes one module per branch.

At a glance

Calls

  • mainsdk adopt scan
  • mainsdk adopt report
  • mainsdk adopt lock
  • mainsdk adopt next
  • mainsdk adopt finish

Guarantees

Whatever the driver.

  • The scan is deterministic and changes no code; it writes main.yaml only
  • What the app already runs is kept and tagged, never replaced
  • Nothing changes until the key flows are locked
  • Each module is one branch that passes check and every locked flow; a failed step keeps its branch and leaves the default branch untouched
  • Runs fully locally and sends nothing

Drivers

1 drivers. Select one to see its line in main.yaml.

main.yamlBuilt in (reads files, runs git) (default)
adopt:
  driver: builtin

Change this one line to swap providers; your calls stay the same.Built-in and local drivers integration

Codes

CodeWhere it appearsMeaning
MAIN-ADOPT-0002Checkmainsdk check, before deployThe stack is not Next.js or Node; adopt stops and changes nothing
MAIN-ADOPT-0003Checkmainsdk check, before deployA route changes or reads data and never checks who is calling (access gap)
MAIN-ADOPT-0004Checkmainsdk check, before deployThe browser queries the database directly, so row rules are the only protection (data gap)
MAIN-ADOPT-0007Checkmainsdk check, before deployA call still sits behind an interface's raw() escape hatch; listed by finish with file and line
MAIN-ADOPT-0001RuntimeError responses and logsadopt next before key flows are locked
MAIN-ADOPT-0006RuntimeError responses and logsThere is nothing to migrate in the module, or it is not a module (secrets, auth, data, other)
MAIN-ADOPT-0008RuntimeError responses and logsThe working tree has uncommitted changes; a module step starts from a clean tree
MAIN-ADOPT-0009RuntimeError responses and logsNo sign-in or checkout flow was found to lock, or a named flow points at text that is not there
MAIN-ADOPT-0010RuntimeError responses and logsA module step is still open, or verify ran with none open
MAIN-ADOPT-0012RuntimeError responses and logsThe folder is not a git repository, or the module branch could not be created
MAIN-ADOPT-0013RuntimeError responses and logsThe name is not an adopt tool, or not an agent adopt writes a skill for

Features

Nothing here has shipped yet. Each feature lands in its phase; the spec ticket builds it.

FeaturePhaseMilestoneSpec ticket
Deterministic scan that keeps what you already runPhase 10.5migration-skill#scan
Gap report in plain languagePhase 10.5migration-skill#gap-report
Locked flows before any changePhase 10.5migration-skill#lock-flows
One module per branchPhase 10.5migration-skill#module-step
Launch reportPhase 10.5migration-skill#finish-report
Agent skill and the adopt MCP toolsPhase 10.5migration-skill#agent-skill

Quick start

bash
npx mainsdk adopt scan      # main.yaml as the app is, no code change
npx mainsdk adopt report    # the gaps against Main 27: secrets, access, data, the rest
npx mainsdk adopt lock      # record sign-in and checkout as locked flows
npx mainsdk adopt next      # one module, one branch, gated by check and the locked flows
npx mainsdk adopt finish    # Main 27 met, or exactly what remains

mainsdk adopt with no step runs the next one, so it is safe to re-run. It runs fully on your machine and sends nothing. Opening the pull request is left to you, your agent or gh: adopt only creates the branch and the commit.

Configuration

adopt has no main.yaml section. Its first step writes main.yaml for you, and its progress lives in .mainsdk/adopt.json, which is git-ignored:

json
{ "step": "module", "done": ["secrets", "auth"], "next": "data", "locked": 6, "byo": ["byo-identity:clerk"] }

byo lists what the app already runs and adopt keeps: a Clerk sign-in stays auth.driver: clerk, an OpenFGA model stays access.driver: openfga. Nothing is replaced.

What you get

CommandWhat it does
mainsdk adopt scanWrites the same main.yaml on every run. Lists the interfaces the app uses and changes no other file
mainsdk adopt reportPlain-language gaps in risk order: secrets, then access, then data, then the rest. Each names the Main 27 rule and the fix. --json for tools
mainsdk adopt lockRecords the sign-in and checkout flows as locked flows. A flow holds while its file exists and still contains the call that makes it work
mainsdk adopt nextOpens one module (secrets, auth, data or other) on its own branch. --module <name> picks it. Refuses to run before flows are locked
mainsdk adopt verifyChecks the open module: only its files changed, mainsdk check shows no new finding and every locked flow holds
mainsdk adopt finishThe launch report: Main 27 is met, or the report lists what remains with file and line. --json for tools

Code that cannot move to an interface yet stays behind that interface's raw() escape hatch, and finish lists it.

With your coding agent

mainsdk adopt mcp starts a stdio MCP server with six tools: adopt.scan, adopt.report, adopt.lock, adopt.plan_module, adopt.verify_module and adopt.finish. mainsdk adopt skill writes the skill for Claude Code (.claude/skills/mainsdk-adopt/SKILL.md), Cursor (.cursor/rules/mainsdk-adopt.mdc) and any agent that reads AGENTS.md. The agent follows the same five steps and cannot skip the lock.

Errors and checks

CodeWhen
MAIN-ADOPT-0001adopt next ran before flows were locked; nothing changed
MAIN-ADOPT-0002The stack is not Next.js or Node; adopt stops and changes nothing
MAIN-ADOPT-0003A route changes or reads data and never checks who is calling
MAIN-ADOPT-0004The browser queries the database directly, so row rules are the only protection
MAIN-ADOPT-0006Nothing to migrate in the module, or it is not a module
MAIN-ADOPT-0007A call still sits behind raw(); listed by finish with file and line
MAIN-ADOPT-0008The working tree has uncommitted changes; a module step starts clean
MAIN-ADOPT-0009No sign-in or checkout flow was found to lock, or a named flow points at text that is not there
MAIN-ADOPT-0010A module step is still open, or verify ran with none open
MAIN-ADOPT-0012The folder is not a git repository, or the module branch could not be created
MAIN-ADOPT-0013The name is not an adopt tool, or not an agent adopt writes a skill for

The full list is in check codes.

Swapping drivers

adopt has one driver, the built-in one, which reads your files and runs git. There is nothing to swap.

Testing

A failing module step leaves your main branch untouched and keeps its branch for review. The scan is deterministic, so a test can run it twice and compare the two main.yaml files. Run mainsdk check after any step to see the same findings the gate uses.

Next

Was this page helpful?

↑↓ moveEnter openEsc close

Not decided yet