Skip to content

Commit 65e54a2

Browse files
gary-x-liGary Li
andauthored
Add http transport support for Bicep mcp server (#19389)
## Description This PR adds support for running the Bicep MCP server over HTTP, in addition to the existing stdio transport. This enables remote hosting scenarios where users can run the MCP server as a container or standalone HTTP service. ### What's changed **HTTP transport support** — Users can now run the MCP server with HTTP transport locally: ``` dnx Azure.Bicep.McpServer --transport http ``` This starts a Streamable HTTP MCP endpoint on port 8080. The default transport remains stdio, so existing users are unaffected. **Updated documentation** — Moved `mcp-tools.md` out of the `experimental` directory. Added description for missing mcp tools, as well as instructions on self-hosting as a remote MCP server. ## Checklist - [x] I have read and adhere to the [contribution guide](https://github.com/Azure/bicep/blob/main/CONTRIBUTING.md). ###### Microsoft Reviewers: [Open in CodeFlow](https://microsoft.github.io/open-pr/?codeflow=https://github.com/Azure/bicep/pull/19389) --------- Co-authored-by: Gary Li <ligar@microsoft.com>
1 parent 36e85fb commit 65e54a2

File tree

7 files changed

+218
-113
lines changed

7 files changed

+218
-113
lines changed

docs/experimental/mcp-tools.md

Lines changed: 0 additions & 89 deletions
This file was deleted.

docs/mcp-tools.md

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# Using the Bicep MCP Server
2+
3+
## What is it
4+
5+
We have built a Bicep MCP server with agentic tools to support Bicep code generation for AI agents in VS Code. To find out more about MCP, see [Use MCP servers in VS Code][00].
6+
7+
### Available Bicep MCP tools
8+
9+
- `get_bicep_best_practices`: Lists up-to-date recommended Bicep best-practices for authoring templates. These practices help improve maintainability, security, and reliability of your Bicep files. This is helpful additional context if you've been asked to generate Bicep code.
10+
- `list_az_resource_types_for_provider`: Lists all available Azure resource types for a specific provider. The return value is a newline-separated list of resource types including their API version, e.g. `Microsoft.KeyVault/vaults@2024-11-01`. Such information is the most accurate and up-to-date as it is sourced from the Azure Resource Provider APIs.
11+
- `get_az_resource_type_schema`: Gets the schema for a specific Azure resource type and API version. Such information is the most accurate and up-to-date as it is sourced from the Azure Resource Provider APIs.
12+
- `list_avm_metadata`: Lists up-to-date metadata for all Azure Verified Modules (AVM). The return value is a newline-separated list of AVM metadata. Each line includes the module name, description, versions, and documentation URI for a specific module.
13+
- `get_bicep_file_diagnostics`: Analyzes a Bicep file (`.bicep`) or Bicep parameters file (`.bicepparam`) and returns all compilation diagnostics including errors, warnings, and informational messages.
14+
- `format_bicep_file`: Formats a Bicep file (`.bicep`) or Bicep parameters file (`.bicepparam`) according to official Bicep formatting standards, respecting `bicepconfig.json` settings.
15+
- `get_file_references`: Analyzes a Bicep or Bicep parameters file and returns a list of all files it references, including modules, parameter files, and other dependencies.
16+
- `decompile_arm_template_file`: Converts an ARM template JSON file into Bicep syntax (`.bicep`). Accepts files with `.json`, `.jsonc`, or `.arm` extensions.
17+
- `decompile_arm_parameters_file`: Converts an ARM template parameters JSON file into Bicep parameters syntax (`.bicepparam`). Accepts files with `.json`, `.jsonc`, or `.arm` extensions.
18+
- `get_deployment_snapshot`: Creates a deployment snapshot from a Bicep parameters file (`.bicepparam`) by compiling and pre-expanding the ARM template, allowing you to preview predicted resources without running a deployment.
19+
20+
Please see below on how to contribute to the Bicep best practices tool.
21+
22+
## Transports
23+
24+
The Bicep MCP Server supports two transports:
25+
26+
- **stdio** (default): Used when the server is launched locally by a client process (e.g., VS Code, Claude Desktop). This is the default behavior.
27+
- **HTTP** (Streamable HTTP): Used for remote hosting scenarios. Start the server with the `--transport http` flag to enable HTTP transport on port 8080.
28+
29+
To run the server locally with HTTP transport:
30+
31+
```
32+
dnx Azure.Bicep.McpServer --transport http
33+
```
34+
35+
Then configure your MCP client to connect to `http://localhost:8080/`.
36+
37+
## Self-hosting with Docker
38+
39+
You can self-host the Bicep MCP Server as a container using the published NuGet tool package. Create a `Dockerfile` with the following contents:
40+
41+
```dockerfile
42+
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS install
43+
44+
RUN dotnet tool install --global Azure.Bicep.McpServer
45+
46+
FROM mcr.microsoft.com/dotnet/aspnet:10.0
47+
48+
COPY --from=install /root/.dotnet/tools /opt/tools
49+
50+
ENV PATH="$PATH:/opt/tools"
51+
52+
USER $APP_UID
53+
54+
EXPOSE 8080
55+
56+
ENTRYPOINT ["Azure.Bicep.McpServer", "--transport", "http"]
57+
```
58+
59+
Build and run the container:
60+
61+
```bash
62+
docker build -t bicep-mcp-server .
63+
docker run -p 8080:8080 bicep-mcp-server
64+
```
65+
66+
> [!NOTE]
67+
> No authentication is included. If hosting on a network or in the cloud, secure the endpoint using a reverse proxy, VNet integration, or other infrastructure-level controls.
68+
69+
## Where can I use it?
70+
71+
The Bicep MCP Server can be used directly in VS Code (preferred), but can also be run locally with other AI services such as Claude Desktop and Code, OpenAI Codex CLI, LMStudio, and other MCP-compatible services.
72+
73+
## How to use the Bicep MCP Server directly in VS Code
74+
75+
### Prerequisites
76+
77+
- Install the latest version of the [Bicep VS Code Extension][01]
78+
- Confirm access to [Copilot in VS Code][02]
79+
80+
### Installing
81+
82+
Ensure you have the latest version of the Bicep extension installed.
83+
84+
### Troubleshooting
85+
86+
The Bicep server may not appear in your list of MCP servers and tools in VS Code until it has been triggered. If you do not see the server, try opening and saving a `.bicep` file and then try providing a Bicep related-prompt in the Copilot chat window in "Agent" mode (as shown in Step #3 of the Viewing and Using Bicep Tools in the Bicep MCP Server section below). You may also need to press the "Refresh" button in the Copilot chat box.
87+
88+
![Refresh copilot tools][05]
89+
90+
If any of the tools are missing from the list of available tools, start/restart the MCP server in VS Code, by hitting `Ctrl + Shift + P`, selecting `MCP: List Servers`, then choosing the Bicep MCP Server and clicking on `Start Server` or `Restart Server`.
91+
92+
### Viewing and Using Bicep MCP Server Tools in VS Code
93+
94+
1. Open the GitHub Copilot extension window and select "Agent Mode".
95+
96+
![Agent Mode Selection][06]
97+
98+
1. Click on the tool icon in the GitHub Copilot chat window and search for "Bicep (PREVIEW)".
99+
100+
![Bicep MCP Tool Selection][07]
101+
102+
1. Start using Agent Mode to help with your Bicep tasks!
103+
104+
![Bicep MCP Usage Example][08]
105+
106+
## How to use the Bicep MCP Server locally with AI Agents
107+
Please refer to [this step by step tutorial](https://github.com/johnlokerse/azure-bicep-mcp-integration-setup) on how to integrate the Bicep MCP Server with Claude Code, Codex, LM Studio, and other AI tools.
108+
109+
This article has all the tools you need to run the Bicep MCP Server locally, with pre-written commands, helper scripts, and client setup guides.
110+
111+
Note: This is contributed by our community member [@johnlokerse](https://github.com/johnlokerse). Thanks John!
112+
113+
## Limitations
114+
115+
> [!NOTE]
116+
> It is your responsibility to review all code generated by an LLM and **deploy at your own risk**.
117+
118+
These tools provide additional context to help the chosen model generate semantically and syntactically correct Bicep code. These tools are not designed to deploy directly to Azure.
119+
120+
There is no way to definitively guarantee whether the agent orchestrator will use any particular Bicep tool. As a workaround, you can view the available Bicep tools and use specific prompting to guide the agent orchestrator to invoke a tool (e.g. "Create a Bicep file to do X using Bicep best practices")
121+
122+
## Contributing and providing feedback
123+
124+
These tools are early on and we value and welcome feedback to improve them. See [`CONTRIBUTING.md`][09] for guidelines.
125+
126+
In particular, we are looking to crowd source community wisdom on the `get_bicep_best_practices` tool. You can contribute to our forum on bicep best practices on [this Bicep Issue][03].
127+
128+
## Raising bugs or feature requests
129+
130+
Please raise bug reports or feature requests under [Bicep Issues][04] and tag with "story: bicep MCP".
131+
132+
<!-- Link reference definitions -->
133+
[00]: https://code.visualstudio.com/docs/copilot/chat/mcp-servers
134+
[01]: https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-bicep
135+
[02]: https://code.visualstudio.com/docs/copilot/overview
136+
[03]: https://github.com/Azure/bicep/issues/17660
137+
[04]: https://github.com/Azure/bicep/issues
138+
[05]: ../images/refresh-mcp-tools.png
139+
[06]: ../images/mcp-agent-mode.png
140+
[07]: ../images/mcp-tools-selection.png
141+
[08]: ../images/use-agent-mode-with-bicep.png
142+
[09]: ../../CONTRIBUTING.md

src/Bicep.McpServer.UnitTests/Files/ServerTests/tools.json

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -240,32 +240,50 @@
240240
},
241241
"tenantId": {
242242
"description": "Optional Azure tenant ID to use as deployment metadata",
243-
"type": "string",
243+
"type": [
244+
"string",
245+
"null"
246+
],
244247
"default": null
245248
},
246249
"managementGroupId": {
247250
"description": "Optional Azure management group ID to use as deployment metadata",
248-
"type": "string",
251+
"type": [
252+
"string",
253+
"null"
254+
],
249255
"default": null
250256
},
251257
"subscriptionId": {
252258
"description": "Optional Azure subscription ID to use as deployment metadata",
253-
"type": "string",
259+
"type": [
260+
"string",
261+
"null"
262+
],
254263
"default": null
255264
},
256265
"resourceGroup": {
257266
"description": "Optional Azure resource group name to use as deployment metadata",
258-
"type": "string",
267+
"type": [
268+
"string",
269+
"null"
270+
],
259271
"default": null
260272
},
261273
"location": {
262274
"description": "Optional Azure location to use as deployment metadata",
263-
"type": "string",
275+
"type": [
276+
"string",
277+
"null"
278+
],
264279
"default": null
265280
},
266281
"deploymentName": {
267282
"description": "Optional deployment name to use as deployment metadata",
268-
"type": "string",
283+
"type": [
284+
"string",
285+
"null"
286+
],
269287
"default": null
270288
}
271289
},

src/Bicep.McpServer/Bicep.McpServer.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@
2525
</ItemGroup>
2626

2727
<ItemGroup>
28-
<PackageReference Include="Microsoft.Extensions.Hosting" />
28+
<FrameworkReference Include="Microsoft.AspNetCore.App" />
2929
<PackageReference Include="ModelContextProtocol" />
30+
<PackageReference Include="ModelContextProtocol.AspNetCore" />
3031
</ItemGroup>
3132

3233
<ItemGroup>

src/Bicep.McpServer/IServiceCollectionExtensions.cs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,20 +39,23 @@ public static IMcpServerBuilder AddBicepMcpServer(this IServiceCollection servic
3939
.WithTools<BicepCompilerTools>()
4040
.WithTools<BicepDecompilerTools>()
4141
.WithTools<BicepDeploymentTools>()
42-
.AddCallToolFilter((next) => async (request, cancellationToken) =>
42+
.WithRequestFilters(filters =>
4343
{
44-
try
44+
filters.AddCallToolFilter(next => async (context, cancellationToken) =>
4545
{
46-
return await next(request, cancellationToken);
47-
}
48-
catch (Exception ex)
49-
{
50-
return new CallToolResult
46+
try
47+
{
48+
return await next(context, cancellationToken);
49+
}
50+
catch (Exception ex)
5151
{
52-
Content = [new TextContentBlock { Text = $"Error: {ex.Message}" }],
53-
IsError = true
54-
};
55-
}
52+
return new CallToolResult
53+
{
54+
Content = [new TextContentBlock { Text = $"Error: {ex.Message}" }],
55+
IsError = true
56+
};
57+
}
58+
});
5659
});
5760
}
5861
}

src/Bicep.McpServer/Program.cs

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,42 @@
22
// Licensed under the MIT License.
33

44
using Bicep.McpServer;
5+
using Microsoft.AspNetCore.Builder;
6+
using Microsoft.AspNetCore.Hosting;
57
using Microsoft.Extensions.DependencyInjection;
68
using Microsoft.Extensions.Hosting;
79

8-
var builder = Host.CreateEmptyApplicationBuilder(settings: null);
10+
var transportArg = args
11+
.SkipWhile(a => !a.Equals("--transport", StringComparison.OrdinalIgnoreCase))
12+
.Skip(1)
13+
.FirstOrDefault() ?? "stdio";
914

10-
builder.Services
11-
.AddBicepMcpServer()
12-
.WithStdioServerTransport();
15+
if (transportArg.Equals("http", StringComparison.OrdinalIgnoreCase))
16+
{
17+
var builder = WebApplication.CreateBuilder(args);
1318

14-
await builder.Build().RunAsync();
19+
builder.WebHost.UseUrls("http://*:8080");
20+
21+
builder.Services
22+
.AddBicepMcpServer()
23+
.WithHttpTransport(options =>
24+
{
25+
options.Stateless = true;
26+
});
27+
28+
var app = builder.Build();
29+
30+
app.MapMcp();
31+
32+
await app.RunAsync();
33+
}
34+
else
35+
{
36+
var builder = Host.CreateEmptyApplicationBuilder(settings: null);
37+
38+
builder.Services
39+
.AddBicepMcpServer()
40+
.WithStdioServerTransport();
41+
42+
await builder.Build().RunAsync();
43+
}

src/Directory.Packages.props

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@
7676
<PackageVersion Include="Microsoft.VisualStudio.Workspace" Version="17.1.11-preview-0002" />
7777
<PackageVersion Include="Microsoft.VisualStudio.Workspace.VSIntegration" Version="17.1.11-preview-0002" />
7878
<PackageVersion Include="Microsoft.Visualstudio.Telemetry" Version="17.12.48" />
79-
<PackageVersion Include="ModelContextProtocol" Version="0.5.0-preview.1" />
79+
<PackageVersion Include="ModelContextProtocol" Version="1.2.0" />
80+
<PackageVersion Include="ModelContextProtocol.AspNetCore" Version="1.2.0" />
8081
<PackageVersion Include="Moq" Version="4.20.72" />
8182
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
8283
<PackageVersion Include="Newtonsoft.Json.Schema" Version="4.0.1" />

0 commit comments

Comments
 (0)