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

Go Plugin Template

MCP Server

一个用于在Go中构建MCP(Model Context Protocol)插件的WebAssembly插件模板,适用于hyper-mcp框架。

工具数

1

提示词数

0

GitHub Stars

0

资源数

0
GoClaudeAI代理Claude DesktopClaudeCursor

安装说明

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

作者 / 组织

hyper-mcp-rs

提供方

hyper-mcp-rs

最后核验

2026/5/17 20:20

快速接入

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

详细介绍

Go插件模板

一个WebAssembly插件模板,用于使用hyper-MCP框架在Go中构建MCP(模型上下文协议)插件。

概述

此模板提供了一个创建作为WebAssembly模块运行的MCP插件的入门项目。它包括实现MCP协议处理程序所需的所有依赖关系和样板代码。

项目结构

.
├── .github/workflows       # Sample workflows for Github Actions
|-- main.go                 # Plugin handler implementations
├── exports.go              # WASM export wrappers for handlers
├── imports.go              # Host function calls
├── types.go                # MCP protocol types
├── go.mod                  # Go module definition
├── go.sum                  # Go module checksums
├── Dockerfile              # Simple build for deploying a WASM
└── .gitignore              # Git ignore rules

入门指南

先决条件

  • 转到1.22或更高版本
  • TinyGo 0.40或更高版本
  • Docker(用于构建WASM)
  • clanglld (用于WASM编译)

发展

  1. 克隆或使用此模板 启动插件项目
  1. 实现插件处理程序main.go:

插件处理程序必须在不使用goroutines的情况下实现 *除非* 您修改了Dockerfile构建以删除 -scheduler=none 从蒂尼戈建造旗帜。请注意,不建议这样做,因为hyper-mcp通常会为您处理并发执行。

注: 你只需要实现与你的插件相关的处理程序。例如,如果你的插件只提供工具,那么只实现 ListTools()CallTool()。所有其他处理程序都有开箱即用的默认实现。
  • ListTools() -描述可用工具
  • CallTool() -执行工具
  • ListResources() -列出可用资源
  • ReadResource() -读取资源内容
  • ListPrompts() -列出可用提示
  • GetPrompt() -获取提示详细信息
  • Complete() -提供自动完成建议
  • ListResourceTemplates() -列出资源模板
  • OnRootsListChanged() -处理根更改
  1. 本地建设 (WASM目标需要Docker):
    GOOS=wasip1 GOARCH=wasm tinygo build -no-debug -panic=trap -scheduler=none -o plugin.wasm
    docker build -t your-registry/your-plugin-name .

依赖项

模板使用:

  • extism/go pdk -Extism插件开发工具包
  • 用于JSON序列化和时间处理的标准Go库

插件处理函数

您的插件可以实现以下处理程序的任意组合。 只实现插件所需的处理程序 -该模板为其他所有内容提供了合理的默认值:

处理程序用途必需
ListTools()声明可用工具提供插件的工具
CallTool()执行工具提供插件的工具
ListResources()声明可用资源资源提供插件
ListResourceTemplates()声明资源模板动态资源插件
ReadResource()读取资源内容资源提供插件
ListPrompts()声明可用提示提示提供插件
GetPrompt()检索特定提示提示提供插件
Complete()提供自动补全功能支持补全的插件
OnRootsListChanged()处理根更改插件对根更改做出反应

示例:仅限工具的插件

如果你的插件只提供工具,你只需要实现:

func ListTools(input ListToolsRequest) (*ListToolsResult, error) {
    return &ListToolsResult{
        Tools: []Tool{
            {
                Name: "greet",
                Description: ptrString("Greet a person"),
                InputSchema: ToolSchema{
                    Type: "object",
                    Properties: map[string]interface{}{
                        "name": map[string]interface{}{
                            "type": "string",
                            "description": "The person's name",
                        },
                    },
                    Required: []string{"name"},
                },
            },
        },
    }, nil
}

func CallTool(input CallToolRequest) (*CallToolResult, error) {
    switch input.Request.Name {
    case "greet":
        name, ok := input.Request.Arguments["name"].(string)
        if !ok {
            return &CallToolResult{
                Content: []json.RawMessage{
                    []byte(`{"type":"text","text":"name argument required"}`),
                },
            }, nil
        }
        return &CallToolResult{
            Content: []json.RawMessage{
                []byte(fmt.Sprintf(`{"type":"text","text":"Hello, %s!"}`, name)),
            },
        }, nil
    default:
        return &CallToolResult{
            Content: []json.RawMessage{
                []byte(fmt.Sprintf(`{"type":"text","text":"Unknown tool: %s"}`, input.Request.Name)),
            },
        }, nil
    }
}

所有其他处理程序将使用其默认实现。

主机功能

您的插件可以调用这些宿主函数与客户端和MCP服务器进行交互。可通过直接函数调用 imports.go:

// Example usage
result, err := CreateElicitation(ElicitRequestParamWithTimeout{...})

用户交互

**CreateElicitation(input ElicitRequestParamWithTimeout) (*ElicitResult, error)**

通过客户端的启发界面请求用户输入。当您的插件在执行过程中需要用户指导、决策或确认时,请使用此功能。

result, err := CreateElicitation(ElicitRequestParamWithTimeout{
    Message: "Please provide your name",
    RequestedSchema: Schema{
        Type: "object",
        Properties: map[string]json.RawMessage{
            "name": json.RawMessage(`{"type":"string"}`),
        },
    },
    Timeout: ptrInt64(30000), // 30 second timeout
})

消息生成

**CreateMessage(input CreateMessageRequestParam) (*CreateMessageResult, error)**

通过客户端的采样接口请求消息创建。当您的插件需要人工智能辅助的智能文本生成或分析时,请使用此功能。

result, err := CreateMessage(CreateMessageRequestParam{
    MaxTokens: 1024,
    Messages: []json.RawMessage{
        // conversation history
    },
    SystemPrompt: ptrString("You are a helpful assistant"),
})

资源发现

**ListRoots() (*ListRootsResult, error)**

列出客户端的根目录或资源。使用此功能可以发现可用的根资源(通常是文件系统根),并了解插件可以访问的资源范围。

roots, err := ListRoots()
if err == nil {
    for _, root := range roots.Roots {
        fmt.Printf("Root: %s at %s\n", *root.Name, root.URI)
    }
}

日志记录

NotifyLoggingMessage(input LoggingMessageNotificationParam) error

向客户端发送诊断、信息、警告或错误消息。客户端的日志记录级别决定了要处理和显示哪些消息。

NotifyLoggingMessage(LoggingMessageNotificationParam{
    Level: LoggingLevelInfo,
    Logger: ptrString("my_plugin"),
    Data: json.RawMessage(`{"message": "Processing started"}`),
})

进度报告

NotifyProgress(input ProgressNotificationParam) error

报告长时间运行操作期间的进度。允许客户端向用户显示进度条或状态信息。

NotifyProgress(ProgressNotificationParam{
    Progress: 50,
    ProgressToken: "task-1",
    Total: ptrFloat64(100),
})

列表更改通知

当插件的可用项更改时通知客户端:

NotifyToolListChanged() error

  • 在添加、删除或修改可用工具时调用此命令

NotifyResourceListChanged() error

  • 在添加、删除或修改可用资源时调用此命令

NotifyPromptListChanged() error

  • 在添加、删除或修改可用提示时调用此命令

NotifyResourceUpdated(input ResourceUpdatedNotificationParam) error

  • 当您修改特定资源的内容时调用此命令
// When your plugin's tools change
NotifyToolListChanged()

// When a specific resource is updated
NotifyResourceUpdated(ResourceUpdatedNotificationParam{
    URI: "resource://my-resource",
})

示例:带有进度的交互式工具

func CallTool(input CallToolRequest) (*CallToolResult, error) {
    switch input.Request.Name {
    case "long_task":
        // Log start
        NotifyLoggingMessage(LoggingMessageNotificationParam{
            Level: LoggingLevelInfo,
            Data: json.RawMessage(`{"message": "Starting long task"}`),
        })

        // Do work with progress updates
        for i := 0; i < 10; i++ {
            // ... do work ...
            NotifyProgress(ProgressNotificationParam{
                Progress: float64((i + 1) * 10),
                ProgressToken: "task-1",
                Total: ptrFloat64(100),
            })
        }

        return &CallToolResult{
            Content: []json.RawMessage{
                []byte(`{"type":"text","text":"Task completed"}`),
            },
        }, nil
    default:
        return &CallToolResult{
            Content: []json.RawMessage{
                []byte(fmt.Sprintf(`{"type":"text","text":"Unknown tool: %s"}`, input.Request.Name)),
            },
        }, nil
    }
}

配电楼

使用Docker

包括 Dockerfile 只需封装您的WASM:

GOOS=wasip1 GOARCH=wasm tinygo build -no-debug -panic=trap -scheduler=none -o plugin.wasm
docker build -t your-registry/your-plugin-name .

Docker构建:

  1. 将Go代码编译为 wasip1 目标
  2. 创建仅包含已编译图像的最小图像 plugin.wasm
  3. 输出OCI兼容的容器映像

手动构建

要在没有Docker的情况下手动构建(需要TinyGo 0.40+):

# Build for WASM
GOOS=wasip1 GOARCH=wasm tinygo build -no-debug -panic=trap -scheduler=none -o plugin.wasm

# Result is at: plugin.wasm

实施指南

创建工具

下面是一个实现简单工具的示例:

func ListTools(input ListToolsRequest) (*ListToolsResult, error) {
    return &ListToolsResult{
        Tools: []Tool{
            {
                Name: "greet",
                Description: ptrString("Greet a person"),
                InputSchema: ToolSchema{
                    Type: "object",
                    Properties: map[string]interface{}{
                        "name": map[string]interface{}{
                            "type": "string",
                            "description": "The person's name",
                        },
                    },
                    Required: []string{"name"},
                },
            },
        },
    }, nil
}

func CallTool(input CallToolRequest) (*CallToolResult, error) {
    switch input.Request.Name {
    case "greet":
        name, ok := input.Request.Arguments["name"].(string)
        if !ok {
            return &CallToolResult{
                Content: []json.RawMessage{
                    []byte(`{"type":"text","text":"name argument required"}`),
                },
            }, nil
        }
        return &CallToolResult{
            Content: []json.RawMessage{
                []byte(fmt.Sprintf(`{"type":"text","text":"Hello, %s!"}`, name)),
            },
        }, nil
    default:
        return &CallToolResult{
            Content: []json.RawMessage{
                []byte(fmt.Sprintf(`{"type":"text","text":"Unknown tool: %s"}`, input.Request.Name)),
            },
        }, nil
    }
}

创建资源

实现资源的示例:

func ListResources(input ListResourcesRequest) (*ListResourcesResult, error) {
    return &ListResourcesResult{
        Resources: []Resource{
            {
                URI: "resource://example",
                Name: "Example Resource",
                Description: ptrString("An example resource"),
                MimeType: ptrString("text/plain"),
            },
        },
    }, nil
}

func ReadResource(input ReadResourceRequest) (*ReadResourceResult, error) {
    switch input.Request.URI {
    case "resource://example":
        return &ReadResourceResult{
            Contents: []json.RawMessage{
                []byte(`{"uri":"resource://example","mimeType":"text/plain","text":"Resource content here"}`),
            },
        }, nil
    default:
        return &ReadResourceResult{
            Contents: []json.RawMessage{
                []byte(fmt.Sprintf(`{"type":"text","text":"Unknown resource: %s"}`, input.Request.URI)),
            },
        }, nil
    }
}

Helper函数

该模板包括一些使用指针的有用辅助函数:

// Helper to create string pointers
func ptrString(s string) *string {
    return &s
}

// Helper to create int64 pointers
func ptrInt64(i int64) *int64 {
    return &i
}

// Helper to create float64 pointers
func ptrFloat64(f float64) *float64 {
    return &f
}

// Helper to create bool pointers
func ptrBool(b bool) *bool {
    return &b
}

hyper-mcp中的配置

构建并发布插件后,在hyper-mcp中配置它:

{
  "plugins": {
    "my_plugin": {
      "url": "oci://your-registry/your-plugin-name:latest"
    }
  }
}

对于本地开发/测试:

{
  "plugins": {
    "my_plugin": {
      "url": "file:///path/to/plugin.wasm"
    }
  }
}

测试

要在本地测试您的插件:

  1. 构建它: docker build -t my-plugin . && docker run --rm -v $(pwd):/workspace my-plugin cp /plugin.wasm /workspace/
  2. 更新hyper-mcp的配置以指向 file:// 统一资源定位符
  3. 使用以下命令启动hyper-mcp RUST_LOG=debug
  4. 通过Claude Desktop、Cursor IDE或其他MCP客户端进行测试

资源

许可证

与hyper-mcp相同-Apache 2.0

目录标签

目录标签

GoClaudeAI代理WebAssembly本地部署MCP协议Go开发插件开发hyper-mcp

支持客户端

Claude DesktopClaudeCursor

接入字段

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

未说明

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

none

工具数量(toolCount,工具数)

1

资源数量(resourceCount,资源数)

0

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

0

权限和风险

未说明none部署方式未说明

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

安装前确认

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

仍需确认:installCommand

来源信息

继续浏览同类 MCP