dryrun
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 --versionnpm-пакет по-прежнему содержит тот же 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 ./snapshotssnapshot 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. Он использует профиль по умолчанию. Альтернатива — запустить отдельный процесс
dryrunmcp-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 --pushsnapshot take --push снимает и публикует снимок за одin шаг. Потребители затягивают его с помощью pull:
dryrun snapshot pull --remote ghcrpull по умолчанию загружает только последний снимок, поэтому «холодные» 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 thuses Google Application Default Credentials напряму». Нет, то есть Google Artifact Registry / Container Registry will work aftergcloud auth login(или ключа сервисного аккаунта, черезGOOGLE_APPLICATION_CREDENTIALS) withoutconfigure-docker. The ADC token will be обновлен автоматически.
Смотрите: docs/dryrun-toml.md — там remote для отдельных профилей и один поток данных на несколько проэктов.
Дополнительно
Учебное руководство — офлайн-, online- и многоузловые сценарийи with полным спровочником инструментов
**Многоузловые характеристики — сбор статистики по всёму кластеру, правило агрегации и обнаружение дисбаланса реплик
**Статистика запросов — захват
pg_stat_statements, группировка по форме запроса и сравнение**Справочник конфигурации — профили
dryrun.toml, соглашения, remote и lint-прала**Стабильность CLI — какие команды stable, а какие в виде экспериментов
**Сеор безопасности — разделение CLI and MCP and маскирование[данных)
**boringSQL — blog и основная страница проэктов
**Страница dryrun — обзор и документация
**Don't let AI touch your production database - why most Postgres MCPs are unsafe and what
dryrundoes differently**RegreSQL — regression testing and
dryrun'companion**Fixturize — подмножество данных и маскирование production data for dev/test
Лицензия
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityFmaintenanceProvides 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.9MIT
- AlicenseNot gradedqualityCmaintenanceSecurely connect AI assistants to PostgreSQL databases with read-only access, schema discovery, querying, and performance analysis tools.9MIT
- FlicenseNot gradedqualityBmaintenanceEnables AI tools to understand a database, inspect schema, and run safe SELECT queries with SQL guardrails, plus optional codebase reading.
- AlicenseAqualityBmaintenanceA read-only MCP server for PostgreSQL schemas and their git history, enabling AI agents to inspect schema details, migrations, ERDs, missing indexes, circular foreign keys, and churn without write access.8AGPL 3.0
Related MCP Connectors
Query PostgreSQL databases in plain English — LLM-generated, safety-validated SQL.
Generate realistic, FK-consistent synthetic test data for your databases from your AI assistant.
The grounded data layer for any LLM: governed SQL, metrics, lineage and catalog over your data.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/boringSQL/dryrun'
If you have feedback or need assistance with the MCP directory API, please join our Discord server