MySQL MCPサーバーの使い方 — スキーマ検査と読み取り専用アクセスの設定
MySQL専用のMCPサーバーmcp-server-mysqlで、スキーマ検査と読み取り専用アクセスを設定する手順です。書き込み許可のフラグとPIIマスキングまで扱います。
MySQLには公式のMCPサーバーがありません。その中で環境変数による権限制御とPIIリダクションまで備えているのがbenborla/mcp-server-mysql(npmパッケージ@benborla29/mcp-server-mysql)です。スキーマの確認からクエリの実行までを、既定で読み取り専用のまま扱えます。汎用DB接続サーバーDBHubを軸にしたMCPからデータベースに接続する方法がすでにありますが、DBHubはPostgreSQL・MySQL・MariaDB・SQL Server・SQLiteを横断する分、MySQL固有の機能までは持ちません。この記事ではmcp-server-mysql固有の導入手順と、READONLY相当の環境変数設計、スキーマ検査の使い方に絞って扱います。読み取り専用設計そのものの一般論と、DBHubを使った最短接続の手順は、リンク先の記事に譲ります。
mcp-server-mysqlとDBHubは何が違うか
同じ「MCPでMySQLに触る」でも、狙っている作業の深さが違います。
| 項目 | DBHub(既存記事) | mcp-server-mysql |
|---|---|---|
| 対応DB | DBHub(既存記事)PostgreSQL / MySQL / MariaDB / SQL Server / SQLite | mcp-server-mysqlMySQLのみ |
| 権限制御 | DBHub(既存記事)既定で読み取り専用の一括制御 | mcp-server-mysql操作ごと(INSERT/UPDATE/DELETE/DDL)に個別フラグ |
| スキーマ単位の権限 | DBHub(既存記事)無し | mcp-server-mysqlデータベースごとに読み書きを個別設定可能 |
| PIIマスキング | DBHub(既存記事)無し | mcp-server-mysql結果セットの機密列を自動マスキング |
| 接続経路 | DBHub(既存記事)ローカル接続が中心 | mcp-server-mysqlSSHトンネル・Unixソケット・リモートHTTPまで対応 |
DBHubが複数DBへ横断的に安全接続することに寄せた設計なのに対し、mcp-server-mysqlはMySQL1本に絞った分、権限とデータ保護をより細かく作り込んでいます。複数のDB種別を1つのMCPサーバーでまとめて扱いたいならDBHub、MySQLだけを対象にスキーマごとの権限やPII保護まで踏み込みたいならmcp-server-mysqlという住み分けです。
インストールとClaude Codeへの接続
必要な環境はNode.js v20以上とMySQL 5.7以上(8.0以上を推奨)です。Claude Codeへの登録が最も簡単で、npx経由でパッケージを都度取得する形になります。
claude mcp add mcp_server_mysql \
-e MYSQL_HOST="127.0.0.1" \
-e MYSQL_PORT="3306" \
-e MYSQL_USER="readonly_user" \
-e MYSQL_PASS="your_password" \
-e MYSQL_DB="your_database" \
-- npx @benborla29/mcp-server-mysqlALLOW_INSERT_OPERATION・ALLOW_UPDATE_OPERATION・ALLOW_DELETE_OPERATIONは指定しなければ全てfalse扱いになるため、上記のコマンドだけで読み取り専用接続が成立します。接続確認はclaude mcp listとclaude mcp get mcp_server_mysql、あるいはClaude Code内で/mcpを実行します。すでにClaude Desktopで設定済みなら、claude mcp add-from-claude-desktopでその設定をそのまま取り込めます。
書き込み許可をどう設計するか — READONLY相当の環境変数
mcp-server-mysqlにはREADONLY=trueのような単一トグルはありません。その代わり、書き込み操作の種類ごとに個別の環境変数で許可します。
| 変数 | 既定値 | 効果 |
|---|---|---|
ALLOW_INSERT_OPERATION | 既定値false | 効果INSERTを許可するか |
ALLOW_UPDATE_OPERATION | 既定値false | 効果UPDATEを許可するか |
ALLOW_DELETE_OPERATION | 既定値false | 効果DELETEを許可するか |
ALLOW_DDL_OPERATION | 既定値false | 効果CREATE/DROP/ALTERなどDDLを許可するか |
MYSQL_DISABLE_READ_ONLY_TRANSACTIONS | 既定値false | 効果読み取り専用トランザクションの強制を無効化するか |
上4つがすべてfalseのままであれば、mysql_queryツールはSELECT系のクエリしか通しません。MYSQL_DISABLE_READ_ONLY_TRANSACTIONSは既定でfalse(つまり読み取り専用トランザクションが有効)になっており、この設定はSQLレベルでも書き込みを弾く二段目の防御です。公式ドキュメントもこの変数だけは注意喚起の記号付きで扱っており、安易にtrueへ変更しないほうが安全です。
さらに一歩進んだ制御として、データベースごとに権限を出し分けるスキーマ単位の権限設定があります。
SCHEMA_INSERT_PERMISSIONS=development:true,test:true,production:false
SCHEMA_UPDATE_PERMISSIONS=development:true,test:true,production:false
SCHEMA_DDL_PERMISSIONS=development:false,test:true,production:false
SCHEMA_DELETE_PERMISSIONS=development:false,test:true,production:falseこの設定なら、開発用DBには書き込みを許しつつ本番DBは読み取り専用のまま、という運用を1つのMCPサーバーで両立できます。複数DBを横断するマルチDBモード(MYSQL_DBを省略して起動する構成)では、MULTI_DB_WRITE_MODE=falseが既定で効き、個別のスキーマ権限設定を上書きしないかぎり全DBの書き込みが止まった状態になります。
スキーマ検査の使い方
接続後、Claudeにテーブル構成を尋ねるとmysql://tablesリソースが呼ばれ、接続先データベースの全テーブルとカラムのメタデータが返ります。「usersテーブルの構造を見せて」と聞けばカラム名・型・NULL許可・キー情報がまとまった形で返るため、スキーマ定義書を別途探す手間が省けます。
集計クエリも自然文で頼めます。「先月作成された注文の件数をステータス別に数えて」と聞けば、mysql_queryツールがSELECT文を組み立てて実行します。書き込み系のフラグをすべてfalseにしたまま運用していれば、誤ってUPDATE文が実行されるリスクなしにこの手の分析を任せられます。
複数のデータベースにまたがってスキーマを探索したい場合は、MYSQL_DBを省略してマルチDBモードで起動します。
claude mcp add mcp_server_mysql_multi \
-e MYSQL_HOST="127.0.0.1" \
-e MYSQL_PORT="3306" \
-e MYSQL_USER="readonly_user" \
-e MYSQL_PASS="your_password" \
-e MULTI_DB_WRITE_MODE="false" \
-- npx @benborla29/mcp-server-mysqlこの構成であれば「サーバー上にあるデータベースを一覧して、それぞれの主要テーブルを教えて」のような、DB単位をまたいだ探索も1つの接続で完結します。1つのMySQLインスタンスに複数サービスのDBが同居している開発環境で、都度接続を切り替えずに全体を見渡したいときに向いています。
PIIリダクションで機密列を自動マスキングする
mcp-server-mysql固有の機能として、クエリ結果に含まれる個人情報を自動でマスキングするPIIリダクションがあります。ENABLE_PII_REDACTION=trueを設定すると、列名からメールアドレスや電話番号らしき列を検出してマスキングします。検出対象はPII_EXTRA_COLUMNS(列名の部分一致)やPII_EXTRA_COLUMN_PATTERNS(正規表現)で追加でき、SELECT *やPII列への直接参照を許すかどうかもPII_ALLOW_SELECT_STAR・PII_ALLOW_REFERENCESで個別に制御できます。
さらに踏み込んで、スキーマそのものの参照を制限することもできます。PII_ALLOW_INTROSPECTIONをfalseのままにすると、PIIリダクションが有効な状態でのスキーマ参照(カラム名や型の取得)を許さなくなり、PII_BLOCK_INTROSPECTIONをtrueにすればスキーマ参照系のSQL文自体を一律で止められます。カラム名から個人情報の存在自体を推測されたくない、より厳格な運用向けの設定です。分析用途でClaudeに幅広くクエリを投げさせつつ、実際の個人情報は画面に出したくない場合に効く設計です。
パフォーマンスと安全弁を調整する
書き込みを止めるだけでなく、読み取りクエリ自体が重すぎて本番DBに負荷をかけることも避けたい場面があります。mcp-server-mysqlはそのための調整項目も持っています。
| 変数 | 既定値 | 効果 |
|---|---|---|
MYSQL_POOL_SIZE | 既定値10 | 効果コネクションプールの上限 |
MYSQL_QUERY_TIMEOUT | 既定値30000 | 効果クエリのタイムアウト(ミリ秒) |
MYSQL_RATE_LIMIT | 既定値100 | 効果1分あたりに許可するクエリ数 |
MYSQL_MAX_QUERY_COMPLEXITY | 既定値1000 | 効果クエリの複雑さスコアの上限 |
MYSQL_CACHE_TTL | 既定値60000 | 効果クエリ結果キャッシュの保持時間(ミリ秒) |
MYSQL_RATE_LIMITとMYSQL_MAX_QUERY_COMPLEXITYは、Claudeが会話の中で次々にクエリを投げても本番DBのCPUを食いつぶさないための安全弁です。分析用途で複雑なJOINを多用するなら複雑さスコアの上限を緩め、逆に本番DBに直結する用途なら既定値のまま絞っておくほうが安全です。同時接続数が多くなりがちな環境ではMYSQL_QUEUE_LIMIT(接続待ちキューの上限、既定100)とMYSQL_CONNECT_TIMEOUT(接続確立自体のタイムアウト、既定10000ミリ秒)も合わせて調整すると、プール枯渇時の挙動を制御しやすくなります。
クエリログを残したい場合はMYSQL_ENABLE_LOGGING=trueとMYSQL_LOG_LEVELを設定すれば、どのクエリがいつ実行されたかを追跡できます。稼働状況を継続的に監視したいならMYSQL_METRICS_ENABLED=trueでパフォーマンスメトリクスの収集も有効にできます。
接続方式のバリエーション
基本のホスト・ポート・ユーザー名・パスワード指定に加えて、いくつかの接続方式があります。リモートのMySQLに社内ネットワーク経由で繋ぐ場合はSSHトンネルをサポートしており、Unixソケット経由の接続もMYSQL_SOCKET_PATHで指定できます。認証情報をローテーションしたい場合はMYSQL_CONNECTION_STRINGでmysqlコマンド形式の接続文字列をまとめて渡す方法もあり、個別の環境変数より扱いやすい場面があります。
暗号化が必要な接続ではMYSQL_SSL=trueとMYSQL_SSL_CA(CA証明書のパス)を指定します。クライアント証明書による相互TLS(mTLS)にも対応しており、MYSQL_SSL_CERTとMYSQL_SSL_KEYにクライアント証明書と秘密鍵のパスを渡せば、サーバー側でクライアントの身元も検証させられます。クラウド上のマネージドMySQLに社内ネットワーク外から繋ぐような構成では、この2段階の証明書設定が接続経路そのものの信頼性を担保します。
ローカルのMCPクライアントからではなく、複数人でチームとして共有したい場合はIS_REMOTE_MCP=trueでHTTPサーバーモードに切り替え、REMOTE_SECRET_KEYで発行したベアラートークンをクライアント側のAuthorizationヘッダーに渡す構成も選べます。日時データを扱う場合はMYSQL_TIMEZONEでタイムゾーンを固定できるため、アプリケーション側とクエリ結果の時刻表示がずれる問題を避けられます。
よくあるつまずき
READONLYという単独の環境変数は存在しない: 読み取り専用にするにはALLOW_*系フラグを何も設定しない(=全部false)ことで実現します。単一トグルを探して見つからずに詰まるケースがあります- マルチDBモードでのテーブル参照:
MYSQL_DBを省略すると複数データベースを横断できますが、クエリ側でdatabase.tableの形式を明示しないと対象が曖昧になります - リモートモードは認証設計を別途必要とする:
IS_REMOTE_MCP=trueにした時点でネットワーク越しにアクセス可能になるため、REMOTE_SECRET_KEYの管理とアクセス元の制限をローカル運用のとき以上に意識します MYSQL_DISABLE_READ_ONLY_TRANSACTIONSを安易にtrueにしない:ALLOW_INSERT_OPERATION等がfalseでも、この変数を有効にすると読み取り専用トランザクションという二段目の防御が外れます
まとめ
MySQLのスキーマ検査と分析クエリをClaude Codeから安全に任せたい場合、mcp-server-mysqlはALLOW_*系フラグとスキーマ単位の権限設定を組み合わせることで、開発DBには書き込みを許しつつ本番DBは読み取り専用に保つ、といった運用を1つの設定で実現できます。PostgreSQL側の同種の選択肢はPostgreSQL MCPサーバーの使い方にまとめています。複数DB種別を横断する用途ならDBHub、MySQL1本に絞って権限とデータ保護を作り込みたいならmcp-server-mysqlを選ぶ、という基準で使い分けます。導入はnpx一発で試せるので、まず個人の開発DBに既定の読み取り専用設定のまま繋いでみて、動作を確認してから本番相当の権限設計に進むのが手戻りの少ない順序です。