chaos-core-mcp
chaos-core-mcp
AI가 노출하는 도구가 아니라 의사결정 커널 그 자체인 MCP 서버입니다. 호출하는 클라이언트(Claude, ChatGPT, Codex, 무엇이든)는 저수준 엔드포인트를 열거하지 않습니다 — Chaos Core에 목표를 넘기면 Cognitive Core가 그 목표에 대해 추론하고, 캐퍼빌리티를 발견하고, 계획을 세우고, 결정론적 정책을 확인하고, 실행하고, 평가하며, 기억합니다.
v0.2부터 인지 코어는 전송 방식에 구애받지 않습니다(transport-agnostic). 동일한 코어, 도구, 정책, 메모리, 캐퍼빌리티 레지스트리에는 두 가지 방식으로 접근할 수 있습니다. 로컬 MCP 클라이언트는 stdio를 통해, Claude custom connectors 같은 원격 MCP 클라이언트는 /mcp의 Streamable HTTP를 통해 접근합니다.
CHAOS CORE
│
Cognitive Core
│
┌────────────────┴────────────────┐
│ │
stdio Streamable HTTP
│ │
▼ ▼
Local MCP clients Remote MCP clients
/mcp인지에 대한 HTTP 변형은 존재하지 않습니다. src/transport/stdio.ts와 src/transport/http.ts 모두 단일 서버 팩토리인 createChaosCoreServer()를 호출합니다 — 전송은 인지 계층에 보이지 않으며, http_reason / remote_plan 같은 중복은 없습니다.
Cognitive Core 루프
objective
↓
context
↓
AI planning
↓
policy
↓
capability execution
↓
evaluation
↓
resultV1은 각 단계를 자체 MCP 도구로 노출하므로 모든 단계가 검사 가능한 상태로 남고, 호출하는 AI가 단계 사이에서 제어권을 유지합니다.
Tool | 목적 |
| 계획이 수립되기 전에 목표와 컨텍스트를 분석합니다 (Intent Analyzer) |
| 목표를 순서가 있고 캐퍼빌리티에 기반한 계획으로 변환합니다 |
| 계획 실행: 정책 확인 → 캐퍼빌리티 선택 → 실행 → 평가 |
| 읽기 전용 조사: 캐퍼빌리티, 정책, 프로바이더, 메모리, 감사 추적, 세션 |
| 사실을 지속형 Semantic Memory에 저장합니다 |
| Semantic Memory에서 조회합니다 |
두 전송 모두 이 동일한 목록을 제공합니다 — 각 전송에서 실제 MCP 클라이언트로 도구를 나열하고 정의를 비교하는 테스트가 이를 강제합니다.
core/brain.ts는 또한 전체 루프를 하나의 조합 가능한 함수(runCognitiveCore)로 구현합니다 — 목표에서 결과까지 곧바로 처리하며, 단계 실패 시 자동 재계획하고 REQUIRE_APPROVAL이 발생하면 즉시 중단합니다. 이 함수는 V1에서 MCP 도구로 등록되지는 않지만(V1 경계 참조) 완전히 연결된 상태로 존재하여, 재작성 없이 향후 chaoscore_achieve 도구를 뒷받침할 준비가 되어 있습니다.
Related MCP server: ellmos-homebase-mcp
아키텍처
src/
index.ts transport dispatcher (stdio by default)
config.ts the only file that reads process.env
server/ ← composition root; transport-independent
create-server.ts createRuntime() + createChaosCoreServer()
register-tools.ts the single definition of the V1 tool surface
types.ts RuntimeServices / ChaosCoreDependencies
schemas.ts shared Zod schemas
tools/ reason plan execute inspect remember recall
transport/ ← the ONLY transport-aware code
stdio.ts local subprocess transport (stdout reserved for JSON-RPC)
http.ts Streamable HTTP at /mcp (stateful sessions)
core/ brain intent planner evaluator context types
capabilities/ registry executor types + built-in/
memory/ store (factory) sqlite (impl) types (MemoryStore interface)
policy/ engine permissions approvals types
providers/ ai-provider (AIProvider interface) openai index
state/ session (Working Memory) execution (trace assembly)
observability/ logger events audit
util/ to-structured의존성 주입과 수명 규칙
createRuntime()은 프로세스 전역 서비스를 한 번 생성합니다: config, 캐퍼빌리티 레지스트리, 정책 엔진, 메모리 저장소, 프로바이더 레지스트리, 감사 로그, 로거. createChaosCoreServer()는 해당 런타임 위에 MCP 세션당 하나의 McpServer를 생성하고, 세션별 SessionState를 추가하며, 결합된 컨테이너를 주입한 상태로 도구를 등록합니다.
구성 요소 | 수명 | 결과 |
메모리, 정책, 캐퍼빌리티, 프로바이더, 감사 | 프로세스별 | 같은 프로세스를 사용하는 원격 HTTP 클라이언트와 로컬 stdio 클라이언트는 동일한 상태를 봅니다 |
| MCP 세션별 | 한 클라이언트의 |
어떤 코어 모듈도 의존성 컨테이너를 import 하지 않습니다. core/intent.ts, core/planner.ts, capabilities/executor.ts는 각각 컨테이너가 우연히 만족시키는 좁은 구조적 인터페이스(IntentDeps, PlannerDeps, ExecutorDeps)를 선언합니다 — 따라서 코어는 독립적으로 테스트 가능하고 서버 및 전송 계층에 대해 전혀 알지 못합니다.
정책은 AI 밖에 있다
AI proposes action
↓
deterministic policy engine
↓
ALLOW / DENY / REQUIRE_APPROVAL모델은 어떤 캐퍼빌리티든 제안할 수 있습니다. policy/engine.ts는 캐퍼빌리티 이름과 운영자가 제어하는 정책 파일의 순수 함수로 실행 여부를 결정합니다. 어떠한 모델도 개입하지 않습니다. 다음과 같이 나뉩니다:
policy/permissions.ts— 허용/거부 목록 (allowedCapabilities,deniedCapabilities)policy/approvals.ts— 허용된 캐퍼빌리티 중 여전히 사람의 승인이 필요한 것 (requireConfirmationFor)policy/engine.ts— 그것들을 결합하고, 제한된 리소스 (httpAllowedDomains)도 처리합니다
data/policy.json은 첫 실행 시 안전한 기본값으로 자동 생성됩니다:
{
"allowedCapabilities": [],
"deniedCapabilities": [],
"requireConfirmationFor": ["http.request"],
"httpAllowedDomains": []
}전송 계층은 정책을 우회할 수 없습니다. capabilities/executor.ts는 계획 단계에서 캐퍼빌리티 핸들러로 가는 유일한 경로이며, 먼저 policy.check()를 호출하고 전송 조건에 따른 분기를 포함하지 않습니다. REQUIRE_APPROVAL로 결정되는 단계는 호출자가 confirmed: true를 전달하지 않으면 건너뜁니다. DENY로 결정되는 단계는 절대 실행되지 않습니다. 모든 결정은 세션 id와 함께 감사 추적에 기록됩니다.
AI 모델은 교체 가능합니다 — 설계상 그렇습니다
src/providers/openai.ts 외의 어떤 것도 AI 벤더 SDK를 import 하지 않습니다. 모든 것은 하나의 인터페이스를 거칩니다:
// src/providers/ai-provider.ts
interface AIProvider {
id: string;
displayName: string;
generateText(instructions, input, options?): Promise<{ text, model, providerId }>;
generateJson(instructions, input, jsonShapeDescription, options?): Promise<{ raw, model, providerId }>;
isConfigured(): boolean;
}인지 단계는 다음과 같이 매핑됩니다: reason → generateJson, plan → generateJson, evaluate → core/evaluator.ts의 결정적 코드. 평가는 의도적으로 프로바이더 호출이 아니므로, 모델은 자신의 실패한 실행을 성공으로 스스로 평가할 수 없습니다.
모델/벤더를 추가하려면: AIProvider를 구현하는 src/providers/<name>.ts를 작성하고 providers/index.ts에 등록한 다음 CHAOS_CORE_PROVIDER=<name>으로 설정합니다. 모델 이름 자체는 OPENAI_MODEL을 통해 한 번 구성되며 — 다른 파일에는 나타나지 않습니다.
캐퍼빌리티 레지스트리 — 확장의 접점
Capability 객체는 { name, description, risk, inputSchema (Zod), annotations, handler } 형태입니다. V1에는 두 개가 포함됩니다:
cognition.generate_text— 활성 프로바이더를 통한 범용 텍스트 생성http.request— GET 전용이며,policy.httpAllowedDomains로 제한됩니다
하나를 추가하려면 — 외부 API, 데이터베이스, 다른 MCP 서버 또는 자체 애플리케이션: Capability를 내보내는 파일을 src/capabilities/built-in/에 만들고 src/capabilities/index.ts에 등록합니다. core/, policy/, server/, transport/에는 아무것도 변경되지 않으며, 로컬 및 원격 클라이언트에 동시에 노출됩니다. AI는 레지스트리의 설명을 통해 무엇이 계획 단계를 해결할지 발견하며, if (task === "email") ...처럼 하드코딩하지 않습니다.
향후 방향: 레지스트리는 확장의 성장 경로입니다 — 캐퍼빌리티 팩(등록된 그룹), 이름이 아니라 risk를 키로 하는 캐퍼빌리티별 정책, 원격 MCP 클라이언트를 감싸 Chaos Core가 다른 MCP 서버를 통합할 수 있게 하는 어댑터 캐퍼빌리티, 반복 목표에 어떤 캐퍼빌리티 시퀀스가 성공하는지 학습하는 지속형 절차적 메모리.
메모리
V1은 지속형 Semantic Memory 계층을 MemoryStore 인터페이스(src/memory/types.ts) 뒤에 구현하고, 팩토리(src/memory/store.ts)가 선택하는 SQLite 구현(src/memory/sqlite.ts)을 사용합니다. node:sqlite를 기반으로 합니다 — Node 22.5+에 내장되어 있고 네이티브 의존성이 전혀 없으며, 태그, TTL, 부분 문자열 검색, 페이지네이션 키/값 저장소입니다.
SQLite를 Postgres 또는 벡터 저장소로 교체하려면 sqlite.ts 옆에 파일을 하나 추가하고 팩토리를 바꾸는 것으로 충분합니다. MCP 도구, 플래너, 인지 코어, 정책 엔진은 SQLite를 참조하지 않으므로 변경할 필요가 없습니다.
요청이 어디서 왔든 동일한 데이터베이스가 사용됩니다 — stdio로 작성된 사실은 HTTP로도 조회 가능하며 재시작 후에도 유지됩니다.
Working Memory(현재 세션 컨텍스트)는 src/state/session.ts입니다. Episodic Memory(과거 작업에서 일어난 일)와 Procedural Memory(학습된 성공 단계 시퀀스)는 아키텍처에서 명명되지만 V1에는 구현되지 않습니다.
설정
npm install
cp .env.example .env # then fill in OPENAI_API_KEY
npm run buildstdio로 실행 (로컬 클라이언트, 개발)
npm startnpm run start:stdio가 명시적인 동등 명령입니다. npm start는 계속 stdio이므로 기존 로컬 설정은 영향받지 않습니다.
stdio에서 stdout은 MCP 프로토콜 소유입니다. 코드베이스의 모든 진단은 observability/logger.ts를 거치며, stdio 트랜스포트는 CHAOS_CORE_LOG_STREAM=stdout으로 설정되어 있더라도 로거가 stderr로 출력되도록 강제합니다.
Streamable HTTP로 실행 (원격 클라이언트)
npm run start:httpHOST:PORT(기본값 127.0.0.1:3000)에서 리슨하고 다음을 노출합니다:
Method | Path | Purpose |
|
| 클라이언트 → 서버 JSON-RPC (initialize, tools/list, tools/call, …) |
|
| 기존 세션에 대한 서버 → 클라이언트 SSE 알림 스트림 |
|
| 명시적 세션 종료 |
|
| 활성 상태 + 활성 세션 수 (MCP의 일부 아님) |
로컬 엔드포인트: http://localhost:3000/mcp
HTTP 전송은 stateful입니다: 각 initialize는 Mcp-Session-Id를 발급하고 이후 요청은 그 id를 포함해야 합니다. 그래서 chaoscore_plan이 원격 클라이언트 사이에 plan_id가 유출되지 않으면서 plan_id를 chaoscore_execute로 전달할 수 있습니다. 알 수 없는 세션 id를 가진 요청은 404를 받고, 세션 id 없는 비-initialize 요청은 400을 받습니다.
환경 변수
Variable | Default | Purpose |
| — | OpenAI 프로바이더에 필요. 서버만 읽을 수 있고 MCP 클라이언트에는 절대 노출되지 않음 |
|
| 기본 모델. 모델 이름을 설정하는 유일한 곳 |
|
|
|
|
| 등록된 |
|
| HTTP 전송 포트 |
|
| HTTP 전송 바인드 주소 |
|
| MCP 엔드포인트가 마운트되는 경로 |
| — | 쉼표 구분 목록; 설정 시 DNS 리바인딩 보호가 활성화됩니다 |
| — | 쉼표 구분 목록; 동일합니다 |
|
|
|
|
|
|
|
| 정책 설정 파일 |
|
|
|
|
| 도구 응답당 최대 문자 수 |
|
|
|
작업 디렉터리의 .env는 자동으로 로드됩니다(Node의 내장 로더 — 의존성 없음). .env.example은 플레이스홀더만을 담고 있습니다. 실제 자격 증명은 커밋해서는 안 됩니다.
0.2 이전의 COGNITION_* 변수 이름은 여전히 폴백으로 동작합니다.
로컬 MCP 클라이언트 연결
Claude Desktop / Claude Code / 모든 stdio 클라이언트:
{
"mcpServers": {
"chaos-core": {
"command": "node",
"args": ["F:/Chaos-Origins/chaos-core-mcp/dist/index.js", "--stdio"],
"env": { "OPENAI_API_KEY": "sk-..." }
}
}
}또는 MCP Inspector를 사용하는 경우:
npm run inspector:stdio원격 MCP 클라이언트 연결
HTTP 전송을 시작한 다음, 클라이언트가 엔드포인트 URL을 가리키게 하세요:
http://localhost:3000/mcpClaude 커스텀 커넥터인 경우 해당 URL로 원격 MCP 서버로 추가하세요(공개 배포에는 공개 HTTPS URL이 필요합니다 — 아래의 보안 경고를 참조하세요). 수동으로 테스트해 보려면:
npm run inspector:http그런 다음 "Streamable HTTP"를 선택하고 URL을 입력하세요.
⚠️ 원격 배포 보안 경고
V1에는 인증이 포함되어 있지 않습니다. 이는 의도적인 선택이며, HTTP 전송이 기본적으로 127.0.0.1에 바인딩되기 때문에 안전한 것뿐입니다. 이 계층은 인증 미들웨어가 깔끔하게 추가될 수 있도록 설계되어 있습니다(src/transport/http.ts의 AuthMiddleware가 MCP 처리 전에 MCP 라우트에 적용됩니다). 하지만 가짜로 구현된 것은 없습니다. 즉, 스텁 OAuth도, 하드코딩된 비밀 값도, 보안처럼 보이기만 하는 베어러 토큰도 제공되지 않습니다.
이를 로컬호스트 밖으로 노출하기 전에 반드시 다음을 추가하세요:
인증 —
/mcp라우트에 적용(MCP 인증 사양에 따른 OAuth 2.1 리소스 서버 또는 identity 인증을 처리하는 게이트웨이)TLS — 서버는 평문 HTTP를 사용하므로 리버스 프록시에서 TLS를 종료하세요.
Rate limiting 및 요청 크기 제한 — 모든
reason/plan호출은 OpenAI 할당량을 소모합니다.DNS 리바인딩 방지 —
MCP_ALLOWED_HOSTS/MCP_ALLOWED_ORIGINS설정검토된
policy.json— 기본값은 확인이 필요한 기능을 제외한 모든 등록된 기능을 허용합니다.영구적인 감사 저장소 — V1 감사 추적은 인메모리 링 버퍼입니다.
미들웨어 없이 루프백이 아닌 주소에 바인딩하면, 서버는 시작 시 정확히 이 사실을 알리는 경고를 로그에 남깁니다. 전체 체크리스트는 docs/remote-deployment.md를 참조하세요.
OpenAI API 키는 providers/openai.ts 내부에서 서버의 환경 변수로 읽히며, 도구 출력, 검사(inspect) 페이로드, 감사 항목, HTTP 응답에는 절대 반환되지 않습니다.
V1 기능과 경계
포함된 것:
TypeScript/Node, MCP SDK, OpenAI Responses API를 기본(교체 가능) 프로바이더로 사용
이중 전송:
/mcp에서의 stdio + Streamable HTTP, 하나의 공유 인지 코어여섯 가지 도구로 구성된 인지 레이어, 두 전송에서 동일
기능 레지스트리 + 결정론적 정책 엔진 + 구조화된 감사 이벤트
교체 가능한
MemoryStore인터페이스 뒤에 위치한 SQLite Semantic Memory모든 도구 입력과 모든 기능 입력에 대한 Zod 검증
의도적으로 제외된 것:
UI 없음
에이전트 스웜 / 멀티 에이전트 아키텍처 없음
자율적인 백그라운드 실행 없음 —
chaoscore_execute는 전달된 단계만 정확히 실행하며,core/brain.ts의 전체 루프 재계획은 존재하지만 도구로 노출되지는 않습니다.OAuth 구현 없음, 멀티 테넌시 없음, 마켓플레이스 없음
MCP 서버 페더레이션 없음(레지스트리는 어댑터 기능을 호스팅할 수는 있지만 어떤 것도 포함되어 제공되지는 않습니다)
빌드 및 테스트
npm run buildnpm test테스트 스위트는 빌드된 결과물을 대상으로 실행되며 다음을 검증합니다: 정책의 결정론성과 비우회 가능성, 시뮬레이션된 재시작 후에도 메모리가 유지되는지, 그리고 두 전송 모두에 연결한 라이브 MCP 클라이언트가 동일한 도구 표면과 공유 메모리를 확인하고, 거부된 기능이 각 전송에서 차단되는지 확인합니다.
Available Tools
6 toolschaoscore_executeExecute PlanADestructive
Run a plan (or inline steps) through the remaining stages of the Cognitive Core loop: policy check -> capability selection -> execution -> evaluation. This is the only tool in this server that can have side effects, and only insofar as the capabilities it invokes do.
Each step is policy-checked individually before it runs (ALLOW / DENY / REQUIRE_APPROVAL — see chaoscore_inspect target="policy"). Steps that are DENY, or REQUIRE_APPROVAL and not yet confirmed, are reported as failed/skipped rather than silently dropped — read each step's error field. Every policy decision and capability call is recorded to the audit trail (chaoscore_inspect target="audit"). This is identical over stdio and over remote HTTP: there is no transport that can reach a capability without passing the policy engine.
Args:
plan_id (string, optional): id from a prior chaoscore_plan call in this session
steps (array, optional): inline steps [{description, capability, input, rationale}], alternative to plan_id
confirmed (boolean): set true to also run steps that resolve to REQUIRE_APPROVAL (default: false)
dry_run (boolean): if true, validates policy + input schema per step without calling any handler (default: false)
response_format ('markdown' | 'json'): Output format (default: 'markdown')
Returns: For JSON format: { "planId": string, "objective": string, "steps": [ { "stepId": string, "capability": string, "success": boolean, "output"?: any, "error"?: string, "policyDecision": { "decision": "allow"|"deny"|"require_approval", "allowed": boolean, "requiresConfirmation": boolean, "reason": string }, "durationMs": number } ], "evaluation": { "success": boolean, "summary": string, "notes": string[] }, "completedAt": string }
Examples:
Use when: You have a plan_id from chaoscore_plan and are ready to run it -> chaoscore_execute(plan_id="...")
Use when: A step came back REQUIRE_APPROVAL and you've now confirmed with the user -> re-run with confirmed=true
Don't use when: You just want to see what a plan would do without side effects -> use dry_run=true
Error Handling:
Returns "Error: plan_id not found in this session" if the plan wasn't created in the current MCP session
Individual step failures do NOT throw — they appear in the steps array with success=false
| Name | Required | Description | Default |
|---|---|---|---|
| steps | No | Inline steps to execute directly, as an alternative to plan_id | |
| dry_run | No | If true, validate policy + input schema for every step but never call any capability handler | |
| plan_id | No | id of a plan previously returned by chaoscore_plan in this MCP session | |
| confirmed | No | Set true to also run steps whose capability policy resolves to REQUIRE_APPROVAL | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses that the tool can have side effects, aligns with destructiveHint=true, and adds depth: each step is policy-checked individually, DENY/REQUIRE_APPROVAL steps are reported as failed/skipped, and all decisions are recorded to an audit trail. It even states transport invariance (stdio/HTTP) regarding policy enforcement, which is valuable context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every part serves a purpose: core functionality, policy details, parameter explanations, return structure, usage examples, and error handling. It is front-loaded with the primary purpose and logically organized. No wasted sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is exhaustive for a complex tool: it covers side effects, policy behavior, both invocation modes, output format details, error handling (plan_id not found), and the fact that step failures don't throw. It even provides a full JSON response structure. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
While the schema already describes all parameters (100% coverage), the description adds meaningful nuance: the relationship between plan_id and steps (alternatives), the confirmed flag's role in running REQUIRE_APPROVAL steps, and the dry_run option to avoid side effects. It also clarifies the response_format's human vs. machine readability. This enriches the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: executing a plan or inline steps through the Cognitive Core loop. It distinguishes from siblings by noting it's the only tool that can have side effects, and it specifies the pipeline (policy check, capability selection, execution, evaluation). This is a specific verb+resource with clear differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage scenarios: 'Use when: You have a plan_id from chaoscore_plan and are ready to run it', and 'Use when: A step came back REQUIRE_APPROVAL and you've now confirmed with the user'. It also gives a clear exclusion: 'Don't use when: You just want to see what a plan would do without side effects -> use dry_run=true'. This is excellent guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
chaoscore_inspectInspect Chaos Core StateARead-onlyIdempotent
Read-only introspection into Chaos Core's current state: registered capabilities, active policy, registered AI providers (and which one is answering reason/plan calls), the audit trail, memory store stats, and this session's most recent reasoning/plan/execution results. Never modifies anything, and never reveals credentials.
Capabilities, policy, memory, and audit are process-wide — a remote HTTP client and a local stdio client inspecting the same running server see the same values. The last_* targets and 'session' are scoped to your own MCP session.
Args:
target ('capabilities'|'policy'|'providers'|'memory'|'audit'|'session'|'last_reasoning'|'last_plan'|'last_execution'): what to inspect
response_format ('markdown' | 'json'): Output format (default: 'markdown')
Returns: Varies by target. 'capabilities': list of {name, description, risk, inputSummary, readOnly, destructive}. 'policy': the active PolicyConfig. 'providers': list of {id, displayName, configured, active}. 'memory': {recordCount, backend}. 'audit': recent {type, ts, sessionId, planId, stepId, capability, ...}[] entries. 'session': {sessionId, startedAt}. For the last_* targets: the most recent ReasoningResult / Plan / ExecutionTrace produced in this session, or null if none yet.
Examples:
Use when: "What can this server actually do?" -> target="capabilities"
Use when: "Which model is actually answering my reason/plan calls right now?" -> target="providers"
Use when: "Why did that step get blocked?" -> target="policy" or target="audit"
Error Handling:
Never errors under normal use; unknown target values are rejected by schema validation before this tool runs
| Name | Required | Description | Default |
|---|---|---|---|
| target | Yes | Which part of Chaos Core state to inspect: 'capabilities' (registry), 'policy' (active policy config), 'providers' (registered AI providers and which is active), 'memory' (record count), 'audit' (recent policy decisions + capability executions), 'session' (this MCP session's id and transport), 'last_reasoning', 'last_plan', or 'last_execution' (this session's most recent result of each stage) | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
While annotations already declare readOnlyHint=true and destructiveHint=false, the description adds critical context beyond those: it never reveals credentials, and clarifies process-wide vs session-scoped state (e.g., capabilities are global, last_* are per-session). It also discloses error behavior ('never errors under normal use'). This enriches the agent's understanding of side effects and safety without contradicting annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (main purpose, Args, Returns, Examples, Error Handling). It front-loads the core purpose and scope, then provides just enough detail per target. Every sentence earns its place—examples are actionable and error handling is concise. It is comprehensive without being redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's 2 parameters with full enum coverage, no output schema, and read-only annotations, the description is remarkably complete. It explains return values for every target, clarifies session vs process-wide scope, addresses credential safety, and covers error handling. An agent has everything needed to invoke it correctly and interpret results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already fully describes both parameters with enums and descriptions (schema coverage 100%). The description's Args section restates the targets but adds value by coupling each target to its return shape in the Returns section (e.g., 'capabilities' returns {name, description, risk, ...}). This goes beyond the schema's generic phrasing and helps the agent anticipate output, though the schema already handles the basic parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it is a read-only introspection tool for Chaos Core's state, listing specific targets (capabilities, policy, providers, memory, audit, session, last_*). It explicitly says 'Never modifies anything' and differentiates from sibling tools (reason/plan/execute) by focusing on inspection. The verb and resource are precise, and the scope is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit examples of when to use this tool: 'What can this server actually do?' -> capabilities, 'Which model is actually answering...' -> providers, 'Why did that step get blocked?' -> policy/audit. This gives clear usage conditions and implicitly contrasts with the mutating siblings. It also states the tool is read-only, reinforcing appropriate use cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
chaoscore_planPlan ObjectiveARead-only
Produce an ordered, executable plan for an objective, using ONLY capabilities currently in the capability registry (capability discovery). Uses the active AI provider to select capabilities and construct step inputs. This is the Planner stage of the Cognitive Core loop.
The returned plan.id must be passed to chaoscore_execute to run it, and is scoped to your MCP session. Planning does NOT execute anything and is NOT authorization to act — policy checks happen at execution time, per step.
Args:
objective (string): The goal to produce a plan for
context (array): Background info as [{source, content}, ...]. Include prior chaoscore_reason output here if you called it first.
reasoning_effort (optional): Override the active provider's default reasoning effort
response_format ('markdown' | 'json'): Output format (default: 'markdown')
Returns: For JSON format: { "id": string, // pass this to chaoscore_execute "objective": string, "steps": [ { "id": string, "description": string, "capability": string, "input": object, "rationale": string } ], "createdAt": string, "model": string, "providerId": string }
Examples:
Use when: "Draft a summary of these release notes" -> plan with a step using capability "cognition.generate_text"
Don't use when: You want to actually run the plan -> follow up with chaoscore_execute(plan_id=...)
Error Handling:
Returns "Error: OPENAI_API_KEY is not set" (or the active provider's equivalent) if the provider isn't configured
If the model references an unregistered capability name, chaoscore_execute reports that step as failed with an "Unknown capability" error — call chaoscore_inspect(target="capabilities") to see what's available
| Name | Required | Description | Default |
|---|---|---|---|
| context | No | Relevant background information to ground the reasoning/plan. Empty array if none. | |
| objective | Yes | The goal to produce an executable plan for | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
| reasoning_effort | No | Override the active provider's default reasoning effort for this call |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, and the description adds valuable context beyond them: planning is explicitly 'NOT authorization to act — policy checks happen at execution time, per step', and it clarifies that no execution occurs. It also discloses provider-configuration error behavior ('OPENAI_API_KEY is not set'). No contradiction with any annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every section earns its place: since no output schema exists, the 'Returns' JSON block is essential, and the error-handling section covers realistic failure modes. It is well-structured with clear headers and front-loads the core purpose before details. Slight redundancy between the Returns block and the parameter glossary keeps it from a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a moderately complex tool (4 params, 2 enums, no output schema, with 5 siblings), the description covers purpose, usage boundaries, return shape, and errors comprehensively. It explains the capability-registry constraint and how to discover valid capabilities via chaoscore_inspect. Minor gaps remain (e.g., no mention of plan length limits or cancellation), but nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all four parameters, giving a baseline of 3. The description adds marginal value by hinting that context should include prior chaoscore_reason output, but repeats most parameter purpose verbatim rather than deepening it. Adequate given the schema's completeness.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-resource pair ('Produce an ordered, executable plan for an objective') plus a hard scoping constraint ('using ONLY capabilities currently in the capability registry'). It explicitly positions itself as 'the Planner stage of the Cognitive Core loop' and states what it is not — 'Planning does NOT execute anything' — which cleanly distinguishes it from the sibling chaoscore_execute.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description contains explicit 'Use when' and 'Don't use when' examples, names chaoscore_execute as the follow-up, tells the agent to pass the returned plan.id to it, and instructs that prior chaoscore_reason output should be placed into the context parameter. Guidance on when to use vs. alternatives is fully spelled out with no inference required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
chaoscore_reasonReason About ObjectiveARead-only
Analyze an objective and its context BEFORE committing to a plan (the Intent Analyzer stage of the Cognitive Core loop: objective -> context -> AI planning -> policy -> capability execution -> evaluation -> result). Uses whichever AI provider is currently active (see chaoscore_inspect target="providers") to produce structured analysis: key considerations, risks, and a recommended approach.
Does NOT produce an executable plan or take any action — call chaoscore_plan next for that.
Args:
objective (string): The goal or question to reason about
context (array): Background info as [{source, content}, ...]. Empty array if none.
reasoning_effort (optional): Override the active provider's default reasoning effort ('none'|'low'|'medium'|'high'|'xhigh'|'max')
response_format ('markdown' | 'json'): Output format (default: 'markdown')
Returns: For JSON format: { "objective": string, "analysis": string, "keyConsiderations": string[], "risks": string[], "recommendedApproach": string, "model": string, "providerId": string }
Examples:
Use when: "Should I migrate memory storage before or after the staging cutover?" -> reason about tradeoffs first
Don't use when: You already know the approach and just need an executable plan -> use chaoscore_plan directly
Error Handling:
Returns "Error: OPENAI_API_KEY is not set" (or the active provider's equivalent) if the provider isn't configured
| Name | Required | Description | Default |
|---|---|---|---|
| context | No | Relevant background information to ground the reasoning/plan. Empty array if none. | |
| objective | Yes | The goal or question to reason about | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
| reasoning_effort | No | Override the active provider's default reasoning effort for this call |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses that the tool does not take action, uses the active AI provider, and includes specific error-handling behavior if the provider is not configured. It also describes the return structure for JSON format. This adds significant richness beyond the annotations and fully explains the tool's non-mutating, provider-dependent nature.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections: purpose, pipeline placement, what it does not do, args, returns, examples, and error handling. It is front-loaded with the primary purpose and every section adds value. The length is justified by the inclusion of a return schema (since no output schema is provided) and error handling, making it efficient rather than verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete for an agent to call this tool correctly. It covers the input parameters, provides a return schema for JSON format, explains the provider dependency and how to inspect it (see chaoscore_inspect), gives usage examples, and documents error cases. With no output schema present, the included return structure is essential and well-provided.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3. The description adds a bit of extra clarity, e.g., for 'context' it specifies the exact structure '[source, content]' and for 'response_format' it notes the default. It also explicitly lists enum values and says 'empty array if none.' While mostly redundant with the schema, it provides a slightly more concise and action-oriented explanation, justifying a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Analyze an objective and its context BEFORE committing to a plan') with a clear resource (the objective and context) and delivers structured analysis. It explicitly distinguishes itself from siblings: 'Does NOT produce an executable plan... call chaoscore_plan next.' The purpose is unambiguous and differentiates well from chaoscore_plan, chaoscore_execute, etc.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides concrete when-to-use and when-not-to-use guidance with an example ('Should I migrate memory storage...?') and explicitly references the alternative ('use chaoscore_plan directly'). It also frames this as the first stage in the Cognitive Core loop, giving clear context for when this tool should be invoked.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
chaoscore_recallRecallARead-onlyIdempotent
Search Semantic Memory records previously stored with chaoscore_remember. Supports exact key lookup, substring search over keys/values, and tag filtering. Expired records (past their ttl_seconds) are never returned. Reads the same durable store regardless of which transport you connected through.
Args:
key (string, optional): Exact key to fetch one record directly
query (string, optional): Substring to match against keys/values
tags (array of strings): Only return records with ALL of these tags (default: [])
limit (number, 1-100): Max results (default: 20)
offset (number): Pagination offset (default: 0)
response_format ('markdown' | 'json'): Output format (default: 'markdown')
Returns: For JSON format (key lookup): { "key": string, "value": string, "tags": string[], ... } or null if not found For JSON format (search): { "total": number, "count": number, "offset": number, "records": [...], "has_more": boolean, "next_offset"?: number }
Examples:
Use when: "What do we know about staging?" -> query="staging"
Use when: "Get the exact record for key X" -> key="staging.region"
Don't use when: You want to write/update a memory -> use chaoscore_remember instead
Error Handling:
Returns "No memory found for key ''" (not an error) if an exact key lookup misses
Returns empty records array (not an error) if a search finds nothing
| Name | Required | Description | Default |
|---|---|---|---|
| key | No | Exact key to fetch a single record. If set, other filters are ignored. | |
| tags | No | Only return records that have ALL of these tags | |
| limit | No | Max results to return | |
| query | No | Substring to match against memory keys and values | |
| offset | No | Number of results to skip for pagination | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds valuable behavioral context beyond these: expired records are never returned, the store is durable across transports, and miss returns are non-error strings/empty arrays. No contradictions with annotations are present.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-organized into sections (Args, Returns, Examples, Error Handling) with the core purpose front-loaded. Every sentence serves a purpose; there is no fluff or repetition. Despite its length, it remains efficient and scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with six parameters and no output schema, the description fully covers behavior: it documents both markdown and JSON return structures, error handling for misses, pagination fields, and example use cases. An agent has all necessary information to call it correctly without external documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description enriches parameter understanding by explaining interaction effects (e.g., 'key' ignores other filters), pagination semantics (offset, has_more, next_offset), and response format differences. It also provides concrete examples that map parameters to real queries, going well beyond bare schema types.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb ('Search') and resource ('Semantic Memory records'), and explicitly distinguishes itself from chaoscore_remember ('previously stored with chaoscore_remember'). It lists the three supported search modes (exact key, substring, tag filtering), leaving no ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit use cases with examples ('What do we know about staging?' -> query='staging') and a clear exclusion ('Don't use when: You want to write/update a memory -> use chaoscore_remember instead'). This gives an agent precise decision criteria for choosing this tool over its sibling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
chaoscore_rememberRememberAIdempotent
Persist a key/value record to Semantic Memory (durable, SQLite-backed), so it can be retrieved later with chaoscore_recall — in this session, in a future session, after a server restart, and from either transport. Writing to an existing key overwrites its value and updates its timestamp, making chaoscore_remember idempotent for a given key/value pair.
Memory is a property of the deployment, not of the connection: a record written over stdio is readable over HTTP and vice versa, provided both point at the same database file.
Args:
key (string, 1-200 chars): Unique identifier for this memory
value (string): The content to remember
tags (array of strings): Optional tags for filtering later (default: [])
ttl_seconds (number, optional): If set, the record is treated as expired (and excluded from chaoscore_recall) after this many seconds
response_format ('markdown' | 'json'): Output format (default: 'markdown')
Returns: For JSON format: { "key": string, "value": string, "tags": string[], "createdAt": string, "updatedAt": string, "expiresAt": string | null }
Examples:
Use when: "Remember that the staging DB uses the Melbourne region" -> key="staging.region", value="Melbourne (australiaeast)"
Don't use when: You need to search existing memories -> use chaoscore_recall instead
Error Handling:
Returns "Error: ..." with the underlying SQLite error message if the write fails (e.g. disk full, path unwritable)
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | Unique key for this memory. Writing an existing key overwrites its value. | |
| tags | No | Optional tags for later filtering with chaoscore_recall | |
| value | Yes | The content to remember | |
| ttl_seconds | No | Optional time-to-live in seconds. Omit for a record that never expires. | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate idempotent, non-read-only, and non-destructive. The description goes further: it explains durable SQLite-backed storage, persistence across sessions/restarts/transports, overwrite semantics with timestamp updates, TTL behavior (exclusion from recall), and error handling. This exceeds annotation coverage without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (Args, Returns, Examples, Error Handling) and front-loads the core purpose. Every sentence conveys necessary information without redundancy, making it appropriately concise for a tool with this complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (5 params, TTL, transport independence, output formats) and lack of an output schema, the description covers all needed aspects: purpose, usage, params, return format, error handling, and examples. An agent can confidently invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all parameters. The description repeats most parameter details and adds minor clarifications (e.g., TTL expiration behavior, key uniqueness), but does not significantly augment the schema. Baseline 3 is appropriate when schema handles the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it persists key/value records to Semantic Memory for later retrieval via chaoscore_recall. It specifies the resource (Semantic Memory), the verb (persist), and distinguishes itself from the recall sibling by explicitly naming it as the retrieval counterpart.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
An explicit 'Examples' section provides a concrete use case ('Remember that the staging DB uses the Melbourne region') and a don't-use case ('You need to search existing memories -> use chaoscore_recall instead'). This directly instructs when to use versus when to use the sibling, leaving no ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
6 tool updates
v0.2.0- First observed
chaoscore_execute - First observed
chaoscore_inspect - First observed
chaoscore_plan - First observed
chaoscore_reason - First observed
chaoscore_recall - First observed
chaoscore_remember
TDQS
Scored across 6 tools
Each tool has a clearly distinct role in the cognitive core loop: reason analyzes before planning, plan produces an executable plan, execute runs it, inspect provides read-only introspection, and remember/recall handle persistent memory. There is no overlap in purpose; even reason and plan, which share similar arguments, are explicitly differentiated by what they produce.
All tools follow a consistent naming pattern: the 'chaoscore_' prefix followed by a lowercase verb (reason, plan, execute, inspect, remember, recall). No mixing of camelCase or inconsistent verb styles; the pattern is uniform and predictable.
With 6 tools, the server is well-scoped. Each tool corresponds to a necessary stage of the cognitive core workflow (reason, plan, execute, inspect) plus persistent memory operations (remember/recall). There are no redundant or extraneous tools, and the count is well within the ideal 3-15 range.
The tool surface covers the full lifecycle: analyze (reason), plan (plan), execute (execute), observe (inspect), and persist/retrieve knowledge (remember/recall). Minor gaps exist, such as no explicit delete tool for memory (though overwrite covers updates) and no dedicated cancel/abort for plans, but these are not critical to the core loop. Overall, the domain is well-covered.
Maintenance
Related MCP Connectors
Persistent memory, hybrid search and a goal graph for AI agents, over stdio or remote HTTP.
Deterministic reasoning stack for AI agents: simulate, decide & compute, plus cross-domain tools.
Hosted runtime for persistent agent teams, durable workflows, memory, schedules, and goals.
Durable, user-controlled goals and governed plans for AI agents.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceDeterministic execution engine for AI agents. 412 modules across 78 categories including browser automation, file I/O, Docker, data parsing, crypto, and scheduling. Supports STDIO and Streamable HTTP transport with execution trace, evidence snapshots, and replay from any step.760 PyPI484Apache 2.0

ellmos-homebase-mcpofficial
AlicenseCqualityBmaintenanceEnables local-first LLM orchestration with persistent memory, knowledge management, routing, swarm patterns, API probing, tests, automation planning, and plugin discovery via a stdio MCP server, using SQLite for offline storage.5162 npm1MIT- AlicenseBqualityAmaintenanceEnables AI agents to maintain a local, event-sourced long-term memory with semantic retrieval, decision confidence checks, and proactive recalls, ensuring data never leaves the machine.233MIT
- AlicenseNot gradedqualityBmaintenanceEnables personal AI agents to perceive ambient context, retain episodic memory with decay, act proactively, and route routine decisions through fast System-1 reflexes while escalating ambiguous multi-hop plans to frontier LLMs. Includes reversible execution checkpoints, token budgets, and local-first memory retention, and plugs into MCP clients like Claude Desktop, Cursor, and Windsurf.7MIT