Adding CLI Authentication Support to the AI Endurance MCP Server
The AI Endurance MCP server currently utilizes a browser-based OAuth 2.0 flow for user authentication. This presents a significant limitation: it prevents the server from being accessed and utilized in non-browser environments, such as command-line interfaces (CLIs), automated scripts, or applications running in headless systems like Docker containers. When a CLI tool attempts to connect, the OAuth 2.0 flow requires a browser redirect, rendering the authentication process impossible to complete.
Root Cause: Browser-Dependent OAuth Flow
The core issue stems from the reliance on the Authorization Code Grant flow with PKCE (Proof Key for Code Exchange), which, while secure for browser-based applications, is inherently interactive. This flow requires a user to be redirected to a login page served by the authorization server (e.g., Google, GitHub), authenticate, and then be redirected back to the application with an authorization code. The application then exchanges this code for an access token. This redirect process is fundamentally incompatible with CLI environments where a browser cannot be opened.
Solution: Implementing Device Authorization Grant
A viable solution is to implement the OAuth 2.0 Device Authorization Grant. This grant type is specifically designed for devices that lack a browser or have limited input capabilities. Here's how it works:
- The CLI application makes a request to the authorization server's device authorization endpoint.
- The authorization server responds with:
- A
device_code: A short code that the CLI application will use to poll for authorization. - A
user_code: A longer, more user-friendly code that the user will enter on a separate device (e.g., a smartphone or computer). - A
verification_uri: The URL where the user will enter theuser_code. - An
expires_invalue: The lifetime of thedevice_codein seconds. - An
intervalvalue: The minimum interval (in seconds) that the CLI application should use when polling for authorization.
- A
- The CLI application displays the
user_codeandverification_urito the user. - The user navigates to the
verification_urion a device with a browser and enters theuser_code. This authenticates the user. - The CLI application polls the authorization server's token endpoint using the
device_codeat the specifiedinterval. - Once the user has authenticated, the authorization server returns an access token to the CLI application.
Here's an example of how the CLI application might initiate the device authorization flow:
import requests
import time
# Configuration
CLIENT_ID = "your_client_id"
DEVICE_AUTH_ENDPOINT = "https://your.auth.server/device_authorization"
TOKEN_ENDPOINT = "https://your.auth.server/token"
# 1. Request device and user codes
device_auth_data = {
"client_id": CLIENT_ID,
"scope": "your_scopes"
}
response = requests.post(DEVICE_AUTH_ENDPOINT, data=device_auth_data)
response.raise_for_status() # Raise HTTPError for bad responses (4xx or 5xx)
device_auth_response = response.json()
device_code = device_auth_response["device_code"]
user_code = device_auth_response["user_code"]
verification_uri = device_auth_response["verification_uri"]
expires_in = device_auth_response["expires_in"]
interval = device_auth_response["interval"]
# 2. Display user code and verification URI
print(f"Please visit {verification_uri} and enter the code: {user_code}")
# 3. Poll for the access token
token_data = {
"grant_type": "urn:ietf:params:oauth:grant-type:device_code",
"device_code": device_code,
"client_id": CLIENT_ID
}
start_time = time.time()
while time.time() - start_time < expires_in:
token_response = requests.post(TOKEN_ENDPOINT, data=token_data)
token_response_json = token_response.json()
if token_response.status_code == 200:
access_token = token_response_json["access_token"]
print(f"Successfully obtained access token: {access_token}")
break
elif token_response_json.get("error") == "authorization_pending":
print("Authorization pending...")
time.sleep(interval)
elif token_response_json.get("error") == "slow_down":
interval += 5 # Increase the polling interval
print(f"Slowing down... New interval: {interval} seconds")
time.sleep(interval)
else:
print(f"Error: {token_response_json}")
break
else:
print("Device code expired.")
This Python code snippet demonstrates the basic implementation. Remember to replace placeholder values like your_client_id, https://your.auth.server/device_authorization, https://your.auth.server/token, and your_scopes with the actual values for your authorization server.
Practical Tips and Considerations
- Error Handling: Implement robust error handling to gracefully handle network issues, expired codes, and other potential problems.
- User Experience: Provide clear and concise instructions to the user on how to authenticate. Consider using a QR code to make it easier for users to access the
verification_urion their mobile devices. - Security: Always use HTTPS for all communication with the authorization server. Store access tokens securely.
- Rate Limiting: Be mindful of rate limits imposed by the authorization server. Implement appropriate backoff strategies to avoid being throttled.
- Token Refresh: Implement token refresh mechanisms to obtain new access tokens when the existing ones expire.
By implementing the Device Authorization Grant, the AI Endurance MCP server can extend its reach to CLI environments, enabling a wider range of use cases and integrations.