Skip to main content
Glama
faizansid3

workspace-ai

by faizansid3
README.md
# workspace-ai — a reusable AI Integration Platform

An internal, self-hostable version of "ChatGPT Connectors / Claude Integrations."
An AI assistant (Claude Code) discovers and calls **your** tools over MCP; those
tools securely access **your** accounts via OAuth2; a web dashboard lets you
**watch every layer happen**. Gmail is the first provider — the architecture lets
new providers (Drive, Slack, GitHub…) plug in **without touching the core**.

> Built as a learning-first, production-quality project: clean architecture,
> strict typing, full test coverage, and an observability dashboard.

## What it does

- **Sign in with Google** (OAuth2 + OpenID Connect), with refresh tokens
  **encrypted at rest** and transparently auto-refreshed.
- **Five Gmail tools** — list labels, search, read, draft, send — each
  self-describing via JSON Schema.
- **An MCP server** so Claude Code (or Claude Desktop) can discover and call
  those tools on real Gmail.
- **A LangGraph agent** (`run_gmail_agent`) that plans → executes → reflects in a
  loop for multi-step tasks, powered by a local or cloud **Ollama** model.
- **An observability dashboard** (Next.js) — system status, the tool registry,
  OAuth/token state (never secrets), a live event feed, and a **React Flow
  visualizer** of the agent's graph.

## Architecture

Everything hangs off one **Tool Registry** (the single source of truth).
Providers register tools into it; two independent **adapters** expose those same
tools to two "brains."

```mermaid
flowchart TD
    subgraph Clients
      CC[Claude Code / Desktop]
      DASH[Next.js Dashboard<br/>read-only observability]
    end

    subgraph Platform
      REG[(Tool Registry<br/>single source of truth)]
      MCP[MCP Adapter]
      AGENT[LangGraph Agent<br/>plan → execute → reflect]
      AUTH[Auth: OAuth2/OIDC<br/>JWT · encrypted tokens]
      DB[(Database<br/>users · tokens · sessions)]
      API[FastAPI backend]
    end

    subgraph Providers
      GMAIL[Gmail provider<br/>5 tools]
    end

    CC -- MCP/stdio --> MCP
    CC -- delegates multi-step --> AGENT
    MCP --> REG
    AGENT --> REG
    GMAIL -- registers tools --> REG
    MCP --> AUTH
    AGENT --> AUTH
    AUTH --> DB
    GMAIL -- calls --> GAPI[Gmail API]
    AGENT -- LLM calls --> OLLAMA[Ollama<br/>local / cloud]
    DASH -- GET /api/* --> API
    API --> REG
    API --> DB
```

**Dependency rule:** `core` depends on nothing; providers and both adapters
depend on `core`; the adapters never depend on each other. That one-directional
rule is what makes the platform extensible.

See [`docs/architecture/`](docs/architecture/) for the full blueprint, request
lifecycles (with sequence diagrams), and per-subsystem design notes.

## Tech stack

**Backend:** Python 3.11 · FastAPI · SQLAlchemy 2.0 + Alembic · Pydantic ·
LangGraph · MCP SDK · Ollama · structlog · `uv` · `ruff` · `mypy --strict`
**Frontend:** Next.js 16 · React 19 · TypeScript · Tailwind v4 · React Flow

## Quick start

```bash
uv sync                              # install Python deps
cp .env.example .env                 # then fill in Google OAuth creds + secrets

uv run alembic upgrade head          # create the database
uv run uvicorn apps.api.main:app --reload    # backend at http://localhost:8000
# open http://localhost:8000 → "Connect Gmail" (one-time login)

cd apps/dashboard && npm install && npm run dev   # dashboard at http://localhost:3000
```

Try things without a browser:

```bash
uv run python scripts/try_gmail.py                  # call Gmail tools on your inbox
uv run python scripts/mcp_smoke.py                  # talk MCP like Claude Code does
OLLAMA_MODEL=llama3.2 uv run python scripts/try_agent.py "list my gmail labels"
```

The MCP server is registered in `.mcp.json`; Claude Code launches it
automatically (approve the `workspace-ai` server when prompted), then you can ask
it to search your Gmail, draft an email, or `run_gmail_agent` on a multi-step task.

## Quality gates

```bash
uv run pytest -q                     # 53 tests
uv run ruff check .                  # lint
uv run mypy packages config apps     # strict type-check
```

## Project layout

| Path | Responsibility |
|---|---|
| `packages/core/` | Contracts (`Tool`, `Provider`, `AuthContext`) + `ToolRegistry`. Depends on nothing. |
| `packages/auth/` | OAuth2/OIDC, JWT, sessions, refresh-token encryption, `TokenStore`. |
| `packages/database/` | SQLAlchemy models, Alembic migrations, repositories. |
| `packages/providers/` | One folder per integration (`gmail/`), on a shared `BaseProvider`/`BaseTool`. |
| `packages/mcp_adapter/` | Exposes the Registry to Claude Code over MCP. |
| `packages/langgraph_agent/` | The plan→execute→reflect agent, exposed as one MCP tool. |
| `packages/observability/` | Structured logging + event bus + in-memory store. |
| `apps/api/` | FastAPI: OAuth routes, auth middleware, dashboard API. |
| `apps/dashboard/` | Next.js observability dashboard (read-only). |
| `docs/` · `tests/` · `config/` · `scripts/` | Docs, test suite, settings, dev scripts. |

## Status

Milestones 0–6 complete — contracts, database, Google login, Gmail tools, the
MCP server, the LangGraph agent + visualizer, and the dashboard. All verified
end-to-end against real Gmail.