Skip to content

Schema cache: bare-key fingerprint is last-writer-wins under per-credential tool sets #61

Description

@rodaddy

Problem (MINOR — found during PR #59 review)

The #58 client-cache coherence stamps the bare-service schema fingerprint (readCacheFingerprint(body.service)) onto /list-tools and /schema responses. The bare entry is maintained by the drift-hook (checkDriftOnConnect(baseServiceName, …)), which writes it over unfiltered listAllTools for whichever credential connection triggered the connect.

If an upstream server returns genuinely different tool SETS per credential (e.g. an admin token sees tools a readonly token doesn't — not just different data), the bare-key fingerprint flip-flops by last writer. A client served credential B's schema can receive a fingerprint derived from credential A's set → a spurious one-shot clear of its warm cache, then re-warm.

Severity: MINOR

  • Self-heals, no loop: a normal mcp2cli <svc> <tool> call doesn't repopulate the bare client cache, so it doesn't re-clear indefinitely.
  • Not a data leak: no schema content crosses identities; each refetch re-pulls the caller's own credential-scoped schema from the daemon.
  • Mitigated in practice: /list-tools and /schema apply no RBAC filtering (only /call does), so per-identity filtering doesn't cause divergence. Divergence requires the upstream to actually expose different tool catalogs per credential, which is uncommon (most servers vary data, not the tool list).

Fix direction (deferred)

A full fix keys the coherence stamp per-credential, which reopens the B1 keyspace-alignment problem (client would need to know its active pool key). Options:

  • Have the client derive its own pool key for the active identity and read/compare that key, with the daemon stamping the matching key.
  • Or skip the bare-key reconcile for services known to vary tool sets per credential.

Out of scope for PR #59 (which fixes the common case correctly). Tracking here.

Related

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions