MCP server for Granola.ai meeting intelligence
Project description
GranolaAI MCP Server
๐๏ธ AI-Powered Meeting Intelligence for Claude Desktop
An experimental Model Context Protocol (MCP) server that bridges Granola.ai meeting intelligence with Claude Desktop. Access your meeting transcripts, notes, and insights directly through natural language conversations.
โจ Features
- ๐ Meeting Search โ Search meetings by title, content, participants, and transcript content
- ๐ Meeting Details โ Get comprehensive meeting metadata with local timezone display
- ๐ Full Transcript Access โ Retrieve complete meeting conversations with speaker identification
- ๐ Rich Document Content โ Access actual meeting notes, summaries, and structured content
- ๐ Pattern Analysis โ Analyze patterns across meetings (participants, frequency, topics)
- ๐ Timezone Intelligence โ All timestamps automatically display in your local timezone
- ๐ 100% Local Processing โ No external API calls; all data stays on your machine
๐๏ธ Architecture
flowchart TB
subgraph Client["๐ค Client Layer"]
CD[Claude Desktop]
end
subgraph MCP["๐ MCP Protocol Layer"]
MCP_STDIO[MCP stdio Transport]
end
subgraph Server["โ๏ธ Granola MCP Server"]
GMCS[GranolaMCPServer]
subgraph Handlers["Request Handlers"]
LIST[list_tools]
CALL[call_tool]
end
subgraph Tools["Available Tools"]
SEARCH[search_meetings]
DETAILS[get_meeting_details]
TRANSCRIPT[get_meeting_transcript]
DOCS[get_meeting_documents]
ANALYZE[analyze_meeting_patterns]
end
subgraph Cache["Cache Management"]
LOAD[_load_cache]
PARSE[_parse_cache_data]
EXTRACT[_extract_document_panel_content]
end
end
subgraph Data["๐พ Data Layer"]
CACHE_FILE[(Granola Cache<br/>cache-v*.json)]
MODELS[Pydantic Models<br/>MeetingMetadata<br/>MeetingDocument<br/>MeetingTranscript]
end
CD -->|stdio| MCP_STDIO
MCP_STDIO -->|MCP Protocol| GMCS
GMCS --> LIST
GMCS --> CALL
CALL --> SEARCH
CALL --> DETAILS
CALL --> TRANSCRIPT
CALL --> DOCS
CALL --> ANALYZE
GMCS --> LOAD
LOAD --> PARSE
PARSE --> EXTRACT
PARSE -->|reads| CACHE_FILE
PARSE --> MODELS
Data Flow
sequenceDiagram
participant User as ๐ค User
participant Claude as ๐ค Claude Desktop
participant Server as โ๏ธ MCP Server
participant Cache as ๐พ Granola Cache
User->>Claude: "Search for meetings about quarterly planning"
Claude->>Server: MCP: search_meetings(query)
Server->>Cache: Read cache file
Cache-->>Server: Raw JSON data
Server->>Server: Parse & validate with Pydantic
Server->>Server: Search across titles, participants, transcripts
Server-->>Claude: Matching meetings with metadata
Claude-->>User: Formatted meeting results
User->>Claude: "Get transcript from yesterday's meeting"
Claude->>Server: MCP: get_meeting_transcript(id)
Server->>Server: Lookup transcript in cache
Server-->>Claude: Full transcript with speakers
Claude-->>User: Readable conversation format
๐ ๏ธ Tech Stack
| Component | Technology |
|---|---|
| Language | Python 3.12+ |
| MCP SDK | mcp>=1.0.0 |
| Data Validation | Pydantic 2.x |
| Package Manager | uv (recommended) or pip |
| Build System | Hatchling |
| Release Automation | python-semantic-release |
๐ฆ Installation
Prerequisites
- uv package manager
- macOS with Granola.ai installed
Claude Desktop
Add to your claude_desktop_config.json:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"granola": {
"command": "uvx",
"args": ["granola-mcp-server"]
}
}
}
Then restart Claude Desktop.
Claude Code
claude mcp add granola -- uvx granola-mcp-server
Cursor
Updating
uvx caches the package after first run. To update to the latest version:
uvx --refresh granola-mcp-server
Then restart your MCP client.
Manual installation (alternative)
If you prefer to install from source:
cd ~
git clone https://github.com/proofgeist/granola-mcp-server
cd granola-mcp-server
uv sync
Then configure your MCP client to run the server directly:
{
"mcpServers": {
"granola": {
"command": "uv",
"args": ["--directory", "/Users/YOUR_USERNAME/granola-mcp-server", "run", "granola-mcp-server"]
}
}
}
To update a source install: git pull && uv sync
pip (alternative)
pip install granola-mcp-server
Then configure your MCP client to run granola-mcp-server.
Environment Variables
| Variable | Description | Default |
|---|---|---|
GRANOLA_PARSE_PANELS |
Enable parsing of document panels for rich notes | 1 (enabled) |
TZ |
Override local timezone detection | Auto-detected |
Set GRANOLA_PARSE_PANELS=0 to disable document panel parsing if you encounter issues.
๐ Usage
Once configured, restart Claude Desktop and start interacting with your Granola meetings using natural language:
Search & Discovery
- "Search for meetings about quarterly planning"
- "Show me yesterday's meetings"
- "Find meetings with David from this week"
- "List all my recent standup meetings"
Transcript Access
- "Get the transcript from yesterday's IA meeting"
- "What was discussed in the Float rollback planning meeting?"
- "Show me the full conversation from the David Tanner meeting"
Content Analysis
- "Analyze participant patterns from last month"
- "What documents are associated with the product review meeting?"
- "Search for mentions of 'schema labeling' in meeting transcripts"
Available Tools
| Tool | Description | Parameters |
|---|---|---|
search_meetings |
Search meetings by title, content, participants | query (string), limit (int, optional) |
get_meeting_details |
Get detailed information about a meeting | meeting_id (string) |
get_meeting_transcript |
Get full transcript with speaker identification | meeting_id (string) |
get_meeting_documents |
Get documents and notes associated with a meeting | meeting_id (string) |
analyze_meeting_patterns |
Analyze patterns across meetings | pattern_type (enum: topics/participants/frequency), date_range (optional) |
๐งช Development
Running Tests
# Run panel parsing test
uv run python test_server.py
# Test with real cache file
uv run python test_real_cache.py
Running the Server Directly
uv run granola-mcp-server
Or using the run script:
uv run python run_server.py
Project Structure
granola-mcp-server/
โโโ granola_mcp_server/
โ โโโ __init__.py # Package initialization
โ โโโ server.py # Main MCP server implementation (~750 lines)
โ โโโ models.py # Pydantic data models
โโโ .github/
โ โโโ workflows/
โ โโโ release.yml # Semantic release automation
โโโ tests/
โ โโโ test_server.py # Unit tests with synthetic cache
โ โโโ test_real_cache.py # Integration tests with real data
โโโ pyproject.toml # Python package configuration + semantic-release config
โโโ run_server.py # Entry point wrapper
โโโ INSTALL.md # Detailed installation guide
โโโ LICENSE # MIT License
โโโ README.md # This file
๐ Security & Privacy
| Feature | Status |
|---|---|
| 100% Local Processing | โ All data stays on your machine |
| No External API Calls | โ No data sent to external services |
| Granola Permissions Respected | โ Uses existing Granola.ai access controls |
| Read-Only Access | โ Server only reads from Granola's cache |
๐ Performance
- Fast Loading: Sub-2 second cache loading for hundreds of meetings
- Rich Content: Extracts 25,000+ character transcripts and meeting notes
- Efficient Search: Multi-field search across titles, content, participants, and transcripts
- Memory Optimized: Lazy loading with intelligent content parsing
- Production Ready: Successfully processes real Granola data (11.7MB cache files)
- Scalable: Handles large datasets with 500+ transcript segments per meeting
๐ Troubleshooting
Common Issues
"Cache file not found"
# Ensure Granola.ai is installed and has processed some meetings
ls -la ~/Library/Application\ Support/Granola/cache-v*.json
"uv command not found"
# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh
Server not appearing in Claude Desktop
- Check Claude Desktop logs:
~/Library/Logs/Claude/mcp-server-granola.log - Restart Claude Desktop after config changes
Meeting notes appear empty
- Granola sometimes stores rich notes inside
documentPanelsrather thannotes_plain - This server reads those panels by default; set
GRANOLA_PARSE_PANELS=0to disable
Manual installation issues
These apply only if you installed from source (git clone) rather than via uvx.
"Permission denied" or "Operation not permitted"
- This happens when the server is installed in
~/Documentsor other protected macOS folders - Move the installation to your home directory:
mv ~/Documents/granola-mcp-server ~/granola-mcp-server cd ~/granola-mcp-server uv sync
Then update the path inclaude_desktop_config.json - Or grant Claude Desktop Full Disk Access in System Settings > Privacy & Security
"Current directory does not exist"
- This error occurs when using
uv runwith the--directoryflag - Ensure the path in your Claude config points to the actual clone location
"Failed to spawn process" or "No such file or directory"
- Run
uv syncin the project directory to rebuild the venv - Verify the script exists:
ls -la ~/granola-mcp-server/.venv/bin/granola-mcp-server
๐ค Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'feat: add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Please ensure your code follows the existing style and includes appropriate tests.
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
Copyright (c) 2025 Proof+Geist
๐ Acknowledgments
- Granola.ai for the amazing meeting intelligence app
- Anthropic for Claude and the Model Context Protocol
- Astral for the uv package manager
โ ๏ธ Disclaimer: This is an experimental project. Granola's cache format may change without notice. Use at your own risk.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file granola_mcp_server-1.3.0.tar.gz.
File metadata
- Download URL: granola_mcp_server-1.3.0.tar.gz
- Upload date:
- Size: 50.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5426c9d72fe532439a52295ae58fa90d0a0bde17f96d84cb6c9b76600e47a27c
|
|
| MD5 |
c49467bae706d81f9a9dd1e6cbe25ebe
|
|
| BLAKE2b-256 |
9588f310a6e952daff1f7bd2111679e3d81ea016ba2501c57cb615f46198dc21
|
Provenance
The following attestation bundles were made for granola_mcp_server-1.3.0.tar.gz:
Publisher:
release.yml on proofgeist/granola-mcp-server
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
granola_mcp_server-1.3.0.tar.gz -
Subject digest:
5426c9d72fe532439a52295ae58fa90d0a0bde17f96d84cb6c9b76600e47a27c - Sigstore transparency entry: 1097245935
- Sigstore integration time:
-
Permalink:
proofgeist/granola-mcp-server@b07b3812bf3241c8f521df9d1e6d8c02cbe5c313 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/proofgeist
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b07b3812bf3241c8f521df9d1e6d8c02cbe5c313 -
Trigger Event:
push
-
Statement type:
File details
Details for the file granola_mcp_server-1.3.0-py3-none-any.whl.
File metadata
- Download URL: granola_mcp_server-1.3.0-py3-none-any.whl
- Upload date:
- Size: 14.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
511637538305c23b2502f745452204ebab1ab26e8fbafc612b328d18dfc3c6a7
|
|
| MD5 |
7714b483878fbe13bf8ebb696ecdf83d
|
|
| BLAKE2b-256 |
931c3e6679b744663f63bd644379cf3ffef7405147efb4d58bea10f7d27b3040
|
Provenance
The following attestation bundles were made for granola_mcp_server-1.3.0-py3-none-any.whl:
Publisher:
release.yml on proofgeist/granola-mcp-server
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
granola_mcp_server-1.3.0-py3-none-any.whl -
Subject digest:
511637538305c23b2502f745452204ebab1ab26e8fbafc612b328d18dfc3c6a7 - Sigstore transparency entry: 1097246238
- Sigstore integration time:
-
Permalink:
proofgeist/granola-mcp-server@b07b3812bf3241c8f521df9d1e6d8c02cbe5c313 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/proofgeist
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b07b3812bf3241c8f521df9d1e6d8c02cbe5c313 -
Trigger Event:
push
-
Statement type: