Agent 365 SDK
TL;DR: You will build a production-grade autonomous agent with the Microsoft 365 Agents SDK, wiring in Microsoft Entra identity, proactive notifications, MCP-based tooling and OpenTelemetry tracing so the agent is governable, auditable and least-privilege by design.
What you will learn
- How to scaffold and deploy a custom engine agent with the Microsoft 365 Agents SDK and the Agents Toolkit.
- How to enforce enterprise identity with Microsoft Entra so the agent acts on a user’s behalf with scoped permissions.
- How to send proactive notifications and handle channel events from Microsoft 365 Copilot.
- How to expose external capabilities through Model Context Protocol (MCP) tools under governed boundaries.
- How to emit OpenTelemetry traces and metrics so every agent action is observable and auditable.
Prerequisites
- A Microsoft 365 Copilot licence (or Copilot Studio pay-as-you-go billing) if the agent must be grounded in organisational data.
- Microsoft Entra ID P2 recommended for Conditional Access and Privileged Identity Management over the agent’s app registration.
- Roles and access: ability to create an Azure Bot Service resource and an Entra app registration, plus admin approval to sideload a custom app in the Teams admin center.
- Tools: the Microsoft 365 Agents Toolkit for Visual Studio or Visual Studio Code, the Agents SDK (C#, JavaScript or Python), and the Azure CLI.
- Earlier tutorial: complete an introductory Copilot extensibility tutorial so you are comfortable with manifests and Agent Store deployment before starting here.
Scaffold and deploy the agent
The Agents SDK is model- and orchestrator-agnostic, so you can pair it with Azure AI Foundry, Semantic Kernel, LangChain or your own stack while keeping a single governed deployment path.
Step 1: Create the project and bot resource
- Install the Microsoft 365 Agents Toolkit, then scaffold a new project from the Echo or Empty Agent sample.
- Create an Azure Bot Service resource with an Entra app registration. The bot service sits between the channel and your code, translating channel activities into a common shape your agent understands.
- Reference the app registration identifier in your agent configuration so Copilot can route activities to your hosted endpoint.
Step 2: Handle channel events
- Register an event listener using the
OnActivityhandler so the agent responds to any message or action from Microsoft 365 Copilot. - Route the incoming activity into your orchestrator, then return a response activity.
agent.OnActivity(ActivityTypes.Message, async (turnContext, cancellationToken) =>
{
var reply = await orchestrator.RunAsync(turnContext.Activity.Text, cancellationToken);
await turnContext.SendActivityAsync(reply, cancellationToken);
});Step 3: Package and deploy
- Generate the Copilot manifest package (a .zip containing the manifest) with the Agents Toolkit.
- Submit the packaged agent to your organisation’s catalogue from the toolkit; it appears as a pending request in the Microsoft 365 admin center.
- An admin reviews capabilities, data access and security, then approves it to publish into Agent Store.
Enforce enterprise identity
An autonomous agent must never run with broad standing permissions. Use Entra to scope what it can see and do per user.
Step 4: Configure on-behalf-of identity
- In Azure Bot Service, enable the option for the agent to request permission to act on the user’s behalf.
- Add token management so the agent exchanges the user’s token to scope its knowledge to that user’s accessible data only.
- Apply Conditional Access and least-privilege Graph scopes to the app registration so the agent inherits no more access than the task requires.
Add MCP tooling and observability
Step 5: Expose governed MCP tools
- Register external capabilities as Model Context Protocol tools so the agent calls them through a typed, auditable contract rather than ad hoc API calls.
- Gate each tool behind explicit consent and least-privilege credentials, and validate inputs and outputs before they cross the agent boundary.
Step 6: Emit OpenTelemetry traces
- Instrument the agent with OpenTelemetry to emit spans for each turn, tool call and identity exchange.
- Export traces and metrics to your observability backend so security teams can reconstruct exactly what the agent did, when and for whom.
export OTEL_EXPORTER_OTLP_ENDPOINT="https://your-collector.example.com"
export OTEL_SERVICE_NAME="agent-365-sdk"
export OTEL_TRACES_SAMPLER="parentbased_always_on"Governance call-outs
- Data leakage: scope knowledge to the signed-in user’s identity; never let one user’s token surface another user’s data through shared agent state.
- Least-privilege knowledge: grant the narrowest Graph and tool scopes that satisfy the task, and review them on every release.
- Compliance gates: route agent deployment through the Microsoft 365 admin center approval flow so capabilities and data access are reviewed before publication.
- Identity and consent: require on-behalf-of token exchange and explicit user consent for each MCP tool rather than standing application permissions.
- Audit trails: retain OpenTelemetry traces and admin-center activity data so every autonomous action is attributable and reviewable.
Hands-on lab
Build a minimal autonomous agent that has an identity, calls one MCP tool and emits an OpenTelemetry trace you can inspect.
Before you start
- You have completed the prerequisites above, including the Microsoft 365 Agents Toolkit and the Agents SDK installed for your chosen language.
- You can create an Entra app registration and an Azure Bot Service resource, or reuse the ones from the steps above.
- You have access to a local OpenTelemetry collector, or an OTLP endpoint you can read traces from.
Steps
-
Scaffold a new agent project from the Empty Agent sample with the Agents Toolkit, then run it locally to confirm it starts.
-
Register an Entra app for the agent and grant it a single, read-only Microsoft Graph scope such as
User.Readso it has a scoped identity. -
Wire on-behalf-of token exchange so the agent acts as the signed-in user rather than with standing application permissions.
-
Register one MCP tool with a typed contract, gated behind explicit consent. Keep it read-only for this lab, for example a tool that reads the user’s profile.
-
Instrument the agent with OpenTelemetry and point the exporter at your collector, as shown below.
export OTEL_EXPORTER_OTLP_ENDPOINT="https://your-collector.example.com" export OTEL_SERVICE_NAME="agent-365-lab" export OTEL_TRACES_SAMPLER="parentbased_always_on" -
Send the agent one message that triggers the MCP tool call, then open your observability backend and inspect the resulting trace.
Check your work
- The agent starts locally and responds to a message.
- The agent authenticates with its Entra identity and exchanges an on-behalf-of token for the signed-in user.
- The single MCP tool is invoked through its typed contract and returns a result.
- A trace appears in your backend with spans for the turn, the identity exchange and the tool call.
- Governance reminder: keep the lab least-privilege. Grant only the one read-only Graph scope the task needs, and remove any broader permissions before you continue.
Next step
Continue with the next tutorial.