mech.app

The mech.app newsletter

Agentic AI, minus the noise.

Get practical field notes on AI agents, automation, developer tools and security delivered to your inbox.

No spam. Unsubscribe anytime.

Dev Tools

Pascal Editor's MCP Architecture: How a 3D CAD Tool Exposes Agent-Safe Geometry Operations

How Pascal Editor implements MCP to expose 3D CAD operations to agents while maintaining data integrity and managing persistent local state in SQLite.

Source: github.com
Pascal Editor's MCP Architecture: How a 3D CAD Tool Exposes Agent-Safe Geometry Operations

Pascal Editor is a local-first 3D CAD tool built with React Three Fiber and WebGPU. It runs in the browser or as a CLI-managed service and exposes parametric geometry operations to agents through the Model Context Protocol (MCP). The project (23K+ stars, trending #2 on GitHub for TypeScript) demonstrates how to bridge visual domain tools and agent workflows without corrupting scene state.

The architecture reveals practical patterns for exposing complex stateful operations to agents: authenticated background services, collision-free port selection, read-only safety boundaries, and persistent SQLite storage for project data.

Why This Matters

Most MCP implementations wrap simple CRUD operations or file systems. Pascal Editor exposes parametric 3D modeling primitives (extrusions, boolean operations, constraints) where naive agent access could corrupt the scene graph or violate geometric invariants. The CLI manages an authenticated MCP server in the background, handles agent connection handshakes, and enforces read-only boundaries for operations like furniture candidate checks.

The project shows how to handle the impedance mismatch between agent text commands and stateful visual operations. Agents can query geometry, propose changes, and check constraints without directly mutating the 3D scene.

Installation and Process Management

The CLI creates a persistent local installation without requiring a repository clone:

npx @pascal-app/cli editor

This command:

  1. Installs the editor and MCP service in ~/.pascal/
  2. Creates a SQLite database at ~/.pascal/data/pascal.db for project storage
  3. Starts the editor UI and an authenticated MCP server in the background
  4. Selects collision-free loopback ports for both services
  5. Writes connection credentials to a local config file

Agents connect using:

pascal mcp connect

The CLI handles process lifecycle, port conflicts, and credential rotation. The MCP server runs as a long-lived background process, not a per-request spawn. This avoids startup latency and keeps the 3D scene graph in memory.

MCP Service Architecture

Pascal’s MCP server exposes geometry operations through a structured tool interface. The server runs authenticated to prevent unauthorized scene mutations. Connection flow:

  1. CLI generates a session token and writes it to ~/.pascal/mcp-credentials.json
  2. Agent reads the token and connects to the loopback port
  3. MCP server validates the token before accepting tool calls
  4. Server maintains a read/write boundary: most agent operations are read-only queries

The authenticated model prevents agents from accidentally corrupting the scene graph. Write operations require explicit user confirmation through the UI.

Read-Only Safety Boundaries

The verified preview (commit 5dabbc3b) adds read-only furniture candidate checks. This pattern shows how to expose domain expertise to agents without granting mutation access:

  • Agent queries the scene for furniture placement candidates
  • MCP server runs collision detection and constraint checks
  • Server returns valid placement zones as structured data
  • Agent proposes placements, but cannot directly insert geometry
  • User confirms or rejects proposals in the UI

This read-only pattern works for any domain where agents need to reason about complex state but should not mutate it directly. The MCP server acts as a query engine, not a command executor.

Hosted Agent Claim and Status Commands

The preview also adds hosted agent claim and status commands. These tools let agents:

  • Claim ownership of a design task (prevents concurrent agent conflicts)
  • Report progress and status updates
  • Release claims when tasks complete or fail

The claim mechanism uses optimistic locking in SQLite. If two agents try to claim the same task, one gets a conflict error and must retry or abort. This prevents race conditions without requiring distributed locks.

State Management and Persistence

Pascal stores project data in SQLite at ~/.pascal/data/pascal.db. The schema includes:

  • 3D geometry (meshes, curves, constraints)
  • Parametric operation history (extrusions, booleans, transforms)
  • Agent task claims and status
  • User preferences and session state

The MCP server queries this database directly. Agents see a consistent view of the scene graph without needing to parse 3D file formats. The database also acts as an event log: the operation history can be replayed to reconstruct the scene or generate diffs.

Collision Detection and Constraint Checking

Furniture candidate checks run collision detection against the existing scene. The MCP server uses the same geometry engine as the UI, so agents get accurate spatial queries. The flow:

  1. Agent requests furniture candidates for a room
  2. MCP server loads the room geometry from SQLite
  3. Server runs a spatial query to find open floor areas
  4. Server checks each candidate against constraints (clearances, accessibility, structural elements)
  5. Server returns a ranked list of valid placements

This pattern generalizes to any domain with spatial or logical constraints. The MCP server encapsulates domain logic (collision detection, constraint solving) and exposes it as structured queries.

Port Selection and Conflict Avoidance

The CLI selects collision-free loopback ports for the editor UI and MCP server. The algorithm:

  1. Try default ports (3000 for UI, 3001 for MCP)
  2. If a port is in use, increment and retry
  3. Write selected ports to ~/.pascal/ports.json
  4. Agents read the port file to discover the MCP endpoint

This avoids hardcoded ports and handles multiple Pascal instances on the same machine. The port file also includes the session token, so agents get both the endpoint and credentials in one read.

Failure Modes and Recovery

Common failure modes and how Pascal handles them:

FailureDetectionRecovery
MCP server crashCLI polls process statusRestart server, rotate token, notify connected agents
SQLite lock timeoutQuery returns error after 5sAgent retries with exponential backoff
Corrupted scene graphGeometry validation on loadRollback to last valid operation in history
Agent connection lossHeartbeat timeout (30s)Release task claims, log partial progress
Port conflict on startupBind fails with EADDRINUSEIncrement port, retry up to 10 times

The operation history in SQLite acts as a write-ahead log. If the scene graph becomes corrupted, Pascal can replay operations from the last known-good state.

Deployment Shape

Pascal runs entirely on the local machine. No cloud dependencies. The deployment shape:

  • Editor UI: Next.js app running on a loopback port
  • MCP server: Node.js process running on a separate loopback port
  • SQLite database: Single file at ~/.pascal/data/pascal.db
  • Agent connection: Local IPC through MCP over HTTP

This local-first architecture avoids network latency and keeps sensitive design data off external servers. Agents run on the same machine and connect through localhost.

For teams, Pascal can run on a shared workstation with remote desktop access. The MCP server accepts connections only from localhost, so agents must run on the same machine or tunnel through SSH.

Observability and Debugging

The CLI writes logs to ~/.pascal/logs/. Key log streams:

  • mcp-server.log: Tool calls, authentication events, query performance
  • editor.log: UI events, scene graph mutations, user actions
  • agent-tasks.log: Task claims, status updates, completion events

Agents can query the MCP server for task status and progress. The server exposes a get_task_status tool that returns structured data from the SQLite database.

For debugging, the CLI includes a pascal mcp logs command that tails the MCP server log in real time. This shows tool calls and responses as they happen.

Code Example: MCP Tool Definition

Here’s how Pascal defines a read-only furniture candidate tool:

// packages/mcp-server/src/tools/furniture-candidates.ts
import { Tool } from '@modelcontextprotocol/sdk/types.js';
import { db } from '../db.js';
import { checkCollisions } from '../geometry/collision.js';

export const furnitureCandidatesTool: Tool = {
  name: 'get_furniture_candidates',
  description: 'Find valid furniture placement zones in a room',
  inputSchema: {
    type: 'object',
    properties: {
      roomId: { type: 'string' },
      furnitureType: { type: 'string', enum: ['desk', 'chair', 'shelf'] },
      minClearance: { type: 'number', default: 0.6 }
    },
    required: ['roomId', 'furnitureType']
  }
};

export async function handleFurnitureCandidates(args: any) {
  const room = await db.getRoom(args.roomId);
  const candidates = await db.getFloorAreas(room);
  
  const valid = candidates.filter(candidate => {
    const collisions = checkCollisions(candidate, room.geometry);
    const clearance = candidate.minDistanceToWalls();
    return collisions.length === 0 && clearance >= args.minClearance;
  });
  
  return {
    content: [{
      type: 'text',
      text: JSON.stringify(valid.map(c => ({
        position: c.center,
        rotation: c.suggestedRotation,
        score: c.accessibilityScore
      })))
    }]
  };
}

The tool queries SQLite for room geometry, runs collision detection, and returns structured placement data. The agent cannot mutate the scene, only query it.

Technical Verdict

Use Pascal’s MCP architecture when:

  • You need to expose complex domain operations (CAD, simulation, constraint solving) to agents
  • You want read-only safety boundaries to prevent agent-induced corruption
  • You need persistent local state with operation history for rollback
  • You can run agents on the same machine as the domain tool (local-first)

Avoid this pattern when:

  • Agents need low-latency access from remote machines (localhost-only MCP server)
  • Your domain operations are stateless or idempotent (simpler to expose as HTTP APIs)
  • You need multi-user concurrent access (SQLite has limited write concurrency)
  • You cannot run a long-lived background process (serverless environments)

Pascal’s authenticated MCP server with read-only boundaries and SQLite persistence is a strong pattern for exposing stateful domain tools to agents. The collision-free port selection and process management make it practical for local development. The operation history provides rollback and audit trails. The main limitation is the localhost-only deployment shape, which requires agents to run on the same machine or tunnel through SSH.