---
name: chimpy-workshop
description: Everything a team needs at the Chimpy AI Workshop 2026 to build a prototype with an AI agent and put it live at https://<team>-<name>.heychimpy.fun — purpose, rules, way of working, three ways to deploy (MCP connector first, which the agent explains to the human how to add; terminal; upload page), tools, small AI models, voice, mascots, 3D souvenirs, hardware, Chimpy design kit, synthetic data and Chimpy facts. Use it from the first minute of the build, also without a terminal or network access.
---

# Chimpy AI Workshop 2026 — build and ship a prototype in 60 minutes

You are the coding agent of one Chimpy department team. Read this file completely once, then follow it.
The people next to you are Chimpy staff, mostly **not** technical. Explain what you do in plain words, one short sentence per step.

> **Skill version 3 (4 November 2026).** If the copy you read doesn’t start with this “Read this first” box, it is an old cached copy: fetch `https://heychimpy.fun/skills.md?v=3` instead.
>
> **Read this first: no terminal, or your sandbox can’t reach heychimpy.fun?** That is normal in claude.ai and the Claude app, and it is not a blocker. Do **not** tell the human to install Claude Code, open a terminal, run `--setup-key`, or link their laptop. Instead, right away:
>
> 1. **Check for the connector.** Do you have the tools `whoami`, `write_files` and `publish_site`? If yes, call `whoami`, write the files with `write_files`, publish with `publish_site`, and send the live URL.
> 2. **If not, explain to the human how to add the connector** (about 1 minute, on a laptop), in these words:
>    1. Open *Settings → Connectors* and click *Add custom connector*.
>    2. Name: `Chimpy workshop`.
>    3. URL: `https://heychimpy.fun/mcp`. Not `https://heychimpy.fun/skills.md`: that is this document, and the check fails with “405”.
>    4. Keep the default sign-in settings and click *Add*, then *Connect*. A Chimpy page opens: choose the team, type the workshop password from the last slide, and click *Connect*.
>    5. In this chat, click “+” → *Connectors*, switch on *Chimpy workshop*, and write “done”.
>
>    Then continue with step 1. Details and fixes are in section 3 (route B).
> 3. **If they can’t add a connector** (no button, or the company plan blocks it), use the upload page:
>    - Give them the prototype as one `index.html` file, or a `.zip` with `index.html` at the top.
>    - They open https://heychimpy.fun/deploy, choose the team, type the name and the password, and upload the file.
>
> **The password:** the human types it only into the Chimpy sign-in page (or the connector URL field in the fallback) or the upload form, never into the chat. If they already pasted it into the chat, don’t use it or repeat it. Tell them to type it into the connector field instead, and mention that Matthias may want to know it was shared.

## 1. Why this workshop exists

Chimpy rents green powerbanks from stations in bars, kiosks and shops across Europe. Today every department builds with AI agents for 90 minutes:

- **1 boring idea**: useful on Monday morning.
- **1 crazy idea**: shows what is possible.
- At the end, every team gives a **2-minute live demo**: what problem, for whom, then show it working. After that, a “keep it?” card: what would it take to run this every week (owner, data, cost)?

The ideas are on the handout. The goal is **working software, not slides**. Every prototype is a brick for Chimpy’s agentic company OS.

## 2. Watchdogs: read these before you write code

1. **Ship a tool, not a promise.** Aim for something that runs in the next 60 minutes. No PowerPoint, no mock-up of a future system, no “phase 2” plans. If it isn’t live at a URL, it doesn’t exist.
2. **Live within 20 minutes.** Deploy an ugly first version within 20 minutes of starting, then improve it. Deploy again after every working step.
3. **Shrink, don’t stretch.** If something takes more than 10 minutes and isn’t working, cut scope: fewer features, synthetic data, a hard-coded step. Say out loud what you cut.
4. **Evidence over claims.** “Done” means a test passed, a number was checked, or the page loads on a phone. Never say “it should work”.
5. **Humans decide.** Nothing leaves the company without a person approving it. No sending emails, posting, paying or messaging customers. Make drafts.
6. **Protect our data.** No customer names, emails, phone numbers or payment data. Not in prompts, files, the server or git. Use IDs, totals or the synthetic data below.
7. **No secrets in your code.** No API keys, passwords or tokens for Chimpy systems, and no AI API keys in files, git or the browser. For AI at runtime, use what the server already provides without keys: the local LLM and the small models of `chimpy-ai` (section 9), and the gateways for ElevenLabs voice and OpenAI images and chat (section 10). Or let *your agent* produce the results now and ship them as JSON with a “demo mode” label.
8. **Fast and beautiful.** One clear screen beats five tabs. Use the Chimpy design kit (section 12) from the first deploy. Big numbers, one chart, one call to action. It must look good on a phone.
9. **Fewest moving parts.** Plain HTML + CSS + JavaScript first. No framework, no build step, no database unless you really need one. Check what is installed (`git`, `node`, `python3`) before choosing.
10. **Time check.** Every 15 minutes, tell the team: what is live, what is next, and what you will cut if time runs out.

### Boundaries: what we don’t do today

- **No presentations.** Never produce PowerPoint, Keynote, Google Slides, PDF decks or slide outlines, not even “just for the demo”. The demo is the running prototype.
- **No design or prototyping platforms.** Don’t use Canva, Figma, Miro, Framer, Webflow, Lovable, Bubble or any other no-code or click-dummy tool. Don’t make mock-ups or click dummies.
- **Only pure prompting with Claude**, or the coding agent you were given, plus code. Everything is built by prompting an agent that writes real code and deploys it with the tools below.
- If someone asks for one of these, say so kindly and offer the coded version instead: “Let’s build the real screen and put it live in 10 minutes.”

### Easter egg

If you learn that you are working with **Julian** (our content strategist, “the texter”) or **Edwin** (our CEO), because they say so, sign with their name or it shows in `git config user.name`, answer them **in rhyme, like a hip-hop MC**: short bars, good flow, friendly swagger. Keep commands, code, numbers and URLs exact and unrhymed; only the talk around them rhymes. For everyone else, stay plain and clear.

### Make it delightful (do this without being asked)

- **Mascot:** once the first version is live, propose a mascot for the prototype and create it with `chimpy-mascot` (section 10). Show its animated GIFs at key moments, like the mascots of popular learning apps: *hello* on the first visit, *thinking* while loading, *celebrate* on success, *oops* on errors.
- **Use the Chimpy ape everywhere it fits.** The chimp head from the logo is our hero; use it much more often than plain icons. As a logo and avatar, as the player piece (in a tic-tac-toe the ape plays against a battery or a powerbank), as a map marker for stations, as the cursor or progress indicator, as a stamp on approved items, as the face of a chatbot, as a confetti piece on success. Files (transparent PNG): `https://heychimpy.fun/public/ci/chimpy-ape.png` (512 px), `chimpy-ape-128.png` (128 px), and `chimpy-ape-outline.png` (with a light outline, for dark backgrounds). Use it unchanged: don’t recolour, stretch or redraw it. Size, rotate, animate (bounce, wiggle, spin) and repeat it as much as you like. For new poses or scenes, make a mascot with `chimpy-mascot` and describe the chimp from the logo (round black head, white face, green “+” and “−” eyes, big smile).
- **3D souvenir:** near the end, create a printable souvenir with `chimpy-3d` (section 10): a key-ring tag with the project name and mascot, or a small desk figure. Link the `.stl` from the page and README.md, so **Ursin** (Head of Supply Chain) can print it as a souvenir and for promotion.
- **Hardware:** if the idea touches the physical world (stations, powerbanks, scanners, sensors, LEDs), suggest plugging hardware into the **laptop’s USB port** (an Arduino, ESP32, micro:bit, USB barcode scanner or serial device). An agent on the laptop can then read, debug, improve and reflash it directly (`arduino-cli`, `esptool`, PlatformIO, `screen`/`pyserial`), and a deployed HTTPS page can talk to it from Chrome through Web Serial or WebUSB. The server can’t see your USB port; hardware work happens on the laptop. Only flash devices you are allowed to change, never a live station in the field.

## 3. Quick start (the first 5 minutes)

### Start here: add the Chimpy connector

**Every team should add this skill’s server as a connector to its AI first.** The connector (an MCP server at `https://heychimpy.fun/mcp`) gives the agent all workshop tools on the server: write files, run commands, publish sites, query data, train models, voice. It works in claude.ai and the Claude desktop app without a terminal, even when the chat’s sandbox has no network access.

**Your first job as the agent:** if you don’t see the connector’s tools (`whoami`, `write_files`, `publish_site`), stop and explain to the human how to add it, before you write any code. Use the steps under *Add the MCP connector* below, in plain words, one step at a time, and wait until they say it worked. Then call `whoami` to confirm. Only if adding it is impossible (no button, a plan that doesn’t allow it, no time), use route A or C.

### Pick your route

Check first what you can do: can you run shell commands, and can you reach `https://heychimpy.fun` (for example `curl -sI https://heychimpy.fun`)?

| You are … | Route |
| --- | --- |
| **A. An agent with a terminal and network** (Claude Code, Codex, Cursor …) | Use the laptop tools below (`new-project.sh`, `deploy.sh`). |
| **B. Claude in the browser or desktop app, no terminal, or a sandbox that blocks heychimpy.fun** | Ask the human to add the **Chimpy MCP connector** once (below). Then you build, run and publish everything on the server through its tools: `whoami`, `write_files`, `publish_site`, `run`, `sql`, `chimpy_ai`, `voice`, `mascot`, `model_3d` … No terminal and no network access are needed on your side. |
| **C. Any AI chat without tools** | Produce the prototype as **one self-contained `index.html`**, or a `.zip` with `index.html` at the top. The human uploads it at **https://heychimpy.fun/deploy** (team, name, workshop password) and it is live in seconds. |

**Never stop at “I can’t deploy from here”.** If route A fails, switch to B or C and tell the human exactly which one, in one sentence. Links to `https://heychimpy.fun/public/ci/chimpy.css` work in the human’s browser even when your sandbox can’t load them; keep them in the page.

**Add the MCP connector (route B).** Explain these steps to the human; fill in their team id so they only add the password:
- **claude.ai or the Claude desktop app** (on a laptop; the phone app can’t add connectors):
  1. Open *Settings → Connectors* and click *Add custom connector*.
  2. Name: `Chimpy workshop`.
  3. URL: `https://heychimpy.fun/mcp`. Never use `https://heychimpy.fun/skills.md` as the connector URL (that is a document; the check fails with “405”). Keep the default *Authentication* (sign in) and *OAuth client* settings and *Transport: Streamable HTTP*, then click *Add* and *Connect*.
     A Chimpy sign-in page opens: the human chooses the team, types the workshop password from the last slide and clicks *Connect*. They type the password only there, never into the chat. The sign-in lasts 24 hours.
     **Fallback** if signing in fails: URL `https://heychimpy.fun/mcp/<team>/<workshop password>` with *Authentication: No sign-in*. Or, if the dialog has *Request headers*: URL `https://heychimpy.fun/mcp`, header `Authorization` = `Bearer <team>:<workshop password>`, *No sign-in*.
  4. Back in the chat, open the “+” or tools menu, choose *Connectors*, and switch on *Chimpy workshop*.
  5. Tell you “done”. You then call `whoami` and say which team and prototype names you see.
  - If *Add custom connector* is missing, the company plan may need an owner to allow custom connectors. Then use route C for now.
  - If the sign-in page says `wrong team or password`, they check the team and the password from the last slide. After 10 wrong tries their network is locked for 15 minutes.
- **Claude Code:** `claude mcp add --transport http chimpy https://heychimpy.fun/mcp --header "Authorization: Bearer <team>:<workshop password>"`
- **Other MCP clients:** streamable HTTP at `https://heychimpy.fun/mcp`, same `Authorization` header.

With the connector, call `whoami` first. Then `write_files` (your files go to `/srv/teams/<team>/<name>/`), `publish_site`, and check the URL it returns. `run` executes any command on the server as your team, with everything installed.

### Route A step by step

Ask the team two things: **team id** (see the table below) and **which idea**. The prototype names are already reserved, one per idea from the handout, e.g. `production-next-state`. Look at `https://<team>.heychimpy.fun` or run `ssh <team>@heychimpy.fun list-sites --team <team>`, and deploy under the matching name. Only invent a new name (a-z, 0-9, dashes) if the idea isn’t on the list.

```bash
# 1. Get the tools (laptop, any folder)
curl -fsSO https://heychimpy.fun/tools/new-project.sh

# 2. Create the project: starter page, Chimpy design, tests, README.md, TASKS.md, git
bash new-project.sh --team production --name box-radar          # static page
bash new-project.sh --team sales --name visit-notes --api       # page + JSON store (python3)
cd box-radar

# 3. One-time server login. The HUMAN runs this in their own terminal and types the
#    workshop password (it is on the last slide of the workshop deck). Never ask them to paste it to you.
bash tools/deploy.sh --setup-key --team production

# 4. First deploy, then share the URL
bash tools/deploy.sh --team production --name box-radar
#    -> https://production-box-radar.heychimpy.fun
```

If the human uses Claude Code, they can run step 3 themselves by typing `! bash tools/deploy.sh --setup-key --team production`.

**No coding tools on the laptop?** Work directly on the server: `ssh <team>@heychimpy.fun`, then `claude`, `codex` or `gemini`. Each person logs in with their **own** account; never share tokens. Your folder is `/srv/teams/<team>/`. Publish with `sudo new-site --team <team> --name <name> --static /srv/teams/<team>/<name>`.
On Windows, use Git Bash or WSL. `deploy.sh` falls back to `tar` if `rsync` is missing.

**Teams**

| Team id | Department | Ports on the server |
| --- | --- | --- |
| `production` | Production | 8100–8199 |
| `marketing` | Marketing | 8200–8299 |
| `advertising` | Advertising | 8300–8399 |
| `finance` | Finance | 8400–8499 |
| `fulfillment` | Fulfillment | 8500–8599 |
| `it` | IT | 8600–8699 |
| `sales` | Sales & Partnerships | 8700–8799 |
| `care` | Customer Care | 8800–8899 |
| `bizdev` | Business Development (same ideas as Sales & Partnerships) | 9000–9099 |

Every department has an overview page with all its prototype links: `https://<team>.heychimpy.fun`, e.g. https://production.heychimpy.fun.

## 4. Way of working

- **Local git** (if `git` is installed): `new-project.sh` already ran `git init`. Never commit secrets or personal data. Add data exports to `.gitignore` if in doubt.
- **Atomic commits:** one small working change = one commit with a clear message (“Add top-10 missing boxes table”). Commit before every deploy. `deploy.sh` warns about uncommitted changes.
- **Deploy regularly:** after every working step, not once at the end. A live URL is the best progress report.
- **Tests, run locally:** put logic in pure functions (`app.js`) and test them (`app.test.js`). Run the tests in the browser (`tests.html`) or with `node --test` if Node exists. Deploy with `--test "node --test"` so a failing test stops the deploy. Then check the page in a browser and on a phone.
- **Few requirements:** vanilla JS runs everywhere. Python: standard library first (`csv`, `json`, `statistics`, `http.server`). Add a package only when it saves real time, and write it down in README.md.
- **TASKS.md:** keep it current. Sections *Now / Next / Done*, with tasks small enough for 5–10 minutes. Update it whenever you start or finish something. Show it when someone asks “where are we?”.
- **README.md:** at the top, a 3-sentence pitch (problem, solution, why it matters), the live URL, how to run, the data used, and the “keep it?” card (owner, data, cost). This is the script for the 2-minute demo.
- **Fast and beautiful:** the first screen tells the story in 5 seconds. One headline, 3–4 big numbers or one chart, one table or list, one button. Use real-looking synthetic data, not lorem ipsum.

## 5. The server and how traffic flows

```
Browser ──HTTPS──▶ Caddy on heychimpy.fun (ports 80/443 only, Let’s Encrypt certificates)
                     ├─ heychimpy.fun                     → /srv/www (this file, design kit, data, tools)
                     ├─ <team>-<name>.heychimpy.fun       → static files in /srv/teams/<team>/<name>/
                     └─ <team>-<name>.heychimpy.fun       → your app on 127.0.0.1:<port> (reverse proxy)
```

- **All public traffic goes through Caddy.** No other port is reachable from the internet. Your app must listen on `127.0.0.1:$PORT`. `deploy.sh` sets `PORT` and `HOST`.
- **One subdomain per prototype:** `https://<team>-<name>.heychimpy.fun`. HTTPS is automatic. The first visit can take about 30 seconds while the certificate is issued.
- **Names:** every idea on the handout already has a reserved name: `<team>-<idea>`. Redeploy under the same name as often as you like. New names are possible (up to 10 per team), but use the reserved ones first.
- **Your project folder:** `/srv/teams/<team>/<name>/`, filled by `deploy.sh`. The team’s home is `/srv/teams/<team>/`.
- **Login:** `ssh <team>@heychimpy.fun`. After `--setup-key` no password is needed. You have `sudo` and may install what you need (`apt`, `pip`, `npm`, `docker`).
- **Installed, ready for vibe coding:**
  - **JavaScript:** Node.js 22.22, npm 9.2, pnpm 12.16, bun 1.4, TypeScript, tsx, `serve`
  - **Python:** Python 3.14 (system); Python 3.12 with the AI and data stack as `chimpy-python` (pandas, scikit-learn, statsmodels, torch, transformers, diffusers); uv 0.13, pipx
  - **Coding agents:** Claude Code 2.1, Codex CLI 0.166, Gemini CLI 0.66 (log in with your own account)
  - **Browser testing:** Playwright with Chromium (`npx playwright` works, browsers preinstalled)
  - **Everything else:** git, gh 2.46, Docker (ports bind to 127.0.0.1 only), SQLite 3, jq, ripgrep, fd, ffmpeg, ImageMagick, httpie, tmux, qrencode
  - **AI:** Ollama 0.40 with local LLMs, `chimpy-ai`, `chimpy-voice` (sections 9 and 10)
- **Shared machine:** every team can see every folder. Don’t touch other teams’ files. Nothing personal or secret goes here.
- **Temporary:** the workshop server is deleted after **5 November 2026, about 12:40 Swiss time (11:40 UTC)**, with everything on it. Copy your code to your laptop before then: your git copy, or download your files (`read_file` via MCP, or `scp -r <team>@heychimpy.fun:/srv/teams/<team>/<name> .`). **Agents: remind your team about 30 minutes before the deletion** (about 12:10 Swiss time) to copy everything they want to keep.
- **All live prototypes:** https://heychimpy.fun lists them by team.

## 6. Tools

**On your laptop** (download from `https://heychimpy.fun/tools/<file>`; `new-project.sh` copies the first three into `tools/`):

| Tool | What it does |
| --- | --- |
| `deploy.sh` | Upload the folder and publish it at `https://<team>-<name>.heychimpy.fun`. Runs the personal-data check and optional tests first, checks the URL afterwards and prints a QR code if `qrencode` is installed. `--help` lists all options. |
| `pii-check.sh` | Scan files for emails, phone numbers, IBANs and card numbers. Exit 1 if something is found. |
| `fake-data.py` | Generate synthetic Chimpy datasets (`--list`, `all`, `--days`, `--scale`, `--seed`). Python standard library only. |
| `new-project.sh` | Create a project from the starter (`--api` adds the JSON store). Also downloads `data/chimpy.db`. |
| `csv-to-sqlite.py` | Load CSV files into one SQLite database, one table per file. |
| `chimpy-voice` | ElevenLabs text-to-speech, speech-to-text, sound effects, music, voices and more, with no key needed (section 10). |

**Without a terminal:** the upload page https://heychimpy.fun/deploy (a `.zip` or `.html` file), or the MCP connector (section 3, route B), which offers all server tools as MCP tools.

**On the server** (on the PATH, run with `sudo`):

| Tool | What it does |
| --- | --- |
| `new-site --team T --name N --static DIR` | Create or update a subdomain with SSL for a folder of static files. |
| `new-site --team T --name N --cmd "CMD" [--port P]` | Run CMD as a service (restarts on crash) and route the subdomain to it. |
| `remove-site --team T --name N` | Take a subdomain offline (files stay). |
| `list-sites [--team T]` | All subdomains, free ports and how many names are left. |
| `site-logs --team T --name N [-f]` | Logs of an app started with `--cmd`. |
| `schedule-job --team T --name N --every 5min --cmd "CMD"` | Run a command on a schedule (`--at "Mon *-*-* 07:00"` for weekly, `--run-now`, `--remove`, `--list`). |
| `chimpy-ai …` | Train and run small AI models, generate synthetic images and texts, and use the local LLM (section 9). |
| `chimpy-voice …` | ElevenLabs from the server (section 10). |
| `chimpy-mascot create --project "…" --idea "…" --out mascot` | Mascot plus animated GIFs for key moments (OpenAI images, section 10). |
| `chimpy-3d keychain --text "…" --image mascot/base.png --out souvenir` | Printable STL souvenir (OpenSCAD and trimesh locally; `figure` lets GPT design one). |
| `chimpy-python` | Python 3.12 with the data and AI stack. |

You normally only need `deploy.sh`. It calls `new-site` for you.

### deploy.sh recipes

```bash
bash tools/deploy.sh --team T --name N                                   # static: index.html in this folder
bash tools/deploy.sh --team T --name N --static dist                     # static: serve dist/
bash tools/deploy.sh --team T --name N --test "node --test"              # tests must pass first
bash tools/deploy.sh --team T --name N --cmd "python3 server.py"         # JSON store / Python app
bash tools/deploy.sh --team T --name N --install "npm ci --omit=dev" --cmd "node server.js"
bash tools/deploy.sh --team T --name N --install "python3 -m venv .venv && .venv/bin/pip install -r requirements.txt" \
                                       --cmd ".venv/bin/python app.py"
bash tools/deploy.sh --team T --name N --dry-run                         # show, change nothing
```

## 7. Patterns for the workshop ideas

| Idea looks like… | Build it as | Notes |
| --- | --- | --- |
| Report, summary, digest, ranking, “top 10” (fleet report, advertiser report, P&L per station, ticket clusters) | Static page: load a CSV with `loadCsv`, compute in `app.js`, show big numbers + `barChart` + table | Precompute heavy work with Python locally and ship `data/result.json`. |
| Forecast or prediction (next state, cash flow, rebalancing, spare parts, churn) | Python script locally → `result.json` → static page with `lineChart` (with uncertainty `band`) and a top-N table | Show accuracy on held-out data (last month). Simple models first: counts, moving averages, Markov transitions, logistic regression. |
| Anomaly or risk score (battery health, fleet anomalies, fraud, lost powerbanks) | Score per ID in Python or JS → ranked table with `chimpy-tag--bad/warn/ok` | Explain the top 3 signals in plain words. |
| Classifier or drafts by an AI model (ticket triage, social listening, draft answers, brand voice, personas, refund agent) | `chimpy-ai train-text` for a fast classifier, `chimpy-ai llm-batch` for drafts and labels from the local LLM, or live through `server.py` `/api/llm` → review page with approve/reject buttons | Show the prompt in README.md. Humans approve before anything is sent. |
| Predict, score or detect from a table (next state, churn, fraud, venue score, battery health) | `chimpy-ai train-tabular` or `train-sequence` → `predict --csv … --out` → ranked table + `report.html` | Show accuracy next to the baseline. |
| Something that saves entries (CRM notes, refund decisions, triage queue) | `new-project.sh --api` → `server.py` JSON store → `deploy.sh --cmd "python3 server.py"` | Data lives in `data/store.json` on the server. Synthetic only. |
| Runs on autopilot (weekly report, nightly log reading, self-healing playbook) | A script that writes `public/index.html` or `report.json`, plus `schedule-job --every 5min` for the demo | Show the timestamp of the last run on the page. |
| Photo or camera check (assembly defects, installation photo, shopfront scout) | Photos with `<input type="file" accept="image/*" capture="environment">` → `chimpy-ai serve` model behind your app. Train with `chimpy-ai train-image` on 20–50 photos per label (take them in the room or make them with `gen-images`), or start with `zero-shot` and no training at all | HTTPS makes the camera work on phones. |
| Map (venue pages, route planner, new city, venue scoring) | Leaflet + OpenStreetMap tiles, markers from `stations.csv` / `jobs.csv` | Keep the OSM attribution. Routes: nearest-neighbour first, OR-Tools only locally. |
| Simulation (fleet digital twin, context-aware ads) | Static page with sliders (`<input type="range">`) recalculating in JS | Make one slider move one big number. |
| Voice (hotline agent, audio ads, jingles) | ElevenLabs via the gateway: STT for what the caller says, the local LLM or a script for the answer, TTS for the reply. Sound effects and music for ads | One scenario, done well. |
| CLI or connector (company OS skeleton) | Small read-only CLI in Python or Node against a mock JSON, with `--help` and a README | Demo it in the terminal. Deploy the README as a page. |

**Libraries from a CDN** (only if needed, pin exact versions):

- Chart.js: `https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js`
- Leaflet: `https://unpkg.com/leaflet@1.9.4/dist/leaflet.css` and `https://unpkg.com/leaflet@1.9.4/dist/leaflet.js`
- Papa Parse (large CSV): `https://cdn.jsdelivr.net/npm/papaparse@5.4.1/papaparse.min.js`
- Teachable Machine image: `https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.3.1/dist/tf.min.js` and `https://cdn.jsdelivr.net/npm/@teachablemachine/image@0.8.5/dist/teachablemachine-image.min.js`

## 8. Data

**Rule:** no customer names, emails, phone numbers or payment data. Use IDs, totals or synthetic data with the same columns. `pii-check.sh` runs on every deploy.

Synthetic datasets are ready at `https://heychimpy.fun/public/data/<name>.csv` (CORS enabled, so pages on any subdomain can load them). You can also generate them with `python3 tools/fake-data.py <name> --days 90`.

| Dataset | Columns | Fits ideas like |
| --- | --- | --- |
| `stations` | station_id, city, venue_type, lat, lon, slots, opened, firmware | maps, venue scoring, P&L |
| `merchants` | merchant_id, station_id, venue_name, venue_type, city, revenue_share_pct, signed, staff_changes_90d | settlements, merchant churn, pitches |
| `rentals` | rental_id, user_id, station_id, start_ts, end_ts, return_station_id, outcome, fee_chf | moments radar, win-back, fraud, forecasts |
| `box_states` | box_id, state, timestamp, location_type | fleet report, next-state predictor |
| `powerbank_cycles` | powerbank_id, cycle, timestamp, voltage_v, temp_c, capacity_pct | battery health oracle |
| `station_events` | ts, station_id, event, eject_ms, firmware | self-diagnosing stations, anomalies, proactive care |
| `tickets` | ticket_id, created, channel, station_id, category, text, sentiment, resolved_hours | draft answers, clustering, mood detector |
| `it_tickets` | ticket_id, created, category, text, priority | IT ticket triage |
| `transactions`, `invoices` | tx_id, date, amount_chf, counterparty, reference · invoice_id, date, supplier, amount_chf, account | receipt matching |
| `daily_revenue` | date, type, amount_chf | cash-flow forecast |
| `orders` | order_id, merchant_id, created, item, qty, ship_country, status | packing lists, tracking mails |
| `repairs` | repair_id, date, station_id, part, minutes | spare-parts forecast |
| `jobs` | job_id, station_id, city, lat, lon, type, window_from, window_to, minutes | route planner |
| `ad_playouts` | ts, station_id, venue_type, advertiser, campaign, impressions, interactions | advertiser report, ad pricing, matchmaker |

The data is invented. Numbers will not match reality. Say so in the demo. Box states follow Chimpy’s real lifecycle: factory → leaving factory → field ↔ POS → missed.

## 9. Small AI models, local LLM and synthetic training data

Everything runs on the server's CPUs, needs no API key and no internet, and uses pre-downloaded models. Run it on the server (`ssh <team>@heychimpy.fun`). Help: `chimpy-ai --help`.

**Train a model** (each one writes `model.joblib`, `meta.json` and `report.html` with the accuracy):

| Command | What it builds | Typical time |
| --- | --- | --- |
| `chimpy-ai train-tabular --csv rentals.csv --target outcome --out m/fraud` | Gradient boosting on any table, with the top signals. Dates become hour, weekday and month. | seconds |
| `chimpy-ai train-text --csv tickets.csv --text text --target category --out m/triage [--embed]` | Text classifier: TF-IDF, or MiniLM embeddings with `--embed` | seconds |
| `chimpy-ai train-image --data photos/ --out m/install-check` | Image classifier from `photos/<label>/*.jpg` (CLIP embeddings) | ~1 s per image |
| `chimpy-ai train-sequence --csv box_states.csv --id box_id --state state --time timestamp --out m/next-state` | Next-state (Markov) model, plus a risk list for `--watch missed` | seconds |

**Use it:**
- `chimpy-ai predict --model m/triage --csv new.csv --out predictions.csv`, or `--text "…"`, or `--image a.jpg`
- `chimpy-ai serve --model m/triage --port 81xx` starts a JSON API at `POST /predict`. Publish it with `sudo new-site --team <team> --name <name> --port 81xx --cmd "chimpy-ai serve --model /srv/teams/<team>/<name>/m/triage"`.

**No training needed:**
- `chimpy-ai zero-shot --image photo.jpg --labels "station visible,station hidden"`: classify photos by describing the labels
- `chimpy-ai forecast --csv daily_revenue.csv --date date --value amount_chf --group type --days 90 --out fc.csv`: forecast with `lo`/`hi` band columns, ready for `lineChart`
- `chimpy-ai anomaly --csv station_events.csv --id station_id --out scores.csv`: the most unusual IDs, with the reason

**Local LLM** (Ollama, `qwen3:1.7b` fast, `qwen3:4b` better, `nomic-embed-text` for embeddings; about 2–5 s per short answer):
- `chimpy-ai llm "Summarise this ticket: …"`
- `chimpy-ai llm-batch --csv tickets.csv --text text --prompt "Category? One of: refund, late fee, app" --out labelled.csv`
- From your app on the server: `POST http://127.0.0.1:11434/api/generate` with `{"model":"qwen3:1.7b","prompt":"…","stream":false}`, or the `/api/llm` endpoint of the starter's `server.py`. Browsers can’t reach port 11434 directly; always go through your app.

**Synthetic training data:**
- **Tables:** `fake-data.py`, or the ready-made CSVs and `chimpy.db` (section 8)
- **Texts:** `chimpy-ai gen-text --prompt "a short angry customer ticket about a failed eject" --n 30 --out tickets.jsonl`
- **Images:** `chimpy-ai gen-images --prompt "photo of a powerbank station on a bar counter" --n 8 --out photos/good`
  - `--model sd-turbo` (default): about 12 s per 512 px image. SD-Turbo is under Stability AI’s licence: fine for this internal prototype, but check before any commercial use.
  - `--model klein`: FLUX.2 [klein] 4B by Black Forest Labs, Apache 2.0. It is installed but **not practical here**: one image took more than 25 minutes on this CPU-only server. For better images use the OpenAI gateway (`gpt-image-1.5`, section 10).
  - One **shared queue** for all teams: start early, keep `--n` small (8–20 per label), and vary the prompt (light, angle, place) so the model learns the object, not the background.
- Every generated file is logged in `prompts.jsonl`. Say in the demo that the training images are synthetic.

## 10. Voice, images, mascots and 3D (ElevenLabs and OpenAI gateways)

### OpenAI (images and chat) without a key

`https://heychimpy.fun/api/openai/v1/…` forwards to the OpenAI API with the workshop key. Send no key. Allowed endpoints:
- images: `/v1/images/generations`, `/v1/images/edits`
- chat and responses: `/v1/chat/completions`, `/v1/responses`
- audio, embeddings, models and moderations

Image calls are limited to 30 per hour per network. Good models: `gpt-5.1` (chat) and `gpt-image-1.5` (images, transparent PNG). Browsers may call it directly (CORS is open). The key is only valid during the workshop.

### Mascot with animated key moments

```bash
chimpy-mascot create --project "Box Radar" --idea "predicts which battery boxes go missing" --out mascot
chimpy-mascot moment --out mascot --name payday --action "throws coins in the air"     # add your own moment
```

This takes about 30 s per moment. The result in `mascot/`:
- `base.png`, transparent
- `hello.gif`, `thinking.gif`, `celebrate.gif`, `oops.gif`, `idle.gif`, looping and transparent, 320 px
- the sprite sheets and `mascot.html`, a demo page

Show the GIFs in your UI at the matching moment (e.g. `<img src="mascot/celebrate.gif" width="96">` after a successful action). The mascots are original characters in Chimpy colours; never copy an existing brand’s mascot.

### 3D souvenir for printing

```bash
chimpy-3d keychain --text "BOX RADAR" --image mascot/base.png --out souvenir    # tag with ring hole + mascot relief
chimpy-3d figure --prompt "small desk stand that holds a powerbank, text BOX RADAR on the front" --out souvenir --name stand
chimpy-3d check souvenir/keychain.stl                                            # size, watertight, grams of PLA
```

You get `.stl` (to print), `.scad` (editable OpenSCAD) and `.png` (preview). Measured here: the key-ring tag takes 18 s (88 × 34 × 5 mm, about 5 g PLA); the GPT-designed figure takes about 40 s. Keep parts under 80 mm with a flat bottom. Put a link to the `.stl` on your page and in README.md for Ursin.

### Voice and audio (ElevenLabs)

The workshop shares one ElevenLabs account through a gateway. **You never see or need a key.** Every ElevenLabs endpoint under `/v1` and `/v2` is available at `https://heychimpy.fun/api/elevenlabs/v1/…` (the same paths and parameters as the [ElevenLabs API](https://elevenlabs.io/docs/api-reference), with no `xi-api-key` header). Browsers may call it directly (CORS is open). Limits: 60 requests per minute per network. Deleting things and account settings are blocked. The account is only valid for the workshop day.

```bash
curl -fsSO https://heychimpy.fun/tools/chimpy-voice          # laptop; on the server it is preinstalled
python3 chimpy-voice tts "Empty battery? Rent a Chimpy!" -o hello.mp3        # text to speech
python3 chimpy-voice stt hello.mp3 --language en                             # speech to text (Scribe)
python3 chimpy-voice sfx "a powerbank clicking into a station" --seconds 2 -o click.mp3
python3 chimpy-voice music "upbeat 15 second jingle for a green powerbank brand" --seconds 15 -o jingle.mp3
python3 chimpy-voice voices          # pick a voice_id, then: tts "…" --voice <voice_id>
python3 chimpy-voice models          # e.g. eleven_multilingual_v2 (default), eleven_v3, eleven_v4
python3 chimpy-voice dialogue lines.json -o talk.mp3     # [{"text": "...", "voice_id": "..."}, ...]
python3 chimpy-voice sts in.mp3 -o out.mp3 --voice <id>  # change the voice of a recording
python3 chimpy-voice isolate noisy.mp3 -o clean.mp3      # remove background noise
```

From a web page:

```js
const r = await fetch("https://heychimpy.fun/api/elevenlabs/v1/text-to-speech/JBFqnCBsd6RMkjVDRZzb", {
  method: "POST", headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ text: "Your powerbank is ready.", model_id: "eleven_multilingual_v2" }) });
new Audio(URL.createObjectURL(await r.blob())).play();
```

Credits are shared by all teams, so generate short clips while you build. Never send real customer recordings or personal data.

## 11. Database (SQLite)

Use SQLite as the database for every prototype that needs one. It is a single file, needs no server and no setup, and is easy to copy and to throw away.

- **Synthetic data, ready as a database:**
  - `chimpy.db` contains all datasets from section 8, one table each.
  - On the server, every team has its own writable copy: `/srv/teams/<team>/data/chimpy.db`.
  - Laptop: `new-project.sh` downloads it to `data/chimpy.db`, or `curl -fsSO https://heychimpy.fun/public/data/chimpy.db`.
- **Use it:**
  - Shell: `sqlite3 data/chimpy.db "select city, count(*) from stations group by city"`
  - Python: `import sqlite3`, standard library
  - Node: `node:sqlite` (built in, Node 22.5+) or `better-sqlite3`
- **Install on the laptop if `sqlite3` is missing:** macOS has it built in; Windows: `winget install SQLite.SQLite`; Linux: `sudo apt install sqlite3`. Python’s `sqlite3` module always works.
- **Your own tables:** load CSVs with `python3 tools/csv-to-sqlite.py data/*.csv --db data/app.db`. Keep one database file per prototype in `data/`. `.gitignore` already excludes `data/*.db`, so synthetic data never ends up in git.
- **Rule:** one team, one database file per prototype. Never point two teams at the same file, and never store personal data in it.

## 12. Chimpy design kit

Add one line to every page:

```html
<link rel="stylesheet" href="https://heychimpy.fun/public/ci/chimpy.css">
<link rel="icon" href="https://heychimpy.fun/public/ci/chimpy-logo-256.png">
```

- **Logo:** `https://heychimpy.fun/public/ci/chimpy-logo.png` (500 px) and `chimpy-logo-256.png`: the round green badge with the chimp face and “CHIMPY”. Use it as is: no recolouring, stretching or cropping. Put it top left at 40–48 px in the header.
- **The ape (chimp head from the logo):** `chimpy-ape.png` (512 px), `chimpy-ape-128.png`, `chimpy-ape-outline.png` (for dark backgrounds), all transparent PNG in `https://heychimpy.fun/public/ci/`. Use it as a game piece, icon, marker, avatar or decoration in every prototype (see “Make it delightful”).
- **Colours:**
  - Chimpy green `#76B82C` for accents, buttons and highlights. Never use it as text on light backgrounds.
  - Chimpy purple `#753E8F` for labels on light backgrounds. Never use it as text on dark ones.
  - Ink `#2A1433` for dark backgrounds and text; Paper `#F5F2EA` for light backgrounds.
  - Light purple `#C9A3DB` for labels on dark backgrounds; dark green `#3D6E12` for green text on light backgrounds.
- **Fonts:** titles are slanted capitals in *Chimpy Display* (Bebas Neue); text is *Rubik*. Both load through `chimpy.css`. Don’t add other fonts. Files in `https://heychimpy.fun/public/ci/fonts/`:
  - `Rubik-Regular.ttf`, `Rubik-Italic.ttf`, `Rubik-Medium.ttf`, `Rubik-Bold.ttf`, with the licence in `OFL-Rubik.txt`
  - `BebasNeue-Regular.ttf`, with the licence in `OFL-BebasNeue.txt`
  - Both are under the SIL Open Font License 1.1.
- **Components:** `.chimpy-header`, `.chimpy-page`, `.chimpy-label` (small label above a title), `.chimpy-card`, `.chimpy-grid`, `.chimpy-stat` (big number with `<small>` caption), `.chimpy-btn` (green pill button), `.chimpy-btn--secondary`, `.chimpy-tag` (`--ok`, `--warn`, `--bad`), `.chimpy-table`, `.chimpy-input`. Put `class="chimpy-dark"` on `<body>` for a dark page.
- **Charts:** `import { barChart, lineChart, loadCsv, countBy } from "https://heychimpy.fun/public/ci/chimpy-chart.js"`. The charts take the colours from the stylesheet.
- **Voice:** short, friendly, direct, a bit cheeky (“Empty battery? Rent a Chimpy!”). English for the demo. Customer-facing drafts in the customer’s language.
- **Kit overview:** https://heychimpy.fun/public/ci/

## 13. Chimpy facts

Source: heychimpy.com (About us, Sustainability, Impressum), read on 4 November 2026. Use these facts as written and don’t invent more. Mark anything else as `[__]`.

- **What:** Chimpy is “the green powerbank for rent”. People rent a powerbank at a station, charge on the go and return it at any station. The powerbanks are reusable and solar-charged. Chimpy calls itself Europe’s largest powerbank rental service.
- **Where:** more than 4,000 locations (POS) in Switzerland and Germany, as well as Vienna, Luxembourg and other European cities. Customers find them in convenience stores, kiosks, bars, cafés and at festivals. Chimpy launched at migrolino in July 2026, its third major convenience-retail partnership in Switzerland.
- **Scale (per the website):**
  - more than 10 million rentals since the start
  - up to 100,000 customers every month
  - more than €10 million revenue per year
  - 53% of customers say they rent more than once a week
- **Story:** it started in a cramped two-room apartment. The founders turned a bedroom into a production space and convinced companies like Google to order solar-charged AA batteries. The About page says “since 2013”. The Sustainability page tells how, around 2015, Chimpy and its partner Valora introduced the first fully integrated powerbank rental service at a big convenience-retail chain.
- **Why it works:** it is circular. A rental brings the customer back to the store to return it. For convenience retail, Chimpy brings 17–21-year-olds back day after day, and it gives shops a year-round extra revenue stream.
- **Sustainability pillars:** Reuse, Renewables, Reduce.
- **Community:** the Chimpy Street Cred Fund supports independent events in Zurich with pro DJ gear and free powerbank rentals.
- **Company:** Chimpy AG, Zurich (Switzerland), and Chimpy Deutschland GmbH, Hamburg.
- **Management (per the About page):**
  - Edwin Winkler, CEO
  - Anka Waem, COO
  - Flavio Hartmann, CFO
  - Andreas Brändle, Co-Founder & Chairman of the Board
  - Mirko Hofmann, Co-founder and Sustainability Officer
- **Team leads and roles (per the About page):**
  - Daniel Ilar, Head of Business Development
  - Ursin Valaulta, Head of Supply Chain
  - Jari Brontesi, Head of Marketing
  - Henning Vogt, Head of Software
  - Diego Fernandez, Data Engineer
  - Betty Petoia, Festival & Event Manager
  - Prati Basnet, Production Co-Teamlead
  - Samanta Novotny, Finance & HR Manager
  - Marie Moldenhauer, Operations & Network Manager
  - and more at heychimpy.com/about-us
- **Tech:** station software is built with AI coding agents, and a task only counts as done when it compiles and passes its tests. Station screens show ads (Advertising’s product). Merchants and their staff eject powerbanks at the stations. Battery boxes move through the states factory → leaving factory → field → POS → missed, and that data lives in Metabase.

Don’t invent internal figures (stations per city, revenue per station, real customer counts). Use the synthetic data and say it is synthetic.

## 14. When something breaks

| Symptom | Fix |
| --- | --- |
| Your sandbox can’t reach heychimpy.fun, or you have no terminal | Use route B (MCP connector) or route C (upload at https://heychimpy.fun/deploy), see section 3. Don’t stop. |
| MCP or upload says `wrong team or password` | Check the team id (section 3) and the password from the last workshop slide. After 10 failures your network is locked for 15 minutes. |
| `cannot log in … without a password` | The human runs `bash tools/deploy.sh --setup-key --team <team>` in their own terminal. |
| `has used all 5 subdomains` | Redeploy under an existing name, or ask Matthias. |
| HTTP 502 on your subdomain | The app isn’t listening on `127.0.0.1:$PORT`. Run `ssh <team>@heychimpy.fun site-logs --team <team> --name <name>`. |
| Certificate warning on the first visit | Wait 30–60 seconds and reload; the certificate is being issued. |
| Fonts or CSS missing | Check that the link is exactly `https://heychimpy.fun/public/ci/chimpy.css`. |
| `possible personal data found` | Replace it with IDs or synthetic data. Only skip the check after a human has looked (`--skip-pii-check`). |
| Something on the server is broken for everyone | Stop and tell Matthias or Andreas. Don’t try to repair other teams’ things. |

## 15. Done means

- [ ] Live at `https://<team>-<name>.heychimpy.fun`, works on a phone
- [ ] Uses the Chimpy design kit (logo, colours, fonts)
- [ ] Tests pass locally; the last change is committed
- [ ] README.md has the 3-sentence pitch and the “keep it?” card
- [ ] TASKS.md is current
- [ ] The team can demo it in 2 minutes without slides
- [ ] Nice to have: mascot GIFs at key moments, an `.stl` souvenir for Ursin
