# Caliper — caliper.fit > Geometry and CAD file metadata extraction. Accepts geometry files by URL or base64, returns structured statistics as JSON. Payment required via x402 (USDC on Base). ## What This Service Does Caliper accepts 3D geometry files and returns structured JSON metadata: bounding boxes, triangle counts, surface area, volume, manifold analysis, point cloud statistics, classification counts, and more. This is a **read-only analysis service**. Caliper does not perform mesh repair, format conversion, boolean operations, or any file modification. ## Supported Formats STL, OBJ, PLY, PCD, LAS / LAZ, glTF / GLB. STEP and IGES support is planned. ## How to Connect ### MCP Transport (recommended for MCP-compatible agents) Connect via Streamable HTTP at: ``` https://caliper.fit/mcp/ ``` This provides tool discovery (`tools/list`) and direct invocation (`tools/call`) using the standard MCP protocol. ### REST API POST to `/tools/caliper_auto_stats` (REST) or call `format_auto` (MCP): ```json {"file_url": "https://example.com/model.stl"} ``` or: ```json {"file_b64": "", "filename": "model.stl"} ``` For multiple files, use `/tools/caliper_batch_stats`: ```json {"files": [{"file_url": "https://example.com/part1.stl"}, {"file_b64": "...", "filename": "part2.obj"}]} ``` **Files under 150KB are free.** Larger files cost $0.02/MB (billable data = file size minus 150KB), rounded up to the next cent. Pay via x402 (USDC on Base) or card via MPP (Stripe; adds $0.35 surcharge). See the Workflow section below for the complete payment flow. ## Tools Available - `format_detect` — Detect the geometry file format from a filename or URL. - `feature_request` — Request a feature or format that Caliper doesn't support yet. - `format_auto` — Auto-detect geometry file format and extract metadata statistics. - `format_stl` — Extract metadata from an STL file (ASCII or binary). - `format_obj` — Extract metadata from an OBJ file. - `format_ply` — Extract metadata from a PLY file (ASCII or binary). - `format_pcd` — Extract metadata from a PCD point cloud file. - `format_las` — Extract metadata from a LAS or LAZ point cloud file. - `format_gltf` — Extract metadata from a glTF or GLB file. - `format_batch` — Analyze multiple geometry files in a single batch request. ## Workflow: Analyze a File A typical multi-step interaction: 1. **Check format support** (free, no payment): ```json {"tool": "format_detect", "arguments": {"filename": "model.stl"}} ``` Response: ```json {"ok": true, "format": "stl", "supported": true, "deferred": false, "supported_formats": ["gltf", "las", "obj", "pcd", "ply", "stl"]} ``` 2. **Analyze the file** — if the file is under 150KB, results are returned immediately: ```json {"tool": "format_auto", "arguments": {"file_url": "https://example.com/model.stl"}} ``` Success response: ```json {"ok": true, "format": "stl", "stats": {"triangle_count": 1848, "vertex_count": 5544, "unique_vertex_count": 926, "bounding_box": {"min": [-5.0, -5.0, 0.0], "max": [5.0, 5.0, 10.0]}, "surface_area": 471.24, "volume": 785.40, "is_watertight": true, "is_manifold": true, "open_edges": 0, "non_manifold_edges": 0}} ``` 3. **If payment is required** (file over 150KB), the response includes payment details: ```json {"ok": false, "error": "payment_required", "message": "Payment of $0.000004 USD (USDC on base) required.", "amount_usdc_atomic": 4, "payTo": "0xF3c5...", "priceToken": "4:1776026505:1fe9...", "accepts": [{"scheme": "exact", "network": "base", "asset": "usdc", "amount": "4", "payTo": "0xF3c5...", "expires": 1776026505, "priceToken": "4:1776026505:1fe9..."}]} ``` 4. **Retry with payment proof** after sending USDC on-chain: ```json {"tool": "format_auto", "arguments": {"file_url": "https://example.com/model.stl", "payment": "{\"transaction\": \"0xabc...\", \"network\": \"base\", \"priceToken\": \"4:1776026505:1fe9...\"}"}} ``` ## Error Responses All errors return structured JSON with `"ok": false`: | Error | Meaning | |---|---| | `{"ok": false, "error": "Provide either file_url or file_b64"}` | Missing input — supply one of the two | | `{"ok": false, "error": "Cannot detect format. Provide filename."}` | Format not detected from URL; add `filename` | | `{"ok": false, "error": "format_not_yet_supported", "format": "step"}` | Requested format is planned but not yet available | | `{"ok": false, "error": "payment_required", ...}` | Payment needed — see workflow step 3 above | | `{"ok": false, "error": "payment_failed"}` | Payment proof invalid or expired | | `{"ok": false, "error": "processing_error", "message": "..."}` | File could not be parsed | | `{"ok": false, "error": "rate_limit_exceeded"}` | Too many requests — see Rate Limits below | ## Rate Limits 60 requests per 60-second sliding window per IP. The `/health` and `/` endpoints are exempt. When exceeded, the server returns HTTP 429 with a `Retry-After` header: ```json {"error": "rate_limit_exceeded", "message": "Too many requests. Limit is 60 per 60s."} ``` ## Input Constraints - `file_url`: HTTP/S only, max 100MB, no private/loopback IPs - `file_b64`: max 200KB decoded (use `file_url` for larger files) - Include `filename` with extension for format detection when using `file_b64` - `file_url` and `file_b64` are mutually exclusive — provide one, not both - Batch requests: max 10 files, max 200MB aggregate ## Discovery Endpoints - `GET /mcp/manifest` — MCP tool manifest (JSON) - `GET /.well-known/mcp/server-card.json` — MCP server card - `GET /.well-known/mcp.json` — MCP discovery manifest - `GET /.well-known/agent.json` — A2A Agent Card - `GET /llms.txt` — LLM-friendly index - `GET /health` — service status