Connect to a Live Database

On Pro, Sqemo can read a real PostgreSQL or MySQL database — to import its schema into an ERD, or to check whether the database has drifted from the ERD you treat as the source of truth. Everything runs locally (or in your CI job) through sqemo-mcp; your database credentials are never sent to Sqemo.

This guide walks the whole flow end to end. Follow it top to bottom the first time.

What you need

  • Node.js 22+ (node --version to check).
  • A Pro Sqemo account (or a Team workspace member). On the Free plan the database commands stop with an upgrade notice before connecting.
  • A database to check — or none at all: see the Docker option below to spin one up in a couple of minutes.

Step 1 — Sign in from the terminal

The database commands need you signed in. Sign in once:

npx sqemo-mcp login
# Email:    you@example.com
# Password: ••••••••

This stores a refresh token in ~/.erdmaker/credentials.json (your password itself is never stored). npx sqemo-mcp logout removes it.

Signed up with Google or GitHub? Set a password first

The terminal sign-in uses email + password. If you created your Sqemo account by clicking Continue with Google / GitHub, your account has no password yet — so login (and the CI env variables) can’t authenticate. Add one once; this does not remove social login, it just adds a second way in:

  1. Open the app at app.sqemo.com and open the sign-in dialog.
  2. Click Forgot your password? / Reset.
  3. Enter the same email your Google/GitHub account uses, and send the reset link.
  4. Open the link from your inbox and set a password.
  5. Now npx sqemo-mcp login works with that email and password. You can still sign in with Google/GitHub in the app as before.

Longer term we plan to add CI-friendly API keys so social-login users won’t need a password at all — for now, this one-time setup is the way in.

Step 2 — Get your ERD as a baseline

Drift is ERD vs database, so you need the ERD side. Two ways:

  • Server ERD (saved to your account): use --erd <id>. The id comes from the list_erds MCP tool, or the app URL when the ERD is open.
  • Local project (lives only in your browser): export it to a file first. In the app: toolbar → Export → Download project. You get a <name>.erd.json file (usually in your Downloads folder). Commit this file to your repo if you’ll run the check in CI — it becomes your schema’s source of truth.

Step 3 — Run the drift check

Point lint at your ERD and your database:

# local project file
npx sqemo-mcp lint "Online Shop Example.erd.json" --db "mysql://user:pass@host:3306/dbname"

# a server ERD instead of a file
npx sqemo-mcp lint --erd <erd-id> --db "postgresql://user:pass@host:5432/dbname"

Connection URL formats:

PostgreSQL: postgresql://user:pass@host:5432/dbname
MySQL:      mysql://user:pass@host:3306/dbname

Which databases are supported?

The rule of thumb: a live --db connection works with PostgreSQL and MySQL (including MariaDB) only. Every other dialect is still supported for exporting/importing SQL, and you can drift-check it through the --schema dump path — you just can’t connect to it live.

DatabaseERD export/importLive --dbDump --schema --dialect
PostgreSQLpostgres
MySQL / MariaDB✓ (mysql://)mysql
Oracle✓* oracle
SQL Server✓* sqlserver
SQLite✓* sqlite
H2✓* h2
CUBRID✓* cubrid

* Parser exists but that dialect isn’t in the officially tested set, so results may vary with the dump’s exact format.

Why only PostgreSQL and MySQL connect live: both ship pure-JavaScript drivers (nothing to install beyond npx) and share the standard information_schema, so one introspection path covers both. The others each need a different driver and catalog — Oracle wants its Instant Client and its own data dictionary, SQLite is a file rather than a server, H2 is Java/JDBC-only, and so on — so for now they go through the dump path.

MariaDB note: connect with the mysql:// scheme (not mariadb://, which isn’t recognised) since it speaks the MySQL protocol; use --dialect mysql for dump mode. MariaDB-specific column types may surface as warnings (which pass by default) rather than errors.

Useful options:

  • --db-schema <name> — schema to read (PostgreSQL defaults to public; MySQL reads the database in the URL).
  • --ignore "flyway_*" — skip tables that live in the DB but not the ERD (migration-history, audit tables). Repeatable.
  • --strict — treat type/representation differences (normally warnings) as failures too.
  • --schema dump.sql --dialect postgres — compare against a pg_dump -s file instead of connecting, so no database URL is needed at all.

Step 4 — Read the result

The command’s exit code is the answer (echo $LASTEXITCODE on PowerShell, echo $? on bash):

ExitMeaning
0ERD and database match.
1Drift found. Each item is listed, e.g. [missing_column] CUST.EMAIL, [missing_table] ORDER_ITEM, plus a summary line.
2Couldn’t compare yet — bad connection, wrong/empty schema, not signed in, Free plan, or a usage error. Passwords in the URL are masked as :****@ in messages.

Note that an empty database (zero tables in the schema) reports exit 2, not “everything is missing” — that almost always means the schema name or database is pointed at the wrong place, so the tool asks you to check rather than drowning you in false positives.

No database yet? Use Docker

You don’t need a hosted database to try this. Spin one up, load your ERD’s schema into it, and check:

# 1) start a throwaway MySQL
docker run -d --name sqemo-my -e MYSQL_ROOT_PASSWORD=pw -e MYSQL_DATABASE=app -p 13306:3306 mysql:8
# wait ~30s for it to initialise

# 2) turn your ERD into SQL and load it
npx sqemo-mcp export "Online Shop Example.erd.json" --format sql --dialect mysql > shop.sql
docker exec -i sqemo-my mysql -uroot -ppw app < shop.sql

# 3) check — matches, so exit 0
npx sqemo-mcp lint "Online Shop Example.erd.json" --db "mysql://root:pw@localhost:13306/app"

# 4) change the DB, then re-check — now exit 1 with the difference
docker exec sqemo-my mysql -uroot -ppw app -e "ALTER TABLE CUST DROP COLUMN EMAIL;"
npx sqemo-mcp lint "Online Shop Example.erd.json" --db "mysql://root:pw@localhost:13306/app"

# 5) clean up
docker rm -f sqemo-my

Swap mysql:8 / the mysql:// URL for postgres:16 / postgresql://postgres:pw@localhost:15432/app (port -p 15432:5432) to try PostgreSQL. Tip: match --dialect to the database — a schema exported for the wrong engine may use types the other one doesn’t have.

Where do the database credentials live?

Sqemo never stores them — you supply the URL at run time. Keep it out of the ERD file and out of version control:

  • Local, occasional runs: an environment variable or a .env file that’s in .gitignore. Avoid typing the password straight on the command line (it lands in your shell history).
  • MCP client (agent): put it in the client’s server config as an env value (e.g. Claude Desktop’s claude_desktop_config.json), which stays on your machine.
  • CI: your platform’s secret store — GitHub Actions Secrets, GitLab CI variables, etc. Never in the workflow file.

Strongly recommended: give the tool a read-only database account. It only queries information_schema / the catalog, so a read-only account loses nothing — and if the secret ever leaks, the blast radius is limited to schema structure, not your data.

Put it in CI (GitHub Actions, step by step)

The point of drift checking is catching it automatically — every push, every pull request — instead of remembering to run it by hand. Here’s the whole setup from scratch, no prior GitHub Actions experience assumed.

1. Commit your ERD to the repo

Export the project (toolbar → Export → Download project) and put the .erd.json in your repository, e.g. erd/app.erd.json, then commit and push it. This file is now your schema’s source of truth — changes to it go through pull-request review like any code.

2. Add the secrets

Secrets are encrypted values GitHub injects into the job; they never appear in your code or logs. In your repository on GitHub:

Settings → Secrets and variables → Actions → New repository secret. Add three:

NameValue
DATABASE_URLyour connection string, e.g. mysql://user:pass@host:3306/db (a read-only account is best)
SQEMO_EMAILyour Sqemo Pro account email
SQEMO_PASSWORDthat account’s password (set one first if you signed up with Google/GitHub — see Step 1)

3. Add the workflow file

Create .github/workflows/schema-drift.yml in your repo with this content:

name: Schema drift
on:
  push:
    paths: ["erd/**"]          # runs when the ERD changes
  pull_request:                # and on every PR, so drift blocks the merge
jobs:
  drift:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "22"
      - run: npx sqemo-mcp lint erd/app.erd.json --db "$DATABASE_URL" --ignore "flyway_*"
        env:
          DATABASE_URL:   ${{ secrets.DATABASE_URL }}
          SQEMO_EMAIL:    ${{ secrets.SQEMO_EMAIL }}
          SQEMO_PASSWORD: ${{ secrets.SQEMO_PASSWORD }}
  • ${{ secrets.NAME }} pulls in the values you added in Step 2 — never paste the real credentials into this file.
  • on: decides when it runs. As written: whenever the ERD changes on a push, and on every pull request. Change paths or add branches to taste.
  • SQEMO_EMAIL / SQEMO_PASSWORD sign in just for that job — no login step or stored token needed.

4. Push, and it runs

Commit the workflow file and push. From now on GitHub runs the check automatically on the events you listed — you don’t trigger it manually. Push a change under erd/, or open a PR, and the job starts on its own.

Optional: no database credentials in CI

If you’d rather not give CI a live database URL, have a job inside your network run pg_dump -s and compare against the dump file instead. No DATABASE_URL, and the --db becomes --schema:

      - run: npx sqemo-mcp lint erd/app.erd.json --schema schema.sql --dialect postgres
        env:
          SQEMO_EMAIL:    ${{ secrets.SQEMO_EMAIL }}
          SQEMO_PASSWORD: ${{ secrets.SQEMO_PASSWORD }}

Optional: check against a server ERD instead of the file

--erd <id> uses an ERD saved in your Sqemo account as the baseline, so you skip committing a file. The CI account must have read access to it.

      - run: npx sqemo-mcp lint --erd <erd-id> --db "$DATABASE_URL"

Trade-off worth knowing: a committed .erd.json is pinned and reviewed — it changes only through a PR, and old commits re-check against their own baseline. A server ERD is the current, mutable standard, so if someone edits it in the app, the CI result can change with no code change. For reproducible PR gating the committed file is the safer default; use --erd when your team deliberately treats the server ERD as the single live standard.

Where do the results show up?

In GitHub, not in Sqemo. Sqemo does not collect or display your CI runs — the drift check is a command that exits 0 (pass) or 1 (drift), and GitHub reports that like any other check:

  • On a pull request, it appears as a status check — green tick or red ✗ next to the PR, with drift able to block the merge if you make the check required (Settings → Branches → branch protection).
  • In the Actions tab, each run’s full log lists exactly what drifted ([missing_column] CUST.EMAIL, …).
  • GitHub emails you (per your notification settings) when a run you’re involved in fails.

So the loop is: push → GitHub runs it → you see red/green on the PR and the details in the Actions log. There’s nothing to check back inside Sqemo.

Security summary

  • Read-only: only information_schema / the catalog is queried; the connection is opened read-only. The tool never writes to your database.
  • Your database URL is used by the local (or CI) process only and is never sent to Sqemo servers.
  • Prefer a read-only DB account, and the --schema dump path when you’d rather not hand credentials to CI at all.