Quickstart¶
Source: https://github.com/brandwe/entrabot-identity-research
Prerequisites¶
- Python 3.12+ on
PATH - Azure CLI (
az) logged in with admin access to your Entra tenant (Application Administratoror higher) gh(GitHub CLI) — optional, used by some helper scripts- Git
- An M365 license available for the Agent User (E3/E5/Teams Enterprise — anything that grants a Teams seat)
- macOS, Linux, or Windows 10 21H2+/11. Windows uses
scripts/setup-windows.ps1(PowerShell 7+); seedocs/runbooks/windows-setup.md.
One-Command Setup (macOS/Linux)¶
git clone https://github.com/brandwe/entrabot-identity-research.git
cd entrabot-identity-research
./scripts/setup.sh
This will:
1. Create a dedicated provisioner app registration (avoids Azure CLI token rejection — Learning #1)
2. Create an Agent Identity Blueprint + BlueprintPrincipal (separate steps — Learning #2)
3. Create an Agent Identity (per-device service principal)
4. Create an Agent User (Entra user account linked to the Agent Identity)
5. Grant consent for Teams/Chat Graph permissions
6. Generate a self-signed certificate, upload public key to Entra, store private key in the OS keystore (Keychain / TPM / Keyring — ADR-003)
7. Install Python dependencies and write .env (no secrets — only the cert thumbprint)
The script is idempotent — safe to re-run. State is persisted in .entrabot-state.json.
Optional flags¶
--use-cloud-memory— opt in to Azure Blob Storage for operational data (interaction log, daily summaries, watched chats, email cursor). Default is local-only.--keep-memory-local— explicit form of the default. Accepted for backwards compatibility.
See docs/reference/setup-script.md for the full flag list, and docs/guides/storage-configuration.md for the local-vs-cloud trade-offs.
After Setup¶
- Assign an M365 license to the Agent User in the Entra admin center (E3/E5/Teams Enterprise).
- Wait 10–15 minutes for Teams/mailbox provisioning. The Agent User won't be reachable in Teams until this completes — there is no faster path.
- Run tests:
Launching the Agent¶
The repo isn't published to npm or pypi — your host CLI loads the local stdio MCP server from .mcp.json in the current directory. No flag is needed for that part; MCP servers in .mcp.json are auto-discovered. What differs between hosts is how inbound Teams DMs reach the agent.
Claude Code (recommended)¶
Channel push: inbound Teams messages and emails arrive as next-turn system reminders without a tool call. Requires the dev-channel allowlist flag:
The double-dash matters. Single-dash silently treats server:entrabot as prompt text — see Learning #44 in docs/runbooks/hard-won-learnings.md. server:entrabot is the MCP server name from .mcp.json, not a publication identifier — the value matches the key inside the mcpServers object in .mcp.json.
GitHub Copilot CLI, Codex, Cursor, and other non-Claude hosts¶
MCP tools work, but there is no notifications/claude/channel equivalent — channel push is silently absent. Inbound Teams messages instead arrive inline as a sponsor_reply field on send_teams_message, which auto-blocks until the sponsor replies. This is host-detected on the server side; no flag, no parameter:
While the agent is blocked waiting on a Teams reply (any host that calls wait_for_sponsor_dm explicitly, or the auto-wait inside send_teams_message on non-Claude hosts), the host CLI shows a heartbeat animation so you know it is listening to Teams, not your keyboard:
Frames cycle every ~30s with an elapsed-time counter:
(•ᴗ•) zZz... listening for Teams DM(•ᴗ•)╯ checking inboxʕ•ᴥ•ʔ waiting on sponsor(´・ω・) sponsor hasn't replied yet`(╯°□°)╯ Teams DM = next turn(◕‿◕) still here, still waiting
Ctrl+C breaks out cleanly. Full host-by-host protocol is in docs/claude-copilot-cli-channel-port.md and prompts/anatomy/channel-discipline.md.
Common Pitfalls¶
- Teams provisioning latency. The 10–15 min wait is real. If
create_chat404s, give it another five minutes before debugging. azCLI tokens hard-403 against Agent Identity APIs. Don'taz restagainst the agent-identity beta — the dedicated provisioner app exists for that reason. Learning #1.pip install -e .inside a worktree silently re-points the parent venv. If you run sub-agents in git worktrees, give them a worktree-local venv. Learning #36.- Stderr must stay visible. Don't
2>/dev/nullsetup scripts — failures become invisible. Learning #6.
Without an Entra Tenant¶
If you just want to run the code and tests locally:
All Graph API calls are mocked in tests — no tenant needed.
Teardown¶
Removes the Agent User, Agent Identity, Blueprint, Provisioner app, and local state.
Next Steps¶
- Read the System Overview
- See Token Flows for auth protocol details
- See Enforcement Flow for how a request moves through the system
- Skim Hard-Won Learnings before changing setup — it captures the 66 things that have already cost engineering hours