Skip to content

Latest commit

 

History

History
480 lines (340 loc) · 22.1 KB

File metadata and controls

480 lines (340 loc) · 22.1 KB

Scream Life API Contract

Version: v2.3.0 Protocol: MCP (stdio / JSON-RPC 2.0) + HTTP (Web Gateway) Base URL: http://localhost:3000 Content-Type: application/json Latency SLA: p50 < 100ms, p95 < 500ms, p99 < 2s (10 concurrent)


General Conventions

All responses are JSON: success returns {"status":"ok",...}, failure returns {"error":"..."} with the corresponding HTTP status code (400 invalid parameters / 404 not found / 500 server error).

Success Response

{ "status": "ok", ... }

Error Response

{ "error": "error description" }

HTTP status codes: 400 (invalid parameters), 404 (not found), 500 (server error)


MCP Protocol (stdio / NDJSON)

Scream Life runs as a standard MCP Server (registered via .mcp.json, stdio transport); all Agents communicate over JSON-RPC 2.0 line by line (NDJSON). Three methods are supported:

Method Purpose
initialize Handshake; returns protocolVersion and capabilities
tools/list Lists the 10 scream-* tools (name / description / inputSchema)
tools/call Invokes a tool; arguments go in params.arguments

tools/call responses are uniformly wrapped: result.content[0].text holds the JSON string of the tool's return value (JSON.stringify(result, null, 2)).

{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"example","version":"0.1.0"}}}
// → {"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2024-11-05","capabilities":{"tools":{}},"serverInfo":{"name":"scream-life","version":"0.1.0"}}}

Execution: The examples below are tools/call request/response pairs. They can be demonstrated via a stdio pipe from the project root:

# Option A: stdio pipe demo (the MCP Server stays resident because of the embedded Web gateway + Chroma child process;
#            press Ctrl+C after the response; an existing instance on port 3000 is auto-reused)
echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"scream-search","arguments":{...}}}' | bun Core/mcp-server.ts

# Option B: real integration — via any MCP client (registered in .mcp.json, the Agent calls tools/call automatically)

HTTP Endpoints (Web Gateway)

The Web gateway provides REST endpoints: health check, system status, decision CRUD, full-text search, bias detection, decision advice, behavioral patterns, statistics, identity management, audit log, and an SSE real-time stream.

GET /api/health — Health check

{ "status": "ok", "timestamp": "2026-07-29T12:00:00.000Z" }

GET /api/status — System status

{ "initialized": true, "identity": {...}, "stats": {...} }

GET /api/decisions — List decisions

Params: type, status, category, limit, offset

POST /api/decisions — Create decision

{ "title": "Should I quit my job to start a company", "type": "major", "category": "career", "confidence": 0.7 }

GET /api/decisions/:id — Decision details

PUT /api/decisions/:id — Update decision

DELETE /api/decisions/:id — Delete decision

GET /api/search?q=xxx — Full-text search

{ "items": [{"decision": {...}, "rank": 0.5, "snippet": "..."}], "total": 5 }

POST /api/analyze — Bias detection

{ "text": "Don't want to miss the AI window, worried about failure" }
// response: { "biases": [{"type": "FOMO", "severity": 0.7, "mitigation": "..."}] }

POST /api/advise — Decision advice

{ "text": "Should I quit my job to start a company?" }
// response: { "summary": "...", "pattern_warnings": [...], "recommendations": [...] }

GET /api/patterns — Behavior patterns

GET /api/stats — Statistics

GET /api/identity / PUT /api/identity — Identity management

GET /api/audit?action=approve&decision_id=xxx — Audit log

{ "items": [{"id": "...", "action": "approve", "decision_id": "...", "previous_state": "...", "new_state": "..."}], "total": 1 }

POST /api/decisions/:id/approve — Approve decision

POST /api/decisions/:id/override — Override decision

{ "choice": "Stay at my current company", "reason": "After re-evaluation" }

POST /api/decisions/:id/reject — Reject / cancel decision

{ "reason": "The timing isn't right" }

GET /stream — SSE real-time stream

Events: decision_created, decision_updated, heartbeat


MCP Tool Call Examples

The 8 examples below are real tools/call invocations. Each request is the full JSON-RPC message sent by the Agent; the text field of each response is also shown as readable JSON. All field names map one-to-one to the handler return values in Core/mcp-server.ts.

scream-save

Records a decision expressed by the user themselves. user_text (the user's exact words) is required — the handler first runs decision-signal validation (excludes Agent voice → requires a decision signal word); on failure it returns no_user_decision_signal.

Request (Agent calls MCP tools/call):

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"scream-save","arguments":{"user_text":"Should I quit my job to start a company?","situation":"Considering quitting my job to start a company","category":"career","choice":"Start a company","confidence":0.7,"outcome":"pending"}}}

Response:

{"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"{\"stored\":true,\"decision_id\":\"dec-2026-07-29-x7k2m9\",\"situation\":\"Considering quitting my job to start a company\",\"category\":\"career\",\"status\":\"decided\",\"choice\":\"Start a company\",\"confidence\":0.7,\"message\":\"Decision recorded\"}"}]}}

text content (readable):

{
  "stored": true,
  "decision_id": "dec-2026-07-29-x7k2m9",
  "situation": "Considering quitting my job to start a company",
  "category": "career",
  "status": "decided",
  "choice": "Start a company",
  "confidence": 0.7,
  "message": "Decision recorded"
}

status is mapped from outcome: pending + choice present → decided; pending + no choicedeciding; non-pendingexecuted.

Rejected example 1: Agent analysis text (contains exclusion words — rejected even with signal words)

{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"scream-save","arguments":{"user_text":"I suggest you consider quitting your job, from a technical perspective the AI industry is promising","situation":"AI industry opportunity analysis","category":"career"}}}

Response:

{"jsonrpc":"2.0","id":2,"result":{"content":[{"type":"text","text":"{\"stored\":false,\"decision_id\":null,\"reason\":\"no_user_decision_signal\",\"message\":\"No user decision signal detected. Only record what the user actually said (e.g. should I / choose / decide / considering); do not record the Agent's analysis or suggestions.\",\"user_text_preview\":\"I suggest you consider quitting your job, from a technical perspective the AI industry is promising\"}"}]}}

Exclusion words take precedence over signal words: user_text matching i suggest / from a technical perspectiveisAgentVoice=true → rejected even though it also contains consider.

Rejected example 2: no decision signal in the text

{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"scream-save","arguments":{"user_text":"The weather is nice today, the code works","situation":"Casual chat","category":"other"}}}

Response:

{"jsonrpc":"2.0","id":3,"result":{"content":[{"type":"text","text":"{\"stored\":false,\"decision_id\":null,\"reason\":\"no_user_decision_signal\",\"message\":\"No user decision signal detected. Only record what the user actually said (e.g. should I / choose / decide / considering); do not record the Agent's analysis or suggestions.\",\"user_text_preview\":\"The weather is nice today, the code works\"}"}]}}

scream-create

Manually creates a decision (structured entry distilled by the Agent from context; the user's exact words are not validated).

Request:

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"scream-create","arguments":{"title":"Whether to move to the new company","category":"career","options":[{"id":"o1","label":"Stay at the current company","pros":["Stability"],"cons":["Slow salary growth"]},{"id":"o2","label":"Join the new company","pros":["Salary +30%","Growth potential"],"cons":["Long commute"]}],"confidence":0.7,"influencing_factors":["Salary","Growth potential"],"trigger":"Offer in hand"}}}

Response:

{"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"{\"status\":\"created\",\"decision_id\":\"dec-2026-07-29-m4n8q2\",\"message\":\"Decision record created\",\"title\":\"Whether to move to the new company\",\"category\":\"career\",\"confidence\":0.7,\"stored\":true}"}]}}

text content (readable):

{
  "status": "created",
  "decision_id": "dec-2026-07-29-m4n8q2",
  "message": "Decision record created",
  "title": "Whether to move to the new company",
  "category": "career",
  "confidence": 0.7,
  "stored": true
}

Required: title, category. All other fields are optional: description, trigger, options, choice, reason, confidence, influencing_factors, tags, success_criteria, timeline, risk_mitigation, consensus_view, deviation_reason, antifragile.


scream-search

Searches historical decisions. strategy accepts vector / fts5 / hybrid / tfidf (default hybrid; automatically falls back to fts5 when no keyword is passed). Note: strategy is not declared in the inputSchema, but the handler supports it directly and it may be passed explicitly.

Strategy 1: Vector semantic search (vector, requires Chroma ready)

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"scream-search","arguments":{"keyword":"startup","strategy":"vector","limit":5}}}

Response:

{"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"{\"total\":2,\"strategy\":\"vector\",\"decisions\":[{\"id\":\"dec-2026-07-29-x7k2m9\",\"title\":\"Considering quitting my job to start a company\",\"category\":\"career\",\"status\":\"decided\",\"choice\":\"Start a company\",\"confidence\":0.7,\"created_at\":\"2026-07-29T08:00:00.000Z\",\"score\":0.87,\"tags\":[\"agent-extracted\",\"mcp\"]},{\"id\":\"dec-2026-07-25-a1b2c3\",\"title\":\"Whether to start a company\",\"category\":\"career\",\"status\":\"deciding\",\"choice\":null,\"confidence\":0.5,\"created_at\":\"2026-07-25T10:30:00.000Z\",\"score\":0.72,\"tags\":[]}]}"}]}}

Strategy 2: Keyword search (fts5)

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"scream-search","arguments":{"keyword":"quit","strategy":"fts5","category":"career","limit":10}}}

Response:

{"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"{\"total\":1,\"strategy\":\"fts5\",\"decisions\":[{\"id\":\"dec-2026-07-29-x7k2m9\",\"title\":\"Considering quitting my job to start a company\",\"category\":\"career\",\"status\":\"decided\",\"choice\":\"Start a company\",\"confidence\":0.7,\"created_at\":\"2026-07-29T08:00:00.000Z\",\"score\":0.5,\"tags\":[\"agent-extracted\",\"mcp\"]}]}"}]}}

Strategy 3: Hybrid search (hybrid, default)

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"scream-search","arguments":{"keyword":"Should I switch jobs to a startup","strategy":"hybrid","limit":10}}}

Response:

{"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"{\"total\":2,\"strategy\":\"hybrid\",\"decisions\":[{\"id\":\"dec-2026-07-29-x7k2m9\",\"title\":\"Considering quitting my job to start a company\",\"category\":\"career\",\"status\":\"decided\",\"choice\":\"Start a company\",\"confidence\":0.7,\"created_at\":\"2026-07-29T08:00:00.000Z\",\"score\":0.85,\"tags\":[\"agent-extracted\",\"mcp\"]}]}"}]}}

decisions[] fields: id / title / category / status / choice / confidence / created_at / score / tags. score depends on the strategy: vector = 1 - distance/2; fts5 = FTS rank (0.5 when absent); hybrid = vector score or TF-IDF rerank score.


scream-get

Fetches the full details of a single decision (returns the entire decisions table row).

Request:

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"scream-get","arguments":{"id":"dec-2026-07-29-x7k2m9"}}}

Response:

{"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"{\"rowid\":1,\"id\":\"dec-2026-07-29-x7k2m9\",\"type\":\"major\",\"status\":\"decided\",\"title\":\"Considering quitting my job to start a company\",\"description\":\"Considering quitting my job to start a company\",\"category\":\"career\",\"trigger\":\"agent_extracted\",\"context\":null,\"options\":null,\"choice\":\"Start a company\",\"reason\":null,\"confidence\":0.7,\"influencing_factors\":\"[]\",\"biases\":null,\"pattern_matches\":null,\"antifragile_score\":0.5,\"result_status\":\"pending\",\"actual_outcome\":null,\"lesson\":null,\"calibration_error\":null,\"tags\":\"[\\\"agent-extracted\\\",\\\"mcp\\\"]\",\"created_at\":\"2026-07-29T08:00:00.000Z\",\"updated_at\":\"2026-07-29T08:00:00.000Z\"}"}]}}

When not found:

{"jsonrpc":"2.0","id":2,"result":{"content":[{"type":"text","text":"{\"error\":\"not_found\",\"message\":\"Decision not found: dec-nonexistent\"}"}]}}

Note: JSON columns such as options / influencing_factors / tags / biases are returned as strings (raw DB rows) and require JSON.parse before use. HTTP equivalent: GET /api/decisions/:id.


scream-profile

Gets or updates the user identity profile. On first call, if no profile exists, default values are initialized automatically.

Read a specific section:

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"scream-profile","arguments":{"section":"decision_style"}}}

Response:

{"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"{\"decision_style\":{\"type_preference\":\"unknown\",\"ambiguity_tolerance\":0.5,\"contrarian_tendency\":0.5}}"}]}}

Update the profile (update supports name / basic / values / personality / preferences / decision_style):

{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"scream-profile","arguments":{"update":{"name":"Boss","basic":{"age":30,"occupation":"Engineer"},"decision_style":{"type_preference":"analytical","ambiguity_tolerance":0.4,"contrarian_tendency":0.6}}}}}

Response (full profile returned after update):

{"jsonrpc":"2.0","id":2,"result":{"content":[{"type":"text","text":"{\"id\":\"self\",\"name\":\"Boss\",\"version\":\"0.1.0\",\"basic\":{\"age\":30,\"occupation\":\"Engineer\"},\"values\":{},\"personality\":{},\"preferences\":{},\"key_life_events\":[],\"calibration_profile\":{\"overall_score\":null,\"tendency\":\"unknown\",\"domain_scores\":{}},\"decision_style\":{\"type_preference\":\"analytical\",\"ambiguity_tolerance\":0.4,\"contrarian_tendency\":0.6},\"created_at\":\"2026-07-29\",\"updated_at\":\"2026-07-29\"}"}]}}

section accepts: basic / values / personality / calibration / decision_style / all (default all). HTTP equivalent: GET/PUT /api/identity.


scream-bias

Detects 8 cognitive biases (FOMO / confirmation bias / overconfidence / loss aversion / herd behavior / anchoring / sunk cost / hindsight bias).

Request:

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"scream-bias","arguments":{"text":"Don't want to miss out on the AI window, if I miss it there's no chance left, must act now"}}}

Response:

{"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"{\"detected\":[{\"type\":\"fomo\",\"label\":\"FOMO (Fear of Missing Out)\",\"severity\":0.61,\"evidence\":\"Matched keywords: miss out, must act now\",\"mitigation\":\"Set a cooling-off period (24-48 hours) and ask yourself: if nobody knew about this decision, would I still choose it?\"}],\"overall_risk\":0.67,\"dominant_bias\":\"fomo\",\"summary\":\"Detected 1 cognitive bias, dominant bias: \\\"FOMO (Fear of Missing Out)\\\" (severity 0.61).\"}"}]}}

text content (readable):

{
  "detected": [
    {
      "type": "fomo",
      "label": "FOMO (Fear of Missing Out)",
      "severity": 0.61,
      "evidence": "Matched keywords: miss out, must act now",
      "mitigation": "Set a cooling-off period (24-48 hours) and ask yourself: if nobody knew about this decision, would I still choose it?"
    }
  ],
  "overall_risk": 0.67,
  "dominant_bias": "fomo",
  "summary": "Detected 1 cognitive bias, dominant bias: \"FOMO (Fear of Missing Out)\" (severity 0.61)."
}

severity = min(1, Σweights/(Σweights+1.5)); overall_risk = min(1, avg(severity) × (1 + count×0.1)). Optional decision_id: when provided, the detected biases are written to that decision record. HTTP equivalent: POST /api/analyze.


scream-patterns

Mines recurring behavioral patterns from decision history and matches them against the latest decision.

Request:

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"scream-patterns","arguments":{"min_confidence":0.5,"include_stored":true}}}

Response:

{"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"{\"discovered\":{\"patterns\":[{\"name\":\"FOMO-Driven Decision Pattern\",\"description\":\"User shows fear-of-missing-out driven rapid decision-making when facing new opportunities\",\"category\":\"fomo_pattern\",\"frequency\":3,\"confidence\":0.72,\"supporting_evidence\":[\"dec-2026-07-29-x7k2m9\",\"dec-2026-07-25-a1b2c3\"],\"recommendation\":\"Set a 48-hour cooling-off period before important decisions\"}],\"total_decisions_analyzed\":5,\"analysis_timestamp\":\"2026-07-29T12:00:00.000Z\"},\"stored_patterns\":[{\"id\":\"pat-2026-07-20-p3q8r5\",\"name\":\"FOMO-Driven Decision Pattern\",\"description\":\"Acts quickly when afraid of missing an opportunity\",\"category\":\"fomo_pattern\",\"confidence\":0.7,\"recommendation\":\"{\\\"action\\\":\\\"Wait 48 hours\\\"}\"}],\"latest_decision_matches\":[{\"pattern_id\":\"pat-2026-07-20-p3q8r5\",\"pattern_name\":\"FOMO-Driven Decision Pattern\",\"match_score\":0.8,\"matched_indicators\":[\"miss out\"],\"evidence\":\"Latest decision contains FOMO indicators\",\"recommendation\":\"{\\\"action\\\":\\\"Wait 48 hours\\\"}\"}]}"}]}}

Params: min_confidence (default 0.3, filters low-confidence patterns), include_stored (default true, loads the saved pattern library). discovered.patterns[].categoryfomo_pattern / fast_decision / risk_aversion / custom.


scream-advice

Provides personalized advice based on the user's historical decision patterns (similar-decision matching + pattern warnings + calibration feedback). This is Scream Life's core value tool.

Request:

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"scream-advice","arguments":{"text":"Should I quit my job to start a company?"}}}

Response:

{"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"{\"similar_decisions\":[{\"id\":\"dec-2026-07-29-x7k2m9\",\"title\":\"Considering quitting my job to start a company\",\"choice\":\"Start a company\",\"result\":\"pending\",\"similarity\":\"3 keyword matches\"}],\"pattern_warnings\":[{\"name\":\"FOMO-Driven Decision\",\"description\":\"You have a pattern of acting quickly out of fear of missing out\",\"confidence\":0.7,\"advice\":\"Wait 48 hours before deciding. Ask yourself: if this opportunity only came around a month from now, would you still be this eager?\"}],\"calibration_feedback\":null,\"recommendations\":[\"In your last 5 decisions you chose: Start a company, Stay at my current company, Buy a house. Does this decision match your previous pattern?\"],\"overall_assessment\":\"You have recorded 5 decisions and discovered 2 behavioral patterns.\"}"}]}}

text content (readable):

{
  "similar_decisions": [
    {
      "id": "dec-2026-07-29-x7k2m9",
      "title": "Considering quitting my job to start a company",
      "choice": "Start a company",
      "result": "pending",
      "similarity": "3 keyword matches"
    }
  ],
  "pattern_warnings": [
    {
      "name": "FOMO-Driven Decision",
      "description": "You have a pattern of acting quickly out of fear of missing out",
      "confidence": 0.7,
      "advice": "Wait 48 hours before deciding. Ask yourself: if this opportunity only came around a month from now, would you still be this eager?"
    }
  ],
  "calibration_feedback": null,
  "recommendations": [
    "In your last 5 decisions you chose: Start a company, Stay at my current company, Buy a house. Does this decision match your previous pattern?"
  ],
  "overall_assessment": "You have recorded 5 decisions and discovered 2 behavioral patterns."
}

calibration_feedback is null when there are fewer than 3 historical decisions or the calibration error is 0. HTTP equivalent: POST /api/advise.


Latency Benchmarks (10 concurrent)

Latency benchmarks for each endpoint under 10 concurrent requests (p50 / p95 / p99); the latency tests run via bun test tests/.

# Run latency tests
bun test tests/
Endpoint p50 p95 p99
GET /api/health < 5ms < 10ms < 20ms
GET /api/decisions < 50ms < 100ms < 200ms
POST /api/analyze < 20ms < 50ms < 100ms
POST /api/advise < 100ms < 500ms < 2s
GET /api/search < 50ms < 200ms < 500ms

Test Commands

Quick verification via curl: bias detection, decision advice, create / approve decisions, view audit log.

# Bias detection
curl -X POST http://localhost:3000/api/analyze \
  -H "Content-Type: application/json" \
  -d '{"text": "Don't want to miss out on the AI window, worried about failure"}'

# Decision advice
curl -X POST http://localhost:3000/api/advise \
  -H "Content-Type: application/json" \
  -d '{"text": "Should I quit my job to start a company?"}'

# Create decision
curl -X POST http://localhost:3000/api/decisions \
  -H "Content-Type: application/json" \
  -d '{"title": "Test decision", "type": "major", "category": "career", "confidence": 0.7}'

# Approve decision
curl -X POST http://localhost:3000/api/decisions/dec-001/approve

# View audit log
curl http://localhost:3000/api/audit