AWS CLIをMCPでClaudeに実行させる — aws-api-mcp-serverの権限設計
aws-api-mcp-serverをClaude Codeに接続してAWS CLIを自然言語で実行する手順と、スコープを絞ったIAM認証情報でプロンプトインジェクションに備える権限設計を示します。
aws-api-mcp-serverは、AWS Labsが公開しているMCPサーバーです。Claude Codeに繋ぐとAWS CLIの全コマンドを自然言語の指示から実行でき、EC2やS3の日常的な確認作業をチャットのやり取りだけで済ませられます。核心は権限設計です。AWS認証情報をそのまま渡すと、権限分だけリスクが膨らみます。プロンプトインジェクションで意図しない削除コマンドが実行される可能性がある以上、スコープを絞ったIAMロールと読み取り専用モードの組み合わせが前提になります。
aws-api-mcp-serverで何ができるか
call_awsツールは1回の呼び出しでAWS CLIコマンドを1つ実行します。「us-west-2のS3バケットを一覧表示して」のような指示から、Claudeが対応するコマンドを組み立てて実行する流れです。suggest_aws_commandsツールは自然言語のクエリに対して候補コマンドを5件提示するため、モデルの知識カットオフ後に追加されたAWS CLIコマンドも扱えます。コマンドは実行前に妥当性を検証します。任意のコード実行はできません。
前提条件
Python 3.10以上と、設定済みのAWS認証情報が必要です。認証情報は環境変数よりもAWS_API_MCP_PROFILE_NAMEでプロファイルを指定する方法が推奨されています。複数プロファイルを使い分けている場合、優先順位を誤ると意図しないアカウントにコマンドが飛ぶため、接続前にaws configure listで有効なプロファイルを確認しておきます。AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKENを環境変数で直接渡す方法もありますが、プロファイル参照より認証情報の露出範囲が広がるため、CI等の一時利用に留めます。
Claude Codeに接続する
uvxを使えばパッケージのインストールは不要です。
claude mcp add --env AWS_REGION=us-east-1 \
--env AWS_API_MCP_PROFILE_NAME=readonly-profile \
--env READ_OPERATIONS_ONLY=true \
--transport stdio aws-api \
-- uvx awslabs.aws-api-mcp-server@latest--より後ろがサーバー起動コマンドです。--envで渡した環境変数はサーバープロセスに引き継がれます。AWS_REGIONを省略すると、boto3の設定チェーンをたどったうえで最終的にus-east-1にフォールバックします。pipでインストールする場合、サーバー同梱のAWS CLIバージョンがローカルのものと衝突し、意図せずダウングレードされることがあります。仮想環境を切ってからpython -m awslabs.aws_api_mcp_server.serverを起動コマンドに指定すると安全です。Dockerで隔離する選択肢もあります。public.ecr.aws/awslabs-mcp/awslabs/aws-api-mcp-serverイメージが提供されています。
使ってみる — 具体的な指示例
接続が終わったら、まずは読み取り系の指示で動作を確認します。「us-west-2のS3バケットを一覧表示して」「稼働中のEC2インスタンスを見せて」といった指示に対し、Claudeはsuggest_aws_commandsで候補コマンドを絞り込み、call_awsで実行します。書き込みを伴う「Webサーバー用のセキュリティグループを新規作成して」のような指示は、IAM権限が許可している場合だけ実行されます。複雑な多段階のタスクにはget_execution_planという実験的なツールもあります。EXPERIMENTAL_AGENT_SCRIPTS=trueで有効にすると、あらかじめ用意された手順書(agent scripts)に沿って複数のAWS操作をまとめて案内します。独自の手順を.script.md形式で追加することもできますが、正式機能ではなく実験的な扱いです。
ログとAgentCoreでの本番運用
本番運用では、ログとホスティング方法も検討します。サーバーはコマンド実行やエラーを~/.aws/aws-api-mcp/aws-api-mcp-server.logに自動でローテーションしながら記録します。CloudWatch Agentを併用すれば、このログをCloudWatch Logsへ集約できます。ローカルでの起動に代えて、Amazon Bedrock AgentCore Runtimeへの自己ホストも選べます。認証とセッション分離を備えたコンテナ環境で、スケーリングやセキュリティの管理をAWS側に任せられます。個人の開発端末で試す段階なら、ローカル起動で十分です。
権限とプロンプトインジェクション対策を設計する
aws-api-mcp-serverはIAM権限をそのまま実行権限として使います。AdministratorAccessロールの認証情報を渡せば書き込みも削除もできてしまうため、用途に応じて権限を絞る設計が本体です。サーバー側には3段の防御があります。
| 防御手段 | 何を止めるか | 向く場面 |
|---|---|---|
| IAMロールのスコープ | 何を止めるかAPIレベルでの操作範囲 | 向く場面常設の一次防御。用途別にロールを分ける |
READ_OPERATIONS_ONLY=true | 何を止めるか書き込み系APIの呼び出し自体 | 向く場面調査・監視のみで使う接続 |
REQUIRE_MUTATION_CONSENT=true | 何を止めるか書き込み実行前のユーザー確認(elicitation対応クライアント限定) | 向く場面書き込みも許すが都度承認したい接続 |
READ_OPERATIONS_ONLYはAWSのAPI分類でWriteでない操作だけを許可します。ただし読み取り系APIでも認証情報や機密情報を含む応答が返ることがあります。IAM側の権限も合わせて絞る必要があります。CloudWatchログや外部ユーザーが書き込んだデータベースのように、信頼できないデータをこのサーバーに接続しないのが公式の注意です。被害の範囲はIAM側の設定で決まります。
サーバーには操作の拒否リストもあり、deploy install/uninstallとemr ssh/sock/get/putはサブプロセスを起動するため一律ブロックされます。それ以上に細かい制御が必要なら、~/.aws/aws-api-mcp/mcp-security-policy.jsonにdenyListとelicitListをコマンド単位(aws iam delete-userのような完全一致)で書けます。ワイルドカードには対応していません。iam:delete-*のような一括禁止はできず、止めたいコマンドを1つずつ列挙します。
複数の制御を組み合わせたときの優先順位は、denyList → 承認が必要なelicitList → IAM権限 → READ_OPERATIONS_ONLYの順です。denyListに載ったコマンドは、他の設定に関わらず実行されません。最終的な安全網はIAM権限で、それ以外の仕組みはすべて補助線と考えておきます。公式ドキュメントはほかに、条件文でリージョンを絞る運用や、CloudTrailでの定期監視も推奨しています。拒否リストと合わせて平時の監査ログも用意しておくと、想定外の呼び出しに気づきやすくなります。
つまずきやすいポイント
- マルチテナント非対応: このサーバーは1ユーザー・1認証情報での利用が前提です。複数人で共有するサーバーとして立てると設計外の使い方になります
- ファイルシステムに既定のサンドボックスがない:
AWS_API_MCP_ALLOW_UNRESTRICTED_LOCAL_FILE_ACCESSが既定のworkdirモードでも、確認を挟まずファイルを上書き・削除します。既定の作業ディレクトリはOSごとのテンポラリ領域(macOSは/private/var/folders/...、Linuxは/tmp/aws-api-mcp/workdir)なので、AWS_API_MCP_WORKING_DIRを明示しておくほうが場所を把握しやすくなります。aws s3 syncはディレクトリごと上書きし得るため、作業ディレクトリを専用に切っておきます - HTTPモードは単一顧客向け:
streamable-httpトランスポートは複数ユーザーへの同時提供を想定していません。ネットワーク越しに使うならAUTH_TYPE=oauthを有効にし、TLSも別途用意します。AWS_API_MCP_ALLOWED_HOSTSとAWS_API_MCP_ALLOWED_ORIGINSでHost/Originヘッダーを検証し、AWS_API_MCP_STATELESS_HTTPは既定のfalseのまま変更しないほうが安全です
後継サーバーへの移行が進んでいる
aws-api-mcp-serverは、AWSが公式に提供するAWS MCP Serverの前身にあたる存在になりました。READMEの先頭には後継サーバーへの案内が明記され、call_awsは後継のaws___call_awsに対応します。複数のAPI呼び出しを1回のスクリプト実行にまとめるaws___run_scriptや、AWS公式ドキュメントをその場で検索するaws___search_documentationが新たに加わっています。後継はAWSが運用するフルマネージドのリモートサーバーで、CloudWatchメトリクスとCloudTrailの監査ログが標準で付きます。旧サーバーには公式ドキュメントを参照する仕組みがなく、モデルの学習データだけを頼りにコマンドを組み立てていました。後継のaws___read_documentationとaws___retrieve_skillは、公式ドキュメントの全文取得とCloudFormation設計パターンのような手順書の検索・読み込みに対応し、新しいAPIパラメータの幻覚(hallucination)を減らす狙いがあります。全リージョンのS3バケットを列挙してタグの無いものだけ処理する、といった多段階の作業も、旧来のcall_awsでは呼び出しのたびに往復が発生していましたが、aws___run_scriptなら1回のスクリプト実行で完結します。aws-api-mcp-serverは動作を続けています。ただしサーバー起動時と各ツールの説明文に移行を促す通知が出るようになりました。この通知はAWS_API_MCP_SUPPRESS_DEPRECATION_WARNING=trueで止められます。新規に接続するなら、この通知を無視して古い方を選ぶ理由は薄いところです。
移行の実体は、サーバー本体をローカルで丸ごと動かす方式から、管理サーバーへ薄いプロキシで繋ぐ方式への切り替えです。設定は次のように変わります。
// Before: aws-api-mcp-serverをローカルで実行
{
"mcpServers": {
"awslabs.aws-api-mcp-server": {
"command": "uvx",
"args": ["awslabs.aws-api-mcp-server@latest"],
"env": { "AWS_REGION": "us-west-2" }
}
}
}// After: mcp-proxy-for-awsで管理サーバーへ接続
{
"mcpServers": {
"aws-mcp": {
"command": "uvx",
"args": [
"mcp-proxy-for-aws@1.6.3",
"https://aws-mcp.us-east-1.api.aws/mcp",
"--metadata", "AWS_REGION=us-west-2"
]
}
}
}uvxが起動するものが変わる点に注意します。Beforeはサーバー本体がローカルで動き、ローカルのboto3でAWS APIを呼びます。Afterはmcp-proxy-for-awsという薄いプロキシだけがローカルで動き、実行はAWSが管理するエンドポイント側で行われます。AWS_REGIONの指定場所も、envブロックからプロキシの--metadata引数に移ります。プロキシのバージョンは@latestではなくmcp-proxy-for-aws@1.6.3のように固定し、依存関係が意図せず更新されるサプライチェーンリスクを避けます。旧サーバーのエントリは削除します。両方を同時に登録すると、ツール名が競合してエージェントが混乱します。
まとめ
aws-api-mcp-serverでAWS CLIをClaudeに委ねるときの要は権限設計です。READ_OPERATIONS_ONLYやREQUIRE_MUTATION_CONSENTはあくまで補助線で、IAMロールを用途別に分けるのが一次防御になります。読み取り専用の調査用途なら、このサーバーで今すぐ十分です。新規導入や本番運用を見据えるなら、後継のAWS MCP Serverへの移行計画も合わせて確認しておきます。MCPサーバーの信頼判断を広く整理したい場合はMCPセキュリティガイド、Kubernetesで同種の権限設計をした例はKubernetes MCPサーバーの権限設計が参考になります。AWS上でClaude Codeを使う別の側面としてはAWS BedrockのClaude料金、CloudFormation/CDKの検証はAWS IaCをMCPで検証するで扱います。メッセージキューではamazon-mq organizationが配布する汎用RabbitMQ向けサーバーがあり、RabbitMQのMCPサーバーで扱います。