Architecture

One capability layer, every surface

jobContext is a single Python capability layer (12 consolidated domain tools over a shared service layer and SQLite) shipped three ways: a native desktop app, a multi-tenant cloud, and a mobile companion. AI assistants, in-browser agents, the dashboard, the CLI, and automation all call the same tools.

The big picture

flowchart TB
  subgraph AGENTS["AI agents"]
    direction LR
    MCPC["Claude · Copilot · Cursor · Windsurf
MCP · stdio / Streamable HTTP"] WEBA["ChatGPT desktop · Chrome OT · Edge
WebMCP · document.modelContext"] end subgraph HUMANS["Human & automation surfaces"] direction LR DASH["React dashboard
web + desktop"] CLI["CLI · REST API
automation, CI"] MOB["Mobile app
share-sheet capture"] end subgraph CORE["jobContext capability layer"] FAC["12 consolidated domain tools · 104 actions
applications · job_search · documents · materials · people · interviews
stories · brand · insights · wellbeing · certification · workspace"] SVC["shared service layer: one implementation of every capability,
no logic duplicated per transport"] DB[("SQLite + JSON audit trail
per-tenant partitions · files")] FAC --> SVC SVC --> DB end MCPC --> FAC WEBA --> FAC DASH --> FAC CLI --> FAC MOB --> FAC classDef hl stroke:#00B5C8,stroke-width:1.5px; class FAC hl

Each tool takes an action parameter; a coverage test guarantees every capability of the historical 88-function surface stays reachable through the facades, so no client, AI or human, ever sees a stale subset. The agent is optional: the same tools serve the CLI, cron jobs, the dashboard, and the mobile app.

Three deployments, one codebase

Desktop

Tauri 2 + sidecar

A native shell embedding the full Python server as a signed sidecar. Local SQLite, loopback-only, embedded AI chat (BYOK or local Ollama), one-click MCP connect, automatic updates.

Cloud

Multi-tenant on AKS

The same server behind Microsoft Entra ID at jobcontext.ai. Every tenant gets an isolated data partition; per-request context routing keeps them apart. CI-driven deploys with an eval smoke gate.

Mobile

Expo companion (iOS)

Share-sheet capture with on-device page extraction: the phone reads postings that block datacenter IPs. Talks to the cloud with a keychain-stored API key.

Desktop creates knowledge, mobile captures reality, cloud synchronizes.

Client transports

MCP · stdio

Local AI clients

Claude Desktop, VS Code + Copilot, Cursor, and Windsurf spawn the server directly. The original transport, still first-class.

MCP · Streamable HTTP

Remote AI clients

Claude.ai, Cursor, and VS Code connect to /mcp over OAuth (dynamic client registration + PKCE proxied to Entra). Runs stateless: every call is self-contained, so deploys never strand a connector session.

WebMCP

In-browser agents

The cloud dashboard republishes the server's tool list in-page via document.modelContext, a W3C community proposal. ChatGPT desktop's browser drives the workspace today with no connector setup; Chrome's origin trial and Edge's preview follow as their support lands.

REST

Dashboard, CLI, mobile

FastAPI serves the React dashboard, the HTTP API the mobile app and automation scripts use, and Prometheus metrics.

The WebMCP bridge

The dashboard is itself an agent surface. On sign-in, the bridge fetches tools/list from /mcp and registers each tool verbatim (names, descriptions, and schemas) as in-page WebMCP tools. There is no second tool surface to maintain, so what a browser agent sees can never drift from what an MCP client sees.

sequenceDiagram
  participant A as In-browser agent
  participant B as WebMCP bridge (in-page)
  participant M as /mcp (stateless Streamable HTTP)
  Note over B: on sign-in: fetch tools/list,
register every tool verbatim A->>B: document.modelContext tool call B->>M: same-origin POST (session cookie) Note over M: CSRF guard: the cookie is
ignored on cross-site requests M-->>B: JSON-RPC result from the same 12 facades
every MCP client gets B-->>A: tool result

Security: an in-page agent acts as the signed-in user, inside their session: the same trust boundary as the user clicking the dashboard by hand. Because the session cookie is ambient, the middleware ignores it on cross-site /mcp requests (Sec-Fetch-Site, with an Origin/Host fallback), so a hostile page can't ride your login. Bearer auth is untouched.

Inside the cloud

Tenant isolation

Every tenant's data lives under its own partition; per-request context routing pins each request, and each background job, to exactly one partition. Background work goes through a control plane: durable work-item rows plus an in-process dispatcher, so long tasks (URL capture, document generation, eval runs, weekly certification) survive restarts and carry their partition with them.

Auth that fails honestly

Entra ID for browsers, OAuth for connectors, personal access tokens for mobile and automation. Token verification distinguishes "invalid" from "can't verify right now": a key-fetch failure returns 503 with Retry-After, never a false 401, so a transient outage never logs anyone out or breaks a connector.

Observability

A zero-dependency metrics library exports Prometheus metrics; in-cluster Prometheus + Grafana dashboards are checked in as code. Incident history lives in PR post-mortems, not tribal memory.

Desktop ⇆ cloud sync

Journal-based and bidirectional: database triggers append every row change to a sync journal; peers exchange journals and resolve upserts last-writer-wins by timestamp. Files sync by SHA-256 manifest, and deletions propagate as tombstones that out-date stale copies instead of resurrecting them. Capture on your phone, assess on your desktop, connect from the cloud; it's the same data everywhere.

The truth gate & evals

Generated resumes and cover letters pass a deterministic provenance gate before they reach you: every claim must trace back to your master resume or your logged history, and the gate's check→revise loop verifies its own corrections. Edits to the master resume are audited, because the gate validates against it.

Behind that sits a three-layer eval framework: deterministic checks, an adversarial LLM-as-judge calibrated against blind human labels, and a planted-error corpus with measured catch rates. Evals run nightly server-side, gate every cloud deploy, and are a product surface too: run the truth suite on your own applications and triage flagged claims from the dashboard.

See also