Skip to content

fix(mcp): pin the tools/list cache hint to private - #533

Open
keysersoft wants to merge 1 commit into
mainfrom
keysersoft/mcp-tools-list-cache-scope
Open

fix(mcp): pin the tools/list cache hint to private#533
keysersoft wants to merge 1 commit into
mainfrom
keysersoft/mcp-tools-list-cache-scope

Conversation

@keysersoft

Copy link
Copy Markdown
Contributor

Follow-up to #532, which made tools/list on the global /mcp endpoint filter by the caller's organization and MCP roles.

A per-caller list must never be cached and reused for a different principal. server/discover advertises a cacheScope for tools/list, and a public value invites a client or proxy to do exactly that — serving one tenant's tool inventory to another and silently undoing the scoping.

private is already the default, so this changes no behaviour. It is pinned because the consequence of changing it is invisible from the code that depends on it: nothing in McpEndpointController would fail and no test would break — the leak would simply reappear at whichever cache sits in front.

mcp-nest does warn when the hint is public while the list varies by caller, but that warning fires once at startup and only helps if someone reads the logs.

Verified

cacheScope: private | ttlMs: 0

tools/list still returns the caller's own tools only. 3853 tests pass.

Also checked while looking for the same class of problem

  • resources/list, prompts/list, resources/templates/listMethod not found. The server declares neither capability and registers no dynamic resources or prompts, so there is nothing to scope.
  • server/discover returns capabilities, versions and cache metadata only — no tool list.
  • No HTTP Cache-Control is set on MCP responses; Vary: Origin only.

`tools/list` is now filtered per caller — by organization and by MCP role — so
its result must never be cached and reused for a different principal. A
'public' hint invites a client or proxy to do exactly that, which would serve
one tenant's tool inventory to another and silently undo the scoping the
previous commit added.

'private' is already the default, so this changes no behaviour. It is pinned
because the consequence of changing it is invisible from the call site that
depends on it: nothing in McpEndpointController would fail, and no test would
break — the leak would simply reappear at whichever cache sits in front.

mcp-nest does warn when the hint is 'public' while the list varies by caller,
but that warning only fires at startup and only if someone reads the logs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant