29 April 2025

IMG-THUMBNAIL

本次探索stdio方式,使用Cloudinary上传图片的场景搭建MCP工具

概述

本文将基于Go语言开发的MCP(Multi - Cloud Processing)服务器,主要功能是将文件上传到Cloudinary云存储服务。服务器通过MCP协议接收文件路径请求,并将对应文件上传到Cloudinary,最后返回文件的安全访问链接。

实现

本身SSE和Stdio的实现方式区别不大,只需要将transport改成NewStdioServerTransport。上传逻辑使用包github.com/cloudinary/cloudinary-go/v2。详细使用方式参考官方文档

解析Env

由于是命令行调用,参数需要通过环境变量解析获取。

for _, env := range os.Environ() {
    ks := strings.Split(env, "=")
    if len(ks) == 2 {
        k, v := ks[0], ks[1]
        if k == "cloud" {
            cloud = v
        } else if k == "key" {
            key = v
        } else if k == "secret" {
            secret = v
        }
    }
}

返回处理

本次场景使用文本格式返回,还支持图片、音频等。

return &protocol.CallToolResult{
    Content: []protocol.Content{
        protocol.TextContent{
            Type: "text",
            Text: res,
        },
    },
}, nil

部署

环境变量

运行项目前,需要设置以下环境变量:

  • cloud: Cloudinary的云名称。
  • key: Cloudinary的API密钥。
  • secret: Cloudinary的API密钥密码。

密钥从这里获取。

运行步骤

  1. 确保Go环境已正确安装(版本1.23.1及以上)。
  2. 设置所需的环境变量。
  3. 在项目根目录下执行以下命令运行项目:
go install gitee.com/cyeam/cloudinary_mcp@latest
{
  "mcpServers": {
    "image_upload": {
      "type": "stdio",
      "command": "cloudinary",
      "args": [],
      "env": {
        "cloud": "cyeam",
        "key": "key",
        "secret": "password"
      }
    }
  }
}

测试代码

package main

import (
	"context"
	"github.com/ThinkInAIXYZ/go-mcp/pkg"
	"log"

	"github.com/ThinkInAIXYZ/go-mcp/client"
	"github.com/ThinkInAIXYZ/go-mcp/protocol"
	"github.com/ThinkInAIXYZ/go-mcp/transport"
)

func main() {
	transportClient, err := transport.NewStdioClientTransport("cloudinary", nil,
		transport.WithStdioClientOptionLogger(pkg.DebugLogger),
		transport.WithStdioClientOptionEnv("cloud=cyeam", "key=key1", "secret=password"))
	if err != nil {
		log.Fatalf("Failed to create transport client: %v", err)
	}
	// Initialize MCP client
	mcpClient, err := client.NewClient(transportClient)
	if err != nil {
		log.Fatalf("Failed to create MCP client: %v", err)
	}
	defer mcpClient.Close()

	// Get available tools
	ctx := context.Background()
	tools, err := mcpClient.ListTools(ctx)
	if err != nil {
		log.Fatalf("Failed to list tools: %v", err)
	}
	for _, tool := range tools.Tools {
		log.Printf("Tool Name: %+v, Description: %s, Required: %+v", tool.Name, tool.Description, tool.InputSchema.Required)
		if tool.Name == "cloudinary" {
			req := &protocol.CallToolRequest{
				Name: tool.Name,
				Arguments: map[string]interface{}{
					"file_path": "/Users/cyeam/Downloads/abc.jpg",
				},
			}
			resp, err := mcpClient.CallTool(context.Background(), req)
			if err != nil {
				log.Fatalf("Failed to call tool: %v", err)
			} else {
				log.Printf("Tool Response: %+v", resp)
			}
		}
	}
}

原文链接:用Go基于stdio通信搭建本地MCP工具,转载请注明来源!

EOF