Quartermaster

Tu bóveda de activos de juego, consultable y ejecutable por agentes de IA (Unity Asset Store y Fab / Unreal) mediante el Protocolo de Contexto de Modelo (MCP).

Documentación

Quartermaster

Release License: MIT Quartermaster MCP server – quality and maintenance score on Glama MCP Ready Platform Telemetry Tests

Este proyecto comenzó porque quería prototipar una presa.

Nada serio — una demo corta, quizás algo más si funcionaba. Antes de construir nada, quería ver qué tenía ya que pudiera acelerar el proceso. Así que busqué en mi biblioteca "presa": no apareció nada. Por supuesto que no apareció nada — ningún activo se llama presa. Pero repartidos entre cuatro paquetes que ya poseía había mallas de hormigón curvo, un sistema de agua, algo de terreno rocoso. Todo lo que la presa necesitaba. Había tenido la mayor parte durante años y nunca conecté las piezas.

Eso es lo que ~1.500 activos en dos tiendas me hicieron cuando esto empezó — una biblioteca que desde entonces ha crecido a más de 7.500 activos en cinco ecosistemas. Casi todo de bundles y ofertas, nada recordado. Y no soy solo yo — ningún asistente de IA lo sabe tampoco. Pídele ayuda a uno y o construye todo desde cero o te manda de compras, mientras cientos de dólares de exactamente-lo-que-necesitas está en tu disco.

Quartermaster indexa todo lo que posees en Unity Asset Store, Fab, Quixel Megascans, Gumroad y Leartes Cosmos — localmente, en tu máquina — y lo sirve a tu agente de código vía MCP. Es la herramienta que deseé que existiera ese día: pregunta por una presa, y te dice que ya posees mallas de hormigón curvo.

you    →  "I want to build a dam — what do I have to work with?"

agent  →  search_owned_assets(...)        finds the concrete meshes, water FX, terrain
          └─ Nordic Coastal Cliff (Quixel) · 5785 px/m · 2.03 × 2.92 × 2.44 m
             maps: Basecolor, Normal, Displacement, Cavity, AO, Roughness…
          validate_stack([...])           checks none of them fight each other
          import_asset_to_project(...)    unpacks into Assets/, demos stripped

Cada resultado es algo que posees o que puedes reclamar gratis — nada es inventado.

Quartermaster spotlight search

Escribiendo una descripción, no un nombre — ninguno de esos resultados comparte una palabra con la consulta.

¿Por qué Quartermaster? El trabajo de un intendente nunca fue recordar lo que hay en los almacenes — es asegurarse de que estés equipado cuando toca moverse. Eso está más cerca del problema real que olvidar. No había perdido nada; sabía que poseía cosas. Lo que no podía hacer era pasar de "quiero prototipar una presa" a "abre estos cuatro paquetes" sin una hora de excavación primero — y quizás algo más si funcionaba no sobrevive a una hora de excavación. Las ideas que llegan así no se rechazan. Simplemente no ocurren en silencio, y nunca descubres si habrían funcionado.

Lo que indexa

FuenteLo que entraCómo
Unity Asset StorePaquetes poseídos, descripciones, arte de galeríaCosecha autenticada
Fab (Epic)Listados de Unreal y Unity poseídosCosecha autenticada
Quixel Megascans / MegaplantsEl catálogo, con densidad de texel, área de escaneo y listas de mapasSincronización de catálogo público
GumroadProductos poseídosCosecha autenticada
Leartes CosmosInventario de Cosmos poseído y reclamable, con galerías de capturas profundas (18 en promedio, hasta 71)Cosecha autenticada

Todo aterriza en una tabla SQLite detrás de una superficie de búsqueda, así que una consulta cruza todas ellas a la vez. Nada está limitado por motor: una superficie de Megascans y un shader de Unity vuelven de la misma pregunta si ambos la responden.

La parte que nadie te cuenta

Ninguna tienda admitirá lo que posees.

Unity eliminó /account/purchases (404 desde agosto de 2026). Fab no tiene API de propiedad, ni botón de exportación, nada. Tu historial de compras existe solo dentro de su GraphQL privado, detrás de SSO, MFA y detección de bots.

Llegar a ello requirió cuatro intentos, tres de ellos fracasos:

  1. Chromium incluido de Playwright — el captcha de Epic lo rechaza rotundamente ("habilita JavaScript").
  2. Playwright conduciendo tu navegador real — inyecta hooks detectables; Epic lanza un segundo muro de seguridad después de la contraseña.
  3. Depurador adjunto durante el inicio de sesión — mismo resultado. Cualquier cosa que toque el flujo de inicio de sesión se marca.
  4. Lo que realmente funciona: deja de automatizar el inicio de sesión por completo. Entras a través de una ventana de navegador ordinaria — sin puerto de depuración, nada entre tú y la tienda — porque la automatización en sí era lo que disparaba los sistemas de riesgo. Solo después de que termines, en una sesión que estableciste tú mismo, Quartermaster adjunta un depurador y reproduce las consultas paginadas propias de la tienda — con sus propios encabezados CSRF, su propio fragmentado (42 IDs por solicitud, porque eso es lo que envía el cliente de Unity).

Ese truco es la mayor parte de este proyecto. El resto — búsqueda, linting, desempaquetado — es honestamente sencillo en comparación.

Dos reglas ganadas con esfuerzo integradas en el diseño, si alguna vez hackeas esto tú mismo:

  • Los navegadores deben cerrarse correctamente (taskkill sin /F). Un cierre abrupto pierde la cookie de confianza de dispositivo de Unity y recibirás desafíos MFA en cada sesión futura.
  • Nunca ejecutes una cosecha de biblioteca sin cabeza. Sin cabeza dispara el sistema de riesgo de Unity incluso con cookies válidas.

Quixel Megascans, y por qué tu biblioteca de Fab parece corta

La vista de biblioteca de Fab y el catálogo de Megascans no son la misma lista, y no hay exportación que las reconcilie — puedes tener derechos sobre mucho más contenido de Megascans del que tu página de biblioteca muestra. Sea cual sea la causa, el resultado práctico es el mismo: desplazarse y buscar a mano algo que ya tienes.

Quartermaster lo evita. Sincroniza los catálogos de vendedores de Quixel Megascans y Quixel Megaplants desde Fab directamente — 5.580 listados al momento de escribir esto — independientemente de lo que muestre tu vista de biblioteca, y los archiva junto a todo lo demás que posees, etiquetados por estado:

  • vault_owned — en tu biblioteca
  • catalog_grant — reclamable gratis bajo la Licencia de Contenido de Epic, aún no adquirido

Ambos son buscables, y cada resultado dice cuál es, así que un agente puede distinguir "posees esto" de "puedes tenerlo gratis" sin adivinar.

Las filas de Megascans también llevan sus especificaciones físicas donde el listado las publica — densidad de texel, área de escaneo, y la lista de mapas (basecolor, normal, displacement, cavity, AO, roughness…). Esa es la diferencia entre un agente que te dice que encontró una roca y un agente que te dice que encontró un escaneo de 1×1 m a 8192 px/m con displacement — que es la parte que decide si es usable.

python -m src.store_client sync-quixel      # catalog
python -m src.store_client enrich-quixel    # texel density, scan area, maps

Lo que obtienes

Búsqueda que entiende intención y visión. Este es el problema de la presa.

  • Palabras clave exactas vía SQLite FTS5.
  • Intención en lenguaje natural vía embeddings de texto ONNX locales (BAAI/bge-small-en-v1.5) — "estructuras de hormigón para contener agua" saca a la superficie mallas y shaders cuyos listados nunca mencionan presas.
  • Comprensión visual multimodal vía embeddings CLIP ONNX (Qdrant/clip-ViT-B-32) — buscar "catedral gótica" literalmente puntúa tus capturas de pantalla y renders promocionales, encontrando activos incluso cuando sus descripciones de texto están completamente en silencio. Un acierto visual también devuelve cuál captura coincidió, no solo el arte de portada.
  • Cada resultado muestra su razonamiento. Cada acierto lleva un campo match — keyword, semantic+vision, keyword+semantic+vision — para que tú y tu agente puedan ver qué señal se disparó. Un acierto puramente visual en un listado con copy de marketing inútil es un tipo de resultado diferente que una coincidencia exacta de título, y debería ser legible como tal.
  • Etiquetas de concepto extraídas de capturas. El pase de visión sin conexión puntúa cada imagen de galería contra un vocabulario visual y escribe los supervivientes de vuelta en el índice FTS, así que "aldea medieval" y "atmósfera de horror oscuro" se vuelven buscables por palabra clave en activos cuyas descripciones nunca dijeron ninguna de las dos. El vocabulario es un archivo JSON que puedes reemplazar — ver docs/concepts.md. Las tres señales se fusionan con Fusión de Rango Recíproco (RRF) de 3 vías en tu CPU. Sin GPU, sin proceso de base de datos vectorial, sin API en la nube — ONNX Runtime y una matriz numpy, en el mismo proceso que todo lo demás.

Medido en un almacén de ~7.500 activos: ~520 MB de RAM pico con ambos modelos residentes, ~1,4 s para la primera consulta (cargando BGE y CLIP), ~85 ms en caliente después de eso. Los modelos se cargan perezosamente, así que un agente que nunca busca nunca paga por ellos.

Verdad fundamental sobre tu disco. Escanea %APPDATA%/Unity/Asset Store-5.x/ y el VaultCache de Epic para que cada resultado sepa si ya está descargado o solo en la nube. Los agentes prefieren lo local — una importación de cero descargas vence a una de 4 GB.

Un linter para stacks. Dos renderizadores de vegetación pelearán. Un módulo de MicroSplat sin el núcleo de MicroSplat silenciosamente no hace nada. Un shader solo-URP en un proyecto HDRP renderiza rosa. Quartermaster detecta estos antes de que pases una tarde en ellos.

Desempaquetado directo. Extrae archivos .unitypackage en caché directamente en Assets/, dejando caer /Demo/, /Samples/, /Documentation/ y PDFs en el camino — típicamente 60–80% menos de hinchazón por paquete. Cada ruta declarada se normaliza y se afirma dentro de <project>/Assets/; los escapes son estructuralmente imposibles, no solo filtrados.

Instalación

El bundle independiente — descarga Quartermaster-windows-x64.zip de Releases, descomprime en cualquier lugar. No se requiere Python.

  • Quartermaster.exe — GUI de escritorio con búsqueda spotlight Win+Alt+V, cosecha de tiendas, navegación de biblioteca y desempaquetado directo.
  • Quartermaster-mcp.exe — Servidor MCP stdio independiente para Claude Desktop, Cursor, Antigravity y Windsurf.

Los datos de tu biblioteca viven de forma segura en %LOCALAPPDATA%\Quartermaster, así que las actualizaciones son simples reemplazos de carpeta con cero pérdida de datos.

Desde el código fuente — requiere Python 3.10+.

git clone https://github.com/Tanshaydar/Quartermaster.git
cd Quartermaster
pip install -r requirements.txt

Siembra tu biblioteca:

1. Inicia sesión. El único paso que te necesita. Se abre una ventana de navegador normal; 2FA y captchas se comportan exactamente como siempre. Ciérrala cuando termines y la sesión persiste localmente.

python -m src.store_client login unity
python -m src.store_client login fab
python -m src.store_client login gumroad     # optional
python -m src.store_client login cosmos      # optional — Leartes Cosmos

2. Cosecha y enriquece. De larga duración, reanudable, seguro de re-ejecutar — cada uno retoma donde se detuvo.

python -m src.store_client fetch unity
python -m src.store_client fetch fab
python -m src.store_client fetch gumroad     # if you signed in above
python -m src.store_client fetch cosmos      # if you signed in above
python -m src.store_client sync-quixel       # Megascans/Megaplants catalog — no login needed
python -m src.store_client enrich            # descriptions and cover art, politely batched
python -m src.store_client enrich-quixel     # Megascans scan specs
python -m src.store_client fab-deep-media    # Fab only: plain HTTP is 403'd, galleries need the authed browser

3. Construye los índices locales, luego escanea tu disco.

python -m src.semantic build     # text embeddings
python -m src.vision build       # screenshot embeddings + concept tagging
python -m src.local_scan         # which of them are already downloaded here

semantic build y vision build son lo que hace que "estructuras de hormigón para contener agua" y las consultas de concepto visual encuentren tus activos. Sáltalos y la búsqueda aún funciona, pero solo en palabras clave exactas.

Ejecuta local_scan después de tener un catálogo, no antes. Escaneado contra un almacén vacío no tiene nada con qué comparar nombres de archivo, así que archiva cada paquete en caché como su propia entrada desnuda. Inofensivo — el siguiente escaneo los reconcilia contra el catálogo real — pero verás duplicados hasta entonces.

¿Ya tienes exportaciones CSV de las tiendas? Salta el navegador por completo:

python -m src.ingest             # eats any CSVs in data/seed/
python -m src.semantic build     # still needed — see the note above
python -m src.local_scan         # then find what's already on disk

Conecta tus agentes:

Opción A: Auto-registro (un comando)

# Standalone binary users:
Quartermaster-mcp.exe --register --all

# Source users:
python -m src.register --all             # Claude Desktop, Cursor, Windsurf, Antigravity
python -m src.register --all --dry-run   # look before you leap

El registro se fusiona en las configuraciones de cliente existentes y crea un .quartermaster-backup primero. No sobrescribirá tus otros servidores.

Opción B: Configuración manual Pega el bloque de servidor en tu configuración de cliente:

Binario independiente:

{
  "mcpServers": {
    "quartermaster": {
      "command": "C:/path/to/Quartermaster/Quartermaster-mcp.exe",
      "args": []
    }
  }
}

Desde el código fuente:

{
  "mcpServers": {
    "quartermaster": {
      "command": "python",
      "args": ["-m", "src.mcp_server"],
      "cwd": "C:/path/to/Quartermaster"
    }
  }
}

Claude Desktop lee %APPDATA%/Claude/claude_desktop_config.json, Cursor ~/.cursor/mcp.json, Windsurf ~/.codeium/windsurf/mcp_config.json.

[!NOTE] Calentamiento de modelos en el primer uso: En la primera búsqueda de lenguaje natural o visión, los modelos de embeddings (BAAI/bge-small-en-v1.5 y clip-ViT-B-32) se descargan y se guardan en caché localmente por ONNX Runtime (~150 MB). La primera consulta puede tomar 3–5 segundos mientras se cargan en memoria; cada consulta subsiguiente se ejecuta en ~100 ms.

Herramientas del agente

HerramientaResponde
search_owned_assets(query, ...)¿Qué poseo que encaja con esto? Híbrido de palabra clave + semántico.
get_asset_details(asset_id)Metadatos completos, notas de uso, galería, URL de la tienda.
get_stack_recommendations(brief)Mapea un brief de características a paquetes poseídos.
validate_stack(asset_ids)¿Pelearán estos entre sí? Conflictos de roles, prerrequisitos faltantes.
list_stack_recipes()Stacks de producción curados resueltos contra tu biblioteca.
audit_project(project_dir)Motor, versión, pipeline de render de un proyecto objetivo.
import_asset_to_project(asset_id, project_dir)Desempaqueta un paquete local en Assets/ (paquetes UPM incluidos en Packages/).
list_asset_categories()Desglose de categorías y conteos.
get_vault_stats()Totales por fuente y categoría, local vs nube.

Dos archivos te permiten enseñar a Quartermaster tu propio vocabulario, sin cambios de código:

  • data/recipes.json — roles, requisitos previos y stacks seleccionados. Esto es con lo que razona el linter de conflictos: qué activos compiten por el mismo trabajo, qué necesita cada uno y qué combinaciones consideras un stack conocido y bueno.
  • data/concepts.json — el vocabulario visual contra el que CLIP puntúa tus capturas de pantalla. La lista incluida tiene forma de juego; si haces archviz o previs, reemplázala y reconstruye.

Ambos son JSON plano leídos en tiempo de ejecución, y ambos tienen una página de referencia en docs/.

Otras formas de acceso

  • Aplicación de escritorio (run_desktop.bat) — búsqueda spotlight PySide6 con icono de bandeja; pulsa Win+Alt+V en cualquier lugar de Windows. Funciona junto a tu agente sin estorbar: la base de datos se ejecuta en modo WAL, por lo que la GUI escribiendo mientras tu agente busca nunca bloquea a ninguno de los dos.

    Es más que la barra de búsqueda, aunque esa es la parte que usarás más:

    • Pulsa espacio en cualquier resultado para una vista previa a tamaño completo, como hace Finder. Los paneles de detalle muestran hasta 24 capturas de galería, decodificadas y almacenadas en caché en segundo plano.
    • Las filas de Megascans muestran sus especificaciones de escaneo en línea — densidad de texel, dimensiones físicas, lista de mapas PBR — para que puedas distinguir un acantilado de 5785 px/m de una superficie de mosaico de 1 m sin abrir la página de la tienda.
    • Revelar en el Explorador, Desempaquetar en Unity (mismo sandbox y eliminación de demos que la herramienta MCP) y Copiar contexto, que vuelca el título, editor, pipelines, formatos, especificaciones y ruta de disco de un activo como un bloque de texto plano que puedes pegar directamente en un chat.
    • Filtra por fuente (Unity, Fab, Quixel, Gumroad, Cosmos), por pipeline (HDRP, URP, Built-in) o por lo que ya está en disco.
    • Los inicios de sesión, las cosechas y la sincronización de Quixel se ejecutan desde aquí con progreso en vivo y una ETA en curso, y todos son reanudables.
  • Interfaz web (run_ui.bat) — panel de modo oscuro en http://localhost:7890.

  • En Unity — importa editor_bridge/Quartermaster-Bridge.unitypackage, luego Window > Quartermaster. Busca e importa sin salir del editor. Nota al margen: ese paquete puente es generado por src/build_bridge.py, que escribe el mismo formato tar que lee unpacker.py. Dogfooding a propósito.

Seguridad

Esto guarda sesiones de tienda y escribe en tus proyectos, así que se toma en serio la API local:

  • Cada endpoint que cambia estado requiere un token (generado en el primer inicio, almacenado en data/.auth_token, reflejado para el puente de Unity). Envíalo como X-Quartermaster-Token o Authorization: Bearer; la interfaz web obtiene una cookie SameSite=Strict automáticamente.
  • Las solicitudes de origen cruzado se rechazan incluso con un token válido.
  • El sandbox del desempaquetador colapsa segmentos .., elimina letras de unidad y caracteres de control, reubica cualquier cosa fuera de Assets/ bajo Assets/_Quartermaster_Imported/ (excepto un paquete UPM incrustado bien formado, que se confina a su propia carpeta Packages/<name>/), y asegura que la ruta final caiga dentro del proyecto — aplicado por pruebas, no por vibraciones (python run_tests.py -v).
  • El proxy de imágenes está en una lista blanca de dominios, bloquea rangos privados y endpoints de metadatos, revalida cada salto de redirección, limita tamaños y poda las entradas más antiguas una vez que la caché supera su límite de archivos.

Nada llama a casa. Tu biblioteca, embeddings, rutas de disco y sesiones de tienda permanecen en esta máquina.

Configuración

Claves opcionales en config.json (creado en el primer inicio):

ClavePredeterminadoPropósito
server_port7890Puerto de la interfaz web / API.
embedding_modelBAAI/bge-small-en-v1.5Cualquier modelo compatible con fastembed. Cámbialo y reconstruye el índice.
fab_vault_dirsauto-detectadoAnula las ubicaciones de Fab VaultCache.
strip_dirs / strip_extsdemos, docs, PDFsLo que descarta el desempaquetador.
enrich_batch_size / enrich_batch_pause20 / 3sAcelerador de cortesía para el enriquecimiento.
media_cache_enabledtrueCaché de disco para el arte de portada proxy.

Limitaciones honestas

  • Primero Windows, capaz en Linux. Windows es la plataforma probada, y el atajo Win+Alt+V es solo de Windows. Se envía una compilación linux-x64 y el escaneo de disco conoce las raíces de caché de Linux y macOS, pero reciben mucho menos uso que las rutas de Windows. No hay compilación para macOS.
  • Una máquina, un usuario. Sin sincronización, sin modo servidor. Deliberado.
  • Cosechar es hacer scraping. Unity y Fab cambian sus internos cuando les place, y lo han hecho — los tamaños de fragmento, endpoints y formas GraphQL aquí son correctos al día en que lo envié, no para siempre. Cuando una búsqueda vuelve vacía, data/store_harvest.log registra cada respuesta JSON vista; ahí es donde empezar a cavar.
  • La taxonomía es heurística. Las categorías se infieren mediante una mezcla multimodal de tokens de límite de palabra, etiquetas de tienda y minería de conceptos visuales CLIP de disparo cero desde capturas de pantalla. Los títulos muy estilizados sin capturas de pantalla se predeterminan a Tools & Utilities, aunque la búsqueda semántica vectorial y la búsqueda híbrida siempre cubren todo el almacén independientemente de la categoría asignada. Ajustar el vocabulario visual está documentado en docs/concepts.md.
  • La indexación se detiene en el límite del paquete y los metadatos de la tienda son ruidosos. La búsqueda opera a través de títulos, descripciones, etiquetas y embeddings CLIP de imagen completa de capturas de galería. Enfrenta dos límites estructurales:
    1. Sin indexación interna de activos: No desempaqueta contenidos de archivo para indexar sub-mallas individuales, prefabs o nombres de archivo internos (por ejemplo, buscar un sub-elemento arquitectónico específico como una "teja" o "contrahuella de hormigón curvo" dentro de un paquete de entorno modular no dará resultados a menos que se declare en el texto del listado o sea prominente en los renders de galería).
    2. Plantillas de tienda vacuas: Una fracción notable de listados de tienda (particularmente las og:description plantillas de Unity) contienen puro relleno de marketing ("Eleva tu flujo de trabajo con...") que lleva cero información técnica. Los embeddings visuales CLIP existen precisamente para cerrar esta brecha, pero los vectores de imagen completa no siempre pueden resolver sub-elementos finos.
  • El desempaquetado es solo Unity. Los activos de Fab se indexan y son buscables, pero la extracción .unitypackage obviamente no aplica.

Cuando se rompe

Abre un issue. Es un proyecto en solitario, así que no puedo prometer un tiempo de respuesta, pero sí los leo.

Lo que ayuda, por síntoma:

  • Una búsqueda volvió vacía o corta. Esto es lo más probable que se rompa, porque las tiendas cambian sus internos sin aviso. data/store_harvest.log registra cada respuesta JSON que la cosecha vio — la cola de ese archivo es el diagnóstico completo. Inclúyelo.
  • La búsqueda no devuelve nada sensato. Revisa python -m src.vision status primero. Un índice no construido degrada a solo palabras clave silenciosamente, y eso explica la mayoría de los informes de "la búsqueda está rota".
  • Categorías incorrectas, o un conflicto que no es real. Eso suele ser la base de conocimiento más que el código — docs/recipes.md y docs/concepts.md cubren cómo arreglarlo tú mismo, y un PR a data/recipes.json con una regla para la que no tengo los activos para probar es genuinamente bienvenido.
  • El standalone no arranca. Es --windowed, así que falla silenciosamente. %LOCALAPPDATA%\Quartermaster\data\crash.log es donde aterriza.

Si construyes algo genial con esto, me encantaría saberlo.

Una nota sobre las tiendas

Quartermaster lee tu propia cuenta, desde tu propia máquina, en un navegador en el que iniciaste sesión tú mismo. No guarda credenciales, no envía nada a ningún servidor mío y no tiene telemetría — la sesión vive en un perfil de navegador local y la biblioteca en un archivo SQLite local. No hay backend compartido que pueda filtrarse.

No está afiliado, respaldado ni conectado a Unity Technologies, Epic Games, Gumroad o Leartes Studios. Unity, Unity Asset Store, Fab, Unreal Engine, Quixel, Megascans, Gumroad, Leartes y Cosmos son marcas comerciales de sus respectivos propietarios. Automatizar el acceso a cualquier servicio es tu decisión según los términos de ese servicio, y esta herramienta no la toma por ti.

Licencia

MIT. Ver LICENSE.