Granola MCP
Meeting notes AI connected via mcporter call granola.<tool>.
Tools
granola.query_granola_meetings query=<string> [document_ids=<uuid[]>]
granola.list_meetings [time_range=this_week|last_week|last_30_days|custom] [custom_start=<ISO>] [custom_end=<ISO>]
granola.get_meetings meeting_ids=<uuid[]> (max 10)
granola.get_meeting_transcript meeting_id=<uuid>
Usage Pattern
- For open-ended questions ("what did we discuss about X?"), use
query_granola_meetings - For listing meetings in a range, use
list_meetings - For full details on specific meetings, use
get_meetingswith IDs from list results - For exact quotes or verbatim content, use
get_meeting_transcript
Prefer query_granola_meetings over list+get for natural language questions. Responses include citation links (e.g. [[0]](url)). Preserve these in replies so the user can click through to original notes.
Setup
- Complete the Granola OAuth flow at
https://mcp-auth.granola.ai/oauth2/authorize - Save credentials to
config/granola_oauth.jsonwith keys:client_id,refresh_token,access_token,token_endpoint - Configure
config/mcporter.jsonwith the Granola MCP server entry andAuthorization: Bearer <token>header - (Optional) Set up a cron job to run
scripts/refresh_token.shperiodically, since OAuth tokens expire every ~6 hours
Auth & Token Refresh
If a call fails with 401/auth error:
bash {baseDir}/scripts/refresh_token.sh
The script reads config/granola_oauth.json, posts to the token endpoint (https://mcp-auth.granola.ai/oauth2/token), and updates both config/granola_oauth.json and config/mcporter.json with the new access token.
Then retry the call. If refresh also fails, the user needs to re-authenticate manually via the OAuth flow above.
Config Files
config/granola_oauth.json— OAuth credentials (client_id, refresh_token, access_token, token_endpoint). Contains secrets; do not commit.config/mcporter.json— MCP server config with bearer token header. Contains secrets; do not commit.