-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
Preamble
Title: Prefix Filtering for Listing Resource / Templates
Status: Proposal
Author: Tapan Chugh (@chughtapan)
Type: Standards Track
Created: 2025-07-31
Abstract
This SEP proposes adding an optional prefix parameter to the resources/list and resources/templates/list requests to enable servers to efficiently filter resources and resource templates by URI prefix, to improve discoverability of resources for clients when servers expose thousands of resources (or more).
Motivation
Resources are a powerful abstraction in MCP to define the scope of information available to LLMs. While the protocol already supports pagination for handling large resource lists, this alone is insufficient when servers expose thousands of resources. Clients must retrieve multiple pages and implement local filtering to find specific resources, which becomes complex when combined with pagination as they must track filtered results across page boundaries. This leads to inefficiency as the same filtering logic is reimplemented in every client, with redundant data transfer for resources that will be discarded. Since resources already use URI format, prefix-based filtering is a natural solution that offloads this common operation to the server.
Specification
Schema Changes
Update ListResourcesRequest and ListResourceTemplatesRequest interfaces to include an optional prefix parameter:
export interface ListResourcesRequest extends PaginatedRequest {
method: "resources/list";
params?: {
/**
* Optional URI prefix to filter resources.
* Only resources whose URI starts with this prefix will be returned.
*/
prefix?: string;
} & PaginatedRequest["params"];
}
export interface ListResourceTemplatesRequest extends PaginatedRequest {
method: "resources/templates/list";
params?: {
/**
* Optional URI prefix to filter resource templates.
* Only templates whose URI template starts with this prefix will be returned.
*/
prefix?: string;
} & PaginatedRequest["params"];
}Behavior
- Prefix matching: The server returns only resources whose URI (or URI template) starts with the prefix
- Pagination compatibility: Prefix filtering works with pagination - the cursor represents position within the filtered results
Examples
Request with prefix filter:
{
"jsonrpc": "2.0",
"id": 1,
"method": "resources/list",
"params": {
"prefix": "file:///project/src/"
}
}Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"resources": [
{
"uri": "file:///project/src/main.py",
"name": "main.py"
},
{
"uri": "file:///project/src/config.json",
"name": "config.json"
}
]
}
}Combining with pagination:
{
"jsonrpc": "2.0",
"id": 2,
"method": "resources/list",
"params": {
"prefix": "https://api.example.com/users/",
"cursor": "cursor-123"
}
}Resource templates with prefix filter:
{
"jsonrpc": "2.0",
"id": 3,
"method": "resources/templates/list",
"params": {
"prefix": "https://api.example.com/"
}
}Response:
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"resourceTemplates": [
{
"uriTemplate": "https://api.example.com/users/{id}",
"name": "User Details"
},
{
"uriTemplate": "https://api.example.com/posts/{postId}",
"name": "Blog Post"
}
]
}
}Rationale
Resources are a powerful abstraction in MCP to define the scope of information available to LLMs. Efficient discoverability of these resources is crucial for effective context management. As the number of resources exposed by servers increases into thousands or millions, naively returning all resources becomes inefficient and convoluted for clients to handle. Given the hierarchical structure inherent in URIs, prefix-based filtering provides the simplest approach to improve resource discoverability.
Alternatives Considered
-
Glob patterns: Although more flexible than simple prefixes, the value from the additional implementation complexity does not seem clear given the hierarchical nature of URIs.
-
Namespaces: (SEP-993: Namespaces #993) I believe this was already rejected in [notes] Core Maintainer Meeting, July 23rd #1061. The hierarchical nature of URIs lends itself to simple path based name-spacing automatically.
-
New search method: ([RFC] Search #322, Open to tools/search and resources/search #204) Creating a new search method only for resources seems like an overkill. Creating a unified search method across components / tools might not work since the search requirements are likely different.
Backward Compatibility
While the prefix parameter is optional in the schema, this feature requires updates to SDKs to expose the prefix parameter. Existing clients continue to work as it is since the parameter is optional.
Reference Implementation
Specification Updates PR: #1279
Python SDK Implementation: modelcontextprotocol/python-sdk#1225
Security Implications
Prefix filtering doesn't grant access to resources that wouldn't already be accessible through pagination. It only provides a more efficient way to retrieve subsets of already-accessible resources.
Open Questions
-
Should we consider path-based prefix matching versus string-based prefix matching? For example, should the prefix
uri://amatchuri://abc/defor not? Assuming the prefix to be path prefix seems like the easiest to implement especially with templates in mix. -
For resource templates with embedded variables (e.g.,
https://api.example.com/users/{id}/operations/{action}), should we resolve partial parameters and try to match them against templates? This seems a little tricky to get right: While resolving template parameters makes sense from an improving discoverability perspective, it's unclear if returning something like:https://api.example.com/users/123/operations/{action}is in line with semantics that we want list_templates to offer.