Skip to content

Document and lock the tools/list pre-auth posture; consider DISCOVERY_METHODS for JSON-RPC method gating #222

Description

@bokelley

Summary

MCP's streamable-HTTP transport accepts tools/list JSON-RPC calls without authentication — the gate only applies to tools/call. This is consistent with the MCP spec (tool discovery is a handshake concern) and with the AdCP spec (get_adcp_capabilities is pre-auth). But the posture isn't documented; the example and integration test both focus on tools/call gating and leave tools/list implicit.

Security reviewer on PR #219 flagged this:

The example middleware only peeks at method == "tools/call"tools/list skips the auth gate entirely. An unauthenticated attacker hits POST /mcp/ with {\"method\": \"tools/list\"} and gets the full inventory: tool names, input schemas, descriptions, annotations.

Severity: medium. Information disclosure (capability surface, parameter shapes) — not direct compromise, but reconnaissance.

Proposed fix

Two-part, minimum:

  1. Document the posture. Add a section to docs/handler-authoring.md and examples/mcp_with_auth_middleware.py docstring stating explicitly:

    • tools/list is unauthenticated per MCP+AdCP spec (handshake concern).
    • Operators who need tool-list auth should gate method in {\"tools/list\", \"tools/call\"} and only skip when name in DISCOVERY_TOOLS.
    • Tool names, schemas, and descriptions are considered non-sensitive by default; operators who embed deployment hints in descriptions should review.
  2. Ship DISCOVERY_METHODS companion frozenset. Parallel to DISCOVERY_TOOLS, expose the JSON-RPC method names that are pre-auth by spec. Initial set: {\"initialize\", \"tools/list\"}. Downstream middleware then composes method in DISCOVERY_METHODS or (method == \"tools/call\" and tool_name in DISCOVERY_TOOLS) for their auth gate.

  3. Update the example to use the composed gate, so copy-paste adopters get the stricter posture by default.

After (dependent on #220)

Once the advertised-tools gate (#220) ships, tools/list only returns the tools the handler overrode, which shrinks the reconnaissance surface significantly. Revisit the default posture then.

Context

Tracked from PR #219 expert security review.

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions