You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Foundation for every OAuth flow on the client side. Without a storage abstraction we cannot persist access tokens, refresh tokens, registered client credentials, or PKCE verifiers across requests/sessions.
Scope
Define Mcp\Client\Auth\TokenStorageInterface with operations: getToken(string $resourceUrl): ?TokenSet, storeToken(string $resourceUrl, TokenSet $token): void, clearToken(string $resourceUrl): void, plus equivalents for registered client metadata.
Value object TokenSet (access_token, refresh_token, expires_at, scope, token_type).
Default implementations:
InMemoryTokenStorage (ephemeral, per-process).
Psr16TokenStorage adapter for PSR-16 CacheInterface.
Wire into Client\Builder::setTokenStorage(...) (optional; defaults to in-memory).
Conformance scenarios unblocked
Prerequisite for all auth/* baseline scenarios.
Dependencies
None — must land first.
Acceptance
Interface + value object + 2 storage adapters in src/Client/Auth/.
Specifically, the TokenStorageInterface must key stored credentials by AS issuer URL, not just by MCP server URL — the cache key should be (resource_server, as_issuer). See umbrella #338 and sibling sub-issue #361 (which adds the cross-AS rejection logic on top of this storage layer).
Activity
chr-hertel commentedon May 26, 2026
Cross-reference: this work is required by SEP-2352 for the MCP Spec 2026-07-28 release.
Specifically, the
TokenStorageInterfacemust key stored credentials by AS issuer URL, not just by MCP server URL — the cache key should be(resource_server, as_issuer). See umbrella #338 and sibling sub-issue #361 (which adds the cross-AS rejection logic on top of this storage layer).[Client] Add OAuth authorization to the HTTP transport
[Client] Add OAuth authorization to the HTTP transport