01 · Install

Python 3.11+ or Node 18+. The cosmo CLI ships with the Python package - run it from your virtualenv even when using the TypeScript SDK.

# Python 3.11+
pip install cosmonapse httpx
02 · Start a Synapse

cosmo synapse start memory boots a local TCP+NDJSON broker - no Docker, no NATS, no Postgres. Swap the URL for nats:// or kafka:// when you move to production - the rest of your code stays the same.

$ cosmo synapse start memory --namespace=quickstart

  URL:        cosmo://127.0.0.1:7070
  Namespace:  quickstart
  Transport:  TCP + NDJSON  (single-host dev only)
  ────────────────────────────────────────────────
03 · Build an Axon

Two steps, the lower-level way: Neuron(source="huggingface", ...) returns a pure async callable, and Axon(neuron_id=..., neuron_fn=...) gives it an identity on the bus. The Axon validates the Neuron's raw output into a Signal; the Neuron itself never sees the protocol. The one-call factory Axon.huggingface() - and .openai(), .anthropic(), .ollama(), .mcp() - is shorthand for exactly this. Set HF_TOKEN to your Hugging Face access token before running.

import os
from cosmonapse import Axon, Neuron

# Lower level, two steps. Neuron(source=...) is a pure async callable;
# the Axon gives it an identity and validates its output into a Signal.
neuron = Neuron(source="huggingface",
    endpoint="https://router.huggingface.co",
    model="meta-llama/Llama-3.1-8B-Instruct",
    api_key=os.environ["HF_TOKEN"], use_chat_api=True)

axon = Axon(neuron_id="llama", neuron_fn=neuron,
    capabilities=["chat"])
04 · Wire a Dendrite

The Dendrite is the only component that touches the Synapse - it hosts the Axon, emits REGISTER / HEARTBEAT / DEREGISTER, and routes inbound TASKs. Run this in a second terminal; it registers and waits for tasks.

worker.py
import asyncio, os
from cosmonapse import Axon, Dendrite, Neuron, connect_synapse

# Build the Neuron, then wire it into an Axon (the two-step, lower-level form).
# role="worker": hosts Axons, replies to TASKs, cannot dispatch.
neuron = Neuron(source="huggingface",
    endpoint="https://router.huggingface.co",
    model="meta-llama/Llama-3.1-8B-Instruct",
    api_key=os.environ["HF_TOKEN"], use_chat_api=True)
axon = Axon(neuron_id="llama", neuron_fn=neuron, capabilities=["chat"])

async def main():
    synapse = await connect_synapse("cosmo://127.0.0.1:7070")
    worker  = Dendrite(synapse=synapse, namespace="quickstart", role="worker")
    worker.attach_axon(axon)
    async with worker:
        await asyncio.sleep(float("inf"))  # serve until Ctrl-C

asyncio.run(main())
05 · Connect an HTTP interface

A role="orchestrator" Dendrite has no Axon - its job is to dispatch tasks and collect results. Keep your web framework at the edge and dispatch TASK Signals from route handlers via the orchestrator Dendrite. Install Flask with pip install flask or Express with npm install express.

server.py
import asyncio, threading
from flask import Flask, jsonify, request
from cosmonapse import Dendrite, connect_synapse

# asyncio loop in a background thread  -  Flask stays synchronous.
loop = asyncio.new_event_loop()
threading.Thread(target=loop.run_forever, daemon=True).start()
orch: Dendrite = None

async def setup():
    global orch
    synapse = await connect_synapse("cosmo://127.0.0.1:7070")
    orch = Dendrite(synapse=synapse, namespace="quickstart", role="orchestrator")
    await orch.start()

asyncio.run_coroutine_threadsafe(setup(), loop).result(timeout=10)
app = Flask(__name__)

@app.post("/task")
def submit():
    # dispatch_and_wait: emit a TASK, await the first terminal Signal,
    # close the Pathway, return the Signal. No manual future plumbing.
    fut = asyncio.run_coroutine_threadsafe(
        orch.dispatch_and_wait(neuron="llama",
                               input=request.get_json(), timeout_s=30.0),
        loop,
    )
    reply = fut.result(timeout=32)
    return jsonify(reply.payload["output"])

app.run(port=5000)
06 · Watch the Signals flow

Attach a Doppler to see every Signal as it crosses the Synapse. It is a passive read-only subscriber - it never competes with Dendrites for messages.

$ cosmo doppler --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

# filter to specific signal types
$ cosmo doppler -n quickstart --type TASK --type AGENT_OUTPUT

# or open Prism  -  the live browser visualization (http://127.0.0.1:7071)
$ cosmo doppler --prism --url=cosmo://127.0.0.1:7070 -n quickstart
07 · Test it

With the synapse, worker, and server all running, send a task:

$ curl -s -X POST http://localhost:5000/task \
       -H "Content-Type: application/json" \
       -d '{"prompt": "Say hello to Cosmonapse."}'

{"response": "Hello! Great to meet you, Cosmonapse..."}

Watch the Doppler terminal - you'll see the full REGISTER → TASK → AGENT_OUTPUT trace as it happens.