loading…
Search for a command to run...
loading…
A starter template for building MCP servers with support for No Auth, API Key, and OAuth authentication using the Dedalus Labs DAuth framework.
A starter template for building MCP servers with support for No Auth, API Key, and OAuth authentication using the Dedalus Labs DAuth framework.
A Granola meeting notes MCP server built on the Dedalus platform.
Search through meeting history, retrieve meeting notes and transcripts, and extract business insights — all through AI assistants using the Model Context Protocol.
grn_).Note: Personal API keys require a Granola Business or Enterprise plan.
cp .env.example .env
Fill in your .env:
# Granola API Key
GRANOLA_API_KEY=grn_your-api-key-here
# Dedalus Platform (for the sample client)
DEDALUS_API_KEY=dsk-live-your-api-key
DEDALUS_API_URL=https://api.dedaluslabs.ai
DEDALUS_AS_URL=https://as.dedaluslabs.ai
# After deploying, set this to your slug
GRANOLA_MCP_SLUG=nickyhec/granola-mcp
GRANOLA_API_KEY from your .env.nickyhec/granola-mcp).uv sync
uv run src/_client.py
=== Granola MCP Agent ===
Server: nickyhec/granola-mcp
Type 'quit' or 'exit' to end the session.
You: What meetings did I have this week?
Assistant: ...
| Variable | Description |
|---|---|
GRANOLA_API_KEY |
Your Granola API key (grn_*). Get from Granola desktop app → Settings → API. |
DEDALUS_API_KEY |
Your Dedalus API key (dsk_*) |
DEDALUS_API_URL |
API base URL (default: https://api.dedaluslabs.ai) |
DEDALUS_AS_URL |
Authorization server URL (default: https://as.dedaluslabs.ai) |
GRANOLA_MCP_SLUG |
Your deployed server slug (e.g. nickyhec/granola-mcp) |
uv run src/main.py
This starts the MCP server on port 8080. The _client.py connects through
Dedalus (not localhost). Use this for local testing with a direct MCP client.
uv run --group lint ruff format src/
uv run --group lint ruff check src/ --fix
uv run --group lint ty check src/
| Tool | Description |
|---|---|
granola_list_notes |
List note summaries with optional date filters and pagination |
granola_get_note |
Get a full note by ID (owner, attendees, calendar event, summary) |
granola_get_note_with_transcript |
Get a full note including its meeting transcript |
granola_get_recent_notes |
Fetch notes from a recent time window (day, week, or month) |
granola_search_notes_by_date |
Filter notes by creation or update date ranges |
granola_list_notes_paginated |
Auto-paginate through all matching notes |
granola_get_meeting_summary |
Get meeting metadata plus summary text for concise responses |
granola_get_transcript_text |
Get normalized transcript entries (speaker, text, timestamps) |
All tools are read-only — this server does not modify any data in Granola.
granola_list_notesList note summaries with optional date filtering and cursor-based pagination.
| Parameter | Type | Default | Description |
|---|---|---|---|
created_before |
str | None |
None |
ISO 8601 datetime upper bound |
created_after |
str | None |
None |
ISO 8601 datetime lower bound |
updated_after |
str | None |
None |
Only notes updated after this time |
cursor |
str | None |
None |
Pagination cursor from previous response |
page_size |
int |
25 |
Notes per page |
granola_get_noteFetch a complete note by ID, including owner info, calendar event, attendees, and AI summary.
| Parameter | Type | Description |
|---|---|---|
note_id |
str |
Note ID (e.g. not_1d3tmYTlCICgjy) |
granola_get_note_with_transcriptSame as granola_get_note but also includes the full meeting transcript.
| Parameter | Type | Description |
|---|---|---|
note_id |
str |
Note ID (e.g. not_1d3tmYTlCICgjy) |
granola_get_recent_notesConvenience wrapper that fetches notes from a relative time window.
| Parameter | Type | Default | Description |
|---|---|---|---|
window |
str |
"week" |
Time window: "day", "week", or "month" |
page_size |
int |
25 |
Notes per page |
granola_search_notes_by_dateFilter notes by specific date ranges. At least one date filter is required.
| Parameter | Type | Default | Description |
|---|---|---|---|
created_after |
str | None |
None |
ISO 8601 datetime lower bound |
created_before |
str | None |
None |
ISO 8601 datetime upper bound |
updated_after |
str | None |
None |
Only notes updated after this time |
page_size |
int |
25 |
Notes per page |
granola_list_notes_paginatedAutomatically follows cursor pagination to retrieve multiple pages of notes.
| Parameter | Type | Default | Description |
|---|---|---|---|
created_after |
str | None |
None |
ISO 8601 datetime lower bound |
created_before |
str | None |
None |
ISO 8601 datetime upper bound |
updated_after |
str | None |
None |
Only notes updated after this time |
max_pages |
int |
10 |
Maximum pages to fetch |
page_size |
int |
25 |
Notes per page |
granola_get_meeting_summaryReturns just the meeting metadata and summary fields — no transcript or heavy content.
| Parameter | Type | Description |
|---|---|---|
note_id |
str |
Note ID (e.g. not_1d3tmYTlCICgjy) |
granola_get_transcript_textReturns normalized transcript entries with speaker identification.
| Parameter | Type | Description |
|---|---|---|
note_id |
str |
Note ID (e.g. not_1d3tmYTlCICgjy) |
Granola provides a REST API at https://public-api.granola.ai. The request
layer dispatches calls through the Dedalus HTTP enclave, which injects API
Key credentials transparently.
src/
├── granola/
│ ├── config.py # Connection definition (API Key / Bearer token)
│ ├── request.py # REST dispatch + coercion helpers
│ └── types.py # Typed dataclass models
├── tools/
│ ├── notes.py # Core note retrieval (list, get, get with transcript)
│ ├── search.py # Date filtering + pagination helpers
│ └── summaries.py # Summary + transcript extraction
├── server.py # MCPServer setup
├── main.py # Server entry point
└── _client.py # Interactive agent client (DAuth)
Granola enforces the following rate limits:
Rate limits apply per-workspace for Enterprise API keys and per-user for Personal API keys. The server does not currently implement automatic retry logic — if you hit rate limits, wait and retry.
The Granola API only returns notes that have completed AI processing (summary and transcript generation). Notes that are still being processed or were never summarized will return 404.
grn_.Transcript format varies by recording platform:
source is "microphone" (local) or "speaker" (remote audio).source is "microphone" with optional diarization_label for speaker identification (e.g. "Speaker A", "Speaker B").The client routes through the Dedalus platform by slug. Common causes:
GRANOLA_MCP_SLUG matches your deployment.Добавь это в claude_desktop_config.json и перезапусти Claude Desktop.
{
"mcpServers": {
"granola-mcp": {
"command": "npx",
"args": []
}
}
}PRs, issues, code search, CI status
Database, auth and storage
Reference / test server with prompts, resources, and tools.
Secure file operations with configurable access controls.