# Mello agent guide

You are a coding agent helping someone build, test and ship a project on **Mello** (https://www.itsmello.cloud).
Read this whole file before you change anything. It tells you what Mello can run, how to structure the code,
how to test it locally and how the person publishes it. Copy it into the repository as `AGENTS.md`
(or `CLAUDE.md`, `.cursor/rules/mello.md`) so future sessions keep the same rules.

---

## 1. What Mello is

Mello hosts small backends and websites. Each **API** is one JavaScript/TypeScript ES module with a `fetch`
handler. Mello gives every API:

| Feature | How your code uses it |
| --- | --- |
| HTTPS endpoint | `https://api.itsmello.cloud/api/<route-id>/<path>` |
| API keys | Callers send `x-api-key: mello_…`. Mello checks and **removes** it before your code runs. |
| Variables & secrets | `env.NAME` (set in Dashboard → Environment) |
| SQL database (SQLite) | `env.DB` (turn on in Dashboard → Database) |
| JSON key-value storage | HTTP calls to `https://www.itsmello.cloud/api/storage` |
| Cron jobs (Plus) | `scheduled(event, env, ctx)` handler |
| Realtime rooms | WebSockets at `/_rooms/<room>` (handled by Mello, not your code) |
| Static websites (Plus) | Upload a built folder with `index.html` |

Mello runs your module on a fast edge runtime that speaks **Web standards** (Fetch API, `Request`, `Response`,
`URL`, `crypto.subtle`, `TextEncoder`, streams). It is **not Node.js**.

---

## 2. Hard rules (check these before you finish)

1. **One default export with `fetch`.** `export default { async fetch(request, env, ctx) { … } }` or a Hono app (`export default app`).
2. **No Node built-ins.** No `fs`, `path`, `child_process`, `net`, `http`, `process.env`. Read config from `env`.
3. **Size:** a single module up to **10 MB** after bundling. Project folders: up to 3.5 MB of source, 300 files.
4. **Paths:** Mello strips `/api/<route-id>` before your code runs. A handler for `/hello` sees `url.pathname === '/hello'`.
5. **Never put secrets in code, tests, fixtures, logs or commits.** Use `env.NAME`. Never print a key.
6. **API keys never go in browser, mobile or game-client code.** Call Mello from a server, or use a key limited to one API, method and path for public widgets.
7. **Return JSON errors** with correct status codes (`400` bad input, `401/403` auth, `404` unknown route, `405` wrong method, `413` too large, `500` unexpected).
8. **Validate input:** check methods, content type, required fields, types and sizes. Cap request bodies you read.
9. **Do not deploy or touch production data** unless the person explicitly asks. Prepare the build and tell them how to publish.

---

## 3. Project shapes Mello accepts

### a) A single file (simplest)

```js
// index.js
export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    if (request.method === 'GET' && url.pathname === '/hello') {
      return Response.json({ message: 'Hello from Mello!' });
    }
    return Response.json({ error: 'Not found' }, { status: 404 });
  },
};
```

TypeScript (`.ts`) is fine: Mello strips types but does **not** type-check. Run `tsc --noEmit` yourself.

### b) A project folder (npm packages, many files)

```
my-api/
  package.json        ← "main": "src/index.ts"  (or Mello finds src/index.ts)
  src/index.ts
  src/routes/*.ts
```

Mello bundles the folder on its servers. Packages in `dependencies` are fetched from npm; pin versions for
repeatable builds. `node_modules`, `.git`, `dist` and build folders are skipped.

Recommended router: **Hono** (small and runs perfectly on Mello).

```ts
import { Hono } from 'hono';

type Env = { DB: D1Database; OPENAI_KEY: string };
const app = new Hono<{ Bindings: Env }>();

app.get('/health', c => c.json({ ok: true }));
app.post('/notes', async c => {
  const body = await c.req.json().catch(() => null);
  if (!body || typeof body.text !== 'string' || body.text.length > 2000) return c.json({ error: 'text is required (max 2000 chars)' }, 400);
  const { meta } = await c.env.DB.prepare('INSERT INTO notes (text, created_at) VALUES (?, ?)').bind(body.text, Date.now()).run();
  return c.json({ id: meta.last_row_id }, 201);
});
app.notFound(c => c.json({ error: 'Not found' }, 404));
app.onError((err, c) => { console.error(err); return c.json({ error: 'Something went wrong' }, 500); });

export default app;
```

---

## 4. Data

### SQL database (`env.DB`)

The person turns it on in **Dashboard → Database**. Create tables from the dashboard SQL console (or a
`migrations/*.sql` file you write for them to paste). Always use bound parameters, never string concatenation.

```js
const { results } = await env.DB.prepare('SELECT id, text FROM notes WHERE user_id = ? ORDER BY id DESC LIMIT 50').bind(userId).all();
const one = await env.DB.prepare('SELECT * FROM notes WHERE id = ?').bind(id).first();
await env.DB.batch([stmtA, stmtB]); // atomic
```

Free: 50 MB. Plus: 1 GB.

### Key-value storage

For small JSON values (settings, caches, counters). Needs an API key saved as the secret `STORAGE_API_KEY`.

```js
const res = await fetch('https://www.itsmello.cloud/api/storage', {
  method: 'POST',
  headers: { 'content-type': 'application/json', 'x-api-key': env.STORAGE_API_KEY },
  body: JSON.stringify({ projectId: 'YOUR_ROUTE_ID', action: 'put', key: 'settings', value: { theme: 'dark' } }),
});
```

Actions: `get` (returns `found` and `value`), `put`, `delete`. Keys: letters, digits, `.`, `_`, `-`, up to 100 chars.
Free: 1,000 keys, 64 KB per value. Plus: 10,000 keys, 256 KB per value.

---

## 5. Scheduled jobs (Mello Plus)

Add a `scheduled` handler, then the person adds the schedule (5-field cron, UTC) in **Dashboard → Cron jobs**.

```js
export default {
  async fetch(request, env) { /* … */ },
  async scheduled(event, env, ctx) {
    await env.DB.prepare('DELETE FROM sessions WHERE expires_at < ?').bind(Date.now()).run();
  },
};
```

---

## 6. Realtime rooms

Mello runs the WebSocket server; you do not write one. Clients connect to:

```
wss://api.itsmello.cloud/api/<route-id>/_rooms/<room>?name=<display-name>
```

From a browser, pass the key as a subprotocol: `new WebSocket(url, ['mello-key.' + KEY])`. Use a key limited to
this API, and add the website origin under **Network → allowed origins**.

Events (JSON): `welcome` (`you`, `members`), `join`, `leave`, `message` (`from`, `data`). Clients send text or
JSON up to 16 KB; it goes to everyone else in the room. Your server can broadcast with
`POST https://api.itsmello.cloud/api/<route-id>/_rooms/<room>` (with `x-api-key` and a JSON body).
Up to 200 connections per API.

---

## 7. Calling the API

```bash
curl https://api.itsmello.cloud/api/<route-id>/hello -H "x-api-key: $MELLO_API_KEY"
```

With a custom domain (Plus), there is no `/api/<route-id>` prefix: `https://api.example.com/hello`.

The gateway also enforces CORS (allowed origins and methods), optional IP allowlists and a per-API rate limit
(30, 60 or 120 requests per minute), all set in **Dashboard → Network**.

---

## 8. Test locally with `mello dev`

Download the CLI (Node.js 22+): `curl -O https://www.itsmello.cloud/mello.mjs`

```bash
node mello.mjs dev ./index.js        # or a project folder
```

It serves on `http://localhost:8787`, loads variables from `.dev.vars` or `.env`, enforces Mello's 120 req/min
and 3 MB request bodies, and reloads on save. Put local-only secrets in `.dev.vars` and add it to `.gitignore`.

Always add a smoke test the person can run, for example `node --test` or a small script that calls
`/health` on the dev server.

---

## 9. Publishing (only when the person asks)

- **Dashboard:** Deploy → drop the file, or "Bundle a project folder". Review in the editor, then **Deploy API**.
- **CLI:** `node mello.mjs deploy <api-name> ./index.js` or `node mello.mjs deploy <api-name> ./my-project`.
  The CLI asks for the Mello email and password each time and never stores them. For CI it can read a
  short-lived token from `MELLO_ID_TOKEN`.
- The previous version stays live until the new one is ready; any earlier version can be restored from
  **Deployments**.

After publishing, test with the **Playground** in the dashboard before sharing the endpoint.

---

## 10. When you finish, report

1. What you built: routes with method, path, input and output.
2. How you tested it: commands and results.
3. The file or folder to publish, and its size.
4. Variables and secrets the person must add (names only), and any SQL to run.
5. Exactly how to publish and how to call it.

If something can't be done on Mello (long-running processes, raw TCP, native modules, files on disk), say so
and suggest the closest Mello-friendly approach instead of guessing.

Help: support@itsmello.cloud · Docs: https://www.itsmello.cloud/docs · Status: https://www.itsmello.cloud/status
