NimCP

Una biblioteca potente basada en macros para crear servidores del Protocolo de Contexto de Modelo (MCP) en el lenguaje de programación Nim.

Documentación

NimCP - Servidores de Model Context Protocol (MCP) fáciles en Nim

Nim License

NimCP es una biblioteca basada en macros para crear servidores de Model Context Protocol (MCP) en Nim. Aprovecha el sistema de macros de Nim para proporcionar una API increíblemente fácil de usar para construir servidores MCP que se integran perfectamente con aplicaciones LLM.

NOTA: ¡El 99.9% de esta biblioteca fue escrita usando Claude Code!

Características

  • API basada en macros - Define servidores, herramientas, recursos y prompts con una sintaxis simple y declarativa
  • Soporte completo de MCP 2024-11-05 - Implementación completa de la especificación MCP con JSON-RPC 2.0
  • Múltiples transportes - Soporta transportes stdio, SSE, HTTP y WebSocket
  • Sistema de tipos mejorado - Soporte para objetos, uniones, enums, tipos opcionales y arrays
  • Generación automática de esquemas - Esquemas JSON generados a partir de firmas de tipos de Nim
  • Sistema de contexto de solicitudes - Seguimiento de progreso, cancelación y gestión del ciclo de vida de solicitudes
  • Plantillas de URI de recursos - Patrones de URI dinámicos con extracción de parámetros (/users/{id})
  • Composición de servidores - Compone múltiples servidores MCP en una única interfaz con prefijos y enrutamiento
  • Registro conectable - Sistema de registro flexible con múltiples manejadores, niveles y salida estructurada
  • Pipeline de middleware - Hooks de transformación y procesamiento de solicitudes/respuestas
  • API fluida - Patrones de encadenamiento de métodos para una configuración elegante del servidor
  • Alto rendimiento - Implementación de HTTP y WebSockets basada en Mummy
  • Procesamiento concurrente - Utiliza la nueva biblioteca taskpools para el transporte stdio
  • Dependencias mínimas - Utiliza solo paquetes esenciales y bien mantenidos

Inicio rápido

Instalación

nimble install nimcp

Ejemplo simple

import nimcp
import strformat

let server = mcpServer("my-server", "1.0.0"):
  
  mcpTool:
    proc echo(text: string): string =
      ## Echo back the input text
      return "Echo: " & text
  
  mcpTool:
    proc add(a: float, b: float): string =
      ## Add two numbers together
      return $fmt"Result: {a + b}"

when isMainModule:
  # Use stdio transport (default):
  let transport = newStdioTransport()
  transport.serve(server)
  
  # Or use HTTP transport:
  # let transport = newMummyTransport(8080, "127.0.0.1")
  # transport.serve(server)
  
  # Or use WebSocket transport for real-time communication:
  # let transport = newWebSocketTransport(8080, "127.0.0.1")
  # transport.serve(server)

¡Eso es todo! Tu servidor MCP está listo para ejecutarse.

Conceptos principales

Herramientas

Las herramientas son funciones que las aplicaciones LLM pueden llamar. Defínelas con la macro mcpTool que extrae el nombre de la herramienta, la descripción y el esquema JSON de tu firma de procedimiento y comentarios de documentación:

mcpTool:
  proc calculate(expression: string): string =
    ## Perform mathematical calculations
    ## - expression: Mathematical expression to evaluate
    # Your calculation logic here
    return "Result: 42"

Herramientas conscientes del contexto vs. herramientas regulares

NimCP también soporta herramientas conscientes del contexto que también reciben el contexto del servidor para acceder al estado del servidor e información de solicitudes:

# Context aware tools need to have first parameter being an McpRequestContext
mcpTool:
  proc notifyTool(ctx: McpRequestContext, args: JsonNode): McpToolResult =
    ## Log request and track processing
    ctx.info("Processing notification request")
    
    # Your notification logic here
    let message = args.getOrDefault("message", %"").getStr()
    
    ctx.info("Notification processing complete")
    return McpToolResult(content: @[createTextContent("Notification: " & message)])

Cuándo usar herramientas conscientes del contexto:

  • Eventos iniciados por el servidor
  • Acceso a la configuración del servidor o características específicas del transporte
  • Integración personalizada de registro o middleware
  • Gestión de estado específico de solicitudes

Métodos de registro manual:

  • server.registerTool(tool, handler) - Herramientas regulares
  • server.registerToolWithContext(tool, handler) - Herramientas conscientes del contexto
  • El mismo patrón se aplica a recursos y prompts

Recursos

Los recursos proporcionan datos que pueden ser leídos por aplicaciones LLM:

mcpResource("data://config", "Configuration", "Application configuration"):
  proc get_config(uri: string): string =
    return readFile("config.json")

Prompts

Los prompts son plantillas reutilizables para interacciones con LLM:

mcpPrompt("code_review", "Code review prompt", @[
  McpPromptArgument(name: "language", description: some("Programming language")),
  McpPromptArgument(name: "code", description: some("Code to review"))
]):
  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(&"Review this {language} code for best practices and potential issues.")
      ),
      McpPromptMessage(
        role: User,
        content: createTextContent(code)
      )
    ]

Creación manual de servidores

Para más control, puedes crear servidores manualmente:

import nimcp

let server = newMcpServer("advanced-server", "2.0.0")

# Register tools manually
let tool = McpTool(
  name: "custom_tool",
  description: some("A custom tool"),
  inputSchema: %*{"type": "object"}
)

proc customHandler(args: JsonNode): McpToolResult =
  return McpToolResult(content: @[createTextContent("Custom result")])

server.registerTool(tool, customHandler)

# Run the server
try:
  let transport = newStdioTransport()
  transport.serve(server)
finally:
  server.shutdown()

Composición de servidores

NimCP soporta componer múltiples servidores en una única interfaz - perfecto para puertas de enlace de API:

import nimcp, nimcp/composed_server

# Create individual servers using macro API
let calculatorServer = mcpServer("calculator-service", "1.0.0"):
  mcpTool:
    proc add(a: float, b: float): string =
      ## Add two numbers together
      return fmt"Result: {a + b}"

let fileServer = mcpServer("file-service", "1.0.0"):
  mcpTool:
    proc readFile(path: string): string =
      ## Read contents of a file
      try:
        return readFile(path)
      except IOError as e:
        return fmt"Error reading file: {e.msg}"

# Compose them into a single gateway
let apiGateway = newComposedServer("api-gateway", "1.0.0")

# Mount each service with prefixes for namespacing
apiGateway.mountServerAt("/calc", calculatorServer, some("calc_"))
apiGateway.mountServerAt("/files", fileServer, some("file_"))

# Run the composed server
let transport = newStdioTransport()
transport.serve(apiGateway)

# Tools are now available as: calc_add, file_readFile

Manejo de errores

NimCP maneja automáticamente los errores JSON-RPC, pero puedes lanzar excepciones en tus manejadores:

mcpTool:
  proc validate(data: string): string =
    ## Validate input data
    if data.len == 0:
      raise newException(ValueError, "Empty data parameter")
    return "Valid!"

Ejemplos

Consulta el directorio examples/ para ver ejemplos completos y revisa el README de ejemplos para más información.

Desde la línea de comandos puedes probar y listar herramientas con, por ejemplo:

echo '{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}' | ./examples/calculator_server

Si estás usando Claude Code, así es como puedes agregarlo como servidor MCP:

  1. Agrega el servidor MCP a Claude Code:
claude mcp add basic_calculator --transport stdio $PWD/examples/basic_calculator
  1. Verifica que se haya agregado:
claude mcp list
  1. Prueba el servidor desde Claude Code:

Una vez agregado, deberías poder usar las herramientas de calculadora directamente en las conversaciones de Claude Code:

  • add: Suma dos números
  • multiply: Multiplica dos números
  • power: Calcula la exponenciación
  • math://constants: Accede al recurso de constantes matemáticas

Ejemplo de uso en Claude Code:

  • "¿Puedes sumar 15 y 27 por mí?"
  • "¿Cuánto es 12 elevado a la potencia de 3?"
  • "Muéstrame las constantes matemáticas"

Si el método CLI no funciona, puedes editar manualmente tu archivo de configuración de MCP (generalmente en ~/.claude.json). Solo cambia la ruta a la que tengas:

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

Pruebas

Ejecuta el conjunto de pruebas:

nimble test

Contribuciones

¡Las contribuciones son bienvenidas! No dudes en enviar un Pull Request.

Licencia

Licencia MIT. Consulta LICENSE para más detalles.

Recursos de MCP