この記事には広告・アフィリエイトリンクも、広告・提携関係もありません。
資格を取った後、次の資格へ進むべきか、何かを作るべきか。この実装では「小さく作り、学んだ概念を具体的な判断へ変える」という進み方を選びました。
ただし、私にはクラウド本番環境の構築・運用経験がありません。資格学習、ラボ、ローカル実装、本番運用は別物です。この記事は本番で通用することの証明ではなく、権限、秘密情報、データ境界、観測、費用を一つの実装で問い直した記録です。資格の証明範囲は、資格・認定が証明すること・しないことで整理しています。
最初の制作物を「狭いread-onlyツール」にした理由
AI Agent開発の最初の構成要素として、既存の計測結果を読むローカルMCP補助サーバーを作りました。これは自律的に計画・実行するAgent本体ではなく、AgentやMCPクライアントがデータを参照するための小さなツール層です。
実装した機能は三つに絞りました。
list_runs: 計測runと条件を一覧するcompare_buckets: bucket別のAIO率と失敗率を比較するget_keyword_evidence: キーワード単位の観測と根拠を確認する
対象は既存のSQLiteだけです。検索計測APIを呼ばず、保存済みデータも変更しない。この狭さによって、「何をさせないか」を設計対象にできました。
2026年8月29日時点で、MCP Python SDKはv2が現行安定ラインで、最新安定版はv2.1.1です。ただし、今回の実装と検証結果はuv.lockで固定したv2.0.0に対するものです。接続はserver.run()のdefaultであるローカルstdioに限定し、HTTP endpointは設けていません。SDK、SQLite設定、上限値、テストの詳細は実装記録へ分け、ここでは設計に使った五つの問いに集中します。
資格知識を五つの問いへ変える
1. Identity(実行主体と権限)— 誰の権限で動くのか
ローカル版の実行主体はMCPクライアントを起動したユーザーで、権限はそのプロセスのファイル権限です。サーバー独自のログインや利用者別認可はなく、IAMを検証した本番構成ではありません。
「誰が呼べるか」「どのDBを読めるか」を明示すると、最小権限が設計上の問いになります。クラウドではサービスID、利用者認証、ツール単位の認可、テナント分離を改めて設計する必要があります。
2. Secret(秘密情報)— ツールへ渡さなくてよい秘密は何か
このcompanionは外部APIを呼ばず、API認証情報を必要としません。API認証情報、raw payload、raw_pathは取得・応答の対象にせず、失敗理由も原文ではなく固定メッセージを返します。DB由来の任意の文字列に秘密が含まれないことまで保証するものではないため、返す列そのものを狭くしました。
これは秘密を安全に保管できた証明ではなく、秘密を境界へ持ち込まない設計です。本番ではシークレット管理、短命な資格情報、ローテーション、監査を別途検証します。
3. Data boundary(データ境界)— 読める範囲と返す範囲はどこか
対象SQLite DBはURIのmode=roでread-onlyに開き、さらにPRAGMA query_only = ONで代表的なデータ変更SQLを拒否しています。query_only単独は完全なread-only保証ではないため、任意SQLを公開しないtool interfaceと不変性テストも組み合わせました。
接続をread-onlyにするだけでは、返却データの境界は決まりません。返す列を限定し、URLからuserinfo、query、fragmentを除き、文字列長と件数にも上限を設けました。外部検索由来の値はuntrusted_externalと表示します。読み取り権限と、Agentへ見せる情報は別の設計です。
各toolにはreadOnlyHintを付けていますが、MCP仕様上のtool annotationはclientへのhintであり、書き込み防止を強制する仕組みではありません。read-onlyの根拠はannotationではなく、SQLiteの接続設定、公開するtool interface、書き込み拒否と不変性のテストです。
4. Observability(観測可能性)— 成功以外をどう見分けるか
計測失敗を「AIOなし」と数えると誤った比較になります。okとfailedを分け、失敗をAIO率の分母から除外しました。対象・観測済み・未観測件数を返し、切り詰めや伏字にはtruncated、redactedを付けます。
これは集中ログ、トレース、アラート、SLOを備えた監視ではありません。ローカルで確かめたのは、欠測や加工を成功データに見せないことです。本番ではツールの利用者、失敗率、遅延を、機密情報を残さず追う仕組みが必要です。
5. Cost(費用)— 無料かではなく、何が増える設計か
照会は追加の有料APIを実行しません。一方で、DBサイズ、クエリ時間、並列数、各返却一覧には上限を設けました。これは料金の最適値ではなく、ローカルツールの資源を有限にするための制約です。
クラウドではコンピューティング、ストレージ、ネットワーク、ログ、シークレット管理、監視の費用が加わります。ローカルでAPI費用が増えなかった事実から、本番も低コストとは結論できません。
今回、どこまで確認できたか
2026年8月30日に再実行し、MCP対象32件、Python全体150件のテストが通りました。コマンド、終了コード、件数は日付付きのリポジトリ内実行記録に固定し、記事の回帰テストから相互照合しています。テストでは書き込み拒否とDBのバイト列・スキーマ不変を確認しています。main DBとpilot DBの実データスモークテストは2026年8月27日に行い、前後のSHA-256、ファイルサイズ、更新日時が一致し、新しいsidecar fileもありませんでした。
一方で、未修正Low指摘が二つあります。改変DBでrun metadataがNULLの場合に文字列"None"となる箇所と、観測0件のbucketでfailure_rateが0.0となり「データなし」と「0%」を混同させ得る表示です。内容と再現条件は実装記録へ集約しました。
テスト合格やhashの一致は、確認した条件で変更を観測しなかったという証拠です。あらゆる環境での安全性や、クラウド運用の適合性を保証するものではありません。
ローカルから本番へ移す前の差分
| 観点 | 今回のローカル実装 | 本番で未検証のこと |
|---|---|---|
| Identity(実行主体と権限) | OSユーザーとファイル権限 | 利用者認証、サービスID、ツール単位認可、テナント分離 |
| Secret(秘密情報) | 外部API認証情報を使わない | シークレット管理、短命資格情報、ローテーション、監査 |
| Data boundary(データ境界) | 1つのDB、read-only接続、返却列と文字列の制限 | ネットワーク境界、暗号化、バックアップ、保持期間、複数利用者の分離 |
| Observability(観測可能性) | status、欠測、伏字、切り詰めを応答に表示 | 集中ログ、トレース、アラート、SLO、監査証跡 |
| Cost(費用) | 追加API実行なし、ローカル資源の上限 | 継続的なコンピューティング・ストレージ・ネットワーク・監視費用 |
最初のAI Agent関連実装チェックリスト
この実装から整理できる最小項目は次のとおりです。
- ツールが答える判断を一文で書けるか
- 初版から不要な書き込み、副作用、外部APIを外したか
- 呼び出し主体と権限の由来を説明できるか
- 秘密を渡さずに成立する部分を先に切り出したか
- 読めるデータと返すデータを別々に列挙したか
- 成功、失敗、空データ、未観測を区別したか
- 件数、時間、並列数、データサイズの上限を置いたか
- 書き込み拒否とデータ不変をテストで確かめたか
- ローカルで確認したことと本番で未検証のことを分けたか
今回の検証範囲では、Agent本体を先に作らず、狭いread-onlyツール層から始められました。この規模でも、資格で学んだ概念を、権限、データ、失敗、費用についての具体的な判断へ変えられます。
最初から九つの項目を完成させる必要はありません。五つの観点から一つを選び、「現状」「最小の検証」「本番へ移す前の未検証事項」を三行で書くところから始めます。次のread-only MCP server実装記録では、五つの問いをコード、ツールのschema、テストへ落とした手順と、途中で見つかった失敗を詳しく整理します。