@-mention any submission/speaker/session as context, clickable entity badges that navigate the app, and inline Approve/Deny confirmation before anything sensitive happens (emails, decisions, publishing, deletes).
One switch
The agent is dormant by default and activates only when a provider key exists:
The frontend follows automatically via
GET /api/agent/capabilities — there is no second flag.
Architecture
api/agent/service.py:run_turn owns the complete provider-neutral turn lifecycle: thread claims and persistence, history, prompts, runtime events, tool dispatch, permission cleanup, and the final reply. In-app Ask is an SSE adapter over that function. The Slack agent is an Events API adapter over the same function, so both transports use the same tools, MCP connectors, thread store, and permission gate; Slack approval requests arrive as Approve/Deny buttons and Slack threads appear in Ask history.
The provider harness is shared — tool registry, event vocabulary, permission gate, thread persistence — with the model loop as the only swappable part. The full provider-swap notes (including what differs when running on Claude) live in the repo at docs/chat-agent.md.
MCP connectors
Organizations can attach external tool servers from Settings → Integrations: Every ships as the first preset, and any Streamable-HTTP MCP server can be added with OAuth (discovery + dynamic client registration + PKCE), a static bearer token, or no auth. External tools are namespacedmcp__<connector>__<tool> and every external mutation passes the same Approve/Deny gate. See MCP connectors.
