# Granola MCP Server
MCP server for Granola meeting notes. Deploys to Cloudflare Workers with OAuth.
## Setup
```bash
npm install
wrangler kv namespace create TOKENS
```
Update `wrangler.toml` with your KV namespace ID, then deploy:
```bash
npm run deploy
```
## Configure MCP Client
Add to your MCP config (e.g. Claude Desktop, ChatGPT):
```json
{
"mcpServers": {
"granola": {
"url": "https://granola-mcp-server.YOUR-SUBDOMAIN.workers.dev/mcp"
}
}
}
```
On first use, you'll be prompted to authenticate via Google. Follow the on-screen instructions.
## Tools
| Tool | Description |
|------|-------------|
| `get_all_meetings` | List recent meetings (limit: default 20) |
| `get_meeting_by_id` | Get single meeting by document ID |
| `get_recent_meetings` | Meetings from last N days |
| `search_meetings` | Search by keyword |
| `get_document_summary` | Full summary for a document |
| `get_todays_meetings` | Today's meetings |
## Development
```bash
npm run dev # Local server at localhost:8787
npm run deploy # Deploy to Cloudflare
wrangler tail # View logs
```
## Debug Endpoints
```bash
# Check token status
curl -H "Authorization: Bearer SESSION_ID" \
https://YOUR-WORKER.workers.dev/debug/test-refresh
# Force token refresh
curl -H "Authorization: Bearer SESSION_ID" \
"https://YOUR-WORKER.workers.dev/debug/test-refresh?force=true"
```
## Notes
- Tokens stored in Cloudflare KV (no expiry, persists until Granola invalidates)
- Access tokens auto-refresh before expiry
- Read-only access to Granola API
- Reverse-engineered from Granola Electron app v6.267.0
## License
MIT. Not affiliated with Granola.