MCP指南(Go)——示例详解
本指南使用此存储库在Go中构建MCP服务器,从最简单的工具到资源、提示、启发和客户端采样。为了清楚起见,这些示例被打包(用例/服务器/cmd),因此域逻辑与传输布线是分开的。
快速开始
package main
import (
"context"
"encoding/json"
"log"
"github.com/viant/jsonrpc"
proto "github.com/viant/mcp-protocol/server"
"github.com/viant/mcp-protocol/schema"
"github.com/viant/mcp/server"
)
func main() {
// Define a simple tool I/O
type AddIn struct {
A int // json:"a"
B int // json:"b"
Note *string // json:"note,omitempty" description:"Optional note"
}
type AddOut struct { Sum int /* json:"sum" */ }
// Configure handler and register the tool
newHandler := proto.WithDefaultHandler(context.Background(), func(h *proto.DefaultHandler) error {
return proto.RegisterTool[*AddIn, *AddOut](
h.Registry,
"add",
"Add two integers",
func(ctx context.Context, in *AddIn) (*schema.CallToolResult, *jsonrpc.Error) {
data, _ := json.Marshal(&AddOut{Sum: in.A + in.B})
return &schema.CallToolResult{
Content: []schema.CallToolResultContentElem{{Text: string(data)}},
}, nil
},
)
})
srv, err := server.New(
server.WithNewHandler(newHandler),
server.WithImplementation(schema.Implementation{Name: "example", Version: "1.0"}),
)
if err != nil { log.Fatal(err) }
// Choose a transport (see sections below)
// Example: HTTP (SSE by default)
log.Fatal(srv.HTTP(context.Background(), ":4981").ListenAndServe())
}MCP检查员
npx @modelcontextprotocol/inspector目录
- 项目结构模式
- 示例矩阵(端口+功能)
- 运行传输(stdio、HTTP SSE/流)
- 示例1:工具(基本)
- 注释选项(模式标记)
- 示例2:具有启发功能的工具(高级)
- 示例3:资源
- 示例4:提示
- 示例5:完整服务器
- 示例6:使用客户端采样的工具(CreateMessage)
- 示例7:HTTP级别身份验证
- 下一步和参考
项目结构模式
每个示例都使用相同的分隔:
- 用例:业务逻辑、DTO、类验证标签
- 服务器:注册工具/资源/提示和委托的MCP接线
usecase - cmd/server:实例化的入口点
usecase,构建服务器,并启动传输
原因:这使您的协议层保持精简和可重用,业务逻辑独立于传输和模式细节。
运行运输
- Stdio(典型的编辑器集成):
stdioSrv := srv.Stdio(ctx)
log.Fatal(stdioSrv.ListenAndServe())- HTTP SSE(默认):
httpSrv := srv.HTTP(ctx, ":4981")
log.Fatal(httpSrv.ListenAndServe())- HTTP流媒体:
srv.UseStreaming(true)
httpSrv := srv.HTTP(ctx, ":4981")
log.Fatal(httpSrv.ListenAndServe())注意:在这个仓库的HTTP服务器中,JSON-RPC端点被挂载在 /.
______________________________________________________________________
示例矩阵
| 示例 | 路径前缀 | 端口 | 功能 |
|---|---|---|---|
| 工具(基本) | docs/guide/tools_basic | 4981 | 类型化工具,自动派生模式 |
| 资源 | docs/guide/resources | 4982 | 可读资源 /hello |
| 提示 | docs/guide/prompts | 4983 | 提示 welcome 有争论 |
| 满 | docs/guide/full | 4984 | 工具+资源+提示 |
| 工具(高级) | docs/guide/tools_advanced | 4985 | 丰富的标签+启发适配器 |
| 工具(取样) | docs/guide/tools_sampling | 4986 | 客户端CreateMessage(翻译器) |
| 身份验证(HTTP级别) | docs/guide/auth_http | 4987 | OAuth2/OIDC在HTTP中间件中的应用 |
______________________________________________________________________
示例1:工具(基本)
示例路径:
- 用例:
docs/guide/tools_basic/usecase - 服务器:
docs/guide/tools_basic/server - 主营业务:
docs/guide/tools_basic/cmd/server - 运行:
go run ./docs/guide/tools_basic/cmd/server(收听次数:4981)
它的作用:
- 显示键入的
add工具 - 输入/输出的模式是从Go结构自动派生的
调用形状(工具/调用参数):
{
"method": "tools/call",
"jsonrpc": "2.0",
"id": 1,
"params": {
"name": "add",
"arguments": { "a": 2, "b": 3 }
}
}结果是一个包含JSON的文本有效载荷,如 { "sum": 5 }.
JSON-RPC代码段(工具/列表):
{ "method": "tools/list", "jsonrpc": "2.0", "id": 2 }______________________________________________________________________
注释选项(模式标记)
struct字段上的这些标签会影响为工具生成的JSON模式:
json:"name":重命名字段;json:"-"排除它omitempty:与非指针类型结合时可选required:"true":所需兵力required:"false"或optional:强制可选description:"...":人类可读的描述format:"email",format:"uri",format:"date-time"等等。choice:"val":可能会出现多次以构建枚举internal:"true":从架构中完全省略该字段- 可空性:默认情况下,指针类型被视为可空
必需vs可选
- 非指针+否
omitempty→ 必需的 - 指针或
omitempty→ 可选的 - 可与
required标签
支持嵌套类型、数组和映射,并相应地映射到JSON模式。
______________________________________________________________________
示例2:带启发式的工具(高级)
示例路径:
- 用例:
docs/guide/tools_advanced/usecase - 服务器:
docs/guide/tools_advanced/server - 适配器:
docs/guide/tools_advanced/adapter(启发助手) - 主营业务:
docs/guide/tools_advanced/cmd/server - 运行:
go run ./docs/guide/tools_advanced/cmd/server(收听次数:4985)
它显示了什么:
- 工具1:
register_user使用丰富的标签(选择、电子邮件、uri、描述、必填、内部) - 工具2:
enrich_profile通过启发请求缺少的字段(elicitation/create)
诱导流(服务器→ 客户):
- 检查输入,构建最小请求模式(字段名→ 类型/标题,必填列表)
- 呼叫
client.Elicit(...)带有消息和模式 - 如果用户接受内容,将值合并到输入中并继续;否则,返回操作
高级示例将此封装在 adapter.ElicitAndMerge,保持处理器清洁。
JSON-RPC代码段(register_user):
{
"method": "tools/call",
"jsonrpc": "2.0",
"id": 10,
"params": {
"name": "register_user",
"arguments": {
"name": "Alice",
"email": "alice@example.com",
"role": "user",
"country": "US"
}
}
}JSON-RPC代码段(rich_profile-当字段缺失时触发启发):
{
"method": "tools/call",
"jsonrpc": "2.0",
"id": 11,
"params": {
"name": "enrich_profile",
"arguments": { "userId": "user-alice-user" }
}
}______________________________________________________________________
示例3:资源
示例路径:
- 用例:
docs/guide/resources/usecase - 服务器:
docs/guide/resources/server - 主营业务:
docs/guide/resources/cmd/server - 运行:
go run ./docs/guide/resources/cmd/server(收听次数:4982)
它的作用:
- 在以下位置注册可读资源
/hello - 返回文本内容和URI
- 您可以扩展它以通知更新(发送
resources/updated通知)
读取形状(资源/读取参数):
{
"method": "resources/read",
"jsonrpc": "2.0",
"id": 2,
"params": { "uri": "/hello" }
}______________________________________________________________________
示例4:提示
示例路径:
- 用例:
docs/guide/prompts/usecase - 服务器:
docs/guide/prompts/server - 主营业务:
docs/guide/prompts/cmd/server - 运行:
go run ./docs/guide/prompts/cmd/server(收听次数:4983)
它的作用:
- 注册a
welcome用必填参数提示name prompts/list显示可用提示prompts/get解析带有参数的消息
获取形状(提示/获取参数):
{
"method": "prompts/get",
"jsonrpc": "2.0",
"id": 3,
"params": {
"name": "welcome",
"arguments": { "name": "Alice" }
}
}______________________________________________________________________
示例5:完整服务器
示例路径:
- 用例:
docs/guide/full/usecase - 服务器:
docs/guide/full/server - 主营业务:
docs/guide/full/cmd/server - 运行:
go run ./docs/guide/full/cmd/server(收听次数:4984)
它的作用:
- 组合资源(
/hello),一个工具(add),并提示(welcome) - 使用切换流媒体
srv.UseStreaming(true)如需要
JSON-RPC代码段(工具/调用添加):
{
"method": "tools/call",
"jsonrpc": "2.0",
"id": 20,
"params": {
"name": "add",
"arguments": { "a": 7, "b": 8 }
}
}______________________________________________________________________
示例6:使用客户端采样的工具(CreateMessage)
示例路径:
- 用例:
docs/guide/tools_sampling/usecase - 服务器:
docs/guide/tools_sampling/server - 主营业务:
docs/guide/tools_sampling/cmd/server - 运行:
go run ./docs/guide/tools_sampling/cmd/server(收听次数:4986)
它的作用:
- 工具
translate要求客户通过以下方式采样sampling/createMessage - 服务器组成
SystemPrompt以及一条单用户短信 - 返回采样文本作为工具结果
笔记:
- 客户必须宣传
sampling能力 - 如果使用身份验证和远程LLM,请参阅身份验证指南
JSON-RPC代码段(工具/调用转换):
{
"method": "tools/call",
"jsonrpc": "2.0",
"id": 30,
"params": {
"name": "translate",
"arguments": { "text": "Guten Tag", "target": "en", "formality": "less" }
}
}______________________________________________________________________
示例7:HTTP级别身份验证
示例路径:
- 用例:
docs/guide/auth_http/usecase - 服务器:
docs/guide/auth_http/server - 主营业务:
docs/guide/auth_http/cmd/server - 运行:
go run ./docs/guide/auth_http/cmd/server(收听次数:4987)
它的作用:
- 仅在HTTP中间件级别演示OAuth2/OIDC保护
- 配置a
Policy.Global具有受保护的资源元数据(RFC 9728) - 电线
server.WithProtectedResourcesHandler和server.WithAuthorizer
客户备注:
- 在中使用auth RoundTripper
github.com/viant/mcp/client/auth/transport处理WWW-Authenticate挑战和获取代币,或包括Authorization: Bearer直接。
有关详细信息和流程,请参阅身份验证指南。
JSON-RPC代码段(工具/调用secure_add)——包括HTTP标头:
POST / HTTP/1.1
Host: localhost:4987
Authorization: Bearer
Content-Type: application/json
{
"method": "tools/call",
"jsonrpc": "2.0",
"id": 40,
"params": {
"name": "secure_add",
"arguments": { "a": 1, "b": 2 }
}
}______________________________________________________________________
后续步骤和参考
- 启动服务器:请参阅本指南的示例和
/docs/howto.md - 创建客户端:请参阅
/docs/client.md - 服务器功能:工具/资源/提示概述
/docs/server_guide.md - 身份验证/OIDC:
/docs/authentication.md - stdio/HTTP的网桥(代理):
/docs/bridge.md
提示
- 保持传输和域逻辑分离(用例/服务器)
- 使用标签来驱动模式;杠杆指针+
omitempty对于可选字段 - 对于启发和采样,封装模式(适配器)以保持处理程序较小
