最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文弄懂用Go實現(xiàn)MCP服務(wù)的示例代碼

 更新時間:2025年04月21日 10:23:58   作者:王中陽講編程  
本文主要介紹了一文弄懂用Go實現(xiàn)MCP服務(wù)的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

最近這段時間,AI領(lǐng)域里有一個非常熱門的概念——MCP(模型上下文協(xié)議)。Anthropic推出的這一開放標(biāo)準(zhǔn)旨在為大型語言模型和AI助手提供統(tǒng)一的接口,使其能夠輕松操作外部工具并完成更復(fù)雜的任務(wù)。

本文將帶你速覽MCP的核心概念,并以Go語言為例,介紹如何開發(fā)MCP服務(wù)端和客戶端

為什么MCP如此重要?

在過去,如果想要讓AI處理特定的數(shù)據(jù),通常只能依賴于預(yù)訓(xùn)練數(shù)據(jù)或者手動上傳數(shù)據(jù),這既麻煩又低效。即便對于強(qiáng)大的AI模型而言,也存在數(shù)據(jù)隔離的問題,無法直接訪問新的數(shù)據(jù)源,每次更新數(shù)據(jù)都需要重新訓(xùn)練或上傳?,F(xiàn)在,MCP解決了這個問題,它使得AI不再局限于靜態(tài)知識庫,而是能夠像人類一樣調(diào)用搜索引擎、訪問本地文件、連接API服務(wù)等,極大提升了AI的動態(tài)交互能力。

MCP總體架構(gòu)

MCP的核心是“客戶端-服務(wù)器”架構(gòu),其中MCP客戶端可以連接到多個服務(wù)器。客戶端是指希望通過MCP訪問數(shù)據(jù)的應(yīng)用程序,如CLI工具、IDE插件或AI應(yīng)用。

使用mcp-go構(gòu)建MCP服務(wù)端與客戶端

要開始使用Go語言構(gòu)建MCP項目,首先需要安裝mcp-go庫,這是Go語言實現(xiàn)的Model Context Protocol庫,支持LLM應(yīng)用與外部數(shù)據(jù)源和工具之間的無縫集成。

go get github.com/mark3labs/mcp-go

構(gòu)建MCP服務(wù)端

接下來,我們將演示如何使用mcp-go提供的server模塊來構(gòu)建一個通過stdio方式連接的MCP服務(wù)器。

創(chuàng)建Server對象

s := server.NewMCPServer("My Server", "1.0.0")

添加工具(Tools)

例如,我們可以創(chuàng)建一個簡單的計算器工具,這次我們實現(xiàn)乘法和除法功能:

calculatorTool := mcp.NewTool("calculate",
    mcp.WithDescription("執(zhí)行基本的算術(shù)運算"),
    mcp.WithString("operation",
        mcp.Required(),
        mcp.Description("要執(zhí)行的算術(shù)運算類型"),
        mcp.Enum("multiply", "divide"), // 修改為僅支持乘法和除法
    ),
    mcp.WithNumber("x",
        mcp.Required(),
        mcp.Description("第一個數(shù)字"),
    ),
    mcp.WithNumber("y",
        mcp.Required(),
        mcp.Description("第二個數(shù)字"),
    ),
)

s.AddTool(calculatorTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
    op := request.Params.Arguments["operation"].(string)
    x := request.Params.Arguments["x"].(float64)
    y := request.Params.Arguments["y"].(float64)

    var result float64
    switch op {
    case "multiply":
        result = x * y
    case "divide":
        if y == 0 {
            return nil, errors.New("不允許除以零")
        }
        result = x / y
    }

    return mcp.FormatNumberResult(result), nil
})
  • 添加資源(Resources)

同樣地,我們也可以注冊一些靜態(tài)資源,比如README.md文件的內(nèi)容:

resource := mcp.NewResource(
    "docs://readme",
    "項目說明文檔",
    mcp.WithResourceDescription("項目的 README 文件"),
    mcp.WithMIMEType("text/markdown"),
)

s.AddResource(resource, func(ctx context.Context, request mcp.ReadResourceRequest) ([]mcp.ResourceContents, error) {
    content, err := os.ReadFile("README.md")
    if err != nil {
        return nil, err
    }

    return []mcp.ResourceContents{
        mcp.TextResourceContents{
            URI:      "docs://readme",
            MIMEType: "text/markdown",
            Text:     string(content),
        },
    }, nil
})
  • 啟動基于stdio傳輸類型的服務(wù)器
if err := server.ServeStdio(s); err != nil {
    fmt.Printf("Server error: %v\n", err)
}

以上步驟完成后,我們就成功搭建了一個基礎(chǔ)的MCP服務(wù)器。

構(gòu)建MCP客戶端

接著,我們將展示如何使用mcp-go提供的client模塊構(gòu)建一個連接至上述MCP服務(wù)器的客戶端。

  • 創(chuàng)建MCP客戶端
mcpClient, err := client.NewStdioMCPClient("./client/server", []string{})
if err != nil {
    panic(err)
}
defer mcpClient.Close()
  • 初始化客戶端連接
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

initRequest := mcp.InitializeRequest{}
initRequest.Params.ProtocolVersion = mcp.LATEST_PROTOCOL_VERSION
initRequest.Params.ClientInfo = mcp.Implementation{
    Name:    "Client Demo",
    Version: "1.0.0",
}

initResult, err := mcpClient.Initialize(ctx, initRequest)
if err != nil {
    panic(err)
}
fmt.Printf("初始化成功,服務(wù)器信息: %s %s\n", initResult.ServerInfo.Name, initResult.ServerInfo.Version)
  • 調(diào)用遠(yuǎn)程工具

最后,我們可以通過構(gòu)造CallToolRequest來調(diào)用服務(wù)器上的工具,如下所示:

toolRequest := mcp.CallToolRequest{
    Request: mcp.Request{
        Method: "tools/call",
    },
}
toolRequest.Params.Name = "calculate"
toolRequest.Params.Arguments = map[string]any{
    "operation": "multiply", // 調(diào)用乘法
    "x":         2,
    "y":         3,
}

result, err := mcpClient.CallTool(ctx, toolRequest)
if err != nil {
    panic(err)
}
fmt.Println("調(diào)用工具結(jié)果:", result.Content[0].(mcp.TextContent).Text)

完整代碼示例

以下是完整的代碼示例,包括服務(wù)端和客戶端的實現(xiàn):

服務(wù)端代碼:

package main

import (
    "context"
    "errors"
    "fmt"
    "os"

    "github.com/mark3labs/mcp-go/mcp"
    "github.com/mark3labs/mcp-go/server"
)

func main() {
    s := server.NewMCPServer("Server Demo", "1.0.0")

    // 添加工具
    calculatorTool := mcp.NewTool("calculate",
        mcp.WithDescription("執(zhí)行基本的算術(shù)運算"),
        mcp.WithString("operation",
            mcp.Required(),
            mcp.Description("要執(zhí)行的算術(shù)運算類型"),
            mcp.Enum("multiply", "divide"),
        ),
        mcp.WithNumber("x",
            mcp.Required(),
            mcp.Description("第一個數(shù)字"),
        ),
        mcp.WithNumber("y",
            mcp.Required(),
            mcp.Description("第二個數(shù)字"),
        ),
    )

    s.AddTool(calculatorTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
        op := request.Params.Arguments["operation"].(string)
        x := request.Params.Arguments["x"].(float64)
        y := request.Params.Arguments["y"].(float64)

        var result float64
        switch op {
        case "multiply":
            result = x * y
        case "divide":
            if y == 0 {
                return nil, errors.New("不允許除以零")
            }
            result = x / y
        }

        return mcp.FormatNumberResult(result), nil
    })

    // 啟動基于 stdio 的服務(wù)器
    if err := server.ServeStdio(s); err != nil {
        fmt.Printf("Server error: %v\n", err)
    }
}

客戶端代碼:

package main

import (
    "context"
    "fmt"
    "time"

    "github.com/mark3labs/mcp-go/client"
    "github.com/mark3labs/mcp-go/mcp"
)

func main() {
    mcpClient, err := client.NewStdioMCPClient("./client/server", []string{})
    if err != nil {
        panic(err)
    }
    defer mcpClient.Close()

    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
    defer cancel()

    initRequest := mcp.InitializeRequest{}
    initRequest.Params.ProtocolVersion = mcp.LATEST_PROTOCOL_VERSION
    initRequest.Params.ClientInfo = mcp.Implementation{
        Name:    "Client Demo",
        Version: "1.0.0",
    }

    initResult, err := mcpClient.Initialize(ctx, initRequest)
    if err != nil {
        panic(err)
    }
    fmt.Printf("初始化成功,服務(wù)器信息: %s %s\n", initResult.ServerInfo.Name, initResult.ServerInfo.Version)

    // 調(diào)用工具
    toolRequest := mcp.CallToolRequest{
        Request: mcp.Request{
            Method: "tools/call",
        },
    }
    toolRequest.Params.Name = "calculate"
    toolRequest.Params.Arguments = map[string]any{
        "operation": "multiply",
        "x":         2,
        "y":         3,
    }

    result, err := mcpClient.CallTool(ctx, toolRequest)
    if err != nil {
        panic(err)
    }
    fmt.Println("調(diào)用工具結(jié)果:", result.Content[0].(mcp.TextContent).Text)
}

希望這篇文章能幫助你快速入門Go語言下的MCP開發(fā)!

到此這篇關(guān)于一文弄懂用Go實現(xiàn)MCP服務(wù)的示例代碼的文章就介紹到這了,更多相關(guān)Go MCP服務(wù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang編譯器介紹

    Golang編譯器介紹

    今天小編就為大家分享一篇關(guān)于go語言編譯器的介紹,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-09-09
  • 一文搞懂Golang 時間和日期相關(guān)函數(shù)

    一文搞懂Golang 時間和日期相關(guān)函數(shù)

    這篇文章主要介紹了Golang 時間和日期相關(guān)函數(shù),本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-12-12
  • 詳解Go語言中如何高效遍歷目錄

    詳解Go語言中如何高效遍歷目錄

    目錄遍歷是一個很常見的操作,它的使用場景有如文件目錄查看、文件系統(tǒng)清理、日志分析、項目構(gòu)建等,本文將詳細(xì)介紹在Go中幾種遍歷目錄文件的方法,需要的可以參考下
    2024-02-02
  • Go語言切片擴(kuò)容原理和過程

    Go語言切片擴(kuò)容原理和過程

    切片(Slice)在 Go 語言中,有一個很常用的數(shù)據(jù)結(jié)構(gòu),切片是一個擁有相同類型元素的可變長度的序列,它是基于數(shù)組類型做的一層封裝,它非常靈活,支持自動擴(kuò)容,并發(fā)不安全,本文給大家介紹了Go 語言切片如何擴(kuò)容,需要的朋友可以參考下
    2025-02-02
  • 詳解Go中如何進(jìn)行進(jìn)行內(nèi)存優(yōu)化和垃圾收集器管理

    詳解Go中如何進(jìn)行進(jìn)行內(nèi)存優(yōu)化和垃圾收集器管理

    這篇文章主要為大家詳細(xì)介紹了Go中如何進(jìn)行進(jìn)行內(nèi)存優(yōu)化和垃圾收集器管理,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價值,感興趣的小伙伴可以了解下
    2023-11-11
  • golang生成指定位數(shù)的隨機(jī)數(shù)的方法

    golang生成指定位數(shù)的隨機(jī)數(shù)的方法

    這篇文章主要介紹了golang生成指定位數(shù)的隨機(jī)數(shù)的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • Go語言異常處理案例解析

    Go語言異常處理案例解析

    這篇文章主要介紹了Go語言異常處理案例解析,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • Go語言調(diào)用Shell與可執(zhí)行文件的實現(xiàn)

    Go語言調(diào)用Shell與可執(zhí)行文件的實現(xiàn)

    這篇文章主要介紹了Go語言調(diào)用Shell與可執(zhí)行文件的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • GoLand編譯帶有構(gòu)建標(biāo)簽的程序思路詳解

    GoLand編譯帶有構(gòu)建標(biāo)簽的程序思路詳解

    這篇文章主要介紹了GoLand編譯帶有構(gòu)建標(biāo)簽的程序,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • Golang使用WebSocket通信的實現(xiàn)

    Golang使用WebSocket通信的實現(xiàn)

    這篇文章主要介紹了Golang使用WebSocket通信的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02

最新評論

安义县| 南丹县| 策勒县| 电白县| 石门县| 来凤县| 台山市| 天津市| 栾城县| 乌拉特后旗| 嘉善县| 柘城县| 渑池县| 九江市| 略阳县| 莱州市| 吉木萨尔县| 信丰县| 通辽市| 历史| 石景山区| 桃江县| 丽江市| 桐城市| 买车| 加查县| 铜陵市| 连云港市| 信阳市| 兴安县| 东乡族自治县| 盐津县| 汶川县| 肇东市| 西和县| 黔西| 项城市| 铁力市| 天祝| 太白县| 黄梅县|