Skip to main content
Glama

WattLab Controlled Fritzing MCP

A strictly controlled local MCP server that lets an AI agent perform narrow, validated Fritzing engineering operations — search parts, inspect connectors, place, wire, validate, render, save — while the AI gets no shell, no arbitrary filesystem access, no generic process execution, no direct Fritzing control. The MCP server is the security boundary; the AI is not trusted.

What this is / is not

  • Is: a Windows MCP server (Python 3.11+, mcp 2.x) over a standard Fritzing install.

  • Is not: a general-purpose AI-computer-control tool; a formal electrical simulator; a nice way to bypass the user’s Fritzing library.

Related MCP server: ps3d

Architecture

AI AGENT
   │ MCP (stdio, tool calls only)
   ▼
server/mcp/tools.py     # narrow tools: search / inspect / create / place / move / wire / validate / render / visual_report / save
   │
   ▼
server/policy.py        # trust levels, lifecycle state machine, save policy
   ▼
server/fritzing/        # parts.db integration, .fz/.fzz generation, validation, rendering
   ▼
artifact manager        # projects/active|completed|rejected/<WTL-FZ-...>/

Everything the AI can touch is a JSON-manifest-authoritative project under C:\Users\...\fritzing_mcp\projects. There is no download/HTTP tool, no file-path tool, no shell tool.

Project lifecycle (enforced)

CREATED → DISCOVERED → PLACED → WIRED → VALIDATED → RENDERED → REVIEWED → READY_TO_SAVE → SAVED
  • fritzing_render requires a validated, non-stale project (dirty == false, status != FAIL).

  • Every structural mutation invalidates validation and reverts state (WIRED/PLACED), forces re-validation.

  • fritzing_save_project requires fresh validation; PASS saves as verified, PASS_WITH_WARNINGS saves only if policy allows warnings, FAIL saves only to the rejected store, and stale/never-validated projects are denied.

Part trust model

OFFICIAL / VERIFIED  -> placeable
COMMUNITY            -> requires policy enablement
GENERATED            -> requires validation
UNKNOWN / REJECTED   -> denied

A client cannot bypass trust by supplying an arbitrary part ID; unknown IDs and connector lookups fail hard.

Project manifest

{
  "project_id": "WTL-FZ-2026-0001",
  "state": "…",
  "parts": [{ "instance_id": "inst_0001", "part_id": "…", "x": 0, "y": 0, "rotation": 0, "view": "breadboard" }],
  "connections": [{ "connection_id": "wire_0001", "from_instance": "…", "from_connector": "…", "to_instance": "…", "to_connector": "…" }],
  "validation": { "status": "PASS | PASS_WITH_WARNINGS | FAIL", "errors": [...], "warnings": [...], "needs_human_review": [...] },
  "artifacts": { "fz": "…/circuit.fz", "fzz": "…/circuit.fzz", "render": { "engine": "…", "svgs": [...] } }
}
  • .fz and .fzz are regenerated from the manifest at save time.

  • Audit log: projects/<id>/audit.jsonl with timestamp, request_id, transaction_id, tool, project, actor, parameters (secrets scrubbed), result.

Security

Capability

Allowed?

run_shell, exec_python, read_file, write_file, http_request

No — no such tools exist

Search / inspect / place / wire / validate / render / save

Yes, narrowly

Relative paths, .., UNC, \\?\, \\.\, absolute paths outside controlled root

Rejected at PATH_NOT_ALLOWED

Path traversal inside .fzz extraction

Rejected; zip bounded (max_files, max_total_bytes, max_member_bytes)

Project-name shell injection / reserved names

Rejected

Overwriting other projects

Blocked

Trust is enforced server-side; the AI cannot escalate with prompt text.

Rendering

Two engines, always truthful:

{ "engine": "fritzing-native" }

or

{ "engine": "builtin-engineering-preview", "precision": "approximate" }
  • fritzing-native: runs the real Fritzing.exe -svg headless against an isolated profile with a dialog-dismissal watchdog.

  • builtin-engineering-preview: draws component SVGs at manifest positions, plus connector markers, labeled endpoints, and explicit wire polylines for every connection. This is an engineering preview, not an authoritative Fritzing render — it is labeled approximate.

If the native export is blank/missing the engine falls back to the preview; the mcp never silently calls a fallback render fritzing-native.

FZZ portability

circuit.fzz is a zip containing circuit.fz, referencing parts by the module IDs from the stock fritzing-parts installation. The artifact:

  • is structurally validated (must parse as XML zip),

  • contains no absolute paths,

  • opens in the installed Fritzing (verified on 1.0.8.0).

For portability beyond the current install, the receiving Fritzing must have the same fritzing-parts-family access (core/contributed modules). The manifest and render artifacts are versioned alongside it.

Validation behavior

fritzing_validate_project produces structured diagnostics and a status:

Checks

Type

manifest schema, duplicate parts/wires

structural

5V↔3V3 rails, rail⇄ground, missing VCC/GND, orphaned part, possible driven-output short

electrical heuristic

duplicate module ID, unknown connector reference

structural

These heuristics are surfaced as ERROR/WARNING/NEEDS_HUMAN_REVIEW and are the basis for saving. They are not a substitute for SPICE/electrical review.

Configuration

  • policy/policy.json — feature flags: filesystem, shell (always off), custom_parts (off by default), community_parts, overwrite, network, save.require_valid_validation, save.allow_warnings, zip limits.

  • Environment overrides: FRITZING_DIR, FRITZING_EXE, FRITZING_PARTS_DIR, FRITZING_DOCUMENTS_DIR.

Running

python -m server.main doctor          # environment diagnostic
python -m server.main serve           # start the MCP server (stdio)
pytest

Open an MCP client (JSON-RPC over stdio). Point it at:

{
  "mcpServers": {
    "fritzing": {
      "command": "python",
      "args": ["-m", "server.main", "serve"],
      "cwd": "C:\\Users\\Stealthy\\Desktop\\MCP\\fritzing_mcp"
    }
  }
}

Tools

Tool

Purpose

fritzing_status

environment + version + policy summary

fritzing_search_parts

indexed search (max 50)

fritzing_get_part

full metadata, trust, views, connectors

fritzing_get_part_connectors

normalized connector table

fritzing_create_project

new WTL-FZ-YYYY-NNNN project

fritzing_get_project

manifest view

fritzing_place_part

add instance (trust/rotation/coordinate validated)

fritzing_move_part

move existing instance

fritzing_wire

add a connection between validated connector IDs (no duplicates)

fritzing_validate_project

run validation pipeline → status

fritzing_render

gated render (native → fallback)

fritzing_visual_report

inspect render artifacts

fritzing_save_project

lifecycle-gated save; forced path (never accepts arbitrary output path)

fritzing_create_part

gated OFF (NOT_IMPLEMENTED) unless custom parts enabled

fritzing_validate_part

custom-part validation hook

Rules for agents

See knowledge/AGENT_CONTRACT.md. Summary: search before wiring, don't invent IDs, validate before render/save, never request shell/filesystem access, treat NEEDS_HUMAN_REVIEW seriously, and never claim electrical correctness beyond what the validator reports.

MCP resources

  • fritzing://rules

  • fritzing://tutorial/create-schematic

  • fritzing://tutorial/validation

  • fritzing://parts/policy

  • fritzing://project-schema

  • fritzing://tool-guide

  • fritzing://troubleshooting

  • fritzing://knowledge/{workflow,parts,schematic,validation,rules,troubleshooting}

MCP prompts

  • fritzing_create_schematic

  • fritzing_debug_schematic

  • fritzing_validate_schematic

  • fritzing_create_custom_part

Known limitations

  1. Native headless render is unreliable on this machine — the isolated profile's installer parts-db lookup does not resolve (Application folder fritzing-parts not found), so native export yields blank canvases on some runs. The fallback engineering preview is deterministic but approximate.

  2. FZZ dependencies — the artifact references stock fritzing-parts module IDs; move it between identical Fritzing installs only.

  3. Heuristic electrical checks are advisory, not proof.

  4. No PNG export — native SVG export only; no Windows multi-format conversion hook yet.

  5. User parts (Documents\Fritzing\parts) currently contain duplicates/__MACOSX files that cause modal Fritzing dialogs — admins should clean that directory; the server ignores arbitrary user-paths, so it is not affected functionally.

Troubleshooting

Symptom

Fix

PART_NOT_FOUND

confirm part id via fritzing_search_parts; IDs are case-sensitive

CONNECTOR_NOT_FOUND

call fritzing_get_part_connectors

PROJECT_NOT_VALIDATED on render

run fritzing_validate_project first; check dirty state

SAVE_DENIED

decode stale/dirty/status and re-validate

RENDER_FAILED/engine = builtin-engineering-preview

native export unavailable; check Fritzing install / profile permissions

Fritzing dialogs blocking

close orphaned Fritzing processes; clean Documents\Fritzing\parts duplicates

Development / testing

python -m pytest tests           # unit + integration + security
python -m pytest tests\integration\test_render.py   # renderer (slow, touches Fritzing.exe)
python -m server.main doctor

Tests are deterministic and do not depend on the polluted user-parts directory.

License

GPL-2.0-or-later, matching the Fritzing project.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables engineering agents to perform parametric CAD operations through a controlled MCP gateway built on FreeCAD, with transactions, diagnostics, and reproducible verification.
    4
    GNU Lesser General Public v2.1 only
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI hosts to interact with a browser CAD workbench through model-neutral local stdio or authenticated remote MCP tools, supporting command discovery, design-health analysis, and scoped previews while never reading local files or taking over open sessions.
    MIT
  • A
    license
    B
    quality
    C
    maintenance
    Enables AI agents to search a 2663-part library, place and wire components, validate and headless-render .fzz sketch bundles, generate custom .fzp parts with view SVGs, and hand sketches off to the Fritzing GUI for human review.
    14
    3
    MIT