An AI agent that triages your Microsoft 365 inbox: it escalates urgent mail to Teams, drafts replies, and emails you a daily briefing - all following rules you write in plain markdown.
Powered by Azure Functions and Microsoft 365 connectors. You bring the markdown logic and a little Python for your rules.
Run it locally in minutes against sample data, point it at your real inbox, then deploy it so it runs on its own.
- π Daily Briefing: a daily summary of what matters lands in your inbox.
- π¨ Escalate: VIP / urgent mail is posted to your Teams channel, with an @mention.
- βοΈ Reply: action-required mail gets a grounded draft reply.
- π¬ Chat: ask read-only questions about your recent mail.
β Full walkthroughs in docs/use-cases.md.
- Python 3.13+. Easiest install: uv, then
uv python install 3.13. - Azure Functions Core Tools v4 β₯ 4.12.0 (the v5 preview is not yet compatible).
- Azure Developer CLI (
azd). - An Azure subscription.
azd provision(Quickstart step 2) creates the Microsoft Foundry model deployment the agents need - required even for the offline path. - For real M365 (or
azd up): permission to authorize Microsoft 365 connectors, plus theconnector-namespaceCLI extension:
macOS / Linux:
curl -fsSL https://aka.ms/connector-namespace-cli-install | shWindows:
powershell -Command "Invoke-WebRequest -Uri 'https://aka.ms/connector-namespace-cli-install' -OutFile 'install.sh'; wsl bash install.sh"Five steps: install, get resources, run locally, try it, deploy.
macOS:
brew tap azure/functions
brew install azure-functions-core-tools@4
brew install azure-dev
npm install -g azurite
curl -LsSf https://astral.sh/uv/install.sh | shLinux / Windows / WSL: Use the Core Tools v4 install guide, azd install guide, Azurite install guide, and uv install guide.
azd provision creates the Foundry model deployment the agents require (needed even offline); hydrate copies the settings into local.settings.json. No API keys - managed identity throughout.
macOS / Linux:
azd provision
./infra/scripts/hydrate-local-settings.shWindows:
azd provision
.\infra\scripts\hydrate-local-settings.ps1Yes - even the offline, sample-data run needs this one-time
azd provision, because the agents call a Foundry model. It provisions the model deployment only; it never touches your inbox.
azurite --silent --skipApiVersionCheck --location .azurite # terminal A
uv run func start # terminal B
uv run python chat.py # terminal C(These commands work identically on macOS, Linux, and Windows.)
πͺ Windows local dev: If
uv run func startfails withModuleNotFoundError: No module named 'azure_functions_agents', the Microsoft Store python.exe alias on yourPATHis shadowing the venv Python. See Troubleshooting: Windows local dev for the fix - you'll need to remove the Store Python and disable App execution aliases in Windows Settings.
Pick 1, 2, or 3. The client shows a π‘ Offline banner and runs every agent in DRY RUN against sample-data/inbox/*.json: it produces the full deliverable as text and calls no connector, so nothing is ever sent. Pick 5 to chat with the sample inbox.
Want it to act on your real inbox while still local? See Go live with real M365.
Set who real mail and Teams posts go to, before you deploy. Without these, the deployed agents stay in DRY RUN (the chat client's doctor banner will tell you).
azd env set MAILBOX_OWNER_EMAIL you@your-tenant.com # required for LIVE mail
azd env set TEAMS_TEAM_ID <team-id> # optional, enables Teams alerts
azd env set TEAMS_CHANNEL_ID <channel-id> # optional, enables Teams alertsGet the Teams ids by opening the target channel in Teams β β― β Get link to channel (the URL contains both ids), or via docs/configuration.md.
Already deployed with placeholders? Set them now and re-run
azd up(or justazd provision) to push the new values to the Function App.
azd upKnown issue (point-in-time):
azd upmay currently fail at the deploy step on Python 3.13 - the Flex remote build uses Python 3.11.8 (Azure/azure-dev#8538). Simple workaround: docs/deploy-python-313.md. This note can be removed once the bug is fixed.
Now inbox-triage fires automatically on every new email - no client, no waiting. Send yourself a message, then watch your Teams channel (VIP / incident) or your inbox (replies). Tail the live trace with azd monitor --logs.
- βοΈ Edit
skills/vip-rules.mdto set your VIPs, what to skip, and what escalates to Teams. - π The
weekly-rule-suggestionsagent proposes tuning that you approve by hand. - π Use this repo as a private template before adding real rules or tenant data.
β Full guide: docs/customize.md.
azd down --purgeHitting an error? See docs/troubleshooting.md.
This is an Azure Functions app on the serverless agents runtime. Each agent is a markdown file (*.agent.md) that reasons over your rules in skills/*.md; a small tools/match_rule.py adds deterministic classification. Microsoft 365 actions go through Entra-authorized MCP connectors - no app secrets, managed identity end to end.
β Deeper dives: How it works Β· Configuration & deployment Β· Customize Β· Troubleshooting & reference