MyBenchLab Documentation Open editor

MCP — drive MyBenchLab from an AI agent

MyBenchLab exposes its bench engine over the Model Context Protocol (MCP). An external agent (Claude Desktop, the Claude.ai web connector, n8n, or your own script) can read the DSL contract, author benches, compile/validate/simulate them, and import/export the .mbl file format — all scoped to the token owner's own benches.

The access stack (Personal Access Tokens, OAuth 2.1, and the MCP gateway) is provided by the shared zodo:auth-mcp-kit package. The connector id is `mybenchlab` and the gateway is mounted at `/mcp`.

1. Mint a token

Log in, open Settings → API tokens (/settings/tokens), and click Generate new token:

1. Name it (e.g. "Claude Desktop personal"). 2. Pick the scopes you want to grant. Scopes are per-tool and grouped by category — use *Select all* to grant the full surface, or a group toggle for just *Benches* or *Type catalog*. 3. Choose an expiration (90 days recommended).

The token is shown once in plaintext (mblmcp_…). Copy it immediately; it is stored only as a hash and cannot be shown again. You can revoke any token at any time from the same screen.

2. Connect a client

Claude Desktop — add the server to ~/.config/Claude/claude_desktop_config.json (or your OS equivalent):

{
  "mcpServers": {
    "mybenchlab": {
      "url": "https://mybenchlab.ai/mcp",
      "headers": { "Authorization": "Bearer mblmcp_YOUR_TOKEN" }
    }
  }
}

curl — every call is standard MCP over Streamable HTTP:

curl -s https://mybenchlab.ai/mcp \
  -H "Authorization: Bearer mblmcp_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

The gateway also supports OAuth 2.1 (DCR/PKCE) for clients that prefer it — see /.well-known/oauth-authorization-server.

3. Tools

Each tool requires the matching scope mybenchlab:<tool>. Every tool acts only on the calling token owner's benches.

ToolWhat it does
kinds_catalogThe engine's catalog: component kinds, connections, ports and categories with docs + params + icons, plus the generated .d.ts DSL contract. Read this first.
bench_listList your benches (metadata only).
bench_getOne bench: metadata, sources, and a compiled summary (components/connections/drivers + BOM).
bench_createCreate a bench from DSL source. Compiles best-effort and returns errors/warnings.
bench_build_frame_benchCreate a workshop bench from parameters (length, height, profile, shelves, casters) — a deterministic builder emits validated geometry, no DSL to author. Only length is required; leg columns are derived from the length. Legs can be square (legSize) or rectangular (legW/legD); pass a named profile (legProfile/railProfile, e.g. metalon-50x30-2.0) as a shorthand for the raw dims.
bench_build_caster_dollyCreate a rolling platform / welding cart from parameters (four casters or leveling feet, a top, an optional pull handle). Only width is required.
bench_build_steel_shelfCreate a steel shelf unit from parameters (U-channel base, round-tube posts, flat-bar rails, wood shelf, optional gusset). Only width is required. Named profiles (channelProfile/postProfile/barProfile) are a shorthand that expands to the raw member dims.
bench_renameRename one of your benches.
bench_update_sourceReplace a source file's content and recompile.
bench_removeDelete a bench.
bench_compileRecompile from stored sources; returns errors + a document summary.
bench_validateRun the static validators (connectivity / envelope / interference). Returns { ok, errors, warnings, meta }.
bench_runCompile and simulate for N ticks (default 120, max 1200); returns final ω (rad/s + RPM) per port and any conflicts.
bench_exportExport the bench as a .mbl JSON object (sources + compiled document + BOM).
bench_importImport a .mbl document (string or object) as a new bench.
part_authoring_guideReturns the part-authoring contract: the feature-list schema (sketch → base op → modifiers), the conventions (mm, closed CCW profile) and worked examples (drilled plate, U-channel). Call it first so YOU (the connected model) know how to build the geometry — no server model involved.
part_createCreate an editable parametric part from a feature list you author (see part_authoring_guide). The server MATERIALIZES it with the engine (rejects it if it is not a sane solid) and adds it to a BENCH (a project) — pass benchId to choose one, or omit it to reuse your sticky active bench (the first call with no benchId creates one and fixes it as active; later calls keep adding to it). The library ("Minhas peças") is opt-in: pass saveToLibrary:true (and an optional free-text category) to also save the part there. No server model, no API key. Returns { ok, benchId, benchCreated, componentId, name, metrics, weightKg, bbox, savedToLibrary, benchUrl, libraryUrl? } or { ok:false, reason, errorInfo } (fix the pointed feature and call again — the failure happens before any bench is created or touched).
part_use_benchSelect or read the active bench used by part_create when called without a benchId. With benchId → verify ownership, make it active, return its info; without → return the current active bench (or { active:null }).
part_from_spec*Fallback:* the SERVER calls a model to turn a free-text dimensional spec into the feature list, then materializes + saves it. Needs a server-side ai-kit provider/key and is gated by `partFromSpec.enabled`. Prefer part_create (you author the list yourself, no key).
part_listList your Part Design bodies (plus the platform seeds): name, material, volume, weight, bbox, category. Pass category to filter the library by an exact bucket.
part_getOne body in detail: the editable feature list, the snapshot (volume/weight/bbox) and the spec sheet.

The DSL itself is documented in /docs/dsl; the static workbench in /docs/static-workbench; the file format in /docs/file-format. kinds_catalog returns the same contract in machine-readable form so an agent never has to guess.

4. Worked example

Step 1 — learn the DSL. Call kinds_catalog (no arguments). It returns the component kinds (statics.steelTubeSquare, mech.spurGear, …), the connection kinds (statics.weld, statics.rest, mech.mesh, …), the port types, and the authoritative .d.ts. Read it before writing any source.

Step 2 — create a bench. Call bench_create with a small static assembly — two upright legs with a rail resting on top and welded to each. A declared envelope is authored as extents from the origin corner (0,0,0)..(x,y,z), so keep the whole assembly in the positive octant:

export default defineBench(({ statics }) => {
  const legL = statics.steelTubeSquare({
    id: 'leg_l',
    width: 50,
    wallThickness: 2,
    length: 700,
    transform: { position: [25, 350, 25], rotation: [-90, 0, 0] },
  });
  const legR = statics.steelTubeSquare({
    id: 'leg_r',
    width: 50,
    wallThickness: 2,
    length: 700,
    transform: { position: [625, 350, 25], rotation: [-90, 0, 0] },
  });
  const rail = statics.steelTubeRectangular({
    id: 'rail',
    width: 40,
    height: 20,
    wallThickness: 2,
    length: 600,
    transform: { position: [325, 710, 25], rotation: [0, 90, 0] },
  });

  statics.weld(legL, rail);
  statics.weld(legR, rail);

  statics.envelope({ x: 700, y: 760, z: 80 });
});

bench_create returns { benchId, errors, warnings }. Because the compile is best-effort, the bench is created even if a validator complains — you fix it with bench_update_source and re-check.

Step 3 — validate. Call bench_validate with the benchId. It compiles and runs the static validators (connectivity / envelope / interference), returning { ok, errors, warnings, meta }. The assembly above returns ok: true; if you tighten the envelope or move a part off its neighbour, the errors point at the exact part — adjust positions, envelope, or weld targets and re-check until ok is true.

Step 4 — export. Call bench_export with the benchId to get the .mbl JSON — sources, the compiled document, and the rolled-up BOM (identical parts grouped with quantity + weight). Store it, feed it to another tool, or hand it back to the user.

For kinematic benches, use bench_run instead of bench_validate: it simulates the gear train and returns each port's final angular velocity so the agent can confirm the output speed before finishing.

Notes