Single account setup
The quickest way to get email working is to connect one account using three vault secrets.Create a Nylas account
Sign up at app.nylas.com. The free tier is sufficient for development and small deployments.
Create an application
In the Nylas dashboard, create a new application and choose Email as the product. Once created, copy your API key — this becomes
nylas_api_key.Connect an email account
Inside your application, go to Grants and add a new grant. This walks you through an OAuth flow to connect a Gmail, Outlook, or other email account to Nylas. After completing the flow, copy the Grant ID — this becomes
nylas_grant_id.Seed the credentials into the vault
Set all three values transiently and run the seed script — they are encrypted and stored in the vault, not in They are stored under the vault keys
.env:nylas_api_key, nylas_grant_id, and nylas_self_email. nylas_self_email is the address of the connected account — Curia uses it to filter self-sent messages and sign outbound emails.Multiple email accounts
For more advanced deployments — for example, connecting multiple inboxes — configure named accounts inconfig/local.yaml using the channel_accounts.email block.
curia, personal) becomes an account name that you pass to email skills via the account parameter. Outbound email sending is governed by the autonomy engine — when the score is below the skill’s action_risk floor, sends are blocked and saved as drafts instead.
When using
channel_accounts.email, the single-account vault keys (nylas_grant_id, nylas_self_email) are no longer used for routing — all accounts must be defined in the YAML block. You still need nylas_api_key in the vault: it’s the application-level key shared by all accounts.Email skills
Once the email channel is active, the following skills become available to Curia and any agents you configure:| Skill | What it does |
|---|---|
email-list | List recent messages in any connected account |
email-get | Fetch the full body of a specific message by ID |
email-send | Compose and send a new email |
email-reply | Reply to an existing thread by message ID |
email-draft-save | Save a draft to a specified account for human review |
send-draft | Send a previously saved draft (CEO-authorized) |
email-archive | Archive a message by ID |
account parameter to target a specific named account. Omit it to use Curia’s own account.
File attachments
Outbound email skills (email-send, email-reply, and their CEO-inbox counterparts) accept an optional list of attachments. Files are referenced by file:// URLs backed by Curia’s temp-file store rather than passed inline, with a cap of 20 MB total across at most 10 attachments per message. Anything an agent has written to the temp-file store can be attached; the drive-download-file skill bridges Google Drive by downloading a file (including Google-native exports) into that store and returning a file:// URL ready to attach. No extra configuration is needed beyond a working Nylas grant — attachments ride the same Send API as the message body.
Troubleshooting
Email channel not activating
Email channel not activating
All three Nylas secrets (Confirm what is seeded with
nylas_api_key, nylas_grant_id, nylas_self_email) must be in the vault. If any is missing, the channel disables itself at startup with one of these log messages:pnpm run seed-vault (it verifies and lists keys), re-seed any missing value, and recreate the container.Messages not appearing
Messages not appearing
Curia polls the Nylas Messages API every 30 seconds by default. If messages are slow to appear, confirm the email account’s OAuth grant is active in the Nylas dashboard and that the grant ID matches the vault’s
nylas_grant_id.You can also adjust the polling interval (non-secret config in .env):Outbound emails going to drafts unexpectedly
Outbound emails going to drafts unexpectedly
Outbound sends are governed by the autonomy engine. If your autonomy score is below 70,
email-send and email-reply are blocked and drafts are saved instead. Ask Curia its current score (“What is your autonomy score?”) and raise it if needed.