MCP guide
Drive meshcheck from Claude Code, Claude Desktop, Cursor, or any MCP client.
meshcheck-mcp is a local-first Model Context Protocol server. It
lets any MCP client validate, render, and inspect GLB/glTF models through the meshcheck API. It reads
models straight off disk by path — an agent that just generated a model hands over a filename, not bytes.
All analysis runs server-side; the package is a thin, faithful client that passes reports through
verbatim and adds zero telemetry.
Register
The server needs a meshcheck API key (mc_live_...) in its environment.
Claude Code
claude mcp add meshcheck -s project \
-e MESHCHECK_API_KEY=mc_live_... \
-- npx -y meshcheck-mcp
Any MCP config
{
"mcpServers": {
"meshcheck": {
"command": "npx",
"args": ["-y", "meshcheck-mcp"],
"env": { "MESHCHECK_API_KEY": "mc_live_..." }
}
}
}
Configuration
| Env var | Required | Default | Purpose |
|---|---|---|---|
MESHCHECK_API_KEY |
yes | — | Your key. The server exits with a clear message if it is missing. |
MESHCHECK_API_URL |
no | https://api.meshcheck.dev/v1 |
Override for staging or self-hosted. |
Tools
| Tool | Deterministic | What it does |
|---|---|---|
validate_model |
yes | Runs the checks and returns the full report JSON with a pass/warn/fail rollup. |
render_model |
yes | Renders stills with the fixed studio rig; returns the render JSON plus the first few stills inline. |
inspect_model |
no | Asks a vision model a semantic question. An opinion surface, priced and isolated separately. |
get_report |
yes | Re-fetches a stored report by id (free). |
Every tool takes either a local path or a public url (exactly one). Large files (≥ ~4.4 MB) go through
the presigned upload flow automatically; async jobs (turntables, very large models) are polled internally,
so you always get the finished report, never a job envelope.
validate_model
validate_model({
path?: string, // local file path (read + uploaded for you)
url?: string, // or a public URL
profile?: "web" | "mobile" | "pc" | "hero",
overrides?: { [param: string]: number },
checks_only?: boolean // skip rendering for faster results
})
Returns the full report JSON: verdict, per-check measured/threshold/status, stats, and (unless
checks_only) screenshots.
render_model
render_model({
path?: string, url?: string,
angles?: { rv: number, rh: number }[],
size?: number,
turntable?: { frames?: number, size?: number, format?: "gif" }
})
Returns the render JSON (signed screenshot URLs + stats) and, inline, the first up to three stills so the agent can look at the model immediately.
inspect_model
inspect_model({
path?: string, url?: string,
check: "VIS-001" | "VIS-002" | "VIS-003",
prompt?: string, // VIS-001
question?: string // VIS-003
})
Non-deterministic — a vision model’s opinion, not a measurement. Use validate_model for anything
measurable.
Errors
Errors pass through from the API verbatim as structured JSON, with the tool result flagged isError. The
MCP layer adds no interpretation:
{ "error": { "code": "INSUFFICIENT_CREDITS", "message": "...", "detail": { "balance": 0, "needed": 2 } } }
Client-side failures (a missing file, a file larger than your plan allows) use the same envelope shape
with codes like FILE_NOT_FOUND and FILE_TOO_LARGE.
The loop
1. Your agent generates model.glb on disk.
2. validate_model({ path: "model.glb", profile: "web" })
→ verdict "fail", PERF-001 fail: 48,231 triangles exceeds budget of 25,000.
3. Your agent regenerates with a lower triangle target.
4. validate_model({ path: "model.glb", profile: "web" })
→ verdict "pass".
See the Meshy and Tripo cookbooks for full generate → validate → fix transcripts.