Context
token-store.ts already has a listMcpTokens prepared statement internally (used by the bulk-revoke paths in markRefreshFailed and deleteTenant), but it is not exported on the public TokenStore interface — by design, deferred to a future operator-facing surface.
What's needed
A small operator tool / endpoint that, given the caller's tenant context (memberId, userId from the Bearer middleware), returns the active Bearers for that user with labels and created_at. Shape sketch:
interface ListedMcpToken {
bearerHashPrefix: string // first 8 hex chars of the sha256 — enough to identify, useless as a credential
label: string | null // operator-supplied "MacBook Claude" etc.
createdAt: number // unix seconds
}
Never return the raw Bearer — that exists only at mint time. Return the hash prefix so the user can match "the one I called 'Laptop'" against what they pasted into Claude/Cursor.
Why deferred
The bulk-revoke paths need the SELECT internally, but exposing it publicly without a UI/CLI to call it would be dead surface. Land it together with the operator tool that uses it.
Acceptance
Spawned from PR #210 round-2 review (Docs agent).
Context
token-store.tsalready has alistMcpTokensprepared statement internally (used by the bulk-revoke paths inmarkRefreshFailedanddeleteTenant), but it is not exported on the publicTokenStoreinterface — by design, deferred to a future operator-facing surface.What's needed
A small operator tool / endpoint that, given the caller's tenant context (
memberId, userIdfrom the Bearer middleware), returns the active Bearers for that user with labels andcreated_at. Shape sketch:Never return the raw Bearer — that exists only at mint time. Return the hash prefix so the user can match "the one I called 'Laptop'" against what they pasted into Claude/Cursor.
Why deferred
The bulk-revoke paths need the SELECT internally, but exposing it publicly without a UI/CLI to call it would be dead surface. Land it together with the operator tool that uses it.
Acceptance
listMcpTokens(memberId, userId)added to the publicTokenStoreinterface./api/oauth/sessions.get.tsendpoint that calls it.listMcpTokensout of "deferred").Spawned from PR #210 round-2 review (Docs agent).