使用说明
Spark MCP Server
MCP server for accessing Spark Desktop meeting transcripts and emails through the Model Context Protocol.
Quick setup / update (any Mac)
This server is installed and registered for Claude Code and Claude Desktop by
setup-mcp.sh in the dotfiles repo,
along with all the other MCP servers:
cd ~/dotfiles && git pull && ./setup-mcp.sh
Then restart Claude Code and Claude Desktop. (More detail, including upgrading an older Mac: the
laptop-setup README.)
The script clones or pulls every server repo into
~/src, builds each environment from its uv.lock, writes the config, and checks that each server
starts. It's safe to re-run anytime.
After that, a plain git pull in this repo is enough: the server launches with uv run --frozen,
which installs any changed dependencies on the next start. Credentials live in ~/.mcp-auth
(synced from Box with unison mcp_auth).
Features
- 📝 Access all meeting transcripts (calendar-based and ad-hoc)
- 🔍 Full-text search across transcript content
- 📊 Statistics and analytics about your transcripts
- 🔒 Read-only access - safe and non-destructive
- ⚡ Fast local SQLite queries - no network required
- 🎯 Captures ad-hoc meetings (primary use case)
Requirements
- macOS (Spark Desktop must be installed)
- Python 3.10+
- Spark Desktop for macOS (App Store version)
Installation
# Install in development mode
pip install -e .
Usage
With Claude Desktop
Add to your Claude Desktop MCP settings (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"spark": {
"command": "python",
"args": ["-m", "spark_mcp.server"],
"cwd": "/Users/feamster/src/spark-mcp"
}
}
}
Or if installed via pip:
{
"mcpServers": {
"spark": {
"command": "spark-mcp"
}
}
}
Restart Claude Desktop, and the tools will be available.
Standalone Testing
# Run the server (communicates via stdio)
python -m spark_mcp.server
Available Tools
1. list_meeting_transcripts
List meeting transcripts with metadata.
Parameters:
limit(optional, default: 20): Max resultsafter(optional): Return transcripts with meetingStartDate after this ISO datetime (e.g., '2026-01-30T13:00:00')before(optional): Return transcripts with meetingStartDate before this ISO datetime (e.g., '2026-01-30T16:00:00')
Example:
{
"after": "2026-02-09T09:00:00",
"before": "2026-02-09T12:00:00",
"limit": 10
}
Returns:
{
"transcripts": [
{
"messagePk": 63336,
"subject": "Prior Art Review for Patent Claims 416 and 571",
"sender": "example@example.com",
"receivedDate": "2025-11-11 15:59:12",
"meetingStartDate": "2025-11-11T15:00:00.000Z",
"meetingEndDate": "2025-11-11T16:00:00.000Z",
"transcriptId": "-8929133086933914113",
"isCalendarEvent": false,
"eventSummary": null,
"textLength": 29893,
"hasFullText": true
}
],
"total": 228
}
2. get_meeting_transcript
Get full transcript content.
Parameters:
messagePk(optional): Message primary key from listtranscriptId(optional): Transcript ID (mtid)
Example:
{
"messagePk": 63336
}
Returns:
{
"messagePk": 63336,
"subject": "Prior Art Review for Patent Claims 416 and 571",
"sender": "example@example.com",
"recipients": "recipient@example.com",
"receivedDate": "2025-11-11 15:59:12",
"meetingStartDate": "2025-11-11T15:00:00.000Z",
"meetingEndDate": "2025-11-11T16:00:00.000Z",
"transcriptId": "-8929133086933914113",
"fullText": "the meeting focused on reviewing prior art for patent claims...",
"metadata": {
"language": "auto",
"status": true,
"autoProcessed": true,
"isKept": true,
"eventSummary": null
}
}
3. search_meeting_transcripts
Full-text search across transcripts.
Parameters:
query(required): Search query (FTS5 syntax supported)startDate(optional): Filter after this dateendDate(optional): Filter before this datelimit(optional, default: 20): Max resultsincludeContext(optional, default: true): Include highlighted excerpts
Example:
{
"query": "neural network AND security",
"limit": 5
}
FTS5 Query Syntax:
word1 AND word2- Both words must be presentword1 OR word2- Either word presentNOT word- Exclude word"exact phrase"- Exact phrase matchword*- Prefix match
Returns:
{
"results": [
{
"messagePk": 62642,
"subject": "Meeting Summary",
"sender": "example@example.com",
"receivedDate": "2025-11-10 23:04:38",
"excerpt": "...discussing <mark>neural network</mark> architectures for <mark>security</mark> applications...",
"relevanceScore": 1.5
}
],
"total": 5
}
4. get_transcript_statistics
Get overview statistics.
Parameters: None
Returns:
{
"totalTranscripts": 233,
"calendarMeetings": 37,
"adHocMeetings": 196,
"keptTranscripts": 228,
"deletedTranscripts": 5,
"withFullText": 225,
"dateRange": {
"earliest": "2024-09-01 10:00:00",
"latest": "2025-11-11 15:59:12"
},
"topSenders": [
{
"email": "colleague@example.com",
"count": 45
}
]
}
Data Sources
Databases Used
-
messages.sqlite- Transcript metadata- Location:
~/Library/Containers/com.readdle.SparkDesktop.appstore/Data/Library/Application Support/Spark Desktop/core-data/messages.sqlite - Tables:
messages,meetTranscriptEvent - Size: ~178 MB
- Location:
-
search_fts5.sqlite- Full transcript text- Location:
~/Library/Containers/com.readdle.SparkDesktop.appstore/Data/Library/Application Support/Spark Desktop/core-data/search_fts5.sqlite - Table:
messagesfts(FTS5 full-text index) - Size: ~232 MB
- Location:
Transcript Types
Calendar-Based Meetings (37 transcripts):
- Scheduled meetings with calendar event info
- Stored in
meetTranscriptEventtable - Have
eventSummaryfield
Ad-Hoc Meetings (196 transcripts):
- User-initiated transcriptions
- Not linked to calendar events
- This is the primary use case for most users
Total: 228 kept transcripts (233 including deleted)
Safety Features
- ✅ Read-only database access
- ✅ No writes or modifications
- ✅ Graceful handling of schema changes
- ✅ Safe concurrent access with Spark
Troubleshooting
"Failed to connect to Spark databases"
- Verify Spark Desktop is installed (App Store version)
- Check database paths exist:
ls -la ~/Library/Containers/com.readdle.SparkDesktop.appstore/Data/Library/Application\ Support/Spark\ Desktop/core-data/
No transcripts found
- Make sure you have meeting transcripts in Spark
- Check that transcripts are marked as "kept" (not deleted)
- Try running
get_transcript_statisticsto see counts
Empty transcript text
Some transcripts may not have full text cached locally:
- Recent transcripts may still be syncing
- Deleted transcripts have no content
- Check
hasFullTextfield in list results
Development
# Install in development mode
pip install -e .
# Run tests (if you add them)
pytest
Future Enhancements
See PLAN.md for detailed roadmap, including:
- General email search and processing
- Alternative data access methods (API, IMAP)
- Additional analytics and insights
- Export capabilities
License
MIT
