Skip to main content
Glama
david-mogbeyi

db-readonly-mcp

db-readonly-mcp

AIアシスタント(Claude Code、Claude Desktop、その他のMCPクライアント)に、保護された読み取り専用のPostgresデータベースアクセスを提供するMCPサーバーです。「昨日作成された全マーチャントを取得して」のような質問をすると、アシスタントがSQLを作成し、このサーバーを通じて実行します。このサーバーはクエリがデータを読み取ることしかできないことを強制します。

Postgresのみ対応です。他のデータベースはサポートされていません。

なぜこれが存在するのか

アシスタントにデータベースを直接クエリさせることは、デバッグやデータ探索、「Xはいくつあるか」といった質問に毎回スクリプトを書かずに答えるために、実際に役立ちます。リスクは明らかです。LLMは幻覚を起こしたり、破壊的なクエリを書くように誘導されたりする可能性があります。このサーバーは、単一の防御に依存するのではなく、複数の独立した保護レイヤーによって、そのリスクをほぼゼロにするために存在します。

Related MCP server: Postgres Scout MCP

安全モデル

実際に信頼される度合いの順にレイヤー化されています:

  1. DBロール — 接続はSELECTのみの権限を持つ専用のPostgresロールを使用します。これが本当の境界です。他のすべてのレイヤーが迂回されたとしても、このロールは書き込みできません。

  2. クエリ検証 — 単一のSELECT/WITH ... SELECT文ではないもの(セミコロンで連結された文、DDL/DMLキーワードを含むもの)をすべて拒否します。

  3. 強制LIMIT — すべてのクエリはSELECT * FROM (...) LIMIT Nでラップされ、要求された値に関係なくMAX_LIMITで上限が設定されます。

  4. statement_timeout — クエリはSTATEMENT_TIMEOUT_MS後に強制終了されます。

  5. 起動時ログ — 起動時に接続先のデータベース/ユーザーをstderrにログ出力するため、クエリ実行前にどのDBを指しているかが明確にわかります。

このサーバーは必ずdev/test/stagingデータベースのみに向けてください。本番には絶対に向けないでください。 レイヤー2〜5は多層防御です。レイヤー1(DBロール)だけが実際に信頼すべきレイヤーであり、それでさえ本番データを扱うべきではありません。

要件

  • Node.js >= 20

  • ロールを作成できるPostgresデータベース

  • MCPクライアント(例:Claude Code、Claude Desktop、またはstdio経由でMCPサーバーをサポートするその他のクライアント)

セットアップ

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の行をスキーマごとに繰り返してください。このサーバーは現在list_tables/describe_tableではpublicスキーマのみをクエリしますが、query_readonlyはロールにアクセス権が付与された任意のスキーマを参照できます。

3. 設定

cp .env.example .env

.envを編集し、DATABASE_URLを読み取り専用ロールの接続文字列に設定します:

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

他の変数については、以下の設定を参照してください。

4. ビルド

npm run build

これによりtscを介してsrc/がdist/にコンパイルされます。変更をプルした後やソースを編集した後は再実行してください。

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 mcp addとスコープオプションについてはClaude Code MCPドキュメントを参照してください。

Claude Desktop / その他のMCPクライアント

stdio経由でMCPサーバーをサポートするクライアントは、同じ方法でこれを使用できます。DATABASE_URL(および必要に応じて以下の他の環境変数)を環境に設定した上で、node /absolute/path/to/db-readonly-mcp/dist/index.jsを指すようにします。MCPサーバー設定の場所についてはクライアントのドキュメントを参照してください。Claude Desktopの場合はclaude_desktop_config.jsonで、上記と同じcommand/args/envの形式を使用します。

設定

すべての設定は環境変数(ローカル実行では.env、MCPクライアント設定のenvブロック)で行います。

変数

必須

デフォルト

説明

DATABASE_URL

はい

—

読み取り専用ロールのPostgres接続文字列。

DEFAULT_LIMIT

いいえ

100

クエリで指定がない場合に適用される行数上限。

MAX_LIMIT

いいえ

1000

要求された値に関係なく、返される行数のハード上限。

STATEMENT_TIMEOUT_MS

いいえ

5000

すべてのクエリに対するPostgresのstatement_timeout(ミリ秒)。

ツール

このサーバーはアシスタントに3つのツールを公開します:

list_tables

publicスキーマ内のテーブルを一覧表示します。引数なし。

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

describe_table(table)

publicスキーマ内のテーブルの列、型、NULL許容性、デフォルト値。

{ "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から)、MCPクライアントのenvブロックまたはnpm run dev/npm startがそれを取得していることを確認してください。

  • 起動時にサーバーが誤ったデータベース/ユーザーをログ出力する — DATABASE_URLを確認してください。起動時ログ(connected as "..." to database "...")は、クエリ実行前にこれを簡単に検出できるように出力されています。

  • 「Query rejected: ...」 — クエリが単一のSELECT/WITH文でないか、許可されていないキーワードが含まれています。これは安全モデルのレイヤー2が意図通りに機能していることであり、バグではありません。

  • クエリがハングしてからエラーになる — おそらくSTATEMENT_TIMEOUT_MSに達しています。ワークロードが正当に長時間を必要とする場合は.envで引き上げるか、クエリを最適化してください。

コントリビューション

IssueとPRを歓迎します。これは意図的に小さく監査可能なツールです。目標は、一般的なクエリビルダーに成長させることではなく、安全モデルを全体を読めるほどシンプルに保つことです。

ライセンス

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