Reasoning · by SeKondBrain
Platform · reasoning engine · MCP + REST

Where the platform
thinks.

Reasoning is SeKondBrain's cognitive backend — the engine that orchestrates every model call and turns freeform input into structured, validated output. Agents reach it over MCP; services reach it over REST.

It runs local-first on self-hosted models with cloud fallback, executes versioned skills and composable chains, and records a Graph of Thought so any decision can be traced back to why.

What it is

Reasoning sits between your agents and the models. Rather than call one model and hope, it runs a disciplined pipeline — route → extract → validate — that picks the right handler for the input, extracts structure, and checks the result against a schema before returning it. You get validated JSON, not a paragraph to parse.

On top of that sit two reusable units of work: skills (a versioned, testable prompt with an input and output schema) and chains (skills and prompts composed into a pipeline with conditionals, parallelism, budgets and guardrails).

PropertyValue
Agent surfaceMCP over Streamable HTTP, or stdio
Service surfaceREST over HTTPS, base path /v1
TenancyPer-organisation; always derived from your credential, never from the request body
InferenceLocal-first, with cloud fallback and per-tenant policy
StreamingServer-sent events for chain execution

Quickstart

1. Call a tool over MCP

Point any MCP-capable client at the endpoint and authenticate with an API key.

curl -X POST https://<YOUR_REASONING_HOST>/v1/mcp \
  -H "X-API-Key: <YOUR_API_KEY>" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
        "jsonrpc": "2.0", "id": 1,
        "method": "tools/call",
        "params": { "name": "list_skills", "arguments": {} }
      }'

{ "skills": [ { "name": "pm.generate_feature_spec_from_goal",
                "description": "Draft a feature spec from a goal | Category: pm/spec_generation | Model: balanced",
                "input_schema": { "type": "object", "properties": { … } } } ],
  "count": 1 }

2. Run a skill

curl -X POST https://<YOUR_REASONING_HOST>/v1/skills/run-by-name \
  -H "Authorization: Bearer <YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
        "skill_name": "pm.generate_feature_spec_from_goal",
        "inputs": { "goal": "Let users log in with SSO",
                    "constraints": ["must support SAML"] },
        "temperature": 0.7
      }'

{ "skill_id": "b1e7…", "skill_name": "pm.generate_feature_spec_from_goal",
  "skill_version": 3,
  "output": { "feature_name": "SSO Login", "acceptance_criteria": ["…"] },
  "execution_id": "8f2c…", "outcome": "success", "duration_ms": 1240,
  "model_used": "…", "tokens_used": 847, "validation_passed": true }

Authentication

CredentialUse
X-API-KeyAgent and service keys for the MCP surface. A per-agent key additionally identifies which agent is calling, which is what the audit log records.
Authorization: BearerA signed token for the REST surface. Reasoning and manifest routes require this.
X-Organization-IDOptional. A service caller may set the acting organisation with it; a user caller cannot use it to reach another organisation.

Your organisation is always resolved from the validated credential. A user caller that names a different organisation in a request body is refused rather than served, and a service caller must name one explicitly rather than defaulting.

The MCP endpoint publishes OAuth discovery documents and supports dynamic client registration, so a spec-compliant client can connect without manual configuration. Tool calls are rate limited per organisation; concurrent sessions are capped.

Fail-closed where it counts

If the rate-limit store is unavailable, write tools fail closed and read tools fail open. Losing a counter should never become an accidental licence to mutate.

MCP tools

Seventeen tools, every one annotated so your client can distinguish reading from writing before it runs anything.

Read — product & specification

TOOLlist_productsProducts available to your organisation.
TOOLget_manifestThe full specification, or one section of it.
TOOLget_context_summaryName, vision and counts — a compact orientation under a token budget.
TOOLget_featureRequirements, acceptance criteria, happy path, edge cases, technical spec, security.
TOOLget_storiesUser stories, optionally filtered to an epic.
TOOLget_product_specThree-phase retrieval — context, journeys, features — each response naming the next phase.
TOOLget_competitorsPositioning, advantages, competitor profiles.
TOOLsemantic_searchRanked features and entities by meaning, with scores.
TOOLget_journey_screensRendered screen markup for a journey.
TOOLget_product_design_systemDesign tokens as semantic CSS variables, a Tailwind theme block, and W3C DTCG JSON.

Read — agent specifications

TOOLlist_agentsAgent products, status and trigger type.
TOOLget_agent_specSystem prompt, trigger and model configuration, memory, tool schemas, constraints, risks, test scenarios.

Write — status

TOOLupdate_feature_statusbacklog · defined · in_progress · developed · testing
TOOLupdate_story_statusdraft · in_progress · done
TOOLupdate_agent_statusspeccing · prompting · building · testing · deployed

Status writes are annotated non-destructive — full version history is retained, so a wrong status is correctable rather than lossy.

Skills

TOOLlist_skillsEvery executable skill in your organisation, with its input schema.
TOOLrun_skillExecute one by name with arguments.

run_skill is deliberately annotated as destructive and non-idempotent — a skill can do anything, so the conservative hint is the honest one. It returns the output plus outcome, skill_version, execution_id, duration_ms, model_used, tokens_used and a trace id.

Tool errors come back as content with an error field rather than as transport failures, so an agent can read the reason and adapt — including when it has been rate limited or has reached across organisations.

MCP prompts

The server also publishes prompts — parameterised starting points a client can offer directly to a user:

PromptFor
s9n-orientGetting oriented in a product before doing anything.
s9n-implement-feature · s9n-implement-storyImplementing a specific feature or story.
s9n-review-specReviewing a specification.
s9n-orient-agent · s9n-build-agent · s9n-test-agent · s9n-refine-agent-promptWorking on an agent specification end to end.

Skills

A skill is a versioned, executable prompt with schemas on both sides. Defining one is a POST, not a deploy.

FieldMeaning
name, descriptionRequired. The description is what semantic discovery searches.
prompt_templatePresence of this makes a skill executable. Rendered in a sandboxed template environment.
input_schema / output_schemaJSON Schema, enforced before and after the call.
system_promptPersona for the call.
model_tierfast · balanced · capable · reasoning.
category, language, frameworks, agent_typesDiscovery metadata.
source, confidencemanual · learned · imported, and a score.

Endpoints

POST/v1/skillsCreate.
GET/v1/skillsFilter by source, confidence, promotion status, project, agent type.
POST/v1/skills/searchFind by meaning.
POST/v1/skills/{id}/run
POST/v1/skills/run-by-nameRun without resolving an id first.
GET/v1/skills/{id}/versions· and POST …/rollback/{n}
GET/v1/skills/{id}/executions· and /history
POST/v1/skills/{id}/promotePromote a learned skill.
POST/v1/skills/detect-gapsFind capabilities you don't have.
POST/v1/skills/import· /export, and skill packs via /packs/upload
GET/v1/skills/analytics/most-used· /success-rate · /cost · /recommendations
Confidence is earned, not asserted

You cannot set a skill's confidence through the metrics endpoint — it is computed from execution history, with a penalty for going stale, and a skill promotes itself once it clears the bar. A number you can write is a number that means nothing.

Model affinity

Different inputs deserve different models. Affinity binds a skill to an ordered model preference per context:

PUT /v1/skills/{skill_id}/affinity
{
  "affinities": [
    { "context": "simple",  "models": ["<fast-model>"],                    "priority": 0 },
    { "context": "complex", "models": ["<strong-model>", "<fallback>"],   "priority": 1 },
    { "context": "default", "models": ["<balanced-model>"],                "priority": 2 }
  ]
}

Models are tried in order; lower priority numbers win. Resolution runs: an explicit model_override on the call (validated against an allowlist), then affinity plus an automatic complexity assessment of the input, then the skill's declared tier, then the platform default.

The complexity assessor is lazy — it only runs when affinity rows exist, so the common path costs nothing.

Chains

A chain composes steps — a skill, a prompt, a raw model call, or another chain — into a pipeline.

POST /v1/chain
{
  "name": "spec_pipeline",
  "routing_mode": "cloud",
  "steps": [
    { "name": "extract_requirements", "step_type": "skill",
      "skill_name": "extract_goals" },
    { "name": "generate_spec", "step_type": "prompt",
      "prompt_template": "Given requirements: {{ previous_output }}\nGenerate a feature spec.",
      "system_prompt": "You are a senior product manager.",
      "uses_previous": true, "is_final_output": true }
  ]
}
CapabilityHow
Sequencinguses_previous feeds the prior output forward; is_final_output marks the result.
ParallelismSteps sharing a parallel_group run concurrently and merge by merge_strategyconcat, merge, list or first_success.
ConditionalsA condition on a field with comparison operators, plus and/or. Skip the step or jump to a named one — with loop detection.
NestingA step can be another chain, bounded in depth with circular-reference detection.
Budgetsmax_cost_usd and max_latency_ms with enforcement of warn, downgrade (switch to a faster model) or abort. Steps marked skippable are dropped first.
GuardrailsPre, inter and post checks — length, quality threshold, basic PII — acting as pass, warn or block.
Failure policyabort, retry_chain, or fall back to a named chain.

A chain of skills

The useful pattern is composing skills rather than prompts — each step is separately versioned, separately tested and reusable somewhere else. A step can also be another chain, so a chain of skills becomes a building block in a larger one.

{
  "name": "intake_pipeline",
  "steps": [
    { "name": "classify",  "step_type": "skill", "skill_name": "doc.classify" },

    // fan out — both run concurrently, results merged
    { "name": "entities",  "step_type": "skill", "skill_name": "doc.extract_entities",
      "parallel_group": "enrich", "uses_previous": true },
    { "name": "summary",   "step_type": "skill", "skill_name": "doc.summarise",
      "parallel_group": "enrich", "uses_previous": true,
      "merge_strategy": "merge" },

    // only escalate when the classifier wasn't confident
    { "name": "deep_review", "step_type": "chain", "chain_name": "expert_review",
      "condition": { "field": "confidence", "op": "<", "value": 0.8 },
      "skip_on_condition_fail": true },

    { "name": "render", "step_type": "skill", "skill_name": "doc.render_report",
      "uses_previous": true, "is_final_output": true }
  ],
  "max_cost_usd": 0.50,
  "budget_enforcement": "downgrade",
  "on_failure_strategy": "abort"
}

Four things are worth noticing. Steps fan out by sharing a group and reconverge by merge strategy. A step skips itself when its condition fails, so the expensive review only runs when the cheap classifier was unsure. A step is another chain, which is how a library of small pipelines composes into a big one. And the whole run carries a budget — on downgrade it drops to faster models rather than failing, which is usually what you want at 3am.

Nesting is depth-bounded with circular-reference detection, so a chain that references itself is refused at execution rather than discovered as a stack overflow.

POST/v1/chain/{name}/execute

Returns final_output, every intermediate_outputs step, errors, total_tokens, execution_time and the models_used — note the plural: one chain routinely spans several models and providers, and the response tells you which ones actually served it.

POST/v1/chain/{name}/execute/stream

The same run as server-sent events: chain_start, chain_step_start, chain_step_complete, chain_step_error, chain_complete.

GET/v1/chain/{id}/versions· /rollback/{n} — edits auto-snapshot.
GET/v1/chain/{id}/analyticsRuns, success rate, average duration, tokens and cost.
POST/v1/chain/provider-keysBring your own provider keys — responses return a masked preview, never the key.

Understanding pipeline

Underneath skills and chains is the primitive that turns text into structure. A unit is a semantic description plus typed slots; the description drives routing, the slots drive extraction and the schema.

POST/v1/routeWhich unit handles this text — with candidates and scores.
POST/v1/executeRoute, extract and validate in one call.
GET/v1/unitsAvailable units and their slots.
StageBehaviour
RouteSemantic match against unit descriptions above a threshold. Total by design — empty input, no match or any internal error falls back to a default unit rather than raising.
ExtractSlots are rendered into a prompt and the model returns JSON at low temperature.
ValidateA JSON Schema is derived from the slots — types, required fields, lengths, ranges, enums, patterns, formats — and the result is checked against it.

Slot types cover strings, numbers, integers, booleans, typed arrays, objects, and formatted strings for date, date-time, email and URL, each with its own constraints.

Validation coerces before it complains

By default validation is lenient: violations are collected and the value is coerced toward the declared type rather than rejected outright, so a nearly-right model response becomes usable data instead of an exception. Strict mode raises with the full error list when you'd rather fail than coerce — choose per call site.

Graph of Thought

Record why, not only what. Reasoning nodes form a directed graph and link to the entities they produced.

POST/v1/reasoning/nodes

A node has a reasoning_type of observation, inference, decision, question or answer, plus content, a confidence, and parent nodes.

GET/v1/reasoning/nodes/{id}/chainWalk root to node.
GET/v1/reasoning/concepts/{type}/{id}/provenanceAsk an entity what produced it.
POST/v1/reasoning/decisions

A design decision carries title, context, decision, rationale, alternatives considered and consequences, with a lifecycle of proposedaccepted · rejected · deprecated.

PATCH/v1/reasoning/decisions/{id}/status
POST/v1/reasoning/search/epics· /search/stories · /search/code

Semantic search across specification and code, filterable by component type and minimum similarity.

Reads are filtered to your organisation; a caller cannot walk another tenant's reasoning. These routes are service-to-service in shape — they expect embeddings supplied by the caller.

Events

State changes publish through a transactional outbox, so an event is committed with the change that caused it rather than best-effort afterwards. Consumption is idempotent through an inbox.

{ "type": "concept.updated", "version": "1.0",
  "timestamp": "2026-08-03T12:00:00Z",
  "event_id": "…", "idempotency_key": "…",
  "producer": "reasoning", "org_id": "…", "project_id": "…",
  "payload": { "concept_id": "…", "concept_type": "Feature",
               "properties": { "name": "My Feature", "status": "backlog" } } }
FamilyEvents
Conceptsconcept.created · concept.updated · concept.linked · concept.relationship.created · concept.batch.ingestion
Specificationmanifest.updated · manifest.item_deleted
Extractionextraction.started · extraction.completed · extraction.entities · cascade.started · cascade.completed
Reasoningreasoning.decision.created · contradiction.detected
Skillsskill.promotion.requested

Webhook deliveries carry the event type, a stable idempotency key that survives retries, and an HMAC signature over the raw body. Delivery is at-least-once with exponential backoff and a bounded retry count before an event is marked failed — so consumers must be idempotent. Ordering is guaranteed per organisation, not globally.

Two idempotency concepts are separate on purpose: a transport key that is stable across retries of the same delivery, and a domain key that dedupes the same logical event.

Multi-model, multi-provider

No single model is right for every call, and no single provider should be a hard dependency. Reasoning treats the model as a routing decision made at call time, from four inputs: the tier a skill declares, its affinity rules, your tenant policy, and what is actually reachable right now.

Tiers, not model names

Skills declare a tier. Swapping the model behind a tier is a configuration change, not a rewrite of every skill that used it.

TierFor
fastAlways-hot small model — classification, routing, cheap transforms.
balancedThe default for most work.
capableHarder reasoning and longer synthesis.
reasoningThe strongest available, for the calls that justify it.

Providers

Self-hosted and cloud providers sit behind one interface, so a skill does not know or care which served it.

ProviderRole
Self-hosted (primary)Your own inference cluster. The default path — lowest cost, and your content stays put.
Self-hosted (secondary route)A second address for the same cluster, so a routing failure isn't a capability failure.
Groq · OpenAI · Anthropic · GeminiCloud providers, used on fallback or when you deliberately select one.

The registry knows which models a provider can actually serve — including whether a model is currently loaded on a self-hosted host. A request for a model that isn't there fails over instead of erroring.

Fallback is a policy, not a hard-code

Each tenant can define its own chain: a primary provider, then an ordered fallback list where every step names the conditions that trigger it.

{
  "primary": { "provider": "self-hosted" },
  "fallback_chain": [
    { "provider": "groq",
      "triggers": ["on_connection_error", "on_timeout", "on_5xx", "on_model_unavailable"] },
    { "provider": "openai", "triggers": ["always"] }
  ],
  "enabled": true
}

Errors are classified before the chain is walked, so a timeout and a bad request are not treated the same way — only the steps whose triggers match are tried. Set no policy and you inherit the platform default. A circuit breaker sits in front of every provider, so one that is failing is skipped fast rather than retried into the ground.

Why this shape

Two things fall out of it. Cost: the expensive provider is a safety net, not the default path. Data control: content only leaves for a third party when a rule you wrote says it may — and on an enterprise deployment in your own cloud, you can write a policy where it never does.

Per-skill affinity

Above the tier, a skill can bind specific models to specific contexts — and the input is classified as simple or complex on the way in, so an easy call doesn't pay for a hard model. See Model affinity. Precedence at call time: an explicit override, then affinity plus complexity, then the declared tier, then the platform default.

Reliability

GuardBehaviour
Circuit breakersPer dependency — inference hosts, vector search, the graph, sibling services. After repeated failures the breaker opens and calls fail fast, then a single trial probes recovery.
Health surfaceBreaker state, failure and success counts are exposed for your own monitoring.
Skill retriesChain steps carry their own retry count; chains carry a failure strategy.
OutboxEvents survive a consumer being down — they are retried with backoff, then parked as failed rather than lost.
Rate limitsPer organisation on the agent surface, with the fail-closed-on-writes rule above.

Errors

Skill outcomes

OutcomeMeaning
successRan, and the output matched its schema.
partialRan and produced output, but it failed output-schema validation. Returned with validation_passed: falseand a 200. Check the field, not just the status code.
failureInput validation, a guardrail block, a template error, a model failure or an unparseable response. The error is in the output body.

Status codes

CodeMeaning
400Skill has no prompt template and can't execute; model override outside the allowlist; a service caller that didn't name an organisation.
401Missing or malformed credential.
403Reaching across organisations.
404No such skill, chain, decision or unit in your organisation.
422Request body failed schema validation.
429Too many concurrent agent sessions.
503A required dependency is unavailable.

Every response carries a correlation id header — quote it when reporting an issue and the whole call is retrievable.

Your data

Reasoning processes the prompts, conversation turns and embeddings you send it, isolated per organisation and always scoped to the credential that made the call. It retains execution and usage records so you can see what ran, on which model, and at what cost.

Inference is local-first: your content is reasoned over by self-hosted models by default. When a request falls back to a cloud provider — or you configure one deliberately, including with your own provider keys — that prompt content leaves to that third party. Which providers, and what they retain, is set out in the privacy policy.

Availability & access

Reasoning ships as part of the SeKondBrain platform — licensed, not open source. It runs in production today behind our own products; you buy the platform and integrate the engine through its MCP surface and REST API, with your organisation provisioned and isolated for you.

Where it runs

ModelWhat it means
Multi-tenant cloudThe default. We operate it; your organisation gets its own isolated tenant and its own endpoint.
Your own cloudFor enterprise. Deployed into your cloud account — which also means inference can stay entirely inside your boundary.

What you get when you're set up

A unique URLYour organisation is issued its own endpoint — that is the <YOUR_REASONING_HOST> in every example on this page, and the address you give an MCP client.
CredentialsAn API key for the agent surface and a token for the REST surface, scoped to your organisation.
A live API referenceYour instance serves its own OpenAPI, matching the version you are running.
Setup guideProvisioning covers connecting your first client, seeding skills and running your first chain.
Request access

Email hello@sekondbrain.ai with the subject “Access for Reasoning” and tell us what you want to build.