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ロールと読み取り専用モードの組み合わせが前提になります。
Claude CodeからAWS CLIを使う道は2つあります。
| 方法 | 実行の場所 | 向く場面 |
|---|---|---|
| aws-api-mcp-server(本記事の主題) | 実行の場所ローカルでAWS CLIを組み立てて実行 | 向く場面既存のプロファイルと権限設計をそのまま使う |
| 後継のAWS MCP Server(AWS公式プロキシ経由) | 実行の場所AWS管理のエンドポイントで実行 | 向く場面新規導入、複数APIをまとめて呼ぶ作業 |
接続コマンドは「Claude Codeに接続する」、後継への切り替えは「後継のAWS MCP Serverへ移すと何が変わるか」にあります。
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で渡した環境変数は、サーバープロセスにそのまま引き継がれます。
Claude Code v2.1.287で、一時ディレクトリを使って-s projectを付けて同じコマンドを実行すると、プロジェクト直下の.mcp.jsonに次のエントリが書き出されました。.mcp.jsonの中身を先に見ておけば、環境変数がどこに入るかを接続前に確かめられます。
{
"mcpServers": {
"aws-api": {
"type": "stdio",
"command": "uvx",
"args": ["awslabs.aws-api-mcp-server@latest"],
"env": {
"AWS_REGION": "us-east-1",
"AWS_API_MCP_PROFILE_NAME": "readonly-profile",
"READ_OPERATIONS_ONLY": "true"
}
}
}
}このコマンドの出力は、書き出し先を伝える2行だけでした。エントリが書けたことと、サーバーが実際に動くかどうかは別の話なので、接続の成否は起動後にClaude Code側で確かめます。
サーバー名の置き場所にも癖があります。--envの直後にサーバー名を書くと、名前が環境変数の1つとして読まれます。実際に--env AWS_REGION=us-east-1 aws-bad -- uvx xと打つと、次のエラーで止まりました。
Invalid environment variable format: aws-bad, environment variables should be added as: -e KEY1=value1 -e KEY2=value2--envは複数の値を取る引数です。上のコマンドで--transport stdioを--envと名前の間に挟んでいるのは、この読み違いを避けるためです。
AWS_REGIONを省略すると、boto3の設定チェーンをたどったうえで最終的にus-east-1にフォールバックします。pipでインストールする場合は注意が要ります。サーバー同梱のAWS CLIバージョンがローカルのものと合わず、ローカルのAWS CLIがダウングレードされることがあるためです。仮想環境を切り、その中のpythonを起動コマンドに指定します。Dockerで隔離する選択肢もあり、public.ecr.aws/awslabs-mcp/awslabs/aws-api-mcp-serverイメージが提供されています。
使ってみる — 読み取り系の指示から始める
接続が終わったら、まずは読み取り系の指示で動作を確認します。請求とコストの参照だけが目的なら、コスト用に定義済みのツールを持つAWS Billing MCPサーバーのほうが権限を絞りやすくなります。「us-west-2のS3バケットを一覧表示して」「稼働中のEC2インスタンスを見せて」といった指示に対し、Claudeはsuggest_aws_commandsで候補コマンドを絞り込み、call_awsで実行します。書き込みを伴う「Webサーバー用のセキュリティグループを新規作成して」のような指示は、READ_OPERATIONS_ONLYを外し、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の話で、読み取り系の操作でもローカルにファイルを書き出すことはあります。また、読み取り系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つずつ列挙します。
制御が重なったときの評価順
- 1
denyList
載っているコマンドは、他の設定に関わらず実行されません。
- 2
elicitList
載っているコマンドは、ユーザーの承認を求めます。承認画面を出せるelicitation対応のクライアントが前提です。
- 3
IAM権限
標準のIAM制御が、すべての操作に掛かります。
- 4
READ_OPERATIONS_ONLY
有効なときだけ、書き込み系の分類に当たる操作を止めます。
READMEが「IAM権限が一次の制御」と明記しているとおり、セキュリティポリシーはIAMを上書きできません。IAMで許していない操作は、elicitListで承認してもAWS側に拒否されます。反対に、IAMが許していてもdenyListに載せれば実行前に止まります。公式はほかに、条件文でリージョンなどを絞る運用と、CloudTrailでの監視も推奨しています。
つまずきやすいポイント
- マルチテナント非対応: このサーバーは1ユーザー・1認証情報での利用が前提です。複数人で共有するサーバーとして立てると設計外の使い方になります
- ファイル操作の制限は引数に直接書いた経路だけ:
AWS_API_MCP_ALLOW_UNRESTRICTED_LOCAL_FILE_ACCESSの既定値はworkdirです。このとき、コマンドの引数に直接書いたパスはAWS_API_MCP_WORKING_DIRの中に限られます。範囲外のパスを含むコマンドは拒否されます。ただし引数が指すファイルの中身から参照される別のファイルは、AWS CLI側で解決されるため制限の対象外です。この制限は引数のパスを照合する仕組みで、OSレベルの隔離ではありません。READMEも"No Sandboxing"と明記しています。unrestrictedにするとシステム全体に届き、no-accessにするとaws s3 cpのようなローカルファイルを要する操作が失敗します。READMEは、aws s3 syncがディレクトリごと上書きし得る点と、書き換えに追加の確認が入らない点も挙げています。作業ディレクトリを専用に切るなら、AWS_API_MCP_WORKING_DIRに絶対パスで指定します。未指定のときは、OSごとの一時領域が既定になります。macOSは/private/var/folders/<hash>/T/aws-api-mcp/workdirです。Linuxは$XDG_RUNTIME_DIR、未設定なら$TMPDIR、それも無ければ/tmpの下のaws-api-mcp/workdirです。 - 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 MCP Serverへ移すと何が変わるか
aws-api-mcp-serverは、AWSが公式に提供するAWS MCP Serverの前身にあたります。READMEの先頭には後継への案内があり、サーバー起動時と各ツールの説明文にも移行を促す通知が出ます。通知はAWS_API_MCP_SUPPRESS_DEPRECATION_WARNING=trueで止められます。旧サーバー自体は動作を続けています。後継側の接続方式の選び方はClaudeとAWS MCPサーバーの連携にあります。
移行で変わる実行の場所
旧: aws-api-mcp-server
uvxがサーバー本体を起動し、ローカルのboto3でAWS APIを呼びます。ツールはcall_awsとsuggest_aws_commandsです。公式ドキュメントを引く仕組みはなく、モデルの学習データを頼りにコマンドを組み立てます。
新: AWS MCP Server
uvxが起動するのはmcp-proxy-for-awsという薄いプロキシだけで、実行はAWSが管理するエンドポイントで行われます。aws___run_scriptを使えば、複数のAPI呼び出しを1回にまとめられます。aws___search_documentationやaws___retrieve_skillでは、最新の公式ドキュメントと手順書を引けます。
API呼び出しの範囲は変わらないと、移行ガイドは述べています。変わるのは往復の回数です。全リージョンのS3バケットを列挙してタグの無いものだけ処理する作業は、call_awsでは呼び出しのたびに往復が発生しました。aws___run_scriptなら1回のスクリプト実行で済みます。
移行ガイドの例はuvx mcp-proxy-for-aws@...の形です。一方、PyPIのREADMEはCLI・uvxで使う場合に依存関係を固定したmcp-proxy-for-aws-cliを案内しています。無印はコードから読み込むライブラリ用です。次の登録例は移行ガイドの表記に合わせています。
claude mcp add --transport stdio aws-mcp \
-- uvx mcp-proxy-for-aws@1.7.0 \
https://aws-mcp.us-east-1.api.aws/mcp \
--metadata AWS_REGION=us-west-2設定ファイルで直接書き換えるときの差し替えは次のとおりです。
// 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.7.0",
"https://aws-mcp.us-east-1.api.aws/mcp",
"--metadata", "AWS_REGION=us-west-2"
]
}
}
}注意点は3つあります。
- リージョンが2つに分かれる: エンドポイントURLのリージョンはMCPサーバーが動く場所で、
--metadata AWS_REGIONは操作の既定リージョンです。両者は別々に決められます。--metadataを省くと、操作はus-east-1が既定になります - プロキシは固定する:
@latestでなくmcp-proxy-for-aws@1.7.0のように版を固定します。移行ガイドの例は1.6.3ですが、PyPIの最新は1.7.0です。未固定だと依存関係が導入時点の最新に解決され、依存先が侵害されたときのサプライチェーンリスクになります。mcp-proxy-for-aws-cliは、依存ツリーごと版を固定した配布物です。固定する版はPyPIで最新を確認して選びます - 旧エントリは消す: 両方を同時に登録するとツールが競合してエージェントが混乱する、と移行ガイドにあります
旧サーバーの環境変数は新側でどこへ行くか
旧設定のenvブロックは、新側では丸ごと不要になります。ただし、権限設計で使った変数は、行き先が変数ごとに違います。
| 旧の環境変数 | 新側での扱い |
|---|---|
READ_OPERATIONS_ONLY | 新側での扱いプロキシの--read-onlyフラグ(書き込みの可能性があるツールごと無効にする)、またはIAM条件キー |
REQUIRE_MUTATION_CONSENT | 新側での扱い対応なし。書き込みの可否はIAMポリシーで制御 |
AWS_API_MCP_PROFILE_NAME | 新側での扱いプロキシの--profile <name> |
AWS_ACCESS_KEY_IDなど | 新側での扱い環境変数では渡さない。aws configureなどのローカル認証チェーンを使う |
AWS_API_MCP_WORKING_DIR | 新側での扱い対応なし。管理サーバーはサンドボックス実行で、ローカルのパスを使わない |
つまずきやすいのはREQUIRE_MUTATION_CONSENTの行です。移行ガイドはこの変数を「不要で、書き込みの可否はIAMポリシーで制御する」としています。承認制だった操作は、新側ではIAMで許すか拒むかの二択になります。移行前に旧サーバーのelicitListに載せていた操作を洗い出し、拒むべきものはIAMポリシーで拒否しておくのが安全です。
まとめ
持ち帰る判断は2つです。1つは、IAMロールを用途別に分けた接続を一次防御にすること。もう1つは、新規に導入するなら後継のAWS MCP Serverも候補に入れることです。
MCPサーバーの信頼判断を広く見たいときはMCPセキュリティガイドが役立ちます。Kubernetesで同種の権限設計をした例はKubernetes MCPサーバーの権限設計にあります。AWS上のClaude利用ではAWS BedrockのClaude料金があり、CloudFormation/CDKの検証はAWS IaCをMCPで検証するが扱っています。メッセージキューは、amazon-mq organizationの汎用RabbitMQ向けサーバーをRabbitMQのMCPサーバーで見られます。