# ArneIron: onboarding a new customer (guide for AI agents) Guide version 3 (arneiron-admin 0.4.31). Primary URL: https://arneiron.net/agent-onboarding/ (HTML). The same text as plain text: https://arneiron.net/agent-onboarding.md. OpenAPI 3.1 of the HTTP calls: https://arneiron.net/agent-onboarding/openapi.json ## 1. Start here **The person** pastes this into their AI agent (ChatGPT agent mode, Claude Code, Codex or similar): ```text Register me on ArneIron. My email is . Follow https://arneiron.net/agent-onboarding/ exactly. ``` **You, the agent**, read this whole page first. Then find the person's current state in section 3 and do only the next action. The steps are plain HTTPS calls. `P=https://arneiron.net`. ```bash # S1 create the account (email only; always 202 with the same neutral text) curl -s -X POST "$P/wp-json/arneiron/v1/signup" -H 'Content-Type: application/json' -d '{"email":"jane@example.com"}' # H1 the person opens the email from ArneIron and chooses a password (you cannot do this) # S4 60-minute token (password from an environment variable, sent on stdin) printf '%s' "$ARN_PASSWORD" | curl -s -X POST "$P/wp-json/arneiron/v1/agent/token" --data-urlencode "email=$ARN_EMAIL" --data-urlencode "password@-" # S5 add their WordPress site; the answer carries the slug curl -s -X POST "$P/wp-json/arneiron/v1/agent/sites" -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' -d '{"site_url":"https://example.com"}' # S6 personalised zip: kind=theme (full setup) or kind=connector (connector only) curl -s -H "Authorization: Bearer $TOKEN" -o arneiron.zip "$P/wp-json/arneiron/v1/agent/sites/$SLUG/download?kind=theme" # end of the account calls: revoke the token curl -s -X DELETE "$P/wp-json/arneiron/v1/agent/token" -H "Authorization: Bearer $TOKEN" ``` Then: install and activate the zip on their WordPress (S7), check it connected (S8), grant write access (S9), the person adds the MCP server `https://hub.arneiron.net/mcp` and approves it (S10, S11), first edit (S12). If you can only read web pages and cannot send POST requests (a normal ChatGPT chat), go to section 8. ## 2. Rules 1. **Use HTTP, not a browser.** Every ArneIron step here is a `curl` call. A cloud browser is often blocked (`net::ERR_BLOCKED_BY_CLIENT`) and gains nothing. Use the terminal. Use a browser only if you have no terminal at all, and then only for the person's own WordPress. 2. **Run non-interactively.** Your shell may have no keyboard (stdin closed). Never call `read -s`, a password prompt or any interactive helper. Put each secret in an environment variable and pipe it into curl on stdin: `printf '%s' "$ARN_PASSWORD" | curl … --data-urlencode "password@-"`. Never put a secret on the command line, in a URL, in a file you keep, or in a log. Never echo it back. 3. **Never change site-wide settings to get past an error.** Do not change permalinks, security or firewall plugins, `.htaccess`, `wp-config.php`, PHP settings, DNS or hosting settings, and do not deactivate plugins, to make an ArneIron step pass. Each of those changes the person's whole site. Report the exact message to the person and stop. They decide. 4. **Never log in to the person's other accounts.** You use exactly two logins: their ArneIron account (only at `https://arneiron.net`) and the WordPress administrator they gave you (only at their own `wp-login.php`). Never log in to ChatGPT, OpenAI, Google, Anthropic, their email, their host or anything else, not even when the person offers. Give them the steps instead. 5. **Ask only for what the current step needs.** First message: their email. After they confirm the email: their ArneIron password, the site URL, a WordPress administrator username and password, and "full" (ArneIron theme plus connector) or "connector only" (their theme stays). Never ask for card data, the emailed link, MCP tokens or application passwords. 6. **Never loop.** On any refusal, read the tables in section 5, do what the row says at most once, and otherwise relay the exact `code` and `message` to the person and stop. Rate limits are real: a loop locks the person out for an hour. 7. **Never create an administrator or an application password yourself.** The connector creates its own restricted `arneiron` user (S9). ArneIron refuses administrator grants. 8. **Report one line per action:** account requested, site added, theme or connector installed (version), activated, connected, write access granted. Never say you did something you did not do. 9. If the person pasted their WordPress password into this chat, recommend that they change it afterwards, or create a temporary administrator for you and delete it when you are done. ## 3. Where are we? State and next action Find the first row that matches, do its next action, then check again. | State | How you know | Next action | |---|---|---| | No account | the person has not signed up | S1 signup with their email | | Account, email not confirmed | S1 answered 202; the person has not opened the email yet | tell them to open the NEWEST email from ArneIron and choose a password (H1); wait for "done" | | Email confirmed | the person says they chose a password | ask for the password, site URL, WordPress admin login, mode; then S4 token | | Token held | S4 answered 200 | S5 add the site | | Site added | S5 answered 201 or 200 with a `slug` | S6 download (`kind=theme` for full, `kind=connector` for connector only) | | Zip downloaded | `Content-Type: application/zip`, one `arneiron-connect.json` inside | S7 install and activate on their WordPress | | Theme or connector installed | the upload page shows success | activate it (S7, follow redirects) | | Connected | S8: `connectState` is `connected` | S9 write access | | Write access granted | the connector page says access was granted to the `arneiron` user | S10: give the person the MCP steps for their AI client | | MCP server added | the person says the plugin or server exists in their client | S11: the person clicks Approve on arneiron.net | | Approved | the person approved on arneiron.net | they start a NEW chat with the server enabled; call `account_profile` (S12) | | Zero balance | a tool answers `INSUFFICIENT_BALANCE` | give the person https://arneiron.net/my-account/my-wallet/ and stop | | Topped up | the person says they topped up | retry the same tool call once | ## 4. Steps ### Setup ```bash P=https://arneiron.net T=$(mktemp -d); chmod 700 "$T"; CJ="$T/wp.jar" trap 'rm -rf "$T"' EXIT # Set these from the person's answers without echoing them: # ARN_EMAIL, ARN_PASSWORD, WP (site URL with https://), WP_USER, WP_PASSWORD ``` Every ArneIron call accepts a JSON body or a normal form body. Every refusal is JSON with a `code` and a `message`. Add `-w '\n%{http_code}\n'` to see the HTTP status. ### S1. Create the account (email only) ```bash curl -s -X POST "$P/wp-json/arneiron/v1/signup" -H 'Content-Type: application/json' \ -d "{\"email\":\"$ARN_EMAIL\"}" -w '\n%{http_code}\n' ``` 202 with `{"status":"accepted","message":"If this address can be used, we have sent an email with a link. Open it and choose a password to confirm the address."}`. The answer is identical for a new address and for an existing one, on purpose. Do not guess which case it was. Send S1 **once**. A repeat within 15 minutes sends no new email, so the first email's link stays valid. A repeat after 15 minutes sends a new link and the older link stops working: the person must then open the NEWEST email. Then tell the person: "If this address can be used, ArneIron has sent you an email. Open the newest email from ArneIron, click the link and choose your ArneIron password. That confirms your email. Then tell me 'done'." ### H1. The person confirms (you cannot do this) Opening the emailed link and choosing a password is the confirmation. Never ask the person to paste the link to you. ### S4. Token with the person's ArneIron password ```bash R=$(printf '%s' "$ARN_PASSWORD" | curl -s -X POST "$P/wp-json/arneiron/v1/agent/token" \ --data-urlencode "email=$ARN_EMAIL" --data-urlencode "password@-") TOKEN=$(printf '%s' "$R" | sed -n 's/.*"token":"\([^"]*\)".*/\1/p') printf 'Authorization: Bearer %s\n' "$TOKEN" > "$T/auth"; chmod 600 "$T/auth" ``` 200 `{"token":"arnag_…","token_type":"Bearer","expires_in":3600,…}`. The token works only for the `/agent/sites` calls and is not a login. The examples send it with `-H @"$T/auth"` so it stays off the command line. ### S5. Add the site ```bash curl -s -X POST "$P/wp-json/arneiron/v1/agent/sites" -H @"$T/auth" -H 'Content-Type: application/json' \ -d "{\"site_url\":\"$WP\"}" -o "$T/s5.json" -w '%{http_code}\n' SLUG=$(sed -n 's/.*"slug":"\([^"]*\)".*/\1/p' "$T/s5.json") ``` 201 (new) or 200 (already in this account): `{"slug":"…","site_url":"…","created":true,"connectState":"awaiting_site","download":{"theme":"…","connector":"…"}}`. `awaiting_site` is normal now. `GET $P/wp-json/arneiron/v1/agent/sites` with the same header lists the account's sites. ### S6. Download the personalised zip ```bash KIND=theme # or: connector curl -s -H @"$T/auth" -D "$T/s6.hdr" -o "$T/arneiron.zip" "$P/wp-json/arneiron/v1/agent/sites/$SLUG/download?kind=$KIND" grep -i '^content-type' "$T/s6.hdr" unzip -l "$T/arneiron.zip" | grep -c arneiron-connect.json ``` Success: `Content-Type: application/zip`, one `arneiron-connect.json` in the zip. Never print that file: it carries a one-time connect token (valid 24 hours). Headers `X-ArneIron-Theme-Version` / `X-ArneIron-Connector-Version` name the version. Install only this zip, never a generic ArneIron zip from elsewhere. Then revoke the token: `curl -s -X DELETE "$P/wp-json/arneiron/v1/agent/token" -H @"$T/auth"` (revoking twice is harmless: 200 again). ### S7. Install and activate on their WordPress Log in (one cookie jar, this host only): ```bash curl -s -c "$CJ" -o /dev/null "$WP/wp-login.php" printf '%s' "$WP_PASSWORD" | curl -s -c "$CJ" -b "$CJ" -o "$T/s7l.html" -w '%{http_code}\n' \ --data-urlencode "log=$WP_USER" --data-urlencode "pwd@-" --data-urlencode "wp-submit=Log In" \ --data-urlencode "redirect_to=$WP/wp-admin/" --data-urlencode testcookie=1 "$WP/wp-login.php" grep -c wordpress_logged_in "$CJ" ``` Check the login page, the login response and the upload page for the blocker markers in section 5.6 before you go on. Scrape each `_wpnonce` from the page that owns the form, after logging in. Follow redirects (`-L`) when you activate: the connector connects on the redirected request. Full mode (theme): ```bash N=$(curl -s -b "$CJ" "$WP/wp-admin/theme-install.php" | grep -oE 'name="_wpnonce" value="[^"]+"' | head -1 | cut -d'"' -f4) curl -s -b "$CJ" -c "$CJ" -o "$T/s7u.html" -F "_wpnonce=$N" -F "themezip=@$T/arneiron.zip;type=application/zip" \ -F "install-theme-submit=Install Now" "$WP/wp-admin/update.php?action=upload-theme" A=$(grep -oE 'themes\.php\?action=activate[^"'"'"']*stylesheet=arneiron[^"'"'"']*' "$T/s7u.html" | head -1 | sed 's/&/\&/g;s/&/\&/g') curl -s -b "$CJ" -c "$CJ" -L -o /dev/null "$WP/wp-admin/$A" ``` The theme installs and activates the bundled ArneIron Connector. Connector only: ```bash N=$(curl -s -b "$CJ" "$WP/wp-admin/plugin-install.php?tab=upload" | grep -oE 'name="_wpnonce" value="[^"]+"' | head -1 | cut -d'"' -f4) curl -s -b "$CJ" -c "$CJ" -o "$T/s7u.html" -F "_wpnonce=$N" -F "pluginzip=@$T/arneiron.zip;type=application/zip" \ -F "install-plugin-submit=Install Now" "$WP/wp-admin/update.php?action=upload-plugin" A=$(grep -oE 'plugins\.php\?action=activate[^"'"'"']*arneiron-connector[^"'"'"']*' "$T/s7u.html" | head -1 | sed 's/&/\&/g;s/&/\&/g') curl -s -b "$CJ" -c "$CJ" -L -o /dev/null "$WP/wp-admin/$A" ``` If the upload says the theme or plugin already exists, use WordPress's "Replace current with uploaded" link from that response page. ### S8. Check the connection ```bash curl -s -H @"$T/auth" "$P/wp-json/arneiron/v1/agent/sites" # get a fresh token (S4) if you revoked it ``` Success: the site shows `"connectState":"connected"`. ArneIron measures this itself; trust it over any badge in wp-admin. ### S9. Give ArneIron write access (restricted user) ```bash H=$(curl -s -b "$CJ" "$WP/wp-admin/admin.php?page=arneiron-connector" | tr '\n' ' ') N=$(printf '%s' "$H" | grep -oE 'value="arncon_wpcred_authorize".{0,600}' | grep -oE 'name="_wpnonce" value="[^"]+"' | head -1 | cut -d'"' -f4) curl -s -b "$CJ" -c "$CJ" -L -o "$T/s9.html" --data-urlencode action=arncon_wpcred_authorize --data-urlencode "_wpnonce=$N" "$WP/wp-admin/admin-post.php" ``` Success: the connector page says access was granted to the `arneiron` user. A refusal: section 5.8. When S9 is done, delete the temporary directory and forget both passwords. ### S10. The person adds the MCP server (they do this, not you) Endpoint: `https://hub.arneiron.net/mcp` (OAuth 2.1). One server is bound to one site; name it after the site. Give the person the steps for their client. Never log in to their client account yourself (rule 4). No plugin packaging, manifest or developer account is needed. **ChatGPT** (web): 1. Open Plugins, click Add (the plus button), then "Add custom MCP server". 2. Name: for example `arneiron-`. URL: `https://hub.arneiron.net/mcp`. Authentication: OAuth. 3. Read the warning, then Create. Install or enable the plugin. 4. A page on arneiron.net opens: log in to ArneIron and click Approve (S11). 5. Start a NEW chat with the plugin enabled. Tools do not appear in a chat that was already open. **Claude Code:** ```bash claude mcp add --transport http arneiron- https://hub.arneiron.net/mcp -s user ``` Then the person runs `/mcp`, picks `arneiron-`, chooses Authenticate, logs in to arneiron.net in the browser and clicks Approve. On a machine without a browser: `claude mcp login arneiron- --no-browser` prints a URL to open anywhere. **Any other MCP client:** add a remote (HTTP) MCP server with URL `https://hub.arneiron.net/mcp` and OAuth, then approve on arneiron.net. ### S11. The person approves (they do this) The approval page on arneiron.net lists their connected sites. They pick the site and click Approve. ### S12. First use In a NEW chat with the server enabled, call `account_profile`. Success: it returns the site (`siteUrl`) with `"connectState":"connected"`. Then make the person's edit, for example: "Change the homepage headline to Fresh bread every morning". If a tool answers `INSUFFICIENT_BALANCE`, see 5.10. ## 5. If you get X, do Y ### 5.1 Signup: `POST /wp-json/arneiron/v1/signup` | You get | Meaning | Do | |---|---|---| | 202 `accepted` | done (same answer for new and existing addresses) | tell the person to open the newest email (S1 text). Do not send S1 again | | 400 `invalid_email` | not an email address | ask the person to type the address again | | 403 `registration_closed` | ArneIron takes no new accounts right now | tell the person; stop | | 403 `cross_origin_refused` | you sent a browser `Origin` header from another site | call from your terminal (curl), with no `Origin` header | | 405 `method_not_allowed` | you sent GET or HEAD | send a real POST | | 429 `rate_limited`, header `Retry-After` | too many signups (5 per hour per IP, 3 per day per address) | wait the `Retry-After` seconds; do not loop; tell the person | | 503 `unavailable` | temporary problem | try once more after a minute, then report it | ### 5.2 The email and the set-password link | Situation | Do | |---|---| | No email after 5 minutes | ask the person to check spam and promotions. Then, only if 15 minutes have passed since your S1, send S1 once more and say "open the NEWEST email" | | "This key is invalid or has already been used" / "already used", or the link expired | an older link: a newer email replaced it. Open the NEWEST email from ArneIron. If none works, request a new link at https://arneiron.net/my-account/lost-password/ (enter the email), then open that newest email | | The person asks you to open the link | refuse kindly: only they can open it and choose the password | ### 5.3 Token: `POST /wp-json/arneiron/v1/agent/token` | You get | Meaning | Do | |---|---|---| | 200 with `token` | done | continue with S5 | | 401 `invalid_credentials` | the email or password is wrong. Before the person confirmed the email, their password does not exist yet, so this is also what you get then | ask: "Did you open the newest ArneIron email and choose a password?" If not, wait for H1. If yes, ask them to re-type the password ONCE and retry once. If it fails again, give them https://arneiron.net/my-account/lost-password/ and stop | | 403 `email_unverified` | right password, email not yet confirmed | ask the person to open the newest email and choose a password; retry after they say "done" | | 403 `account_blocked` | the account cannot be used | stop; the person contacts ArneIron | | 403 `account_not_usable` | the account cannot use this API | stop; relay the message | | 400 `invalid_request` | email or password missing | fix your call (section 4, S4) | | 403 `cross_origin_refused` / 405 `method_not_allowed` | browser call / GET | use curl with POST | | 429 `rate_limited` | 5 tries per hour per address, 20 per IP | wait `Retry-After`; never keep guessing passwords | ### 5.4 Sites: `GET` / `POST /wp-json/arneiron/v1/agent/sites` | You get | Meaning | Do | |---|---|---| | 201 | site added | S6 | | 200 | the site was already in this account | S6 | | 401 `invalid_token` | token missing, expired (60 minutes) or revoked | get a new token (S4) | | 400 `invalid_site_url` | not a usable URL | ask for the URL again (`example.com` is fine) | | 409 with `"hub_code":"SITE_ALREADY_REGISTERED"` | the site belongs to a DIFFERENT ArneIron account | stop. Tell the person: "This site is already registered to another ArneIron account. Log in with that account, or contact ArneIron." Never retry with another account | | 409 `not_linked` / `link_revoked`, 502 `hub_unreachable` / `hub_unavailable` | the account is still being set up, or the hub is busy | wait one minute, retry once, then report it | | 409 or other with `add_site_refused` | the hub refused | relay `hub_code` and `hub_message`; stop | | 429 `rate_limited` | 20 adds per hour | wait `Retry-After` | ### 5.5 Download: `GET /wp-json/arneiron/v1/agent/sites//download?kind=theme|connector` | You get | Meaning | Do | |---|---|---| | 200 `application/zip` | done | S7 | | 400 `invalid_kind` / `missing_site` | wrong `kind` or slug | use `kind=theme` or `kind=connector` and the slug from S5 | | 401 `invalid_token` | token expired or revoked | new token (S4) | | 403 `not_your_site` | that slug is not in this account | use the slug from S5 or from `GET …/agent/sites` | | 404 `rest_no_route` | the URL is wrong (slug format, path) | use the `download` URL from the S5 answer | | 502 `token_mint_failed` | the one-time connect token could not be made | retry once after a minute, then report it | | 503 `release_unverified` (with `reason`) | the release could not be verified | retry once after a minute, then report it with its `reason` | | 500 `build_unavailable` | server problem | report it; stop | ### 5.6 The person's WordPress (S7) Look for these markers in the login page, the login response and the upload page. If you see one, stop the automated install, tell the person what you saw, and hand over the manual steps (Appendix B): they log in at https://arneiron.net/my-account/, open My Sites, click "Download theme" or "Download plugin" for this site, and upload it in wp-admin themselves. | Marker | Meaning | |---|---| | `name="authcode"`, `two-factor`, `wfls-` | two-factor login | | `g-recaptcha`, `cf-turnstile`, `h-captcha` | captcha on the login | | header `cf-mitigated: challenge`, title "Just a moment" | Cloudflare challenge | | `wp-login.php` answers 404 | renamed login URL: ask the person for their login URL, then retry once | | login answers 200 with `login_error` and no `wordpress_logged_in` cookie | wrong WordPress username or password: ask the person to re-type them once | | upload page has no `themezip` / `pluginzip` field | file changes disabled (`DISALLOW_FILE_MODS`) or the user lacks the capability | | `id="request-filesystem-credentials-form"` | WordPress asks for FTP details | Never disable 2FA, a captcha, a firewall rule or a security plugin to get through (rule 3). ### 5.7 Connection (S8) | You see | Do | |---|---| | `connectState` `awaiting_site` one minute after activation, or "Not connected" on the connector page | submit the connector page's Retry form once (recipe below this table), then check S8 again once | | still `awaiting_site`, or the connector says the token expired or was already used | download again (S6: a new zip has a new token) and install it over the old one ("Replace current with uploaded"), activate, check S8 | | `connectState` `unprovable` | wait one minute and check once more; then report it | Retry form (a POST with that form's own nonce): ```bash H=$(curl -s -b "$CJ" "$WP/wp-admin/admin.php?page=arneiron-connector" | tr '\n' ' ') N=$(printf '%s' "$H" | grep -oE 'value="arncon_retry".{0,400}' | grep -oE 'name="_wpnonce" value="[^"]+"' | head -1 | cut -d'"' -f4) curl -s -b "$CJ" -c "$CJ" -L -o /dev/null --data-urlencode action=arncon_retry --data-urlencode "_wpnonce=$N" "$WP/wp-admin/admin-post.php" ``` ### 5.8 Write access (S9) The connector page shows a message. Find it here; never edit server files yourself (rule 3). | Code or message | Do | |---|---| | `rest_disabled`: "The WordPress REST API (/wp-json/) is not reachable on this site …" | check both: `curl -s -o /dev/null -w '%{http_code}\n' "$WP/wp-json/"` and `curl -s -o /dev/null -w '%{http_code}\n' "$WP/?rest_route=/"`. Report both numbers and the message to the person and stop. If `/?rest_route=/` answers 200 while `/wp-json/` does not, the site uses "plain" or `/index.php/` permalinks: ArneIron is adding support for this. Do NOT change the permalink structure: it changes every URL of the site, and only the person may decide that (Settings, Permalinks) | | `auth_header_stripped`: "Your web server removed the Authorization header …" | tell the person: their host must pass the `Authorization` header to PHP (on Apache: `SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1` in `.htaccess`). They or their host make that change, not you. Writes do not work until then | | `site_unreachable`: "ArneIron could not reach this site …" | check that `$WP` loads over HTTPS with a valid certificate; report what you see; stop | | `user_too_privileged` / `not_service_user` | the site runs an old connector: download the current zip (S6), install it over the old one, retry S9 once | | `not_connected` | go back to S8 | | `hub_unreachable` / `hub_error` | wait one minute, retry once, then report it | | `service_user_unavailable` | another plugin blocks creating the `arneiron` user: tell the person; stop | | `app_passwords_unavailable` / `not_https` | the site must be on HTTPS with Application Passwords enabled: tell the person; stop | | anything else | relay the exact message; stop | ### 5.9 MCP (S10 to S12) | Situation | Do | |---|---| | The current chat shows no ArneIron tools after the person added the server | 1) did they click Approve on arneiron.net? 2) is the plugin/server enabled for this chat? 3) start a NEW chat. Then call `account_profile` | | The approval page says "You have no connected site yet" | the site is not connected: back to S8 | | `account_profile` shows another site, or `connectState` is not `connected` | the server is bound to that account's site; check S8, or add a separate server named after the right site | | "Unexpected error" in the AI client after Approve | relay it as given; do not loop | | The person offers their ChatGPT or Google login | decline (rule 4); give them the S10 steps | ### 5.10 Money | You get | Do | |---|---| | `INSUFFICIENT_BALANCE` (with `topup_url`) | nothing was charged. Tell the person: "Your ArneIron wallet is empty. Top it up here: https://arneiron.net/my-account/my-wallet/ and tell me when you are done." Stop. You never handle card data | | the person says they topped up | retry the same call once | | `BILLING_BLOCKED` / `BILLING_UNAVAILABLE` | relay the message; stop | ## 6. Words to use with the person - After S1: "If this address can be used, ArneIron has sent you an email. Open the newest one, click the link and choose your ArneIron password. Then tell me 'done'." - Before S4: "Please give me your ArneIron password, your WordPress site address, a WordPress administrator username and password, and whether you want the full ArneIron setup or the connector only." - After S9: "Your site is connected and ArneIron can write to it through its own limited user. Last step: add ArneIron to your AI app (steps below) and click Approve." - On any stop: the exact `code` and `message`, what you checked, and what they can do. ## 7. Clients at a glance | Client | Can do the HTTP steps itself? | MCP setup | |---|---|---| | ChatGPT agent mode (with a terminal) | yes, with curl (its browser may be blocked) | the person adds the plugin (S10, ChatGPT) | | Claude Code, Codex, other terminal agents | yes | `claude mcp add …` (S10) or the client's own command | | A Custom GPT with an Action from the OpenAPI file | yes (S1 to S6) | the person adds the plugin (S10, ChatGPT) | | A normal ChatGPT chat | no (GET only): section 8 | the person adds the plugin (S10, ChatGPT) | ## 8. If you are a normal ChatGPT chat (you can only read pages) Be honest. You **can**: read this guide, explain the steps, and give the person links and commands. You **cannot**: send the signup request, log in, download the personalised zip, or install anything. Never say you did. Do not recommend third-party form-filling or automation tools: nothing else is needed. Give the person one of these two: 1. The prefilled signup link (it creates nothing; they click Register): `https://arneiron.net/my-account/?signup_email=`, for example `https://arneiron.net/my-account/?signup_email=jane%40example.com` 2. Or the one-line command, if they use a terminal: `curl -s -X POST https://arneiron.net/wp-json/arneiron/v1/signup -H 'Content-Type: application/json' -d '{"email":"jane@example.com"}'` Then: they open the newest email and choose a password; log in at https://arneiron.net/my-account/; in My Sites add the site and click "Download theme" (or "Download plugin" for connector only); install it in wp-admin (Appendix B); add the MCP server (S10). ChatGPT agent mode (or Work mode) with a terminal can run all the curl steps of this guide itself. Suggest it if the person wants the agent to do the work. ## Appendix A. The same steps through the web pages (fallback only) Use these only if the HTTP calls above are unavailable. Cookie jar `J="$T/portal.jar"`. Scrape every nonce from the page that owns the form, after you log in. S1 register (success: "Check your email", no `wordpress_logged_in` cookie): ```bash N=$(curl -s -c "$J" -b "$J" "$P/my-account/" | grep -oE 'name="woocommerce-register-nonce" value="[^"]+"' | cut -d'"' -f4) curl -s -c "$J" -b "$J" -o "$T/s1.html" --data-urlencode "email=$ARN_EMAIL" --data-urlencode "woocommerce-register-nonce=$N" \ --data-urlencode "_wp_http_referer=/my-account/" --data-urlencode "register=Register" "$P/my-account/" grep -c 'Check your email' "$T/s1.html" ``` S4 log in (refused with "Please confirm your email address first" until the email is confirmed): ```bash N=$(curl -s -c "$J" -b "$J" "$P/my-account/" | grep -oE 'name="woocommerce-login-nonce" value="[^"]+"' | cut -d'"' -f4) printf '%s' "$ARN_PASSWORD" | curl -s -c "$J" -b "$J" -L -o "$T/s4.html" --data-urlencode "username=$ARN_EMAIL" --data-urlencode "password@-" \ --data-urlencode "woocommerce-login-nonce=$N" --data-urlencode "_wp_http_referer=/my-account/" --data-urlencode "login=Log in" "$P/my-account/" grep -c wordpress_logged_in "$J" ``` S5 add site, then S6 download (the site card links carry a per-site nonce): ```bash N=$(curl -s -b "$J" "$P/my-account/arneiron-sites/" | grep -oE 'name="arnpx_add_site_nonce" value="[^"]+"' | cut -d'"' -f4) curl -s -b "$J" -c "$J" -L -o "$T/s5.html" --data-urlencode arnpx_add_site=1 --data-urlencode "arnpx_add_site_nonce=$N" \ --data-urlencode "arnpx_new_site_url=$WP" "$P/my-account/arneiron-sites/" U=$(grep -oE "admin-post\.php\?action=arnpx_download_${KIND}(&|&|&)[^\"' ]+" "$T/s5.html" | head -1 | sed 's/&/\&/g;s/&/\&/g') curl -s -b "$J" -D "$T/s6.hdr" -o "$T/arneiron.zip" "$P/wp-admin/$U" ``` S8 on the web page: the site card has the class `arnpx-site__connect--ok` (text "Connected"). ## Appendix B. Manual steps (hand these to the person) 1. Account: open https://arneiron.net/my-account/, enter the email under Register, open the newest email from ArneIron and choose a password, then log in. 2. My Sites: add the site address. Click "Download theme" (full setup) or "Download plugin" (connector only). 3. Full setup: WordPress admin, Appearance, Themes, Add New, Upload Theme, choose the ArneIron zip, Install Now, Activate. 4. Connector only: WordPress admin, Plugins, Add New, Upload Plugin, choose the connector zip, Install Now, Activate Plugin. 5. On the ArneIron page in wp-admin, click "Give ArneIron access". 6. Add the MCP server to the AI app (S10) and click Approve on arneiron.net. Start a new chat.