返回市场
内麦服

内麦服

作者:gokr16 星标更新:2025-09-01

项目介绍

NimCP - 在Nim中轻松创建模型上下文协议(MCP)服务器

Nim License

NimCP 是一个基于宏的库,用于在 Nim 中创建 模型上下文协议 (MCP) 服务器。它利用 Nim 的宏系统提供了一个极其易于使用的 API,用于构建与 LLM 应用无缝集成的 MCP 服务器。

注意:此库的99.9%是由Claude Code编写的!

特性

  • 宏驱动的API - 使用简单、声明式的语法定义服务器、工具、资源和提示
  • 完整的MCP 2024-11-05支持 - 完整实现MCP规范,采用JSON-RPC 2.0
  • 多种传输方式 - 支持标准输入输出、服务器发送事件(SSE)、HTTP和WebSocket传输
  • 增强的类型系统 - 支持对象、联合类型、枚举、可选类型和数组
  • 自动模式生成 - 从Nim类型签名生成JSON模式
  • 请求上下文系统 - 进度跟踪、取消和请求生命周期管理
  • 资源URI模板 - 动态URI模式,带参数提取 (/users/{id})
  • 服务器组合 - 将多个MCP服务器组合成单个接口,带有前缀和路由
  • 插件式日志系统 - 灵活的日志系统,具有多个处理器、级别和结构化输出
  • 中间件管道 - 请求/响应转换和处理钩子
  • 流畅API - 方法链模式,用于优雅的服务器配置
  • 高性能 - 基于Mummy的HTTP和WebSockets实现
  • 并发处理 - 使用新的任务池库进行标准输入输出传输
  • 最小依赖 - 仅使用基本且维护良好的包

快速开始

安装

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"

上下文感知工具 vs 普通工具

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服务器的方法:

  1. 将MCP服务器添加到Claude Code:
claude mcp add basic_calculator --transport stdio $PWD/examples/basic_calculator
  1. 验证是否已添加:
claude mcp list
  1. 从Claude Code内部测试服务器:

一旦添加,您应该能够在Claude Code对话中直接使用计算器工具:

  • add: 将两个数字相加
  • multiply: 将两个数字相乘
  • power: 计算幂
  • math://constants: 访问数学常量资源

在Claude Code中的示例用法:

  • "你能帮我计算15加27吗?"
  • "12的三次方是多少?"
  • "显示数学常量"

如果CLI方法不起作用,您可以手动编辑您的MCP配置文件(通常位于~/.claude.json)。只需更改路径为您所拥有的:

{
  "mcpServers": {
    "calculator_server": {
      "type": "stdio",
      "command": "/path/to/examples/calculator_server",
      "args": [],
      "env": {}
    }
  }
}

测试

运行测试套件:

nimble test

贡献

欢迎贡献!请随时提交Pull Request。

许可证

MIT许可证。详情见LICENSE

MCP资源