Local session tracker and semantic search for AI coding assistants
Project description
Spooling
Local session tracker and semantic search for AI coding assistants.
Track your AI coding sessions across OpenAI Codex CLI, GitHub Copilot, Cursor, Windsurf, Kiro, Google Antigravity, and opencode, all in one place. Get usage stats, cost estimates, per-provider breakdowns, semantic search via pgvector, and a built-in AI chat agent to explore your history.
Website: spooling.ai
Prerequisites
- Python 3.11+
- Node.js 18+
- Docker (for PostgreSQL + pgvector)
- pipx or uv (optional, alternative install methods)
- Ollama (optional, for free local AI chat) or an Anthropic API key
How it works
Four commands. Zero cloud.
01 Clone & start the database
git clone https://github.com/sashimiboi/spooling && cd spooling
docker compose up -d # postgres + pgvector :5434
02 Install backend + UI
Choose one:
# pip (recommended)
python3 -m venv .venv && source .venv/bin/activate
pip install -e .
# pipx
pipx install .
# uv
uv sync
Then install the UI:
cd ui && npm install && cd ..
03 Detect providers & sync
spooling init # scan for available providers
spooling sync # embed every session into pgvector
04 Search & explore
spooling ui # API :3002 · MCP :3004 · GUI :3003
spooling search "that redis race condition"
Open http://localhost:3003 and you're in.
Connect Spooling to your AI coding agent
spooling ui automatically exposes an MCP server at http://127.0.0.1:3004/mcp (HTTP streamable transport). Any MCP-speaking agent can connect to it and pull context from your local KB mid-conversation. The agent gets tools like spooling_search, spooling_recent_sessions, spooling_get_session, spooling_workspace_stats, and spooling_top_projects.
Cursor / Windsurf / Codex / Antigravity
Edit your client's MCP config (usually ~/.cursor/mcp.json, ~/.codeium/windsurf/mcp_config.json, or the equivalent) and add:
{
"mcpServers": {
"spooling": {
"type": "http",
"url": "http://127.0.0.1:3004/mcp"
}
}
}
Restart the client. The spooling server and its tools should appear in the MCP panel.
Generic JSON-RPC smoke test
curl -s http://127.0.0.1:3004/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | jq
Should return the five spool_* tools. If you get "connection refused", spooling ui is not running (or its ports got squatted, run lsof -ti :3004 | xargs kill -9 and retry).
CLI Usage
All CLI commands require the venv to be active and the database running.
source .venv/bin/activate
spooling init
Check database connection and show which AI coding tool providers are detected on your system. This scans default paths for Codex CLI, GitHub Copilot, Cursor, and Windsurf session data.
spooling init
spooling sync
Parse and ingest sessions from all connected providers into the database. Chunks and embeds message content into pgvector for semantic search.
spooling sync # Full sync with embeddings
spooling sync --no-embed # Skip embeddings (faster initial sync)
spooling sync -p cursor # Sync only Cursor sessions
spooling sync -p codex # Sync only Codex CLI sessions
spooling stats
Show usage statistics - sessions, messages, tool calls, tokens, costs, broken down by project and day.
spooling stats # Overview + last 7 days
spooling stats --week # Weekly breakdown
spooling stats --days 30 # Last 30 days
spooling search <query>
Semantic search across all your session history using natural language.
spooling search "snowflake connector"
spooling search "authentication bug" -n 5
spooling search "database migration" -p ~/myproject
Options:
-n, --limit- Number of results (default: 10)-p, --project- Filter by project name
spooling watch
Watch all connected provider directories for new session data and auto-sync in real time.
spooling watch
spooling serve
Start the API server only (for when you want to run the GUI separately).
spooling serve # Default: http://127.0.0.1:3002
spooling serve --port 8080 # Custom port
spooling serve --host 0.0.0.0 # Bind to all interfaces
spooling ui
Start the API server, the MCP HTTP server, and the Next.js UI together.
spooling ui
spooling mcp
Start the Spooling MCP server on its own. Defaults to streamable-HTTP at
http://127.0.0.1:3004/mcp, which any MCP-compatible agent can connect to
by URL. spooling ui already launches this alongside the API, so you only
need to run it directly when you want the MCP server without the GUI.
spooling mcp # streamable-HTTP at http://127.0.0.1:3004/mcp (default)
spooling mcp --stdio # stdio transport, for stdio-only clients
Spooling Cloud (optional)
By default Spooling stays 100% local. If you also want your sessions in the
hosted workspace at spooling.ai (so teammates can
search the same pool, or you can chat with sessions from any browser),
the CLI ships with a spooling cloud subcommand.
One-time setup
-
Mint an API key in the GUI at
app.spooling.ai/settings/api-keys(looks likesk_live_...). -
Save it locally:
spooling cloud login --key sk_live_...
The key is stored at
~/.config/spooling/cloud.jsonwith0600perms. You can override the API base with--api-urlor theSPOOLING_CLOUD_URLenv var (default:https://api.spooling.ai).
Push once
Send the most recent local sessions up to the cloud:
spooling push # 100 sessions, batches of 20
spooling push --limit 500 # bigger backfill
The server upserts by session id, so re-running is safe.
Watch (continuous push)
Stream new and updated sessions to the cloud on a timer. Stop with Ctrl+C.
spooling cloud watch # every 60s, 1000 sessions/cycle
spooling cloud watch --interval 30 # tighter cadence
spooling cloud watch --lookback 60 # widen the overlap window if you edit old sessions
What it does each cycle:
- Reads
last_push_atfrom~/.config/spooling/cloud.json. - Queries local sessions where
started_at >= last_push_at - lookback(default lookback: 10 minutes, so messages appended to an in-progress session get re-uploaded). - POSTs to
/v1/sessions/batchin chunks of--batch(default 20). - Advances
last_push_atto the cycle start on success.
Cycles with no new work are silent. If a push fails the watermark is not advanced, so the next cycle retries the same window.
Status / logout
spooling cloud status # show what is in the cloud + stored API base
spooling cloud logout # remove the stored API key
Auto-start at login (macOS)
Run spooling cloud watch as a launchd agent so it survives reboots:
cat > ~/Library/LaunchAgents/ai.spooling.cloud-watch.plist <<'PLIST'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key><string>ai.spooling.cloud-watch</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/spooling</string>
<string>cloud</string>
<string>watch</string>
</array>
<key>RunAtLoad</key><true/>
<key>KeepAlive</key><true/>
<key>StandardOutPath</key><string>/tmp/spooling-cloud-watch.log</string>
<key>StandardErrorPath</key><string>/tmp/spooling-cloud-watch.log</string>
</dict>
</plist>
PLIST
launchctl load ~/Library/LaunchAgents/ai.spooling.cloud-watch.plist
(Adjust the spooling path with which spooling if it lives elsewhere.)
MCP Endpoint
Spooling exposes an MCP server so any AI agent can query your session history
as a context source. The server runs over streamable-HTTP at
http://127.0.0.1:3004/mcp and is started automatically alongside spooling ui.
Drop this into your MCP client config (~/.mcp.json, Cursor,
Codex, or any other streamable-HTTP capable agent):
{
"mcpServers": {
"spooling": {
"url": "http://127.0.0.1:3004/mcp"
}
}
}
Or register it with an MCP client's config file.
The Settings page in the GUI shows the endpoint URL, a copy button, and the full config snippet so you don't have to remember it.
Tools exposed
| Tool | Purpose |
|---|---|
list_traces |
Recent Spooling traces, filterable by provider/project |
get_trace |
Full detail for one trace: header, spans, eval scores |
search_sessions |
Semantic search over embedded session chunks |
get_stats |
Top-line stats: traces, tokens, cost, errors |
get_top_vendors |
Most-used external vendors by tool-call count |
list_evals |
Recent eval runs, optionally filtered by rubric |
list_rubrics |
All configured Strands eval rubrics |
run_eval |
Run a rubric against a trace and persist the result |
Stdio (legacy clients)
For MCP clients that only speak stdio, run spooling mcp --stdio and register
it with the command-based form:
# MCP config for stdio transport
GUI
The Spooling GUI runs on http://localhost:3003 and includes:
| Page | Description |
|---|---|
| Dashboard | Overview stats, per-provider breakdown, daily activity chart, projects, top tools, recent sessions |
| Sessions | Browse all sessions with provider labels, filtering, click into any session for full conversation view |
| Search | Semantic search across all session history with similarity scores |
| Analytics | Charts for daily usage, cost trends, token usage, tool distribution, filterable by provider (AG Charts) |
| Chat | AI assistant that can answer questions about your session data (RAG-powered) |
| Connections | Connect/disconnect AI coding tools (Codex, Copilot, Cursor, Windsurf) |
| Settings | Configure the AI chat provider (Ollama or Anthropic) |
Running the GUI
# Terminal 1: API server
source .venv/bin/activate
spooling serve
# Terminal 2: Next.js dev server
cd ui
npm run dev
Or use spooling ui to start both at once.
Chat Agent Setup
The chat page lets you ask questions about your coding sessions in natural language. It uses RAG - retrieves relevant context from pgvector before answering.
Option A: Ollama (free, local)
# Install Ollama
brew install ollama
# Start the server
ollama serve
# Pull a model
ollama pull gemma3:4b
Go to Settings in the GUI and select Ollama. The model will auto-detect.
Option B: Anthropic API (bring your own key)
Go to Settings in the GUI, select Anthropic, and paste your API key from console.anthropic.com.
Available models: Sonnet, Haiku, Opus.
Architecture
spooling/
├── docker-compose.yml # PostgreSQL + pgvector
├── init.sql # Database schema
├── pyproject.toml # Python package config
├── spooling/ # Python backend
│ ├── cli.py # Click CLI
│ ├── config.py # Configuration
│ ├── db.py # Database connection
│ ├── providers/ # Provider plugins (codex, copilot, cursor, windsurf)
│ ├── parser.py # Session JSONL parser
│ ├── embeddings.py # sentence-transformers (all-MiniLM-L6-v2)
│ ├── ingest.py # Sync pipeline
│ ├── search.py # pgvector semantic search
│ ├── stats.py # Usage statistics
│ ├── watcher.py # File watcher (watchdog)
│ ├── agent.py # Chat agent (Ollama + Anthropic)
│ └── server.py # FastAPI API server
└── ui/ # Next.js frontend
├── next.config.js # API proxy to :3002
└── src/
├── components/ # shadcn/ui components
├── lib/ # API helpers
└── app/(app)/ # Pages (dashboard, sessions, search, etc.)
Stack
| Layer | Technology |
|---|---|
| Database | PostgreSQL 16 + pgvector (Docker) |
| Embeddings | sentence-transformers / all-MiniLM-L6-v2 (local) |
| Backend | Python, FastAPI, Click |
| Frontend | Next.js 14, shadcn/ui, Tailwind CSS, AG Charts |
| Chat AI | Ollama (local) or Anthropic API |
Ports
| Service | Port |
|---|---|
| PostgreSQL | 5434 |
| API Server | 3002 |
| GUI | 3003 |
| MCP Server (streamable-HTTP) | 3004 |
Environment Variables
All optional - defaults work out of the box for local development.
| Variable | Default | Description |
|---|---|---|
SPOOLING_DB_HOST |
localhost |
Database host |
SPOOLING_DB_PORT |
5434 |
Database port |
SPOOLING_DB_NAME |
spooling |
Database name |
SPOOLING_DB_USER |
spooling |
Database user |
SPOOLING_DB_PASSWORD |
spooling |
Database password |
SPOOLING_EMBEDDING_MODEL |
all-MiniLM-L6-v2 |
Sentence transformer model |
SPOOLING_UI_HOST |
127.0.0.1 |
API server host |
ANTHROPIC_API_KEY |
- | Anthropic API key (alternative to setting in UI) |
Supported Providers
| Provider | Data Location | Format |
|---|---|---|
| JSONL Sessions | ~/.sessions/projects/ |
UUID-named JSONL files with conversation history, tool calls, git context |
| OpenAI Codex CLI | ~/.codex/sessions/ |
rollout-*.jsonl files organized by date |
| GitHub Copilot | ~/Library/Application Support/Code/User/workspaceStorage/ |
Chat session JSON from VS Code |
| Cursor | ~/Library/Application Support/Cursor/User/workspaceStorage/ |
Chat and composer sessions from SQLite |
| Windsurf | ~/Library/Application Support/Windsurf/User/workspaceStorage/ |
Chat and Cascade sessions from SQLite |
| Kiro | ~/Library/Application Support/Kiro/User/workspaceStorage/ |
AWS Kiro chat and agent sessions from SQLite |
| Google Antigravity | ~/Library/Application Support/Antigravity/User/workspaceStorage/ |
Antigravity chat and agent sessions from SQLite |
| opencode | ~/.local/share/opencode/opencode.db |
sst/opencode SQLite database with session/message/part tables (Vercel AI SDK part shape) |
Run spooling init to see which providers are detected on your system.
No data is sent to external servers. Everything runs locally.
Project details
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 spooling-0.1.4.tar.gz.
File metadata
- Download URL: spooling-0.1.4.tar.gz
- Upload date:
- Size: 130.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4a8f831aa89d5d948f6eff323045ce950efe9037b70eec0073c51ed186334dff
|
|
| MD5 |
248e9fbceba3d946589960e08d540a18
|
|
| BLAKE2b-256 |
78313875aad4d02b5f524ff3355024e611f8dcdd43ddb7deab172816129cafd9
|
Provenance
The following attestation bundles were made for spooling-0.1.4.tar.gz:
Publisher:
release.yml on sashimiboi/spooling
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
spooling-0.1.4.tar.gz -
Subject digest:
4a8f831aa89d5d948f6eff323045ce950efe9037b70eec0073c51ed186334dff - Sigstore transparency entry: 1780728787
- Sigstore integration time:
-
Permalink:
sashimiboi/spooling@3d7934fe3b0226c7c0a4db8d32b98f8140dc652a -
Branch / Tag:
refs/tags/v0.1.4 - Owner: https://github.com/sashimiboi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3d7934fe3b0226c7c0a4db8d32b98f8140dc652a -
Trigger Event:
push
-
Statement type:
File details
Details for the file spooling-0.1.4-py3-none-any.whl.
File metadata
- Download URL: spooling-0.1.4-py3-none-any.whl
- Upload date:
- Size: 141.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
501a8ffbb20c936bb44180bf0f65da403aeab7afc8fff77502fb12c8d9df29a5
|
|
| MD5 |
39ffe1a7325f63bf6071d0e6f00c4d35
|
|
| BLAKE2b-256 |
6535973091174599bd411a38bec2684db8f8b56acb9ff3b2bdfac166c0766db9
|
Provenance
The following attestation bundles were made for spooling-0.1.4-py3-none-any.whl:
Publisher:
release.yml on sashimiboi/spooling
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
spooling-0.1.4-py3-none-any.whl -
Subject digest:
501a8ffbb20c936bb44180bf0f65da403aeab7afc8fff77502fb12c8d9df29a5 - Sigstore transparency entry: 1780729020
- Sigstore integration time:
-
Permalink:
sashimiboi/spooling@3d7934fe3b0226c7c0a4db8d32b98f8140dc652a -
Branch / Tag:
refs/tags/v0.1.4 - Owner: https://github.com/sashimiboi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3d7934fe3b0226c7c0a4db8d32b98f8140dc652a -
Trigger Event:
push
-
Statement type: