Agents
A Tokenrip agent is a reusable package of instructions, memory schema, and brain artifacts that runs in your own model harness. Tokenrip stores the agent, mounts, sessions, and memory. Your model does the thinking. Think of an agent as something you load into your runtime — not a hosted chatbot you talk to.Three first-class objects
Agents separate three pieces that are usually bundled together:| Object | What it is | Lifecycle |
|---|---|---|
Agent (Agent) | The published instructions, manifest, and memory schema | Created at publish; publishedVersion auto-increments on every update |
Mount (AgentMount) | One deployment of an agent by an owner (you, or a team) | Created lazily on first load, or explicitly via the CLI. Snapshots agentVersionAtCreate so the dashboard can show drift |
Session (AgentSession) | One harness conversation against a mount | Per conversation |
Mount context. Each mount also carries an operator-editable markdown document — the mount context — that the brain reads on every load. This is what lets a single
blog-writing agent be mounted once for “flowers” and once for “engineering” with different theme, voice, and audience inputs. See Mount context vs memory below.Package folders
Publishing or forking an agent automatically creates a managed folder under its owner labeledAgent: <slug>. The brain artifacts, hero image, sample sessions, and shared-scope memory are filed into it. Re-publishing reconciles the contents without disturbing artifacts you haven’t touched.
Mounting an agent creates a Mount: <agent>/<name> folder for the mount’s context document and team-scope memory. Each operator who joins the mount gets their own private mount folder for their operator-private memory and theme state.
Managed folders are locked — you can’t rename them, delete them directly, or move artifacts into or out of them. Deleting the agent or unmounting cascades: the folder and every artifact it holds go with it, so there’s no orphan cleanup. See Managed folders for the operator-side view.
How it works
Load a mount
Your harness calls
agent_load("agent-slug") to load (or lazy-create) your personal default mount, or agent_load("agent-slug", { team: "acme" }) for a team mount. If the agent declares a mountIntake starter, the new mount’s context document is cloned from the starter scaffold; the brain receives <mount-context alias="…" version="…">…</mount-context> in its system prompt. Claude Code uses the generic /tokenrip bootloader instead, which drives the same load through the rip CLI.Run locally
Your model follows the returned instructions. Tokenrip does not run inference and does not see your transcript unless your harness writes back.
Record memory
If the agent declares it, your harness calls
agent_record (rows) or agent_rewrite_artifact (narrative).Agents vs Tokenrip accounts
A Tokenrip account is arip1... actor — it has API keys, owns artifacts, sends messages, and can be linked to an operator. An agent is not an account.
| Capability | Tokenrip account | Agent |
|---|---|---|
rip1... identity | Yes | No |
| Owns artifacts directly | Yes | No (the agent owner owns brain artifacts; mounts own memory artifacts) |
| Sends messages | Yes | No |
| Has API keys | Yes | No |
| Runs in your harness | Optional | Required |
The four memory layers
Loading a session compiles four layers from the mount and the active caller:| Layer | What it holds | Owned by | Visible to | Active when |
|---|---|---|---|---|
| Brain | Instructions, methodology, frameworks | Agent owner | Anyone with load access | Always |
| Shared memory | Anonymized cohort patterns across all sessions of this agent | Agent owner | Anyone with load access | Always |
| Team memory | Narrative + structured context shared across the team | The mount | Current members of the mount’s team | The mount has a team |
| Private memory | Operator-only context, commitments, working style | Mount + operator | One operator | Always |
- Team memory is partitioned by mount, not by team. Two team mounts of the same agent by the same team get two separate team-memory partitions. That’s how “Engineering Content” and “Marketing Content” stay clean.
- Private memory works on every mount — including personal mounts. You don’t need a team to use an agent that declares operator-private memory.
Mount context vs memory
Mount context and memory both live on the mount, but they’re different primitives:| Mount context | Memory | |
|---|---|---|
| Who writes it | The operator (once at create, then fine-tunes) | The agent (over time, via agent_record / agent_rewrite_artifact) |
| What it’s for | Imperative configuration — theme, voice, audience, codebase facts | Accumulated state — commitments, observations, narrative profile |
| Brain envelope | <mount-context alias="…" version="…">…</mount-context> (always read) | Compiled into shared / team / private layers per scope |
| Templated | Yes — cloned from the agent’s mountIntake starter (if declared) | Schema-bound rows or rewrite-bound markdown |
| Edit surface | Dashboard or rip agent mount-context <id> --edit | Through the agent during sessions |
blog-writing agent mounted once for “flowers” and once for “engineering” has the same brain and the same memory schema; what differs is the populated mount context. Don’t put per-deployment configuration in memory — it belongs in the context document.
Personal mounts vs team mounts
| Personal mount | Team mount | |
|---|---|---|
| Owned by | One operator | A team |
| Created via | agent_load(slug) (lazy) or rip agent mount <slug> | agent_load(slug, { team }) (lazy) or rip agent mount <slug> --team <slug> |
| Team memory active | No | Yes |
| Private memory active | Yes (the owner) | Yes (per current team member) |
| Cross-session references | No (no other operators to reference) | Yes |
| Context artifact owner | The operator | The mount creator (shared to the team) |
--name "..."). Pass --context-from <file> to seed the mount’s context at create time.
Agent versioning
Every agent has apublishedVersion that auto-increments on every successful publish. The CLI prints Published <slug> as v<N> after each publish; the dashboard shows the version under the agent label.
Each mount captures agentVersionAtCreate — the agent version that was current when the mount was created. The dashboard uses this to surface a drift signal:
Agent has updated since this mount was created.Operators can refresh the mount context (via the dashboard or by re-running Moa’s mount-creation flow) when the agent changes meaningfully, or ignore the signal. Mounts continue to load against the latest brain regardless — versioning is for visibility, not pinning.
Memory primitives
An agent declares memory in two flavors:- Memory tables (
memoryTables[]) — schema-bound rows. Use for queryable, filterable records (commitments, observed patterns, decisions). - Memory artifacts (
memoryArtifacts[]) — versioned narrative documents the agent rewrites holistically (agent_rewrite_artifact). Use for evolving understanding (operator profile, team context).
| Scope | Materialized when | Owner | Partition |
|---|---|---|---|
shared | At agent publish | Agent owner | Global per agent |
team | At first load of a team mount | Mount | agent_mount_id |
operator-private | At first load of any mount, per operator | Mount + operator | (agent_mount_id, operator_account_id) |
agent | (deprecated synonym of operator-private — coerced at parse time) | (same) | (same) |
sensitive. Treat it as a product surface, not a place for secrets.
Cross-session references
A team-aware agent may declarecrossSessionReferences. When the operator loads a team mount, agent_load returns flagged or recent items from other current team members’ operator-private memory — paraphrased by the brain, never quoted verbatim.
The reference window is bounded by recentWindowDays (default 14) and an eligibleFlag column on an operator-private table. On personal/solo mounts the references no-op with { active: false, reasonInactive: "no-team" } so the brain can adapt.
Themes — cross-session continuity
Themes give agents durable, named working clusters within a mount. An agent that manages multiple ongoing efforts — quarterly planning, hiring pipeline, product launch — can track each one as a separate theme with its own state document, and pick up where it left off across sessions. Two layers, opt-in:- Layer 0 — last-session summary (always on). Every mount surfaces the most recent ended session’s summary in the next session’s brain envelope. No manifest change needed.
- Layer 1 — named themes (opt-in). When the agent declares a
themesblock, the runtime tracks named themes per mount. The agent curates them viaagent_theme_upsert.
Declaring themes
Add athemes block to the manifest:
| Field | Required | Description |
|---|---|---|
scope | yes | operator-private (per-operator) or team (shared across team members) |
examples | no | Slug-shaped hints (≥2 chars, lowercase/digits/hyphens) so the agent understands what kinds of themes to create. Max 16. |
starterArtifactAlias | no | Cloned into each new theme’s state artifact. Must be a published, text-readable artifact owned by the agent owner. |
How themes work
- Auto-default. At the first
agent_session_endwith a non-empty summary on a themes-enabled mount, the runtime auto-creates adefaulttheme with the summary as initial state. - Explicit upsert. The agent calls
agent_theme_upsert(sessionToken, { slug, summary, name?, isCurrent? })to create or update a theme. New slug creates a new theme; existing slug updates the state artifact. - Brain envelope.
agent_loadreturns athemesblock with active themes sorted by recency, plus the manifest’s example hints. The brain reads<themes>in its system prompt. - Caps. 32 active themes per scope-partition. Archived themes don’t count.
Themes vs mount context vs memory
| Mount context | Memory | Themes | |
|---|---|---|---|
| Who writes | Operator (once, then fine-tunes) | Agent (over time) | Agent (per working cluster) |
| What it holds | Configuration — voice, audience, codebase | Accumulated state — commitments, observations | Named working clusters — each with its own state |
| Lifecycle | Set at mount creation | Grows over sessions | Created/updated as work evolves |
| Use case | Same agent, different focus | Durable agent learning | Multiple concurrent efforts within one mount |
teamContext signaling
Agents declare how they relate to teams via the optional teamContext field:
| Value | Meaning |
|---|---|
ignored | Manifest declares no team-scope memory. Solo and team deployments behave identically. |
supported | Manifest declares team-scope memory. Both solo and team deployments work; the team layer activates only with a team. |
recommended | Same as supported, plus the discovery surface hints “best deployed with a team.” Chief of Staff is the canonical example. |
recommended agent still mounts cleanly as personal — the team layer just stays inactive.
Two-tier publishing
Tokenrip publishes in two tiers. Neither tier requires platform-admin status.Tier 1 — personal or team use (anyone)
--team <slug> to publish as a team-owned agent that any current team member can edit. The agent does not appear on /agents.
Tier 2 — public listing (Publisher-approved)
To list an agent on the public/agents directory, the agent owner must first apply for a Publisher — the public-facing brand for listed agents. Tokenrip reviews and approves Publishers; once approved, the owner can self-serve public listing on any agent they own:
Forking
Tokenrip ships canonical templates (Office Hours, Moa, Chief of Staff). Anyone can fork them:--publish.
”My Agents” dashboard
The operator dashboard’s My Agents tab (/operator/agents) lists every mount the operator can access — personal mounts they own, plus team mounts in current teams — and shows the four-layer breakdown for each: which artifacts compose the brain, what’s in shared memory, what’s in team memory (and who else can see it), and what’s in the operator’s private layer.
Tools and workflow tables
Imprints can declare tools for external I/O — sending email, posting Slack notifications, generating PDFs, receiving inbound email, or posting to social platforms like Twitter. Tools are declared in the manifesttools[] array and materialize as AgentToolBinding rows on the mount.
Each entry declares an intent ({ "bind": "tw", "kind": "twitter" }). The platform knows one or more implementations per kind (e.g. twitter-cli-local, twitter-api-server, twitter-browser-claude-in-chrome) and picks the right one at session start based on what the caller’s environment can support. The brain receives the chosen impl’s runbook in its context.
Some kinds ship a free default plus a bring-your-own (BYO) upgrade. email-outbound is the first: an agent sends email out of the box via email-outbound-free (a shared Tokenrip AgentMail inbox, metered at 100 emails/month per account). When the operator stores a Postmark API key on the account (rip cred set email-outbound --postmark-api-key=... --server, or the dashboard Email panel), the higher-priority email-outbound impl takes over and sends from the operator’s own domain, unmetered. Over the free quota the tool returns a non-throwing { ok: false, reason: "quota_exceeded", upgrade } result — the agent records a durable note and moves on rather than failing.
| Tool kind | Built-in impls | Direction |
|---|---|---|
email-outbound | email-outbound-free (AgentMail, free tier), email-outbound (Postmark, BYO) | Write |
email-inbound | email-inbound (Postmark webhook) | Read |
notify | notify-slack | Write |
twitter | twitter-cli-local, twitter-api-server, twitter-browser-claude-in-chrome | Write |
pdf-generate | pdf-generate (stub) | Write |
doc-parse, doc-check | (backend) | Read |
backend (server-side, credentials stored encrypted), harness (the agent’s local environment runs it), or auto (server tries first, falls back to harness). The mode is derived at dispatch time from which handlers (execute / submit) the impl registers — not configured per-binding.
Two-phase agent_load
When a manifest declares any tools[], agent_load runs as a two-phase handshake. The harness first calls agent_load({ slug }) and gets back a probe manifest — a list of candidate impls per binding with the capabilities each one requires. The harness probes its environment (Is tw on the PATH? Is the Claude-in-Chrome MCP loaded? Is the operator signed into twitter.com in the local browser?) and re-invokes agent_load({ slug, capabilities: [...] }) to resolve bindings and start the session. The server augments the caller’s advertised set with server-credential:* caps it already knows about from ServiceCredential rows on the mount, so the harness never has to probe for stored credentials.
The resolve response carries:
toolBindings[]— every resolved binding, each with itsresolvedImpl,executionMode, and the chosen impl’s runbook (which the brain reads inline as<tool-runbook>).unavailableTools[]— bindings the resolver couldn’t satisfy, with the missing capabilities and asetupHintper candidate. The brain’s Phase 0 reads this and relays setup options to the operator.
probedAt: 'fresh' to bust the per-mount probe cache (1h TTL) — useful after the operator fixes a missing capability and wants the resolver to re-evaluate.
The same shape is available over REST at POST /v0/agents/:slug/sessions for harnesses that don’t speak MCP.
Local credentials (rip cred)
Some impls (like twitter-cli-local’s probe, or twitter-api-server setup via rip cred set twitter --consumer-key=...) read fields from ~/.config/tokenrip/credentials.json — a local-only file managed via the rip cred command group. The platform never sees the values; the bootloader’s local-config-file probe checks only the presence of the kind.
Backend-mode impls instead need their credential stored server-side, encrypted, scoped to the account. Add --server to the same command (rip cred set email-outbound --postmark-api-key=... --server, or use the operator dashboard) — it writes to the backend rather than the local file. The secret is never returned: rip cred get email-outbound --server reports existence only. The resolver synthesizes a server-credential:<kind> capability for any account that has one stored, so the BYO impl binds on the next agent_load.
Workflow tables (workflowTables[] in the manifest) are mount-shared tables that track the external state tools produce — correspondence records, pipeline stages, flags, decisions. They’re distinct from memory tables: workflow tables are written by tool handlers, memory tables are written by the brain via agent_record.
The brain interacts with tools via two MCP tools:
agent_tool_execute— server-side execution forbackendorautomode bindingsagent_tool_submit— submit harness-produced results forharnessorautomode bindings
/operator/workflows/:mountId) and the Demand-Scout dashboard (/operator/scout/:mountId) both read and write through the same generic mount-tables surface — /v0/operator/mounts/:mountId/tables/*. There are no imprint-specific operator controllers; the operator dashboard is a thin row-editor and domain logic stays on the agent. See Mount Tables API and rip agent table.
Tagged tables
Each workflow table can declare atags: string[] array in its manifest entry. The /tables-by-tag/:tag/rows endpoint interleaves rows across every table carrying that tag — so the Demand-Scout dashboard’s unified “best bid targets” view is a single API call (tags: ["bid"] on upwork-leads + jobboard-leads), with no backend knowledge of which slugs belong together. Any imprint can add a tag-grouped view without backend changes.
Examples
- Office Hours — solo-friendly. Shared memory only, no team layer.
teamContext: "ignored". - Moa — agent builder. Per-mount private memory.
teamContext: "ignored". - Chief of Staff — team-aware. Team-shared narrative memory plus operator-private commitments and profile, with paraphrased cross-session references.
teamContext: "recommended". Forks cleanly to personal use; the team layer just stays inactive.
MCP Server
Connect a hosted client to Tokenrip’s agent tools.
Agent CLI
Mount, fork, publish, and manage agents from the CLI.
Publisher
The public-facing brand for listed agents.
Operators
The human dashboard alongside your agent.