A custom Azure AI Foundry agent that answers questions from SharePoint documents using the SharePoint Grounding tool, letting Frontline Workers chat with company data without the $30/user/month Microsoft 365 Copilot license.
v2/ explored using Azure AI Foundry's built-in one-click Publish to push the agent directly to Teams / M365 Copilot — eliminating the custom App Registration, Bot Service, App Service, and manual Teams manifest.
However, Publish currently does not support the SharePoint tool or OAuth authentication for tools — both are listed as temporary limitations with fixes in progress (source). This means the SharePoint Grounding tool that powers this project will not work in a published agent today.
The v2 folder remains as a reference (RBAC documentation, SDK test scripts, and future-proofing). For a working deployment, use either:
- openwebui/ — recommended; web-based chat with per-user passthrough auth (→ README)
- v1 (below) — full-control Teams bot with custom OAuth
→ v2 README (RBAC docs, SDK scripts) | → v2 Tutorial (agent setup steps)
Microsoft 365 Copilot costs $30 per user per month. For organisations with hundreds or thousands of Frontline Workers (F1/F3 licences) who only need to ask questions about a handful of SharePoint sites, that cost is prohibitive.
This project proves that a Custom AI Agent backed by Azure AI Foundry can deliver the same "chat with your SharePoint data" experience at a fraction of the cost — paying only for Azure OpenAI token consumption (pay-as-you-go) instead of a per-seat Copilot licence.
Could this be done with Copilot Studio instead? Yes — see CopilotStudioAlternative.md for an honest feature, licensing, and cost comparison between the pro-code path and the low-code Copilot Studio alternative.
| Layer | Component | Purpose |
|---|---|---|
| Identity | Entra ID App Registration (SharePoint-Copilot-Agent) |
Delegated permissions + OBO flow |
| Bot | Azure Bot Service (sharepoint-copilot-bot) |
Teams channel, OAuth connection |
| Agent | Azure AI Foundry Agent (SharePoint-Agent / gpt-4.1) |
LLM orchestration |
| Knowledge | SharePoint Grounding tool (SDK-only) | Searches SharePoint on behalf of the signed-in user |
| SDK Scripts | Python package (sharepoint_agent) |
Configure, test, and manage the agent from code |
flowchart LR
A["Teams App
(Frontline Worker)"] <--> B["Azure Bot Svc
(OAuth / OBO)"]
B <--> C["App Service
(bot.py bridge)
Python 3.12 / F1"]
C <--> D["AI Foundry Agent
(gpt-4.1)"]
D <--> E["SharePoint Online
(user's sites)"]
D -- "sharepoint_grounding" --> E
style D fill:#0078D4,color:#fff
| Requirement | Version |
|---|---|
| Python | ≥ 3.11 |
| Azure CLI | logged in (az login) |
| Azure subscription | with AI Foundry + Bot Service |
| M365 tenant | with SharePoint Online |
# 1. Clone
git clone <repo-url>
cd sharepoint-agent
# 2. Copy .env.example and fill in YOUR Azure resource IDs
# Windows:
Copy-Item .env.example .env
# Linux / macOS:
cp .env.example .env
# Then open .env in your editor and replace every placeholder.
# 3. Setup (creates .venv, installs package)
# Windows:
.\scripts\setup.ps1
# Linux / macOS:
./scripts/setup.sh
# 4. Activate the virtual environment
# Windows:
.\.venv\Scripts\Activate.ps1
# Linux / macOS:
source .venv/bin/activate
# 5. Configure the agent (attach SharePoint tool + update instructions)
# Windows:
.\scripts\configure.ps1
# Linux / macOS:
./scripts/configure.sh
# 6. Test
# Windows:
.\scripts\test.ps1
# Linux / macOS:
./scripts/test.shAfter pip install -e . (done by the setup script), these commands are
available inside the .venv:
| Command | What it does |
|---|---|
sp-configure |
Attach SharePoint Grounding tool to the agent (idempotent) |
sp-fix |
Update agent system instructions |
sp-test |
Run a single query with full step trace |
sp-test-multi |
Run 3 queries and verify tool invocation |
sp-serve |
Start the bot web server (local dev on port 3978) |
.\scripts\package-teams.ps1 |
Build Teams app .zip for sideloading |
.\scripts\deploy-appservice.ps1 |
Deploy bot to Azure App Service (free tier, 9-step) |
Copy .env.example to .env and fill in your values — the scripts
load it automatically via python-dotenv. Every variable below can also
be set as a regular environment variable:
| Variable | Default | Description |
|---|---|---|
AGENT_ENDPOINT |
https://<your-ai-services-account>.services.ai.azure.com/… |
AI Foundry project endpoint |
AGENT_ID |
<your-agent-id> |
Agent assistant ID |
AZURE_SUBSCRIPTION_ID |
<your-subscription-id> |
Azure subscription |
AZURE_RESOURCE_GROUP |
<your-resource-group> |
Resource group |
AI_SERVICES_ACCOUNT |
<your-ai-services-account> |
Cognitive Services account |
AI_FOUNDRY_PROJECT |
proj-default |
AI Foundry project name |
SHAREPOINT_CONNECTION_NAME |
SharePointOBO |
SharePoint connection name |
MICROSOFT_APP_ID |
(your client ID) | Entra ID App Registration ID (for Teams packaging) |
MICROSOFT_APP_PASSWORD |
(your client secret) | Entra ID Client Secret (for bot auth) |
MICROSOFT_APP_TENANT_ID |
(your tenant ID) | Entra ID Tenant ID (required — bot is SingleTenant) |
sharepoint-agent/
├── pyproject.toml # Package metadata & dependencies
├── .env.example # Template — copy to .env and fill in
├── README.md # This file (WHY / WHAT / HOW)
├── TUTORIAL.md # Step-by-step reproduction guide
├── .gitignore
│
├── src/
│ └── sharepoint_agent/
│ ├── __init__.py # Package version
│ ├── config.py # Shared Azure resource IDs
│ ├── configure_agent.py # Attach SharePoint Grounding tool
│ ├── fix_agent.py # Update system instructions
│ ├── test_agent.py # Single-query trace
│ ├── test_agent_multi.py # Multi-query smoke test
│ ├── bot.py # Bot Framework bridge to AI Foundry
│ └── app.py # aiohttp web server entry-point
│
├── requirements.txt # Explicit deps for App Service deploy
│
├── scripts/
│ ├── setup.ps1 / setup.sh # One-time env setup
│ ├── configure.ps1 / configure.sh # Agent configuration
│ ├── test.ps1 / test.sh # Run smoke tests
│ ├── package-teams.ps1 / .sh # Build Teams + Copilot app package
│ └── deploy-appservice.ps1 # Deploy bot to Azure App Service
│
└── teams/
├── manifest.json # Teams app manifest v1.19 (template)
├── color.png # 192×192 app icon
└── outline.png # 32×32 outline icon
The deploy script (deploy-appservice.ps1) uses the Kudu zipdeploy
endpoint — not az webapp deploy --type zip (OneDeploy). This is
critical because OneDeploy does not trigger the Oryx build pipeline,
so pip install never runs and the app crashes.
The deployment zip must have a flat layout (sharepoint_agent/ at
the root, not inside src/) because App Service runs
python -m sharepoint_agent.app from /home/site/wwwroot.
SingleTenant auth: The Azure Bot is registered as SingleTenant.
The bot adapter requires MICROSOFT_APP_TENANT_ID to validate incoming
Bot Framework tokens. Without it, the bot silently ignores all messages.
See TUTORIAL.md — Step 12c for the full walkthrough with troubleshooting.
The Teams app package (v1.19 manifest) includes a declarative agent
that surfaces the bot inside Microsoft 365 Copilot Chat. The agent uses
Copilot's native OneDriveAndSharePoint capability to search your
configured SharePoint site.
The app works as both:
- A standalone Teams bot — no Copilot licence needed (F1/F3 users)
- A Copilot Chat agent — requires Copilot or Copilot Chat (pay-as-you-go, ~$1/metered message)
See TUTORIAL.md — Step 12f for setup and testing instructions.
| Component | Cost |
|---|---|
| M365 Copilot licence | $0 (not required) |
| User licence (F1/F3/E3) | Existing — no change |
| LLM inference (gpt-4.1) | Azure OpenAI pay-as-you-go |
| Bot Service (Teams channel) | Free (standard channels) |
| App Service (bot hosting) | Free (F1 tier) |
| SharePoint Grounding | Free (Graph API, included in M365) |
This repository contains two approaches:
| Aspect | v1 (this folder) | v2/ |
|---|---|---|
| Setup time | ~60–90 minutes | ~15–30 minutes |
| App Registration | Manual (portal, 4 steps) | Auto (Foundry Publish) |
| Bot Service | Manual creation | Auto-provisioned |
| App Service | Required (bot.py bridge) | Not needed |
| Teams Manifest | Hand-built + sideloaded | Auto-generated |
| Env vars | 10+ | 4 (SDK testing only) |
| Dependencies | 7 (incl. botbuilder, aiohttp) | 4 (SDK only) |
| Maintenance | Secret rotation, App Service monitoring | Minimal (platform-managed) |
| Use case | Full control, custom bot logic | Recommended for most teams |
Recommendation: Start with v2 unless you need custom bot middleware, custom OAuth flows, or other advanced scenarios that require full control over the infrastructure.
MIT