
DevOps AgentにMCPサーバーを追加してEC2のOS調査をしてみた
こんにちは。たかやまです。
DevOps Agentは環境を変更しないガードレールの観点から、EC2のOS上でコマンドを実行して調べることはできません。
そのため、プロセスやOSのログといった情報は、CloudWatchなどに送っていない限り、DevOps Agentの調査の材料になりません。
アップデートで追加されたDirected Actions(エージェントアクション)を使えば、SSM Documentを通じてOS調査を実行することはできます。
ただ、こちらは実行のたびに承認が必要で、Investigation(自律調査)の中では使えません。
できれば参照だけの権限に絞ったまま、Investigationの中でもOS調査ができるようにしたいところです。
そこで使えそうなのが、MCPサーバーによるDevOps Agentの機能拡張です。
MCPサーバーのテンプレートは、以下のブログで紹介されています。
今回は、EC2のOS情報を取得するMCPサーバーを作り、Investigationの中でOS調査させられるかを試してみます。
さきにまとめ
- MCPサーバーはLambda Function URL(
AWS_IAM)で公開し、DevOps AgentからはSigV4で接続する - MCPサーバーでは、OS情報を取るコマンドをSSM Documentに固定してツールとして公開することで、破壊的な操作をされるリスクを最小化する
- OS調査用MCPサーバー追加することで、Investigation内でもOSの情報から自律的に原因のプロセスを特定可能
構成
今回の構成は以下のようになります。

DevOps AgentがMCPのツールを呼ぶと、MCPサーバー(Lambda)がSSM Run Commandで自作のDocumentを実行します。
DocumentはEC2上で固定のコマンドを実行し、その結果がAgentに返ります。
Agent自身にはSSMの権限を持たせず、SSMを呼べるのはLambdaの実行ロールだけにしています。
やってみる
MCPの実装
OS調査の場合は、ssm:SendCommandでEC2上のコマンドを実行する必要があります。
ただ、SendCommandは任意のコマンドを実行できる権限なので、破壊的な操作をされるリスクがあります。
DevOps Agentの標準の権限にSendCommandが含まれていないのも、このためだと考えられます。
そこで、今回は実行するコマンドをSSM Documentに固定し、Agentには「どの調査を、どのインスタンスに対して行うか」だけを渡す形にしました。
公開したツールは以下の7つです。
| ツール | 取得できる内容 | 主な引数 |
|---|---|---|
get_os_summary |
OS種別、カーネル、ホスト名、稼働時間 | instance_id |
get_resource_usage |
CPUとメモリの状況、CPU使用率の高いプロセス | instance_id、top_n |
get_disk_usage |
ファイルシステムごとの空き容量とinode使用状況 | instance_id |
get_network_state |
LISTEN中のポートとプロセス、ソケットの統計 | instance_id |
get_service_status |
systemdサービスの状態と直近のログ | instance_id、service |
search_system_log |
journalctlのエラーログ(文字列で絞り込み可) | instance_id、pattern、lines |
get_kernel_messages |
dmesgの末尾 | instance_id、lines |
各ツールは、SSM Documentのactionパラメーターに対応しています。
actionに指定できるのは決められた7つの値だけで、targetに使える文字も英数字と一部の記号に限っています。
値がこの条件に合わなければ、SSMがInvalidParametersで拒否します。
parameters:
action:
type: String
allowedValues: [os_summary, resource_usage, disk_usage, network_state, service_status, system_log, kernel_messages]
target:
type: String
default: ''
allowedPattern: '^[A-Za-z0-9._@:-]{0,64}$'
limit:
type: String
default: '200'
allowedPattern: '^[1-9][0-9]{0,3}$'
SSM Documentの実行部分(抜粋)
case "{{ action }}" in
os_summary)
uname -a
cat /etc/os-release
hostnamectl 2>/dev/null || hostname
uptime
;;
resource_usage)
uptime
free -m
ps aux --sort=-%cpu | head -n "{{ limit }}"
;;
disk_usage)
df -hT
df -i
;;
# 以下、network_state / service_status / system_log / kernel_messages
*)
echo "unsupported action"
exit 1
;;
esac
また、LambdaのIAMポリシーでは、ssm:SendCommandの対象をこのDocumentに絞っています。
AWS-RunShellScriptのように任意のコマンドを実行できるDocumentは、Lambdaから送れません。
今回はLambdaをFunction URL(認証方式AWS_IAM)で公開し、CDKでデプロイします。
npx cdk deploy os-investigation-mcp-stack
cdkアプリは以下のリポジトリに公開しています。
デプロイが終わると、Function URLがOutputに出力されます。
Outputs:
os-investigation-mcp-stack.McpEndpoint = https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.lambda-url.ap-northeast-1.on.aws/
os-investigation-mcp-stack.InvestigationDocumentName = OsInvestigationReadOnly
DevOps AgentにMCPサーバーを登録する
次に、デプロイしたLambdaをDevOps AgentにMCPサーバーとして登録します。
対象のAgent Spaceで「機能」 > 「MCP サーバー」を開き、登録を進めます。


認証フローは「AWS SigV4」を選び、以下のように設定します。
| 項目 | 設定値 |
|---|---|
| エンドポイントURL | Function URL |
| IAMロール | DevOps Agentが引き受けるIAMロール |
| AWSリージョン | ap-northeast-1 |
| サービス名 | lambda |


「DevOps Agentが引き受けるIAMロール」には、Function URLを呼び出す権限を設定しておく必要があります。

登録できたら、「MCP サーバーツール」から使うツールを選びます。
ツールは、以下の3つの分類のどれかに振り分ける必要があり、分類によってAgentがツールを呼び出すときの動作が変わります。
| 分類 | 意味 | 動作 |
|---|---|---|
READ_ONLY |
情報を読み取るだけのツール | 読み取り専用のアクションとして使える |
MUTATIVE |
リソースを作成または変更できるツール | エージェントアクションの有効化と、チャットでの操作ごとの承認が必要になる |
DESTRUCTIVE |
リソースを削除する、または元に戻せない変更をするツール | Agentはこの分類のツールを呼び出さない |
参考 : Categorizing tools for third-party integrations
カスタムMCPサーバーの場合、この分類はユーザーの責務で決める必要があります。

今回はOSの状態を確認するコマンドだけを定義したSSM Documentを使うため、READ_ONLYに振り分けます。
InvestigationでOS調査してみる
では実際にInvestigationで調査させてみます。
検証用のEC2(Amazon Linux 2023)で、yesコマンドをreport-batchという名前で2本動かし、CPUを張り付かせておきます。
yesのままだとプロセス名で原因が分かってしまうため、バッチ処理を想定した名前に変えています。
Session ManagerでEC2に接続し、以下のコマンドを実行します。
sudo cp /usr/bin/yes /usr/local/bin/report-batch
sudo setsid -f /usr/local/bin/report-batch > /dev/null 2>&1
sudo setsid -f /usr/local/bin/report-batch > /dev/null 2>&1
この状態で、Investigationに以下のプロンプトで原因を調べさせます。
EC2 インスタンス i-xxxxxxxxxxxxxxxxx(Amazon Linux 2023)で CPU 使用率が高い状態が続いており、応答が遅いという報告がありました。
このインスタンスは CloudWatch に OS 内部のメトリクスやログを送っていません。
CPU 使用率が上がっている原因を調査し、原因の候補を報告してください。
確認できた事実と、確認できなかった事項は分けて記載してください。
まずはMCPサーバーを外した状態で調査させてみます。
調査ギャップにある通り、OS内部は確認できないため、原因となっているプロセスの特定には至りませんでした。
(なお、仮説にはreport-batchが挙がっていますが、これは事前に検証したときの調査結果を参照したもので、今回の調査で判明したものではありません。)

次に、MCPサーバーを追加した状態で同じプロンプトを投げてみます。
今度は、SSMが使える状態かを確認したうえで、登録したOS調査用のMCPツールを呼び出しています。

MCPツールの中身はSSM DocumentのRun Commandなので、Run Commandの「コマンド履歴」に実行の記録が残ります。
CloudWatch Logsへ出力するように設定すれば、OS調査の結果も残せます。

OSの情報を取得できたことで、根本原因としてreport-batchのプロセスを特定し、プロセスを停止する緩和計画まで作成されました。
OSの情報をもとにしているので、緩和計画もOS上の操作を含む内容になっていますね。


せっかくなので、この緩和計画をエージェントアクションで実行するよう指示してみます。

実行内容を見ると、AWS-RunShellScriptでreport-batchのプロセスを停止するコマンドを実行しています。
{
"service_name": "ssm",
"operation_name": "send_command",
"parameters": {
"InstanceIds": [
"i-0ab9924cc6707a117"
],
"DocumentName": "AWS-RunShellScript",
"Parameters": {
"commands": [
"sudo kill -9 121621 121623",
"sleep 2",
"echo '=== プロセス停止確認 ==='",
"ps aux | grep report-batch | grep -v grep || echo 'report-batch プロセスはすべて停止しました'",
"echo '=== 現在の CPU ロード ==='",
"uptime"
]
},
"Comment": "緩和計画ステップ1: report-batch 重複プロセスの停止"
},
"aws_region": "ap-northeast-1",
"aws_account_id": "xxxxxxxxxxxx"
}
エージェントアクションも正常に完了して、CPUメトリクスの回復まで確認できました。


最後に
今回はEC2のOS情報を取得するMCPサーバーを作り、DevOps Agentに追加してみました。
OS上でコマンドを実行する以上、Agentに任意のコマンドを実行させないことが重要になります。
実行する内容はSSM Documentに固定し、Lambdaの実行ロールもそのDocumentしか送れないようにすることで、Agentには調べる対象だけを選ばせ、想定外のコマンドがOS上で実行されないようにしています。
今回はLinuxを対象に、OSの基本的な状態を確認するコマンドだけに絞りましたが、
SSM Documentに調査の種類を足していけば、アプリのログの確認やWindows向けの調査など、環境に合わせた調査も組めると思います。
MCPサーバーを追加したことで、Investigationの中でもOSの情報をもとに原因のプロセスまで特定でき、エージェントアクションでの緩和までつなげられました。
参照だけの権限に絞ったままOS調査を足せるので、CloudWatchにOSの情報を送っていない環境でもDevOps AgentでのOS調査が可能になります。
こちらの記事がどなたかの助けになれば幸いです。
以上、たかやま(@nyan_kotaroo)でした。









