Skip to content

CSTP API Reference

The Cognition State Transfer Protocol (CSTP) is a JSON-RPC 2.0 API exposed over HTTP. All method calls use POST /cstp with a bearer token in the Authorization header.


Protocol Basics

Request Format

json
{
  "jsonrpc": "2.0",
  "method": "cstp.<methodName>",
  "params": { ... },
  "id": "unique-request-id"
}

Response Format — Success

json
{
  "jsonrpc": "2.0",
  "result": { ... },
  "id": "unique-request-id"
}

Response Format — Error

json
{
  "jsonrpc": "2.0",
  "error": {
    "code": -32003,
    "message": "Query failed: ..."
  },
  "id": "unique-request-id"
}

Authentication

All requests must include a bearer token:

Authorization: Bearer <agent>:<token>

The agent name is extracted from the token pair and included in audit trails.

Error Codes

CodeNameDescription
-32700Parse ErrorMalformed JSON
-32600Invalid RequestMissing required fields
-32601Method Not FoundUnknown CSTP method
-32602Invalid ParamsParameter validation failed
-32603Internal ErrorUnexpected server error
-32002Rate LimitedToo many requests
-32003Query FailedError during decision query
-32004Guardrail Eval FailedError evaluating guardrails
-32005Record FailedError recording decision
-32006Review FailedError reviewing decision
-32007Decision Not FoundDecision ID not found
-32008Attribution FailedError attributing outcomes

Non-Authenticated Endpoints

GET /health

Health check with uptime tracking.

Response:

json
{
  "status": "ok",
  "version": "0.10.0",
  "agent": "cognition-engines",
  "uptime_seconds": 3600,
  "timestamp": "2026-02-07T12:00:00Z"
}

GET /.well-known/agent.json

A2A agent discovery card.

Response:

json
{
  "name": "cognition-engines",
  "description": "Decision Intelligence Service",
  "version": "0.10.0",
  "url": "http://localhost:9991",
  "capabilities": ["queryDecisions", "checkGuardrails", "recordDecision", "reviewDecision", "getCalibration", "getDecision", "getReasonStats"],
  "protocol": "cstp",
  "protocolVersion": "0.10.0"
}

CSTP Methods

cstp.queryDecisions — Search Decision Memory

Search for semantically similar decisions using vector similarity, keyword matching, or hybrid search.

Parameters:

ParamTypeRequiredDefaultDescription
querystringNatural language search query
limitint10Maximum results
include_reasonsboolfalseInclude decision reasons in results
retrieval_modestring"semantic""semantic", "keyword", or "hybrid"
bridge_sidestring"both""structure", "function", or "both"
hybrid_weightfloat0.7Semantic weight in hybrid mode (0.0–1.0)
filtersobject{}Filtering criteria (see below)

Filter object:

FieldTypeDescription
categorystringFilter by decision category
min_confidencefloatMinimum confidence (0.0–1.0)
max_confidencefloatMaximum confidence (0.0–1.0)
stakesstring[]Filter by stakes level ("low", "medium", "high", "critical")
statusstring[]Filter by status ("pending", "reviewed")
projectstringFilter by project name
featurestringFilter by feature name
printFilter by PR number
has_outcomeboolOnly reviewed (true) or pending (false)
date_afterstringISO 8601 minimum date
date_beforestringISO 8601 maximum date

Example request:

json
{
  "jsonrpc": "2.0",
  "method": "cstp.queryDecisions",
  "params": {
    "query": "database selection for agent memory storage",
    "limit": 5,
    "retrieval_mode": "hybrid",
    "include_reasons": true,
    "filters": {
      "category": "architecture",
      "min_confidence": 0.6
    }
  },
  "id": "q-001"
}

Example response:

json
{
  "jsonrpc": "2.0",
  "result": {
    "decisions": [
      {
        "id": "2026-01-15-decision-a1b2c3",
        "title": "Use ChromaDB for semantic memory",
        "category": "architecture",
        "confidence": 0.85,
        "stakes": "high",
        "status": "reviewed",
        "outcome": "success",
        "date": "2026-01-15",
        "distance": 0.234,
        "reasons": ["Lightweight vector DB", "HTTP API", "Good Python support"]
      }
    ],
    "total": 1,
    "query": "database selection for agent memory storage",
    "query_time_ms": 142,
    "agent": "cognition-engines",
    "retrieval_mode": "hybrid",
    "scores": {
      "2026-01-15-decision-a1b2c3": {
        "semantic": 0.892,
        "keyword": 0.654,
        "combined": 0.821
      }
    }
  },
  "id": "q-001"
}

cstp.checkGuardrails — Evaluate Policy Rules

Check a proposed action against all active guardrails.

Parameters:

ParamTypeRequiredDescription
actionobjectAction context
action.descriptionstringWhat the agent intends to do
action.categorystringDecision category
action.stakesstringStakes level (default: "medium")
action.confidencefloatAgent's confidence (0.0–1.0)
action.contextobjectArbitrary context fields for condition matching
agentobjectAgent identity
agent.idstringAgent identifier
agent.urlstringAgent callback URL

Example request:

json
{
  "jsonrpc": "2.0",
  "method": "cstp.checkGuardrails",
  "params": {
    "action": {
      "description": "Deploy new ML pipeline to production",
      "category": "deployment",
      "stakes": "high",
      "confidence": 0.75,
      "context": {
        "affects_production": true,
        "code_review_completed": false
      }
    }
  },
  "id": "g-001"
}

Example response:

json
{
  "jsonrpc": "2.0",
  "result": {
    "allowed": false,
    "violations": [
      {
        "guardrail_id": "no-production-without-review",
        "name": "Production changes require code review",
        "message": "Production changes require completed code review",
        "severity": "block",
        "suggestion": "Complete code review before proceeding"
      }
    ],
    "warnings": [],
    "evaluated": 3,
    "evaluated_at": "2026-02-07T12:00:00Z",
    "agent": "cognition-engines"
  },
  "id": "g-001"
}

cstp.listGuardrails — List Active Guardrails

Parameters:

ParamTypeRequiredDescription
scopestringFilter by scope/project

Example response:

json
{
  "jsonrpc": "2.0",
  "result": {
    "guardrails": [
      {
        "id": "no-production-without-review",
        "description": "Production changes require code review",
        "action": "block",
        "scope": null,
        "conditions": 1,
        "requirements": 1
      }
    ],
    "total": 3
  },
  "id": "lg-001"
}

cstp.recordDecision — Record a Decision

Record a new decision with full metadata, reasoning trace, and optional guardrail pre-check.

Parameters:

ParamTypeRequiredDefaultDescription
decisionstringDecision text / title
confidencefloatConfidence level (0.0–1.0)
categorystringCategory (e.g., "architecture", "trading")
stakesstring"medium""low", "medium", "high", "critical"
contextstringFree-text context
reasonsarray[]List of reason objects
reasons[].typestringReason type: "technical", "risk", "constraint", etc.
reasons[].textstringReason text
reasons[].strengthfloatWeight (0.0–1.0)
alternatives_consideredarray[]List of rejected alternatives
review_instring"7d"Review cadence: "24h", "3d", "7d", "30d"
projectobjectProject context
project.namestringProject name
project.featurestringFeature name
project.printPull request number
project.filesarrayAffected files
reasoning_tracearrayStep-by-step reasoning
bridgeobjectBridge definition (structure + function)
bridge.structurestringWhat the decision looks like (pattern)
bridge.functionstringWhat problem it solves (purpose)
bridge.tolerancearrayFeatures that don't matter
bridge.enforcementarrayFeatures that must be present
bridge.preventionarrayFeatures that must be absent
pre_decision_protocolobjectTrack whether query + guardrail check were performed

Example request:

json
{
  "jsonrpc": "2.0",
  "method": "cstp.recordDecision",
  "params": {
    "decision": "Use PostgreSQL for persistent state storage",
    "confidence": 0.82,
    "category": "architecture",
    "stakes": "high",
    "bridge": {
        "structure": "PostgreSQL with row-level security",
        "function": "secure multi-tenant data storage"
    },
    "context": "Evaluating database options for agent state persistence",
    "reasons": [
      {"type": "technical", "text": "ACID compliance for critical state", "strength": 0.9},
      {"type": "risk", "text": "Team has PostgreSQL experience", "strength": 0.7}
    ],
    "alternatives_considered": ["SQLite", "Redis", "MongoDB"],
    "project": {
      "name": "CryptoTrader",
      "feature": "state-persistence",
      "pr": 42
    }
  },
  "id": "r-001"
}

Example response:

json
{
  "jsonrpc": "2.0",
  "result": {
    "success": true,
    "decision_id": "2026-02-07-decision-a1b2c3d4",
    "path": "decisions/2026/02/2026-02-07-decision-a1b2c3d4.yaml",
    "indexed": true,
    "guardrails_checked": false,
    "bridge_auto": false,
    "deliberation_auto": true,
    "deliberation_inputs_count": 3,
    "related_count": 5,
    "message": "Decision recorded and indexed"
  },
  "id": "r-001"
}

cstp.reviewDecision — Record Outcome

Record the actual outcome of a previously recorded decision.

Parameters:

ParamTypeRequiredDescription
decision_idstringDecision ID (full or prefix)
outcomestring"success", "failure", "partial", "abandoned"
actual_resultstringDescription of what actually happened
lessonsstringLessons learned

Example request:

json
{
  "jsonrpc": "2.0",
  "method": "cstp.reviewDecision",
  "params": {
    "decision_id": "2026-02-07-decision-a1b2c3d4",
    "outcome": "success",
    "actual_result": "PostgreSQL has been stable for 30 days with zero data loss",
    "lessons": "Connection pooling was needed sooner than expected"
  },
  "id": "rv-001"
}

cstp.getDecision — Get Decision Details

Retrieve full decision record including bridge definition and deliberation trace.

Parameters:

ParamTypeRequiredDescription
idstringDecision ID

Example response:

json
{
  "jsonrpc": "2.0",
  "result": {
    "id": "2026-02-07-decision-a1b2c3d4",
    "title": "Use PostgreSQL",
    "deliberation": {
      "inputs": [{"type": "query", "content": "db options"}],
      "steps": [{"step": 1, "thought": "PostgreSQL meets ACID reqs"}]
    },
    "bridge": {
      "structure": "PostgreSQL",
      "function": "persistence"
    }
  },
  "id": "gd-001"
}

cstp.updateDecision - Update Existing Decision

Update fields on an existing decision. Use after recording to finalize with actual outcomes.

Parameters:

ParamTypeRequiredDescription
idstringDecision ID
updatesobjectFields to update

Allowed update fields: decision, confidence, context, tags, pattern, reasons, bridge

Note: deliberation is intentionally excluded - it's append-only via recordThought.

Example request:

json
{
  "jsonrpc": "2.0",
  "method": "cstp.updateDecision",
  "params": {
    "id": "dec_abc123",
    "updates": {
      "decision": "Used Redis with connection pooling",
      "confidence": 0.90,
      "context": "Deployed successfully. Latency improved 5x.",
      "tags": ["caching", "redis", "infrastructure"]
    }
  },
  "id": 1
}

Response:

json
{
  "jsonrpc": "2.0",
  "result": {
    "success": true,
    "id": "dec_abc123",
    "applied": ["decision", "confidence", "context", "tags"],
    "indexed": true
  },
  "id": 1
}

cstp.recordThought - Capture Reasoning Steps

Record chain-of-thought reasoning. Pre-decision mode accumulates in the tracker; post-decision mode appends to an existing decision's trace.

Parameters:

ParamTypeRequiredDescription
textstringReasoning text
decision_idstringIf set, appends to existing decision (post-decision mode)

Pre-decision example (no decision_id):

json
{
  "jsonrpc": "2.0",
  "method": "cstp.recordThought",
  "params": {
    "text": "Considering Redis vs Memcached - Redis has persistence"
  },
  "id": 1
}

Response:

json
{
  "jsonrpc": "2.0",
  "result": {
    "success": true,
    "mode": "pre-decision",
    "agent_id": "emerson"
  },
  "id": 1
}

Post-decision example (with decision_id):

json
{
  "jsonrpc": "2.0",
  "method": "cstp.recordThought",
  "params": {
    "text": "Redis chosen - persistence and pub/sub clinched it",
    "decision_id": "dec_abc123"
  },
  "id": 1
}

Response:

json
{
  "jsonrpc": "2.0",
  "result": {
    "success": true,
    "mode": "post-decision",
    "decision_id": "dec_abc123",
    "step_number": 4
  },
  "id": 1
}

cstp.getReasonStats - Reason Analytics

Analyze success rates and diversity of decision reasons.

Parameters:

ParamTypeRequiredDescription
min_reviewedintMinimum number of reviewed decisions (default 10)

Example response:

json
{
  "jsonrpc": "2.0",
  "result": {
    "success_rates": {"technical": 0.9, "intuition": 0.6},
    "diversity_score": 0.75,
    "dominant_type": "technical"
  },
  "id": "grs-001"
}

cstp.getCalibration — Calibration Statistics

Compute confidence calibration metrics for reviewed decisions.

Parameters:

ParamTypeRequiredDescription
agentstringFilter by recording agent
categorystringFilter by decision category
stakesstringFilter by stakes level
projectstringFilter by project
featurestringFilter by feature
windowstringTime window: "30d", "60d", "90d"

Example response:

json
{
  "jsonrpc": "2.0",
  "result": {
    "total_decisions": 47,
    "reviewed_decisions": 32,
    "overall": {
      "brier_score": 0.142,
      "accuracy": 0.78,
      "calibration_gap": 0.05,
      "interpretation": "Good calibration"
    },
    "buckets": [
      {"range": "0.0-0.2", "decisions": 2, "predicted": 0.15, "actual": 0.0, "brier": 0.023},
      {"range": "0.2-0.4", "decisions": 5, "predicted": 0.32, "actual": 0.4, "brier": 0.051},
      {"range": "0.4-0.6", "decisions": 8, "predicted": 0.52, "actual": 0.5, "brier": 0.098},
      {"range": "0.6-0.8", "decisions": 10, "predicted": 0.72, "actual": 0.7, "brier": 0.089},
      {"range": "0.8-1.0", "decisions": 7, "predicted": 0.88, "actual": 0.86, "brier": 0.021}
    ],
    "confidence_stats": {
      "mean": 0.64,
      "std_dev": 0.21,
      "min": 0.12,
      "max": 0.95,
      "habituation_detected": false
    },
    "recommendations": [
      {"type": "improvement", "message": "Consider more decisions in 0.0-0.2 range", "severity": "low"}
    ]
  },
  "id": "c-001"
}

cstp.attributeOutcomes — Automatic Outcome Attribution

Automatically attribute outcomes to decisions based on PR stability (age).

Parameters:

ParamTypeRequiredDefaultDescription
projectstringProject name
sincestring"30d"Look-back window
stability_daysint7Days before PR is considered stable
dry_runboolfalsePreview only, don't modify files

cstp.checkDrift — Calibration Drift Detection

Compare recent calibration against historical baseline to detect degradation.

Parameters:

ParamTypeRequiredDefaultDescription
categorystringFilter by category
projectstringFilter by project
brier_thresholdfloat0.05Brier score change threshold for alerts
accuracy_thresholdfloat0.1Accuracy change threshold for alerts

Example response:

json
{
  "jsonrpc": "2.0",
  "result": {
    "drift_detected": true,
    "alerts": [
      {
        "type": "brier_degradation",
        "recent_value": 0.22,
        "historical_value": 0.14,
        "change_pct": 57.1,
        "severity": "warning"
      }
    ],
    "recent_period": "30d",
    "historical_period": "90d+",
    "recommendations": ["Review recent high-stakes decisions for confidence accuracy"]
  },
  "id": "d-001"
}

cstp.reindex — Full Reindex

Delete and rebuild the ChromaDB collection from YAML files.

Parameters:

ParamTypeRequiredDescription
decisions_pathstringOverride decisions directory

Example response:

json
{
  "jsonrpc": "2.0",
  "result": {
    "success": true,
    "decisions_indexed": 47,
    "errors": 0,
    "duration_ms": 12340
  },
  "id": "ri-001"
}

MCP Interface (Model Context Protocol)

Since v0.9.0, CSTP exposes decision intelligence capabilities as MCP tools for native integration with any MCP-compliant agent. The MCP layer is a thin bridge — each tool maps 1:1 to an existing CSTP service method with zero code duplication.

Transports

TransportEndpointUse Case
Streamable HTTPPOST/GET http://host:9991/mcpRemote access from any network-reachable MCP client
stdiopython -m a2a.mcp_serverLocal access or Docker exec

Connecting

bash
# Claude Code — add as remote MCP server
claude mcp add --transport http cstp-decisions http://your-server:9991/mcp

# Claude Desktop — add to claude_desktop_config.json (stdio via Docker)
{
  "mcpServers": {
    "cstp": {
      "command": "docker",
      "args": ["exec", "-i", "cstp", "python", "-m", "a2a.mcp_server"]
    }
  }
}

# Local development (stdio)
python -m a2a.mcp_server

MCP Tools

query_decisions

Search similar past decisions using semantic search, keyword matching, or hybrid retrieval.

Input Schema:

FieldTypeRequiredDefaultDescription
querystringNatural language query
limitint5Max results (1–50)
retrieval_modestring"hybrid""semantic", "keyword", or "hybrid"
filtersobjectcategory, stakes, project, has_outcome

Maps to: cstp.queryDecisions


check_action

Validate an intended action against safety guardrails and policies.

Input Schema:

FieldTypeRequiredDefaultDescription
descriptionstringAction you intend to take
categorystringAction category
stakesstring"medium""low", "medium", "high", "critical"
confidencefloatYour confidence (0.0–1.0)

Maps to: cstp.checkGuardrails


log_decision

⚠️ Last resort. Prefer pre_action with auto_record: true for the standard flow.

Record a decision to the immutable decision log manually. Use only when pre_action wasn't called (legacy clients, spontaneous decisions, no prior context).

Input Schema:

FieldTypeRequiredDefaultDescription
decisionstringWhat you decided (state the choice)
confidencefloatConfidence level (0.0–1.0)
categorystring"architecture", "process", "integration", "tooling", "security"
stakesstring"medium"Stakes level
contextstringSituation context
reasonsarray[{"type": "analysis", "text": "..."}] — types: authority, analogy, analysis, pattern, intuition
tagsarrayTags for categorization
projectstringProject in owner/repo format
featurestringFeature or epic name
printPull request number
agent_idstringAgent identifier for multi-agent deliberation isolation
decision_idstringDecision ID to scope deliberation consumption

Maps to: cstp.recordDecision


review_outcome

Record the outcome of a past decision for calibration.

Input Schema:

FieldTypeRequiredDescription
idstringDecision ID (8-char hex)
outcomestring"success", "partial", "failure", "abandoned"
actual_resultstringWhat actually happened
lessonsstringLessons learned
notesstringAdditional review notes

Maps to: cstp.reviewDecision


get_stats

Get calibration statistics to assess decision-making quality.

Input Schema:

FieldTypeRequiredDescription
categorystringFilter by category
projectstringFilter by project (owner/repo)
windowstring"30d", "60d", "90d", or "all"

Maps to: cstp.getCalibration


Create typed edges between decisions in the knowledge graph.

Input Schema:

FieldTypeRequiredDescription
source_idstringSource decision ID
target_idstringTarget decision ID
edge_typestring"relates_to", "supersedes", "depends_on"
weightfloatEdge weight (0.0-1.0, default 1.0)
contextstringWhy these decisions are linked

Maps to: cstp.linkDecisions


get_graph

Query subgraph around a decision with configurable depth.

Input Schema:

FieldTypeRequiredDescription
decision_idstringCenter decision ID
depthintTraversal depth (default 1)
edge_typesstring[]Filter by edge type

Maps to: cstp.getGraph


get_neighbors

Lightweight query for direct connections of a decision.

Input Schema:

FieldTypeRequiredDescription
decision_idstringDecision ID to query
edge_typestringFilter by edge type

Returns neighbor IDs with edge types and weights. Faster than get_graph when you only need immediate connections.

Maps to: cstp.getNeighbors


Debug: cstp.debugTracker

Inspect live deliberation tracker state. Available via JSON-RPC only (not as MCP tool).

bash
curl -X POST http://localhost:8100/cstp \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"cstp.debugTracker","params":{},"id":1}'

Returns active sessions with composite tracker keys, input counts, thought text, source, and age in seconds. Useful for debugging multi-agent deliberation isolation.


Error Handling

MCP tool errors are returned as TextContent with JSON:

json
{
  "error": "validation_error",
  "message": "1 validation error for QueryDecisionsInput..."
}

Error types:

  • validation_error — Invalid input (Pydantic validation failure)
  • internal_error — Unexpected server error

cURL Quick Reference

bash
# Query decisions
curl -X POST http://localhost:9991/cstp \
  -H "Authorization: Bearer myagent:mytoken" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"cstp.queryDecisions","params":{"query":"authentication approach"},"id":"1"}'

# Check guardrails
curl -X POST http://localhost:9991/cstp \
  -H "Authorization: Bearer myagent:mytoken" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"cstp.checkGuardrails","params":{"action":{"description":"Deploy to prod","stakes":"high","context":{"affects_production":true}}},"id":"2"}'

# Record decision
curl -X POST http://localhost:9991/cstp \
  -H "Authorization: Bearer myagent:mytoken" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"cstp.recordDecision","params":{"decision":"Use Redis for caching","confidence":0.8,"category":"architecture"},"id":"3"}'

# Health check (no auth)
curl http://localhost:9991/health

Released under the Apache 2.0 License.