Skip to content

Commit 141ef90

Browse files
authored
add mcp updates (#3)
1 parent ea51435 commit 141ef90

63 files changed

Lines changed: 2597 additions & 545 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

azure.yaml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ hooks:
2727
postprovision:
2828
windows:
2929
shell: pwsh
30-
run: ./scripts/write_env.ps1; ./scripts/setup_credential.ps1
30+
run: ./scripts/write_env.ps1;
3131
continueOnError: true
3232
interactive: true
3333
posix:
3434
shell: sh
35-
run: chmod u+r+x ./scripts/write_env.sh; chmod u+r+x ./scripts/setup_credential.sh; ./scripts/write_env.sh; ./scripts/setup_credential.sh
35+
run: chmod u+r+x ./scripts/write_env.sh; chmod u+r+x ./scripts/write_env.sh;
3636
continueOnError: true
3737
interactive: true
3838

@@ -44,7 +44,11 @@ services:
4444
language: csharp
4545
host: appservice
4646
contoso-store-api:
47-
project: ./src/backend/contoso-store-api
47+
project: ./src/backend/contoso-store/contoso-store-api
48+
language: csharp
49+
host: appservice
50+
contoso-store-mcp:
51+
project: ./src/backend/contoso-store/contoso-store-mcp
4852
language: csharp
4953
host: appservice
5054
web:

docs/docs/02-lab-2-using_azure_foundry.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ In this lab, you’ll learn how to build and extend the capabilities of your AI
6666
6767
For your agent to interact with this API, you need to update the API specification (Swagger file) with the correct endpoint URL:
6868
69-
- Got to `swagger.json` file in the `resources` directory of your project.
69+
- Got to `contoso-store-api-swagger.json` file in the `resources` directory of your project.
7070
- Replace `<APP-SERVICE-URL>` with the actual URL of the Contoso Store API.
7171
7272
You can find this URL in your `.env` file under the variable name `CONTOSO_STORE_API_URL`.

docs/docs/03-lab-3.1-ai_application_architecture.md

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,24 @@
22

33
In this lab, you will learn how to integrate an AI Agent into your own application.
44

5-
The example app is built using a .NET backend API and a React-based chat UI. It walks through a basic scenario of a **Technical Support Agent** that can answer user questions to demonstrate the core concepts.
5+
The example app is built using a .NET backend API and a React-based chat UI.
6+
7+
It walks through a building an AI assistant solution for **Contoso Bike Store** that demonstrates the use of MCP (Model Context Protocol) tools with Azure AI Foundry Agents.
68

79
The goal is to provide a view of the end-to-end data flow between the frontend, backend, and Azure AI services.
810

911
---
1012

1113
## How It Works
1214

13-
![architecture](../media/architecture-2.png)
15+
![architecture](../media/mcp/architecture.png)
1416

15-
- The AI agent is set up in Azure AI Foundry. It can answer IT questions, help with support tickets, and more.
17+
- The AI agent is set up in Azure AI Foundry.
1618
- The .NET backend API connects the chat website to the agent and handles the following requests:
1719
- Calls the AI agent to answer user prompts
1820
- Create Agent and chat threads
1921
- Get chat history for the thread
20-
- The agent has tools (stubs) to do things like set up Office 365 accounts or fix network issues.
22+
- The agent has access to MCP tools to help it answer questions.
2123
- The React frontend is a simple chat page. It sends your messages to the backend and shows the full chat history of the thread.
2224

2325
---
@@ -39,9 +41,9 @@ The goal is to provide a view of the end-to-end data flow between the frontend,
3941
- `GET /api/chat/history?agentId={agentId}&threadId={threadId}`
4042
Retrieves the chat message history for a given thread.
4143

42-
2. Update the `TechSupportAgentConfig` class.
44+
2. Update the `ContosoBikeStoreAgentConfig` class.
4345

44-
The file `src/backend/ai-agent-api/Agents/TechSupportAgentConfig.cs` already exists.
46+
The file `src/backend/ai-agent-api/Agents/ContosoBikeStoreAgentConfig.cs` already exists.
4547

4648
Add or update the following method overrides to define the agent's display name, description, and system message:
4749

@@ -51,21 +53,21 @@ The goal is to provide a view of the end-to-end data flow between the frontend,
5153
```csharp
5254
public override string GetAgentDisplayName()
5355
{
54-
return "Technical Support Agent";
56+
return "Contoso Bike Store Agent";
5557
}
5658

5759
public override string GetDescription()
5860
{
59-
return "This agent provides IT and technical support for the company. " +
60-
"It assists users with troubleshooting, technical queries, and problem resolution. " +
61-
"The agent utilizes the `TechSupportTools` to effectively address and resolve technical issues.";
61+
return "This agent provides customer support for Contoso Bike Store. " +
62+
"It assists users with product inquiries, order status, and store information. " +
63+
"The agent utilizes the `MCP` tools to effectively address and resolve customer questions.";
6264
}
6365

6466
public override string GetSystemMessage()
6567
{
66-
return "You are a technical support agent. " +
67-
"Your role is to assist users with IT and technical issues, providing solutions and troubleshooting steps. " +
68-
"Use the tools available to you to resolve problems efficiently.";
68+
return "You are a customer support agent for Contoso Bike Store. " +
69+
"Your role is to assist users with product information, order status, and store details. " +
70+
"Use the tools available to you to provide accurate and helpful responses.";
6971
}
7072
```
7173

@@ -105,19 +107,17 @@ The goal is to provide a view of the end-to-end data flow between the frontend,
105107

106108
Copy the URL and open it in your browser to access the chat UI.
107109

108-
![chat-bot-ui.png](../media/chat-bot-ui_01.png)
109-
110-
The Agent has access to the tools defined in the `src/backend/ai-agent-api/KernelTools/TechSupportTools.cs` file. These methods are stubs and simulate the actions that the agent can perform for an IT support scenario.
110+
![chat-bot-ui.png](../media/mcp/chat-1.png)
111111

112112
9. Now start chatting with the agent!
113113

114114
You can ask the agent questions like:
115115

116-
- Reset the password for John Doe
117-
- Create a new Office 365 account for John Doe
118-
- Send a Welcome email to John Doe
116+
- What are the available bike models?
117+
- Can you help me track my order #12345?
118+
- I want to place a new order for a mountain bike. Could you assist me with that?
119119

120-
![chat-bot-ui.png](../media/chat-bot-ui_03.png)
120+
![chat-bot-ui.png](../media/mcp/chat-2.png)
121121

122122
---
123123

@@ -134,4 +134,4 @@ Test your understanding and extend the solution with these challenges:
134134
3. **Create a New Agent Scenario**
135135
Design and implement a new agent for a different use case.
136136

137-
For example, integrate the `ContosoInventoryAgent` we built in a previous lab.
137+
For example, create a **Policy Agent** that can answer questions about company policies and procedures.
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# Build a Simple Chat UI for Your AI Agent
2+
3+
In this lab, you will learn how to integrate an AI Agent into your own application.
4+
5+
The example app is built using a .NET backend API and a React-based chat UI. It walks through a basic scenario of a **Technical Support Agent** that can answer user questions to demonstrate the core concepts.
6+
7+
The goal is to provide a view of the end-to-end data flow between the frontend, backend, and Azure AI services.
8+
9+
---
10+
11+
## How It Works
12+
13+
![architecture](../media/architecture-2.png)
14+
15+
- The AI agent is set up in Azure AI Foundry. It can answer IT questions, help with support tickets, and more.
16+
- The .NET backend API connects the chat website to the agent and handles the following requests:
17+
- Calls the AI agent to answer user prompts
18+
- Create Agent and chat threads
19+
- Get chat history for the thread
20+
- The agent has tools (stubs) to do things like set up Office 365 accounts or fix network issues.
21+
- The React frontend is a simple chat page. It sends your messages to the backend and shows the full chat history of the thread.
22+
23+
---
24+
25+
## Build the Application
26+
27+
1. The code for the backend and frontend is in the `src/` folder of the repository.
28+
29+
Refer to the file `/src/backend/ai-agent-api/Controllers/ChatController.cs` for the details of the API endpoints that the frontend uses.
30+
31+
It has the following endpoints:
32+
33+
- `GET /api/agent`
34+
Gets information about the chat agent (name, display name, description).
35+
36+
- `POST /api/chat/send`
37+
Sends a chat message to the agent and returns the agent thread id.
38+
39+
- `GET /api/chat/history?agentId={agentId}&threadId={threadId}`
40+
Retrieves the chat message history for a given thread.
41+
42+
2. Update the `TechSupportAgentConfig` class.
43+
44+
The file `src/backend/ai-agent-api/Agents/TechSupportAgentConfig.cs` already exists.
45+
46+
Add or update the following method overrides to define the agent's display name, description, and system message:
47+
48+
!!! info
49+
The setup uses a simple Factory pattern to create the agent configuration. In real applicaitons you would store the agent configuration in a database or a configuration file and load it dynamically.
50+
51+
```csharp
52+
public override string GetAgentDisplayName()
53+
{
54+
return "Technical Support Agent";
55+
}
56+
57+
public override string GetDescription()
58+
{
59+
return "This agent provides IT and technical support for the company. " +
60+
"It assists users with troubleshooting, technical queries, and problem resolution. " +
61+
"The agent utilizes the `TechSupportTools` to effectively address and resolve technical issues.";
62+
}
63+
64+
public override string GetSystemMessage()
65+
{
66+
return "You are a technical support agent. " +
67+
"Your role is to assist users with IT and technical issues, providing solutions and troubleshooting steps. " +
68+
"Use the tools available to you to resolve problems efficiently.";
69+
}
70+
```
71+
72+
3. Review the source code in the file `src/backend/ai-agent-api/Services/AzureAIAgentService.cs` to understand how the backend API interacts with the Azure AI Agent.
73+
74+
!!! warning
75+
Some API methods from the Semantic Kernel SDK are in preview and may change in future releases.
76+
77+
Check the official docs for updates.
78+
79+
4. Build the backend API to ensure it compiles correctly.
80+
If the build completes without errors, you are ready to proceed to deployment.
81+
82+
```bash
83+
dotnet build src/backend/ai-agent-api/AIAgent.API.sln
84+
```
85+
86+
## Deploy the Application
87+
88+
5. The Azure resources were already created in a previous lab (with `azd up`).
89+
6. Run the following command. This will build the backend and frontend applications and deploy them to Azure.
90+
91+
```bash
92+
azd deploy
93+
```
94+
95+
!!! note
96+
If you want to run the app locally, you can use `dotnet run` for the backend and `npm start` for the frontend. Make sure you have the required environment variables set up.
97+
98+
7. The backend and the frontend applications are hosted in Azure App Service.
99+
100+
You can find the URLs in the Azure portal or in the `azd` output.
101+
102+
![web-app-url.png](../media/web-app-url.png)
103+
104+
8. You can find the url of the chat UI in the `.env` file with the variable `FRONTEND_APP_URL`.
105+
106+
Copy the URL and open it in your browser to access the chat UI.
107+
108+
![chat-bot-ui.png](../media/chat-bot-ui_01.png)
109+
110+
The Agent has access to the tools defined in the `src/backend/ai-agent-api/KernelTools/TechSupportTools.cs` file. These methods are stubs and simulate the actions that the agent can perform for an IT support scenario.
111+
112+
9. Now start chatting with the agent!
113+
114+
You can ask the agent questions like:
115+
116+
- Reset the password for John Doe
117+
- Create a new Office 365 account for John Doe
118+
- Send a Welcome email to John Doe
119+
120+
![chat-bot-ui.png](../media/chat-bot-ui_03.png)
121+
122+
---
123+
124+
## Code Challenges
125+
126+
Test your understanding and extend the solution with these challenges:
127+
128+
1. **Add a Knowledge Tool**
129+
Enhance the agent by integrating a file search tool. This tool should allow the agent to read a file and answer user questions based on its content.
130+
131+
2. **Execute Tasks via OpenAI Spec**
132+
Use the OpenAI Spec tool to execute tasks by calling external APIs. For example, expose an API that allows the agent to create a new support ticket in an external system.
133+
134+
3. **Create a New Agent Scenario**
135+
Design and implement a new agent for a different use case.
136+
137+
For example, integrate the `ContosoInventoryAgent` we built in a previous lab.
79.7 KB
Loading

docs/docs/media/mcp/chat-1.png

40.7 KB
Loading

docs/docs/media/mcp/chat-2.png

74.3 KB
Loading

infra/main.bicep

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ module app 'modules/app.bicep' = {
136136
foundryProjectEndpoint: aiProject.outputs.endpoint
137137
foundryProjectName: aiProject.outputs.name
138138
openAIDeploymentName: chatCompletionModel
139+
appInsightsConnectionString: shared.outputs.appInsightsConnectionString
139140
}
140141
}
141142

@@ -151,6 +152,7 @@ output AZURE_AI_PROJECT_ENDPOINT string = aiProject.outputs.endpoint
151152
output BACKEND_APP_URL string = app.outputs.BACKEND_APP_URL
152153
output FRONTEND_APP_URL string = app.outputs.FRONTEND_APP_URL
153154
output CONTOSO_STORE_APP_URL string = app.outputs.CONTOSO_STORE_APP_URL
155+
output CONTOSO_STORE_MCP_URL string = app.outputs.CONTOSO_STORE_MCP_URL
154156

155157
output AZURE_OPENAI_DEPLOYMENT_NAME string = chatCompletionModel
156158
output TEXT_MODEL_NAME string = chatCompletionModel //TODO: to be removed when the notebook is updated

infra/modules/app.bicep

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ param tags object
66
param foundryProjectEndpoint string
77
param foundryProjectName string
88
param openAIDeploymentName string
9+
param appInsightsConnectionString string = ''
910

1011
var frontendAppName = '${resourcePrefix}-web-${uniqueSuffixValue}'
1112
var backendAppName = '${resourcePrefix}-api-${uniqueSuffixValue}'
1213
var contosoStoreAppName = '${resourcePrefix}-contoso-store-${uniqueSuffixValue}'
14+
var mcpServerAppName = '${resourcePrefix}-mcp-${uniqueSuffixValue}'
1315

1416
resource appServicePlan 'Microsoft.Web/serverfarms@2022-03-01' = {
1517
name: '${resourcePrefix}-plan-${uniqueSuffixValue}'
@@ -60,6 +62,14 @@ resource backendApp 'Microsoft.Web/sites@2022-03-01' = {
6062
name: 'Azure__SubscriptionId'
6163
value: subscription().subscriptionId
6264
}
65+
{
66+
name: 'CONTOSO_STORE_MCP_URL'
67+
value: 'https://${mcpServerApp.name}.azurewebsites.net/sse'
68+
}
69+
{
70+
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
71+
value: appInsightsConnectionString
72+
}
6373
]
6474
}
6575
}
@@ -84,6 +94,10 @@ resource frontendApp 'Microsoft.Web/sites@2022-03-01' = {
8494
name: 'VITE_API_BASE_URL'
8595
value: 'https://${backendAppName}.azurewebsites.net'
8696
}
97+
{
98+
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
99+
value: appInsightsConnectionString
100+
}
87101
]
88102
}
89103
}
@@ -101,6 +115,41 @@ resource contosoStoreApp 'Microsoft.Web/sites@2022-03-01' = {
101115
properties: {
102116
serverFarmId: appServicePlan.id
103117
httpsOnly: true
118+
siteConfig: {
119+
appSettings: [
120+
{
121+
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
122+
value: appInsightsConnectionString
123+
}
124+
]
125+
}
126+
}
127+
}
128+
129+
resource mcpServerApp 'Microsoft.Web/sites@2022-03-01' = {
130+
name: mcpServerAppName
131+
location: location
132+
tags: union(tags, {
133+
'azd-service-name': 'contoso-store-mcp'
134+
})
135+
identity: {
136+
type: 'SystemAssigned'
137+
}
138+
properties: {
139+
serverFarmId: appServicePlan.id
140+
httpsOnly: true
141+
siteConfig: {
142+
appSettings: [
143+
{
144+
name: 'CONTOSO_STORE_URL'
145+
value: 'https://${contosoStoreAppName}.azurewebsites.net'
146+
}
147+
{
148+
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
149+
value: appInsightsConnectionString
150+
}
151+
]
152+
}
104153
}
105154
}
106155

@@ -128,3 +177,4 @@ resource backendAppRoleAssignment2 'Microsoft.Authorization/roleAssignments@2022
128177
output BACKEND_APP_URL string = 'https://${backendApp.name}.azurewebsites.net'
129178
output FRONTEND_APP_URL string = 'https://${frontendApp.name}.azurewebsites.net'
130179
output CONTOSO_STORE_APP_URL string = 'https://${contosoStoreApp.name}.azurewebsites.net'
180+
output CONTOSO_STORE_MCP_URL string = 'https://${mcpServerApp.name}.azurewebsites.net/sse'

resources/contoso-store-api-swagger.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
},
77
"servers": [
88
{
9-
"url": "https://aiagentwks-contoso-store-mbo43n.azurewebsites.net"
9+
"url": "<APP-SERVICE-URL>"
1010
}
1111
],
1212
"paths": {

0 commit comments

Comments
 (0)