如何用 V 语言 mcp 模块编写 MCP Server 并接入 AI 客户端
【免费下载链接】vSimple, fast, safe, compiled language for developing maintainable software. Compiles itself in <1s with zero library dependencies. Supports automatic C => V translation. https://vlang.io项目地址: https://gitcode.com/GitHub_Trending/v/v
vlib/mcp是 V 语言对 Model Context Protocol(MCP)的原生实现,同时提供客户端和服务端,覆盖2025-11-25版规范。如果你的目标是写一个能被 Claude Desktop、Cursor 等 AI 客户端调用的 MCP Server,本文给出完整路径:用mcp模块创建 Server、注册 tools/resources/prompts、选择 stdio 或 Streamable HTTP 传输启动,最后用 V 自带客户端和模块测试套件验证接入是否成功。
模块能力与适用边界
编写前先确认你的功能在模块支持范围内。vlib/mcp/README.md 给出的能力清单包括:
- JSON-RPC 2.0 基础协议
- stdio 传输(换行分隔)
- Streamable HTTP 传输(POST + GET,SSE,会话管理)
Origin头校验(DNS rebinding 防护)- Tools(含
annotations)、Resources、资源模板、Prompts、completion/complete logging/setLevel+notifications/message、notifications/progress与合作式取消- 服务端主动发起的
roots/list、sampling/createMessage、elicitation/create
两项能力目前是 deferred 状态,规划内不包含:Tasks 工具(tasks/*,实验性)和 OAuth 授权。如果你的接入方案依赖这两项,当前版本无法满足。
准备条件
需要一个可用的 V 编译器(仓库自带Makefile等构建入口可自行构建v)。本文所有命令均假定v在PATH中,且你在 V 仓库根目录下执行——示例代码路径(如examples/mcp/server.v)都是相对仓库根目录的。
写一个最小可运行的 MCP Server
模块 README 给出的 server quick start 是最短主路径:mcp.new_server创建服务、add_tool注册一个工具、serve_stdio()以 stdio 传输启动。
import mcp fn main() { mut server := mcp.new_server( name: 'my-v-mcp-server' version: '1.0.0' enable_logging: true ) server.add_tool(mcp.Tool{ name: 'say_hello' description: 'Greets the caller' annotations: mcp.ToolAnnotations{ read_only_hint: true } }, fn (_ mcp.Context, _ string) !mcp.ToolResult { return mcp.tool_text_result('Hello, user!') })! server.serve_stdio()! }几个关键字段的用途(定义见 vlib/mcp/server.v 中的ServerConfig):
name/version:服务端标识,客户端initialize握手后通过server_info拿到的就是它;enable_logging:声明logging能力,允许客户端调用logging/setLevel。默认关闭,只有当 Server 会发出notifications/message时才打开;allowed_origins:Streamable HTTP 下接受的Origin头白名单。留空时只接受没有Origin头或来自回环地址(http://localhost[:port]、http://127.0.0.1[:port]、http://[::1][:port]、字面量null)的请求;http_path:HTTP 模式下服务挂载的路径,默认/mcp。
add_tool的 handler 签名是fn (ctx mcp.Context, arguments string) !ToolResult:第二个参数是调用方传入的 JSON 字符串,需要自己解码。input_schema字段则是原样的 JSON Schema 字符串,AI 客户端靠它决定怎么传参。返回结果用mcp.tool_text_result(...)这类内容助手生成,它们返回符合规范ContentBlock联合(type: "text" | "image" | "audio" | "resource" | "resource_link")的 JSON 字符串。
参考完整示例:tools、resources、prompts 与 completions
仓库内的 examples/mcp/server.v 是覆盖vlib/mcp全部能力的参考 Server,可直接作为你的项目骨架。它的main里先注册四类能力,再按命令行参数选择传输:
register_tools(mut server)! register_resources(mut server)! register_prompts(mut server)! register_completions(mut server)! // Strip a leading `--` so the same binary works whether launched as // `./v run server.v -- --http :8080` (V's run forwards `--`) or as the // pre-compiled binary `./server --http :8080`. args := os.args[1..].filter(it != '--') if args.len > 0 && args[0] == '--http' { addr := if args.len > 1 { args[1] } else { '127.0.0.1:8080' } eprintln('mcp showcase listening on http://${addr}/mcp') server.serve_http(addr)! } else { server.serve_stdio()! }注册 tools 时,示例展示了三类典型的ToolAnnotations写法:echo标注read_only_hint: true且idempotent_hint: true(纯只读、可重复调用);delete_record标注destructive_hint: true,提示宿主在调用前提醒用户。参数解码用的是json2:
server.add_tool(mcp.Tool{ name: 'count_to' description: 'Count up to N with progress notifications. Cooperatively cancellable.' input_schema: '{"type":"object","required":["n"],"properties":{"n":{"type":"integer","minimum":1,"maximum":50}}}' }, fn (ctx mcp.Context, arguments string) !mcp.ToolResult { args := json.decodeCountArgs or { return mcp.tool_text_result('invalid arguments: ${err.msg()}') } // ... return mcp.tool_text_result('counted to ${args.n}') })!resources、prompts 和 completions 的注册方式与 tools 同构,分别在register_resources、register_prompts、register_completions函数中:静态资源demo://welcome.txt、URI 模板demo://greet/{language}、带两个必填参数的reviewprompt,以及针对language参数的补全(对照supported_languages列表做前缀过滤)。
启动 Server 并选择传输
参考示例文件头注释给出了两种启动方式:
# stdio 传输(默认) v run examples/mcp/server.v # Streamable HTTP 传输,监听 127.0.0.1:8080 v run examples/mcp/server.v -- --http # 指定其他地址 v run examples/mcp/server.v -- --http 127.0.0.1:9000注意--http前的--:v run会把--之后的参数转发给程序,示例代码里的filter(it != '--')同时兼容v run和已编译二进制两种启动方式。HTTP 模式启动后会在 stderr 打印mcp showcase listening on http://127.0.0.1:8080/mcp,这是服务已就绪的信号。
HTTP 模式下客户端与http://127.0.0.1:8080/mcp的交互行为由 README 明确约定:
- POST:默认返回 JSON;仅当客户端发送
Accept: text/event-stream时返回 SSE; - GET:打开一个 SSE 流读取排队的通知,可用
Last-Event-ID断点续读; - DELETE:终止会话(必须携带
MCP-Session-Id); - 状态码语义:
Origin不被允许返回 403,MCP-Protocol-Version不支持返回 400,Accept中既无application/json也无text/event-stream返回 406。
可选分支(生产环境注意):示例为了演示把allowed_origins设为['*'],源码注释明确写了 "*only for the demo; tighten this for real deployments"。真实部署应改成具体的 Origin 值;改成回环场景时也可以直接留空,利用默认的回环白名单。
接入 AI 客户端
examples/mcp/server.v 的头部注释直接说明了接入方式:
Connect a client (e.g. Claude Desktop / Cursor / a custom MCP client) to the command above for stdio, or POST to
http://127.0.0.1:8080/mcpfor HTTP.
对应两条接入路径:
- stdio:在 AI 客户端的 MCP Server 配置中,把启动命令指向上面的
v run examples/mcp/server.v(或你替换后的自己的 Server 文件),客户端通过子进程的 stdin/stdout 与 Server 交换换行分隔的 JSON-RPC 消息。具体的客户端配置文件格式取决于各客户端自身文档,V 仓库没有提供。 - HTTP:客户端直接连接
http://127.0.0.1:8080/mcp(或你--http指定的地址),按 Streamable HTTP 协议交互。
如果你不用现成的 AI 客户端,而是自己写一个 V 的 MCP 客户端,mcp.v 提供了三种连接入口:connect(url)/connect_http(url, config)连接 Streamable HTTP 端点,connect_stdio(command, args, config)启动本地 stdio Server 进程作为传输层。
验证接入结果
验证分两层。
第一层:用 V 客户端完成握手。README 的 client quick start:
import mcp fn main() { mut client := mcp.connect('http://localhost:8000/mcp')! init := client.initialize()! println(init.server_info.name) client.close() }运行前把connect的 URL 换成你自己 HTTP 端点的实际地址(参考示例的默认值是http://127.0.0.1:8080/mcp)。initialize()返回的server_info.name应该等于你new_server时传入的name——两边一致说明握手和序列化都正确。client.close()释放底层传输。
第二层:跑模块自身的测试套件。README 给出的命令:
v test vlib/mcp其中 spec_compliance_test.v 会把线上报文形状与官方 schema 逐项交叉比对。README 同时提醒:任何时候改动了 payload 字段,都要在这里补一个用例。
长耗时工具:进度与取消
如果注册的工具要跑较长时间(如示例的count_to),handler 收到的Context提供两个协作机制(README "Cancellation and progress" 一节):
- 客户端请求里带
_meta.progressToken时,handler 调用ctx.notify_progress(progress, total, message)上报进度; - 长循环中定期轮询
ctx.is_cancelled()——客户端发送notifications/cancelled后该标记翻转为true,直到请求结束。示例的count_to就是在循环里检查它并提前返回'cancelled at ${i - 1}'。
这两个机制是可选项:纯短耗时工具(如echo)不需要处理ctx。
已知限制
- Tasks 工具(
tasks/*)与 OAuth 授权在能力表中均为 deferred,不可用; mcp.connect/mcp.connect_http只面向 Streamable HTTP 端点;stdio 场景要用mcp.connect_stdio启动子进程;- HTTP 模式的
Origin校验默认只放行回环来源,跨机器接入时务必显式配置allowed_origins,避免所有请求被 403 拒绝。
完成v test vlib/mcp与客户端握手验证后,这个 V 编写的 MCP Server 就可以作为常驻服务挂给 AI 客户端使用了。
【免费下载链接】vSimple, fast, safe, compiled language for developing maintainable software. Compiles itself in <1s with zero library dependencies. Supports automatic C => V translation. https://vlang.io项目地址: https://gitcode.com/GitHub_Trending/v/v
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考