代码片段管理服务

基于Azure Functions的MCP服务器,用于管理和存储代码片段,支持本地开发和云端部署。

  • by mjeewani
  • Bicep
  • 本地部署
  • 更新于
在 GitHub 查看 mjeewani/mcp-functions

使用说明

代码片段 MCP 服务器 - Azure Functions!--


一个基于Azure Functions的简洁干净的MCP(模型上下文协议)服务器,用于管理代码片段。名称:带Azure Functions的远程MCP(.NET/C#)

描述:在Azure Functions上运行远程MCP服务器。

特征页面类型:示例

语言:

  • 列出代码片段获取带有元数据的所有可用代码片段 - C#

  • 获取代码片段通过名称检索特定代码片段 - bicep

  • 保存代码片段存储一个新的代码片段或更新现有的一个——azdeveloper

产品:

API 端点 - azure-functions

  • Azure(注:Azure是微软公司推出的一款云计算服务平台,直接音译为“阿兹尔”或保持原英文名“Azure”在中文语境中更为常见,根据具体使用场景可选择)

  • GET /api/snippets - 列出所有片段URL片段:remote-mcp-functions-dotnet

  • GET /api/snippets/{name} - 获取特定代码片段---

  • POST /api/snippets/{name} - 保存代码片段-->

存储# 使用Azure Functions (.NET/C#) 开始与远程MCP服务器交互

  • 本地开发使用蓝铜矿存储模拟器。这是一个快速入门模板,可轻松使用Azure函数在云上构建和部署自定义远程MCP服务器。您可以在本地机器上克隆/恢复/运行,并进行调试 azd up 几分钟内就能将其部署到云端。MCP服务器通过设计使用密钥和HTTPS进行保护,并且允许使用EasyAuth和/或API管理进行更多OAuth选项,以及使用VNET实现网络隔离。

  • Azure 环境使用带托管身份的Azure Blob存储

观看视频概览

快速入门

本地开发

  1. 安装Azurite:

    
    npm install -g azurite
    
    ```[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/Azure-Samples/remote-mcp-functions-dotnet)
    
    
    
    
  2. 启动蓝铜矿(或:启动天青石,注:Azurite通常指蓝铜矿,但有时也可能泛指具有蓝色调的宝石或矿物,具体翻译需根据上下文确定)## 前提条件

    
    azurite --silent --location c:\azurite --debug c:\azurite\debug.log+ [.NET 8 SDK](https://dotnet.microsoft.com/download/dotnet/8.0)
    
    ```+ [Azure Functions Core Tools](https://learn.microsoft.com/azure/azure-functions/functions-run-local?pivots=programming-language-csharp#install-the-azure-functions-core-tools) >= `4.0.7030`
    
    
  1. 构建并运行:+ 要使用 Visual Studio 在本地运行和调试:

    
    cd src  + Make sure to select the **Azure development** workload during installation.
    
    dotnet build+ To use Visual Studio Code to run and debug locally:
    
    func start  + [Visual Studio Code](https://code.visualstudio.com/)
    
    ```  + [Azure Functions extension](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurefunctions)
    
    
    
    
  2. 测试API以下是使用Azure Functions的远程MCP服务器的架构图:

    
    # List snippets![Architecture Diagram](architecture-diagram.png)
    
    curl http://localhost:7071/api/snippets
    
    ## Prepare your local environment
    
    # Save a snippet
    
    curl -X POST http://localhost:7071/api/snippets/test -d '{"title":"Test","content":"Hello World"}'An Azure Storage Emulator is needed for this particular sample because we will save and get snippets from blob storage. 
    
    
    
    # Get a snippet1. Start Azurite
    
    curl http://localhost:7071/api/snippets/test
    
    ```    ```shell
    
     docker run -p 10000:10000 -p 10001:10001 -p 10002:10002 \
    
    

Azure 部署 mcr.microsoft.com/azure-storage/azurite

```
  1. 使用 Azure 开发者 CLI 进行部署:

    ```powershell>注 如果你使用的是来自 VS Code 扩展的 Azurite,你需要运行 Azurite: Start 现在操作,否则您会看到错误。

    这个短语“azd up”在常规的英语表达中并不常见,可能是某种特定语境或俚语下的表达,直接翻译可能没有确切的对应意思。但如果我们尝试根据字母和常见表达模式来推测,可以将其大致理解为“快点”或“加油”的意思(尽管这不是标准的翻译)。在中文中,更常见的表达可能是“快点”或者根据具体语境用“加油”等词来传达相似的意思。不过,具体翻译还需结合上下文来确定

    
    
    
    
  2. 测试已部署的API1. 来自 src 文件夹,运行此命令以在本地启动 Functions 主机:

    
    curl https://your-function-app.azurewebsites.net/api/snippets    ```shell
    
    ```    cd src
    
     func start
    
    

配置

本地设置(local.settings.json)注:默认情况下,这将使用 webhook 路由: /runtime/webhooks/mcp稍后我们将在Azure中使用这个来设置客户端/主机调用的密钥: /runtime/webhooks/mcp?code=<system_key>


{## Connect to the *local* MCP server from within a client/host

  "IsEncrypted": false,

  "Values": {### VS Code - Copilot Edits

    "AzureWebJobsStorage": "UseDevelopmentStorage=true",

    "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated"1. **Add MCP Server** from command palette and add URL to your running Function app's MCP endpoint:

  }    ```shell

}    http://localhost:7071/runtime/webhooks/mcp

```    ```

1. **List MCP Servers** from command palette and start the server

### Azure Environment Variables1. In Copilot chat agent mode enter a prompt to trigger the tool, e.g., select some code and enter this prompt

- `AZURE_STORAGE_ACCOUNT_NAME`: Name of the Azure Storage Account

- Managed Identity permissions for Blob Storage access    ```plaintext

    Say Hello 

## Project Structure    ```



```    ```plaintext

src/    Save this snippet as snippet1 

├── Program.cs           # Application entry point    ```

├── SnippetsTool.cs      # Main snippets functionality

├── FunctionsMcpTool.csproj  # Project dependencies    ```plaintext

├── host.json            # Functions host configuration    Retrieve snippet1 and apply to NewFile.cs

└── local.settings.json  # Local development settings    ```

```1. When prompted to run the tool, consent by clicking **Continue**



## Dependencies1. When you're done, press Ctrl+C in the terminal window to stop the `func.exe` host process.



- Microsoft.Azure.Functions.Worker 2.0.0### MCP Inspector

- Azure.Storage.Blobs 12.22.1

- Azure.Identity 1.12.11. In a **new terminal window**, install and run MCP Inspector

- Application Insights for monitoring

    ```shell

## Notes    npx @modelcontextprotocol/inspector node build/index.js

    ```

- All endpoints use `AuthorizationLevel.Anonymous` for easy testing

- Snippets are stored in a `snippets` container in Blob Storage1. CTRL click to load the MCP Inspector web app from the URL displayed by the app (e.g. http://0.0.0.0:5173/#resources)

- Automatic container creation on first use1. Set the transport type to `Streamable HTTP` 

- JSON content type for all snippet data1. Set the URL to your running Function app's MCP endpoint and **Connect**:
    ```shell
    http://0.0.0.0:7071/runtime/webhooks/mcp
    ```
1. **List Tools**.  Click on a tool and **Run Tool**.  

## Verify local blob storage in Azurite

After testing the snippet save functionality locally, you can verify that blobs are being stored correctly in your local Azurite storage emulator.

### Using Azure Storage Explorer

1. Open Azure Storage Explorer
1. In the left panel, expand **Emulator & Attached** → **Storage Accounts** → **(Emulator - Default Ports) (Key)**
1. Navigate to **Blob Containers** → **snippets**
1. You should see any saved snippets as blob files in this container
1. Double-click on any blob to view its contents and verify the snippet data was saved correctly

### Using Azure CLI (Alternative)

If you prefer using the command line, you can also verify blobs using Azure CLI with the storage emulator:

```shell
# List blobs in the snippets container
az storage blob list --container-name snippets --connection-string "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;"
# Download a specific blob to view its contents
az storage blob download --container-name snippets --name <blob-name> --file <local-file-path> --connection-string "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;"

这个验证步骤确保您的MCP服务器能够正确地与本地存储模拟器进行交互,并且在部署到Azure之前,确认Blob存储功能按预期工作。

部署到Azure以支持远程MCP(多云平台/管理控制平台,具体含义根据上下文确定)

运行这个 azd 命令用于配置函数应用,包括任何所需的Azure资源,并部署您的代码:

azd up

您可以选择在示例中使用虚拟网络(VNet)。为此,请在开始之前执行以下操作: azd up

azd env set VNET_ENABLED true

此外, API 管理 可以用于增强您MCP服务器的安全性和策略管理,并且 App Service 内置认证 可以用来设置您喜欢的OAuth提供商,包括Entra。

从客户端连接到您的远程MCP服务器函数应用

您的客户将需要一个密钥来调用新的托管MCP端点,该端点的形式为 https://<funcappname>.azurewebsites.net/runtime/webhooks/mcp托管函数默认需要一个系统密钥,该密钥可以从(某处)获取 门户网站 或者CLI(命令行界面)az functionapp keys list --resource-group <resource_group> --name <function_app_name>)。 获取名为(此处应接具体名称,但原文未给出)的系统密钥 mcp_extension。

在MCP Inspector中连接到远程MCP服务器

对于MCP Inspector,您可以在URL中包含该密钥:

https://<funcappname>.azurewebsites.net/runtime/webhooks/mcp?code=<your-mcp-extension-system-key>

在 VS Code 中连接到远程 MCP 服务器 - GitHub Copilot

对于VS Code中的GitHub Copilot,您应该将密钥设置为 x-functions-key 标题(或头部)进入 mcp.json,然后你只需使用 https://<funcappname>.azurewebsites.net/runtime/webhooks/mcp 对于URL。以下示例使用了一个输入,并且在您从VS Code启动服务器时会提示您提供密钥。注意: mcp.json(注:这是一个文件名,直接翻译为中文即“mcp.json”,在中文语境中,文件名通常保持原样,不进行翻译,因为它们是特定于计算机系统和应用程序的标识符。) 已经包含在这个仓库中,并且将被VS Code自动识别。点击服务器上的“开始”按钮,将会提示输入包括……的值 functionapp-name (在你的 /.azure/*/.env 文件中)并且 functions-mcp-extension-system-key 可以从上面的CLI命令或门户中的Function App API密钥中获取。

{
    "inputs": [
        {
            "type": "promptString",
            "id": "functions-mcp-extension-system-key",
            "description": "Azure Functions MCP Extension System Key",
            "password": true
        },
        {
            "type": "promptString",
            "id": "functionapp-name",
            "description": "Azure Functions App Name"
        }
    ],
    "servers": {
        "remote-mcp-function": {
            "type": "http",
            "url": "https://${input:functionapp-name}.azurewebsites.net/runtime/webhooks/mcp",
            "headers": {
                "x-functions-key": "${input:functions-mcp-extension-system-key}"
            }
        },
        "local-mcp-function": {
            "type": "http",
            "url": "http://0.0.0.0:7071/runtime/webhooks/mcp"
        }
    }
}

在服务器上点击“开始”,系统将提示输入包括以下值: functionapp-name (在你的 /.azure/*/.env 文件中)并且 functions-mcp-extension-system-key 这可以从上面的CLI命令或门户中的Function App API密钥中获取。

重新部署你的代码

你可以运行 azd up 根据需要多次运行该命令,以同时配置您的 Azure 资源并部署代码更新到您的函数应用。

[!NOTE] (注:此为标记,意为“注意”) 已部署的代码文件总是会被最新的部署包覆盖。

清理资源

当您完成对函数应用及相关资源的操作后,可以使用此命令从Azure中删除函数应用及其相关资源,以避免产生任何进一步的费用:

azd down

源代码

该功能的代码为 GetSnippet 并且 SaveSnippet 在……中定义了端点 SnippetsTool.cs. 那个 McpToolsTrigger 应用于异步(操作)的属性 Run 该方法将代码函数作为MCP服务器暴露出来。

以下是几个MCP服务器示例的代码(获取字符串、获取对象、保存对象):

[Function(nameof(SayHello))]
public string SayHello(
    [McpToolTrigger(HelloToolName, HelloToolDescription)] ToolInvocationContext context
)
{
    logger.LogInformation("Saying hello");
    return "Hello I am MCP Tool!";
}

[Function(nameof(GetSnippet))]
public object GetSnippet(
    [McpToolTrigger(GetSnippetToolName, GetSnippetToolDescription)] ToolInvocationContext context,
    [BlobInput(BlobPath)] string snippetContent)
{
    return snippetContent;
}

[Function(nameof(SaveSnippet))]
[BlobOutput(BlobPath)]
public string SaveSnippet(
    [McpToolTrigger(SaveSnippetToolName, SaveSnippetToolDescription)] ToolInvocationContext context,
    [McpToolProperty(SnippetNamePropertyName, PropertyType, SnippetNamePropertyDescription)] string name,
    [McpToolProperty(SnippetPropertyName, PropertyType, SnippetPropertyDescription)] string snippet)
{
    return snippet;
}

下一步行动