MCP Forge
Build a Model Context Protocol (MCP) server that any AI client — VS Code Copilot, a Microsoft Foundry agent, Claude, or ChatGPT — can discover and call. This page explains the what, the why, and the how, then hands you the real Azure Functions code.
🔌 What is the Model Context Protocol?
MCP is an open standard — "a USB-C port for AI applications." Instead of writing a custom integration for every AI app, you expose your tools and data once over MCP, and every MCP-compatible client can use them. It's supported across VS Code, GitHub Copilot, Claude, ChatGPT, Cursor, and Microsoft Foundry Agent Service.
A tool is just a function with a name, a description, and typed parameters. When you host those functions on an MCP server, an AI agent can discover what tools exist, decide which one a user's request needs, call it with the right arguments, and ground its answer in the real result. That's the leap from a chatbot that only talks to an agent that can act on your systems.
The discover → call → return loop
tool(args) over MCP.The live demo animates this exact loop so you can see it before you build it.
🎯 Use cases
⚖️ Pros, cons & limitations
✓ Pros
- Write a tool once — every MCP client can use it.
- Serverless: no servers to manage, scales to zero.
- Entra identity, OBO, and RBAC for enterprise security.
- Works directly inside Foundry agents and VS Code Copilot.
- Open standard — no vendor lock-in for the protocol.
✕ Cons / trade-offs
- Another service to deploy, secure, and monitor.
- Tool quality depends on clear descriptions & schemas.
- Agents can call tools wrong if params are ambiguous.
- Cold starts on Consumption plans add first-call latency.
△ Limitations
- The Azure Functions MCP extension is in preview — APIs and endpoints may change.
- Auth/endpoint details differ between local and deployed.
- MCP is for tools/data, not a full agent runtime by itself.
- Verify the latest docs before production use.
📦 Get the code
Three ways to go from this page to a working MCP server. Start with the prompt for speed, or follow the inline build to understand every piece.
Paste this into GitHub Copilot Chat (agent mode) in VS Code, or any capable coding model. It's a complete, professional spec that scaffolds the whole project.
You are a senior Azure platform engineer and an expert on the Model Context Protocol (MCP).
Build me a production-ready MCP server on Azure Functions (Python) that exposes custom
tools any MCP client can call — VS Code Copilot, a Microsoft Foundry agent, Claude, or ChatGPT.
REQUIREMENTS
1. Stack
- Python Azure Functions (v4, Linux) with the MCP extension.
- Use the MCP Tool Trigger (generic_trigger with type="mcpToolTrigger") so each tool
is exposed at the built-in /runtime/webhooks/mcp endpoint. No extra web framework.
2. Tools (each its own MCP tool, with clear descriptions + typed toolProperties)
- get_weather(city: string) -> current conditions
- search_orders(customer, limit: int) -> recent orders
- query_inventory(sku: string) -> stock levels across warehouses
- create_ticket(title, severity: int) -> opens a support ticket
Return JSON strings; validate inputs; log structured diagnostics.
3. Local dev
- func init / func new commands and a func start workflow.
- A .vscode/mcp.json that registers the server so VS Code Copilot can call it.
4. Security & deploy
- Secure the endpoint; then show how to switch to Microsoft Entra auth using the
Function App managed identity, plus OAuth On-Behalf-Of (OBO) for the signed-in user.
- az CLI to create the Function App and `func azure functionapp publish`.
- How to add this server to a Microsoft Foundry agent (Add Tools -> MCP server) and to
Claude/ChatGPT as a remote MCP connector.
5. Quality
- Input validation, structured logging, clear error returns.
- A README explaining the discover -> reason -> call -> execute -> return flow.
- One end-to-end example: "what's the weather in Seattle?" -> get_weather -> grounded answer.
Generate the full project: function_app.py, host.json, requirements.txt, .vscode/mcp.json,
local.settings.json template, README.md, and the exact CLI commands. Then tell me how to
verify it live from VS Code Copilot. Ask me anything you need; otherwise build it.
func start and ask Copilot a question that triggers a tool.Prefer to understand every file? Build it by hand in ~10 minutes.
1. The MCP server — function_app.py
Each @app.generic_trigger with type="mcpToolTrigger" exposes one MCP tool at /runtime/webhooks/mcp.
import json
import azure.functions as func
app = func.FunctionApp()
def _tool(context):
"""Helper: parse the MCP tool-call context into an args dict."""
return json.loads(context).get("arguments", {})
@app.generic_trigger(
arg_name="context", type="mcpToolTrigger",
toolName="get_weather",
description="Returns current conditions for a city.",
toolProperties=json.dumps([
{"propertyName": "city", "propertyType": "string",
"description": "City name, e.g. Seattle"},
]),
)
def get_weather(context) -> str:
city = _tool(context).get("city", "Seattle")
# TODO: replace with a real weather API call
return json.dumps({"city": city, "tempF": 61, "sky": "clear"})
@app.generic_trigger(
arg_name="context", type="mcpToolTrigger",
toolName="query_inventory",
description="Checks stock levels across warehouses for a SKU.",
toolProperties=json.dumps([
{"propertyName": "sku", "propertyType": "string",
"description": "Product SKU, e.g. AX-200"},
]),
)
def query_inventory(context) -> str:
sku = _tool(context).get("sku", "AX-200")
# TODO: query your real inventory system
return json.dumps({"sku": sku, "onHand": 142, "sites": 4})
2. Host & dependencies
{
"version": "2.0",
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle.Preview",
"version": "[4.*, 5.0.0)"
}
}
azure-functions
3. Register the server with a client — .vscode/mcp.json
{
"servers": {
"my-azure-tools": {
"type": "sse",
"url": "http://localhost:7071/runtime/webhooks/mcp/sse"
}
}
}
// Deployed: use https://<app>.azurewebsites.net/runtime/webhooks/mcp/sse
// with the function's system key. In Foundry: Add Tools -> MCP server -> paste the URL.
4. Build, run & ship
- Install the tools:
Azure Functions Core Tools v4and theAzure FunctionsVS Code extension. - Scaffold:
func init my-mcp --pythonthenfunc new --template "MCP Tool Trigger" --name get_weather. - Drop in the
function_app.py,host.json, andrequirements.txtabove. - Run locally:
func start. VS Code Copilot can now discover and call your tools. - Ask Copilot: "What's the weather in Seattle?" — watch it call
get_weatherand ground the answer. - Deploy:
func azure functionapp publish my-mcp, then add the deployed/runtime/webhooks/mcp/sseURL to a Foundry agent or Claude.
/sse) and auth (system key vs. Entra) evolve — confirm against the current Azure Functions MCP docs.A ready-to-clone GitHub repository for MCP Forge is on the way.
🎮 See it before you build it
The interactive holographic demo animates the full MCP discover → call → return loop. Register tools, ask an agent, and watch the call flow light up.
Launch the live demo