What is a reasoning harness?

A runtime layer your agent calls before generating output. One call returns the discipline for the task: a failure mode to block, an approach to follow, a checkpoint, and shortcuts to suppress.

Without the harness, the agent accepts its first interpretation and stops checking. The errors compound silently across the chain.

With it, the agent reads the failure mode before it generates, follows the approach, runs the check. Same model, different reasoning shape.

Two endpoints. Pick whichever fits how your agent talks.

Pick MCP if you're plugging into a client that already speaks it. Pick REST if you're writing the agent code yourself.

MCP

api.ejentum.com/mcp

If your agent speaks MCP (Claude Code, Claude Desktop, Cursor, Windsurf, others), point it here. No code.

# Claude Code
claude mcp add ejentum --transport http \
  https://api.ejentum.com/mcp

# Any MCP client
URL: https://api.ejentum.com/mcp
Header: Authorization: Bearer YOUR_KEY
MCP guide

REST API

api.ejentum.com/harness/

Anything else, one HTTP call. Bearer auth, JSON in, JSON out.

curl -X POST https://api.ejentum.com/harness/ \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query":"...","mode":"reasoning"}'
API reference

Dynamic and adaptive.

Dynamic

The harness retrieves the best-fit reasoning operation for your task and returns it as-is. Same operation works for many tasks of the same kind. Pool: 1,000 calls on Go, 5,000 on Super, 1,000 in the free trial.

Adaptive

The harness retrieves the same operation, then rewrites the approach to fit the specific shape of your task. The safety locks (failure guard, suppression, checkpoint) stay frozen. Higher quality per call, costs more compute. Pool: 250 calls on Go, 1,500 on Super. Not in the free trial.

In the API: pass mode: reasoning for dynamic, mode: adaptive-reasoning for adaptive. Same pattern across the other three.

What comes back.

Query sent: "We changed the checkout flow and conversion rose. Did the change cause it?"

[
  {
    "reasoning": "
      [PROCEDURE]
      Step 1: Identify the intervention, variable, or agent whose impact
              is being attributed.
      Step 2: Simulate the counterfactual world where ONLY that element
              is absent while all correlated variables are held at their
              natural values.
      Step 3: Compute the difference between the factual and counterfactual
              outcome distributions.
      Step 4: Check SUTVA (Stable Unit Treatment Value Assumption) and flag
              violations where removal of the target variable changes the
              values of the supposedly held-constant covariates.
      Step 5: Reject attribution claims that do not survive the isolation
              test, where a proposed cause is actually a proxy for a
              correlated variable that carries the true causal load.

      [REASONING TOPOLOGY]
      N{accept_attribution_based_correlation_alone} → FORK:
      ├→ S1a:simulate_factual(with_intervention) → ACTUAL[]
      └→ S1b:simulate_counterfactual(without_intervention,
              hold_covariates) → CONTROL[]
      → JOIN → C{causal_impact = outcome(factual)
                              - outcome(counterfactual)}
      → S2:apply_causal_impact → S3:check_SUTVA
      → G1{covariates_shift?}
        --yes→ FLAG:contaminated_isolation → OUT:invalid_attribution
        --no→ G2{attribution_survives?}
              --yes→ OUT:confirmed_impact
              --no→ REJECT:proxy_for_correlated_var → OUT:rejected

      [COGNITIVE PAYLOAD]
      Amplify: potential outcomes simulation; counterfactual world
               construction; SUTVA enforcement
      Suppress: correlation based attribution; shared variance credit diffusion
      Cognitive Style: potential outcomes simulation

      [FALSIFICATION TEST]
      If the effect of a specific variable is estimated without verifying
      controlling for correlated co-variables, impact isolation was not
      performed.

      [NEGATIVE GATE]
      The sales increase is attributed to the new marketing campaign,
      ignoring correlated economic factors and treatment spillover.

      [TARGET PATTERN]
      The effect of a variable is credited only after the counterfactual is
      simulated and correlated factors are held fixed. Attribution is accepted
      when it survives the isolation test, and rejected when the proposed cause
      is a proxy for a correlated variable carrying the true causal load.
    "
  }
]

Live output from the production API. Adaptive rewrites PROCEDURE and REASONING TOPOLOGY (and DETECTION TOPOLOGY for anti-deception) to fit the task. The COGNITIVE PAYLOAD, FALSIFICATION / INTEGRITY CHECK, and NEGATIVE GATE / DECEPTION PATTERN stay frozen. Toggle to compare across the three harnesses.

Already on a framework? We ship the tool.

Install the shim. The harness becomes a tool your agent calls. No manual HTTP plumbing.

CrewAI

from crewai import Agent
from crewai_ejentum import EjentumTool

agent = Agent(
  role="Senior Engineer",
  goal="Review code for security issues",
  tools=[EjentumTool(mode="code")],
)

Also for TypeScript

Vercel AI SDK, Mastra, LangGraph, Genkit, n8n.

Also for Python

LangChain, Agno, LlamaIndex, Pydantic AI, smolagents, Letta, Autogen.

Two endpoints. Four modes. One JSON per call. That's the full surface.