Quickstart
Two scripts, run one after the other, show the whole loop: run one records a correction, run two starts with that correction injected into the model call. The terminal on the right runs the direct memory calls from the second section against api.mubit.ai; switch it between Python, Node, and Rust with the buttons in the title bar.
Get your API key
Sign in to the Mubit console, open Settings → API keys and pick the project: this lands on the project's Settings tab, whose API keys card creates a named key (User or Admin role). The key is shown once. Keys look like mbt_<instance>_<key_id>_<secret>: the instance segment routes your call to the right region; the key id is safe to log; the secret is not.
The console shows four .env lines with the key. Copy all four; the SDK, the CLI and the console read the same values.
MUBIT_API_KEY="mbt_<instance>_<key_id>_<secret>"
MUBIT_ENDPOINT="https://api.mubit.ai"
MUBIT_PROJECT="first-project"
MUBIT_ENV="dev"mubit.init() and Client() read all four on start. MUBIT_ENV matters: lessons are partitioned by env, so both runs below must use the same value. See SDK configuration for the full variable list.
Local server
To run against a local Mubit, set MUBIT_ENDPOINT=http://127.0.0.1:3000 and MUBIT_API_KEY to the value of the server's MUBIT_BOOTSTRAP_ADMIN_API_KEY (the server logs Bootstrap admin API key loaded … for instance 'local' at start). Keys whose instance tag is local are accepted only by a local endpoint.
Install
The examples call OpenAI, so OPENAI_API_KEY must also be set. Any wrapped provider works the same way; see LLM providers.
Learn from one run, apply on the next
Both processes share three scenario values. Put them at the top of each script.
Run one ends when the with block (Python) or the run() callback (JS) returns. The server distils lessons a few seconds later; mubit status --agent <id> shows reflections_finished and lessons_stored. Run two, using the same MUBIT_API_KEY and the same MUBIT_ENV, receives the lesson inside the system message.
pipx install mubit-sdk # the CLI ships with the Python package
mubit status --agent invoice-helperEvery failure on this path is visible: a wrong key, an unreachable endpoint or a kill switch prints one WARNING mubit: … line per process, and run.outcome() returns an OutcomeReceipt whose reason says what happened (ok, nothing_to_record, unauthorized, unreachable, killed).
Didn't work?
Run mubit doctor. It prints the endpoint, the masked key, the server mode (loop_v1, legacy, or unreachable), the resolved project/env, and one line per problem. With a wrong key the SDK prints mubit: WARNING context fetch failed at https://… (HTTP 401 Unauthorized); running without memory once per process; if you see no lessons on run two and no warning, check that both runs used the same MUBIT_ENV.
mubit doctorendpoint: https://api.mubit.ai
key: mbt_acme_k1_****
mode: loop_v1 (server 0.4.0, policy starter@1)
scope: project=first-project env=dev agent=(unset)
health: ok (/v2/core/health)More cases are in Troubleshooting.
Store and search memory directly
The loop above stores and injects lessons for you. When you want to write and read memory yourself, use the Client namespaces. The script below stores a memory under one run and recalls it from a second run, keyed by the same user. The right-hand terminal runs this flow.
recall() returns the wire response as a plain dict / object (answer["final_answer"] in Python, answer.final_answer in JS), roughly:
{
"final_answer": "Taylor prefers to receive updates in a concise written format delivered on Friday afternoons, and explicitly dislikes receiving phone calls.",
"confidence": 1.0,
"mode": "agent_routed",
"evidence": [
{ "id": "f7bfcb26-…", "score": 1.0, "content": "Taylor prefers concise written updates on Friday afternoons; no phone calls." }
]
}Cross-run visibility: facts (kind="fact") are visible in the run that wrote them. To recall a memory from a different run keyed by user, store it as a lesson with visibility="global"; that is why the example above does so. See SDK helpers for the full set.
Pick your path
Most readers want the loop. Switch only when you outgrow it.
mubit.init() plus mubit.wrap_openai() / mubit.wrapOpenAI(). Lessons inject before each call, turns are captured after it, and the server distils new lessons when the run ends.
Call client.memory, client.runs, client.lessons and client.outcomes yourself when you want explicit control over scope, runs and metadata.
Plug Mubit into the framework's own memory interface. CrewAI, LangGraph, LangChain, LlamaIndex, ADK, Agno, Vercel AI SDK, MCP.
What to do next
- Get the mental model in Concepts — the memory model, retrieval semantics and the learning loop.
- Pick a pattern that matches your problem — handoffs, shared team memory, bi-temporal facts, context assembly.
- Open the run in the Loop console: the Runs tab shows the events, the injection receipt and the outcome you just recorded; the Lessons tab shows the distilled lesson.
- Inspect the helper surface in SDK helpers:
run,step,outcome,context,note,remember,recall. - Record per-step outcomes with step-level outcomes.
- Read the environment variable table before you set
MUBIT_ENV=prod. - Upgrading from 0.13? See Migration and Versioning.
- Plug into your framework via Framework integrations.
- Browse the full control surface at Control HTTP reference.