Modal MCP について
Modal MCPは、ローカルのModal CLIを通じてアプリ、コンテナ、ボリューム、シークレットを管理するMCPサーバーです。Claude CodeなどのMCPクライアントからModalアプリをデプロイ、実行、調査したい開発者向けです。
主な機能
- 01リソースとアプリ履歴の確認
- 02アプリログの取得と検索
- 03アプリのデプロイとタスク実行
- 04アプリ状態の管理とロールバック
- 05コストとシークレットの確認
活用シーン
- 01アプリログのエラー調査
- 02共有可能なアプリエンドポイントのデプロイ
- 03単発またはデタッチ実行のジョブ
MCP 対応
MCPクライアントにModal管理用の12個のツールを提供します。各ツールはローカルの`modal` CLIを呼び出し、マシンに設定されたModalプロファイルと認証情報を使用します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
12掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| env | any | いいえ | |
| action | string | はい | |
| version | any | いいえ | |
| app_identifier | string | はい |
詳細
MCP Modal サーバー
Modal(アプリ、コンテナ、ボリューム、シークレット)を管理し、Claude Code やその他の MCP クライアントから Modal アプリを直接デプロイして実行するための MCP サーバーです。
すべてのツールはローカルの modal CLI を呼び出すため、お使いのマシンで設定されている Modal プロファイルと認証情報を使用して動作します。管理が必要な追加のトークンはありません。
インストール
このサーバーは PyPI に mcp-modal として公開されています。手動でインストールする必要はありません。推奨される実行方法は、必要に応じて取得して起動する uvx を使うことです。MCP クライアントで、以下のコマンドを指定してください(設定を参照)。
すべてのバージョンはタグ付けされ、リリースページにも公開されています。リリースノートと、PyPI で配布されているものと同じ .whl/.tar.gz が添付されています。バージョンを固定する場合、ネットワークに接続できない環境にインストールする場合、またはバージョン間の変更点を確認する場合に便利です。
Modal へのログイン
このサーバーはローカルの Modal 認証情報を使用します。まだ認証していない場合は、次を実行してください。
modal setup
ブラウザーが開いてログインし、トークンが ~/.modal.toml に保存されます。すでに別の場所でログインしている場合は、modal profile current で確認してください。
設定
claude mcp CLI を使って、Claude Code にサーバーを追加します。
claude mcp add mcp-modal -- uvx mcp-modal@latest
または、プロジェクトのルートにある .mcp.json ファイルに追加することもできます。チームで使う場合はこちらが適しています。リポジトリを開く全員に、同じ設定が適用されます。
{
"mcpServers": {
"mcp-modal": {
"command": "uvx",
"args": ["mcp-modal@latest"]
}
}
}
@latest を使う理由と、バージョンを固定する場合
uvx は初回実行時に構築した環境をキャッシュし、その後は PyPI を再確認しません。
「uvx は、初回の呼び出し時に、要求されたツールの利用可能な最新バージョンを使用します。 その後は、別のバージョンが要求された場合、キャッシュが削除された場合、またはキャッシュが更新された場合を除き、uvx はツールのキャッシュ済みバージョンを使用します。」 — uv のドキュメント
つまり、単に uvx mcp-modal と指定すると、インストール時点では最新ですが、その後は永久に固定されます。キャッシュはディスク上に保存されるため、クライアントを再起動したり、マシンを再起動したりしても変わりません。初回実行の時期によって利用者ごとに異なるバージョンになり、警告も表示されません。
mcp-modal@latestは起動のたびにバージョンを再解決するため、再起動すると新しいリリースが反映されます。起動時にネットワークへのラウンドトリップが1回発生します。ツールの仕様がまだ変化している間に使ってください。[email protected](明示的なバージョン指定)は再現性があり、アップグレードも1行を意図的に変更して行えます。安定性を重視する場合や、より多くの利用者に展開する場合に使ってください。
すでに古いビルドがキャッシュされているマシンを移行する場合は、上記のどちらかに切り替えるだけで十分です。バージョンを指定するとキャッシュが無効になります。それ以外の場合は、uv cache clean mcp-modal を実行すると強制的に更新できます。
要件
- Python 3.11 以降
uv(uvxを提供)- 有効な認証情報で設定された Modal CLI 1.5 以降(
modal setup)。1.5 ではmodal billing summary/ratesが追加され、請求レポートの列が snake_case に変更されました。コストツールはどちらの表記にも対応していますが、これら2つのビューには1.5が必要です。 - Modal の デプロイおよび実行をサポートする場合:
- デプロイ/実行するプロジェクトでは、依存関係管理に
uvを使用する必要があります。 modalがそのプロジェクトの仮想環境にインストールされている必要があります。
- デプロイ/実行するプロジェクトでは、依存関係管理に
セキュリティ
このサーバーは、~/.modal.toml にある認証情報を使って、ローカルの modal CLI をシェルから実行します。一部のツールは設計上、強力な権限を持ちます。サーバーを操作する MCP クライアントがプロンプトインジェクションを受けた場合(たとえば、取得したログに含まれる悪意のあるテキストによって)、以下の手段で権限が昇格される可能性があります。これらは自動承認せず、クライアントのツール承認プロンプトを必ず介すようにしてください。
deploy_modal_app/run_modal_app— ホスト上で任意のローカル Python を実行します(modal deployはアプリファイルをインポートし、uv runは対象プロジェクトの依存関係を解決してインストールします)。modal_volume_files(action="put") — 任意のローカルファイル(例:~/.ssh/id_rsa、~/.modal.toml)を読み取り、クラウドボリュームにアップロードできます(データを外部に持ち出すための手段になります)。modal_volume_files(action="get"とforce=True) — 任意のローカルパスを上書きできます(例:~/.zshrcやシェルプロファイル。永続化の手段になります)。manage_modal_container(action="exec") — 設計上、コンテナ内で任意のコマンドを実行します。
すべてのツールは MCP ツールアノテーションを宣言しているため、クライアントは、読み取り専用の4つのツール(list_modal_resources、get_modal_logs、search_modal_logs、analyze_modal_costs。いずれも readOnlyHint: true)と、リモートの状態を変更するかコンピューティングを開始する8つのツールを区別できます。この8つのうち6つは destructiveHint: true です。例外は、何かを削除したり上書きしたりせずにコンピューティングを開始する run_modal_app と inspect_modal_secret です。読み取り操作は自動承認し、それ以外は承認プロンプトを介すようにしてください。
ローカルパスの許可リスト(任意)
ファイルシステムにアクセスする2つのボリュームツールの動作を制限するには、MCP_MODAL_ALLOWED_LOCAL_PATHS 環境変数に、ディレクトリを os.pathsep で区切ったリスト(macOS/Linux では :)を設定します。この変数が設定されている場合、解決後のパス(~ を展開し、.. やシンボリックリンクを正規化した後)がいずれかのルートディレクトリ内にないローカルパスに対する modal_volume_files の操作は拒否されます。対象となるのは、action="put" の local_path と、action="get" の保存先です。ダウンロード先が "-"(ファイルに書き込まず内容を返す)の場合は、ディスクに何も書き込まないため対象外です。
環境変数が未設定(デフォルト)の場合、制限はありません。そのため、既存の設定には影響しません。たとえば、MCP クライアントで次のように設定します。
{
"mcpServers": {
"mcp-modal": {
"command": "uvx",
"args": ["mcp-modal"],
"env": { "MCP_MODAL_ALLOWED_LOCAL_PATHS": "/Users/me/modal-workspace:/tmp/modal" }
}
}
}
すべてのツールは、ユーザー指定の名前やパスを -- で示すオプション終端セパレーターの後に渡すため、- で始まる値も常にデータとして扱われ、modal CLI のフラグになることはありません。manage_modal_secret に渡されたシークレット値は、エコーされるコマンド、ログ、エラー出力からマスキングされます。
サポート対象のツール
ツールは12個です。関連する操作は、CLI のサブコマンドごとに分けるのではなく、action/resource 引数の背後にまとめられています。各ツールのスキーマはセッション全体を通じてモデルのコンテキストに読み込まれるため、ツールの数を抑えることで、実際の作業に使える余地が増え、モデルが選択する類似ツールも少なくなります。
環境ごとにスコープされたリソースを扱うツールでは、特定の Modal 環境を指定するための env 引数を任意で指定できます。省略した場合は、プロファイルのデフォルト(または MODAL_ENVIRONMENT)が使われます。例外は manage_modal_container とコンテナログです。コンテナ ID はグローバルに一意であり、CLI では環境を指定できません。
読み取り専用
-
Modal リソースの一覧表示(
list_modal_resources)— アカウント全体を一度に検索します。- パラメーター:
resource(必須)、name、path(デフォルトは/)、env resourceの値:値 返される内容 nameの意味appsデプロイ済み/実行中/最近停止したアプリ — app_history1 つのアプリのデプロイバージョン(ロールバック用) アプリ名/ID containers実行中のコンテナ( ta-...)絞り込みに使うアプリ ID volumes名前付きボリューム — volume_filesボリューム内のファイル( pathを使用)ボリューム名 secretsシークレット名(値は公開されません) — environmentsこのワークスペースで有効な envの値— profileアクティブなプロファイルとすべてのプロファイル — volume_filesの一覧取得で実際に何も見つからない場合は、メッセージとともにempty: trueが設定されるため、空のディレクトリと誤ったパスを区別できます。- 200 件を超える一覧は上限が適用され、除外された件数は
omitted_itemsに示されます。
- パラメーター:
-
Modal ログの取得(
get_modal_logs)— アプリ または コンテナのログを取得またはストリーミングします。- パラメーター:
identifier(必須)、target(auto/app/container、デフォルトはauto—ta-で始まるものはコンテナです)、timeout_seconds(デフォルトは 30)、env、since、until、tail、source(stdout/stderr/system)、timestamps、follow tailを指定せずにsinceを指定すると、範囲内のすべてのログが取得されます。負荷の高いアプリの出力を制限するには、untilも指定してください(最大範囲は 35 日、tailの上限は 20,000 件です)。follow=Trueの場合、アプリ/コンテナが停止するかtimeout_secondsに達するまでログがストリーミングされ、truncated: trueを含むスナップショットが返されます。- 対象は stdout/stderr/system ストリームのみです。一部の障害(例:「... exited with ...」として報告されるクラッシュ)はログ行ではなく Modal ダッシュボードのイベントであるため、ここには表示されません。
- パラメーター:
-
Modal ログの検索(
search_modal_logs)— ログを grep し、「どこで問題が起きたのか?」をデバッグできるよう、各ヒットと前後の行を取得します。ログは一度取得してローカルで検索するため、前後のコンテキスト、正規表現、大文字と小文字の区別、正確な一致件数を利用できます。- パラメーター:
identifier(必須)、pattern(必須)、target(デフォルトはauto)、regex、case_sensitive、context_lines(デフォルトは 3)、max_matches(デフォルトは 50)、since、until、tail(デフォルトでは直近の 1000 件)、source、exclude(検索前にノイズ行を除外します。例:"queue put failed")、prefilter、timestamps(デフォルトはtrue)、timeout_seconds、env - 負荷の高いアプリでは検索範囲を絞ってください。
sinceのみを指定すると、その時点から現在までのすべてが取得されます。ログの多いアプリでは 1 時間あたり数百 KB に達するため、30 秒の取得制限で中断され(logs_truncated: true)、さらに出力予算によって切り詰められます。調べたい時間帯の前後にsinceとuntilを指定すれば解決でき、通常は数 KB で済みます。 prefilter=Trueを指定すると、patternがサーバー側の部分文字列フィルター(modal app logs --search)として Modal に渡され、一致しない行は取得されません。取得しきれないほど大きなログに有効です。regex=Falseが必要で、前後の行には他の一致行のみが表示されます。そのため、時間帯を特定する用途に使い、その後prefilter=Falseで再検索してください。match_countとmatchesが返されます。matchesはタイムスタンプと行番号を含むコンテキストブロックで、一致した行には>が付加されます。例:> 8: 2026-06-04T... ValueError: bad input。取得したログ全体が必ず検索されるため、返されるブロックが少なくてもmatch_countは正確です。returnedは返された一致件数です(隣接する一致は 1 つのブロックにまとめられ、returned_blocksで数えられます)。excludeを使用した場合はexcluded_linesが報告されます。- CLI が拒否する検索範囲(逆転した期間、35 日超、
tailが 20,000 件超)を指定した場合は、終了コードだけではなく、Modal 独自のメッセージとともにsuccess: falseが返されます。 get_modal_logsと同様、対象は stdout/stderr/system のみです。
- パラメーター:
デプロイと実行
-
Modal アプリのデプロイ(
deploy_modal_app)- Modal アプリをデプロイします(
modal deploy)。デプロイされた Web エンドポイントは有効なまま維持されるため、出力に含まれるリンクは有効で共有できます(urlsで返されます)。 - パラメーター:
absolute_path_to_app(必須)、env、name、tag、strategy(rolling/recreate)、stream_logs - アプリのディレクトリでは、仮想環境に
modalをインストールした状態でuvを使用する必要があります。
- Modal アプリをデプロイします(
-
Modal アプリの実行(
run_modal_app)- 関数またはローカルのエントリーポイントを一度実行し、出力を収集します(
modal run)。 - パラメーター:
absolute_path_to_app(必須)、function_name、env、detach、timeout_seconds(デフォルトは 120) - タイムアウト時に実行が続いている場合は、
truncated: trueを含むスナップショットを返します。 タイムアウト後も Modal 上で長時間実行されるジョブを継続するには、detach=Trueを指定します。
- 関数またはローカルのエントリーポイントを一度実行し、出力を収集します(
modal serveツールがないのはなぜですか?modal serveは、ブロッキングプロセスの実行中に限りエンドポイントを維持します。応答を返す MCP ツールで実行すると、エンドポイントが直ちに破棄され、無効な URL が返されます。永続的に利用でき、共有可能なエンドポイントにはdeploy_modal_appを使用してください。
状態の変更
-
Modal アプリの管理(
manage_modal_app)—actionはstop(アプリを停止してコンテナを終了)またはrollback(以前のバージョンを再デプロイ)です。- パラメーター:
action(必須)、app_identifier(必須)、version(rollbackの場合のみ。直前のバージョンがデフォルトです)、env
- パラメーター:
-
Modal コンテナの管理(
manage_modal_container)—actionはexec(実行中のコンテナ内でコマンドを実行。modal container exec --no-pty)またはstop(コンテナを終了)です。- パラメーター:
action(必須)、container_id(必須)、command(execの場合のみ。引数のリスト。例:["python", "-c", "print('hi')"])、timeout_seconds(デフォルトは 60)
- パラメーター:
-
Modal ボリュームの管理(
manage_modal_volume)—actionはcreate、delete(ボリュームとその全データを削除します。取り消せません)、またはrenameです。- パラメーター:
action(必須)、volume_name(必須)、new_name(renameの場合のみ)、env
- パラメーター:
-
Modal ボリュームのファイル(
modal_volume_files)— ボリューム内のファイルに対する書き込み操作です。actionはput(アップロード)、get(ダウンロード)、cp(ボリューム内でコピー)、またはrmです。- パラメーター:
action(必須)、volume_name(必須)、local_path、remote_path、paths(cpの場合:コピー元の後にコピー先)、recursive、force、env local_path="-"を指定してaction="get"を実行すると、ファイルを書き込む代わりにファイルの内容を返します。- ボリュームの内容を一覧表示するには、
list_modal_resources(resource="volume_files")を使用します。
- パラメーター:
-
Modal シークレットの管理(
manage_modal_secret)—actionはcreateまたはdeleteです。- パラメーター:
action(必須)、secret_name(必須)、key_values(辞書)、from_dotenv(パス)、from_json(パス)、force、env。作成時は、key_values、from_dotenv、from_jsonのいずれかが少なくとも 1 つ必要です。 - 返されるすべてのフィールドで、エラー出力も含め、シークレットの値はマスキングされます。
- シークレット名を一覧表示するには、
list_modal_resources(resource="secrets")を使用します。
- パラメーター:
コスト
- Modal のコストを分析(
analyze_modal_costs)— 読み取り専用です。modal billingを一度取得してローカルで集計するため、何百もの生データ行ではなく、順位付けされた合計と期間ごとの変化を確認できます。- パラメーター:
view(デフォルトはby_app)、period、start、end、resolution(d/h)、timezone、app、environment、top_n(デフォルトは 10)、tag_names viewの値:値 回答する質問 by_app「最もコストがかかっているアプリは?」— 支出額順のアプリと、全体に占める割合 timeline「月曜日のコストが高かったのはなぜ?」— 区間ごとのコストに加え、ピーク区間をその直前の区間と比較し、増加したアプリを順位付けする explanationby_environmentどの環境に費用がかかっているか by_resourceCPU、GPU クラス、メモリ、ストレージの内訳 summary月次サイクルの請求コストと計測コスト、およびクレジットやプランの調整 rates現在の単価 groupsがtop_n件に制限されても、total_costは常に期間内のすべての行を対象とします。表示された行を合計せず、total_costをそのまま引用してください。- 請求情報はワークスペース全体が対象です(CLI では
-eを指定しません)。そのため、このツールはすべての環境を対象にレポートします。environmentを指定すると、その後で行が絞り込まれます。 - Modal が報告するのは完了した区間のみのため、途中まで経過した日のコストは低く表示されます。
- パラメーター:
シークレット — 内容の確認
- Modal シークレットを確認(
inspect_modal_secret)— シークレット内のキー名を一覧表示します。値は決して表示しません。- パラメーター:
secret_name(必須)、env、image、timeout_seconds(デフォルトは 300) - Modal は設計上、CLI、SDK、gRPC レイヤーのいずれにも API を提供していません。シークレットに定義されているキーを確認する唯一の方法は、コンテナにマウントして環境変数を一覧表示することです。そのため、このツールは
compgen -e(エクスポートされた変数の名前のみを出力する bash 組み込みコマンド)を使ってmodal shell --secret <name>を実行します。コンテナ内でも、値が出力されることはありません。その後、イメージと Modal ランタイムが設定する変数を除外します。既知の 23 個の名前に加え、6 つのプレフィックス(MODAL_、PYTHON、PIP_、NVIDIA_、CUDA_、LD_LIBRARY_PATH)に一致するものも除外します。これにより、すべてのコンテナにあるMODAL_TOKEN_*認証情報も対象になります。 - この呼び出しではリモートコンピューティングが起動するため、数十秒かかり、数セントの費用が発生します(イメージのビルドが必要な場合はさらに時間がかかります)。このサーバーのそれ以外の読み取り処理はすべて無料です。存在するシークレットの確認には
list_modal_resources(resource="secrets")を使い、シークレットの中身を知る必要がある場合にのみ、このツールを使用してください。 keysに加えて、フィルター適用前のall_env_namesも返します。これにより、ランタイム変数のように見えるキーも、黙って除外されずに確認できます。imageを省略すると、Modal のデフォルトが使用されます(サーバーの Python に合わせてビルドされており、最も確実な選択肢です)。ワークスペースのイメージビルダーがその Python バージョンを拒否する場合は、python:3.12-slimなどを指定してください。
- パラメーター:
プロンプト
このサーバーには、クライアントから直接呼び出せる 4 つの MCP プロンプト(複数ステップのワークフロー)も付属しています(Claude Code では /mcp__mcp-modal__<name> として表示されます)。プロンプトは必要に応じて取得されるため、ツールとは異なり、セッションごとのコンテキストを消費しません。
debug_modal_app(app_name、symptomは省略可能)— アプリが起動していることを確認し、コンテキストを含めてログ内のトレースバックを検索します。ログ取得結果が途中で切り詰められていた場合は、範囲を広げるのではなく狭め、ログ末尾の取得に切り替えます。続いて、同じ時間帯に関連アプリにも影響があったかを確認し、コンテナを調査した後、デプロイ履歴と比較してロールバックを検討する、順序立てたトリアージ手順です。deploy_and_verify(absolute_path_to_app、envは省略可能)— 対象のワークスペースを確認してデプロイし、公開 URL を報告した後、アプリが正常だと思い込まずに実際に検証します。review_modal_account(envは省略可能)— 読み取り専用のインベントリです。アイドル状態のアプリ、説明のつかない実行中コンテナ、孤立したボリュームやシークレットを特定し、それぞれをクリーンアップするための具体的な呼び出しを示しますが、実行はしません。investigate_modal_costs(period、appは省略可能)— 支出の増加を日ごとの推移からピーク時間、リソースクラス、そして原因となったデプロイまたは実行中のコンテナまでたどります。
出力の上限
ログ、実行、exec の出力は返される前に上限が適用されるため、出力の多いアプリによってコンテキストウィンドウが埋め尽くされることはありません。デフォルトの上限はテキストフィールドあたり 40,000 文字(約 10k トークン)です。フィールドが切り詰められた場合、結果の output_capped: true が設定され、テキストには削除された量を示すマーカーが含まれます。上限に達したフィールドには先頭と末尾の両方が残るため、起動時のバナーと末尾のトレースバックをどちらも確認できます。
検索結果は、検索前に切り詰められることはありません。search_modal_logs は取得したログ全体を grep し、返されるコンテキストブロック数だけを制限するため、match_count は常に正確です。
ログ検索の結果が途中で切れている場合、timeout_seconds や出力上限を引き上げるのは通常適切な対処ではありません。取得量を減らすのが有効です。since と until で期間を絞り、source/exclude でフィルタリングするか、prefilter=True を設定して Modal 内で一致しない行を除外してください。
MCP_MODAL_MAX_OUTPUT_CHARS を設定すると、上限を引き上げたり引き下げたりできます。0 を設定すると、上限が無効になります。
{
"mcpServers": {
"mcp-modal": {
"command": "uvx",
"args": ["mcp-modal"],
"env": { "MCP_MODAL_MAX_OUTPUT_CHARS": "80000" }
}
}
}
レスポンス形式
すべてのツールは標準化された形式でレスポンスを返します。操作の種類によって、多少の違いがあります。
# Lookups (list_modal_resources):
{
"success": True,
"apps": [...], # or "containers", "volumes", "contents", "secrets", ...
"omitted_items": 0 # present when the listing was capped at 200 entries
}
# Action operations (deploy, stop, rollback, create, delete, rename, cp, put, get, rm):
{
"success": True,
"message": "Operation successful message",
"command": "executed command string",
"stdout": "command output", # if any
"stderr": "error output" # if any
}
# Log / run / exec operations (snapshot-based):
{
"success": True,
"logs": "...", # or "output" for run/exec
"truncated": False, # True when cut off at timeout_seconds
"output_capped": False, # True when text was trimmed to fit MCP_MODAL_MAX_OUTPUT_CHARS
"command": "executed command string"
}
# Log search (search_modal_logs):
{
"success": True,
"match_count": 12, # exact: the whole fetched log is searched
"returned": 5, # matches actually shown
"returned_blocks": 2, # adjacent matches merge into one context block
"matches": ["> 8: ...", ...],
"logs_truncated": False, # True when the log fetch hit timeout_seconds
"output_capped": False,
"command": "executed command string"
}
# Error case (all operations):
{
"success": False,
"error": "Error message describing what went wrong",
"command": "executed command string",
"stdout": "command output", # if available
"stderr": "error output" # if available
}
ライセンス
このプロジェクトは MIT ライセンスの下でライセンスされています。詳細については LICENSE ファイルを参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。