Pistis

Drive Pistis from an agent (MCP)

Connect any MCP client to Pistis and let it hand off tasks, wait for them and answer approvals.

Pistis speaks MCP at /mcp on the same address as the web app. An agent or MCP client you already use can then hand a task to a Pistis sandbox, wait for it, read what happened, and approve the steps you allow it to. It acts as you, so it can do what you can do in the web app, and nothing more.

Use Pistis from your tools

Your name → MCP clients shows everything below for your server: its address with a Copy button, what your role allows, and the clients you've connected.

  1. Add a remote MCP server in your client with the address https://pistis.example.com/mcp.
  2. Sign in with your browser. The client opens a Pistis page that says which client asks and where your browser goes back to. Choose Allow. There's no token to copy.
  3. Revoke it on the same page when you stop using it. Its tokens stop working at once.

Signing in this way needs an https publicUrl.

Connect with an API token

For a client that can't sign in with a browser: create a token under Your name → API tokens (with pnpm pistis dev, use the one it printed) and send it as a Bearer header. Most clients take a server entry like this one:

MCP client config
{
  "mcpServers": {
    "pistis": {
      "type": "http",
      "url": "https://pistis.example.com/mcp",
      "headers": { "Authorization": "Bearer <token>" }
    }
  }
}

Any client that speaks MCP over Streamable HTTP connects the same way: the URL, plus the token as a bearer header. Without a token, /mcp answers 401.

Who may use it

It is part of each person's role, set on People › Roles (Roles). The role's MCP clients permission is one of three:

ChoiceWhat happens
NoneTheir tokens get 403, and their browser sign-in shows a page naming their role and asking them to see an administrator. No code reaches the client.
Read-onlyA client that asks for full access gets read-only, and tools that change anything (start a session, send, approve, stop) answer 403 insufficient_scope.
Full accessWhat the person can do in the web app. Member starts here, and Admin always has it.

A change applies at once, to tokens issued before it too: every call is checked against the person's role as it is now.

Control center → MCP servers lists, under Connected clients, every client someone signed in: its name, who, its access and when it was last used. Revoke stops its tokens; the person signs in again to use it. Every role change and every Revoke is in the Control center → Audit log with the admin's name.

What an agent can do

ToolWhat it does
start_sessionStarts a session and, with input, gives it its first task. Optional repo, model, requestId (same key, same session).
send_messageSends a message. While a turn runs it waits its turn, and waiting messages run in the order sent; steer joins the running one; mode: plan proposes first; mode: auto approves its own waiting steps (where the server allows it).
wait_for_turnWaits until the turn is done, or a person is needed (an approval or a question), up to timeoutSeconds. Returns the status and the agent's last reply.
get_transcriptThe timeline: messages, the agent's replies and steps, each step's output. afterSeq for only what's new.
list_approvals, decide_approvalSteps waiting for approval, and approving or denying one.
list_questions, answer_questionQuestions the agent asked, and answering one.
list_pending, withdraw_message, stopMessages waiting their turn, taking one back, stopping the current work.
retry_tool_call, branch_sessionRunning an earlier step again; a new session from an earlier point.
attach_file, get_attachmentFiles for the next message, and reading one back (base64).
get_session, list_sessions, list_subagents, get_usage, get_sandboxWhere a session is, your sessions (and ones shared with you), the sessions its steps started, what it spent, its sandbox.
list_models, set_modelThe models you can pick, and switching a session's model.
rename_sessionNames a session.
pause_sessionPauses the agent for everyone on the session, or resumes it with paused: false.
list_decisionsWho approved, denied, answered, took over or paused, and when.
list_stopped_steps, retry_stopped_stepsSteps stopped after repeated crashes, and running them again.
look_at_screenA picture of what the session's browser shows now.
make_flowAsks the agent to draft a flow from the session, to save with decide_approval.
find_reposRepositories you may start a session on, by part of their path.
end_sessionEnds a session. Its sandbox goes; the transcript and the work pushed to your code host stay.

The web app's live timeline has no MCP equivalent: MCP calls are one request, one answer, so a reply reaches an agent finished, never as it streams (wait_for_turn returns the last reply once the turn is done; the HTTP event stream carries the text as it is written). Granting access to a session stays in the web app.

Approvals stay yours to give

An agent with your token can approve a step, exactly as you could. If you want a person to decide, use a token whose owner isn't an approver for those sessions, or answer the approval in the web app or Slack yourself; the agent then sees the turn waiting in wait_for_turn.

On this page