MicrosoftMicrosoft Certified: Multi-Agent AI Solutions Expert2026-102.3 Build and integrate tool ecosystems
Publish function handlers as discoverable MCP tools
Completed by the knowledge check
Learning objective
Expose Azure Functions through MCP tool triggers.
Core idea
The Azure Functions MCP extension turns function handlers into tools exposed through a shared remote MCP endpoint. For an architect reusing serverless business operations, the key choice is to expose the intended tool contract through the extension rather than expecting an ordinary HTTP function to become discoverable automatically.
The trigger defines the advertised name, description, and arguments. The handler implements the operation. The extension supplies the MCP endpoint through which clients discover and call those tools. Your function still owns business validation and downstream permissions.
Microsoft also documents hosting servers built with official MCP SDKs on Functions as a preview path. That is a separate hosting option, not the tool-trigger mechanism taught here. Built-in MCP server authentication is also documented as preview. Keep those status claims attached to their respective features.
How it works
Select the extension and programming model
For C#, use Microsoft.Azure.Functions.Worker.Extensions.Mcp and the isolated worker model; the trigger documentation says the extension supports only that model for C#. The overview requires Microsoft.Azure.Functions.Worker version 2.1.0 or later and Azure.Functions.Sdk project SDK version 1.0.0 or later.
For JavaScript and TypeScript, the overview requires @azure/functions version 4.9.0 or later. Python requires azure-functions version 1.24.0 or later. The extension overview documents the Microsoft.Azure.Functions.ExtensionBundle configuration with the version range [4.0.0, 5.0.0) for bundle-based projects. Check the setup instructions for the chosen language instead of copying C# package installation into a Python deployment.
Local execution requires Azure Functions Core Tools version 4.0.7030 or later. These minimums matter when a handler compiles but the host doesn’t recognize its binding. A valid function body can’t compensate for an unsupported worker library or an extension missing from the runtime.
The overview excludes PowerShell apps, and the tool-trigger page says Go support isn’t available for this binding. Don’t infer trigger support from Azure Functions supporting a language in some other execution model.
Describe the function as a tool
C# uses McpToolTriggerAttribute, with a required ToolName and optional Description. It can bind a call to ToolInvocationContext, which contains the tool name and arguments, or to a JSON-serializable plain-old CLR object whose properties define tool arguments.
For a typed object, the property type determines the MCP type. Use Description attributes to explain properties and the C# required keyword for properties the operation can’t omit. Alternatively, the documented builder API configures a tool with ConfigureMcpTool() and adds properties with WithProperty(). The latter takes protocol type names such as "boolean", not the CLR spelling bool.
For JavaScript and TypeScript, app.mcpTool() registers the handler with toolName, description, toolProperties, and handler. The arg helpers from @azure/functions provide a typed way to describe properties. Python uses the mcp_tool_trigger decorator and defines the tool properties in its trigger configuration.
Across these models, explicitly mark essential properties as required. The trigger documentation says properties are optional by default and identifies a behavior change from extension preview version 1.0.0-preview.7. Don’t rely on examples that omit required markers while assuming clients must supply every property.
The typed declaration helps the client collect arguments. In the handler, still check identifier ownership, allowed values, and business state. A discoverable property named invoice_id doesn’t prove that the caller may read that invoice; see 2.3.1 for the difference between structural and business validation.
Connect to the extension endpoint
The extension exposes Streamable HTTP at /runtime/webhooks/mcp. It also documents the separate SSE endpoint /runtime/webhooks/mcp/sse, and recommends Streamable HTTP unless a client specifically requires the SSE transport.
Use the extension endpoint for MCP discovery and invocation. An ordinary HTTP trigger URL isn’t equivalent to that protocol endpoint. The official-SDK hosting path in Microsoft’s tutorial uses /mcp; copying that path into an extension-based client configuration selects the wrong route.
At local development time, the documented endpoint is http://localhost:7071/runtime/webhooks/mcp. In Azure, replace the host with the function app’s domain. A client then discovers the registered operations and their advertised properties through the MCP interface; see 2.3.3 for tools/list and tools/call.
Verify discovery and execution separately. The tool list should contain the intended name, description, and required arguments. A representative call should reach the intended handler and return the expected business result. Finding a name in the list proves registration, not successful access to a downstream service.
Configure access at the webhook
By default, a hosted extension endpoint requires the system key named mcp_extension. Supply it through the x-functions-key HTTP header or the code query parameter; Microsoft’s overview says a missing key produces HTTP 401. Prefer a client secret input or credential store over checking a key into the endpoint configuration.
The host setting extensions.mcp.system.webhookAuthorizationLevel defaults to "System" and accepts "System" or "Anonymous". Setting it to "Anonymous" removes the extension’s key requirement. That setting doesn’t by itself establish an identity-based replacement.
Microsoft’s tutorial documents built-in MCP server authentication as preview. Its portal action Turn on MCP authentication configures Microsoft Entra ID and automatically disables default key-based access. In the manual extension path, the documented application setting AzureFunctionsJobHost__extensions__mcp__system__webhookAuthorizationLevel=Anonymous removes the key gate; the identity layer must still require authentication.
Keep endpoint admission distinct from downstream authorization. Possession of a shared system key isn’t a per-customer invoice permission. Likewise, a client approval decision doesn’t grant the function’s identity permission to read storage. The handler must execute with suitable backend access and enforce the caller’s business scope. See 2.3.4 for approval and credential handling at the client.
Key distinctions and trade-offs
Tool trigger versus HTTP trigger: The MCP extension advertises a tool contract and dispatches MCP calls to a function. A generic HTTP route doesn’t supply MCP discovery merely because it accepts JSON.
Extension versus official-SDK hosting: The extension route is /runtime/webhooks/mcp. The separate official-SDK hosting tutorial uses /mcp and labels that hosting capability preview.
System key versus identity: mcp_extension is a shared admission secret. Preview built-in MCP authentication uses an identity provider. Neither replaces business authorization inside the tool operation.
A managed extension reduces protocol-hosting code and fits existing function handlers. It also constrains the programming models and versions you can use. Select the supported runtime first, then design the tool interface around a narrow business capability.
Architecture / decision scenario
A team exposes a serverless invoice-reading operation to several assistants. It chooses the C# isolated worker extension, installs the documented package, and binds the tool arguments to a typed object with a required invoice identifier. The handler validates caller access and reads the authorized invoice.
Clients connect to /runtime/webhooks/mcp, confirm the advertised tool schema, and test an actual lookup. The team starts with the mcp_extension system key supplied from its client credential configuration. A missing key fails at endpoint admission; an unauthorized invoice fails at the business operation. These failures require different fixes.
If the team adopts preview built-in MCP authentication, it verifies the identity layer before removing key enforcement. It doesn’t change the client URL to /mcp, because it still uses the extension rather than an official-SDK server. For consumption through Foundry Agent Service, its hosting comparison documents Functions access as key-based and directs OAuth through API Management. Check that integration constraint separately from the Functions built-in authentication feature. Clients retain their tool allowlists and approval policy independently of the server’s authentication choice.
Common exam traps
- Assuming any HTTP-triggered function is discoverable as an MCP tool.
- Using the C# in-process model for this extension.
- Assuming tool properties are required by default.
- Connecting an extension client to the official-SDK hosting route.
- Using a generic function key instead of the documented
mcp_extensionsystem key. - Setting
Anonymousand assuming that alone enables Microsoft Entra authentication.
What to remember
Define a supported MCP tool trigger, advertise explicit typed properties, and use the extension’s protocol endpoint. Configure key or identity-based admission deliberately, while preserving handler authorization. Keep preview SDK hosting and preview built-in authentication separate from the trigger mechanism.
Knowledge check
A team exposes a C# invoice handler through the Azure Functions MCP extension. Every call must carry an invoice identifier. Which implementation supplies that interface?
A deployed Functions app uses the MCP extension with default key enforcement. Which client configuration reaches the protocol endpoint with the documented credential?
/mcp with an ordinary function keymcp_extension key/runtime/webhooks/mcp with the mcp_extension system key/runtime/webhooks/mcp with an ordinary function key/runtime/webhooks/mcp and requires the mcp_extension system key by default. The /mcp route belongs to the separate official-SDK hosting path; an ordinary handler route or generic function key is not the documented extension configuration.The team sets webhookAuthorizationLevel to Anonymous while preparing identity-based access. What does this change establish on its own?
Anonymous removes the extension’s key gate. Identity-based admission still needs its own configured layer, and neither endpoint setting implements business authorization or client-side approval.References
- Microsoft, Connect agents to MCP server endpoints
- Microsoft, MCP bindings for Azure Functions
- Microsoft, MCP tool trigger for Azure Functions
- Microsoft, Tutorial: Host a remote MCP server on Azure Functions