Skip to main content
Glama
Daemon-Killer

google-activity-assistant

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.

License: MIT Python 3.12+

Doc

Use when

docs/HOW_TO.md

Full walkthrough: what it can/can’t do, Takeout, CLI, MCP, FAQ

docs/AUTOMATION.md

Drive + Data Portability OAuth loop

docs/MCP_AND_TAKEOUT.md

Short MCP + export reference

SECURITY.md

Privacy / what not to commit

CONTRIBUTING.md

Dev setup & PRs


Why

Mainstream chatbots don’t have your Search/YouTube history. This project turns a Takeout export into:

  1. Structured + full-text search (SQLite + FTS5)

  2. MCP tools so agents can answer with citations from your real activity

  3. 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: ingest, status, search, reindex

MCP: search (modes), stats, import_takeout, reindex_embeddings

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 (serve-ui)

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 sync

Sample 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.csv

Optional better semantic model (ONNX, no PyTorch):

uv sync --extra semantic
uv run gaa reindex   # rebuilds missing rows with FastEmbed when available

Your Takeout

  1. Open takeout.google.com

  2. Prefer My Activity (Search + YouTube) and/or YouTube → History, format JSON if available (HTML also works)

  3. Avoid exporting full Photos/video libraries if you only want activity search

  4. Ingest:

uv run gaa ingest /path/to/takeout.zip
# or extracted folder
uv run gaa ingest /path/to/Takeout
uv run gaa status

Real 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_ID

Full setup: docs/AUTOMATION.md


MCP (Claude / Cursor / Grok / …)

Start the stdio server:

uv run gaa serve-mcp

Grok 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 = 60

Claude 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_activity

Search with mode: keyword | semantic | hybrid (default)

get_activity_stats

Counts / date range / embedding coverage

get_db_info

Local paths only

import_takeout

Ingest a local Takeout zip/folder path

reindex_embeddings

Build vectors for hybrid/semantic search

get_insights

Top channels/searches, hour/weekday heat

summarize_period

Counts + samples for a date range

on_this_day

Same calendar day across years

find_journeys

Search→watch pairs (local heuristic)

similar_activity

Embedding neighbors for a hit id

random_memories

Random rows

export_activity

Write CSV/JSON to a local path

google_login / google_auth_status

Desktop OAuth

list_drive_takeouts / refresh_from_drive_takeouts

Auto-ingest new Drive Takeouts

start_portability_export / get_portability_status / download_portability_job

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:8788

API 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 + exports

Development

uv sync --extra dev
uv run pytest

See CONTRIBUTING.md.


Privacy & license

Takeout is Google’s official data export. This project is unaffiliated with Google.


Roadmap

  1. Better multi-product My Activity coverage (Chrome, Maps activity)

  2. Background poller for Portability jobs (still ~daily, not live)

  3. Packaging / one-command installers

PRs welcome.

Available Tools

3 tools
get_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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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)
ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYes
productNo
end_dateNo
start_dateNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

  1. 3 tool updatesv0.1.0
    • First observedget_activity_stats
    • First observedget_db_info
    • First observedsearch_activity

TDQS

A4.4/5.0
Disambiguation5/5

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.

Naming Consistency5/5

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.

Tool Count4/5

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.

Completeness4/5

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

ActivityMaintained
ResponsivenessNo issues

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

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    An 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
    -

Latest Blog Posts

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