ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

awesome-copilot 实战:基于官方 go-sdk 构建 Go MCP Server 的完整开发指南

awesome-copilot 实战:基于官方 go-sdk 构建 Go MCP Server 的完整开发指南 awesome-copilot 实战基于官方 go-sdk 构建 Go MCP Server 的完整开发指南【免费下载链接】awesome-copilotCommunity-contributed instructions, agents, skills, and configurations to help you make the most of GitHub Copilot.项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-copilot导读本指南以 awesome-copilot 仓库中的 go-mcp-server.instructions.md 为核心骨架系统讲解如何基于官方github.com/modelcontextprotocol/go-sdk在 Go 中构建 Model Context ProtocolMCP服务器。你将掌握服务器初始化、Tools / Resources / Prompts 三种核心能力的注册、stdio 与 HTTP 两种传输方式、错误处理与 context 取消、JSON Schema 标签驱动的类型安全以及测试、日志、优雅关闭等生产级工程模式。全文结合仓库内的专家 Agentagents/go-mcp-expert.agent.md、项目生成 Skillskills/go-mcp-server-generator/SKILL.md与开发插件plugins/go-mcp-development/README.md中的源码级模板提供可直接复制运行的完整示例。一、环境与模块初始化1.1 初始化 Go 模块MCP 服务器也是一个标准 Go 项目首先创建模块并引入官方 SDKgo mod init github.com/yourusername/yourserver go get github.com/modelcontextprotocol/go-sdklatest生成后的go.mod应形如module github.com/yourusername/yourserver go 1.23 require github.com/modelcontextprotocol/go-sdk v1.0.0awesome-copilot 仓库中的 go-mcp-server-generator Skill 建议将模块路径替换为实际组织名如github.com/yourusername/myserver并保持go 1.23及以上版本以匹配官方 SDK 的依赖要求。1.2 推荐的项目目录结构Skill 模板给出了一套清晰的工程布局便于把工具、资源、配置与入口分离myserver/ ├── go.mod ├── go.sum ├── main.go ├── tools/ │ ├── tool1.go │ └── tool2.go ├── resources/ │ └── resource1.go ├── config/ │ └── config.go ├── README.md └── main_test.go这样做的目的main.go保持精简只负责装配与启动业务逻辑下沉到各 packagetools、resources、config各自职责单一便于测试与复用。二、创建 MCP Server 实例使用mcp.NewServer创建服务器第一参数是描述服务器实现的mcp.Implementation包含名称与版本第二参数是可选的mcp.Optionsimport github.com/modelcontextprotocol/go-sdk/mcp server : mcp.NewServer( mcp.Implementation{ Name: my-server, Version: v1.0.0, }, nil, // or provide mcp.Options )Implementation的Name和Version会通过 MCP 协议暴露给客户端如 IDE 或 Copilot用于识别服务器身份建议与go.mod中的模块名、版本保持一致。若暂时不需要声明额外能力Options传nil即可。三、添加 Tools类型安全是 Go 方案的核心优势3.1 定义输入/输出结构体Go SDK 的显著特性是基于结构体struct的输入输出。用json标签声明字段序列化名称用jsonschema标签提供人类可读的说明SDK 会自动将其转换为 JSON Schema 暴露给客户端type ToolInput struct { Query string json:query jsonschema:the search query Limit int json:limit,omitempty jsonschema:maximum results to return } type ToolOutput struct { Results []string json:results jsonschema:list of search results Count int json:count jsonschema:number of results found }omitempty表示可选字段jsonschema标签的文案会成为客户端可见的参数描述直接影响大模型对工具用法的理解质量务必写清楚。3.2 实现处理函数并注册处理函数的签名固定为func(ctx, *mcp.CallToolRequest, Input) (*mcp.CallToolResult, Output, error)。返回nil作为*mcp.CallToolResult时SDK 会用类型化的 Output 自动构造结果这是与返回字符串/结构化内容旧式写法的重要区别func SearchTool(ctx context.Context, req *mcp.CallToolRequest, input ToolInput) ( *mcp.CallToolResult, ToolOutput, error, ) { // Implement tool logic results : performSearch(ctx, input.Query, input.Limit) return nil, ToolOutput{ Results: results, Count: len(results), }, nil } // Register the tool mcp.AddTool(server, mcp.Tool{ Name: search, Description: Search for information, }, SearchTool, )mcp.AddTool接收服务器实例、工具描述Name是客户端调用标识、Description说明用途和处理函数。Skill 模板skills/go-mcp-server-generator/SKILL.md进一步建议每个工具放在独立文件如tools/tool1.go并在tools/registry.go中集中注册package tools import github.com/modelcontextprotocol/go-sdk/mcp func RegisterTools(server *mcp.Server) { RegisterTool1(server) RegisterTool2(server) // Register additional tools here }这样main.go只需一行tools.RegisterTools(server)即可挂载全部工具扩展新工具时零侵入。四、添加 Resources向客户端暴露可读数据Resources 用于向客户端提供“数据文件”式的可读内容文档、配置、快照等通过 URI 定位。用mcp.AddResource注册处理器返回mcp.ReadResourceResultfunc GetResource(ctx context.Context, req *mcp.ReadResourceRequest) (*mcp.ReadResourceResult, error) { content, err : loadResourceContent(ctx, req.URI) if err ! nil { return nil, err } return mcp.ReadResourceResult{ Contents: []any{ mcp.TextResourceContents{ ResourceContents: mcp.ResourceContents{ URI: req.URI, MIMEType: text/plain, }, Text: content, }, }, }, nil } mcp.AddResource(server, mcp.Resource{ URI: file:///data/example.txt, Name: Example Data, Description: Example resource data, MIMEType: text/plain, }, GetResource, )要点注册时声明的URI、Name、Description、MIMEType会先于处理器被客户端看到用于资源发现listing处理器根据req.URI动态加载内容并包装进TextResourceContents其中MIMEType描述内容类型text/plain、application/json等若加载失败文件不存在、权限不足直接返回error客户端会收到 MCP 错误码而非异常数据。五、添加 Prompts可复用的提示词模板Prompts 允许服务器定义可复用的提示模板客户端可以填充参数后使用。用mcp.AddPrompt注册type PromptInput struct { Topic string json:topic jsonschema:the topic to analyze } func AnalyzePrompt(ctx context.Context, req *mcp.GetPromptRequest, input PromptInput) ( *mcp.GetPromptResult, error, ) { return mcp.GetPromptResult{ Description: Analyze the given topic, Messages: []mcp.PromptMessage{ { Role: mcp.RoleUser, Content: mcp.TextContent{ Text: fmt.Sprintf(Analyze this topic: %s, input.Topic), }, }, }, }, nil } mcp.AddPrompt(server, mcp.Prompt{ Name: analyze, Description: Analyze a topic, Arguments: []mcp.PromptArgument{ { Name: topic, Description: The topic to analyze, Required: true, }, }, }, AnalyzePrompt, )与 Tools 类似Prompt 也用带jsonschema标签的结构体接收参数mcp.PromptArgument的Required字段控制该参数是否必填。返回的mcp.PromptMessage中Role可取mcp.RoleUser等角色Content使用mcp.TextContent承载最终拼接的提示文本。六、传输方式配置6.1 Stdio 传输桌面集成的默认选择stdio 通过标准输入/输出与父进程如 IDE、Copilot CLI通信是最常见的本地/桌面集成方式if err : server.Run(ctx, mcp.StdioTransport{}); err ! nil { log.Fatal(err) }注意stdio 模式下不要向 stdout 打印业务日志会污染协议通道日志应走 stderr 或log/slog的文件/系统输出。6.2 HTTP 传输需要面向网络提供服务时使用mcp.HTTPTransportAddr指定监听地址import github.com/modelcontextprotocol/go-sdk/mcp transport : mcp.HTTPTransport{ Addr: :8080, // Optional: configure TLS, timeouts, etc. } if err : server.Run(ctx, transport); err ! nil { log.Fatal(err) }安全提醒一旦服务暴露到网络就进入远程服务器范畴。awesome-copilot 中的 mcp-implementation-security-review Skill 明确将 Go SDK 列为MCP-05SDK-firstTier 1 完全受支持的官方 SDK但它同时强调网络暴露的服务器必须落实身份认证MCP-01、会话安全MCP-02、限流MCP-03、入参 Schema 校验MCP-04等基线控制并警惕命令注入、路径穿越、SSRF 等 RCE 向量。仅切换传输方式并不会自动获得这些安全能力需由业务层补充。七、错误处理与 Context 使用7.1 错误处理规范SDK 约定处理函数返回的error会被转译为 MCP 错误反馈给客户端。因此要校验输入、包装错误、保留调用链func MyTool(ctx context.Context, req *mcp.CallToolRequest, input MyInput) ( *mcp.CallToolResult, MyOutput, error, ) { // Check context cancellation if ctx.Err() ! nil { return nil, MyOutput{}, ctx.Err() } // Return errors for invalid input if input.Query { return nil, MyOutput{}, fmt.Errorf(query cannot be empty) } // Perform operation result, err : performOperation(ctx, input) if err ! nil { return nil, MyOutput{}, fmt.Errorf(operation failed: %w, err) } return nil, result, nil }三条规则与 agents/go-mcp-expert.agent.md 中专家模式的要求一致输入校验失败返回明确错误信息如query cannot be empty不要让无效请求进入业务逻辑底层错误用fmt.Errorf(...: %w, err)包装保留%w包裹的原始错误链便于errors.Is/errors.As判断长耗时操作在入口处先检查ctx.Err()。7.2 尊重 Context 取消与超时对长任务使用select同时监听取消信号与结果通道func LongRunningTool(ctx context.Context, req *mcp.CallToolRequest, input Input) ( *mcp.CallToolResult, Output, error, ) { select { case -ctx.Done(): return nil, Output{}, ctx.Err() case result : -performWork(ctx, input): return nil, result, nil } }一旦客户端断开或超时ctx.Done()立即触发避免 goroutine 泄漏和资源空耗。八、JSON Schema 标签详解jsonschema标签是 SDK 将 Go 结构体转换为客户端可见 Schema 的关键支持required、description、范围、格式等约束type Input struct { Name string json:name jsonschema:required,descriptionUsers name Age int json:age jsonschema:minimum0,maximum150 Email string json:email,omitempty jsonschema:formatemail Tags []string json:tags,omitempty jsonschema:uniqueItemstrue Active bool json:active jsonschema:defaulttrue }常用约束对照标签写法生成的 Schema 约束适用场景requiredrequired: true必填参数description...description参数说明会被大模型读取minimum0,maximum150数值上下界数值校验formatemailformat: email邮箱、URI 等格式uniqueItemstrue数组元素唯一去重集合defaulttruedefault客户端可感知的默认值带omitempty的字段同时表达“可选”required且不带omitempty的字段为必填。越完整的 Schema客户端与模型越能正确生成调用参数——这同时也天然满足了 MCP-04 输入校验的基线要求。九、Server Options 与能力声明通过mcp.Options显式声明服务器能力客户端据此决定调用哪些端点options : mcp.Options{ Capabilities: mcp.ServerCapabilities{ Tools: mcp.ToolsCapability{}, Resources: mcp.ResourcesCapability{ Subscribe: true, // Enable resource subscriptions }, Prompts: mcp.PromptsCapability{}, }, } server : mcp.NewServer( mcp.Implementation{Name: my-server, Version: v1.0.0}, options, )Tools: mcp.ToolsCapability{}声明支持工具调用Resources: mcp.ResourcesCapability{Subscribe: true}声明资源能力并开启订阅资源变更可推送通知Prompts: mcp.PromptsCapability{}声明提示模板能力。go-mcp-server-generator Skill 生成项目时默认同时开启三类能力并在main.go中统一装配与上述 Options 结构完全对应。十、测试工具处理函数签名是纯函数式的因此无需启动服务器即可单测func TestSearchTool(t *testing.T) { ctx : context.Background() input : ToolInput{Query: test, Limit: 10} result, output, err : SearchTool(ctx, nil, input) if err ! nil { t.Fatalf(SearchTool failed: %v, err) } if len(output.Results) 0 { t.Error(Expected results, got none) } }测试要点参考 skills/go-mcp-server-generator/SKILL.md 的main_test.go模板直接传入context.Background()与nil请求对象即可调用处理函数本例中的工具不依赖req内容断言返回的Output字段如Status success、结果非空对类型化输出方案*mcp.CallToolResult返回nil属预期行为应单独断言建议每个工具至少一个测试必要时用表驱动测试覆盖边界与错误路径。十一、生产级常见模式11.1 结构化日志使用标准库log/slog在工具入口记录调用信息参数注意脱敏import log/slog logger : slog.Default() logger.Info(tool called, name, req.Params.Name, args, req.Params.Arguments)日志既能辅助排障也对应 MCP-08 审计与遥测的要求——记录调用者、工具名与时间戳。11.2 配置管理用环境变量或配置文件驱动配置提供默认值type Config struct { ServerName string Version string Port int } func LoadConfig() *Config { return Config{ ServerName: getEnv(SERVER_NAME, my-server), Version: getEnv(VERSION, v1.0.0), Port: getEnvInt(PORT, 8080), } }Skill 模板的 config/config.go 模板 给出了可直接落地的getEnv(key, defaultValue string) string辅助函数实现并约定SERVER_NAME、VERSION、LOG_LEVEL默认info等标准环境变量。11.3 优雅关闭监听os.InterruptCtrlC与syscall.SIGTERM容器/进程管理器收到信号后取消根 context让server.Run安全退出ctx, cancel : context.WithCancel(context.Background()) defer cancel() sigCh : make(chan os.Signal, 1) signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM) go func() { -sigCh cancel() }() if err : server.Run(ctx, transport); err ! nil { log.Fatal(err) }该模式与 Skill 生成的主程序模板signal.Notify 信号 goroutine server.Run完全一致确保进程在停止时能完成清理而非被直接杀死。十二、与 awesome-copilot 生态的协同使用本指南对应的指令只是 awesome-copilot 中 Go MCP 开发生态的一环仓库提供了完整的配套工具链专家 Agentagents/go-mcp-expert.agent.md 定义了Go MCP Server 开发专家的完整行为画像——强制类型安全设计、JSON Schema 标签、context 管理、错误包装、测试与文档规范适合以聊天模式获得实时代码指导项目生成 Skillskills/go-mcp-server-generator/SKILL.md 可一键生成上述完整工程目录结构、go.mod、main.go、tools/resources/config 模板、main_test.go、README内含 10 条生成指令与最佳实践清单开发插件plugins/go-mcp-development/README.md 将指令、Skill 与 Agent 打包可通过copilot plugin install go-mcp-developmentawesome-copilot安装并提供/go-mcp-server-generator斜杠命令与go-mcp-expert智能体安全审查 Skillskills/mcp-implementation-security-review/SKILL.md 提供针对 MCP 实现的基线控制MCP-01~05、RCE 向量与 OWASP MCP Top 10 审查流程发布网络暴露型 Go MCP 服务器前建议先跑一遍。三者与本文档配合可形成指令规范 → 专家指导 → 项目生成 → 安全审查的完整开发闭环。结语基于官方github.com/modelcontextprotocol/go-sdk构建 Go MCP 服务器核心在于发挥 Go 的类型系统优势用结构体 json/jsonschema标签定义工具、资源与提示模板的契约通过mcp.NewServer、mcp.AddTool、mcp.AddResource、mcp.AddPrompt快速装配按场景选择 stdio 或 HTTP 传输并始终遵守校验输入、包装错误、尊重 context三条铁律。结合本仓库的专家 Agent、项目生成 Skill 与安全审查 Skill你可以从零快速产出结构清晰、可测试、可安全上线的 Go MCP 服务器。如需在本地初始化项目可先阅读 README.md 了解仓库全貌再按 skills/go-mcp-server-generator/SKILL.md 的模板动手实践。【免费下载链接】awesome-copilotCommunity-contributed instructions, agents, skills, and configurations to help you make the most of GitHub Copilot.项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-copilot创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表