The seven steps below build a working brain by hand, so you see every wire before anything writes code for you. If you'd rather place components on a canvas and let Genesis generate the same files, switch to the .

Python 3.11+

The cosmo CLI ships inside the cosmonapse package - one install gets you both.

An HF token

Free at huggingface.co/settings/tokens. Swap Axon.huggingface for .openai, .anthropic or .ollama if you'd rather use those.

One terminal

The brain runs in one process on an in-process bus. A synapse and Prism are two more terminals, when you want to watch.

01 · Install

Python 3.11+. The [receptor] extra brings FastAPI and uvicorn for the HTTP interface below.

# Python 3.11+. The cosmo CLI ships inside the package.
$ pip install 'cosmonapse[receptor]' httpx
02 · Scaffold, then code

cosmo init writes the skeleton every example follows: one of each primitive, a component per module, and brain.py as the only entry. It runs before you write a line. The steps below code the quickstart on top of it: a Hugging Face Axon under neurons/, an HTTP Receptor under receptors/, and the wiring in brain.py.

$ cosmo init my-app -n quickstart

  Scaffolded my-app in ./my-app
    + config.py        + neurons/hello.py      + effector/tools.py
    + engram/store.py  + receptors/terminal.py + brain.py

$ cd my-app
$ python brain.py greet --name Ada   # one process, in-process bus - no setup
Hello, Ada!
$ python brain.py                    # a REPL on the same brain
03 · Build an Axon

Axon.huggingface() pairs a Neuron (a pure async callable around the model) with the Axon that gives it an identity on the bus and validates its output into a Signal. The Neuron never sees the protocol. .openai(), .anthropic(), .ollama() and .mcp() are the same shape. Set HF_TOKEN to your Hugging Face access token.

neurons/llama.py
from cosmonapse import Axon

from config import hf_token

# Axon.huggingface() (and .openai(), .anthropic(), .ollama(), .mcp())
# combines the Neuron factory + Axon wiring in one call.
AXON = Axon.huggingface(
    neuron_id="llama",
    endpoint="https://router.huggingface.co",
    model="meta-llama/Llama-3.1-8B-Instruct",
    api_key=hf_token(),
    use_chat_api=True,
    capabilities=["chat"],
)
04 · Add a Receptor

A Receptor is the interface: here an HTTP request becomes a TASK. The lifespan, body parsing, 504 on timeout and SSE streaming are the Receptor's job, so your web framework never touches the Synapse and the Neuron never sees HTTP.

receptors/api.py
from cosmonapse import ApiReceptor

RECEPTOR = ApiReceptor(
    neuron="llama",
    path="/task",
    timeout_s=30.0,
    # host="127.0.0.1", port=8000 are the defaults
)
05 · Wire the brain

A Dendrite is a node's attachment to the Synapse: it hosts components, emits REGISTER / HEARTBEAT / DEREGISTER, and routes inbound TASKs. One node hosts the Axon as a worker; the Receptor originates TASKs, so it gets an orchestrator node of its own. main() hands both to run_brain, which starts every node before serving any interface.

brain.py
import asyncio
import contextlib
import signal

from cosmonapse import Dendrite, MemorySynapse, connect_synapse, run_brain

from config import NAMESPACE, SYNAPSE_URL
from neurons import llama
from receptors import api


def build_llama(synapse) -> Dendrite:
    """Hosts the llama Axon. role="worker": replies to TASKs, never dispatches."""
    node = Dendrite(synapse=synapse, namespace=NAMESPACE,
                    dendrite_id="llama-node", role="worker")
    node.attach_axon(llama.AXON)
    return node


def build_api(synapse) -> Dendrite:
    """Hosts the HTTP Receptor on the one node allowed to dispatch."""
    node = Dendrite(synapse=synapse, namespace=NAMESPACE,
                    dendrite_id="api-node", heartbeat_s=0)
    node.attach_receptor(api.RECEPTOR)
    return node
06 · Run it

One process. The endpoint takes the TASK input as its body, or {"input": ..., "mode": ...} for fire-and-forget and streaming.

$ export HF_TOKEN=hf_xxxxxxxxxxxxxxxx
$ python brain.py
  api-receptor on http://127.0.0.1:8000

$ curl -s localhost:8000/task -H 'content-type: application/json' \
       -d '{"prompt": "Say hello to Cosmonapse."}'
{"response": "Hello! Great to meet you, Cosmonapse ...", "meta": {...}}

# the same endpoint, the other two shapes
$ curl -s  localhost:8000/task -H 'content-type: application/json' -d '{"input": "hi", "mode": "send"}'
$ curl -sN localhost:8000/task -H 'content-type: application/json' -d '{"input": "hi", "mode": "stream"}'
07 · Watch the Signals flow

Point the same brain at a real synapse with SYNAPSE_URL and attach Prism. It is a passive, read-only subscriber: it never competes with Dendrites for messages. Swap the URL for nats:// or kafka:// in production.

# terminal 1 - a dev synapse (TCP + NDJSON, no Docker)
$ cosmo synapse start memory --namespace=quickstart

# terminal 2 - the same brain over it; nothing in the code changes
$ SYNAPSE_URL=cosmo://127.0.0.1:7070 python brain.py

# terminal 3 - every Signal as it crosses
$ cosmo prism --tail --url=cosmo://127.0.0.1:7070 -n quickstart
  REGISTER      neuron=llama  capabilities=['chat']
  TASK          trace=trc_01...  neuron=llama
  AGENT_OUTPUT  trace=trc_01...  neuron=llama

# ...or Prism in the browser (http://127.0.0.1:7071)
$ cosmo prism --url=cosmo://127.0.0.1:7070 -n quickstart

The full example is cosmonapse-examples/01-quickstart; the examples build on it.