背景
随着 AI 领域中 USB 协议 —— MCP 协议的火爆,越来越多的人希望体验这一协议,但往往由于需要本地部署而止步。我们可通过集成 MCP 服务,在 API 调用中实现“开罐即用”,免去本地部署的繁琐步骤。接下来,将详细说明如何实现该集成。
API 调用示例
在标准的 OpenAI API 调用方式基础上,新增最外层的 mcps 字段(标准接口会忽略无效字段,仅在我们的服务中生效),每个 MCP 协议工具对应一个 name 字段,该字段必须与 MCP SERVER 中对应工具的 Name 保持一致。
示例 1:使用时间工具
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| curl --location 'http://localhost:8094/api/v1/chat-with-mcp' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer sk-xxxx' \ --data '{ "model": "deepseek-v3-tool", "stream": true, "messages": [ { "role": "user", "content": "东京时间几点了" } ], "max_tokens": 2048, "temperature": 1, "mcps": [ { "name": "time" } ] }'
|
调用后,通过时间工具获取当前东京时间,返回结果示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| { "id": "chatcmpl-68d11dee3f3a25431297ea9b8b715002", "object": "chat.completion", "created": 1744182433, "model": "deepseek-v3-tool", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "当前东京时间是 2025年4月9日 16:07(日本标准时间)。" }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 0, "completion_tokens": 0, "total_tokens": 0 } }
|
MCP 协议的工具说明
MCP 协议本质上是对某个专项服务的 tools 包装,使之具备通用性和灵活性。下面分别介绍两种常见场景所提供的 tools 列表。
获取时间工具
QINIU 云存储工具
ListBuckets
返回当前认证用户拥有的所有 bucket 列表。使用此操作需要具有 s3:ListAllMyBuckets 权限。
ListObjectsV2
每次请求返回 bucket 中部分或全部(最多 100 个)对象。可通过设置参数选择性返回。如果需要继续列出对象,请设置 start_after 为上一次返回结果中最后一个文件的 key。
GetObject
用于从 Amazon S3 检索对象。需要在请求中指定对象的完整 key 名称。支持通用和目录 bucket 的虚拟托管请求。注意:目录 bucket 只支持虚拟托管方式,并需通过 Zonal endpoint 发出请求。
集成 MCP 协议示例
我们采用了 MCP-GO 与 Eino 两个开源项目来实现 MCP 服务集成。下面给出具体实现过程。
1. 启动 MCP 服务
假设已经通过如下命令启动 MCP 服务(该命令也适用于其它服务如 npm、uv 等):
1
| docker run -it --rm mcp/time
|
2. 创建 MCP 客户端
通过以下代码启动 MCP 服务客户端:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import ( "context" mcpeino "github.com/cloudwego/eino-ext/components/tool/mcp" client "github.com/mark3labs/mcp-go/client" )
func McpClient(ctx context.Context, command string, envs []string, args ...string) (client.MCPClient, error) { cli, err := client.NewStdioMCPClient(command, envs, args...) if err != nil { return nil, fmt.Errorf("failed to create client: %v", err) } _, err = cli.Initialize(ctx, mcp.InitializeRequest{}) if err != nil { return nil, fmt.Errorf("failed to initialize client: %v", err) } return cli, nil }
|
通过如下调用启动 MCP 服务:
1 2 3 4 5 6
| cli, err := McpClient( ctx, mcpConfig.Command, mcp.Env, mcpConfig.Args..., )
|
使用以下代码获取服务中注册的 tools:
1
| tools, err := mcpeino.GetTools(ctx, &mcpeino.Config{Cli: cli})
|
4. 集成 Agent 实现 API 调用
通过 Eino 平台,实现与 MCP 服务的对接,示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| package xxx
import ( "chat/globals" "context" "errors" "io"
"github.com/cloudwego/eino-ext/components/model/openai" "github.com/cloudwego/eino/flow/agent/react" "github.com/cloudwego/eino/schema" )
func createAgentRequest(props *adaptercommon.AgentProps) error { ctx := context.Background() endpoint := "xxxx" config := &openai.ChatModelConfig{ Model: props.Model, APIKey: conf.GetRandomSecret(), BaseURL: endpoint, } llm, err := openai.NewChatModel(ctx, config) if err != nil { return err } agent, err := react.NewAgent(ctx, &react.AgentConfig{ Model: llm, ToolsConfig: props.EinoTools, }) if err != nil { return err }
message, err := getMessage(props) if err != nil { return err } stream, err := agent.Stream(ctx, message) if err != nil { return err } defer stream.Close()
for { response, err := stream.Recv() if errors.Is(err, io.EOF) { break } fmt.Println(response.Content) }
return nil }
func getMessage(props *adaptercommon.AgentProps) ([]*schema.Message, error) { var message []*schema.Message for _, msg := range props.Message { message = append(message, &schema.Message{ Role: schema.RoleType(msg.Role), Content: msg.Content, }) } return message, nil }
|
通过以上步骤,即可实现 MCP 服务的云端集成,从而避免本地部署带来的复杂性。