
本文继续上一篇介绍mcp client。首先还是实现一个mcp server,作为实验用。
package main
import (
"context"
"errors"
"fmt"
"os"
"github.com/mark3labs/mcp-go/mcp"
"github.com/mark3labs/mcp-go/server"
)
func main() {
s := server.NewMCPServer(
"Server Demo",
"1.0.0",
)
// 添加工具
{
calculatorTool := mcp.NewTool("calculate",
mcp.WithDescription("执行基本的算术运算"),
mcp.WithString("operation",
mcp.Required(),
mcp.Description("要执行的算术运算类型"),
mcp.Enum("add", "subtract", "multiply", "divide"), // 保持英文
),
mcp.WithNumber("x",
mcp.Required(),
mcp.Description("第一个数字"),
),
mcp.WithNumber("y",
mcp.Required(),
mcp.Description("第二个数字"),
),
)
s.AddTool(calculatorTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
op := request.Params.Arguments["operation"].(string)
x := request.Params.Arguments["x"].(float64)
y := request.Params.Arguments["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 nil, errors.New("不允许除以零")
}
result = x / y
}
return mcp.FormatNumberResult(result), nil
})
}
// 添加资源
{
// 静态资源示例 - 暴露一个 README 文件
resource := mcp.NewResource(
"docs://readme",
"项目说明文档",
mcp.WithResourceDescription("项目的 README 文件"),
mcp.WithMIMEType("text/markdown"),
)
// 添加资源及其处理函数
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
})
}
// 添加提示词
{
// 简单问候提示
s.AddPrompt(mcp.NewPrompt("greeting",
mcp.WithPromptDescription("一个友好的问候提示"),
mcp.WithArgument("name",
mcp.ArgumentDescription("要问候的人的名字"),
),
), func(ctx context.Context, request mcp.GetPromptRequest) (*mcp.GetPromptResult, error) {
name := request.Params.Arguments["name"]
if name == "" {
name = "朋友"
}
return mcp.NewGetPromptResult(
"友好的问候",
[]mcp.PromptMessage{
mcp.NewPromptMessage(
mcp.RoleAssistant,
mcp.NewTextContent(fmt.Sprintf("你好,%s!今天有什么可以帮您的吗?", name)),
),
},
), nil
})
}
// 启动基于 stdio 传输类型的服务
if err := server.ServeStdio(s); err != nil {
fmt.Printf("Server error: %v\n", err)
}
}go build -o server ./main.go然后,用golang实现一个mcp client
package main
import (
"context"
"fmt"
"time"
"github.com/mark3labs/mcp-go/client"
"github.com/mark3labs/mcp-go/mcp"
)
func main() {
// 创建一个基于 stdio 的MCP客户端
mcpClient, err := client.NewStdioMCPClient(
"./server",
[]string{},
)
if err != nil {
panic(err)
}
defer mcpClient.Close()
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
fmt.Println("初始化 mcp 客户端...")
initRequest := mcp.InitializeRequest{}
initRequest.Params.ProtocolVersion = mcp.LATEST_PROTOCOL_VERSION
initRequest.Params.ClientInfo = mcp.Implementation{
Name: "Client Demo",
Version: "1.0.0",
}
// 初始化MCP客户端并连接到服务器
initResult, err := mcpClient.Initialize(ctx, initRequest)
if err != nil {
panic(err)
}
fmt.Printf(
"\n初始化成功,服务器信息: %s %s\n\n",
initResult.ServerInfo.Name,
initResult.ServerInfo.Version,
)
// 从服务器获取提示词列表
fmt.Println("提示词列表:")
promptsRequest := mcp.ListPromptsRequest{}
prompts, err := mcpClient.ListPrompts(ctx, promptsRequest)
if err != nil {
panic(err)
}
for _, prompt := range prompts.Prompts {
fmt.Printf("- %s: %s\n", prompt.Name, prompt.Description)
fmt.Println("参数:", prompt.Arguments)
}
// 从服务器获取资源列表
fmt.Println()
fmt.Println("资源列表:")
resourcesRequest := mcp.ListResourcesRequest{}
resources, err := mcpClient.ListResources(ctx, resourcesRequest)
if err != nil {
panic(err)
}
for _, resource := range resources.Resources {
fmt.Printf("- uri: %s, name: %s, description: %s, MIME类型: %s\n", resource.URI, resource.Name, resource.Description, resource.MIMEType)
}
// 从服务器获取工具列表
fmt.Println()
fmt.Println("可用工具列表:")
toolsRequest := mcp.ListToolsRequest{}
tools, err := mcpClient.ListTools(ctx, toolsRequest)
if err != nil {
panic(err)
}
for _, tool := range tools.Tools {
fmt.Printf("- %s: %s\n", tool.Name, tool.Description)
fmt.Println("参数:", tool.InputSchema.Properties)
}
fmt.Println()
// 调用工具
fmt.Println("调用工具: calculate")
toolRequest := mcp.CallToolRequest{
Request: mcp.Request{
Method: "tools/call",
},
}
toolRequest.Params.Name = "calculate"
toolRequest.Params.Arguments = map[string]any{
"operation": "add",
"x": 1,
"y": 1,
}
// Call the tool
result, err := mcpClient.CallTool(ctx, toolRequest)
if err != nil {
panic(err)
}
fmt.Println("调用工具结果:", result.Content[0].(mcp.TextContent).Text)
}首先NewStdioMCPClient,它的参数传入刚刚我们实现的server的路径,拼接好client的参数,也就是组装我们上一篇介绍的grpcjson后,初始化客户端,initResult, err := mcpClient.Initialize(ctx, initRequest),然后我们就可以通过函数来获取资源、提示词和工具列表
mcpClient.ListPrompts(ctx, promptsRequest)mcpClient.ListResources(ctx, resourcesRequest) mcpClient.ListTools(ctx, toolsRequest)最后组装参数调用我们的工具
toolRequest := mcp.CallToolRequest{
Request: mcp.Request{
Method: "tools/call",
},
}
toolRequest.Params.Name = "calculate"
toolRequest.Params.Arguments = map[string]any{
"operation": "add",
"x": 1,
"y": 1,
}
// Call the tool
result, err := mcpClient.CallTool(ctx, toolRequest)
if err != nil {
panic(err)
}测试下效果
go run ./main.go
[{human [What is 1 + 1?]} {ai [<think>
I need to determine the sum of 1 and 1.
First, I'll identify the two numbers involved in the addition: 1 and 1.
Next, I'll perform the addition by combining these two numbers.
Finally, I'll state that the result of adding 1 and 1 is 2.
</think>
**Solution:**
To find the sum of \(1 + 1\), follow these simple steps:
1. **Identify the numbers to add:**
The numbers are \(1\) and \(1\).
2. **Perform the addition:**
\[
1 + 1 = 2
\]
3. **State the final answer:**
\[
\boxed{2}
\]]}]至此一个完整的client使用例子介绍完毕。
本文分享自 golang算法架构leetcode技术php 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!