
定义完了mcp server,除了给cursor使用,也可以在langchain中作为agent使用,llm通过agent获取想要的信息时候,可以直接调用mcp server获得返回值。如何把mcp server的返回值潜入到langchain流程里呢?需要langchan 的adapter:github.com/i2y/langchaingo-mcp-adapter,由于该模块还不完善,使用过程中的效果并不理想。
首先我们定义一个mcp server
package main
import (
"context"
"errors"
"fmt"
"io"
"log"
"net"
"net/http"
"github.com/mark3labs/mcp-go/mcp"
"github.com/mark3labs/mcp-go/server"
)
func main() {
// Create MCP server
s := server.NewMCPServer(
"ip-mcp",
"1.0.0",
)
// Add tool
tool := mcp.NewTool("ip_query",
mcp.WithDescription("query geo location of an IP address"),
mcp.WithString("ip",
mcp.Required(),
mcp.Description("IP address to query"),
),
)
// Add tool handler
s.AddTool(tool, ipQueryHandler)
// Start the stdio server
if err := server.ServeStdio(s); err != nil {
fmt.Printf("Server error: %v\n", err)
}
}
func ipQueryHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
ip, ok := request.Params.Arguments["ip"].(string)
if !ok {
return nil, errors.New("ip must be a string")
}
parsedIP := net.ParseIP(ip)
if parsedIP == nil {
log.Printf("invalid IP address: %s", ip)
return nil, errors.New("invalid IP address")
}
resp, err := http.Get("https://ip.rpcx.io/api/ip?ip=" + ip)
if err != nil {
log.Printf("Error fetching IP information: %v", err)
return nil, fmt.Errorf("Error fetching IP information: %v", err)
}
defer resp.Body.Close()
data, err := io.ReadAll(resp.Body)
if err != nil {
log.Printf("Error reading response body: %v", err)
return nil, fmt.Errorf("Error reading response body: %v", err)
}
return mcp.NewToolResultText(string(data)), nil
}然后使用adapter,首先初始化mcp client,指定mcp server的路径,然后把client作为参数来初始化adpter,在adapter内部实现 client 参数的组装。最后通过Tools方法,从adpter中获得tool,得到tool后我们就可以通过tool初始化agent,把它嵌入到langchain流程中。
package main
import (
"context"
"log"
"github.com/mark3labs/mcp-go/client"
"github.com/tmc/langchaingo/agents"
"github.com/tmc/langchaingo/chains"
"github.com/tmc/langchaingo/llms/openai"
langchaingo_mcp_adapter "github.com/i2y/langchaingo-mcp-adapter"
)
func main() {
// Create an MCP client using stdio
mcpClient, err := client.NewStdioMCPClient(
// Path to an MCP server
"./ip-mcp",
nil, // Additional environment variables if needed
)
if err != nil {
log.Fatalf("Failed to create MCP client: %v", err)
}
defer mcpClient.Close()
// Create the adapter
adapter, err := langchaingo_mcp_adapter.New(mcpClient)
if err != nil {
log.Fatalf("Failed to create adapter: %v", err)
}
// Get all tools from MCP server
mcpTools, err := adapter.Tools()
if err != nil {
log.Fatalf("Failed to get tools: %v", err)
}
ctx := context.Background()
llm, err := openai.New(
openai.WithBaseURL("http://127.0.0.1:11434/v1/"),
openai.WithToken("ollama"),
openai.WithModel("deepseek-r1:1.5b"),
)
if err != nil {
log.Fatalf("Create AI client: %v", err)
}
// Create a agent with the tools
agent := agents.NewOneShotAgent(
llm,
mcpTools,
agents.WithMaxIterations(3),
)
executor := agents.NewExecutor(agent)
// Use the agent
question := "Can you help me query geo location of an IP address ip: 8.8.8.8 ?"
result, err := chains.Run(
ctx,
executor,
question,
)
if err != nil {
log.Fatalf("Agent execution error: %v", err)
}
log.Printf("Agent result: %s", result)
}使用结果如下
% go run ./langchain/go/exp17/main.go
2025/04/12 13:32:43 Agent execution error: unmarshal input: invalid character 'O' after top-level value我们发现adapter实现并不好,在提取参数的时候,提取到的是
{"ip": "8.8.8.8"}Observation::而不是
{"ip": "8.8.8.8"}导致json解析失败,最后调用mcp server失败。
本文分享自 golang算法架构leetcode技术php 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!