CLI + skill · for Claude Code, Cursor, Windsurf, Copilot

Hand the migration to your agent.

The Graftport CLI plus a bundled skill turn any coding agent into a migration engineer. It investigates source data, drafts and publishes JSONata mappings, runs sandbox dry-runs, and triages failures. Anything that costs real money stays human-gated.

Start a migration Install the CLI
· Works over a plain shell tool· No MCP required· Human gate on every cost
claude-code · graftport-migration-engineer
$graftport source rows mig_8f2a product --limit 5
5 rows · entity_id 12481, 12482, 12483, …
$graftport mappings show map_prd_4a1 --raw > current.jsonata
$graftport mappings validate map_prd_4a1 \
$--jsonata current.jsonata --limit 50
3 errors · AMOUNT_MISMATCH, MISSING_REQUIRED, TYPE_COERCION
# agent edits current.jsonata, fixes weight conversion + status enum
$graftport mappings validate map_prd_4a1 \
$--jsonata current.jsonata --limit 50
50/50 rows pass · ready to publish
$graftport mappings publish map_prd_4a1 \
$--jsonata current.jsonata --notes "fix AMOUNT_MISMATCH"
published v5 · re-load flag set on 12,481 records
 
$graftport runs start mig_8f2a
! human-gated · costs 12,481 Shopify writes + platform credits
type 'yes' to proceed:
The loop

The same loop a migration engineer runs,
done by your agent.

01

Investigate

The agent samples real source rows for any resource: products, customers, orders, redirects. It reads JSON straight off your store via the CLI, not from a stale schema diagram.

$ graftport source rows <mig_id> product --limit 5
02

Draft a mapping

The agent pulls the current JSONata mapping, edits it to handle whatever the samples revealed (custom attributes, oddly-shaped variants, unit mismatches), and writes a new file.

$ graftport mappings show <map_id> --raw > current.jsonata
03

Validate against real rows

Every change is validated against a sample of source rows before it ships. The validator returns structured error codes the agent already knows how to fix.

$ graftport mappings validate <map_id> --jsonata current.jsonata --limit 50
04

Publish & dry-run

When validation is green, the agent publishes a new immutable version of the mapping and kicks a sandbox dry-run. Zero Shopify writes, zero cost. You see the exact shape Shopify would receive.

$ graftport runs start <mig_id> --dry-run
CLI + skill

Two installs. Any agent.

The CLI is a normal Python package on PyPI. The skill is a Markdown document that teaches your coding agent how to use it — the iterative mapping workflow, every validation error code, and the JSONata patterns that fix each one. One install command writes the skill to the right place for whichever agent you run.

The CLI

Every Graftport action is exposed as a JSON-on-stdout command. Auth via the same OAuth loopback flow as gh auth login --web. Read-only by default; cost-incurring actions print a live estimate to stderr and block on a human yes.

uv tool install graftport
graftport auth login
graftport migrations list

The skill

Auto-detects which coding agents are installed for your user and writes the right file for each. Claude Code, Claude Desktop, Windsurf land instantly. Cursor and Copilot need a one-time paste of the same skill text.

graftport skill install
# detects Claude Code, Claude Desktop, Windsurf
# writes ~/.claude/skills/graftport-migration-engineer/
# and the Windsurf global-rules block
Human-approval contract

The agent never spends your money.

State-changing actions split into two tiers. The bundled skill explicitly forbids the agent from passing --yes on any gated command. The agent composes the command, prints the cost, and stops. You decide whether to ship.

Agent-allowed

no gate
mappings publish

Metadata write only; flags downstream records for re-load on the next run, which is itself gated.

runs start --dry-run

Computes payloads against a sandbox without pushing to Shopify. Zero load cost, zero credit usage.

All read-only commands

migrations, mappings, runs, records, source — list, show, status, failures.

Human-gated

interactive yes
runs start (real load)

Costs Shopify API calls and platform credits per record loaded. Prints a live cost estimate to stderr; blocks on a yes.

runs cancel

Destructive — may lose in-flight work for already-loaded records.

records retry

Re-loads one record; small but real cost. Distinct exit code (3) on decline so scripts can branch.

Works with

One CLI. Every coding agent
already on your laptop.

Agent
Install
Note
Claude Code
auto · ~/.claude/skills/graftport-migration-engineer/
First-class. Shell tool + the skill format Anthropic ships natively. Reference experience.
Claude Desktop
auto · same path as Claude Code
Anthropic unified the on-disk skill location, so one graftport skill install serves both products.
Windsurf
auto · ~/.codeium/windsurf/memories/global_rules.md
Skill is merged as an idempotent block into your global rules file. Cascade picks it up on next session.
Cursor
manual paste · Settings → Rules → User Rules
Run graftport skill > skill.md and paste into User Rules. Cursor only reads User Rules from its Settings UI.
GitHub Copilot Workspace
manual paste · .github/copilot-instructions.md
Per-repo only by Copilot's design. Drop the skill in the repo and Copilot picks it up there.
Aider / AGENTS.md / custom agents
manual paste · AGENTS.md or your agent's instructions file
Anything with a shell tool can drive the CLI. The skill is a single Markdown file you can hand to any model.
Why this works

An agent on a rail,
not a wild horse.

AI is good at the boring, iterative work that has clear feedback signals — exactly what migration mapping is. The CLI gives it a tight feedback loop. The skill gives it the playbook. The human-approval contract makes sure nobody wakes up to a Shopify bill nobody authorised.

Source samples, not guesses

The agent sees real source rows on every iteration, so mappings handle the long tail of weird data instead of the schema diagram's happy path.

Structured error codes

Validation returns codes like AMOUNT_MISMATCH and TYPE_COERCION. The bundled skill maps each one to the JSONata pattern that fixes it.

Versioned, never destructive

Every publish is an immutable mapping version. The agent can ship freely; rolling back to v3 is one click and one re-run.

Dry-run by default

The agent's start-a-run command always carries --dry-run unless you remove it. Nothing leaks into Shopify until you say so.

Distinct decline exit code

Gated commands exit 3 when you decline (vs 1 for failure). Your wrapping scripts can tell the difference, and the agent knows to stop and ask.

Read-only by design

Source-side credentials are read-only, and Graftport never writes back to Magento, WooCommerce, BigCommerce, or the source Shopify, regardless of who is driving.

AI migration FAQ

The questions
agencies ask first.

Do not see yours? Email hello@graftport.com. We read every message.

Anything that has a shell tool. The CLI exposes every action as a JSON-on-stdout command, so Claude Code, Cursor, Windsurf, GitHub Copilot Workspace, Aider, and any custom agent that can run a shell command all work. No MCP server required.

Put your agent on the migration.

Create the migration in the app, install the CLI and the skill, and your coding agent picks up the migration-engineer role from there. Costly steps stay on you.

Start a migration Read the playbook
uv tool install graftport · graftport skill install