Skip to main content
Glama
angelcreative

moji-mcp-worker

README.md
# moji-mcp-worker

Remote MCP server for [AudienseMoji](https://audiensemoji.vercel.app). Lets any MCP client
(Claude Desktop, Claude Code, Cursor, etc.) compose a Moji illustration and get back a valid,
ready-to-import `.moji.json` file — without ever guessing an asset id.

Same architecture pattern as the existing Titan MCP (`mcp-remote-worker.titands.workers.dev`):
a stateless Cloudflare Worker exposing Streamable HTTP MCP, no server-side LLM call. The
composing intelligence is the host model (Claude/Cursor); this worker only supplies the real
asset catalog and validates/serializes the result.

## Tools

- **`moji_list_catalog({ category? })`** — with no args, returns category counts + layer shape
  rules + defaults. With `category` (`heads`, `torsos`, `decorations`, `accessories`,
  `expressions`, `brand`, `snaps`, `presets`), returns every real asset id in that bucket.
- **`moji_build({ name?, aspectRatio?, colors?, background?, layers })`** — validates each layer
  against the live catalog and returns:
  - `{ valid: false, errors: [...] }` if something doesn't match the catalog (unknown assetId,
    missing required field for that category, etc.) — fix and retry.
  - `{ valid: true, mojiJson, downloadFilename, importInstructions }` — `mojiJson` is the exact
    `.moji.json` envelope the Moji app already knows how to read (`format: "audiensemoji"`).

## Where the catalog comes from

`env.MOJI_CATALOG_URL` (default `https://audiensemoji.vercel.app/moji-catalog.json`) is a static
JSON file generated straight from `AudienseMoji/src/illustrations/assets.tsx` by
`AudienseMoji/scripts/export-moji-catalog.mjs`. Re-run that script (and redeploy Moji) whenever
assets change — this worker never hand-duplicates ids, so it can't drift.

## Develop

```bash
npm install
npm run dev        # wrangler dev on http://localhost:8788/mcp
npm run typecheck
```

Test locally with the MCP Inspector:

```bash
npx @modelcontextprotocol/inspector@latest
# connect to http://localhost:8788/mcp
```

## Deploy

```bash
npx wrangler login   # one-time
npm run deploy
```

Wrangler prints the live URL, e.g. `https://moji-mcp-worker.<account>.workers.dev/mcp`.

## Connect a client

**Cursor** (`.cursor/mcp.json`, same shape as the `titands` entry):

```json
{
  "mcpServers": {
    "moji": { "url": "https://moji-mcp-worker.<account>.workers.dev/mcp" }
  }
}
```

**Claude Desktop / Claude Code** (via the `mcp-remote` local proxy, since not every client
speaks remote MCP natively yet):

```json
{
  "mcpServers": {
    "moji": {
      "command": "npx",
      "args": ["mcp-remote", "https://moji-mcp-worker.<account>.workers.dev/mcp"]
    }
  }
}
```

## Using it end to end

1. Ask the model: "Use the moji tool to build an illustration of two people doing a hi-5, with a
   speech bubble that says 'Nice work!'."
2. It calls `moji_list_catalog` to find real preset/decoration ids, then `moji_build` with a
   `layers` array.
3. Save the returned `mojiJson` to `<downloadFilename>`.
4. In [audiensemoji.vercel.app](https://audiensemoji.vercel.app) → **My Creations** → **Import
   Moji file** → pick that file. It opens as an editable draft; hit Save to keep it.

## Roadmap (not implemented yet)

- **Phase 2**: `moji_publish_link` stores the built JSON in KV/R2 and returns an
  `https://audiensemoji.vercel.app/import?src=<id>` link that opens the draft directly, skipping
  the manual save/import step. Needs a small route addition in the Moji app.
- **Phase 3**: direct-to-gallery publish via a paired Firebase session (no manual step at all) —
  bigger scope, needs an auth/pairing flow between the MCP client and the user's Moji account.