CotForce MCP

Servidor MCP que impone el razonamiento paso a paso (Chain-of-Thought) — convierte modelos 4B

Documentación

CotForce-MCP

Node MCP License

"Dale cerebro a tus modelos pequeños."
CotForce impone el razonamiento paso a paso (Chain-of-Thought), convirtiendo modelos de 4B parámetros en razonadores metódicos.


Por qué existe esto

Un Gemma de 4 mil millones de parámetros no puede resolver SEND + MORE = MONEY. Es un clásico acertijo criptoaritmético — 8 dígitos únicos, 5 columnas, 4 valores de acarreo. Un modelo 4B desnudo adivina al azar. Alucina dígitos. Pierde el rastro de los acarreos después de la columna 2.

El mismo modelo, con 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 pasos estructurados de razonamiento. Cero alucinaciones. Respuesta correcta.

CotForce no hace más inteligentes a los modelos pequeños. Los obliga a pensar antes de hablar — que suele ser todo lo que necesitan.


⚡ Dos modos — una línea de configuración

CotForce usa el protocolo de muestreo MCP (sampling/createMessage) para llamar a los LLM. Si tu cliente lo soporta (Claude Desktop, Cursor), no necesitas nada adicional.

Si no — o si estás usando un modelo local como Gemma vía LMStudio — cambia al modo HTTP directo:

{
  "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"
      }
    }
  }
}

Eso es todo. El mismo Gemma 4B que no podía resolver SEND+MORE=MONEY arriba — ahora con CotForce, funcionando localmente a través de LMStudio.


🚀 Características

  • Imposición rígida de CoT — obliga a cualquier LLM a generar JSON válido {reasoning, result} mediante prompts de sistema estrictos y ejemplos few-shot.
  • Parser adaptativo multicapa — arquitectura de plugins con 5 parsers integrados (JSON directo, bloques delimitados, XML/etiquetas, balanceo de llaves, recuperación truncada) en un pipeline ordenado por prioridad. Añade parsers personalizados vía la interfaz CotParser. Selecciona parsers mediante la variable de entorno COT_PARSERS.
    1. JSON directo (con eliminación de cercas de código)
    2. JSON dentro de bloques delimitados de markdown
    3. Extracción por XML / etiquetas heurísticas (<reasoning>, Reasoning:)
    4. Escáner de balanceo de llaves para objetos JSON anidados
  • Validación en tiempo de ejecución con Zod — valida argumentos de herramientas y salida CoT parseada con esquemas estrictos.
  • Reintento automático con aumento de temperatura — hasta 3 intentos (configurable) con temperatura creciente y sufijos de corrección.
  • Memorándum de rechazo por solicitud — sin estado mutable global; seguro bajo llamadas concurrentes a herramientas.
  • Presupuesto de tokens con tiktoken — conteo preciso de tokens usando la codificación cl100k_base de OpenAI, con respaldo a heurística de caracteres. Ajusta vía REASONING_OVERHEAD.
  • Modelo configurable — establece la variable de entorno MODEL para sugerir un modelo específico; déjala sin definir para el predeterminado del host.
  • Prompts específicos por modelo — selecciona automáticamente prompts de sistema ajustados para Claude, GPT-4, Gemini y Grok según MODEL.
  • Compatibilidad universal — funciona con muestreo MCP (Claude Desktop) o llamadas HTTP directas a LLM (OpenAI, LMStudio, Ollama, cualquier API compatible con OpenAI). Establece API_KEY para usar modo directo.
  • Registro estructurado — registros con marca de tiempo y filtro por nivel a stderr (soporta LOG_LEVEL).
  • Detección de truncamiento de salida — detecta cuando la respuesta del LLM alcanza el límite de tokens y reintenta con una pista de concisión (TRUNCATION_THRESHOLD).
  • Exposición de uso de tokens — cada respuesta incluye conteos de tokens de entrada / salida / presupuesto para que los llamadores puedan optimizar.
  • Esquema de resultado proporcionado por el usuario — el parámetro opcional resultSchema valida el mapa de tipos del campo result; las discrepancias provocan reintentos.
  • Métricas estructuradas — contadores en memoria para solicitudes, tasas de éxito/fallo, truncamientos, reintentos, latencia y uso de tokens. Registrados al apagar.
  • Suite de pruebas integral — 151 pruebas que cubren el pipeline de parsers, presupuesto de tokens, métricas, validación de esquemas, bucle de reintentos, notificaciones de progreso, caché e integración del servidor MCP.

📦 Instalación

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

Requiere Node.js ≥ 18.

Inicio rápido — Claude Desktop

Añade a claude_desktop_config.json:

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

Sin clonar, sin compilar. npx -y descarga y ejecuta directamente desde npm.


🔧 Configuración

El servidor se configura mediante variables de entorno (todas opcionales):

VariablePredeterminadoDescripción
MODEL(no definida)Sugerencia de nombre de modelo (p. ej. claude-3-5-sonnet, gpt-4o). Si está vacía, no se envía sugerencia – el host MCP decide.
MAX_RETRIES2Número de intentos de reintento antes de devolver la salida cruda.
BASE_TEMP0.1Temperatura inicial de muestreo.
TEMP_INCREMENT0.2Temperatura añadida por cada intento de reintento.
TIMEOUT60000 / 120000Tiempo de espera de muestreo en ms (60s). El modo HTTP directo usa un valor predeterminado más largo (120s) porque los modelos locales son más lentos.
CACHE_TTL3600000TTL de caché de resultados en ms (predeterminado 1 hora). Establece a 0 para desactivar.
CACHE_MAX_ENTRIES100Máximo de resultados en caché antes de expulsar los más antiguos.
COT_PARSERS(todos)Nombres de parsers separados por comas a usar (p. ej., direct-json,fenced-block). Omite los demás.
TRUNCATION_THRESHOLD0.95Proporción de salida/presupuesto que activa la detección de truncamiento. Primero intenta recuperar JSON truncado, luego reintenta con 1.5x de presupuesto.
REASONING_OVERHEAD800Sobrecarga fija de tokens añadida a la fórmula de presupuesto. Auméntala para modelos verbosos.
FALLBACK_MODELS(no definida)Lista separada por comas de modelos de respaldo (p. ej. gpt-4o,claude-3-5-sonnet). Se recorren en caso de fallo.
MODEautoauto, sampling o direct. auto usa HTTP directo cuando API_KEY está definida y el cliente carece de soporte de muestreo.
API_KEY(no definida)Clave API del LLM para modo HTTP directo. Opcional para endpoints locales (LMStudio, Ollama). Requerida para proveedores remotos (OpenAI, Anthropic, etc.).
API_BASE_URLhttps://api.openai.comURL base para modo HTTP directo. Cámbiala para LMStudio (http://localhost:1234/v1) u otros proveedores.
LOG_LEVELINFOUno de DEBUG, INFO, WARN, ERROR.

Ejemplo

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

🧪 Uso

Como herramienta MCP

Añade a la configuración de tu cliente MCP. Se incluye un archivo .mcp.json en el paquete para auto-descubrimiento por clientes como Cursor, VS Code y Windsurf. Copia la configuración relevante a los ajustes de tu cliente:

Con muestreo MCP (Claude Desktop):

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

Con HTTP directo a 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 es opcional para endpoints locales como LMStudio u Ollama. Es requerida para proveedores remotos como OpenAI o Anthropic.

El index.js raíz es un lanzador que delega en dist/index.js. Protege contra builds faltantes con un mensaje de error útil.


🩺 Solución de problemas

Respuesta truncada a mitad del razonamiento

Lo que ves: finish_reason: "length" en la respuesta del LLM. El razonamiento se corta antes del campo result.

Por qué: El presupuesto de tokens es demasiado ajustado. Un razonamiento complejo (como SEND+MORE=MONEY) puede necesitar 3000+ tokens de salida, pero el mínimo predeterminado es 4096 — mientras que el límite predeterminado a nivel de modelo puede variar.

Solución: Aumenta la sobrecarga del presupuesto:

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

O salta las capas de parser que consumen muchos tokens para ahorrar presupuesto para el razonamiento:

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

Tiempo de espera agotado del cliente MCP

Lo que ves: MCP error -32001: Request timed out antes de que aparezca la solución.

Por qué: El razonamiento CoT complejo lleva tiempo — 60-90 segundos para modelos locales como Gemma. Este error puede venir de dos lugares:

  1. El propio tiempo de espera de CotForce — predeterminado 120s para modo HTTP directo. Controlado por la variable de entorno TIMEOUT.
  2. El tiempo de espera del cliente MCP — LM Studio, Claude Desktop, Cursor, etc. tienen cada uno su propio tiempo de espera predeterminado para llamadas a herramientas (a menudo 30-60s). Esto es independiente del tiempo de espera de CotForce.

Solución — revisa ambos lados:

Aumenta el tiempo de espera de CotForce:

TIMEOUT=180000  # 3 minutes

Revisa el ajuste de tiempo de espera de tu cliente MCP:

LM Studio — añade "timeout" a mcp.json (milisegundos):

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

Claude Desktop — el tiempo de espera de llamadas a herramientas no es directamente configurable. Un workaround es aumentar el TIMEOUT de CotForce para completar dentro de la ventana del cliente, o usar un modelo más rápido.

Cursor / VS Code — revisa la extensión MCP o .vscode/mcp.json para un ajuste de timeout o requestTimeout.


Llama a la herramienta

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

Con validación de esquema de resultado

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

Si el campo result no coincide con el esquema, el servidor reintenta con una pista de corrección.

Más ejemplos

Consulta EXAMPLES.md para 16 ejemplos diversos que incluyen:

  • Acertijos de lógica, probabilidad, problemas de palabras
  • Análisis de código, regex, consultas SQL
  • Escritura creativa, adaptación de recetas
  • JSON anidado con validación de esquema
  • Uso con diferentes modelos y respaldos

Ejemplo de respuesta

{
  "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"
  }]
}

Si el parseo falla tras todos los reintentos, el servidor devuelve la salida cruda del LLM con una advertencia.


🧩 Parsers personalizados

El parser es un pipeline de plugins ordenado por prioridad. Cinco parsers integrados se ejecutan en orden:

PrioridadNombreQué hace
10direct-jsonParsea toda la salida como JSON (elimina cercas ```json)
20fenced-blockExtrae JSON de bloques de código markdown
30heuristicBusca etiquetas XML <reasoning>/<result> o etiquetas Reasoning:/Result:
40brace-balancedEncuentra el primer {} balanceado en texto arbitrario
50truncated-recoveryRecupera razonamiento de JSON truncado (alcanzó el límite de tokens)

Filtra parsers vía la variable de entorno COT_PARSERS:

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

Escribe un 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
  }
}

Luego regístralo programáticamente:

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

📚 API

Herramienta: solve_problem

  • Entrada: { prompt: string } — el problema a resolver.
  • Salida: ya sea:
    • Éxito — resultado CoT estructurado.
    • Fallo suave — salida cruda del LLM si el parseo falla tras todos los reintentos.

Muestreo / Llamada al LLM

CotForce soporta dos modos para llamar al LLM:

Muestreo MCP (predeterminado con clientes compatibles):

  • Usa sampling/createMessage nativo de MCP
  • El cliente selecciona y llama al modelo
  • Requiere soporte del cliente (Claude Desktop, etc.)

HTTP directo (para clientes sin soporte de muestreo):

  • Llama directamente a /v1/chat/completions compatible con OpenAI
  • Funciona con OpenAI, LMStudio, Ollama y cualquier proveedor compatible
  • Se activa automáticamente en MODE=auto cuando API_KEY está definida y el cliente carece de muestreo
  • O fuerza con MODE=direct

Ambos modos usan el mismo prompt de sistema con ejemplos few-shot y restricciones estrictas de esquema.


🏗️ Arquitectura

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

🧠 Cómo funciona

  1. El prompt de sistema impone salida JSON con reasoning y result. Variantes específicas por modelo ajustadas para Claude, GPT-4, Gemini, Grok.
  2. El pipeline de parsers ejecuta 5 parsers integrados en orden de prioridad (JSON directo, bloques delimitados, XML/etiquetas, balanceo de llaves, recuperación truncada). La primera coincidencia válida gana. Se pueden añadir parsers personalizados vía la variable de entorno COT_PARSERS y la interfaz CotParser.
  3. Lógica de reintento — si el parseo falla, inyecta un sufijo de corrección y aumenta la temperatura. Soporta modelos de respaldo (FALLBACK_MODELS) cuando el modelo principal se niega.
  4. Memoria de rechazo almacena un fragmento del último fallo para contextualizar la siguiente llamada (limitada por solicitud, segura para hilos).
  5. Presupuesto de tokens usa estimateTokens() (heurística ligera) para el cálculo del presupuesto y countTokens() (tiktoken) para conteos exactos. Establece maxTokens dinámicamente (entre 4096 y 8192) mediante la fórmula overhead + inputTokens × 4. Detecta truncamiento vía finish_reason: "length" e intenta recuperación JSON antes de reintentar.

🛠️ Desarrollo

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

ScriptPropósito
npm run buildCompilar TypeScript (src/ → dist/)
npm run devCompilación en modo de observación
npm run typecheckVerificación de tipos de TypeScript para código fuente y pruebas
npm testEjecutar la suite completa de pruebas Jest (133 pruebas)
npm run test:smokePrueba rápida de humo mediante la CLI de mcp-tester
npm run test:toolsListar herramientas disponibles mediante la CLI de mcp-tester

Pruebas

La suite de pruebas utiliza Jest con ts-jest (ESM) y @slbdn/mcp-tester para pruebas de integración del servidor MCP:

  • Pruebas de parser (tests/parser.test.ts) — 47 pruebas unitarias que cubren los 5 plugins de parser, casos límite y validación de AgenticCotSchema.
  • Pruebas de tokens (tests/tokens.test.ts) — 16 pruebas unitarias para integración de tiktoken, cálculo de presupuesto y ajuste de REASONING_OVERHEAD.
  • Pruebas de esquema (tests/schema.test.ts) — 8 pruebas unitarias para validación de resultSchema proporcionado por el usuario.
  • Pruebas de métricas (tests/metrics.test.ts) — 9 pruebas unitarias para contadores de solicitudes, seguimiento de latencia y promedios de uso de tokens.
  • Pruebas de prompts (tests/prompts.test.ts) — 10 pruebas unitarias para selección de prompts específicos del modelo.
  • Pruebas de LLM (tests/llm.test.ts) — 3 pruebas unitarias para detección de modo HTTP directo.
  • Pruebas de servidor (tests/server.test.ts) — 11 pruebas de integración para descubrimiento de herramientas, validación de argumentos, ciclo de vida del servidor y llamadas concurrentes.

Los matchers personalizados de Jest están disponibles mediante @slbdn/mcp-tester:

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

⚠️ Limitaciones y Evaluación Honesta

  • Sin monitoreo de producción real — solo registros estructurados; sin métricas agregadas.
  • La fórmula de presupuesto de tokens es heurística — puede requerir ajustes para modelos muy verbosos.
  • Las sugerencias de modelo son recomendaciones — el host de MCP decide qué modelo usar.
  • Consulta la lista de tareas pendientes para mejoras planificadas.

📄 Licencia

MIT © Slobodan Ivkovic


⭐ Soporte

Si encuentras útil CotForce-MCP, ¡considera dar una estrella al repositorio y compartir tus comentarios!