Claude Code Action + AWS MCPサーバーを用いたインフラコストの事前要約
はじめに
こんにちは!サロンスタッフ予約サービス「minimo」でインフラ周りを担当している洗川です。
minimoでは、サービスの安定稼働のために週次で「インフラ定例」を開催し、AWSの利用料金や各種サービスのメトリクスを定点観測しています。しかし人の目で見る以上、多少の手間や見落としがどうしても発生してしまいます。
そこで今回は、この定例確認項目をClaude Code ActionおよびBilling and Cost Management MCP サーバーで事前要約し、効率化と人の目では見落としがちな変化点の発見を目指した取り組みをご紹介します。
Claude Code Action (Beta) での実装
まず私たちが試したのが、他リポジトリで既に利用されていたanthropics/claude-code-action@beta
です。これを使って、費用や特定のCloudWatchダッシュボードのメトリクスを先々週と比較し、その推移を要約させるGitHub Actionsのワークフローを組みました。
手動で実行できるよう、workflow_dispatch
をトリガーにしています。
# Claude Code Action (Beta版)
name: Claude Infra Summary Action (Beta)
on:
workflow_dispatch:
jobs:
claude-infra-summary:
runs-on: ubuntu-latest
timeout-minutes: 35
env:
AWS_REGION: ap-northeast-1
permissions:
contents: read
id-token: write
actions: write
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: astral-sh/setup-uv@557e51de59eb14aaaba2ed9621916900a91d50c6 # v6.6.1
with:
enable-cache: true
- uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b # v2.1.1
id: generate-token
with:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4.3.1
with:
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
aws-region: ${{ env.AWS_REGION }}
- id: mcp-config
run: echo "config=$(jq -c . .claude/mcp.json)" >> $GITHUB_OUTPUT
- uses: anthropics/claude-code-action@beta
with:
mode: "agent"
timeout_minutes: "30"
github_token: ${{ steps.generate-token.outputs.token }}
use_bedrock: "true"
model: "apac.anthropic.claude-sonnet-4-20250514-v1:0"
custom_instructions: |
文章は日本語で記述してください。
mcp_config: ${{ steps.mcp-config.outputs.config }}
allowed_tools: |
Bash(aws cloudwatch list-dashboards:*)
Bash(aws cloudwatch get-dashboard:*)
mcp__billing-cost-management-mcp-server__cost-explorer
mcp__billing-cost-management-mcp-server__cost-comparison
mcp__billing-cost-management-mcp-server__session-sql
mcp__cloudwatch-mcp-server__get_metric_data
mcp__cloudwatch-mcp-server__get_metric_metadata
mcp__cloudwatch-mcp-server__get_active_alarms
direct_prompt: |
具体的な指示を記述する
実装で少しハマった3つのポイント
一見シンプルに見えますが、このワークフローを安定して動かすまでには、いくつかのポイントで少しハマりました。
mcp_config
の見落とし
ポイント1: Claude Code ActionがAWSの情報を取得するには、MCP (Model Context Protocol) という仕組みでツールを定義する必要があり、そのための設定がmcp_config
です。これは必須の設定項目でしたが、これを見落としJSONを用意するだけにとどまっており、「なぜかAWS系のツールだけ動かない…」という状況で少し時間を溶かしてしまいました。
ポイント2: 複数行JSONの渡し方の工夫
mcp_config
にはJSON形式で設定を渡しますが、GitHub Actionsのoutputs
で複数行の文字列を扱うには少し工夫が必要です。当初、cat .claude/mcp.json
のようにファイル内容をそのまま渡そうとしたところ、複数行の文字列がうまく扱えずInvalid format
エラーが発生してしまいました。
これは、複数行の文字列を正しくエスケープしてoutputs
に渡すのが難しいためです。そこで、jq -c .
コマンドを使ってJSONファイルを一行の文字列に圧縮し、引き渡すことでこの問題を解決しました。
ポイント3: 意図しないリージョンの参照
無事にツールが動き出したと思いきや、今度はCloudWatchから空のメトリクスが返ってくる事象に遭遇。原因は、MCPサーバーがデフォルトで参照するリージョンが、私たちの意図しないリージョンになっていたことでした。
対策として、mcp.jsonファイル内で、各ツールが使用するAWSリージョンをap-northeast-1に明示的に指定することで解決しました。
{
"mcpServers": {
"billing-cost-management-mcp-server": {
"command": "uvx",
"args": ["awslabs.billing-cost-management-mcp-server@latest"],
"env": {
"AWS_REGION": "ap-northeast-1"
}
},
"cloudwatch-mcp-server": {
"command": "uvx",
"args": ["awslabs.cloudwatch-mcp-server@latest"],
"env": {
"AWS_REGION": "ap-northeast-1"
}
}
}
}
v1へのアップグレードと改善
試行錯誤の末に稼働したBeta版ですが、v1が提供されていることからアップグレードすることにしました。公式ドキュメントを参考に移行作業を進めました。
v1ではパラメータの構成が大きく変わり、Beta版のmode
やcustom_instructions
, direct_prompt
などがprompt
とclaude_args
に集約され、よりシンプルで分かりやすくなりました。
最終的なワークフロー (v1)
そして、こちらがv1に移行した最終的なワークフローです。
# Claude Code Action (v1)
name: Claude Infra Summary Action
on:
workflow_dispatch:
jobs:
claude-infra-summary:
runs-on: ubuntu-latest
timeout-minutes: 35
env:
AWS_REGION: ap-northeast-1
permissions:
contents: read
id-token: write
actions: write
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: astral-sh/setup-uv@557e51de59eb14aaaba2ed9621916900a91d50c6 # v6.6.1
with:
enable-cache: true
- uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b # v2.1.1
id: generate-token
with:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4.3.1
with:
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
aws-region: ${{ env.AWS_REGION }}
- uses: anthropics/claude-code-action@fd2c17f101639b10696381c1fd85fa735239090a # v1.0.5
with:
github_token: ${{ steps.generate-token.outputs.token }}
use_bedrock: "true"
prompt: |
具体的な指示を記述する
claude_args: |
--model apac.anthropic.claude-sonnet-4-20250514-v1:0
--system-prompt "文章は日本語で記述してください。"
--allowedTools "Bash(aws cloudwatch list-dashboards:*)" "Bash(aws cloudwatch get-dashboard:*)"
--allowedTools "mcp__billing-cost-management-mcp-server__cost-explorer" "mcp__billing-cost-management-mcp-server__cost-comparison" "mcp__billing-cost-management-mcp-server__session-sql"
--allowedTools "mcp__cloudwatch-mcp-server__get_metric_data" "mcp__cloudwatch-mcp-server__get_metric_metadata" "mcp__cloudwatch-mcp-server__get_active_alarms"
--mcp-config .claude/mcp.json
v1へのアップグレードにより、苦労したmcp_config
の指定が--mcp-config .claude/mcp.json
のようにファイルパスを直接渡すだけで済むようになり、YAMLの可読性が大幅に向上しました。
まとめ
Claude Code Actionを活用してインフラ定例のサマリーを自動化したことで、AIが客観的な視点でメトリクスの変動を網羅的にチェックしてくれるため、これまで人の目では気づきにくかったようなコストの変動を捉えることに繋がるようになったかと思います。
GitHub Actionsと生成AIを組み合わせることで、開発生産性だけでなく、このような運用業務も大きく効率化できる可能性を感じました。
同じような定例業務に課題を感じている方の参考になれば幸いです。
最後に
minimoでは、サービス開発に一緒に挑戦してくれる仲間を募集しています!ご興味のある方は、ぜひ採用ページをご覧ください。
Discussion