Skip to main content
Glama
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.