Every user-writable setting, in one model — the single description of these columns.
Both transports bind to this: POST /users/setup (web) and POST /mcp/tools/update_settings
(MCP + the in-app agent). Field names are the column names on purpose, so the field an
error names — outreach_blocker in routers/shared/pipelines.py prints raw column names —
is the argument an agent sends back to fix it, with nothing to translate in between.
The descriptions are not decoration: fastapi-mcp builds the remote MCP input schema from
this model (main.py FastApiMCP), and services/agent_tools reads model_json_schema() for
the in-app agent, so this text is what both agents see. Plain # comments are invisible
to both.
Every field is optional; only the ones passed are written (model_dump(exclude_none=True)).