Skip to main content

memfleet

Agent teams forget. memfleet makes them remember — with judgment, provenance, and an operator in control.

memfleet is the command-line client for memfleet.com, the hosted platform for Strata, the open-source memory engine. Connected in two commands, without leaving the terminal:

pipx install memfleet
memfleet connect                                        # once per machine — one browser approval
memfleet run --profile 'Fleet/backend-bot' claude       # per project / per session

connect links the machine to your account. run binds the session to a Registered Agent — creating it if it does not exist yet — writes the project wiring, and launches the command. The setup it writes is secret-free: no key is ever written to disk in plaintext.

A teammate who holds only an enrollment code and no account of their own reaches the same with:

memfleet run --code XXXX --name mate --scope g_backend claude

What the fleet gets

  • Governed memory, not a shared scratchpad. Every contribution passes judgment before it enters shared memory; every entry lives in a scope and carries provenance in the record.
  • The operator is sovereign. See exactly what any scope's agents see, and steer memory directly. No hidden state.
  • Agents connect over MCP or REST — the same service layer either way. A bind wires up the hosted /mcp endpoint; /agent/v1 is the same service under a different door.
  • The engine is open source. Run Strata yourself, or let memfleet run the fleet for you.

A note on the version history

Releases of the memfleet distribution at or below 1.6.1 were the Strata engine — that package has been renamed and now ships as strata-mem (import package and CLI still strata). memfleet 2.0.0 was the first release of the cloud client, and 3.0.0 is the connect / run split described here (a clean break — see 2.x → 3.0.0 below). The major-version jump at 2.0.0 was deliberate: the repurposed package's "latest" must never resolve to an old engine release.

Install

Requires Python 3.11+ (stdlib tomllib, and the strata-mem dependency is 3.11+).

pipx install memfleet
# older default interpreter? point pipx at a newer one:
pipx install --python python3.11 memfleet

Depends on strata-mem (the Strata engine's install machinery); pip resolves it automatically. A No matching distribution found for memfleet error from pip almost always means the installing interpreter is older than 3.11 — note that pipx uses its own interpreter, not your shell's: an apt-installed pipx on Ubuntu 22.04 runs the system 3.10 even inside an activated 3.11 venv. Use pipx install --python "$(which python)" memfleet, or plain pip install memfleet inside any 3.11+ venv.

The two-command story

How often Command What happens
Once per machine memfleet connect Device-flow browser approval; the owner token lands in the OS keychain. Re-running it is a no-op that reports the existing connection — it asks nothing about agents.
Per project / per session memfleet run --profile '<Workspace>/<agent>' claude Binds to the Registered Agent — minting a key for one that exists, creating one that does not — writes the secret-free project setup (MCP config, contribution Stop-hook, the scope's skill), saves the agent profile as the project default, and execs claude with the agent key in its environment.

memfleet run is a generic launcher: everything after the flags is the command it starts (claude, bash, anything). The agent key is injected into that process's environment only — it never touches a file or your shell, and dies with the process. It is what the committed .mcp.json's ${MEMFLEET_AGENT_KEY} resolves at session start.

Once a project is bound, later sessions are just:

memfleet run claude          # the project default profile, no network at all

That fast path is the common one: a key already stored for the resolved profile means run execs immediately, making no request.

Connecting more agents

  • Another projectcd there and memfleet run --profile '<Workspace>/<agent>' claude. No browser step: the machine is already connected.
  • A second agent in the same project (say, a different scope) — memfleet run --profile 'Fleet/reviewer' --scope g_review claude. Every bind saves its own profile (<workspace>/<agent>); the newest becomes the project default.
  • Choose per sessionmemfleet run --profile "Fleet/other-agent" claude. Two terminals on the same repo can run as different agents concurrently (sessions bind, not machines — nothing is exported globally).
  • A teammate without owner accessmemfleet run --code XXXX --name mate --scope g_backend claude with an enrollment code you mint from the Console (no owner login involved).

Commands

Command What it does
memfleet connect Device-flow login; the owner token goes to the OS keychain. Idempotent, and asks no agent question.
memfleet run [--profile X] [--code XXXX] [--scope ID] [--name N] [--] COMMAND… Bind (or create) the Registered Agent, wire the project, exec COMMAND with the agent key injected into its environment.
memfleet status Report the resolved server, whether this machine is connected, what this directory binds to, and whether the scope's skill is installed. Read-only.
memfleet logout Forget the stored owner token.
memfleet workspaces list | create Manage workspaces over /api/v1/manage/*.
memfleet scopes list | create List / define scopes (validated engine-side).
memfleet agents list | create | revoke Manage Registered Agents.
memfleet codes list | create | revoke Manage enrollment codes.
memfleet profiles list | use List agent profiles; use writes the project default.
memfleet env [--profile X] Print eval-able export lines (shell/CI bridge; prints the key to stdout by design).
memfleet setup (Re)write the additive project setup on its own.

--workspace on scopes, agents and codes takes a Workspace id or its name — the same reference run --profile '<Workspace>/<agent>' resolves. memfleet workspaces list prints both.

memfleet status

Read-only, always exits 0 — a network failure is reported as a line, never a traceback — and it never prints a secret:

$ memfleet status
server   https://memfleet.com  (default)
account  connected (2 workspaces)
binding  profile Fleet/backend-bot  (project default)
         key     keychain
         agent   backend-bot — workspace Fleet, scope g_backend, skill code-writer
skill    installed (.claude/skills/code-writer/SKILL.md)

Each line answers one question:

  • server — the resolved URL and which of the four precedence rungs decided it (--server flag / MEMFLEET_SERVER / project .memfleet/config.toml / default);
  • account — whether an owner token is stored for that server, verified live with one /manage/workspaces call (connected (N workspaces) / token invalid — run memfleet connect / not connected — run memfleet connect);
  • binding — the resolved agent profile and its source (--profile flag / MEMFLEET_PROFILE / project default / none), where its key comes from (keychain / encrypted file / env / none), and — when a key resolves — the live /agent/v1/me identity;
  • skill — whether the bound scope's skill body is installed in this directory, compared against the server's own copy (installed / not installed — a bind via memfleet run installs it / scope has no skill body).

2.x → 3.0.0

A clean break: connect no longer touches agents, so there are no compatibility shims. The mapping is one-for-one.

2.x 3.0.0 Why
memfleet login memfleet connect connect absorbed it; the name is already truthful. login now errors with this pointer.
memfleet connect (guided: workspace → scope → name → agent) memfleet run --profile '<Workspace>/<agent>' [--scope ID] COMMAND connect conflated machine↔account with session↔agent, so a second terminal in a new directory re-asked questions already answered.
memfleet connect --workspace W --scope S --name N memfleet run --profile 'W/N' --scope S COMMAND The agent flags moved with the act they belong to.
memfleet connect --code XXXX --name N --scope S memfleet run --code XXXX --name N --scope S COMMAND The enrollment-code plane moved to run too — one command for a teammate with no account.
memfleet connect refused an existing agent name memfleet run --profile 'W/existing' binds to it An existing agent is the bind target now; that is the command's whole point.
connect --skill / --template / --create-workspace / --define-scope / --scope-name / --stratum / --parent memfleet workspaces create, memfleet scopes create, memfleet agents create run binds inside an existing Workspace and never creates one. Topology is an explicit act.
connect --project / --diff memfleet setup --project / --diff run's wiring is non-interactive by construction; setup is still the preview/rewrite door.
(nothing) memfleet status There was no way to see which server, account or binding a directory resolved.

The binding model

Three credential planes, never crossed:

  • the owner token (sot_…) — device-flow issued, manages the fleet;
  • the agent key (sak_…) — what a session presents; one agent ⇄ one (scope, skill) binding, fixed at registration;
  • the enrollment code (sge_…) — delegation to non-owners.

Sessions bind, not machines. Locally there are only named agent profiles (<workspace>/<agent>); the binding lives server-side. One machine may hold many profiles and each concurrent session resolves its own.

Secrets never touch disk in plaintext

By default secrets live only in the OS keychain (via keyring) or the environment — the client never writes an owner token or an agent key to a file in plaintext:

  • the owner token is keyed by server URL;
  • each agent key is keyed by its profile name.

With a keychain present, a bind prints no key at all. Where no keychain backend exists (headless, CI, containers), secrets come from the environment instead:

  • MEMFLEET_AGENT_KEY — the agent key for the active profile (the same name the written MCP config resolves at session start);
  • MEMFLEET_OWNER_TOKEN — an owner token for the management plane.

In that mode a plaintext write cannot persist without putting a secret on disk, which the client refuses to do; it prints the env var to set instead — or, if you opt in, it stores the credentials in the encrypted file store below. Either way, no secret is ever written to disk in plaintext.

Opt-in encrypted file store

On a keychain-less machine you may choose to store credentials in ~/.memfleet/credentials.enc instead of managing export lines by hand. It is opt-in only — nothing is stored unless you accept the prompt (or pass --credential-store file), and declining keeps the show-once export behavior exactly as before. When enabled:

  • credentials are sealed with AES-256-GCM under a key derived from a passphrase (scrypt), the file is chmod 600, and every write re-seals under a fresh nonce — no plaintext secret ever lands on disk;
  • connect, run, status, and env resolve profiles transparently, prompting once per process for the passphrase to unlock the store (the derived key is cached for that process only, never written);
  • logout clears the owner token from the store, and re-binding a profile overwrites its entry — no stale credentials accumulate.

A wrong passphrase fails with a clean message, never a traceback.

What a bind writes (additive, idempotent, secret-free)

Setup is strictly additive and reuses the engine's install machinery (strata.install) — an existing entry is never overwritten. A second bind in the same directory changes nothing; memfleet setup --diff previews without writing.

  • an MCP config entry for the hosted /mcp endpoint, keyed memfleet (distinct from the local engine's strata entry, so a project may run both). It is secret-free: the agent key is resolved at session start from the profile env (MEMFLEET_AGENT_KEY) —

    {
      "mcpServers": {
        "memfleet": {
          "type": "http",
          "url": "https://memfleet.com/mcp",
          "headers": { "Authorization": "Bearer ${MEMFLEET_AGENT_KEY}" }
        }
      }
    }
    
  • the memfleet-contribution skill into .claude/skills/.

  • the bound scope's skill body, when the owner authored one, as .claude/skills/<skill name>/SKILL.md (a skill-less scope installs under <scope_id>-scope). It is fetched from GET /agent/v1/skill-body with the agent key, so the owner and enrollment-code planes install it identically.

  • the contribution Stop-hook — the script at .claude/hooks/memfleet-stop-hook plus its hooks.Stop wiring merged into .claude/settings.json. Both blocks are server-rendered and fetched from the owner-token management endpoint; dependency-free and secret-free, the hook reads the agent key from the environment and degrades to a no-op when none is present. The enrollment-code plane has no owner token, so it notes the skip in one line and everything else proceeds.

The MCP entry is written to .mcp.json at the project root (the file where Claude Code expands ${VAR} in HTTP headers); it is secret-free and safe to commit — a committed config with no profile present simply fails to authenticate the MCP server, and the session degrades silently.

Machines without an OS keychain (headless / CI / containers)

run still completes: the setup is written as usual and the agent key is shown ONCE as an export line at the end (no secret is ever written to disk in plaintext). You then have two choices:

  • Show-once exports (default). Set them in the session environment — memfleet run passes an ambient MEMFLEET_AGENT_KEY through — or re-run the bind for a fresh key. memfleet profiles list marks such profiles (key: env), and memfleet status reports key env.
  • Opt into the encrypted file store. On the keychain-less path you are asked once: "No OS keychain is available. Store credentials in an encrypted file (~/.memfleet/credentials.enc) protected by a passphrase? [y/N]". Answer y (or pass --credential-store file for non-interactive setups) to seal the credentials into an AES-GCM file chmod 600, protected by a passphrase-derived key. connect, run, status, and env then resolve profiles automatically (see Opt-in encrypted file store above). Declining keeps the show-once behavior byte-for-byte.

Configuration precedence

  • server--server flag → MEMFLEET_SERVER env → project .memfleet/config.toml server → default https://memfleet.com. No URL appears in the normal path; --server is for test / self-hosted only. memfleet status names the rung that won.
  • agent profile--profile flag → MEMFLEET_PROFILE env → project .memfleet/config.toml default_profile → none. The env override lets concurrent same-repo sessions each resolve their own profile; status names this rung too.
  • agent key, for the resolved profile — OS keychain → opt-in encrypted file store → ambient MEMFLEET_AGENT_KEY. A key from any of the three is the no-network fast path.

.memfleet/config.toml holds only non-secret project state (a server URL and a default profile name). It is .memfleet/, not .strata/, so a project may run a local strata engine and the cloud side by side.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

memfleet-3.0.2.tar.gz (68.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

memfleet-3.0.2-py3-none-any.whl (51.5 kB view details)

Uploaded Python 3

File details

Details for the file memfleet-3.0.2.tar.gz.

File metadata

  • Download URL: memfleet-3.0.2.tar.gz
  • Upload date:
  • Size: 68.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for memfleet-3.0.2.tar.gz
Algorithm Hash digest
SHA256 5bb526d3536dfe75f8471aa71a03163f820bcb1c293ccd3ab2e9d86832d32f49
MD5 db125470d4036ef88340a836ad056e31
BLAKE2b-256 2cf8181386cf560e1983f31f3ac59b315c1a84bc8e39f4cefade98c81509e4bf

See more details on using hashes here.

Provenance

The following attestation bundles were made for memfleet-3.0.2.tar.gz:

Publisher: publish-client.yml on oren198/strata-web

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file memfleet-3.0.2-py3-none-any.whl.

File metadata

  • Download URL: memfleet-3.0.2-py3-none-any.whl
  • Upload date:
  • Size: 51.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for memfleet-3.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 14694d8d3543a8b2b492036e9c487ca3726b1b5abbb8c90cb2715b158830498a
MD5 a249acca2294b45d292602004c101aa6
BLAKE2b-256 829843b46e6d6769913a3cd08aca701a26fdf5dd737628c52e046da4b05b27ef

See more details on using hashes here.

Provenance

The following attestation bundles were made for memfleet-3.0.2-py3-none-any.whl:

Publisher: publish-client.yml on oren198/strata-web

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

3.0.3

2 files

This release

3.0.2 This release

2 files

3.0.1

2 files

2.1.0

2 files

2.0.10

2 files

2.0.9

2 files

2.0.8

2 files

2.0.7

2 files

2.0.6

2 files

2.0.5

2 files

2.0.4

2 files

2.0.3

2 files

2.0.2

2 files

2.0.1

2 files

2.0.0

2 files

1.6.1

2 files

1.6.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page