关于 Creating an MCP Server in Go and Serving it with Docker
这篇教程展示如何用 Go 编写一个 MCP 服务,通过 curl 和给定的 URL 获取网页内容。内容面向学习 MCP 服务开发与 Docker 打包的读者,使用 mcp-go 实现单一网页抓取工具。
主要功能
- 01用 Go 实现 MCP 服务
- 02通过 curl 获取网页内容
- 03接收必填 URL 参数
- 04返回网页文本并处理错误
- 05使用 Docker 打包服务
适用场景
- 01学习 MCP 工具的基本调用流程
- 02获取网页供大模型分析
- 03在 Docker 中构建并运行服务
MCP 相关
示例使用 mcp-go 和 stdio 传输实现 MCP 服务,向 MCP 客户端提供一个名为 use_curl 的工具,用于获取网页内容。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
在 Go 中创建 MCP 服务并通过 Docker 提供服务
简介
今天,我们来看看如何在 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 的创建者开发(我在上一篇博客文章中介绍并使用了 mcphost)。
mcp-go 项目的优势在于它简单易用,还提供了开发 MCP 客户端的工具,这对今后的博客文章会很有帮助。
创建 MCP 服务
这里我不会详细介绍或实现 MCP 服务的所有功能,只会实现核心部分:
- 为大模型提供工具列表
- 在大模型调用工具时执行这些工具
使用大模型时,有一件事是我希望能够做到的:给它一个网站链接,让它查找其中的信息、为我生成摘要等。
于是我创建了一个 MCP 服务,它会调用 curl 工具,并将 URL 作为参数传入,然后返回网页内容。下面来看看源代码:
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() {
// Create MCP server
s := server.NewMCPServer(
"mcp-curl",
"1.0.0",
)
// Add a tool
tool := mcp.NewTool("use_curl",
mcp.WithDescription("fetch this webpage"),
mcp.WithString("url",
mcp.Required(),
mcp.Description("url of the webpage to fetch"),
),
)
// Add a tool handler
s.AddTool(tool, curlHandler)
fmt.Println("🚀 Server started")
// Start the stdio server
if err := server.ServeStdio(s); err != nil {
fmt.Printf("😡 Server error: %v\n", err)
}
fmt.Println("👋 Server stopped")
}
func curlHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
url, ok := request.Params.Arguments["url"].(string)
if !ok {
return mcp.NewToolResultError("url must be a string"), 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命令以获取网页内容 - 当然,我也处理了错误,并将网页内容作为文本返回
使用 Docker 打包 MCP 服务
为了方便起见,我会使用 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 分为两部分:
- 第一部分使用 Go 构建 MCP 服务
- 第二部分使用包含
curl的curlimages/curl:8.6.0镜像,并将我的mcp-curl服务复制到镜像中(因此mcp-curl是调用curl的可执行文件)
要构建 Docker 镜像,我会运行以下命令:
docker build -t mcp-curl .
现在来看看如何使用 mcphost 调用我们的新 MCP 服务:
使用 mcphost 调用 MCP 服务
首先,我们需要为 mcphost 创建配置文件 mcp.json:
{
"mcpServers": {
"mcp-curl-with-docker" :{
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"mcp-curl"
]
}
}
}
然后,我们就可以通过 mcphost 使用我们的 MCP 服务和 Ollama 上的大模型,命令如下:
mcphost --config ./mcp.json --model ollama:qwen2.5-coder:14b
mcphost 已识别出 MCP 服务:

你可以使用 /tools 命令查看可用工具列表:

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

稍等片刻:

网页内容如下:

总结
可以看到,只需几行代码,就能轻松为大模型赋予“超能力”。在今后的博客文章中,我会展示如何使用 Ollama 和 Go 语言的 MCP 客户端创建生成式 AI 应用,与我们的 MCP 服务交互。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。