Skip to content
Developer Preview — APIs and language features may change before 1.0

Cells

A cell is your mashin environment. It is a persistent, networked computing unit that contains your machines, their execution history, credentials, and settings. Think of it as “your mashin.” A cell is where intents become actions: every intent produced by your machines is mediated within the cell’s governance context before execution. Whether it runs on your laptop, a Docker container, a Mac Mini in your closet, or in the cloud, it has the same shape and the same capabilities.

What is in a cell

Every cell has four properties: it is owned (belongs to a user or organization), persistent (state survives restarts), networked (can communicate with other cells), and equivalent (every cell is a full peer on the Kortex, an equally valid position from which to observe and manage the entire network).

~/.mashin/cells/default/
mashin.db # machines, runs, ledger, vectors
history.git/ # version control for machines
credentials.db # encrypted API keys and secrets

The database holds everything: machine definitions, execution runs, behavioral ledger entries, vector embeddings for memory. The git history tracks every change to every machine. Credentials are encrypted at rest.

Multiple cells

You can have multiple cells on one machine:

CellUse case
defaultPersonal development
workOrganization projects
stagingPre-production testing

Each cell is isolated. Different credentials, different machines, different execution history. Switch between them in koda or via the CLI.

Cell settings

Each cell has settings that affect how machines run:

Default model

Configure the default reasoning provider so machines that omit using: get a sensible default:

cell.default_model = "anthropic:claude-sonnet-4-6"

API credentials

Store API keys for reasoning providers, external services, and machine dependencies:

mashin credentials set anthropic_api_key sk-ant-...
mashin credentials set openai_api_key sk-...

Credentials are encrypted and scoped to the cell. Machines declare their requirements in ensures > needs, and the cell satisfies them at runtime.

Token budgets

Set spending limits per machine, per run, or per day:

cell.budget.daily_limit = 10.00
cell.budget.per_run_limit = 1.00

If a run would exceed the budget, the governance interpreter denies the step.

Cell identity

Every cell has a cryptographic identity. This identity is used for:

  • Signing behavioral ledger entries (provenance)
  • Authenticating with kura (the registry) when publishing or pulling machines
  • Establishing trust when cells communicate over kortex (the network fabric)

You do not need to manage this identity manually. It is created when the cell is initialized and used automatically.

Cell lifecycle

Initialize a cell

Terminal window
mashin cell init

Creates the database, git history, and credential store.

Check cell status

Terminal window
mashin cell status

Shows the current cell, its machines, recent runs, and health.

Run a machine in the current cell

Terminal window
mashin run email_triage --input '{"subject": "Invoice", "body": "Payment due"}'

The machine runs in the cell’s context: using the cell’s credentials, respecting the cell’s budgets, recording to the cell’s ledger.

Where cells run

The same cell concept works everywhere:

EnvironmentWhat it looks like
LaptopA directory under ~/.mashin/cells/
DockerA container with the cell mounted as a volume
Cloud (mashin.live)A managed cell in the cloud, one per organization
Mac Mini / serverA headless process running your cell on disk

Code does not change between environments. A machine that runs in your laptop cell runs identically in a cloud cell. The behavioral ledger, credentials, and governance all work the same way.

Cells and kortex

Cells can communicate with each other through kortex, the governed network fabric. A machine in your cell can call a machine in another cell. The call goes through governance on both sides: your cell checks that you are allowed to make the call, and the remote cell checks that you are authorized to invoke that machine.

Three tiers of networking:

  • Local: cells on the same machine, zero configuration
  • Organizational: cells within the same organization, deployment-backed
  • Cross-organization: cells across organizations, portable governance

Exposing local machines to the internet

Local cells are not directly reachable from the internet. The Kortex tunnel solves this by opening a persistent WebSocket connection to the cloud server and relaying requests to your local cell.

How it works

Any machine with an expresses section is automatically exposed through the tunnel when your cell starts. You do not need to configure anything manually. The flow:

  1. Your cell boots and detects machines with expresses sections
  2. A tunnel agent connects to mashin.live and registers those machines
  3. External clients reach your machines at https://mashin.live/tunnel/{machine-slug}
  4. Requests flow through the cloud relay to your desktop, execute locally, and return results

All surface types work through the tunnel: api, webhook, page, mcp, a2a, and websocket.

Using the CLI

You can also start a tunnel manually for a specific machine:

Terminal window
mashin tunnel my_machine.mashin

The CLI shows the public URL when the tunnel connects. Press Ctrl+C to stop.

Webhook integration

When a machine declares a webhook surface, the tunnel provides a public URL that webhook providers (Microsoft Graph, Stripe, GitHub) can deliver to. Your machine accesses this URL via context.cell.webhook_urls:

machine outlook_bridge
expresses
webhook
path: "/outlook"
provider: microsoft
implements
// context.cell.webhook_urls["/outlook"] resolves to:
// https://mashin.live/tunnel/outlook_bridge/outlook
ask register, from: "@mashin/actions/http/post"
url: "https://graph.microsoft.com/v1.0/subscriptions"
body: {changeType: "created", notificationUrl: context.cell.webhook_urls["/outlook"], resource: "me/mailFolders('Inbox')/messages"}

Cloud vs local cells

BehaviorCloud cellLocal cell with tunnel
ReachabilityDirect (subdomain URL)Via tunnel relay
ExecutionOn cloud serverOn your machine
GovernanceSameSame
LedgerCloud databaseLocal database
LatencyLower (no relay hop)Slightly higher (relay roundtrip)
AvailabilityAlways onOnly while tunnel is connected

Koda tunnel management

From Koda or any tool context, you can manage tunnels programmatically:

  • TunnelSupervisor.tunnel_status() returns state, registered machines, and cloud URL
  • TunnelSupervisor.start_tunnel() starts with auto-detected machines
  • TunnelSupervisor.stop_tunnel() disconnects the tunnel
  • TunnelSupervisor.add_machine("slug") adds a machine to the active tunnel
  • TunnelSupervisor.remove_machine("slug") removes a machine

Troubleshooting

“Not authenticated”: Run mashin login --token YOUR_API_KEY to store your API key.

“No org_id configured”: Your credentials file needs an org_id field. Run mashin login with an org-scoped API key.

Tunnel not starting: Check that at least one machine has an expresses section. The tunnel only starts when there are machines to expose.

Slow responses: The tunnel adds a relay roundtrip. For latency-sensitive workloads, deploy to a cloud cell instead.

Try it

Initialize a new cell, set up an API credential, and run a simple machine. Then check the cell status to see the run recorded in the behavioral ledger.

Terminal window
mashin cell init --name dev
mashin credentials set anthropic_api_key your-key-here
mashin run greeter --input '{"name": "World"}'
mashin cell status

Next steps