Contact Us 1-800-596-4880

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

MCP Tools Progressive Disclosure

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 via search_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 hotTools configuration.

  • 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

Omni Gateway Local Mode

The MCP Tools Progressive Disclosure policy isn’t supported in Local Mode.

Managed Omni Gateway and Omni Gateway Connected Mode

When you apply the policy from the UI, the following parameters are displayed:

Element Description Default

Search Result Limit

The maximum number of matches a search_tools query returns per page when the query omits its own limit parameter.

20

Hot Tools

Tool names or patterns that bypass disclosure. Matched tools appear in the client-facing tools/list with their original upstream schemas.

[] (empty)

Meta Tool Prefix

A prefix prepended to the search_tools and invoke_tool meta-tool names to avoid namespace collisions with upstream tool names. The prefix is concatenated directly with no separator added (such as _) in the prefix value itself.

"" (empty)

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:

  1. Forwards the request upstream to get the live, per-caller-filtered tool catalog.

  2. Replaces the full catalog with the two meta-tools (search_tools and invoke_tool).

  3. Includes any tools matching the configured hotTools patterns with their original schemas.

Tool Discovery

When a client calls search_tools:

  1. The policy forwards a synthesized tools/list request upstream.

  2. The upstream access control policy filters the list per caller.

  3. The policy runs the search query against the filtered list.

  4. Matching tools are returned with their full schemas, sufficient to construct an invoke_tool call.

Tool Invocation

When a client calls invoke_tool:

  1. The policy rewrites the request as a native tools/call with the wrapped tool name.

  2. All upstream policies see the real tool name (not invoke_tool).

  3. 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/list response on every request.

  • Only tools the caller is authorized to see (per the chain’s access control policy) will match.

Use Cases

Frequently-used tools: Keep high-traffic tools immediately available to reduce search round-trips.

hotTools:
  - "get_weather"
  - "get_user"

Namespace patterns: Expose all tools from a specific namespace.

hotTools:
  - "weather_*"
  - "user_*"

Search Tool Usage

The search_tools meta-tool accepts a JSON object with the following parameters:

Parameter Type Required Description

query

string

Yes

A case-insensitive regular expression to match against tool names and descriptions. Separate alternative keywords with | (spaces match literally).

limit

integer

No

Maximum number of results to return per page. If omitted, uses the configured searchResultLimit.

cursor

string

No

Opaque pagination cursor from a prior search’s nextCursor field. Pass it back to fetch the next page.

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

name

string

Yes

The tool name returned from search_tools

arguments

object

Yes

The tool’s input parameters as returned in the inputSchema from search_tools

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:

  1. A search_tools call triggers a synthesized tools/list request upstream.

  2. The upstream access control policy filters the list per caller.

  3. The policy runs the query against the filtered list.

  4. 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 invoke_tool

-32602

invalid_params

Missing or invalid arguments.name or arguments.arguments

Malformed search_tools

-32602

invalid_params

Empty/missing/non-string query, exceeds 256 characters, invalid regex, bad limit, missing id, malformed cursor, or cursor/query mismatch

Errors produced upstream (access control denials, upstream tool errors) pass through unchanged.