Skip to main content
Glama
README.md
# arena-mcp

A [Model Context Protocol](https://modelcontextprotocol.io) server for [Are.na](https://www.are.na) — create channels, browse, search, and add products to your boards **with guaranteed real product images**. Plus a weekly **Style Radar** that scans underground menswear trends and stages fresh finds.

Are.na is a quieter, human-curated alternative to Pinterest: channels are boards, blocks are the things you pin.

## Tools

| Tool | What it does |
| --- | --- |
| `arena_me` | The authenticated user's profile. |
| `arena_list_my_channels` | List channels you own. |
| `arena_get_channel` | Fetch a channel by slug + a page of its blocks. |
| `arena_create_channel` | Create a channel (`public`/`closed`/`private`). |
| `arena_add_block` | Add a raw block from a URL or Markdown (no image validation). |
| **`arena_remove_block`** | **Remove a block from a board** by deleting its connection (block ids come from `arena_get_channel`). Detaches it from the board without destroying the block. |
| **`arena_add_product`** | **Add a product with a GUARANTEED real image.** Resolves the image (og:image + Are.na fetcher fallback), rejects dead/redirecting links, screenshot renders, blanks, and error pages; sets the product-name title. Refuses rather than add a broken block. |
| **`arena_add_products`** | Batch version — per-item report, skips (never adds) anything without a real image. |
| `arena_search` | Full-text search (requires Are.na Premium). |
| **`style_log`** | **Append a style learning** (preference shift, dislike, new direction) to the Style Journal channel. Append-only capture from any surface. |
| **`style_directives`** | **Read the living style directives** -- the mutable layer (current-season focus + recent preference shifts) that a styling skill loads on top of its durable rules. |
| **`style_set_directives`** | **Replace the directives doc** (full Markdown body). The fast loop for keeping styling current without republishing a skill. |

`arena_add_product` accepts `fallback_urls` — if the primary link is dead it tries the fallbacks (a GOAT `goat.com`, Amazon `/dp/`, or garmentory product URL image-resolves reliably).

## The image pipeline (`src/pipeline.ts`)

The hard-won bit. For any candidate URL it: skips listing/search pages; scrapes `og:image` with a browser UA; **detects dead links** (a product URL that redirects off its `/products/` path to a catalog is dead); falls back to Are.na's own fetcher; and **pixel-validates** with `sharp` — rejecting `2560×2560` screenshot renders, blanks (`std<20`), error pages (`mean>248`), and tiny images. Only a real product photo gets added. Reliable image hosts: Carhartt WIP, Uniqlo, Nike (valid product URLs), Amazon `/dp/`, **GOAT**, garmentory product pages, watch retailers.

## Run

Requires Node 18+. `npm install && npm run build`.

**Local (stdio, for Claude Code / Desktop):**
```json
{ "mcpServers": { "arena": { "command": "node", "args": ["/abs/path/arena-mcp/dist/index.js"],
  "env": { "ARENA_ACCESS_TOKEN": "…" } } } }
```

**Remote (streamable HTTP, hosted on Fly):** set `MCP_HTTP=1` and it serves `POST /mcp` on `$PORT` behind a bearer token (`MCP_AUTH_TOKEN`). Deployed at `https://arena-mcp.fly.dev/mcp`. Connect from Claude Desktop / claude.ai as a custom connector with `Authorization: Bearer <MCP_AUTH_TOKEN>`.

Get a personal access token at [dev.are.na](https://dev.are.na) → `ARENA_ACCESS_TOKEN` (write scope to create channels/blocks).

## Style Radar (`src/radar.ts`)

A weekly trend scanner (runs as a scheduled Fly machine, `node dist/radar.js`). It scrapes underground/enthusiast RSS (r/streetwear, r/rawdenim, r/goodyearwelt, r/malefashionadvice, Hypebeast, Highsnobiety, Die Workwear, Permanent Style, Put This On), then uses the Anthropic API **with web search** to find fresh, on-aesthetic pieces *and their real product URLs*, runs them through the image pipeline, and posts survivors to a **Radar** Are.na channel (a staging board you review). Env: `ANTHROPIC_API_KEY`, `RADAR_CHANNEL_SLUG`, `ARENA_ACCESS_TOKEN`.

## Style evolution (keeping a styling skill from going stale)

A static styling skill locks in whatever taste it was written with. Three tools + two Are.na channels give it a feedback loop:

- **`style_log`** captures raw learnings ("done with cropped hems") into a **Style Journal** channel, append-only, from any surface (Desktop, mobile, claude.ai).
- **`style_directives`** / **`style_set_directives`** read and write a **Style Directives** channel -- a single living Markdown doc holding current-season focus + recent shifts. A skill loads it at the start of a task so recommendations reflect the latest direction without republishing the skill (the *fast loop*).
- A periodic human-gated review (the companion `style-review` skill) reads the journal, promotes durable learnings into the skill proper, folds temporary ones into the directives, and discards noise (the *slow loop*). Uses a `Last reviewed: <date>` watermark in the directives to avoid re-processing (Are.na blocks can't be individually deleted).

Channel slugs are configured via `STYLE_JOURNAL_SLUG` / `STYLE_DIRECTIVES_SLUG` (default `style-journal` / `style-directives`).

## Deploy notes (v3 API)

Built against Are.na **v3** (`https://api.are.na/v3`; v2 writes are wound down). Blocks: `POST /v3/blocks {value, channel_ids}`; image URL under `image.src`; `visibility` not `status`. A block *entity* can't be deleted (`DELETE /v3/blocks/:id` -> 405), but a block can be **removed from a board** by deleting its connection (`DELETE /v3/connections/:connection_id`, where the id is on each contents item's `connection` object) -- this is what `arena_remove_block` does, so no full rebuild is needed just to drop a few pieces. Search is Premium-gated.

## License

MIT

TDQS

B3.4/5.0

Scored across 13 tools

Disambiguation4/5

Most tools target distinct resources and actions: account, channels, blocks, products, search, and style directives. The only potential overlap is between arena_add_block and arena_add_product, but the descriptions clearly distinguish general block creation from product-specific image handling.

Naming Consistency3/5

The arena_ prefix is consistent for the primary domain, but style_ tools use a different prefix, and arena_me does not follow the verb_noun pattern. Overall the convention is understandable but not uniform.

Tool Count4/5

13 tools is within a reasonable range for the server's scope covering channel management, block/product operations, search, and a style journal. The count feels slightly high due to the style sub-domain, but each tool has a clear purpose.

Completeness3/5

Core channel CRUD is present except delete, and blocks support add/remove but not update. Product handling is thorough with single and batch add, though removal relies on the generic remove_block. Style tools form a complete workflow. Minor lifecycle gaps prevent a higher score.

Maintenance

ActivitySlowing
ResponsivenessNo issues