google-activity-assistant
This server provides MCP tools for querying your locally ingested Google Takeout activity data, including Search and YouTube history. It operates entirely offline with no Google network calls.
search_activity: Perform full-text keyword search across activity entries (titles, URLs, channels), with optional filters for product type (search, youtube, maps, chrome, assistant, play, other), date range, and result limit (1-100, default 20). Returns matching entries with citations. Use an empty query to list recent activity.
get_activity_stats: Get summary statistics like entry counts, date range, and product distribution to check import status and coverage.
get_db_info: Return the local database path and confirm existence.
Allows agents to search and analyze your YouTube activity history (watch and search) from a local Google Takeout export, with full-text search and date/product filters.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@google-activity-assistantsearch my activity history for 'MCP servers'"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Google Activity Assistant
Local-first tools over your Google Takeout activity — keyword search in SQLite, MCP tools for any compatible client, and an optional local web dashboard.
Not a live Google API. You export Takeout once (or periodically), ingest locally, then query with Claude Desktop, Cursor, Grok, or
gaa search.
Doc | Use when |
Full walkthrough: what it can/can’t do, Takeout, CLI, MCP, FAQ | |
Drive + Data Portability OAuth loop | |
Short MCP + export reference | |
Privacy / what not to commit | |
Dev setup & PRs |
Why
Mainstream chatbots don’t have your Search/YouTube history. This project turns a Takeout export into:
Structured + full-text search (SQLite + FTS5)
MCP tools so agents can answer with citations from your real activity
Optional local dashboard (timeline / journeys)
Privacy-first: processing stays on disk under data/ (gitignored).
Related MCP server: Hoard
Similar work & positioning
This is not “the only personal-data project” and not “the only MCP.” Adjacent work exists; the packaging here is specific.
Category | Examples / reality | Overlap with this repo |
Google Takeout itself | Official takeout.google.com | Data source only |
Offline Takeout parsers / privacy research | Scripts, blogs, personal-data tooling | Ingest inspiration |
Personal RAG (“chat with my notes/PDFs”) | Common portfolio pattern | Same idea (local memory + LLM), different corpus |
MCP for browser history | e.g. local browser-history MCP servers | Same shape (history → tools), not Google Takeout |
Google Workspace / product MCPs | Gmail, Drive, Calendar, Looker, SecOps, etc. | Live product APIs — not My Activity dumps |
Live “My Activity API” for third parties | Does not exist as a simple public stream | Why we use Takeout + local DB |
What this project emphasizes
Takeout-first Search / YouTube history (JSON and HTML history files)
SQLite + FTS5 as system of record (portable, offline)
MCP tools so any compatible host can query your export with citations
Explicit honesty: no live My Activity sync, multi-GB media exports out of scope for v0.1
How to describe it (interviews / README pitch)
Prefer: “Most Google MCPs hit Drive/Gmail; this wires Takeout My Activity / YouTube history into a local index and MCP tools.”
Avoid: “Nobody has ever built personal history + AI.”
Features (v0.1)
Feature | Status |
Ingest Takeout JSON (My Activity / YT history) | ✅ |
Ingest Takeout HTML watch/search history | ✅ |
Selective zip extract (skips huge media) | ✅ |
SQLite + FTS5 keyword search | ✅ |
Hybrid search (FTS + embeddings, RRF) | ✅ v0.2 |
Embeddings: hashing default; FastEmbed optional | ✅ |
CLI: | ✅ |
MCP: search (modes), stats, | ✅ |
Insights (top channels/searches, by hour/weekday/month) | ✅ v0.3 |
Period summary, on this day, journeys, similar, random | ✅ v0.3 |
Local CSV/JSON export | ✅ v0.3 |
Local FastAPI + React dashboard ( | ✅ |
Synthetic fixtures for demos/tests | ✅ |
Drive auto-import of Takeout zips | ✅ v0.4 |
Data Portability API export → download → ingest | ✅ v0.4 |
Quick start
Requirements
Python 3.12+
uv (recommended)
git clone https://github.com/Daemon-Killer/google-activity-assistant.git
cd google-activity-assistant
uv syncSample data (no Google account needed)
uv run gaa ingest-fixtures
uv run gaa reindex # embeddings for hybrid/semantic search
uv run gaa status
uv run gaa search "React Server" # hybrid by default
uv run gaa search "React Server" --mode keyword
uv run gaa insights
uv run gaa on-this-day
uv run gaa journeys
uv run gaa random
uv run gaa export ./data/export.csvOptional better semantic model (ONNX, no PyTorch):
uv sync --extra semantic
uv run gaa reindex # rebuilds missing rows with FastEmbed when availableYour Takeout
Open takeout.google.com
Prefer My Activity (Search + YouTube) and/or YouTube → History, format JSON if available (HTML also works)
Avoid exporting full Photos/video libraries if you only want activity search
Ingest:
uv run gaa ingest /path/to/takeout.zip
# or extracted folder
uv run gaa ingest /path/to/Takeout
uv run gaa statusReal exports and data/activity.db are gitignored. Never commit them.
Automate re-import (Drive / Portability)
Manual zip ingest is the fallback. For a real loop, use OAuth once, then:
# docs/AUTOMATION.md — Cloud OAuth client + .env
uv run gaa google login --preset all
uv run gaa google refresh # new Takeout files on Drive → ingest
uv run gaa google export-start -r youtube # official Portability job
uv run gaa google export-status JOB_ID
uv run gaa google export-download JOB_IDFull setup: docs/AUTOMATION.md
MCP (Claude / Cursor / Grok / …)
Start the stdio server:
uv run gaa serve-mcpGrok Build (~/.grok/config.toml)
[mcp_servers.google_activity]
command = "uv"
args = [
"run",
"--directory",
"/absolute/path/to/google-activity-assistant",
"gaa",
"serve-mcp",
]
enabled = true
startup_timeout_sec = 60Claude Desktop
claude_desktop_config.json:
{
"mcpServers": {
"google-activity": {
"command": "uv",
"args": [
"run",
"--directory",
"/absolute/path/to/google-activity-assistant",
"gaa",
"serve-mcp"
]
}
}
}Tools
Tool | Purpose |
| Search with |
| Counts / date range / embedding coverage |
| Local paths only |
| Ingest a local Takeout zip/folder path |
| Build vectors for hybrid/semantic search |
| Top channels/searches, hour/weekday heat |
| Counts + samples for a date range |
| Same calendar day across years |
| Search→watch pairs (local heuristic) |
| Embedding neighbors for a hit id |
| Random rows |
| Write CSV/JSON to a local path |
| Desktop OAuth |
| Auto-ingest new Drive Takeouts |
| Official export API |
After ingest + reindex, ask: “Search my YouTube for romantic Bollywood songs and cite titles + dates.”
Or: “Refresh from Drive, then get_activity_stats.”
Full walkthrough (export, FAQ, demo script): docs/HOW_TO.md · MCP config short ref: docs/MCP_AND_TAKEOUT.md
Local dashboard
# If web/dist is missing:
cd web && npm install && npm run build && cd ..
uv run gaa serve-ui
# → http://127.0.0.1:8788API routes under /api/* (stats, activity list, journeys). Binds to localhost by default.
Project layout
google-activity-assistant/
├── src/google_activity_assistant/
│ ├── cli.py # gaa commands
│ ├── mcp_server.py # FastMCP tools
│ ├── parse_takeout.py # JSON + HTML parsers
│ ├── ingest.py
│ ├── db.py # SQLite + FTS5
│ ├── search.py
│ ├── journeys.py # search→watch proximity
│ └── api.py # FastAPI dashboard API
├── web/ # React + Vite dashboard
├── fixtures/ # synthetic Takeout samples
├── docs/
│ ├── HOW_TO.md # full user guide
│ └── MCP_AND_TAKEOUT.md
├── tests/
└── data/ # gitignored — your DB + exportsDevelopment
uv sync --extra dev
uv run pytestSee CONTRIBUTING.md.
Privacy & license
SECURITY.md — local-first, what not to commit
LICENSE — MIT
Takeout is Google’s official data export. This project is unaffiliated with Google.
Roadmap
Better multi-product My Activity coverage (Chrome, Maps activity)
Background poller for Portability jobs (still ~daily, not live)
Packaging / one-command installers
PRs welcome.
Available Tools
3 toolsget_activity_statsA
Return counts and date range for the local activity database. Use this to check whether Takeout data has been imported and which products exist.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must disclose behavior. It adds context that the database is local and that it checks import status, implying a safe read-only operation, but it doesn't explicitly state side-effect-free behavior, authentication requirements, or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two crisp sentences: the first states the core function, the second gives a concrete use case. No waste, front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter stats tool with an output schema, the description sufficiently covers purpose, usage context, and domain context (local database, Takeout import). There are no meaningful gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the baseline is 4 per the rubric. The description naturally introduces no parameter confusion, and the output schema handles return value documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the tool returns counts and date range for the local activity database, which is a specific action on a specific resource. It differentiates from sibling tools by focusing on aggregate statistics rather than searching (search_activity) or general database info (get_db_info).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells the user to use this tool to check whether Takeout data has been imported and which products exist, providing a clear use case. It doesn't name alternatives, but the context makes it distinct from siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_db_infoA
Return local DB path and whether the file exists (no Google network calls).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full burden. It discloses a key behavioral trait: no Google network calls are made, which is critical for an agent to know. While it doesn't explicitly state 'read-only' or describe error handling, the simple return of path and existence suggests a safe, non-mutating operation, and offering the no-network detail is valuable beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that conveys purpose, scope, and a key constraint without any redundant or extraneous information. It is front-loaded with the primary action and resource.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parameters and an output schema present, the description sufficiently explains what the tool does and its distinguishing trait (no network calls). This is complete enough for an agent to select it appropriately among siblings, as it clearly covers the tool's role and usage context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the description has no parameter semantics to add beyond the empty schema. According to the baseline for 0 params, a score of 4 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function with a specific verb ('return') and identifies the exact resources: the local DB path and file existence. It distinguishes itself from sibling tools by explicitly noting it makes 'no Google network calls', which contrasts with the likely network-based search and activity tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context: this tool is for local database path and existence checking without network calls. It does not explicitly name alternatives or exclusion criteria, but the 'no Google network calls' phrase implies usage when avoiding network calls is desired, giving reasonable guidance relative to siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_activityA
Search the user's ingested Google activity by keyword (full-text).
Args:
query: Keywords to match against titles/URLs/channels (FTS5).
Use empty string with filters to list recent activity.
product: Optional filter: search | youtube | maps | chrome | assistant | play | other
start_date: Optional ISO date/time lower bound (e.g. 2024-01-01)
end_date: Optional ISO date/time upper bound (e.g. 2024-12-31)
limit: Max hits (1–100, default 20)
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes | ||
| product | No | ||
| end_date | No | ||
| start_date | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden. It clearly indicates this is a search operation, which implies read-only, and adds useful context like 'ingested' data and FTS5. It does not explicitly state non-mutating behavior or edge cases, but overall is transparent for a search tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is appropriately sized for a 5-parameter tool. It opens with a one-sentence purpose, then uses a clear, structured Args list. Every sentence adds value, and there is no fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (5 params, 1 required), the description covers all parameters, usage context, and a special case. Since an output schema exists, return values need not be explained. The tool context and sibling names are clear from the description.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage, but the description fully compensates. It explains each parameter in plain language, provides examples for date formats, enumerates allowed product values, and specifies limits/defaults. This is exactly the needed semantic enrichment.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Search the user's ingested Google activity by keyword'), clearly distinguishing it from sibling tools like get_activity_stats and get_db_info. It also notes 'full-text' search, clarifying the method.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit context for using the tool, including a specific scenario ('Use empty string with filters to list recent activity'). However, it does not compare to alternatives or state when not to use this tool, such as when statistics or database info would be more appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
3 tool updates
v0.1.0- First observed
get_activity_stats - First observed
get_db_info - First observed
search_activity
TDQS
Each tool has a clearly distinct purpose: search_activity performs full-text search, get_activity_stats provides aggregate counts and date range, and get_db_info returns local database metadata. There is no overlap or ambiguity between them.
All tool names follow a consistent verb_noun snake_case pattern: search_activity, get_activity_stats, get_db_info. The naming is predictable and uniform.
With 3 tools, the set is at the lower end of the typical range but each tool serves a necessary role for the server's purpose: searching, understanding the dataset, and checking database state. It feels slightly thin but not unreasonable.
The domain is searching Google activity data. The set covers the core need (search), provides statistical overview (stats), and exposes database status (db_info). There are minor gaps such as no explicit ability to list all products or fetch a single record by ID, but these are workable via the existing tools.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Search your AI chat history (ChatGPT, Claude, Codex) from any MCP client. Remote, private, read-only
- MysocialOAuthio.mysocial
Social media MCP server: your Instagram, TikTok, YouTube, LinkedIn and Threads history for your AI.
1 A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceAn MCP server that interfaces with the Rewind.ai SQLite database to provide access to audio transcripts, screen OCR data, and activity tracking. It enables AI models to search personal memory, retrieve past conversations, and analyze application usage history.19-
- AlicenseNot gradedqualityDmaintenanceLocal MCP server for indexing personal knowledge into SQLite with hybrid search, chunk-level citations, memory tools, and agent orchestration.4MIT
- AlicenseNot gradedqualityDmaintenanceMCP server that exposes local Granola meeting notes, summaries, and transcripts to AI assistants via SQLite-backed search and retrieval.MIT
- AlicenseNot gradedqualityDmaintenancePersonal memory MCP server backed by SQLite FTS5 BM25 search with temporal reranking.121MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Daemon-Killer/google-activity-assistant'
If you have feedback or need assistance with the MCP directory API, please join our Discord server