将 MCP 服务器添加到扩展

Azure开发人员 CLI (azd) 扩展可以通过模型上下文协议 (MCP) 服务器向 AI 代理公开工具。 添加mcp-server功能时,GitHub Copilot等代理可以发现和调用扩展的工具。 本文介绍如何为创建示例扩展快速入门中的 Contoso 资源标记器示例扩展添加 MCP 服务器。 可以将相同的模式应用于任何扩展。

Note

azd 扩展目前以 beta 版提供。

MCP 服务器的工作原理

模型上下文协议是一种开放标准,允许 AI 代理发现和调用外部服务器提供的工具。 当扩展声明 mcp-server 该功能时, azd 可以将扩展作为 MCP 服务器启动,并将工具请求从代理路由到扩展。 扩展实现代理调用执行任务的工具,例如为项目建议标准化标记。

声明能力

mcp-server 功能添加到 extension.yaml 清单:

capabilities:
  - custom-commands
  - mcp-server

还可以在清单中添加 mcp 部分,以配置 azd 如何启动 MCP 服务器。 该 serve 属性支持 argsenvazd 已经知道该扩展的可执行文件,因此无需指定命令:

mcp:
  serve:
    args:
      - mcp
      - start

添加 MCP 命令

添加启动 MCP 服务器的命令。 azd 调用此命令以将扩展作为 MCP 服务器运行。 使用适用于 Go 的 MCP 服务器库(如 mcp-go)来处理协议。

  1. 在你的 internal/cmd 目录中创建一个名为 mcp.go 的文件:

    package cmd
    
    import (
        "context"
        "fmt"
    
        "github.com/mark3labs/mcp-go/mcp"
        "github.com/mark3labs/mcp-go/server"
        "github.com/spf13/cobra"
    )
    
    func newMcpCommand() *cobra.Command {
        mcpCmd := &cobra.Command{
            Use:    "mcp",
            Short:  "Model Context Protocol server commands.",
            Hidden: true,
        }
    
        mcpCmd.AddCommand(newMcpStartCommand())
        return mcpCmd
    }
    
    func newMcpStartCommand() *cobra.Command {
        return &cobra.Command{
            Use:   "start",
            Short: "Starts the MCP server.",
            RunE: func(cmd *cobra.Command, args []string) error {
                s := server.NewMCPServer(
                    "Contoso Resource Tagger",
                    "0.1.0",
                )
    
                // Register the suggest_tags tool.
                s.AddTool(newSuggestTagsTool())
    
                // Serve over stdio so azd and agents can connect.
                return server.ServeStdio(s)
            },
        }
    }
    
  2. mcp 命令注册到根命令中:

    rootCmd.AddCommand(newMcpCommand())
    

开发一个工具

定义 AI 代理调用的工具。 将以下 suggest_tags 工具添加到之前创建的同一 internal/cmd/mcp.go 文件。 mcpserver标识符来自该文件中已导入的包(github.com/mark3labs/mcp-go/mcpgithub.com/mark3labs/mcp-go/server),处理程序还使用了contextfmt导入的内容。 将该函数添加到 mcp.go 会复用这些导入,从而使代码能够编译:

func newSuggestTagsTool() (mcp.Tool, server.ToolHandlerFunc) {
    tool := mcp.NewTool(
        "suggest_tags",
        mcp.WithDescription("Suggests standardized Azure resource tags for a project."),
        mcp.WithString("environment",
            mcp.Description("The target environment, such as dev or prod."),
            mcp.Required(),
        ),
    )

    handler := func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
        environment, err := request.RequireString("environment")
        if err != nil {
            return mcp.NewToolResultError(err.Error()), nil
        }

        suggestion := fmt.Sprintf(
            "Suggested tags: environment=%s, managed-by=azd, cost-center=<required>",
            environment,
        )

        return mcp.NewToolResultText(suggestion), nil
    }

    return tool, handler
}

测试 MCP 服务器

添加 MCP 服务器后,重新生成扩展并验证服务器是否启动:

  1. 重新生成扩展:

    azd x build
    
  2. 直接启动 MCP 服务器以验证它是否运行而不出错:

    azd tagger mcp start
    

    服务器启动并监听标准输入和标准输出。 MCP 客户端(例如配置为使用扩展的 AI 代理)连接到此服务器以调用工具。