Search Result Limit
MCP Tools Progressive Disclosure Policy
Policy Name |
MCP Tools Progressive Disclosure |
Summary |
Reduces context window token cost by exposing tools on-demand through search |
Category |
MCP |
First Omni Gateway version available |
v1.13.0 |
Release Notes |
|
Returned Status Codes |
No return codes exist for this policy. |
| This policy supports Model Context Protocol (MCP) version 2025-06-18 and earlier. To learn more about MCP, see MCP Specification. |
Summary
The MCP Tools Progressive Disclosure policy reduces an MCP client’s context-window token cost by hiding the tools/list catalog behind these tools:
-
search_tools: Finds relevant tools on demand by matching a query against tool names and descriptions. -
invoke_tool: Calls a tool discovered viasearch_tools.
With this policy, you can:
-
Reduce token consumption by exposing tools on-demand rather than listing all tools up front.
-
Keep frequently-used tools immediately available through
hotToolsconfiguration. -
Support paginated search results for large tool catalogs.
-
Preserve normal tool invocation semantics for upstream policies.
| This policy must be positioned after the MCP Support Policy but before any other MCP authorization policies, such as access control, tool mapping, or schema validation policies. To learn more about MCP authorization policies, see Configuring MCP Access Control Policies. |
The policy performs no tool caching. Every tools/list, search_tools, and invoke_tool request is resolved against the live upstream, so the client always sees the real, per-caller-filtered upstream state.
Configuring Policy Parameters
Managed Omni Gateway and Omni Gateway Connected Mode
When you apply the policy from the UI, the following parameters are displayed:
| Element | Description | Default |
|---|---|---|
The maximum number of matches a |
|
|
Hot Tools |
Tool names or patterns that bypass disclosure. Matched tools appear in the client-facing |
|
Meta Tool Prefix |
A prefix prepended to the |
|
Configuration Example
- policyRef:
name: mcp-tools-progressive-disclosure-policy-flex
config:
searchResultLimit: 20
hotTools:
- "get_weather"
- "list_*"
metaToolPrefix: "mcp_"
The metaToolPrefix value "mcp_" produces mcp_search_tools and mcp_invoke_tool. The underscore is part of the configured prefix, not added automatically.
|
How It Works
Meta-Tool Advertisement
When a client requests tools/list, the policy:
-
Forwards the request upstream to get the live, per-caller-filtered tool catalog.
-
Replaces the full catalog with the two meta-tools (
search_toolsandinvoke_tool). -
Includes any tools matching the configured
hotToolspatterns with their original schemas.
Tool Discovery
When a client calls search_tools:
-
The policy forwards a synthesized
tools/listrequest upstream. -
The upstream access control policy filters the list per caller.
-
The policy runs the search query against the filtered list.
-
Matching tools are returned with their full schemas, sufficient to construct an
invoke_toolcall.
Tool Invocation
When a client calls invoke_tool:
-
The policy rewrites the request as a native
tools/callwith the wrapped tool name. -
All upstream policies see the real tool name (not
invoke_tool). -
The response is returned to the caller unchanged.
This normalization ensures that access control, tool mapping, and other policies operate on the real tool name without progressive-disclosure awareness.
Hot Tools Configuration
The hotTools configuration enables you to keep frequently-used tools immediately visible without requiring a search. Tools matching the patterns appear in tools/list alongside search_tools and invoke_tool.
Pattern Matching
-
Use exact names:
"get_weather". -
Use glob patterns:
"list_*","*_info". -
Matches are evaluated against the live upstream
tools/listresponse on every request. -
Only tools the caller is authorized to see (per the chain’s access control policy) will match.
Search Tool Usage
The search_tools meta-tool accepts a JSON object with the following parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
|
string |
Yes |
A case-insensitive regular expression to match against tool names and descriptions. Separate alternative keywords with |
|
integer |
No |
Maximum number of results to return per page. If omitted, uses the configured |
|
string |
No |
Opaque pagination cursor from a prior search’s |
Example Request
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search_tools",
"arguments": {
"query": "weather",
"limit": 3
}
}
}
Example Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "Found 1 matching tool(s)."
}
],
"structuredContent": {
"matches": [
{
"name": "get_weather",
"description": "Return the current weather for a city",
"inputSchema": {
"type": "object",
"required": ["city"],
"properties": {
"city": {
"type": "string"
}
}
}
}
]
}
}
}
Pagination
When more tools match than fit on a page, the response includes a nextCursor field under structuredContent:
{
"structuredContent": {
"matches": [...],
"nextCursor": "eyJxIjoid2VhdGhlciIsIm8iOjIwfQ=="
}
}
To fetch the next page, pass the cursor back in the arguments:
{
"method": "tools/call",
"params": {
"name": "search_tools",
"arguments": {
"cursor": "eyJxIjoid2VhdGhlciIsIm8iOjIwfQ=="
}
}
}
Each page resolves against a fresh upstream tools/list, ensuring the correct authorization. The query parameter may be omitted when using a cursor (the cursor carries it).
Invoke Tool Usage
The invoke_tool meta-tool wraps a call to a discovered tool. It accepts:
| Parameter | Type | Required | Description |
|---|---|---|---|
|
string |
Yes |
The tool name returned from |
|
object |
Yes |
The tool’s input parameters as returned in the |
Example Request
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "invoke_tool",
"arguments": {
"name": "get_weather",
"arguments": {
"city": "San Francisco"
}
}
}
}
The policy rewrites this as a native tools/call:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "get_weather",
"arguments": {
"city": "San Francisco"
}
}
}
All upstream policies see get_weather (not invoke_tool), ensuring access control, tool mapping, and other policies operate correctly.
Filter Chain Ordering
The MCP Tools Progressive Disclosure policy must be positioned after the MCP Support Policy but before any other MCP policies in the filter chain, particularly before any policy that reads tool names (access control, tool mapping, schema validation).
If positioned after an access control policy, that policy would see invoke_tool (the meta-tool) in the request and gate the envelope—not the real tool inside—creating an authorization bypass.
Delegated Authorization
The policy maintains per-caller authorization parity by delegating to the chain:
-
A
search_toolscall triggers a synthesizedtools/listrequest upstream. -
The upstream access control policy filters the list per caller.
-
The policy runs the query against the filtered list.
-
Only tools the caller is authorized to see are included in results.
This ensures:
-
Callers don’t see tools they cannot invoke.
-
Results reflect live authorization state.
-
No caching of authorization decisions.
If no access control policy is present, search_tools returns the full unfiltered catalog—the same as a direct tools/list would in that chain.
Error Responses
The policy returns JSON-RPC error objects with a stable data.reason field for machine-checkable error handling.
| Case | Code | data.reason |
Description |
|---|---|---|---|
Malformed |
|
|
Missing or invalid |
Malformed |
|
|
Empty/missing/non-string query, exceeds 256 characters, invalid regex, bad |
Errors produced upstream (access control denials, upstream tool errors) pass through unchanged.



