Thesis
Enables AI agents to access and synthesize per-ticker financial research data from multiple providers within a private, self-hosted workspace.
README
Thesis
Self-hosted per-ticker research workspace for retail investors. Capture content from anywhere via the PWA share sheet. The workspace exposes an MCP server so your own agent (Claude, ChatGPT, Codex CLI) does the synthesis. Single-user MVP — your data stays in your Cloudflare account.
Research aid, not advice. The agent writes; you decide.
Architecture
┌─────────────────────────────────────────────────────────────┐
│ Browser / Mobile │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ PWA (Vite + React + Tailwind) │ │
│ │ - Web Share Target - Workspace tabs │ │
│ │ - Tiptap rich text - Component renderer │ │
│ └────────────────────┬─────────────────────────────────┘ │
└───────────────────────┼─────────────────────────────────────┘
│ /api/* /mcp
┌───────────────────────▼─────────────────────────────────────┐
│ Cloudflare Worker (Hono) │
│ ┌───────────────────────────────┐ ┌──────────────────┐ │
│ │ Workspace Durable Object │ │ WorkspaceAgent │ │
│ │ SQLite + embedding BLOB │ │ DO (Slice 4) │ │
│ │ 30 MCP tools │ │ nightly cron │ │
│ └───────────────────────────────┘ └──────────────────┘ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ Data providers │ │
│ │ Yahoo Stooq EDGAR Finnhub FRED │ │
│ └───────────────────────────────────────────────────────┘ │
│ ┌──────────────┐ ┌────────────┐ ┌──────────────────────┐ │
│ │ R2 (docs) │ │ KV cache │ │ CF AI Gateway │ │
│ └──────────────┘ └────────────┘ └──────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Future:
┌─────────────────────────┐
│ Auth app (Slice 5) │
│ better-auth + Postgres │
│ Docker → Fly.io │
└─────────────────────────┘
Quick start
git clone <repo> && cd invest
npm install
cp apps/worker/.dev.vars.example apps/worker/.dev.vars
# Edit apps/worker/.dev.vars — set THESIS_BEARER_TOKEN, optionally FINNHUB_API_KEY + FRED_API_KEY
# Terminal 1 — worker on :8787
npm run dev:worker
# Terminal 2 — PWA on :5173 (proxies /api and /mcp to :8787)
npm run dev:pwa
Open http://localhost:5173. Add a bearer token in Settings (use the value from .dev.vars).
Connect an agent (BYOA)
GET /api/mcp-info returns the MCP endpoint, tool list, and auth instructions. The Settings page renders the same info with copy-ready URLs.
- Streamable HTTP (preferred):
POST /mcp,GET /mcp - Legacy SSE:
GET /mcp/sse,POST /mcp/messages - Auth:
Authorization: Bearer <token>or?token=<token>
Env vars
All secrets go in apps/worker/.dev.vars for local dev. See apps/worker/.dev.vars.example.
| Var | Required | Notes |
|---|---|---|
THESIS_BEARER_TOKEN |
Yes | Shared secret for all API + MCP requests |
FINNHUB_API_KEY |
Optional | Free at finnhub.io — enables fundamentals, earnings, news |
FRED_API_KEY |
Optional | Free at fred.stlouisfed.org — enables macro tiles |
STOOQ_API_KEY |
Optional | 2025 captcha gate — skip to use Yahoo fallback |
ANTHROPIC_API_KEY |
Slice 4 | Required for embedded agent nightly runs |
CF_AIG_TOKEN |
Slice 4 | Cloudflare AI Gateway token |
CF_ACCOUNT_ID |
Slice 4 | Your CF account ID |
AGENT_MONTHLY_TOKEN_CAP |
Optional | Default 200000 tokens/month per workspace |
Slices shipped
Full decision log and slice history: docs/roadmap/GRILL-ME.md
| Slice | Description | Status |
|---|---|---|
| W0–W5 | Foundation, authorship, synthesis, lenses, evidence, data | ✅ |
| Slice 0 | Stabilisation, Stooq doc, EDGAR retry, theme-color | ✅ |
| Slice 1 | Composition primitive — layout_json + set_layout MCP |
✅ |
| Slice 1.5 | Full slot map + extended component vocab | 🔄 |
| Slice 2 | Retrieval — embeddings (BLOB cosine), retrieve tool, backfill |
✅ |
| Slice 3 | Temporal — catch_up, reactivate_check, Catch Up UI |
✅ |
| Slice 4 | Embedded agent — WorkspaceAgent DO, nightly cron, AI Gateway | ✅ |
| Slice 5 | Auth — better-auth, Dockerised auth app | Designing |
| Slice 6 | Chat surface | Designing |
| Slice 7 | Cross-ticker Vectorize tier | Designing |
Smoke tests
Categorised smoke tests live in smoke/.
# All Playwright specs (UI + E2E)
npm run smoke
# Individual shell scripts (worker API — no browser needed)
bash smoke/ingestion/capture.smoke.sh
bash smoke/claims/claims.smoke.sh
bash smoke/agent/agent.smoke.sh # needs ANTHROPIC_API_KEY
Deploy
Cloudflare Worker + PWA
# 1. Build PWA into apps/pwa/dist
npm run build:pwa
# 2. Set production secrets (one-time)
cd apps/worker
wrangler secret put THESIS_BEARER_TOKEN
wrangler secret put ANTHROPIC_API_KEY
wrangler secret put CF_AIG_TOKEN
wrangler secret put FINNHUB_API_KEY
wrangler secret put FRED_API_KEY
# 3. Deploy worker + PWA assets
wrangler deploy
The Worker serves the PWA from the same origin. /share-target, /mcp, and /api/* are all first-party.
Full deployment guide including auth-app Docker target, DNS, and post-deploy smoke checks: docs/deployment.md.
Tech stack
| Layer | Tech |
|---|---|
| Worker runtime | Cloudflare Workers + Durable Objects (SQLite) |
| API framework | Hono |
| MCP | Hand-rolled JSON-RPC over HTTP + SSE (30 tools) |
| PWA | Vite 5 + React 18 + Tailwind 3 |
| Rich text | Tiptap |
| Embeddings | Workers AI bge-small-en-v1.5 (384-dim, BLOB cosine) |
| Agent | Plain Durable Object (WorkspaceAgent) + CF AI Gateway |
| Documents | R2 + document_captures join table |
| Shared types | packages/shared (Zod) |
Contributing
- Read
docs/STATUS.md— current state + forward plan - Read
docs/architecture/v2-embedded-agent.md— v2 design - Run
npm run typecheckbefore pushing - Add smoke coverage for new endpoints in
smoke/
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.