FastAPI backend for a multi-agent assistant that combines:
- OpenAI Agents SDK orchestration
- user-connected app data (Gmail and Google Drive)
- browser automation via Playwright MCP
- WhatsApp runtime + MCP integration
The API exposes a single streaming agent endpoint (/v1/run-agent) plus onboarding, OAuth, session history, and WhatsApp connect endpoints.
At runtime:
orchestrator_agentis the main entry point.- Connected user-data agents (
gmail,drive,whatsapp) are exposed to the orchestrator as tools. - Handoff-enabled specialists (currently
browser) can receive delegated control. - Browser and WhatsApp MCP clients are created lazily per run and cleaned up after streaming completes.
- Gmail OAuth connect/disconnect and read-only Gmail tools.
- Google Drive OAuth connect/disconnect and read-only file search tools.
- Browser agent via Playwright MCP for guided web workflows.
- WhatsApp runtime connect/status/disconnect endpoints + WhatsApp MCP agent support.
- SSE streaming from the agent with tool/handoff/reasoning events.
- Chat session persistence in Supabase (
chat_sessions) linked to OpenAI conversation IDs. - Onboarding profile + browser credential management with secrets stored in Supabase Vault.
orchestrator_agent- Tool-access agents:
gmail,drive,whatsapp(when connected/available) - Handoff agent:
browser(when Playwright MCP is configured)
The workflow is assembled in app/agents/workflow.py and agent registration is in app/agents/registry.py.
- Most API routes require
Authorization: Bearer <supabase_user_jwt>. - Token validation attempts Supabase native
auth.get_userfirst. - Fallback validation uses
SUPABASE_JWT_SECRETif native validation is unavailable.
- Browser session provider (
BROWSER_SESSION_PROVIDER):localimplementedcontrollerplaceholder (not implemented)
- WhatsApp session provider (
WHATSAPP_SESSION_PROVIDER):localimplementedcontrollerplaceholder (not implemented)
- Python
>=3.10 - Supabase project with required tables/RPC functions
- OpenAI API key
- Google OAuth client secrets JSON (shared by Gmail + Drive)
- Playwright MCP endpoint (required by startup validation)
- Create/activate an environment (venv or conda).
- Install dependencies:
pip install -r requirements.txt- Copy env file:
cp .env.example .env- Set required variables in
.env(see below).
SESSION_SECRET_KEYSUPABASE_URLSUPABASE_API_KEYSUPABASE_SERVICE_ROLE_KEY(needed for vault RPC access)OPENAI_API_KEYGOOGLE_CLIENT_SECRETS_FILEGMAIL_SCOPESGMAIL_REDIRECT_URIGMAIL_POST_CONNECT_REDIRECTGOOGLE_DRIVE_SCOPESGOOGLE_DRIVE_REDIRECT_URIGOOGLE_DRIVE_POST_CONNECT_REDIRECTOAUTH_STATE_SIGNING_SECRETPLAYWRIGHT_MCP_URLWHATSAPP_SESSION_PROVIDER(localby default)WHATSAPP_BRIDGE_JWT_SECRET(required whenWHATSAPP_SESSION_PROVIDER=local)
If WHATSAPP_MCP_CONNECT_ON_STARTUP=true:
WHATSAPP_MCP_URLWHATSAPP_MCP_JWT_AUDIENCEWHATSAPP_MCP_JWT_SUBJECTWHATSAPP_MCP_JWT_SCOPESWHATSAPP_BRIDGE_JWT_SECRET
If WHATSAPP_SESSION_PROVIDER=controller:
WHATSAPP_SESSION_CONTROLLER_URLWHATSAPP_SESSION_CONTROLLER_JWT_SECRETWHATSAPP_SESSION_CONTROLLER_JWT_AUDIENCE(default:whatsapp-session-controller)WHATSAPP_SESSION_CONTROLLER_JWT_ISSUER(default:omicron-api)WHATSAPP_SESSION_CONTROLLER_JWT_TTL_SECONDS(default:60)WHATSAPP_SESSION_CONTROLLER_TIMEOUT_SECONDS(default:10)
If BROWSER_SESSION_PROVIDER=controller:
- controller fields exist in settings, but controller mode is currently not implemented.
SUPABASE_JWT_SECRET(JWT fallback validation)OAUTH_STATE_TTL_SECONDS(defaults to600)OAUTH_STATE_ISSUER(defaults toomicron-api)GMAIL_TOKENS_ENCRYPTION_KEY- if omitted, startup fetches vault secret
gmail_tokens_encryption_key.
- if omitted, startup fetches vault secret
Use GOOGLE_CLIENT_SECRETS_FILE for Google OAuth credentials. Both Gmail and Google Drive settings read this key.
Apply SQL files from app/db/table_schemas/:
vault_secret_functions.sqluser_profiles_schema.sqluser_onboarding_schema.sqlgmail_schema.sqlgoogle_drive_schema.sqloauth_transactions_schema.sqlsessions_schema.sqlbrowser_sessions_schema.sqlwhatsapp_connections_schema.sql
Also review:
browser_credentials_vault_contract.md
Development mode:
python run.pyAlternative:
uvicorn app.main:app --reloadNotes:
run.pysetsOAUTHLIB_INSECURE_TRANSPORT=1for local HTTP OAuth callbacks.- API base prefix defaults to
/v1.
POST /v1/run-agent- Body:
{ "query": "...", "session_id": "..."? } - Response:
text/event-stream
- Body:
GET /v1/apps/supported
GET /v1/oauth/gmail/startGET /v1/oauth/gmail/status/{transaction_id}GET /v1/oauth/gmail/callbackPOST /v1/oauth/gmail/disconnect
GET /v1/oauth/google-drive/startGET /v1/oauth/google-drive/status/{transaction_id}GET /v1/oauth/google-drive/callbackPOST /v1/oauth/google-drive/disconnect
GET /v1/sessionsPOST /v1/sessionsDELETE /v1/sessions/{session_id}GET /v1/sessions/{session_id}/history
GET /v1/onboarding/statePUT /v1/onboarding/profileGET /v1/onboarding/browser-credentialsPOST /v1/onboarding/browser-credentialsDELETE /v1/onboarding/browser-credentials/{site_key}POST /v1/onboarding/complete
POST /v1/whatsapp/connect/startGET /v1/whatsapp/connect/statusPOST /v1/whatsapp/connect/disconnect
SSE messages include:
session_iddeltareasoning_deltareasoning_donemessagetool_calledtool_outputreasoningagent_updatedhandoff- terminal:
[DONE]
curl -X GET "http://localhost:8000/v1/oauth/gmail/start" \
-H "Authorization: Bearer $SUPABASE_USER_JWT"curl -N -X POST "http://localhost:8000/v1/run-agent" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $SUPABASE_USER_JWT" \
-d '{"query":"Summarize unread Gmail from last 7 days"}'app/main.py: FastAPI app creation + lifespanapp/auth.py: Bearer token validationapp/core/settings.py: typed env settings + startup security validationapp/api/v1/endpoints/: HTTP routesapp/agents/: orchestrator/specialists + workflow wiringapp/integrations/gmail/: Gmail tool/service layerapp/integrations/google_drive/: Drive tool/service layerapp/browser_sessions/: browser runtime provider abstraction + lazy MCP clientapp/whatsapp_sessions/: WhatsApp runtime provider abstraction + lazy MCP client + JWT bridge authapp/db/: Supabase data accesstests/: tests and local/manual scripts
Run full test suite:
pytestUseful focused tests:
pytest tests/test_startup_security_config.py
pytest tests/test_auth_context.py
pytest tests/test_whatsapp_bridge_auth.pycontrollerproviders for browser and WhatsApp sessions are not implemented yet.- Startup currently requires
PLAYWRIGHT_MCP_URL. pyproject.tomldependency list is minimal; userequirements.txtfor full local setup.