What it does
The `resources/list` method is sent by an MCP client to a server to enumerate all resources the server currently exposes. A client first checks that the server declared the `resources` capability during initialization; if it did not, sending this request is a protocol violation. The request body is minimal — an optional `cursor` string for pagination is the only parameter. The server responds synchronously with a `resources` array where each entry carries at minimum a `uri` and `name`, and optionally a `description`, `mimeType`, and `annotations`. An optional `nextCursor` field signals that more pages exist.\n\nPagination is cursor-based rather than offset-based, so clients must page forward by re-issuing `resources/list` with the returned `nextCursor` until a response arrives with no `nextCursor`. The cursor is opaque to clients — do not parse or store it beyond the current pagination walk. If the server sends a `notifications/resources/list_changed` notification mid-walk, the safest response is to restart the listing from the beginning, because cursors may be invalidated when the resource set changes.\n\nError scenarios a client must handle include: `MethodNotFound (-32601)` if the server did not advertise the `resources` capability, `InvalidParams (-32602)` if a stale or malformed cursor is supplied, and general `InternalError (-32603)` responses from servers that fail to enumerate their backing store. Clients should not assume list results are stable between calls; treat each full page-walk as a snapshot taken at a single point in time.
When to use
After initialize or on list_changed.
When NOT to use
Per-tool-call — cache and listen for change notifications.
Notes
Capability gate is mandatory
The server must include `{"resources": {}}` (or a richer object) in its `capabilities` response during the `initialize` handshake before a client may send `resources/list`. Sending the request without that capability being declared should be treated as a client bug; well-behaved servers will respond with `MethodNotFound (-32601)`.
Cursor opacity and pagination restart
Cursors are opaque server tokens — never attempt to decode, increment, or persist them across sessions. If a `notifications/resources/list_changed` event arrives while you are mid-pagination, discard all accumulated results and restart from a null cursor. Reusing a cursor from before the change notification is likely to return `InvalidParams (-32602)` or silently skip or duplicate resources.
Caching strategy
Cache the resource list locally and invalidate the entire cache on each `notifications/resources/list_changed` notification rather than trying to diff individual entries. The notification carries no payload indicating which resource changed, so partial cache invalidation is not reliable. Re-fetching all pages immediately on notification is appropriate for small resource sets; for large sets, lazy re-fetch on next access is safer.
mimeType is advisory, not guaranteed
The `mimeType` field in each Resource object is populated at list time by the server on a best-effort basis. The actual content returned by a subsequent `resources/read` call may differ — for example, a server that proxies remote files may not know the MIME type until it fetches the content. Always re-check the `mimeType` in the `resources/read` response blob rather than trusting the value from the list.
SDK default behavior for list_changed
Several official MCP SDKs (TypeScript, Python) expose a `onResourceListChanged` callback that fires after the SDK has already acknowledged the notification. Do not issue a new `resources/list` call synchronously inside this callback on the same transport connection — schedule it as a microtask or use the SDK's built-in refresh helper to avoid re-entrancy issues in the request dispatcher.
Request parameters
| Name | Type | Purpose |
|---|---|---|
| cursor | string? | Pagination cursor. |
Response fields
| Name | Type | Purpose |
|---|---|---|
| resources | Resource[] | Available resources. |
| nextCursor | string? | Pagination. |
Examples
List resources
{ "method": "resources/list" }
Common mistakes
❌ Polling instead of subscribing
✅ Listen for notifications/resources/list_changed.