当前位置: 首页 > wzjs >正文

做资讯网站盈利织梦网站栏目不能更新

做资讯网站盈利,织梦网站栏目不能更新,钓鱼网站的主要危害,深圳市设计网站公司文章目录 1. 写在最前面2. 动手实现一个 MCP Client2.1 How 天气查询 Client2.1.1 向 Cursor 提问的艺术2.1.2 最终成功展示2.1.3 client 的代码 3. MCP 协议核心之一总结3.1 SSE vs WebSocket 4. 碎碎念5. 参考资料 1. 写在最前面 学习了 MCP Server 的实现后,刚好…

文章目录

    • 1. 写在最前面
    • 2. 动手实现一个 MCP Client
      • 2.1 How 天气查询 Client
        • 2.1.1 向 Cursor 提问的艺术
        • 2.1.2 最终成功展示
        • 2.1.3 client 的代码
    • 3. MCP 协议核心之一总结
      • 3.1 SSE vs WebSocket
    • 4. 碎碎念
    • 5. 参考资料

1. 写在最前面

学习了 MCP Server 的实现后,刚好趁着今天又是提测的间隙,抽点时间学习一下 MCP Client 的实现。

注:千万不能让自己成为,你试一下……,你再试一下的开发……。

2. 动手实现一个 MCP Client

之前的文章中有介绍过如何实现一个 MCP Server。那这个 MCP Client 的就简单的实现为调用之前的天气查询的 MCP Server 吧。

2.1 How 天气查询 Client

考虑到 cursor 没有办法查询非当前工作区的内容,笔者只能采用最原始的方式将 MCP Server 的源码拷贝过来,直接在 MCP Client 的项目中进行使用。

2.1.1 向 Cursor 提问的艺术

经过这阶段的 Cursor 使用下来,笔者最深刻的一个感受就是提问的内容一定要具体,具体成伪代码为最佳。

错误示例:

问:你能帮我实现一个 mcp 的 client 吗?

答:其他省略,请看总结

在这里插入图片描述

注:明显这个解法是没有办法调用之前的天气查询的 MCP Server 的。

正确示例:

问:localhost:8080 地址的 mcp server ,调用 server 代码如下 package main ……

答:

在这里插入图片描述

注:这个回答就很不错了,基本符合笔者最初的构想,但是美中不足的是,还是再修复一次错误。

错误修复过程:

在这里插入图片描述

不得不感叹于 Cursor 强大的能力,三个问题,就实现了对天气查询 MCP Server 的调用。

2.1.2 最终成功展示

以下是 MCP 的 Client 在调用 Server 的效果展示:

在这里插入图片描述

2.1.3 client 的代码

mcp client 实现的代码结构:

-> mcp_client tree
.
├── README.md
├── go.mod
├── go.sum
├── main.go
├── mcp_client
└── pkg└── client└── client.go2 directories, 6 files

client.go 的实现:

package clientimport ("bytes""context""encoding/json""fmt""io""net/http""sync"
)// MCPResponse 定义 MCP 响应格式
type MCPResponse struct {Type    string      `json:"type"`Content interface{} `json:"content"`
}// MCPToolResponse 定义工具响应格式
type MCPToolResponse struct {Name       string      `json:"name"`Parameters interface{} `json:"parameters,omitempty"`Response   interface{} `json:"response,omitempty"`Error      string      `json:"error,omitempty"`
}// Client 代表 MCP 客户端
type Client struct {serverAddr stringhttpClient *http.Clientconnected  boolmu         sync.RWMutex
}// NewClient 创建一个新的 MCP 客户端实例
func NewClient(serverAddr string) *Client {return &Client{serverAddr: serverAddr,httpClient: &http.Client{},}
}// Connect 连接到 MCP 服务器
func (c *Client) Connect(ctx context.Context) error {c.mu.Lock()defer c.mu.Unlock()// 检查健康状态resp, err := c.httpClient.Get(fmt.Sprintf("http://%s/health", c.serverAddr))if err != nil {return fmt.Errorf("服务器连接失败: %v", err)}defer resp.Body.Close()if resp.StatusCode != http.StatusOK {return fmt.Errorf("服务器状态异常: %s", resp.Status)}c.connected = truereturn nil
}// GetWeather 获取指定城市的天气信息
func (c *Client) GetWeather(ctx context.Context, city string) (*MCPToolResponse, error) {payload := map[string]interface{}{"tool": "get_weather","parameters": map[string]string{"city": city,},}jsonData, err := json.Marshal(payload)if err != nil {return nil, fmt.Errorf("序列化请求失败: %v", err)}req, err := http.NewRequestWithContext(ctx, "POST", fmt.Sprintf("http://%s/sse/invoke", c.serverAddr), bytes.NewBuffer(jsonData))if err != nil {return nil, fmt.Errorf("创建请求失败: %v", err)}req.Header.Set("Content-Type", "application/json")resp, err := c.httpClient.Do(req)if err != nil {return nil, fmt.Errorf("发送请求失败: %v", err)}defer resp.Body.Close()body, err := io.ReadAll(resp.Body)if err != nil {return nil, fmt.Errorf("读取响应失败: %v", err)}var response MCPToolResponseif err := json.Unmarshal(body, &response); err != nil {return nil, fmt.Errorf("解析响应失败: %v", err)}return &response, nil
}// Status 获取服务器状态
func (c *Client) Status(ctx context.Context) (string, error) {c.mu.RLock()defer c.mu.RUnlock()if !c.connected {return "未连接", nil}resp, err := c.httpClient.Get(fmt.Sprintf("http://%s/health", c.serverAddr))if err != nil {return "", fmt.Errorf("检查服务器状态失败: %v", err)}defer resp.Body.Close()if resp.StatusCode == http.StatusOK {return fmt.Sprintf("已连接到 %s,服务器状态正常", c.serverAddr), nil}return fmt.Sprintf("已连接到 %s,但服务器状态异常: %s", c.serverAddr, resp.Status), nil
}// Close 关闭客户端连接
func (c *Client) Close() error {c.mu.Lock()defer c.mu.Unlock()c.connected = falsereturn nil
}

main.go 的实现:


package mainimport ("context""fmt""os""os/signal""syscall""example/mcp_client/pkg/client""github.com/spf13/cobra"
)var (serverAddr stringmcpClient  *client.Client
)var rootCmd = &cobra.Command{Use:   "mcp-client",Short: "MCP Client - A command line tool for interacting with MCP server",Long: `MCP Client is a command line tool that allows you to interact with the MCP (Master Control Program) server.
It provides various commands for managing and monitoring your MCP resources.`,PersistentPreRun: func(cmd *cobra.Command, args []string) {mcpClient = client.NewClient(serverAddr)ctx := context.Background()if err := mcpClient.Connect(ctx); err != nil {fmt.Printf("连接服务器失败: %v\n", err)os.Exit(1)}},
}var statusCmd = &cobra.Command{Use:   "status",Short: "Check the status of MCP server",RunE: func(cmd *cobra.Command, args []string) error {status, err := mcpClient.Status(context.Background())if err != nil {return err}fmt.Println(status)return nil},
}var weatherCmd = &cobra.Command{Use:   "weather [city]",Short: "Get weather information for a city",Args:  cobra.MaximumNArgs(1),RunE: func(cmd *cobra.Command, args []string) error {city := "北京" // 默认城市if len(args) > 0 {city = args[0]}response, err := mcpClient.GetWeather(context.Background(), city)if err != nil {return err}if response.Error != "" {return fmt.Errorf("获取天气信息失败: %s", response.Error)}// 格式化输出天气信息fmt.Printf("%s的天气信息:\n", city)fmt.Printf("%+v\n", response.Response)return nil},
}func init() {rootCmd.PersistentFlags().StringVarP(&serverAddr, "server", "s", "localhost:8080", "MCP server address")rootCmd.AddCommand(statusCmd)rootCmd.AddCommand(weatherCmd)
}func main() {// 设置信号处理sigChan := make(chan os.Signal, 1)signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)// 在后台监听信号go func() {<-sigChanfmt.Println("\n正在关闭客户端...")if err := mcpClient.Close(); err != nil {fmt.Printf("关闭客户端时发生错误: %v\n", err)}os.Exit(0)}()if err := rootCmd.Execute(); err != nil {fmt.Println(err)os.Exit(1)}
}

3. MCP 协议核心之一总结

笔者通过动手实现一对极简的 MCP Server 和 MCP Client 发现,SSE(Server-Sent Events)协议应该是 MCP 协议实现的基石之一。

于是,笔者翻阅了 MCP 的官方文档说明,得出 — MCP includes two standard transport implementations:

  • Standard Input/Output (stdio)

  • Server-Sent Events (SSE)

3.1 SSE vs WebSocket

笔者看到 SSE 协议是基于 http 实现的,不仅好奇 SSE 跟 WebSocket 协议的区别:

Curosr 总结的 SSE 和 WebSocket 的对比:

  • 通信方式:

    • SSE:单向通信,服务器向客户端推送数据

    • WebSocket:双向通信,客户端和服务器都可以主动发送数据

  • 协议:

    • SSE:基于 HTTP,使用标准的 HTTP 连接

    • WebSocket:独立的协议,使用 ws:// 或 wss:// 协议前缀

  • 连接特性:

    • SSE:自动重连,浏览器实现了断线重连机制

    • WebSocket:需要手动实现重连逻辑

  • 数据格式:

    • SSE:仅支持文本数据(UTF-8)

    • WebSocket:支持文本和二进制数据

  • 使用场景:

    • SSE:适用于服务器到客户端的实时通知、事件流

    • WebSocket:适用于需要低延迟、高频率双向通信的场景

  • 兼容性:

    • SSE:较好的浏览器兼容性,但IE不支持

    • WebSocket:现代浏览器都支持

4. 碎碎念

做人不能太贪心,就像一口没办法吃成一个胖子,知识也不是一天就能学完的,那就慢慢积累着吧!

  • 不妨大胆点,反正没人能活着离开这个世界。

  • 突然觉得自己真的很好,有点小漂亮,善解人意,懂得换位思考,分享欲比较旺盛,三观正,待人真诚,自愈能力也强。即使自己情绪不好陷入内耗也还是会倾听他人的烦恼开导别人。能在无数次的崩溃中慢慢自愈,能在滥情的世界里始终保持清醒,但别否定和怀疑自己啦,你真的超棒的。

5. 参考资料

  • Transports - Model Context Protocol
http://www.dtcms.com/wzjs/568158.html

相关文章:

  • 监控摄像机网站建设注册公司要求什么条件
  • 网站开发及app开发报价大航母网站建设在哪里
  • 北京模板网站开发西安优化多钱
  • 门户网站建设创新零基础考二建有多难
  • 做外贸的网站平台有哪些内容教学小程序
  • 东莞网站制作很好 乐云践新珠海网站建设公司哪个好
  • wap 网站源码重庆好网互联
  • 网站建设有那些内容凡客有家
  • 优惠券网站怎样做浏览器打不开wordpress
  • 陕西建设注册中心网站页面设计工资有多少
  • acm手表网站上海网站备案号查询
  • flash怎么做电子书下载网站东莞规划局官方网站
  • 南京门户网站制作佛山建设工程交易中心网站
  • 外贸简单网站建设备案用网站建设方案
  • 网站优化课程培训网站建设工程师待遇
  • 一个公司做100个网站网站模板下载器
  • 北京网站建设正邦php网站开发实例视频
  • 佛山建网站的公司企业咨询是什么
  • 成都网站搭建公司网站制作维护
  • ppt做网站网上书城网站建设总结
  • cms下载官方网站python基础教程文档
  • 南京电商网站建设公司私人做的网站怎么挣钱
  • 网站建设hnshangtian购物网站建设的选题意义
  • 小游戏网站开发做电子商务的网站
  • 那个网站做扑克牌便宜网站怎么样排名
  • 做足球经理头像的网站wordpress官方中文版
  • 网站免费响应建设网站已备案添加新域名
  • 丰都网站建设案例大连手机自适应网站建设价格
  • 网站内容搜索福州企业网站
  • 成品网站管理系统百度推广客户端电脑版