anthropics / anthropics/claude-code
MCP: server advertising `resources` capability is treated as having none
- 主要言語
- Python
- スター
- 145k
- フォーク
- 23.1k
- PR マージ指標
- PR 指標を取得中
説明
### What happens
An MCP server that advertises the `resources` capability in its `initialize` response is treated by Claude Code as having no resource support:
- `ListMcpResourcesTool` with that server name returns `No resources found. MCP servers may still provide tools even if they have no resources.`
- `ReadMcpResourceTool` against a valid URI returns `Server "" does not support resources`
`tools/*` from the same server works fine. Another MCP server configured in the same session (a `stdio` one) *does* have its resources listed correctly, so resource support is working in general — just not for this server.
### The server is advertising it
Server is Rust + [`rmcp`](https://crates.io/crates/rmcp) 3.1.4, Streamable HTTP transport, stateless (`legacy_session_mode: false`, `json_response: true`). Verified directly on the wire with `curl`:
`initialize`:
```json
{"jsonrpc":"2.0","id":1,"result":{
"protocolVersion":"2025-11-25",
"capabilities":{"resources":{},"tools":{}},
"serverInfo":{"name":"...","version":"..."}
}}
```
`resources/list`:
```json
{"jsonrpc":"2.0","id":2,"result":{"resources":[
{"uri":"schema://.../relationships.md","name":"...","mimeType":"text/markdown","size":13995}
]}}
```
`resources/read` returns the document, and `resources/templates/list` returns `{"resourceTemplates":[]}`. All HTTP 200.
Identical `capabilities` are returned when the client negotiates `2024-11-05`, `2025-06-18`, `2025-11-25` or `2026-07-28`, and the same results come through when the server is reached via the `mcp-remote` stdio bridge rather than directly.
### The client received it
Claude Code's own MCP log for the session records a line from that same handshake:
```
{"debug":"Server instructions truncated from 2221 to 2048 chars", ...}
```
The server's `instructions` string is exactly 2221 characters, so the `initialize` response that the client parsed is the one shown above — the one carrying `"resources":{}`. No connection error is logged.
### Possibly relevant
The one observable difference from the `stdio` server whose resources *do* get listed is the shape of the capability object:
| server | `capabilities` |
|---|---|
| works | `{"resources":{"listChanged":false},"tools":{"listChanged":false}}` |
| fails | `{"resources":{},"tools":{}}` |
Both are spec-legal — `resources: {}` means "supported, no optional sub-capabilities". The bundled MCP SDK's own `assertCapability` check (`if (!this._capabilities.resources) throw ...`) treats `{}` as present, since `{}` is truthy, so that check is not the one rejecting it. Something upstream of it appears to decide the server has no resources.
### Environment
- Claude Code in the desktop app (Code tab), macOS 15 (Darwin 25.4.0)
- Server: self-hosted, `rmcp` 3.1.4, Streamable HTTP at `http://localhost:/core/mcp`
- Also reproduced through `mcp-remote` 0.1.38 as a stdio bridge to the same server
### Expected
A server advertising `capabilities.resources` (including as an empty object) has its resources listed by `ListMcpResourcesTool` and readable by `ReadMcpResourceTool`.
コントリビューションガイド
このリポジトリのコントリビューションガイドは索引されていません
調査の方向性
Start at ListMcpResourcesTool and ReadMcpResourceTool, then trace the upstream MCP capability check and parsing of the initialize response. Compare handling of capabilities.resources as {} with the working {"listChanged":false} shape. Done means servers advertising an empty resources object can list and read resources without changing behavior for unsupported servers.
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- python
- 領域
- api, backend
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 活発
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 48/100