@three-ws/avatar-mcp
v0.3.0
Published
MCP server for three.ws 3D avatars by three.ws — render a live, rotatable on-chain avatar inline (interactive MCP App), get a paste-anywhere embed iframe, or fetch avatar metadata. Free, no API key.
Maintainers
Readme
A thin, zero-config, read-only Model Context Protocol server that brings three.ws 3D avatars into any MCP client — Claude Desktop, Claude Code, Cursor, or any other host. Render a live, rotatable avatar inline, get a paste-anywhere embed iframe, or fetch avatar metadata. Every tool reads live from the real three.ws endpoints — no mock data. Public and unlisted avatars need no API key. Registry name:
io.github.nirholas/threews-avatar. Built by three.ws.
Need wallets, voice, generation, or pump.fun powers? See the sibling package @three-ws/avatar-agent, a full 3D AI agent in a box.
Install
npm install @three-ws/avatar-mcpRun it directly with npx (no install needed) or install globally for the avatar-mcp CLI:
npx -y @three-ws/avatar-mcp # MCP stdio server
npm install -g @three-ws/avatar-mcp # exposes `avatar-mcp`Setup
Claude Code, one line:
claude mcp add threews-avatar -- npx -y @three-ws/avatar-mcpClaude Desktop / Cursor (JSON config):
{
"mcpServers": {
"threews-avatar": {
"command": "npx",
"args": ["-y", "@three-ws/avatar-mcp"]
}
}
}No environment variables are required. To read avatars from a different host (e.g. a preview deployment), set THREEWS_BASE_URL. Restart your client after editing the config.
Inspect the tool surface in a GUI:
npx -y @modelcontextprotocol/inspector npx -y @three-ws/avatar-mcpQuick start
Once connected, ask your client in plain language:
Render the avatar for @nirholas in the chat, dark background, auto-rotating.
render_avatar returns three things so it looks great in every client:
- a preview image that renders inline everywhere,
- an interactive
text/htmlresource — a real<model-viewer>you can orbit and zoom, for hosts that render HTML resources, and - the embed URL + iframe to drop the live avatar into any page.
Tools
All three tools are free, read-only, and annotated (readOnlyHint, idempotentHint, openWorldHint) so hosts can run them without confirmation prompts. There is no x402 charge. Identify an avatar by id (UUID), handle (nirholas or @nirholas), or a raw model GLB URL.
| Tool | Selectors | What it does |
| ------------------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| render_avatar | id · handle · model | Renders the avatar inline. On MCP Apps-capable hosts it shows a live, rotatable 3D model right in the chat; other clients get a preview image + embed URL. Params: background (transparent/dark/light), scene (portrait/headshot/upper-body/full-body), auto_rotate, height (160–1080). |
| avatar_embed_code | id · handle · model | Returns a ready-to-paste <iframe> that embeds the live avatar anywhere — as easy as a YouTube embed. Params: background, width (CSS), height (160–1080), idle (loop the idle animation), overlay (chrome-free mode for OBS/overlays). |
| get_avatar | id · handle | Fetches avatar metadata: name, GLB model_url, owner, visibility. |
Interactive 3D in the chat — the differentiator
render_avatar is an MCP App (SEP-1865): it declares a ui:// resource that supporting hosts render in a sandboxed iframe — a real, orbit-and-zoom <model-viewer>, not a static image. The avatar is live in the conversation: rotate it, zoom it, watch it idle, without leaving the chat. Hosts without MCP Apps support still get a rendered preview image and a one-tap live embed, so the tool degrades gracefully everywhere.
Example calls
// render_avatar — live, rotatable avatar in chat
{ "handle": "nirholas", "background": "dark", "auto_rotate": true }
// avatar_embed_code — paste into any website
{ "id": "c3d4e5f6-a7b8-9c0d-1e2f-3a4b5c6d7e8f", "height": 560 }
// get_avatar — metadata
{ "handle": "@nirholas" }Every tool also advertises an outputSchema describing its structuredContent, so typed clients can consume results without re-parsing the text blocks.
Prompts
| Prompt | Arguments | What it does |
| ----------------- | ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| showcase-avatar | avatar — id (UUID) or @handle | One-step showcase: renders the live, rotatable avatar inline and produces the embed iframe, ending with a copy-paste summary (name, viewer URL, embed URL, <iframe> snippet). |
How it works
Each selector maps to a real three.ws endpoint. Raw model URLs must be https:// (or http://localhost for dev); other schemes are rejected.
| Selector / asset | Endpoint |
| ---------------- | --------------------------------------------------- |
| id | GET https://three.ws/api/avatars/:id |
| handle | GET https://three.ws/api/users/:handle/avatar |
| preview image | GET https://three.ws/api/avatar/render?avatar=:id |
| live embed | https://three.ws/avatar-embed.html?... |
| viewer | https://three.ws/viewer?src=:glb |
Requirements
- Node
>=20. - No credentials. Public and unlisted avatars need no API key.
| Variable | Required | Notes |
| -------------------- | -------- | ----------------------------------------------------------- |
| THREEWS_BASE_URL | Optional | three.ws host to read from. Defaults to https://three.ws. |
| THREEWS_TIMEOUT_MS | Optional | Per-request network timeout. Defaults to 30000. |
Links
- Homepage: https://three.ws
- Sibling package:
@three-ws/avatar-agent— full 3D AI agent (wallet, voice, pump.fun) - Changelog: https://three.ws/changelog
- Issues: https://github.com/nirholas/three.ws/issues
- License: Apache-2.0 — see LICENSE
