Skip to content

Emit MCP-related information when deploying code to a MCP function app #6043

@im-samz

Description

@im-samz

1. Background

Goal: minimize the friction to add a custom MCP tool hosted on Functions to your agent.

Problem: developers must know to construct the remote MCP endpoint themselves, get the authentication information, and know where to go to supply this information to their agent.

Note

This is a point-in-time optimization until we can declaratively add MCP tools hosted on Functions to agents.

2. Ideal user journey

  1. Developer initializes MCP function app project: e.g., azd init --template python-mcp-sdk-functions-azd
  2. Developer modifies sample code and tests locally
  3. Developer runs azd up to deploy MCP server to Azure
    a. Terminal returns information to help the next step.
  4. Developer manually adds the MCP tool to their Foundry agent, inputting information copied from terminal.
  5. [LATER] Developer modifies code and runs azd deploy
    a. Terminal returns same information to help with next steps.

Bold is the scope of this issue.

3. Information to emit

  • P0: Remote MCP server endpoint - https://{function_app_name}.azurewebsites.net/mcp
  • P0: How do I add my MCP function app as a tool to a Foundry agent? aka.ms/functions-mcp-next-steps
    • I'm open on the wording

Note

Long-term, we should still be emitting the remote mcp server endpoint. However, the recommended doc will no longer be necessary once we can automate adding tools to agent.s

4. Technical requirements

  1. P0: Identify that the function app is a MCP server
  2. P0: Construct the endpoint
  3. P1: Provide tailored auth recommendations

4.1 Identify that the function app is a MCP server

4.1.1. Approach 1 - Interrrogate the function app

Make two api calls since we support two ways of building MCP servers:

  • GET /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Web/sites/{app_name}/functions?api-version=2022-03-01
    • Parse entries for content.value for "properties.config.bindings.type": "mcpToolTrigger"
  • GET https://management.azure.com/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Web/sites/{app_name}/hostruntime/admin/vfs//host.json?relativePath=1&api-version=2022-03-01
    • Parse response for "configurationProfile": "mcp-custom-handler"

4.1.2 Approach 2 - Infer MCP app from azure.yaml

Potentially, we could standardize a way to define a MCP function app. Maybe something like:

name: python-mcp-sdk-functions-azd
metadata:
  template: [email protected]
services:
  mcp:
    project: .
    language: python
    host: function

So, MCP Function app == (services is mcp AND host is function)

4.1.3. Approach 3 - Rely on hardcoded outputs

In main.bicep we could ensure we output the right endpoint path since the author of the template would know what technology the MCP server is built with.

  • output SERVICE_MCP_ENDPOINT string = '${mcp.outputs.SERVICE_MCP_DEFAULT_HOSTNAME}/mcp' or
  • output SERVICE_MCP_ENDPOINT string = '${mcp.outputs.SERVICE_MCP_DEFAULT_HOSTNAME}/runtime/webhooks/mcp'

4.2. Construct the endpoint

There are two technologies to build MCP Function apps, each has its own endpoint path:

  • MCP Extension: {function_app_default_hostname}/runtime/webhooks/mcp
  • Self-hosted MCP: {function_app_default_hostname}/mcp

An example of the MCP Extension is https://my-mcp-app.azurewebsites.net/runtime/webhooks/mcp

4.3. Provide tailored auth recommendations

Out of scope for now, but including for creativity's sake

Theoretically, we could also define somewhere in /infra what auth type the function app is using. That way, azd can output what az cli command to run to fetch that information for the developer - or even ask permission to run it.

Not in scope because if we link to docs, the developer can figure it out themselves.

cc. @rajeshkamal5050

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions