Skip to main content
Glama

EnfusionTexKit

Headless PBR-Texture-Adapter für Arma Reforger / Enfusion — von einer Quelltextur zum einsatzbereiten .emat im Addon, per MCP oder CLI.

TexKit portiert die Map-Erzeugungs-Algorithmen von Materialize (GPL-3.0) in einen schlanken Python-Kern und ergänzt genau das, was Materialize für Enfusion prinzipbedingt nicht liefern kann: das korrekte Enfusion-Kanal-Packing, die .emat-Generierung und die atomare Ablage im Ziel-Addon.


Warum das Ganze

Materialize erzeugt gute PBR-Einzelmaps, aber sein Output passt nicht auf Enfusion:

  • Die Property-Map packt nur R/G/B — Enfusion braucht Occlusion in NMO.a und Roughness in BCR.a.

  • Materialize liefert Smoothness, Enfusion will Roughness (R = 1 − S).

  • .emat-Erzeugung und Addon-Ablage fehlen komplett.

TexKit schließt diese Lücke. Es ist bewusst ein Adapter, kein Materialize-Ersatz: kein GUI, keine Echtzeit-Vorschau, kein GPU-Pfad. Quelltextur (oder fertige Materialize-Exporte) rein → fertiges Enfusion-Material im Addon raus. Materialize bleibt für die Handarbeit (Tiling, Alignment) im Werkzeugkasten.


Related MCP server: ReforgerForge MCP

Was es kann

  • End-to-end Map-Generierung aus einer einzigen Diffuse-Quelltextur: Licht/Schatten-Entfernung → Height → Normal (DirectX) → Metallic/Roughness → AO → optional Edge-Wear.

  • Enfusion-Kanal-Packing nach Vanilla-Konvention (BCR / NMO / Opacity).

  • Material-Presets als Erkennungslogik, nicht als Flachwerte — eine Uniform bleibt matt, ihre Schnallen glänzen trotzdem (siehe Presets).

  • Alpha-Dilation gegen den schwarzen Saum an Cutout-Texturen — automatisch in der Foliage-Pipeline und als eigenständiges tex_dilate (siehe Alpha-Dilation).

  • Zwei-Phasen-.emat-Flow, der echte .edds-GUIDs aus dem Workbench-Import verdrahtet.

  • Ingest-Brücke für bereits in Materialize erzeugte Einzelmaps (Smoothness→Roughness, Normal-Y-Konvention).

  • Kanal-Kontaktblatt pro Lauf als visuelle Kontrolle + tex_inspect für Zahlen ohne Viewer-Fehldeutung.

  • Läuft als MCP-Server (für Claude) und als CLI über demselben Kern.

Nicht-Ziele (v1)

Kein GUI/Vorschau, kein GPU-Pfad, kein eigener BCn/EDDS-Encoder (die Workbench kompiliert PNG→.edds), kein Tiling-Maker, kein Perspektiv-Alignment, keine Modell-/Prefab-Zuweisung (das macht enfusion-mcp).


Installation & Start

Runtime: Python ≥ 3.12, Abhängigkeiten numpy, pillow, scipy.

Als MCP-Server (registriert in claude_desktop_config.json und ~/.claude.json)

uv run --no-project --with mcp --with numpy --with pillow --with scipy server.py

--with mcp allein würde eine isolierte Umgebung ohne den Bildstack erzeugen. Das mcp-Paket bleibt bewusst nicht global installiert.

Als CLI

python cli.py <command> ...

Der Zwei-Phasen-Workflow

Feldbefund aus Vanilla und Phillips Addons: .emat referenziert ausschließlich .edds, nie PNG. Die .edds (+ .edds.meta mit GUID) entsteht erst durch den Workbench-Import. Deshalb ist der Ablauf zwingend zweistufig:

┌─ Phase 1 (TexKit) ──────────────┐   ┌─ Dazwischen ────────┐   ┌─ Phase 2 (TexKit) ─────────────┐
│ tex_material / material         │   │ Workbench-Import     │   │ tex_emat / material-finalize    │
│ Quelle → Maps → Packing →       │──▶│ PNG → .edds +        │──▶│ liest GUIDs aus .edds.meta,     │
│ PNGs atomar ins Addon staged    │   │ .edds.meta (WB-GUID) │   │ schreibt fertiges .emat         │
└─────────────────────────────────┘   └─────────────────────┘   └─────────────────────────────────┘

Fehlen in Phase 2 die .edds.meta, bricht TexKit mit einer klaren Import-Aufforderung ab, statt ein kaputtes Material zu schreiben. Der Workbench-Import selbst läuft außerhalb von TexKit (headless via enfusion-mcp orchestrierbar).


MCP-Werkzeuge

Alle Tools sind zustandslos — jeder Aufruf ist vollständig über seine Argumente beschrieben.

Tool

Phase

Zweck

tex_material(source, preset, addon_dir, name, sub_path?, overrides?, overwrite?)

1

End-to-end: Quelle → alle Maps → Packing → atomar ins Addon staged, mit Kontaktblatt. Schreibt bewusst noch kein .emat.

tex_generate(source, preset, out_dir, overrides?)

Nur Maps + Kontaktblatt in einen freien Ordner (kein Addon-Schreiben). Für Experimente/Sichtprüfung.

tex_emat(addon_dir, name, family, sub_path?, overwrite?)

2

Schreibt das .emat, nachdem die Workbench die PNGs zu .edds importiert hat. Liest GUIDs aus .edds.meta.

tex_pack(maps_dir, out_dir, name, normal_y?)

Ingest: Materialize-Einzelmaps → BCR/NMO. Invertiert Smoothness zu Roughness. normal_y: directx (Default) / opengl.

tex_dilate(image, out, masks?, threshold?, min_gain?, dry_run?)

Alpha-Dilation gegen den schwarzen Cutout-Saum. Zieht die Farbe der deckenden Pixel per NN über die Silhouette; Alpha byte-identisch. Schreibt nur bei messbarem Gewinn.

tex_params(preset?)

Alle Presets mit sämtlichen Parametern + Defaults als JSON. Die Feldnamen sind zugleich die gültigen Override-Pfade.

tex_inspect(image)

Kanalstatistiken (min/max/mean je R/G/B/A) + Neutralitäts-Hinweise — prüft BCR/NMO/Masken ohne Viewer.


CLI

Spiegelt die MCP-Tools; Fehler → error: ... auf stderr + Exit 1.

# Nur Maps + Kontaktblatt in einen Ordner
python cli.py generate <source> --preset metall --out <dir> [--overrides '{"roughness.base_rough":0.5}']

# Phase 1: Maps ins Addon stagen
python cli.py material <source> --preset stoff --addon <addon_dir> --name MyMat [--sub-path Assets/TexKit] [--overwrite]

# Phase 2: .emat aus .edds.meta-GUIDs (nach Workbench-Import)
python cli.py material-finalize --addon <addon_dir> --name MyMat --family stoff [--overwrite]

# Ingest: Materialize-Einzelmaps packen
python cli.py pack <maps_dir> --out <dir> --name MyMat [--normal-y directx|opengl]

# Alpha-Dilation gegen den schwarzen Cutout-Saum
python cli.py dilate <image> --out <png> [--mask <opacity.png> ...] [--threshold 250] [--gain 8] [--dry-run]

# Presets + Parameter als JSON listen
python cli.py params

Material-Presets

Presets sind Erkennungslogik, keine Flachwerte. Reale Assets mischen Materialien in einer Textur — jede Familie definiert daher neben den Basiswerten eine Detail-Erkennung (Sättigungs-/Luminanz-Heuristik), die abweichende Bereiche findet und dort Metalness/Roughness lokal umsteuert.

Preset

Basis

Erkennung tut

Cutout

metall

metallisch, glänzend

senkt Metal/Glanz auf Dreck, Rost, Gummi-/Stoffanteilen (auch für Fahrzeuge/lackiertes Metall)

nein

stoff

matt, Metal 0 (base_rough=0.92)

gibt nur an Metall-Hardware und Glanzleder Glanz frei (strengere Schwellen: sat_gain=4.0, lum_floor=0.35)

nein

foliage

dielektrisch matt (base_rough=0.75)

Metal hart 0 (detect_gain=0, metal_cap=0) — Alphakanal Pflicht, erzeugt _Opacity

ja

Overrides per flachem Punktpfad-Dict — der Pfad ist entweder ein Top-Level-Preset-Feld oder ein sub_params.feld:

{ "roughness.base_rough": 0.5, "edge_wear": 0.2, "metallic.sat_gain": 3.0 }

tex_params listet jeden gültigen Pfad. Ein unbekannter Pfad wirft ValueError mit Nennung des Pfads.


Kanal-Konventionen

Datei

Packung

<Name>_BCR

BaseColor (RGB) + Roughness in A

<Name>_NMO

Normal.RG (DirectX, Y-down/Grün invertiert) + Metal in B + Occlusion/AO in A

<Name>_Opacity / _Mask

Graustufe in RGB, A = 255 (nur bei Cutout-Presets)

⚠️ Viewer deuten Daten-Alpha als Transparenz fehl. Beurteile gepackte Maps deshalb nie am RGBA-Bild direkt, sondern über das Kontaktblatt (<Name>_contact.png, pro Lauf erzeugt) oder tex_inspect.

Die Silhouetten-Maske wird immer genutzt, wenn die Quelle echte Transparenz trägt (alpha.min() < 1.0, Schwelle alpha ≥ 8/255) — sonst prägen sich Hintergrund-Halos in Height/Normal ein. cutout-Presets verlangen diese Maske zusätzlich und brechen ohne Alpha mit ValueError ab.


Alpha-Dilation (schwarzer Cutout-Saum)

Blätter, Netze und Laub mit weichem Alpha-Rand zeigen im Spiel einen dunklen Saum: die halbtransparenten Randpixel wurden beim Speichern gegen den schwarzen Hintergrund verrechnet, ihre Farbe ist dauerhaft abgedunkelt, und die GPU mischt beim Mipmapping zusätzlich mit dem schwarzen Umfeld. TexKit zieht die Farbe der voll deckenden Pixel per Nearest-Neighbour über die Silhouette hinaus — die Maske/der Alphakanal bleibt byte-identisch, nur die Farbe darunter wird korrigiert.

  • Automatisch in der foliage/Cutout-Pipeline vor dem BCR-Packing — neu erzeugte Materialien haben den Saum ab Werk nicht.

  • Manuell via tex_dilate / python cli.py dilate für bestehende oder fremde Texturen.

Drei nicht offensichtliche Regeln sind fest eingebrannt (haben im Vorgänger-Script mehrere Fehlversuche gekostet):

  1. Schwelle 250, nicht 200. Die Schwarz-Verrechnung reicht weit in den scheinbar deckenden Bereich; erst ab Maskenwert ~251 ist die Farbe sauber. Schwelle 200 verschleppt dunkle Werte nach außen.

  2. Masken im R-Kanal lesen, nicht in der Luminanz — manche Masken haben Daten nur auf R, convert("L") drückt die künstlich herunter.

  3. Vereinigungsmenge bei mehreren Masken (--mask mehrfach) — wird eine Textur mit verschiedenen Masken benutzt, darf kein Pixel geändert werden, der unter einer anderen Maske sichtbar ist. Größenunterschiede werden per NEAREST aufgelöst.

⚠️ Ohne --mask wird der Alphakanal der Textur selbst als Silhouette genommen — richtig für eine Cutout-Quelle, aber falsch für ein gepacktes _BCR/_NMO (dort ist Alpha = Roughness/AO). In dem Fall immer die zugehörige Opacity-Maske übergeben.

Reimport-Falle: Erzeugte PNGs müssen über die Workbench reimportiert werden. Die bestehende <name>.edds.meta liegen lassen → GUID bleibt erhalten → Material-Referenzen bleiben heil. PNG niemals einfach in .edds umbenennen.

Robustheit

  • Atomare Schreibvorgänge: erst temp, dann rename — kein halbes PNG landet im Addon.

  • Staging innerhalb des Addons (gleiche Partition ⇒ echter Rename, kein EXDEV-Copy): der Normalfall ist ein einziger atomarer Verzeichnis-Rename.

  • Überschreibschutz: existierende Zieldateien ⇒ Abbruch mit Kollisionsliste, außer overwrite=True.

  • Rollback mit Rettungsanker: schlägt ein Overwrite mittendrin fehl, wird vollständig zurückgerollt; überschriebene Dateien liegen im _backup und werden nie stillschweigend gelöscht.

  • Kontaktblatt landet neben Data/, nicht darin (unregistrierte PNGs im Asset-Baum erscheinen sonst als 0000-GUID-Transienten im Resource Browser).


Projektstruktur

EnfusionTexKit/
├── texkit/                  # Rechenkern — importiert weder MCP noch CLI
│   ├── ops.py               # Box-Blur, Blur-Pyramide, Push-Pull-Inpaint, Resampling, atomares Speichern
│   ├── diffuse.py           # Edit-Diffuse (Licht/Schatten/Hotspot-Entfernung)
│   ├── height.py            # Height-from-Diffuse (Frequency-EQ)
│   ├── normal.py            # Normal-from-Height (Vorwärtsdifferenzen, DirectX-G)
│   ├── metallic.py          # Metallic-Heuristik (HSL-Distanz)
│   ├── roughness.py         # Roughness (invertierte Smoothness)
│   ├── ao.py                # Multi-Scale AO
│   ├── dilate.py            # Alpha-Dilation gegen den schwarzen Cutout-Saum (NN, scipy)
│   ├── edge.py              # Curvature/Edge-Map (fließt optional in Roughness)
│   ├── presets.py           # metall/stoff/foliage + Override-Auflösung
│   ├── packer.py            # BCR/NMO/Mask/Opacity-Packing
│   ├── emat.py              # .emat-Generator aus templates/
│   ├── contact.py           # Kanal-Kontaktblatt
│   ├── ingest.py            # Materialize-Export-Erkennung & -Übernahme
│   ├── validate.py          # Name/sub_path/preset-Validierung (von server.py & cli.py geteilt)
│   └── pipeline.py          # Orchestrierung: generate / material / finalize_material
├── templates/               # .emat-Vorlagen je Familie (aus Vanilla destilliert)
├── server.py                # MCP-Server (stdio)
├── cli.py                   # CLI-Zugang
├── tests/                   # Golden- & Invarianten-Tests, Dogtag-Fixture (61 Tests)
├── docs/                    # Spec, Plan, Backlog, Verifikation
└── LICENSE                  # GPL-3.0

Tests

python -m pytest
  • Golden-Tests: Referenztextur → SHA-256 der Maps; Algorithmus-Drift schlägt an.

  • Invarianten-Tests: NMO außerhalb der Silhouette neutral, Roughness-Roundtrip, Kanalbelegung, Masken RGB-identisch mit A=255.

  • Realfall-Fixture: der Dogtag-Durchlauf.

test_server_smoke wird ohne mcp im Test-Interpreter übersprungen; der echte Regressionsschutz für server.py ist der uv-Smoke (uv run --with mcp ... -c "import server").

Status (2026-08-03): v1 auf master, 61 Tests grün, MCP registriert. Engine-Parse live verifiziert (Workbench lädt/parst das erzeugte .emat). Offen: reine In-World-Sichtprüfung (Normal-Richtung/Glanz am Objekt im Licht).


Status & Roadmap

Voller Backlog aus dem Final-Review: docs/backlog.md.

v1.1 (Aufräumen): ungenutzte write_meta/texture.meta.tpl markieren, Zweierpotenz-Warnung, overlay_blur_frac verdrahten oder entfernen.

v2 (Substanz): .gamemat/SurfaceProperties je Familie differenzieren, voll templategetriebene Slot-Ableitung in finalize_material, Ingest-Cutout-Support, weitere Familien (Leder/Holz/Gummi), Tiling-Maker, Alignment, GPU-Pfad, Workbench-Auto-Import-Verkettung, .mtz-Import.


Lizenz

GPL-3.0. Die Map-Erzeugungs-Algorithmen sind Ports aus Materialize (GPL-3.0), daher steht das gesamte Projekt unter GPL-3.0. Lokale Nutzung ist davon unberührt — die GPL-Pflichten greifen nur bei Weitergabe.

Available Tools

6 tools
tex_ematB

Phase 2: .emat schreiben, nachdem die Workbench die gestagten PNGs zu .edds importiert hat. Liest die GUIDs aus den .edds.meta und verdrahtet echte .edds-Referenzen. family = metall/stoff/foliage (bestimmt Shader-Template).

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
familyYes
sub_pathNoAssets/TexKit
addon_dirYes
overwriteNo

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations (readOnlyHint=false is default, no useful info), the description must carry the behavioral burden. It discloses that the tool writes files (writes .emat), that it depends on prior .edds imports, and that it reads .edds.meta GUIDs. However, it does not disclose the overwrite behavior, error conditions (e.g., missing .edds), or what happens on failure, though the overwrite parameter exists in schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single dense paragraph of two sentences, which is reasonably economical. However, it mixes workflow context, technical mechanics, and parameter semantics in a compact run-on structure without clear separation. It is not front-loaded with the primary action verb; 'Phase 2' precedes the actual tool function, making the intent less immediately scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a file-writing (mutation) tool with no annotations and no output schema, operating within a complex multi-phase pipeline. The description should clarify prerequisites (that .edds must exist first), error states, and the overwrite behavior—none of which are covered. The 3 undocumented remaining parameters and the tool's role in a multi-step workflow leave the agent under-informed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate for 5 undocumented parameters. It partially does: family is explained (determines shader template), and it implies name/sub_path relate to file generation. But overwrite and addon_dir have zero explanation, and the description doesn't map which parameters are involved beyond family. The description adds some meaning but leaves gaps for 3+ parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool writes .emat files ('Phase 2: .emat schreiben') after PNGs are imported to .edds by the workbench, reading GUIDs from .edds.meta and wiring real .edds references. The family parameter role is explained (determines shader template). While it lacks an explicit verb+resource target contrast with siblings, the purpose is specific and technical.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies a sequential workflow ('Phase 2', 'nachdem die Workbench...') and states the family choices (metall/stoff/foliage). However, it does not explicitly contrast with sibling tools like tex_material or tex_generate, nor does it state when NOT to use this tool. The phase-ordering context is useful but not elaborated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

tex_generateB

Nur Maps + Kontaktblatt in einen freien Ordner erzeugen (kein Addon-Schreiben). Gleiche Pipeline wie tex_material, fuer Experimente und Sichtpruefung.

ParametersJSON Schema
NameRequiredDescriptionDefault
presetYes
sourceYes
out_dirYes
overridesNo

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations show readOnlyHint: false (not read-only) and no destructive/idempotent hints, so the description carries the burden. The description does disclose the key behavioral trait: it writes to a free folder rather than to addons ('kein Addon-Schreiben'), which is non-destructive behavior worth noting. However, annotations contradict in nuance - readOnlyHint:false suggests mutation, but the 'kein Addon-Schreiben' implies it doesn't modify project state. Given no annotations cover write behavior, the description provides modest transparency but lacks detail on what happens on repeated runs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, compact and informative. Each sentence earns its place - one states the deliverable and scope, the second provides the pipeline context and purpose. No filler or redundancy. Slightly under-specified on params but structurally efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 0% schema coverage, no output schema, and no annotation support for behavior, the description is minimal. It captures the main purpose (generate maps + contact sheet to a free folder) and intended use (experiments/inspection). However, given 4 params are entirely undocumented, and the tool is a pipeline with potential for significant behavior, the description feels incomplete for guiding an agent through correct invocation. The reference to tex_material being 'the same pipeline' helps but assumes agent familiarity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description provides NO parameter-level information. The schema itself only lists param names (source, preset, out_dir, overrides) with generic titles and no descriptions or enums. The description mentions 'Gleiche Pipeline wie tex_material' which implies presets/sources work like that sibling tool, but doesn't explain what values these parameters accept, formats, or relationships. For a 4-param tool with zero schema coverage, the description should compensate significantly but doesn't.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it generates Maps + a contact sheet into a free folder (not addon-writing). The verb 'erzeugen' (generate) plus the specific deliverable (maps + contact sheet) is specific. It references the same pipeline as tex_material, which gives some sibling differentiation context, though it could be clearer on exactly what distinguishes it from tex_material itself.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description mentions it's for experiments and visual inspection ('fuer Experimente und Sichtpruefung'), which implies a use case. It also contrasts with 'kein Addon-Schreiben' which implicitly distinguishes it from writing tools. However, it doesn't explicitly state when NOT to use this vs tex_material or tex_emat, leaving the boundary somewhat implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

tex_inspectA
Read-onlyIdempotent

Kanalstatistiken eines Bildes (min/max/mean je R/G/B/A) plus Neutralitaets-Hinweise — zum Nachpruefen erzeugter BCR/NMO/Masken ohne Viewer (Viewer deuten Daten-Alpha als Transparenz fehl).

ParametersJSON Schema
NameRequiredDescriptionDefault
imageYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and idempotentHint=true, so the safe-read nature is covered. The description adds meaningful context: that the tool doesn't need a viewer and that it reports neutrality hints. However, it doesn't disclose the return format, whether it prints to console or returns structured data, or behavior on missing/invalid images. With annotations covering safety, this is acceptable but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, dense sentence with a clear purpose and a parenthetical rationale. It's front-loaded with the core capability (channel statistics per RGBA) followed by the use case. No wasted words, though the German language and nested clauses make it slightly dense. Efficient for a one-parameter tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple (1 param, read-only, no output schema, no nested objects), so the description covers the essential purpose well. It explains the neutrality-hints feature and the reason viewers are misleading. The main gap is lack of detail on parameter format/expected input and output presentation, but for a read-only inspection tool these are minor. Adequate for the complexity level.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There's only 1 parameter (image) and schema description coverage is 0%. The description doesn't elaborate on the image parameter beyond the tool's overall purpose—no mention of supported image formats, whether it accepts file paths vs base64, or constraints. The single parameter's semantics are largely inferable from the tool's purpose, but given 0% coverage, the description should have specified the expected format.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb+resource: inspecting image channel statistics (min/max/mean per R/G/B/A) plus neutrality hints. It clearly distinguishes itself from siblings (tex_material, tex_generate, tex_emat, tex_params) by referencing BCR/NMO/masks inspection without a viewer. It could be considered slightly verbose but purpose is distinct.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use it: to verify generated BCR/NMO/masks without a viewer, because viewers misinterpret data-alpha as transparency. This explains a specific usage scenario that distinguishes it from the sibling texture tools. It doesn't explicitly say when NOT to use it, but the context is clear and actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

tex_materialA

End-to-end Phase 1: Quelltextur -> alle Maps (Preset metall/stoff/foliage) -> Enfusion-Packing (BCR/NMO/Opacity) -> atomar ins Addon gestaged, mit Kanal-Kontaktblatt. Schreibt bewusst noch KEIN .emat: erst der Workbench-Import erzeugt .edds+.edds.meta, danach tex_emat aufrufen. overrides: dict mit Punktpfaden wie {'roughness.base_rough': 0.5}.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
presetYes
sourceYes
sub_pathNoAssets/TexKit
addon_dirYes
overridesNo
overwriteNo

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations are minimal (readOnlyHint false, no idempotent/destructive hints), so the description carries the burden. It discloses the important behavioral trait that this step deliberately skips .emat creation, which is valuable sequencing info. However, it doesn't mention whether overwrite behavior is destructive, what happens to existing staged files, or whether the operation is reversible — gaps for a mutating tool with no annotation coverage on safety profile.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single dense paragraph that packs a lot of information but is not front-loaded or scannable. It buries the overrides example (the most schema-compensating content) at the end. The German terminology mixed with English makes parsing harder. It's efficient in word count but poorly structured for quick comprehension.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has 7 parameters with 0% schema coverage and no output schema, so completeness burden is high. The description covers the pipeline stages and the overrides format, plus the critical .emat sequencing note. But it omits return behavior (contact sheet format?), error conditions, and meaning of half the parameters. Given 7 params and no schema enrichment, this is only partially complete — adequate but with notable gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate for parameter meaning. The description does explain the 'overrides' parameter with a concrete example ({'roughness.base_rough': 0.5}) and dotted-path semantics, which is genuinely helpful. However, it provides no explanation for the other 6 parameters (source, preset, addon_dir, name, sub_path, overwrite), leaving the agent to infer them from names alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states what the tool does: it processes a source texture end-to-end through presets (metall/stoff/foliage), packs to Enfusion formats (BCR/NMO/Opacity), and stages atomically into the addon with a channel contact sheet. However, it heavily uses German technical jargon ('Quelltextur', 'atomar ins Addon gestaged', 'Kanal-Kontaktblatt') that may reduce clarity for English-speaking agents, and it doesn't explicitly contrast with sibling tools like tex_emat or tex_generate in the purpose statement.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear sequencing guidance: it explicitly states it does NOT write .emat and instructs that tex_emat should be called after workbench import creates .edds files. This gives strong when-to-use and what-to-do-next context. However, it doesn't explicitly name sibling tools like tex_generate or tex_inspect for specific exclusion scenarios, though the pipeline framing makes the flow reasonably clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

tex_packA

Ingest-Bruecke: von Phillip manuell in Materialize erzeugte Einzelmaps (Suffixe _height/_diffuse/_normal/_metallic/_smoothness/_edge/_ao) zu Enfusion-BCR/NMO packen. Invertiert Smoothness zu Roughness; normal_y 'directx' (Materialize Max Style, Default) oder 'opengl' (invertiert Gruen). Fehlende Maps werden neutral aufgefuellt und in warnings gemeldet.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
out_dirYes
maps_dirYes
normal_yNodirectx

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations to rely on, the description discloses key behaviors: inverting smoothness to roughness, supporting two normal_y conventions, neutrally filling missing maps, and reporting warnings. It does not explicitly mention file writing or overwrite behavior, but the transformative details are substantial. It stops short of full transparency regarding filesystem side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single dense sentence with many meaningful details, but it is somewhat run-on. It is not overly long and every phrase adds value, though breaking it into structured points would improve readability. It earns a 4 for efficiency without being bloated.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the core behavior: input maps, output format, transformations, normal_y options, and missing-map handling with warnings. There is no output schema, so it partially explains what the tool produces. It does not mention return values or file structure, but for a packing tool, the operational context is mostly complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 0% description coverage, so the description must compensate. It explains 'normal_y' with its directx/opengl options, but does not describe 'maps_dir', 'out_dir', or 'name'. The description implies the output format and missing-map handling, but fails to clarify three of the four parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: packing manually created Materialize single maps into Enfusion BCR/NMO format, with specific transformation details. The verb 'packen' and the resource 'Einzelmaps' make the purpose unambiguous and distinct from sibling tools that generate or inspect textures.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context: it is an ingest bridge for maps manually created in Materialize with specific suffixes. It does not explicitly name alternatives or exclusions, but the context is clear enough to infer when this tool applies. No explicit 'when not to use' is given, hence not a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

tex_paramsA
Read-onlyIdempotent

Alle Presets (metall/stoff/foliage) mit saemtlichen Parametern und Defaults als JSON — die Feldnamen sind zugleich die gueltigen Override-Punktpfade.

ParametersJSON Schema
NameRequiredDescriptionDefault
presetNo

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and openWorldHint=false, so the agent knows this is a safe, deterministic read. The description adds the behavioral detail that field names serve as override point-paths, which explains how output maps to other tools' usage. Given annotation coverage, the description adds meaningful extra context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, dense sentence that conveys purpose, scoping, output format, and a critical coupling detail (field names = override paths). Zero wasted words. Impactful and front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple reference-lookup tool with one optional parameter, strong annotations (readOnly, idempotent), and no output schema, the description covers the essential needs: what it returns, the three preset scopes, and how output connects to the override system. The one gap is that the preset parameter's accepted values are only implied, not enumerated, but this is a minor gap for such a low-complexity tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There's one parameter (preset) with a default of null, and schema description coverage is 0%. The description compensates by stating presets are metall/stoff/foliage, making it clear the preset parameter filters among these named options. This adds meaning beyond the bare schema. A brief mention that preset accepts these three values explicitly would push it to 5, but the enums are inferable from the description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states it returns all presets (metall/stoff/foliage) with all parameters and defaults as JSON, and clarifies field names double as valid override point-paths. This clearly defines the resource (presets) and the output format. It doesn't explicitly contrast with siblings like tex_generate or tex_inspect, but the description is specific enough about what it returns.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description conveys that this tool provides parameter reference data for the presets and that field names serve as override paths. This implies it's for lookup/reference purposes before generating or inspecting materials, but no explicit when-to-use vs alternatives (e.g., tex_inspect, tex_emat) is given. Sibling differentiation is only implicit through the output being reference data.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 6 tool updatesv0.1.0
    • First observedtex_emat
    • First observedtex_generate
    • First observedtex_inspect
    • First observedtex_material
    • First observedtex_pack
    • First observedtex_params

TDQS

A3.7/5.0

Scored across 6 tools

Disambiguation4/5

Tools are mostly distinct: tex_generate and tex_material both create maps, but one writes to a folder and the other stages into the addon, so purpose is clear. tex_pack vs tex_material both pack to BCR/NMO but differ in input source (existing maps vs full pipeline). Minor overlap exists but descriptions reduce ambiguity.

Naming Consistency4/5

All tools share the 'tex_' prefix and lowercase snake_case, making them predictable. However, the suffix is not uniformly a verb (params, material, emat are nouns), so it deviates slightly from a strict verb_noun pattern. Still consistent and readable.

Tool Count5/5

6 tools is well-scoped for the Enfusion texture pipeline, covering generation, parameter inspection, verification, packing, and .emat creation. No unnecessary bloat, each tool has a clear role.

Completeness5/5

The toolset covers the full workflow from source texture to final .emat, including experimental generation, inspection, and manual map packing. External workbench import is acknowledged, so no major gaps are apparent.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    Not graded
    maintenance
    An MCP server for Arma Reforger and Enfusion engine modding that enables users to create mods, search API classes, and generate scripts through natural language. It provides a comprehensive suite of tools for scaffolding addons, generating prefabs, and building projects using the Workbench CLI.
    89
    14
    -
  • A
    license
    B
    quality
    C
    maintenance
    Exposes procedural material and isometric terrain generation as MCP tools, allowing agents to create deterministic PBR textures and 2:1 isometric tiles from JSON recipes.
    12
    1
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/WKImods/EnfusionTexKit'

If you have feedback or need assistance with the MCP directory API, please join our Discord server