Twisp in Your Agent Platform

You run your own agents. Make Twisp the place they act on money, with every action bounded by policies you set, recorded with its reason, run in preview first, and tested against recorded traffic before a change ships.

If you already run your own agents, Twisp is not another agent framework. It is where your agents act on money: the ledger that enforces your accounting rules whatever an agent decides, the policies that bound what each agent can touch, and the record of everything each agent did and why. Your agents keep their models, orchestration, memory, and evaluation. Twisp makes their actions correct, governed, and auditable.

The shape

Your agents reach Twisp through an MCP server you define, or through the GraphQL API. An MCP server offers the tools you choose, each a versioned Starlark program with input and output schemas, and every request to it is recorded as an execution.

Your platformTwisp
Models, planning, orchestration, memoryThe ledger, its rules, and the tools agents may call
Agent identitiesPrincipals, each with its own policies
Runs and conversationsMCP sessions: one history, rate limit, and kill switch each
TracesRequests that record your trace context, the agent's stated intent, and every call beneath them
EvaluationRecorded requests you can replay against a changed tool

Put the rules in the ledger

An agent's prompt is not a control. Put what must hold in Twisp, where it holds for every caller:

  • Tran codes define what each business event may write; a posting through one cannot write anything else, and every transaction balances.
  • Velocity controls refuse postings that break limits, such as overdrafts or daily spending.
  • Tool schemas and code decide what an agent may ask for. Prefer narrow tools, such as issue_refund(transaction_id, reason), to giving an agent the whole API.

Give each agent its own authority

Each agent authenticates as its own principal, with a client whose policies are that agent's ceiling. A call through an MCP server must be allowed by the principal, then by the server's policies, then by the tool's own: a server never grants more than its caller has. Hosts learn from the policies which tools only read: a tool whose policies allow only SELECT is marked read-only, so a host can call it without asking a person.

One session per run

Group a server's sessions by your own run or conversation ID, sent in each request's _meta:

mcp: {
  name: "payments-ops"
  session: { start: { input: { principal: "execution.input.principal", run: "execution.input.meta[\"com.acme/run\"]" } } }
}
session: {
  inputSchema: {
    type: "object"
    properties: { principal: { type: "string", minLength: 1 }, run: { type: "string", minLength: 1 } }
    required: ["principal", "run"]
    additionalProperties: false
  }
  id: "string(size(session.input.principal)) + ':' + session.input.principal + ':' + session.input.run"
}

Each run is then its own session: its own ordered history, its own rate limit, and its own kill switch. closeSession stops one runaway run at once, without touching the others. A request without the field is refused, so every request is attributed.

Connect your traces

Everything in a request's _meta other than the protocol's own fields is recorded on its execution, including W3C trace context. Send your traceparent and run ID, and every Twisp execution can be found from your traces, and every trace from Twisp:

query RunRequests($server: UUID!, $session: String!) {
  actions {
    executions(where: { actionId: $server, sessionId: $session }, first: 100) {
      nodes {
        executionId
        created
        status
        mcpRequest { method name intent meta clientInfo { name version } }
      }
    }
  }
}

Every tool requires an intent: a sentence from the agent saying why it made the call. It is recorded with the request and never passed to the tool, so an investigator reads what the agent did and what it said it was doing, side by side. Lineage walks from a request to every call and write beneath it.

Atomic work, previewed

Agents often need several steps that must all happen or none: a fee, a transfer, and a settlement. With program, which a server offers by listing it in tools, an agent sends one Starlark program over the server's tools, and Twisp runs it in one transaction. With commit: false it runs every step and commits nothing, returning every row it would write, so the agent, or your platform's review step, can check the effect before running the same program with commit: true.

Preview first

A new server starts in preview mode: every call runs against your real data and returns real results, and none of its writes commit. Each call records the writes it would have made. Point a new agent at a preview server, review what it would have written, and promote the server to LIVE when you trust it.

Change tools safely

When you change a tool, replay your agents' recorded requests against a draft of the server that uses the new version, before you publish it. A replay reruns each request with its recorded arguments against current data, rolls back its writes, and records them, so you compare outputs and write sets request by request. Pin tool versions in servers your agents depend on, so a change reaches them only when you update the server.

Let the ledger call you

When something in the ledger should start work in your platform, such as a large debit or an account opened, a webhook endpoint delivers the change to your HTTPS endpoint as a signed request, filtered by CEL. Work that should stay inside the ledger's audit boundary can run in Twisp: an action with a trigger runs on the change itself, with retries, and a Twisp agent can be started by your agents as an MCP task, which a host without the Tasks extension reads with get_task.

Previous
Reconciling ACH Files