云计算百科
云计算领域专业知识百科平台

用 Go 实现一个 Model Context Protocol(MCP) 服务器

最近我在看 Istio 的代码,顺带了解了一下 MCP(Model Context Protocol)协议,发现虽然这个协议现在不再是主流(Istio 已逐步转向 xDS 协议),但作为服务配置下发的一种协议形式,还是挺有意思的,我这边结合学习过程,写一篇自己的实践记录。

🤔 什么是 MCP?

MCP,全称是 Model Context Protocol,是一种 用于配置分发的 gRPC 协议,最初被 Istio 引入,用于把配置从 control plane 推送到 data plane。

简单来说,它让你可以通过 gRPC 发送一大堆“配置资源”(例如服务发现、路由规则、安全策略等)给一个客户端。客户端接收之后就可以更新本地的服务网格配置。

虽然 MCP 后来被 xDS 替代,但了解它仍有价值,毕竟设计思想是类似的。


🔧 搭建一个最小可运行的 MCP Server

首先我们要定义的是:MCP 本质上是基于 protobuf 和 gRPC 的协议,所以我们要准备以下几个部分:

  • Protobuf 定义文件(.proto)
  • 生成对应的 Go 文件(用 protoc + Go 插件)
  • 实现服务端逻辑
  • 启动 gRPC 服务监听客户端连接

  • 📦 Protobuf 定义(简化版)

    下面是一个最精简的 .proto 定义,保留核心结构:

    syntax = "proto3";

    package mcp;

    service AggregatedResourcesService {
    rpc StreamAggregatedResources(stream AggregatedResourcesRequest) returns (stream AggregatedResourcesResponse);
    }

    message AggregatedResourcesRequest {
    string node_id = 1;
    string type_url = 2;
    }

    message AggregatedResourcesResponse {
    string type_url = 1;
    bytes resource = 2;
    }

    这个定义里我们关注的是:

    • StreamAggregatedResources 是核心 RPC 方法,支持双向流。
    • 客户端会发出请求(比如我想要某种类型的配置)
    • 服务器响应对应的资源内容。

    ⚙️ 生成 Go 代码

    你需要安装如下插件:

    go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
    go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

    然后生成代码:

    protoc –go_out=. –go-grpc_out=. mcp.proto

    生成之后,会得到一组 .pb.go 文件,可以直接 import 使用。


    🚀 实现 MCP Server

    package main

    import (
    "log"
    "net"

    "google.golang.org/grpc"
    pb "your_project_path/mcp"
    )

    type server struct {
    pb.UnimplementedAggregatedResourcesServiceServer
    }

    func (s *server) StreamAggregatedResources(stream pb.AggregatedResourcesService_StreamAggregatedResourcesServer) error {
    for {
    req, err := stream.Recv()
    if err != nil {
    log.Printf("Error receiving request: %v", err)
    return err
    }
    log.Printf("Received request for type_url: %s from node: %s", req.TypeUrl, req.NodeId)

    // 模拟返回一个响应
    resp := &pb.AggregatedResourcesResponse{
    TypeUrl: req.TypeUrl,
    Resource: []byte(`{"config":"example"}`),
    }
    if err := stream.Send(resp); err != nil {
    log.Printf("Error sending response: %v", err)
    return err
    }
    }
    }


    🧪 启动 gRPC 服务

    func main() {
    lis, err := net.Listen("tcp", ":50051")
    if err != nil {
    log.Fatalf("Failed to listen: %v", err)
    }
    grpcServer := grpc.NewServer()
    pb.RegisterAggregatedResourcesServiceServer(grpcServer, &server{})
    log.Println("MCP server listening on port 50051…")
    if err := grpcServer.Serve(lis); err != nil {
    log.Fatalf("Failed to serve: %v", err)
    }
    }

    运行:

    go run main.go


    🎯 客户端

    conn, _ := grpc.Dial("localhost:50051", grpc.WithInsecure())
    client := pb.NewAggregatedResourcesServiceClient(conn)
    stream, _ := client.StreamAggregatedResources(context.Background())
    stream.Send(&pb.AggregatedResourcesRequest{
    NodeId: "test-node",
    TypeUrl: "type.googleapis.com/example.Config",
    })
    resp, _ := stream.Recv()
    fmt.Println("Received:", string(resp.Resource))


    📌 总结

    通过上面这些步骤,我们就实现了一个最小可用的 MCP Server:

    • 🧱 基于 Protobuf + gRPC 协议
    • 📦 提供了资源类型的请求和响应
    • 🚀 可以扩展为配置中心、服务网格控制组件等

    虽然 MCP 现在不再是主流(Istio 改用 xDS 了),但这个练手项目依然适合用来学习 gRPC 流式传输、协议设计、配置推送等内容。


    🔍 延伸思考

    • 如果你熟悉 Envoy 或 Istio,可以对比一下 MCP 和 xDS 协议的设计差异。
    • MCP 中也有资源版本、Nonce 等机制来支持一致性和确认机制,这里我们为了简洁省略了。
    • 想进一步练习的朋友可以试试加个客户端 + 资源监听逻辑 + 资源更新推送。

    📎 参考链接:

    • https://github.com/istio/api/tree/master/mcp

    🧑‍💻 本文由 @你的名字 撰写,更多 Go 网络协议实现和服务端框架开发内容,欢迎关注!

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 用 Go 实现一个 Model Context Protocol(MCP) 服务器
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!