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 secretsThe 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:
| Cell | Use case |
|---|---|
default | Personal development |
work | Organization projects |
staging | Pre-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.00cell.budget.per_run_limit = 1.00If 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
mashin cell initCreates the database, git history, and credential store.
Check cell status
mashin cell statusShows the current cell, its machines, recent runs, and health.
Run a machine in the current cell
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:
| Environment | What it looks like |
|---|---|
| Laptop | A directory under ~/.mashin/cells/ |
| Docker | A container with the cell mounted as a volume |
| Cloud (mashin.live) | A managed cell in the cloud, one per organization |
| Mac Mini / server | A 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:
- Your cell boots and detects machines with
expressessections - A tunnel agent connects to mashin.live and registers those machines
- External clients reach your machines at
https://mashin.live/tunnel/{machine-slug} - 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:
mashin tunnel my_machine.mashinThe 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
| Behavior | Cloud cell | Local cell with tunnel |
|---|---|---|
| Reachability | Direct (subdomain URL) | Via tunnel relay |
| Execution | On cloud server | On your machine |
| Governance | Same | Same |
| Ledger | Cloud database | Local database |
| Latency | Lower (no relay hop) | Slightly higher (relay roundtrip) |
| Availability | Always on | Only 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 URLTunnelSupervisor.start_tunnel()starts with auto-detected machinesTunnelSupervisor.stop_tunnel()disconnects the tunnelTunnelSupervisor.add_machine("slug")adds a machine to the active tunnelTunnelSupervisor.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.
mashin cell init --name devmashin credentials set anthropic_api_key your-key-heremashin run greeter --input '{"name": "World"}'mashin cell statusNext steps
- Platform Overview - How all the platform components fit together
- Deployment - Getting cells to production
- Publishing - Sharing machines via the registry
- koda - The IDE that manages your cells