feat: scope query param auth to MCP endpoints

Restrict api_key query parameter to /mcp/tools, /mcp/tool/call,
and /mcp/sse only. Updated documentation to reflect query param
usage for ChatGPT UI without header support.
This commit is contained in:
2026-01-29 21:07:37 +01:00
parent b990c6c527
commit 0a2a21cc52
3 changed files with 21 additions and 34 deletions

View File

@@ -77,9 +77,12 @@ API key authentication ENABLED (1 key(s) configured)
# Without key - should fail with 401
curl https://mcp.yourdomain.com/mcp/tools
# With valid key - should succeed
# With valid key (header) - should succeed
curl -H "Authorization: Bearer YOUR_KEY_HERE" \
https://mcp.yourdomain.com/mcp/tools
# With valid key (query param) - should succeed
curl "https://mcp.yourdomain.com/mcp/tools?api_key=YOUR_KEY_HERE"
```
---

View File

@@ -29,8 +29,7 @@ aegis-gitea-mcp Up 0.0.0.0:8080->8080/tcp
```bash
# Replace YOUR_API_KEY with your actual key
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://mcp.yourdomain.com/mcp/tools
curl "https://mcp.yourdomain.com/mcp/tools?api_key=YOUR_API_KEY"
# Expected: JSON response with available tools
# If error: Check AUTH_SETUP.md troubleshooting
@@ -50,22 +49,12 @@ curl -H "Authorization: Bearer YOUR_API_KEY" \
3. **Enter Server Details**
```
Name: AegisGitea MCP
URL: https://mcp.yourdomain.com
URL: https://mcp.yourdomain.com?api_key=YOUR_API_KEY_HERE
Type: HTTP/SSE (Server-Sent Events)
Auth: None (or Mixed, leave OAuth fields empty)
```
4. **Add Custom Header**
```
Header Name: Authorization
Header Value: Bearer YOUR_API_KEY_HERE
```
**Important:**
- Include the word "Bearer" followed by a space
- Then paste your full 64-character API key
- No quotes around the key
5. **Save Configuration**
4. **Save Configuration**
### Step 4: Test Connection
@@ -168,18 +157,18 @@ curl https://mcp.yourdomain.com/health
### Issue: "Authentication failed"
**Check 1: Authorization header format**
**Check 1: MCP Server URL format**
Correct:
```
Authorization: Bearer a1b2c3d4e5f6g7h8...
https://mcp.yourdomain.com?api_key=YOUR_KEY
```
Wrong:
```
Authorization: a1b2c3d4... (missing "Bearer ")
Authorization: "Bearer a1b2c3d4..." (extra quotes)
Authorization:Bearer a1b2c3d4... (missing space after colon)
https://mcp.yourdomain.com (missing api_key)
https://mcp.yourdomain.com?api_key= (empty key)
https://mcp.yourdomain.com?api_key=short (too short)
```
**Check 2: Key matches .env**
@@ -197,7 +186,7 @@ docker-compose logs aegis-mcp | tail -50
Look for:
- `invalid_api_key` → Key doesn't match
- `missing_api_key` → Header not sent
- `missing_api_key` → api_key not provided
- `invalid_key_format` → Key too short
### Issue: "No repositories visible"
@@ -211,8 +200,7 @@ Look for:
**Test manually:**
```bash
curl -H "Authorization: Bearer YOUR_KEY" \
https://mcp.yourdomain.com/mcp/tool/call \
curl "https://mcp.yourdomain.com/mcp/tool/call?api_key=YOUR_KEY" \
-X POST \
-H "Content-Type: application/json" \
-d '{"tool": "list_repositories", "arguments": {}}'
@@ -241,8 +229,7 @@ Too many failed authentication attempts
**Verify tools are registered:**
```bash
curl -H "Authorization: Bearer YOUR_KEY" \
https://mcp.yourdomain.com/mcp/tools
curl "https://mcp.yourdomain.com/mcp/tools?api_key=YOUR_KEY"
```
Should return JSON with tools array.
@@ -320,8 +307,7 @@ You can call tools directly via API:
```bash
# List repositories
curl -X POST https://mcp.yourdomain.com/mcp/tool/call \
-H "Authorization: Bearer YOUR_KEY" \
curl -X POST "https://mcp.yourdomain.com/mcp/tool/call?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"tool": "list_repositories",
@@ -329,8 +315,7 @@ curl -X POST https://mcp.yourdomain.com/mcp/tool/call \
}'
# Get file contents
curl -X POST https://mcp.yourdomain.com/mcp/tool/call \
-H "Authorization: Bearer YOUR_KEY" \
curl -X POST "https://mcp.yourdomain.com/mcp/tool/call?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"tool": "get_file_contents",
@@ -350,8 +335,7 @@ For automated workflows, you can integrate MCP tools into CI/CD:
# Example GitHub Actions (future enhancement)
- name: Sync to Gitea via MCP
run: |
curl -X POST https://mcp.yourdomain.com/mcp/tool/call \
-H "Authorization: Bearer ${{ secrets.MCP_API_KEY }}" \
curl -X POST "https://mcp.yourdomain.com/mcp/tool/call?api_key=${{ secrets.MCP_API_KEY }}" \
-H "Content-Type: application/json" \
-d '{...}'
```

View File

@@ -74,8 +74,8 @@ async def authenticate_request(request: Request, call_next):
auth_header = request.headers.get("authorization")
api_key = auth_validator.extract_bearer_token(auth_header)
# Fallback: allow API key via query parameter (for ChatGPT UI without headers)
if not api_key:
# Fallback: allow API key via query parameter only for MCP endpoints
if not api_key and request.url.path in {"/mcp/tools", "/mcp/tool/call", "/mcp/sse"}:
api_key = request.query_params.get("api_key")
# Validate API key