mirror of
https://github.com/tiennm99/litellm.git
synced 2026-06-18 03:31:23 +00:00
19024e0602
* add has_client_credentials * MCPOAuth2TokenCache * init MCP Oauth2 constants * MCPOAuth2TokenCache * resolve_mcp_auth * test fixes * docs fix * address greptile review: min TTL, env-configurable constants, tests, docs - Fix zero-TTL edge case: floor at MCP_OAUTH2_TOKEN_CACHE_MIN_TTL (10s) - Make all MCP OAuth2 constants env-configurable via os.getenv() - Move test file to follow 1:1 mapping convention (test_oauth2_token_cache.py) - Add MCP OAuth doc page (mcp_oauth.md) with M2M and PKCE sections - Update FAQ in mcp.md to reflect M2M support - Add E2E test script and config Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix mypy lint * fix oauth2 * remove old files * docs fix * address greptile comments * fix: atomic lock creation + validate JSON response shape - Use dict.setdefault() for atomic per-server lock creation - Add isinstance(body, dict) check before accessing token response fields Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: replace asserts with proper guards, wrap HTTP errors with context - Replace `assert` statements with `if/raise ValueError` (asserts can be disabled with python -O in production) - Wrap `httpx.HTTPStatusError` to provide a clear error message with server_id and status code - Add tests for HTTP error and non-dict JSON response error paths - Remove unused imports Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
67 lines
2.3 KiB
Python
67 lines
2.3 KiB
Python
"""
|
|
Simple test to validate MCP auth header priority behavior.
|
|
|
|
Validates that:
|
|
1. auth_value is not required in config.yaml
|
|
2. Server-specific headers (x-mcp-server-name-authorization) take precedence over config auth_value
|
|
"""
|
|
|
|
import pytest
|
|
from litellm.proxy._experimental.mcp_server.mcp_server_manager import MCPServerManager
|
|
from litellm.types.mcp import MCPAuth, MCPTransport, MCPSpecVersion
|
|
from litellm.types.mcp_server.mcp_server_manager import MCPServer
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_mcp_server_works_without_config_auth_value():
|
|
"""
|
|
Test that MCP servers work without auth_value in config when headers are provided.
|
|
This validates that auth_value is truly optional in config.yaml.
|
|
"""
|
|
# Create a server WITHOUT config auth_value
|
|
server_without_config_auth = MCPServer(
|
|
server_id="test-server-no-config",
|
|
name="Test MCP Server No Config Auth",
|
|
server_name="test_server_no_config",
|
|
alias="test_no_config",
|
|
url="https://api.example.com/mcp",
|
|
transport=MCPTransport.http,
|
|
auth_type=MCPAuth.authorization,
|
|
authentication_token=None, # No config auth
|
|
)
|
|
|
|
manager = MCPServerManager()
|
|
|
|
# Test that it works with only header auth
|
|
client = await manager._create_mcp_client(
|
|
server=server_without_config_auth,
|
|
mcp_auth_header="Bearer token_from_header_only",
|
|
)
|
|
|
|
# Verify header token is used
|
|
assert client._mcp_auth_value == "Bearer token_from_header_only"
|
|
assert client.auth_type == MCPAuth.authorization
|
|
|
|
|
|
@pytest.mark.parametrize("token_key", ["authentication_token", "auth_value"])
|
|
async def test_mcp_server_config_auth_value_header_used(token_key):
|
|
"""Ensure auth header is sent when auth token configured in config"""
|
|
config = {
|
|
"test_server": {
|
|
"url": "https://api.example.com/mcp",
|
|
"transport": "http",
|
|
"auth_type": "bearer_token",
|
|
token_key: "example_token",
|
|
}
|
|
}
|
|
|
|
manager = MCPServerManager()
|
|
await manager.load_servers_from_config(config)
|
|
|
|
server = next(iter(manager.config_mcp_servers.values()))
|
|
client = await manager._create_mcp_client(server)
|
|
headers = client._get_auth_headers()
|
|
|
|
assert headers["Authorization"] == "Bearer example_token"
|
|
assert client.auth_type == MCPAuth.bearer_token
|