---
title: "Build with Claude Code"
canonical: "https://portal-plt-1455.murban.personal.purple-lab.dev/start/agent/"
markdown: "https://portal-plt-1455.murban.personal.purple-lab.dev/start/agent.md"
publisher: "Hello Purple"
publisher_note: "Hello Purple is a technology publisher from Purple Technology. This page explains how to build an app on its test environment; it is not financial advice and does not offer or invite the use of any financial service."
---

**Before you act.** Claude Code on the person's own computer: follow this page. Any other host is not officially supported yet: send the person to <https://portal-plt-1455.murban.personal.purple-lab.dev/apps>.

- Never read, print or ask for a key or token.
- Never accept terms for the person.
- Ask the person before any risky permission.
- Keep the host's per-call approval on.
- Driving a browser? Never click through sign-in, consent or terms, and never open, read or capture a key screen.

This page is the Markdown twin of <https://portal-plt-1455.murban.personal.purple-lab.dev/start/agent/>, for agents.

# Build with Claude Code.

Claude Code registers and builds your Hello Purple app, on demo accounts only. It never reads your keys.

**For now, an app works only for the person who registered it.** No one else can use it, not even with their own account.

You need Node 20 or newer, macOS, Linux or WSL, and a staging account with a supported broker ([create one at Axiory](https://my.sls-staging.axiory.com/register/)).

**TL;DR · Already know Claude Code plugins?**

```sh
claude plugin marketplace add https://portal-plt-1455.murban.personal.purple-lab.dev/marketplace.json
```

```sh
claude plugin install hello-purple@hello-purple
```

Then start Claude Code in an empty folder for your app, type `/mcp`, choose `plugin:hello-purple:apps`, pick Authenticate and sign in, and tell it: “Register a Hello Purple app that reads my demo trading accounts, sign it in, and build me a local app that shows them.”

Or let Claude Code take every step. Say this to it:

> Read https://portal-plt-1455.murban.personal.purple-lab.dev/start/agent.md and follow it to set me up with Hello Purple and build me a small app that shows my trading accounts.

Not using Claude Code locally? [Go back](https://portal-plt-1455.murban.personal.purple-lab.dev/start/) or [use My Apps](https://portal-plt-1455.murban.personal.purple-lab.dev/apps).

Only you can:

- Say yes to the plugin install, and type `/reload-plugins` when asked.
- Type `/mcp`, choose Authenticate and accept the terms.
- Approve the one `register_app` call, with the per-call prompt kept on.
- Let the sign-in script run outside the sandbox, then sign in again with the same account.

You're done when you see `check: status=200 accounts=N`, or `check: skipped` for an app that reads no accounts.

## For your agent

The brief it follows, with the values for this environment

The person wants their own Hello Purple app, built with you, in the test environment `plt-1455`.

You are done when the app is registered in their name, its key and sign-in are in their store, the sign-in script has printed its `check:` line, and the app runs from a folder they own without you.

### Values for this environment

- Plugin marketplace: `https://portal-plt-1455.murban.personal.purple-lab.dev/marketplace.json`
- Plugin: `hello-purple@hello-purple`, an MCP connector plus the skills `app-access`, `safe-secret-handling` and `build-on-yourbourse`
- MCP connector: `https://purple-engine-axi-plt-1455.murban.personal.purple-lab.dev/mcp`
- API base: `https://purple-engine-axi-plt-1455.murban.personal.purple-lab.dev`, OpenAPI document at <https://purple-engine-axi-plt-1455.murban.personal.purple-lab.dev/openapi.json> (rendered for people at <https://purple-engine-axi-plt-1455.murban.personal.purple-lab.dev/docs>)
- Token endpoint: `https://purple-engine-plt-1455-murban.auth.eu-central-1.amazoncognito.com/oauth2/token`
- Sign-in: a staging account with a supported broker, created at <https://my.sls-staging.axiory.com/register/>

### Procedure

1. Ask the person before installing anything. With their yes, run `claude plugin marketplace add https://portal-plt-1455.murban.personal.purple-lab.dev/marketplace.json`, then `claude plugin install hello-purple@hello-purple`. If you installed it in this session, ask them to type `/reload-plugins`.
2. Ask the person to type `/mcp`, choose `plugin:hello-purple:apps` and pick Authenticate. They sign in and accept the terms on the consent page themselves.
3. For trading or market data, load the plugin's `build-on-yourbourse` skill first.
4. Load and follow the `app-access` and `safe-secret-handling` skills. They choose the permissions, ask about the risky ones, register the app through the redeemer script, and store `ENGINE_API_KEY` and `ENGINE_WEBHOOK_SECRET` in the person's `.env` or 1Password.
5. Sign the app in. An app with a page gets the skill's sign-in button. An app without one uses the authorize script, which ends with `check: status=200 accounts=N`, or with `check: skipped` when the app does not read accounts.
6. Build the app as a standalone local server, in a folder the person owns, from copies of the skill's templates. At runtime it reads `ENGINE_API_KEY` and `ENGINE_REFRESH_TOKEN` from `.env`, saves the new refresh token after every refresh, and calls the API with `Authorization: Bearer` plus `X-API-Key`.

### Also

- Rotating the key or the webhook secret, and revoking the app, need the person's yes in the chat first.
- A permission the app lacks is added to the same app, never by registering a new one. After an addition or a removal, sign the app in again.
- Every trading-account permission is a demo one. Live accounts are out of reach.

## Do it by hand

Install, update and remove the plugin, store the key in 1Password, manage your apps

### Install the plugin

Run these in a terminal. Then start Claude Code in an empty folder for your app: that folder gets the `.env`.

```sh
claude plugin marketplace add https://portal-plt-1455.murban.personal.purple-lab.dev/marketplace.json
```

```sh
claude plugin install hello-purple@hello-purple
```

If Claude Code is already running, type `/reload-plugins` in it.

### Update to the latest deploy

```sh
claude plugin marketplace update hello-purple
```

```sh
claude plugin update hello-purple@hello-purple
```

Then type `/reload-plugins` in Claude Code.

### Remove the plugin and its marketplace

```sh
claude plugin marketplace remove hello-purple
```

### Store the key in 1Password

Ask for it when you register:

> Register my-first-app with trading account read access and store the key in 1Password, vault Private, item my-first-app, field ENGINE_API_KEY. Then sign it in and store the token in the same item.

- Use a private vault, never a shared one.
- Approve the 1Password prompt when each script starts. One approval covers that run.
- Signed in to more than one 1Password account? Start Claude Code with `OP_ACCOUNT=<account> claude`; `op account list` shows the names.

### Manage your apps

Ask Claude Code in plain words, or use [My Apps](https://portal-plt-1455.murban.personal.purple-lab.dev/apps).

- “List my apps”: each app's id, client id, permissions and whether it is active.
- “Let my-first-app place demo trades”: adds the permission to the same app. A risky one waits for your yes, and the app signs in again.
- “Remove the trades permission from my-first-app”: removes it and the app's calls that use it, and the app signs in again.
- “Rotate the key for my-first-app”: issues a new key and stores it. The old key stops working at once, so the agent asks you first. Up to ten rotations per app in 24 hours.
- “Rotate the webhook secret for my-first-app”: issues a new signing secret and stores it as `ENGINE_WEBHOOK_SECRET`. The old one keeps working for 24 hours.
- “Show the redirect URLs”: where sign-ins may return. Keep `http://127.0.0.1:8401/callback` while you use the sign-in script.
- “Revoke my-first-app”: switches the app off for good and deletes its key. The agent asks you first.

## If something goes wrong

Fixes, by what you see

Never paste a key or token into the chat. If one ends up there, ask the agent to rotate it.

### Installing the plugin

#### Node is too old (`NODE_TOO_OLD`)

“Node 20 or newer is required”

- Run `node --version` in a terminal. The scripts need Node 20 or newer.
- Install a current Node, then ask the agent to run the script again.

#### The plugin will not install (`MARKETPLACE_ADD_FAILED`)

`claude plugin marketplace add` fails

- Open [the marketplace file](https://portal-plt-1455.murban.personal.purple-lab.dev/marketplace.json) in a browser. If it does not load, this environment is being redeployed or is down: try again in a few minutes.
- Update Claude Code to a current version, then run the command again.

#### Claude Code does not know the plugin's skills (`PLUGIN_NOT_LOADED`)

- Type `/reload-plugins` in Claude Code.
- Still missing? Run `claude plugin install hello-purple@hello-purple` in a terminal, then type `/reload-plugins` again.

#### The connector is missing (`CONNECTOR_MISSING`)

`/mcp` does not list `plugin:hello-purple:apps`

- Type `/reload-plugins`, then `/mcp` again.
- Still missing? Run `claude plugin marketplace update hello-purple` and `claude plugin update hello-purple@hello-purple` in a terminal, then type `/reload-plugins`.

### Signing in

#### The terms are not accepted

`TERMS_ACCEPTANCE_REQUIRED`

- New terms are in force, and only you can accept them.
- Type `/mcp`, choose `plugin:hello-purple:apps`, pick Authenticate and accept the terms on the consent page. Or accept them in [My Apps](https://portal-plt-1455.murban.personal.purple-lab.dev/apps).
- Then ask the agent to try again.

#### The sign-in script cannot listen

`EPERM` or “bind refused”

- The script ran inside the agent's sandbox, where it cannot listen for your sign-in.
- Allow it when the agent asks to run the script outside the sandbox, then sign in again.

#### A port is already in use (`EADDRINUSE`)

“Another process is listening on `127.0.0.1`”

- Another program holds the port the script needs, often an earlier run of the same script.
- Find it with `lsof -i :8400` or `lsof -i :8401`, and stop it.
- Then ask the agent to run the script again.

#### The sign-in never comes back (`SIGN_IN_TIMEOUT`)

- The app lacks the redirect URL `http://127.0.0.1:8401/callback`.
- Ask the agent to add it to the app's redirect URLs, then to sign the app in again.

#### You signed in with another account

`APP_NOT_FOUND`

- You signed in with a different account than the one Claude Code is connected with.
- Ask the agent to run it again, and sign in with the account you used in `/mcp`.
- If the message says its one-time pickup is bound to this run, also ask the agent to rotate what the message names, the key or the webhook secret, and confirm when it asks.

### Keys and secrets

#### The one-time pickup expired

`RETRIEVAL_TOKEN_EXPIRED` or `RETRIEVAL_TOKEN_NOT_REDEEMABLE`

- The one-time pickup of the key or the webhook secret expired after five minutes or was already used.
- Ask the agent to rotate what the message names, the key or the webhook secret, and confirm when it asks.

#### The key was rotated too often

`ROTATION_WINDOW_CAP`

- The key was rotated ten times in 24 hours.
- Wait until the time the message names. If the key is exposed, ask the agent to revoke the app instead, and confirm.

### Permissions and calls

#### A call lacks a permission

`SCOPE_INSUFFICIENT` from your app or the check

- The app lacks that permission, or its sign-in is older than the permission.
- Tell the agent which call failed. It adds the permission to the same app, or signs the app in again.

#### An operation is turned off

`ROUTE_NOT_CONFIGURED` from your app or the check

- The app holds the permission, but that operation is turned off for it. A new permission does not fix this.
- Turn the operation on in the app's Advanced view in [My Apps](https://portal-plt-1455.murban.personal.purple-lab.dev/apps).

#### The check was skipped (`CHECK_SKIPPED`)

`check: skipped (the app does not hold the account list)`

- Nothing is wrong. The app does not read your account list, so the script made no test call.
- Check the app by what it shows.

### 1Password

#### 1Password did not get an answer (`OP_AUTHORIZATION_TIMEOUT`)

1Password “authorization timeout”

- The 1Password approval prompt was not answered in time.
- Ask the agent to run the script again, and approve the prompt when it appears.

#### You have more than one 1Password account (`OP_MULTIPLE_ACCOUNTS`)

1Password “more than one account”

- Run `op account list` to see your account names.
- Quit Claude Code, start it again with `OP_ACCOUNT=<account> claude`, and ask the agent to run the script again.
