Skip to content

fix(web): always request offline_access for MCP refresh_token grant#1292

Open
fatmcgav wants to merge 3 commits into
sourcebot-dev:mainfrom
fatmcgav:fix-atlassian-mcp-scopes
Open

fix(web): always request offline_access for MCP refresh_token grant#1292
fatmcgav wants to merge 3 commits into
sourcebot-dev:mainfrom
fatmcgav:fix-atlassian-mcp-scopes

Conversation

@fatmcgav

@fatmcgav fatmcgav commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Atlassian (and other providers) only honour the refresh_token grant when
offline_access is included in the authorization scope. The client was
already declaring refresh_token in clientMetadata.grant_types but never
injecting offline_access into requestedOAuthScopes, so the /authorize
request was incomplete and Atlassian rejected it.

  • PrismaOAuthClientProvider now appends OFFLINE_ACCESS_SCOPE before
    normalization so it appears in both clientMetadata.scope and the
    /authorize request. Injection is unconditional (matching the existing
    behaviour of always declaring refresh_token); a comment explains the
    tradeoff vs checking oauthScopesSupported.
  • buildMcpOAuthScopeEntries defaults offline_access to enabled when
    present in available scopes so the admin UI reflects what will be sent.
  • New oauthScopeUtils.test.ts covers the default-enabled behaviour and
    general normalization/filtering helpers.
  • Updated prismaOAuthClientProvider.test.ts to assert offline_access is
    always present and that it is not duplicated when already supplied.
  • Added a note to the connectors doc explaining why offline_access is
    pre-ticked in the OAuth scopes UI.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Summary by CodeRabbit

  • Bug Fixes

    • OAuth connectors (e.g., Atlassian) now always include the offline_access scope in authorization requests, preventing connector rejections and enabling token refresh.
  • Documentation

    • Clarified OAuth Scopes docs to state offline_access is enabled by default when offered by a connector, even if not explicitly selected by an admin.
  • Tests

    • Added and updated tests to verify offline_access is included and handled correctly across connector flows.

fatmcgav and others added 2 commits June 9, 2026 14:02
Atlassian (and other providers) only honour the `refresh_token` grant when
`offline_access` is included in the authorization scope. The client was
already declaring `refresh_token` in `clientMetadata.grant_types` but never
injecting `offline_access` into `requestedOAuthScopes`, so the /authorize
request was incomplete and Atlassian rejected it.

- `PrismaOAuthClientProvider` now appends `OFFLINE_ACCESS_SCOPE` before
  normalization so it appears in both `clientMetadata.scope` and the
  /authorize request. Injection is unconditional (matching the existing
  behaviour of always declaring `refresh_token`); a comment explains the
  tradeoff vs checking `oauthScopesSupported`.
- `buildMcpOAuthScopeEntries` defaults `offline_access` to enabled when
  present in available scopes so the admin UI reflects what will be sent.
- New `oauthScopeUtils.test.ts` covers the default-enabled behaviour and
  general normalization/filtering helpers.
- Updated `prismaOAuthClientProvider.test.ts` to assert `offline_access` is
  always present and that it is not duplicated when already supplied.
- Added a note to the connectors doc explaining why `offline_access` is
  pre-ticked in the OAuth scopes UI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ot-dev#1292]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 233565a9-994f-42df-95d5-79514097449e

📥 Commits

Reviewing files that changed from the base of the PR and between 96c446e and 26714e0.

📒 Files selected for processing (2)
  • packages/web/src/app/api/(server)/ee/askmcp/callback/route.test.ts
  • packages/web/src/app/api/(server)/ee/askmcp/connect/route.test.ts

Walkthrough

This PR ensures MCP OAuth connectors always request the offline_access scope, preventing authorization rejections. It introduces a constant for the scope, forces it enabled in scope entry building, integrates it into the OAuth client provider, adds comprehensive test coverage, and documents the behavior for admins.

Changes

MCP OAuth Offline Access Scope

Layer / File(s) Summary
Core scope utilities and logic
packages/web/src/ee/features/chat/mcp/oauthScopeUtils.ts, packages/web/src/ee/features/chat/mcp/oauthScopeUtils.test.ts
OFFLINE_ACCESS_SCOPE constant is defined and used to force offline_access as enabled in scope entries regardless of requested scopes. Tests cover scope normalization (trim, deduplicate, sort), scope entry building (default offline_access enablement and merging), and enabled-scope extraction (filter, sort, deduplicate).
OAuth client provider integration
packages/web/src/ee/features/chat/mcp/prismaOAuthClientProvider.ts, packages/web/src/ee/features/chat/mcp/prismaOAuthClientProvider.test.ts, packages/web/src/app/api/(server)/ee/askmcp/*
PrismaOAuthClientProvider imports OFFLINE_ACCESS_SCOPE and unconditionally appends it to requestedOAuthScopes before normalization, ensuring client metadata always includes the scope. Tests and connector flow assertions updated to expect offline_access in provider client metadata and to avoid duplication.
Documentation and changelog
CHANGELOG.md, docs/docs/features/ask/connectors.mdx
Changelog documents the EE fix for MCP OAuth connectors. Documentation notes that offline_access is enabled by default when offered and is required for token refresh.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Suggested reviewers

  • brendan-kellam
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main fix: ensuring offline_access is always requested for MCP OAuth connectors to support the refresh_token grant, which aligns with the core purpose of all changes across the codebase.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

…ccess` injection

Both mocks asserted `clientMetadata.scope === 'repo'`; the scope is now
`'offline_access repo'` after the fix in the previous commit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@brendan-kellam brendan-kellam requested a review from jsourcebot June 9, 2026 22:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant