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
"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 ambienteCOT_PARSERS.- JSON direto (com remoção de cercas de código)
- JSON dentro de blocos cercados de markdown
- Extração de rótulos XML / heurística (
<reasoning>,Reasoning:) - 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_baseda OpenAI, com fallback para heurística de caracteres. Ajuste viaREASONING_OVERHEAD. - Modelo configurável — defina a variável de ambiente
MODELpara 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_KEYpara 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
resultSchemavalida o mapa de tipos do camporesult; 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ável | Padrão | Descriçã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_RETRIES | 2 | Número de tentativas antes de retornar a saída bruta. |
BASE_TEMP | 0.1 | Temperatura inicial de amostragem. |
TEMP_INCREMENT | 0.2 | Temperatura adicionada por tentativa. |
TIMEOUT | 60000 / 120000 | Tempo limite de amostragem em ms (60s). O modo HTTP direto usa padrão mais longo (120s) pois modelos locais são mais lentos. |
CACHE_TTL | 3600000 | TTL do cache de resultados em ms (padrão 1 hora). Defina como 0 para desativar. |
CACHE_MAX_ENTRIES | 100 | Má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_THRESHOLD | 0.95 | Proporçã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_OVERHEAD | 800 | Sobrecarga 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. |
MODE | auto | auto, 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_URL | https://api.openai.com | URL base para modo HTTP direto. Altere para LMStudio (http://localhost:1234/v1) ou outros provedores. |
LOG_LEVEL | INFO | Um 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.jsraiz é um lançador que delega paradist/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:
- Tempo limite do próprio CotForce — padrão de 120s para modo HTTP direto. Controlado pela variável de ambiente
TIMEOUT. - 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:
| Prioridade | Nome | O que faz |
|---|---|---|
| 10 | direct-json | Analisa a saída inteira como JSON (remove cercas ```json) |
| 20 | fenced-block | Extrai JSON de blocos de código markdown |
| 30 | heuristic | Procura por tags XML <reasoning>/<result> ou rótulos Reasoning:/Result: |
| 40 | brace-balanced | Encontra o primeiro {} balanceado em texto arbitrário |
| 50 | truncated-recovery | Recupera 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/createMessagenativo 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/completionscompatível com OpenAI diretamente - Funciona com OpenAI, LMStudio, Ollama e qualquer provedor compatível
- Ativado automaticamente em
MODE=autoquandoAPI_KEYestá 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
- Prompt de sistema impõe saída JSON com
reasoningeresult. Variantes específicas por modelo ajustadas para Claude, GPT-4, Gemini, Grok. - 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_PARSERSe a interfaceCotParser. - 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. - Memória de rejeição armazena um trecho da última falha para contextualizar a próxima chamada (escopo por solicitação, seguro para threads).
- Orçamento de tokens usa
estimateTokens()(heurística leve) para cálculos de orçamento ecountTokens()(tiktoken) para contagens exatas. DefinemaxTokensdinamicamente (entre 4096 e 8192) via fórmulaoverhead + inputTokens × 4. Detecta truncamento viafinish_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
| Script | Finalidade |
|---|---|
npm run build | Compilar TypeScript (src/ → dist/) |
npm run dev | Compilação em modo de observação |
npm run typecheck | Verificação de tipos TypeScript para código-fonte e testes |
npm test | Executar a suíte completa de testes Jest (133 testes) |
npm run test:smoke | Teste rápido de fumaça via CLI mcp-tester |
npm run test:tools | Listar 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 deAgenticCotSchema. - Testes de token (
tests/tokens.test.ts) — 16 testes unitários para integração comtiktoken, cálculo de orçamento e ajuste deREASONING_OVERHEAD. - Testes de esquema (
tests/schema.test.ts) — 8 testes unitários para validação deresultSchemafornecidos 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!