arielshad/3d-asset-server

★ 221⑂ 19

3d assets api and mcp

About arielshad/3d-asset-server

arielshad/3d-asset-server is an open-source project on GitHub, mainly written in TypeScript. 3d assets api and mcp It currently holds 221 stars and 19 forks with 0 open issues, and was last pushed on an unknown date (repository created unknown).

Project Overview

AI Homed tracks it on the Today's Trending board, currently at rank #76 with 0 new stars today.

GitHub Repository Details

Repository arielshad/3d-asset-server · default branch - · size 0 KB · watchers 0 · source: GitHub REST API and repository README

README

       +------------+
      /            /|      _____ ____       _                 _
     /            / |     |___ /|  _ \     / \   ___ ___  ___| |_
    +------------+  |       |_ \| | | |   / _ \ / __/ __|/ _ \ __|
    |            |  |      ___) | |_| |  / ___ \\__ \__ \  __/ |_
    |            |  +     |____/|____/  /_/   \_\___/___/\___|\__|
    |            | /       ____
    |            |/       / ___|  ___ _ ____   _____ _ __
    +------------+        \___ \ / _ \ '__\ \ / / _ \ '__|
                           ___) |  __/ |   \ V /  __/ |
                          |____/ \___|_|    \_/ \___|_|

one search box for 3D models, materials, textures, HDRIs & game assets HTTP API MCP server web UI * CLI

3d-asset-server searches 19 asset sites at once and downloads what you pick, ready to drop into a game or a website. Use it from a browser, from curl, from the command line, or let your AI assistant drive it over MCP.

"I need a low-poly tree pack, a mossy rock material and a sunset HDRI for my Three.js scene."
> Your assistant calls search_assets three times, shows you the options with their licences, and
download_asset puts glTF, textures and the HDRI into your project's assets/ folder.
PBR maps at the resolution you ask for, HDRIs, or zipped packs (extracted for you). must credit the author. so you still know where else to look.

---

Contents

---

How it works

   +-----------+   +-----------+   +-----------+   +-----------+
   |  Web UI   |   |   curl /  |   |  Claude,  |   |    CLI    |
   | (browser) |   |  your app |   |  Cursor.. |   |           |
   +-----+-----+   +-----+-----+   +-----+-----+   +-----+-----+
         |               |               |               |
         |   GET /       |  /v1/*        | MCP           | search
         |               |               | stdio or /mcp |
         v               v               v               v
   +-----------------------------------------------------------+
   |                      3d-asset-server                      |
   |                                                           |
   |   +-----------------+   +-------------------------------+ |
   |   |  REST API (Hono)|   |  MCP tools                    | |
   |   |  /v1/search     |   |  search_assets   get_asset    | |
   |   |  /v1/assets/..  |   |  download_asset  list_provid..| |
   |   +--------+--------+   +---------------+---------------+ |
   |            |                            |                 |
   |            +-------------+--------------+                 |
   |                          v                                |
   |   +-------------------------------------------------------+
   |   |  AssetService                                         |
   |   |   fan-out --> per-site timeout --> rank --> dedupe    |
   |   +-------------------------------------------------------+
   |                          |                                |
   |   +----------------------+--------------------------------+
   |   |  HTTP client: User-Agent, timeouts, LRU cache,        |
   |   |  in-flight request dedupe                             |
   |   +-------------------------------------------------------+
   +-----------------------------+-----------------------------+
                                 |
         +-------------+---------+---------+-------------+
         v             v                   v             v
   +-----------+ +-----------+       +-----------+ +-----------+
   | API       | | scrape    |  ...  | scrape    | | link-only |
   | Poly Haven| | Kenney    |       | itch.io   | | Fab       |
   | ambientCG | | TextureCan|       | HDRI Hub  | | Poliigon  |
   | BlenderKit| | Quaternius|       | ...       | | TurboSquid|
   +-----------+ +-----------+       +-----------+ +-----------+

What a single search does:

  "sunset" type=hdri free=true
           |
           v
  +------------------+   skip sites that don't carry HDRIs, or are paid-only
  |   pick sources   |-----------------------------------------------------+
  +--------+---------+                                                     |
           |  in parallel, each with its own timeout (default 12s)         |
     +-----+------+------------+------------+------------+                 |
     v            v            v            v            v                 v
  Poly Haven   ambientCG   BlenderKit    HDRMaps     Poliigon        cgbookcase,
   ok 24        ok 24        ok 24        ok 12      link ->         kenney, ...
     |            |            |            |            |            skipped
     +------------+-----+------+------------+            |
                        v                                 |
  +---------------------------------------------+         |
  | rank:  60% text match (title > tags > desc) |         |
  |        20% the site's own ranking           |         |
  |        10% API > scrape                     |         |
  |        +free  +direct download              |         |
  |        diversity penalty per site           |         |
  +---------------------+-----------------------+         |
                        v                                 v
           results[]  +  per-site report (ok / error / timeout / skipped / link)

A slow or broken site never fails the search. It shows up in the per-site report with its error and a link to the same search on that site.

---

Sources

| Source | Best for | Search | Direct download | Licence | |---|---|---|---|---| | Poly Haven | HDRIs, PBR textures, scanned models | API | yes: glTF / blend / fbx, maps, HDR / EXR | CC0 | | ambientCG | Realistic materials, HDRIs, models | API | yes: per-resolution zips | CC0 | | CGBookcase | PBR textures | API (catalogue) | no: hotlink-protected CDN, links to the download page | CC0 | | ShareTextures | Textures and realistic models | API (tag search) | no: its licence forbids automated downloads | CC0 + site terms | | BlenderKit | Blender assets of every kind | API | yes for free assets (GLB / blend); paid ones need BLENDERKIT_API_KEY | CC0 / royalty free | | Fab | Game assets, environments, characters | link only (bot wall) | no | per listing | | Kenney | Low-poly 3D, 2D, UI and audio packs | scrape | yes: pack zips, auto-extracted | CC0 | | Poliigon | Premium materials and models | link only (bot wall) | no | per listing | | Quaternius | Low-poly models, animated characters | scrape | no: Google Drive / itch.io links | CC0 / QAL | | Polyfork | Low-poly models and themed kits for web and games | API | yes for free assets (GLB from Polyfork's CDN); FBX / USDZ / OBJ need an account | royalty free, no redistribution | | 3DTextures.me | Realistic and stylized PBR | WordPress API | no: Google Drive folders | CC0 | | 3DTexel | PBR materials, HDRIs, decals, 3D assets | API | no: downloads need a free account | CC0 | | TextureCan | PBR materials and a few models | scrape | yes: 1K-4K zips | CC0 | | Textures.com | Photo textures, 3D foliage, decals, skies | JSON API | no: credit system | Textures.com licence | | HDRMaps | HDRIs and backplates | WooCommerce API | yes for free HDRIs (EXR) | royalty free | | HDRI Hub | HDRI environments | scrape | no: checkout | royalty free | | CGTrader | Free and paid models | JSON listing | no: login | per listing | | TurboSquid | Free and paid models | link only (bot wall) | no | per listing | | itch.io | Indie art, 3D packs, UI, audio | scrape | no: itch's download flow | per listing |

  search + direct download    Poly Haven, ambientCG, BlenderKit (free), Kenney,
                              Polyfork (free), TextureCan, HDRMaps (free)

search + link to the page CGBookcase, ShareTextures, Quaternius, 3DTextures.me, 3DTexel, Textures.com, HDRI Hub, CGTrader, itch.io

link to the site's search Fab, Poliigon, TurboSquid

Notes:

from home connections. On a server, run behind a proxy with NODE_USE_ENV_PROXY=1. When it is blocked, the report says so and links to CGTrader's own search. keep working. npm run test:live checks every site.

---

Quick start

Needs Node.js 20 or newer.

git clone https://github.com/arielshad/3d-asset-server.git
cd 3d-asset-server
npm install
npm run build

npm start # web UI + HTTP API + MCP on http://localhost:8787 node dist/cli.js mcp # MCP over stdio, for Claude Desktop / Claude Code / Cursor node dist/cli.js search "low poly tree" --type model --free

With Docker:

docker build -t 3d-asset-server .
docker run -p 8787:8787 3d-asset-server

---

Web UI

Live at **, or run npm start and open .

The website lives in web/: Astro with React islands, Tailwind CSS 4, shadcn/ui and Magic UI components. Every page is pre-rendered HTML, so search engines and AI crawlers see the full content; only the interactive parts hydrate.

| Page | What it is | |---|---| | / | Landing page: hero search, sources, agent setup, FAQ | | /search | The search app: type chips, free/direct-download switches, source picker, per-site status, detail sheet with format/resolution picker, download, curl and agent snippets | | /docs | Quick start | | /docs/mcp | Setup for Claude Code, Cursor, VS Code, Windsurf, Codex CLI, Gemini CLI, the Claude apps and any stdio client | | /docs/api | REST API guide with curl, JavaScript and Python examples | | /docs/api/reference | Interactive OpenAPI reference (Scalar, self-hosted) | | /docs/sources | All sources with licences, generated from the provider registry | | /docs/self-hosting | Docker, Node, configuration, metrics |

exactly which files you'll get and their size; download the file or one zip; copy a curl command or a prompt for your agent.

For AI agents

Point an agent at https://3d.shep.bot and it finds its way:

| URL | For | |---|---| | /AGENTS.md | The agent guide: MCP setup, REST workflow, licensing rules, an example | | /llms.txt, /llms-full.txt | llms.txt index and every guide in one file | | /docs/*.md | Markdown twin of every docs page | | /skill/SKILL.md | A Claude Code skill (~/.claude/skills/3d-assets/SKILL.md) | | /openapi.json | OpenAPI 3.1 |

Requests with Accept: text/markdown get markdown instead of HTML (/ → /AGENTS.md, sent with Vary: Accept), unknown paths answer agents with a Markdown 404 that links to the docs, llms.txt and the sitemap, every page advertises its twin with Link: <…>; rel="alternate"; type="text/markdown", and curl https://3d.shep.bot returns a JSON index that points at all of the above. /about, /contact and /privacy describe who runs the service and what it records; /docs/api/versioning is the versioning, deprecation and rate-limit policy.

---

MCP: use it from an AI assistant

  you: "find me a free sci-fi crate model and put it in the project"
   |
   v
  assistant --search_assets("sci-fi crate", types=[model], free_only)--> ranked results
   |
   +--------get_asset("polyhaven:...", format="gltf")-----------------> formats, licence,
   |                                                                     files, size
   +--------download_asset("polyhaven:...", resolution="2k")----------> ./assets/polyhaven-.../
   |
   v
  "Done: CC0, no credit needed. Saved to assets/polyhaven-.../crate_2k.gltf"

Claude Code

claude mcp add 3d-assets -e ASSET_DOWNLOAD_DIR="$PWD/assets" -- node /path/to/3d-asset-server/dist/cli.js mcp

Claude Desktop, Cursor, or any stdio MCP client

{
  "mcpServers": {
    "3d-assets": {
      "command": "node",
      "args": ["/path/to/3d-asset-server/dist/cli.js", "mcp"],
      "env": { "ASSET_DOWNLOAD_DIR": "/path/to/your/game/assets" }
    }
  }
}

Remote (Streamable HTTP)

The public server needs no setup or key:

claude mcp add --transport http 3d-assets https://3d.shep.bot/mcp

Other clients: see . For your own server, point the client at http://:8787/mcp. If you set ASSET_SERVER_API_KEY, send Authorization: Bearer .

Over HTTP, download_asset is off by default because it would write to the server's disk, not yours. Instead, get_asset returns direct file URLs plus a one-click bundleUrl zip. Set ASSET_SERVER_HTTP_DOWNLOADS=true if the server and the files should live on the same machine.

Tools

| Tool | What it does | |---|---| | search_assets | query, plus optional types (model, texture, material, hdri, sprite, ui, audio, font, pack), providers, free_only, downloadable_only, limit, offset. Returns ranked results, also_search_on links for link-only sites, and any sites that failed. | | get_asset | Details for an id such as polyhaven:ArmChair_01: description, licence, available formats and resolutions, and exactly which files a download would fetch for a given format / resolution. | | download_asset | Saves into <dest_dir>/-/ (default ./assets), keeps companion files in place and extracts zips. Returns the paths, licence and an attribution line when credit is required. | | list_providers | Every source: what it's best for, asset types, pricing, licence, and whether it supports direct downloads. |

---

HTTP API

| Endpoint | | |---|---| | GET /v1/search?q=&type=&providers=&free=&downloadable=&limit=&offset= | Ranked, merged results plus a per-site report (ok, error, timeout, skipped, link). | | GET /v1/providers | The source catalogue. | | GET /og/query.png?q=&type=&free= · GET /og/asset.png?id= | 1200×630 share cards for search and asset links (see below). | | GET /v1/catalog | Catalog census, counted daily: listings per source, by asset type, licence and category, free and CC0 counts, the last 30 days' releases, most downloaded assets. Same as /catalog.json; daily history at /catalog-history.json. | | GET /v1/stats | Usage totals (searches by surface, downloads, MCP tool calls, top clients and asset types) and per-source health (success rate, p50/p95 latency). Shown on /stats. | | GET /v1/assets/{provider}:{id} | Full details, including every file. | | GET /v1/assets/{id}/files?format=&resolution=&maps=&all= | The files a download would fetch. | | GET /v1/assets/{id}/download?format=&resolution= | 302 to the file when it is one self-contained file; otherwise a streamed zip with its companions. | | POST /mcp | MCP endpoint (Streamable HTTP, stateless). | | GET /openapi.json | OpenAPI 3.1 description. | | GET / | Web UI in a browser; a JSON index of endpoints for API clients. | | GET /health | Liveness check. |

curl 'localhost:8787/v1/search?q=brick+wall&type=material&free=true&limit=5'
curl -OJ 'localhost:8787/v1/assets/polyhaven:WoodenChair_01/download?format=gltf&resolution=1k'

Search response (shortened):

{
  "query": "brick wall",
  "results": [
    {
      "id": "polyhaven:brick_wall_001",
      "title": "Brick Wall 001",
      "type": "material",
      "url": "https://polyhaven.com/a/brick_wall_001",
      "license": { "name": "CC0", "commercialUse": true, "attributionRequired": false },
      "price": { "free": true },
      "resolutions": ["1k", "2k", "4k", "8k"],
      "downloadable": true,
      "score": 1
    }
  ],
  "providers": [
    { "provider": "polyhaven", "status": "ok", "count": 5, "tookMs": 210 },
    { "provider": "fab", "status": "link", "searchUrl": "https://www.fab.com/search?q=brick+wall&is_free=1" }
  ]
}

---

CLI

$ node dist/cli.js search "low poly tree" --type model --free --limit 5

1.00 model free blenderkit:72fac4cb-901c-4a48-8fc8-84a0baa0bd21 Low poly tree — https://www.blendkit.com/asset-gallery-detail/72fac4cb-.../ 0.93 model free cgtrader:lowpoly-tree-collection-01-200-trees-lowpoly-collection Low Poly Trees Mega Pack - 200 Trees — https://www.cgtrader.com/free-3d-models/... 0.93 model free itchio:brokenvector/low-poly-tree-pack Low Poly Tree Pack — https://brokenvector.itch.io/low-poly-tree-pack 0.91 model free blenderkit:346d99d8-36fb-4f9d-a4a1-2f9ad9233e79 Low poly tree — https://www.blendkit.com/asset-gallery-detail/346d99d8-.../ 0.84 model free itchio:mark-auman/low-poly-trees-asset-pack Low-Poly Trees Asset Pack — https://mark-auman.itch.io/low-poly-trees-asset-pack

Sources: polyhaven ok 1 blenderkit ok 5 fab link 0 https://www.fab.com/search?q=low+poly+tree&is_free=1 kenney ok 2 quaternius ok 5 cgtrader ok 5 turbosquid link 0 https://www.turbosquid.com/Search/3D-Models/free/low-poly-tree itchio ok 5 ...

3d-asset-server serve                    HTTP API + web UI + MCP at /mcp
3d-asset-server mcp                      MCP over stdio
3d-asset-server search  [--type model,hdri] [--providers a,b] [--free] [--limit N]

---

Downloads

Unless you say otherwise, a download picks game- and web-friendly files:

  asset type   preferred format, in order          resolution
  ----------   ---------------------------------   --------------------------
  model        glb > gltf > fbx > obj > blend      closest to 2k
  hdri         hdr > exr                           closest to 2k
  material     jpg maps > png maps > zip           closest to 2k
  texture      jpg > png > zip > exr               closest to 2k
  packs        zip (extracted)                     -

Companion files keep their relative paths, so a glTF loads straight away:

  assets/
  `-- polyhaven-WoodenChair_01/
      |-- WoodenChair_01_2k.gltf
      |-- WoodenChair_01.bin
      `-- textures/
          |-- WoodenChair_01_diff_2k.jpg
          |-- WoodenChair_01_nor_gl_2k.jpg
          `-- WoodenChair_01_arm_2k.jpg

assets/ `-- kenney-nature-kit/ <- zip downloaded and extracted `-- kenney_nature-kit/ |-- Models/GLTF format/... `-- License.txt

Safety:

---

Configuration

| Variable | Default | | |---|---|---| | PORT / HOST | 8787 / 0.0.0.0 | HTTP bind address | | ASSET_SERVER_API_KEY | – | Require Authorization: Bearer , x-api-key or ?api_key= on /v1/* and /mcp | | ASSET_SERVER_PUBLIC_URL | request origin | Base URL used in links handed to MCP clients | | ASSET_SERVER_PROVIDERS | all | Comma list to enable only some sources, e.g. polyhaven,ambientcg,kenney | | ASSET_DOWNLOAD_DIR | ./assets | Default download folder for MCP | | ASSET_SERVER_HTTP_DOWNLOADS | false | Expose download_asset on the HTTP MCP endpoint (writes to the server's disk) | | ASSET_SERVER_MAX_DOWNLOAD_BYTES | 2 GiB | Per-download size guard | | ASSET_SERVER_PROVIDER_TIMEOUT_MS | 12000 | Per-site search timeout | | ASSET_SERVER_HTTP_TIMEOUT_MS | 15000 | Per-request HTTP timeout | | ASSET_SERVER_CACHE_TTL_MS | 10 min | In-memory HTTP cache TTL | | ASSET_SERVER_USER_AGENT | 3d-asset-server/0.1 | User-Agent sent to the sites | | BLENDERKIT_API_KEY | – | Optional; unlocks plan and purchased BlenderKit assets | | NODE_USE_ENV_PROXY | – | Set to 1 so Node's fetch uses HTTPS_PROXY | | ASSET_SERVER_RATE_LIMIT | 120 | Requests per client per window on /v1/* and /mcp; responses carry RateLimit-Policy / RateLimit (+ RateLimit-Limit/Remaining/Reset), and 429 adds Retry-After. 0 = off | | ASSET_SERVER_RATE_LIMIT_WINDOW | 60 | Rate-limit window in seconds | | METRICS_PORT | – | Serve Prometheus metrics on this port at /metrics and log one JSON line per search, download and MCP tool call (see below) | | PROMETHEUS_URL | – | Prometheus that scrapes METRICS_PORT. /v1/stats (and the /stats page) then report the last 24 hours and 7 days across replicas; without it they count this process since it started |

If you set ASSET_SERVER_API_KEY on a public server, note that ?api_key= (used by the web UI's
download button) can end up in browser history and server logs.

Analytics

With METRICS_PORT set (src/core/analytics.ts), metrics are served on that separate port (never on the public listener), with bounded labels only:

| Metric | Labels | |---|---| | asset_server_searches_total | surface (web, api, mcp), client family, type, free_only, has_results | | asset_server_search_duration_seconds, asset_server_search_results | surface | | asset_server_provider_requests_total, asset_server_provider_duration_seconds | provider, status | | asset_server_downloads_total, asset_server_asset_views_total | surface, client, provider | | asset_server_mcp_tool_calls_total, asset_server_mcp_tool_duration_seconds | tool, client (claude-code, cursor, vscode, …) | | asset_server_http_requests_total, asset_server_page_views_total | route / page |

Each search also logs {"event":"search","query":…,"results":…,"surface":…} to stdout for top-query and zero-result analysis in a log store. No IPs, keys or cookies are recorded. In the shep.bot cluster a ServiceMonitor (deploy/servicemonitor.yaml) feeds Prometheus, Loki collects the event lines, and the 3D Asset Server Grafana dashboard shows both.

The public /stats page reads the same counters back through GET /v1/stats (src/core/stats.ts): from Prometheus when PROMETHEUS_URL is set (cached for a minute), otherwise from in-

GitHub Stars & Activity

221Stars
19Forks
0Open issues
TypeScriptLanguage

GitHub Popularity

GitHub stars221
Forks19
Open issues0
Primary languageTypeScript
License-
Stars gained today0
Created-
Last pushed-

Trending History

Daily boardrank #76 · ▲ 0 stars

Related AI Projects

1

deepseek-ai / deepseek-harness

TypeScript★ 244,544⑂ 0
→
2

n8n-io / n8n

TypeScript★ 206,762⑂ 0
→
3

firecrawl / firecrawl

TypeScript★ 189,134⑂ 0
→
4

thedotmack / claude-mem

TypeScript★ 97,052⑂ 8,555▲ 536 stars
→
5

ruvnet / ruflo

TypeScript★ 73,998⑂ 8,799▲ 87 stars
→
6

heygen-com / hyperframes

TypeScript★ 57,834⑂ 5,158▲ 582 stars
→
7

ChromeDevTools / chrome-devtools-mcp

TypeScript★ 53,035⑂ 5,704▲ 45 stars
→
8

wonderwhy-er / DesktopCommanderMCP

TypeScript★ 9,940⑂ 1,247▲ 13 stars
→

More AI Rankings