-
-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Description
Problem
AI coding assistants (Claude Code, Cursor, Copilot, etc.) may make unauthenticated requests to Sentry endpoints. Currently, they receive standard 401/403 errors or login redirects that aren't optimized for LLM consumption.
We want to intercept these requests and return LLM-friendly guidance directing them to the Sentry MCP server.
Proposed Solution
Add middleware that detects AI agent requests via Accept header content negotiation and returns markdown responses with MCP setup guidance.
Detection Strategy: Accept Header
Use the emerging standard of AI agents requesting text/markdown or text/plain content types:
Accept headers to detect:
text/markdown- Standard markdown MIME typetext/x-markdown- Alternative markdown MIME typetext/plain- Plain text (commonly used by LLMs)
Why Accept header over User-Agent:
- Standards-based content negotiation
- Future-proof as AI tools adopt this convention
- Google Gemini CLI, Bun, and others are adopting this pattern
- Cleaner signal than parsing User-Agent strings
Interception Logic
- Check if request has
text/markdown,text/x-markdown, ortext/plainin Accept header - Check if request is unauthenticated (no Authorization header, no valid session)
- If both conditions met, return markdown response with MCP guidance
- Otherwise, pass through to normal request handling
Response Content
Return markdown that LLMs can easily parse:
# Sentry API Access
This endpoint requires authentication. For AI assistants, we recommend using the **Sentry MCP Server**.
## MCP Server Setup
Add the Sentry MCP server to your AI assistant's configuration:
- **Server name**: `sentry`
- **Documentation**: https://docs.sentry.io/api/mcp/
## Alternative: API Authentication
If you need direct API access, create an auth token:
1. Go to https://sentry.io/settings/account/api/auth-tokens/
2. Create a token with appropriate scopes
3. Include `Authorization: Bearer <token>` header
---
*Requested path: /api/0/organizations/*Implementation Details
New Files
src/sentry/utils/ai_agent.py- Accept header detection utilitysrc/sentry/middleware/ai_agent.py- Request interception middleware
Modified Files
src/sentry/conf/server.py- Register middleware (after auth middleware)
Middleware Placement
Must run AFTER AuthenticationMiddleware to check authentication status:
MIDDLEWARE = (
# ... earlier middleware ...
"sentry.middleware.auth.AuthenticationMiddleware",
"sentry.middleware.ai_agent.AIAgentMiddleware", # After auth
# ... rest of middleware
)Behavior Matrix
| Accept Header | Authenticated | Result |
|---|---|---|
text/markdown |
No | → Markdown MCP response |
text/x-markdown |
No | → Markdown MCP response |
text/plain |
No | → Markdown MCP response |
text/markdown |
Yes | → Normal request handling |
application/json |
No | → Normal 401 response |
text/html |
No | → Normal login redirect |
Edge Cases
- Authenticated requests: Always pass through, even with markdown Accept
- Authorization header present: Treated as "authenticated attempt", passes through
- Session auth: Users with valid sessions pass through
- Mixed Accept headers: Check if any markdown/plain type is present
Status Code
Recommendation: 200 OK
This is proper HTTP content negotiation - the client requested markdown content, we're successfully returning markdown content. The response body contains useful guidance, not an error.
Alternative considered: 401 would imply "retry with auth", but we're intentionally directing them to MCP instead.
Metrics
Track these interceptions for analytics:
from sentry import metrics
metrics.incr(
"middleware.ai_agent.intercepted",
tags={
"accept_type": "text/markdown", # or text/plain, text/x-markdown
"path_prefix": request.path.split("/")[1], # api, organizations, etc.
},
)This helps us understand:
- Volume of AI agent requests hitting unauthenticated endpoints
- Which Accept headers are most common
- Which endpoints agents are trying to access
Open Questions
- Should we also detect via User-Agent as a fallback? (e.g.,
Claude-Code,Cursor) - Should the response include JSON as well as markdown for structured parsing?