DuckDB / MotherDuck MCPサーバーでローカル分析基盤に繋ぐ
MotherDuck公式のmcp-server-motherduck(DuckDBローカルMCPサーバー)で、ファイル・S3・MotherDuckクラウドに繋ぎ、データベースを切り替えながら分析する手順をまとめます。
サーバーを立てずに手元のファイルをそのまま分析できるのがDuckDBの持ち味です。MotherDuck公式が配布するmcp-server-motherduckは、この特性をMCP経由でClaudeに渡します。ローカルのDuckDBファイル・インメモリDB・S3上のファイル・MotherDuckクラウドのいずれにも同じサーバーで接続でき、実行中に接続先を切り替えることもできます。バージョン1系で既定の挙動が変わっているので、移行の注意点も含めて手順をまとめます。
最短の起動は、uvを入れたうえでuvx mcp-server-motherduck --db-path :memory: --read-writeを実行することです。MotherDuckクラウドに繋ぐなら--db-path md:とmotherduck_token環境変数を指定します。DockerでもHTTPサーバーとして起動できます。
ローカルMCPとリモートMCP、2つの選択肢
MotherDuckは同じ用途に対して2種類のMCPサーバーを用意しています。この記事で扱うのはローカル版です。
MotherDuckが用意する2種類のMCP
リモートMCP
セットアップは不要で、読み書きの両方に対応します。エンドポイントはhttps://api.motherduck.com/mcpです。ローカルファイルは扱えません。
ローカルMCP
自分の環境にインストールして起動します。読み書きに対応し、ローカルとリモートのDBをまたいだファイルの入出力ができます。
手元のCSVをそのまま読ませたい、ローカルファイルとS3を横断してクエリを投げたい、といった用途はローカルMCPでないと成立しません。逆にセットアップの手間を省き、MotherDuckクラウドのデータだけを扱うならリモートMCPのほうが手早く始められます。
リモートMCPをClaude Codeで使うには、次のコマンドで登録します。
claude mcp add --transport http MotherDuck https://api.motherduck.com/mcp登録したらclaudeを起動し、/mcpでMotherDuckを選んで「Authenticate」に進むと、OAuthで認証できます。トークンをBearerヘッダーで渡す方法もあります。全プロジェクトで使うなら--scope userを付けます。
バージョン1系で既定の挙動が変わった
もう1点、MotherDuck接続を読み取り専用モードで使う場合は、通常のトークンではなくread-scalingトークンが必要です。通常のMotherDuckトークンで読み書きしたい場合は--read-writeを付けます。
接続手順 — インメモリ・ローカルファイル・MotherDuck
前提としてuvをインストールしておきます(pip install uvまたはbrew install uv)。用途に応じて3通りの設定があります。
まず、ガードなしで試したいだけのインメモリDBです。
{
"mcpServers": {
"DuckDB (in-memory, r/w)": {
"command": "uvx",
"args": ["mcp-server-motherduck", "--db-path", ":memory:", "--read-write", "--allow-switch-databases"]
}
}
}特定のローカルファイルに読み取り専用で繋ぐ場合はこちらです。ファイルロックを保持しないため、書き込み用の別接続と同時に使えます。
{
"mcpServers": {
"DuckDB (read-only)": {
"command": "uvx",
"args": ["mcp-server-motherduck", "--db-path", "/absolute/path/to/your.duckdb"]
}
}
}MotherDuckクラウドに読み書きで繋ぐ場合はトークンを環境変数に渡します。
{
"mcpServers": {
"MotherDuck (local, r/w)": {
"command": "uvx",
"args": ["mcp-server-motherduck", "--db-path", "md:", "--read-write"],
"env": { "motherduck_token": "<YOUR_MOTHERDUCK_TOKEN>" }
}
}
}Claude Codeではclaude mcp addで同じ設定をCLIから登録できます。
claude mcp add --scope user motherduck --transport stdio \
--env motherduck_token=YOUR_TOKEN \
-- uvx mcp-server-motherduck --db-path md: --read-write登録先の--scopeには落とし穴があります。claude mcp add --help(v2.1.287)では、スコープはlocal・user・projectの3択で、省略時はlocalです。作業用ディレクトリで--scope projectを付けて登録してみました。そのディレクトリに.mcp.jsonが作られ、motherduck_tokenには渡した文字列がそのまま入っていました。
{
"mcpServers": {
"motherduck": {
"type": "stdio",
"command": "uvx",
"args": ["mcp-server-motherduck", "--db-path", "md:", "--read-write"],
"env": { "motherduck_token": "YOUR_TOKEN" }
}
}
}.mcp.jsonはリポジトリに置いてチームで共有するためのファイルです。本物のトークンを入れたままprojectスコープで登録すると、そのままコミット対象になります。トークンを使う接続はlocalかuserで登録するのが無難です。チームで共有したい場合は、"motherduck_token": "${MOTHERDUCK_TOKEN}"と書き、値は各自の環境変数に置く方法もあります。
Claude Desktopには.mcpb形式のワンクリックインストールも用意されています。設定画面のDeveloper → Edit Configから、上記のJSONを直接貼り付ける方法も使えます。
提供ツールとデータベースの切り替え
現行バージョンが公開するツールは5つです。
| ツール | 機能 | 必須入力 |
|---|---|---|
execute_query | 機能DuckDB方言でSQLクエリを実行 | 必須入力sql |
list_databases | 機能全データベースを一覧表示 | 必須入力なし |
list_tables | 機能テーブル・ビューを一覧表示 | 必須入力なし(database/schemaで絞り込み可) |
list_columns | 機能テーブル・ビューのカラムを一覧表示 | 必須入力table |
switch_database_connection | 機能接続先データベースを切り替え | 必須入力path(create_if_not_existsも指定可) |
一覧系の3ツールは、見る範囲がlist_databases、list_tables、list_columnsの順に狭くなります。list_tablesはdatabaseとschema、list_columnsはtableに加えてdatabaseとschemaでも絞り込めます。SQLを書く前にカラム名を確かめたいときはlist_columnsが手軽です。list_databasesは、MotherDuckや複数のDBをアタッチしているときに、接続先の全体を確かめる起点になります。
switch_database_connectionだけは--allow-switch-databasesフラグを付けて起動しないと使えません。このツールが有効だと、会話の途中で「今度はS3上のこのファイルを見て」と言うだけで、ローカルファイル・MotherDuck・S3のいずれにも接続を切り替えられます。逆にフラグを付けなければ、起動時に指定した1つのデータベースだけに固定され、意図しない接続先への切り替えを防げます。結果は全てJSONで返り、既定では1024行・50,000文字までに制限されます(--max-rows・--max-charsで変更可能)。
本番でサードパーティに公開する場合の注意
読み取り専用モードにしただけでは、ローカルファイルシステムへのアクセスやDuckDBの設定変更まで防げるわけではありません。社外の相手にこのMCPサーバーへのアクセスを渡す構成は、読み取り専用フラグだけでは不十分です。
第三者にアクセスを渡す本番用途では、MotherDuck自身がホストするリモートMCPが推奨されています。ゼロセットアップで読み書き両対応、運用の負担がMotherDuck側に寄ります。ローカルMCPを自前でホストし続ける場合は、サービスアカウントとread-scalingトークンを組み合わせ、SaaSモードでローカルファイルへのアクセスを制限する構成にします。DuckDB単体のファイルに対するセキュリティ設定は--init-sqlで追加できます。
自前ホストのままread-scalingトークンとSaaSモードで絞るか、リモートMCPにホスティングごと任せるか。社外の相手にサーバーを触らせるなら、この2択から選ぶことになります。
コマンドラインパラメータ一覧
設定ファイルのargsに渡すフラグは、用途に応じて組み合わせます。主なものは次のとおりです。
| パラメータ | 既定値 | 内容 |
|---|---|---|
--db-path | 既定値:memory: | 内容ローカルファイル(絶対パス)・md:(MotherDuck)・s3://URLのいずれか |
--read-write | 既定値False | 内容書き込みアクセスを有効化 |
--allow-switch-databases | 既定値False | 内容switch_database_connectionツールを有効化 |
--max-rows | 既定値1024 | 内容返す行数の上限 |
--max-chars | 既定値50000 | 内容返す文字数の上限 |
--query-timeout | 既定値-1(無効) | 内容クエリタイムアウト(秒) |
--init-sql | 既定値なし | 内容起動時に実行するSQL |
--motherduck-saas-mode | 既定値False | 内容MotherDuck SaaSモード(ローカルアクセスを制限) |
--transport | 既定値stdio | 内容stdioまたはhttp |
大きな結果セットを扱うノートブック的な用途では--max-rowsと--max-charsを引き上げ、逆に応答を軽くしたい場合は絞り込みます。--query-timeoutは既定で無効なので、長時間クエリを止めたい場合は明示的に秒数を指定します。
MotherDuckへの接続に使う--motherduck-connection-parametersの既定値はsession_hint=mcp&dbinstance_inactivity_ttl=0sです。形式はkey=valueを&でつないだもので、追加の指定もできます。
session_hintは現行名session_nameの旧名で、クエリ履歴にこの名前が残るため、MCP経由のクエリを見分けられます。dbinstance_inactivity_ttl=0sは、最後の接続を閉じたらDBインスタンスのキャッシュを残さない設定です(既定は15分)。
--motherduck-tokenでもトークンを渡せますが、省略するとmotherduck_token環境変数(大文字のMOTHERDUCK_TOKENも可)が使われます。
HTTP起動では、待ち受けは既定で--host 127.0.0.1・--port 8000です。--stateless-httpはAWS Bedrock AgentCore Runtimeなどとの互換用で、サーバー側の状態は共有されたままです。
セキュリティ強化のために起動時SQLを流し込みたい場合は--init-sqlを使います。DuckDB自体のセキュリティ設定(Securing DuckDBガイド)と組み合わせれば、ファイルシステムへのアクセス範囲や拡張機能の読み込みを制限した状態でMCPサーバーを起動できます。
Dockerでstreamable HTTPとして起動する
stdio以外にDockerコンテナとしても配布されています。既定はインメモリDuckDBで、ポート8000でstreamable HTTPが待ち受けます。
docker build -t mcp-server-motherduck .
docker run --rm -p 8000:8000 mcp-server-motherduckMotherDuckに繋ぐ場合は、トークンを渡しつつコマンドを上書きします。
docker run --rm -p 8000:8000 \
-e motherduck_token="$MOTHERDUCK_TOKEN" \
mcp-server-motherduck --transport http --db-path md:このときのMCPエンドポイントはhttp://localhost:8000/mcpです。コンテナで動かす場合も、これまでのCLIフラグと環境変数はそのまま適用されます。
S3上のDuckDBファイルに接続する
--db-pathにs3://bucket/path.duckdb形式のURLを渡すと、S3上のファイルにそのまま接続できます。認証はAWSの標準的な環境変数で渡します。S3上のファイルは常に読み取り専用でアタッチされるため、--read-writeを付けても既存ファイルには書き込めません。
| 環境変数 | 用途 |
|---|---|
AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY | 用途アクセスキーによる認証 |
AWS_SESSION_TOKEN | 用途IAMロール・SSO・EC2インスタンスプロファイルの一時credential |
AWS_DEFAULT_REGION | 用途接続先リージョン |
AWS_ENDPOINT | 用途S3接続のエンドポイント |
HOME | 用途DuckDBの拡張機能・設定の保存先。未設定の場合は--home-dirで明示する |
よくあるつまずき
spawn uvx ENOENTエラーが出る:commandに指定したuvxのフルパスが解決できていない。which uvxで確認したフルパスを設定に書く- 書き込みができない: v1系は既定で読み取り専用。
--read-writeフラグを付け忘れている - MotherDuckの読み取り専用接続でトークンエラーになる: 起動時のメッセージは
The --read-only flag with MotherDuck requires a read-scaling token.で始まり、読み取り専用モードにはread-scalingトークンが必要だと分かる - ファイルがロックされて開けない:
--ephemeral-connections(既定で有効)を無効にしていないか、読み書きモードで接続していないかを確認する
よくある質問
Claude以外のクライアントでも使えますか
使えます。Claude Code・Codex CLI・Gemini CLI・Cursor・VS Code・Kiroなど、複数のMCPクライアント向けにCLIコマンドや設定例が配布元から公開されています。設定形式はクライアントごとに多少異なりますが、渡す--db-pathや--read-writeなどのフラグ自体は共通です。
複数のDuckDBファイルを同時に使えますか
switch_database_connectionは接続先を切り替えるツールです。同時に引くものではありません。複数のファイルをJOINしたい場合は、execute_queryでATTACHしてからdatabase.schema.tableの完全修飾名で参照します。サーバー自身も、ATTACHを前提にした説明をClaudeに渡しています。
まとめ
mcp-server-motherduckは、ローカルファイル・インメモリ・S3・MotherDuckクラウドを同じサーバーで扱えるのが強みです。v1系からは既定が読み取り専用に変わっているため、書き込みが必要なら--read-writeを、MotherDuckに繋ぐなら--db-path md:を明示します。switch_database_connectionを--allow-switch-databases付きで有効にしておけば、会話の途中でも分析対象を切り替えられます。社外の相手にアクセスを渡す本番運用では、読み取り専用フラグだけに頼らずMotherDuckのリモートMCPかサービスアカウント構成を検討するのが安全です。クラウドDWH側の選択肢はClaude Snowflake連携ガイド、大規模ログ集計に寄せた選択肢はClickHouse MCPサーバーにまとめています。