mark3labs/mcp-go

GitHub: mark3labs/mcp-go

一个基于 Go 语言的 Model Context Protocol (MCP) SDK,旨在帮助开发者快速构建服务端,实现 LLM 应用与外部数据源及工具之间的标准化无缝集成。

Stars: 8254 | Forks: 776

MCP Go Logo [![Build](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/6f087f103a153806.svg)](https://github.com/mark3labs/mcp-go/actions/workflows/ci.yml) [![Go Report Card](https://goreportcard.com/badge/github.com/mark3labs/mcp-go?cache)](https://goreportcard.com/report/github.com/mark3labs/mcp-go) [![GoDoc](https://pkg.go.dev/badge/github.com/mark3labs/mcp-go.svg)](https://pkg.go.dev/github.com/mark3labs/mcp-go) Model Context Protocol (MCP) 的 Go 实现,实现 LLM 应用与外部数据源及工具之间的无缝集成。
[![教程](http://img.youtube.com/vi/qoaeYMrXJH0/0.jpg)](http://www.youtube.com/watch?v=qoaeYMrXJH0 "Tutorial")
在 [Discord](https://discord.gg/RqSS2NQVsY) 上讨论 SDK
``` package main import ( "context" "fmt" "github.com/mark3labs/mcp-go/mcp" "github.com/mark3labs/mcp-go/server" ) func main() { // Create a new MCP server s := server.NewMCPServer( "Demo 🚀", "1.0.0", server.WithToolCapabilities(false), ) // Add tool tool := mcp.NewTool("hello_world", mcp.WithDescription("Say hello to someone"), mcp.WithString("name", mcp.Required(), mcp.Description("Name of the person to greet"), ), ) // Add tool handler s.AddTool(tool, helloHandler) // Start the stdio server if err := server.ServeStdio(s); err != nil { fmt.Printf("Server error: %v\n", err) } } func helloHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { name, err := request.RequireString("name") if err != nil { return mcp.NewToolResultError(err.Error()), nil } return mcp.NewToolResultText(fmt.Sprintf("Hello, %s!", name)), nil } ``` 就是这样! MCP Go 处理所有复杂的协议细节和服务器管理,因此您可以专注于构建出色的工具。它旨在提供高级且易于使用的体验。 ### 主要特性: * **快速**:高级接口意味着更少的代码和更快的开发速度 * **简单**:以极少的样板代码构建 MCP 服务器 * **完整***:MCP Go 旨在提供完整的 MCP 核心规范实现 (*重点是“旨在”) 🚨 🚧 🏗️ *MCP Go 正处于活跃开发中,MCP 规范本身也是如此。核心功能已可正常工作,但部分高级功能仍在开发中。* ## 目录 - [安装](#installation) - [快速开始](#quickstart) - [什么是 MCP?](#what-is-mcp) - [核心概念](#core-concepts) - [服务器](#server) - [资源](#resources) - [工具](#tools) - [提示词](#prompts) - [示例](#examples) - [附加功能](#extras) - [传输层](#transports) - [会话管理](#session-management) - [基本会话处理](#basic-session-handling) - [单会话工具](#per-session-tools) - [工具过滤](#tool-filtering) - [使用 Context](#working-with-context) - [请求钩子](#request-hooks) - [工具处理程序中间件](#tool-handler-middleware) - [重新生成服务器代码](#regenerating-server-code) ## 安装 ``` go get github.com/mark3labs/mcp-go ``` ## 快速开始 让我们创建一个简单的 MCP 服务器,公开一个计算器工具和一些数据: ``` package main import ( "context" "fmt" "github.com/mark3labs/mcp-go/mcp" "github.com/mark3labs/mcp-go/server" ) func main() { // Create a new MCP server s := server.NewMCPServer( "Calculator Demo", "1.0.0", server.WithToolCapabilities(false), server.WithRecovery(), ) // Add a calculator tool calculatorTool := mcp.NewTool("calculate", mcp.WithDescription("Perform basic arithmetic operations"), mcp.WithString("operation", mcp.Required(), mcp.Description("The operation to perform (add, subtract, multiply, divide)"), mcp.Enum("add", "subtract", "multiply", "divide"), ), mcp.WithNumber("x", mcp.Required(), mcp.Description("First number"), ), mcp.WithNumber("y", mcp.Required(), mcp.Description("Second number"), ), ) // Add the calculator handler s.AddTool(calculatorTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { // Using helper functions for type-safe argument access op, err := request.RequireString("operation") if err != nil { return mcp.NewToolResultError(err.Error()), nil } x, err := request.RequireFloat("x") if err != nil { return mcp.NewToolResultError(err.Error()), nil } y, err := request.RequireFloat("y") if err != nil { return mcp.NewToolResultError(err.Error()), nil } var result float64 switch op { case "add": result = x + y case "subtract": result = x - y case "multiply": result = x * y case "divide": if y == 0 { return mcp.NewToolResultError("cannot divide by zero"), nil } result = x / y } return mcp.NewToolResultText(fmt.Sprintf("%.2f", result)), nil }) // Start the server if err := server.ServeStdio(s); err != nil { fmt.Printf("Server error: %v\n", err) } } ``` ## 什么是 MCP? [Model Context Protocol (MCP)](https://modelcontextprotocol.io) 允许您构建服务器,以安全、标准化的方式向 LLM 应用公开数据和功能。可以把它想象成 Web API,但专门为 LLM 交互而设计。 MCP 服务器可以: - 通过 **Resources(资源)** 公开数据(把它们看作类似 GET 端点;用于将信息加载到 LLM 的上下文中) - 通过 **Tools(工具)** 提供功能(类似 POST 端点;用于执行代码或产生副作用) - 通过 **Prompts(提示词)** 定义交互模式(LLM 交互的可重用模板) - 以及更多! mcp-go 实现了 Model Context Protocol 规范版本 2025-11-25,并向下兼容 2025-06-18、2025-03-26 和 2024-11-05 版本。 ## 核心概念 ### 服务器
显示服务器示例 服务器是您与 MCP 协议的核心接口。它处理连接管理、协议合规性和消息路由: ``` // Create a basic server s := server.NewMCPServer( "My Server", // Server name "1.0.0", // Version ) // Start the server using stdio if err := server.ServeStdio(s); err != nil { log.Fatalf("Server error: %v", err) } ```
### 资源
显示资源示例 资源是您向 LLM 公开数据的方式。它们可以是任何东西——文件、API 响应、数据库查询、系统信息等。资源可以是: - 静态(固定 URI) - 动态(使用 URI 模板) 这是一个静态资源的简单示例: ``` // Static resource example - exposing a README file resource := mcp.NewResource( "docs://readme", "Project README", mcp.WithResourceDescription("The project's README file"), mcp.WithMIMEType("text/markdown"), ) // Add resource with its handler s.AddResource(resource, func(ctx context.Context, request mcp.ReadResourceRequest) ([]mcp.ResourceContents, error) { content, err := os.ReadFile("README.md") if err != nil { return nil, err } return []mcp.ResourceContents{ mcp.TextResourceContents{ URI: "docs://readme", MIMEType: "text/markdown", Text: string(content), }, }, nil }) ``` 这是一个使用模板的动态资源示例: ``` // Dynamic resource example - user profiles by ID template := mcp.NewResourceTemplate( "users://{id}/profile", "User Profile", mcp.WithTemplateDescription("Returns user profile information"), mcp.WithTemplateMIMEType("application/json"), ) // Add template with its handler s.AddResourceTemplate(template, func(ctx context.Context, request mcp.ReadResourceRequest) ([]mcp.ResourceContents, error) { // Extract ID from the URI using regex matching // The server automatically matches URIs to templates userID := extractIDFromURI(request.Params.URI) profile, err := getUserProfile(userID) // Your DB/API call here if err != nil { return nil, err } return []mcp.ResourceContents{ mcp.TextResourceContents{ URI: request.Params.URI, MIMEType: "application/json", Text: profile, }, }, nil }) ``` 这些示例很简单,但展示了核心概念。资源可以更加复杂——提供多种内容、与数据库或外部 API 集成等。
### 工具
显示工具示例 工具允许 LLM 通过您的服务器执行操作。与资源不同,工具旨在执行计算并具有副作用。它们类似于 REST API 中的 POST 端点。 #### 任务增强型工具 任务增强型工具异步执行并通过轮询返回结果。这对于长时间运行的操作非常有用,可以避免阻塞或超时。任务工具支持三种模式: - **TaskSupportForbidden**(默认):工具不能作为任务调用 - **TaskSupportOptional**:工具可以作为任务调用或同步调用 - **TaskSupportRequired**:工具必须作为任务调用 ``` // Example: A tool that requires task execution processBatchTool := mcp.NewTool("process_batch", mcp.WithDescription("Process a batch of items asynchronously"), mcp.WithTaskSupport(mcp.TaskSupportRequired), mcp.WithArray("items", mcp.Description("Array of items to process"), mcp.WithStringItems(), mcp.Required(), ), ) // Task tool handler returns CreateTaskResult instead of CallToolResult s.AddTaskTool(processBatchTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CreateTaskResult, error) { items := request.GetStringSlice("items", []string{}) // Long-running work here for i, item := range items { select { case <-ctx.Done(): // Task was cancelled return nil, ctx.Err() default: // Process item... processItem(item) } } // Return result - task ID and metadata are managed by the server return &mcp.CreateTaskResult{ Task: mcp.Task{ // Task fields (ID, status, etc.) are populated by the server }, }, nil }) // Enable task capabilities when creating the server s := server.NewMCPServer( "Task Server", "1.0.0", server.WithTaskCapabilities( true, // listTasks: allows clients to list all tasks true, // cancel: allows clients to cancel running tasks true, // toolCallTasks: enables task augmentation for tools ), server.WithMaxConcurrentTasks(10), // Optional: limit concurrent running tasks ) ``` 任务执行流程: 1. 客户端带任务参数调用工具 2. 服务器立即返回任务 ID 3. 工具在后台异步执行 4. 客户端轮询 `tasks/result` 以获取结果 5. 服务器在完成时发送任务状态通知 对于可选任务工具,同一个工具可以同步调用(不带任务参数)或异步调用(带任务参数): ``` // Tool with optional task support analyzeTool := mcp.NewTool("analyze_data", mcp.WithDescription("Analyze data - can run sync or async"), mcp.WithTaskSupport(mcp.TaskSupportOptional), mcp.WithString("data", mcp.Required()), ) // Use AddTaskTool for hybrid tools that support both modes s.AddTaskTool(analyzeTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CreateTaskResult, error) { // This handler runs when called as a task data := request.GetString("data", "") result := analyzeData(data) return &mcp.CreateTaskResult{ Task: mcp.Task{}, }, nil }) // The server automatically handles both sync and async invocations // When called without task param: executes handler and returns immediately // When called with task param: executes handler asynchronously ``` ##### 限制并发任务 为了防止资源耗尽,您可以限制并发运行的任务数量: ``` s := server.NewMCPServer( "Task Server", "1.0.0", server.WithTaskCapabilities(true, true, true), server.WithMaxConcurrentTasks(10), // Allow up to 10 concurrent running tasks ) ``` 当达到限制时,新的任务创建请求将失败并报错。已完成、失败或取消的任务不计入限制——仅计入处于“working”状态的任务。如果未指定 `WithMaxConcurrentTasks` 或将其设置为 0,则对并发任务没有限制。 对于传统同步工具,即执行并立即返回结果的工具: 简单计算示例: ``` calculatorTool := mcp.NewTool("calculate", mcp.WithDescription("Perform basic arithmetic calculations"), mcp.WithString("operation", mcp.Required(), mcp.Description("The arithmetic operation to perform"), mcp.Enum("add", "subtract", "multiply", "divide"), ), mcp.WithNumber("x", mcp.Required(), mcp.Description("First number"), ), mcp.WithNumber("y", mcp.Required(), mcp.Description("Second number"), ), ) s.AddTool(calculatorTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { args := request.GetArguments() op := args["operation"].(string) x := args["x"].(float64) y := args["y"].(float64) var result float64 switch op { case "add": result = x + y case "subtract": result = x - y case "multiply": result = x * y case "divide": if y == 0 { return mcp.NewToolResultError("cannot divide by zero"), nil } result = x / y } return mcp.FormatNumberResult(result), nil }) ``` HTTP 请求示例: ``` httpTool := mcp.NewTool("http_request", mcp.WithDescription("Make HTTP requests to external APIs"), mcp.WithString("method", mcp.Required(), mcp.Description("HTTP method to use"), mcp.Enum("GET", "POST", "PUT", "DELETE"), ), mcp.WithString("url", mcp.Required(), mcp.Description("URL to send the request to"), mcp.Pattern("^https?://.*"), ), mcp.WithString("body", mcp.Description("Request body (for POST/PUT)"), ), ) s.AddTool(httpTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { args := request.GetArguments() method := args["method"].(string) url := args["url"].(string) body := "" if b, ok := args["body"].(string); ok { body = b } // Create and send request var req *http.Request var err error if body != "" { req, err = http.NewRequest(method, url, strings.NewReader(body)) } else { req, err = http.NewRequest(method, url, nil) } if err != nil { return mcp.NewToolResultErrorFromErr("unable to create request", err), nil } client := &http.Client{} resp, err := client.Do(req) if err != nil { return mcp.NewToolResultErrorFromErr("unable to execute request", err), nil } defer resp.Body.Close() // Return response respBody, err := io.ReadAll(resp.Body) if err != nil { return mcp.NewToolResultErrorFromErr("unable to read request response", err), nil } return mcp.NewToolResultText(fmt.Sprintf("Status: %d\nBody: %s", resp.StatusCode, string(respBody))), nil }) ``` 工具可用于任何类型的计算或副作用: - 数据库查询 - 文件操作 - 外部 API 调用 - 计算 - 系统操作 每个工具应该: - 具有清晰的描述 - 验证输入 - 优雅地处理错误 - 返回结构化响应 - 使用适当的结果类型
### 提示词
显示提示词示例 提示词是可重用的模板,可帮助 LLM 有效地与您的服务器交互。它们就像是编码到服务器中的“最佳实践”。以下是一些示例: ``` // Simple greeting prompt s.AddPrompt(mcp.NewPrompt("greeting", mcp.WithPromptDescription("A friendly greeting prompt"), mcp.WithArgument("name", mcp.ArgumentDescription("Name of the person to greet"), ), ), func(ctx context.Context, request mcp.GetPromptRequest) (*mcp.GetPromptResult, error) { name := request.Params.Arguments["name"] if name == "" { name = "friend" } return mcp.NewGetPromptResult( "A friendly greeting", []mcp.PromptMessage{ mcp.NewPromptMessage( mcp.RoleAssistant, mcp.NewTextContent(fmt.Sprintf("Hello, %s! How can I help you today?", name)), ), }, ), nil }) // Code review prompt with embedded resource s.AddPrompt(mcp.NewPrompt("code_review", mcp.WithPromptDescription("Code review assistance"), mcp.WithArgument("pr_number", mcp.ArgumentDescription("Pull request number to review"), mcp.RequiredArgument(), ), ), func(ctx context.Context, request mcp.GetPromptRequest) (*mcp.GetPromptResult, error) { prNumber := request.Params.Arguments["pr_number"] if prNumber == "" { return nil, fmt.Errorf("pr_number is required") } return mcp.NewGetPromptResult( "Code review assistance", []mcp.PromptMessage{ mcp.NewPromptMessage( mcp.RoleUser, mcp.NewTextContent("Review the changes and provide constructive feedback."), ), mcp.NewPromptMessage( mcp.RoleAssistant, mcp.NewEmbeddedResource(mcp.ResourceContents{ URI: fmt.Sprintf("git://pulls/%s/diff", prNumber), MIMEType: "text/x-diff", }), ), }, ), nil }) // Database query builder prompt s.AddPrompt(mcp.NewPrompt("query_builder", mcp.WithPromptDescription("SQL query builder assistance"), mcp.WithArgument("table", mcp.ArgumentDescription("Name of the table to query"), mcp.RequiredArgument(), ), ), func(ctx context.Context, request mcp.GetPromptRequest) (*mcp.GetPromptResult, error) { tableName := request.Params.Arguments["table"] if tableName == "" { return nil, fmt.Errorf("table name is required") } return mcp.NewGetPromptResult( "SQL query builder assistance", []mcp.PromptMessage{ mcp.NewPromptMessage( mcp.RoleUser, mcp.NewTextContent("Help construct efficient and safe queries for the provided schema."), ), mcp.NewPromptMessage( mcp.RoleUser, mcp.NewEmbeddedResource(mcp.ResourceContents{ URI: fmt.Sprintf("db://schema/%s", tableName), MIMEType: "application/json", }), ), }, ), nil }) ``` 提示词可以包含: - 系统指令 - 必需参数 - 嵌入资源 - 多条消息 - 不同内容类型(文本、图像等) - 自定义 URI 方案
## 示例 有关示例,请参阅 [`examples/`](examples/) 目录。 关键示例包括: - [`examples/task_tool/`](examples/task_tool/) - 演示了具有 TaskSupportRequired 和 TaskSupportOptional 模式的任务增强型工具 - 示例目录中涵盖资源、提示词等的更多示例 ## 附加功能 ### 传输层 MCP-Go 支持 stdio、SSE 和 streamable-HTTP 传输层。对于 SSE 传输,您可以使用 `SetConnectionLostHandler()` 来检测和处理断开连接,以实现重连逻辑。 ### 会话管理 MCP-Go 提供了一个强大的会话管理系统,允许您: - 为每个连接的客户端维护独立状态 - 注册和跟踪客户端会话 - 向特定客户端发送通知 - 提供单会话工具定制
显示会话管理示例 #### 基本会话处理 ``` // Create a server with session capabilities s := server.NewMCPServer( "Session Demo", "1.0.0", server.WithToolCapabilities(true), ) // Implement your own ClientSession type MySession struct { id string notifChannel chan mcp.JSONRPCNotification isInitialized bool // Add custom fields for your application } // Implement the ClientSession interface func (s *MySession) SessionID() string { return s.id } func (s *MySession) NotificationChannel() chan<- mcp.JSONRPCNotification { return s.notifChannel } func (s *MySession) Initialize() { s.isInitialized = true } func (s *MySession) Initialized() bool { return s.isInitialized } // Register a session session := &MySession{ id: "user-123", notifChannel: make(chan mcp.JSONRPCNotification, 10), } if err := s.RegisterSession(context.Background(), session); err != nil { log.Printf("Failed to register session: %v", err) } // Send notification to a specific client err := s.SendNotificationToSpecificClient( session.SessionID(), "notification/update", map[string]any{"message": "New data available!"}, ) if err != nil { log.Printf("Failed to send notification: %v", err) } // Unregister session when done s.UnregisterSession(context.Background(), session.SessionID()) ``` #### 单会话工具 对于更高级的用例,您可以实现 `SessionWithTools` 接口以支持单会话工具定制: ``` // Implement SessionWithTools interface for per-session tools type MyAdvancedSession struct { MySession // Embed the basic session sessionTools map[string]server.ServerTool } // Implement additional methods for SessionWithTools func (s *MyAdvancedSession) GetSessionTools() map[string]server.ServerTool { return s.sessionTools } func (s *MyAdvancedSession) SetSessionTools(tools map[string]server.ServerTool) { s.sessionTools = tools } // Create and register a session with tools support advSession := &MyAdvancedSession{ MySession: MySession{ id: "user-456", notifChannel: make(chan mcp.JSONRPCNotification, 10), }, sessionTools: make(map[string]server.ServerTool), } if err := s.RegisterSession(context.Background(), advSession); err != nil { log.Printf("Failed to register session: %v", err) } // Add session-specific tools userSpecificTool := mcp.NewTool( "user_data", mcp.WithDescription("Access user-specific data"), ) // You can use AddSessionTool (similar to AddTool) err := s.AddSessionTool( advSession.SessionID(), userSpecificTool, func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { // This handler is only available to this specific session return mcp.NewToolResultText("User-specific data for " + advSession.SessionID()), nil }, ) if err != nil { log.Printf("Failed to add session tool: %v", err) } // Or use AddSessionTools directly with ServerTool /* err := s.AddSessionTools( advSession.SessionID(), server.ServerTool{ Tool: userSpecificTool, Handler: func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { // This handler is only available to this specific session return mcp.NewToolResultText("User-specific data for " + advSession.SessionID()), nil }, }, ) if err != nil { log.Printf("Failed to add session tool: %v", err) } */ // Delete session-specific tools when no longer needed err = s.DeleteSessionTools(advSession.SessionID(), "user_data") if err != nil { log.Printf("Failed to delete session tool: %v", err) } ``` #### 工具过滤 您还可以应用过滤器来控制某些会话可以使用哪些工具: ``` // Add a tool filter that only shows tools with certain prefixes s := server.NewMCPServer( "Tool Filtering Demo", "1.0.0", server.WithToolCapabilities(true), server.WithToolFilter(func(ctx context.Context, tools []mcp.Tool) []mcp.Tool { // Get session from context session := server.ClientSessionFromContext(ctx) if session == nil { return tools // Return all tools if no session } // Example: filter tools based on session ID prefix if strings.HasPrefix(session.SessionID(), "admin-") { // Admin users get all tools return tools } else { // Regular users only get tools with "public-" prefix var filteredTools []mcp.Tool for _, tool := range tools { if strings.HasPrefix(tool.Name, "public-") { filteredTools = append(filteredTools, tool) } } return filteredTools } }), ) ``` #### 使用 Context 会话上下文会自动传递给工具和资源处理程序: ``` s.AddTool(mcp.NewTool("session_aware"), func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { // Get the current session from context session := server.ClientSessionFromContext(ctx) if session == nil { return mcp.NewToolResultError("No active session"), nil } return mcp.NewToolResultText("Hello, session " + session.SessionID()), nil }) // When using handlers in HTTP/SSE servers, you need to pass the context with the session httpHandler := func(w http.ResponseWriter, r *http.Request) { // Get session from somewhere (like a cookie or header) session := getSessionFromRequest(r) // Add session to context ctx := s.WithContext(r.Context(), session) // Use this context when handling requests // ... } ```
### 请求钩子 通过创建一个包含您所选回调的 `Hooks` 对象来介入请求生命周期。这可以实现跨所有功能的遥测和对各种事实的可观测性,例如计算格式错误的请求的能力,或在初始化期间记录代理身份。 在创建服务器时使用 `server.WithHooks` 选项添加 `Hooks`。 ### 工具处理程序中间件 使用 `server.WithToolHandlerMiddleware` 选项向工具调用处理程序添加中间件。中间件可以在服务器创建时注册,并应用于每次工具调用。 提供了一个恢复中间件选项,用于从工具调用的 panic 中恢复,可以使用 `server.WithRecovery` 选项添加到服务器。 ### 重新生成服务器代码 服务器钩子和请求处理程序是生成的。通过运行以下命令重新生成它们: ``` go generate ./... ``` 您需要安装 `go` 并确保 `goimports` 工具可用。生成器会自动运行 `goimports` 以格式化代码和修正导入。 ### 自动补全 当用户填写特定提示词(通过名称标识)或资源模板(通过 URI 标识)的参数值时,服务器可以提供上下文建议。 要启用补全支持,请在创建服务器时使用 `server.WithCompletions()` 选项。 #### 补全提供程序 您可以通过实现相应的接口并将它们作为选项传递给服务器,为提示词参数和资源模板参数提供补全逻辑。
显示补全提供程序示例 ``` type MyPromptCompletionProvider struct{} func (p *MyPromptCompletionProvider) CompletePromptArgument( ctx context.Context, promptName string, argument mcp.CompleteArgument, context mcp.CompleteContext, ) (*mcp.Completion, error) { // Example: provide style suggestions for a "code_review" prompt if promptName == "code_review" && argument.Name == "style" { styles := []string{"formal", "casual", "technical", "creative"} var suggestions []string // Filter based on current input for _, style := range styles { if strings.HasPrefix(style, argument.Value) { suggestions = append(suggestions, style) } } return &mcp.Completion{ Values: suggestions, }, nil } // Return empty suggestions for unhandled cases return &mcp.Completion{Values: []string{}}, nil } type MyResourceCompletionProvider struct{} func (p *MyResourceCompletionProvider) CompleteResourceArgument( ctx context.Context, uri string, argument mcp.CompleteArgument, context mcp.CompleteContext, ) (*mcp.Completion, error) { // Example: provide file path completions if uri == "file:///{path}" && argument.Name == "path" { // You can access previously completed arguments from context.Arguments // context.Arguments is a map[string]string of already-resolved arguments paths := getMatchingPaths(argument.Value) // Your custom logic return &mcp.Completion{ Values: paths[:min(len(paths), 100)], // Max 100 items Total: len(paths), // Total available matches HasMore: len(paths) > 100, // More results available }, nil } return &mcp.Completion{Values: []string{}}, nil } // Register the provider mcpServer := server.NewMCPServer( "my-server", "1.0.0", server.WithCompletions(), server.WithPromptCompletionProvider(&MyPromptCompletionProvider{}), server.WithResourceCompletionProvider(&MyResourceCompletionProvider{}), ) ```
#### 补全上下文 对于具有多个参数的提示词或资源模板,`CompleteContext` 参数提供对先前已完成参数的访问。这允许您根据之前的选择提供上下文建议。
显示补全上下文示例 ``` func (p *MyProvider) CompleteResourceArgument( ctx context.Context, uri string, argument mcp.CompleteArgument, context mcp.CompleteContext, ) (*mcp.Completion, error) { // Access previously completed arguments if previousValue, ok := context.Arguments["previous_arg"]; ok { // Provide suggestions based on previous_arg value return getSuggestionsFor(argument.Value, previousValue), nil } return &mcp.Completion{Values: []string{}}, nil } ```
#### 响应约束 返回补全结果时: - 每次响应最多 100 个项目 - 使用 `Total` 指示可用匹配项的总数 - 使用 `HasMore` 表示返回值之外是否还有更多结果
标签:Anthropic, CIS基准, Claude, CVE检测, DLL 劫持, EVTX分析, EVTX分析, Go, Golang, LLM, MCP, Model Context Protocol, RAG, Ruby工具, stdio, Unmanaged PE, 上下文, 中间件, 人工智能, 协议实现, 外部数据源, 大语言模型, 安全编程, 工具, 开发包, 日志审计, 服务器, 检索增强生成, 用户模式Hook绕过, 编程库, 网络调试, 自动化, 集成