// Primitives

Six pieces. Nothing hidden.

There is no framework object that runs your system. Routing decisions, workflow rules and lifecycle policy stay with you - Core gives you the parts and the contract they speak.

01

Signal The envelope

One shared contract for everything that crosses the bus - TASK, AGENT_OUTPUT, TOOL_CALL, RECALL, IMPRINT, FINAL. Two components that emit valid Signals can always talk to each other. That is the only guarantee Core makes, and everything else is built on it.

02

Neuron The unit of work

A pure async function - fn(input, context) → output - with zero protocol knowledge. The Neuron factory wraps OpenAI, Anthropic, HuggingFace, Groq, Ollama or an MCP server behind that same signature, so swapping a provider never touches the system around it.

03

Axon Agent-side identity

Owns a Neuron's identity and capabilities and wraps its output into protocol-valid Signals. An Axon never touches the Synapse - that boundary is enforced in code, not by convention, which is what keeps a Neuron portable.

04

Dendrite Synapse-side connector

The only component that touches the Synapse. It hosts Axons, emits REGISTER / HEARTBEAT / DEREGISTER, routes inbound TASKs to the right Neuron, and exposes every dispatch primitive: fire-and-forget, dispatch_and_wait, capability routing, competitive bidding.

05

Engram Memory

Shared memory as a protocol citizen rather than a library you import. Recall and Imprint are Signals on the same bus, backed by InMemory, SQLite or Postgres - which means memory access shows up in your traces like everything else.

06

Effector Tools and side effects

Anything that reaches out of the system. An Effector services TOOL_CALL Signals and mirrors what it did into an Engram, so the record of a side effect is part of the run and not a line in a log file somewhere.

Every concept in the protocol
// The edge

Receptors: where people come in.

A system nobody can talk to is not a product. A Receptor is an interface - a CLI, an HTTP API, a chat or voice surface - that funnels an outside request into the same dispatch trio every internal component uses. Same Signals, same traces, no special path for “the user-facing bit”.

One entry point

brain.py attaches Receptors and calls Dendrite.run(). That is the whole entry point - no separate CLI script, no second server, no drift between how you test the system and how it runs.

Interfaces are not special

A Receptor is caller-side and introduces no new wire types. Whether a TASK came from a terminal, an HTTP request or another Neuron, it is the same TASK - which is why Prism can show you a user-initiated run and an internal one side by side.

// Transport

Scale is a URL change.

The Synapse is an adapter, not an architecture decision you have to make on day one. Your Neuron code does not know or care which one is underneath it.

memory://
MemorySynapse
In-process. Tests, prototypes, single-host demos.
cosmo://
DevSynapse
Local TCP + NDJSON broker. cosmo synapse start boots it in a second.
nats://
NatsSynapse
The production default - the cleanest fit for the protocol's shape.
kafka://
KafkaSynapse
A durable, replayable log of every Signal that ever crossed the bus.
// Tooling

One CLI, two SDKs.

cosmo

cosmo init scaffolds a project. cosmo synapse start boots a local broker. cosmo dispatch fires a TASK from the terminal. cosmo validate checks envelope conformance. One implementation, installable from pip.

The wire, not the language

The Python SDK is the reference implementation, but nothing about the protocol is Python. Any component that emits and accepts valid Signals is a participant on the bus - the envelope is the whole contract.

Read the spec

The envelope specification is short on purpose. If you want to write a Cosmonapse implementation in a third language, that page plus cosmo schema is everything you need.

Learn by running something

Fourteen examples cover routing, bidding, retries, RAG, MCP tools, memory and full agents - each one a project you can clone and run rather than a snippet.