@zegazone_mcp/mcp
v2.0.15
Published
MCP server wrapper for Zegazone thirdparty-v1 API
Readme
@zegazone_mcp/mcp
MCP server for Zegazone — collections, media, sharing, collaborators, and player UI control. Wraps POST /functions/v1/thirdparty-v1 with 64 typed tools (Zod input schemas on every operation).
New to MCP? An MCP server is a small program your AI client (Claude, Cursor, OpenClaw) talks to over stdio. You pair once with your Zegazone account; the AI then calls tools like collections_list or media_search on your behalf.
Docs: https://www.zegazone.com/api-docs
Quick start (3 steps)
Step 1 — Pair your account (one time)
npx @zegazone_mcp/mcp@latest --pairOpens a browser for OAuth. Credentials are saved to ~/.zegazone-mcp/credentials.json and refresh automatically.
Step 2 — Add to your AI client
Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"zegazone": {
"command": "npx",
"args": ["@zegazone_mcp/mcp@latest"]
}
}
}Cursor (.cursor/mcp.json or Settings → MCP):
{
"mcpServers": {
"zegazone": {
"command": "npx",
"args": ["@zegazone_mcp/mcp@latest"]
}
}
}Restart the client after saving.
Step 3 — Test it works
Ask your AI:
Use Zegazone MCP to ping and tell me who I'm logged in as.
Or run:
npx @zegazone_mcp/mcp@latest --list-toolsOpenClaw
OpenClaw uses MCP over stdio like other clients, but you configure it in OpenClaw settings (not Claude's JSON file).
Pair (terminal on the machine running OpenClaw):
npx @zegazone_mcp/mcp@latest --pairComplete the browser OAuth flow.
Add MCP server in OpenClaw — either settings UI or config:
- Command:
npx - Args:
["@zegazone_mcp/mcp@latest"]
Or via CLI:
openclaw config set mcpServers.zegazone.command "npx" openclaw config set mcpServers.zegazone.args '["@zegazone_mcp/mcp@latest"]'- Command:
Reload OpenClaw (restart the gateway or refresh MCP servers).
Test with natural language:
- "Run zegazone ping"
- "List my zegazone collections"
- "Use media_search to find items tagged holiday"
Use @zegazone_mcp/mcp@latest so you get typed parameters on all 64 tools.
Common patterns
Bulk collection enrichment
To enrich all images in a collection with AI-generated tags and descriptions:
media_listwithcollection_idto get all items- Filter for items with
viewer: "image"that lack descriptions or tags - For each:
media_download_urlto get a fetchable URL, analyse with your vision model, thenmedia_updatewith tags and description - After all items:
collections_updatewith collection-level tags and description
For 50+ items expect ~2-3 minutes at one call per second. Skip items that already have both description and tags.
Note for Claude Code users: fetch image URLs from an artifact (browser context), not from bash. The bash sandbox cannot reach api.zegaphone.com.
Uploading files
Agents with local file bytes (generated images, attachments, etc.) use a 3-step presigned upload flow. Playback URLs still use token-based r2-proxy; this path is upload-only.
- Get URL —
media_get_upload_urlorcollections_get_upload_url(REST:media.get_upload_url/collections.get_upload_url). Returnsupload_url,r2_key, andexpires_at(15 minutes). - PUT bytes —
curl -X PUT -H "Content-Type: image/jpeg" --data-binary @photo.jpg "<upload_url>"(no Bearer token on the PUT). - Register — Pass
r2_keyassource_urlinmedia_create, or asthumbnail_urlinmedia_create/media_update/collections_update.
# Step 1 — presigned upload URL (REST)
curl -sS -X POST 'https://api.zegaphone.com/functions/v1/thirdparty-v1' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"op":"media.get_upload_url","collection_id":123,"filename":"photo.jpg","content_type":"image/jpeg"}'
# Step 2 — upload (use upload_url from response)
curl -X PUT -H 'Content-Type: image/jpeg' --data-binary @photo.jpg 'PASTE_upload_url_HERE'
# Step 3 — create media row
curl -sS -X POST 'https://api.zegaphone.com/functions/v1/thirdparty-v1' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"op":"media.create","collection_id":123,"source_url":"r2://YOUR_USER_ID/123/..._photo.jpg","viewer":"image","name":"My Photo"}'Collection covers: use collections.get_upload_url, PUT the image, then collections.update with thumbnail_url set to the returned r2_key.
Working with different AI agents
Zegazone prompt templates (copy-paste from the app UI) include self-assessment steps so the same prompt works across Claude, Cursor, OpenClaw, GPT-4o, Gemini, and other MCP clients.
Image generation (collection covers)
| Agent | Real PNG/JPEG | Fallback |
|-------|---------------|----------|
| OpenClaw, GPT-4o, Gemini | ✅ Native or built-in tools | — |
| Claude Desktop, Claude.ai | ❌ | SVG via artifact, uploaded as image/svg+xml |
Template 6 ("Set collection cover") asks the agent to assess its own capability first. Agents that can generate raster images upload JPEG via collections.get_upload_url + PUT + collections.update. Agents limited to SVG (typical Claude) upload an SVG placeholder with the same flow but content_type="image/svg+xml" and should note in the response that a real image requires an agent with image generation.
Image analysis (vision enrichment)
| Agent | Vision | Notes |
|-------|--------|-------|
| Claude Desktop / Claude.ai | ✅ | Use media_download_url in an artifact (bash sandbox cannot fetch URLs) |
| OpenClaw, GPT-4o | ✅ | Fetch media.download_url or upload |
| Any agent without vision | — | Falls back to filename, collection name, and metadata |
Bulk enrichment templates (Template 5) include a per-item vision self-assessment. Items with viewer: "image" are analysed visually when possible; otherwise tags and descriptions are inferred from text metadata. The agent reports vision vs text-only counts in its summary.
You do not need to pick a different prompt per agent — paste the template and let the agent choose the correct path.
Text notes (media_text_note_add / media_text_note_update)
Note content uses text as the primary field name on media.text_note.add and media.text_note.update. The API also accepts body as an alias (same value) for backward compatibility with older docs and agents.
How to talk to the MCP server
You do not call tools yourself — ask your AI in plain English. Examples by category:
Finding things
- "Find my collection about boating"
- "Look up media item 1936 and tell me its description"
- "Search my media for anything tagged holiday"
- "Search public collections for photography"
- "What's in collection ID 42?"
- "Resolve the share URL charliefairbairn/boating and list its media"
- "Show collections shared with me"
- "What collection is open in my Zegazone player right now?" (
ui_state_get)
Creating
- "Create a new Zegazone collection called Research 2026 with tags research and 2026"
- "Add this URL to my research collection: https://example.com/video.mp4"
- "Create a text note in my journal collection titled Meeting notes" (API field:
text;bodyis also accepted as an alias) - "Create a sub-collection under my boating collection"
Managing
- "Add the tag travel to my boating collection"
- "Share my photography collection publicly with slug my-photos"
- "Invite tom22 to collaborate on my research collection"
- "Move media 1936 to my archive collection"
- "Reorder items in collection 42 so video X plays first"
- "Archive the collection I no longer need"
- "Get a download link for media item 1936"
Social
- "Like the collection at https://www.zegazone.com/charliefairbairn/boating"
- "Follow the doggy channel on Zegazone"
- "Show collections I follow"
- "Show me the most viewed public collections" (
collections_stats_get/ browse) - "List my liked collections"
UI control
- "Open my boating collection in the Zegazone player"
- "Select media item 1936 in the player"
- "Switch to grid view in the current collection"
Meta / discovery
- "Call operations_list and summarize what I can do"
- "Describe the media.create operation fields"
Troubleshooting
| Problem | Fix |
|--------|-----|
| "Not authenticated" or 401 | Run npx @zegazone_mcp/mcp@latest --pair again. Check ~/.zegazone-mcp/credentials.json exists. |
| Can't find a collection | Use collections_search (public, min 3 chars) or collections_browse instead of listing everything. |
| Can't find media | Use media_search with a keyword; use media_get only when you already have an ID. |
| Tool parameters look empty / wrong | Update MCP config to npx @zegazone_mcp/mcp@latest (or restart the MCP server after npm update). |
| Don't know what tools exist | npx @zegazone_mcp/mcp@latest --list-tools or ask AI to call operations_list. |
| Delete didn't happen | Destructive ops default to dry_run. Say "confirm delete" or pass confirm: true. |
| Wrong API host | Set ZEGA_API_BASE=https://api.zegaphone.com in env. |
CLI reference
npx @zegazone_mcp/mcp@latest # Start MCP server (stdio)
npx @zegazone_mcp/mcp@latest --pair # OAuth pairing
npx @zegazone_mcp/mcp@latest --version # Print version
npx @zegazone_mcp/mcp@latest --help # Usage + tools with descriptions
npx @zegazone_mcp/mcp@latest --list-tools # Tools grouped by categoryWhat this server does
- Maps stable MCP tool names (
media_move,collections_delete, …) to APIopvalues (media.move,collections.delete, …). - Typed Zod schemas on all 64 tools — field names, types, and descriptions (including
media_id/collection_id). - Safety defaults: destructive ops use
dry_rununlessconfirm: true. - Auto
idempotency_keyon mutating calls when omitted. - Generic
thirdparty_callfor forward compatibility.
Lookup tools (use these first)
| MCP tool | When |
|----------|------|
| media_get | You know a media id |
| collections_get | You know a collection id |
| collections_get_by_slug | You have a public URL (handle + slug) |
| media_search | You have a keyword, not an id |
| collections_search | Discover public collections by keyword |
Configuration
| Variable | Default | Purpose |
|----------|---------|---------|
| ZEGA_API_BASE | https://api.zegaphone.com | API origin |
| ZEGA_APP_BASE | https://www.zegazone.com | App / OAuth URLs |
| ZEGA_CREDENTIALS_PATH | ~/.zegazone-mcp/credentials.json | OAuth token file |
| ZEGA_ACCESS_TOKEN | — | Legacy: static JWT instead of pairing |
| ZEGA_DEFAULT_DRY_RUN | true for destructive | Force dry-run |
| ZEGA_TIMEOUT_MS | 30000 | HTTP timeout |
Copy .env.example to .env.local for local dev.
Local development
cd supabase/mcp-zegazone-thirdparty
npm install
npm run build
npm run devnpm run test # error-format + token-provider tests
npm run smoke # live API smoke (needs token)npm
Published as @zegazone_mcp/mcp.
