ご利用中のAIを、システム保守に強くしたい皆様へ。
開発支援AIは、コード自体に関する回答にはよく答えます。ただ「このデータベースを止めたら誰が困る?」と聞いた時、その結果は期待外れになると感じています。そのシステムを誰が、どの業務で使っているかは、細切れの資料や担当者の記憶の中にあり、コードには書かれていないからです。
この記事では、そうした質問に的確に答えるために、MCPサーバーが役立つ様子をご紹介します。Claude CodeにMCPサーバーを1行で足し、登録なしで開ける公開サンプルを使って、この質問への答えと、その根拠をたどるところまでを手元で再現します。
使うのは、私たちが運営しているIceShore(アイスショア)のMCPサーバーです。ターミナルでのコマンド2つとClaude Codeへの質問3つで答えまでたどり、最後にcurlとjqで、AIを通さずに同じ結果を出します。
足りないのは、システムと業務の関連づけ
Claude Codeがリポジトリから読み取れるのは、構造までです。どのサービスがどのデータベースに書き込むかは、コードやCloudFormation、Terraformを読めば分かります。
一方で「その書き込みは、誰のどの業務のためか」はコードに書かれておらず、資料や担当者の記憶に散らばっています。データベースを止めたときに困る相手を答えるには、構造に加えて、システムごとのユースケース(誰が、どのくらいの人数で、どの経路を通って何をするか)が要ります。
IceShoreは、このユースケースを定義言語ADL(Architecture Description Language)で書いた構成図として持ち、MCPでClaude Codeに渡します。ADLはJSONで書かれているので、後半ではAIを通さずにjqでも同じ集計をします。
Claude CodeにMCPサーバーを足す
ターミナルで次の1行を実行します。
claude mcp add -s user iceshore --transport http https://mcp.iceshore.ai/mcp
実行するとこう返ります。
Added HTTP MCP server iceshore with URL: https://mcp.iceshore.ai/mcp to user config
File modified: /Users/<あなた>/.claude.json
iceshore の部分は、Claude Codeがこの接続を呼ぶときの名前です。-s user は利用者全体の設定を書き換えます。案件ごとに作業環境を分ける規程があるなら、プロジェクト単位のスコープをご利用ください。試し終えたら、claude mcp remove iceshore -s user で外せます。
繋がったかは、次のコマンドで確かめます。
claude mcp list
iceshore: https://mcp.iceshore.ai/mcp (HTTP) - ✔ Connected
IceShoreの行が ✔ Connected を返していれば、接続はできています。なお、この表示はClaude Codeのバージョンによって変動する可能性があります。
ここで認証は求められません。登録やログインなしで呼べるのは、公開サンプルの一覧を返す list_samples、サンプルの中身を返す get_content、使い方の案内を返す get_guide の3つです。サンプルを読むだけなら、この3つで足ります。
質問1:データベースを止めたら誰が困るか
ここからはClaude Codeに話しかけます。使ったプロンプトはこれです。
サンプルの構成図を見せて。診療記録のデータベースを止めたら誰が困る?
Claude Codeはサンプルの一覧を取り、IceShoreに掲載された公開サンプル「Clivasoft 診療記録・予約システム」の構成図を読み、経路を遡って答えます。別のサンプルが選ばれたときは、プロンプトでこの名前を指定してください。返ってきたのは次の4つでした。
- 医師が診療記録を見る経路(診療記録参照)
- 患者のオンライン予約
- 受付スタッフの予約管理
- 毎夜2時に実行されるバックアップ
構成図には、それぞれの起点が次のように書かれています。
| 業務 | 起点 | 構成図に書かれた規模 |
|---|---|---|
| 診療記録参照 | 担当医師 | 20名 |
| 予約管理(受付スタッフ) | 受付スタッフ | 8名 |
| オンライン予約 | 患者・デジタル医療利用者 | 外部の利用者 |
| 夜間データバックアップ | 定時の処理 | 毎日2:00 |
4つ目は定時の処理で、人が操作しなくても毎晩実行されます。データベースを止める作業は、2時前後を避けて組めます。
質問2:答えの根拠を見せてもらう
答えが推測でないことは、構成図の中身で確かめられます。続けて、こう聞きます。
いまの答えの根拠になったADLの箇所を見せて。
このサンプルのADLでは、ユースケースごとに、起点(trigger)と、そこから続く経路(traffics)が書かれています。起点を始める人や外部の利用者は「アクター」と呼び、actors に人数とともに定義されています。医師の診療記録参照を抜き出すと、次の形です(説明文や通信量の項目は省いています)。
"recordAccess": {
"title": { "ja": "診療記録参照" },
"trigger": {
"start": { "$ref": "#/actors/clinicPhysicians" },
"end": [{ "$ref": "clivasoft-03-publicalb.yaml#/resources/PublicApplicationLoadBalancer" }]
},
"traffics": {
"t1WebAsgEhr": {
"source": { "$ref": "#/useCases/recordAccess/trigger" },
"end": [{ "$ref": "clivasoft-04-web.yaml#/resources/WebAutoScalingGroup" }]
},
"t2RdsRecord": {
"source": { "$ref": "#/useCases/recordAccess/traffics/t1WebAsgEhr" },
"end": [{ "$ref": "clivasoft-03-rds.yaml#/resources/DatabaseCluster" }]
}
}
}
たどり方は3段です。
-
endがDatabaseClusterを指している経路を探します(ここではt2RdsRecord)。 - その経路の
sourceを、triggerに着くまで遡ります。 -
triggerのstartが指すアクターが、困る相手です。ここではclinicPhysicians(担当医師)です。
end の先は、CloudFormationのテンプレートの中のリソース名をそのまま指しています。ADLはリソースの構造を写し取らず、構成管理ファイルを参照します。ADLが足すのは、その上に載る「誰が・何のために」の部分です。
バックアップだけは形が違います。人の操作ではないので、trigger の start はアクターではなく、スケジューラ(EventBridge Schedulerの NightlyExportSchedule)を指しています。答えの「毎夜2時」は、そのスケジューラを定義したCloudFormationのテンプレートにある cron(0 2 * * ? *) から来ています。
質問3:変更の影響範囲を聞く
止める話だけでなく、変更の話も同じ形で聞けます。
Web層のEC2 Auto Scalingグループ(WebAutoScalingGroup)を入れ替えると、どの業務に波及する?
構成図の上では、オンライン予約、予約管理(受付スタッフ)、診療記録参照の3つが、途中の経路で WebAutoScalingGroup を通ります。夜間のバックアップは、スケジューラから書き出しのLambda関数を経てデータベースへつながる経路で、Web層を通らないので、ここには入りません。
curlとjqで、AIを通さずに同じ結果を出す
AIの答えを、AIを通さずに確かめたいこともあります。サンプルの読み出しは認証が要らないので、curlでMCPサーバーへ直接 get_content を呼べます。戻り値の中にADLがJSONの文字列として入っているので、fromjson で2回ほどいて adl.json に保存します。
curl -s https://mcp.iceshore.ai/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_content","arguments":{"id":"d26016a3b9b07c3e635.00868034","mode":"root"}}}' \
| jq -r '.result.content[0].text | fromjson | .data[0].data | fromjson' > adl.json
id は、list_samples が返すClivasoftのサンプルのIDです。
次のjqは、指定したリソースに触れるユースケースと、その起点を返します。
jq -r --arg r DatabaseCluster '
. as $adl
| .useCases[]
| select(
[.trigger, .traffics[]?]
| map(.start["$ref"], .end[]?["$ref"])
| any(. != null and endswith("/" + $r))
)
| [ .title.ja,
($adl.actors[.trigger.start["$ref"] | split("/") | last].title.ja
// "(定時の処理)") ]
| @tsv
' adl.json
オンライン予約 患者・デジタル医療利用者
予約管理(受付スタッフ) 受付スタッフ
診療記録参照 担当医師
夜間データバックアップ (定時の処理)
式の読み方は次のとおりです。
-
[.trigger, .traffics[]?]で、ユースケースの起点と経路を1つの配列にまとめます。 -
.start["$ref"]と.end[]?["$ref"]で参照先を取り出します。$はjqでは変数の印なので、.$refとは書けません。 - 参照先の末尾が
/DatabaseClusterのものが1つでもあれば、そのユースケースを残します。 - 起点の
startがアクターを指していれば、その名前を引きます。アクターでなければ定時の処理として表示します。
--arg r WebAutoScalingGroup に変えると、バックアップを除く3つが返ります。質問1と質問3の答えと一致します。
この式は source を遡らず、ユースケースの中で対象のリソースを参照している箇所があるかだけを見ています。1つのユースケースの経路は1本につながっているので、今回のADLではそれで同じ結果になります。また、リソース名だけで照合しているので、別のテンプレートに同じ名前のリソースがあれば、それも拾います。
ADLの言語仕様とスキーマは、Apache License 2.0で公開されています。IceShoreを使わなくても、同じ形のJSONをリポジトリに置けば、このjqで同じ集計ができます。
構成図をブラウザで見る
同じサンプルは、ブラウザでも開けます。答えが合っているかを、図で確かめられます。
IceShoreに掲載された公開サンプル「Clivasoft 診療記録・予約システム」を、接続したAIが読んだ結果です。
ご自身のリポジトリで使うとき
ご自身のシステムで使うときは、Claude Codeに「このリポジトリのシステムをIceShoreに登録して」と頼みます。Claude Codeが手元の資料とCloudFormationやTerraformなどの構成管理ファイルを読み(なくても構いません)、ユースケースを整理して、ADLを下書きします。IceShoreに保存されるのは、ADLと、そこから参照する構成管理ファイルです。パスワードなどに見える値は、保存の前にマスクされます。保存にはログインが要り、その場面でClaude Codeがご登録方法を案内します。
人が最初にすることは、出来上がった構成図の確認です。構成図が思ったものと異なっていれば、Claude Codeがあなたのシステムをそのように理解している、ということです。違うところを指摘して直させると、次の質問からはその理解の上で答えます。
以上です。
なお、IceShoreは有償ですが(無料プランがあり、1人で使う範囲なら構成図の数に上限はありません)、構成図の記述に使うADLはオープンソースです。IceShoreは、システムごとのユースケースの整理をお使いのAIに促し、構成図を自動生成する構成管理プラットフォームです。
IceShore
https://iceshore.ai/?utm_source=qiita&utm_medium=referral&utm_campaign=launch2610&utm_content=c-0069

