CotForce MCP

Servidor MCP que impõe raciocínio passo a passo do tipo Chain-of-Thought — transforma modelos de 4B em raciocinadores metódicos.

Documentação

CotForce-MCP

Node MCP License

"Dê cérebros aos seus modelos pequenos."
CotForce impõe raciocínio passo a passo (Chain-of-Thought), transformando modelos de 4B parâmetros em raciocinadores metódicos.


Por que isso existe

Um Gemma de 4 bilhões de parâmetros não consegue resolver SEND + MORE = MONEY. É um quebra-cabeça criptoaritmético clássico — 8 dígitos únicos, 5 colunas, 4 valores de carry. Um modelo 4B puro chuta aleatoriamente. Ele alucina dígitos. Ele perde o controle dos carries após a coluna 2.

O mesmo modelo, com CotForce:

Step 1: Analyze the leftmost column. S+M+C3 = MO. Max sum is 19998. ∴ M=1.
Step 2: S+1+C3 = 10+O. With M=1 and carry, O must be 0.
Step 3: D+E = Y+10C1 → C1=1. Now R+C1=9 → C1=0→R=9 (used), C1=1→R=8.
...
Step 11: All digits assigned. 9567 + 1085 = 10652. Verified.

11 etapas estruturadas de raciocínio. Zero alucinações. Resposta correta.

CotForce não torna modelos pequenos mais inteligentes. Ele os força a pensar antes de falar — o que muitas vezes é tudo o que eles precisam.


⚡ Dois modos — uma linha de configuração

CotForce usa o protocolo de amostragem MCP (sampling/createMessage) para chamar LLMs. Se o seu cliente suportar (Claude Desktop, Cursor), nada extra é necessário.

Se não — ou se você estiver usando um modelo local como Gemma via LMStudio — mude para o modo HTTP direto:

{
  "mcpServers": {
    "cotforce": {
      "command": "node",
      "args": ["node_modules/@slbdn/cotforce-mcp/index.js"],
      "env": {
        "MODE": "direct",
        "API_BASE_URL": "http://localhost:1234/v1",
        "MODEL": "gemma-4-e4b-it-mlx"
      }
    }
  }
}

É isso. O mesmo Gemma 4B que não conseguia resolver SEND+MORE=MONEY acima — agora com CotForce, funcionando localmente através do LMStudio.


🚀 Recursos

  • Imposição rígida de CoT — força qualquer LLM a gerar JSON válido {reasoning, result} via prompts de sistema estritos e exemplos few-shot.
  • Parser adaptativo de múltiplas camadas — arquitetura de plug-ins com 5 parsers integrados (JSON direto, blocos cercados, XML/rótulos, balanceamento de chaves, recuperação truncada) em um pipeline ordenado por prioridade. Adicione parsers personalizados via interface CotParser. Selecione parsers via variável de ambiente COT_PARSERS.
    1. JSON direto (com remoção de cercas de código)
    2. JSON dentro de blocos cercados de markdown
    3. Extração de rótulos XML / heurística (<reasoning>, Reasoning:)
    4. Scanner de balanceamento de chaves para objetos JSON aninhados
  • Validação em tempo de execução com Zod — valida argumentos de ferramentas e saída CoT analisada com esquemas estritos.
  • Tentativas automáticas com aumento de temperatura — até 3 tentativas (configurável) com temperatura crescente e sufixos de correção.
  • Memória de rejeição por solicitação — sem estado global mutável; seguro sob chamadas de ferramentas concorrentes.
  • Orçamento de tokens com tiktoken — contagem precisa de tokens usando a codificação cl100k_base da OpenAI, com fallback para heurística de caracteres. Ajuste via REASONING_OVERHEAD.
  • Modelo configurável — defina a variável de ambiente MODEL para sugerir um modelo específico; deixe vazio para o padrão do host.
  • Prompts específicos por modelo — seleciona automaticamente prompts de sistema ajustados para Claude, GPT-4, Gemini e Grok com base em MODEL.
  • Compatibilidade universal — funciona com amostragem MCP (Claude Desktop) ou chamadas HTTP diretas de LLM (OpenAI, LMStudio, Ollama, qualquer API compatível com OpenAI). Defina API_KEY para usar o modo direto.
  • Registro estruturado — logs com timestamp e filtro por nível para stderr (suporta LOG_LEVEL).
  • Detecção de truncamento de saída — detecta quando a resposta do LLM atinge o limite de tokens e tenta novamente com uma dica de concisão (TRUNCATION_THRESHOLD).
  • Exposição de uso de tokens — cada resposta inclui contagens de tokens de entrada / saída / orçamento para que os chamadores possam otimizar.
  • Esquema de resultado fornecido pelo usuário — parâmetro opcional resultSchema valida o mapa de tipos do campo result; incompatibilidades acionam nova tentativa.
  • Métricas estruturadas — contadores em memória para solicitações, taxas de sucesso/falha, truncamentos, tentativas, latência e uso de tokens. Registrados no encerramento.
  • Suíte de testes abrangente — 151 testes cobrindo pipeline de parser, orçamento de tokens, métricas, validação de esquema, loop de tentativas, notificações de progresso, cache e integração do servidor MCP.

📦 Instalação

npm install @slbdn/cotforce-mcp
# or
git clone https://github.com/islobodan/cotforce-mcp
cd cotforce-mcp
npm install
npm run build

Requer Node.js ≥ 18.

Início rápido — Claude Desktop

Adicione a claude_desktop_config.json:

{
  "mcpServers": {
    "cotforce": {
      "command": "npx",
      "args": ["-y", "@slbdn/cotforce-mcp"],
      "env": {
        "MODEL": "claude-3-5-sonnet"
      }
    }
  }
}

Sem clone, sem build. npx -y baixa e executa diretamente do npm.


🔧 Configuração

O servidor é configurado via variáveis de ambiente (todas opcionais):

VariávelPadrãoDescrição
MODEL(não definido)Sugestão de nome do modelo (ex.: claude-3-5-sonnet, gpt-4o). Se vazio, nenhuma sugestão é enviada – o host MCP decide.
MAX_RETRIES2Número de tentativas antes de retornar a saída bruta.
BASE_TEMP0.1Temperatura inicial de amostragem.
TEMP_INCREMENT0.2Temperatura adicionada por tentativa.
TIMEOUT60000 / 120000Tempo limite de amostragem em ms (60s). O modo HTTP direto usa padrão mais longo (120s) pois modelos locais são mais lentos.
CACHE_TTL3600000TTL do cache de resultados em ms (padrão 1 hora). Defina como 0 para desativar.
CACHE_MAX_ENTRIES100Máximo de resultados em cache antes de remover os mais antigos.
COT_PARSERS(todos)Nomes de parsers separados por vírgula (ex.: direct-json,fenced-block). Ignora os demais.
TRUNCATION_THRESHOLD0.95Proporção de saída/orçamento que aciona a detecção de truncamento. Tenta recuperação de JSON truncado primeiro, depois tenta novamente com orçamento 1,5x.
REASONING_OVERHEAD800Sobrecarga fixa de tokens adicionada à fórmula de orçamento. Aumente para modelos verbosos.
FALLBACK_MODELS(não definido)Lista separada por vírgulas de modelos de fallback (ex.: gpt-4o,claude-3-5-sonnet). Alternados em caso de falha.
MODEautoauto, sampling ou direct. auto usa HTTP direto quando API_KEY está definido e o cliente não suporta amostragem.
API_KEY(não definido)Chave de API do LLM para modo HTTP direto. Opcional para endpoints locais (LMStudio, Ollama). Necessária para provedores remotos (OpenAI, Anthropic, etc.).
API_BASE_URLhttps://api.openai.comURL base para modo HTTP direto. Altere para LMStudio (http://localhost:1234/v1) ou outros provedores.
LOG_LEVELINFOUm de DEBUG, INFO, WARN, ERROR.

Exemplo

MODEL=gpt-4o MAX_RETRIES=3 BASE_TEMP=0.2 TEMP_INCREMENT=0.15 LOG_LEVEL=DEBUG npx @slbdn/cotforce-mcp

🧪 Uso

Como Ferramenta MCP

Adicione à configuração do seu cliente MCP. Um arquivo .mcp.json está incluído no pacote para descoberta automática por clientes como Cursor, VS Code e Windsurf. Copie a configuração relevante abaixo para as configurações do seu cliente:

Com amostragem MCP (Claude Desktop):

{
  "mcpServers": {
    "cotforce": {
      "command": "node",
      "args": ["/path/to/cotforce-mcp/index.js"],
      "env": {
        "MODEL": "claude-3-5-sonnet",
        "MAX_RETRIES": "2"
      }
    }
  }
}

Com HTTP direto de LLM (LMStudio, OpenAI, Ollama):

{
  "mcpServers": {
    "cotforce": {
      "command": "node",
      "args": ["/path/to/cotforce-mcp/index.js"],
      "env": {
        "MODE": "direct",
        "API_BASE_URL": "http://localhost:1234/v1",
        "MODEL": "local-model",
        "MAX_RETRIES": "2"
      }
    }
  }
}

Nota: API_KEY é opcional para endpoints locais como LMStudio ou Ollama. É necessária para provedores remotos como OpenAI ou Anthropic.

O index.js raiz é um lançador que delega para dist/index.js. Ele protege contra builds ausentes com uma mensagem de erro útil.


🩺 Solução de Problemas

Resposta truncada no meio do raciocínio

O que você vê: finish_reason: "length" na resposta do LLM. O raciocínio é cortado antes do campo result.

Por quê: O orçamento de tokens é muito apertado. Raciocínio complexo (como SEND+MORE=MONEY) pode precisar de 3000+ tokens de saída, mas o mínimo padrão é 4096 — enquanto o limite padrão no nível do modelo pode variar.

Correção: Aumente a sobrecarga do orçamento:

REASONING_OVERHEAD=1600  # default is 800, raise for verbose models

Ou pule camadas de parser com uso intenso de tokens para economizar orçamento para o raciocínio:

COT_PARSERS=direct-json,fenced-block  # skip heuristic and brace-balanced

Tempo limite do cliente MCP

O que você vê: MCP error -32001: Request timed out antes da solução aparecer.

Por quê: Raciocínio CoT complexo leva tempo — 60-90 segundos para modelos locais como Gemma. Este erro pode vir de dois lugares:

  1. Tempo limite do próprio CotForce — padrão de 120s para modo HTTP direto. Controlado pela variável de ambiente TIMEOUT.
  2. Tempo limite do cliente MCP — LM Studio, Claude Desktop, Cursor, etc. cada um tem seu próprio tempo limite padrão para chamadas de ferramentas (frequentemente 30-60s). Isso é separado do tempo limite do CotForce.

Correção — verifique ambos os lados:

Aumente o tempo limite do CotForce:

TIMEOUT=180000  # 3 minutes

Verifique a configuração de tempo limite do seu cliente MCP:

LM Studio — adicione "timeout" ao mcp.json (em milissegundos):

{
  "mcpServers": {
    "cotforce": {
      "command": "node",
      "args": ["index.js"],
      "env": {
        "TIMEOUT": "180000"
      },
      "timeout": 300000
    }
  }
}

Claude Desktop — o tempo limite de chamada de ferramenta não é diretamente configurável. Uma solução alternativa é aumentar o TIMEOUT do CotForce para concluir dentro da janela do cliente, ou usar um modelo mais rápido.

Cursor / VS Code — verifique a extensão MCP ou .vscode/mcp.json para uma configuração de timeout ou requestTimeout.


Chamar a Ferramenta

{
  "name": "solve_problem",
  "arguments": {
    "prompt": "What is 7 * 8 + 2?"
  }
}

Com Validação de Esquema de Resultado

{
  "name": "solve_problem",
  "arguments": {
    "prompt": "List the prime numbers between 10 and 20",
    "resultSchema": {
      "primes": "object",
      "count": "number"
    }
  }
}

Se o campo result não corresponder ao esquema, o servidor tenta novamente com uma dica de correção.

Mais Exemplos

Veja EXAMPLES.md para 16 exemplos diversos incluindo:

  • Quebra-cabeças de lógica, probabilidade, problemas de palavras
  • Análise de código, regex, consultas SQL
  • Escrita criativa, adaptação de receitas
  • JSON aninhado com validação de esquema
  • Uso com diferentes modelos e fallbacks

Exemplo de Resposta

{
  "content": [{
    "type": "text",
    "text": "🤖 Agentic CoT Result:\n\n**Reasoning:** Step 1: Multiply 7 * 8 = 56. Step 2: Add 2 to get 58.\n\n**Answer:** 58\n\n📊 Token Usage: 42 in / 150 out / 4096 budget"
  }]
}

Se a análise falhar após todas as tentativas, o servidor retorna a saída bruta do LLM com um aviso.


🧩 Parsers Personalizados

O parser é um pipeline de plug-ins ordenado por prioridade. Cinco parsers integrados executam em ordem:

PrioridadeNomeO que faz
10direct-jsonAnalisa a saída inteira como JSON (remove cercas ```json)
20fenced-blockExtrai JSON de blocos de código markdown
30heuristicProcura por tags XML <reasoning>/<result> ou rótulos Reasoning:/Result:
40brace-balancedEncontra o primeiro {} balanceado em texto arbitrário
50truncated-recoveryRecupera raciocínio de JSON truncado (atingiu o limite de tokens)

Filtre parsers via variável de ambiente COT_PARSERS:

COT_PARSERS=direct-json,fenced-block node index.js

Escreva um parser personalizado:

import { CotParser, AgenticCotSchema } from "@slbdn/cotforce-mcp";

class YamlParser implements CotParser {
  name = "yaml";
  priority = 35; // runs after heuristic, before brace-balanced

  parse(raw: string): { reasoning: string; result: unknown } | null {
    // Custom YAML parsing logic here
    return null; // return null if this output isn't YAML
  }
}

Então registre-o programaticamente:

import { defaultParserPipeline, ParserPipeline } from "@slbdn/cotforce-mcp";
const pipeline = defaultParserPipeline();
pipeline.addParser(new YamlParser());
const result = pipeline.parse(rawText);

📚 API

Ferramenta: solve_problem

  • Entrada: { prompt: string } — o problema a resolver.
  • Saída: ou:
    • Sucesso — resultado CoT estruturado.
    • Falha suave — saída bruta do LLM se a análise falhar após todas as tentativas.

Amostragem / Chamada de LLM

CotForce suporta dois modos para chamar o LLM:

Amostragem MCP (padrão com clientes compatíveis):

  • Usa sampling/createMessage nativo do MCP
  • O cliente seleciona e chama o modelo
  • Requer suporte do cliente (Claude Desktop, etc.)

HTTP Direto (para clientes sem suporte a amostragem):

  • Chama /v1/chat/completions compatível com OpenAI diretamente
  • Funciona com OpenAI, LMStudio, Ollama e qualquer provedor compatível
  • Ativado automaticamente em MODE=auto quando API_KEY está definido e o cliente não tem amostragem
  • Ou force com MODE=direct

Ambos os modos usam o mesmo prompt de sistema com exemplos few-shot e restrições estritas de esquema.


🏗️ Arquitetura

cotforce-mcp/
├── src/
│   ├── index.ts           # MCP server, tool handlers, routing logic
│   └── lib/
│       ├── parser.ts      # Parser pipeline: CotParser interface + 5 plugin parsers + Zod schemas
│       ├── tokens.ts      # tiktoken integration + budget computation
│       ├── prompts.ts     # Model-specific system prompts
│       ├── metrics.ts     # In-memory request/performance counters
│       └── llm.ts         # Direct HTTP LLM client (OpenAI-compatible)
├── tests/
│   ├── cache.test.ts      # 10 unit tests for result caching
│   ├── parser.test.ts     # 47 unit tests for parser layers
│   ├── tokens.test.ts     # 23 unit tests for token budgeting
│   ├── schema.test.ts     # 8 unit tests for result schema validation
│   ├── metrics.test.ts    # 9 unit tests for metrics tracking
│   ├── prompts.test.ts    # 12 unit tests for model-specific prompts
│   ├── llm.test.ts        # 6 tests for direct mode detection
│   ├── retry.test.ts      # 4 integration tests for retry loop
│   ├── progress.test.ts   # 5 unit tests for progress notifications
│   └── server.test.ts     # 9 integration tests via @slbdn/mcp-tester
├── index.js               # Root launcher (delegates to dist/)
├── dist/                  # Compiled TypeScript output
└── package.json

🧠 Como Funciona

  1. Prompt de sistema impõe saída JSON com reasoning e result. Variantes específicas por modelo ajustadas para Claude, GPT-4, Gemini, Grok.
  2. Pipeline de parser executa 5 parsers integrados em ordem de prioridade (JSON direto, blocos cercados, XML/rótulos, balanceamento de chaves, recuperação truncada). A primeira correspondência válida vence. Parsers personalizados podem ser adicionados via variável de ambiente COT_PARSERS e a interface CotParser.
  3. Lógica de tentativas — se a análise falhar, injeta sufixo de correção e aumenta a temperatura. Suporta modelos de fallback (FALLBACK_MODELS) quando o modelo primário recusa.
  4. Memória de rejeição armazena um trecho da última falha para contextualizar a próxima chamada (escopo por solicitação, seguro para threads).
  5. Orçamento de tokens usa estimateTokens() (heurística leve) para cálculos de orçamento e countTokens() (tiktoken) para contagens exatas. Define maxTokens dinamicamente (entre 4096 e 8192) via fórmula overhead + inputTokens × 4. Detecta truncamento via finish_reason: "length" e tenta recuperação de JSON antes de tentar novamente.

🛠️ Desenvolvimento

git clone https://github.com/islobodan/cotforce-mcp
cd cotforce-mcp
npm install
npm run build      # compile TypeScript to dist/
npm run dev        # tsc --watch
npm run typecheck  # type-check src/ and tests/

Scripts

ScriptFinalidade
npm run buildCompilar TypeScript (src/ → dist/)
npm run devCompilação em modo de observação
npm run typecheckVerificação de tipos TypeScript para código-fonte e testes
npm testExecutar a suíte completa de testes Jest (133 testes)
npm run test:smokeTeste rápido de fumaça via CLI mcp-tester
npm run test:toolsListar ferramentas disponíveis via CLI mcp-tester

Testes

A suíte de testes usa Jest com ts-jest (ESM) e @slbdn/mcp-tester para testes de integração do servidor MCP:

  • Testes de parser (tests/parser.test.ts) — 47 testes unitários cobrindo todos os 5 plugins de parser, casos extremos e validação de AgenticCotSchema.
  • Testes de token (tests/tokens.test.ts) — 16 testes unitários para integração com tiktoken, cálculo de orçamento e ajuste de REASONING_OVERHEAD.
  • Testes de esquema (tests/schema.test.ts) — 8 testes unitários para validação de resultSchema fornecidos pelo usuário.
  • Testes de métricas (tests/metrics.test.ts) — 9 testes unitários para contadores de requisições, rastreamento de latência e médias de uso de tokens.
  • Testes de prompt (tests/prompts.test.ts) — 10 testes unitários para seleção de prompt específico por modelo.
  • Testes de LLM (tests/llm.test.ts) — 3 testes unitários para detecção de modo HTTP direto.
  • Testes de servidor (tests/server.test.ts) — 11 testes de integração para descoberta de ferramentas, validação de argumentos, ciclo de vida do servidor e chamadas concorrentes.

Matchers personalizados do Jest estão disponíveis via @slbdn/mcp-tester:

expect(tools).toHaveTool("solve_problem");
expect(tools).toHaveToolWithSchema("solve_problem");
expect(result).toReturnTextContaining("Reasoning:");

⚠️ Limitações e Avaliação Honesta

  • Sem monitoramento de produção real — apenas logs estruturados; sem métricas agregadas.
  • A fórmula de orçamento de tokens é heurística — pode precisar de ajustes para modelos muito verbosos.
  • As sugestões de modelo são apenas recomendações — o host MCP decide qual modelo usar.
  • Consulte a lista de TODO para melhorias planejadas.

📄 Licença

MIT © Slobodan Ivkovic


⭐ Suporte

Se você achar o CotForce-MCP útil, considere dar uma estrela no repositório e compartilhar seu feedback!