Splitting the OAuth dance into its own service is why the MCP server never has to think about consent screens or refresh timing — it reads a session file and gets on with the API. The cost is that both have to be running, and the first-run sequence matters: sign in before starting the MCP server, or there is nothing for it to read. Because the OAuth client is one you created, the consent and the token both stay yours.
Two servers that work together: a FastAPI OAuth service that runs Google's authorization flow and stores the access and refresh tokens locally, and an MCP server that uses those saved credentials to talk to the Google Calendar API v3 over streamable HTTP.
- Natural-language interaction with your calendar through a Calendar API v3 wrapper
- A separate OAuth server that handles the consent flow and refreshes access tokens as they expire
- Tokens written to a local `session.json` rather than held by a third party
- Typed definitions for the Calendar v3 API in the codebase, so the tool surface tracks the real API rather than an approximation
Your own Google Cloud OAuth 2.0 client: create or select a project, enable the Google Calendar API, create a Desktop App OAuth client id, add test user emails to the audience, and download the credentials as `client_secret.json` into the project root. Then `poetry install`, start the OAuth server with `poetry run uvicorn src.main:app --host 0.0.0.0 --port 8000` and complete the browser sign-in, which writes `session.json`. Start the MCP server with `poetry run python src/server.py`; it serves at `http://localhost:8080/mcp`. Claude Desktop reaches it through `npx mcp-remote` pointed at that URL. The project is `google-calendar-mcp-server` (0.1.0 in pyproject).
