Redmine MCP Server
by daxonet
README.md
# Redmine MCP 1.2.0 — native OAuth, clean reconnect
Requires Redmine 7.0+. MCP tools always enforce the signed-in user's Redmine project, issue, workflow and write permissions. An OAuth scope never grants additional business rights.
Applications are managed in **Administration → Applications**. Open an MCP application to inspect authorizations and revoke access for one user; deleting an application revokes every grant. Users can revoke their own grants in **My account → Authorized applications**. There is no separate MCP authorization menu.
Enable Redmine REST API for native OAuth. Configure **Administration → Plugins → Redmine MCP → Configure** with exact trusted callback URLs. An empty allowlist disables dynamic registration. Public MCP clients request `mcp_tools` and must use S256 PKCE. Manually registered Applications must include that scope. Discovery points to `/oauth/authorize`, `/oauth/token`, `/oauth/revoke`; MCP dynamic registration remains `/mcp/oauth/register`. Only MCP-scoped applications receive the PKCE/one-hour access/30-day rolling refresh policies. Other OAuth apps retain Redmine defaults.
## Upgrade from 1.0.x
1. Stop the application and take a complete database + application/files backup.
2. Upgrade Redmine core and migrate it first; deploy this plugin and run `bundle exec rake redmine:plugins:migrate NAME=redmine_mcp RAILS_ENV=production`.
3. Version 1.2.0 deliberately clears historical MCP applications, grants and tokens after the 1.1.0 migration step. Existing MCP connections become invalid; users must remove/reconnect the server in their MCP client and authorize again. This is a one-time migration, including for installations already on 1.1.0. Unrelated native OAuth applications and the separate Azure AD login-provider configuration are preserved.
4. Verify that old client IDs/tokens are rejected and historical duplicates are absent; reconnect a client and check discovery, fresh S256 authorization, MCP permissions, token refresh and per-user revocation before reopening traffic.
Existing `/mcp/oauth/authorize` and `/mcp/oauth/token` URLs remain compatibility routes to the native server; the old `mcp:tools` authorization scope is normalized to `mcp_tools` at the compatibility authorization URL. Already-open old consent pages need a new authorization attempt. Legacy client metadata remains for audit only; legacy token and authorization-code rows are deleted. Runtime never accepts legacy credentials, and rerunning the historical importer is forbidden. Keep pre-upgrade backups restricted since they contain legacy plaintext credentials.
Rollback restores the pre-upgrade database and matching old application together. The migration deliberately has no lossy down conversion from hashed native secrets. Do not run the old plugin against the migrated database.
## Dynamic registration
Identical public-client name, canonical callback URL set and MCP scope reuse one native Application, backed by a unique database registration key. URI ordering/duplicates and the old `mcp:tools` scope do not create duplicates. Each user has separate grants and tokens; reconnecting another user does not revoke existing grants. Different metadata creates a separate application. An administrator-edited client is not reused for mismatching metadata. Do not merge by display name alone.
## Tests
Run `RAILS_ENV=test bundle exec rake redmine:plugins:test NAME=redmine_mcp` against a dedicated test database. Standalone checks run separately: `ruby test/standalone/tool_authorization_check.rb` and `ruby test/standalone/tool_serialization_check.rb`. CI covers Redmine 7 with MySQL, PostgreSQL and SQLite. Native OAuth integration tests cover migration, PKCE, token rotation, expiry, user lock, scopes, revocation and compatibility URLs.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues