[MCPServer] Optional ResourcesAsTools support ala FastMCP
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 45/100
調査の方向性
Look at the MCP server implementation in the python-sdk, particularly how resources and tools are registered and exposed. Examine FastMCP's ResourcesAsTools transform for reference. The work involves adding a new transform class, modifying tool generation logic, and ensuring compatibility with existing resource definitions. Start by understanding the server's resource and tool handling in the SDK's core modules.
索引モデルが issue の本文から書いたものです。
説明
Description
As per FastMCP's documentation:
Some MCP clients only support tools. They cannot list or read resources directly because they lack resource protocol support.
An example of this is Cursor.
A workaround for this is that FastMCP provides the ResourcesAsTools transform to bridge this gap by exposing list_resources and read_resource as tools.
It would be great if we support this feature here. Would love to open & scope a PR here if it's something we should support.
Additional Implementation Considerations
However, the above still requires tool-only clients (and the LLM using them) to:
- Call
list_resourcesto discover available resources/templates. - Identify the relevant URI or URI template.
- Construct the resource URI manually for templates.
- Call
read_resourcewith that URI.
This is particularly awkward for resource templates, where the parameters are already known by the resource definition but are not exposed as a tool input schema.
For example:
@mcp.resource("user://{user_id}/profile")
def user_profile(user_id: str) -> str:
...
A tool-only client currently has to discover the template and construct:
user://42/profile
before calling read_resource.
It would be great if ResourcesAsTools could optionally expose each resource and resource template as an individual tool.
For example:
@mcp.resource("config://app")
def app_config() -> str:
...
@mcp.resource("user://{user_id}/profile")
def user_profile(user_id: str) -> str:
...
mcp.add_transform(ResourcesAsTools(mcp, individual_tools=True))
could expose tools resembling:
app_config()
user_profile(user_id: str)
The generated tools would:
- Reuse the resource's name, description, MIME type, and other metadata where appropriate.
- Derive their input schema from the resource template parameters.
- Internally resolve/read the corresponding resource.
- Preserve the resource URI in the tool result where possible.
- Continue to respect the server's existing middleware, authorization, visibility, and other resource-level behavior.
This would make resources much more natural to consume from clients that only support tools/list / tools/call, while keeping the existing ResourcesAsTools behavior available for applications that prefer the generic list_resources / read_resource interface.
Example
Given:
@mcp.resource("data://{dataset}/{year}")
def dataset(dataset: str, year: int) -> str:
...
a generated tool could look conceptually like:
{
"name": "dataset",
"description": "...",
"inputSchema": {
"type": "object",
"properties": {
"dataset": {"type": "string"},
"year": {"type": "integer"}
},
"required": ["dataset", "year"]
}
}
The client could then simply call:
await client.call_tool(
"dataset",
{"dataset": "election_results", "year": 2022}
)
without needing to know how the underlying resource URI is constructed.
Alternatives considered
If maintainer's want to support this, the existing list_resources + read_resource approach works, but it exposes the resource protocol's URI-oriented abstraction directly to the model. Generating tools would instead let tool-only clients consume the same resources through the interface they already understand.
Proposed Scope
We should PR iteratively:
- Add FastMCP-stype
list_resourcesandread_resourcetools. - Optional Add
individual_tool=True. This allows for one tool per resource/template with anInputSchema.
Other
- Willing to submit PR
- AI Assistance (Cursor)
References
No response
- 主要言語
- Python
- スター
- 24.3k
- フォーク
- 4k
- 平均マージ
- 1日 11時間
- マージ済み PR(30日)
- 30
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
modelcontextprotocol/python-sdk のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
modelcontextprotocol/python-sdk#3566 ·
-
v1 v2
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
modelcontextprotocol/python-sdk#3546 · コメント 5 件 ·
-
v1 v2
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
modelcontextprotocol/python-sdk#3545 · コメント 1 件 ·
-
v1 v2
難易度 1/5 1時間未満 初心者へのやさしさ 91/100
modelcontextprotocol/python-sdk#3508 · コメント 2 件 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 64/100
modelcontextprotocol/python-sdk#3504 ·
modelcontextprotocol/python-sdk の issue をすべて見る
似ている issue
-
essnmx good first issue
難易度 1/5 1時間未満 初心者へのやさしさ 95/100
-
[Feature] 奇物选择添加优先级 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
syfoud/Simulated_Scepter#174 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
Giskard-AI/giskard-oss#2840 · コメント 1 件 ·
-
A claim comment carrying the issue number is silently declined while the workflow reports success オープンarea: repo bug perceived difficulty: 2
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
yeti-platform/yeti#1380 ·