Skip to main content
Glama
README.md
# 3d-eyes 👁️

**Give your coding agent eyes for 3D.**

An MCP server that lets Claude Code (or any MCP client) *see* and diagnose 3D
files - meshes **and** Gaussian splats - with **zero GPU / OpenGL / Blender
dependency**. Pure numpy rendering: it runs on any machine, any container, any CI.

[中文文档](README.zh.md) · [Agent Skill](skill/SKILL.md) · [Broken zoo](examples/broken-zoo)

---

Your agent can write Three.js all day, but until now it debugged 3D files
blind. Ask it "why is my model black?" and it guesses. With 3d-eyes it *looks*:

![inspect_scene contact sheet of a cube with flipped normals - every face red](docs/assets/demo-inspect.png)

That's `inspect_scene` on a real broken file: six orthographic views plus
perspective, **inward-facing triangles painted red**, and a JSON report that
says exactly what's wrong:

```json
{
  "severity": "error",
  "summary": "All face normals are inverted (negative enclosed volume).",
  "symptom": "Model renders dark/black or shows red faces on every side.",
  "fix": "Invert face winding: mesh.invert() in trimesh, or flip normals on export."
}
```

The agent fixes the file, then proves it with `diff_renders`:

![before/after diff render](docs/assets/demo-diff.png)

## Gaussian splats too

3d-eyes speaks 3DGS: `.ply` (training output layout) and `.splat`. It renders
turntable previews and runs a quality report with **density-adaptive floater
detection** - the isolated blobs your training run left hanging in space:

![splat contact sheet with floaters visible](docs/assets/demo-splat.png)

```json
"floaters": { "floater_count": 60, "floater_fraction": 0.0099,
              "examples": [[3.4, -2.8, 3.1], ...] }
```

## Quickstart

```bash
# Claude Code
claude mcp add 3d-eyes -- uvx 3d-eyes

# or from source
git clone https://github.com/murphy977/3d-eyes && cd 3d-eyes
pip install -e . && claude mcp add 3d-eyes -- 3d-eyes
```

Then ask your agent things like:

> "Check `assets/robot.glb` before I ship it."
> "My model renders black in Three.js - here's the file."
> "Are there floaters in `scene.splat`?"

For best results, install the [Agent Skill](skill/SKILL.md) so your agent knows
the symptom → cause table by heart:

```bash
mkdir -p ~/.claude/skills/3d-debugging && cp skill/SKILL.md ~/.claude/skills/3d-debugging/
```

## Tools

| Tool | What it does |
|---|---|
| `inspect_scene(path)` | Contact sheet (6 ortho + perspective views) + structure stats + defect report. Red = faces seen from behind. Auto-detects splat files. |
| `render_views(path, cameras)` | Custom angles: `[{"azimuth": 30, "elevation": -60, "distance": 1.2, "ortho": false}]` - zoom in, look underneath, get exact silhouettes. |
| `diff_renders(path_a, path_b)` | Same-camera side-by-side of two files, plus both defect verdicts. Verify every fix. |

**Detects:** flipped/inconsistent normals · degenerate faces · non-manifold
edges · missing texture/buffer references · scale unit mistakes (mm vs m) ·
splat floaters · nearly-transparent splat bloat. Corrupt files return a parse
diagnosis instead of a crash.

**Formats:** GLB, GLTF, OBJ, PLY, STL (meshes) · 3DGS PLY, .splat (Gaussian splats).

## Try it on the broken zoo

Every defect has a minimal sample file in [`examples/broken-zoo/`](examples/broken-zoo):

```bash
3d-eyes inspect examples/broken-zoo/cube_flipped_normals.obj   # all red + report
3d-eyes inspect examples/broken-zoo/torus_with_floaters.ply    # 60 floaters found
3d-eyes diff examples/broken-zoo/cube_flipped_normals.obj fixed.obj
```

(The CLI mirrors the MCP tools - handy for humans and CI pipelines.)

## Why software rendering?

Agents run everywhere: laptops, devcontainers, CI runners, remote boxes. Any
renderer that needs EGL/OSMesa/GPU drivers will eventually fail on one of
them. 3d-eyes rasterizes with numpy + PIL - preview quality by design, 100%
portability by design. An agent doesn't need path tracing to see that your
normals are flipped.

## Roadmap

- [ ] `.spz` splat format
- [ ] Texture-mapped rendering
- [ ] USD support
- [ ] Animation / skeleton sanity checks
- [ ] Optional pyrender backend for high-quality output
- [ ] Screenshot-vs-render comparison for engine-side bug isolation

Issues and PRs welcome - the codebase is small and readable on purpose.

## License

MIT