# MCP Server Authentication Guide
## Authentication Methods
### 1. Environment Variable Authentication (Simple)
**Setup:**
```bash
export CALCULATOR_API_KEY="your-secret-key-here"
export CALCULATOR_REQUIRE_AUTH="true"
```
**MCP Configuration (.kiro/settings/mcp.json):**
```json
{
"mcpServers": {
"calculator-auth": {
"command": "python",
"args": ["/Users/anshikagupta/calculator/calculator_mcp_server_auth.py"],
"env": {
"CALCULATOR_API_KEY": "my-secret-key-123",
"CALCULATOR_REQUIRE_AUTH": "true"
},
"disabled": false
}
}
}
```
**Usage:**
When calling tools, include the auth_token parameter:
```json
{
"a": 5,
"b": 3,
"auth_token": "my-secret-key-123"
}
```
---
### 2. JWT Token Authentication (Secure)
**Setup:**
```bash
# Install PyJWT
pip install PyJWT
# Set JWT secret
export JWT_SECRET="your-super-secret-jwt-key"
```
**MCP Configuration:**
```json
{
"mcpServers": {
"calculator-jwt": {
"command": "python",
"args": ["/Users/anshikagupta/calculator/calculator_mcp_jwt.py"],
"env": {
"JWT_SECRET": "your-super-secret-jwt-key"
},
"disabled": false
}
}
}
```
**Usage:**
1. First, generate a token:
```json
{
"user_id": "anshika"
}
```
2. Use the token in subsequent calls:
```json
{
"a": 5,
"b": 3,
"jwt_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```
---
### 3. OAuth2 / API Key Headers (Advanced)
For production systems, you might want to use:
**HTTP-based MCP Server with OAuth2:**
```python
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
async def verify_token(token: str = Depends(oauth2_scheme)):
# Verify with your OAuth provider
if not is_valid_token(token):
raise HTTPException(status_code=401, detail="Invalid token")
return token
```
---
## Security Best Practices
### 1. Never Hardcode Secrets
❌ Bad:
```python
API_KEY = "my-secret-key"
```
✅ Good:
```python
API_KEY = os.getenv("CALCULATOR_API_KEY")
```
### 2. Use Environment Variables
Store secrets in:
- `.env` files (add to .gitignore)
- System environment variables
- Secret management services (AWS Secrets Manager, HashiCorp Vault)
### 3. Token Expiration
Always set expiration times for tokens:
```python
"exp": datetime.now() + timedelta(hours=24)
```
### 4. HTTPS Only
For network-based MCP servers, always use HTTPS.
### 5. Rate Limiting
Implement rate limiting to prevent abuse:
```python
from slowapi import Limiter
limiter = Limiter(key_func=get_remote_address)
@limiter.limit("10/minute")
async def call_tool():
pass
```
---
## Testing Authentication
### Test Environment Variable Auth:
```bash
# Set the key
export CALCULATOR_API_KEY="test-key-123"
# Run the server
python calculator_mcp_server_auth.py
# Test with correct key (should work)
# Test without key (should fail)
```
### Test JWT Auth:
```bash
# Set JWT secret
export JWT_SECRET="my-jwt-secret"
# Run the server
python calculator_mcp_jwt.py
# Generate a test token first
# Then use it for calculations
```
---
## Common Authentication Patterns
### 1. API Key in Header
```python
def verify_api_key(api_key: str = Header(None)):
if api_key != VALID_API_KEY:
raise HTTPException(401, "Invalid API Key")
```
### 2. Bearer Token
```python
def verify_bearer_token(authorization: str = Header(None)):
if not authorization or not authorization.startswith("Bearer "):
raise HTTPException(401, "Missing token")
token = authorization.split(" ")[1]
return verify_token(token)
```
### 3. Basic Auth
```python
from fastapi.security import HTTPBasic, HTTPBasicCredentials
security = HTTPBasic()
def verify_credentials(credentials: HTTPBasicCredentials = Depends(security)):
if credentials.username != "admin" or credentials.password != "secret":
raise HTTPException(401, "Invalid credentials")
```
---
## Troubleshooting
### "Authentication failed"
- Check if API key is set correctly
- Verify environment variables are loaded
- Check for typos in the key
### "Invalid or expired JWT token"
- Token might have expired (check exp claim)
- JWT secret might be different
- Token format might be incorrect
### "Permission denied"
- Check if user has required permissions
- Verify permissions array in JWT payload
---
## Production Recommendations
1. **Use JWT** for stateless authentication
2. **Implement refresh tokens** for long-lived sessions
3. **Add rate limiting** to prevent abuse
4. **Log authentication attempts** for security monitoring
5. **Use HTTPS** for all network communication
6. **Rotate secrets regularly**
7. **Implement role-based access control (RBAC)**