mcpField
T
tokenlite-mysql-mcp

tokenlite-mysql-mcp

ローカル
github.com/andezdevデータベース021 週間前に更新

tokenlite-mysql-mcp について

tokenlite-mysql-mcpは、AIクライアントからデータベースを利用するチーム向けのMySQL MCPサーバーです。クエリ保護、意味情報を含むスキーマコンテキスト、簡潔なCSV結果を備えています。

主な機能

  1. 01EXPLAINによる全表スキャンの遮断
  2. 02ASTによるクエリ上限の注入
  3. 03設定可能な書き込み権限
  4. 04セマンティック辞書とSQLテンプレート
  5. 05リレーションに基づくスキーマ情報
  6. 06簡潔なCSVクエリ結果

活用シーン

  1. 01関連情報を用いたMySQLスキーマの探索
  2. 02本番データベースへの上限付きクエリ
  3. 03承認済み指標と業務定義の提示
  4. 04LLMに送る結果トークンの削減

MCP 対応

MCPクライアントにMySQLのスキーマとクエリ機能を公開し、MCP Prompts APIを通じてセマンティックテンプレートを提供します。テーブル名とテンプレートキーワードの補完にも対応します。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"andezdev-tokenlite-mysql": {
"command": "npx",
"args": [
"-y",
"@andezdev/tokenlite-mysql-mcp"
],
"env": {
"DB_HOST": "<DB_HOST>",
"DB_PORT": "<DB_PORT>",
"DB_USER": "<DB_USER>",
"DB_PASSWORD": "<DB_PASSWORD>",
"DB_NAME": "<DB_NAME>",
"MCP_EXPLAIN_MAX_SCAN_ROWS": "<MCP_EXPLAIN_MAX_SCAN_ROWS>",
"MCP_QUERY_ROW_LIMIT": "<MCP_QUERY_ROW_LIMIT>",
"MCP_SAFE_QUERY_MAX_ROWS": "<MCP_SAFE_QUERY_MAX_ROWS>",
"MCP_SAFE_QUERY_ENABLE_BLOCKING": "<MCP_SAFE_QUERY_ENABLE_BLOCKING>",
"MCP_METADATA_PATH": "<MCP_METADATA_PATH>",
"MCP_TEMPLATES_PATH": "<MCP_TEMPLATES_PATH>",
"TOOL_PREFIX": "<TOOL_PREFIX>",
"MCP_RATE_LIMIT_RPM": "<MCP_RATE_LIMIT_RPM>",
"MYSQL_QUERY_TIMEOUT": "<MYSQL_QUERY_TIMEOUT>",
"MYSQL_CONNECTION_LIMIT": "<MYSQL_CONNECTION_LIMIT>",
"MYSQL_CONNECT_TIMEOUT": "<MYSQL_CONNECT_TIMEOUT>",
"MYSQL_RETRY_ATTEMPTS": "<MYSQL_RETRY_ATTEMPTS>",
"MYSQL_RETRY_DELAY_MS": "<MYSQL_RETRY_DELAY_MS>",
"MYSQL_QUEUE_LIMIT": "<MYSQL_QUEUE_LIMIT>",
"MCP_DDL_CACHE_TTL": "<MCP_DDL_CACHE_TTL>",
"MCP_LOG_LEVEL": "<MCP_LOG_LEVEL>",
"ALLOW_INSERT_OPERATION": "<ALLOW_INSERT_OPERATION>",
"ALLOW_UPDATE_OPERATION": "<ALLOW_UPDATE_OPERATION>",
"ALLOW_DELETE_OPERATION": "<ALLOW_DELETE_OPERATION>",
"ALLOW_DDL_OPERATION": "<ALLOW_DDL_OPERATION>",
"DB_SSL": "<DB_SSL>",
"DB_SSL_REJECT_UNAUTHORIZED": "<DB_SSL_REJECT_UNAUTHORIZED>"
}
}
}
}
起動コマンドnpx -y @andezdev/tokenlite-mysql-mcp
設定が必要な環境変数
DB_HOSTMySQL Host address (defaults to localhost)
DB_PORTMySQL Port (defaults to 3306)
DB_USERMySQL Username (defaults to root)
DB_PASSWORDシークレットMySQL Password (defaults to empty string)
DB_NAMEMySQL Database name
MCP_EXPLAIN_MAX_SCAN_ROWSEXPLAIN guardrail: max estimated rows for unindexed full table scans before blocking (defaults to 1000). MCP_SAFE_QUERY_MAX_ROWS is a deprecated alias.
MCP_QUERY_ROW_LIMITMax rows returned per SELECT; injected as LIMIT at the AST level (defaults to 500)
MCP_SAFE_QUERY_MAX_ROWSDeprecated alias for MCP_EXPLAIN_MAX_SCAN_ROWS
MCP_SAFE_QUERY_ENABLE_BLOCKINGEnable or disable the EXPLAIN guardrail (defaults to true)
MCP_METADATA_PATHAbsolute path to your custom metadata.json dictionary
MCP_TEMPLATES_PATHAbsolute path to your custom templates.json pre-approved queries
TOOL_PREFIXPrefix for tool names, e.g., to run multiple instances (defaults to DB_NAME, e.g. mydb_). Only set to override.
MCP_RATE_LIMIT_RPMMax tool invocations per minute, sliding window (defaults to 60). Set to 0 to disable.
MYSQL_QUERY_TIMEOUTMax execution time for a query in milliseconds to protect against DoS (defaults to 15000)
MYSQL_CONNECTION_LIMITMax concurrent pool connections (defaults to 10)
MYSQL_CONNECT_TIMEOUTMax time to wait for a connection socket to establish in milliseconds (defaults to 10000)
MYSQL_RETRY_ATTEMPTSMax retries on transient connection errors (defaults to 3)
MYSQL_RETRY_DELAY_MSBase delay in milliseconds for exponential backoff between retries (defaults to 1000)
MYSQL_QUEUE_LIMITMax queued requests when all pool connections are busy to prevent memory leak (defaults to 50)
MCP_DDL_CACHE_TTLTime-to-live in seconds for cached DDL statements (defaults to 60)
MCP_LOG_LEVELMinimum severity level for MCP log notifications (defaults to info). Levels: debug, info, notice, warning, error, critical, alert, emergency
ALLOW_INSERT_OPERATIONEnable INSERT and REPLACE queries (defaults to false)
ALLOW_UPDATE_OPERATIONEnable UPDATE queries (defaults to false)
ALLOW_DELETE_OPERATIONEnable DELETE and TRUNCATE queries (defaults to false)
ALLOW_DDL_OPERATIONEnable Data Definition Language queries like CREATE, ALTER, DROP, RENAME (defaults to false)
DB_SSLEnable TLS for the MySQL connection (defaults to false)
DB_SSL_REJECT_UNAUTHORIZEDシークレットReject self-signed or untrusted TLS certificates when DB_SSL is true (defaults to true)

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npm@andezdev/tokenlite-mysql-mcp4.1.0

ツール

5

掲載時のツール一覧 · 2 週間前に更新

パラメーター型必須説明
querystringはい検索するテーブルまたはエンティティの名前(例:'users'、'invoices')。

詳細

TokenLite MySQL MCP

npm version

Anthropic の Model Context Protocol(MCP) に基づいて実装された、堅牢で安全な MySQL データベースサーバーです。 段階的な機能縮退、アクティブなパフォーマンス保護、積極的なトークン最適化によって、現在の汎用 MCP サーバーの欠点を解消することを目的に設計されています。


🌟 中核となる柱

  1. 安全なクエリオプティマイザー(AST と EXPLAIN):クエリを事前分析し、本番データベースを保護します。設定可能なしきい値を超える、インデックスが使われないフルテーブルスキャンをブロックし、AST レベルで厳格な LIMIT 句を自動的に挿入します。
  2. AST ベースのきめ細かな書き込み権限:TokenLite はデフォルトで 100% 読み取り専用です。環境変数を使って、特定の書き込み操作(INSERT、UPDATE、DELETE、DDL)だけを選択的に有効化できます。ファイアウォールは厳格な AST 解析を用いて SQL インジェクションやコメントによる回避を防ぎ、権限昇格コマンド(GRANT や CALL など)を厳格に禁止します。
  3. セッションレベルの多層防御:サーバーが厳格な読み取り専用モード(すべての書き込み変数が無効)で設定されている場合、TokenLite は接続プールのソケットに SET SESSION TRANSACTION READ ONLY を直接挿入します。これにより、AST パーサーに理論上の回避手段があったとしても、MySQL エンジン自体がデータ変更を物理的に拒否します。
  4. ビジネスインテリジェンスの注入:生データと社内ロジックの橋渡しをします。データベーススキーマの探索にセマンティック辞書(metadata.json)を自動的に添付し、公式の MCP Prompts API(templates.json)を通じてセマンティックテンプレートを提供することで、LLM がクエリを幻覚で生成するのではなく、事前承認済みの分析クエリを使用するようにします。
  5. グラフベースのセマンティックスキーマ:コンテキストウィンドウを圧迫する巨大なスキーマを LLM に送信することを避けます。テーブルが検索されると、エンジンはヒューリスティックを使って暗黙的な関係を推定し、正確な「自動 JOIN コンテキスト」をまとめます。
  6. CSV トークン圧縮:データベースの結果を曖昧さのない NULL 表現(∅)を用いた表形式の CSV Markdown に効率よく変換し、冗長な JSON と比べて出力トークンを最大 50% 削減します。結果が適用された LIMIT に達すると、-- rows: N (truncated at LIMIT X) というフッターが追加されるため、LLM が完全なデータセットだと誤認しません。
  7. MCP 補完機能:テーブル名とテンプレートキーワードは、リソーステンプレート(mysql://tables/{name})および query_templates プロンプトで、公式の completions/complete 機能をサポートします。

📋 要件

  • Node.js v20 以降
  • MySQL 5.7 以降(MySQL 8.0 以降を推奨)
  • SELECT および SHOW VIEW 権限を持つ MySQL ユーザー。

🚀 インストールと使用方法

この MCP サーバーは、互換性のある任意のクライアントで使用できます。以下に、よく使われるクライアントの設定を示します。

1. Claude Desktop

claude_desktop_config.json(Windows では通常 %APPDATA%\Claude\claude_desktop_config.json、macOS では ~/Library/Application Support/Claude/claude_desktop_config.json にあります)を編集し、以下を追加します。

NPX を使用する場合(推奨)

{
  "mcpServers": {
    "tokenlite-mysql": {
      "command": "npx",
      "args": [
        "-y",
        "@andezdev/tokenlite-mysql-mcp"
      ],
      "env": {
        "DB_HOST": "localhost",
        "DB_PORT": "3306",
        "DB_USER": "your_db_user",
        "DB_PASSWORD": "your_password",
        "DB_NAME": "your_database",
        "MCP_EXPLAIN_MAX_SCAN_ROWS": "1000",
        "MCP_QUERY_ROW_LIMIT": "500",
        "MCP_SAFE_QUERY_ENABLE_BLOCKING": "true"
      }
    }
  }
}
2. Claude Code(CLI)

このサーバーは、Claude Code に簡単にグローバル統合できます。

claude mcp add tokenlite_mysql \
  -e DB_HOST="127.0.0.1" \
  -e DB_PORT="3306" \
  -e DB_USER="root" \
  -e DB_PASSWORD="your_password" \
  -e DB_NAME="your_database" \
  -- npx -y @andezdev/tokenlite-mysql-mcp
3. Cursor IDE

Cursor IDE で使用するには:

  1. Cursor の Settings > Features > MCP を開きます。
  2. + Add New MCP Server をクリックします。
  3. Type を command に設定します。
  4. 名前を tokenlite-mysql に設定します。
  5. command を次のように設定します。
    npx -y @andezdev/tokenlite-mysql-mcp
    

(注:Cursor は IDE の UI で環境変数を直接扱います。ここで DB の認証情報を追加してください。)


⚙️ 環境変数リファレンス

クエリ制限の理解(独立した 2 つの設定項目)

execute_safe_query は別々の 2 つの制限を適用します。混同しないでください。

変数制御する内容デフォルト例
MCP_EXPLAIN_MAX_SCAN_ROWSセキュリティゲート:EXPLAIN プランで全テーブルスキャン(type: ALL)が示され、推定行数がこのしきい値を超えるクエリをブロックします。クエリは実行前に拒否されます。10005000 を設定すると、インデックスなしで約5000行までのテーブルをスキャンできます
MCP_QUERY_ROW_LIMIT結果の上限:LLM に返す最大行数です。AST レベルで LIMIT として挿入されます。この上限に達すると、CSV に -- rows: N (truncated at LIMIT X) が含まれます。5001000 を設定すると、SELECT 1回あたり最大1000行を返します

非推奨のエイリアス: MCP_SAFE_QUERY_MAX_ROWS は、MCP_EXPLAIN_MAX_SCAN_ROWS のフォールバックとしてのみ引き続き機能します。結果の LIMIT は制御しません。

customers テーブル(約1502行)で、MCP_EXPLAIN_MAX_SCAN_ROWS=5000、MCP_QUERY_ROW_LIMIT=500 を設定した例:

  1. SELECT * FROM customers → EXPLAIN を通過し(1502 < 5000)、LIMIT 500 を付けて実行され、500行と切り捨てを示す末尾行が返されます。
  2. 同じ設定でも、テーブルの行数が8000行の場合は、実行前に EXPLAIN によってブロックされます。
変数説明デフォルト必須
DB_HOSTMySQL ホストのアドレスlocalhostいいえ
DB_PORTMySQL ポート3306いいえ
DB_USERMySQL ユーザー名rootいいえ
DB_PASSWORDMySQL パスワード''いいえ
DB_NAMEMySQL データベース名testはい
MCP_EXPLAIN_MAX_SCAN_ROWSEXPLAIN ガードレール:ブロックする前に許可される、インデックスなしの全テーブルスキャンの最大推定行数です。1000いいえ
MCP_QUERY_ROW_LIMITSELECT 1回あたりの最大返却行数(AST による LIMIT の挿入と切り捨てを示す末尾行)。500いいえ
MCP_SAFE_QUERY_ENABLE_BLOCKINGEXPLAIN ガードレールを有効または無効にします。trueいいえ
MCP_METADATA_PATHカスタムの metadata.json 辞書への絶対パスです。(無効)いいえ
MCP_TEMPLATES_PATHカスタムの templates.json クエリへの絶対パスです。(無効)いいえ
TOOL_PREFIXツール名のプレフィックス(複数のインスタンスを実行する場合に便利です)。DB_NAME から生成(例:mydb_)。DB_NAME が未設定の場合のみ、ランダムな値にフォールバックします。いいえ
MCP_RATE_LIMIT_RPM1分あたりのツール呼び出し最大数(スライディングウィンドウ)。0 に設定すると無効になります。60いいえ
MYSQL_QUERY_TIMEOUTクエリの最大実行時間(ミリ秒)。DoS を防ぐため、負荷の高いクエリを中断します。15000いいえ
MYSQL_CONNECTION_LIMIT同時に使用できる接続プールの最大接続数です。10いいえ
MYSQL_CONNECT_TIMEOUTソケット接続の確立を待つ最大時間(ミリ秒)です。10000いいえ
MYSQL_RETRY_ATTEMPTS一時的な接続エラー(ECONNREFUSED、PROTOCOL_CONNECTION_LOST など)発生時の最大再試行回数です。3いいえ
MYSQL_RETRY_DELAY_MS再試行間の指数バックオフに使用する基本待機時間(ミリ秒、1秒、2秒、4秒…)です。1000いいえ
MYSQL_QUEUE_LIMIT接続プールの全接続が使用中の場合にキューに入れられるリクエストの最大数です。MySQL が停止している場合のキューの無制限な増加を防ぎます。50いいえ
MCP_DDL_CACHE_TTLキャッシュされた DDL 文の有効期間(秒)です。search_schema の繰り返し呼び出し時のレイテンシを低減します。refresh_schema によって無効化されます。60いいえ
MCP_LOG_LEVELMCP ログ通知の最小重大度です:debug、info、notice、warning、error、critical、alert、emergency。infoいいえ
ALLOW_INSERT_OPERATIONINSERT および REPLACE クエリを有効にします。falseいいえ
ALLOW_UPDATE_OPERATIONUPDATE クエリを有効にします。falseいいえ
ALLOW_DELETE_OPERATIONDELETE および TRUNCATE クエリを有効にします。falseいいえ
ALLOW_DDL_OPERATIONデータ定義言語(CREATE、ALTER、DROP、RENAME)を有効にします。falseいいえ
DB_SSLMySQL 接続で TLS を有効にします(マネージドデータベース/クラウドデータベースでの利用を推奨)。falseいいえ
DB_SSL_REJECT_UNAUTHORIZEDDB_SSL=true の場合、自己署名または信頼されていない TLS 証明書を拒否します。trueいいえ

🛡️ ビジネスインテリジェンス機能(オプトイン)

TokenLite を使って、会社のビジネスルールを LLM に教えることができます。有効にするには、.env または MCP クライアントの設定で、2 つの JSON ファイルの絶対パスを指定します。

metadata.json(セマンティック辞書)

整数のステータスや社内用語を変換し、LLM がデータを理解できるようにします。

{
  "orders.status": {
    "pending": "The order is waiting for payment validation",
    "shipped": "The order has left the warehouse"
  }
}
カスタムリレーションシップ

ヒューリスティックエンジンで自動検出できない FK マッピング(例:created_by → users)を定義します。metadata.json に _relationships キーを追加してください。

{
  "orders.status": { "pending": "...", "shipped": "..." },
  "_relationships": {
    "orders.created_by": "users.id",
    "categories.parent_id": "categories.id"
  }
}

これらはヒューリスティックではなく、信頼できる情報として扱われ、自動検出より優先されます。

ヒューリスティックエンジンは、推測した各 FK に信頼度スコア(0~100)も割り当てます。スコアは、名前の一致(+40)、データ型の検証(+30)、主キーの検証(+20)、インデックスの有無(+10)に基づきます。70 以上の FK のみが採用されます。

templates.json(事前承認済み SQL)

精査済みのテンプレートを用意することで、複雑なメトリクスを LLM が幻覚で生成するのを防ぎます。

[
  {
    "name": "Customer Lifetime Value (LTV)",
    "description": "Calculates total revenue generated by delivered orders per customer.",
    "sql": "SELECT c.id, SUM(oi.price) FROM customers c JOIN orders o... WHERE o.status='delivered'"
  }
]

📈 ベンチマークとトークン削減

TokenLite には、効率向上を測定するための自動ベンチマークスイートが含まれています。トークン数の測定には o200k_base トークナイザー(GPT-4o/GPT-5 標準)を使用します。トークン数は概算です。Claude 4.x は独自のトークナイザーを使用するため、実際の数値は多少異なる場合があります。

ご自身の環境でベンチマークを実行するには、次のようにします。

npm run benchmark
ベースライン:標準的な MCP パターン

ベンチマークでは、汎用 MySQL MCP サーバーで使用される標準的なパターンと比較します。スキーマ全体を information_schema.columns として整形済み JSON で公開し、クエリ結果を実行時間のメタデータとともに JSON.stringify(rows, null, 2) として返します。

1. スキーマ検出(入力トークン)

標準的な MCP サーバーは、スキーマ全体を LLM に出力します。大規模なデータベースでは、これにより毎回数千の入力トークンを消費します。TokenLite のリレーショナルグラフは、ローカライズされた自動結合コンテキスト(対象テーブル+直接の親テーブル+直接の子テーブル)を提供します。

シナリオ標準的な MCP パターンTokenLite📉 削減率
モック(50 テーブル、エンタープライズ CRM)15,566 tokens883 tokens94.3%
実環境(9 テーブル、テスト DB)2,208 tokens531 tokens75.9%

削減量はテーブル数に応じて増加します。標準的なパターンではすべてのテーブルを出力する一方、TokenLite は対象テーブルと 1 ホップのリレーションシップのみを取得するため、データベース内のテーブルが多いほど削減効果が高くなります。

2. クエリ結果のペイロード(出力トークン)

TokenLite は、生のデータベース行を密度の高い構造化 CSV 形式に変換します。これにより、JSON 構文(角括弧、中括弧、繰り返されるキー)のオーバーヘッドを避け、LLM に返される出力ペイロードを圧縮します。行数がサーバー側で注入される LIMIT に達した場合、結果には切り詰めを示すフッター(例:-- rows: 500 (truncated at LIMIT 500))が含まれ、エージェントはさらにデータが存在する可能性を把握できます。

モックデータ(NULL、長い説明文、さまざまな文字列長を含む):

返される行数標準的な MCP パターン(トークン数)TokenLite CSV(トークン数)📉 出力削減率(%)
10 行1,16760148.5%
50 行5,8032,92749.6%
100 行11,6075,84249.7%
500 行57,99029,11949.8%

実データ(NULL、ENUM、可変長テキストを含む実際の MySQL テストデータベース):

返される行数標準的な MCP パターン(トークン数)TokenLite CSV(トークン数)📉 出力削減率(%)
10 行1,00762837.6%
50 行5,0293,11438.1%
100 行10,0716,23238.1%
500 行50,32731,11638.2%

📊 ロギングと可観測性

TokenLite は、生の stderr 出力ではなく notifications/message を使用して、MCP ネイティブのロギングを行います。MCP ロギングに対応したクライアント(例:MCP Inspector)には、重大度レベル、ロガー名、JSON データを含む構造化ログメッセージが届きます。

重大度レベル(低いものから高いものの順):debug、info、notice、warning、error、critical、alert、emergency。

デフォルトでは、サーバーは info レベル以上のログを出力します。最小レベルは MCP_LOG_LEVEL で設定するか、実行時に MCP の logging/setLevel リクエストを通じて動的に設定できます。

MCP セッションが確立される前(例:プールの初期化中)は、ログは stderr に出力されます。


🌐 高度なネットワーキングとリモート接続

設計上、tokenlite-mysql-mcp は Unix の哲学に従っています。単一のこと(AI を活用した MySQL とのやり取り)を、標準の stdio トランスポートを介して安全に実行します。HTTP サーバーや SSH クライアントを組み込んで、コードベースを不必要に肥大化させることは意図的に避けています。

リモートデータベースに接続する場合や、このサーバーをネットワーク経由で公開する場合は、次のエンタープライズグレードの方法を推奨します。

1. リモートデータベースへの接続(SSH トンネル)

SSH ライブラリを組み込む代わりに、OS ネイティブのトンネルを使用することを推奨します。こちらのほうがはるかに安全で、~/.ssh/config を尊重し、高度な認証(2FA、ハードウェアキー)にも対応します。

ターミナルを開き、次のコマンドを実行するだけです。

ssh -N -L 3306:127.0.0.1:3306 [email protected]

次に、tokenlite-mysql-mcp の接続先を localhost、ポートを 3306 に設定します。

2. MCP サーバーを HTTP/ネットワーク経由で公開する

この MCP サーバーをクラウド(AWS、GCP)でホストし、複数の Claude デスクトップクライアントから HTTP/SSE 経由でリモート接続する必要がある場合は、Express/HTTP のロジックを追加するためにこのコードベースを変更しないでください。 代わりに、mcp-proxy のような標準のオープンソース MCP プロキシでプロセスをラップしてください。これにより、トランスポート層のセキュリティと AI ロジックを明確に分離できます。

🐛 トラブルシューティング

エラー:OptimizerError: Full table scan detected... LLM が、インデックスを使用せずに数千行をスキャンする必要のあるクエリを実行しようとしました。 解決方法:explain_query を使用して EXPLAIN の完全な出力を確認し、クエリがブロックされた理由を把握してください。インデックス付きの WHERE 句を使ってクエリを書き直してください。テーブル全体をスキャンする必要がある場合は、設定で MCP_EXPLAIN_MAX_SCAN_ROWS の値を増やしてください。クエリごとに返す行数を増やすには、別途 MCP_QUERY_ROW_LIMIT を調整してください。

エラー:calling "initialize": invalid character... MCP JSON-RPC プロトコルがクラッシュしたことを示しています。DB の認証情報が正しく渡されていること、またデータベースが稼働しており、MCP サーバーの実行マシンからアクセスできることを確認してください。


AI エンジニアリング時代のために構築されました。


コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。