@mmtr-tech/postgres-mcp
v0.2.0
Published
Model Context Protocol server for PostgreSQL (single DATABASE_URL or multi-target YAML catalog)
Maintainers
Readme
@mmtr-tech/postgres-mcp
MCP-сервер для PostgreSQL. Один процесс — одна БД (DATABASE_URL) или несколько targets из YAML (TARGETS_FILE). Tools: list_targets / list_tables / describe_table / query.
English: README.md
Быстрый старт
cp .env.example .env
npm install
npm run test:unit
npm run typecheck
npm run devCursor mcp.json
Одна БД (без YAML)
{
"mcpServers": {
"db-orders": {
"command": "npx",
"args": ["-y", "@mmtr-tech/postgres-mcp"],
"env": {
"DATABASE_URL": "postgresql://mcp_ro:SECRET@host:5432/orders",
"READ_ONLY": "true"
}
}
}
}Параметр target в tools необязателен. list_targets вернёт один target default.
Несколько БД (YAML-каталог)
Не задавайте одновременно DATABASE_URL и TARGETS_FILE — будет ошибка при старте.
{
"mcpServers": {
"pg-stand": {
"command": "npx",
"args": ["-y", "@mmtr-tech/postgres-mcp"],
"env": {
"READ_ONLY": "true",
"TARGETS_FILE": "/absolute/path/to/pg-targets.yaml"
}
}
}
}Пример каталога — pg-targets.example.yaml:
defaults:
url: postgresql://readonly_user:[email protected]:5432/{db}
targets:
orders: {}
inventory: {}
archive:
url: postgresql://readonly_user:[email protected]:5432/archive{db} заменяется на имя target. Для разных стендов лучше отдельный MCP + YAML (prod часто Disabled), а не смешивать окружения в одном файле.
После изменений — Restart Cursor.
Переменные
| Переменная | Обязательно | Описание |
|------------|-------------|----------|
| DATABASE_URL | одно из | Одна БД: postgresql://user:pass@host:5432/dbname |
| TARGETS_FILE | одно из | Путь к YAML-каталогу (лучше абсолютный) |
| READ_ONLY | нет (default true) | true / false |
Ровно одна из DATABASE_URL / TARGETS_FILE. Строки из одних пробелов считаются пустыми.
Tools
list_targets— список БД (defaultв single-режиме)list_tables— таблицы и view (target?,schema?)describe_table— колонки (table,target?,schema?, default schemapublic)query— одна SQL statement (sql,target?)
При TARGETS_FILE передавайте target= (обязателен в runtime). При только DATABASE_URL — target можно не указывать.
При READ_ONLY=true в query допускаются только SELECT / WITH … SELECT. Ответ обрезается до 200 строк (truncated), timeout 30s. JOIN между разными logical DB — два вызова query.
Защита: что даёт MCP и чего не даёт
При READ_ONLY=true:
- MCP отклоняет не-SELECT и multi-statement до отправки в БД
- MCP выполняет запрос в транзакции с
SET TRANSACTION READ ONLY - Timeout и лимит строк ограничивают «тяжёлые» выборки
Флаг не гарантирует 100% защиту. Обход проверки SQL в приложении теоретически возможен; SELECT по-прежнему читает всё, к чему есть GRANT у роли; при READ_ONLY=false модель может менять данные в рамках прав подключения.
Полная гарантия read-only — только отдельный пользователь БД с правами
SELECT(без INSERT/UPDATE/DELETE/DDL).READ_ONLY=trueв MCP — дополнительный барьер для ИИ, не замена RO-роли в Postgres.
Рекомендация для проверки данных: READ_ONLY=true и URL с read-only ролью. READ_ONLY=false — только осознанно.
Лицензия
MIT
