Atlas / Skills / elcodabra / lego-build-inventory

lego-build-inventoryBLOCK

skills/elcodabra/lego-build-inventory

LEGO from my bricks: photograph your parts, get build ideas and step-by-step instructions. Agent Skill + MCP server for Claude and ChatGPT.

Verdict
BLOCK
Grade
D
Trust score
69 /100
Version
—
Hosts
4 documented
License
MIT
Stars
0
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

[](https://m8ven.ai/mcp/elcodabra-lego-build-inventory-nwdiqy?s=readme)

A Skill plus an MCP server for Claude and ChatGPT. It designs LEGO models only from the parts you actually own, checks that the model holds together and that you have enough of every part, and renders step-by-step instructions in the style of an official booklet (PNG, mp4 1080×1920 / 1920×1080).

Main scenario: photograph your parts → get ideas for what you can build → get the instructions.

📷 photo of one part  → Brickognize (part number + colour) ─┐
📷 photo of a pile    → Claude/ChatGPT reads it by eye → CSV ─┼→ inventory → ideas_suggest → idea_build → preview / mp4
sets / CSV / BrickLink                                    ─┘

Ideas are parametric models: house, tree, mushroom, rocket, robot, tower, heart, pyramid, fire truck, rover, spaceship, and a spaceport scene (a vehicle plus a ship side by side). The pile-driven ones (spaceship, spaceport) try to use as many of your parts as possible, and ideas are sorted so the one that takes the most parts comes first. Each is built from your parts: it picks the largest size that fits, the colours you have, and the part lengths available. Every proposed model passes the check (no overlaps, nothing floating, all parts in the inventory). Alongside the ideas that build now, it lists the ones that are close, with the exact parts missing. On top of the ideas, the agent can design any custom model from the same parts.

Built on the siliconbag/lego-build engine (MIT). On top of it this repo adds an inventory, a check against the inventory with substitute suggestions, JSON models, the MCP server, and packaging for Claude Code, claude.ai, Claude Desktop, Codex and ChatGPT.

.claude-plugin/marketplace.json        Claude Code marketplace
.agents/plugins/marketpla
Read from source at commit a5c0f4f0d0dbOBSERVED · 2026-10-10
Advertisement
02

Install

Commands as the repository documents them. They are shown, not run.

npm install && npx playwright install chromium
03

Host compatibility

What the documentation claims. We have not run a compatibility test.

HostStatusNotes
claude-codementioned
claude-desktopmentioned
codexmentioned
cursormentioned
04

What it tells the agent

The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.

---
name: lego-from-my-bricks
description: Suggests what to build from the user's own LEGO bricks and gives step-by-step build pictures. Use when the user shows photos of their LEGO parts or lists their parts/sets and asks what they can build, wants ideas, instructions or a parts list for a small model (house, tree, rocket, robot, tower, mushroom, heart, pyramid, fire truck, rover, spaceship, spaceport scene, or a custom one). Triggers — "что собрать из моих деталей", "вот мои лего детали", "сфоткал лего, что можно сделать", "инструкция из моих кубиков", "what can I build with these LEGO bricks", "build ideas from my parts". Not for buying sets, prices or official LEGO instructions.
---

# LEGO from my bricks

The user wants to build something from the LEGO parts they actually have. The result is a short answer with **pictures shown inline in the chat**: the finished model first, step pictures only when asked. Explicit user instructions override anything here.

**One picture per answer.** Give the user exactly one PNG per answer (never several files, never `.svg`, never a bare video link). If you can display it inline (e.g. a markdown image), do that; otherwise attach that single PNG.

## Two ways to run

**A. With the MCP app "LEGO из моих деталей" connected** (tools like `parts_from_pile_photo`, `ideas_suggest`, `show_build`): use the tools, they do recognition, building and rendering on the server. Follow the "MCP flow" below.

**B. Without the app** (only this skill): run the Node scripts in `scripts/` in the code sandbox. They need only Node, no npm install. Follow the "Script flow".

Check which tools are available first; prefer A.

## MCP flow

1. **Parts.**
   - Photo with many parts → call `parts_from_pile_photo` with the uploaded file (`files`). Do not describe the photo yourself first, and never write a parts list by eye with `inventory_import` when the photo can be passed (the server recognises far more parts). A new photo replaces the saved list (send several photos of one pile in one call); `inventory_undo` brings the previous list back. Use `mode: "add"` only when the user says the photo adds to what was saved.
   - Photos with one part each → `parts_from_photo` (`add: true`, `qty` = how many of that part the user has).
   - A text list, a set number → `inventory_import` / `inventory_add_set`.
   - Show the recognised parts as a compact table and ask only about lines marked unsure. Fix with `inventory_update`.
2. **Ideas.** `ideas_suggest` shows a card with a real picture of every idea, built from the user's own parts, and a «Собрать» button. Answer in one or two sentences (recommend the first idea, it uses the most parts). Never add images from the web or invent ideas that are not in the list. Mention at most one "almost" idea with what is missing.
3. **Build.** After the user picks: `idea_build` → `show_build` (mode `picture`). The card shows the model and its parts: answer in one sentence, do not retell parts or steps. Never add images from the web or of official sets: only the card, drawn from the user's own parts.
4. **On request only:** `show_build` mode `steps` (step pictures) or mode `video`. Always use `show_build` for these (it plays the video inside the card); do not use `model_render`/`model_preview`.
5. **Own design** (the user wants something not in the ideas): read `lego_guide`, design a model JSON from the inventory, `model_check` until ok, `model_save`, `show_build`.

Images returned to you by a tool are seen by you, not by the user. If the card is not visible in this chat (e.g. you are running as an agent), put the markdown from the tool answer into your reply so the user sees the pictures; never write "shown above" unless it really is.

## Script flow (no app)

Work in a folder, e.g. `/mnt/data/lego`. `S` = path to this skill's `scripts/`.

1. **Parts.** From photos, read the parts yourself following `references/photos.md` (count studs, tell plates from bricks, name colours by key). Write `parts.csv` (`part,color,qty`), show it to the user as a table and let them correct it. Be honest that counting from a photo is approximate.
   ```
   node $S/tools/inventory.cjs import parts.csv --inv inventory.json
   node $S/tools/inventory.cjs show --inv inventory.json
   ```
2. **Ideas.** `node $S/tools/ideas.cjs --inv inventory.json` → offer 2–4 of the "Можно собрать" lines, plus at most one "Почти".
3. **Build and picture.**
   ```
   node $S/tools/ideas.cjs build <idea> [size] --inv inventory.json --out models/<idea>.json
   node $S/tools/draw.cjs models/<idea>.json --all --out out
   ```
   Give the one file `out/<idea>-build.png`: the finished model on the left, numbered steps on the right (new parts of each step outlined in yellow). Text: one sentence plus a compact parts list (`node $S/tools/inventory.cjs bom models/<idea>.json`). Do not describe the steps in text unless asked. `draw.cjs` makes the PNG itself (pure Node), no converter is needed.
4. **Bigger step pictures on request** (e.g. "покажи шаг 3 крупно"): `--steps` writes `<idea>-step1..N.png`; give only the one asked for. `--sheet` gives just the step grid, without the model.
5. **Video.** Not available without the app: say that the build video comes with the "LEGO из моих деталей" app, and offer the step pictures instead.
6. **Own design.** Follow `references/modeling.md`; check with `node $S/tools/check-model.cjs models/<name>.json --inv inventory.json` until it says `no overlaps, everything is held, all parts are in the inventory`.

## Rules

- Use only parts the user has. If something is missing, say exactly what (part, colour, count) instead of silently substituting.
- Only real LEGO parts and colours; no invented printed parts.
- Keep answers short: pictures carry the model. No long step lists in text.
- A model that passes the check was not built by hand: do not promise it is sturdy.
- LEGO is a trademark of the LEGO Group; do not present results as official instructions.

## Files

- `script
05

Trust audit

BLOCKgrade D · trust 69/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (2 observation(s))
Network
declared (1 observation(s))
Shell
declared (2 observation(s))
Dependencies
not all pinned
Secrets in source
none-found

Findings (23)

HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
plugins/lego-inventory-build/skills/lego-inventory-build/scripts/youtube-auth.mjs:65
exec(`${process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start ""' : 'xdg-open'} "${auth}"`);
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
MEDIUMObfuscation / stealth · obf.homoglyph · CWE-506, CWE-94
chatgpt-skill/lego-from-my-bricks/scripts/tools/ideas.cjs:42
console.log('\nПочти получается, не хватает:');
MEDIUMObfuscation / stealth · obf.homoglyph · CWE-506, CWE-94
chatgpt-skill/lego-from-my-bricks/scripts/tools/inventory.cjs:24
console.log(`${s.file}\nвсего деталей ${s.totalParts}, из них в библиотеке движка ${s.drawableParts}`);
MEDIUMObfuscation / stealth · obf.homoglyph · CWE-506, CWE-94
plugins/lego-inventory-build/skills/lego-inventory-build/tools/ideas.cjs:42
console.log('\nПочти получается, не хватает:');
MEDIUMObfuscation / stealth · obf.homoglyph · CWE-506, CWE-94
plugins/lego-inventory-build/skills/lego-inventory-build/tools/inventory.cjs:24
console.log(`${s.file}\nвсего деталей ${s.totalParts}, из них в библиотеке движка ${s.drawableParts}`);
LOWInventory / provenance · inv.hidden_file · CWE-1104
auth/.vercelignore
.vercelignore
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
plugins/lego-inventory-build/skills/lego-inventory-build/.vercelignore
.vercelignore
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
plugins/lego-inventory-build/skills/lego-inventory-build/api/_store.mjs:24
const hash = (buf) => crypto.createHash('sha1').update(buf).digest('hex');
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
plugins/lego-inventory-build/skills/lego-inventory-build/api/_youtube.mjs:39
export const sha1File = (file) => crypto.createHash('sha1').update(fs.readFileSync(file)).digest('hex');
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
plugins/lego-inventory-build/skills/lego-inventory-build/api/mcp.mjs:99
const sha = crypto.createHash('sha1').update(buf).digest('hex');
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
plugins/lego-inventory-build/skills/lego-inventory-build/mcp/tools.mjs:443
const filmKey = (m, format, q) => require('node:crypto').createHash('sha1')
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
plugins/lego-inventory-build/skills/lego-inventory-build/test/video-fast.mjs:92
const h = crypto.createHash('sha1').update(cv.data()).digest('hex');
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
auth/test/e2e.mjs:25
const MCP_DIR = path.resolve(HERE, '../../plugins/lego-inventory-build/skills/lego-inventory-build');
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
auth/test/prod-chatgpt.mjs:6
const req = createRequire(new URL('../../plugins/lego-inventory-build/skills/lego-inventory-build/package.json', import.meta.url));
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
plugins/lego-inventory-build/skills/lego-inventory-build/test/security.mjs:17
for (const bad of [path.join(tmp, 'evil.js'), path.join(tmp, 'secret.json'), '../../etc/passwd', 'a/b', 'x.json', '']) {
LOWNetwork egress · net.metadata_ip · CWE-200, CWE-319
plugins/lego-inventory-build/skills/lego-inventory-build/test/security.mjs:39
await rejects(() => photo.loadImage('https://169.254.169.254/latest/meta-data'), /not allowed/, 'cloud metadata refused');
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
auth/test/e2e.mjs:47
const AMP_ENV = { AMPLITUDE_API_KEY: 'test-key', AMPLITUDE_ENDPOINT: `http://127.0.0.1:${AMP_PORT}/2/httpapi` };
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
auth/test/e2e.mjs:61
if (q.url === '/oauth/client.json') { s.setHeader('content-type', 'application/json'); return s.end(JSON.stringify({ client_id: CIMD_ID, client_name: 'Test CIMD client', redirect_uris: [`http://127.0.
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
auth/test/e2e.mjs:91
get redirectUrl() { return `http://127.0.0.1:${CB_PORT}/callback`; },
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
auth/test/e2e.mjs:92
get clientMetadata() { return { client_name: 'E2E test client', redirect_uris: [`http://127.0.0.1:${CB_PORT}/callback`], grant_types: ['authorization_code', 'refresh_token'], response_types: ['code'],
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
auth/test/e2e.mjs:110
await page.route(`http://127.0.0.1:${CB_PORT}/**`, (route) => { callback = route.request().url(); return route.fulfill({ status: 200, body: 'ok' }); });
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
auth/package.json
@simplewebauthn/browser, @simplewebauthn/server, @upstash/redis, jose, next, react, react-dom, undici
Why it matters. 12 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
plugins/lego-inventory-build/skills/lego-inventory-build/package.json
@modelcontextprotocol/sdk, @napi-rs/canvas, @vercel/blob, @vercel/functions, heic-decode, jose, zod, ffmpeg-static
Why it matters. 9 dependency range(s) float
Fix. pin exact versions or ship a lockfile

Gates applied: no_behavioural_pass.

Audited 2026-10-10 · audit v0.4.1 · source sha a5c0f4f0d0dbfull audit observations/trust-audit/skill/elcodabra__lego-build-inventory.json · Report an issue / request a re-scan
06

Audit history

Every audit this skill has had.

DateSourceVerdictGradeScoreChange
2026-10-10a5c0f4f0d0dbBLOCKD69first audit
07

Questions

What does the lego-build-inventory skill do?

LEGO from my bricks: photograph your parts, get build ideas and step-by-step instructions. Agent Skill + MCP server for Claude and ChatGPT.

Is lego-build-inventory safe to install?

No — not without reading the findings first. The audit graded it D (69/100) and found 1 critical or high issue in the source. Each one is listed on this page with the file and line it is on.

What can lego-build-inventory access on my machine?

The audit observed that it reaches the network, runs shell commands and reads or writes files. Each of those is consistent with what it says it does. Secrets in the source: none found.

Which assistants does lego-build-inventory work with?

Its documentation mentions claude-code, claude-desktop, codex and cursor. That is what the text claims, not a compatibility test we ran.

How current is this page?

The grade is for one exact copy of the source (a5c0f4f0d0db), read on 2026-10-10. The repository is watched, and a new audit runs when it changes — this is the first audit.

Advertisement