Skip to content

v2.1.0: FastMCP v3 native OAuth auth (breaking)

Choose a tag to compare

@jztan jztan released this 29 May 14:32

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_ID and REDMINE_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/mcp and /.well-known/oauth-authorization-server/mcp discovery paths remain; the root and /mcp/... prefix aliases now return 404. Follow WWW-Authenticate headers from 401 responses for discovery.
  • Upstream introspection failures now return 401 instead of 503; switch monitoring from 503 spikes to 401-rate or the /health introspection probe.

Changed

  • OAuth mode validates tokens via Doorkeeper RFC 7662 introspection (POST /oauth/introspect) instead of GET /users/current.json, exposing token scopes through claims.

Added

  • /health probes Doorkeeper introspection in OAuth mode and reports status (ok/degraded) with a checks.introspection detail, cached per HEALTH_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 starlette 1.0.0 to 1.0.1 to fix PYSEC-2026-161 (malformed Host header handling).

Acknowledgements

Thanks to @aadnehovda for contributing:

  • narrowed the RFC 8414 AS metadata path from root to /.well-known/oauth-authorization-server/mcp so 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

Links