mcpField
D
devtu-fix-tool

devtu-fix-tool

github.com/mims-harvard開発1.8k380 回インストール2 日前に更新
リポジトリ

devtu-fix-tool について

ToolUniverse ツールの障害を診断・修正する、設定や実装、テストを保守する開発者向けスキルです。CLI で再現を確認し、エラー種別に応じて根本原因を修正してから検証します。

主な機能

  1. 01CLI で障害の再現を先に確認
  2. 02エラー種別から設定・コード修正を特定
  3. 03API ドキュメントとパラメーター定義を確認
  4. 04ツール設定とテストの更新
  5. 05ツール再生成と検証の実行

活用シーン

  1. 01応答データとスキーマの不整合を調査
  2. 02パラメーター検証や API エンドポイントの修正
  3. 03修正後の統合テストと単体テストの確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mims-harvard/tooluniverse --skill devtu-fix-tool

インストール後、Claude Code で/devtu-fix-toolを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

EXAMPLES.md
QUICK-REFERENCE.md
unit-tests-reference.md

詳細

ToolUniverse ツールの修正

エラーの体系的な特定、的を絞った修正、検証を通じて、失敗する ToolUniverse ツールを診断し、修正します。

バグ修正の基本原則

修正を書く前に、次の点を確認してください。なぜユーザーはこの失敗状態に陥るのでしょうか?

  1. 復旧するのではなく、予防する — 失敗後にヒントを追加するのではなく、失敗が起きないよう根本原因を修正します
  2. 出力時ではなく入力時に検証する — 誤ったパラメーター、不明な疾患名、未対応の薬剤は、サイレントな API 呼び出しの後に判明させるのではなく、明確なガイダンスとともに早期に検出して拒否します
  3. サイレントな変更を隠さない — 入力が自動正規化される場合(融合表記、タイトルケース)、両方の形式をネイティブに受け入れるか、明確なガイダンスとともに拒否します。サイレントに変換して隠すことは避けてください
  4. 「データなし」と「クエリ不正」を区別する — フィルターが誤っているために結果がゼロ件になる場合と、データが存在しないためにゼロ件になる場合は異なります。レスポンスではこの違いを明確に示す必要があります
  5. 個々の事例ではなく、抽象化を修正する — パラメーター名に一貫性がない場合は、インターフェイスを修正します。増え続けるエイリアスのリストを追加するのではありません

避けるべきアンチパターン:

  • 事前に検証せず、結果がゼロ件のメッセージにヒントを追加する
  • 命名の一貫性を修正せず、パラメーターのエイリアスを追加する
  • 事前検証する代わりに、クエリの失敗後に調査して救済しようとする

バグの検証(重要)

バグ報告に対応する前に、まず CLI で検証してください:

python3 -m tooluniverse.cli run <ToolName> '<json_args>'

エージェントから報告されるバグの多くは、MCP インターフェイスの混乱による誤検知です。修正を実装する前に、必ずバグが再現可能であることを確認してください。


手順

失敗するツールを修正する場合:

  1. 対象を絞ったテストを実行してエラーを特定します:
python scripts/test_new_tools.py <tool-pattern> -v
  1. API が正しいことを確認します — 公式 API ドキュメントをオンラインで検索し、エンドポイント、パラメーター、使用パターンが正しいことを確認します

  2. エラーの種類を特定します(「エラーの種類」セクションを参照)

  3. エラーパターンに応じて適切な修正を適用します

  4. JSON 設定またはツールクラスを変更した場合は、ツールを再生成します:

python -m tooluniverse.generate_tools
  1. tests/tools/ にツールテストが存在する場合は、確認して更新します:
ls tests/tools/test_<tool-name>_tool.py
  1. 統合テストとユニットテストを再実行して修正を検証します

  2. 問題、根本原因、解決策、テスト結果を含む修正概要を提示します

修正箇所

問題の種類変更するファイル
バイナリレスポンスsrc/tooluniverse/*_tool.py + src/tooluniverse/data/*_tools.json
スキーマの不一致src/tooluniverse/data/*_tools.json(return_schema)
データラッパーの欠落src/tooluniverse/*_tool.py(操作メソッド)
エンドポイント URLsrc/tooluniverse/data/*_tools.json(endpoint フィールド)
無効なテスト例src/tooluniverse/data/*_tools.json(test_examples)
ツールテストの更新tests/tools/test_*_tool.py(存在する場合)
パラメーターとしての API キーsrc/tooluniverse/data/*_tools.json(パラメーターを削除)+ *_tool.py(環境変数を使用)
ツールが読み込まれない(任意キー)src/tooluniverse/data/*_tools.json(required_api_keys ではなく optional_api_keys を使用)

エラーの種類

1. JSON 解析エラー

症状:Expecting value: line 1 column 1 (char 0)

原因:ツールは JSON を想定していますが、バイナリデータ(画像、PDF、ファイル)を受け取っています

修正方法:Content-Type ヘッダーを確認します。バイナリレスポンスの場合は、JSON を解析する代わりに説明文字列を返します。return_schema を {"type": "string"} に更新します。

2. スキーマ検証エラー

症状:Schema Mismatch: At root: ... is not of type 'object' または Data: None

原因:data フィールドのラッパーがない、またはスキーマの型が誤っています

修正方法はエラーによって異なります:

  • Data: None の場合 → すべての操作メソッドに data ラッパーを追加します(下記の「複数操作パターン」を参照)
  • 型が一致しない場合 → JSON 設定の return_schema を更新します:
    • データが文字列の場合:{"type": "string"}
    • データが配列の場合:{"type": "array", "items": {...}}
    • データがオブジェクトの場合:{"type": "object", "properties": {...}}

重要な概念:スキーマはレスポンス全体ではなく、data フィールドの内容を検証します。

3. Null 許容フィールドのエラー

症状:Schema Mismatch: At N->fieldName: None is not of type 'integer'

原因:API がオプションフィールドに None/null を返します

修正方法:JSON 設定で {"type": ["<base_type>", "null"]} を使用して、null 許容型を指定します。オプションフィールドに使用し、必須の識別子には使用しないでください。

4. 相互排他的なパラメーターのエラー

症状:別のパラメーターを渡したときに、Parameter validation failed for 'param_name': None is not of type 'integer' が発生します

原因:ツールは paramA または paramB のどちらか一方を受け付けますが、両方が固定型で定義されています。一方だけを指定すると、もう一方が None になるため、検証に失敗します。

例:

{
  "neuron_id": {"type": "integer"},      // ❌ Fails when neuron_name is used
  "neuron_name": {"type": "string"}      // ❌ Fails when neuron_id is used
}

修正方法:相互排他的なパラメーターを null 許容にします:

{
  "neuron_id": {"type": ["integer", "null"]},      // ✅ Allows None
  "neuron_name": {"type": ["string", "null"]}      // ✅ Allows None
}

一般的なパターン:

  • id または name パラメーター(ID または名前で取得)
  • acronym または name パラメーター(記号または正式名称で検索)
  • 指定されない場合があるオプションのフィルターパラメーター

重要:相互排他的でない場合でも、真にオプションのパラメーター(filter_field、filter_value など)も null 許容にしてください。

5. 混在型フィールドのエラー

症状:Schema Mismatch: At N->field: {object} is not of type 'string', 'null'

原因:コンテキストによってフィールドが異なる構造を返します

修正方法:複数の異なるスキーマを持つフィールドには、JSON 設定で oneOf を使用します。これは、同じ基本型と null を指定する null 許容型({"type": ["string", "null"]})とは異なります。

6. 無効なテスト例

症状:404 ERROR - Not found または 400 Bad Request

原因:テスト例で無効または古い ID を使用しています

修正方法:以下のリスト → 取得、または検索 → 詳細のパターンを使って、有効な例を見つけます。

7. API パラメーターのエラー

症状:400 Bad Request またはパラメーター検証エラー

修正方法:正しい型、必須フィールド、列挙値を指定して、JSON 設定のパラメータースキーマを更新します。

8. API キー設定のエラー

症状:API キーがオプションの場合にツールが読み込まれない、または api_key パラメーターが混乱を招く

原因:オプションにすべきキーに required_api_keys を使用している、または API キーをツールパラメーターとして公開している

主な違い:

  • required_api_keys:キーがない場合、ツールはスキップされます
  • optional_api_keys:キーがなくてもツールは読み込まれて動作します(パフォーマンスは低下します)

修正方法:匿名でも動作するものの、キーがあるとレート制限が緩和される API には、JSON 設定で optional_api_keys を使用します。API キーは環境変数からのみ読み込み(os.environ.get())、ツールパラメーターとしては使用しないでください。

9. API エンドポイントパターンのエラー

症状:有効なリソースで 404 が発生する、または予期しない結果が返される

修正方法:公式 API ドキュメントを確認し、値を URL パスとクエリパラメーターのどちらに含めるべきかを確かめます。

10. 一時的な API エラー

症状:タイムアウト/接続/5xx エラーにより、テストが断続的に失敗します

修正方法:単体テストでは、一時的なエラーに pytest.skip() を使用します。外部 API の停止によってテストを失敗させないでください。

よくある修正パターン

スキーマ検証パターン

スキーマが検証するのは応答全体ではなく、data フィールドの内容です。return_schema の型を、data の中身(配列、オブジェクト、文字列)に合わせてください。

複数操作ツールのパターン

すべての内部メソッドは {"status": "...", "data": {...}} を返す必要があります。トップレベルで別のフィールド名を使用しないでください。

有効なテスト例を見つける

テスト例が 400/404 で失敗した場合は、次の方法で有効な ID を見つけます:

  • リスト → 取得:最初にリストエンドポイントを呼び出し、結果から ID を抽出します
  • 検索 → 詳細:既知のエンティティを検索し、返された ID を使用します
  • バージョンを順に試す:対応している場合は、異なるデータセットのバージョンを試します

単体テストの管理

単体テストの確認

ツールを修正した後、単体テストがあるか確認します:

ls tests/tools/test_<tool-name>_tool.py
ユニットテストを更新するタイミング

次の場合は、ユニットテストを更新してください。

  1. 戻り値の構造を変更する場合:result["data"] の構造を確認するアサーションを更新します
  2. 操作を追加/変更する場合:新しい操作のテストケースを追加します
  3. エラー処理を変更する場合:エラーに関するアサーションを更新します
  4. 必須パラメーターを変更する場合:パラメーター検証テストを更新します
  5. スキーマの問題を修正する場合:テストで正しいデータ構造を検証できるようにします
  6. バイナリ処理を追加する場合:バイナリ応答のテストを追加します
ユニットテストの実行
# Run specific tool tests
pytest tests/tools/test_<tool-name>_tool.py -v

# Run all unit tests
pytest tests/tools/ -v
ユニットテストのチェックリスト
  • tests/tools/test_<tool-name>_tool.py が存在するか確認します
  • 修正の前後にユニットテストを実行します
  • データ構造が変更された場合はアサーションを更新します
  • 直接テストとインターフェーステストの両方が成功することを確認します

ユニットテストのパターンと例について詳しくは、unit-tests-reference.md を参照してください。

検証

統合テストの実行
python scripts/test_new_tools.py <pattern> -v
ユニットテストの実行(存在する場合)
pytest tests/tools/test_<tool-name>_tool.py -v
ツールの再生成

JSON 設定またはツールクラスを変更した後は、次を実行します。

python -m tooluniverse.generate_tools

次の場合は再生成してください。

  • src/tooluniverse/data/*_tools.json ファイルを変更した場合
  • ツールクラスの実装を変更した場合

テストスクリプトの変更では再生成は不要です。

出力形式

修正後、次の概要を提示してください。

問題:[問題の簡単な説明]

根本原因:[失敗した理由]

解決策:[変更した内容]

変更内容:

  • ファイル 1:[説明]
  • ファイル 2:[説明]
  • ファイル 3(該当する場合):[ユニットテストの更新]

統合テストの結果:

  • 修正前:X 件のテスト、Y 件成功(Z%)、N 件失敗、M 件のスキーマが無効
  • 修正後:X 件のテスト、X 件成功(100.0%)、0 件失敗、0 件のスキーマが無効

ユニットテストの結果(該当する場合):

  • 修正前:X 件のテスト、Y 件成功、Z 件失敗
  • 修正後:X 件のテスト、X 件成功、0 件失敗

テストのベストプラクティス

テスト前にパラメーター名を確認する

重要:正しいパラメーター名を確認するため、必ずツールの JSON 設定または生成されたラッパーを読んでください。パラメーター名を推測しないでください。

誤ったテストの例:

# ❌ WRONG - assumed parameter name
AllenBrain_search_genes(query='Gad1')  # Fails: unexpected keyword 'query'

正しい方法:

# ✅ RIGHT - checked config first
# Config shows parameters: gene_acronym, gene_name
AllenBrain_search_genes(gene_acronym='Gad1')  # Works!

正しいパラメーター名の確認方法:

  1. JSON 設定を読みます:src/tooluniverse/data/*_tools.json
  2. 生成されたラッパーを確認します:src/tooluniverse/tools/<ToolName>.py
  3. JSON 設定内の test_examples を確認します
系統的なテスト方法

複数のツールをテストする場合:

  1. まずサンプルをテストする:API ごとに 1~2 個のツールをテストし、パターンを特定します
  2. エラーを分類する:エラーの種類(パラメーター検証、API エラー、データ構造)ごとにまとめます
  3. 系統的に修正する:同じ種類の問題があるツールをまとめて修正します
  4. 一度だけ再生成する:すべての JSON の変更後に python -m tooluniverse.generate_tools を実行します
  5. すべてを検証する:修正したすべてのツールを徹底的にテストします
データ構造を理解する

ツールが返すデータ構造はさまざまです。

  • オブジェクト:{"data": {"id": 1, "name": "..."}} - 単一の結果
  • 配列:{"data": [{"id": 1}, {"id": 2}]} - 複数の結果
  • 文字列:{"data": "description text"} - テキスト応答

データ構造に応じてテストしてください:

# For object data
result = tool()
data = result.get('data', {})
value = data.get('field_name')  # ✅

# For array data
result = tool()
items = result.get('data', [])
count = len(items)  # ✅
first = items[0] if items else {}  # ✅

よくある落とし穴

  1. スキーマが検証するのは data フィールドであり、応答全体ではありません
  2. すべてのメソッドで {"status": "...", "data": {...}} のラッパーが必要です
  3. JSON 設定の変更後は再生成が必要です
  4. キーなしで動作する API には optional_api_keys を使用してください
  5. 正しいエンドポイントの形式については、公式 API ドキュメントを確認してください
  6. 一時的な API 障害ではユニットテストを失敗させず、スキップしてください
  7. 相互排他的なパラメーターは null を許容する必要があります - 新しいツールで最もよくある問題です
  8. 設定からパラメーター名を確認してください - 推測や当て推量は避けてください
  9. 正しいデータ構造を想定してテストしてください - リスト、辞書、文字列を区別します

デバッグ

  • API 応答を調べる:ステータスコード、Content-Type ヘッダー、本文のプレビューを確認します
  • ツール設定を確認する:ToolUniverse を読み込み、ツールの設定を調べます
  • デバッグ出力を追加する:run メソッドで URL、パラメーター、ステータス、Content-Type を記録します

クイックリファレンス

タスクコマンド
統合テストを実行するpython scripts/test_new_tools.py <pattern> -v
単体テストを実行するpytest tests/tools/test_<tool-name>_tool.py -v
単体テストが存在するか確認するls tests/tools/test_<tool-name>_tool.py
ツールを再生成するpython -m tooluniverse.generate_tools
ステータスを確認するgit status --short | grep -E "(data|tools|.*_tool.py|tests/tools)"
エラーの種類修正箇所
JSON 解析エラーsrc/tooluniverse/*_tool.py の run() メソッド
スキーマの不一致src/tooluniverse/data/*_tools.json の return_schema
404 エラーsrc/tooluniverse/data/*_tools.json の test_examples または endpoint
パラメーターエラーsrc/tooluniverse/data/*_tools.json の parameter スキーマ
単体テストの失敗tests/tools/test_*_tool.py のアサーション
ツールがスキップされた(オプションのキー)src/tooluniverse/data/*_tools.json で optional_api_keys を使用する
API キーをパラメーターとして指定しているJSON の params から削除し、Python で os.environ.get() を使用する

コメント