Newer
Older
TelosDB / journals / 20260223-0022-MCPツール応答形式の標準化と検索エラーの修正.md

作業報告: MCPツール応答形式の標準化と検索エラーの修正 (20260223-0022)

1. 作業実施の理由

Qwen などの LLM モデルから MCP 経由で search_text を実行した際、ツール実行エラー(Tool call failed)が発生する問題に対応するため。

2. 指示 (背景、観点、意図を含む)

  • 背景: 以前の search_text 実装では、検索結果(シリアライズされた JSON オブジェクトの配列)をそのまま content フィールドに返しており、MCP 仕様(各要素が {type: "text", text: "..."} 形式であること)に準拠していなかった。
  • 観点: Qwen 等のモデルは、レスポンスが仕様に合わない場合に「引数が間違っている」といった誤解を伴うエラーメッセージを出すことがある。
  • 意図: 全ての MCP ツールの応答を標準化し、LLM が正しく結果を解釈できるようにする。また、空の検索クエリによる FTS5 のエラーも防止する。

3. 指摘事項とその対応

  • 指摘: Qwen で search_text を使うと「content パラメータは文字列である必要がある」といったエラーが返ってくる。
  • 対応: AIエージェントは、search_text の検索結果を JSON 文字列として 1 つのテキストブロックにまとめ、MCP 準拠の形式で返すように修正した。また、エラー応答時も isError: true を含む標準形式に変更した。

4. 作業詳細

4.1 MCP レスポンスの標準化

AIエージェントは、mcp.rs 内の全ツールにおいて、応答形式を厳格に MCP 仕様へ適合させた。

  • search_text: 検索結果の配列を serde_json::to_string_pretty でデコードし、{ "type": "text", "text": "..." } の配列として返却。
  • エラー処理: Some(json!({ "error": ... })) となっていた箇所を、{ "content": [...], "isError": true } 形式に統一。
  • 入力ガード: content が空の場合に FTS5 (BM25) が「empty string not allowed」エラーを出すのを防ぐため、事前チェックを追加。

4.2 冗長なコードの整理

AIエージェントは、旧 UI 用に残っていた lsa_search メソッドを search_text に統合、またはエイリアスとして整理し、コードの重複を排除した。

5. 修正後の MCP 通信構造

sequenceDiagram
    participant LLM as LLM (Qwen/Claude)
    participant Bridge as MCP Bridge
    participant Server as TelosDB Server

    LLM->>Bridge: tools/call {name: "search_text", arguments: {content: "秋と冬"}}
    Bridge->>Server: tools/call
    Server->>Server: Hybrid Search (FTS5 + Vector)
    Note over Server: JSON-format result string
    Server-->>Bridge: {content: [{type: "text", text: "[...]"}], isError: false}
    Bridge-->>LLM: Result string
    LLM->>User: 検索結果に基づき回答

6. AI視点での結果

AIエージェントは、ツール実装時の単純な配列返却が MCP プロトコルレベルでの拒絶(デパース失敗)を招いていたことを特定し、解決した。これにより、多様な LLM モデル(Qwen, Claude, GPT 等)から一貫して TelosDB の検索機能を利用可能になった。また、エラーハンドリングを標準化したことで、不測の事態でも LLM が「何が起きたか」を正しくユーザーに伝えられるようになった。