MCP tool & Sheet reference
Server surface
The v0.31 server surface exposes 39 modeling tools, one reusable prompt, one skill catalog entry for plugin-import scans, and 60 resources at https://app.confbuild.com/mcp. The toolset decides which tools a connection lists: modeling (default) holds every project, render, export, and comparison tool; ?toolset=video on the MCP URL (https://app.confbuild.com/mcp?toolset=video) lists the nine Video Studio tools plus the shared basics, and ?toolset=all lists both (48 tools). Tools outside the toolset cannot be called on that connection; confbuild_start_design_session reports the active toolset. v0.30 also adds the browser channel’s visibility and adoption logic, asynchronous checkpoints, deterministic repair operations, and the finish dry run — each described with the affected tools. The catalog does not install a skill for a direct MCP connection; confbuild-mcp-agent is bundled with the confBuild plugin. Transport is Streamable HTTP with OAuth/PKCE. Structured results are returned as MCP text and structuredContent, with screenshots additionally returned as native image blocks. The local STDIO transport exposes the same functional surface for developers.
The reusable prompt is named confbuild-design. It instructs the client to call confbuild_start_design_session first and follow the complete create/edit/render loop.
OAuth access is enforced per tool: mcp covers the protocol and prompt surface, projects:read covers project/session reads, projects:write covers mutations, and render covers render/export jobs and artifact delivery. Starting a render or export requires both projects:read and render; missing authorization returns INSUFFICIENT_SCOPE with the exact missing scopes.
The server advertises io.modelcontextprotocol/skills. skills/list and skills/get return the complete skill with its resource manifest and SHA-256 digests; resources/read returns every declared file. Under the current OpenAI contract, Scan Tools uses this interface for a static plugin import, not for runtime installation in a connected client. Direct MCP connections use the confbuild-design prompt as the compatible entry point.
Tools by phase
Orientation and prompts
| Tool | Purpose | Writes |
|---|---|---|
confbuild_start_design_session |
Mandatory first call; infers profile, optionally resolves the target, and returns the prompt bundle | No |
confbuild_plan_sheet_topology |
Declares one indivisible sheet or a Composite-style Main Part plus functional child sheets before any mutation |
No |
confbuild_get_prompt_sections |
Loads the profile and selected semantic prompt packs for a direct design session; optional maxChars/offsetChars windows |
No |
confbuild_explain_row_type |
Canonical header columns, example rows, placement notes, and the repository documentation excerpt for one row type (e.g. gear, aluprofile, pneumatic) — cheaper than loading the whole catalog pack |
No |
confbuild_get_prompt_bundle |
Gets a prompt bundle without creating a design session | No |
confbuild_list_prompt_resources |
Lists prompt resources with URI, size, MIME type, and SHA-256 | No |
Important confbuild_start_design_session inputs:
{
"request": "Complete user request",
"projectReference": "optional ID or URL",
"client": "codex",
"model": "exact public model ID when known",
"profile": "machine",
"promptDetail": "progressive",
"knownBundleHashes": ["sha256 of a bundle you already hold"],
"knownSectionHashes": ["sha256 of bundle sections you cached"]
}
Classify the domain yourself and pass an explicit profile (building, machine, 3dprint, structure for halls/frames/trusses, furniture, generic); auto only triggers a keyword fallback for clients that cannot classify. In the default mode, read the compact base, call confbuild_get_prompt_sections with the designSessionId and ids from progressiveLoading.requiredBeforeEditing, and then load only packs the design actually needs. nextProjectTool identifies the project call that follows. knownBundleHashes can omit a cached base completely; knownSectionHashes omits known base, profile, or pack text. essential and full remain available as monolithic compatibility modes.
Access and projects
| Tool | Purpose | Writes |
|---|---|---|
confbuild_auth_status |
Verifies the OAuth-bound confBuild identity without revealing tokens | No |
confbuild_resolve_project_reference |
Resolves an ID or URL as an owned private or public project | No |
confbuild_create_project |
Creates a private project, optionally with initial Sheets | Yes |
confbuild_clone_project |
Copies a public/read-only project into a private project | Yes |
confbuild_read_project |
Reads metadata and hydrated Sheets, optionally filtered | No |
confbuild_create_project and confbuild_clone_project support an idempotencyKey. Reusing the same key in the same user account resolves to the same deterministic project ID.
model is optional. The client should report only its exact public model ID and omit the field otherwise; the server never guesses a model. Pass designSessionId into create, clone, and begin edit.
The request value passed to confbuild_start_design_session is stored verbatim in the admin-only MCP history. Clients must put only the actual user request there, never private reasoning, screenshot analysis, or credentials. After successful commits, the server additionally stores the latest Sheet state; intermediate patches are not archived as history entries.
Separately, the server maintains content-free usage statistics: tool, time, user/client ID, optional reported model on the start event, status/error code, duration, bytes, Sheet/row/cell quantities, commits, project actions, and render activity. Prompt text, cell values, images, and reasoning are never copied into this telemetry. Model tokens consumed by the MCP client are technically invisible to the server.
MCP-created and MCP-edited projects receive a compact metadata.agentMcp provenance marker: created/edited, timestamps/count, client/tool, optional reported model, profile, and MCP client name/version. The admin area shows these fields in “MCP History” and “Recent user work”; the marker contains no prompts, Sheet values, screenshots, responses, or reasoning.
confbuild_read_project can limit context:
{
"reference": "PROJECT_ID",
"sheetNames": ["Main Part", "Frame"],
"maxRowsPerSheet": 500
}
If truncated: true is returned, the client must not replace that complete Sheet until it has read the untruncated content.
Editing and persistence
| Tool | Purpose | Writes |
|---|---|---|
confbuild_begin_edit |
Loads the complete workbook and base revision into a temporary edit session | Only when auto-cloning |
confbuild_apply_sheet_patch |
Applies up to 1,000 operations to the session working copy, including the deterministic repairs wire_child, set_default_material, and auto_fix; every server-side rewrite is listed in normalizations; no project commit yet |
Session state only |
confbuild_read_edit_workbook |
Reads the current session working copy, optionally by Sheet name | No |
confbuild_validate_edit |
Also checks sheet topology, cyclic/orphan children, and parent-to-child parameter contracts, plus structure, markers, IDs, serialization, size limits, engine-trap lint, and saved-configuration shadowing | No |
confbuild_commit_edit |
Atomically saves workbook and scriptcode with optimistic revision protection and a mandatory pre-commit rollback snapshot |
Yes |
confbuild_publish_checkpoint |
Fast path for one coherent model stage: patch, one validation, atomic commit with rollback snapshot, and an in-place rebuild in the connected clean tab; returns right after the save by default (editorRevisionPending: true) while the tab rebuilds in the background |
Yes |
confbuild_discard_edit |
Drops the temporary edit session; committed data remains | Session destructive |
confbuild_find_rows |
Searches cell values (substring/exact/regex, optionally restricted to columns) across the sheets of an edit session or project, returning matches with sheet, row, column, and a row preview | No |
confbuild_list_edit_sessions |
Lists your live edit sessions (project, dirty state, commit count, expiry) — a lost editSessionId can be recovered instead of abandoning the session |
No |
confbuild_list_project_snapshots |
Lists the rollback snapshots of an owned project, newest first | No |
confbuild_restore_project_snapshot |
Commits a snapshot’s workbook and scriptcode as the new revision; the pre-restore state is snapshotted first |
Yes |
confbuild_diff_revisions |
Sheet row diff plus content-free scriptcode SHA-256/size comparison between revisions |
No |
confbuild_update_scene_settings |
Reads or changes project.sceneSettings (base lighting, sun, environment map, background, fog, rendering mode, view toggles) that no sheet row can express; revision-protected, returns the previous values as rollback, and re-applies the look in the connected tab without a rebuild |
Yes |
Always pass the designSessionId returned by confbuild_start_design_session to confbuild_create_project, confbuild_clone_project, and confbuild_begin_edit. This keeps attribution, the user request, and committed Sheets associated with the correct history entry when multiple agents run concurrently.
confbuild_commit_edit can also update project fields:
{
"editSessionId": "edit-…",
"mutationId": "stable-client-mutation-42",
"projectPatch": {
"name": "Portal Mill 800",
"projectType": "machine-component",
"description": "Parametric portal milling machine",
"metadata": { "source": "mcp-client" }
}
}
Each commit stores the pre-commit workbook and project scriptcode together as a rollback snapshot (preCommitSnapshotId in the result). Protection is mandatory: the legacy "snapshot": false field remains accepted but is ignored, and snapshot failure leaves the saved project unchanged. Retention keeps the newest snapshots per project and prunes older ones automatically. A restore commits the snapshot as a regular new revision and first snapshots the state it replaces, so rollback is itself undoable. Legacy workbook-only snapshots remain readable and explicitly preserve the current source when restored.
Since v0.30, confbuild_publish_checkpoint returns right after the atomic save by default (waitForEditorMs: 0): editorRevisionPending: true means the connected clean tab accepted the revision and rebuilds in the background, and nextTool is the normal stage continuation. Render, inspection, interaction, and export starts wait a few seconds at most for the exact revision and otherwise queue behind the running rebuild (editorRevisionPending on the poll). An extra confbuild_prepare_browser call is only needed when a result reports BROWSER_TAB_REQUIRED or names a user action.
From the interfaces stage on, a checkpoint also starts an asynchronous diagnostics-only engine check of the committed revision in the connected tab by default (engineCheck: 'async'; false for the early stages, true waits in the call). The result — rows without geometry, actionable engine warnings, placement audit, and defect signals — arrives once as previousEngineCheck on the next patch, checkpoint, or confbuild_validate_edit result.
Browser and visual loop
| Tool | Purpose | Writes |
|---|---|---|
confbuild_prepare_browser |
Mandatory: proves a signed-in tab before creation, then the exact project/configuration revision; returns reuse, reload, navigate, or open-new with a clickable target |
No |
confbuild_browser_capabilities |
Reports the private browser-tab channel remotely; local mode also reports Playwright/CDP | No |
confbuild_open_editor |
Opens the interactive confBuild app (dashboard or one project) inside the host’s conversation panel or fullscreen; uses the normal sign-in, checked against the MCP account; mutates nothing and is the only tool allowed before a design session | No |
confbuild_render_and_wait |
Preferred: starts the render and long-polls it in the same call; returns the completed result within waitMs or the running job for follow-up polls |
No |
confbuild_inspect_outputs |
Produces a four-image inspection set for exact output IDs: zoomed focus with ghosted surroundings, isolation, automatic center section, and x-ray | No |
confbuild_run_project_interaction |
Executes one persisted project interaction in the exact prepared revision — an input button’s ONCLICK, a declared script function, or a registered script action — and returns before/after images plus script diagnostics; the replacement for raw editor clicks |
No |
confbuild_validate_animation |
Deterministic animation gate for a persisted pose function: pose(0) is a no-op, pose(mid) moves something, pose(1) loops seamlessly into pose(0), and reset restores the rest state; optional pose sweep with intermediate frames |
No |
confbuild_render_project |
Starts an asynchronous render job for an ID/URL or edit session | No |
confbuild_get_render_result |
Long-polls a job (default waitMs 25 s) and returns status, diagnostics (outputIdAudit.rowsWithoutGeometry, engineWarnings, defectSignals, per-part bounds), and optionally up to seven PNGs; diagnosticsDetail: 'summary' for cheap routine polls |
No |
confbuild_export_project |
Starts an app-native STEP/STL/GLB/3MF, sanitized BOM, drawing-set PDF, sheet-metal flat-pattern DXF, cost, quote, purchasing-list, or variant-metrics export | No |
confbuild_get_export_result |
Long-polls the export job; embeds files up to maxContentBytes (default 8 MB) and safely directs larger files to chunk delivery |
No |
confbuild_get_export_chunk |
Returns up to 4 MB of a completed export at offsetBytes; continue with chunk.nextOffsetBytes until chunk.complete is true |
No |
confbuild_compare_variants |
Starts a sequential comparison of 2–8 project or saved-configuration URLs by price, mass, CO2e, or scene dimensions | No |
confbuild_get_variant_comparison_result |
Long-polls the comparison and returns ranks, coverage, deltas, warnings, and explicit per-variant failures | No |
Call confbuild_prepare_browser immediately after session setup. With no project yet, pass the design session: an existing signed-in confBuild tab is reused, otherwise the dashboard is opened before creation. Then call it for the resolved/created/cloned target and again after every commit or restore until connected: true. Exact clean tab ⇒ reuse; clean stale tab ⇒ reload; dashboard ⇒ navigate; another project/configuration, any dirty tab, or no tab ⇒ open-new. Codex/Claude performs the action with host browser control; without browser control, it presents the resource link and waits.
Tab presence carries visibilityState, visibilityChangedAtMs, and a heartbeat that a worker clock refreshes every 20 seconds, also in hidden tabs. Since v0.31, visibility alone never asks the user: a hidden tab keeps rebuilding, claiming, and capturing, and neither a connected hidden tab nor a claimed job is interrupted for being hidden. An assigned tab without a heartbeat for 75 seconds (measured at the server-side write time, so a skewed client clock cannot fake a stall) is replaced once before anyone is asked: confbuild_prepare_browser adopts an open, unassigned, responsive matching tab (replacedStalledTabId) or returns state: 'tab-stalled' with action: 'open-new' for exactly one new tab; while that tab loads, later prepares return tab-opening. Render polls on the stalled tab report tabStalled: true with nextTool: confbuild_prepare_browser, and a job started after the switch targets the new tab. A non-connected handoff, a BROWSER_TAB_REQUIRED error, or a running render/inspection poll returns userActionRequired: 'focus-tab' with userAction.instruction only when the replacement did not connect within 4 minutes or stalled again within 30 minutes, when known pending work (an in-place rebuild or an unclaimed job) waited 3 minutes while a responsive tab stayed hidden, or when a job expired unfinished while hidden; a connected stalled tab without an assigned session stays usable for edits and commits but reports renderRequiresVisibleTab: true. The server does not wait on a handoff that names a user action — the client asks the user once, in their language, to bring the confBuild tab to the front or into its own window. When the user opens the exact project in a new tab and exactly one clean matching tab exists, the running session adopts it inside the same call (browserConnectionAdoption); BROWSER_CONNECTION_REPLACED remains for ambiguous or missing replacements.
A failed browser-tab job keeps the family code RENDER_FAILED or PROJECT_INTERACTION_FAILED and adds a stable failureCode (JOB_EXPIRED_UNCLAIMED, JOB_EXPIRED_WHILE_CAPTURING, MODEL_NOT_READY, CAPTURE_BLANK, AUTO_INSPECTION_FRAME_UNAVAILABLE, BROWSER_TAB_DIRTY, CONFIGURATION_CHANGED, …), failureStage, lastJobStatus, the target tab’s tabVisibility, and a concrete nextTool or userActionRequired. Only a job that expired unfinished is attributed to a hidden or stalled tab; a job that failed with its own error keeps that error’s next step. The client follows that step instead of retrying blindly.
confbuild_get_render_result supports includeImages: false for status-only checks. For visual approval, use includeImages: true with maxImages covering every view. The result interleaves caption and image for Codex/Claude and reports omissions in presentation.omittedImageCount. Render tools also accept captureScope: isolateOutputIds, zoomToOutputIds, ghostOtherObjects, automatic or explicit sectionPlane, and xray. views accepts default, right, front, left, back, top, and bottom.
waitMs (0–120,000; below the client timeout) turns the poll into a server-side long-poll. Browser-tab is the default with no automatic server fallback. rendererMode: "server-headless" is allowed only with serverRenderingExplicitlyRequested: true after the user explicitly requested server rendering; browser connection remains mandatory.
When an export exceeds maxContentBytes, confbuild_get_export_result reports delivery: "chunked", downloadWith: "confbuild_get_export_chunk", and nextOffsetBytes: 0. The client assembles the byte ranges; private Cloud Storage and local filesystem paths are never exposed.
The additional export format names are drawing-pdf, sheetmetal-dxf, cost-json, quote-pdf, purchase-json, purchase-csv, and variant-metrics-json. Drawing pages are fully hydrated before PDF generation; a drawing window opened only for the job is closed without saving. Cost, quote, and purchasing outputs use the application’s canonical BOM and pricing services. Quote and purchasing fail on mixed currencies; quote also fails when required prices are missing. Purchasing lists remain usable when supplier prices are unavailable and report estimated-cost coverage for those lines. No exchange-rate conversion is performed. quote-pdf additionally requires a configured seller identity: a meaningful company or seller name in companyName and either a complete postal contact (street and zipCity) or a valid electronic contact (email, phone, or website). Commercial failures return machine-readable codes such as INVALID_SELLER_IDENTITY, MIXED_CURRENCIES, or MISSING_REQUIRED_PRICES plus PII-free details, for example field names, missing requirements, BOM positions, or currency codes instead of seller or customer data.
Before confbuild_compare_variants, prepare every variant reference separately through confbuild_prepare_browser and keep those tabs open. The comparison rebuilds every saved variant sequentially in the real editor. Saved configurations are pinned to their document path and SHA-256 revision; a missing or changed revision fails only that row. price requires one unambiguous currency and complete coverage, mass requires complete position coverage, co2 defaults to an 80% mass-coverage gate, and bounds metrics are explicit scene-axis measurements.
Completed results include two additional evidence blocks:
diagnostics.geometry: an approximate geometry audit with BVH-confirmed collision pairs, AABB-suspected overlaps, detached parts that touch nothing, far outliers, and model bounds. Findings are advisory and map onto the model-loop defect categories; the client verifies them against the returned views.iterationDelta: mesh/output/collision/detachment/bounds deltas against the previous completed render of the same project, so “did my patch change anything” does not need a screenshot comparison.
Completion
| Tool | Purpose |
|---|---|
confbuild_finish_design_session |
Closes design/edit state after final image inspection and returns the project URL; dryRun: true first lists every remaining blocker without closing anything |
Completion fails while the edit session contains uncommitted changes or the specified final render job is incomplete.
The finish call accepts a structured, content-free outcome: completionState (complete/partial/blocked), iterationsUsed, and fixedDefectCategories/residualDefectCategories restricted to the model-loop defect enum. Only these enums and counts are stored for loop-quality trends; the free-text summary is returned to the client and never persisted.
With dryRun: true, the finish call evaluates every completion gate for the requested completionState (default complete) and returns all blockers with their nextTool plus the passedGates, without closing or recording anything — run it after the last commit and before the inspection sweep and the final render. The four-image inspection evidence is bound to the exact revision instead of the design session and stays valid for seven days, so a continuation session reuses it.
Workbook format
A workbook is an array of Sheet objects:
[
{
"name": "Main Part",
"visible": true,
"data": [
["INPUTID", "TYP", "VALUE", "VALIDATED", "UNIT", "LABEL", "VISIBLE", "MIN", "MAX", "PARAMS", "ONCLICK", "ONCHANGE"],
["width", "slider", 1000, true, "mm", "Width", true, 500, 2000, "", "", ""],
["OUTPUTID"],
["#", "type", "width", "height", "depth", "material", "x", "y", "z", "rx", "ry", "rz"],
["body", "cube", "=C2", 600, 400, "#8C30F5", 0, 0, 0, 0, 0, 0]
]
}
]
The complete columns and geometry rules come from the prompt bundle. Resource confbuild://schema/workbook describes the compact MCP format.
Patch operations
| Operation | Required fields | Effect |
|---|---|---|
replace_workbook |
sheets |
Replaces all Sheets |
upsert_sheet |
sheet |
Adds a Sheet by name or replaces it |
delete_sheet |
sheetName or sheetIndex |
Removes a Sheet |
rename_sheet |
Sheet address, newName |
Renames a Sheet uniquely |
set_sheet_visibility |
Sheet address, visible |
Shows or hides a Sheet |
set_cells |
Sheet address, cells |
Sets individual cells by A1 or row/column |
replace_rows |
Sheet address, startRow, rows |
Replaces as many rows as supplied |
insert_rows |
Sheet address, startRow, rows |
Inserts rows before the start position |
delete_rows |
Sheet address, startRow, count |
Removes rows |
upsert_sheet_tsv |
sheetName, tsv |
Adds or replaces a Sheet from tab-separated text |
upsert_output_rows |
Sheet address, rows or tsv |
Replaces output rows by the OUTPUTID in column A or appends new ones to the output block |
patch_scriptcode |
replacements (find, replace, optional all/count) |
Edits the project script by search and replace |
wire_child |
childName, optional parentSheetName, outputId, placement, parameters |
Writes or repairs the parent’s SHEET: <child> row with a governing # header that passes every planned child input |
set_default_material |
Sheet address, mechanicalMaterialId, optional onlyMissing, rowTypes |
Fills mechanicalMaterialId on the Sheet’s physical rows |
auto_fix |
optional fixes |
Repairs same-row VALIDATED formulas, groupend cells, and control-type aliases, and derives manufacturing metadata from the topology plan |
The three repair operations are deterministic and, like every other server-side rewrite, are reported per row in normalizations — including the silent 0/1 number-to-checkbox normalization. The validation errors TOPOLOGY_CHILD_REFERENCE_MISSING and TOPOLOGY_REFERENCE_PARAMETER_MISSING carry the matching wire_child operation as suggestedOperation; PHYSICAL_MATERIAL_MISSING names a library suggestion per row type (such as S235JR, EN AW-6060, C45E; none for building and furniture rows). autoFix: true on a patch or checkpoint appends the auto_fix operation automatically.
Indexing
sheetIndexis zero-based.row, numericcolumn,startRow, and A1 addresses are one-based.- Columns may be numbers or letters.
Set cells
{
"editSessionId": "edit-…",
"operations": [
{
"op": "set_cells",
"sheetName": "Main Part",
"cells": [
{ "a1": "C2", "value": 1200 },
{ "row": 2, "column": "F", "value": "Width" }
]
}
]
}
Add or replace a Sheet
{
"op": "upsert_sheet",
"sheet": {
"name": "Frame",
"visible": true,
"data": [["INPUTID"], ["OUTPUTID"]]
}
}
Validation
Validation returns valid, errors, warnings, and statistics. Hard errors include:
- empty workbook;
- empty or duplicate Sheet names;
- rows that are not arrays;
- unserializable values or non-finite numbers;
- more than 2,000,000 cells.
Warnings include a missing INPUTID header, missing OUTPUTID marker, or duplicate output IDs. A deterministic engine-trap lint additionally flags mistakes that would otherwise surface only as a wrong render: a bare cell reference such as D4 where =D4 was meant (NAKED_CELL_REFERENCE), text in numeric columns that the engine silently coerces to 0 (NON_NUMERIC_VALUE), two consecutive # header rows of which only the last takes effect (CONSECUTIVE_HEADER_ROWS), data cells beyond the governing header (ROW_WIDER_THAN_HEADER), output rows without any header (MISSING_OBJECT_HEADER), and — new in v0.30 — an output row under a # header that lacks its primary column and leads with another type’s column (ROW_TYPE_HEADER_MISMATCH): the engine maps cells by position and silently builds degenerate geometry. VALUE_SHADOWED_BY_CONFIGMODEL warns when a saved editor configuration overrides a patched VALUE cell, so the render shows the saved value rather than the patch. A workbook may be formally saved despite warnings; the client must evaluate them professionally.
Since v0.17, confbuild_plan_sheet_topology first declares whether the model is truly one indivisible part or whether Main Part orchestrates named functional child sheets. Composite projects are immediately seeded with the planned subsheets. Validation blocks missing or unplanned children, cycles, wrong parent references, missing child inputs, and empty parameter cells in the parent reference row. Completion additionally requires matching subsheetCount/subprojectCount diagnostics. Formula, SHEET:/PROJECT: resolution, row-type, and input-range checks remain in force. A failed commit returns validation or snapshot errors inline; no new revision is stored without a complete rollback snapshot.
Persistence and large Sheets
Small workbooks are stored inline in the project. Above approximately 700 KB of serialized Sheet data, the server automatically uses generation-specific chunks of approximately 240 KB. The manifest and new chunks are written atomically; stale project-Sheet chunks are cleaned afterward.
The client does not manage this storage. On read, the server hydrates both variants into the same workbook format.
State lifetime
| State | Lifetime |
|---|---|
| Design session | 6 hours |
| Edit session | 6 hours, extended on access (at least 5.5 hours after the last access) |
| Render job | 24 hours |
| Render iteration baseline (per project) | 7 days |
| Inspection evidence (per revision) | 7 days |
| Rollback snapshots | Newest per project retained, pruned on commit |
| Committed project | Persistent in confBuild/Firebase |
In Remote mode, design, edit, and render state is separated by UID and stored in compressed private Cloud Storage. It therefore survives stateless Function instances and becomes invalid after expiry. Local STDIO keeps temporary state only in process memory. Committed projects remain persistent in both modes.