Skip to main content
Pascal exposes a Model Context Protocol server that lets an AI agent create, inspect, edit, validate, and save 3D building projects. Changes use the same project store as the editor, so you can watch the result and continue editing it in Pascal. Decide three things before you connect:
  1. Which store holds the project. Projects in your Pascal account or organization use the hosted endpoint below. Projects made with the local Pascal CLI stay on your machine, and pascal editor starts their MCP service; no hosted account or API key is required. The two stores are separate: connecting the hosted server does not upload local projects. See Hosted MCP, local CLI, and the MCP package.
  2. How the client signs in. Claude and the official Pascal Cursor connector sign in through the browser. Other hosted clients use an API key. See Connect your Pascal account.
  3. How you check the result. Ask the agent to validate and save, then return the editorUrl Pascal reports. Open it, reload, and confirm the change is there. See Start an agent session.
Pascal’s scene checks look for modeling problems; they are not an engineering, survey, or building-code review. The tools a server offers depend on its release and on what the connection may do, so read them from the server rather than from a copied list: MCP discovery names each hosted tool and the scope it needs. For local projects, the Pascal agent skills 0.1.7 Claude Code plugin supplies pascal mcp connect automatically; other clients configure the same connector once. Jump to local MCP. The hosted endpoint is:
Pascal is also in the official MCP Registry as app.pascal/editor; see Install from the MCP Registry.

Connect your Pascal account

Claude (on the web, Claude Desktop and Claude Code) and the official Pascal Cursor connector support browser OAuth: sign in to Pascal, select your personal or organization workspace, and review the requested permissions. The connection acts in that workspace; it does not create another user or transfer local projects. For Claude, follow Connect Pascal to Claude. For Cursor, choose the hosted pascal-hosted server. Only registered clients can use this flow. Dynamic client registration is disabled. Use the API-key setup below for other clients. The deployment’s MCP metadata and OAuth resource metadata report which authentication methods are enabled, and MCP discovery lists every tool with the scope it needs. An agent can follow the whole flow from /auth.md; challenges, insufficient_scope and rate-limit headers are described in Errors, rate limits and versioning. OAuth here connects an agent to Pascal. Connecting a ChatGPT subscription is a separate account feature and does not authorize a connector to spend Pascal credits. A connection spends credits (Studio renders, videos, and views rendered on Pascal’s servers) only after you turn on Can spend credits for it under Connected apps.

Create an API key

  1. Sign in and open Settings.
  2. In API keys, enter a name and choose the personal or organization workspace.
  3. Click Create and copy the key immediately. Pascal does not show it again.
  4. Open Connect an AI agent and choose your client for a copy-ready command.
Use a key created by the same Pascal user or organization that owns the projects you want the agent to edit. Agent self-registration creates a separate account, so its projects do not automatically appear in your current browser account.
Treat the API key like a password. Keep it out of source control, chat transcripts, screenshots, and shell history. Revoke a key from Settings when it is no longer needed.

Agent accounts and workspace invitations

Use your existing user/workspace key when an agent is helping with your projects. An autonomous agent can create its own private account through POST /api/auth/agent/register when the requested task authorizes it. Registration returns userId, a persistent agentId, an API key, and starterProjectId. Keep the key in the host’s secret store and reuse the identity across sessions. Agent accounts have no email address or browser login. The Pascal CLI (npm install --global @pascal-app/cli) includes these commands for hosts where the agent key is available as PASCAL_API_KEY:
The claim command requests a 15-minute code and opens a prefilled claim page. Use --no-open on a headless host or --json for structured output without opening a browser. A new request supersedes the previous code. Direct integrations can use POST /api/auth/agent/claim/start and GET /api/auth/agent/status instead. After the person completes the handoff, run pascal agent status --json or call GET /api/auth/agent/status with the same Bearer key. A successful response confirms that the key is active and reports only the agent ID, autonomous/delegated mode, claim state, and whether the key is organization-scoped. It does not disclose who claimed the agent or expose credential metadata. Claiming links identities; it does not transfer projects, grant either identity access to the other’s private work, or link local CLI projects. This is separate from the browser OAuth connection. Verify the intended recipient’s project access before returning a handoff. To join a workspace, obtain a single-use agent invite link from a workspace manager. Send the opaque token or the full invite URL in the body of POST /api/auth/agent/invites/redeem. An agent that already has an API key sends it with this request and keeps its existing identity. Without a key, redemption creates another agent account. Invite-link creation requires a human manager session; new agents cannot receive email-addressed invitations. The endpoint also accepts an existing Pascal browser session. Autonomous agent claims and local CLI authentication are separate from the hosted browser OAuth flow.

Exchange project files

Project files collect uploaded references and completed deliverables, including chat attachments, plugin documents, snapshots and Studio outputs. Threads and messages remain separate. The same files appear in Pascal’s Files panel and through MCP. Use get_project_assets to search or list files; follow nextCursor until null. get_project_file returns one file’s metadata and download URL. Files from the workspace library that a member linked to the project are listed and readable the same way; their downloads are private and short-lived, so request a fresh URL instead of storing one. Removing such a file from the project only removes its link. Pass projectId, or omit it after loading the project. File access requires project membership even when the scene is public, and an organization key can only reach its own workspace. Use upload_project_file with phase: "text" for a small CSV, Markdown or JSON result. For binary files, use phase: "prepare" with the filename, MIME type and byte size, PUT the bytes to the returned signed URL, then call phase: "complete" with the returned file ID and storage key. Completion is safe to retry with the same ID. Files appear only after completion. The limit is 500 MiB; SVG is not accepted. rename_project_file preserves identity and content links. delete_project_file removes the file from the catalog and from Studio where applicable; existing references may retain the bytes. It does not guarantee storage erasure. Existing asset and Studio storage URLs remain public, including files belonging to private projects; membership checks on the catalog do not make those URLs private. collect_matterport_evidence saves a public Matterport tour’s metadata, camera poses, panorama images and original geometry to a Matterport MODEL_ID folder, with a report of what is missing. Pass url (https://my.matterport.com/show/?m=…), then call again with the returned continuation until it is null; each call saves up to 128 files. It needs scene:write and doesn’t change the scene. Pascal shows no permission prompt on MCP, so ask the person before calling it: a tour can take about 10 minutes and add thousands of files. Read referenceFileId and reportFileId for what was saved; protected exports and files over 48 MiB are reported as gaps. collect_listing_evidence does the same for a Zillow, Redfin, Realtor.com or Trulia listing: its photos, floor plans and property facts, in a folder named after the property. Pass url, then call again with the returned continuation until it is null. It needs scene:write and the person’s remembered Always allow grant for Listing collection in this project, enabled from an Architect chat approval card; otherwise run the request in chat. Read briefFileId first. REST equivalents live under /api/projects/{id}/files; the OpenAPI document describes listing, metadata, content, upload preparation/completion, rename and removal. OAuth uses scene:read for reads and scene:write for mutations.

Connect your client

Replace paste_key_here with the key you just created.

Codex CLI

Register the server once, then start Codex from a terminal where PASCAL_API_KEY is set. Export the variable again in each new terminal, or supply it through your existing shell or secret-manager configuration. Codex stores the variable name, not its value. Remove commands containing the actual key from shell history.

Claude Code

Claude Code can sign in with your Pascal account instead of a key; see Connect Pascal to Claude. To use an API key:
This saves Pascal and its API key in Claude Code’s user configuration, so the connection is available when you start Claude in another project. To keep it local to the current project instead, replace --scope user with --scope local. The command contains the actual key after replacement; remove it from shell history after setup and keep Claude Code’s configuration private.
This command connects hosted Pascal projects. If Pascal agent skills 0.1.7 is installed, open /mcp and disable its local server, plugin:pascal-agent-skills:pascal, before adding this hosted connection. The plugin server reads local CLI projects; this server reads the account or organization that issued the API key.

VS Code and GitHub Copilot

Add Pascal to VS Code opens the install prompt in VS Code, where Copilot agent mode can then use the Pascal tools. VS Code asks for the API key the first time it starts the server and keeps it in its own secret storage, so the key is never written into the configuration file. To configure it by hand instead, add the server to .vscode/mcp.json for one workspace, or to your user configuration through MCP: Open User Configuration:

Cursor

The official Pascal plugin includes a local server and a hosted server. Enable the one for your project’s store. For a standalone hosted connection, use:
Follow Cursor’s browser sign-in prompt and approve the intended Pascal workspace. These scene permissions do not include paid service access.

Another mcp.json client

Add this server to .cursor/mcp.json or your client’s equivalent configuration:
Prefer an environment-variable or secret-store interpolation supported by your client instead of committing a literal key.

Install from the MCP Registry

Pascal is listed in the official MCP Registry as app.pascal/editor (Pascal 3D Editor). A client that installs servers from the registry finds it under that name. The listing’s version follows the @pascal-app/mcp npm release, 1.0.6 at the moment. It offers two ways to connect: The remote entry needs the same authentication as any other hosted connection. Browser sign-in works only for registered clients, so most clients installing from the registry need an API key sent as Authorization: Bearer <key>. The package entry needs no account or key. It runs only the MCP server, not the editor; to work on projects you also open in the local editor, use the Pascal CLI connector instead.

OpenClaw

Use OpenClaw’s current skill and integration documentation to configure a compatible MCP client or an explicit HTTP workflow. Skill installation alone does not connect a hosted server or authorize account creation. The portable Pascal skills and their required tools are maintained in the public editor repository.

Start an agent session

For incoming events and unattended workflows, use Project automations. Full-authority human-script keys can manage custom connections and automations and call start_project_run, get_project_run, cancel_project_run and answer_project_run. Setup secrets stay in Pascal’s UI or authenticated REST responses. OAuth scene grants and agent credentials cannot create broader persistent delegations. Ask the client to connect to Pascal and read the pascal://agent-guide resource first. That guide describes the expected project workflow, semantic construction tools, validation, saving, and final handoff. An example first request is:
Agents should return the editorUrl produced by Pascal tools rather than constructing a URL themselves. Open that URL to inspect the browser-visible draft.

Projects with live collaboration

An organization project that uses live collaboration accepts hosted MCP edits like any other project; they reach everyone with the project open. Two differences apply:
  • Saves go to the live draft. save_scene with saveMode: "checkpoint" is refused; save versions from the editor.
  • Snapshot undo and redo are refused. Use the editor’s history, or make a targeted edit that reverses the change.
A save is refused when someone else changed the project since the agent loaded it; reload with get_project_status, then edit again.

What MCP exposes

The server provides:
  • Tools for projects, rooms, walls, openings, levels, stairs, roofs, furniture (on the floor, or hung on a wall, a ceiling or another item), scene queries, measurements, validation, collision checks, saving, and version status. They are the same tools Pascal’s in-app chat uses.
  • A view of the scene (hosted server). view_scene returns a picture of the project from a view the agent chooses. Pass interior: { "zoneId": "zone_…" } to stand inside a room at eye height and look across it. Your open editor tab of the project renders the view for free, so keep it in front; a tab in the background answers with the editor link and the agent asks you to bring it forward. When no tab has the project open, Pascal renders the view in an editor on its own servers. Each view rendered there costs credits from the workspace that owns the project. The first one can take up to a minute to start: the tool waits for it, and only if it is still starting after about 45 seconds answers editor_starting for the agent to call again. Server views need an API key, a browser session, or an OAuth connection allowed to spend credits (Can spend credits under Connected apps). An agent account renders on Pascal’s servers only once it is claimed. To keep views free, turn off Render views on Pascal’s servers when no editor is open in the editor’s Settings → Preferences. Each answer carries a viewId naming that exact picture; pass it to generate_studio_media to render that view without taking it again. view_scene stays read-only.
  • Catalog pictures. view_assets returns pictures of up to six catalog items by id (from search_assets or furnish_room), with each item’s size and the surface names paint accepts as role. Use it to check what an item looks like before placing it.
  • Designed items. validate_design checks a procedural item recipe (schema: pascal://schema/design) without changing the scene, and reports diagnostics and measurements. place_design places one instance of a recipe that passes, on a level, wall or ceiling. Placement accepts version 1 recipes only for now.
  • A design brief (hosted server). design_brief records what the request asks for, axis by axis. It lasts for the MCP session. Until one is written, place_items, furnish_room, place_in_room, add_object and place_design refuse with design_brief_required.
  • Starting over. clear_scene empties a project on purpose, back to a site, a building and one level, when you ask the agent to start over. On the hosted server, any other write that would leave a project empty is refused, and the project stays as it was.
  • Resources for the agent guide, current scene, scene summary, constraints, and the item catalog (on the hosted server, the published library the editor places from).
  • Prompts for building from a brief, iterating from feedback, and renovations from photos when the client supports MCP sampling.
  • Hosted services for discovering an installed plugin’s service access, retrieving site context, generating project media and reopening saved results. These use the same contracts as Ask Pascal and curated plugin agents. See Hosted services for costs and required access.
The MCP server card lists the released contracts. A tool appearing in discovery does not grant permission to execute it. Pascal’s private workflows and experimental tools are not part of this public contract. Use semantic tools such as create_room, add_door, add_window, and furnish_room before reaching for raw scene patches. Finish with verify_scene, save_scene, and get_project_status. The hosted server always runs the newest tools. A local CLI or @pascal-app/mcp release can list an older set, so an agent should use the tools the connected server actually lists.

Common tool calls

Each example shows a tool’s arguments. Ids such as level_… come from earlier calls like list_levels or find_by_type.

Find and read nodes

find_by_type finds everything of one kind: node types (wall, door, stair, roof-segment, a plugin’s bones:studs), item categories, light, or typed parts inside objects (a porch’s columns). It also filters by level, parent, zone and importer source ids. Leave out type to find every node the filters match.
Results list each node’s id, name, kind, level and parent, up to 200 at a time. count is the full number of matches, and truncated says when there are more: narrow the call or raise limit. A level, parent or zone that doesn’t exist is refused, and so is a type that names nothing in the scene. get_node reads one node whole: its stored fields, values the scene resolves for it (a wall’s resolvedHeight and resolvedThickness, a door’s resolvedOpening, a level’s displayName), and its ancestorIds, parent first.
find_nodes and describe_node are retired. Calling them returns a tool_retired error naming the replacement (find_by_type and get_node).

Paint surfaces

Find a library material with search_materials, then apply it with paint. One search_materials call runs up to 12 searches or browses:
Each result’s ref (library:<id>) goes straight into paint:
paint covers walls, slabs, ceilings, roofs, stairs, blocks, cabinets, doors, windows, columns, fences, items and other built parts. role picks the surface: a wall’s exterior or interior face (or a and b), a roof’s top, edge, wall or fascia, a glazed roof’s glazing-frame, glazing-glass or glazing-solid, a stair’s treads, body or railing. Instead of material, pass color (#rrggbb, matched to the nearest library colour) or erase: true. If any target is missing, has no such role, or the material is unknown, the whole call is refused and nothing is painted.

Build stairs

create_stair builds straight, L and U stairs. (x, z) is the middle of the bottom riser, and rotation sets the climb direction (0 climbs toward +Z, 90 toward +X). An L-shaped stair turning left, with black cable railings:
lowerSteps sets how many risers the first flight gets. railingStyle takes balusters, post-and-rail, cable, boards, glass or metal. For porch or deck steps that don’t reach another level, pass toLevelId: null with a rise:
Steps like these cut no floor opening and create no level. The result includes every segment id, the whole footprint, and the point where the top step arrives.

Build barrel and glazed roofs

Barrel and glazed roofs need @pascal-app/cli or @pascal-app/mcp 1.0.5 or newer on a local server; the hosted server has them. create_roof with roofType: "barrel" builds an arched roof. Each segment’s depth is the arch’s span. barrelRise sets the arch height and can be at most half the span; barrelSegments sets how many flat bays approximate the curve (4 to 32, default 12):
roofSystem: "glazed" builds the roof as a framed glass roof, like a conservatory or skylight, instead of a covered one. It works with gable, shed (straight) and barrel roofs; any other shape is refused with unsupported_glazing. glazing optionally sets the frame, glass and grid:
glazing takes across and along grids (layout of count, maximum-spacing or fixed-spacing, with count or spacing), frameWidth, frameDepth, glassThickness, frameColor, glassColor, glassOpacity, panelType (glass, solid or empty) and glazedEnds. Paint a glazed roof’s parts with the glazing-frame, glazing-glass and glazing-solid roles:
Without a role, paint finishes a glazed segment’s frame and solid panels and leaves the glass alone. A barrel rise larger than half the span is refused with invalid_barrel_rise.

Set a gable’s overhang

Each roof segment can reach past its gable-end walls by its own distance, separate from the eaves. create_roof builds the roof. To change the gable ends of one segment, find its id with find_by_type ({ "type": "roof-segment" }), then set gableOverhang, in metres measured in plan:
That is an apply_patch call. When gableOverhang is absent, the gable ends reach as far as the eaves. It applies to gable, gambrel and shed segments. In the editor, the same value is the segment’s Gable overhang slider.

Read the site

get_site is a free read of the site stored in the project: the lot and its area, the buildable area inside the setbacks with each edge’s frontage and depth, the street side, north, whether the ground is sloped, flat or not read yet, and the typical house footprint range for the lot (30 to 45% of it). Pass building or site when the scene has more than one.
get_site only reads what the project already holds. To fetch parcel, zoning, flood and other sourced site data, use the paid pull_site_data and reopen the result with get_site_pull. See Hosted services.

Choose the level

The hosted server can’t see which floor you have open in the editor. A call that names no level acts on the lowest storey, so pass levelId (from list_levels) whenever the work is on another floor. The local servers that pascal mcp connect and the pascal-mcp command start work the same way. An application that embeds @pascal-app/mcp 1.0.5 or newer and shows the scene to its user can tell the tools which floor that person is viewing. Pass activeLevelId to createSceneOperations: a call that names no level then acts on that floor, as Pascal’s in-app chat does. list_levels reports it as activeLevelId. Leave the option out, or return null, and calls fall back to the lowest storey:
The shared tools, add_object, add_column and the scripted add_window and add_door read it. An explicit levelId always wins.

Set the ground floor and add a basement

A building’s levels stand on a ground line: the ground floor stands at grade and the levels under it are basements. list_levels answers groundLevels and, for each level, gradeStanding (at-grade, partly-below-grade or below-grade) and isGroundLevel. set_ground_level makes a level the ground floor (on a local server, it needs @pascal-app/cli or @pascal-app/mcp 1.0.5 or newer):
It moves the building in height only, so its floor sits on the foundation just over the ground, and renumbers the floors so this one is 0 and those under it -1, -2. A roof or support level is refused with not_a_storey. To add a basement, call add_level with position: "below": it goes under the lowest level and every floor keeps its place. verify_scene reports basement_at_grade when a basement is the level standing at grade; set_ground_level is the fix. On a basement level, a wall that add_wall or create_room builds against the ground, given no thickness, is a foundation wall for the site’s region: block in the United States and where the region is unknown, cast concrete in Europe.

Build objects in Blender

add_object, add_window, add_door and add_column accept language: "bpy" to build the geometry from a Blender Python module instead of a three.js one. See Pascal for Blender.

Convert a three.js design

author_scene turns a whole design your agent wrote in three.js into native, editable Pascal nodes in one call. Use it when the agent has designed a home freely and needs real walls, doors, windows, rooms and furniture rather than one imported mesh. For small edits to an existing house, use the semantic tools above. The agent reads its own module and sends a payload of levels. Each level holds walls (centerlines with their openings; a wall can curve through a point or be a glass curtain wall), rooms (a name and a seed point inside), slabs, voids (double-height openings in the floor), columns, stairs, items (each piece of furniture with its own three.js module, as for add_object) and lights. An optional roof covers the top level. Coordinates are metres, plan x/z, Y up. Load or create the project first:
Pascal runs the conversion on its servers against the project’s saved draft: it compiles each item, places everything, derives the rooms with their floors and ceilings, runs its checks and saves. The answer is a report: counts of what was written, ids mapping your ids to Pascal node ids, snapped wall ends, defaults it applied, warnings, and defects naming what it refused by your id. checks lists Pascal’s checks of the result (openings, glass, floors, pieces, outside, faces, stairs, levels and refused), each with passed and a detail saying what failed. complete is true when every check passes; green is true when there are no defects. Nothing is dropped silently. Fix what the checks name and call again. Instead of the payload, the agent can send its module (the three.js design) and an adapter, a program that reads the module and returns the payload. Pascal runs the adapter on its servers, with no network or file access; one that throws comes back with its error (adapter_failed) and nothing is written. Both are stored with the scene. To revise, call again with replace: true. It updates the previous conversion and keeps your manual edits. Rather than resending whole files, send edits, each one replacing text that occurs exactly once in the stored module or adapter:
Pascal applies the edits in order, reruns the adapter and stores the changed texts. A find that is missing or appears more than once is refused (edit_not_found, edit_ambiguous), and edits can’t be combined with a payload. With replace: true and nothing else, the stored conversion is written again. buildingId picks a building when there are several. Things to know:
  • Give every wall and item an id that is unique across all levels. A repeated id is refused with duplicate_source_id.
  • A window with no type is written as fixed and cannot open.
  • An item module allows at most 300k triangles and 32 materials.
  • Pascal builds wall caps, floors and ceilings itself. Express baseboards as a wall’s skirting, floor finishes as a room’s floor or floorCode, and wall finishes as faceLeft/faceRight or a room’s wallCode. Don’t model them as slabs or items.
  • A second conversion without replace: true is refused with conversion_exists.
  • A building that already holds work not made by author_scene is never cleared (existing_design). Edit it with the native tools, or convert into another building.
  • A stair in a level’s stairs climbs to the next level and cuts the floor above it. Never model a stair as an item.
  • The module and adapter can each be up to 400,000 characters, and an adapter has 60 seconds to run.
  • add_object can also describe an object in words (piece), which Pascal’s in-app chat uses. On the hosted MCP a piece is refused with pieces_unavailable, so send each item’s code.

Ask the Architect

You can hand a whole task to the Architect, Pascal’s building model, instead of making each edit yourself. Your agent sends a brief, the Architect works on the project in the background, and your agent checks back until the turn ends. The turn edits the project with the Architect’s own tools and saves what it changed as a version, as a turn in the editor’s chat does.
Connect with an API key to use these tools: create one in Settings and send Authorization: Bearer sk_live_.... An OAuth connection offers them only when its grant includes the architect:run scope, which Pascal allows only for the official Pascal Cursor connector; the OAuth setups on this page request scene scopes only. Without that scope the Architect tools are left out of the tool list, and a call is refused with insufficient_scope.
Ask your agent, for example:
The agent’s first call is ask_architect:
It answers at once with the turn’s id and status: "queued". Pass that id to get_architect_turn until the status is completed, incomplete, failed or cancelled:
A completed turn carries the Architect’s reply and the version it saved. To stop a turn, call cancel_architect_turn with the same id; only the person who started it can. ask_architect always runs the turn in the background, so the 13-minute limit for requests that follow their turn doesn’t apply at any effort, pro included. Each turn spends Pascal credits, as a chat message does. See Credits. Without max_credits a turn is not capped. When the turn reaches max_credits, it stops starting new work and ends incomplete with incomplete_details.reason: "max_credits". The work it finished is saved. Work already under way finishes, so a turn can end slightly above the cap. If a call times out and you aren’t sure the turn started, call ask_architect again with the same idempotency_key: you get back the turn it started instead of a second one. A turn reads the same as one started with the Pascal API: an id from either works with get_architect_turn and GET /v1/responses/{id}. To start and follow turns from a terminal instead, use pascal architect in the Pascal CLI 1.0.6 or newer.

Errors

A call that fails returns a tool error whose text is the API’s error, with the call’s request_id and the HTTP status the API would answer. Branch on error.code:
  • api_key_required: the connection’s credential can’t run the Architect. Reconnect with an API key.
  • no_project: pass project_id, or call load_scene first.
  • turn_not_found (404): no turn with this id that you can read, or a turn someone else started when you cancel it. project_not_found (404): no project with this id that your key can edit.
  • insufficient_quota (402) and upgrade_required (403), as on the API page.
  • turn_in_progress (409): another turn is already running on the project. Its id is in error.response_id.
  • idempotency_mismatch (409): you sent this idempotency_key with a different request. Use a new key for a new request.
  • invalid_input (400): an argument is malformed.
A turn that ends failed also comes back as a tool error: its text is the whole response body, with the turn’s error. Too many requests to the MCP endpoint answer HTTP 429 with a Retry-After header; wait that many seconds, then call again.

Check furniture dimensions

For a bounded first task, supply measured room dimensions, item dimensions, placement, and the clearances you want checked. Ask the agent to load the authorized project, confirm units, use the measurement and footprint collision tools, and return a report with the source revision, measured distances, conflicts, and missing evidence. A plan footprint does not prove height clearance, door swing, a delivery path, or exact mesh intersection. An undimensioned photo or incomplete scan may be insufficient for a fit decision. The export_glb MCP tool is not implemented; a JSON export or a preview must not be presented as a downloadable GLB. To get a project’s 3D file, publish it and download the GLB with an API key, as described in Pascal API.

Hosted MCP, local CLI, and the MCP package

These entry points share core scene tools and use different project stores. Hosted service tools are explicitly enabled by the host:

Local MCP with the Pascal CLI

Start Pascal normally. The editor and authenticated MCP service start together on collision-free loopback ports:
The MCP service is already running. The Pascal agent skills 0.1.7 Claude Code plugin already includes the stable stdio connector. Keep pascal on the PATH used to launch Claude Code and do not also run pascal mcp setup claude. If a previous manual setup created a user-scoped entry, remove it before reloading or restarting Claude Code:
Use /mcp to remove or disable project- or local-scoped duplicates so only plugin:pascal-agent-skills:pascal remains active. Local plugin use needs no account or API key. Codex still needs the local connector configured once:
If you use Claude Code without the plugin, configure the same connector manually with pascal mcp setup claude instead. Never keep the manual and plugin-provided Pascal servers active together. For a JSON-based client:
The setup command uses the client’s official CLI and never overwrites an existing Pascal entry. The connector discovers the running service and starts Pascal automatically when it is stopped. Use pascal mcp status, pascal mcp config, or pascal doctor to inspect the integration; the CLI reference lists every pascal mcp command. A typical existing-project workflow is list_scenes → load_scene → semantic editing tools → verify_scene → save_scene → get_project_status. The returned editorUrl opens the same local project. Use the standalone @pascal-app/mcp package directly only when embedding Pascal tools in another application or providing a custom scene store.

Serve a plugin’s agent tools

A plugin can ship its own agent tools as two extra exports: ./agent-tools, a PluginAgentTools object of tool contracts (@pascal-app/core/agent-tools), and ./agent-operations, one operation per tool that runs on the scene (AgentOperations, @pascal-app/core/agent-operations). A host running @pascal-app/mcp registers each runsIn: 'operation' tool with registerOperationTool, the same runner the built-in tools use:
Each call is validated against the contract, applied as one undo step, and answered with what changed or a coded refusal. The host chooses the annotations it advertises; a contract’s own annotations are hints only. Tools with runsIn: 'editor' need a live editor tab and aren’t served this way. The hosted MCP endpoint does not serve plugin tools.

Troubleshooting

  • Unauthorized — confirm the Bearer prefix, credential scope, and that the client sends the expected header. Reuse a valid existing key; replace it only when revoked or lost. Reconnecting does not require another agent account. A suspended account’s sessions, API keys and OAuth connections all answer 401 with “This account cannot be used right now. Contact support.”
  • The project is missing in the browser — confirm that the key belongs to the same user or organization you opened in Pascal. Self-registered agents own a separate workspace.
  • The browser looks stale or empty — ask the agent to call get_project_status, load the correct project, save a draft, and return the reported editorUrl.
  • A session expired or moved servers (HTTP 404 / MCP -32001; formerly HTTP 419) — Every connection (API key, OAuth or browser session) keeps its session in Pascal’s database, so any server answers it. A session lasts up to 24 hours, and ends sooner after 2 hours without a request. An expired, closed or revoked session still needs recovery. Create a fresh MCP client and transport once, then call get_project_status with the known project ID to load its persisted draft. Compare the version and graph hash before continuing. Do not replay an edit whose outcome is uncertain; check the saved scene first. If the replacement session also fails, stop reconnecting and use an authenticated Scene API read to confirm saved work. The error reports executedOnThisInstance: false for this HTTP attempt and lastMutationCommitState: "unknown" for earlier calls. Unbound edits and undo history cannot be recovered from a replacement session. The TypeScript MCP SDK 1.30 client surfaces this error without automatically reinitializing; a new transport must not reuse the old session ID.
  • Session limits — one person can hold 5 open sessions. A sixth connection closes one of your sessions that isn’t running a tool, preferring one with no project loaded, then the least recently used. If all 5 sessions are running a tool, the sixth connection is refused: initialize answers HTTP 429 with Retry-After: 5 and “All 5 Pascal connections are running a tool. Retry when one finishes.” A closed session’s next request answers 404; initialize again, without signing in again. A session that ended (closed, evicted or idle) always answers 404; only a call whose outcome is uncertain answers 409, so check the saved scene before repeating it. DELETE on a session that already ended answers 204. Send DELETE when you’re done to free the slot.
  • A repeated tool call ran twice — on durable sessions a JSON-RPC id is not an idempotency key. A tools/call re-sent under the same id replays its first answer only if it is the session’s latest request and finished less than 5 minutes ago; otherwise it runs again. To retry a mutation safely, send the same _meta["app.pascal/client-operation-id"].
  • “Another tool is running” (HTTP 409) — one tool runs at a time per session. ping and tools/list, prompts/list, resources/list and resources/templates/list answer while a tool runs; tools/call, resources/read and prompts/get wait their turn.
  • A session credential or authority changed (HTTP 403) — initialize a new session after switching API keys, browser sessions, workspaces, or agent authority. A session belongs to the exact credential that created it, even when two keys share an owner.
  • Photo tools fail — vision tools require an MCP client that supports sampling.
  • Service permission denied — check the credential, project, installed plugin and membership in Hosted services. On an OAuth connection, spending_not_allowed means the person hasn’t turned on Can spend credits for it under Connected apps.
For direct HTTP integrations, use the OpenAPI document. MCP clients should use the native Streamable HTTP endpoint instead of reimplementing MCP over OpenAPI.