{"record":{"id":"062932f526080516","repo":"odysseus-dev/odysseus","slug":"error-email-mcp-requires-an-authenticated-owner-o","errorCode":null,"errorMessage":"Error: email MCP requires an authenticated owner or ODYSSEUS_MCP_EMAIL_OWNER when owner-scoped email accounts are configured.","messagePattern":"Error: email MCP requires an authenticated owner or ODYSSEUS_MCP_EMAIL_OWNER when owner-scoped email accounts are configured\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mcp_servers/email_server.py","lineNumber":314,"sourceCode":"        \"smtp_security\": os.environ.get(\"SMTP_SECURITY\", \"\"),\n        \"smtp_user\": os.environ.get(\"SMTP_USER\", \"\"),\n        \"smtp_password\": os.environ.get(\"SMTP_PASSWORD\", \"\"),\n        \"smtp_starttls\": os.environ.get(\"SMTP_STARTTLS\", \"false\").lower() == \"true\",\n        \"smtp_ssl\": os.environ.get(\"SMTP_SSL\", \"true\").lower() == \"true\",\n        \"from_address\": os.environ.get(\"EMAIL_FROM\", \"\"),\n        \"archive_folder\": os.environ.get(\"ARCHIVE_FOLDER\", \"Archive\"),\n        \"trash_folder\": os.environ.get(\"TRASH_FOLDER\", \"Trash\"),\n        \"cache_db\": os.environ.get(\n            \"EMAIL_CACHE_DB\",\n            EMAIL_CACHE_DB,\n        ),\n        \"account_id\": None,\n        \"account_name\": None,\n    }\n\n    raw_rows = _read_accounts_from_db()\n    if _mcp_owner_required(raw_rows):\n        raise ValueError(_OWNER_SCOPE_ERROR)\n    rows = _filter_accounts_for_owner(raw_rows)\n    row = _resolve_account_from_rows(rows, account)\n    if _current_owner() and raw_rows and not rows:\n        raise ValueError(\"No email account is configured for the authenticated owner\")\n    if account and rows and not row:\n        available = \", \".join(\n            f\"{r.get('name') or r.get('imap_user')} <{r.get('imap_user') or r.get('from_address') or '?'}>\"\n            for r in rows\n        )\n        raise ValueError(f\"Email account not found for selector {account!r}. Available accounts: {available}\")\n    if row:\n        cfg[\"account_id\"] = row[\"id\"]\n        cfg[\"account_name\"] = row[\"name\"]\n        cfg[\"imap_host\"] = row[\"imap_host\"] or cfg[\"imap_host\"]\n        cfg[\"imap_port\"] = int(row[\"imap_port\"] or cfg[\"imap_port\"])\n        cfg[\"imap_user\"] = row[\"imap_user\"] or cfg[\"imap_user\"]\n        # Passwords in email_accounts are stored encrypted via\n        # src.secret_storage.encrypt — decrypt before handing to IMAP","sourceCodeStart":296,"sourceCodeEnd":332,"githubUrl":"https://github.com/odysseus-dev/odysseus/blob/f9235ebbf13f693a6fd29ce70b097f6ec83705bf/mcp_servers/email_server.py#L296-L332","documentation":"ValueError (_OWNER_SCOPE_ERROR) raised while resolving the email MCP server's account config. When accounts in the database are owner-scoped (_mcp_owner_required true) but no authenticated owner is present and ODYSSEUS_MCP_EMAIL_OWNER is unset, the server refuses to start because it cannot tell which owner's mailboxes it may access.","triggerScenarios":"Starting/invoking the email MCP server (build of cfg) with owner-scoped account rows in the accounts DB while the request/context carries no owner and the ODYSSEUS_MCP_EMAIL_OWNER environment variable is empty.","commonSituations":"Running the MCP server as a standalone process without the app's auth context; env var lost in a new deployment or service file; accounts migrated to per-owner mode without updating the launcher.","solutions":["Set ODYSSEUS_MCP_EMAIL_OWNER to the username whose email accounts should be used","Or run the server within the authenticated app context so _current_owner() resolves","If owner scoping is unwanted, remove owner values from the account rows so _mcp_owner_required returns false"],"exampleFix":"# before\n$ python mcp_servers/email_server.py  # owner-scoped rows, no owner → ValueError\n# after\n$ ODYSSEUS_MCP_EMAIL_OWNER=alice python mcp_servers/email_server.py","handlingStrategy":"validation","validationCode":"import os\nowner = _current_owner() or os.environ.get('ODYSSEUS_MCP_EMAIL_OWNER')\nrows = _read_accounts_from_db()\nif _mcp_owner_required(rows) and not owner:\n    raise RuntimeError('Set ODYSSEY_MCP_EMAIL_OWNER before starting the email MCP server')","typeGuard":null,"tryCatchPattern":"try:\n    cfg = build_email_config()\nexcept ValueError as e:\n    if 'authenticated owner' in str(e):\n        sys.exit('Set ODYSSEUS_MCP_EMAIL_OWNER=<username> and restart the email MCP server')\n    raise","preventionTips":["Set ODYSSEUS_MCP_EMAIL_OWNER in the service unit/launcher env","Run the MCP server inside the authenticated app context when possible","Document which account rows are owner-scoped when onboarding new owners"],"tags":["email","mcp","configuration","environment","authorization"],"backgroundTag":null,"analyzedSha":"f9235ebbf13f693a6fd29ce70b097f6ec83705bf","analyzedAt":"2026-08-14T21:47:48.359Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}