Asset Inventory

Scan every UE project you work with into one local inventory. Search by triangle count, Nanite status, source, or name. See which assets are reused across projects, then migrate them with full dependency cascade. One Slate panel. One JSON-RPC namespace. One CLI surface.

On This Page


Overview

The Problem

You're working across multiple UE projects. Some came from Fab packs, some from Megascans / USD downloads, some you imported by hand. You need to find every "bench" mesh you own, see which ones are reused across projects, and migrate the right one (with all its dependencies) into your current project. Content Browser only searches one project at a time. Fab's search finds products you bought, not meshes inside them. You can't filter by triangle count, Nanite status, or LOD count. And after the Quixel Bridge shutdown, your Megascans library is scattered across folders with no index.

The Solution

Asset Inventory scans every UE project you point it at into a local SQLite catalog at your Home Project. One scan picks up assets from four sources in a single pass: Fab packs, generic /Game/ walks (anything you imported manually), USD/USDZ files, and explicit Manual tagging. Triangle counts, Nanite status, LOD counts, disk sizes, source attribution, and per-project memberships are all indexed.

Search two ways. Natural language for exploration: ask Claude "find all vegetation StaticMeshes under 5,000 triangles, used in more than one project" and get results in seconds. Claude translates your intent into a query, runs it through the editor.inventory.* JSON-RPC namespace, and returns results. Direct CLI or MCP tools for precision: repeatable, deterministic queries for CI pipelines, shared scripts, or audits hit the same local catalog. The Slate Asset Inventory panel gives you the same data interactively, with the Asset Usage Report nomad tab ranking assets by how many projects use them.

The local catalog ships in every edition. Pro adds an optional Neo4j sync that mirrors the SQLite inventory into a graph database for cross-project Cypher analytics. Migrate assets between projects with full dependency cascade through one JSON-RPC call. The whole pipeline works offline, scans what's actually on disk (no Fab API dependency), and costs nothing beyond the AgentUX edition you already own.

UE Projects ──scan──▶ Local SQLite catalog (asset_v2 + asset_project_membership)
   (Fab + USD + GameWalk + Manual)         │
                                           ├──▶ Slate Asset Inventory panel
                                           ├──▶ Asset Usage Report nomad tab
                                           ├──▶ editor.inventory.* JSON-RPC (13 methods)
                                           ├──▶ Python CLIs (scan, usage report, migrate)
                                           └──▶ Optional Neo4j sync (Pro)
                                                  → Cypher queries, graph analytics
ComponentPurposeTier
scan_project.pyScan the running UE project; multi-source ingest into the local SQLite catalogAll
usage_report.pyList projects, list assets, find cross-project usagesAll
migrate_asset.pyCopy an asset into another project with hard-package dependency cascadeAll
inventory_cleanup.pySearch-first / purge-second destructive cleanup with safety token gateAll
sync_inventory_to_neo4j.pyMirror the SQLite catalog into Neo4j as :InventoryAsset / :InventoryProject / :InventoryCollectionPro
showcase_assets.pySpawn matching assets in editor as a walkable showcase gridPro
editor.inventory.*13 JSON-RPC methods (scan, list, find usages, usage report, migrate, sync, cleanup)Free for everything except sync; Pro for sync
Slate Asset Inventory panelIn-editor browse, sort, search, detail pane, right-click migrateAll
Asset Usage Report nomad tabCross-project usage ranking with cross-tab jump to inventory rowsAll

Architecture: Multi-Source, Multi-Project, Scan-Based

Asset Inventory is local-first by design. Every scan writes to a single SQLite catalog at {HomeProject}/FabCatalog/catalog.db shared across all your UE projects. Each scan is idempotent: rescanning a project updates membership rows for assets it still finds and prunes ones that are gone. Assets belong to many projects via an explicit membership table, so the same mesh used in three projects shows up once with three project links.

Sources

SourceWhat It CapturesHow It's Detected
fabAssets from Fab pack downloads with full pack identityFab provider walks the pack metadata and asset lists
gamewalkAnything under /Game/ in the Asset Registry that wasn't already attributedGeneric walk over the live registry; first-provider-wins-source dedup
usdUSD / USDZ files including Megascans contentUSD provider shells out to the bundled scan_usd_assets.py via FMonitoredProcess
manualAnything you tag explicitly via --source-overrideAuthor-supplied attribution at scan time

Why this shape

The headline value is cross-project usage reporting and asset migration. Both depend on the catalog knowing every project an asset lives in. The single shared SQLite database, the multi-source scan engine, and the per-project membership table exist to make those two questions cheap to answer: which assets are reused where, and what does it take to move one of them.


Prerequisites

RequirementDetails
UE Editor5.6+ with AgentUX plugin enabled
AgentUX PluginWebSocket server active on port 9877
Home Project configuredSet during install.py or via --home-project flag; SQLite catalog lives at {HomeProject}/FabCatalog/catalog.db
Python 3.10+For the Python CLIs (scan_project.py, usage_report.py, etc.)
Claude CodeFor MCP tool access (optional, scripts work standalone)
Neo4jOptional. Required only for the Pro Neo4j sync (localhost:7474 / localhost:7687)

Step 1: Organize Downloads (Optional)

Asset Inventory works against any UE project regardless of layout. If you're starting fresh and want a clean structure, one UE project per asset category keeps both projects and inventory categories tidy:

D:/FabCatalog/
├── ArchVizInteriors/         # Architecture & interior packs
├── CityParkEnvironment/      # Outdoor environment pack
├── QuixelTrees/              # Megascans vegetation
├── NatureVegetation/         # Other vegetation
└── UrbanModern/              # Urban/modern assets

Download asset packs from Fab.com or your other sources, then point each category project at the AgentUX scanner. If you already have a working project layout, skip this step entirely; the scanner doesn't care.


Step 2: Scan Projects

From the editor toolbar

The fastest path is one click. With your project open in UE, click Scan This Project in the Level Editor toolbar. A Slate notification shows progress; on completion it reports the asset count upserted into the catalog.

Level Editor toolbar with the Scan This Project button, tooltip explaining that the button populates the local Asset Inventory for the currently loaded project
The Scan This Project button lives on the Level Editor toolbar. The tooltip confirms what it does before you click.

From the CLI

For scripted, headless, or CI-driven scans, the editor must still be running on the target project (the scanner queries the live Asset Registry):

python scan_project.py --show-progress

The scan runs all four providers in one pass: Fab attribution where pack metadata is detectable, USD for any .usd* files under Content/ (gated on the USDCore plugin), generic /Game/ walk for everything else, and Manual override if you supply --source-override.

StaticMesh and SkeletalMesh assets are enriched with triangle count, vertex count, LOD count, and Nanite status during the scan. Materials get textures-used edges. Other classes get name, path, and class.

FlagDescription
--projectProject path (optional; defaults to the running editor's project, validated against it on submit)
--source-overrideForce a source label on every asset: fab / usd / gamewalk / manual (useful for baseline imports of Fab-seeded directories)
--show-progressHeartbeat output with elapsed, assets seen, and memory
--poll-intervalSeconds between status polls (default tracks the server-side scan via async scan_id; AIR-FIX-6)
--timeoutPer-call WebSocket timeout in seconds
--jsonEmit machine-readable JSON instead of human-readable summary

Internally the CLI calls editor.inventory.scanProject (returns a scan_id immediately), polls editor.inventory.getScanStatus until the scan reaches a terminal state, and supports Ctrl+C for cooperative cancellation via editor.inventory.cancelScan. Long scans no longer trip client-side timeouts; the server-side scan continues regardless of poll cadence.

USD-only scans without the editor

The legacy scan_usd_assets.py still ships and runs without the editor (handy for headless USD ingestion):

python scan_usd_assets.py --source-dir "D:/FabCatalog/QuixelTrees/Content" \
    --project-name "QuixelTrees" --show-progress

For most workflows, prefer scan_project.py; it picks up USD content automatically as part of a single multi-source pass.


In the editor: Slate Asset Inventory panel

Open Window > AgentUX > Asset Inventory. The panel shows an Excel-like sortable list of every asset in the catalog: name, source, class, project count, size, last seen. Click any row to see metadata, project memberships, and dependencies in the detail pane. Right-click any row for Migrate to Project. Wildcard search supports * and ? across asset names. The Show in Content Browser button on the detail pane jumps the editor to the asset, with a friendly fallback dialog when the asset belongs to a different project.

Asset Inventory nomad tab docked in the Unreal Editor, showing a sortable list of assets with Name, Source, Class, Project Count, Size, and Last Seen columns
The Asset Inventory panel. Source column tells you which provider attributed each asset; Project Count tells you how many projects it lives in.
Asset Inventory Quick Reference popup listing the four sources, the scan limits, and a link to the full guide
The ? button in the panel opens a Quick Reference popup with the source list, scan limits, and a link to the full guide.

In the editor: Asset Usage Report

Open Window > AgentUX > Asset Usage Report. This nomad tab ranks every asset by how many projects use it (most-reused first), with a drill-down pane showing the project list. Click Show in Asset Inventory on any row to jump back to the main inventory panel focused on that asset. Useful for finding the assets that earn their keep across your library and the ones that exist only in one place.

Asset Usage Report nomad tab ranking assets by project count DESC, with the most-reused assets at the top of the list
Asset Usage Report ranks your catalog by cross-project reuse. The Project Count column is the headline signal.
Asset Usage Report drill-down showing the list of projects that contain the currently selected asset
Select any row to see the projects that contain the asset. Show in Asset Inventory jumps back to the main panel focused on it.

Via Claude Code (natural language)

With the AgentUX MCP server running, use natural language prompts:

  • "Find all vegetation StaticMeshes across my projects"
  • "What's in the CityParkEnvironment project?"
  • "Which assets are used in more than one project?"
  • "Find assets in CityPark that aren't in any other project"

Claude calls the editor.inventory.* JSON-RPC namespace (13 methods) through the MCP bridge wrappers:

MethodPurpose
editor.inventory.listAssetsBrowse assets, optionally filtered by project_path and/or source
editor.inventory.listProjectsEvery project observed in the inventory with asset counts
editor.inventory.findUsagesCross-project memberships for one asset
editor.inventory.getUsageReportCross-project usage report; assets ranked by project count DESC
editor.inventory.scanProjectAsync scan that returns a scan_id immediately
editor.inventory.getScanStatusPoll an in-flight or recently-terminal scan
editor.inventory.migrateAssetCopy an asset and its hard-package dependency cascade into another project

From the CLI

Same data, scriptable:

# List every project in the catalog
python usage_report.py --mode list-projects

# List assets in a project, paginated
python usage_report.py --mode list-assets --project "E:/UnrealProjects/CityPark"

# Find every project that uses a specific asset
python usage_report.py --mode find-usages --unreal-path "/Game/Meshes/SM_Bench01"

Step 4: Migrate Assets Between Projects

Once you've found the asset you want, migrate it into your working project. Three ways to do it.

From the Slate panel

Right-click the row in the Asset Inventory panel and choose Migrate to Project.... A modal dialog lists every other project in the catalog as a target. Toggle the cascade checkbox to include hard-package dependencies (default on; recommended), then click Migrate. The result pane shows counts of migrated, skipped, and conflicts.

Migrate to Project dialog in the Asset Inventory panel, with the target project combo expanded and the cascade dependencies checkbox visible
Migrate to Project dialog. Target combo lists every other project in the catalog; cascade copies the hard-package dependencies alongside the asset.

From the CLI

# Migrate one asset with cascade (default)
python migrate_asset.py \
  --unreal-path "/Game/Meshes/SM_Bench01" \
  --target-project "E:/UnrealProjects/MyGame"

# Dry-run prints the JSON-RPC request without connecting (CI-friendly)
python migrate_asset.py \
  --unreal-path "/Game/Meshes/SM_Bench01" \
  --target-project "E:/UnrealProjects/MyGame" \
  --dry-run

Via JSON-RPC directly

{"method": "editor.inventory.migrateAsset", "params": {
  "unreal_path": "/Game/Meshes/SM_Bench01",
  "target_project": "E:/UnrealProjects/MyGame",
  "cascade": true
}}

Migration semantics: copy (the source is left in place), cascade walks hard-package dependencies via the Asset Registry, conflict resolution is skip-on-conflict (you can pre-check via editor.inventory.listAssets if you need to). The source project must be the editor's current project; cross-process migration is out of scope.


Step 5: Sync to Neo4j (Pro)

For graph analytics, cross-project Cypher queries, or shared studio tooling, mirror the local SQLite catalog into Neo4j with one call. The sync writes a disjoint label namespace (:InventoryAsset / :InventoryProject / :InventoryCollection) so it coexists with any other graphs in the same Neo4j instance.

From the CLI

# Dry-run first to preview counts
python sync_inventory_to_neo4j.py --dry-run --show-progress

# Live sync (idempotent; rerun safely)
python sync_inventory_to_neo4j.py --show-progress

# Tune batch size for very large catalogs
python sync_inventory_to_neo4j.py --batch-size 1000 --show-progress

Via JSON-RPC

{"method": "editor.inventory.syncToNeo4j", "params": {
  "batch_size": 500,
  "dry_run": false
}}

This method is gated to the Pro tier. On Free, it returns a tier-gate error pointing at the upgrade path. After the sync, the same data is queryable directly via Cypher, the agentux_inventory_* MCP wrappers, or natural language through Claude.

The installer prints a non-blocking recommendation to run the sync when it detects a Pro or Team Studio installation with a populated local catalog and a reachable Neo4j instance. You can run it whenever you want; it's idempotent.


Step 6: Showcase Matching Assets

Spawn matching assets in the editor as a walkable grid for visual browsing:

python showcase_assets.py --project-name "CityParkEnvironment" --show-progress

Assets are grouped by name affinity (SM_Wall_01, SM_Wall_02 appear together), sorted by size within each group (smallest in front, largest in back), and separated by group gaps for easy visual scanning.

FlagDescription
--project-nameRequired. Source project
--categoryFilter by category (e.g., vegetation)
--max-assetsCap spawned assets (default: 100)
--group-gapWhitespace between groups in UU (default: 500)
--dry-runPrint layout without spawning
--no-groupingDisable semantic grouping

Showcase ships in the Pro edition packaging set.


Neo4j Schema Reference

The Pro Neo4j sync writes a disjoint label namespace so it never collides with the GraphRAG engine knowledge base or any other graphs in the same Neo4j instance.

Node Labels

LabelKey PropertyDescription
InventoryAssetunrealPath (unique)A scanned UE asset (one node per unique unrealPath regardless of how many projects use it)
InventoryProjectprojectPath (unique)A scanned UE project (canonicalized path)
InventoryCollectioncollectionId (unique)A grouping unit (Fab pack identity, USD collection, etc.)

Relationships

RelationshipFromToDescription
:IN_PROJECTInventoryAssetInventoryProjectAsset is referenced by this project
:IN_COLLECTIONInventoryAssetInventoryCollectionAsset belongs to this Fab pack or USD collection

InventoryAsset Properties

PropertyTypeDescription
namestringAsset name (e.g., SM_Rock06)
unrealPathstringFull UObject path (unique key)
classNamestringUE class
sourcestringSource provider: fab / usd / gamewalk / manual
diskSizeintFile size in bytes (when available; not populated for GameWalk-scanned assets in current release)
trianglesintTriangle count (StaticMesh / SkeletalMesh)
verticesintVertex count (StaticMesh / SkeletalMesh)
lodsintLOD count (StaticMesh / SkeletalMesh)
naniteEnabledboolNanite flag (StaticMesh)

For the canonical, plugin-side schema document including the full property mapping table and example Cypher queries, see Docs/INVENTORY_NEO4J_SCHEMA.md in the AgentUX distribution.


Troubleshooting

Editor not reachable (port 9877)

Open UE Editor with your project, enable the AgentUX plugin (Edit > Plugins > search "AgentUX"), and restart the editor. Verify with netstat -an | grep 9877.

Auth token required

Scripts auto-resolve tokens from the credential file at <Project>/Saved/AgentUX/.creds/mcp_auth or the OS keyring. Set the token in the AgentUX Settings panel if missing.

Empty scan results or empty panel after scan

The scanner queries the live Asset Registry. Ensure the project is actually open in the editor and assets are loaded. The Slate Asset Inventory panel must be closed before destructive RPC calls (deleteProject, canonicalizeProjectKeys, deleteAssets) and is automatically refreshed after scans complete.

scanProject scan_id pending forever

Polling continues against editor.inventory.getScanStatus. Check the editor's Output Log for scan progress. Use Ctrl+C to send a cooperative cancel via editor.inventory.cancelScan.

Phantom project rows from typo'd paths

Run editor.inventory.pruneProjectKeys (or use the panel's cleanup helpers) to remove project_path entries that don't resolve to real directories. For pre-AIR-FIX-2 catalogs, run editor.inventory.canonicalizeProjectKeys once to merge non-canonical duplicates.

Neo4j connection refused (sync only)

Start Neo4j. On Windows: neo4j console or start the Neo4j Desktop app. The local SQLite catalog and all Free-tier features work without Neo4j; only sync_inventory_to_neo4j.py needs it.

Tier-gate error on syncToNeo4j (Community)

The Neo4j sync is gated to the Pro edition. Free ships the full local Asset Inventory; the Neo4j sync is the upgrade differentiator.

Showcase spawns nothing

Verify the project has StaticMesh entries: python showcase_assets.py --project-name "MyProject" --dry-run


See Docs/FAB_INVENTORY_GUIDE.md and Docs/INVENTORY_NEO4J_SCHEMA.md in the plugin distribution for the complete reference including additional Cypher query examples and per-method JSON-RPC parameter documentation.