# Personal agents

A personal agent is an assistant you run yourself and talk to from a chat app: Hermes, OpenClaw, ZeroClaw and others. With Swytchcode as its execution layer, you can ask it *"send Acme an invoice for $200"* from your phone, and the call goes through Swytchcode with your credentials, your guardrails, your approval and an audit trail.

```text
You (Telegram / WhatsApp / Slack / terminal)
│
▼
Personal agent + its LLM
│ swytchcode_* MCP tools
▼
swy mcp serve --profile operator --project ~/agent-swy
│ tooling.json, policies.json, credentials, audit
▼
Provider API (Stripe, Gmail, GitHub, ...)
```

The agent sets integrations up on its own: it searches, fetches providers, enables methods and adds guardrails. Four things always stay with you:

- signing in and connecting accounts,
- approving calls,
- removing or loosening a guardrail,
- entering API keys and secrets, which never go through the chat.

---

## Before you begin

- The [Swytchcode CLI](/cli/overview/) on the machine the agent runs on.
- The agent installed and connected to its chat app.
- A Swytchcode account. For approvals, the Business or Enterprise plan (see [Human approval](/policies/human-approval/#workspace-policies-and-plans)).

---

## 1. Set up the project

Run this once, on the agent's machine, in a terminal:

```bash
swy init --operator --editor=hermes --project ~/agent-swy # or openclaw, zeroclaw, none
swy login
```

`init --operator`:

- creates `~/agent-swy` as the agent's Swytchcode project, in sandbox mode;
- adds the baseline policy, which holds every call that changes something for your approval (see [below](#the-baseline-policy));
- installs the Swytchcode skill, which tells the agent to check Swytchcode first for anything involving a third-party app;
- registers the Swytchcode MCP server with the agent through the agent's own CLI. Hermes asks you to confirm the tools. If `init` isn't running in a terminal, it prints the command for you to run.

For ZeroClaw, `init` prints the config to add and the step that grants it to your agent; see the [ZeroClaw quickstart](/quickstarts/zeroclaw/). For any other agent, use `--editor=none`: `init` writes the skill to `~/agent-swy/agent-skill/` and prints the MCP server command to add.

Keep the project **outside** the agent's own workspace, so its file tools can't edit `policies.json`. `init` warns, and `doctor --agent` reports an error, when it isn't.

## 2. Set the approval channel

In [app.swytchcode.com](https://app.swytchcode.com), set the workspace's approval channel to Telegram or Slack, then start a chat with the Swytchcode bot. Use a **private** chat, not a group, and not the agent's own bot. See [Personal agents](/policies/human-approval/#personal-agents) in Human approval.

## 3. Restrict the agent

Swytchcode only checks calls made through its MCP tools. If the agent also has a shell, it can edit `policies.json` or run `swy policy remove` itself. If it can change its own config, it can switch the Swytchcode server to a different profile.

Before you connect the agent to a chat, make sure it has:

- no shell or code-execution tool, unless that tool runs in a sandbox with no access to this machine's files;
- write access only to its own work folder, not to the project or `~/.swytchcode`;
- no tool that changes its own settings.

`init --operator` prints the settings for your agent, and `doctor --agent` reports an error for each one that's missing.

### Hermes

`HERMES_WRITE_SAFE_ROOT` on its own isn't enough. It only limits the file tools, and the terminal can still edit any file.

1. Turn off the command tools in `~/.hermes/config.yaml`. Under `agent:`, this applies to every chat platform, to cron jobs and to subagents:

```yaml
agent:
disabled_toolsets:
- terminal
- code_execution
- computer_use
```

Edit the file directly. `hermes config set` saves the list as a string, which Hermes doesn't read correctly.

2. Limit file writes to the agent's own folder:

```bash
echo 'HERMES_WRITE_SAFE_ROOT=/home/you/hermes-work' >> ~/.hermes/.env
```

3. Restart the Hermes gateway.

### OpenClaw

Deny the command tools (`group:runtime`) and the tools that change OpenClaw's config or schedule jobs (`group:automation`, which has `gateway` and `cron`). Keep the file tools inside its workspace. If you already have a deny list, add these to it.

```bash
openclaw config set tools.deny '["group:runtime","group:automation"]' --strict-json
openclaw config set tools.fs.workspaceOnly true --strict-json
```

Then restart the OpenClaw gateway.

### ZeroClaw

Set these in the agent's risk profile. Setting a key replaces ZeroClaw's whole default list for it, so start from the defaults (`zeroclaw config get risk_profiles. . `) and add to them:

- `forbidden_paths`: add the project and `~/.swytchcode`.
- `allowed_commands`: remove shells, interpreters and anything that runs other programs. The default list has `python`, `python3`, `node`, `git`, `npm` and `pip`, and each of them can get around `forbidden_paths`. Don't add `swytchcode`.
- `auto_approve`: add the 11 Swytchcode tools (`init` prints them). Otherwise ZeroClaw asks you to confirm every Swytchcode call in the chat, as well as Swytchcode's own approval. `swytchcode__*` doesn't work; list each name.

See the [ZeroClaw quickstart](/quickstarts/zeroclaw/).

### Other agents

Use `--editor=none` and apply the same three rules with the agent's own settings. `doctor` can't check them for other agents.

## 4. Check the setup

```bash
swy doctor --agent hermes --project ~/agent-swy
```

`doctor --agent` checks the login, the baseline policy, the agent's MCP server and skill, and the restrictions above. It reads the agent's config and asks its CLI; it never changes anything.

---

## What a conversation looks like

**You:** *Send an invoice for $200 to Acme through Stripe.*

1. The agent checks Swytchcode first: `swytchcode_list`, then `swytchcode_discover "send an invoice"`.
2. It fetches and enables the method: `swytchcode_get stripe`, `swytchcode_add stripe.invoice.create`.
3. It may add a guardrail you asked for, like "block invoices over $1,000", and tells you it did.
4. Stripe isn't connected yet, so it calls `swytchcode_connect` and sends you a link. You tap it on your phone and sign in to Stripe.
5. It runs the call. Creating an invoice changes something, so the baseline policy holds it, and the Swytchcode bot posts Approve / Deny in your approval chat. The agent tells you it's waiting.
6. You tap Approve. The call runs in the background, and its result shows on the approval message and in `swy audit`.

A read, like *"list my invoices"*, runs straight away.

If Swytchcode doesn't have the app at all, the agent uses its own tools and tells you the call is running outside Swytchcode, without its guardrails or audit. It never falls back like that because a Swytchcode call was blocked, is waiting for approval, isn't connected, or failed.

---

## Connecting accounts

| Provider uses | What the agent sends you |
|---|---|
| OAuth (Gmail, Stripe, GitHub...) | A one-time link to open. Don't forward it: whoever opens it first connects their account. |
| API key, basic auth, signed requests (e.g. Binance) | A command to run on the machine, e.g. `cd ~/agent-swy && swy auth connect binance`. |

`swytchcode_connect` has no field for a key, so the agent can't pass one on even if you paste it into the chat. If you do paste one, rotate it.

---

## What the agent can and can't do

The agent connects with the `operator` [MCP profile](/reference/mcp-reference/#operator-profile-11-tools).

| Action | Agent | You, on the machine |
|---|---|---|
| list, search, discover, info | Yes | |
| get a provider, add a method | Yes | |
| add a new policy that blocks, requires approval, redacts or truncates | Yes | |
| change or remove a policy, add `ALLOW` / `MODIFY` / `notify` | No: it gets the command to give you | Yes |
| exec | Yes, always under policies | |
| demo calls, raw methods | No | Yes |
| log in, connect accounts, enter keys | No: it sends you a link or command | Yes |
| approve or deny | No | Yes, in the approval chat |

If you ask the agent to remove the approval rule, it gives you the command to run instead, for example `cd ~/agent-swy && swytchcode policy remove agent-writes-need-approval`.

### The baseline policy

`init --operator` adds this policy to `~/agent-swy/.swytchcode/integrations/policies.json`:

```json
{
"id": "agent-writes-need-approval",
"target": ["*"],
"when": { "field": "$http_method", "operator": "not_in", "value": ["GET", "HEAD", "OPTIONS"] },
"action": { "type": "REQUIRES_APPROVAL", "message": "This call changes something, so a person has to approve it first." }
}
```

- It applies to every call in the project, not only the agent's. An approved call is replayed from the command line and has to match the same policy to use its one-time approval.
- The agent can't replace it: it may only add policies with new ids. Policy precedence is block > approval > allow, so nothing it adds can override it.
- **Reads aren't held.** For providers with mail, files or money, add an approval policy on every call to that provider, for example `"target": ["google.*"]` with `{"field": "$tool", "operator": "exists"}`.
- Edit or remove it like any policy, with [`swy policy`](/reference/commands/).

---

## Shared bots and end users

The MCP server runs with your own accounts. To run a server for one end user of your app, pin them when it starts:

```bash
swy mcp serve --profile operator --project ~/agent-swy --tenant alice
```

The tenant is never a tool argument, so the agent can't choose whose account a call uses. A bot that many people share in one chat (a family group, a business WhatsApp number) isn't supported yet: it would need one server per person, chosen by something the LLM can't change. See [Multi-tenant apps](/guides/multi-tenant/).

---

## Troubleshooting

| Symptom | Fix |
|---|---|
| The agent can't see the Swytchcode tools | Run `swy doctor --agent `, then restart the agent's session. |
| `doctor` says the server runs `mcp serve`, not the operator profile | A plain `swy init --editor=hermes` (or `openclaw`) replaced it. Run `swy init --operator --editor= --project ~/agent-swy` again. |
| "approval required but no workspace linked" | The project links a workspace on its first `get`. Have the agent fetch a provider, or run `swy workspace use ` in the project. |
| Approvals never arrive | Check the approval channel in the app, and that you started a chat with the Swytchcode bot. |
| ZeroClaw asks "[Y]es / [N]o / [A]lways" before each Swytchcode tool | Add the Swytchcode tools to the risk profile's `auto_approve`. |
| `doctor` reports `shell` or `restrictions` errors | The agent can get around Swytchcode. Follow the steps for your agent in [Restrict the agent](#3-restrict-the-agent). |
