v2.1.0: FastMCP v3 native OAuth auth (breaking)
Highlights
OAuth mode now uses FastMCP v3 native authentication. Token validation moves from GET /users/current.json to Doorkeeper's RFC 7662 introspection endpoint (POST /oauth/introspect), which exposes a token's real scopes and closes a middleware-skip-list auth-bypass risk.
This is a breaking upgrade for OAuth deployments. You must set two new env vars, REDMINE_INTROSPECT_CLIENT_ID and REDMINE_INTROSPECT_CLIENT_SECRET, register a confidential OAuth client in Redmine, and enable Doorkeeper token introspection; the server fails fast at startup if either is missing. Only the canonical /.well-known/.../mcp discovery paths remain (the root and prefix aliases now 404), and upstream introspection failures now return 401 instead of 503.
/health gains an OAuth-mode introspection probe (HTTP 200 with a JSON status field, cached 30s), and a starlette bump fixes a malformed Host header advisory. See the OAuth setup guide, Step 2, for the walkthrough.
Changes
Breaking
- OAuth mode requires two new env vars,
REDMINE_INTROSPECT_CLIENT_IDandREDMINE_INTROSPECT_CLIENT_SECRET; register a confidential OAuth client and enable Doorkeeper introspection. The server fails fast at startup if either is missing. - Only the canonical
/.well-known/oauth-protected-resource/mcpand/.well-known/oauth-authorization-server/mcpdiscovery paths remain; the root and/mcp/...prefix aliases now return 404. FollowWWW-Authenticateheaders from 401 responses for discovery. - Upstream introspection failures now return 401 instead of 503; switch monitoring from 503 spikes to 401-rate or the
/healthintrospection probe.
Changed
- OAuth mode validates tokens via Doorkeeper RFC 7662 introspection (
POST /oauth/introspect) instead ofGET /users/current.json, exposing token scopes through claims.
Added
/healthprobes Doorkeeper introspection in OAuth mode and reportsstatus(ok/degraded) with achecks.introspectiondetail, cached perHEALTH_INTROSPECTION_TTL_SECONDS(default 30s).- Structured warning logs on introspection upstream failures so alerting can separate real outages from per-token 401s.
- Live OAuth integration test suite exercising real Doorkeeper introspection against a sandbox Redmine (runs under
--integration).
Security
- Bump
starlette1.0.0 to 1.0.1 to fix PYSEC-2026-161 (malformedHostheader handling).
Acknowledgements
Thanks to @aadnehovda for contributing:
- narrowed the RFC 8414 AS metadata path from root to
/.well-known/oauth-authorization-server/mcpso the MCP server no longer claims the root discovery slot when co-hosted with another app (#135).
Installation
pip install redmine-mcp-server==2.1.0