Commit Graph

233 Commits

Author SHA1 Message Date
Taylor Wilsdon
156a1f20ef Merge pull request #573 from seidnerj/fix/oauth-response-pages
fix: improve OAuth response pages for browser compatibility
2026-03-17 11:49:10 -04:00
Taylor Wilsdon
66011fd814 remove consent from reauth flow and add tests 2026-03-17 08:36:08 -04:00
Taylor Wilsdon
6a386b4255 refac 2026-03-15 17:29:09 -04:00
Bortlesboat
b7365c661e fix(auth): auto-refresh expired tokens in single-user stdio mode
When credentials had a refresh_token but credentials.expired was False
(e.g., token=None with no stored expiry), the refresh was skipped and
the server would start a new OAuth flow instead. This changes the
condition to attempt refresh whenever credentials are not valid and a
refresh_token is available, regardless of the expired flag.
2026-03-15 17:22:36 -04:00
seidnerj
4bdc96a554 fix: use consistent "tab" wording in success page CTAs
Change "Close Window" to "Close Tab" and "This window will close" to
"This tab will close" on the success page to match the rest of the PR.
2026-03-14 07:35:18 +02:00
seidnerj
31e27b76b6 fix: improve OAuth response pages for browser compatibility
window.close() is blocked by modern browsers for tabs not opened via
window.open(). The success page's close button and auto-close timer
silently fail as a result.

- Add tryClose() that attempts window.close() and falls back to
  showing "You can close this tab manually" after 500ms
- Remove ineffective auto-close scripts from error pages
2026-03-14 01:37:18 +02:00
github-actions[bot]
5eb5e06a1e style: auto-fix ruff lint and format 2026-03-09 16:52:41 +00:00
mickey-mikey
f26c2f9e87 Merge branch 'taylorwilsdon:main' into feat/tasks-manage-permission 2026-03-05 15:13:08 +11:00
Taylor Wilsdon
4cc456602f drive scope fix 2026-03-04 16:36:34 -05:00
mickey-mikey
0fce7c78b6 fix: also deny clear_completed under tasks:manage
Addresses CodeRabbit review — clear_completed is destructive and should
be blocked alongside delete at the manage permission level.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 16:21:51 +11:00
mickey-mikey
377791080c feat: add tasks:manage permission level to deny delete without blocking other writes
The consolidated manage_task tool bundles create/update/delete/move into a
single tool, making it impossible to deny just the delete action via tool
tiers or scope-based filtering.

This adds:
- A `manage` permission level for tasks (between readonly and full)
- A SERVICE_DENIED_ACTIONS registry mapping (service, level) to denied actions
- An is_action_denied() helper that tools call before executing actions
- Guards in manage_task and manage_task_list that reject denied actions

Usage: --permissions tasks:manage
Allows create, update, move. Denies delete.
tasks:full remains unchanged (all actions allowed).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 15:04:31 +11:00
Taylor Wilsdon
ef9c6a9c69 make better 2026-03-01 17:34:02 -05:00
Baris Sencan
3361ed29e6 Fix PKCE code verifier not being generated for initial OAuth flow
When `create_oauth_flow()` is called without an explicit `code_verifier`
(i.e. during the initial auth flow in `start_auth_flow()`), the function
never sets `autogenerate_code_verifier=True` on the Flow constructor.

oauthlib 3.2+ automatically adds `code_challenge` to the authorization
URL at the session level, so Google expects a matching `code_verifier`
during the token exchange. However, since `Flow.code_verifier` remains
`None`, that `None` gets stored in the session store and later passed
back during the callback — causing Google to reject the token exchange
with `(invalid_grant) Missing code verifier`.

The fix adds `autogenerate_code_verifier=True` in the else branch so
the Flow object generates and exposes a proper PKCE code verifier that
gets stored and reused during the callback token exchange.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 18:38:29 +00:00
Taylor Wilsdon
768ec5eef0 refac 2026-02-28 16:17:43 -04:00
Taylor Wilsdon
8ae833f0c7 Merge branch 'main' of https://github.com/taylorwilsdon/google_workspace_mcp into issues/503 2026-02-28 11:13:23 -04:00
Taylor Wilsdon
9dc9b1c825 pkce fix 2026-02-28 10:06:50 -04:00
Taylor Wilsdon
92d2c15b80 Merge branch 'issues/503' of https://github.com/taylorwilsdon/google_workspace_mcp into issues/503 2026-02-27 16:59:38 -04:00
Taylor Wilsdon
bb197243cd pr feedback 2026-02-27 16:59:18 -04:00
github-actions[bot]
86a8e1be4d style: auto-fix ruff lint and format 2026-02-25 23:44:33 +00:00
Taylor Wilsdon
cfc68d8605 implement --permissions flag 2026-02-24 21:28:50 -04:00
Taylor Wilsdon
aa520b72d3 fix all them tests 2026-02-24 21:09:14 -04:00
Taylor Wilsdon
e85b7aa3db logfix 2026-02-24 11:23:22 -04:00
Taylor Wilsdon
1ebc758490 Merge branch 'main' of https://github.com/taylorwilsdon/google_workspace_mcp into fastmcp_v3
# Conflicts:
#	uv.lock
2026-02-24 10:13:14 -04:00
Taylor Wilsdon
9b8dc6568c chat spaces readonly scope 2026-02-18 12:46:08 -05:00
Taylor Wilsdon
28f03c2e92 ruff 2026-02-18 12:36:25 -05:00
Taylor Wilsdon
96725470ec Merge branch 'main' of github.com:taylorwilsdon/google_workspace_mcp into add-chat-spaces-readonly-scope 2026-02-18 12:36:18 -05:00
Taylor Wilsdon
f62e0bbd26 pr feedback 2026-02-18 12:28:17 -05:00
Taylor Wilsdon
3cc40c1357 Merge branch 'issues/483' of github.com:taylorwilsdon/google_workspace_mcp into issues/483 2026-02-18 12:22:32 -05:00
Taylor Wilsdon
90a2a9c00b set for scopes 2026-02-18 12:22:13 -05:00
github-actions[bot]
950206c707 style: auto-fix ruff lint and format 2026-02-18 16:49:48 +00:00
Taylor Wilsdon
a28fa0a249 address issues/483 2026-02-18 11:48:53 -05:00
Seth Ladd
d964324e5d Add chat.spaces.readonly scope for listing spaces
The list_spaces tool was using chat.messages.readonly which is overly
broad for simply enumerating available spaces. This adds the
chat.spaces.readonly scope and uses it for list_spaces, following the
principle of least privilege.

Closes #479

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 20:58:08 -08:00
Rob Sherman
f1705ce81b fix(auth): filter non-credential files from list_users()
LocalDirectoryCredentialStore.list_users() enumerates all .json files
in the credentials directory, but oauth_states.json (written by
PersistentOAuthStateStore) is not a user credential file. In
single-user mode, this file can be picked up first alphabetically,
causing a TypeError when accessing credentials.scopes (None) since
the state file has no scopes field.

Filter out known non-credential files and filenames without '@' to
ensure only actual user credential files are returned.
2026-02-13 13:40:56 -08:00
Nicholas Xavier Ferrara
eddf940454 fix: add missing token_uri, client_id, client_secret to OAuth 2.1 refresh store_session
The store_session call in the OAuth 2.1 credential refresh path (get_credentials)
omits token_uri, client_id, client_secret, and issuer. These are stored as None,
causing subsequent refresh attempts to fail and forcing full re-authentication.

The correct pattern already exists in three other store_session calls in the same
file (lines 151, 522, 750) — this aligns the refresh path to match.
2026-02-13 13:51:47 -05:00
Taylor Wilsdon
0075e8338f v3 auth middleware fix 2026-02-13 10:20:39 -05:00
Taylor Wilsdon
ad53debf2f Merge pull request #432 from Milofax/fix/cross-service-scopes
fix(auth): add cross-service Drive scopes for docs and sheets tools
2026-02-11 15:38:14 -05:00
Milofax
821804cf60 style: format DOCS_SCOPES list for ruff compliance
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 18:06:19 +01:00
Taylor Wilsdon
bbee795c16 ruff 2026-02-10 17:22:28 -05:00
Taylor Wilsdon
35fc66f329 persistence call 2026-02-10 17:19:18 -05:00
Taylor Wilsdon
3b75ab11fb fix 448 2026-02-10 17:00:41 -05:00
Taylor Wilsdon
72f06d5853 refac 2026-02-07 13:35:53 -05:00
Taylor Wilsdon
24dca13425 refac 2026-02-07 13:35:32 -05:00
Taylor Wilsdon
dbab29d356 fix #433 2026-02-07 13:29:22 -05:00
Milofax
d91070502f fix(auth): add cross-service Drive scopes for docs and sheets tools
Several docs tools (search_docs, get_doc_content, list_docs_in_folder,
export_doc_to_pdf) and sheets tools (list_spreadsheets) internally use
the Google Drive API but only receive docs/sheets-specific OAuth scopes
when configured with `--tools docs sheets` (without `drive`).

This adds the minimal required Drive scopes as cross-service dependencies:
- docs: drive.readonly (metadata queries) + drive.file (PDF export)
- sheets: drive.readonly (spreadsheet listing)

This follows the existing pattern where appscript already includes
DRIVE_FILE_SCOPE for its Drive API dependency.

The alternative workaround of adding `--tools drive` exposes 14
full-access Drive tools which is undesirable from a security perspective.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 12:19:05 +01:00
Taylor Wilsdon
bae425f754 refac 2026-02-06 20:33:59 -05:00
Taylor Wilsdon
88542afe31 refac 2026-02-06 14:45:15 -05:00
Taylor Wilsdon
ece2ee12d7 fix 2026-02-06 14:40:16 -05:00
Taylor Wilsdon
b0743ec923 fix import 2026-02-06 14:33:24 -05:00
Taylor Wilsdon
1877d70077 Merge branch 'main' of github.com:taylorwilsdon/google_workspace_mcp into external-oauth-clean 2026-02-06 12:50:07 -05:00
Alexander
b7d8f61cf7 Update external_oauth_provider.py
avoided depreciated date time format
2026-02-06 12:10:43 -05:00