{"id":49200968,"url":"https://github.com/dend/brick-mcp-app","last_synced_at":"2026-04-23T14:03:52.977Z","repository":{"id":340452517,"uuid":"1164174815","full_name":"dend/brick-mcp-app","owner":"dend","description":"🧱 MCP App for making my brick dreams a reality","archived":false,"fork":false,"pushed_at":"2026-03-16T21:55:02.000Z","size":8518,"stargazers_count":2,"open_issues_count":1,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-17T08:18:55.671Z","etag":null,"topics":["ai","lego","mcp","mcp-apps","model-context-protocol","server"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dend.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-22T18:46:15.000Z","updated_at":"2026-03-16T21:55:07.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dend/brick-mcp-app","commit_stats":null,"previous_names":["dend/brick-mcp-app"],"tags_count":0,"template":false,"template_full_name":"dend/template","purl":"pkg:github/dend/brick-mcp-app","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dend%2Fbrick-mcp-app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dend%2Fbrick-mcp-app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dend%2Fbrick-mcp-app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dend%2Fbrick-mcp-app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dend","download_url":"https://codeload.github.com/dend/brick-mcp-app/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dend%2Fbrick-mcp-app/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32183353,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-23T11:42:27.955Z","status":"ssl_error","status_checked_at":"2026-04-23T11:42:18.877Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","lego","mcp","mcp-apps","model-context-protocol","server"],"created_at":"2026-04-23T14:03:51.977Z","updated_at":"2026-04-23T14:03:52.972Z","avatar_url":"https://github.com/dend.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003ch1\u003eBrick Builder MCP App\u003c/h1\u003e\n  \u003cp\u003e\n    A Three.js MCP App for designing 3D brick constructions inside MCP-enabled hosts like Claude Desktop and Visual Studio Code. Build interactively or let the AI build structures for you through natural language.\n    \u003cbr /\u003e\u003cbr /\u003e\n    \u003ca href=\"#quick-start\"\u003eQuick Start\u003c/a\u003e\n    ·\n    \u003ca href=\"#connecting-to-hosts\"\u003eConnecting\u003c/a\u003e\n    ·\n    \u003ca href=\"#mcp-tools\"\u003eTools\u003c/a\u003e\n    ·\n    \u003ca href=\"#adding-new-brick-types\"\u003eExtensibility\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/dend/brick-mcp-app/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/dend/brick-mcp-app/actions/workflows/ci.yml/badge.svg\" alt=\"CI\"\u003e\u003c/a\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-blue\" alt=\"License: MIT\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/dend/brick-mcp-app\"\u003e\u003cimg src=\"https://img.shields.io/github/stars/dend/brick-mcp-app\" alt=\"GitHub stars\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"media/ext-apps-bricks.gif\" alt=\"Brick Builder in action — AI building a structure in real time\" width=\"600\" /\u003e\n  \u003cbr /\u003e\u003cem\u003eBrick Builder running in Claude, building a structure through natural language\u003c/em\u003e\n\u003c/p\u003e\n\n## Quick Start\n\n```sh\ngit clone https://github.com/\u003cowner\u003e/brick-mcp-app.git\ncd brick-mcp-app\nnpm install\nnpm run build\nnpm run serve\n```\n\nThe server starts at **http://localhost:3001/mcp**.\n\n### Prerequisites\n\n- **Node.js** 20+\n- **npm** 10+\n\n### Commands\n\n| Command | Description |\n|---------|-------------|\n| `npm install` | Install dependencies |\n| `npm run build` | Build client (Vite) + server (esbuild) |\n| `npm run serve` | Start server in dev mode (tsx, auto-reload) |\n| `npm run dev` | Watch client + serve concurrently |\n| `npm start` | Build then serve (one command) |\n\n## Architecture\n\nThe server is the **single source of truth** for all scene state. Both the AI (LLM) and the interactive UI mutate state exclusively through MCP tools. The server validates every operation — collision detection, bounds checking, support verification — and returns authoritative results.\n\n### Key Design Decisions\n\n- **Shared module-level state**: The host creates separate MCP sessions for the LLM and the app iframe. Scene state lives at module level so both sessions read/write the same scene.\n- **Polling for cross-session sync**: The UI polls `brick_get_scene` every second to pick up LLM-initiated changes. User-initiated changes (via `callServerTool`) are reflected instantly.\n- **Single-brick placement**: The LLM places one brick per `brick_place` call and receives the placed brick's footprint in the response, enabling precise positioning of subsequent bricks.\n\n## Connecting to Hosts\n\n\u003e [!TIP]\n\u003e You can use [Cloudflare Tunnels](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/) to expose your locally-hosted server to the internet. This lets you connect from claude.ai or any remote MCP host without port forwarding or VPNs:\n\u003e ```sh\n\u003e cloudflared tunnel --url http://localhost:3001\n\u003e ```\n\u003e Then use the generated `*.trycloudflare.com` URL in place of `http://localhost:3001` in the configurations below.\n\n### Claude Desktop\n\nClaude Desktop does not natively support streamable HTTP servers through config. You need to add the server as a **custom connector** (available on paid plans):\n\n1. Open Claude Desktop settings\n2. Navigate to **Connectors** and add a new custom connector\n3. Set the URL to the hosted URL of your MCP server (if you are using Cloudflare Tunnels, append `/mcp`)\n\n### Visual Studio Code\n\nVisual Studio Code supports Streamable HTTP MCP servers natively. Create `.vscode/mcp.json` in your workspace:\n\n```json\n{\n  \"servers\": {\n    \"brick-builder\": {\n      \"type\": \"http\",\n      \"url\": \"http://localhost:3001/mcp\"\n    }\n  }\n}\n```\n\nOr use the Command Palette: **MCP: Add Server** \u003e **HTTP** \u003e `http://localhost:3001/mcp`\n\n## MCP Tools\n\nThe following tools are accessible from whatever client you're using to interact with the app.\n\n| Tool | Description |\n|------|-------------|\n| `brick_read_me` | Returns the building guide, coordinate system, and examples |\n| `brick_get_available` | Returns all brick types with IDs, dimensions, and categories |\n| `brick_render_scene` | Opens the 3D viewer iframe (must call before placing bricks) |\n| `brick_place` | Place a single brick. Returns placed brick with footprint for precise adjacent positioning |\n| `brick_get_scene` | Read the current scene state with all bricks and their footprints |\n| `brick_remove_brick` | Remove a single brick by ID. Cascades to remove unsupported bricks above it |\n| `brick_clear_scene` | Remove all bricks from the scene |\n| `brick_export_scene` | Export as JSON or a human-readable summary |\n\n## Interactive UI\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"media/emp-state.png\" alt=\"Brick Builder 3D editor interface\" width=\"720\" /\u003e\n\u003c/p\u003e\n\nThe 3D viewport supports seven interaction modes, switchable via the toolbar or keyboard shortcuts:\n\n| # | Mode | Shortcut | Action |\n|---|------|----------|--------|\n| 1 | Look | `1` | Orbit, pan, and zoom the camera. No brick interaction. |\n| 2 | Place | `2` | Click the grid to place bricks. Ghost preview shows valid (green) or invalid (red) positions. |\n| 3 | Select | `3` | Click a brick to select it (highlighted). |\n| 4 | Move | `4` | Drag a brick to a new position. |\n| 5 | Rotate | `5` | Click a brick to rotate it 90 degrees. |\n| 6 | Delete | `6` | Click a brick to remove it. |\n| 7 | Paint | `7` | Click a brick to change its color. |\n\n**Additional shortcuts:**\n\n| Key | Action |\n|-----|--------|\n| `R` | Cycle rotation (0 / 90 / 180 / 270) in place mode |\n| `Delete` | Remove the selected brick |\n| `Escape` | Deselect / cancel drag |\n\n## Brick Types\n\n\u003e [!NOTE]\n\u003e This list is not final — more brick types will be added over time. See [Adding New Brick Types](#adding-new-brick-types) for how to contribute new types.\n\n20 brick types across three categories:\n\n| Category | Types |\n|----------|-------|\n| **Bricks** (standard height, 3 plate units) | 1x1, 1x2, 1x3, 1x4, 1x6, 1x8, 2x2, 2x3, 2x4, 2x6, 2x8 |\n| **Plates** (1/3 height, 1 plate unit) | 1x1, 1x2, 1x4, 2x2, 2x4, 2x6, 4x4 |\n| **Slopes** (angled top) | 1x2, 2x2, 2x3 |\n\n### Coordinate System\n\n\u003e[!NOTE]\n\u003eI might expand this further (or get rid of the baseplate altogether) in the future. The current setup is very much experimental.\n\n- **Baseplate**: 48 x 48 studs (X and Z axes)\n- **Y axis**: Height in plate units (1 standard brick = 3 Y units)\n- **Rotation**: 0, 90, 180, or 270 degrees (swaps X/Z dimensions)\n- All positions are integers snapped to the stud grid\n\n## Adding New Brick Types\n\nAdding a new brick requires just two files. The catalog, server validation, geometry rendering, and UI selector all pick it up automatically.\n\n### Step 1: Create the definition\n\nCreate a file in `src/bricks/definitions/`. The `BrickDefinition` interface:\n\n```typescript\ninterface BrickDefinition {\n  id: string;                  // Unique ID used in tool calls (e.g. 'brick_3x2')\n  name: string;                // Display name (e.g. '3×2 Brick')\n  category: 'brick' | 'plate' | 'slope' | 'technic' | 'corner';\n  studsX: number;              // Width in studs (X axis)\n  studsZ: number;              // Depth in studs (Z axis)\n  heightUnits: number;         // Height in plate units (standard brick = 3, plate = 1)\n  blockout?: BlockoutZone[];   // Optional zones where bricks can't sit on top (slopes)\n}\n```\n\n**Example** — `src/bricks/definitions/brick_3x2.ts`:\n\n```typescript\nimport type { BrickDefinition } from '../types.js';\n\nconst brick_3x2: BrickDefinition = {\n  id: 'brick_3x2',\n  name: '3×2 Brick',\n  category: 'brick',\n  studsX: 3,\n  studsZ: 2,\n  heightUnits: 3,\n};\n\nexport default brick_3x2;\n```\n\n**Example with blockout** (slope) — the angled face blocks stud connections:\n\n```typescript\nconst slope_2x3: BrickDefinition = {\n  id: 'slope_2x3',\n  name: '2×3 Slope 45°',\n  category: 'slope',\n  studsX: 2,\n  studsZ: 3,\n  heightUnits: 3,\n  blockout: [{ minX: 0, maxX: 2, minZ: 1, maxZ: 3, height: 3 }],\n};\n```\n\n### Step 2: Export from the index\n\nAdd one line to `src/bricks/definitions/index.ts`:\n\n```typescript\nexport { default as brick_3x2 } from './brick_3x2.js';\n```\n\n### Checklist\n\nThe brick is now:\n\n- In `BRICK_CATALOG` (auto-populated from exports)\n- Available to the LLM via `brick_get_available` and `brick_place`\n- Shown in the UI brick selector panel\n- Validated by server-side collision, bounds, and support checks\n- Rendered with auto-generated geometry based on `category`\n\nNo changes to `server.ts`, `BrickBuilder.tsx`, or any other file are needed to make things happen.\n\n### How categories map to geometry\n\nThe `category` field determines which geometry builder creates the 3D model:\n\n| Category | Height convention | Geometry |\n|----------|-------------------|----------|\n| `brick` | `heightUnits: 3` (standard) | Rectangular with studs on top, hollow underneath |\n| `plate` | `heightUnits: 1` (thin) | Same as brick, 1/3 height |\n| `slope` | `heightUnits: 3` | Angled top face, studs only on flat portion |\n| `technic` | `heightUnits: 3` | Pin holes in walls for axle connections |\n| `corner` | `heightUnits: 1` | L-shaped body with partial stud grid |\n\n### Adding a new category\n\nTo add an entirely new geometry style:\n\n1. Create a geometry builder in `src/bricks/geometry/` (e.g. `cylinder.ts`)\n2. Add a case to the switch in `src/bricks/geometry/index.ts`:\n   ```typescript\n   case 'cylinder': geometry = createCylinderGeometry(bt); break;\n   ```\n3. Add the category to the `BrickDefinition` type union in `src/bricks/types.ts`\n4. Geometries must be **corner-origin** — spanning `[0, w] x [0, h] x [0, d]` in local space\n\n### Unit reference\n\n| Unit | World size | Real-world |\n|------|-----------|------------|\n| 1 stud (X/Z) | 1.0 | 8 mm |\n| 1 plate unit (Y) | 0.4 | 3.2 mm |\n| 1 standard brick (Y) | 1.2 (3 plates) | 9.6 mm |\n\n## Local Testing\n\n### Test harness\n\nThe project includes a built-in visual test harness for testing MCP tools without a host. Start the server and navigate to:\n\n```\nhttp://localhost:3001/test\n```\n\nThe harness connects directly to the MCP server and provides a sidebar with buttons for every tool — render the scene, place bricks, clear, export, etc. The 3D viewport is embedded alongside so you can see results immediately.\n\n### basic-host\n\nYou can also test using the MCP Apps SDK basic-host, which simulates the full host environment (iframe, postMessage, `callServerTool`):\n\n```sh\n# Terminal 1: start the server\nnpm run build \u0026\u0026 npm run serve\n\n# Terminal 2: run basic-host\ngit clone --depth 1 https://github.com/modelcontextprotocol/ext-apps.git /tmp/mcp-ext-apps\ncd /tmp/mcp-ext-apps/examples/basic-host\nnpm install\nSERVERS='[\"http://localhost:3001/mcp\"]' npm run start\n# Open http://localhost:8080\n```\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdend%2Fbrick-mcp-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdend%2Fbrick-mcp-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdend%2Fbrick-mcp-app/lists"}