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.
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues