Blog Post

Microsoft Developer Community Blog
5 MIN READ

Distributing Agents to Microsoft Teams and Microsoft 365 Copilot Part 4/5

Lee_Stott's avatar
Lee_Stott
Icon for Microsoft rankMicrosoft
Aug 18, 2026

This is the fourth post in our series on the Microsoft agent platform. We cover the Distribute in M365 pillar — publishing your agents to Microsoft Teams and Microsoft 365 Copilot so they reach users where they already work.

All examples reference the FibreOps repository, demonstrated at Microsoft Build BRK241.

The Distribution Story

Building a great agent is only half the challenge. The other half is getting it into the hands of users without asking them to learn a new tool, visit a new URL, or change their workflow. Microsoft 365 Copilot and Microsoft Teams are where enterprise users already spend their day, making them the natural distribution surface for agents.

With the GA release, publishing an agent to Teams and M365 Copilot is a single command. No separate app registration portal, no manual manifest assembly, no multi-step approval workflow for development and testing.

Publishing to Microsoft 365 Copilot (GA)

FibreOps ships as a declarative agent + action plugin ready for sideload. A single CLI command produces the complete package:

python -m fibreops.demo publish-m365 --out dist/m365

# Output:
#  ✓ wrote dist/m365/declarativeAgent.json
#  ✓ wrote dist/m365/fibreops-action.json
#  ✓ wrote dist/m365/manifest.json
#  ✓ wrote dist/m365/color.png  (192x192)
#  ✓ wrote dist/m365/outline.png ( 32x32)
#  ✓ wrote dist/m365/fibreops-copilot.zip

What Gets Generated

FilePurpose
declarativeAgent.jsonDefines the agent's persona, capabilities, and conversation starters for M365 Copilot
fibreops-action.jsonAction plugin that proxies tool calls to the deployed FastAPI backend via OpenAPI
manifest.jsonTeams app manifest with publisher metadata, permissions, and capabilities
color.png / outline.pngApp icons for Teams and M365 surfaces
fibreops-copilot.zipReady-to-upload package for Teams Admin Center

Configuration

Set the base URL to your deployed FastAPI app before publishing — the action plugin uses this to resolve the OpenAPI runtime:

# Set the public HTTPS hostname of the deployed FastAPI app
$env:M365_ACTION_BASE_URL = "https://fibreops-demo.azurewebsites.net"

# Optional: customise publisher metadata
$env:M365_PUBLISHER_NAME = "Contoso Network Operations"
$env:M365_PUBLISHER_WEBSITE = "https://contoso.com/noc"

# Generate the package
python -m fibreops.demo publish-m365 --out dist/m365
Environment VariablePurpose
M365_ACTION_BASE_URLPublic HTTPS root for the FastAPI /openapi.json (e.g., Container Apps FQDN)
M365_APP_IDOverride the generated Teams app GUID (default: deterministic per repo)
M365_PUBLISHER_NAMEPublisher name shown in M365 Admin Center
M365_PUBLISHER_WEBSITEPublisher website link

Uploading the Package

Upload the generated fibreops-copilot.zip through either path:

  1. Teams Admin Center → Manage apps → Upload new app
  2. M365 Admin Center → Integrated apps → Upload custom apps

Once uploaded, the declarative agent:

  • Inherits the publisher metadata you configured
  • Advertises conversation starters from the FibreOps deck (e.g., "What is the current outage status?", "Dispatch an engineer to FN-LDN-001")
  • Proxies tool calls to the deployed FastAPI app via the action plugin
  • Appears in Microsoft 365 Copilot as a specialised agent users can invoke

How Declarative Agents Work

A declarative agent in Microsoft 365 Copilot is defined by metadata rather than code running in the M365 surface. The intelligence lives in your backend — Copilot handles the conversational UX, tool orchestration schema, and user authentication.

The flow:

  1. User invokes the agent in Microsoft 365 Copilot or Teams
  2. Copilot renders conversation starters and accepts natural language input
  3. When the agent needs to act, Copilot calls the action plugin (your OpenAPI endpoint)
  4. Your FastAPI backend processes the request using the full agent pipeline
  5. Results return to the user in the Copilot/Teams UX

This architecture means your agent logic stays in one place — the backend. The M365 surface is purely a distribution and interaction layer.

Action Plugins and OpenAPI

The action plugin (fibreops-action.json) references your FastAPI app's /openapi.json endpoint. FibreOps exposes a JSON API that the action plugin can call:

  • /api/runs — List and query agent runs
  • /api/optimiser — Get optimizer scores and suggestions
  • /sdk/chat — Natural language interaction with the agent system
  • /healthz — Liveness probe

Because FastAPI auto-generates OpenAPI schemas from your typed Python endpoints, the action plugin gets accurate parameter descriptions, response schemas, and error codes without any manual specification work.

Publishing as Autopilots (Public Preview)

Autopilots take distribution one step further — agents that operate autonomously without requiring a user to initiate each interaction. An Autopilot can:

  • React to events (e.g., a critical telemetry signal) without human initiation
  • Take actions within defined guardrails
  • Notify users only when human intervention is needed
  • Operate continuously across Microsoft 365 surfaces

For FibreOps, an Autopilot would monitor the Event Hub stream continuously and only surface to the NOC team when an incident exceeds automated resolution capability — a fully autonomous operations agent.

Teams Adaptive Cards

FibreOps posts rich Adaptive Card notifications to Microsoft Teams throughout the agent pipeline. This is separate from the declarative agent — it is a push notification channel for real-time operational awareness.

# The NetOps agent posts an outage notice via Incoming Webhook
def post_outage_notice(incident_id, node_id, severity, summary, engineer=None):
    card = {
        "type": "AdaptiveCard",
        "body": [
            {"type": "TextBlock", "text": f"🚨 Outage: {node_id}", "weight": "Bolder", "size": "Large"},
            {"type": "FactSet", "facts": [
                {"title": "Severity", "value": severity.upper()},
                {"title": "Incident", "value": incident_id},
                {"title": "Summary", "value": summary},
            ]},
        ],
        "actions": [
            {"type": "Action.OpenUrl", "title": "View in NOC Console", "url": f"{base_url}/runs/{incident_id}"}
        ]
    }
    # POST to Teams webhook or append to outbox for offline mode
    ...

If TEAMS_WEBHOOK_URL is not configured, cards are appended to state/teams_outbox.jsonl for review in the NOC console's Teams panel.

End-to-End: From Code to Copilot

Here is the complete flow from development to distribution:

  1. Build — Develop agents with Microsoft Agent Framework, test locally with python -m fibreops.demo --backend local
  2. Publish agents — python -m fibreops.demo publish creates hosted Prompt Agents in Foundry
  3. Deploy infrastructure — azd up provisions App Service, ACR, Event Hub, Key Vault, and Application Insights
  4. Deploy hosted agent — azd env set FIBREOPS_DEPLOY_HOSTED true && azd up
  5. Generate M365 package — python -m fibreops.demo publish-m365 --out dist/m365
  6. Upload to Teams — Upload fibreops-copilot.zip via Teams Admin Center
  7. Users interact — The agent is now available in Microsoft 365 Copilot and Teams

Security Considerations

  • Managed Identity — The deployed app uses system-assigned managed identity for all Azure service access. No secrets in code.
  • Least privilege — Each role grant is scoped to the minimum required (Event Hubs Data Owner, Key Vault Secrets User, AcrPull, Azure AI Developer).
  • Authentication — The M365 Copilot surface handles user authentication; your backend receives authenticated requests.
  • Guardrails — Autopilots operate within defined boundaries; human-in-the-loop escalation is built into the Routine and agent decision logic.

Key Takeaways

  • Publishing to Teams and M365 Copilot is GA — a single command generates the complete package.
  • Declarative agents separate distribution (M365) from intelligence (your backend).
  • Action plugins leverage your existing FastAPI OpenAPI schema — no manual specification needed.
  • Autopilots (Public Preview) enable fully autonomous operation within guardrails.
  • Adaptive Cards provide real-time push notifications alongside the conversational agent surface.
  • The same backend serves the NOC console, the Copilot SDK, and the M365 declarative agent.

Next Steps

Updated Jul 29, 2026
Version 1.0
No CommentsBe the first to comment