# MetaModel MCP Server [![npm](https://img.shields.io/npm/v/metamodel-mcp)](https://www.npmjs.com/package/metamodel-mcp) [![MCP](https://img.shields.io/badge/MCP-compatible-blue)](https://modelcontextprotocol.io) [![license](https://img.shields.io/badge/license-MIT-green)](LICENSE) An [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server that lets AI assistants use MetaModel's formula engine for certified computation. Turn published calculators, pricing tools, and engineering models into AI-callable tools — no hallucinated math. > **All tools are read-only.** This server fetches published project schemas and runs stateless computations. It never writes, modifies, or stores any data. ## Quick Start ### Remote (hosted) — easiest No install. Add the URL as a custom connector: ``` https://www.metamodel.app/api/mcp ``` - **Claude.ai / Claude Desktop**: Settings → Connectors → Add custom connector → paste the URL - **Claude Code**: `claude mcp add --transport http metamodel https://www.metamodel.app/api/mcp` Works on web and mobile; no Node required. The hosted endpoint is stateless, read-only, and rate-limited. ### Claude Desktop Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS): ```json { "mcpServers": { "metamodel": { "command": "npx", "args": ["-y", "metamodel-mcp"] } } } ``` ### Claude Code ```bash claude mcp add metamodel -- npx -y metamodel-mcp ``` ### Other MCP Clients Any MCP-compatible client can connect via stdio: ```bash npx -y metamodel-mcp ``` ## Tools ### `metamodel_list_projects` Browse available calculators and engineering models. Returns project names, descriptions, publish tokens, and model names. - **Annotations:** `readOnlyHint: true` ### `metamodel_get_schema` Discover inputs and outputs for a specific project. Returns model names, input parameters (with types, defaults, validation rules), output fields, and formulas. - **Annotations:** `readOnlyHint: true` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `token` | string | Yes | Project publish token (from `metamodel_list_projects`) | ### `metamodel_compute` Run a computation with input values. Send inputs once — they're auto-routed to the correct model by property name. Outputs from all models are returned, including cross-model cascading. - **Annotations:** `readOnlyHint: true` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `token` | string | Yes | Project publish token | | `model` | string | No | Target a specific model. When omitted, returns all models (recommended). | | `inputs` | object | No | Input values as key-value pairs. Auto-routed to the correct model. Omitted inputs use defaults. | ## Examples ### Example 1: List Available Projects **Prompt:** "What calculators are available on MetaModel?" **Tool call:** `metamodel_list_projects()` **Response (truncated):** ```json { "projects": [ { "token": "989bc6ae-e4d7-4585-8908-bfd03358043e", "name": "Deck Builder", "description": "Interactive deck builder with code-compliant sizing. Uses LOOKUP tables for beams, frost depths, and railing requirements.", "models": ["deck", "platformModel", "beamsModel", "postsModel", "railingModel", "summaryModel"] }, { "token": "fdc5fbef-9d4b-46c3-b72d-1950e03d4bf4", "name": "Building Engineer", "description": "Complete building engineering calculator. Enter room dimensions to auto-size HVAC, electrical, and lighting systems with full cost estimation.", "models": ["room", "hvac", "electrical", "lighting", "costEstimator"] }, { "token": "363c7753-ac4b-4de4-b1e7-e4536cb2f9bb", "name": "Life Expectancy Calculator", "description": "Estimate your life expectancy based on age, sex, and lifestyle factors.", "models": ["basics", "lifestyle", "results"] } ] } ``` ### Example 2: Get Project Schema **Prompt:** "What inputs does the Building Engineer calculator need?" **Tool call:** `metamodel_get_schema({ token: "fdc5fbef-9d4b-46c3-b72d-1950e03d4bf4" })` **Response (truncated):** ```json { "projectName": "Building Engineer", "models": [ { "name": "room", "title": "Room Dimensions", "inputs": [ { "name": "length", "type": "number", "defaultValue": 35.26 }, { "name": "width", "type": "number", "defaultValue": 60 }, { "name": "height", "type": "number", "defaultValue": 12 } ], "outputs": [ { "name": "floorArea", "formula": "floorArea = length * width" }, { "name": "volume", "formula": "volume = length * width * height" } ] }, { "name": "hvac", "title": "HVAC Sizing", "inputs": [ { "name": "climateZone", "defaultValue": "cold" }, { "name": "btuFactor", "type": "number", "defaultValue": 25 } ], "outputs": [ { "name": "btuRequired", "formula": "btuRequired = volume@room * btuFactor" }, { "name": "tonnage", "formula": "tonnage = btuRequired / 12000" }, { "name": "annualCost", "formula": "annualCost = tonnage * 120" } ] } ] } ``` Note the cross-model references: `volume@room` means "use the `volume` output from the `room` model." MetaModel handles this cascading automatically. ### Example 3: Run a Computation **Prompt:** "Size the HVAC, electrical, and lighting for a 50×80 ft room with 14 ft ceilings" **Tool call:** `metamodel_compute({ token: "fdc5fbef-...", inputs: { length: 50, width: 80, height: 14 } })` **Response:** ```json { "models": { "room": { "outputs": { "floorArea": 4000, "volume": 56000, "wallArea": 3640 } }, "hvac": { "outputs": { "btuRequired": 1400000, "tonnage": 116.7, "annualCost": 14000 } }, "electrical": { "outputs": { "outletsNeeded": 304, "totalAmps": 456, "circuitCount": 23 } }, "lighting": { "outputs": { "totalLumens": 201240, "fixtureCount": 51, "totalWattage": 2040 } }, "costEstimator": { "outputs": { "hvacMaterial": 415917, "electricalMaterial": 18400, "lightingMaterial": 7650, "totalLabor": 89321, "grandTotal": 531288 } } }, "metadata": { "projectName": "Building Engineer", "evaluationMs": 7.1 } } ``` One API call → room geometry, HVAC sizing, electrical load, lighting design, and full cost estimate. All computed from real formulas in ~7ms, not LLM-generated. ## Development To test against a local MetaModel instance: ```bash # Clone and build cd packages/mcp-server npm install npm run build # Run with local URL node dist/index.js --url http://localhost:3000 # Test with MCP Inspector npx @modelcontextprotocol/inspector node dist/index.js --url http://localhost:3000 ``` ## Privacy Policy MetaModel's MCP server is **stateless and read-only**: - **No authentication required** — all published projects are public - **No personal data collected** — computations are anonymous - **No data stored** — inputs are evaluated and discarded immediately - **No cookies or tracking** — the server makes direct API calls to metamodel.app - **No third-party data sharing** — results go only to the requesting client Full privacy policy: [https://www.metamodel.app/privacy](https://www.metamodel.app/privacy) ## About MetaModel [MetaModel](https://www.metamodel.app) lets you build calculators, pricing tools, and engineering models with a spreadsheet-like formula language. Describe what you want, AI builds it, publish in seconds. Models become API-callable computation endpoints that any AI assistant can use via this MCP server. ## License MIT ## Troubleshooting - **"Project not found or not published"** — the token belongs to an unpublished or deleted project. Ask the project owner for a current publish token, or list what's available with `metamodel_list_projects`. - **Unknown input names** — inputs are matched by property name. Call `metamodel_get_schema` first; it returns the exact input names, types, and defaults for the project. - **Inputs sent as a JSON string** — pass `inputs` as a JSON object (`{"width": 12}`), not a stringified object. Stringified inputs fail with an "Unknown input" error naming a character index. - **Rate limits (hosted endpoint)** — the hosted URL is rate-limited per client. For heavy use, run the npm package locally with your own network egress. - **Node version (local install)** — the stdio server needs Node 18+.