<!-- Source: https://dev.dbmigratepro.com/docs/mcp-setup -->

# Connect an AI assistant

DBMigratePro speaks the **Model Context Protocol (MCP)**, so an assistant can price a migration,
create it, watch it finish, and manage your backup schedules without you opening the dashboard.

Two servers are published. Both are **streamable HTTP** endpoints, and both authenticate with the
same personal API token:

| Server | Endpoint | Covers |
|---|---|---|
| Migrations | `https://dev.dbmigratepro.com/mcp-migrations` | List, inspect, pre-flight, create, retry, reset, and delete migrations |
| Backups | `https://dev.dbmigratepro.com/mcp` | List and create backup schedules, run one on demand, inspect history, restore |

If your client does not speak MCP, everything below is also available over plain HTTP — skip to
[REST instead of MCP](#rest-instead-of-mcp).

## Step 1 — get a token

[Create an API token in Settings → API Tokens](/settings/api-tokens). Give it a name you will
recognise later, such as `claude-desktop`.

The plaintext token is shown **once**. Copy it straight into the configuration below; if you lose it,
revoke it and mint another. A token carries full access to your account, so treat it like a password:
keep it out of committed files and out of screenshots.

## Step 2 — add the server to your client

Replace `YOUR_TOKEN` with the token from step 1 in each snippet.

### Claude Code

```bash
claude mcp add --transport http dbmigratepro-migrations https://dev.dbmigratepro.com/mcp-migrations \
  --header "Authorization: Bearer YOUR_TOKEN"

claude mcp add --transport http dbmigratepro-backups https://dev.dbmigratepro.com/mcp \
  --header "Authorization: Bearer YOUR_TOKEN"
```

Then run `/mcp` inside Claude Code and check both servers report as connected. `claude mcp add`
writes the configuration without testing the credential, so a bad token shows up here as a failed
connection rather than as an error at setup time.

### Claude Desktop

Claude Desktop's built-in **Connectors** panel authenticates with OAuth and has no field for a
bearer token, so a token-authenticated server has to go through the `mcp-remote` bridge, which runs
locally and adds the header for you. It needs [Node.js](https://nodejs.org) installed.

Open **Settings → Developer → Edit Config** — or edit the file directly:

- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`

```json
{
  "mcpServers": {
    "dbmigratepro-migrations": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://dev.dbmigratepro.com/mcp-migrations",
        "--header",
        "Authorization:${AUTH_HEADER}"
      ],
      "env": {
        "AUTH_HEADER": "Bearer YOUR_TOKEN"
      }
    }
  }
}
```

Restart Claude Desktop afterwards. The header is passed through an environment variable on purpose:
`mcp-remote` mangles arguments that contain spaces on some platforms, and `Authorization: Bearer …`
has one.

### Cursor

Put this in `~/.cursor/mcp.json` for every project, or `.cursor/mcp.json` for one:

```json
{
  "mcpServers": {
    "dbmigratepro-migrations": {
      "url": "https://dev.dbmigratepro.com/mcp-migrations",
      "headers": {
        "Authorization": "Bearer ${env:DBMIGRATEPRO_TOKEN}"
      }
    }
  }
}
```

Cursor expands `${env:NAME}` from your environment, so the token stays out of the file — set
`DBMIGRATEPRO_TOKEN` in your shell profile. If you would rather paste it inline, replace the whole
value with `Bearer YOUR_TOKEN`.

### VS Code (Copilot agent mode)

In `.vscode/mcp.json`. The `inputs` block makes VS Code prompt for the token and keep it out of the
committed file:

```json
{
  "inputs": [
    {
      "type": "promptString",
      "id": "dbmigratepro-token",
      "description": "DBMigratePro API token",
      "password": true
    }
  ],
  "servers": {
    "dbmigratepro-migrations": {
      "type": "http",
      "url": "https://dev.dbmigratepro.com/mcp-migrations",
      "headers": {
        "Authorization": "Bearer ${input:dbmigratepro-token}"
      }
    }
  }
}
```

### Zed

Settings → AI → MCP Servers, or in your Zed settings file:

```json
{
  "context_servers": {
    "dbmigratepro-migrations": {
      "url": "https://dev.dbmigratepro.com/mcp-migrations",
      "headers": {
        "Authorization": "Bearer YOUR_TOKEN"
      }
    }
  }
}
```

### Windsurf

In `~/.codeium/windsurf/mcp_config.json`. Note the key is `serverUrl`, not `url`:

```json
{
  "mcpServers": {
    "dbmigratepro-migrations": {
      "serverUrl": "https://dev.dbmigratepro.com/mcp-migrations",
      "headers": {
        "Authorization": "Bearer YOUR_TOKEN"
      }
    }
  }
}
```

## Step 3 — check it works

Ask your assistant something read-only first:

> List my DBMigratePro migrations.

An empty list is a success — it means the token authenticated and the account simply has no
migrations yet. A 401 means the token is wrong or was not sent; a 403 means the token is valid but
the resource belongs to a different team.

## What the tools do

MCP is self-describing: on connect your client discovers each tool's exact name and input schema, so
this table is orientation rather than a contract.

**Migrations** (`https://dev.dbmigratepro.com/mcp-migrations`)

| Tool | What it does |
|---|---|
| `list-migrations-tool` | List your migrations — id, status, type, size, cost. |
| `get-migration-tool` | Full detail for one migration, plus recent log lines. |
| `preview-migration-tool` | Pre-flight a source and target pair: reachability, measured size, transfer vs. conversion, price. Creates nothing. |
| `prepare-migration-tool` | Create a migration from a preview. Never charges; returns a checkout link when a payment hold is due. |
| `retry-migration-tool` | Re-queue a failed migration. |
| `reset-migration-tool` | Clean the target and run it again. |
| `delete-migration-tool` | Delete a migration. Irreversible. |

**Backups** (`https://dev.dbmigratepro.com/mcp`)

| Tool | What it does |
|---|---|
| `list-backups-tool` | List your backup schedules. |
| `create-backup-tool` | Point a schedule at a database. Daily is the shortest interval accepted. |
| `run-backup-now-tool` | Take a backup immediately instead of waiting for the schedule. |
| `list-backup-runs-tool` | Run history for a schedule. |
| `restore-backup-tool` | Restore a completed run into a target database URL. Free, on any host. |

Every call is scoped to the token owner's acting team, so an assistant only ever sees and touches
your own databases.

## Guardrails an integrator should know about

**Nothing is charged without a person.** An assistant cannot complete a payment. When a run needs
one, `prepare-migration-tool` returns a `checkout_url` for the user to authorise in a browser, and
the run starts by itself once they do. Pro subscribers and a qualifying first migration have no
payment step at all. A failed migration is never charged, and restores are never charged — so an
assistant can say both plainly.

**Destructive calls ask first.** Delete and reset are called once without confirmation to preview
what would happen, then again with `confirm=true` after the user agrees.

**Rate limits are tiered by what a call costs us**, keyed on the token owner:

| Tier | Limit | Applies to |
|---|---|---|
| AI | 10 per minute, 200 per day | The MCP servers and the natural-language endpoints — each call spends money on a model |
| Probe | 20 per minute | Anything that dials a database you supply: pre-flight, estimates, connection tests |
| Read | 300 per minute | Ordinary `GET`s |
| Write | 60 per minute | Ordinary mutations |
| Token minting | 10 per hour | Creating API tokens |

Restores are deliberately kept out of the probe and write tiers — they inherit only the generous read
limit, because a restore has to work in the middle of an outage. They are never metered either.
Exceeding a limit returns `429` with a `Retry-After` header; back off rather than retrying
immediately.

**Connection URLs are write-only.** Database URLs are encrypted at rest and never returned by any
endpoint, so an assistant cannot read back a URL it did not just receive from the user. Ask the user
for the exact source and target URLs; never invent one. Refer to work by id.

## REST instead of MCP

The REST API is identical in capability and needs no MCP client — send
`Authorization: Bearer YOUR_TOKEN` on every request:

```bash
curl https://dev.dbmigratepro.com/api/migrations \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json"
```

A machine-readable description of every endpoint, generated from the live route table, is published
at [`/openapi.json`](/openapi.json) — point a generic agent framework or an HTTP client generator at
that. The narrative version is the [Migrations API](/docs/migrations-api) guide, and
[AI agents](/docs/ai-agents) covers the create-then-poll flow an agent should follow.

Two more machine-readable entry points, if you are pointing a model at this site rather than
integrating with it: [`/llms.txt`](/llms.txt) summarises what the product does, and
[`/llms-full.txt`](/llms-full.txt) is this entire documentation set as one plain-text file. Any
documentation page is also plain Markdown with `.md` appended to its URL.

## Troubleshooting

**401 Unauthorized.** The token is missing, mistyped, or revoked. Confirm the header reads
`Authorization: Bearer ` followed by the token, and that you copied the whole value including the
digits and `|` before the random part.

**403 Forbidden.** The token is valid but the resource belongs to another team. Switch the acting
team with `POST /api/teams/{team}/switch`.

**429 Too Many Requests.** You hit one of the tiers above. Wait for the `Retry-After` interval.

**The client shows the server as failed to connect.** Check the URL is exactly
`https://dev.dbmigratepro.com/mcp-migrations` or `https://dev.dbmigratepro.com/mcp`, over HTTPS, with no trailing slash. For Claude Desktop
specifically, confirm Node.js is installed and on your `PATH` — the bridge runs through `npx`.

Still stuck? [Contact us](/contact) with the client you are using and the error it reports.
