Searching Poly Haven, AmbientCG, and Kenney from Claude

by Fireal Software · ~7 min read

Placeholder art slows down iteration. You’re building a platformer prototype, you need grass tiles, you open a browser tab, search Kenney, scroll through thumbnails, download a zip, extract it, drag it into Godot, wait for the importer, tweak import settings. Twenty minutes of meta-work before you ship one pixel.

Godot Catalyst collapses that loop. Claude searches three CC0 providers from the MCP session, downloads what fits, and points you at where it landed.

The three providers

src/assets/providers.ts wires up three libraries:

Poly Haven — HDRIs, PBR textures, 3D models. CC0. Real API at api.polyhaven.com. Used by pros, works for games. Good for stylized realism.

AmbientCG — PBR materials, surface textures, some 3D assets. CC0. API at ambientcg.com/api/v2/full_json. Best bet for tiling surfaces (brick, wood, metal, fabric).

Kenney — CC0 game asset packs. 2D sprites, 3D kit-bash sets, UI, audio, fonts. No formal API, so Godot Catalyst ships a static catalog of the most-used packs. Good for prototype art, especially blocky 3D scenes and retro 2D.

Every asset from all three is CC0 — public domain, no attribution required. You can ship them in a commercial game without licensing worry.

The tools

Five asset tools, all pure TypeScript, no Godot plugin needed:

Results come back as a uniform JSON shape:

{
  "id": "brick_wall_006",
  "name": "Brick Wall 006",
  "provider": "ambientcg",
  "type": "material",
  "url": "https://ambientcg.com/view?id=brick_wall_006",
  "preview_url": "https://.../brick_wall_006.png",
  "license": "CC0",
  "categories": ["brick", "wall", "red", "old"],
  "download_url": "https://.../brick_wall_006_2K-JPG.zip"
}

Claude gets preview_url and can show it in the conversation if the client renders images. It gets download_url and can follow up with godot_download_asset to grab it.

How Claude picks

Ask Claude “I need a brick wall texture for my level” and it does something like:

  1. godot_search_assets({"query": "brick wall", "type": "textures"})
  2. Reads back 10-20 candidates with thumbnails
  3. Picks the top match based on category tags and name relevance
  4. godot_download_asset({"url": download_url, "dest_dir": "/path/to/project/textures/"})
  5. godot_reimport_asset to tell the Godot editor to scan the new file
  6. Suggests you assign it to your wall material

The ranking happens in Claude’s head — the search returns a flat list and the model picks based on semantic match. Poly Haven results come back ordered by the substring match in name/categories/tags. AmbientCG uses its own relevance. Kenney is a catalog filter by categories and name.

If you want determinism, prompt Claude explicitly: “pick the asset with the highest texture resolution”, “prefer tileable variants”, “avoid old or damaged variants”.

Download security

The downloader only accepts URLs from an allowlist. src/assets/providers.ts defines ALLOWED_DOWNLOAD_DOMAINS:

const ALLOWED_DOWNLOAD_DOMAINS = [
  "polyhaven.com",
  "cdn.polyhaven.com",
  "api.polyhaven.com",
  "ambientcg.com",
  "acg-download.netlify.app",
  "kenney.nl",
  "dl.polyhaven.org",
];

Any other domain throws. This is deliberate — the agent shouldn’t be able to download arbitrary URLs through a tool called “download asset”. If you need external downloads for other purposes, use godot_create_http_request from the networking category, which has no allowlist and is explicitly general-purpose.

The import step matters

Downloading a file to res://assets/textures/brick.jpg isn’t the same as having a texture available. Godot needs to import it — generate a .import file, create a .godot/imported/*.ctex cache entry, register the UID. Until that happens, load("res://assets/textures/brick.jpg") returns null.

Two tools handle this:

For textures, Claude usually wants to set compress/mode to VRAM-Compressed for 3D or Lossless for pixel art. For audio, set force/8_bit off and force/max_rate_hz to 44100. For meshes, set save_to_file/enabled true to cache baked meshes.

A typical asset pull

User: "Add some grass texture to the terrain."

Claude: (searches for grass textures)
  → godot_search_assets({"query": "grass", "type": "textures"})
  → Returns 15 hits, top three are Poly Haven grass_field, grass_pure_short, 
    AmbientCG Grass001.

Claude: (picks Poly Haven grass_field for its tiling quality)
  → godot_download_asset({
      "url": "https://api.polyhaven.com/files/grass_field",
      "dest_dir": "<project>/textures/ground/"
    })
  → Writes grass_field_2k.png to disk.

Claude: (imports it)
  → godot_reimport_asset({"path": "res://textures/ground/grass_field_2k.png"})
  → Triggers Godot's importer.

Claude: (applies it)
  → godot_setup_material3d with the grass texture on the terrain's material

Six calls end to end. No browser tabs, no zip extraction, no import waiting.

What Kenney’s catalog is doing

Kenney doesn’t expose a search API, so Godot Catalyst ships a static list of the 15 most-used packs (Platformer Art Deluxe, Space Shooter Redux, Nature Kit, UI Pack, etc.) with curated tags. When Claude searches “platformer pixel art”, it matches against the catalog’s categories field.

This has one downside: we’re not searching Kenney’s full library, just the curated catalog. If you need a specific Kenney pack that isn’t in the list, download it manually from kenney.nl. If the pack you want to see in the catalog is missing, open an issue on the godot-catalyst repo — adding entries is one JSON object per asset.

The advantage of the static catalog: search is instant. No network call to Kenney means no rate limits, no API keys, no deprecation risk when their site changes.

What’s not here

Godot’s Asset Library is not in the search. That’s a separate pipeline — addons and plugins, not free-to-use art. Claude can install plugins via manual steps but there’s no godot_install_asset_library tool yet.

Textures.com, Sketchfab, itch.io marketplaces, Unreal’s Quixel Megascans — none of those are integrated. The reason is license hygiene. Poly Haven, AmbientCG, and Kenney are all CC0 by default. The others have per-asset licenses that need checking case by case. Godot Catalyst’s design principle: if Claude can download it, the license is known safe for commercial use.

Set GODOT_PROJECT_PATH in your MCP config so downloads land in the right place.

Turn Claude into a Godot co-developer

Godot Catalyst is an MCP server with 240+ tools for Godot 4.x. GDScript LSP, DAP debugging, offline parsing, asset pipelines. 7-day free trial, $25 one-time.

Try Godot Catalyst