Integrations

Personal Agents

Use Appstrate as the execution backend for a personal agent, over the REST API or MCP.

A personal agent is an assistant that runs on your own machine and acts for you. When you need it to act on behalf of many users, run many agents in parallel, or keep credentials away from the LLM, you can delegate the work to Appstrate.

The pattern: let the personal agent reason locally, and delegate execution to Appstrate. Brain local, arms remote. Appstrate does not ship an SDK for this: it is a usage pattern over the REST API and the platform's MCP endpoint.

Why this pattern

  • Parallel runs. Appstrate schedules concurrent runs on your infrastructure. The default caps are 50 concurrent runs and 200 launches per minute per organization, tunable with PLATFORM_RUN_LIMITS (see Environment Variables).
  • Multi-user execution. The Appstrate-User header lets one backend launch runs on behalf of distinct end-users, each with their own connected accounts and an audit trail.
  • Credentials hidden from the LLM. The sidecar injects credentials at request time. The model driving the run never sees a token, and neither does the personal agent that launched it. See How integrations work.
  • Sandbox. With the docker or firecracker run adapter, every run gets its own container (or microVM) and its own network.

Wire-up

Create an API key in the dashboard (Organization settings > Space > API Keys) with the permissions the personal agent needs, for example agents:run and runs:read. Keys start with apst_, are bound to one organization and one space, and the secret is shown once. See Authentication.

export APPSTRATE_KEY=apst_your_key
export APPSTRATE_URL=https://appstrate.yourcompany.com

Delegate a single run

The personal agent decides to run @acme/triage-support-tickets on behalf of end-user eu_alice. Agent routes use @scope/name:

curl -X POST "$APPSTRATE_URL/api/agents/@acme/triage-support-tickets/run" \
  -H "Authorization: Bearer $APPSTRATE_KEY" \
  -H "Appstrate-User: eu_alice" \
  -H "Content-Type: application/json" \
  -d '{ "input": { "ticket_id": 42 } }'

The call returns 201 with the full run resource. Its id identifies the run. If an integration the agent needs has no usable connection, the call fails with 409 missing_integration_connection and lists what to connect or choose (see How integrations work). Pass connection_overrides to pick connections explicitly.

To wait for the result, long-poll the run (the wait is capped at 55 seconds per call, so loop until the status is terminal):

curl "$APPSTRATE_URL/api/runs/$RUN_ID?wait=55" \
  -H "Authorization: Bearer $APPSTRATE_KEY"

Terminal statuses are success, failed, timeout and cancelled, and the output is in the run's result. To stream progress instead, subscribe to the realtime stream:

curl -N "$APPSTRATE_URL/api/realtime/runs/$RUN_ID?token=$APPSTRATE_KEY"

Delegate a fleet

Fan out across end-users:

const users = await listUsers();
const runs = await Promise.all(
  users.map((u) =>
    fetch(`${APPSTRATE_URL}/api/agents/@acme/triage-support-tickets/run`, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${APPSTRATE_KEY}`,
        "Appstrate-User": u.externalId,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ input: u.payload }),
    }).then((r) => r.json()),
  ),
);

Appstrate runs each in its own sandbox, with that end-user's connections. The personal agent collects the results. Launches beyond the per-organization caps are refused, so batch accordingly.

Over MCP

If your personal agent speaks the Model Context Protocol, it can use Appstrate as an MCP server instead of calling REST. Each organization has one endpoint, /api/mcp/o/<orgId>, authenticated with an API key (header) or a browser OAuth login. The run_and_wait tool launches an agent run and returns when it reaches a terminal status. The server exposes only what the key's permissions allow, and every call goes through the same checks as the REST API.

claude mcp add --transport http appstrate-acme https://appstrate.yourcompany.com/api/mcp/o/<orgId> \
  --header "Authorization: Bearer $APPSTRATE_KEY"

The key needs mcp:read and mcp:invoke, plus agents:run and runs:read for run_and_wait. The command above is for Claude Code; other clients take the same URL and header in their own configuration. Full details, including the tool list and the OAuth path, are in Connecting MCP clients.

Division of responsibility

ConcernPersonal agent (brain)Appstrate (arms)
Reasoning, planningYesNo
User-facing chatYesNo
Pick which agent to runYesNo
Execute the run in isolationNoYes
Hold end-user credentialsNoYes
Parallel fan-outNoYes
Audit log of who did whatNoYes

The split keeps the ergonomics and ownership of your personal agent, and adds platform-grade execution when you need scale, isolation or multi-tenancy.

Reference

  • Authentication: API keys, scopes, end-user impersonation.
  • Multi-tenancy: how Appstrate-User composes with the organization and space hierarchy.
  • Design choices: why runs are isolated, multi-tenant and API-first.

On this page