three.ws for Grok
io.github.nirholasv1.0.0Updated Oct 10, 2026
Free text/image to 3D for Grok Bot, plus your three.ws agents once signed in. Never spends.
Overview
Lets an assistant generate, rig, animate, and render 3D models and avatars from text or images through the three.ws pipeline.
- What it does
- The 3D Studio MCP server at three.ws exposes the platform's 3D pipeline as roughly 40 tools, including text_to_3d, image_to_3d, auto_rig_model, apply_animation, stylize_model, retexture_model, and segment_model. An assistant can generate a textured GLB from a prompt or one to six photos, rig and animate it, and render it as an inline interactive artifact mid-conversation. The same engine is also reachable as a free, auth-free REST endpoint.
- When to use it
- Useful when you want an assistant to produce or modify 3D assets during a conversation, for example turning a description or reference photos into a downloadable model, or rigging and animating an existing model without leaving the chat.
- Requirements
- Remote streamable HTTP endpoint at three.ws; no packages, environment variables, or headers are declared in the manifest. The README's self-hosted setup instead needs Node.js 24+, npm 10+, a Neon Postgres database, a Cloudflare R2 bucket, and an Anthropic API key. The README's separate npx MCP server takes MCP_EVM_PAYMENT_ADDRESS and MCP_SVM_PAYMENT_ADDRESS.
Installation
In SourceWeft
- Open three.ws for Grok in the dashboard and add it to a workspace.
- Enable the server for the chats that should use its tools.
Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.
Other MCP clients
Add this to your client's mcpServers config.
{
"mcpServers": {
"threews-grok": {
"type": "http",
"url": "https://three.ws/api/mcp-grok"
}
}
}README
three.ws
Website · Docs · Changelog · X / Twitter · GitHub · $THREE on pump.fun
[site] [npm] [npm] [MCP Registry] [x402scan] [License: Apache 2.0] [good first issues]
https://github.com/user-attachments/assets/d52515d1-cb04-4dd6-98bd-fef233312dc4
Give your AI a body. three.ws is an open source (Apache-2.0), browser-native 3D AI agent platform. Type a prompt and Forge generates a textured 3D model, or drop a GLB you already have. Add an LLM brain, register on-chain, and embed anywhere: no plugins, no server uploads, no installs required.
Try it in 60 seconds: open three.ws/forge, type "a brass steampunk owl, full body", and download the GLB. Text→3D, image→3D, and sketch→3D — free draft tier, no account. Jump to the Forge section ↓
Want to build it with us? Your first contribution goes from clone to open pull request in about 15 minutes, with a full worked example. Every
good first issuenames the file to change and the command that proves it worked. Say hello in Discussions or Telegram.
Meet the avatar: a live 3D model, right here in markdown
Drag to rotate. This is not an image or a video: it is an interactive 3D model rendered natively by GitHub. The avatar was generated from a one-line text prompt on three.ws Forge (free tier), decimated to 1,200 triangles, and embedded as ASCII STL with readme-3d, our open-source toolkit for putting 3D models in any GitHub README, issue, or discussion.
Want your own? npx readme-3d your-model.glb converts any GLB into a paste-ready markdown block. How it works →
$THREE
$THREE is the native token of the three.ws ecosystem — the one and only coin of the platform.
Always verify the contract address above before trading.
$THREEis the only token associated with three.ws.
Table of Contents
- What is three.ws?
- Key Features
- Screenshots
- Forge — Text & Image to 3D
- Platform Pages
- Getting Started
- Examples
- Tutorials
- Architecture
- Tech Stack
- Project Structure
- The Agent System
- Animation System
- Web Component & Embedding
- Widget System
- Embed Editor
- Pose Studio
- Avatar Accessories & Coin Launchpad
- Launchpad
- The Club
- Walk & Multiplayer
- Coin Communities
- Coin Wars & Live Events
- City
- Friends, Presence & Social
- In-Game Economy
- Voice Lab & Mocap Studio
- Talk Mode & Lip-Sync
- Demos Hub
- Skill Library
- Developer SDKs
- API Reference
- Authentication & OAuth 2.1
- MCP Server
- Brain Proxy & LLM Routing
- Claude Code Integration
- Install in Claude Code
- Cloud Marketplaces
- Ecosystem Directories
- IBM watsonx & Granite
- x402 Payments
- A2A — Agent-to-Agent Protocol
- On-Chain Identity (ERC-8004 + Metaplex Core)
- Pump.fun Integration
- WASM Vanity Grinder
- Solana Mobile (Seeker)
- Vision
- Roadmap
- Selfie Reconstruction Pipeline (Phase 1)
- Voice & Persona Hub (Phase 2)
- Livepeer Inference Network (Phase 4)
- News CMS & Syndication
- Security Hardening
- Database Schema
- Build & Deployment
- Environment Variables
- Testing
- FAQ & Troubleshooting
- Community
- Contributing
- Contributors
- License
What is three.ws?
three.ws is a full-stack system for creating, deploying, and embedding 3D AI agents. It combines a WebGL model viewer, an LLM-driven agent runtime, on-chain identity contracts, and a distributable web component into one cohesive platform.
At its core, it does five things:
-
Generate: turns a text prompt, up to 6 photos, or a sketch into a textured, downloadable GLB via Forge. Free draft tier, no account required; auto-rigging, restyling, and retexturing in the same flow.
-
Render — loads and validates glTF 2.0 / GLB models in WebGL 2.0 with zero server-side processing. Drag a file onto the browser and it renders instantly with full Draco, KTX2, and Meshopt decompression.
-
Embody — wraps any avatar with an LLM brain. The agent listens to the user, thinks with Claude, executes tools (animations, gestures, memory operations, skill calls), and expresses emotion through morph-target blending on the 3D model in real time.
-
Register — optionally mints the agent on-chain: as an ERC-8004 token on any EVM chain, or as a Metaplex Core NFT on Solana. Either path gives the agent a stable on-chain identity, a wallet address, signed action history, and a reputation score that cannot be forged.
-
Embed — distributes the agent as an
<agent-3d>web component that anyone can drop into a page, or as one of five purpose-built widget types (turntable, animation gallery, talking agent, passport card, hotspot tour) with Open Graph and oEmbed support built in.
The backend is a set of serverless-style handlers (in api/) served in production by a single Google Cloud Run container (server/index.mjs), backed by Neon Postgres for metadata, Cloudflare R2 for model storage, and Upstash Redis for rate limiting. It exposes a full OAuth 2.1 authorization server and an MCP (Model Context Protocol) endpoint so external AI systems can drive avatars programmatically.
three.ws is production-ready and serves three.ws live on Google Cloud Run: GET https://three.ws/api/version returns the exact commit the site is running right now. The entire stack (viewer, agent runtime, contracts, backend, and web component) is open source in this repository under the Apache License 2.0: fork it, self-host it, and ship commercial work on it.
Key Features
Companion (your notifications, delivered in person)
- three.ws/companion: connect your own Telegram bot, the private iCal link your calendar publishes, your inbox over IMAP with an app password, or nothing but a token your phone, your Mac, a build script or an AI agent can POST to
- Every message is scored out of 100 (a saved contact asking you something, a one-time code, a meeting in ten minutes, a payment that failed); what clears your bar is spoken out loud, and everything else is kept in a feed with the reason it stayed quiet
- Give a contact an avatar and a voice, and their messages arrive wearing that body
- Reaches you on the site, as a push on your phone, and on your desktop via the companion app, a character that walks across your screen
- Developers:
@three-ws/companionships the client, the same triage rules the server runs (score your own mail locally), a drop-in 3D stage, a CLI, and an MCP server so an agent can interrupt a human in person
Text → 3D Generation (Forge)
- Prompt-to-3D at three.ws/forge — describe an object in a sentence and download a textured GLB
- Image→3D (one to six photos) and sketch→3D in the same composer
- Multiple generation engines with live health checks: self-hosted lanes plus bring-your-own-key Meshy and Tripo (keys stay in the browser)
- Prompt-to-avatar at three.ws/create/prompt — a description becomes a rigged, animatable 3D avatar
- Generated models carry straight into Scene Studio, embeds, worlds, and on-chain deployment
3D Viewer
- WebGL 2.0 rendering via three.js r184
- glTF 2.0 and GLB with Draco geometry compression, KTX2 texture compression, and Meshopt mesh optimization
- Khronos-spec glTF validation with line-level error reporting
- HDR environment maps, PBR materials, skinned mesh animations, morph targets, and embedded cameras
- OrbitControls (pan, zoom, rotate) with configurable auto-rotation
- Real-time parameter tweaking (lights, exposure, morph weights) via dat.GUI
Agent Runtime
- LLM brain powered by Claude (Anthropic API) with a structured tool-loop architecture
- Up to 8 tool iterations per turn before returning final output
- Built-in tools:
wave,lookAt,play_clip,setExpression,speak,remember - Composable skill system — install skills from IPFS, Arweave, or HTTP; each skill is a self-contained bundle with a description, tool definitions, and async handlers
- Weighted emotion blending (celebration, concern, curiosity, empathy, patience) driven by protocol events, not a finite-state machine
- Web Speech API for STT/TTS out of the box; on-device speech-to-text when the manifest sets
voice.stt.providerto"whisper"(Moonshine for English, Whisper for 99 languages, run in the browser through transformers.js, with the NVIDIA Riva lane as fallback), so dictation works in Firefox and Safari too; ElevenLabs integration for production-quality voice - Talk mode with audio-driven ARKit-52 lip-sync — TTS audio is analysed in real time and drives 52 standard blendshapes on the avatar
- Anonymous Groq-powered chat for unauthenticated visitors; owner-card gating when an agent has a paying author
x402 Payments & Bazaar
- Native x402 paid endpoints on Base, BSC, and Solana — agents pay other agents in USDC for API calls, asset downloads, and skill royalties
- Coinbase CDP facilitator on Base mainnet; direct-scheme payments on BSC
- Permit2 gas-sponsoring siblings on every CDP-settled endpoint (buyer signs, relayer pays gas)
- Pay-by-name —
/api/x402/pay-by-nameresolves@username,*.sol(incl. subdomains), or raw base58 to a recipient and builds an unsigned USDC transfer for the payer's wallet. Every 402 manifest emitted by a named agent advertisesrecipient_namenext to the wallet, so payers verify a human-readable name before signing - SKU catalog + Stripe-style checkout at
/dashboard/x402; receipts ledger - Subscriptions, idempotency tokens, offer receipts, paid asset download, and a bazaar listing/search API
- SIWX (Sign-In with X-chain) server for auth-gated paid endpoints
- Listed on x402scan and the MCP Registry
SNS / *.threews.sol subdomains
/threews/claimlets any signed-in user mint[username].threews.solin a single atomic Solana transaction —createSubdomain→ URL record →transferSubdomainto the user's wallet, with three.ws absorbing gas- Brave Browser resolves the subdomain directly to the user's
/u/[username]showcase via the SNS URL record - Agents can bind a
.solname (theirs or a fresh registration) via/api/agents/:id/sns; once bound, every public surface — agent page, x402 manifest, MCP listing, marketplace card — displays the name in place of the raw wallet
A2A — Agent-to-Agent Protocol
- A2A client + server, MCP bridge, DID resolution, spending ledger, receipts storage
- Agents transact autonomously via their delegated signer wallets and EIP-7710 permissions
Identity & On-Chain
- ERC-8004 smart contracts (IdentityRegistry, ReputationRegistry, ValidationRegistry) deployable on any EVM chain — plus a program-free Metaplex Core analog on Solana (asset pubkey = agent ID, SPL Memo–anchored reputation + validation attestations)
- Each agent is an ERC-721 token with a stable
agentId, owner wallet, delegated signer (EIP-712), and IPFS-pinned manifest - Signed action log — every
speak,remember,skill-done, andvalidateevent is recorded on-chain-optionally or in the database with a cryptographic signature - EIP-7710 delegated permissions for composable agent-to-agent authorization
- Solana support (SIWS sign-in, Solana wallet linking, Metaplex NFT option)
Embedding & Distribution
<agent-3d>custom element — drop it anywhere with no framework dependency- Five widget variants: turntable, animation gallery, talking agent, ERC-8004 passport card, hotspot tour
- Widget Studio at
/studio: pick an avatar (or paste your own model URL), pick a widget type, tune it live, copy the snippet; no account needed for the URL-baked types - Launchpad at
/launchpad— hosted public launch pages at/p/[slug]for tokens, agents, and drops - Open Graph metadata and oEmbed support for rich social previews when links are shared
- Versioned CDN bundles at
/agent-3d/x.y.z/agent-3d.js
Social & Multiplayer 3D
- Coin Communities at
/communities+/play— every Solana token gets a live 3D world; pick the same coin and land together, with peer avatars, chat, emotes, voxel building, and a live market-cap screen - City at
/city— free-roam walkable 3D city scene - Friends, presence & DMs — account-level social graph with live presence ("Online · Mainland"), direct messages, and a per-account realtime delivery hub
- The Club at
/club— multiplayer venue with rigged dancers, audio tracks, tips, leaderboard, payouts cron, perf-aware renderer that auto-downgrades on slow frames - Walk at
/walk— authoritative multiplayer walk scene backed by a Colyseus server inmultiplayer/(deployable on Google Cloud Run) - Pose Studio at
/pose, Voice Lab at/voice, Mocap Studio at/mocap-studio— author poses, bind voices, and capture/retarget motion into reusable clips
Backend & Integrations
- OAuth 2.1 server (RFC 6749 + PKCE, RFC 7591 dynamic registration, RFC 7009 revocation, RFC 7662 introspection, RFC 8414 discovery)
- Developer API keys with scope and expiry
- MCP (Model Context Protocol) over HTTP with JSON-RPC 2.0 for tool-calling from external AI systems; A2A bridge exposes paid tools as x402 endpoints
- Avaturn (photo-to-avatar), Character Studio (in-browser builder), Avatar Studio (rebranded marketplace), and Privy (embedded wallet) integrations
- Replicate-backed avatar regeneration provider for photo-to-avatar workflows
- Native selfie reconstruction pipeline (Phase 1) + Livepeer inference network (Phase 4) wired into the agent runtime
- DCA strategy execution and on-chain subscription scheduling via cron jobs
- Solana Mobile (Seeker) MWA wallet wired into the web app + Solana Mobile dApp Store release pipeline
- Hardened API surface: SSRF guard, CSRF gates, header-origin pinning, fail-closed crons
- OpenAPI 3.1 spec generated at
/openapi.json
Screenshots
Every image below is a real capture of the live production site. Click any caption to open that page.
More captures appear inline in the sections below: Widget Studio, Embed Editor, Pose Studio, City, Walk, Launchpad, vanity grinder, Demos Hub, and Chat.
Forge — Text & Image to 3D
Type a sentence, get a 3D model. Forge turns a text prompt, one to six photos, or a rough sketch into a textured, downloadable GLB, in the browser, with a free draft tier and no account required.
Three quality tiers — draft (~12k polygons), standard (~30k, default), high (~200k + PBR textures) — and two generation paths: the platform-keyed image pipeline (FLUX → TRELLIS) that works with no key at all, and bring-your-own-key native geometry via Meshy or Tripo for the cleanest quad topology (your key stays in your browser).
Forge is not a dead end. Every generated model carries straight into the rest of the platform: open it in Scene Studio, auto-rig it into an animatable character, restyle it (voxel / brick / voronoi / low-poly), retexture it from a prompt, embed it with <agent-3d>, give it an LLM brain, or deploy it on-chain. Prompt-to-avatar lives at three.ws/create/prompt — a description becomes a rigged, animatable agent body.
REST API
The same engine is one HTTP call, free and auth-free:
Image→3D is the same endpoint with image_urls: ["https://…/front.png", …] (1 to 6 views) instead of a prompt. GET /api/forge?catalog returns the live tier/backend/cost matrix.
From Claude, Cursor, or any MCP client
The 3D Studio MCP server at https://three.ws/api/mcp-3d exposes the full pipeline as 40 tools (text_to_3d, image_to_3d, auto_rig_model, apply_animation, stylize_model, retexture_model, segment_model, and more), so an AI assistant can generate, rig, and animate a model mid-conversation and render it as an inline interactive artifact. See docs/mcp-3d-studio.md.
Pay-per-call for autonomous agents (x402)
POST /api/x402/forge is the monetized twin: agents pay per generation in USDC on Solana mainnet, with no API key and no account. Draft $0.05, standard $0.15, high $0.50; polling is free; retried payments are idempotent and never double-charge. See docs/api/forge-x402.md.
Learn more
- Tutorial: Turn a Text Prompt into a 3D Model — first model in about a minute
- Tutorial: Turn Photos into a 3D Model: reconstruct a real object from up to 6 photos
- 3D Studio MCP server — generate from inside Claude or Cursor
- Paid generation API (x402) — autonomous agent-to-agent generation
Platform Pages
A map of every user-facing route. STRUCTURE.md maps each product surface to the directory that implements it, and data/pages.json is the registry every public route is generated from (sitemap, llms.txt, features.json, changelog).
Getting Started
Prerequisites
- Node.js 24+ (the project pins
"engines.node": "24.x"inpackage.json; earlier majors are not tested) - npm 10+
- A Neon Postgres database
- A Cloudflare R2 bucket
- An Anthropic API key
Installation and Setup
- Clone the repository:
- Install dependencies:
- Set up environment variables:
Copy the
.env.examplefile to.env.localand fill in the required values. See the Environment Variables section for more details. - Initialize the database: The schema is idempotent. Run it against your Postgres instance to create all tables:
- Run the development server:
The application will be available at
http://localhost:3000.
Examples
Copy-paste ready snippets for the most common use cases. Swap in your own GLB URL and go.
Run these without cloning anything: three.ws/examples renders the same snippets with a Run button on each. The code executes in a sandboxed frame on the page against the production CDN bundle, so what you see running is exactly what you copy. That page also lists every example that ships in
examples/, generated by scanning the repo so it cannot drift.
1. Minimal viewer (no AI)
The simplest possible setup — one script tag, one element, zero build step.
Drag-to-rotate, scroll-to-zoom, full PBR rendering — no API key, no account required. Swap body= for any publicly accessible .glb URL.
2. Talking agent with inline instructions
Add brain= and instructions= to turn the viewer into a conversational agent.
The chat input and mic button appear automatically when brain is set. No UI to build.
3. Floating bubble (support widget style)
Pin the agent to a corner of the page so it persists as users scroll.
position accepts bottom-right, bottom-left, top-right, or top-left.
4. Load a registered agent by ID
If you've registered an agent on the platform, load it entirely from its manifest — no inline attributes needed.
The element fetches the manifest (model URL, instructions, skills, memory config) automatically.
5. Custom chat UI with JavaScript API
Hide the built-in chrome and wire in your own input using the element's JS API.
Full JS API:
Key events: agent:ready, brain:message, brain:thinking, skill:tool-called, voice:transcript
6. iframe widget (works in Notion, Substack, Webflow)
Use a widget URL directly — no script tag needed.
Generate the src URL from Widget Studio — pick an avatar, choose a widget type, and copy the snippet.
7. Agent manifest JSON
For anything beyond a quick one-liner, define the agent in a manifest file and reference it with manifest=.
agent.json:
8. Dead-simple copy-paste widget
For the absolute simplest way to embed an agent, use this snippet. It requires no build tools or imports. Just copy and paste it into your HTML.
The loader (public/artifact.js) mounts a rotatable 3D viewer into every [data-agent-id] element on the page. You can find your agent ID in the agent's settings page. This method is great for quick integrations on platforms like WordPress, Ghost, or any static HTML site; size it with the style attribute. For a configurable snippet (chat mode, environments, size presets), use the Widget Studio at /studio.
Tutorials
66 step-by-step guides ship in docs/tutorials/, and every one is published live at three.ws/tutorials. If you would rather run code than read, three.ws/examples executes each snippet on the page. The core path:
Beyond the core path, the catalog covers every surface in this README. A sampler, grouped by what you want to do:
- Embed & integrate: Embed in 30 seconds · Add a 3D assistant to your app · Build a site concierge · Shopify shopping assistant · JS API and events · Trigger from page events
- Avatars & 3D: Selfie to avatar · Animate your avatar · Build a 3D scene · View in AR · Upload a custom GLB · Voice and lip-sync
- Agents & AI: Connect an AI brain · Agent personality · Create and edit memory · Multi-agent coordination · MCP server for your agent
- On-chain & payments: Claim your threews.sol name · Mint a pump.fun token · Mine a vanity address · x402 server SDK · Solana agent reputation
Common gotchas
CORS — if your GLB is hosted on a different domain, the server must send Access-Control-Allow-Origin: *. Without it the fetch is blocked and the canvas stays blank. Uploading via the platform's storage sets this automatically.
File size — models over ~50 MB load slowly. Compress with Draco:
Voice on HTTPS — getUserMedia (microphone) requires HTTPS. Localhost is exempt; any remote deployment needs TLS. Vercel and Netlify both provide it automatically.
CSP — if your page has a strict Content Security Policy, add:
For sandboxed iframes use the widget embed path instead — it runs in its own browsing context.
Architecture
The platform is organized into four layers. All layers communicate through a single event bus (agent-protocol) rather than direct calls.
The event bus decouples every component. The avatar emotion system reacts to speak events without knowing the runtime exists. The identity module records actions without knowing the UI exists. This makes the system testable, embeddable in isolation, and composable across pages.
The backend is stateless serverless functions. All persistent state lives in Postgres (Neon), object storage (Cloudflare R2), or on-chain. Cron jobs handle scheduled blockchain operations (ERC-8004 crawl, DCA execution, subscription execution).
Design Docs & Specs
The architecture above is the bird's-eye view; each load-bearing surface has a dedicated spec that defines its wire format, invariants, and extension points. New contributors should skim the spec for any subsystem they're about to change.
Longer-form architecture and how-to documentation lives under docs/: docs/architecture.md, docs/agent-system.md, docs/3d-asset-pipeline.md, docs/animations.md, docs/web-component.md, docs/api-reference.md, docs/mcp.md, docs/permissions.md, docs/security.md, docs/smart-contracts.md, and more.
3D asset pipeline — FBX, GLB, JSON
Every avatar the site renders is a GLB (binary glTF 2.0 — the body, rig, and textures in one file); every shared gesture and dance is a format-light clip JSON (a serialized THREE.AnimationClip — motion only, retargeted onto any rig at runtime); and both originate as FBX source from Mixamo or a DCC tool. Two conversions come off one FBX — npm run convert:fbx for a full character GLB, npm run build:animations for a reusable library clip — then npm run optimize:glb makes it web-ready (~90% smaller). The full explainer, format specs, runtime modules, and the generate→rig→animate→export capability chain are in docs/3d-asset-pipeline.md.
Tech Stack
Frontend
- Main UI: The core application, including the 3D viewer, agent creation, and marketplace, is built with vanilla JavaScript modules and Vite.
- Chat: The chat interface is a standalone Svelte application located in the
chat/directory. - 3D Rendering: three.js (r184) is used for WebGL 2.0 rendering.
Backend (Google Cloud Run)
- Runtime: Node.js — serverless-style handlers in
api/served by one Express container (server/index.mjs) on Cloud Run (three-ws-api,us-central1). - Database: Neon Postgres (serverless)
- Storage: Cloudflare R2 for model and avatar storage.
- Rate Limiting: Upstash Redis.
- LLM: The agent's brain is powered by the Anthropic (Claude) SDK.
Smart Contracts
- Language: Solidity 0.8+
- Framework: Foundry for compiling, testing, and deploying the ERC-8004 contracts.
- Standards: ERC-721, EIP-712, EIP-7710.
Browser Support
The viewer targets every browser that ships WebGL 2.0 on a desktop or modern mobile device. Concrete support matrix:
Capabilities and graceful degradation
- WebGL 2.0 is required; the viewer refuses to boot without it and shows a fallback message.
- WebAssembly is required for the Draco / KTX2 / Meshopt decoders that are copied into
public/three/draco/andpublic/three/basis/byscripts/copy-three-decoders.mjsonpostinstall(both paths are generated and gitignored, so they only exist afternpm install), plusnode_modules/three/examples/jsm/libs/. getUserMedia(microphone) requires HTTPS — see Common gotchas. Without it the agent falls back to text input.speechSynthesisis detected at runtime; agents fall back to silent text replies when TTS is unavailable.- WebGPU is not required and is not used yet — Phase 4 reserves it for client-side inference experiments.
Project Structure
src/: The core frontend JavaScript for the main application, including the 3D viewer, agent protocol, custom element, and feature modules (club-*.js,walk*.js,pose-*.js,voice/,selfie-*.js). Social/gameplay surfaces live ingame/(Coin Communities:coincommunities*,spin-wheel-ui,cosmetics-visual,avatar-rig),city/(the/cityworld),social/(sentiment, X-post impact),community/(coin lobby/town), plusfriends.js,communities.js,marketplace*.js, andtoken-pay.js.api/: Serverless-style handlers that form the backend API, served in production by the Cloud Run container (server/index.mjs) withvercel.json-parity routing. Subdirectories includex402/,a2a/,club/,pump/,persona/,news/,admin/,agents/,auth/,oauth/,cron/, plus the social/game surfacesplay/,token/,three-token/,friends/,social/,community/,marketplace/, andmocap/.public/: Static assets and various sub-applications (club/,seeker/,news/,persona/,vanity-wallet.html,pumpfun.html).chat/: A standalone Svelte application for the chat interface.character-studio/: A sub-project for in-browser character creation; also serves the rebranded Avatar Studio marketplace.rider/: A-Frame WebVR music visualization experiment.contracts/: Solidity smart contracts for on-chain identity (ERC-8004) and the multichain payment factory.multiplayer/: Colyseus WebSocket server for/walkand/play(WalkRoom); deployable on Fly.io. Holds the authoritative world logic and single sources of truth —items.js,playerStore.js,game-token.js,play-pass.js,holder-pass.js, and the per-accountsocial-hub.js.sdk/:@three-ws/sdk(the AgentKit SDK; the legacy avatar helpers live insdk/agent-sdk/).agent-payments-sdk/: EVM agent payments SDK (Base / BSC / other EVM chains).solana-agent-sdk/: SDK for Solana blockchain interactions (Metaplex Core mints, SIWS, attestations).pump-fun-skills/: Skills related to the pump.fun integration.scripts/: Node.js scripts for development, build, deployment, and pump.fun launch automation.workers/: Code for background workers — includes the Cloudflare Worker mirror of the pump.fun MCP read API inworkers/pump-fun-mcp/.docs/: Public-facing developer docs.docs/internal/: Working docs (PLAN, STATUS, TODO, NEXT, PROGRESS, RELEASE_CHECKLIST, club venue notes) — not part of the published docs surface.tests/: Vitest unit tests (tests/api/,tests/src/,tests/workers/) and Playwright end-to-end smokes (tests/e2e/).
The Agent System
Event Bus (Agent Protocol)
src/agent-protocol.js implements a lightweight EventTarget subclass that is the nervous system of the platform. Every component — avatar, runtime, identity, UI — communicates exclusively through this bus. There are no direct method calls between layers.
The bus maintains a 200-action ring buffer for debugging and replay. Embed variants expose a filtered subset of events through postMessage to the host page.
Core event types:
Identity-relevant events (speak, remember, sign, skill-done, validate, load-end) are fire-and-forwarded to POST /api/agent-actions for durable logging.
LLM Runtime
src/runtime/index.js implements the Runtime class, which drives the agent's LLM-powered brain.
Tool-loop flow:
- User message (text or STT transcript) arrives
- System prompt is assembled: manifest instructions + recalled memory + skill descriptions
- Claude is called with the conversation history and all available tools
- Tool calls are dispatched in order — each built-in tool or skill handler receives a rich context object:
- Tool results are appended to conversation history as
tool_resultmessages - Steps 3–5 repeat until Claude returns with no tool calls, or the iteration limit (8) is hit
- Final text response is optionally spoken via TTS
Providers (src/runtime/providers.js):
AnthropicProvider— connects to the Anthropic API, supports streamingNullProvider— no-op for testing and offline mode
Built-in tools (src/runtime/tools.js):
Skills can define additional tools that override or augment the built-ins. The skill registry is loaded from the agent manifest before each conversation turn.
Empathy Layer
src/agent-avatar.js implements the Empathy Layer — a continuous weighted emotion blend that drives the avatar's facial morph targets and head orientation in real time.
Emotions are not a finite-state machine. Each emotion is a float (0..1) that decays linearly per frame at a different rate. Protocol events inject spikes:
Decay half-lives (approximate):
- Patience: ~20s — persists during long operations
- Empathy: ~13s — lingers after emotional events
- Concern: ~12s — sustained worry
- Curiosity: ~8s — alert, fades moderately
- Celebration: ~6s — brief, upbeat
The blended emotion mix drives morph target values each frame. For example:
- Celebration →
mouthSmile 0.85,mouthOpen 0.2 - Concern →
mouthFrown 0.55,browInnerUp 0.6 - Empathy →
eyeSquint 0.4,browInnerUp 0.5
Head tilt and lean are also driven by the blend — curiosity tilts the head, patience leans slightly back.
This architecture means the avatar feels responsive and emotionally coherent without any hand-authored animation triggers.
Skills
Skills are self-contained capability bundles that extend the agent's tool set. Each skill lives in its own directory:
tools.json example:
handlers.js example:
Skills are loaded from the agent manifest at runtime. The SkillRegistry supports three trust modes:
any— install skills from any source (development only)owned-only— only skills the agent owner has registeredwhitelist— only approved skill URIs
Skills are distributed over IPFS, Arweave, or HTTP. The public skills registry is at /public/skills-index.json.
Memory
src/memory/index.js implements a file-based memory system (mirroring this project's own Claude memory system). Memories are Markdown files with YAML frontmatter, organized by type:
A MEMORY.md index file is auto-maintained. At the start of each conversation turn, the memory store is scanned and high-salience entries are injected into the system prompt; the MEMORY.md index itself is injected in full, capped at the spec's 200 lines.
Storage modes:
local— stored in the browser's local storage (default for development)remote— persisted per-agent via/api/agent-memory(owner-only)ipfs— pinned to IPFS via Pinata or Web3.Storageencrypted-ipfs— encrypted before pinning (user holds the key)none— stateless, no memory between sessions
Memory types (user, feedback, project, reference) follow the same taxonomy used by this codebase's own Claude guidelines.
Plugging a custom memory backend
You don't fork Memory to add a vector store or episodic log — register a backend and select it by name. Built-in modes are unchanged; your mode is just another option.
Only load is required; persist makes it durable, recall makes search semantic (it falls back to substring matching if it throws). To swap only the ranker while keeping built-in storage, point manifest.json → memory.retriever at a skill instead. Full reference: specs/MEMORY_SPEC.md → Custom backends.
Memory snapshot contract
memory.snapshot() returns a synchronous, JSON-safe memory/0.1 object so embedded widgets can serialize/deserialize state across page reloads; Memory.fromSnapshot(snap, { mode, namespace }) rehydrates it (rebuilding the index if absent).
Animation System
The avatar runtime ships with a slot-based animation manager that decouples animation clips from rigs — a clip authored for one body can be retargeted to any other rig at load time.
A new clip can be authored against any rig in Blender, exported as a GLB, and dropped into the animation library — the manager picks it up automatically and the agent runtime can invoke it via the play_clip tool.
The sitidle clip is shipped as the default seated idle for chat-mode avatars; the gemini-jump clip drives the hero on /.
Web Component & Embedding
The <agent-3d> custom element (src/element.js) is the primary distribution mechanism. It lazy-boots on intersection (IntersectionObserver), so off-screen agents don't load until visible.
Basic usage:
Key attributes:
The element fires a postMessage API for host-page communication (documented in specs/EMBED_HOST_PROTOCOL.md). Hosts can send events to the agent and receive speak, think, and skill-done events back.
Versioned CDN bundles are published at /agent-3d/x.y.z/agent-3d.js. Use latest for auto-updates or pin to a version for stability:
Iframe quickstart with the embed SDK
For when you want a chromeless iframe that you control from the parent page (rather than the <agent-3d> web component), drop in the embed SDK:
Origin contract. The SDK derives the iframe's origin from iframe.src and refuses to start if it can't (no wildcard targets, ever). The iframe locks onto the parent's origin from the first authenticated message it sees and ignores any later messages from a different origin. See specs/EMBED_SPEC.md §"Bridge origin model" for the full rules.
Typed host bridge (npm-friendly)
For TypeScript/bundler workflows, import EmbedHostBridge directly:
Both surfaces speak the same v1 wire protocol — pick the one that fits your stack.
Widget System
The Widget Studio (three.ws/studio) lets anyone build a shareable, embeddable 3D experience without writing code. Pick an avatar, pick a widget type, configure it, and get an iframe snippet.
Five widget types:
Each widget has:
- A public URL at
/w/<id>with server-rendered Open Graph metadata for rich link previews - An oEmbed endpoint at
/api/widgets/oembedfor WordPress, Ghost, Notion embedding - An iframe embed URL at
/api/widgets/<id>/view - A view counter tracked at
/api/widgets/<id>/stats - A duplicate API at
/api/widgets/<id>/duplicate
Widgets are stored as JSON config in Postgres, pointing at an avatar in R2.
Embed Editor
The WYSIWYG embed editor lives in the Widget Studio at three.ws/studio (public/studio/studio.js). The standalone /embed page merged into it: the bare path 301s to /studio, and a parameter-carrying /embed?… link rewrites there, because the Studio reads the same parameter names.
Pose Studio
three.ws/pose is a 3D pose-reference tool inspired by setpose.com. It builds a Three.js scene with an articulated mannequin, orbit camera, ground + grid, and a control panel that lets you pick presets, drag joints to pose them, fine-tune with sliders, swap body type, add floor props, change lighting and FOV, and export a PNG screenshot.
Poses author cleanly into the avatar runtime via the play_clip tool — the agent can adopt any saved pose on demand. Exported PNGs are useful as marketing renders or as reference frames for downstream image/video pipelines.
Avatar Accessories & Coin Launchpad
Avatars are not just GLB files — they're composable rigs that the runtime can decorate with onchain accessories.
Accessories
- Hats, glasses, props attached to named bone slots via src/agent-accessories.js
- Accessories are themselves ERC-1155 tokens, ownable and tradeable independently of the avatar
- Equipping is non-destructive — the agent's base manifest stays unchanged, the accessory is layered at runtime
Coin Launchpad
Every agent can mint a coin alongside its avatar — turning the agent into a tradeable economic object.
The coin's metadata points back at the agent's onchain identity — ERC-8004 token on EVM or Metaplex Core asset on Solana — and the agent's manifest references the coin. The two-way binding is read from the bazaar, marketplace, and reputation registry on either chain.
Launchpad
The Launchpad at three.ws/launchpad is a hosted-page builder for token launches, agent debuts, and drop campaigns. Each published page lives at a public URL like /p/<slug> with full Open Graph metadata for sharing. The live launch directory is at three.ws/launches.
Launchpad templates are JSON-configured and can embed any combination of <agent-3d> widget, x402 paid endpoint, or pump.fun launch button. Pages are stored in Postgres and served as static HTML with hydration for interactive elements.
The Club
three.ws/club is a multiplayer 3D venue: a club scene with rigged dancers, audio tracks, spotlights, mirror-ball cube cam, and on-chain tips (screenshot in the gallery above).
Stack:
- Venue GLB + HDRI lit by four spotlights; bloom + chromatic aberration on the high tier
- Audio tracks streamed from R2 with synchronized playback across clients
- Camera state machine — DJ booth, overhead, dance-floor, follow-cam — sequenced per track
- Performance profile detector picks
high/medium/lowfromnavigator.deviceMemory,hardwareConcurrency,pointer: coarse, and the UA string - Frame-budget watchdog auto-downgrades the profile if sustained slow frames are detected
Economics:
- Tips API at
/api/club/tips— viewers tip dancers in USDC via x402 (CDP-settled, Permit2-gasless sibling available) - Leaderboard at
/api/club/leaderboardwith windowed top-tipper rankings, memoized for 15s so a full room costs one aggregate per window rather than one per viewer, and answering503with a retry hint when the database is over capacity instead of a bare failure. Each row also carriesagent_tip_count, the share oftip_countpaid from a registered platform wallet, so the page can split tips from people and tips from agents - Live tip feed at
/api/club/tips/stream(SSE); a cold stream rewinds its cursor to the moment the first viewer arrives, so a room that went quiet does not replay the banked backlog as if it were live. Rows from the feed and from/api/club/tipscarryagent(true when the payer is inx402_ring_wallets) and the style's choreography (durationSec,track,pole,sequence), so every viewer replays the routine that was bought - Hourly payouts cron sweeps the tips ledger into the dancers' treasury wallets
Detail: performance notes, venue plan, and release checklist live in docs/internal/ alongside other internal working docs.
Walk & Multiplayer
three.ws/walk is an authoritative multiplayer walk scene. Players join a shared 3D space, see each other's avatars in real time, and emit gestures over a WebSocket connection.
The serverless-style request/response layer can't hold long-lived WebSockets, so the multiplayer server lives in its own workspace at multiplayer/ — a Colyseus server packaged with a Fly.io fly.toml and Dockerfile. The Vite client at /walk autodiscovers the server (ws://localhost:2567 in dev, your deployed host in prod).
WalkRoom (multiplayer/src/rooms/WalkRoom.js) is the authoritative state container — position, rotation, gesture, presence. Origin allow-listing is enforced at the WS upgrade (ALLOWED_ORIGINS env, with *.vercel.app and *.three.ws always permitted for preview deploys). The same Colyseus server also runs a per-account social hub (multiplayer/src/social-hub.js) for presence and live event delivery.
Coin Communities
Every Solana token gets a live 3D world. Coin Communities (three.ws/communities, screenshot in the gallery above) turns a mint address into a shared multiplayer space: pick the same coin as someone else and you land together, walk around, emote, voice-chat, build with voxels, and watch the live market-cap chart on an in-world screen.
How it works
- Real pump.fun data, no mocks. The lobby and coin profiles pull live trending coins, search results, bonding-curve pricing, and recent trades from the pump.fun feed.
- Bring any avatar. Use a default, an uploaded GLB/VRM, or paste a model URL. The same rig (
src/game/avatar-rig.js) drives/play,/walk, and/citywith no drift. - Realtime presence + chat. Each coin is its own room. Town chat is backed by the CoinCommunities service — reads work out of the box; posting unlocks behind X-OAuth sign-in + a linked wallet. If
CC_API_KEYis unset, chat renders its designed locked state. - Voxel building & spatial voice. Collaborative block placement (server-capped) and optional geofenced WebRTC voice (
src/game/voice-chat.js). - Holder-gated rooms. A coin can require token holders (tier
holdersvs general); gating is enforced server-side via a sealed play-pass.
Key files: src/communities.js (lobby), src/game/coincommunities.js + coincommunities-ui.js (3D scene + HUD), src/game/community-net.js (socket bridge), api/community/* (worlds, messages, ws-ticket, capabilities, me), api/_lib/coin-communities.js (CoinCommunities SDK client). Coin art comes through the platform image proxy rather than straight off a launch metadata URI, so a hot-linked image that blocks cross-origin reads still renders instead of leaving a broken tile.
Coin Wars & Live Events
Two coin communities can meet in one arena and fight for their coin. Every world on /play carries a war portal in its plaza (src/game/war-portal.js): walk up to it and the board shows the community's Elo rating, rank, record, K/D, and its last battles. Press E to queue; when a second community queues, both sides are handed the same battle and the arena opens at three.ws/play/war.
The gate is server-side, not cosmetic: the arena will not seat you under a community whose coin you do not hold, and the pairing itself is sealed into a signed war ticket so a fighter cannot open an arena against a community that never agreed to fight. Results are written to a battle ledger and the league is folded from that ledger by multiplayer/src/war-standings.js, the same module the arena's own league reads, so a portal board is never a second opinion. One endpoint serves all of it: GET /api/wars (board), GET /api/wars?action=live (spectator poll), POST /api/wars?action=queue|leave, and the game server's HMAC-signed ?action=report write (api/wars.js). Full reference: docs/coin-wars.md.
Live events run in the same world. A countdown, an agenda, per-segment banners, and a synchronized fireworks show are driven from one config file, so an event exists (or stops existing) without a code change (src/game/meetup-event.js, src/game/event-countdown.js, docs/play-live-events.md). Everyone who walks into the event world while it is live is handed a free commemorative wearable that is never granted again afterwards and is never purchasable: see docs/event-souvenirs.md.
City
three.ws/city is a free-roam 3D city scene: a walkable urban world (real Manhattan map data) with a follow camera, map, and player controller, built on the same Three.js stack as the rest of the platform.
Key files: src/city/city-world.js (scene + render loop), city-map.js (layout), city-player.js (movement/controller), city-camera.js (follow cam), city.css.
Friends, Presence & Social
A full account-level social layer spans the multiplayer surfaces. Friendships are durable; presence is volatile — and both are keyed to the account, not the ephemeral session, so they survive reconnects and realm changes.
Friends are stored in Postgres (friendships, direct_messages, user_mutes — see migration api/_lib/migrations/2026-06-01-friends.sql); presence lives in Upstash Redis and self-heals if a process dies. Muting is send-side only — a muted account is never told it was muted. The friends panel UI (src/friends.js, src/game/friends-panel.js) surfaces requests, DM threads, and "Online" / "Offline" status inside /play. The src/social/ module adds sentiment + X-post-impact scoring used by community surfaces.
In-Game Economy
The three.ws/play open world runs on two currencies that are kept strictly separate, and the separation is the whole design. Cash (the carried purse) is a pure game resource: earned by gathering, fishing, and combat, spent at vendors, never on-chain and never a token. $THREE is the platform's only coin, spent on-chain from the player's connected Solana wallet to unlock premium cosmetics. Price tables live in one module (multiplayer/src/shop.js) that the authoritative server and the client both import, so the price a player is shown is exactly the price the server charges.
USD prices convert to $THREE at the live rate through fetchTokenPriceUsd, which walks a primary-then-fallback feed chain and caches the result briefly. If every feed is unavailable the server refuses to issue a quote rather than guessing at a price. Progression backs the whole loop: five skills (combat, woodcutting, mining, fishing, cooking) to a level cap of 99, a 24-slot inventory, and a 6-slot hotbar (multiplayer/src/economy.js). Server config: GAME_TOKEN_MINT, GAME_TOKEN_TREASURY, GAME_TOKEN_DECIMALS, GAME_TOKEN_SECRET.
This in-game rail is distinct from two neighbours it is easy to confuse it with: the USDC x402 cosmetic rail (api/x402/cosmetic-purchase.js), which sells a different catalog for the standalone character creator, and the public settled-sale cosmetics ledger at /fits. Vendor and banking trades settle purely in the Colyseus room state; only the boutique and paid spins touch the chain.
Every catalog, gate and odds table above is published live at three.ws/play/economy, served by GET /api/play/economy (api/play/economy.js). That endpoint imports the game's own modules rather than restating them, so the public reference cannot drift from what the server charges. Full reference: docs/in-game-economy.md. Hands-on walkthrough: docs/tutorials/earn-and-spend-in-play.md.
Voice Lab & Mocap Studio
Two creator tools sit alongside Pose Studio:
- Voice Lab (
/voice,src/voice-lab.js) — audition and bind voices to an agent, building on the Voice & Persona Hub. - Mocap Studio (
/mocap-studio,src/mocap-studio.js,api/mocap/): record webcam face mocap (MediaPipe FaceLandmarker) on a rigged avatar, calibrate to a neutral pose, then save, replay, and share the clips via/api/mocap/clips(public clips are replayable by anyone, resolved by slug).
Talk Mode & Lip-Sync
The talk interaction mode wires together the LLM runtime, ElevenLabs TTS, and an audio-driven ARKit-52 lip-sync driver that maps live audio amplitude + formant analysis onto the 52 standard ARKit blendshapes.
When the agent speaks, the driver runs at ~60fps and drives mouthClose, jawOpen, mouthSmileLeft/Right, and the rest of the ARKit-52 set — the Empathy Layer's emotional morphs continue to blend on top, so the avatar simultaneously emotes and articulates. Unit tests for the ARKit-52 mapping live in tests/src/arkit-morphs.test.js.
Activating talk mode
Set mode="talk" on the <agent-3d> element and supply an ElevenLabs voice ID in the agent manifest:
Pipeline (step by step)
- User speaks →
getUserMediacaptures audio → Web Speech API produces a text transcript. - Transcript enters the LLM tool-loop; the final reply text is sent to ElevenLabs TTS.
- The returned
AudioBufferis piped through a Web Audio APIAnalyserNode. - The lip-sync driver (
src/voice/lipsync-driver.js) samples the analyser every animation frame, extracts amplitude and spectral centroid, and maps them to ARKit-52 blendshape weights. - Weights are applied directly to the loaded GLB's morph targets via
src/voice/avatar-morph-target.js— no scene re-render required. - The Empathy Layer injects its emotional morph weights in the same frame, so articulation and emotion blend simultaneously without fighting each other.
The driver is source-agnostic: it accepts any AudioBuffer, so it works identically with ElevenLabs, browser TTS, or a pre-recorded clip. The canonical ARKit-52 blendshape table lives in src/voice/arkit-blendshapes.js; per-rig binding (mapping standard names to the specific morph targets in a loaded GLB) is handled by src/voice/avatar-morph-target.js.
Demos Hub
three.ws/demos is a curated index of sandbox pages that exercise individual platform capabilities in isolation. Each demo is a single HTML file in public/demos/: perfect for screen recordings, bug reproductions, or showing off one feature without the rest of the app. Every path below is a live link.
The demos are intentionally separate from production routes (/create, /avatars/[id], etc.) so the production flow keeps working while we test new ideas.
Skill Library
The platform ships with a set of built-in agent skills, packaged in src/agent-skills-*.js and registered via public/skills-index.json.
Third-party skills are distributed over IPFS / Arweave / HTTP. See docs/skills.md for the full skill manifest spec and authoring guide.
Developer SDKs
Fifteen packages ship from this repo, all published to npm under the @three-ws scope. Install only what you need — each has its own README with a copy-paste quick start and a full API/tools reference.
Avatar & 3D
Agents & payments
MCP servers (run over stdio with one command — also in the official MCP registry)
Per-server deep dives (every tool, argument, env var, and example): Scenes · x402 Wallet · Intel · Vanity · Naming · Marketplace. Full catalog: docs/mcp.md.
@three-ws/sdk quickstart:
@three-ws/sdk also exposes AgentClient (x402 paid calls), PermissionsClient, and ERC-8004 registry helpers. See sdk/README.md, the SDK guide, and examples.
API Reference
The full OpenAPI 3.1 spec is available at /openapi.json. The key API surface is organized below.
Agent API
Avatar API
Three-step upload flow:
Widget API
Memory API
Chat & LLM
Cron Jobs
Cron schedules are declared in vercel.json (still the live cron/route config the server reads) and executed in production by Google Cloud Scheduler, which calls each endpoint on its schedule. All cron endpoints are fail-closed — a missing auth token aborts with an error rather than silently skipping (see Security Hardening).
The crons in vercel.json (139 entries on 2026-10-10) are routed through a single dynamic handler at api/cron/[name].js; the name segment selects the handler function. Scheduler jobs are provisioned from the vercel.json cron list via scripts/create-gcp-scheduler.mjs. The table below is a selection of the notable jobs, each schedule quoted verbatim from vercel.json; that file is the complete list.
Authentication & OAuth 2.1
three.ws supports three authentication methods:
1. Email + Password (Session cookie)
2. Wallet (SIWE / SIWS)
3. Developer API Keys
OAuth 2.1 Server (RFC 6749 + PKCE)
For third-party apps and MCP integrations:
Token scopes (the full list lives in api/_lib/oauth-scopes.js): avatars:read, avatars:write, avatars:delete, profile, offline_access, memory:read, memory:write, agents:read, agents:write, feedback:read, home:read, home:act, wallet:read, wallet:write, services:write. A bearer token is held to the scopes it was granted: every route that moves an agent's funds requires wallet:write, and a bearer can only mint an API key with scopes it holds itself.
Access tokens are short-lived JWTs (1 hour). Refresh tokens are opaque strings stored hashed in Postgres.
MCP Server
api/mcp.js is a thin HTTP entrypoint (POST / GET-SSE / DELETE) that implements the Model Context Protocol 2025-06-18 specification over JSON-RPC 2.0. The protocol logic is split across api/_mcp/: auth.js (Bearer/OAuth + x402 paywall), dispatch.js (JSON-RPC routing), catalog.js (dynamic tool catalog), payments.js (x402 paid-tool settlement), render.js, and embed-policy.js. Tools are registered per category under api/_mcp/tools/ (14 category modules: avatars.js, models.js, solana.js, pumpfun.js, animations.js, agents.js, garments.js, memory.js, oracle.js, trader.js, embed.js, sign.js, crypto-data.js, tokenize.js). External AI systems (including Claude Desktop, other agents, or custom integrations) can drive avatars programmatically through this surface.
Endpoint: POST /api/mcp (tools), GET /api/mcp (SSE), DELETE /api/mcp (session terminate)
Auth: OAuth 2.1 Bearer token or API key, with each tool checking its own scope (for example avatars:read, or avatars:delete for delete_avatar); some tools additionally require x402 USDC payment
Registry: Listed on the official MCP Registry as io.github.nirholas/three.ws, alongside the other three.ws servers published under the io.github.nirholas namespace (threews-3d-studio, threews-avatar, threews-pumpfun, threews-x402-bazaar, three-token-mcp, and more). Also discoverable on Smithery, Glama, and PulseMCP.
x402scan: view on x402scan — paid MCP tool calls and revenue
Available tools:
The catalog is assembled dynamically at request time from the per-category tool modules. Current tools:
Avatars (api/_mcp/tools/avatars.js)
Models (api/_mcp/tools/models.js)
Solana (api/_mcp/tools/solana.js) — all public, no auth required
Pump.fun (api/_mcp/tools/pumpfun.js)
Ten further category modules register the rest of the catalog: Animations (list_animations, animation_signature, find_similar_animations, apply_animation, text_to_animation), Agents (call_agent, register_agent, attach_avatar_to_agent, identity_check), Garments (generate_garment, garment_status, list_garment_catalog), Memory (remember, recall, forget), Oracle (oracle_top_plays, oracle_coin, oracle_arm_watch, oracle_watch_status), Trader (trader_leaderboard, trader_profile, copy_subscribe, copy_status), Embed (get_embed_code, create_gated_embed), Sign (list_sign_vocabulary, sign_text), Crypto data (crypto_data, token_snapshot), and Tokenize (mint_3d_asset, get_3d_asset_onchain).
MCP discovery: configured in .mcp.json at the repo root for Claude Desktop integration.
SSE stream: GET /api/mcp returns a Server-Sent Events stream for real-time notifications from long-running operations (validation, optimization).
Brain Proxy & LLM Routing
three.ws supports multiple LLM providers behind a single brain interface. The runtime is provider-agnostic: switch from Claude to GPT to Gemini to a local model with a one-line change. See it in the wild on the live chat surface at three.ws/chat (model selector, tools, skills, wallet).
[Chat with model selector, live]
Switching providers
Provider selection is per-agent and controlled by the manifest brain.provider field:
Supported provider values: anthropic · groq · openrouter · null (offline). Adding a new provider means implementing the two-method interface (chat() and stream()) in src/runtime/providers.js — no other files need to change.
Free-first routing policy
The platform's DEFAULT_PROVIDER_ORDER in src/llm.js ensures AI chat never fails silently due to a single quota: free tiers (Groq, OpenRouter :free models, NVIDIA) are always tried first; paid keys (Anthropic, OpenAI) are last-resort only. An OpenRouter fallback key is configured for :free models so that even a depleted primary account doesn't take down the /chat surface.
Owner-card gating
When an agent has a paying owner — established via ERC-8004 mint or x402 subscription — the embed unlocks:
- Longer context windows (up to 32k tokens per turn vs the anonymous 8k cap)
- Access to higher-tier models (Claude Sonnet / Opus vs Groq fallback)
- An owner-attribution card displayed below the avatar in the embed chrome
The gating check runs server-side in api/chat.js against the agent's subscription record in Postgres. It cannot be bypassed from the client — the model selection and context limit are applied at the API layer before the request reaches the LLM provider.
Claude Code Integration
three.ws ships as a first-class Claude Code SDK. There are two ways to integrate — pick one or use both:
1. MCP server (paid tools via npx)
Add the @three-ws/mcp-server to your Claude Desktop, Cursor, or Claude Code config in one step:
Once configured, Claude can call these tools directly in conversation — no API key required, each call is settled in USDC via x402:
See mcp-server/README.md for full environment variable reference and programmatic client usage.
2. Slash commands (marketplace/plugins/three-ws-developer/commands/)
This repo ships three Claude Code slash commands that work in any project referencing this repo:
Commands live in marketplace/plugins/three-ws-developer/commands/ and ship with the three-ws-developer plugin, so Claude Code picks them up once that plugin is installed.
Install in Claude Code
three.ws ships an official Claude Code plugin marketplace — install wallet, payments, pump.fun trading, agent scaffolding, and the 3D Forge as namespaced skills and MCP tools, in one command. Add the marketplace once:
Then install any of the four plugins:
Run /reload-plugins and the skills appear under each plugin's namespace (e.g. /three-ws-3d:forge-3d). Plugins that expose MCP tools (three-ws-developer, three-ws-3d) wire the published @three-ws/* MCP servers automatically — forge_free is free (no wallet); the paid lanes settle over x402 in USDC. The canonical manifest lives at .claude-plugin/marketplace.json.
Cloud Marketplaces
three.ws is available on major cloud marketplaces and open to infrastructure partnerships.
Ecosystem Directories
three.ws is indexed in chain-ecosystem dApp directories so the community can discover, vet, and rank it.
IBM watsonx & Granite
three.ws is an IBM Business Partner, and the agent runtime runs on IBM Granite foundation models served through IBM watsonx.ai. One IBM Cloud API key + project unlocks the whole suite; every call is real inference (no mock path: endpoints return 503 when unconfigured). Full docs: docs/ibm.md. Live showcase: three.ws/galaxy.
The public showcase is not the partnership. The demos under
/ibm/*are independent tools three.ws built for developers to explore Granite on watsonx.ai and build their own integrations — they are not official IBM partnership deliverables, not IBM products, and not endorsed by IBM. Our formal partnership work with IBM is being built on the IBM platform and is not yet public.
Three live surfaces put it on screen: the Agent Galaxy (every public agent embedded by Granite into a navigable semantic 3D star-map), the x402 Granite demo (pay-per-call Granite inference settled in USDC), and the hello-world embed. The backend endpoints behind them live in api/ibm/ (galaxy, oracle, twin, vision, attest). The standalone connector @three-ws/ibm-watsonx-mcp (npm) exposes watsonx.ai to any MCP host; it is community-built and not an IBM product. The hosted platform integration is what runs on IBM watsonx.ai.
Pay-per-call Granite over MCP (x402)
The world's first x402-enabled MCP server on IBM Cloud: @three-ws/ibm-x402-mcp turns IBM Granite into a metered utility any AI agent can call. The operator holds the IBM credentials and funds inference; the caller pays a few cents of USDC per call — no IBM Cloud account, no subscription, no API-key signup. Full guide: docs/ibm-x402-mcp.md.
The same five tools ship over two transports: stdio (npx @three-ws/ibm-x402-mcp, for Claude Desktop / Code / Cursor, paid on Solana) and Streamable HTTP (https://three.ws/api/ibm-mcp, for hosted clients and watsonx Orchestrate, paid on Base or Solana). An unpaid tools/call returns a 402 quoting the exact USDC price; x402-capable clients pay and retry automatically, settling on-chain only after the tool succeeds. Independent project integrating IBM Granite via watsonx.ai — not an IBM product.
x402 Payments
three.ws is a first-class x402 host. Agents can both pay for and expose paid endpoints. Settlement runs on Base, BSC, and Solana; the bazaar at three.ws/x402 is the discovery surface.
The x402 extension for VS Code brings that flow into the editor: browse the Bazaar, inspect a 402 challenge, and pay with $THREE or USDC on Solana. The $THREE contract address is FeMbDoX7R1Psc4GEcvJdsbNbZA3bfztcyDCatJVJpump. The setup guide covers secure wallet storage, token selection, confirmation, and settlement receipts.
Public proof: the server is listed on x402scan with its paid tool calls and revenue, and three.ws/pulse renders every settled agent-to-agent payment as it lands on-chain (hundreds of x402 settlements per day, live counters, real events only).
Payment rails
Every CDP-settled endpoint ships a Permit2 sibling that accepts an EIP-2612 permit instead of an upfront approval — the buyer signs once, and the relayer pays gas. Wire-level checks live in tests/e2e/ and exercise the buyer/seller flow end-to-end.
Paid endpoints
Bazaar, SKUs, and subscriptions
How to expose a paid endpoint
The helper handles the 402 challenge, Permit2 sibling, receipt write-back, idempotency-token enforcement, and CSRF/SSRF guards. Optional hooks: metered attaches a signed metered-job receipt to the response (the inference network's proof-of-work lane), and onSettled fires fire-and-forget after settlement (used for per-call skill royalty accrual). See api/_lib/x402-paid-endpoint.js.
Wire checks
- Wire-level CORS, CDP, and Permit2 sibling checks:
tests/e2e/ - Offer receipts schema + buyer fetch: api/_lib/x402-buyer-fetch.js
- Error envelope: full 402 body returned in the
PAYMENT-REQUIREDheader
A2A — Agent-to-Agent Protocol
Agents transact with each other directly through an A2A bridge that sits on top of the MCP server and x402 payments.
How it works
When agent A wants to call a paid tool from agent B:
- Discover — A resolves B's DID via
POST /api/x402/did, receiving B's MCP endpoint URL and payment wallet address. - Call — A sends a
tools/callJSON-RPC request to B's MCP endpoint. - Pay — B's server returns
402 Payment Requiredwith a USDC price. A's SDK settles the x402 payment on-chain (Base or Solana) and retries with the payment proof in theX-PAYMENTheader. - Execute — B verifies the payment, runs the tool, and writes a signed receipt to
api/a2a/receipts. - Ledger — Both sides accumulate a row in
api/a2a/spending— A for outbound spend, B for inbound revenue.
Agent wallets sign with EIP-7710 delegated permissions — the delegated signer acts on behalf of the agent's root key without ever exposing it.
SIWX (Sign-In with X-chain) brokers cross-chain identity for paid sessions: an agent on Base proves ownership of a Solana wallet (or vice versa) to unlock chain-specific paid endpoints.
On-Chain Identity (ERC-8004 + Metaplex Core)
three.ws supports two onchain identity paths as first-class peers — every reputation, attestation, and discovery surface reads from both, and SIWX brokers proofs between them so a single agent can hold reputation on both at once.
- EVM path — ERC-8004, a draft standard for verifiable 3D agent identity, deployed on Base, BSC, and other supported EVM chains. The
contracts/directory contains a full Foundry implementation (IdentityRegistry, ReputationRegistry, ValidationRegistry). - Solana path — Metaplex Core asset minted via the
solana-agent-sdk. No custom on-chain program is required: the asset pubkey is the agent ID, and feedback / validation events are written as on-chain memos that the indexer rolls up into a reputation score (see the Solana variant section below).
ERC-8004 (EVM)
ERC-8004 is a draft standard for verifiable 3D agent identity. The contracts/ directory contains a full Foundry implementation.
Contracts
IdentityRegistry.sol — the primary EVM contract. Each agent is an ERC-721 token with:
agentId— stable numeric ID (the token ID)owner— EVM address of the agent's ownerdelegatedSigner— optional secondary address for runtime signing (EIP-712 typed signature)tokenURI— IPFS URL of the agent manifest JSONmetadata— on-chain name, description, image pointer
On Solana, the equivalent identity is a Metaplex Core asset: the asset pubkey is the agent ID, the asset's update_authority is the owner, and the asset's URI points at the same IPFS-pinned manifest. No custom program is deployed — Metaplex Core handles mint, transfer, and update natively.
ReputationRegistry.sol — stores signed feedback scores. Each reviewer can submit one score per agent. Scores are averaged for an on-chain reputation metric. The Solana analog is an SPL Memo with envelope threews.feedback.v1, posted in a transaction whose accounts include the agent's Metaplex Core asset pubkey — readable by any client via getSignaturesForAddress.
ValidationRegistry.sol — records validator attestations for off-chain proofs (glTF validation reports, skill audits, security reviews). The Solana analog uses SPL Memo with envelope threews.validation.v1 against the agent's Metaplex Core asset pubkey.
Deployment Addresses
See contracts/DEPLOYMENTS.md for current mainnet and testnet addresses. All three registries are deployed via CREATE2 against a custom vanity-prefixed factory, so the same address is used on every supported EVM chain within an environment class — mainnet contracts have one address, testnet contracts another.
Mainnet (across Ethereum, Optimism, BSC, Gnosis, Polygon, Fantom, zkSync Era, Moonbeam, Mantle, Base, Arbitrum One, Celo, Avalanche, Linea, Scroll):
Testnet (BSC Testnet, Ethereum Sepolia, Base Sepolia, Arbitrum Sepolia, Optimism Sepolia, Polygon Amoy, Avalanche Fuji):
CREATE2 Factory (ThreeWSFactory)
A custom vanity-prefixed CREATE2 deployer at 0x00000000D49195AE81759cd247cFeDD9D0B479df (7 leading zeros) is used to mint matching addresses across chains. The factory init code hash is 0x30f9d9020bf9622bbe7f8a1625d447efe350dfafd0a91e6dbd62d56547db835f; bytecode is byte-identical on every deployed chain. Source is verified on each chain's explorer.
Audits & EAS
- Smart contract audits are scheduled for the reputation, royalty, and delegation contracts as part of Phase 3
- EAS (Ethereum Attestation Service) integration ships as a sibling reputation surface — see
/demos/eas-reputation.htmlfor the viewer - 0xsplits SDK is wired for splitting skill royalties across multiple authors
Registration Flow (EVM)
The agent is now an ERC-721 token. Its manifest lives on IPFS. Its action history is anchored to its agentId. Any third party can verify the agent's identity, owner, and reputation without trusting three.ws.
Registration Flow (Solana)
Solana ships an ERC-8004 analog without any custom on-chain program — identity is a Metaplex Core asset, reputation + validation are SPL Memo–anchored attestations referencing that asset.
The agent is now a Metaplex Core NFT. Its asset pubkey is the canonical agent ID. Anyone can read every feedback / validation attestation about it via getSignaturesForAddress(assetPubkey) — see Solana variant — same shape, no deployed program below.
On-Chain Indexing
api/cron/erc8004-crawl.js runs every 15 minutes to index new IdentityRegistry mint events. Indexed agents appear in /discover and can be imported via /hydrate.
Solana variant — same shape, no deployed program
Solana ships an ERC-8004 analog without any custom on-chain program:
- Identity — Metaplex Core NFT minted via
registerSolanaAgent()(the asset pubkey is the agent ID). - Reputation + Validation — signed SPL Memo transactions referencing the agent asset pubkey, with a JSON envelope (
threews.feedback.v1/threews.validation.v1). Anyone can read every attestation about an agent viagetSignaturesForAddress(assetPubkey).
SDK:
Server read endpoint: GET /api/agents/solana-attestations?asset=<pubkey>&kind=feedback|validation|all&network=devnet|mainnet.
Demo page: sdk/example/solana-attest.html.
Pump.fun signals (Solana off-chain reputation)
Solana agents can ingest live pump.fun activity (GitHub social-fee claims, token graduations) as off-chain trust signals that feed into the agent's Solana reputation score and surface through the Empathy Layer in real time.
The crawler runs on a */15 * * * * schedule (see vercel.json) and writes into the pumpfun_signals table. Agents subscribed via watch-start react to incoming events through the existing protocol bus — no new event types required.
Full design and configuration in docs/solana-pumpfun.md.
Pump.fun Integration
Beyond the Solana reputation signals described above, the platform also ships consumer-facing pump.fun tooling:
- Pump.fun Stream (live at three.ws/pumpfun): a live feed of every launch, trade, graduation and fee claim with a reacting, optionally narrating 3D agent, source in public/pumpfun.html. Its "Launch a coin" button opens the launcher at three.ws/launch.
- Live Dashboard (live at three.ws/pump-live): real-time tracker for new tokens, source in pages/pump-live.html.
- Skills — the pump-fun-skills/ directory contains agent skills for reading and acting on pump.fun.
Token launcher (USDC v2)
The launcher uses pump.fun's v2 USDC quote payload and supports a creator-signer split — the agent's owner can authorize a delegated signer to publish the token without exposing the root key.
Pump-swap buyback
A buyback flow lets an agent route revenue from x402 paid endpoints into pump-swap purchases of its own token — closing the loop between paid usage and tokenholder value. See scripts/pump-launch-usdc.mjs and the inaugural-launch self-contained prompts in docs/internal/.
Pump visualizer
three.ws/pump-visualizer is a live view of pump.fun activity with three modes:
The visualizer supports search, sort, live pulses, and auto-refresh. Backed by the same Helius webhooks and JSON-RPC client as the cron crawler.
Pump.fun MCP edge worker
For external agents that need pump.fun data with strict latency, a Cloudflare Worker mirror of the read API lives in workers/pump-fun-mcp/. Deploy with wrangler deploy — the worker proxies the upstream pumpfun-claims-bot and answers MCP tools/call requests at the edge.
Channel & Telegram bridge
Vanity mint addresses
The platform's pump.fun launches pre-grind vanity mint addresses with the WASM grinder so token addresses end in a brand-relevant suffix (…pump, …ws, etc.). See WASM Vanity Grinder.
WASM Vanity Grinder
three.ws/vanity-wallet is a browser-based vanity-address grinder compiled to WebAssembly. Generate EVM addresses with a prefix (0xBEEF…) or pattern, or Solana addresses (base58 prefix / suffix, e.g. …pump) in seconds, fully client-side, without leaking the private key to any server.
[Vanity wallet generator, live]
Common use cases on the platform: branded agent wallet addresses (e.g. an agent named agent.eth getting an address starting with 0xA6EF…), or pump.fun token mint vanity (e.g. ending in pump).
The Solana grinder backs the platform's pump.fun launches — the inaugural USDC token launches use a vanity mint pre-grind to produce shareable token addresses.
Solana Mobile (Seeker)
three.ws ships with Mobile Wallet Adapter (MWA) wired into the web app and a release pipeline for the Solana Mobile dApp Store.
Wallet detection priority
On Seeker / Saga hardware the app prefers seed-vault-backed signing — private keys never leave the secure element. On standard Android or desktop, the app falls back through WalletConnect and then to browser-extension wallets automatically, with no code change required.
What MWA unlocks on Seeker hardware
- x402 USDC payments signed from the seed vault without any browser extension
- Metaplex Core agent mints (Solana on-chain registration) without leaving the app
- SPL Memo attestations (reputation and validation) with hardware-secured signatures
- SIWS (Sign-In with Solana) sessions authenticated at the chip level, not the software layer
Release pipeline
- dApp Store listing copy and release config live under
solana-mobile/publish/ - Release pipeline scripts handle build → sign → APK submission for dApp Store updates
- The listing targets Seeker-first and is compatible with Saga Gen 1 and Gen 2
Vision
One day, creating your agent should be as simple as taking a selfie.
Point your camera at yourself — or anyone — and watch a fully realized 3D avatar emerge: your face, your voice, your personality, alive in the browser. That avatar becomes an agent with memory and skills, registered onchain — as an ERC-8004 token on EVM or a Metaplex Core asset on Solana — permanent and verifiable by anyone forever. No 3D software. No wallet setup. No uploads. Just a photo and a name.
This is the direction three.ws is heading: photo → avatar → agent → onchain identity, in a single flow. The infrastructure is already here — the viewer, the runtime, the contracts, the embedding layer. What comes next is closing the gap between a picture of a person and a living, ownable, embeddable piece of them that exists on the internet permanently.
Roadmap
three.ws ships in five phases. Each phase closes a specific gap between the current platform and the end-state vision: anyone can mint a 3D agent of themselves, own it onchain, and embed it anywhere on the internet.
Phase 0 — Foundations (Shipped)
The full stack is live at three.ws: WebGL viewer, LLM agent runtime, ERC-8004 identity contracts (EVM) and Metaplex Core mints (Solana), OAuth 2.1 server, MCP endpoint, and the <agent-3d> web component. Anyone can register an agent today — but the avatar still has to come from a 3D artist or a third-party tool.
What works: model upload, agent runtime, onchain registration, embedding, signed action history, reputation scores. What doesn't: there is no automated path from a real human face to a usable 3D avatar.
Phase 1 — Selfie → Avatar Engine
Goal: any user takes 3 selfies (left, center, right) and receives a rigged, animatable 3D avatar in under 60 seconds.
Deliverables
- Mobile-first capture UX with realtime quality gates (lighting, framing, blur). Shipped: src/selfie-capture.js, src/selfie-gates.js
- Multi-view face reconstruction pipeline (landmark fitting on top of a base body mesh). Shipped: workers/avatar-reconstruction morphs a rigged template head to the person's 468 MediaPipe landmarks and projects the photo onto its skin
- Hosted inference workers for sub-minute generation. Shipped on Cloud Run: submission, job status, the rig chain, and the abandoned-tab backstop are all live (see Reconstruction backend below)
- Output written directly to R2 and minted as a draft agent token: ERC-8004 on EVM, Metaplex Core asset on Solana. Shipped: api/_lib/reconstruct-finalize.js
Open track: likeness fidelity, measured by Identity Shape Error rather than by eye. The metric, the reference set and the adversarial set live in workers/avatar-reconstruction/eval; the program plan is docs/avatar-fidelity-program.md.
Reconstruction backend: selfie → rigged GLB
The path a capture actually takes, end to end. Each hop is a real service; nothing here is stubbed.
Compute requirements
- A100/H100-class GPUs for inference, sized to ~10k avatars/day at launch
- Training budget for fine-tuning a stylized face-fitter on a curated dataset
- CDN egress scaling for high-res GLB delivery
Verification: 1,000 test users complete capture and mint an onchain agent of themselves end-to-end with ≥4/5 likeness score.
Phase 2 — Agent Personalization
Goal: the avatar isn't just you — the agent acts like you.
Deliverables
- Voice cloning (30+ seconds of speech → ElevenLabs custom voice bound to the agent)
- Persona extraction from a short onboarding interview (tone, vocabulary, interests)
- Memory seeding from connected accounts (X, GitHub, Farcaster) with explicit user consent
- Per-agent fine-tuned system prompt stored in the manifest, signed and pinned to IPFS
Verification: users return to converse with their own agent; ≥30% week-2 retention on minted agents.
Phase 3 — Onchain Economy
Goal: agents are real economic objects on EVM and Solana, not just collectibles.
Deliverables
- Agent tokens — ERC-8004 mints with bonding-curve pricing or fair launch options
- Reputation markets — stake on agents, earn from their action history (extends
ReputationRegistry.sol) - Skill royalties — skill authors earn per-call fees through EIP-7710 delegated permissions
- Agent-to-agent payments — agents transact autonomously via their delegated signer wallets
- Subscriptions & DCA — recurring onchain payments to creators (cron infra already in place)
Funding requirements
- Smart contract audits (multi-firm) for the reputation, royalty, and delegation contracts
- Liquidity for agent token launches
- Indexer infrastructure across Base, Solana, and additional EVM chains
Verification: ≥1,000 agents minted with active onchain reputation; ≥$X in cumulative skill royalties paid out.
Phase 4 — Open Inference Network
Goal: decouple agent inference from any single provider. Anyone can run a node; agents pay nodes onchain for compute.
Deliverables
- Open protocol for agent inference (model weights, GPU runtime, signed responses)
- Node operator client (Docker + GPU drivers) with onchain registration
- Onchain settlement for inference jobs — pay-per-token with cryptographic receipts
- Federation with existing decentralized compute networks where appropriate
Shipped so far: anyone can run a node today. The packages/node-operator/ client registers with the coordinator using a signature under its own Solana ed25519 key (no shared secret to leak), claims jobs from the /api/nodes queue, executes them with a real open model on CPU or CUDA, and returns results signed over a canonical receipt binding job, model, and input/output hashes, which the coordinator recomputes before accepting. npm run e2e in that package proves the whole loop against the real handlers. Paid inference on /api/x402/llm-proxy settles through the metered hook on the x402 paid-endpoint wrapper, and POST /api/x402/inference-verify publishes the platform signing key so receipts verify offline. Wire contract: specs/inference-nodes.md. Operator guide: docs/inference-node-operator.md.
Compute requirements
- Bootstrap GPU credits for early node operators
- Cryptoeconomic security model (slashing, validator set) — research + audit budget
Verification: ≥50% of production agent traffic served by independent node operators; latency parity with centralized inference.
Phase 5: Native Widgets
Goal: your agent lives on the home screen, not only in a browser tab. A glanceable widget that shows the agent you own, one live number about it, and a single tap back into the app.
This is a different product from the embeddable web widgets at three.ws/widgets, which put a 3D agent on someone else's web page. Phase 5 is about the operating system surfaces: the Android home screen, the Windows 11 widgets board, and the macOS and iOS widget galleries.
Why it is next. The Android shell already exists. three.ws ships as a signed Trusted Web Activity (ws.three.app) for the Solana dApp Store, Digital Asset Links verify against the live release key, and deep links, shortcuts and the share sheet already open the app. A widget is the piece that makes the app worth keeping installed between visits. The render side exists too: POST /api/render/avatar-clip already produces a posed, camera-framed PNG of any avatar from the headless renderer, which is exactly the image a widget needs, because no widget runtime on any of these platforms can execute WebGL.
Order of delivery
Deliverables
- ✅ A cacheable card endpoint, /api/glance/card, serving one model as JSON, SVG, PNG and Adaptive Card, plus /api/glance/mine for the owner's own agent, authenticated by the session cookie or by a widget's own bearer token, and answering every state (signed out, widget unlinked, no agent yet) as a designed card rather than a 401. Spec: specs/GLANCE_CARD.md
- ✅ Windows 11 widget through the PWA manifest, so it installs with no separate store submission, degrading to the last cached card when the machine is offline and to a sign-in card when nobody is signed in
- ✅ Card content that is worth a home screen slot: the agent, one live number (actions in the last 24 hours), its last action, and a direct way back in
- ✅ A playground and install guide at /glance, and an npm client, @three-ws/agent-glance, with a terminal renderer
- ✅ Android app widget in two layouts (2x2, and 4x2 / 4x3), refreshed by WorkManager on a battery-aware schedule, degrading to the last cached card when the device is offline
- A native shell for Apple platforms, which is also the prerequisite for an iOS build of three.ws
Verification: a widget installed from the Android app updates without opening the app, survives a reboot and airplane mode, and returns the user into the right screen on tap. The Apple half is one WidgetKit extension over the same endpoint, shared by a Mac menu bar app and the iPhone app; npm run check:apple-widget holds its two Xcode projects and its wire contract honest without a Mac. Product doc: docs/native-widgets.md. Sources: apple/.
What we need
Phases 1 and 2 unblock the consumer story — anyone gets an agent of themselves. Phases 3 and 4 unblock the onchain story — those agents are real economic actors that don't depend on any one company to keep running. Both are required for the vision; neither is funded yet.
If you want to support the project — compute credits, grants, partnerships, or contributions — open an issue or reach out via three.ws.
Selfie Reconstruction Pipeline (Phase 1)
Anyone takes 3 selfies (left, center, right) and receives a rigged, animatable 3D avatar in under a minute. The pipeline ships native — no third-party black box.
Reconstruction inference runs against the same Cloud Run handler pool as the agent runtime, with optional offload to the Livepeer Inference Network (see below) for GPU-heavy steps.
Voice & Persona Hub (Phase 2)
The avatar isn't just you — the agent acts like you. The Voice & Persona Hub captures the inputs that turn a body into a personality.
Memory seed extensions (X, GitHub, Farcaster) feed the agent's memory store at creation time with explicit user consent — see docs/persona-hub.md.
The per-agent fine-tuned system prompt is stored in the manifest, signed, and pinned to IPFS — the persona becomes a verifiable part of the agent's onchain identity.
Livepeer Inference Network (Phase 4)
three.ws wires the Livepeer decentralized GPU network as an alternative inference backend alongside the platform's own open inference network.
- Open protocol: model weights, GPU runtime, signed responses
- Onchain settlement: pay-per-token with cryptographic receipts, mediated by the same x402 rails described above
- Node operator client (Docker + GPU drivers) with onchain registration
- Federation with existing decentralized compute networks where appropriate
Federation is live behind a flag: with LIVEPEER_FEDERATION_ENABLED set, the text-to-image chain can route one GPU job class to Livepeer gateways (runbook: docs/ops/livepeer-federation.md). The goal: ≥50% of production agent traffic served by independent node operators with latency parity to centralized inference.
News & Syndication
News posts live in the repo (data/rss/items.json) and ship with a deploy; the former in-app CMS was removed with the admin panel.
Security Hardening
The platform has been hardened against the OWASP top-10 plus a set of issues specific to agent payments and cross-chain identity.
Database Schema
The Postgres schema (api/_lib/schema.sql) is fully idempotent — every CREATE TABLE uses IF NOT EXISTS, so the file is safe to re-run on any environment. Per-feature migrations live under api/_lib/migrations/ and are applied with npm run db:migrate.
The schema currently defines ~53 tables grouped below. Columns shown are the most commonly queried ones; the source file is authoritative.
Core identity & content
OAuth 2.1
Wallet & signing
Authentication extras
Widgets
ERC-8004 / EVM indexing
Solana attestations & registration
Marketplace, skills & royalties
Subscriptions, DCA & payments
Usage & quotas
Build & Deployment
npm Scripts
Claude CLI
scripts/claude.sh (aliased as npm run claude) wraps the npm scripts above with confirmation prompts on destructive commands (deploy, db-migrate). Useful when you want guard-rails or a single entry point for an agent to drive.
Production Deployment (Google Cloud Run)
Production runs on Google Cloud Run (three-ws-api, region us-central1): one Express container (server/index.mjs) serves the static frontend, the vercel.json route table, and every api/** handler, fronted by a global HTTPS load balancer + Cloud CDN. Deployment is two steps, build then submit, from a clean deploy worktree (npm run prep:worktree -- --apply):
npm run deploy:gcp runs deploy:gcp:submit (the migration gate db:check and the upload and import checks, then gcloud builds submit --config server/cloudbuild.yaml), then deploy:gcp:sync-crons, which creates a Cloud Scheduler job for any newly declared cron, then a synchronous CDN purge and smoke:prod. npm run deploy:gcp:full is the build and the deploy in one command. Routing, cache headers, and cron schedules are defined in vercel.json, which the server reads at runtime. The scheduled jobs (one per entry in the crons array of vercel.json) run on Cloud Scheduler (provisioned by scripts/create-gcp-scheduler.mjs); the GPU inference workers run as their own Cloud Run services. Full ops runbook (load balancer, DNS/TLS, env, rollback, recovery): docs/ops/gcp-production.md.
Environment variables live on the Cloud Run service, not in .env files — inspect or update them with gcloud run services describe/update three-ws-api --region us-central1. See Environment Variables for the full list.
Self-Hosting
For a traditional server deployment:
- Build:
npm run build→dist/ - Serve
dist/as static files (nginx, Caddy, Express) - Run
api/endpoints via Node.js (serve them with the Express container in server/index.mjs, same as production) - Connect to Postgres (Neon or self-hosted)
- Connect to S3-compatible storage (R2, MinIO, AWS S3)
- Schedule cron jobs with node-cron or systemd timers
Minimal nginx config:
Versioning & Compatibility
three.ws follows Semantic Versioning. The authoritative version lives in package.json; the current release is reflected in the badge at the top of this README.
What "stable" means
Pinning recommendations
- For production embeds, pin to the patch version (
/agent-3d/1.5.2/agent-3d.js) and bump deliberately. - For prototypes, pin to the major (
/agent-3d/1.x/agent-3d.js) so you receive bug-fixes automatically. - For agent manifests, always set the
specfield — the loader rejects manifests with an unknown spec rather than guessing. - For API consumers, request
application/jsonand inspect the responseversionheader (present on every endpoint).
Deprecation policy. Stable surfaces get a deprecation notice in the changelog plus a runtime warning for at least one minor release before removal. Anything marked unstable in the table above may change at any time.
Environment Variables
Required (Backend)
Optional (Backend)
Multiplayer / game server. The Colyseus server in
multiplayer/reads its own config —PLAY_GATE_MINT/PLAY_GATE_MINandHOLDER_PASS_SECRETfor the play-gate, andGAME_TOKEN_MINT/GAME_TOKEN_TREASURY/GAME_TOKEN_BURN/GAME_TOKEN_SECRETfor the in-game $THREE economy. These belong to the game server's environment, not the Cloud Run handler pool.
Optional (Frontend, prefixed VITE_)
Testing
npm run test runs Vitest (unit + integration) followed by Playwright (end-to-end). API tests stub the database and auth layer; frontend tests stub the viewer. The project currently has ~1,500 test files spread across tests/, tests/api/, tests/src/, and tests/e2e/.
Representative Vitest coverage (full inventory under tests/):
Playwright end-to-end smokes
Browser-driven smokes live in tests/e2e/ and run against the local dev stack (Vite + the api/ handlers). They cover user-visible flows that don't fit in Vitest.
Run with npx playwright test (or npm run test:e2e). Configuration in playwright.config.js; results in test-results/ (gitignored).
Smart contracts
Smart contract tests are in contracts/test/ and run via Foundry:
CREATE2 vanity grinds for the multichain factory and payment contracts are recorded in contracts/DEPLOYMENTS.md.
FAQ & Troubleshooting
Does three.ws require a wallet to use?
No. The viewer, agent runtime, manifest editor, and /app work without a wallet or an account. A wallet is only required for on-chain registration (ERC-8004 mint, Solana Metaplex Core mint) and for paid surfaces (x402 endpoints, agent token launches).
Does my GLB get uploaded anywhere? Not unless you explicitly choose to publish or register the agent. Drag-and-drop in the viewer is fully client-side — the file never leaves the browser. The "Publish" and "Register" flows are the points where the GLB is uploaded to R2.
Which LLM does the agent use?
The default is Anthropic Claude (claude-sonnet-4-6 for production, claude-haiku-4-5-20251001 for low-cost development). Brain routing is configurable per-agent through the manifest and via the brain attribute on <agent-3d>. Other providers can be wired in by extending src/runtime/providers.js.
Can I run three.ws fully offline?
Yes for the viewer, no for the agent runtime. With sandbox set on <agent-3d> the element refuses all network calls; you can still load a local GLB, play animations, and exercise the manifest. The LLM brain, voice, and on-chain features require network connectivity.
Why does the avatar appear black or all-white?
Usually a missing HDR environment or a material that expects an environment map. Confirm the GLB has a default scene, that the lighting attributes (exposure, env) are set, and that your build has access to public/env/ (the HDR assets ship there). For all-white avatars, check that morph targets aren't being zeroed by an empty emotion mix.
The agent never speaks back. What's wrong?
Most often the chat input isn't reaching the brain. Check (in order): (1) the brain attribute or manifest.brain is set; (2) the network panel shows a POST /api/chat (or the configured proxy) succeeding; (3) the response body isn't blocked by a Content Security Policy; (4) TTS is supported and not muted at the OS level. If running locally, set ANTHROPIC_API_KEY in .env.local.
Why does microphone capture fail on my deployment?
getUserMedia requires HTTPS. Localhost is exempt; any remote deployment needs TLS. Vercel and Netlify provide it automatically. Self-hosted deployments must terminate TLS in front of the app.
How big can a GLB be?
Hard ceiling: 50 MB before the loader refuses (configurable via the maxBytes attribute). Soft target: ≤8 MB for sub-3-second cold start over a typical broadband connection. Run npx gltf-transform draco input.glb output.glb and npx gltf-transform ktx output.glb output.ktx2.glb to compress aggressively without visual loss.
Can I host the web component on my own CDN?
Yes. Run npm run build:lib and serve the resulting dist-lib/agent-3d.js from anywhere. Update the <script> tag in your embed snippet accordingly. The element has no hard-coded origin assumption — it only contacts the backend you point its manifest/brain attributes at.
How do I rotate JWT_SECRET without invalidating sessions?
Increment JWT_KID and add the new secret. Existing tokens continue to validate against the old kid; new tokens sign with the new one. Drop the old kid from rotation after the session window (default 30 days) expires.
Where do I get help?
- Bugs and feature requests: open a GitHub issue
- Security: see Reporting Security Issues
- Discussion and showcase: GitHub Discussions
- Live status: three.ws
Community
three.ws is built in the open. Pick the room that fits what you want to do.
Guidance on which channel suits which question, plus the house rules, lives in docs/community.md.
Want to contribute? Your first contribution goes from clone to open pull request in about 15 minutes with a complete worked example, and good first issue is a curated list where every entry names the file to change and the command that proves it worked. How we triage and how fast you can expect a response: docs/triage.md.
Contributing
See CONTRIBUTING.md for the full contributor guide. Contributors are expected to follow the Contributor Covenant Code of Conduct in every project space — issues, pull requests, discussions, and any community channel that links to this repository.
Quick rules:
- Match existing style — no reformatting adjacent code
- Every changed line should trace to the task
- Add tests for new API endpoints
- Run
npm run verifybefore opening a PR (Prettier + build check) - Keep PRs focused — one concern per PR
Branch conventions:
feat/...— new featuresfix/...— bug fixesrefactor/...— structural changes without behavior changesdocs/...— documentation only
Development tips:
- The viewer runs standalone at
/app— no auth, no backend required - Use
mode=viewin the<agent-3d>element to test rendering without a brain - Set
CHAT_MODEL=claude-haiku-4-5-20251001locally to keep API costs low during development - The MCP server can be tested with
curl— it's plain JSON-RPC over HTTP
Reporting Security Issues
Please do not file public GitHub issues for vulnerabilities. Disclosure runs on a coordinated timeline so users get a fix before details circulate.
- Email [email protected] or open a private GitHub security advisory, with a clear write-up: affected component, reproduction steps, and the impact you observed.
- You will receive an acknowledgement within two business days.
- We aim to ship a fix or mitigation within 30 days for high-severity reports, and to credit reporters in the release notes (unless you ask to remain anonymous).
The current threat model and hardening notes live in specs/SECURITY.md and docs/security.md. The Security Hardening section above summarises the in-tree controls.
In-scope: this repository and its deployed surfaces (three.ws including the /cdn/ asset route, and *.three.ws). Out-of-scope: third-party services we integrate with (Google Cloud, Neon, Cloudflare R2, Upstash, Privy, Anthropic, ElevenLabs, pump.fun) — please report directly to them.
Contributors
Thanks to everyone improving three.ws through code, reviews, bug reports, and design ideas. The living roll is on three.ws/contributors, with commit-level history in GitHub's contributors graph.
Special thanks to @Victoriaali04 for the precise Forge photo-upload report in issue #164. Its timestamps, request sequence, and redacted R2 signature evidence led directly to better storage health checks and an honest retryable error instead of a misleading “network error.”
Want your name there? A contribution is more than a commit: open a PR, report a reproducible bug, improve the docs, or bring a design question that makes the platform better. See Contributing.
License
three.ws is open source under the Apache License 2.0. You may use, modify, distribute, and build commercial products on it, including in closed-source work, provided you keep the license and attribution notices and state what you changed. Apache-2.0 also carries an explicit patent grant from every contributor, which matters for the on-chain contracts in this repository.
Contributions are accepted under the same license; see CONTRIBUTING.md.
Vendored third-party code keeps its own license. Attribution for derived code and assets lives in character-studio/LICENSE, src/scene-studio/vendor/LICENSE, public/animations/LICENSES.md, and the per-asset LICENSES.md files under public/club/.
Support the project
If three.ws saves you time, star it on GitHub. Stars are how other developers and AI agents find the repositories worth trusting, and they cost you one click.
Know someone who would use it? Post on X · Share on Bluesky · Share on LinkedIn · Submit to Hacker News · Share on Reddit
Built for AI agents too
Coding agents and LLM tooling can read this repo directly: AGENTS.md, llms.txt, llms-full.txt. Point an agent at https://github.com/nirholas/three.ws and it has the context it needs.
More from the same author
- All repositories by nirholas: the full catalog, grouped by topic
- three.ws: the platform for 3D AI agents with Solana wallets, a skill marketplace and x402 payments
- Questions or ideas: open an issue or start a discussion
Contributors
Star history
Source: README.md at commit 0e68f46
Tools
0Version history
1- v1.0.0LatestOct 10, 2026
