Skip to content

Commit 2af7dac

Browse files
committed
Merge branch 'mcp-apps' of https://github.com/ggailey777/azure-docs-pr into mcp-apps
2 parents b1388bb + 252e35a commit 2af7dac

3 files changed

Lines changed: 55 additions & 27 deletions

File tree

articles/azure-functions/TOC.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
- name: Custom remote MCP server
3737
displayName: AI, agent, agentic, tools, trigger
3838
href: scenario-custom-remote-mcp-server.md
39-
- name: MCP Apps server
39+
- name: MCP Apps
4040
displayName: AI, agent, agentic, tools, MCP Apps, UI
4141
href: scenario-mcp-apps.md
4242
- name: Host MCP server using SDKs

articles/azure-functions/functions-bindings-mcp-resource-trigger.md

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ For information on setup and configuration details, see the [overview](functions
2121
> For C#, the Azure Functions MCP extension supports only the [isolated worker model](dotnet-isolated-process-guide.md).
2222
::: zone-end
2323

24-
::: zone pivot="programming-language-csharp,programming-language-python,programming-language-typescript"
24+
::: zone pivot="programming-language-csharp,programming-language-python,programming-language-typescript,programming-language-javascript"
2525
## Example 1
2626

2727
Example 1 shows how to leverage resource to implement the UI element of MCP Apps.
@@ -125,12 +125,15 @@ In this example, a folder called `assets` containing the `readme` is bundled wit
125125
</ItemGroup>
126126
```
127127

128-
The `PreserveNewest` directive copies everything under `assets` into the build output, preserving the folder structure. When deployed to Azure Functions, these files are extracted to the function app root directory (`%HOME%\site\wwwroot`), so a file at `assets/readme.md` in the project is accessible at runtime via `Path.Combine(AppContext.BaseDirectory, "assets", "readme.md")`. This works the same way both locally and when deployed to Azure. The asset files are packaged with the deployment artifact rather than uploaded separately to external storage. For the complete code example, see the [Azure Functions MCP Extension repo](https://github.com/Azure/azure-functions-mcp-extension/tree/main/test/TestAppIsolated).
128+
For the complete code example, see the [Azure Functions MCP Extension repo](https://github.com/Azure/azure-functions-mcp-extension/tree/main/test/TestAppIsolated).
129129

130130
::: zone-end
131131

132132
::: zone pivot="programming-language-java"
133-
The MCP extention in Java does not support resource today.
133+
134+
> [!IMPORTANT]
135+
> The MCP extension in Java does _not_ support resource today.
136+
134137
::: zone-end
135138

136139
::: zone pivot="programming-language-javascript"
@@ -215,7 +218,9 @@ app.mcpTool("getWeather", {
215218
For the complete code example, see [weatherMcpApp.ts](https://github.com/Azure-Samples/remote-mcp-functions-typescript/blob/McpAppDemo/src/functions/weatherMcpApp.ts).
216219

217220
> [!NOTE]
218-
> The MCP resource trigger for TypeScript requires version `4.12.0-preview.2` or later of the [`@azure/functions`](https://www.npmjs.com/package/@azure/functions/v/4.12.0-preview.2) package, which is in _preview_ extension bundle version `[4.32.0, 5.0.0)`. Check `host.json` to make sure the correct bundle version is specified:
221+
> The MCP resource trigger for TypeScript requires version `4.12.0-preview.2` or later of the [`@azure/functions`](https://www.npmjs.com/package/@azure/functions/v/4.12.0-preview.2) package.
222+
>
223+
> The function app must include the preview extension bundle version `[4.32.0, 5.0.0)`. Check `host.json` to make sure the correct bundle version is specified:
219224
>
220225
> ```json
221226
> "extensionBundle": {
@@ -288,18 +293,23 @@ def get_weather(location: str) -> Dict[str, Any]:
288293
For the complete code example, see [function_app.py](https://github.com/Azure-Samples/remote-mcp-functions-python/blob/main/src).
289294

290295
> [!NOTE]
291-
> The MCP resource trigger for Python requires version `1.25.0b3` or later of the [`azure-functions`](https://pypi.org/project/azure-functions/1.25.0b3/) package, which is in _preview_ extension bundle version `[4.32.0, 5.0.0)`. Check `host.json` to make sure the correct bundle version is specified:
296+
> The MCP resource trigger for Python requires version `1.25.0b3` or later of the [`azure-functions`](https://pypi.org/project/azure-functions/1.25.0b3/) package.
297+
>
298+
> If the app is using Python 3.9 - 3.12, add the following app setting to `local.settings.json` if running locally or as an environment variable if running in production: `PYTHON_ISOLATE_WORKER_DEPENDENCIES: 1`.
299+
>
300+
> Using this feature requires the preview extension bundle version `[4.32.0, 5.0.0)`. Check host.json to make sure the correct bundle version is specified:
292301
>
293302
> ```json
294303
> "extensionBundle": {
295-
> "id": "Microsoft.Azure.Functions.ExtensionBundle.Preview",
304+
> "id": "Microsoft.Azure.Functions.ExtensionBundle.Preview"
296305
> "version": "[4.32.0, 5.0.0)"
297306
> }
298307
> ```
299308
300309
::: zone-end
301310
302311
[!INCLUDE [functions-mcp-extension-powershell-note](../../includes/functions-mcp-extension-powershell-note.md)]
312+
303313
::: zone pivot="programming-language-csharp"
304314
305315
## Attributes

articles/azure-functions/scenario-mcp-apps.md

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,34 @@
11
---
22
title: Build an MCP Apps server using Azure Functions
3-
description: "Learn how to create and deploy an MCP Apps server that returns interactive UI using Azure Functions. This quickstart uses the Azure Developer CLI to deploy an MCP Apps project that enables AI clients to access tools with rich interactive interfaces hosted on Azure's Flex Consumption plan."
3+
description: "Learn how to create and deploy an MCP App that returns interactive UI using Azure Functions. This quickstart uses the Azure Developer CLI to deploy an MCP App project that enables AI clients to access tools with rich interactive interfaces hosted on Azure's Flex Consumption plan."
44
ms.date: 02/20/2026
55
ms.update-cycle: 180-days
66
ms.topic: quickstart
77
ai-usage: ai-assisted
88
ms.collection:
99
- ce-skilling-ai-copilot
1010
zone_pivot_groups: programming-languages-set-functions
11-
#Customer intent: As a developer, I want to create an MCP Apps server that returns interactive UI from my MCP tools, so AI clients can render rich visual experiences using Azure Functions.
11+
#Customer intent: As a developer, I want to create an MCP Apps that returns interactive UI from my MCP tools, so AI clients can render rich visual experiences using Azure Functions.
1212
---
1313

14-
# Quickstart: Build an MCP Apps server using Azure Functions
14+
# Quickstart: Build an MCP Apps using Azure Functions
1515

16-
In this quickstart, you create an MCP Apps server from a template project by using the Azure Developer CLI (`azd`). [MCP Apps](https://blog.modelcontextprotocol.io/posts/2026-01-26-mcp-apps/) is an extension of the Model Context Protocol (MCP) specification that lets tools return interactive elements instead of plain text.
16+
In this quickstart, you create an [MCP App](https://blog.modelcontextprotocol.io/posts/2026-01-26-mcp-apps/) from a template project by using the Azure Developer CLI (`azd`). [MCP Apps](https://blog.modelcontextprotocol.io/posts/2026-01-26-mcp-apps/) is an extension of the Model Context Protocol (MCP) specification that lets tools return rich, interactive user interfaces (HTML/JavaScript in sandboxed iframes) instead of plain text.
1717

18-
The MCP server you create uses the Azure Functions MCP server extension to provide tools with rich UI for AI models, agents, and assistants. After running the project locally and verifying your code by using GitHub Copilot, you deploy it to a new serverless function app in Azure Functions that follows current best practices for secure and scalable deployments.
18+
This quickstart will use the Azure Functions MCP extension to build an MCP App using the MCP tool and resource trigger. After running the project locally and verifying your code by using GitHub Copilot, you deploy it to a new serverless function app in Azure Functions that follows current best practices for secure and scalable deployments.
1919

2020
>[!TIP]
21-
>If you want to create a custom MCP server that uses text-based tools instead of interactive UI, see [Quickstart: Build a custom remote MCP server using Azure Functions](scenario-custom-remote-mcp-server.md).
21+
>MCP tools built with the Azure Functions MCP extension don't have to return results in interactive UIs. If your server only needs text-based tools, see [Quickstart: Build a custom remote MCP server using Azure Functions](scenario-custom-remote-mcp-server.md).
2222
2323
Because the new app runs on the Flex Consumption plan, which follows a _pay-for-what-you-use_ billing model, completing this quickstart incurs a small cost of a few USD cents or less in your Azure account.
2424

25-
::: zone pivot="programming-language-javascript,programming-language-java,programming-language-powershell"
25+
::: zone pivot="programming-language-javascript,programming-language-java"
2626
> [!IMPORTANT]
27-
> While [creating custom MCP servers](./functions-bindings-mcp.md) is supported for all Functions languages, this MCP Apps quickstart currently only has examples for C#, Python, and TypeScript. To complete this quickstart, select one of these supported languages at the top of the article.
27+
> While [creating custom MCP servers](./functions-bindings-mcp.md) is supported for Java and JavaScript, this MCP Apps quickstart currently only has examples for C#, Python, and TypeScript. To complete this quickstart, select one of these supported languages at the top of the article.
2828
::: zone-end
29+
30+
[!INCLUDE [functions-mcp-extension-powershell-note](../../includes/functions-mcp-extension-powershell-note.md)]
31+
2932
::: zone pivot="programming-language-typescript"
3033
This article supports version 4 of the Node.js programming model for Azure Functions.
3134
::: zone-end
@@ -49,10 +52,9 @@ This article supports version 2 of the Python programming model for Azure Functi
4952
::: zone pivot="programming-language-csharp,programming-language-python,programming-language-typescript"
5053
+ [Node.js](https://nodejs.org/) (required to build the MCP Apps UI)
5154

52-
+ [Visual Studio Code](https://code.visualstudio.com/) with these extensions:
55+
+ [Visual Studio Code Insiders](https://code.visualstudio.com/insiders) with these extensions:
5356

5457
+ [Azure Functions extension](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurefunctions). This extension requires [Azure Functions Core Tools](functions-run-local.md) and attempts to install it when not available.
55-
5658
+ [Azure Developer CLI extension](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.azure-dev).
5759

5860
+ [Azurite storage emulator](../storage/common/storage-install-azurite.md#install-azurite)
@@ -61,6 +63,9 @@ This article supports version 2 of the Python programming model for Azure Functi
6163

6264
+ An Azure account with an active subscription. [Create an account for free](https://azure.microsoft.com/pricing/purchase-options/azure-account?cid=msft_learn).
6365

66+
> [!IMPORTANT]
67+
> MCP Apps require [Visual Studio Code Insiders](https://code.visualstudio.com/insiders). The stable release of VS Code doesn't yet support rendering MCP App UI resources.
68+
6469
## Initialize the project
6570

6671
Use the Azure Developer CLI to create an Azure Functions code project from a template.
@@ -110,7 +115,7 @@ The MCP Apps weather tool includes a frontend application that you must build be
110115
cd src/McpWeatherApp/app
111116
npm install
112117
npm run build
113-
cd ../../..
118+
cd ../
114119
```
115120

116121
::: zone-end
@@ -122,9 +127,18 @@ The MCP Apps weather tool includes a frontend application that you must build be
122127
cd src/app
123128
npm install
124129
npm run build
125-
cd ../..
130+
cd ../
131+
```
132+
133+
1. In the `/src` directory, install Python dependencies:
134+
135+
```console
136+
pip install -r requirements.txt
126137
```
127138

139+
> [!NOTE]
140+
> It is a best practice to create a virtual environment before doing the pip install to avoid dependency issues or collisions, or if you are running in CodeSpaces. See [Python Environments in VS Code](https://code.visualstudio.com/docs/python/environments) for more information.
141+
128142
::: zone-end
129143
::: zone pivot="programming-language-typescript"
130144

@@ -177,9 +191,9 @@ You can review the code that defines the MCP Apps tools. An MCP Apps tool requir
177191
::: zone pivot="programming-language-csharp"
178192
The function code for the MCP Apps weather tool is defined in the `src/McpWeatherApp` folder. The `[McpMetadata]` attribute adds UI metadata to the tool, and the `[McpResourceTrigger]` attribute serves the HTML widget:
179193

180-
:::code language="csharp" source="~/functions-scenarios-custom-mcp-dotnet/src/McpWeatherApp/WeatherFunction.cs" range="12-46" :::
194+
:::code language="csharp" source="~/functions-scenarios-custom-mcp-dotnet/src/McpWeatherApp/WeatherFunction.cs" range="48-76" :::
181195

182-
:::code language="csharp" source="~/functions-scenarios-custom-mcp-dotnet/src/McpWeatherApp/WeatherFunction.cs" range="48-55" :::
196+
:::code language="csharp" source="~/functions-scenarios-custom-mcp-dotnet/src/McpWeatherApp/WeatherFunction.cs" range="34-46" :::
183197

184198
The `ToolMetadata` constant declares a `ui.resourceUri` that tells the MCP host to fetch the interactive UI from `ui://weather/index.html` after the tool runs. The `GetWeatherWidget` function serves the bundled HTML file at that URI using `[McpResourceTrigger]`.
185199

@@ -188,11 +202,9 @@ You can view the complete project template in the [Azure Functions .NET MCP Serv
188202
::: zone pivot="programming-language-python"
189203
The function code for the MCP Apps weather tool is defined in the `src/function_app.py` file. The `metadata` parameter on `@app.mcp_tool()` adds UI metadata to the tool, and `@app.mcp_resource_trigger()` serves the HTML widget:
190204

191-
:::code language="python" source="~/functions-scenarios-custom-mcp-python/src/function_app.py" range="14-24" :::
192-
193-
:::code language="python" source="~/functions-scenarios-custom-mcp-python/src/function_app.py" range="85-95" :::
205+
:::code language="python" source="~/functions-scenarios-custom-mcp-python/src/function_app.py" range="109-130" :::
194206

195-
:::code language="python" source="~/functions-scenarios-custom-mcp-python/src/function_app.py" range="118-122" :::
207+
:::code language="python" source="~/functions-scenarios-custom-mcp-python/src/function_app.py" range="64-105" :::
196208

197209
The `TOOL_METADATA` constant declares a `ui.resourceUri` that tells the MCP host to fetch the interactive UI from `ui://weather/index.html` after the tool runs. The `get_weather_widget` function serves the bundled HTML file at that URI using `@app.mcp_resource_trigger()`.
198210

@@ -201,9 +213,15 @@ You can view the complete project template in the [Azure Functions Python MCP Se
201213
::: zone pivot="programming-language-typescript"
202214
The function code for the MCP Apps weather tool is defined in the `src/functions/weatherMcpApp.ts` file. The `metadata` property on `app.mcpTool()` adds UI metadata to the tool, and `app.mcpResource()` serves the HTML widget:
203215

204-
:::code language="typescript" source="~/functions-scenarios-custom-mcp-typescript/src/functions/weatherMcpApp.ts" range="6-25" :::
216+
:::code language="typescript" source="~/functions-scenarios-custom-mcp-typescript/src/functions/weatherMcpApp.ts" range="13-17" :::
217+
218+
:::code language="typescript" source="~/functions-scenarios-custom-mcp-typescript/src/functions/weatherMcpApp.ts" range="54-87" :::
219+
220+
:::code language="typescript" source="~/functions-scenarios-custom-mcp-typescript/src/functions/weatherMcpApp.ts" range="102-110" :::
221+
222+
:::code language="typescript" source="~/functions-scenarios-custom-mcp-typescript/src/functions/weatherMcpApp.ts" range="29-52" :::
205223

206-
:::code language="typescript" source="~/functions-scenarios-custom-mcp-typescript/src/functions/weatherMcpApp.ts" range="87-106" :::
224+
:::code language="typescript" source="~/functions-scenarios-custom-mcp-typescript/src/functions/weatherMcpApp.ts" range="89-97" :::
207225

208226
The `TOOL_METADATA` constant declares a `ui.resourceUri` that tells the MCP host to fetch the interactive UI from `ui://weather/index.html` after the tool runs. The `getWeatherWidget` handler serves the bundled HTML file at that URI when registered with `app.mcpResource()`.
209227

0 commit comments

Comments
 (0)