mcp用作AI工具上

为什么要用AI工具呢?

突破传统工具的局限性

1.语义理解能力​

传统SQL:无法解析"帮我找上周投诉过且消费超过5000的VIP客户"

AI方案:LLM模型解析自然语言后生成SQL查询,准确率可达92%

2.​模糊匹配升级​

传统LIKE查询处理"红色连衣裙"需要人工设置同义词表

结合CLIP模型:可同时用文字搜索图片,支持跨模态检索

在MCP出现之前,AI工具调用也面临两大痛点:

第一是接口碎片化:每个接口使用不同的指令格式,每个工具API也有独特的数据结构,开发者需要为每个组合编写定制化连接代码;

第二是开发低效:这种"一对一翻译"模式成本高昂且难以扩展

接口和大模型的结合,也解决了单纯大模型带来的

  1. 无法直接访问实时数据(如监控数据等)

  2. 无法执行外部操作(如发送邮件、控制设备等)

  3. 无法访问用户的本地文件或其他私有数据

MCP则采用了一种通用语言格式(JSON - RPC),一次学习就能与所有支持这种协议的工具进行交流。一个通用翻译器,不管什么LLM,用上它就能使用工具 / 数据了

MCP的主要目的在于解决当前 AI 模型因数据孤岛限制而无法充分发挥潜力的难题,MCP 使得 AI 应用能够安全地访问和操作本地及远程数据,为 AI 应用提供了连接万物的接口

MCP 采用客户端-服务器架构,主要包含以下几个组件:

  • MCP 主机(Host):如 Claude Desktop、IDE 或其他 AI 工具,通过 MCP 访问数据

  • MCP 客户端(Client):与服务器保持 1:1 连接的协议客户端

  • MCP 服务器(Server):轻量级程序,通过标准化的 MCP 协议公开特定功能

  • 本地数据源(Local Data Source):计算机上的文件、数据库和服务,MCP 服务器可以安全访问这些内容

  • 远程服务(Remote Service):通过互联网可用的外部系统(例如通过 API),MCP 服务器可以连接这些服务

流程示例:

MCP client 充当 LLM 和 MCP server 之间的桥梁,MCP client 的工作流程如下:

  • MCP client 首先从 MCP server 获取可用的工具列表。

  • MCP client 将用户的查询连同工具描述通过 function calling 一起发送给 LLM。

  • LLM 决定是否需要使用工具以及使用哪些工具,返回到 MCP client。

  • 如果需要使用工具,MCP client 会通过 MCP server 执行相应的工具调用。

  • 工具调用的结果会被发送回 MCP client。

  • MCP client 发送到 LLM 进行加工处理。

  • LLM 基于所有信息生成自然语言响应。

  • 最后将响应返回展示给用户。

分层设计

  • 抽象接口层

  • 业务实现层

  • 公共组件层

// ================== 框架核心层 ==================
// tool_def.go - 工具定义抽象层
package toolkit

import (
	"context"
	mcp "your_mcp_package"
)

// 工具元数据
type ToolMeta struct {
	Name        string
	Description string
	Parameters  []ParameterConfig
}

// 参数配置
type ParameterConfig struct {
	Name         string
	Type         ParameterType
	Required     bool
	DefaultValue interface{}
	Title        string
	Description  string
}

type ParameterType int

const (
	TypeString ParameterType = iota
	TypeInt
	TypeBool
	TypeFloat
)

// 工具接口
type Tool interface {
	Meta() ToolMeta
	Handler(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error)
}

// 注册器
type ToolRegistry struct {
	tools []Tool
}

func NewToolRegistry() *ToolRegistry {
	return &ToolRegistry{
		tools: make([]Tool, 0),
	}
}

// 注册工具到MCP服务器
func (r *ToolRegistry) RegisterTo(server *server.MCPServer) {
	for _, tool := range r.tools {
		server.AddTool(r.createMcpTool(tool), r.createHandlerWrapper(tool))
	}
}

// 创建MCP工具实例
func (r *ToolRegistry) createMcpTool(t Tool) mcp.Tool {
	meta := t.Meta()
	baseTool := mcp.NewTool(
		meta.Name,
		mcp.WithDescription(meta.Description),
	)

	for _, param := range meta.Parameters {
		switch param.Type {
		case TypeString:
			baseTool = r.addStringParam(baseTool, param)
		case TypeInt:
			baseTool = r.addIntParam(baseTool, param)
		// 其他类型扩展...
		}
	}
	return baseTool
}

// 包装处理器(添加统一错误处理、日志等)
func (r *ToolRegistry) createHandlerWrapper(t Tool) mcp.ToolHandler {
	return func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
		// 统一前置处理(日志、参数校验等)
		log.Printf("Tool [%s] called with params: %v", t.Meta().Name, req.Params)

		// 执行实际处理
		res, err := t.Handler(ctx, req)
		
		// 统一后置处理
		if err != nil {
			log.Printf("Tool [%s] failed: %v", t.Meta().Name, err)
			return mcp.NewToolResultText("系统错误,请稍后重试"), nil
		}
		return res, nil
	}
}

// ================== 业务实现层 ==================
// mempool_tool.go - 具体工具实现
type MempoolTool struct{}

func NewMempoolTool() Tool {
	return &MempoolTool{}
}

func (t *MempoolTool) Meta() ToolMeta {
	return ToolMeta{
		Name:        "mempool",
		Description: "查询指定设备的mempool信息",
		Parameters: []ParameterConfig{
			{
				Name:         "hostip",
				Type:         TypeString,
				Required:     true,
				DefaultValue: "10.148.224.131",
				Title:        "设备IP",
				Description:  "需要查询配置的设备IP,必须提供",
			},
			{
				Name:         "slab",
				Type:         TypeString,
				Required:     true,
				DefaultValue: "lb_svc",
				Title:        "mempool",
				Description:  "需要查询的mempool名称,默认为lb_svc",
			},
		},
	}
}

func (t *MempoolTool) Handler(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
	params := ParseParams(req, t.Meta())
	
	res, err := GetHostMempool(
		params.GetString("hostip", ""),
		params.GetString("slab", ""),
	)
	
	if err != nil {
		return nil, fmt.Errorf("获取mempool失败: %w", err)
	}
	
	return mcp.NewToolResultText(fmt.Sprintf(`
Mempool 状态报告:
设备IP: %s
SLAB名称: %s
当前使用率: %.2f%%
`, params.GetString("hostip", ""), params.GetString("slab", ""), res)), nil
}

// ================== 公共组件层 ==================
// param_parser.go - 参数解析器
type ToolParams struct {
	values map[string]interface{}
}

func ParseParams(req mcp.CallToolRequest, meta ToolMeta) *ToolParams {
	params := make(map[string]interface{})
	
	for _, pConfig := range meta.Parameters {
		switch pConfig.Type {
		case TypeString:
			params[pConfig.Name] = getString(req, pConfig.Name, pConfig.DefaultValue.(string))
		case TypeInt:
			params[pConfig.Name] = getInt(req, pConfig.Name, pConfig.DefaultValue.(int))
		}
	}
	
	return &ToolParams{values: params}
}

func (p *ToolParams) GetString(key, def string) string {
	if v, ok := p.values[key].(string); ok {
		return v
	}
	return def
}

// ================== 主程序集成 ==================
func main() {
	// 初始化注册器
	registry := toolkit.NewToolRegistry()
	
	// 注册各种工具(通过配置或自动发现)
	registry.Register(
		NewMempoolTool(),
		NewDeviceInfoTool(),
		NewInterfaceTool(),
		// 新增工具只需在此添加...
	)
	
	// 创建MCP服务器
	s := server.NewMCPServer(...)
	
	// 统一注册所有工具
	registry.RegisterTo(s)
	
	// 启动服务器...
}

扩展流程

开发者->>+框架核心: 实现Tool接口
框架核心->>+业务实现: 定义Meta()
业务实现->>+框架核心: 配置参数
框架核心->>+MCP服务器: 自动生成适配器
MCP服务器-->>-主程序: 完成注册

// cpu_tool.go
type CPUMonitorTool struct{}

func NewCPUMonitorTool() Tool {
	return &CPUMonitorTool{}
}

func (t *CPUMonitorTool) Meta() ToolMeta {
	return ToolMeta{
		Name:        "cpu_monitor",
		Description: "获取CPU使用情况",
		Parameters: []ParameterConfig{
			{
				Name:        "interval",
				Type:        TypeInt,
				Default:     60,
				Description: "监控间隔(秒)",
			},
			{
				Name:     "threshold",
				Type:     TypeFloat,
				Required: true,
			},
		},
	}
}

func (t *CPUMonitorTool) Handler(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
	params := ParseParams(req, t.Meta())
	
	data, err := GetCPUUsage(
		params.GetInt("interval", 60),
		params.GetFloat("threshold", 80.0),
	)
	
	return mcp.NewToolResultChart(data), nil
}

核心优势

  • 标准化开发​:所有工具遵循统一接口

  • 参数管理​:通过配置式声明参数,自动生成校验逻辑

  • 扩展性​:新增工具只需实现接口,无需修改框架代码

  • 统一管控​:错误处理、日志、参数解析等公共逻辑集中管理

并发处理

mcp server使用自带sse协议流式通信,原生自带强大的并发能力

在go语言中,每一次请求都会创建一个独立的goroutine去支持并发响应

返回cos链接​时,如有多个会自动汇总到一个cos中,返回汇总链接

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐