# More personal agents

This page sets up agents that don't have their own quickstart as a [personal agent](/guides/personal-agents/) that runs third-party API calls through Swytchcode. For Hermes and OpenClaw, see the [Hermes](/quickstarts/hermes/) and [OpenClaw](/quickstarts/openclaw/) quickstarts, and [Personal agents](/quickstarts/personal-agents/) for every supported agent.

- [ZeroClaw](#zeroclaw)
- [NanoClaw](#nanoclaw)
- [Dify](#dify)
- [Any other agent](#any-other-agent)

Every agent needs the Swytchcode CLI on its machine first:

**npm**

```bash
npm install -g swytchcode
```

**macOS / Linux**

```bash
curl -fsSL https://cli.swytchcode.com/install.sh | sh
```

**Windows**

```powershell
irm https://cli.swytchcode.com/install.ps1 | iex
```

After setting up your agent, [connect the app](#connect-the-app) and [chat with it](#chat-with-it).

---

## ZeroClaw

ZeroClaw grants MCP servers and skills to each agent through bundles, so Swytchcode doesn't change its config for you: `swy init` prints exactly what to add.

### 1. Create the agent's project

```bash
swy init --operator --editor=zeroclaw --project ~/agent-swy
swy login
```

This creates the project in sandbox mode, adds the [baseline approval policy](/guides/personal-agents/#the-baseline-policy), and writes the Swytchcode skill to `~/agent-swy/agent-skill/swytchcode-operator/SKILL.md` (with `always: true`, so it stays in the agent's prompt).

### 2. Add the skill to a bundle

```bash
mkdir -p ~/.zeroclaw/shared/skills/swytchcode
cp -R ~/agent-swy/agent-skill/swytchcode-operator ~/.zeroclaw/shared/skills/swytchcode/
```

If you set `ZEROCLAW_CONFIG_DIR`, use that folder instead of `~/.zeroclaw`; `init` prints the right paths.

### 3. Add the MCP server

Open `~/.zeroclaw/config.toml` and paste the block `init` printed at the end of the file. It looks like this:

```toml
[[mcp.servers]]
name = "swytchcode"
command = "swytchcode"
args = ["mcp", "serve", "--profile", "operator", "--project", "/home/you/agent-swy"]

[mcp_bundles.swytchcode]
servers = ["swytchcode"]

[skill_bundles.swytchcode]
```

- If the file already has `[[mcp.servers]]` entries, keep them. This is one more entry.
- If it already has a `[mcp_bundles.swytchcode]` or `[skill_bundles.swytchcode]` section, don't add a second one. TOML refuses duplicate sections and ZeroClaw won't load the file.

This only defines the server and the bundles. No agent can use them until you grant them in the next step.

### 4. Grant it to your agent

1. Find the name of the agent you chat with:

```bash
zeroclaw agents list
```

Use that name wherever ` ` appears below. If the list is empty, create one with `zeroclaw agents create `. Grant Swytchcode only to the agent you chat with, not to every agent.

2. See which bundles it already has:

```bash
zeroclaw config get agents. .mcp_bundles
zeroclaw config get agents. .skill_bundles
```

3. Add `swytchcode` to both lists. `config set` replaces the whole list, so include what step 2 printed:

```bash
zeroclaw config set agents. .mcp_bundles '["swytchcode"]' # e.g. '["web","swytchcode"]'
zeroclaw config set agents. .skill_bundles '["swytchcode"]'
```

Then [connect the app](#connect-the-app). To chat, run `zeroclaw agent --agent `.

### Optional: lock ZeroClaw down

Swytchcode only checks calls made through its tools. If the agent's risk profile lets it run `python`, `node`, `git` or `npm`, it can edit `policies.json` or read your saved credentials directly. And without `auto_approve`, ZeroClaw asks *"[Y]es / [N]o / [A]lways"* before every Swytchcode call. Do this before you use real accounts.

1. Find the agent's risk profile and print its lists:

```bash
zeroclaw security status --agent --json # "alias" under risk_profile is the profile name
zeroclaw config get risk_profiles. .allowed_commands
zeroclaw config get risk_profiles. .auto_approve
```

2. Set both lists again, starting from what was printed. `config set` replaces the whole list, and it must be a JSON list:

- `allowed_commands`: remove `python`, `python3`, `node`, `git`, `npm`, `pip`, `cargo`, `find` and any shell.
- `auto_approve`: add the 11 Swytchcode tools `init` printed. A wildcard like `swytchcode__*` doesn't match.

```bash
zeroclaw config set risk_profiles. .allowed_commands '["ls","cat","grep","head","tail","wc","date"]'
zeroclaw config set risk_profiles. .auto_approve '["file_read","memory_recall","swytchcode__swytchcode_add","swytchcode__swytchcode_connect","swytchcode__swytchcode_discover","swytchcode__swytchcode_exec","swytchcode__swytchcode_get","swytchcode__swytchcode_info","swytchcode__swytchcode_list","swytchcode__swytchcode_policy","swytchcode__swytchcode_policy_add","swytchcode__swytchcode_policy_check","swytchcode__swytchcode_search"]'
```

Replace the example entries with your own printed lists. If the agent has no profile yet, set one first: `zeroclaw config set agents. .risk_profile personal`.

3. Run `swy doctor --agent zeroclaw --project ~/agent-swy` again. The warnings should be gone. Restart the agent's session.

ZeroClaw's default `forbidden_paths` usually already covers the project and `~/.swytchcode`; `doctor` tells you if it doesn't.

---

## NanoClaw

NanoClaw runs each agent in its own Docker container. Swytchcode runs on the host, outside the container, and the agent reaches it over HTTP. Your credentials and `policies.json` never enter the container, so the agent's shell can't reach them and there is nothing to lock down.

Run these on the NanoClaw host, as the user that runs NanoClaw.

### 1. Create the agent's project

```bash
swy init --operator --editor=none --project ~/agent-swy
swy login
```

This creates the project in sandbox mode, adds the [baseline approval policy](/guides/personal-agents/#the-baseline-policy), and writes the Swytchcode skill to `~/agent-swy/agent-skill/swytchcode-operator/`.

### 2. Start the MCP server

Run the server over HTTP, where the agent's container can reach it:

**Linux**

On Linux, containers reach the host through Docker's bridge, so the server listens there:

```bash
BRIDGE=$(docker network inspect bridge --format '{{(index .IPAM.Config 0).Gateway}}')
swy mcp serve --profile operator --project ~/agent-swy --transport http --bind "$BRIDGE" -d
```

**macOS**

Docker Desktop forwards `host.docker.internal` to the Mac itself, so the default address works:

```bash
swy mcp serve --profile operator --project ~/agent-swy --transport http -d
```

The server needs its bearer token on every request. `-d` runs it in the background; start it again after a reboot.

### 3. Add it to your agent

Find the agent's group id, then add the server with its token:

```bash
ncl groups list
ncl groups config add-mcp-server --id --name swytchcode \
--url http://host.docker.internal:5476/mcp \
--headers "{\"Authorization\":\"Bearer $(swy mcp token)\"}"
```

The agent can read the token in its own config. It only gives the agent the same Swytchcode tools it already has.

### 4. Add the skill

Copy the skill into NanoClaw's shared skills, from the NanoClaw folder, and restart the agent:

```bash
cp -R ~/agent-swy/agent-skill/swytchcode-operator container/skills/
ncl groups restart --id
```

Agents use every shared skill unless their `skills` setting lists only some. If `ncl groups config get --id ` shows a list, add `swytchcode-operator` to it.

Then [connect the app](#connect-the-app). To chat, use the agent's channel, or `pnpm run chat " "` from the NanoClaw folder.

---

## Dify

Dify runs in Docker and calls MCP servers over HTTP, so Swytchcode runs on the host as for NanoClaw. This needs self-hosted Dify: Dify Cloud can't reach your machine.

Run these on the Dify host.

### 1. Create the project

```bash
swy init --operator --editor=none --project ~/agent-swy
swy login
```

### 2. Start the MCP server

**macOS**

```bash
swy mcp serve --profile operator --project ~/agent-swy --transport http -d
```

**Linux**

```bash
BRIDGE=$(docker network inspect bridge --format '{{(index .IPAM.Config 0).Gateway}}')
swy mcp serve --profile operator --project ~/agent-swy --transport http --bind "$BRIDGE" -d
```

Dify's outbound calls go through its `ssrf_proxy` container, which doesn't know `host.docker.internal` on Linux. Add it in `docker/docker-compose.override.yaml`:

```yaml
services:
ssrf_proxy:
extra_hosts:
- "host.docker.internal:host-gateway"
```

### 3. Let Dify reach the host

Dify's SSRF proxy blocks private addresses, including your host. Allow only `host.docker.internal` in `docker/.env`, then restart the proxy:

```bash
SSRF_PROXY_ALLOW_PRIVATE_DOMAINS=host.docker.internal
```

```bash
docker compose up -d ssrf_proxy
```

Without this, adding the server fails with *403 Forbidden*.

### 4. Add the server in Dify

1. In Dify, open **Tools → MCP → Add MCP Server (HTTP)**.
2. Set **Server URL** to `http://host.docker.internal:5476/mcp`, and **Name** and **Server Identifier** to `swytchcode`.
3. Under **Headers**, add `Authorization` with the value `Bearer `, using the token from `swy mcp token`.
4. Save. Dify lists the 11 Swytchcode tools.

### 5. Give your agent the tools and the rules

Dify has no skills. In your Agent app, add the Swytchcode tools, and paste the body of `~/agent-swy/agent-skill/swytchcode-operator/SKILL.md` (everything below the `---` header) into the agent's **Instructions**.

Then [connect the app](#connect-the-app).

Keep in mind:

- **Everyone who uses the Dify app shares one project:** its credentials, limits and approvals. Run one server per project to keep them apart.
- **A call that needs approval doesn't wait.** The tool returns *"approval requested"*, and the call runs once someone approves it. The agent can tell the user. A workflow that needs the result shouldn't depend on such calls.

---

## Any other agent

```bash
swy init --operator --editor=none --project ~/agent-swy
swy login
```

`init` writes the skill to `~/agent-swy/agent-skill/` and prints the MCP server command. Add both to your agent the way it adds skills and stdio MCP servers. If the agent runs in a container, run the server on the host over HTTP as for [NanoClaw](#2-start-the-mcp-server).

---

## Connect the app

Connect the app before you ask the agent to use it. For Stripe:

1. **Fetch it and add the key.** Stripe uses an API key, which you enter here, never in the chat. Use a test key (`sk_test_...`) while the project is in sandbox mode.

```bash
cd ~/agent-swy
swy get stripe
swy auth connect stripe
```

2. **Set the base URL.** Stripe has no separate sandbox host, so set it yourself in `~/agent-swy/.swytchcode/integrations/manifest.json`, in the entry that starts with `Stripe.stripe@`:

```json
"Stripe.stripe@ ": {
"sandbox_endpoint": "https://api.stripe.com",
...
}
```

Most apps don't need this. If one does, its first call stops with *"base URL ... (sandbox) is not set"* and names the entry.

Apps that use OAuth (Gmail, GitHub) don't need a key: `swy auth connect ` opens a sign-in link, or the agent sends you one when it needs it. See [Connecting apps](/guides/personal-agents/#connecting-apps).

## Chat with it

Start a chat with your agent and ask:

```text
Show my Stripe balance.
```

The balance is a read, so it runs at once. A call that changes something, like creating an invoice, waits for your approval in the workspace's approval channel (Telegram or Slack, set in [app.swytchcode.com](https://app.swytchcode.com)).

If the agent says it has no Swytchcode tools, check that the server is registered and restart the agent. For ZeroClaw, `swy doctor --agent zeroclaw --project ~/agent-swy` shows what's missing.
