A daily-use mailbox triage agent built with the Microsoft Agent Framework and deployed as a hosted agent on Microsoft Foundry. It connects to a mailbox over IMAP, classifies recent inbox messages with a model (any language, including Chinese), and either non-destructively tags them or auto-filters them into folders.
Deployments are guarded by a blocking pre-deploy evaluation gate — a classification regression never ships.
- Model-based classification into
important,routine,low-priority,promotion,product-update,spam,newsletter(deterministic keyword heuristic as fallback). TagTriageInbox(non-destructive): adds afilter-agent-<category>label to each recent message; never moves or deletes. Re-runs replace prior labels instead of stacking.AutoFilterInbox: archivespromotion/newsletter/low-priority, movesspamto Spam (or Trash), keepsimportant/routine/product-updatein the Inbox.- Per-message mailbox tools:
ListInboxEmails,MoveEmail,ArchiveEmail,DeleteEmail. - Scheduled daily run at 09:00 UTC+8 via a Foundry Routine (tag-only).
- Observability: GenAI traces plus custom per-email and phase-timing spans to Application Insights.
Foundry Routine (daily 09:00 UTC+8)
│ dispatch
▼
email-filter hosted agent (.NET 10, Agent Framework, Responses protocol)
│ tools
▼
IMAP mailbox ◄──► email-classifier sub-agent (model: gpt-5.4-mini)
│
▼
Application Insights (traces, per-email + phase spans)
The agent source is split into focused classes under src/email-filter/; see the agent README for the file-by-file layout.
- .NET 10 SDK
- Azure Developer CLI (
azd) with theazure.ai.agentsextension - Azure CLI (
az) (for telemetry queries) - Python 3.13+ (for the eval gate and routine scripts)
- A Foundry project, and a mailbox that supports IMAP + app passwords (Gmail by default)
| Variable | Purpose |
|---|---|
GMAIL_ADDRESS |
mailbox address (e.g. you@gmail.com) |
GMAIL_APP_PASSWORD |
16-character app password (stored in Windows Credential Manager, not the azd .env) |
EMAIL_FILTER_TRUSTED_DOMAINS |
optional CSV of always-important sender domains |
AZURE_AI_MODEL_DEPLOYMENT_NAME |
classifier model deployment (set by azd) |
Non-secret mailbox settings (IMAP host/port, folder paths, label prefix) live in src/email-filter/appsettings.json under a neutral Mailbox section and can be overridden with Mailbox__<Key> env vars.
# 1. Store the mailbox app password securely (one-time, local).
.\scripts\Set-GmailSecret.ps1
# 2. Provision Foundry resources (one-time per environment).
azd provision
# 3. Deploy (runs the eval gate first, then ships the agent).
.\scripts\Deploy.ps1Run the agent host from the project folder:
cd src/email-filter
dotnet runThe host listens on http://localhost:8088 and speaks the Responses protocol. With the mailbox env vars set, send it a message:
azd ai agent invoke --local "Tag my 20 most recent inbox emails for triage evaluation, do not move anything."Or call the endpoint directly:
curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" \
-d '{"input": "What is Microsoft Foundry?", "stream": false}'For sample queries and the full list of tools, see the agent README.
Always deploy through the secure wrapper, which injects the mailbox app password from Windows Credential Manager only for the duration of the deploy and scrubs it afterward:
.\scripts\Deploy.ps1Deploy.ps1 runs azd deploy. The project-level predeploy hook (scripts/Run-Eval.ps1, defined in azure.yaml) runs the classification eval gate before the deploy proceeds. The gate is blocking: if the mean category_match score drops below pass_threshold (default 1.0), azd aborts the deploy and the regression never ships. Each successful deploy registers a new immutable agent version.
To run the gate on demand without deploying:
.\scripts\Run-Eval.ps1See the agent README for how the eval set is built and grown.
| Path | Contents |
|---|---|
src/email-filter/ |
The .NET 10 agent (split into focused classes), agent.yaml, appsettings.json, and the detailed agent README. |
infra/ |
Bicep templates for the Foundry project, ACR, Application Insights, storage, etc. |
scripts/ |
Deploy wrapper, secret management, eval gate, routine setup, and telemetry helpers. |
scripts/eval/ |
The classification eval target, exact-match evaluator, and runner. |
.foundry/datasets/ |
The PII-scrubbed eval seed dataset and its lineage manifest. |
eval.yaml |
Local evaluation intent (dataset, evaluator, model, pass threshold). |
azure.yaml |
azd service definition, model deployment, and the predeploy eval hook. |
- Agent README — detailed usage, tools, configuration, evaluation, the scheduled routine, and observability.
- Hosted agents on Foundry
- Microsoft Agent Framework