Skip to main content
Glama
Daemon-Killer

google-activity-assistant

README.md
# Google Activity Assistant

**Local-first** tools over **your** [Google Takeout](https://takeout.google.com/) 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](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)

| Doc | Use when |
|-----|----------|
| **[docs/HOW_TO.md](docs/HOW_TO.md)** | Full walkthrough: what it can/can’t do, Takeout, CLI, MCP, FAQ |
| [docs/AUTOMATION.md](docs/AUTOMATION.md) | Drive + Data Portability OAuth loop |
| [docs/MCP_AND_TAKEOUT.md](docs/MCP_AND_TAKEOUT.md) | Short MCP + export reference |
| [SECURITY.md](SECURITY.md) | Privacy / what not to commit |
| [CONTRIBUTING.md](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).

---

## 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](https://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](https://docs.astral.sh/uv/) (recommended)

```bash
git clone https://github.com/Daemon-Killer/google-activity-assistant.git
cd google-activity-assistant
uv sync
```

### Sample data (no Google account needed)

```bash
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):

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

### Your Takeout

1. Open [takeout.google.com](https://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:

```bash
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:

```bash
# 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](docs/AUTOMATION.md)**

---

## MCP (Claude / Cursor / Grok / …)

Start the stdio server:

```bash
uv run gaa serve-mcp
```

### Grok Build (`~/.grok/config.toml`)

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

```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](docs/HOW_TO.md) · **MCP config short ref:** [docs/MCP_AND_TAKEOUT.md](docs/MCP_AND_TAKEOUT.md)

---

## Local dashboard

```bash
# 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

```bash
uv sync --extra dev
uv run pytest
```

See [CONTRIBUTING.md](CONTRIBUTING.md).

---

## Privacy & license

- [SECURITY.md](SECURITY.md) — local-first, what not to commit  
- [LICENSE](LICENSE) — **MIT**

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.

TDQS

A4.4/5.0

Scored across 3 tools

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