Skip to main content
Glama
david-mogbeyi

db-readonly-mcp

db-readonly-mcp

Сервер MCP, который даёт ИИ-ассистенту (Claude Code, Claude Desktop или любому другому MCP-клиенту) защищённый, только для чтения доступ к базе данных Postgres. Можно спросить что-то вроде «покажи всех мерчантов, созданных вчера» — и ассистент напишет SQL и выполнит его через этот сервер, который гарантирует, что запрос сможет только читать данные.

Только Postgres — другие базы данных не поддерживаются.

Зачем это существует

Предоставление ассистенту прямого доступа к вашей базе данных действительно полезно для отладки, исследования данных и ответов на вопросы вида «сколько X» без необходимости писать скрипт каждый раз. Риск очевиден: LLM может галлюцинировать или быть спровоцирован на написание деструктивного запроса. Этот сервер существует, чтобы свести этот риск почти к нулю, используя несколько независимых уровней защиты, а не полагаясь на какой-то один.

Related MCP server: Postgres Scout MCP

Модель безопасности

Многоуровневая, в порядке степени доверия к каждому уровню:

  1. Роль БД — подключение использует выделенную роль Postgres с грантами только на SELECT. Это настоящая граница: даже если все остальные уровни будут обойдены, роль не сможет писать.

  2. Валидация запросов — отклоняется всё, что не является одиночным оператором SELECT/WITH ... SELECT (никаких операторов, разделённых точкой с запятой, никаких ключевых слов DDL/DML).

  3. Принудительный LIMIT — каждый запрос оборачивается в SELECT * FROM (...) LIMIT N, с ограничением сверху MAX_LIMIT независимо от того, что запрошено.

  4. statement_timeout — запросы прерываются после STATEMENT_TIMEOUT_MS.

  5. Журнал запуска — при старте в stderr выводится подключённая база данных/пользователь, чтобы было очевидно, к какой БД вы подключены, до выполнения любого запроса.

Направляйте этот сервер только на dev/test/staging базу данных — никогда на production. Уровни 2–5 — это эшелонированная защита; уровень 1 (роль БД) — единственный уровень, которому действительно стоит доверять, и даже ему не стоит доверять прод-данные.

Требования

  • Node.js >= 20

  • База данных Postgres, в которой вы можете создать роль

  • MCP-клиент (например, Claude Code, Claude Desktop или любой другой клиент, поддерживающий MCP-серверы через stdio)

Установка

1. Клонирование и установка

git clone https://github.com/david-mogbeyi/db-readonly-mcp.git
cd db-readonly-mcp
npm install

2. Создание роли только для чтения

Выполните это для вашей целевой базы данных Postgres — замените имя роли, пароль, имя базы данных и схему/владельца, если ваше приложение использует что-то кроме public:

CREATE ROLE myapp_readonly WITH LOGIN PASSWORD '<choose-a-password>';
GRANT CONNECT ON DATABASE myapp TO myapp_readonly;
GRANT USAGE ON SCHEMA public TO myapp_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO myapp_readonly;

-- Keeps future tables (new migrations) readable automatically, without
-- re-running this grant every time the schema changes.
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO myapp_readonly;

Если ваша схема не public или у вас несколько схем, повторите строки GRANT USAGE/GRANT SELECT/ALTER DEFAULT PRIVILEGES для каждой из них. Этот сервер в настоящее время запрашивает только схему public для list_tables/describe_table, но query_readonly может обращаться к любой схеме, к которой роли предоставлен доступ.

3. Настройка

cp .env.example .env

Отредактируйте .env и задайте DATABASE_URL — строку подключения роли только для чтения:

DATABASE_URL=postgresql://myapp_readonly:<password>@localhost:5432/myapp

Остальные переменные см. в разделе Конфигурация ниже.

4. Сборка

npm run build

Это компилирует src/ в dist/ через tsc. Повторно запускайте после получения изменений или правки исходного кода.

Регистрация в MCP-клиенте

Claude Code

В проекте, из которого вы хотите выполнять запросы, добавьте .mcp.json (или отредактируйте существующий):

{
  "mcpServers": {
    "db-readonly": {
      "command": "node",
      "args": ["/absolute/path/to/db-readonly-mcp/dist/index.js"],
      "env": {
        "DATABASE_URL": "postgresql://myapp_readonly:<password>@localhost:5432/myapp"
      }
    }
  }
}

Замените /absolute/path/to/db-readonly-mcp на путь, куда вы клонировали этот репозиторий. Перезапустите Claude Code (или переподключите MCP-серверы), чтобы изменения вступили в силу.

Также можно зарегистрировать его глобально, а не для конкретного проекта — см. документацию Claude Code MCP по claude mcp add и вариантам области действия.

Claude Desktop / другие MCP-клиенты

Любой клиент, поддерживающий MCP-серверы через stdio, может использовать это так же: укажите ему node /absolute/path/to/db-readonly-mcp/dist/index.js с DATABASE_URL (и при необходимости остальными переменными окружения ниже), заданными в его окружении. См. документацию вашего клиента о том, где находится конфигурация MCP-сервера — для Claude Desktop это claude_desktop_config.json с той же структурой command/args/env, что и выше.

Конфигурация

Вся конфигурация задаётся через переменные окружения (в .env для локальных запусков или в блоке env конфигурации вашего MCP-клиента).

Переменная

Обязательная

По умолчанию

Описание

DATABASE_URL

Да

—

Строка подключения Postgres для роли только для чтения.

DEFAULT_LIMIT

Нет

100

Лимит строк, применяемый, когда запрос не указывает свой.

MAX_LIMIT

Нет

1000

Жёсткий потолок возвращаемых строк независимо от запрошенного.

STATEMENT_TIMEOUT_MS

Нет

5000

Postgres statement_timeout для каждого запроса, в миллисекундах.

Инструменты

Сервер предоставляет ассистенту три инструмента:

list_tables

Выводит список таблиц в схеме public. Без аргументов.

→ [
    { "table_name": "merchants" },
    { "table_name": "orders" },
    ...
  ]

describe_table(table)

Колонки, типы, допустимость NULL и значения по умолчанию для таблицы в схеме public.

{ "table": "merchants" }
→ [
    { "column_name": "id", "data_type": "uuid", "is_nullable": "NO", "column_default": "gen_random_uuid()" },
    { "column_name": "created_at", "data_type": "timestamp with time zone", "is_nullable": "NO", "column_default": "now()" },
    ...
  ]

query_readonly(sql, limit?)

Выполняет один защищённый оператор SELECT (или WITH ... SELECT). limit необязателен и ограничивается сверху MAX_LIMIT, даже если передано большее значение.

{ "sql": "SELECT id, name, created_at FROM merchants WHERE created_at > now() - interval '1 day'" }
→ { "rowCount": 3, "rows": [ { "id": "...", "name": "...", "created_at": "..." }, ... ] }

Всё, что не является одиночным оператором SELECT/WITH — несколько операторов, DDL, DML, SET и т. д. — отклоняется до обращения к базе данных, с объяснением причины.

Локальная разработка

npm run dev   # runs src/index.ts directly via tsx, loads .env via Node's --env-file

Структура проекта

src/
  index.ts    # MCP server setup and tool definitions
  sqlGuard.ts # query validation (layer 2 of the safety model)
  db.ts       # Postgres pool setup (statement_timeout, pool size)
  config.ts   # env var loading/validation

Устранение неполадок

  • «DATABASE_URL environment variable is required» — .env отсутствует или не загружается; убедитесь, что он существует (из cp .env.example .env) и что блок env вашего MCP-клиента или npm run dev/npm start его подхватывает.

  • Сервер при запуске логирует не ту базу данных/пользователя — проверьте DATABASE_URL; журнал запуска (connected as "..." to database "...") выводится именно для того, чтобы это было легко заметить до выполнения любого запроса.

  • «Query rejected: ...» — запрос либо не был одиночным оператором SELECT/WITH, либо содержал запрещённое ключевое слово. Это уровень 2 модели безопасности работает как задумано, а не ошибка.

  • Запрос зависает, затем завершается ошибкой — скорее всего, сработал STATEMENT_TIMEOUT_MS; увеличьте его в .env, если вашей нагрузке действительно нужно больше времени, или оптимизируйте запрос.

Участие в разработке

Приветствуются issues и pull request'ы. Это намеренно небольшой, проверяемый инструмент — цель в том, чтобы модель безопасности оставалась достаточно простой для полного прочтения, а не превращалась в универсальный конструктор запросов.

Лицензия

MIT

Related MCP Connectors

Related MCP Servers

  • F
    license
    A
    quality
    D
    maintenance
    Enables AI assistants to interact with PostgreSQL databases using natural language queries, providing secure read-only access to database schemas and SQL translation capabilities.
    6
    8 npm
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to safely explore, analyze, and maintain PostgreSQL databases with read-only mode by default, SQL injection prevention, query performance analysis, and optional write operations.
    52 npm
    Apache 2.0
  • F
    license
    A
    quality
    C
    maintenance
    Enables read-only exploration of a Postgres database using natural language, with multiple safety layers to prevent any modifications.
    5
    -
  • 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.
    42 npm
    MIT