monad

πŸ“– TypeDocs Β Β·Β  API Reference


monad.ai

monad.ai 2.2.0

npm docs

Active execution agents inside semantic namespaces.

A monad is a daemon that runs a .me kernel, exposes it over HTTP, resolves namespace paths, and registers itself on a mesh surface so other monads and users can find it.

npm install -g monad.ai
monads                         # start the daemon on port 8161
monads proxy                   # start browser gateway on port 8160 (routes name.monad)

What a monad does

.me kernel      β†’ semantic tree, memory log, identity proof
HTTP surface    β†’ GET /path/name, POST / (write), /__bootstrap (health)
cleaker         β†’ anchors the kernel to a namespace (suign.cleaker.me)
mesh            β†’ announces self, accepts remote monad registrations

Every HTTP request carries a Host header. The monad resolves it into a namespace and routes the read or write into the correct kernel branch:

GET /profile/name
Host: suign.cleaker.me
β†’ me://suign.cleaker.me:read/profile/name

URL model

monad.ai separates meaning (namespace + path) from execution (which daemon answers):

me://<namespace>/<path>         canonical semantic address
http://127.0.0.1:<port>/path    transport address for browser / curl / fetch

The HTTP surface is what you call. The me:// address is what the namespace, mesh, logs, and routing layer use internally.

curl http://127.0.0.1:8161/profile/name -H "Host: suign.cleaker.me"
# β†’ reads profile.name from the suign.cleaker.me kernel

curl -X POST http://127.0.0.1:8161/ \
  -H "Host: suign.cleaker.me" \
  -H "Content-Type: application/json" \
  -d '{"expression":"profile.name","value":"Sui"}'
# β†’ writes into the namespace memory log

monad[name] β€” scope-chain routing

Targets can name a specific monad using bracket syntax:

me://suign.cleaker.me:read/monad[frank]/projects/x

The bridge extracts monadId = "frank" and resolves via fallback chain:

1. frank @ suign.cleaker.me   (compound β€” exact match)
2. frank @ cleaker.me         (rootspace β€” fallback)
3. 404

Same name resolves differently depending on namespace context. Mirrors JS prototype chain / CSS cascade / DNS resolution.

The bridge strips the monad[name] prefix before proxying β€” frank’s endpoint receives the request at /projects/x, not at /monad[frank]/projects/x.


Mesh β€” announce and discovery

Outgoing: monad announces itself

Set MONAD_SURFACE_URL to any surface and the monad announces itself on startup and every 30 seconds:

MONAD_SURFACE_URL=https://cleaker.me monads        # announce to public mesh
MONAD_SURFACE_URL=http://sui-macbook.local:8161 monads  # announce to LAN mesh
# (unset) = local-only, invisible to any remote surface

The announce interval is configurable:

MONAD_ANNOUNCE_INTERVAL_MS=60000 monads  # announce every 60s instead of 30s

Incoming: POST /.mesh/announce

Any monad can register on any surface:

POST /.mesh/announce
{
  "monad_id": "monad:abc123",
  "name": "frank",
  "namespace": "suign.cleaker.me",
  "endpoint": "http://raspberry.local:8161",
  "claimed_namespaces": ["suign.cleaker.me"],
  "tags": ["raspberry", "sensor"],
  "scope_path": "/projects/music"
}

Response:

{ "ok": true, "registered": true, "namespace": "suign.cleaker.me", "monad_id": "monad:abc123" }

Surfaces throttle repeated announces: minimum 10 seconds between accepted registrations from the same monad_id. Entries go stale after 5 minutes without a heartbeat.

Query: GET /.mesh/monads

Returns all registered monads on this surface. Used by the surface[] mesh resolver.


Environment variables

Variable Default Description
PORT 8161 HTTP port
SEED β€” Kernel seed (required for identity)
MONAD_SURFACE_URL β€” Surface to announce self to
MONAD_ANNOUNCE_INTERVAL_MS 30000 Heartbeat interval (min 10s)
MONAD_SELF_IDENTITY β€” Explicit namespace override
CLEAKER_NAMESPACE_ROOT β€” Namespace root override
HOSTNAME / COMPUTERNAME β€” Auto-discovered for local surface

Identity & claims

Before a namespace can receive writes, it must be claimed. A claim anchors a cryptographic identity β€” derived from (who, secret) via this.me β€” to the namespace:

POST /
Host: suign.cleaker.me
{ "operation": "claim", "secret": "...", "proof": { ... } }

Opening a claimed namespace returns the memory log for that identity. The caller replays it locally into their own .me kernel:

POST /
Host: suign.cleaker.me
{ "operation": "open", "secret": "...", "identityHash": "..." }
β†’ returns memories[] replayable by .me

The daemon verifies the proof but never holds the seed. The seed never leaves the client.


The kernel is the storage

Every write becomes a memory event in an append-only, hash-chained log:

memoryHash β†’ prevMemoryHash β†’ path β†’ operator β†’ value β†’ timestamp β†’ namespace

The /blocks endpoint projects that log. No separate database. No migrations. On restart, the daemon hydrates from the DiskStore β€” nothing is lost.


Surface hierarchy

Priority order for surface resolution:
1. local processes first
2. LAN / .local devices  (os.hostname() β†’ suis-macbook-air.local)
3. trusted mirrors
4. public surface (cleaker.me)

Every monad auto-discovers its own local surface via os.hostname(). This is the same mechanism cleaker uses for fallback β€” no configuration needed, devices find each other naturally on the LAN.


Deployment topologies

Local only (no mesh, invisible externally)

# MONAD_SURFACE_URL unset
SEED="my-seed" monads
# Reachable only from same machine at http://localhost:8161

Personal LAN mesh

MONAD_SURFACE_URL=http://sui-macbook.local:8161 SEED="my-seed" monads
# All LAN devices announce to the Mac; Mac serves as private mesh registry

Community namespace (public mesh)

MONAD_SURFACE_URL=https://cleaker.me SEED="my-seed" monads
# Monad appears in public directory
# Namespace owner controls traffic rules, billing, access policies

Running locally

cd npm
npm install
npm run build
SEED="your-seed" node dist/src/index.js
# read
curl http://localhost:8161/profile/name

# write
curl -X POST http://localhost:8161/ \
  -H "Host: suign.cleaker.me" \
  -H "Content-Type: application/json" \
  -d '{"expression":"profile.name","value":"Sui"}'

# health
curl http://localhost:8161/__bootstrap

Install

# Global daemon
npm install -g monad.ai

# Project dependency
npm install monad.ai

KDF deterministic identity

When SEED is set, monad derives its Ed25519 keypair deterministically via HKDF:

HKDF-SHA256(compound_seed, salt='', info='monad.ai/ed25519/v1', length=32) β†’ Ed25519 seed

Same (who, secret) β†’ same monad identity everywhere, every time. No key files to sync across machines.

SEED="your-seed" monads   # deterministic identity
monads                    # random keypair (backwards compatible)

Browser gateway

monads proxy               # start on port 8160 (default)
monads proxy --port 9000   # custom port

Configure browser to use PAC file: http://127.0.0.1:8160/proxy.pac

Then open frank.monad, local.monad, or localhost:8161 in the browser β€” all route to the correct running monad.


The stack

this.me    β†’ sovereign kernel. derives identity from (who, secret) seed. works offline.
cleaker    β†’ resolver. projects .me into a namespace surface. handles fallback chain.
monad.ai   β†’ daemon. runs the kernel over HTTP. registers on the mesh.
netget     β†’ gateway. routes physical requests to monad endpoints.

The namespace is not storage. The namespace is chemistry. It is the surface where identities react and compounds form.