← ./articles-ja

MCPツールのdescriptionはAI向けUIとして設計する

MCPサーバーでツールを公開するとき、description はただの説明文ではありません。

人間向けのUIなら、ボタン名、ラベル、補足テキスト、エラーメッセージが使いやすさを左右します。MCPでは、それに近い役割を description と引数スキーマが持ちます。AIクライアントはそれを読んで「どのツールを使うべきか」「どの引数を渡すべきか」を判断します。

つまり、MCPツールのdescriptionはAI向けUIです。

短すぎるdescriptionは誤用される

悪い例です。

{
  "name": "search",
  "description": "Search articles"
}

これでは、何を検索するのか分かりません。タイトルだけなのか、本文まで見るのか、タグ検索なのか、言語指定できるのか、結果に本文が含まれるのかも不明です。

AIは不足分を推測します。その推測が外れると、期待したツールではなく別のツールを呼んだり、不必要に大きな結果を要求したりします。

改善例です。

{
  "name": "search_articles",
  "description": "Search published Markdown articles by title, description, tags, and body text. Returns metadata only, not full article bodies."
}

これなら、検索対象と戻り値の範囲が分かります。「本文は返らない」と明記しているので、AIは詳細が必要なときに別の get_article のようなツールを使いやすくなります。

使うべき時と使わない時を書く

ツール説明では、できることだけでなく、使うべき場面も書きます。

たとえば記事取得ツールなら、次の2つは違います。

Retrieve an article.
Retrieve a single published article by slug when the caller already knows the slug. Use search_articles first when the slug is unknown.

後者は、AIに手順を教えています。slugが分からないのに get_article を呼び続ける無駄を減らせます。

MCPではツールの数が増えるほど、AIが選ぶコストも増えます。descriptionに「いつ使うか」を入れると、ツール選択の失敗が減ります。

引数説明は制約まで書く

引数の説明も重要です。

悪い例です。

{
  "slug": {
    "type": "string",
    "description": "Article slug"
  }
}

改善例です。

{
  "slug": {
    "type": "string",
    "description": "Lowercase article slug such as 'mcp-stdio-server-logging-stderr'. Do not include '/articles/' or a trailing slash."
  }
}

この説明なら、AIがURL全体を渡すミスを避けやすくなります。/ja/articles/foo/ のようなパスを受け付けないなら、それも書きます。

言語引数も同じです。

{
  "lang": {
    "type": "string",
    "enum": ["en", "ja"],
    "description": "Article language. Use 'ja' for Japanese articles and 'en' for English articles. Defaults to 'en'."
  }
}

enum だけで機械的な制約は伝わりますが、descriptionがあるとAIはユーザーの自然言語から値へ変換しやすくなります。

戻り値のサイズを説明する

AIクライアントでは、戻り値が大きすぎると会話の文脈を圧迫します。記事一覧ツールが本文全体を返すと、1回の呼び出しで大量のテキストが流れます。

Markdown知識ベースをMCPで返す場合の全体設計は、MCPサーバーでMarkdown知識ベースを配信する設計: HTMLに変換しない理由 で扱っています。この記事では、その中でもツール定義文と引数説明に絞ります。

ツール説明には、戻り値のサイズ感も書きます。

Returns an array of article metadata: slug, title, date, description, tags, and lang. Does not return article body Markdown.

これでAIは、一覧取得と本文取得を分けて使えます。

逆に全文を返すツールでは、次のように書きます。

Returns metadata and the full raw Markdown body for one article. Use only after narrowing to a specific slug.

「一度絞ってから使う」と書いておくと、検索代わりに全文取得を乱用しにくくなります。

stdio transportでツールを実装する場合は、ツールレスポンスとログ出力を混ぜないことも重要です。ログの出し先は MCP stdioサーバーのログはstderrへ: stdoutを汚さない設計 を参照してください。

エラー時の振る舞いもUIの一部

ツールが見つからない記事を要求されたとき、エラー文もAI向けUIです。

曖昧なエラーです。

Not found

改善例です。

Error: article "foo" with lang "ja" was not found. Use list_articles or search_articles to find a valid slug.

このメッセージなら、AIは次に何をすべきか分かります。人間向けの親切さと同じで、AIにも回復手順を渡すほうが安定します。

チェックリスト

MCPツールを追加したら、次を確認します。

  • ツール名は動詞 + 対象になっているか
  • descriptionに検索対象、戻り値、使う場面が書かれているか
  • 引数説明に形式、例、禁止形式があるか
  • enumやrequiredで機械的な制約を表しているか
  • 大きな本文を返すツールとメタデータだけ返すツールが分かれているか
  • エラー文に次の行動が含まれているか

まとめ

MCPツールのdescriptionは、AIが読むUIです。

短い説明でも動くことはありますが、ツールが増えるほど誤用されやすくなります。使う場面、引数の形式、戻り値の範囲、エラー時の回復手順まで書くと、AIクライアントはツールを選びやすくなります。

MCPサーバーの使いやすさは、実装だけでなく、ツール定義の文章で大きく変わります。