Skip to content

feat: LLM-Friendly Responses for AI Agent Requests #106334

@dcramer

Description

@dcramer

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 type
  • text/x-markdown - Alternative markdown MIME type
  • text/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

  1. Check if request has text/markdown, text/x-markdown, or text/plain in Accept header
  2. Check if request is unauthenticated (no Authorization header, no valid session)
  3. If both conditions met, return markdown response with MCP guidance
  4. 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

  1. src/sentry/utils/ai_agent.py - Accept header detection utility
  2. src/sentry/middleware/ai_agent.py - Request interception middleware

Modified Files

  1. 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

  1. Should we also detect via User-Agent as a fallback? (e.g., Claude-Code, Cursor)
  2. Should the response include JSON as well as markdown for structured parsing?

References

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions