Purge standalone OAuth setup for Gmail and Gcal

- Deleted gmail_oauth_setup.py and gcal_oauth_setup.py (Skald handles OAuth)
- Removed google-auth-oauthlib dependency from requirements.txt and connector.json
- Simplified setup_instructions to point to Skald's OAuth flow
- Updated docstrings and error messages in *_mcp_server.py (no more refs to
  *_oauth_setup.py, point to Skald OAuth / env-var instead)
- connectors.json: removed oauth_setup.py from files[], updated sha256 hashes
This commit is contained in:
2026-07-17 21:53:17 +01:00
parent 46c1446eae
commit b1a3944fc8
9 changed files with 24 additions and 256 deletions
+2 -4
View File
@@ -10,12 +10,10 @@
"tags": ["calendar", "mcp", "local", "google"],
"dependencies": [
"google-api-python-client>=2.150.0",
"google-auth>=2.35.0",
"google-auth-oauthlib>=1.2.0"
"google-auth>=2.35.0"
],
"setup_instructions": [
"Install dependencies: pip install -r requirements.txt",
"Run: python3 gcal_oauth_setup.py (optional, for standalone use — Skald handles OAuth)"
"Activated from Skald: an admin configures the Google sign-in provider, then each user signs in from the connector page (OAuth handled by Skald)."
],
"docs": [
{
+5 -8
View File
@@ -13,7 +13,6 @@ Capabilities (callable as `mcp__gcal__<tool>`):
Skald mode: Skald injects credentials via GCAL_CREDS_JSON env var (authorized_user JSON).
Standalone mode: reads from GOOGLE_CREDS_PATH or ./secrets/google_creds.json.
Run scripts/gcal_oauth_setup.py to (re-)authenticate (standalone).
Required OAuth scopes:
https://www.googleapis.com/auth/calendar
@@ -282,21 +281,20 @@ def _format_google_error(e: Exception, api_label: str) -> str:
if RefreshError is not None and isinstance(e, RefreshError):
return (
f"Error: {api_label} API token refresh failed (the refresh token may have been revoked "
"or expired). Re-run scripts/gcal_oauth_setup.py to re-authenticate."
"or expired). Re-authenticate via Skald's OAuth flow (Sign in from the connector page)."
)
if HttpError is not None and isinstance(e, HttpError):
status = getattr(e, "status_code", None)
if status == 401:
return (
f"Error: {api_label} API rejected the access token (401). The OAuth token is invalid "
"or revoked. Re-run scripts/gcal_oauth_setup.py to re-authenticate."
)
f"Error: {api_label} API rejected the access token (401). The OAuth token is invalid "
"or revoked. Re-authenticate via Skald's OAuth flow (Sign in from the connector page)." )
if status == 403:
return (
f"Error: {api_label} API returned 403 Forbidden. The OAuth scopes granted are "
"insufficient for this operation, or the Calendar API is disabled in the Google Cloud "
"Console. Verify the scopes in scripts/gcal_oauth_setup.py and the API enablement."
"Console. Verify the scopes in the Google OAuth provider config and the API enablement."
)
if status == 404:
return (
@@ -350,9 +348,8 @@ def _gcal_status(args: dict | None = None) -> str:
except Exception as e:
return _status_report("", "AUTH_OR_API_ERROR", "action needed",
f"The Calendar API did not respond to the probe call: {_format_google_error(e, 'Calendar')}",
["Run scripts/gcal_oauth_setup.py to refresh / re-issue credentials.",
["Re-authenticate via Skald's OAuth flow (Sign in from the connector page).",
"If credentials are valid, verify the Google Calendar API is enabled in the Google Cloud Console."])
items = result.get("items", []) if isinstance(result, dict) else []
primary = next((c for c in items if c.get("primary")), None)
suffix = f"\nAccount: {primary.get('id')}" if primary else ""
-106
View File
@@ -1,106 +0,0 @@
#!/usr/bin/env python3
"""Generate a Google OAuth token for the Calendar API (read + write).
This script runs a local OAuth flow that:
1. Opens your browser automatically to the Google authorization page
2. Handles the callback via a local HTTP server
3. Saves the resulting token to ./secrets/google_creds.json
Required OAuth scope: https://www.googleapis.com/auth/calendar
(full access — needed for create, update, delete, respond).
No manual copy-paste required.
"""
from __future__ import annotations
import json
import os
import sys
SCOPES = [
"https://www.googleapis.com/auth/calendar",
]
_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SECRET_PATH = os.path.join(_ROOT, "secrets", "google_creds.json")
_OAUTH_CLIENT_PATH = os.path.join(_ROOT, "secrets", "google_oauth_client.json")
def _load_oauth_client() -> tuple[str, str]:
if not os.path.exists(_OAUTH_CLIENT_PATH):
print(f"Missing OAuth client file: {_OAUTH_CLIENT_PATH}")
print('Create it with: {"client_id": "...", "client_secret": "..."}')
sys.exit(1)
with open(_OAUTH_CLIENT_PATH) as f:
data = json.load(f)
return data["client_id"], data["client_secret"]
def main() -> None:
try:
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
except ImportError as e:
print(f"Missing dependencies: {e}")
print("Install with: pip install google-auth google-auth-oauthlib google-api-python-client")
sys.exit(1)
creds = None
# Try to load existing credentials first.
if os.path.exists(SECRET_PATH):
print(f"Existing credentials found at {SECRET_PATH}")
try:
creds = Credentials.from_authorized_user_file(SECRET_PATH, SCOPES)
except Exception:
creds = None
if creds and creds.valid:
print("Credentials are already valid!")
print(f" Scopes: {creds.scopes}")
return
if creds and creds.expired and creds.refresh_token:
print("Token expired. Attempting refresh...")
try:
creds.refresh(Request())
print("Token refreshed successfully!")
except Exception as e:
print(f"Refresh failed: {e}")
creds = None
if not creds or not creds.valid:
client_id, client_secret = _load_oauth_client()
flow = InstalledAppFlow.from_client_config(
{
"installed": {
"client_id": client_id,
"client_secret": client_secret,
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"redirect_uris": ["http://localhost"],
}
},
SCOPES,
)
print("\nOpening browser for Google authorization...")
creds = flow.run_local_server(
port=0,
open_browser=True,
prompt="consent",
access_type="offline",
)
os.makedirs(os.path.dirname(SECRET_PATH), exist_ok=True)
with open(SECRET_PATH, "w") as f:
f.write(creds.to_json())
print(f"\n✅ Google Calendar OAuth token saved to {SECRET_PATH}")
print(f" Scopes: {creds.scopes}")
if __name__ == "__main__":
main()
-1
View File
@@ -1,3 +1,2 @@
google-api-python-client>=2.150.0
google-auth>=2.35.0
google-auth-oauthlib>=1.2.0