MeshValidationMCP
БесплатноНе проверенMCP server that lets AI agents validate 3D mesh manipulations with deterministic geometric checks and multi-view visual renders.
Описание
MCP server that lets AI agents validate 3D mesh manipulations with deterministic geometric checks and multi-view visual renders.
README
An MCP server for validating 3D mesh manipulations. It combines deterministic geometric checks with multi-view rendered feedback, giving coding agents a reliable way to verify their own mesh-processing code.
Overview
Testing geometry code is hard: unit tests may pass while the result is visibly wrong.
This server closes that gap. An agent writes mesh-manipulation code, exports the result,
and calls validate_mesh with the file path and its expected properties. The server
returns a per-check pass/fail report together with rendered views, so the agent can
confirm the result both numerically and visually — and fix its own mistakes before
reporting back.
write code → export mesh → validate_mesh → inspect report + renders → fix → repeat
Features
- Deterministic validation — volume, surface area, bounding box, centroid, vertex/face counts, watertightness, body count and Euler number, with global and per-check tolerances
- Localized-change validation — for edits confined to a selected region (emboss, pocket, fillet), verify that only that region changed, that the rest of the mesh is untouched, and the signed height/depth of the change (+ material added, − removed)
- Mesh integrity checks — self-intersections, non-manifold and boundary edges,
degenerate/sliver/duplicate/flipped faces, and triangle quality; defects that
is_watertightalone would hide (and that silently corrupt the volume) - Visual feedback — labeled multi-view contact sheets with axis gizmos, returned as images; failed integrity checks highlight the offending faces in red. Validators paint the quantity they check onto the render: a signed displacement heatmap (red = material added, blue = removed) for deformations, a thin-wall heatmap for thickness, a draft/undercut heatmap, the cut band for a section, and the fitted region for a feature fit — so the agent can confirm the manipulation visually, not just numerically
- Colour & material inspection — reads the colour actually authored on the mesh
(per-face, per-vertex, a material base colour, or a base-colour texture) and reports each
colour with a human name, its share of the surface area, how many separate patches it
forms, and where it sits on the part ("the +X half is red") — plus a render in the
mesh's true colours instead of the usual grey —
render_meshshows real colours by default too, and says in its meta which mode it used - Transform detection — compares before/after meshes and classifies the change
(
identical | translation | rotation | rigid | similarity | mirrored | deformed), reporting translation vector, rotation axis/angle and uniform scale - Distance metrics — sampled chamfer and Hausdorff distances, plus a displacement heatmap render
- Confidence tiers & fail-closed checks — every check and distance is tagged with how
it was derived (
exact|topological|sampled|estimated) and a numeric error bound; a volume that cannot be trusted (non-watertight, winding-inconsistent, or self-intersecting mesh) fails rather than silently passing - Property oracles — named before/after invariants any operation can assert
(
conserves_volume,preserves_watertight/genus,no_new_defects,centroid_fixed,monotonic_offset,bounded_hausdorff) and golden/reference matching - Feature & operation validators — cross-sections, wall thickness, draft/undercut, fillet/bore fitting, boolean/CSG volume-bound + containment checks, symmetry, linear/polar arrays, extrude/revolve (by volumetric signature), remesh, clearance, silhouette and a pure-geometry DfM composite
- Agent-friendly errors — failures return a structured JSON envelope
(
{"code", "message", "hint"}) the caller can parse and act on - Deterministic output — fixed seeds, cameras and lighting; identical inputs produce identical reports
Supported formats: STL, OBJ, PLY, GLB/glTF, OFF, 3MF.
Requirements
- uv — provisions the pinned Python (3.13) and all dependencies automatically
Installation
git clone https://github.com/baho0/MeshValidationMCP.git
cd MeshValidationMCP
uv sync
uv run pytest # optional: verify the installation
Registering with Claude Code
The repository ships a project-scoped .mcp.json; opening Claude Code inside the repo picks the server up automatically. To register it globally:
claude mcp add mesh-validator --scope user -- \
uv run --directory /path/to/MeshValidationMCP mesh-validation-mcp
Tools
| Tool | Purpose |
|---|---|
validate_mesh(file_path, expectations, include_render?) |
Check a mesh against structured geometry + integrity expectations; returns a pass/fail report and a 4-view render (defects highlighted) |
inspect_mesh(file_path) |
Full geometric + integrity report — use it to ground truth a mesh before writing expectations |
inspect_appearance(file_path, merge_tolerance?, max_colors?, include_render?) |
Every colour authored on the mesh: name, hex, area share, patch count, bbox and where it sits on the part; renders in true colours |
find_color_region(file_path, color, tolerance?, max_patches?, include_render?) |
Locate a colour ("which part is red?") by name/hex/RGB; returns its extent, patches, and a face_ids/box region you can pass to the other tools |
render_mesh(file_path, views?, style?, resolution?, combine?, color_mode?) |
Render canonical views (iso, front, top, ...) without running checks; shows the mesh's own colours when the file has any (color_mode: auto/true_color/body/plain) |
compare_meshes(file_a, file_b, localized?, sample_count?, include_render?) |
Detect and classify the transform (now incl. affine shear/anisotropic scale) between two meshes; distances, metric deltas, transform-invariant assertions, displacement heatmap, and (with localized) region-scoped change verification |
Advanced validation tools
Each returns results tagged with a confidence tier and error bound, and fails closed on
unreliable input.
| Tool | Purpose |
|---|---|
assert_properties(file_path, properties, reference_path?) |
Assert named before/after invariants (volume conserved, watertight/genus preserved, no new defects, centroid fixed, monotonic offset, bounded Hausdorff) |
compare_to_golden(file_path, reference_path, tolerance?) |
Does the output match a reference — exact per-vertex (matching topology) or bounded surface distance |
inspect_section(file_path, plane_origin, plane_normal) |
Planar cross-section: per-loop perimeter and net/gross area (exact) |
measure_thickness(file_path, sample_count?) |
Inscribed-sphere wall/feature thickness (min/p5/median) |
analyze_draft(file_path, pull_direction, min_draft_deg?) |
Area-weighted draft angle and undercut area for a pull direction |
fit_feature(file_path, region, kind) |
Fit a plane/sphere/cylinder to selected feature faces (fillet/bore radius, chamfer) with residual |
validate_boolean(file_a, file_b, file_result, operation, ...) |
Boolean/CSG result: volume bounds + signed-distance containment + seam integrity |
detect_symmetry(file_path, rel_tolerance?) |
Mirror planes and rotational fold |
validate_array(file_result, file_base, pattern) |
Linear/polar array: count, congruence, positions |
validate_generative(file_path, operation, profile_area, ...) |
Extrude (area × height) / revolve (Pappus) by volume signature |
measure_displacement(file_a, file_b) |
Whole-mesh signed displacement field (deformation) |
validate_remesh(file_before, file_after, max_deviation, ...) |
Retessellation kept shape + topology + quality |
check_clearance(file_a, file_b, min_clearance?) |
Assembly interference / minimum clearance |
compare_silhouette(file_a, file_b, view_axis?, resolution?) |
Orthographic outline IoU (profile preserved) |
units_sanity(file_path, expected_units?, ...) |
Units/scale plausibility + sampling self-consistency |
validate_dfm(file_path, min_wall_thickness?, pull_direction?, ...) |
Pure-geometry DfM: min wall + draft/undercut + trapped voids |
All file paths must be absolute. All values are interpreted in the file's native units.
Renders use a Z-up convention: front looks along +Y, iso views from the (+X, −Y, +Z)
octant.
Expectations example
{
"volume": 500,
"surface_area": {"expected": 400, "rel_tol": 0.02},
"bbox_extents": [10, 10, 5],
"vertex_count": {"min": 6, "max": 9},
"watertight": true,
"self_intersecting_face_count": 0,
"non_manifold_edge_count": 0,
"tolerance": {"relative": 0.01}
}
Only the keys you set are checked. Geometry keys: volume, surface_area, bbox_min,
bbox_max, bbox_extents, centroid, vertex_count, face_count, watertight,
winding_consistent, body_count, euler_number. Integrity keys (usually 0):
self_intersecting_face_count, non_manifold_edge_count, boundary_edge_count,
degenerate_face_count, sliver_face_count, duplicate_face_count, flipped_face_count,
plus min_triangle_quality (a floor). Scalars and vectors accept a bare value (global
tolerance, default 1 % relative) or an object with rel_tol/abs_tol overrides; counts
accept an exact integer or a min/max range. The pass rule is
|actual − expected| ≤ max(abs_tol, rel_tol · |expected|).
Localized-change validation
For an edit confined to a selected region — the common CAD case ("emboss this area by
3mm", "pocket here 2mm deep") — export the mesh before and after, then pass localized
to compare_meshes:
{
"region": {"kind": "box", "min": [-12, -12, 1.5], "max": [12, 12, 8]},
"emboss_height": 3.0,
"max_unchanged_deviation": 0.01
}
The region can be a box (min/max), sphere (center/radius), plane (origin/normal
half-space), or explicit vertex_ids / face_ids. The tool reports how much moved inside
the region, whether everything outside stayed put (max_unchanged_deviation), and the
signed feature displacement (emboss_height for material added, pocket_depth for
material removed) — so a change that leaks outside the intended area, or moves the wrong
distance, fails the check.
Colour inspection
Colour is read from wherever the format keeps it — per-face colours, per-vertex colours, a
material base colour, or a base-colour texture. STL has none, so it always reports
has_color: false rather than a colour that silently failed to apply.
inspect_appearance(file_path="/abs/part.glb")
-> red #ff0000 50% of the surface "+X side" 1 patch
yellow #ffff00 50% of the surface "-X side" 1 patch
+ a 4-view render in the mesh's true colours
find_color_region(file_path="/abs/part.glb", color="red")
-> matched: bbox, span, centroid, 1 patch, and
region = {"kind": "face_ids", "face_ids": [...]} <- pass to any other tool
Colours are grouped and named in CIE Lab, so merge_tolerance / tolerance (in ΔE) mean
about the same to the eye across the whole gamut: ~2.3 is a just-noticeable difference, 10
groups shades of one colour, 30 starts merging red into orange.
A glTF round-trip rewrites per-face colours as per-vertex colours, which leaves every
triangle on a colour border interpolated (a red/yellow border comes back orange). Those
faces are reported separately and their area is split between the two colours that meet on
them, so the report says "50% red, 50% yellow with a blended border" instead of inventing an
orange region. color_boundary_resolution states how precisely a border can be located at
all — never finer than one triangle.
The returned region is the bridge back to the geometric tools: hand it to
measure_thickness, fit_feature or compare_meshes(localized=...) to check the geometry
of a coloured area.
Rendering backends
| Backend | Selection | Notes |
|---|---|---|
| matplotlib (default) | automatic | Pure CPU, works everywhere; orthographic views with edge overlay — well suited to flat-faced CAD parts |
| pyrender + EGL | MESH_MCP_RENDERER=pyrender |
GPU offscreen rendering; install with uv sync --extra gl. Falls back to matplotlib on any GL failure |
Configuration
| Environment variable | Default | Description |
|---|---|---|
MESH_MCP_RENDERER |
matplotlib |
Render backend (matplotlib or pyrender) |
MESH_MCP_MAX_FILE_MB |
500 |
Maximum input file size |
MESH_MCP_MAX_FACES |
5000000 |
Maximum face count at load |
MESH_MCP_RENDER_MAX_FACES |
120000 |
Faces above this are subsampled for display only |
MESH_MCP_SELFINT_MAX_FACES |
200000 |
Above this the self-intersection test is skipped |
Development
src/mesh_validation_mcp/
├── server.py # MCP wiring (the only module importing the mcp SDK)
├── loading.py # file loading and normalization
├── confidence.py # confidence tiers + numeric error bounds
├── metrics.py # geometric metrics (+ cross-checks, topology, curvature, inertia)
├── integrity.py # mesh-integrity metrics (self-intersection, manifoldness, quality)
├── region.py # Region primitive (box/sphere/plane/vertex-ids/face-ids)
├── validation.py # expectations schema and assertion engine (fail-closed)
├── comparison.py # transform/affine detection, distances, signed field, localized change
├── oracles.py # named property oracles + golden.py reference matching
├── section.py # planar cross-sections and section-area profiles
├── curvature.py primitives.py topology.py # curvature, primitive fits, genus/loops
├── features.py # wall thickness, draft/undercut, region primitive fits
├── boolean_validate.py array_validate.py generative_validate.py remesh_validate.py
├── symmetry.py clearance.py silhouette.py units.py dfm.py
└── rendering/ # camera math, backends, contact-sheet composition
tests/ # unit tests + in-memory MCP integration tests
uv run pytest
License
Установка MeshValidationMCP
У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.
▸ github.com/baho0/MeshValidationMCPFAQ
MeshValidationMCP MCP бесплатный?
Да, MeshValidationMCP MCP бесплатный — установка в пару кликов через Unyly без оплаты.
Нужен ли API-ключ для MeshValidationMCP?
Нет, MeshValidationMCP работает без API-ключей и переменных окружения.
MeshValidationMCP — hosted или self-hosted?
Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.
Как установить MeshValidationMCP в Claude Desktop, Claude Code или Cursor?
Открой MeshValidationMCP на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
Похожие MCP
Fetch
Web content fetching and conversion for efficient LLM usage.
Roblox Studio
Enables AI coding tools to control Roblox Studio for workspace exploration, instance manipulation, and script management. It provides tools for playtesting, sce
автор: paralovOpencode Omniroute Plugin
OpenCode plugin for the OmniRoute AI Gateway. Drives dynamic model discovery, /connect auth flow, and multi-instance OmniRoute providers via the official @openc
автор: GitHub ActionsAWS KB Retrieval
Retrieval from AWS Knowledge Base using Bedrock Agent Runtime.
автор: modelcontextprotocolSpring AI MCP Server
Provides auto-configuration for setting up an MCP server in Spring Boot applications.
llm-analysis-assistant
A very streamlined mcp client that supports calling and monitoring stdio/sse/streamableHttp, and can also view request responses through the /logs page. It also
автор: xuzexin-hzMCP-Agent
A simple, composable framework to build agents using Model Context Protocol by [LastMile AI](https://www.lastmileai.dev)
автор: lastmile-aiSpring AI MCP Client
Provides auto-configuration for MCP client functionality in Spring Boot applications.
mcp.natoma.ai
A Hosted MCP Platform to discover, install, manage and deploy MCP servers by [Natoma Labs](https://www.natoma.ai)
MCPHub
Website to list high quality MCP servers and reviews by real users. Also provide online chatbot for popular LLM models with MCP server support.
Compare MeshValidationMCP with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории ai
