Microsoft Copilot Studio Integration
with MCP Server - Overview¶
Connect your MCP Server to Microsoft Copilot Studio to create low-code/no-code AI agents with enterprise data access.
Perfect for business users and citizen developers.
Table of contents
What You'll Build¶
- Custom Copilot with MCP tool integration
- Conversational AI for domain-specific tasks
- Enterprise Chatbot with Azure service access
- Teams/Web deployment ready
Prerequisites¶
- Microsoft Copilot Studio license
- MCP Server deployed with public endpoint
- Microsoft Teams (optional, for Teams deployment)
Quick Start¶
Step 1: Access Copilot Studio
- Navigate to Copilot Studio
- Sign in with your Microsoft account
- Select your environment (or create new)
Step 2: Create New Copilot
- Click Create → New Copilot
- Choose From Blank
- Enter details:
- Name: Healthcare Assistant (or your industry)
- Description: AI assistant with MCP-powered data access
- Language: English
- Click Create
Step 3: Add MCP Server as Tool
Option A (Recommended): MCP onboarding wizard:Copilot Studio supports connecting directly to an MCP server using the Model Context Protocol tool type.
- In your Copilot, go to the Tools page
- Select Add a tool → New tool
- Select Model Context Protocol
- Enter:
- Server URL:
https://your-mcp.azurecontainerapps.io/mcp - Authentication: None, API key, or OAuth 2.0
Note
- Copilot Studio currently supports the Streamable transport type for MCP.
- This repo’s MCP server exposes a standards-based Streamable endpoint at
POST /mcp(JSON-RPC).
Option B: Custom connector (MCP Streamable): If you need to manage the connection via Power Apps, create a custom connector using a minimal OpenAPI schema that points to POST /mcp and includes the MCP protocol marker.
swagger: '2.0'
info:
title: Azure MCP Blueprint
description: MCP Streamable endpoint for Copilot Studio
version: 1.0.0
host: your-mcp.azurecontainerapps.io
basePath: /
schemes:
- https
paths:
/mcp:
post:
summary: MCP Streamable endpoint
x-ms-agentic-protocol: mcp-streamable-1.0
operationId: InvokeMCP
responses:
'200':
description: JSON-RPC response
'202':
description: Accepted (notifications / responses)
Step 4: Configure Topics with MCP Tools
Example: Healthcare Patient Lookup
- Go to Topics tab
- Click + New topic → From blank
- Name: "Patient Lookup"
- Add trigger phrases:
- "Find patient"
- "Search for patient records"
- "Show me patient information"
Conversation Flow:
Node 1: Trigger - Patient lookup request detected
Node 2: Question - Get patient details
- "What is the patient name or ID you're looking for?"
- Save response as: patientQuery
Node 3: Action - Call MCP Tool
- Tool: `search_documents`
- Arguments:
{
"query": "{patientQuery}",
"top": 5
}
- Save response as: searchResults
Node 4: Message - Display results
- "I found the following patient records:"
- {searchResults.content.results[0].firstName} {searchResults.content.results[0].lastName}
- Patient ID: {searchResults.content.results[0].patientId}
- Last Visit: {searchResults.content.results[0].lastVisitDate}
Node 5: Question - Follow-up
- "Would you like more details on any patient?"
- Options: Yes / No
- Save topic
- Test in Test Copilot pane
Step 5: Industry-Specific Topics
Example topic mappings (Industry → Trigger → MCP tool call)
| Industry | Topic | Trigger phrase examples | MCP tool | Example action (tool → parameters/query) |
|---|---|---|---|---|
| Healthcare | Medication Lookup | “What medications is patient taking?”, “Show meds for {patientId}” | cosmos_query_items |
cosmos_query_items → SELECT c.medications FROM c WHERE c.patientId = '{patientId}' |
| Healthcare | Allergy Check | “Check patient allergies”, “Is {patientId} allergic to {allergy}?” | search_documents |
search_documents → {"query":"","top":10,"filter":"allergies/any(a: a eq '{allergy}')"} |
| Retail | Product Search | “Find product”, “Search {product}”, “Products under $50” | search_documents |
search_documents → {"query":"{productQuery}","top":10,"filter":null} |
| Retail | Inventory Check | “Check stock availability”, “Is SKU {sku} in stock?” | cosmos_query_items |
cosmos_query_items → SELECT * FROM c WHERE c.sku = '{sku}' |
| Finance | Transaction Search | “Show my transactions”, “Transactions last 30 days” | cosmos_query_items |
cosmos_query_items → SELECT * FROM c WHERE c.accountId = '{accountId}' ORDER BY c.timestamp DESC |
| Finance | Fraud Alert | “Check for suspicious activity”, “High fraud scores” | cosmos_query_items |
cosmos_query_items → SELECT * FROM c WHERE c.fraudScore > 0.7 ORDER BY c.fraudScore DESC |
Step 6: Generative Answers (Optional)
Publish to Demo Website: Enable generative responses powered by MCP data.
- Go to Settings → Generative AI
- Enable Generative answers
- Configure:
- Data source: MCP Server (via connector)
- Moderation: Medium
-
Content safety: Enabled
-
Create Generative Topic:
System Instructions:
You are a {industry} AI assistant with access to real-time data via MCP tools.
Available Tools:
- search_documents: Full-text search
- cosmos_query_items: SQL-like queries
- search_semantic: AI-powered semantic search
- openai_chat_completion: Generate insights
When users ask questions:
1. Identify the appropriate MCP tool
2. Call the tool with correct parameters
3. Interpret results clearly
4. Provide helpful, accurate responses
Always maintain data privacy and security.
Step 7: Test Your Copilot
- Click Test your copilot (top right)
- Try example queries:
- "Find all diabetic patients"
- "Search for products under $50"
-
"Show high-value transactions"
-
Verify MCP tool calls in Test pane
Step 8: Publish
Publish to Demo Website:
- Go to Publish tab
- Click Publish
- Select Demo website
-
Share link:
https://your-copilot.powerapps.com/...Publish to Microsoft Teams:
-
Go to Publish tab
- Click Publish
- Select Microsoft Teams
- Configure:
- Icon
- Short description
- Full description
- Submit for approval (if required)
-
Install in Teams
Embed in Website:
<!DOCTYPE html>
<html>
<head>
<title>Healthcare Assistant</title>
</head>
<body>
<h1>Healthcare AI Assistant</h1>
<!-- Copilot Studio Embed Code -->
<div id="copilot-container"></div>
<script src="https://cdn.botframework.com/botframework-webchat/latest/webchat.js"></script>
<script>
window.WebChat.renderWebChat({
directLine: window.WebChat.createDirectLine({
secret: 'YOUR_DIRECT_LINE_SECRET'
}),
userID: 'user-' + Date.now(),
username: 'User',
locale: 'en-US',
styleOptions: {
botAvatarImage: 'https://your-logo.png',
botAvatarInitials: 'HA',
userAvatarImage: '',
userAvatarInitials: 'You',
primaryFont: 'Segoe UI, sans-serif'
}
}, document.getElementById('copilot-container'));
</script>
</body>
</html>
Advanced Features¶
Authentication & Security
Azure AD Authentication:
- In Settings → Security
- Enable Authentication
- Select Azure Active Directory
- Configure:
- Tenant ID
- Client ID
-
Redirect URI
Row-Level Security:
# In MCP Server, implement user-scoped queries
def get_user_data(user_id: str, query: str):
# Add user filter to all queries
scoped_query = f"{query} AND c.ownerId = '{user_id}'"
return cosmos_client.query(scoped_query)
Analytics & Monitoring
- Go to Analytics tab
- View metrics:
- Total sessions
- Resolution rate
- Escalation rate
-
MCP tool usage
-
Export logs for analysis
Multi-Language Support
- Settings → Languages
- Add languages:
- Spanish
- French
- German
- MCP server returns localized results
Industry Templates¶
Each row maps a user intent to a specific MCP tool call, what to pass, and what to show.
| Industry | Topics (deep dive) | Trigger phrases (examples) | MCP tools used | Example calls (shapes) | What to display back | Notes (design + safety) |
|---|---|---|---|---|---|---|
| Healthcare | - Patient Lookup - Medication History - Appointment Scheduling - Lab Results Inquiry - Allergy Checker |
- “Find patient”, “Find patients with diabetes” - “Show medications for {patientId}” - “Book with Dr. Smith next week” - “Show latest labs / HbA1c” - “Is {patientId} allergic to penicillin?” |
- search_documents- cosmos_query_items- search_semantic- openai_chat_completion |
- Search: {"query":"diabetes","top":5,"filter":null}- Cosmos: {"query":"SELECT c.medications FROM c WHERE c.patientId = '{patientId}'"}- Semantic: {"query":"latest lab results HbA1c for {patientId}","top":5}- Foundry: {"messages":[...],"model":"gpt-4o"} |
- Patient match list (name, patientId, lastVisitDate) - Medication/allergy fields only (minimal data) - Lab snippets + dates - Clarifying questions for scheduling |
- Prefer patientId over names for precision - Keep outputs descriptive (not prescriptive medical advice) - Avoid returning entire patient record unless required |
| Retail | - Product Search - Inventory Status - Order Tracking - Loyalty Points - Recommendations |
- “Search headphones”, “Laptops under $1000” - “Is SKU {sku} in stock?” - “Track order {orderId}” - “My loyalty points” - “Recommend products like {productName}” |
- search_documents- cosmos_query_items- openai_chat_completion |
- Search: {"query":"headphones","top":10,"filter":null}- Cosmos: {"query":"SELECT * FROM c WHERE c.transactionId = '{orderId}'"}- Foundry: {"messages":[...],"model":"gpt-4o"} |
- Product list (name/category/price if indexed) - Availability/stock fields (if present) - Order status + last update - Loyalty point balance - Short recommendation list |
- Confirm identifier formats (orderId vs transactionId) - For recommendations: Search first (grounding) then summarize with Foundry - Minimize PII (use customerId, not email) |
| Finance | - Account Balance - Transaction History - Fraud Alerts - Payment Processing - Financial Insights |
- “Balance for account {accountId}” - “Transactions last 30 days” - “Suspicious activity?” - “Pay my bill / send $50” - “Spending insights” |
- cosmos_query_items- openai_chat_completion |
- Cosmos: {"query":"SELECT * FROM c WHERE c.accountId = '{accountId}' AND c.timestamp >= '{isoDate}' ORDER BY c.timestamp DESC"}- Fraud: {"query":"SELECT * FROM c WHERE c.fraudScore > 0.7 ORDER BY c.fraudScore DESC"}- Foundry: {"messages":[...],"model":"gpt-4o"} |
- Balance + currency (if stored) - Recent transactions (amount/merchant/time) - Flagged transactions + fraudScore - Confirmation step for payments - Category insights + next steps |
- Present fraud as a signal, not a final determination - Only simulate payments unless you have a real backend - Best pattern for insights: Cosmos query → Foundry summary |
Important: Template data is synthetic but can contain PII-like fields such as names, email addresses, phone numbers, addresses, and dates of birth. Avoid logging tool outputs and apply least-privilege access.
| Operations area | Symptom / goal | What to check | Fix |
|---|---|---|---|
| Topic design | Topic tries to do too much | One topic is handling multiple intents | Split into multiple topics; keep each topic to a single task. |
| Fallback | Users ask unhandled questions | No fallback topic / poor trigger phrases | Add a fallback topic; expand trigger phrases; route to a “help me choose” question. |
| Testing | Tools don’t fire in Test pane | Action node not reached; variables not set | Add explicit questions to capture inputs; verify the tool name and JSON shape; save tool response into a variable. |
| Monitoring | Need usage + quality visibility | No review cadence | Review Copilot Studio analytics weekly; correlate with MCP server logs (App Insights / platform logs). |
| MCP connector | Connector fails to connect | Endpoint not public; auth mismatch; CORS; wrong URL | Verify the MCP URL is reachable and points to /mcp; validate auth settings (none/API key/OAuth); configure allowed origins if enforced by the server. |
| Tool call failures | Tool returns an error | Bad arguments; missing dependent Azure service config | Validate against the tool’s input schema; check MCP server logs; verify Cosmos/Search/Foundry endpoints and credentials/managed identity permissions. |
Sample Copilot Export¶
See the Copilot Studio sample exports in the source repository for:
- Healthcare Assistant (.zip export)
- Retail Assistant (.zip export)
- Finance Assistant (.zip export)