---
title: "Build with your AI agent"
canonical: "https://portal-plt-1490.murban.personal.purple-lab.dev/start/agent/"
markdown: "https://portal-plt-1490.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, Codex, Gemini CLI, Antigravity, Grok Build, Grok Bot: follow this page. Others, or no browser where scripts run: send them to <https://portal-plt-1490.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-1490.murban.personal.purple-lab.dev/start/agent/>, for agents.

# Build with your AI agent.

Your agent 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-1490.murban.personal.purple-lab.dev/marketplace.json
```

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

Then start Claude Code in an empty folder, type `/mcp`, choose `plugin:hello-purple:apps`, pick Authenticate, 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 your agent take every step, from an empty folder. Say:

> Read https://portal-plt-1490.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.

Another agent? [Install on your agent](https://portal-plt-1490.murban.personal.purple-lab.dev/start/agent/#install). claude.ai? [Use the connector](https://portal-plt-1490.murban.personal.purple-lab.dev/start/agent/#for-ai-agents). None? [Use My Apps](https://portal-plt-1490.murban.personal.purple-lab.dev/apps).

Only you can:

- Approve the install; reload your agent when asked.
- Sign in to the connector; accept the terms.
- Approve the registration with the per-call prompt on.
- Let sign-in scripts run outside the sandbox, sign in again in your app with the same account, and approve it at the broker.

You're done when your app, run from your folder, shows your demo accounts (`check: status=200 accounts=N` confirms a script sign-in).

## 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-1490`.

You are done when the app is registered in their name, its key and sign-in are in their store, and the app runs from a folder they own without you and, if it reads accounts, shows their demo accounts. An app without a page signs in with the authorize script, whose `check:` line confirms that sign-in.

The plugin's scripts take the person's sign-in on 127.0.0.1 of the machine they run on, so a hosted agent whose machine the person's browser cannot reach (claude.ai, the Claude apps, a cloud Claude Code session) cannot finish this procedure. For a page with no server, use the connector instead: it needs neither Node nor the plugin. Ask the person to add it in claude.ai as a custom connector, with exactly this URL and no slash added:

```text
https://purple-engine-axi-plt-1490.murban.personal.purple-lab.dev/mcp
```

If they use claude.ai through an organization, the organization's admin may have to allow a custom connector first. Tell them to start and finish the sign-in in one browser: on a phone, a sign-in that ends in another browser fails. One sign-in serves claude.ai, the Claude apps and cloud Claude Code sessions on that account. Then call `plan_access`, then `register_browser_app`, which hands over no key, and build the page from the values its result carries, under the rules of [the builder brief](https://portal-plt-1490.murban.personal.purple-lab.dev/start/browser/). A server app still needs an agent on the person's own computer.

### Values for this environment

- Plugin marketplace (Claude Code): `https://portal-plt-1490.murban.personal.purple-lab.dev/marketplace.json`
- Plugin folder (every other host): `https://portal-plt-1490.murban.personal.purple-lab.dev/plugin.zip`, unpacked to `~/.hello-purple/hello-purple` (on Grok Bot, `/workspace/hello-purple`)
- 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-1490.murban.personal.purple-lab.dev/mcp`
- API base: `https://purple-engine-axi-plt-1490.murban.personal.purple-lab.dev`, OpenAPI document at <https://purple-engine-axi-plt-1490.murban.personal.purple-lab.dev/openapi.json> (rendered for people at <https://purple-engine-axi-plt-1490.murban.personal.purple-lab.dev/docs>)
- Token endpoint: `https://purple-engine-plt-1490-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, install the plugin for your host as [Install on your agent](https://portal-plt-1490.murban.personal.purple-lab.dev/start/agent/#install) shows (Claude Code: `claude plugin marketplace add https://portal-plt-1490.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 reload you (`/reload-plugins` in Claude Code) or start a new session.
2. Ask the person to sign in to the connector `apps` as that table says (Claude Code: `/mcp`, choose `plugin:hello-purple:apps`, pick Authenticate). They sign in and accept the terms on the consent page themselves.
3. On Grok Bot no host loads the skills: read `/workspace/hello-purple/skills/safe-secret-handling/grok-bot.md` first, then each skill’s `SKILL.md` under `/workspace/hello-purple/skills/` in full, and follow them as skills.
4. For trading or market data, load the plugin's `build-on-yourbourse` skill first.
5. 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.
6. 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.
7. 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 the plugin on your agent, update and remove it, store the key in 1Password, manage your apps

### Install on your agent

On your own computer (macOS, Linux or WSL), every agent but Claude Code installs from one folder: download and unpack it first. Grok Bot downloads it itself, as its row says.

```sh
mkdir -p ~/.hello-purple && curl -fsSL https://portal-plt-1490.murban.personal.purple-lab.dev/plugin.zip -o ~/.hello-purple/plugin.zip && rm -rf ~/.hello-purple/hello-purple && unzip -q ~/.hello-purple/plugin.zip -d ~/.hello-purple/hello-purple
```

Install the plugin, then sign in to its connector, named apps. Run the commands in a terminal.

| Agent | Install | Sign in to the connector |
| --- | --- | --- |
| Claude Code | `claude plugin marketplace add https://portal-plt-1490.murban.personal.purple-lab.dev/marketplace.json`, then `claude plugin install hello-purple@hello-purple`, then type `/reload-plugins` | Type `/mcp`, choose `plugin:hello-purple:apps`, pick Authenticate |
| Codex CLI | `codex plugin marketplace add ~/.hello-purple/hello-purple`, then `codex plugin add hello-purple@hello-purple` | `codex mcp login apps` |
| Gemini CLI | `gemini extensions link ~/.hello-purple/hello-purple --consent` | In Gemini CLI, type `/mcp auth apps` |
| Antigravity | `agy plugin install ~/.hello-purple/hello-purple` | Sign in when Antigravity asks for `apps`. If the browser page then shows a code, paste it into Antigravity |
| Grok Build | `grok plugin install ~/.hello-purple/hello-purple --trust`. Skip it if Claude Code already has the plugin: Grok reads Claude Code’s plugins | Sign in when Grok opens the browser, on first use |
| Grok Bot | Say to the Bot: “Download https://portal-plt-1490.murban.personal.purple-lab.dev/plugin.zip, unpack it into /workspace/hello-purple, add the MCP server https://purple-engine-axi-plt-1490.murban.personal.purple-lab.dev/mcp, and follow https://portal-plt-1490.murban.personal.purple-lab.dev/start/agent.md.” | Authorize on the card the Bot shows. The scripts print a sign-in link and a match code: open the link on your own phone or computer and type the code. Without the relay, take over the Bot’s browser in its computer view |

No unzip? Replace its step with `python3 -m zipfile -e ~/.hello-purple/plugin.zip ~/.hello-purple/hello-purple`. To update, run the download again, then: Gemini CLI, nothing more (it reads the folder); Codex, `codex plugin add hello-purple@hello-purple`; Antigravity, `agy plugin install ~/.hello-purple/hello-purple`; Grok Build, `grok plugin uninstall hello-purple && grok plugin install ~/.hello-purple/hello-purple --trust`. Start a new session afterwards.

### Claude Code: start in an empty folder

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-1490.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 (Claude Code)

```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 (Claude Code)

```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 your agent with `OP_ACCOUNT=<account>` set (for example `OP_ACCOUNT=<account> claude`); `op account list` shows the names.

### Manage your apps

Ask your agent in plain words, or use [My Apps](https://portal-plt-1490.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`, the download or your agent’s install command fails

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

#### Your agent does not know the plugin's skills (`PLUGIN_NOT_LOADED`)

- Type `/reload-plugins` in Claude Code. In another agent, start a new session.
- Still missing? Run your agent’s update step ([Install on your agent](https://portal-plt-1490.murban.personal.purple-lab.dev/start/agent/#install)), then reload it.

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

Your agent lists no `apps` server (in Claude Code, `/mcp` does not list `plugin:hello-purple:apps`)

- Claude Code: type `/reload-plugins`, then `/mcp` again. Another agent: start a new session.
- Still missing in Claude Code? Run `claude plugin marketplace update hello-purple` and `claude plugin update hello-purple@hello-purple` in a terminal, then type `/reload-plugins`. Another agent: run its update step ([Install on your agent](https://portal-plt-1490.murban.personal.purple-lab.dev/start/agent/#install)).

### Signing in

#### The terms are not accepted

`TERMS_ACCEPTANCE_REQUIRED`

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

#### The Hello Purple page says it cannot continue (`CONNECTOR_PAGE_ERROR`)

“This request cannot continue”, “This sign-in cannot finish here” or “You already answered”, with an error code such as `consent_expired`

- If your agent already says it is connected (in Claude Code: “Authentication successful”), you are done: close the page.
- Otherwise start the sign-in again from your agent (in Claude Code: type `/mcp`, choose `plugin:hello-purple:apps`, pick Authenticate). You are signed in now, so it usually goes straight through.
- The page with the terms stays open for 10 minutes, and Allow can take a few seconds to answer.

#### Signing in leaves you on the broker’s own pages (`BROKER_DID_NOT_RETURN`)

After you sign in, your account area at the broker opens and nothing else happens

- The broker lost the way back to Hello Purple. That can happen after signing in with a passkey, changing your password or registering on the way.
- Go back to your agent and start the sign-in again (in Claude Code: type `/mcp`, choose `plugin:hello-purple:apps`, pick Authenticate). You are signed in now, so it goes straight to the next step.

#### 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`, or the sign-in page refused the request because the app’s sign-in link does not ask for `prompt=login`.
- Ask the agent to add the redirect URL to the app's redirect URLs, then to sign the app in again.
- If the page names `prompt=login`, the app is built from an older template. Ask the agent to update it, so its sign-in link carries `prompt=login`, then sign in again.

#### The app is not approved (`CONSENT_REQUIRED`)

`CONSENT_MISSING`, `CONSENT_REVOKED` or `CONSENT_SCOPE_NOT_GRANTED`

- You have not approved this app, you withdrew your approval, or the app asks for a permission you have not approved. Only you can fix it.
- Tell the agent to stop and not to retry. Ask it to sign the app in again, sign in with your account, and approve the app on the sign-in page.
- Then ask the agent to try again.

#### You signed in with another account

`APP_NOT_FOUND`

- You signed in with a different account than the one your agent’s connector is signed in with.
- Ask the agent to run it again, and sign in with the account you used for the connector.
- 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.

#### The API key was refused (`API_KEY_REFUSED`)

`API_KEY_MISSING`, `API_KEY_MISMATCH` or `API_KEY_VALUE_MISSING`

- A server app sent no API key, or one that belongs to another app. A page of a browser app sends no key.
- For a server app, ask the agent to check that the key in the app's environment is the one the app received at registration, or to rotate the key and store the new one, and confirm when it asks. For a page, ask the agent to check that the app is declared a browser app.

#### 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-1490.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 your agent, start it again with `OP_ACCOUNT=<account>` set (for example `OP_ACCOUNT=<account> claude`), and ask the agent to run the script again.
