Skip to main content
Glama

mcp-dbserver

Самодельный MCP-сервер, который предоставляет AI-агенту — Claude Code, Claude Desktop или любому MCP-совместимому клиенту — доступ только для чтения с ограничением прав к трем движкам баз даннных одновременнно: PostgreSQL (с pgvector), DynamoDB и MongoDB Atlas (с Atlas Vector Search). Это личный проект, расширяющий более чем 17-летний опыт работы с мультиоблачной архитектрой баз даннных в область AI/агентных инструментов: цель не в том, чтобы «агент мог выполнять запросы к базе даннных», а в демонстрации той же диспиплины наименших привилегий и многоуровневой защиты, которую потребовала бы производственная эталонная архитектра, примененной к вызывающей стороне, которая являтся LLM, а не сервисом.

Никакие даннные работодателя, схемы или бизнес-логика (текущие и прошедшие) не присуствуют в этом репозитории — только публичные или синтетические даннные, созданные специално для этого проекта.

Архитект ра

flowchart LR
    Client["MCP client<br/>(Claude Code / Claude Desktop)"]

    subgraph Server["mcp-dbserver (stdio)"]
        direction TB
        Tools["Fixed tool surface<br/>(no generic 'run query' tool)"]
        Guard["guardrails.py + allowlist.py<br/>read-only + row-limit re-check"]
        Tools --> Guard
    end

    Client -- "MCP tool calls" --> Tools

    Guard --> PG[("PostgreSQL + pgvector<br/>RDS, IAM or password auth")]
    Guard --> DDB[("DynamoDB<br/>fixed table-target registry")]
    Guard --> Mongo[("MongoDB Atlas + Vector Search<br/>fixed collection-target registry")]

Каждая стрелка в базу даннных — это именованная операция из списа разрешённых, а не сырой SQL, сырой MongoDB-фильтр или сырое услове ключа DynamoDB. Полное описание — в ARCHITECTURE.md.

Related MCP server: Secure RDS Read-Only MCP Server

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

Именно эта часть проекта призвана отличить его от типичного демо «направь агента на базу данных». Полные подробности (включая две вещи, обнаруженные при реальном тестировании защитных механизмов, а не только при их проектировании) — в ARCHITECTURE.md; кратко:

  1. Только чтение — и никаких исключений. Для любого движка в v1 не существует инструментов записи, обновления или удаления. Версия с поддержкой записи, если она вообще появится, — это отдельный проект с собственной моделью угроз.

  2. Документированноая граница, обнаруженная тестированием. Ограничение «нет инструментов записи» сдерживает то, что агент может сделать через протокол MCP. Оно не может ограничить клиента, способного выполнять код (такого как Claude Code, в отличие от чат-клиента Claude Desktop), у которого есть независимый доступ к тем же учётным данным. При тестировании Claude Code, как и ожидалось, не нашёл инструмента удаления — а затем написал собственный скрипт на psycopg и попытался выполнить удаление напрямую, полностью в обход MCP-сервера. Ему это не удалось только потому, что у настроенной роли базы данных не было прав на запись. Это делает роль только для чтения на уровне БД/IAM настоящей последней линией обороны от клиента, способного выполнять код, — а не отсутствие метода записи в этом коде; это задокументировано явно, а не оставлено неявным.

  3. Никаких сырых запросов от агента. Каждая операция — это именованная форма из списка разрешённых с типизированными параметрами — фиксированный SQL-шаблон (Postgres), фиксированный реестр целевых таблиц/коллекций плюс типизированный ключ (DynamoDB/MongoDB) — и никогда не документ-фильтр, выражение условия ключа или SQL-строка, построенная из ввода агента. Более ранний черновик инструмента векторного поиска принимал имя таблицы/колонки как прямой аргумент; это было обнаружено и исправлено (реалная поверхность SQL-инъекции через f-string интерполяцию) до того, как сервер был подключён к живому клиенту.

  4. Многоуровневая защита во время выполнения. Даже разрешённый Postgres-запрос повторно проверяется модулем guardrails.py перед выполением (отклоняет всё, что не является SELECT/WITH, отклоняет несколько инструкций в одном запросе, принудительно ограничивает максимум строк независимо от запрошенного), а каждое соединение устанавливает default_transaction_read_only = on на уровне базы данных.

  5. Учётные данные: только переменные окружения, никогда не логируются и не зашиваются в код. Поддерживается аутентификация RDS IAM для базы данных, и она предпочтительнее сохранённого пароля Postgres (новый токен примерно на 15 минут на каждое подключение через rds:GenerateDBAuthToken, вообще без долгоживущего секрета БД).

Поддерживаемые движки и инструменты

Движок

Инструменты

PostgreSQL + pgvector

query_postgres, list_postgres_queries, semantic_search_documents

DynamoDB

list_dynamodb_tables, get_dynamodb_item, list_dynamodb_items, count_dynamodb_items

MongoDB Atlas + Vector Search

list_mongodb_collections, get_mongodb_document, list_mongodb_documents, count_mongodb_documents, semantic_search_mongodb

Полные описания каждого инструмента и обоснование каждого из них — в ARCHITECTURE.md. semantic_search_documents и semantic_search_mongodb работают с одним и тем же демонстрационным набором данных и одной и той же локальной моделью эмбеддингов — специально для того, чтобы результаты pgvector и Atlas Vector Search можно было напрямую сравнивать.

Настройка

python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
cp .env.example .env   # fill in your own, personal, non-work credentials

Запустите тестовый набор (живая база данных не требуется — логика защитных механизмов и списков разрешённого покрыта модульными тестами на фейковых объектах для всех трёх движков):

pytest

Запустите MCP-сервер (транспорт stdio, для локального использования с Claude Code / Claude Desktop):

mcp-dbserver

Инструменты регистрируются только для тех движков, для которых заданы необходимые переменные окружения — например, если задан только POSTGRES_DSN, появятся только инструменты Postgres. Все переменные, для каждого движка, см. в .env.example.

Демонстрационный набор данных Postgres

data/demo_documents.jsonl — это небольшой синтетический набор из примерно 30 коротких объясняющих фрагментов о программном обеспечении и инфраструктуре (написан для этого проекта). Загрузите его и сгенерируйте эмбеддинги локально (ONNX-рантайм fastembed — офлайн, без внешнего API-ключа, без зависимостей torch/torchvision):

python scripts/load_demo_dataset.py
python scripts/smoke_test_postgres.py      # connectivity + read-only guardrail
python scripts/verify_demo_dataset.py      # row count + semantic search sanity check

DynamoDB

Таблицы не настраиваются через переменные окружения — доступные таблицы берутся из фиксированного реестра в engines/dynamodb.py (_TABLE_TARGETS). Задайте AWS_REGION (а также стандартные учётные данные AWS через переменные окружения, профиль или роль инстанса, ограниченные правами dynamodb:GetItem/Scan/DescribeTable на зарегистрированные ARN таблиц), чтобы включить инструменты *_dynamodb_*.

Демонстрационный набор данных MongoDB Atlas

Полностью повторяет настройку Postgres — тот же набор данных, та же модель эмбеддингов — так что результаты напрямую сопоставимы. Задайте MONGODB_URI/MONGODB_DATABASE (пользователь Atlas со встроенной ролью read, не readWrite), затем:

python scripts/load_demo_dataset_mongodb.py    # upserts data + creates the Atlas Vector Search index
python scripts/verify_demo_dataset_mongodb.py  # index builds asynchronously; re-run if search comes back empty

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

src/mcp_dbserver/
  guardrails.py        # read-only + row-limit enforcement, engine-agnostic
  allowlist.py          # named, parameterized Postgres query registry
  config.py              # env-var credential loading, per engine
  engines/
    postgres.py           # allowlisted queries + pgvector semantic search
    dynamodb.py             # fixed table-target registry, get/scan/count
    mongodb.py                # fixed collection-target registry, get/list/count/$vectorSearch
  server.py             # MCP entrypoint, registers tools per configured engine
tests/                   # guardrail/allowlist/engine unit tests, all three engines (no live DB needed)
scripts/                 # demo dataset loaders/verifiers, Postgres smoke test

Что я сделал бы иначе в производственном масштабе

Честное перечисление того, что v1 намеренно не решает, говорит больше, чем притворство, что проект полностью готов к продакшену:

  • Аутентификация клиент ↔ сервер. v1 работает через stdio и запускается клиентом напрямую как подпроцесс — граница процесса ОС и есть граница доверия, что нормально для локального однопользовательского использования и неприемлемо для всего остального. Сетевое развёртывание (HTTP/SSE, доступное более чем одному клиенту) требует API-ключей для каждого клиента, ограниченных по движкам, и завершения TLS перед сервером, прежде чем это станет чем-то большим, чем демо.

  • Наблюдаемость. Журналирования запросов или метрик пока нет. Как минимум перед любым сетевым развёртыванием: какая именованная операция/запрос была вызвана, когда и завершилась ли она успешно — и намеренно никогда значения параметров или содержимое строк, чтобы незаметно не создать в логах вторую копию данных.

  • Ограничение частоты запросов. Не реализовано; это становится важно только когда сервер станет доступен более чем одному локальному stdio-клиенту, но это пробел, который лучше назвать заранее, чем обнаружить под нагрузкой.

  • MySQL. Явно вне области действия v1. При добавлении следовал бы тому же шаблону «список разрешённого + защитные механизмы», что и Postgres, — новое проектирование не требуется, только обвязка для четвёртого движка.

  • Вопрос формы фильтров для DynamoDB/MongoDB стал проще, чем планировалось, а не сложнее. В исходном дизайне рассматривалась типизированная схема для каждого разрешённого фильтра DynamoDB/MongoDB. В итоге вышло меньше: фиксированный реестр целевых объектов плюс фиксированный небольшой набор именованных операций на движок, без какого-либо универсального инструмента find(filter) или query(key_condition). Это стоит отметить, потому что инстинкт построить DSL для валидации был более «эффектно звучащим» вариантом, а более простой оказался надёжнее закрывающим тот же пробел — нет всепрощающей формы, в которой могли бы спрятаться $where или произвольное условие ключа, потому что для неё нет поля.

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides read-only access to PostgreSQL databases via MCP, enforcing least-privilege roles, row-level security, masked views, and SQL AST guardrails to prevent data leakage and unauthorized operations, enabling AI agents to safely query sensitive production data.
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables read-only access to company data across PostgreSQL, MongoDB Atlas, and flat files through MCP tools, allowing AI assistants to query and retrieve information via natural language.
  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides governed, read-only PostgreSQL access for AI agents via MCP. Enforces schema/table allowlists, query limits, and audit events.
    MIT

View all related MCP servers

Related MCP Connectors

  • Analytical memory for AI agents: a real Postgres queried in plain English over MCP. One command.

  • Connect MCP clients to 2,000+ AI models without managing provider API keys.

  • A paid remote MCP for AI SDK data query MCP, built to return verdicts, receipts, usage logs, and aud

View all MCP Connectors

Latest Blog Posts

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/stanisraja/mcp_model'

If you have feedback or need assistance with the MCP directory API, please join our Discord server