feat: add MCP server endpoint with OAuth 2.0 authentication#1014
Open
feat: add MCP server endpoint with OAuth 2.0 authentication#1014
Conversation
Expose a remote MCP (Model Context Protocol) server at /mcp/ that MCP clients like Claude Code can connect to. Authentication uses OAuth 2.1 with PKCE via django-oauth-toolkit, with browser-based login through the existing allauth flow (GitHub/GitLab/email). New components: - mcp_server app: FastMCP server with submit_job, get_job_status, and list_repositories tools - OAuth2 middleware: Bearer token validation for MCP requests - OAuth metadata discovery: /.well-known/oauth-authorization-server - Dynamic client registration: POST /oauth/register/ (RFC 7591) - ASGI routing: /mcp/* dispatched to MCP server, rest to Django https://claude.ai/code/session_017YfDWNCnbPsdbVJZ9t4XV4
- Add proper type annotations to ASGI app and auth middleware - Add OAuth token scope validation and DB error handling - Fix broken test_server.py tests (.fn attribute doesn't exist) - Add transaction=True to async DB tests in test_auth.py - Make list_repositories async to avoid blocking the event loop - Remove redundant RepoClient.create_instance() in NotImplementedError handler - Remove unused conf.py (ENABLED flag was never checked) - Validate redirect_uris entries are strings in client registration - Add lifespan startup/shutdown error logging in ASGI app - Add MCP endpoint documentation and Nginx rate limiting guide - Add custom OAuth authorize page matching DAIV design system
…fy ASGI - Move oauth_register_client to Django Ninja router with Pydantic schemas, AnonRateThrottle (5/m), and automatic validation - Use django.urls.reverse() in oauth_metadata instead of hardcoded paths - Simplify ASGI app by delegating lifespan to MCP Starlette app - Fix scope validation to use allow_scopes() instead of substring check - Nest NotImplementedError retry inside outer except Exception block - Add logging around Application.objects.create in registration - Remove redundant Nginx rate limiting docs (app-level throttle suffices)
Add optional `wait` parameter to both MCP tools that polls until the job completes (up to 10 minutes), returning the full result inline. Eliminates the need for clients to manually poll get_job_status. Also fixes duplicate CHANGELOG sections, stale Django docs URL, incorrect OAuth registration path in docs, and adds tests for previously uncovered error branches (DB exceptions during polling, timeout with job never found).
Restructure around quick-start setup for Claude Code, Cursor, and Codex CLI. Remove internal OAuth details, security considerations, and rate limiting sections. Add usage examples with natural-language prompts.
Claude Code SDK expects client_secret to be absent (not null) for public clients. Use a model_serializer to strip None fields from the registration response JSON.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Expose a remote MCP (Model Context Protocol) server at /mcp/ that MCP
clients like Claude Code can connect to. Authentication uses OAuth 2.1
with PKCE via django-oauth-toolkit, with browser-based login through
the existing allauth flow (GitHub/GitLab/email).
New components:
list_repositories tools