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: AgentCAD

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
    A security-hardened MCP server that enables AI models to safely interact with Obsidian vaults through sandboxed file operations and todo tracking. It implements strict validation layers and resource limits to protect the local filesystem from potentially hostile tool calls.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables engineering agents to perform parametric CAD operations through a controlled MCP gateway built on FreeCAD, with transactions, diagnostics, and reproducible verification.
    2
    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