diff --git a/src/mcp/client/auth/extensions/client_credentials.py b/src/mcp/client/auth/extensions/client_credentials.py index cb6dafb40..c59c4626b 100644 --- a/src/mcp/client/auth/extensions/client_credentials.py +++ b/src/mcp/client/auth/extensions/client_credentials.py @@ -90,6 +90,7 @@ async def _exchange_token_client_credentials(self) -> httpx.Request: """Build token exchange request for client_credentials grant.""" token_data: dict[str, Any] = { "grant_type": "client_credentials", + "client_id": self._fixed_client_info.client_id, } headers: dict[str, str] = {"Content-Type": "application/x-www-form-urlencoded"} diff --git a/tests/client/auth/extensions/test_client_credentials.py b/tests/client/auth/extensions/test_client_credentials.py index 0003b1679..dfa68faff 100644 --- a/tests/client/auth/extensions/test_client_credentials.py +++ b/tests/client/auth/extensions/test_client_credentials.py @@ -249,6 +249,7 @@ async def test_exchange_token_client_credentials(self, mock_storage: MockTokenSt content = urllib.parse.unquote_plus(request.content.decode()) assert "grant_type=client_credentials" in content + assert "client_id=test-client-id" in content assert "scope=read write" in content assert "resource=https://api.example.com/v1/mcp" in content @@ -272,6 +273,7 @@ async def test_exchange_token_without_scopes(self, mock_storage: MockTokenStorag content = urllib.parse.unquote_plus(request.content.decode()) assert "grant_type=client_credentials" in content + assert "client_id=test-client-id" in content assert "scope=" not in content assert "resource=" not in content