MCPサーバーをstdioで作る—外部APIをツール化


freee用のPythonクライアントができても、Hermes Agentが直接使えるわけではありません。間にMCPサーバーを置き、「何ができるか」「どんな入力を受け取るか」「結果をどう返すか」を明示します。

stdioを選んだ理由

ローカルで動く専用連携には、標準入力と標準出力を使うstdio transportが扱いやすい選択でした。別ポートを開けず、Hermes Agentが必要な時に子プロセスとして起動できます。

MCPサーバーは、標準出力へログを混ぜないことが重要です。標準出力はJSON-RPCメッセージ専用にし、診断ログは標準エラーへ送ります。そうしないと通信内容が壊れます。

公開するツールを小さくする

freee連携では、次のように役割を分けました。

  • 状態確認
  • 事業所、勘定科目、税区分、取引の参照
  • 取引登録payloadの準備
  • 確認済み取引の作成

一つの「freeeを操作する」ツールへまとめるより、読み取りと書き込み、prepareとcreateを分ける方が、AIにも利用者にも境界が見えます。

入力スキーマを厳密にする

MCPのToolは名前、説明、入力スキーマを持ちます。金額を文字列で受けたり、未知の項目を何でも許したりすると、後段で曖昧さが増えます。JSON Schemaで必須項目、型、選択肢、追加プロパティの可否を指定します。

サーバー側でも再検証します。スキーマを通過したから安全と考えず、日付の実在性、金額上限、権限、確認コードを業務ロジックとして確認します。

Hermesへ登録して一覧を確認する

登録では、専用Python環境とサーバーファイルを指定します。公開記事では実パスをダミーにします。

hermes mcp add freee \
  --command /path/to/venv/bin/python \
  --args /path/to/freee_mcp_server.py

hermes mcp test freee

テストでは、接続成功だけでなく、意図したToolだけが一覧に出ることを確認します。設定を変えた後は新しいHermesセッションで再読み込みします。

再現チェック

  • [ ] 標準出力はJSON-RPC専用
  • [ ] ログは標準エラーへ出す
  • [ ] Tool名と説明から副作用が分かる
  • [ ] 入力スキーマが型と必須項目を制限する
  • [ ] サーバー側でも再検証する
  • [ ] hermes mcp testでTool一覧を確認した

次回は、同じ考え方をNotionのタスク受付へ適用します。

参考にした一次情報


Back to top