Seedfast

Seedfast

MCP Setup Guide

By Mikhail Shytsko, Founder at Seedfast · Updated

The Model Context Protocol (MCP) enables AI assistants to interact directly with developer tools. Seedfast's MCP server brings database seeding into that workflow, so you ask your assistant instead of switching to a terminal.

This guide walks through connecting Seedfast MCP to Claude Desktop, Cursor IDE, VS Code, or Claude Code CLI.

Understanding MCP Architecture

Before diving into configuration, it helps to understand what MCP actually does:

┌──────────────────────┐       ┌──────────────────────┐       ┌──────────────────────┐
│   AI Assistant       │ ◄───► │   Seedfast MCP       │ ◄───► │   Your Database      │
│   (Claude/Cursor)    │       │   Server             │       │   (PostgreSQL)       │
│                      │       │                      │       │                      │
│   Natural language   │       │   JSON-RPC protocol  │       │   SQL execution      │
│   commands           │       │   Tool orchestration │       │   Data generation    │
└──────────────────────┘       └──────────────────────┘       └──────────────────────┘

The MCP server acts as a bridge between your AI assistant and Seedfast's backend. When you ask Claude to "seed my database with test users," the assistant invokes MCP tools that execute the actual seeding operations.

Prerequisites

Before starting, ensure you have:

  • A Seedfast account (free plan at seedfa.st)
  • PostgreSQL database accessible from your machine
  • Node.js 18+ installed (for npx-based MCP server)
  • One of: Claude Desktop, Cursor IDE, VS Code with Continue.dev, or Claude Code CLI

Installation

No separate installation required. The MCP server is built into the Seedfast CLI and runs via npx directly from your configuration.

Pin the version

Every example below asks for an exact version rather than seedfast@latest. That matters because your MCP config is a file your whole team runs from, and @latest re-resolves on every server start. We ship often enough that two people on the same branch in the same week can end up on different builds, which turns "works on my machine" into a question nobody can answer from the config alone.

Pin it, and bump the pin when you choose to:

npm view seedfast version   # what's current

For a throwaway local experiment, @latest is fine. Anything committed, shared, or running in CI should name a version. One caveat worth knowing: the CLI talks to the Seedfast API, so a pin you leave untouched for many months can eventually fall behind what the API expects. Treat bumping it as routine maintenance rather than something you do only when a run breaks.

Keep the API key out of the file

Four of the five clients here can read the key from your environment instead of storing it in the config, which is what you want for any file that lives in a repository. Each one spells it differently, and the sections below use the right syntax for each. Claude Desktop is the exception and needs a literal value, though its config sits in your OS application-support directory rather than your project, so it is not something you would commit by accident.

Export the key once in your shell profile:

export SEEDFAST_API_KEY="sfk_live_your_actual_key_here"

Configure Claude Desktop

Claude Desktop is the official Anthropic client with native MCP support.

Locate your config file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json

Add the Seedfast server:

{
  "mcpServers": {
    "seedfast": {
      "command": "npx",
      "args": ["-y", "seedfast@2.6.3", "mcp"],
      "env": {
        "SEEDFAST_API_KEY": "sfk_live_your_api_key_here"
      }
    }
  }
}

Claude Desktop does not expand variables in this file, so the key has to be written out in full. Because the config lives in your application-support directory and not in a project, that is a smaller problem than it looks, but the file does hold a usable credential in plain text and deserves the same care as any other dotfile that does.

Restart Claude Desktop to load the new configuration.

Configure Cursor IDE

Cursor runs MCP servers in a sandboxed environment. Authentication is configured directly in the MCP config's env section.

Add to .cursor/mcp.json or global settings:

{
  "mcpServers": {
    "seedfast": {
      "command": "npx",
      "args": ["-y", "seedfast@2.6.3", "mcp"],
      "env": {
        "SEEDFAST_API_KEY": "${env:SEEDFAST_API_KEY}"
      }
    }
  }
}

Cursor interpolates ${env:NAME} in command, args, env, url and headers, so .cursor/mcp.json can be checked in as it stands and each person supplies their own key through the environment.

Configure VS Code with Continue.dev

Continue.dev provides MCP support for VS Code users.

Add to .continue/config.json:

{
  "experimental": {
    "modelContextProtocolServers": [
      {
        "transport": {
          "type": "stdio",
          "command": "npx",
          "args": ["-y", "seedfast@2.6.3", "mcp"],
          "env": {
            "SEEDFAST_API_KEY": "${{ secrets.SEEDFAST_API_KEY }}"
          }
        }
      }
    ]
  }
}

Continue resolves ${{ secrets.NAME }} in args and env against its own secret store, so the key never appears in config.json.

Configure Claude Code CLI

For terminal-based workflows with Claude Code:

Add to your .mcp.json:

{
  "mcpServers": {
    "seedfast": {
      "command": "npx",
      "args": ["-y", "seedfast@2.6.3", "mcp"],
      "env": {
        "SEEDFAST_API_KEY": "${SEEDFAST_API_KEY}"
      }
    }
  }
}

Claude Code expands ${VAR} and ${VAR:-default} in command, args, env, url and headers. Since .mcp.json is meant to be committed so everyone on the team picks up the same servers, referencing the variable is the whole point: the file describes the setup and your shell supplies the credential.

Claude Code skill

The MCP server hands Claude the tools. A skill hands it the procedure. Without one, an agent works the order out from the tool descriptions on every fresh conversation, which is usually close enough and occasionally not, and what slips is the schema read, or the reply from seedfast_run being reported as a finished job when it only acknowledges that a run has started.

Seedfast ships two of them. The seedfast skill pins the sequence, carries the scope-writing conventions measured on scope examples, points at the prompts the MCP server publishes for the harder cases, and spells out the rules about production databases and invented table names. When the tools are missing instead, or the key is rejected, or a connection string will not resolve, seedfast-setup is what loads, and it walks through the fix without ever asking you to paste the key into the chat. Claude Code decides which one a conversation needs, so there is no command to remember and no cost when the subject never comes up.

Install with the plugin

The Seedfast plugin bundles the MCP server configuration with both skills, and Claude Code asks for your API key while installing it, then keeps that key in its own storage instead of a file you might commit.

/plugin marketplace add seedfast-ai/claude-plugins
/plugin install seedfast@seedfast

Skip the marketplace and copy the folders directly if a pinned Claude Code build predates plugin support, or the team just prefers files it can review in a diff.

Install by copying the folders

The npm package carries both skills under skills/. Copying them into a project means everyone who clones the repository picks them up:

mkdir -p .claude/skills
cp -R "$(npm root -g)/seedfast/skills/seedfast" .claude/skills/
cp -R "$(npm root -g)/seedfast/skills/seedfast-setup" .claude/skills/

Point the same two commands at ~/.claude/skills instead and the skills follow you across every project on the machine. With Seedfast installed as a project dependency rather than globally, the source path is node_modules/seedfast/skills/..., and Windows PowerShell wants Copy-Item -Recurse for the same job. Restart Claude Code afterwards and run /skills, which should now list seedfast and seedfast-setup.

Should the version you pinned predate the release that added these folders, nothing is lost. The seeding skill is reproduced below in full. Save it as .claude/skills/seedfast/SKILL.md, restart, and you have the same behaviour without waiting on an upgrade.

---
name: seedfast
description: Fill a PostgreSQL database with realistic, relationally valid test data using Seedfast over MCP. Use when the user wants to seed, populate or fill a database, needs test, demo or staging data, has empty tables to work against, wants a dev database that behaves like production, or says "seed the database", "seed my database", "populate my postgres with test data", "fill the staging database", "generate test data for these tables", "my dev database is empty", "I need demo data", "fixtures", "synthetic data" or "seedfast". Covers the environment check, the connection test, reading the schema, writing the plain-language scope, previewing a plan, starting a run, polling it to completion, answering a question the run raises, and counting what landed.
---

# Seeding a database with Seedfast

Seedfast reads a live PostgreSQL schema and generates data that satisfies it: foreign keys resolve, constraints hold, and values look like the domain rather than `test_user_1`. The work happens on Seedfast's backend, and the MCP tools here drive it.

## The loop

```
doctor -> connections_test -> schema_info -> plan -> [user approves] -> run -> run_status (poll) -> count
```

Skipping straight to `seedfast_run` is allowed, but only when the user has clearly said "just seed it" and the target is obviously disposable.

### 1. Check the environment

Call `seedfast_doctor` first, once per session. It reports CLI status and version, whether the API key is configured, and the platform. If it reports a missing API key, stop and route the user to the `seedfast-setup` skill instead of retrying.

If the `seedfast_*` tools are not visible at all, the MCP server is not registered with the client. That is also `seedfast-setup`, and no amount of retrying makes the tools appear.

### 2. Verify the connection before anything else

`seedfast_connections_test` with the DSN. It opens a pool and pings with a 10-second timeout, and masks credentials in its output. This catches a wrong password or a closed firewall port in one second instead of surfacing it as a confusing planner failure a minute later.

DSN format:

```
postgres://user:password@host:5432/dbname
postgres://user:password@host:5432/dbname?sslmode=require
```

Never print a DSN back to the user with the password intact. When you need to refer to a database, name it (`the staging DB`), don't echo the string.

### 3. Read the schema before writing a scope

`seedfast_schema_info` returns tables, columns, primary keys, foreign keys, and approximate row counts. Use it to ground the scope in tables that actually exist.

Row counts come from `pg_class.reltuples`. They are approximate, can be stale between `ANALYZE` runs, and are `-1` on never-analyzed tables. Treat them as a size hint, never as a fact to report.

The `dsn` argument is optional here. With it omitted, the server falls back to `SEEDFAST_DSN` or `DATABASE_URL` in its own environment.

### 4. Plan, then let the user look

`seedfast_plan` generates a plan without writing a single row, and stores it in the session. It returns a plan ID, the scope echoed back, and the table list.

Show the user the table list and the scope before running. This is the whole point of the plan step: it is the last cheap moment to catch "that scope also touches `billing_invoices`".

`seedfast_plan` requires an API key.

### 5. Run it

`seedfast_run` returns immediately with a `runId`, and the seeding proceeds in the background.

- Pass `planId` to execute an approved plan. The scope is derived from the plan's tables and the `scope` argument is ignored.
- Without `planId`, `scope` is required.
- Always pass an `idempotencyKey`. A retry carrying the same key returns the existing run instead of seeding twice, which is the difference between a dropped connection costing you nothing and costing the user a doubled `orders` table.

### 6. Poll to completion

`seedfast_run_status` is safe to call repeatedly. It reports state (`pending`, `running`, `awaiting_input`, `completed`, `failed`, `cancelled`), progress as completed vs total tables, row totals, the table currently being seeded, and a summary once finished.

Poll at a human pace, a few seconds between calls rather than a tight loop. Report progress to the user as it moves rather than going silent for two minutes.

### 7. Answer questions the run raises

A run can move to `awaiting_input` when the backend needs a decision about scope or a replan. `seedfast_run_status` surfaces the `questionId`, and the full text is at `seedfast://runs/{runId}/pending_question`.

Reply with `seedfast_run_answer`:

- `answer.human_answer = true` approves the current plan or scope as-is.
- `answer.human_answer = false` plus `answer.raw` with a textual refinement (`"seed only the org schema"`) adjusts it.

**Bring the question to the user.** Do not auto-approve on their behalf, because the backend asks precisely when the right call is not obvious. The CLI blocks for up to 5 minutes waiting for the reply, so answer promptly once the user decides.

### 8. Count what landed

Run `SELECT count(*)` against the tables the scope named and put those numbers beside the ones the scope asked for. A `completed` status says the run finished. Only the counts say it filled the database the user had in mind.

## Writing scopes

Scopes are plain English, interpreted by the backend. Do not pre-parse them into a DSL.

```
seed the users and posts tables with 1000 rows each
HR schema only
everything except the audit and billing tables
enough orders across 50 customers to exercise the reporting dashboard
```

Two things make a scope good: naming real tables from `seedfast_schema_info`, and saying how much. "Some test data" produces a plan nobody can review.

For more patterns, request the server's `scope-examples` prompt (`general`, `ci`, or `exploration`). For a production-shaped target, request the `seed-production-db` prompt before starting.

Worked descriptions of four different sizes, with the row counts each one produced on the same schema, are at https://seedfa.st/docs/scope-examples. Keep the final wording in the repository next to the migrations, since the same text feeds `seedfast seed --scope` at a terminal and a CI step behind an API key.

## Safety

**Seedfast writes rows to a real database.** Before the first `seedfast_run` of a session, confirm the target is a development, staging, or test database. If the DSN host looks production-shaped (`prod`, `live`, a customer domain, an RDS writer endpoint), stop and ask outright.

**Cancellation does not roll back.** `seedfast_run_cancel` stops the run, but rows already inserted stay inserted. A cancelled run leaves a partially seeded database that someone has to clean up. Say so when you cancel.

**`seedfast_plan_delete` is irreversible** and does not touch runs started from that plan.

## Guardrails

**Never invent a table name.** Every table a scope names comes from `seedfast_schema_info`. A guessed name produces nothing and reports nothing about having produced nothing.

**Never read success out of the `seedfast_run` response.** That call returns before the first insert, carrying a run ID and `pending`. Only `seedfast_run_status` reporting `completed` describes a result.

**Never start a second run to fix a slow one.** Poll it, or cancel it and then start a single run with a corrected scope. Two runs against the same tables leave a mess that has to be cleaned up by hand.

**Counted rows are the only real evidence.** Status text describes what the backend thinks it did. The counts from step 8 are what you report to the user.

## Plans

Plans live in the MCP session, in memory, unless the user configured a run-history file. They do not survive an MCP server restart. Do not promise a user that a plan will be there tomorrow.

| Tool                   | Use                                                                                                                                                       |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `seedfast_plans_list`  | Find plan IDs (accepts `limit`)                                                                                                                           |
| `seedfast_plan_get`    | Full table list and preview for one plan                                                                                                                  |
| `seedfast_plan_create` | Store a hand-built plan, skipping the planner round-trip. Needs `scope` and at least one entry in `tables`                                                |
| `seedfast_plan_update` | Change `tables`, `scope`, or `preview`. Only non-empty fields overwrite, omitted fields are preserved, and there is no way to clear a field back to empty |
| `seedfast_plan_delete` | Discard a plan. Irreversible                                                                                                                              |

`seedfast_plan_create` is the fast path when the tables are already known from a previous run, since it needs no API key and no backend call.

## Resources

Read these directly when the status text is not enough:

| URI                                        | Contents                                              |
| ------------------------------------------ | ----------------------------------------------------- |
| `seedfast://runs/{runId}/summary`          | Run summary as JSON                                   |
| `seedfast://runs/{runId}/log`              | Event log, NDJSON, the place to look when a run fails |
| `seedfast://runs/{runId}/pending_question` | The question an `awaiting_input` run is blocked on    |
| `seedfast://plans/{planId}`                | Full plan as JSON                                     |

## When a run fails

1. `seedfast_run_status` for the error message and the failed-tables map.
2. `seedfast://runs/{runId}/log` for the events leading up to it.
3. Read the failure before re-running. A constraint the generator could not satisfy will fail again identically, so the scope or the schema is what needs to change.

## Which tools need the API key

Only `seedfast_plan` and `seedfast_run` reach the Seedfast backend. Everything else works without a key: `doctor`, `connections_test`, `schema_info`, all plan management, run status, cancel, and answer. A missing key is not a reason to abandon schema exploration.

## Scale

PostgreSQL only today. MySQL, Oracle, and SQLite are in development. If the user points this at a MySQL database, say that plainly rather than trying the DSN.

## Reference

- [MCP setup guide](https://seedfa.st/docs/mcp-setup-guide) has the config block each client expects, the API key, and the troubleshooting cases.
- [Seeding with an AI agent](https://seedfa.st/docs/ai-agent-seeding) walks one complete session, with the calls, the description, and the SQL that counted the rows afterwards.

Then ask for what you want in ordinary words, naming the database and roughly how much data you need. The agent checks the environment, tests the connection, reads the schema, drafts the description, waits for your approval and only then starts writing rows. Seeding with an AI agent shows what that session looks like from the first call to the counting queries at the end.

Verify Installation

After configuration, verify the MCP server is accessible. In your AI assistant, ask:

Use seedfast_doctor to check the installation

Here is what the check returns. The path is specific to the machine it ran on, so it appears here as <where the binary was installed>, and the Platform line will differ on a Mac or Linux machine:

CLI Status: OK
Version: seedfast 2.6.3
backend 2.0.0
Path: <where the binary was installed>
Auth: OK (SEEDFAST_API_KEY configured)
Platform: windows/amd64
Go Version: go1.25.1
MCP Server Version: 1.0.0

Configure Authentication

Seedfast MCP uses config-based authentication via the env section in your MCP configuration.

Get Your API Key:

  1. Log in to seedfa.st
  2. Open Settings, then API Keys
  3. Click Create New Key
  4. Copy the key (format: sfk_live_xxxxx...)

Point the config at the key:

Export it in your shell profile so the value lives in one place:

export SEEDFAST_API_KEY="sfk_live_your_actual_key_here"

Then reference it from the env section. Each client has its own syntax:

ClientConfig fileValue to use
Claude Code.mcp.json${SEEDFAST_API_KEY}
Cursor.cursor/mcp.json${env:SEEDFAST_API_KEY}
Continue.dev.continue/config.json${{ secrets.SEEDFAST_API_KEY }}
Codex CLIconfig.tomlenv_vars = ["SEEDFAST_API_KEY"]
Claude Desktopclaude_desktop_config.jsonthe literal key, no expansion

Codex is the odd one out in shape rather than intent: instead of substituting a value it whitelists the variable name and forwards whatever your shell already has.

In CI, set SEEDFAST_API_KEY as a pipeline secret and the same committed config keeps working without a local edit.

Your First AI-Powered Seed

With everything configured, try your first seeding operation.

Test Database Connection:

Test the database connection to postgresql://myuser:mypass@localhost:5432/mydb

Run a Seed:

Seed all tables in all schemas of my database at postgresql://myuser:mypass@localhost:5432/mydb

Your assistant runs the seed in the background and reports progress as it goes. How to write the description, and a real session end to end, is on seeding with an AI agent.

Available MCP Tools

Two tools need SEEDFAST_API_KEY in the server's environment, seedfast_plan and seedfast_run. The others read local session state or the database and work without it.

Checks:

  • seedfast_doctor reports CLI status and version, the binary path, whether the key is set, the platform, and the Go and MCP server versions.
  • seedfast_connections_test opens a connection to the database at the given DSN and returns success or failure, with the credentials masked.
  • seedfast_schema_info reads the schema and returns tables, columns, primary keys, foreign keys and approximate row counts as JSON.

Runs:

  • seedfast_run starts a seeding run in the background and returns the run ID with its initial status right away.
  • seedfast_run_status returns a run's state and progress, and its summary once it has finished.
  • seedfast_run_answer submits an answer to a run that is waiting on a question and returns a short confirmation.
  • seedfast_run_cancel requests cancellation of a pending or running operation. Rows already written stay in the database.

Plans:

  • seedfast_plan builds a seeding plan for a scope without writing data, stores it for the session and returns the plan ID with its table list.
  • seedfast_plans_list lists the plans stored in the current session.
  • seedfast_plan_get returns one stored plan by its ID.
  • seedfast_plan_create stores a plan you supply directly, skipping the planning round trip.
  • seedfast_plan_update changes the tables or scope on a stored plan.
  • seedfast_plan_delete removes a stored plan.

MCP Resources: Beyond Tools

Seedfast MCP also exposes resources, which are read-only data endpoints an AI assistant can read for context instead of calling a tool.

  • seedfast://plans/{planId} returns a stored plan's details, as JSON.
  • seedfast://runs/{runId}/summary returns a run's status and results, as JSON.
  • seedfast://runs/{runId}/log streams a run's events as NDJSON.
  • seedfast://runs/{runId}/pending_question returns the question a run is waiting on while its state is awaiting_input, as JSON.

MCP Prompts

  • seed-production-db walks the assistant through checking the environment, testing the connection, planning, and running a seed in that order, and takes a required scope argument for what to seed plus an optional dsn_description naming the target database.
  • scope-examples returns example scope strings for a given use_case argument, one of general, ci, or exploration.

Writing the description

The scope argument you pass to seedfast_plan or seedfast_run is plain text, not a query language. Inside an MCP client, your assistant typically drafts that text itself, from the schema seedfast_schema_info returns and from whatever project documents it has open, then shows you the wording before anything runs. Seeding with an AI agent covers the principles behind a good description and walks through one complete run, and scope examples shows four descriptions of increasing size run from the terminal.

Anti-Patterns to Avoid

Don't Seed in Production Without Explicit Intent

Seedfast writes rows wherever your connection string points, and it has no way to tell a production database from a development one. There is no host allow-list, no environment check, and no confirmation step before a run. Whatever guard you want here, you build on your side. The two that cost nothing are keeping the production connection string out of any environment the agent can read, and gating the CI job on your own branch or environment condition. Narrowing database privileges is worth testing before you rely on it, because a role with reduced grants can fail the inserts outright rather than limiting them.

Knowing the blast radius shapes how much guarding is worth building. A run only inserts. It does not drop, truncate or update anything, so a bad scope leaves unwanted rows in a live table for you to clean up.

Troubleshooting

"npx: command not found"

Node.js isn't installed or not in your PATH. Install Node.js 18+ from nodejs.org.

"Not authenticated" or "SEEDFAST_API_KEY not configured" error

Verify your API key is configured in MCP config:

  1. Open your MCP config file (see configuration sections above for location)
  2. Check that the env section contains SEEDFAST_API_KEY
  3. Verify the key starts with sfk_live_
  4. Restart your AI assistant to reload the config

You can also verify auth status by asking:

Run seedfast_doctor to check the installation

Expected output should show: Auth: OK (SEEDFAST_API_KEY configured)

Claude Desktop doesn't see the server

  • Verify JSON syntax in config file
  • Ensure Claude Desktop was fully restarted (not just minimized)
  • Check Developer Tools console for errors

Cursor IDE issues

  • Verify JSON syntax in .cursor/mcp.json
  • Restart Cursor completely
  • Check that SEEDFAST_API_KEY is in the env section

npm package not found

If you see errors about the package not being found, try clearing npm cache:

npm cache clean --force
npx -y seedfast@2.6.3 --version

Use the same version your config pins, so a success here tells you something about the build you actually run.