Skip to content
Closed
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules/
.DS_Store
.idea/
2 changes: 2 additions & 0 deletions docs/specification/2025-03-26/server/prompts.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ sequenceDiagram
Note over Client,Server: Discovery
Client->>Server: prompts/list
Server-->>Client: List of prompts
Client->>Server: prompts/search
Server-->>Client: Results of prompts search

Note over Client,Server: Usage
Client->>Server: prompts/get
Expand Down
2 changes: 2 additions & 0 deletions docs/specification/2025-03-26/server/resources.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ sequenceDiagram
Note over Client,Server: Resource Discovery
Client->>Server: resources/list
Server-->>Client: List of resources
Client->>Server: resources/search
Server-->>Client: Result of resources search

Note over Client,Server: Resource Access
Client->>Server: resources/read
Expand Down
2 changes: 2 additions & 0 deletions docs/specification/2025-03-26/server/tools.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ sequenceDiagram
Note over Client,Server: Discovery
Client->>Server: tools/list
Server-->>Client: List of tools
Client->>Server: tools/search
Server-->>Client: Tools search results

Note over Client,LLM: Tool Selection
LLM->>Client: Select tool to use
Expand Down
177 changes: 177 additions & 0 deletions docs/specification/2025-03-26/server/utilities/search.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
---
title: Search
---

<Info>**Protocol Revision**: 2025-03-26</Info>

The Model Context Protocol (MCP) provides a standardized way for agents to search tools,
resources, prompts, and other features.

## User Interaction Model

Search in MCP is designed to facilitate discovery of tools for assisting and automating
tasks, especially in environments where the number of tools is either too large to be
reasonably paginated or there are concerns with LLM context length for the number of tools.

For example, given a prompt such as what's the weather in San Francisco, an LLM could
request a search of tools such as "Get weather data for North America". The list of tools
will be returned and ordered by relevance, with the server's approximation of most relevant
tools at the top.

Implementations are free to use any different method to enable search, from very simple
keyword search, to more complex embedded vectorization search.

## Capabilities

Servers that support search **MUST** declare the `search` capability in the respective
feature area:

```json
{
"capabilities": {
"tools": {
"search": true
}
}
}
```

```json
{
"capabilities": {
"prompts": {
"search": true
}
}
}
```

```json
{
"capabilities": {
"resources": {
"search": true
}
}
}
```

## Protocol Messages

### Requesting earch

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Request Search


To get completion suggestions, clients send the appropriate request to the server, `tools/search`,
identifying both what feature set is being searched and providing a query. Pagination is handled
through the cursor, but the client **MUST** provide the original query parameter paired with the
cursor.

**Request:**

```json
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/search",
"params": {
"query": "tools to return the weather in San Francisco",
"cursor": "optional-cursor-value"
}
}
```

**Response:**

```json
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [
{
"name": "get_weather",
"description": "Get current weather information for a location",
"inputSchema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name or zip code"
}
},
"required": ["location"]
}
}
],
"nextCursor": "next-page-cursor"
}
}
```

### Search Results

Servers return an array of search results, matching the format of the list call for, for the
various features, ranked by relevance, with:

- Maximum 10 items per response
- Optional next cursor

## Message Flow

```mermaid
sequenceDiagram
participant Client
participant Server

Note over Client,Server: Tools Search
Client->>Server: tools/search
Server-->>Client: Search Results

Note over Client,Server: Resources Search
Client->>Server: resources/search
Server-->>Client: Search Results

Note over Client,Server: Prompts Search
Client->>Server: prompts/search
Server-->>Client: Search Results
```

## Data Types

### SearchRequest

- `query`: Arbitrary text that expresses what is being searched for. This can be a keyword (e.g., 'weather'), a description (e.g., 'cities weather is available for'), or a use case (e.g., 'trying to generate weather reports').
- `cursor`: An opaque pagination token

### SearchResult
Please see the list results in [Tools](/specification/2025-03-26/server/tools),
[Prompts](/specification/2025-03-26/server/prompts), and [Resources](/specification/2025-03-26/server/resources),

## Error Handling

Servers **SHOULD** return standard JSON-RPC errors for common failure cases:

- Method not found: `-32601` (Capability not supported)
- Missing required arguments: `-32602` (Invalid params)
- Internal errors: `-32603` (Internal error)

## Implementation Considerations

1. Servers **SHOULD**:
- Return suggestions sorted by relevance
- Implement embedded vectorization when possible to enable better natural language results
- Rate limit search results
- Validate all inputs
- Resources **SHOULD** be deeply indexed (i.e. the content itself is indexed, not just the name and description)

2. Clients **SHOULD**:
- Use batching if it's not clear whether a tool, resource, or prompt is appropriate for the situation

@LucaButBoring LucaButBoring Apr 15, 2025 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be interesting if this could somehow be leveraged on the server side to do a single large search rather than three separate ones, that might be a tricky optimization, though. I suppose the server could hypothetically have a reactive stream consuming and batching client search requests to handle in a single query, maybe 🤔

Not a criticism and I don't have concrete suggestions about it, it's just something that stood out to me when I re-read this line, since the complexity trade-off is questionable. Realistically with a "sufficiently-fast" index it shouldn't make much of a difference anyways, since this is an edge case already.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ya, I actually originally started going the direction of a single search/query endpoint - the BIGGEST issue is you end up in a situation where implementors have to make a lot more implementation decisions about how you interleave results, and the consuming LLM would I think get more confused. So, the options are:

  1. Single return with sections:
{ 
toolResults: {
   items: []
   nextCursor: tring
},
promptResults: {
...
},
resourceResults: {
...
}
}

That strikes me as too confusing for the llm to really process today, maybe that gets revisted a few years from now
2. A single result list, with items intermingled. This is somewhat doable with good vector lookups, but let's say the LLM knows it wants a tool, it has to craft an input that includes a filter, and suddenly we're back to quite a bit of client complexity.

I'm actually open to all three options here, but when I really thought through all this, it just seemed like separate endpoints was the for the llm, easiest for the implementors, and most understandable all around.

But, great feedback

- Clients should avoid caching search results, or use a very short TTL
- Facilitate pagination through the `cursor` field

## Security

Implementations **MUST**:

- Validate all search inputs
- Implement appropriate rate limiting
- Limit access to search results based on appropriate user controls
189 changes: 189 additions & 0 deletions docs/specification/draft/server/utilities/search.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
---
title: Search
---

<Info>**Protocol Revision**: DRAFT</Info>

The Model Context Protocol (MCP) provides a standardized way for agents to search tools,
resources, prompts, and other features as they're added.

## User Interaction Model

As MCP servers scale, and the number of tools increases, it can become more unwieldy for clients
to capture tools and present them to the model in a cost-effective and context preserving way.
Search can help this by allowing clients to request a constrained list of tools, resources, or prompts,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nanonit: "Search can help with this"? "Search can help alleviate this"? Feels like some word is missing there.

thus minimizing the data added to the model context. Search is an OPTIONAL capability to be used in
environments where the number of tools is either too large to be reasonably paginated or there are
concerns with LLM context length for the number of tools.

For servers that support this capability, rather than paginating all tools and adding all tools to context,
clients should present the model with a search tool and a prompt that directs the model to search for tools

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: is this intentionally or unintentionally a lowercase "should"?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More importantly, maybe we should avoid calling this a tool here - a tool is already a specific concept, so calling this a search tool begs the question at this point (prior to digging through the spec) of how this is any different from a regular tool call that triggers a list update. Maybe just "a search interface"?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, this is only one client integration pattern and others may find better ways to leverage this, so maybe that can be made more clear with some extra comment like a "client applications are free to integrate this search interface into their tool selection workflows in any manner," even though what you have here is a good recommended integration pattern to lead with.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ya, this is tool in the LLM sense, NOT the MCP sense. So, could genericize it to function call, it's a good call out

with a clean description of the MCP server and the tools it supplies from the MCP Server Metadata. An example
flow is outlined below.

Server implementations are free to use any different method to enable search, from very simple
keyword search, to more complex embedded vectorization search.

## Capabilities

Servers **MAY** declare the `search` capability in the respective feature area:

```json
{
"capabilities": {
"tools": {
"search": true
}
}
}
```

```json
{
"capabilities": {
"prompts": {
"search": true
}
}
}
```

```json
{
"capabilities": {
"resources": {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likely need one for resource templates, too.

"search": true
}
}
}
```

## Protocol Messages

### Requesting Search

To request a filtered list of tools, resources, resource templates, or prompts, clients send the
appropriate request to the server, `tools/search`, identifying both what feature set is being
searched and providing a query. Pagination is handled through the cursor, but the client **MUST**
provide the original query parameter paired with the cursor.
Comment on lines +67 to +68

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd also add something here like "The server SHOULD validate that the query parameter has not changed between cursors, and MAY return an InvalidParams error if this condition is violated."

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coming in late here, but I see this was added in the initial commit and I was curious why it was there. If a server needs the original query for its pagination logic, then it could easily encode that into the cursor string. Servers that are pointed to database and just use the database's cursor might not even have a way to readily validate the original query without an extra storage mechanism.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, GENERALLY in search it's a best practice to include the query in repeated requests, but it's true some of these queries could be long, I'll think about this. It's just kinda ugly to change the request besides the cursor tbh


**Request:**

```json
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/search",
"params": {
"query": "tools to return the weather in San Francisco",
"cursor": "optional-cursor-value"
}
}
```

**Response:**

```json
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [
{
"name": "get_weather",
"description": "Get current weather information for a location",
"inputSchema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name or zip code"
}
},
"required": ["location"]
}
}
],
"nextCursor": "next-page-cursor"
}
}
```

### Search Results

Servers return an array of search results, matching the format of the list call for the
various features, ranked by relevance, with:

- Maximum 10 items per response

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could use an optional maxResults parameter to leave this up to client app implementors? For some models, 10 could be too many already (though I'm not aware of any such models), while others can handle more without any issues. Or, I might just want to limit result sets even more to further reduce the odds of the model selecting an incorrect tool. On the server side, maybe I want to spend a bit more time on search relevance to send more results at once to reduce bandwidth. Either way, I don't think the maximum number of items per page should be specification-defined.

On the other hand, I imagine the reason why this wasn't made into a parameter here is because individual servers setting their own limits is difficult to negotiate prior to making a request. Maybe the max results can be added as a parameter with a requirement that servers clamp the result set to at most maxResults if it is provided, which still allows for servers to set their own, lower limits too.

- Optional next cursor

## Message Flow

```mermaid
sequenceDiagram
participant Host
participant Client
participant Server

Note Over Host,Server: Initialization
Client->>Server: Discover Search Capability
Client->>Host: In LLM prompt, include search as primary tool

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we agree to remove "tool" verbiage here as suggested at the top of the doc, this could be changed to "Expose search interface to LLM".


Note over Client,Server: Tools Search
Host->>Client: Search Tools requested
Client->>Server: tools/search
Server-->>Client: Search Results
Client->>Host: Prompt for tool selection with Curated tool list
Host->>Client: Select tool
Client->>Server: Call Tool (Elided)


Note over Client,Server: Resources Search
Client->>Server: resources/search
Server-->>Client: Search Results

Note over Client,Server: Prompts Search
Client->>Server: prompts/search
Server-->>Client: Search Results
```

## Data Types

### SearchRequest

- `query`: Arbitrary text that expresses what is being searched for. This can be a keyword (e.g., 'weather'), a description (e.g., 'cities weather is available for'), or a use case (e.g., 'trying to generate weather reports').
- `cursor`: An opaque pagination token

### SearchResult
Please see the list results in [Tools](/specification/draft/server/tools),
[Prompts](/specification/draft/server/prompts), [Resources](/specification/draft/server/resources),
[Resource Template](/specification/draft/server/resource-templates),

## Error Handling

Servers **SHOULD** return standard JSON-RPC errors for common failure cases:

- Method not found: `-32601` (Capability not supported)
- Missing required arguments: `-32602` (Invalid params)
- Internal errors: `-32603` (Internal error)

## Implementation Considerations

1. Servers **SHOULD**:
- Return suggestions sorted by relevance
- Implement embedded vectorization when possible to enable better natural language results
- Rate limit search results
- Validate all inputs
- Resources **SHOULD** be deeply indexed (i.e. the content itself is indexed, not just the name and description)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: phrasing should be consistent with the other bullet points, e.g. "Deeply index resources"


2. Clients **SHOULD**:
- Provide clear guidance to models on the capabilities of the server and the way search can be used to filter tools lists
- Clients should avoid caching search results, or use a very short TTL

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: phrasing should be consistent with the other bullet points, e.g. "Avoid caching search results"

- Facilitate pagination through the `cursor` field

## Security

1. Implementations **MUST**:
- Validate all search inputs
- Implement appropriate rate limiting
- Limit access to search results based on appropriate user controls
Loading