MCPサーバーを作り始めると迷いやすいのが、同じ機能をtools、resources、promptsのどこへ実装するべきかという問題です。
たとえば社内ドキュメントを取得する機能は、
search_documentsというTool
にもできますし、
docs://manual/auth
というResourceにもできます。コードレビュー機能も、
review_code Tool
として実装する方法と、
review_code Prompt
として実装する方法があります。どちらでも一見動くため、MCPサーバーを作り始めた段階では違いが分かりにくいところです。
現在のMCPでは、この3種類はServer Primitiveとして明確に役割が分かれています。MCP公式仕様では、Promptsはユーザーが選択するもの、Resourcesはアプリケーションがコンテキストとして扱うもの、Toolsはモデルが必要に応じて呼び出すもの、というControl Hierarchyで整理されています。つまり最もシンプルに考えるなら、
Tools → モデルに処理を実行させる Resources → モデルへ参照データを渡す Prompts → ユーザーが実行するAI向けテンプレートを用意する
と考えると分かりやすくなります。この記事では、MCPのtools、resources、promptsの違いと、検索、データ取得、ファイル参照、更新処理、コードレビューなどをどこへ実装するべきかを解説します。MCPサーバーの作り方全般はClaude Code MCP完全ガイドを参照してください。
- tools・resources・promptsはMCP Serverの3つの基本機能
- Toolsはモデルが必要に応じて呼び出す機能
- Toolは「書き込み処理」だけではない
- 検索はToolに向いている
- 更新・削除・送信処理は基本的にTool
- ToolにはinputSchemaがある
- Resourcesはアプリケーションがモデルへ渡す参照データ
- ResourceはURIで識別する
- 既知のデータを参照させるならResource
- Resourceは静的ファイルである必要はない
- Resource TemplateならURIに引数を持たせられる
- 「IDを指定して顧客を取得」はToolとResourceのどちらでも作れる
- ResourcesにはSubscriptionもある
- Promptsはユーザーが選択するAI向けテンプレート
- PromptはSlash Commandのような用途に向いている
- Promptは処理を実行する場所ではない
- Promptの引数はToolほど複雑ではない
- PromptからResourceを利用することもできる
- ToolsからResource相当の情報を返すこともできる
- ドキュメント検索ではToolとResourceを組み合わせると分かりやすい
- APIのGETだからResource、POSTだからToolではない
- 「副作用がないからResource」とも限らない
- 「AIにやらせたい作業」はPromptかToolか
- Prompt内から勝手にToolを実行するわけではない
- MCP Clientが呼び出すProtocol Methodも違う
- MCP Inspectorでも別々に確認できる
- 迷ったときの判断基準
- Model-controlledならTool
- Application-controlledならResource
- User-controlledならPrompt
- 何でもToolにするとTool一覧が肥大化する
- 逆に何でもResourceにするとモデルが自律的に取得しにくい
- PromptsへBusiness Logicを詰め込まない
- 1つの機能を3つに分ける設計もできる
- 2026-07-28でも3つの基本的な役割は変わっていない
- MCPのtools・resources・promptsに関するよくある質問
- MCP Serverでは「何ができるか」より「誰が選ぶか」で分ける
tools・resources・promptsはMCP Serverの3つの基本機能
MCP Serverは、外部システムの機能や情報をAI Applicationへ提供します。その中心となるのが、
Tools Resources Prompts
です。2026年7月28日仕様に対応する現行MCP SDKでも、この3つは引き続きServer側の主要Primitiveとして提供されています。TypeScript SDK v2は2026-07-28仕様を実装するStable Releaseで、ServerはTools、Resources、Promptsを公開できます。
Python SDKでは、それぞれ
@mcp.tool()
@mcp.resource(...)
@mcp.prompt()
で登録できます。たとえば次のMCP Serverです。
from mcp.server import MCPServer
mcp = MCPServer("Example")
@mcp.tool()
def search_books(query: str) -> str:
"""Search books."""
return f"Results for {query}"
@mcp.resource("config://app")
def app_config() -> str:
"""Return application configuration."""
return "language=ja"
@mcp.prompt()
def review_code(code: str) -> str:
"""Create a code review request."""
return f"Review this code:\n\n{code}"
見た目はどれもPython Functionですが、MCP Clientからの扱われ方は大きく異なります。
Toolsはモデルが必要に応じて呼び出す機能
Toolsは、モデルが呼び出せるFunctionです。MCP Python SDKの現行ドキュメントでも、Toolは「モデルが呼び出せる関数」と定義されています。たとえば、
@mcp.tool()
def search_products(
query: str,
limit: int = 10
) -> str:
"""Search products."""
return search_database(
query=query,
limit=limit
)
というToolを公開したとします。ユーザーが、
RTX 5070搭載PCを探して
と依頼すると、AIモデルが、
この依頼にはsearch_productsが必要
と判断し、Tool Callを生成できます。つまり実行を決める主体は基本的にモデルです。MCPのConceptual Documentationでは、ToolsはModel-controlledとして整理されています。
Toolは「書き込み処理」だけではない
Toolという名前から、
Databaseを更新する メールを送る ファイルを書き込む
など副作用のある処理だけを実装するものだと思うかもしれません。しかしToolは読み取り処理にも使えます。たとえば、
search_products get_stock_price find_customer search_documents get_weather
などもToolとして自然です。ポイントは、
読み取りか書き込みか
ではなく、
モデルが状況に応じて引数を組み立て、実行するFunctionか
です。MCP公式のServer Overviewでも、ToolsはActionを実行するだけでなく、情報を取得するExecutable Functionとして説明されています。
検索はToolに向いている
たとえば大量の商品Databaseがあります。ユーザーが、
10万円以下でRTX 5070搭載のPCを探して
と質問するとします。検索条件は毎回変わります。この場合、
@mcp.tool()
def search_products(
keyword: str | None = None,
max_price: int | None = None,
gpu: str | None = None
):
...
のようなToolが向いています。モデルがユーザーの要求から、
{
"keyword": "gaming pc",
"max_price": 100000,
"gpu": "RTX 5070"
}
を生成してToolを呼び出せるからです。「条件を判断して問い合わせる」処理はToolsとの相性がよくなります。
更新・削除・送信処理は基本的にTool
外部システムへ変更を加える処理もToolsへ実装します。たとえば、
@mcp.tool()
def create_issue(
title: str,
body: str
) -> str:
...
や、
@mcp.tool()
def send_email(
recipient: str,
subject: str,
body: str
) -> str:
...
です。Database更新なら、
@mcp.tool()
def update_customer(
customer_id: int,
name: str
) -> dict:
...
となります。このような処理をResourceとして実装するのは不自然です。Resourceは基本的にデータを「読む」ためのPrimitiveだからです。
ToolにはinputSchemaがある
Toolの大きな特徴が、入力Schemaを持てることです。Python SDKなら型HintからSchemaを生成できます。
@mcp.tool()
def search_products(
query: str,
limit: int = 10
) -> str:
"""Search products."""
...
これによりMCP Clientは、
query = string limit = integer
という入力条件を理解できます。現行Python SDKでは関数の型HintがToolのInput Schemaとして扱われ、不正な引数はSDK側でValidationされます。
2026-07-28仕様ではToolのinputSchemaとoutputSchemaがJSON Schema 2020-12へ拡張され、oneOf、anyOf、allOf、条件Schema、$refなども利用できるようになりました。Input SchemaのRootは引き続きObjectである必要があります。
複雑な構造の引数をモデルから受け取りたい処理ほど、Toolに向いています。
Resourcesはアプリケーションがモデルへ渡す参照データ
Resourcesは、MCP ServerがClientへ公開する「読めるデータ」です。現行MCP Python SDKでは、Resourceは「アプリケーションが読み取るために公開するデータ」と説明されています。Toolを呼ぶかどうかはモデルが決めますが、Resourceを読み込むかどうかはApplication側が決め、必要なContextとしてモデルへ提示します。
たとえば、
設定ファイル ドキュメント Database Record Git履歴 API仕様 ソースコード テンプレート
などがResourcesに向いています。
ResourceはURIで識別する
ToolはFunction Nameを持ちます。ResourceはURIを持ちます。たとえば、
@mcp.resource("config://app")
def get_config() -> str:
"""Return application configuration."""
return """
language=ja
theme=dark
"""
とします。Clientは、
get_config
というFunction名を呼び出すのではなく、
config://app
というURIを読みます。現行Python SDKでも、Resourceは名前ではなくURIによってアドレスされ、Clientはresources/readでそのURIのContentを取得します。
既知のデータを参照させるならResource
たとえばMCP ServerからCoding Ruleを公開したいとします。
@mcp.resource("docs://coding-rules")
def coding_rules() -> str:
return """
# Coding Rules
Use TypeScript.
Do not use any.
Run tests after changes.
"""
このデータに対して、
検索条件をモデルに考えさせる
必要はありません。単純に、
docs://coding-rulesを読む
だけです。このような「名前やURIで特定できる情報」はResourceに向いています。
Resourceは静的ファイルである必要はない
Resourceという名前から、MarkdownやText Fileなどの静的ファイルだけを想像しがちです。しかしResourceの内容はFunction実行時に生成できます。たとえば、
@mcp.resource("status://system")
def system_status() -> dict:
return {
"api": "healthy",
"database": "healthy"
}
のような動的データもResourceにできます。Resourceはresources/listされた時点でFunctionが実行されるわけではなく、Clientが実際にresources/readしたときに対象Resourceの処理が実行されます。
したがって判断基準は、
静的か動的か
ではありません。
Applicationが特定の内容をContextとして読み込むものか
が重要です。
Resource TemplateならURIに引数を持たせられる
Resourceには固定URIだけでなくResource Templateもあります。たとえば、
@mcp.resource("customer://{customer_id}")
def customer(
customer_id: str
) -> dict:
return load_customer(customer_id)
とできます。この場合、
customer://100 customer://101 customer://102
といったResourceを表現できます。現行Python SDKではURIにParameterを含めるとTemplate Resourceとして登録され、固定Resourceとは別にresources/templates/listから取得できます。大量のDocumentやRecordをResource化するときに便利です。
「IDを指定して顧客を取得」はToolとResourceのどちらでも作れる
ここが設計上迷いやすいところです。たとえば、
顧客ID 123を取得する
処理は、
@mcp.tool()
def get_customer(
customer_id: int
):
...
とも書けます。Resourceなら、
@mcp.resource(
"customer://{customer_id}"
)
def customer(
customer_id: str
):
...
とも書けます。どちらも技術的には成立します。違いは「誰が選択するか」です。ユーザーの質問を見たモデルが必要に応じて、
customer_id=123を取得しよう
と判断させたいならToolが自然です。一方、Application側が、
現在開いている顧客123の情報をContextへ付けよう
と判断する設計ならResourceが自然です。この「Controlの主体」がToolsとResourcesを分ける最も重要なポイントです。MCP公式もToolsをModel-controlled、ResourcesをApplication-controlledとして整理しています。
ResourcesにはSubscriptionもある
Resourceには、情報の変化をClientへ伝える仕組みもあります。MCP Serverが対応していればClientがResourceをSubscribeし、内容が変化したことをNotificationで知ることができます。Resources CapabilityにはsubscribeやlistChangedがあります。
たとえば、
status://build
というResourceがあれば、Build状態の更新をClientへ知らせる構成も考えられます。「参照対象として存在し、その内容が変化する」というデータモデルを持つものはResourceと相性があります。
Promptsはユーザーが選択するAI向けテンプレート
PromptsはToolsやResourcesとはさらに役割が違います。MCP Python SDKの現行ドキュメントでは、Promptは「ユーザーが選択するMessage Template」と定義されています。ClientがメニューやSlash CommandなどとしてPromptを表示し、ユーザーが選んで引数を入力すると、生成されたMessageがConversationへ入ります。
たとえば、
@mcp.prompt()
def review_code(
code: str
) -> str:
"""Review code."""
return f"""
Review the following code.
Check correctness, security,
performance and maintainability.
{code}
"""
とします。これはモデルが勝手に呼び出すToolではありません。ユーザーが、
review_code
というPromptを選択し、対象Codeを入力するイメージです。
PromptはSlash Commandのような用途に向いている
たとえば開発チームで毎回、
セキュリティ 型安全性 エラー処理 テスト不足 パフォーマンス
を確認するCode Reviewを行うとします。毎回ユーザーが長いPromptを書く必要はありません。MCP Serverへ、
@mcp.prompt()
def security_review(
code: str
) -> str:
return f"""
Review this code for security issues.
Pay special attention to:
authentication,
authorization,
input validation,
secret handling.
Code:
{code}
"""
を登録できます。Client側ではこれをReusable Promptとしてユーザーへ表示できます。MCP公式のControl HierarchyではPromptsはUser-controlledです。ToolsがModel-controlledなのとは対照的です。
Promptは処理を実行する場所ではない
たとえば、
データベースから顧客を削除する
処理をPromptとして実装するのは適切ではありません。PromptはMessageを組み立てる機能です。現行Python SDKの説明でも、Promptは最終的にはMessageを構築するFunctionであり、文字列を返せばUser MessageとしてConversationへ入ります。
外部システムへ副作用を起こしたいならToolを使います。Prompt自身は、
モデルへ何を依頼するか
を組み立てるものです。
Promptの引数はToolほど複雑ではない
ToolsではJSON Schemaによって複雑な入力構造を定義できます。一方、現行Python SDKのPromptsではArgumentsは名前付きStringのFlat Listとして扱われ、ToolのようなInput Schemaはありません。Default Valueを持つParameterはOptionalになります。
そのため、
複雑なJSON Object 複数階層の条件 厳密な型Validation
をモデルから受け取る処理ならToolのほうが向いています。Promptは、
language style audience code topic
など、ユーザーがTemplateへ与える比較的単純な値に向いています。
PromptからResourceを利用することもできる
PromptsとResourcesは排他的ではありません。たとえば、
style://python
というResourceにPython Coding Styleを公開するとします。Prompt側でこのResourceをAttachmentとして含め、
Coding Styleを参照してCode Reviewする
というTemplateを作れます。MCP Python SDKではPrompt MessageへEmbeddedResourceを含められ、ResourceをAttachmentとしてモデルへ渡す構成がサポートされています。つまり、
Resource → 参照するCoding Style Prompt → そのStyleに基づいてReviewする指示
という分担ができます。
ToolsからResource相当の情報を返すこともできる
逆方向の組み合わせも可能です。Tool ResultにはTextだけでなくImage、Audio、Embedded Resourceなどを含められます。MCP SDKでもToolsがResource Contentを返せる構成があります。たとえば、
search_documents Tool
でDocumentを検索し、その結果としてDocument Resourceを返すような設計です。そのためMCPのPrimitiveは、
どれか1つしか使えない
ものではありません。役割を分けながら組み合わせます。
ドキュメント検索ではToolとResourceを組み合わせると分かりやすい
大量の社内DocumentをMCPで扱うケースを考えます。検索部分はToolにします。
@mcp.tool()
def search_docs(
query: str
) -> list[dict]:
return search_index(query)
個々のDocumentはResourceとして公開します。
@mcp.resource("docs://{doc_id}")
def document(
doc_id: str
) -> str:
return load_document(doc_id)
この構成なら、
ユーザーの質問 ↓ モデルがsearch_docsを実行 ↓ 関連Documentを発見 ↓ 必要なDocument Resourceを読み込む ↓ 回答
と役割を分離できます。検索は「モデルが条件を決めて実行する処理」なのでTool、Documentそのものは「URIを持つ参照データ」なのでResourceです。
APIのGETだからResource、POSTだからToolではない
REST APIとの対応で考えるのも注意が必要です。たとえば、
GET /weather?city=Tokyo
だからResource、
POST /orders
だからTool、と単純に分けるわけではありません。ユーザーの質問を見たモデルがCityを判断してWeather APIを実行するなら、
@mcp.tool()
def get_weather(
city: str
):
...
のほうが自然です。HTTP Methodではなく、
MCP側で誰がその処理を選択するか
を基準に考えます。
「副作用がないからResource」とも限らない
同じ理由で、
Databaseを変更しない
からResourceというわけでもありません。たとえば、
売上が100万円以上で 今月注文が減った顧客を探す
というQueryがあります。副作用はありません。それでもモデルがユーザーの条件を解釈し、
{
"minimum_sales": 1000000,
"order_trend": "decreasing"
}
として検索させるならToolが適しています。ToolsとResourcesの違いは、Read / WriteよりControl Modelで判断したほうが迷いにくくなります。
「AIにやらせたい作業」はPromptかToolか
もうひとつ迷いやすいのが、
文章を要約する コードをレビューする SQLを書く
といった純粋なLLM Taskです。たとえばCode Reviewを、
@mcp.prompt()
def review_code(
code: str
) -> str:
return f"Review this code:\n{code}"
とできます。一方、
@mcp.tool()
def review_code(
code: str
) -> str:
return call_external_review_service(code)
というToolも成立します。違いは処理主体です。前者は、
現在のMCP Hostが使っているモデルへ レビューを依頼するためのテンプレート
です。後者は、
外部のReview Serviceを Functionとして実行する
ものです。LLMへのReusable InstructionならPrompt、外部処理の実行ならToolと考えると判断しやすくなります。
Prompt内から勝手にToolを実行するわけではない
Promptを、
@mcp.prompt()
def deploy():
return """
Deploy this application to production.
"""
と書いたとしても、Prompt Function自身がDeploymentを実行するわけではありません。Conversationへ、
Deploy this application to production.
というMessageを追加するだけです。その後モデルが利用可能なToolsからDeploy Toolを選択する可能性はありますが、それは別の処理です。PromptとToolを分離しておけば、
ユーザーがWorkflowを開始する ↓ Prompt ↓ モデルが状況を判断する ↓ Toolを呼び出す
という構成も作れます。
MCP Clientが呼び出すProtocol Methodも違う
3つのPrimitiveはProtocol Methodも分離されています。Toolsでは、
tools/list tools/call
が使われます。Resourcesでは、
resources/list resources/templates/list resources/read
が使われます。Promptsでは、
prompts/list prompts/get
が使われます。現行Python SDKのGetting Startedでも、それぞれのCapabilityと利用可能なMethodがこのように整理されています。つまりProtocol Levelでも、3つは単に表示方法が違うだけの同一機能ではありません。
MCP Inspectorでも別々に確認できる
MCP Inspectorを使うとTools、Resources、Promptsを別々に確認できます。Python SDKなら、
uv run mcp dev server.py
でServerを起動できます。InspectorではTools TabでTool Callを実行し、ResourcesではResourceをReadし、PromptsではPrompt Argumentを入力してRendered Messageを確認できます。どこに実装するべきか迷っている場合、一度Inspectorで各Primitiveを実際に触ると違いが理解しやすくなります。
迷ったときの判断基準
実装先は次のように考えると整理できます。
| 実装したいもの | 向いているPrimitive |
|---|---|
| 商品を条件検索する | Tool |
| Databaseを更新する | Tool |
| メールを送信する | Tool |
| GitHub Issueを作成する | Tool |
| Weather APIを条件付きで呼ぶ | Tool |
| 特定Documentを公開する | Resource |
| Application設定を参照させる | Resource |
| Database RecordをURIで公開する | Resource |
| Coding Guideをモデルへ渡す | Resource |
| コードレビュー用テンプレート | Prompt |
| 議事録要約テンプレート | Prompt |
| PR説明文作成テンプレート | Prompt |
| Resourceを使ったReview Workflow | Prompt + Resource |
| Document検索と本文取得 | Tool + Resource |
重要なのは、処理内容そのものより、
誰が利用を決定するのか
を見ることです。
Model-controlledならTool
ユーザーが自然言語で依頼し、その内容からモデルが、
このFunctionを呼ぶ必要がある
と判断するものはToolです。たとえば、
東京の天気を教えて
に対してモデルが、
get_weather(city="Tokyo")
を実行するならToolです。特にParameterをモデルに組み立てさせたい処理はToolとの相性がよくなります。
Application-controlledならResource
ApplicationやMCP Host側が、
この情報をモデルへContextとして渡そう
と判断するものはResourceです。たとえば現在Editorで開いているDocumentに関連する、
docs://api/authentication
をClient側で読み込み、モデルへAttachmentとして渡す構成です。Resourceは「モデルが外部関数を実行する」というより、
モデルが参照するContextを提供する
役割に向いています。
User-controlledならPrompt
ユーザーが、
コードレビュー PR説明文作成 要約 設計レビュー
など特定Workflowを自分で開始する場合はPromptが向いています。PromptはユーザーがClient UIから選択し、必要なArgumentを入力してConversationへMessageを追加する仕組みです。つまり3つをまとめると、
モデルが選ぶ → Tool アプリが選ぶ → Resource ユーザーが選ぶ → Prompt
となります。
何でもToolにするとTool一覧が肥大化する
MCP Serverを作り始めると、すべてをToolに実装したくなることがあります。たとえば、
read_coding_rules read_api_document read_database_schema read_company_policy read_manual
を全部Toolにします。しかしこの設計では、モデルへ渡されるTool Catalogが増えます。モデルはその中から毎回適切なToolを選択しなければなりません。単純な参照データならResourcesへ分けることで、
実行可能なFunction
Contextとして読むData
を明確に分離できます。ツール数が増えるほど選択精度が落ちる問題はAIエージェントが存在しないツールを呼び出す原因で詳しく解説していますが、その意味でも何でもTool化する必要はありません。
逆に何でもResourceにするとモデルが自律的に取得しにくい
Resourcesへ寄せすぎる問題もあります。たとえば、
search://products?query=...
のようなURI設計を大量に作り、すべての検索処理をResourceにするとします。技術的には実装できても、モデル自身がユーザーの要求を解釈してParameterを組み立てて実行する用途ではToolのほうが自然です。ResourcesはApplication-controlledなので、
AI Agentに必要に応じて自律検索させたい
のであればToolとして公開したほうがMCPのControl Modelと一致します。
PromptsへBusiness Logicを詰め込まない
Promptsも便利なので、
顧客検索 注文作成 メール送信
などの手順を巨大なPromptへ書きたくなる場合があります。しかし外部SystemとのInteractionはToolsへ切り出したほうが管理しやすくなります。Promptには、
どのように作業を進めるか どの観点で判断するか どの形式で回答するか
を記述します。実際の操作はToolsで提供します。参照情報はResourcesへ分離します。この構成ならPromptを変更してもAPI Integration自体へ影響しません。
1つの機能を3つに分ける設計もできる
たとえば「障害調査MCP」を作るとします。Resourceには、
runbook://database runbook://network runbook://application
というRunbookを公開します。Toolには、
search_logs get_metrics restart_service
などを公開します。Promptには、
incident_investigation
を登録します。ユーザーがIncident Investigation Promptを選びます。Promptによってモデルへ調査手順が示されます。Clientは必要なRunbook ResourceをContextとして渡せます。モデルは状況に応じてsearch_logsなどのToolを呼び出します。このように、
Prompt → Workflow Resource → Knowledge Tool → Action
と分割するとMCP Serverの設計が分かりやすくなります。
2026-07-28でも3つの基本的な役割は変わっていない
2026年7月28日のMCP仕様では、Protocol CoreのStateless化、Multi Round-Trip Requests、Header-based Routing、Cache Hintなど大きな変更が入りました。しかしTools、Resources、PromptsというServer Primitive自体は引き続き存在します。
tools/list、prompts/list、resources/list、resources/readにはCache Hintも追加され、ClientはServerの指示に基づいてCatalogやResource ContentをCacheできるようになっています。また2026-07-28ではtools/callだけでなく、prompts/getやresources/readもMulti Round-Trip Requestへ対応でき、処理途中で追加入力が必要な場合にinput_requiredを返せます。
つまり機能は高度になっていますが、
Tools = Function Resources = Context Data Prompts = Message Template
という基本設計は変わっていません。
MCPのtools・resources・promptsに関するよくある質問
Q「顧客IDを指定して取得する」処理はToolとResourceのどちらで実装すべきですか
Aどちらが自然かは「誰がその処理を選ぶか」で判断します。ユーザーの自然言語での依頼からモデルがIDを判断して取得するならTool、Application側が現在表示中の顧客情報をあらかじめContextへ付けたいならResourceが向いています。
QResourceはURIで識別すると聞きましたが、動的なデータは扱えますか
A扱えます。Resourceの内容はresources/readが呼ばれた時点でFunctionが実行されるため、静的なファイルだけでなくDatabase参照やシステム状態のような動的なデータも公開できます。判断基準は静的か動的かではなく、Applicationが特定の情報をContextとして読み込むものかどうかです。
QPromptの中でToolやResourceを呼び出すことはできますか
APrompt自身がTool実行やResource取得を行うわけではありません。PromptはConversationへMessageを追加するだけの機能です。ただしPrompt MessageにResourceの内容をEmbedded Resourceとして含めることはできますし、Prompt選択後にモデルが必要なToolを呼び出す流れを作ることもできます。
Qすべての機能をToolとして実装しても問題ありませんか
A動作はしますが推奨されません。Toolが増えるほどモデルへ渡されるTool Catalogが肥大化し、選択精度が落ちる原因になります。単純な参照データはResourceへ、ユーザーが明示的に選ぶテンプレートはPromptへ分けたほうが、Tool一覧を小さく保てます。
QREST APIのGET・POSTとMCPのResource・Toolは対応しますか
A単純には対応しません。GETだからResource、POSTだからToolと決まっているわけではなく、HTTP Methodではなく「誰がその処理を選択して実行するか」を基準に判断します。副作用がなくてもモデルが条件を組み立てて実行する処理はToolに向いています。
Q2026-07-28仕様でtools・resources・promptsの役割は変わりましたか
A基本的な役割(ToolはModel-controlled、ResourcesはApplication-controlled、PromptsはUser-controlled)は変わっていません。ただしtools/callだけでなくprompts/getやresources/readもMulti Round-Trip Requestsへ対応し、tools/list・prompts/list・resources/list・resources/readにCache Hintが追加されるなど、Protocol Levelの機能は拡張されています。
MCP Serverでは「何ができるか」より「誰が選ぶか」で分ける
MCPのtools、resources、promptsは、似た処理を実現できる場合があるため、最初は境界が分かりにくく感じます。しかし、実装内容そのものではなくControlの主体を見ると整理できます。
モデルがユーザーの要求を解釈し、Parameterを作って必要な処理を実行するならToolです。
search_products create_issue send_email update_customer
などが該当します。Application側が特定の情報を読み込み、モデルへContextとして渡すならResourceです。
docs://coding-rules config://app customer://123
などです。ユーザーがメニューやSlash Commandなどから選択し、再利用可能なAI向けMessageを生成するならPromptです。
review_code summarize_document create_pr_description
などが該当します。MCP公式の整理でも、この違いはToolsがModel-controlled、ResourcesがApplication-controlled、PromptsがUser-controlledと表現されています。
そして実際のMCP Serverでは、3つを競合する選択肢として考える必要はありません。検索はTool、検索して見つかったDocumentはResource、Documentを使ってレビューするWorkflowはPrompt、というように組み合わせられます。
MCP Serverを設計するときは、「これはToolかResourceか」とデータの種類だけで判断するのではなく、「誰がいつこれを選択するべきなのか」を基準にすることが、最も分かりやすい設計方法です。
