Commit Graph

230 Commits

Author SHA1 Message Date
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
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
Taylor Wilsdon
c7d677ffff refac _find_any_credentials to tuple for legacy mode refresh fix 2026-02-06 10:53:59 -05:00
Taylor Wilsdon
885a413a5a ruff 2026-02-05 11:31:44 -05:00
Taylor Wilsdon
13b6092cda jwt handling improvements 2026-02-05 11:17:59 -05:00