使用说明
Go MCP框架
用于构建模型上下文协议(MCP)服务器的Go框架,使大型语言模型(LLM)能够安全地访问工具和数据源。
安装
go get github.com/gomcpgo/mcp
快速开始
下面是一个创建MCP服务器的最小示例:
package main
import (
"context"
"log"
"github.com/gomcpgo/mcp/pkg/handler"
"github.com/gomcpgo/mcp/pkg/server"
"github.com/gomcpgo/mcp/pkg/protocol"
)
func main() {
// Create handler registry
registry := handler.NewHandlerRegistry()
// Register your tool handler
registry.RegisterToolHandler(&MyToolHandler{})
// Create and start server
srv := server.New(server.Options{
Name: "my-server",
Version: "1.0.0",
Registry: registry,
})
if err := srv.Run(); err != nil {
log.Fatal(err)
}
}
// MyToolHandler implements the ToolHandler interface
type MyToolHandler struct{}
func (h *MyToolHandler) ListTools(ctx context.Context) (*protocol.ListToolsResponse, error) {
return &protocol.ListToolsResponse{
Tools: []protocol.Tool{
{
Name: "my-tool",
Description: "Description of my tool",
InputSchema: json.RawMessage(`{
"type": "object",
"properties": {
"param1": {
"type": "string",
"description": "Description of param1"
}
},
"required": ["param1"]
}`),
},
},
}, nil
}
func (h *MyToolHandler) CallTool(ctx context.Context, req *protocol.CallToolRequest) (*protocol.CallToolResponse, error) {
// Handle tool execution
result := "Tool execution result"
return &protocol.CallToolResponse{
Content: []protocol.ToolContent{
{
Type: "text",
Text: result,
},
},
}, nil
}
处理程序类型
该框架支持三种类型的处理程序:
1.工具处理器
为了实现LLM可以执行的工具:
type ToolHandler interface {
ListTools(ctx context.Context) (*ListToolsResponse, error)
CallTool(ctx context.Context, req *CallToolRequest) (*CallToolResponse, error)
}
2.资源处理程序
为了公开LLM可以读取的数据:
type ResourceHandler interface {
ListResources(ctx context.Context) (*ListResourcesResponse, error)
ReadResource(ctx context.Context, req *ReadResourceRequest) (*ReadResourceResponse, error)
}
3.提示处理程序
要提供提示模板:
type PromptHandler interface {
ListPrompts(ctx context.Context) (*ListPromptsResponse, error)
GetPrompt(ctx context.Context, req *GetPromptRequest) (*GetPromptResponse, error)
}
完整示例
下面是一个更完整的示例,显示了所有处理程序类型:
package main
import (
"context"
"encoding/json"
"log"
"github.com/gomcpgo/mcp/pkg/handler"
"github.com/gomcpgo/mcp/pkg/server"
"github.com/gomcpgo/mcp/pkg/protocol"
)
type MyServer struct {
handler.ToolHandler
handler.ResourceHandler
handler.PromptHandler
}
func (s *MyServer) ListTools(ctx context.Context) (*protocol.ListToolsResponse, error) {
return &protocol.ListToolsResponse{
Tools: []protocol.Tool{
{
Name: "my-tool",
Description: "Description of my tool",
InputSchema: json.RawMessage(`{
"type": "object",
"properties": {
"param1": {"type": "string"}
}
}`),
},
},
}, nil
}
func (s *MyServer) CallTool(ctx context.Context, req *protocol.CallToolRequest) (*protocol.CallToolResponse, error) {
return &protocol.CallToolResponse{
Content: []protocol.ToolContent{
{
Type: "text",
Text: "Tool result",
},
},
}, nil
}
func (s *MyServer) ListResources(ctx context.Context) (*protocol.ListResourcesResponse, error) {
return &protocol.ListResourcesResponse{
Resources: []protocol.Resource{
{
URI: "file:///example.txt",
Name: "Example File",
Description: "An example resource",
MimeType: "text/plain",
},
},
}, nil
}
func (s *MyServer) ReadResource(ctx context.Context, req *protocol.ReadResourceRequest) (*protocol.ReadResourceResponse, error) {
return &protocol.ReadResourceResponse{
Contents: []protocol.ResourceContent{
{
URI: req.URI,
Text: "Resource content",
MimeType: "text/plain",
},
},
}, nil
}
func (s *MyServer) ListPrompts(ctx context.Context) (*protocol.ListPromptsResponse, error) {
return &protocol.ListPromptsResponse{
Prompts: []protocol.Prompt{
{
Name: "my-prompt",
Description: "A prompt template",
Arguments: []protocol.PromptArgument{
{
Name: "arg1",
Description: "First argument",
Required: true,
},
},
},
},
}, nil
}
func (s *MyServer) GetPrompt(ctx context.Context, req *protocol.GetPromptRequest) (*protocol.GetPromptResponse, error) {
return &protocol.GetPromptResponse{
Messages: []protocol.Message{
{
Role: "user",
Content: protocol.MessageContent{
Type: "text",
Text: "Prompt content",
},
},
},
}, nil
}
func main() {
myServer := &MyServer{}
registry := handler.NewHandlerRegistry()
registry.RegisterToolHandler(myServer)
registry.RegisterResourceHandler(myServer)
registry.RegisterPromptHandler(myServer)
srv := server.New(server.Options{
Name: "complete-server",
Version: "1.0.0",
Registry: registry,
})
if err := srv.Run(); err != nil {
log.Fatal(err)
}
}
与Claude Desktop一起使用
要将MCP服务器与Claude Desktop一起使用,请将其添加到 claude_desktop_config.json:
{
"mcpServers": {
"my-server": {
"command": "path/to/your/server",
"args": ["arg1", "arg2"]
}
}
}
配置文件的位置:
- MacOS:
~/Library/Application Support/Claude/claude_desktop_config.json - 窗户:
%APPDATA%\Claude\claude_desktop_config.json
测试
该框架包括用于测试MCP服务器的实用程序。这里有一个例子:
func TestMyServer(t *testing.T) {
myServer := &MyServer{}
registry := handler.NewHandlerRegistry()
registry.RegisterToolHandler(myServer)
// Test tool listing
tools, err := myServer.ListTools(context.Background())
if err != nil {
t.Fatalf("ListTools failed: %v", err)
}
// Test tool execution
resp, err := myServer.CallTool(context.Background(), &protocol.CallToolRequest{
Name: "my-tool",
Arguments: map[string]interface{}{
"param1": "test",
},
})
if err != nil {
t.Fatalf("CallTool failed: %v", err)
}
}
最佳实践
-
错误处理
- 使用适当的错误类型
- 提供有意义的错误消息
- 处理所有错误情况
-
配置
- 对敏感数据使用环境变量
- 使文件路径可配置
- 验证所有配置
-
安全
- 验证所有输入
- 限制文件系统访问
- 使用适当的权限
-
测试
- 编写单元测试
- 测试边缘案例
- 使用提供的测试工具