今天我们将探讨如何使用Go创建一个MCP服务器,并通过Docker来提供服务。
前提条件:阅读过理解模型上下文协议(MCP)
要编写一个MCP服务器,有几个官方SDK可供选择:
近年来,我对Go产生了浓厚的兴趣,因此我查找了是否有Go的实现。在页面https://github.com/punkpeye/awesome-mcp-servers?tab=readme-ov-file#frameworks,我发现了一些,特别是https://github.com/mark3labs/mcp-go,这是mcphost的创建者(我在之前的博客文章中讨论并使用了它)。
mcp-go项目的优点是简单,并且还提供了开发MCP客户端的工具,这对未来的博客文章非常有用。
这里不会详细或实现MCP服务器的所有可能性。我只会实现基本内容:
当我使用LLM时,我希望能够做一件事:给它一个网站链接,让它在那里找到信息,为我生成摘要等。
所以我创建了一个MCP服务器,该服务器使用带有URL参数的curl实用程序,并返回其内容。但让我们看看源代码:
go.mod:
module mcp-curl
go 1.23.4
require github.com/mark3labs/mcp-go v0.8.2
require github.com/google/uuid v1.6.0
main.go:
package main
import (
"context"
"fmt"
"os/exec"
"github.com/mark3labs/mcp-go/mcp"
"github.com/mark3labs/mcp-go/server"
)
func main() {
// 创建MCP服务器
s := server.NewMCPServer(
"mcp-curl",
"1.0.0",
)
// 添加一个工具
tool := mcp.NewTool("use_curl",
mcp.WithDescription("获取这个网页"),
mcp.WithString("url",
mcp.Required(),
mcp.Description("要获取的网页的URL"),
),
)
// 添加一个工具处理器
s.AddTool(tool, curlHandler)
fmt.Println("🚀 服务器已启动")
// 启动标准输入输出服务器
if err := server.ServeStdio(s); err != nil {
fmt.Printf("😡 服务器错误: %v\n", err)
}
fmt.Println("👋 服务器已停止")
}
func curlHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
url, ok := request.Params.Arguments["url"].(string)
if !ok {
return mcp.NewToolResultError("url必须是一个字符串"), nil
}
cmd := exec.Command("curl", "-s", url)
output, err := cmd.Output()
if err != nil {
return mcp.NewToolResultError(err.Error()), nil
}
content := string(output)
return mcp.NewToolResultText(content), nil
}
这真的非常简单。我的服务器将只提供一个工具。代码实现了一个基于curl的服务器,该服务器暴露了一个用于“抓取”网页的工具。
mcp-curl版本1.0.0的MCP服务器,该服务器与标准输入输出(stdio)一起工作。use_curl的工具,该工具需要一个url参数。handler,该处理器执行带有-s选项的curl命令以检索网页内容。为了使我的生活更轻松,我将使用一个Dockerfile来构建包含我的MCP服务器的Docker镜像。这样,我可以更容易地在不同平台上部署它,或者让任何人使用它。
Dockerfile:
FROM golang:1.23.4-alpine AS builder
WORKDIR /app
COPY go.mod .
COPY main.go .
RUN <<EOF
go mod tidy
go build
EOF
FROM curlimages/curl:8.6.0
WORKDIR /app
COPY --from=builder /app/mcp-curl .
ENTRYPOINT ["./mcp-curl"]
我的Dockerfile有两个部分:
curl的curlimages/curl:8.6.0镜像,并将我的mcp-curl服务器复制到该镜像中(所以mcp-curl是调用curl的可执行文件)。要构建Docker镜像,我运行以下命令:
docker build -t mcp-curl .
现在让我们看看如何使用新的MCP服务器与mcphost:
mcphost使用MCP服务器首先,我们需要为mcphost创建一个配置文件mcp.json:
{
"mcpServers": {
"mcp-curl-with-docker" :{
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"mcp-curl"
]
}
}
}
然后我们可以使用mcphost来使用我们的MCP服务器和Ollama中的LLM,如下所示:
mcphost --config ./mcp.json --model ollama:qwen2.5-coder:14b
MCP服务器被mcphost识别:

你可以使用/tools命令请求可用工具列表:

现在你可以请求网页的内容并分析其内容(在我的例子中,我从GitHub获取Go代码):

稍等片刻:

这是网页的内容:

可以看到,只需几行代码,就可以真正轻松地赋予你的LLMs“超能力”。在未来的一篇博客文章中,我将向你展示如何使用Ollama和Go中的MCP客户端创建一个生成式AI应用程序,以与我们的MCP服务器交互。