litellm/tests/test_litellm/proxy/_experimental
Tin Chi Lo 8bf3594c4a feat(mcp): graft client_credentials (M2M) to the v2 resolver
First real port body for the graft: HttpxClientCredentialsFetcher (v2_port_bodies.py), an
imperative-shell adapter that runs the RFC 6749 client_credentials grant via litellm's
configured httpx client, mirroring v1's grant for parity (client_id/client_secret/scope in the
body, parse access_token/expires_in, default TTL 3600; the arm's 60s _REFRESH_BUFFER handles
re-mint, matching v1's default buffer). The token response is validated with a pydantic model
rather than poking raw JSON. Error mapping: rejected grant (4xx) -> misconfigured (500, the
gateway's service-account config is wrong), endpoint down / 5xx / network -> upstream_unavailable
(503).

Wired into the bridge composition root (replaces the _Unwired fetcher; service-token store stays
in-memory, matching v1's per-worker caching) and grafted: _to_server_spec now maps v1 M2M
servers (oauth2 + oauth2_flow=client_credentials, i.e. has_client_credentials) to
ClientCredentialsConfig. The body lives on the v1/integration side so the v2 core keeps its
no-v1-imports invariant. The SDK's ClientCredentialsOAuthProvider is deferred to Phase 2 (it is
a connection-session-coupled httpx.Auth, attached when v2 owns the upstream MCP transport).

Tests: fetcher grant shape / token parsing / error mapping (rejected->500, 5xx->503,
network->503, missing access_token->500), the M2M adapter mapping, and an end-to-end graft test
(mocked token endpoint -> Bearer header). 74 tests pass; bridge typechecks clean.
2026-06-18 14:19:54 -07:00
..
mcp_server feat(mcp): graft client_credentials (M2M) to the v2 resolver 2026-06-18 14:19:54 -07:00