mesh-prep-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mesh-prep-mcpPrep scan.obj for real-time: repair, decimate to 20k faces, export GLB"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mesh-prep-mcp
An MCP server that lets an LLM agent turn a raw 3D asset into an experience-ready one — inspect, repair, decimate, rescale and export triangle meshes through the Model Context Protocol, with a small C++17 core for the numbers the agent bases its decisions on.
Why
Getting a scan or CAD export into a real-time scene is a chain of small judgement calls: is it watertight? are these millimetres? how far can I decimate before the silhouette suffers? Those calls are usually made by hand. This project exposes the underlying operators to an agent as MCP tools, returns before/after statistics for every step, and lets the agent decide — and explain — what it did. It is deliberately small: a rehearsal of agent-driven 3D data preparation, not a product.
Related MCP server: openusd-mcp
What the agent gets
Tool | What it does |
| Loads OBJ / STL / PLY / GLB / glTF / OFF / 3MF …, registers it, returns a first inspection |
| Bounds, extent, area, volume, face/vertex counts, degenerate faces, boundary & non-manifold edges, duplicate vertices, plus an issue list with the operator that fixes each one |
| Welds duplicates, drops degenerate/duplicate faces and fold-overs, fixes winding, fills small holes → new id, before/after |
| Quadric-error decimation to a face budget → new id, reduction %, surface-area drift |
| Unit conversion (e.g. mm → m) → new id |
| OBJ / GLB / glTF / STL / PLY / OFF |
| Everything in the session with full provenance |
resource | Markdown report of one mesh |
prompt | A guided full preparation pass |
Every operator returns a new mesh_id; earlier ids stay valid, so the agent can compare, branch or roll back without any undo logic.
Demo (no LLM needed)

$ python scripts/make_sample_mesh.py # 82k-face noisy "scan" in millimetres, with holes and degenerate faces
$ python scripts/demo_client.py # talks to the server over stdio, like Claude Desktop does
tools: load_mesh, inspect_mesh, repair_mesh, decimate_mesh, scale_mesh, export_mesh, list_meshes
[load_mesh] m1: 81,920 faces, 40,962 verts, extent (502, 501, 502), backend=cpp
issue: 3 degenerate (zero-area or collapsed) faces -> repair_mesh
issue: open surface: 9 boundary edges (not watertight) -> repair_mesh fills small holes; ...
[repair_mesh] m1: 81,920 faces, 40,962 verts, watertight=False, issues=2
-> m2: 81,920 faces, 40,962 verts, watertight=True, issues=0
[decimate_mesh] m2: 81,920 faces, 40,962 verts, watertight=True, issues=0
-> m3: 20,000 faces, 10,002 verts, watertight=False, issues=1
75.6% fewer faces, surface area -0.49%
issue: 1 non-manifold edges (shared by 3+ faces)
[repair_mesh] verify after decimation
-> m4: 19,998 faces, 10,001 verts, watertight=True, issues=0
[scale_mesh] x0.001 (mm -> m): extent (0.501, 0.501, 0.502)
[export_mesh] examples/output/sample_scan_ready.glb (360,752 bytes)Note the step after decimation: quadric collapse can leave a fold-over, so the client inspects the result and repairs once more before exporting — the agent gets numbers, not "done", precisely so it can make that call. With Claude Desktop the same run is one sentence: "Prepare examples/sample_scan.obj for a real-time scene with a 20k-face budget and explain what you changed."
Architecture
Claude Desktop / Claude Code
│ MCP (stdio, JSON-RPC)
▼
src/mesh_prep_mcp/server.py tools · resource · prompt (mcp SDK, 1.x and 2.x)
│
src/mesh_prep_mcp/ops.py load / inspect / repair / decimate / scale / export (trimesh, fast-simplification)
│
cpp/ meshstats C++17: bounds, area, signed volume, degenerate faces,
└─ bindings.cpp boundary & non-manifold edges, duplicate vertices (pybind11)The C++ backend is optional: if the extension is not built, ops.inspect falls back to a NumPy implementation and reports backend: "python". The C++ library has no Python dependency and its own tests (ctest).
Quick start
git clone https://github.com/Horuspokus/mesh-prep-mcp && cd mesh-prep-mcp
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
# C++ core + pybind11 module (optional but recommended)
cmake -S cpp -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
ctest --test-dir build --output-on-failure
pytest -q # Python tests
python scripts/make_sample_mesh.py && python scripts/demo_client.pyIf
import mesh_prep_mcpfails after the editable install (seen once on macOS with Python 3.14 in an iCloud-synced folder), install it non-editable instead:python -m pip install --force-reinstall --no-deps .— and re-run that after editing files undersrc/.
Claude Desktop
Copy examples/claude_desktop_config.json into your claude_desktop_config.json and replace the two absolute paths. MESH_PREP_ROOT sandboxes file access to one directory (recommended).
Claude Code
claude mcp add mesh-prep -e MESH_PREP_ROOT=$PWD/examples -- $PWD/.venv/bin/mesh-prep-mcpDesign notes
Immutable results. Operators never mutate a registered mesh; they add a new one with its provenance (
history). Cheap, and it makes "compare budgets A and B" or "go back to the repaired version" trivial for the agent.Numbers, not adjectives. Every tool returns measured before/after values (face count, surface-area drift, watertightness) so the agent's explanation to the user is grounded.
Issue → operator mapping.
inspect_meshdoes the triage once, in code; the agent only has to follow the recommendation or argue with it.Safety.
MESH_PREP_ROOTrejects paths outside one directory; exports never overwrite the input by default naming.C++ where it pays. The statistics pass is the one thing that runs on every step and on every mesh size, so it lives in C++ with the GIL released; everything else stays in Python for readability.
Roadmap
IFC input through IfcOpenShell (element-level preparation, properties kept as metadata)
glTF LOD chains (
decimate_chain(budgets=[200k, 50k, 10k]))Material / texture checks (missing UVs, oversized textures)
Scene assembly: place several prepared assets into one glTF scene
Streamable-HTTP transport for use behind a web app
License
MIT — Gökhan Dönmez, 2026.
This server cannot be deployed
Maintenance
Related MCP Connectors
214 tools for AI agents over one MCP endpoint: image, video, audio, 3D, data, storage, mail, GPUs.
OCR, transcription, file extraction, and image generation for AI agents via MCP.
Convert, lint and generate LLM tool schemas for OpenAI, Anthropic, Gemini and MCP
Generate, edit, and deploy immersive 3D/WebGL web projects from any MCP assistant.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceExposes 50+ Blender tools (object manipulation, materials, animation, etc.) via MCP for AI-driven 3D workflows and automation.1MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to read, inspect, and manipulate OpenUSD 3D scenes, including scene graph traversal, property querying, mesh export, and variant switching.10MIT
- AlicenseNot gradedqualityDmaintenanceEnables LLMs to create and manipulate 3D models using OpenSCAD through MCP tools for code-based modeling, preview, and export.1MIT
- FlicenseNot gradedqualityDmaintenanceConverts GeoJSON geometries into 3D triangulated meshes using a local LLM (Ollama), exposing an MCP tool for mesh generation.-