NimCP

Uma biblioteca poderosa baseada em macros para criar servidores Model Context Protocol (MCP) na linguagem de programação Nim.

Documentação

NimCP - Servidores de Model Context Protocol (MCP) Fáceis em Nim

Nim License

NimCP é uma biblioteca baseada em macros para criar servidores Model Context Protocol (MCP) em Nim. Ela aproveita o sistema de macros do Nim para fornecer uma API incrivelmente fácil de usar para construir servidores MCP que se integram perfeitamente com aplicações LLM.

NOTA: 99,9% desta biblioteca foi escrita usando Claude Code!

Recursos

  • API Orientada a Macros - Defina servidores, ferramentas, recursos e prompts com sintaxe declarativa simples
  • Suporte Completo ao MCP 2024-11-05 - Implementação completa da especificação MCP com JSON-RPC 2.0
  • Múltiplos Transportes - Suporta transportes stdio, SSE, HTTP e WebSocket
  • Sistema de Tipos Aprimorado - Suporte para objetos, uniões, enums, tipos opcionais e arrays
  • Geração Automática de Esquemas - Esquemas JSON gerados a partir de assinaturas de tipos Nim
  • Sistema de Contexto de Requisição - Rastreamento de progresso, cancelamento e gerenciamento do ciclo de vida de requisições
  • Modelos de URI de Recursos - Padrões de URI dinâmicos com extração de parâmetros (/users/{id})
  • Composição de Servidores - Componha múltiplos servidores MCP em uma única interface com prefixos e roteamento
  • Registro Flexível - Sistema de registro flexível com múltiplos manipuladores, níveis e saída estruturada
  • Pipeline de Middleware - Ganchos de transformação e processamento de requisição/resposta
  • API Fluente - Padrões de encadeamento de métodos para configuração elegante de servidores
  • Alto Desempenho - Implementação HTTP e WebSockets baseada em Mummy
  • Processamento Concorrente - Usa a nova biblioteca taskpools para transporte stdio
  • Dependências Mínimas - Usa apenas pacotes essenciais e bem mantidos

Início Rápido

Instalação

nimble install nimcp

Exemplo Simples

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)

É isso! Seu servidor MCP está pronto para executar.

Conceitos Principais

Ferramentas

Ferramentas são funções que aplicações LLM podem chamar. Defina-as com a macro mcpTool que extrai o nome da ferramenta, descrição e esquema JSON da assinatura do procedimento e comentários de documentação:

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

Ferramentas Cientes de Contexto vs. Regulares

NimCP também suporta ferramentas cientes de contexto que também recebem o contexto do servidor para acessar o estado do servidor e informações de requisição:

# 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)])

Quando usar Ferramentas Cientes de Contexto:

  • Eventos iniciados pelo servidor
  • Acesso à configuração do servidor ou recursos específicos do transporte
  • Integração personalizada de registro ou middleware
  • Gerenciamento de estado específico de requisições

Métodos de Registro Manual:

  • server.registerTool(tool, handler) - Ferramentas regulares
  • server.registerToolWithContext(tool, handler) - Ferramentas cientes de contexto
  • O mesmo padrão se aplica a recursos e prompts

Recursos

Recursos fornecem dados que podem ser lidos por aplicações LLM:

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

Prompts

Prompts são modelos reutilizáveis para interações 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)
      )
    ]

Criação Manual de Servidores

Para mais controle, você pode criar 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()

Composição de Servidores

NimCP suporta compor múltiplos servidores em uma única interface - perfeito para gateways 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

Tratamento de Erros

NimCP lida automaticamente com erros JSON-RPC, mas você pode lançar exceções em seus manipuladores:

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

Exemplos

Confira o diretório examples/ para exemplos abrangentes e veja o README de exemplos para mais informações.

Direto da linha de comando você pode testar e listar ferramentas com, por exemplo:

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

Se você estiver usando Claude Code, é assim que você pode adicioná-lo como um servidor MCP:

  1. Adicione o servidor MCP ao Claude Code:
claude mcp add basic_calculator --transport stdio $PWD/examples/basic_calculator
  1. Verifique se foi adicionado:
claude mcp list
  1. Teste o servidor de dentro do Claude Code:

Uma vez adicionado, você deve ser capaz de usar as ferramentas de calculadora diretamente nas conversas do Claude Code:

  • add: Adiciona dois números
  • multiply: Multiplica dois números
  • power: Calcula exponenciação
  • math://constants: Acessa o recurso de constantes matemáticas

Exemplo de uso no Claude Code:

  • "Você pode adicionar 15 e 27 para mim?"
  • "Quanto é 12 elevado à potência de 3?"
  • "Mostre-me as constantes matemáticas"

Se o método CLI não funcionar, você pode editar manualmente seu arquivo de configuração MCP (geralmente em ~/.claude.json). Apenas mude o caminho para o que você tem:

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

Testes

Execute a suíte de testes:

nimble test

Contribuindo

Contribuições são bem-vindas! Sinta-se à vontade para enviar um Pull Request.

Licença

Licença MIT. Veja LICENSE para detalhes.

Recursos MCP