Skip to main content
Glama

DryRun PostgreSQL MCP

Это PostgreSQL MCP-сервер, которому не нужно подключение к продакшену.

dryrun даёт AI-агентам, IDE и CI полное понимание схемы. На основе офлайн-снимка, а не живого подключения к базе данных. Проверяйте схему, валидируйте запросы, оценивайте безопасность миграций и исследуйте графы внешних ключей. Всё без учётных данных, покидающих машину DBA.

dryrun — часть набора boringSQL наряду с RegreSQL и Fixturize.

Проблема

LLM/AI-ассиcтенты для кода очень хорошо пишут код и SQL-запросы. Но они слепы. Они не знают вашу схему, ваши индексы или ваши ограничения. Они могут сгенерировать миграцию, которая ставит блокировку ACCESS EXCLUSIVE на самой нагруженной таблице и кладёт ваше приложение.

Некоторые PostgreSQL MCP-серверы просят вас дать доступ к базе данных. А для выполнения административных задач может понадобиться привилегия SUPERUSER. Это буквально напрашиваться на проблемы.

Мы уже видели, к чему это приводит: продакшен-базы, уничтоженные AI-агентами, и SQL-инъекции в MCP-серверах, которые должны были быть read-only.

Модели не нужно обращаться к запросам к вашей базе данных. Ей нужно понимать вашу схему: структуру, ограничения, статистику и поведение, зависящее от версии PostgreSQL. Это знание структурно. Оно меняется, когда вы выкатываете миграцию, а не между запросами.

Related MCP server: pg-lens-mcp

Возможности DryRun

dryrun — это два компонента: CLI-инструмент и MCP-сервер. CLI извлекает и анализирует схему. MCP-сервер передаёт этот анализ AI-ассистентам. Они разделены намеренно.

CLI — извлечение и анализ

CLI подключается к вашей базе данных PostgreSQL, интроспектирует полный каталог (таблицы, представления, индексы, ограничения, секции, функции, enum, политики RLS, триггеры, расширения, GUC) и сохраняет снимок в .dryrun/history.db. Это снимок — источник истины для всего остального.

Как только у вас есть снимок, CLI работает офлайн:

  • Линтинг — более 20 правил конвенций (именование, типы, первичные ключи, временные метки, секционирование) и 13 правил структурного аудита (дублирующиеся индексы, покрытие FK, циклические FK, настройка vacuum)

  • Безопасность миграций — анализ типов блокировок, оценка времени выполнения, проверка заставления перезаписи таблиц, безопасные альтернативы для каждого DDL-выражения

  • Валидация запросов — разбор SQL через libpg_query, проверка ссылок на колонки на основании реальной схемы, обнаружение антипаттернов

  • Сравнение снимков — сравнение схемы, статистики планировщика или активности между снимками; обнаружённые расхождения с живой базой

  • Query stats — собирает pg_stat_statements по узлам, превращает варианты ORM-запросов в фигуры, сравнивает два снятых снимка, чтобы найти новые или замедленные запросы

  • Multi-node stats — статистика по репликам, точки seq_scan высокого использования, расхождения маршрутизации

MCP-сервер — дайте своему AI-ассистенту «мозг» для схемы

MCP-сервер читает тот же снимок. Он предоставляет 14 инструментов через stdio или SSE: исследование схемы, валидация запросов, анализ планов, проверка миграций, линтинг, состояние V-que и сохранённые топовые запросы pg_stat_statements. При подключении к живой базе данных подключаются ещё три (explain_query, check_drift, columnar_report). Ваш AI-ассистент понимает вашу базу данных, пока пишет SQL.

Подключение к БД не требуется. Ассистент никогда не видит учётных данных.

Почему офлайн

Контекст схемы должен жить в файле, а не в живом подключении. Типы столбцов, оценки размера, определения индексов, связи по внешним ключам и версию PostgreSQL можно экспортировать один раз и закоммитить в репозиторий. Один человек с доступом к базе делает снимок схемы. Все остальные — и люди, и AI-агенты — получают ещё полную информацию о схеме без credential.

Учётные данные не должны уходить с машины DBA. Если MCP-серверу для полезной работы необходим DATABASE_URL, то каждый разработчик, который его использует, получит доступ к продакш базе. Это проблема безопасности, которая никак не связана с инструментами AI.

Сервер должен выполнять анализ, а не быть прокси. Возвращать сырой вывод \d+ — это лишь не прошхое то, что вы просто вставляете его в чат. Ценность — в интерпретации этих данных: проверять, безопасна ли миграция для вашей версии PostgreSQL, отмечать отсутствующие индексы по внешним ключам и сверять ссылки на столбцы с реальной схемой.

Установка

Homebrew:

Homebrew 6.0 требует, чтобы сторонние tap стали доверенными, пре все их формулы могут загружаться:

brew trust --tap boringsql/boringsql
brew install boringsql/boringsql/dryrun

На Homebrew 5.x и старее пропустите шаг brew trust. Если не хотите доверять всему tap, доверьте только формуле командой brew trust --formula boringsql/boringsql/dryrun.

npm / npx:

Если у вас уже есть Node.js, можно запустить dryrun без какой-либо установки:

npx @boringsql/dryrun --version

Это скачает преднастроенный бинарник для вашей платформы (darwin-arm64, linux-x64, linux-arm64), кэширует его и печатает версию. Чтобы добавить dryrun в PATH на постоянной основе:

npm install -g @boringsql/dryrun
dryrun --version

npm-пакет по-прежнему содержит тот же Go-бинарник; все команды CLI работают идентично. Команды вроде lint сначала нуждаются в снимке схемы — смотрите раздел Быстрый старт. Готовые бинарники покрывают macOS (Apple Silicon и Intel), Linux (x64 и arm64) и Windows x64. На других платформах (Alpine/musl, Windows arm64) используйте Homebrew или соберите из исходников.

Из исходников:

Требуется Go 1.26+. Если его нет — установите с go.dev/dl.

git clone https://github.com/boringsql/dryrun.git
cd dryrun
go build -o bin/dryrun ./cmd/dryrun

Бинарник будет в bin/dryrun.

Демо за 30 секунд

С установленным dryrun можно проанализировать готовый снимок схемы из клона этого репозитория, без БД и подготовки:

git clone https://github.com/boringsql/dryrun.git
cd dryrun/examples/demo
dryrun lint

(Устанавливали через npm или Homebrew, но не клонировали репозиторий? Тогда у вас не будет examples/demo — переходите в Быстрый старт, чтобы указать dryrun на свою схему. Пример вывода под lint показан ниже.)

[ERROR] public.audit_log: table has no primary key
       fix: add a primary key (bigint GENERATED ALWAYS AS IDENTITY recommended)
[WARN ] public.audit_log: gap in range partitions: ends at '2024-07-01' but next starts at '2024-10-01'
       fix: inserts into the gap will fail unless a DEFAULT partition exists
[ERROR] public.task_comments: table has no primary key
       fix: add a primary key (bigint GENERATED ALWAYS AS IDENTITY recommended)
[WARN ] public.projects.created_at: timestamp column uses timestamp without time zone instead of timestamptz
       fix: use timestamptz for timestamp columns
[ERROR] public.tasks.project_id: FK 'tasks_project_id_fkey' on column(s) (project_id) has no covering index
       fix: add an index on FK columns to avoid sequential scans on DELETE/UPDATE
[WARN ] public.users.email: column 'email' uses character varying(255), prefer text
       fix: VARCHAR(n) adds a hidden CHECK constraint with no performance benefit
[WARN ] public.user_notifications: table is missing 'created_at' column
       fix: add: created_at timestamptz NOT NULL DEFAULT now()

26 finding(s): 6 error, 20 warning, 0 info (13 tables checked)

Не нужна никакая база данных. Всё работает из офлайн-снимка.

То же самое демо работает через MCP. Из examples/demo зарегистрируйте сервер для вашего ассистента:

claude mcp add dryrun -- npx -y @boringsql/dryrun mcp-serve

Затем запросите оттуда: «Какие у меня есть таблицы и что в них не так?»

MCP-сервер

Одна команда подключает сервер к вашей AI-платформе. setup обнаруживает Claude Code, Cursor, Codex и Zed, записывает MCP-конфиг агента и добавляет специальную директиву в AGENTS.md/CLAUDE.md, чтобы агент проверял схему перед написанием SQL:

dryrun setup

Чтобы выбрать агенты самостоятельно или запустить из неинтерактивного shell, передайте --agents:

dryrun setup --agents=claude,cursor   # or: all

Чтобы зарегистрировать сервер вручную:

# for claude code
claude mcp add dryrun -- dryrun mcp-serve

# for codex
codex mcp add dryrun -- dryrun mcp-serve

Если вы собирали из исходников, укажите полный пусть к бинарнику:

claude mcp add dryrun -- /path/to/dryrun mcp-serve

Или, не выполняя ничего вручную, направьте клиент на npx:

claude mcp add dryrun -- npx -y @boringsql/dryrun mcp-serve

Клиентский конфиг для этой формы выглядит так:

{
  "mcpServers": {
    "dryrun": {
      "command": "npx",
      "args": ["-y", "@boringsql/dryrun", "mcp-serve"]
    }
  }
}

Сервер читает самый свежий снимок из .dryrun/history.db в текущем проекте. Никаких учетных данных БД не нужно — ассистент получает полное знание о схеме из офлайн-снимка.

Если снимка нет, сервер всё равно запускается, а при запросе его инструменты говорят, что схема не загружена. Снимите его командой dryrun init --db "$DATABASE_URL" или возьмите созданный коллегой (dryrun snapshot pull --from-path ./snapshots, см. Быстрый старт), затем вызовите у ассистента инструмент reload_schema. Новая схема подимется без перезапуска сервера.

Для проектов с несколькими базами данных запускайте свой dryrun mcp-serve для каждой БД и добавляйте на отдельную запись в конфиге клиента. Нативная поддержка многих баз данных внутри одного MCP-процесса отслеживается в #7.

Подробнее о настройке живой базы, SSE-транспорте и конфигурации Claude Desktop см. в Руководстве.

Быстрый старт

Есть два способа начать, выберите подходящий.

Вариант A: у вас есть доступ к базе

Если вы можете подключиться к экземпляру PostgreSQL (локальному, тестовому или боевому), всё делает одна команда:

dryrun init --db "$DATABASE_URL"

При этом создаются dryrun.toml (с [project] id и профилем по умолчанию), каталог данных .dryrun/, база копируется в .dryrun/history.db. Снимки ключаются по (project_id, database_id); устанавливайте database_id для каждого профиля, если проекте несколько баз данных (например, auth, billing). Полное описание конфигурации — в docs/dryrun-toml.md.

Вариант B: доступ к базе есть у другого человека

Человек с правом доступа —снимает базу один раз и передаёт результат в общий каталог — например, в репозиторий или в любое другое общее место:

dryrun init --db "$DATABASE_URL"
dryrun snapshot push --to-path ./snapshots

Он коммитит оба элементов: dryrun.toml и ./snapshots. Все остальные подтягивают изменения:

dryrun snapshot pull --from-path ./snapshots

snapshot pull загружает снимок в .dryrun/history.db. База для других не требуется.

Коммитить dryrun.toml — обязательно: снимки идентифицируются по (project_id, database_id), и dryrun init берёт database_id этого имени живого БД. Коллега, запустивший dryrun init без --db, получает другой database_id, и pull сообщит 0 copied, потому что будет искать у источника ключ, которого у него нет.

Отправленный снимок несёт вместе со схемой статистику планировщика и активности, так что работают и офлайн-инструменты, которым нужны размеры и данные о V-разрядке, — чего не умеет обычный JSON-экспорт. Если нужен реестр, а не простой каталог, см. dryrun remote add и snapshot push --remote. Чтобы передать читаемый JSON человеку или агенту, используйте dryrun dump-schema; это матричный вывод, не входные данные.

Далее используйте его

dryrun lint

Все команды работают офлайн из `/release? change? GXP17 replaces the command. There is no 'web. Change is automatically from .dryrun/history.db'? For "Then use it" we might need "Затем применяйте". But GXP17 should be paragraph after "Then use it". We'll include.

GXP17 after "### Затем используйте его"

"Все команды работают офлайн из .dryrun/history.db. Каждый проект имеет собственные dryrun.toml и .dryrun/, глобального состояния нет. Добавьте .dryrun/ в .gitignore.

Снимки хранятся в .dryrun/history.db, ключом служат (project_id, database_id). Это единственный источник схемы: MCP-сервер, lint и drift читают только его. Устаревший .dryrun/schema.json` от старой версии игнорируется."

Multi-node: захват активности с реплик

snapshot take выполняется против primary и записывает схему и статистику планировщика. Счётчики активности (idx_scan, n_dead_tup, время last vacuum) живут на каждой реплике, поэтому снимайте их отдельно:

dryrun --profile primary  snapshot take
dryrun --profile replica1 snapshot activity --from "$REPLICA1_URL" --label replica1
dryrun --profile replica2 snapshot activity --from "$REPLICA2_URL" --label replica2

Инструменты MCP describe_table (разбиение по узлам) и detect kind=anomalies затем показывают idx_scan по узлам, чтобы можно было заметить перекосы маршрутизации. См. docs/multi-node-stats.md.

Несколько баз в проекте

dryrun snapshot take ключает снимки по (project_id, database_id). Работает по умолчанию: project_id — имя вашей папки, database_id — настоящее имя БД из current_database():

dryrun init --db "$AUTH_DB"            # captures auth
dryrun snapshot take --db "$BILLING_DB" # captures billing into its own stream
dryrun snapshot list --db "$AUTH_DB"    # only auth snapshots

Для стабильных ссылок (чтобы list / diff работали без указания URL заново) объявите профили в dryrun.toml:

[project]
id = "myapp"

[profiles.auth]
db_url = "${AUTH_DATABASE_URL}"
database_id = "auth"

[profiles.billing]
db_url = "${BILLING_DATABASE_URL}"
database_id = "billing"

Затем:

dryrun --profile billing snapshot list
dryrun --profile billing snapshot diff --latest

Полное описание всех параметров профиля — в docs/dryrun-toml.md.

Команды для работы БД (init, probe, dump-schema, drift, stats apply, все подкоманды snapshot) принимают --profile, и если --db не передан, используют db_url из найденного профиля. lint работает офлайн: читает .dryrun/history.db и прикасается к live-базе, только если явно передан --db.

Примечание: MCP-сервер сейчас single-database. Он использует профиль по умолчанию. Альтернатива — запустить отдельный процесс dryrun mcp-serve на каждую базу. Поддержка нескольких баз внутри одного MCP-процесса — в планах ** номер #7 *).

Обмен снимками внутри команды

Ценность DryRun растёт в командной работе. Несколько разработчиков могут тянуть снимки из любого каталога, совместимого с POSIX.

Чтобы опубликовать снимки, необходимо:

cd project_name

# capture from the live DB (use cwd name for project name)
dryrun init --db "$DATABASE_URL"
dryrun snapshot take --db "$DATABASE_URL"
dryrun snapshot push --to-path ./snapshots --all

Затем разработчики смогут импортировать снимки в локальную историю:

dryrun snapshot pull --from-path ./shared/snapshots --all

Снимки адресуются по содержимому ({project}/{database}/{ts}-{hash}.json zby) и идемпотентен: при повторном дворе, анном деплое одного и того же снимка ничего не изменится.

Самое простое решение — отдельный git-репозиторий. Создайте его и добавьте в .gitattributes строку *.json.zst binary, чтобы git не пытался отображать изменения в бандликах.

Офлайн-инструменты (lint, check_migration, drift) начинают работать сразу после pull.

Нет сервера, нет его кредентций. То же обещание, что и раньше, только в офлайне.

Публикация снимков в OCI-реестр

Любой OCI-реестр может хранить снимки: GitHub Container Registry, Google Artifact Registry, Amazon ECR, Docker Hub, Harbor или собственный экземпляр. Реестр берёт на себя аутентификацию, хранение и контроль доступа, поэтому запускать отдельный сервер не нужно.

Аутентифицируйтесь так же, как для docker push, зарегистрируйте удалённый реестр и выполните push:

docker login ghcr.io
dryrun remote add ghcr --ref ghcr.io/myorg/dryrun --default
dryrun snapshot take --push

snapshot take --push снимает и публикует снимок за одin шаг. Потребители затягивают его с помощью pull:

dryrun snapshot pull --remote ghcr

pull по умолчанию загружает только последний снимок, поэтому «холодные» pull (свеж-ж-окржения CI, пустая history.db) остаются по-прежнему лёгкими, независимо от того, скольто истории хронistory в реестре. Используйте --full, чтобы добрать всю историю, или --since 7d (2w, 24h or UTC-дат, 2026-01-01) for an interval. push always отправляет ввю локальную истоin ``, but since we are dealing with content hash, only one push, only new entries each time are recorded.

--ref— это базовое значенние реестра. Под ней (its) каждая база данных получает собственный репозиторий— <ref>/<project_id>/<database_id>, так что для базы данных auth in the application myapp path is ghcr.io/myorg/dryrun/myapp/auth. Снимки соответствуют OCI-артифактам, адресуемым по контентному хэшу, поэтому отправка одного или того же снимка дважды ничего не меняет, а общие blobs дедуплицируются в реестре. Google Artifact Registry just run gcloud auth configure-docker us-docker.pkg.dev instead of docker login; all the rest is the same.

Authentication. Бy default dryrun re-uses your Docker credentials (~/.docker/config.json) and helpers, so any registry you can atenticate in docker login to work with without additional configuration. Two overrides are enough for everything else:

  • --token-env VAR считывает статический bearer-токен из переменной окржения для реестров, выдащих коротко-живущие токенs (например, --token-env GAR_TOKEN, полученное через gcloud auth print-acess-token).

  • --auth th uses Google Application Default Credentials напряму». Нет, то есть Google Artifact Registry / Container Registry will work after gcloud auth login (или ключа сервисного аккаунта, через GOOGLE_APPLICATION_CREDENTIALS) without configure-docker. The ADC token will be обновлен автоматически.

Смотрите: docs/dryrun-toml.md — там remote для отдельных профилей и один поток данных на несколько проэктов.

Дополнительно

Лицензия

Лицензия BSD 2-Clause

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides AI-IDEs with real-time access to PostgreSQL and Supabase database schemas through the Model Context Protocol, enabling smarter code generation in tools like Cursor, Windsurf, and VS Code + Cline.
    10
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Securely connect AI assistants to PostgreSQL databases with read-only access, schema discovery, querying, and performance analysis tools.
    7 npm
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to query PostgreSQL, inspect schemas, and explain queries, designed for local and development databases with read-only safety by default.
    19 npm
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Enables AI agents to format SQL, explain queries in plain English, analyze schemas, build queries from natural language, and generate migrations, all without requiring a database connection.
    5
    8 npm
    MIT