Skip to content

McpServer: let the server set the cache hint of list results (ttlMs is always 0 for 2026-07-28) #9933

Open

Description

@artile

What

For protocol 2026-07-28, McpServer sends the same cache hint on every cacheable result: ttlMs: 0, cacheScope: "private". The value is a constant in packages/effect/src/ai/internal/mcpProtocol/v2026_07_28.ts (privateStaleCache, line 214 on v4/next-minor). It is spread into server/discover, tools/list, resources/list, resources/templates/list, resources/read and prompts/list. There is no option to change it.

So a client must treat each list as stale at once, and it asks again before each use.

Why it matters

  • Since Add request-aware visibility to McpServer #9661, McpServer.visibility can hide tools per request (for example per user). That makes tools/list an effectful check per request. A server with many tools and a per-user filter does this work on every list call, although the answer for one user rarely changes.
  • The reference TypeScript SDK (@modelcontextprotocol/server 2.1.0) lets the server set the hint. Our production MCP endpoint sends ttlMs: 60000, cacheScope: "private" for tools/list. With McpServer we cannot keep that contract.
  • Numbers from our spike (Effect 4.0.0, Bun, 140 tools for an admin, 17 for a restricted role): a per-request filtered tools/list cost 9.6 ms CPU on McpServer against 0.56 ms on the SDK. A client that may cache for 60 s calls it far less often.

Proposal

An option for the cache hint, with today's value as the default, so nothing changes for current users. For example, on the server layer:

McpServer.layerHttp({
  name: "app",
  version: "1.0.0",
  path: "/mcp",
  cacheHints: {
    tools: { ttlMs: 60_000, cacheScope: "private" },
    // resources, resourceTemplates, prompts, discover: default { ttlMs: 0, cacheScope: "private" }
  }
})

Only cacheScope: "private" is needed for our case. "public" is unsafe when visibility depends on the user, so it could stay out, or be allowed only when no visibility is registered.

Related

I can open a PR if the shape is acceptable.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions