MCP官方 Go SDK v1.0 正式发布,我立马实现了自己的MCP server

MCP(Model Context Protocol)是 Anthropic 推出的一种标准化协议,用于让 AI 模型(如 Copilot Agent)安全、高效地调用外部工具和服务。通过 MCP,你可以将数据库查询、API 调用、文件操作等能力暴露给 AI,使其具备"行动力"。

今日,随着MCP官方发布了Go SDK,AI的风终于吹到的go。本文将带你从零开始 ,使用官方 mcp Go SDK 编写一个简单的 MCP 服务器,实现 "获取当前时间""读取本地文件" 两个工具,并在 VS Code 中测试调用。

一、什么是 MCP?

MCP 是一种基于 JSON-RPC 2.0 的双向通信协议,运行在 stdio(标准输入输出)HTTP 上。其核心概念包括:

  • Tool(工具) :AI 可调用的函数,如 readFilelistIssues
  • Resource(资源):可被引用的数据,如文件内容、数据库记录
  • Prompt(提示):提供上下文的文本片段

MCP 服务器启动后,会向客户端(如 VS Code)注册自己支持的工具,客户端在需要时发起调用。


二、准备工作

1. 创建项目

bash 复制代码
mkdir mcp-demo && cd mcp-demo
go mod init mcp-demo

2. 安装官方 SDK

bash 复制代码
go get github.com/modelcontextprotocol/go-sdk@latest

三、编写 MCP 服务器代码

创建 main.go

go 复制代码
// main.go
package main

import (
	"context"
	"fmt"
	"os"
	"time"

	"github.com/modelcontextprotocol/go-sdk/mcp"
	"github.com/modelcontextprotocol/go-sdk/mcp/transport"
)

func main() {
	// 创建 MCP 服务器
	server := mcp.NewServer("mcp-demo", "1.0.0")

	// 注册 "getCurrentTime" 工具
	server.AddTool(mcp.Tool{
		Name:        "getCurrentTime",
		Description: "获取当前时间(支持时区)",
		InputSchema: map[string]interface{}{
			"type": "object",
			"properties": map[string]interface{}{
				"timezone": map[string]interface{}{
					"type":        "string",
					"description": "时区,如 'Asia/Shanghai',默认为本地时区",
					"default":     "Local",
				},
			},
			"required": []string{},
		},
		Handler: func(ctx context.Context, args map[string]interface{}) (interface{}, error) {
			tzName, _ := args["timezone"].(string)
			loc := time.Local
			if tzName != "" && tzName != "Local" {
				var err error
				loc, err = time.LoadLocation(tzName)
				if err != nil {
					return nil, fmt.Errorf("无效时区: %v", err)
				}
			}
			now := time.Now().In(loc).Format("2006-01-02 15:04:05 MST")
			return map[string]string{"time": now}, nil
		},
	})

	// 注册 "readFile" 工具
	server.AddTool(mcp.Tool{
		Name:        "readFile",
		Description: "读取本地文本文件内容",
		InputSchema: map[string]interface{}{
			"type": "object",
			"properties": map[string]interface{}{
				"path": map[string]interface{}{
					"type":        "string",
					"description": "文件路径(相对或绝对)",
				},
			},
			"required": []string{"path"},
		},
		Handler: func(ctx context.Context, args map[string]interface{}) (interface{}, error) {
			path, ok := args["path"].(string)
			if !ok {
				return nil, fmt.Errorf("缺少 path 参数")
			}

			// 安全限制:只允许读取当前目录及子目录
			if !mcp.IsSubPath(".", path) {
				return nil, fmt.Errorf("禁止访问上级目录")
			}

			content, err := os.ReadFile(path)
			if err != nil {
				return nil, fmt.Errorf("读取文件失败: %v", err)
			}
			return map[string]string{
				"content": string(content),
				"path":    path,
			}, nil
		},
	})

	// 启动 stdio 传输(VS Code 默认通过 stdio 通信)
	if err := transport.RunStdio(server); err != nil {
		fmt.Fprintf(os.Stderr, "MCP 服务器启动失败: %v\n", err)
		os.Exit(1)
	}
}

代码说明:

  1. mcp.NewServer:创建服务器实例,指定名称和版本。
  2. AddTool :注册工具,包含:
    • Name:工具唯一标识
    • Description:AI 理解用途的描述
    • InputSchema:JSON Schema 定义输入参数
    • Handler:实际执行逻辑
  3. 安全限制
    • readFile 使用 mcp.IsSubPath 防止路径穿越(如 ../../../etc/passwd
  4. transport.RunStdio:通过标准输入输出与 VS Code 通信(最常用方式)

四、构建可执行文件

bash 复制代码
go build -o mcp-demo .

生成 mcp-demo(Linux/macOS)或 mcp-demo.exe(Windows)。


五、在 VS Code 中注册 MCP 服务器

1. 创建 MCP 配置文件

在任意目录创建 mcp.json(推荐放在项目根目录):

json 复制代码
{
  "servers": {
    "mcp-demo": {
      "command": "./mcp-demo"
    }
  }
}

💡 Windows 用户请写 "command": ".\\mcp-demo.exe"

2. 加载 MCP 服务器

  • 打开 VS Code
  • Ctrl+Shift+P(Windows/Linux)或 Cmd+Shift+P(Mac)
  • 输入 MCP: Open User Configuration
  • 将上述 mcp.json 内容粘贴保存

VS Code 会自动启动你的 MCP 服务器,并在聊天工具列表中显示 getCurrentTimereadFile


六、测试调用

在 VS Code 的 Copilot Chat 中输入:

text 复制代码
使用 getCurrentTime 工具获取上海当前时间

text 复制代码
使用 readFile 工具读取 README.md 的内容

你将看到 AI 自动调用你的工具,并返回结构化结果!


总结

通过本文,你已掌握:

✅ 使用 Go SDK 创建 MCP 服务器

✅ 定义安全的工具(Tool)

✅ 在 VS Code 中注册并调用

✅ 防范路径穿越等安全风险

MCP 是连接 AI 与现实世界的桥梁。你可以用它集成:

  • 内部 API 网关

  • 数据库查询

  • 企业知识库

现在,就去构建属于你自己的 AI 工具吧!🚀

相关推荐
swipe16 小时前
09|(前端转全栈)商品为什么不能随便上下架?后端状态机思维入门
前端·后端·全栈
zhangjw3416 小时前
第36篇:Spring Boot进阶:Web开发+参数校验+全局异常处理
前端·spring boot·后端
倒流时光三十年16 小时前
第一阶段 02 · Mapping 与数据类型(text vs keyword 是重点)
后端·python·django
Zane199416 小时前
JMM 与 happens-before:一次搞懂 Java 内存模型
java·后端
用户2986985301416 小时前
在线将 Word 文档转换为 TXT 格式:快速免费的方法
人工智能·后端
shepherd11116 小时前
别再把 MCP 当成大模型的“手脚”:LLM 并不会直接调用 MCP
后端·ai编程·mcp
SimonKing17 小时前
别再写 setter 了!MapStruct Plus vs MapStruct,谁才是 Bean 转换的真神?
java·后端·程序员
名字还没想好☜17 小时前
Go for-range 循环变量陷阱:goroutine 里全打印同一个值(Go 1.22 前后差异)
开发语言·后端·golang·go
AI多Agent协作实战派17 小时前
AI多Agent协作系统实战(二十五):Spring Boot静态资源同步:为什么你改了代码但线上还是旧的?
后端
码栈研说17 小时前
Go 语言大白话入门 12 - JSON:工作里最常见的数据格式
后端·程序员