NimCP 是一个基于宏的库,用于在 Nim 中创建 模型上下文协议 (MCP) 服务器。它利用 Nim 的宏系统提供了一个极其易于使用的 API,用于构建与 LLM 应用无缝集成的 MCP 服务器。
注意:此库的99.9%是由Claude Code编写的!
/users/{id})nimble install nimcp
import nimcp
import strformat
let server = mcpServer("my-server", "1.0.0"):
mcpTool:
proc echo(text: string): string =
## 回显输入文本
return "回显: " & text
mcpTool:
proc add(a: float, b: float): string =
## 将两个数字相加
return $fmt"结果: {a + b}"
when isMainModule:
# 使用标准输入输出传输(默认):
let transport = newStdioTransport()
transport.serve(server)
# 或者使用HTTP传输:
# let transport = newMummyTransport(8080, "127.0.0.1")
# transport.serve(server)
# 或者使用WebSocket传输进行实时通信:
# let transport = newWebSocketTransport(8080, "127.0.0.1")
# transport.serve(server)
就这样!你的MCP服务器已经准备好运行了。
工具是LLM应用可以调用的函数。使用mcpTool宏定义它们,该宏从您的过程签名和文档注释中提取工具名称、描述和JSON模式:
mcpTool:
proc calculate(expression: string): string =
## 执行数学计算
## - 表达式: 要评估的数学表达式
# 您的计算逻辑在这里
return "结果: 42"
NimCP还支持接收服务器上下文的上下文感知工具,以访问服务器状态和请求信息:
# 上下文感知工具需要第一个参数为McpRequestContext
mcpTool:
proc notifyTool(ctx: McpRequestContext, args: JsonNode): McpToolResult =
## 记录请求并跟踪处理
ctx.info("正在处理通知请求")
# 您的通知逻辑在这里
let message = args.getOrDefault("message", %"").getStr()
ctx.info("通知处理完成")
return McpToolResult(content: @[createTextContent("通知: " & message)])
何时使用上下文感知工具:
手动注册方法:
server.registerTool(tool, handler) - 普通工具server.registerToolWithContext(tool, handler) - 上下文感知工具资源提供可以被LLM应用读取的数据:
mcpResource("data://config", "配置", "应用程序配置"):
proc get_config(uri: string): string =
return readFile("config.json")
提示是LLM交互的可重用模板:
mcpPrompt("code_review", "代码审查提示", @[
McpPromptArgument(name: "language", description: some("编程语言")),
McpPromptArgument(name: "code", description: some("要审查的代码"))
]):
proc review_prompt(name: string, args: Table[string, JsonNode]): seq[McpPromptMessage] =
let language = args.getOrDefault("language", %"unknown").getStr()
let code = args.getOrDefault("code", %"").getStr()
return @[
McpPromptMessage(
role: System,
content: createTextContent(&"审查这段{language}代码的最佳实践和潜在问题。")
),
McpPromptMessage(
role: User,
content: createTextContent(code)
)
]
为了获得更多的控制,您可以手动创建服务器:
import nimcp
let server = newMcpServer("高级服务器", "2.0.0")
# 手动注册工具
let tool = McpTool(
name: "自定义工具",
description: some("一个自定义工具"),
inputSchema: %*{"type": "object"}
)
proc customHandler(args: JsonNode): McpToolResult =
return McpToolResult(content: @[createTextContent("自定义结果")])
server.registerTool(tool, customHandler)
# 运行服务器
try:
let transport = newStdioTransport()
transport.serve(server)
finally:
server.shutdown()
NimCP支持将多个服务器组合成单一接口——非常适合API网关:
import nimcp, nimcp/composed_server
# 使用宏API创建单独的服务器
let calculatorServer = mcpServer("计算器服务", "1.0.0"):
mcpTool:
proc add(a: float, b: float): string =
## 将两个数字相加
return fmt"结果: {a + b}"
let fileServer = mcpServer("文件服务", "1.0.0"):
mcpTool:
proc readFile(path: string): string =
## 读取文件内容
try:
return readFile(path)
except IOError as e:
return fmt"读取文件错误: {e.msg}"
# 将它们组合成单一网关
let apiGateway = newComposedServer("api网关", "1.0.0")
# 为命名空间挂载每个服务
apiGateway.mountServerAt("/calc", calculatorServer, some("calc_"))
apiGateway.mountServerAt("/files", fileServer, some("file_"))
# 运行组合服务器
let transport = newStdioTransport()
transport.serve(apiGateway)
# 工具现在可用为:calc_add, file_readFile
NimCP自动处理JSON-RPC错误,但您可以在处理程序中抛出异常:
mcpTool:
proc validate(data: string): string =
## 验证输入数据
if data.len == 0:
raise newException(ValueError, "空的数据参数")
return "有效!"
查看examples/目录中的综合示例,并参阅示例README获取更多信息。
只需从命令行测试和列出工具,例如:
echo '{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}' | ./examples/calculator_server
如果您使用的是Claude Code,这是如何将其添加为MCP服务器的方法:
claude mcp add basic_calculator --transport stdio $PWD/examples/basic_calculator
claude mcp list
一旦添加,您应该能够在Claude Code对话中直接使用计算器工具:
在Claude Code中的示例用法:
如果CLI方法不起作用,您可以手动编辑您的MCP配置文件(通常位于~/.claude.json)。只需更改路径为您所拥有的:
{
"mcpServers": {
"calculator_server": {
"type": "stdio",
"command": "/path/to/examples/calculator_server",
"args": [],
"env": {}
}
}
}
运行测试套件:
nimble test
欢迎贡献!请随时提交Pull Request。
MIT许可证。详情见LICENSE。