Token导航 LogoToken导航TokenDH.com
MCP Client Manager Go logo
AI代理未说明官方级别未说明来源级核验

MCP Client Manager Go

MCP Server

一个轻量级的MCP客户端管理工具,用于管理多个MCP传输、分发事件并提供工具调用、提示和资源访问的便捷接口。

工具数

0

提示词数

0

GitHub Stars

3

资源数

0
轻量级GoAI代理

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

VikashLoomba

提供方

VikashLoomba

最后核验

2026/5/17 20:20

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

详细介绍

MCP客户经理(Go)

mcpmgr 是围绕 modelcontextprotocol/go-sdk 客户。它使多个MCP传输(stdio或HTTP)保持活动状态,扇出 事件,并展示人体工程学助手,用于列出或调用工具、提示、, 以及Go应用程序中的资源。同伴 mcpgateway 包构建 在...之上 mcpmgr 通过单个Streamable公开每个托管服务器 HTTP端点。

安装

go get github.com/vikashloomba/mcp-client-manager-go/pkg/mcpmgr
go get github.com/vikashloomba/mcp-client-manager-go/pkg/mcp-gateway

使用预先注册的服务器进行初始化

package main

import (
    "context"
    "time"

    "github.com/vikashloomba/mcp-client-manager-go/pkg/mcpmgr"
)

func main() {
    manager := mcpmgr.NewManager(map[string]mcpmgr.ServerConfig{
        "stdio-example": &mcpmgr.StdioServerConfig{
            BaseServerConfig: mcpmgr.BaseServerConfig{Timeout: 30 * time.Second},
            Command:          "npx",
            Args:             []string{"@modelcontextprotocol/server-everything"},
        },
        "streamable-example": &mcpmgr.HTTPServerConfig{
            BaseServerConfig: mcpmgr.BaseServerConfig{Timeout: 30 * time.Second},
            Endpoint:         "https://gitmcp.io/modelcontextprotocol/go-sdk",
        },
    }, &mcpmgr.ManagerOptions{DefaultClientName: "my-app", AutoConnect: true})

    ctx := context.Background()
    // AutoConnect will dial the transports in the background; ensure you close
    // them before exiting.
    defer manager.DisconnectAllServers(ctx)
}

初始化后添加服务器

ctx := context.Background()

config := &mcpmgr.HTTPServerConfig{
    BaseServerConfig: mcpmgr.BaseServerConfig{Timeout: 45 * time.Second},
    Endpoint:         "https://gitmcp.io/modelcontextprotocol/go-sdk",
}

if _, err := manager.ConnectToServer(ctx, "docs-server", config); err != nil {
    panic(err)
}

列出和调用工具

tools, err := manager.ListTools(ctx, "streamable-example", nil)
if err != nil {
    panic(err)
}

for _, tool := range tools.Tools {
    println("Tool:", tool.Name)
}

result, err := manager.ExecuteTool(ctx, "streamable-example", "fetch_url_content", map[string]any{
    "url": "https://example.com",
})
if err != nil {
    panic(err)
}
println("Result:", result.Content)

阅读提示和资源

prompts, err := manager.ListPrompts(ctx, "stdio-example", nil)
if err != nil {
    panic(err)
}
for _, prompt := range prompts.Prompts {
    println("Prompt:", prompt.Name)
}

resources, err := manager.ListResources(ctx, "stdio-example", nil)
if err != nil {
    panic(err)
}
for _, resource := range resources.Resources {
    println("Resource:", resource.URI)
}

details, err := manager.ReadResource(ctx, "stdio-example", &mcp.ReadResourceParams{URI: resources.Resources[0].URI})
if err != nil {
    panic(err)
}
println("First resource size:", len(details.Resource.Data))

运行可流式MCP网关

mcpgateway 软件包重新导出由管理的每个工具、提示和资源 mcpmgr 通过单个Streamable HTTP端点,因此仅限下游客户端 必须连接一次。

package main

import (
    "context"
    "log"
    "time"

    mcpgateway "github.com/vikashloomba/mcp-client-manager-go/pkg/mcp-gateway"
    "github.com/vikashloomba/mcp-client-manager-go/pkg/mcpmgr"
)

func main() {
    manager := mcpmgr.NewManager(map[string]mcpmgr.ServerConfig{
        "stdio-example": &mcpmgr.StdioServerConfig{
            BaseServerConfig: mcpmgr.BaseServerConfig{Timeout: 30 * time.Second},
            Command:          "npx",
            Args:             []string{"@modelcontextprotocol/server-everything"},
        },
    }, &mcpmgr.ManagerOptions{DefaultClientName: "gateway-example", AutoConnect: true})

    gateway, err := mcpgateway.NewGateway(manager, &mcpgateway.Options{Addr: ":8787", Path: "/mcp"})
    if err != nil {
        log.Fatalf("gateway init failed: %v", err)
    }

    ctx := context.Background()
    defer manager.DisconnectAllServers(ctx)

    log.Println("Serving MCP gateway on http://localhost:8787/mcp")
    if err := gateway.ListenAndServe(ctx); err != nil {
        log.Fatalf("gateway stopped: %v", err)
    }
}

检查 cmd/gateway-example 对于可运行的示例和下的包文档 pkg/mcp-gateway 对于命名空间策略等定制选项, 通知挂钩、进度扇出和启发桥接。

检查并序列化服务器配置

GetServerSummaries() 返回一段摘要,其中 Config 是一个 ServerConfig 接口由实现 *StdioServerConfig*HTTPServerConfig。为了避免在每个呼叫站点进行类型切换,请使用辅助程序 防护装置和窄缝器:

summaries := manager.GetServerSummaries()
for _, s := range summaries {
    switch mcpmgr.TransportOf(s.Config) {
    case mcpmgr.TransportStdio:
        if cfg, ok := mcpmgr.AsStdio(s.Config); ok {
            // Use cfg.Command, cfg.Args, cfg.Env, etc.
        }
    case mcpmgr.TransportHTTP:
        if cfg, ok := mcpmgr.AsHTTP(s.Config); ok {
            // Use cfg.Endpoint, cfg.MaxRetries, cfg.PreferSSE, etc.
        }
    }
}

注: BaseServerConfig 包含功能字段(例如。, OnError, RPCLogger) 哪个 encoding/json 不能元帅。当生成返回的API时 将摘要转换为JSON,构造一个JSON安全的DTO,而不是封送配置 直接。例如:

type serverSummaryDTO struct {
    ID     string                 `json:"id"`
    Status mcpmgr.ConnectionStatus `json:"status"`
    Config map[string]any         `json:"config"`
}

func buildSummaryDTOs(m *mcpmgr.Manager) ([]serverSummaryDTO, error) {
    sums := m.GetServerSummaries()
    out := make([]serverSummaryDTO, 0, len(sums))
    for _, s := range sums {
        dto := serverSummaryDTO{ID: s.ID, Status: s.Status, Config: map[string]any{}}
        switch mcpmgr.TransportOf(s.Config) {
        case mcpmgr.TransportStdio:
            if c, ok := mcpmgr.AsStdio(s.Config); ok {
                dto.Config = map[string]any{
                    "type":           "stdio",
                    "command":        c.Command,
                    "args":           c.Args,
                    "env":            c.Env,
                    "timeoutSeconds": int(c.BaseServerConfig.Timeout / time.Second),
                    "version":        c.BaseServerConfig.Version,
                }
            }
        case mcpmgr.TransportHTTP:
            if c, ok := mcpmgr.AsHTTP(s.Config); ok {
                dto.Config = map[string]any{
                    "type":           "http",
                    "endpoint":       c.Endpoint,
                    "maxRetries":     c.MaxRetries,
                    "sessionId":      c.SessionID,
                    "preferSse":      c.PreferSSE,
                    "timeoutSeconds": int(c.BaseServerConfig.Timeout / time.Second),
                    "version":        c.BaseServerConfig.Version,
                }
            }
        }
        out = append(out, dto)
    }
    return out, nil
}

添加自定义HTTP路由

如果您想在MCP网关旁边托管额外的端点(用于健康 检查、指标等),呼叫 ServeMux() 获取底层多路复用器 在启动服务器之前注册路由:

gateway, _ := mcpgateway.NewGateway(manager, &mcpgateway.Options{Addr: ":8787", Path: "/mcp"})

// Add custom routes on the same server.
mux := gateway.ServeMux()
mux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) })

// Start the gateway's server.
_ = gateway.ListenAndServe(context.Background())

或者,您可以运行自己的 http.Server 并重用网关的 处理程序和状态:

srv := &http.Server{Addr: ":8787"}
// If Handler is nil, ListenAndServeServer will install gateway.Handler().
_ = gateway.ListenAndServeServer(context.Background(), srv)

当通过启用承载令牌保护时 Options.TokenVerifier,只有 可流化MCP端点由该中间件保护。其他路线您 寄存器不会自动打包;根据需要应用自己的身份验证。

UI根镜像

一些MCP服务器根据客户端的UI限制对文件资源的访问 “根”。网关可以将UI的根集镜像到每个下游服务器。 当你的UI学习到它的有效根时,使用新的助手:

// Replace all roots at once (diffed and propagated to all downstream servers):
gateway.SetUIRoots([]*mcp.Root{{URI: "file:///workspace", Name: "Workspace"}})

// Or incrementally add/remove roots:
gateway.AddUIRoots(&mcp.Root{URI: "file:///tmp", Name: "Temp"})
gateway.RemoveUIRoots("file:///tmp")

当通过连接新服务器时 gateway.AttachServer,当前缓存 根被推送到该服务器的客户端,因此它立即反映了UI集。

干净地删除服务器

网关现在暴露 DetachServerRemoveServer 助手:

// Detach removes a server's tools/prompts/resources from the aggregated view.
_ = gateway.DetachServer(ctx, serverID)

// Remove detaches and then calls manager.RemoveServer to close and delete it.
_ = gateway.RemoveServer(ctx, serverID)

另外, mcpmgr.Manager 发出网关订阅的删除事件 给;打电话 manager.RemoveServer(ctx, id) 自动修剪服务器的 网关的功能,这样它们就不会再出现在客户端面前。

进度通知

两者 mcpmgr 网关保护 _meta.progressToken 价值观和前进 notifications/progress 端到端,即使上游服务器发出浮点数 令牌或客户端省略令牌(网关会自动为每个请求生成一个令牌)。 下游消费者只需在连接时注册处理程序:

client := mcp.NewClient(
    &mcp.Implementation{Name: "ui", Version: "1.0.0"},
    &mcp.ClientOptions{
        ProgressNotificationHandler: func(_ context.Context, req *mcp.ProgressNotificationClientRequest) {
            if req == nil || req.Params == nil {
                return
            }
            log.Printf("progress %s %.0f/%.0f", req.Params.Message, req.Params.Progress, req.Params.Total)
        },
    },
)
session, err := client.Connect(ctx, transport, nil)

如果您需要观察Go服务中的上游进度(用于指标或 UI继电器),设置 ManagerOptions.DefaultClientOptions.ProgressNotificationHandler 或打电话 manager.AddNotificationHandler(serverID, mcpmgr.NotificationSchemaProgress, ...).

可选OAuth 2.0保护

mcpgateway 在转发任何MCP流量之前,可能需要承载令牌。到 启用此功能,填充 mcpgateway.Options.TokenVerifier 用你的代币 检查逻辑并提供匹配 TokenOptions (auth.RequireBearerTokenOptions).当两者都存在时,网关会封装 可流式处理程序 auth.RequireBearerToken,自动托管 /.well-known/oauth-protected-resource,回答正确 WWW-Authenticate: Bearer resource_metadata=… header,并在上启用CORS 元数据端点。集 Options.AuthorizationServer 因此,元数据响应 链接到您的发行人,并覆盖 Options.ResourceURL 如果公共URL 客户端将使用不匹配 http://localhost .

样品在 cmd/gateway-example 将此行为与环境切换 变量,这样您就可以在不更改代码的情况下选择加入:

变量描述示例值
AUTHORIZATION_SERVER_URL发出网关令牌的OAuth 2.0/OIDC授权服务器的基本URL。https://example-server.modelcontextprotocol.io/
OAUTH_RESOURCE_METADATA_URL客户端发现网关资源元数据的完全限定URL。这通常应该是您部署的网关 /.well-known/oauth-protected-resource.https://example-server.modelcontextprotocol.io/.well-known/oauth-protected-resource

mcpgateway.Options.ResourceURL 控制 "resource" 返回的值 元数据端点。它默认为 http://localhost ,匹配 进程内监听器,因此在公共网关URL存在时明确设置它 在代理后面或使用与本地侦听器不同的TLS/主机名。

如果设置了这两个变量,则该示例将附加您的验证器并保护 可流化端点;如果其中任何一个为空,则网关仍对本地用户开放 发展。最小启动顺序如下:

export AUTHORIZATION_SERVER_URL="https://example-server.modelcontextprotocol.io/"
export OAUTH_RESOURCE_METADATA_URL="https://example-server.modelcontextprotocol.io/.well-known/oauth-protected-resource"
go run ./cmd/gateway-example

样品内部 TokenVerifier,用真正的JWT替换占位符逻辑 对您的授权服务器进行检查或令牌自检调用。

MCP管理器用户界面(弃权3)

apps/mcp-manager-ui/ 目录包含一个Wails 3桌面项目,该项目练习管理器和网关API。使用 wails3 dev 用于实时开发或 wails3 build 生成可分发的二进制文件。

UI模块导入以下包 github.com/vikashloomba/mcp-client-manager-go/pkg/mcpmgr。因为存储库在中定义了一个工作区 go.work:

use (
    .
    ./apps/mcp-manager-ui
)

Go在此签出中将这些导入解析到本地源,而不是获取已发布的模块。这使UI与后端保持相同的提交状态——不需要替换指令——因此您可以迭代 pkg/mcpmgr, pkg/mcp-gateway,同时具有腰部前端。

回应启发请求

manager.SetElicitationCallback(func(ctx context.Context, event *mcpmgr.ElicitationEvent) (*mcp.ElicitResult, error) {
    println("Elicitation from", event.ServerID, "message:", event.Message)

    // Option A: respond immediately.
    return &mcp.ElicitResult{Content: []any{"acknowledged"}}, nil
})

// Option B: defer the response and use RespondToElicitation later.

manager.SetElicitationCallback(func(ctx context.Context, event *mcpmgr.ElicitationEvent) (*mcp.ElicitResult, error) {
    go func(id string) {
        manager.RespondToElicitation(id, &mcp.ElicitResult{Content: []any{"done"}})
    }(event.RequestID)
    return nil, nil // pending response will be delivered asynchronously.
})

下一步

  • 通过注册通知处理程序 OnToolListChanged, OnResourceUpdated,

AddNotificationHandler 对服务器事件做出反应。

  • 提供自定义 RPCLogger 通过 ManagerOptions 发出JSON-RPC流量

您的日志记录或可观察性管道。

发布

推到 main 分支通过以下方式自动剪切释放 .github/workflows/release.yml:

  • 工作流程比较 HEAD 到最近 v*.*.* 标记并碰撞

版本(默认为补丁)。包含 #minor#major 在提交消息中 要求更大的颠簸; BREAKING CHANGE 也迫使一个重大的释放。

  • 测试成功后,跨平台 manager-example 构建二进制文件

作为发布资产上传。然后,工作流创建标签,发布 GitHub发布了一个更新日志,并触发了pkg.go.dev。

目录标签

目录标签

轻量级GoAI代理客户端管理本地部署工具调用资源访问事件分发

接入字段

传输方式(transport,传输协议)

未说明

鉴权方式(authType,认证方式)

oauth

工具数量(toolCount,工具数)

0

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

未说明oauth部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

仍需确认:installCommand

来源信息

继续浏览同类 MCP