Skip to content

Concepts

The ideas you need to use Me well, in the order you meet them. Each section ends with the commands that go with it. The CLI reference has every flag.

A tenant is one private space: a person, a household or a company. Every record, plugin setting, integration and audit entry belongs to exactly one tenant, and the database enforces that (row-level security). One server can host several tenants.

The first tenant and its owner are created on the server host with Me.Server setup, which prints the owner’s first access token (see Getting started). The person who creates a tenant owns it.

A tenant is personal by default: every member may do anything the risk rules allow. A company can switch on organization mode (me directory org enable, which needs a passkey step-up). Members then get a baseline (reading and local edits, on data up to Internal) plus whatever their roles allow, and only admins manage roles.

Terminal window
me whoami # who you are, and in which tenant
me status # server, tenant and the config file in use
me use tn_… # switch tenant

A principal is anything that acts. Three kinds matter to you:

Kind Who How it gets in
Person (human) You, and the other members of a tenant Me.Server setup for the owner; tokens for each device (me token create)
Agent An AI assistant acting for a person me agent register <name>: an agent principal plus a delegation from you
Plugin A provider or domain service Installed with the server; turned on per tenant (me plugin enable)

An agent never acts as you. It acts for you, within its delegation, and the system records whom it acted for (me policy explain <op_…> shows it as onBehalfOf). Some things only a person may do, whatever a delegation says: registering and revoking agents, adding and removing integrations, enabling plugins, approving operations, and the consent switches (me attention enable, me session line enable).

Terminal window
me agent register "Claude Code" # default: everything but payments, up to ExternalReversible / Confidential, 90 days
me agent list
me agent revoke pr_…

Every record has a short typed ref, such as task_01J…, per_01J…, msg_01J… or conn_01J…. Refs work everywhere: me get <ref>, me relations <ref>, and as flag values.

Every command that changes something is an operation. Operations are idempotent: retrying with the same --idempotency-key never does the work twice. --dry-run shows what would happen without doing it. Each operation ends in one of these states:

Outcome Meaning Exit code
Succeeded Done; result has the details 0
AwaitingEvidence Waiting for a person’s approval (see below) 6
Denied Not allowed; the error says why 5
effect_unknown It may have happened. Check me op show <op_…> before you retry, and retry only with the same key 10

Every error has a code, a message, a hint and next (commands that usually help). Other exit codes: 2 usage, 3 not found, 4 invalid input, 7 conflict, 8 temporarily unavailable (safe to retry later), 9 not logged in.

Output is JSON when piped (as it is for an agent) and readable text in a terminal. --json and --human force either one, and so does ME_OUTPUT=json|human.

Every operation has a risk tier. The authorization gate decides from the tier, from who is asking, and from the delegation they hold:

Risk tier Examples A person running it An agent running it
Read, LocalWrite task.create, note.update, money.import Runs Runs if its delegation allows it
ExternalReversible calendar.event.create, mail.move Runs Runs if its delegation allows it
ExternalCommunication comms.send, comms.reply, sms.send Waits for approval Waits, unless its delegation explicitly reaches this tier
High money.payment.prepare, device.invoke, directory.role.assign Waits for approval Same as above
Critical money.payment.execute, directory.org.enable Needs a passkey step-up Always refused

An operation that waits is in AwaitingEvidence. Its approval.how gives you the exact command:

Terminal window
me op approve op_… --digest sha256:… # the digest pins exactly what you approve: a changed draft needs a new approval
me op reject op_… --reason "not now"
me op approve-passkey op_… # Critical operations: approve with your passkey in the browser
me passkey add --label laptop # register a passkey first

Agents are always refused when they try to approve. Before something consequential, me policy check <operation> tells you what the gate would decide, without doing anything. Afterwards, me policy explain <op_…> tells you why it decided that.

A delegation is authority one principal grants another: operation patterns (task.*, money.*), deny patterns (which win), a maximum risk tier, a maximum sensitivity and an expiry. me agent register creates one; me delegation grant adds more.

Terminal window
me delegation grant pr_… --allow "task.*" --allow "note.*" --max-risk LocalWrite --days 30
me delegation list
me delegation revoke dlg_…

A standing order is what lets something act for you later: a trigger, a workflow, or a consent switch such as me attention enable runs one operation type as you, and it is checked against the gate again every time it fires. me standing list shows them; me standing revoke <so_…> stops one for good.

Everything above the small kernel is a plugin: tasks, notes, people, money, search, attention, workflows, and every provider (Microsoft 365, Telnyx, Claude…). Plugins implement contracts: typed, versioned schemas such as task.create or calendar.agenda. The CLI and the MCP tools are generated from the contracts, so when a plugin arrives its commands appear without a new CLI.

  • Operation and query a.b.verb becomes me a b verb (money.payment.prepare → me money payment prepare).
  • A resource type a.thing becomes me a thing list and me a thing get <ref>. When both parts are the same, it collapses: task.task → me task list.

Plugins are installed with the server and turned on per tenant:

Terminal window
me plugin list
me plugin enable --all # or name them: me plugin enable com.me.tasks com.me.notes
me contract list # every contract the server knows
me contract show task.create # one contract and its JSON Schema

An integration is one account at a provider: a mailbox, a phone number, a calendar, a Teams sign-in, a Claude API key. Each one is a connection (conn_…) that belongs to a provider plugin. You can have several per provider, such as one per mailbox.

  • You add them; agents can’t. Credentials belong to the person. Settings come from flags or prompts. Secrets are typed only at a hidden prompt, or piped as JSON with --secrets-stdin.
  • They are stored encrypted, then checked. me integration add stores the connection, with its secret encrypted, then asks the provider whether it works (for every provider that supports a check). A failed check doesn’t undo the add: the answer carries verified: {ok: false, …} with the reason, and you fix it or remove the connection.
  • Sign-in providers keep no secret on your side. Microsoft 365 opens your browser. You sign in at Microsoft, and the server keeps the tokens. Plugins only ever get short-lived access tokens, never the refresh token.
  • Webhooks need a public address. Providers that push events (Telnyx, Cloudflare mail) need one, which the operator sets up as a Cloudflare tunnel. me integration add then prints the connection’s webhook URL (me integration list doesn’t show it).
Terminal window
me integration list # every provider you can set up, its fields, and your connections
me integration add com.me.calendar.m365 --name "Work calendar" --client-id <app id>
me integration test conn_…
me integration remove conn_…

See Integrations for each provider.

Attention decides whether and when something interrupts you. Plugins raise items (an unusual charge, an overdue bill, escalated work, an overdue reply, a Claude Code session that needs you), and each item has a level. Teams @-mentions are coming soon (PR #139). Levels:

Level Meaning
ambient Worth knowing; shows when you look
boundary Tell me after the current command or answer
interrupt Pause and tell me now
critical Immediately, and it needs an acknowledgement
  • me attention pending lists what needs you, most urgent first, each with a reason and what you can do.
  • Every me response, on the CLI and over MCP, may carry an attention block with items at boundary and above. An agent working on something else therefore learns about urgent items without polling.
  • me attention enable (yours to run) also lets urgent items notify you, in the inbox and by SMS once a number is connected. me attention disable turns that off.
  • interrupt and critical items are yours to close. An agent may open (me attention open --item att_…) and look into them, but not dismiss them for you.
  • In Claude Code, the UserPromptSubmit hook me attention hook adds interrupt-level items to your next prompt. See Getting started.

A trigger says “whenever this happens, do that”. It is one line:

Terminal window
me when "money.transaction.unusual" do task.create --title "Check the {{data.payee}} charge" --tags money
me when "comms.message.received channel:sms" do task.create --title "Reply to {{data.sender.display}}"
  • field:value matches when the event’s data.field equals the value, or is a list that contains it. {{data.x}} is filled in from the event (a field that doesn’t exist becomes empty text).
  • Actions are local writes, and each runs as the person who set it up (as a standing order).
  • me trigger list shows each trigger’s fired count; me trigger delete --trigger trg_… stops it.
  • For richer conditions, use me trigger create with a JSON Logic when.

Anything that repeats is one schedule with an RFC 5545 RRULE, in a local time zone, and stays correct across daylight-saving changes.

Terminal window
me task series create --title "Take out the trash" --rrule "FREQ=WEEKLY;BYDAY=TU" --start 2026-10-27T19:00:00 --timezone America/New_York
me schedule create --title "Standup" --rrule "FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR;BYHOUR=9;BYMINUTE=0" --start 2026-10-26T09:00 --timezone America/New_York
  • A task series creates an ordinary task at each occurrence.
  • A schedule publishes schedule.occurrence.due, which triggers and workflows react to.
  • On a schedule, --misfire (run_once by default, or skip, latest_only, catch_up) says what happens to occurrences missed while the server was down. A task series always uses run_once.
  • pause, resume, skip and delete work on both.

A workflow is a list of steps that Temporal runs durably, across restarts. Step kinds:

  • operation: a local write, run as you.
  • query: a bounded read.
  • timer: a wait for a duration.
  • wait_event: a wait for a correlated event, with a timeout.

when (JSON Logic) skips a step. for_each, on an operation step, runs it once per item. Outputs from one step feed the next ({{steps.t.output.task}}).

Terminal window
me workflow publish --input "@docs/demo/plumber-followup.workflow.json" # from the repo root
me workflow run --workflow plumber-followup --input '{"what":"the water heater"}'
me workflow execution list

Publishing again makes a new version. For a single step, use me when instead. Workflows need Temporal, which the local install runs for you.

A session is your ongoing conversation with the system, and you never create, name or close one. Your me calls are grouped per person and surface (CLI or MCP), and a quiet gap starts a new session. Set ME_CLIENT_SESSION to an id of your own (one per agent session, for example) to group calls explicitly. Each session is split into segments by lane (tasks, finance, comms…). An urgent item you open becomes an overlay: it is stacked on top, kept separate, and never mixed into the topic you were working on.

Terminal window
me session list
me session show --session ses_…
me session import claude-code --since 2026-10-01 # make your past Claude Code sessions findable with `me find`

Memory keeps short statements worth remembering: facts, preferences, decisions, procedures and relationships. Facts and preferences you propose yourself, at Internal or below, are kept at once. Everything else, and anything an agent proposes, waits in me memory review for you to accept or reject. A commitment (“I’ll send it Friday”) becomes a task.

Terminal window
me memory propose --kind preference --text "I prefer morning appointments, before 10am"
me memory list
me memory forget --item mem_…

Every record has a sensitivity: Public, Internal, Confidential or Restricted. Money is Confidential, for example. Sensitivity limits:

  • what a delegation may touch (--max-sensitivity);
  • what a notification channel may carry (an SMS gets less than the inbox);
  • what may be sent to an AI model or an outside channel. Without a signed BAA for a provider, nothing above Internal goes through it, and the system falls back to fixed wording.

Account numbers are never stored, only masks like ••1234.