Automation (API and MCP)
LinceCAD can be driven by other programs on the same computer: Python scripts, other programs and AI assistants (Claude, for example) through MCP (Model Context Protocol). They can open and save drawings, query and create entities, change layers, run commands, evaluate AutoLISP, plot to PDF and see the drawing as an image. Everything goes through local channels: nothing leaves the computer.
Enabling it
Automation is off by default. Turn it on in OPTIONS, Automation tab:
| Setting | What it does |
|---|---|
| Allow automation (API/MCP) | Opens the local API channel. Without it, no program can connect to the window |
| Read-only (they can read, not change) | Programs can read the drawing but not change it, save it or run commands |
| Confirm the changes of AI assistants (AI Actions palette) | Whatever an AI assistant wants to change waits in the AIACTIONS palette until you accept it |
| Allowed folders | Drawings are only opened, saved and plotted in those folders (empty: anywhere) |
| MCP server over HTTP on 127.0.0.1, port | MCP server over HTTP, on 127.0.0.1 only, to connect an assistant to the running LinceCAD |
The settings are saved at once in api.toml, in the user configuration folder (%APPDATA%\lince on Windows, ~/.config/lince on Linux), together with the token: the password programs present when they connect. Only your user can read it. Generate a new token changes it (programs holding the old one can no longer get in).
Control over what the AI does
- One undo step per call: everything a call changes is undone with a single UNDO.
- AI Actions (AIACTIONS): with confirmation on, each change requested by an assistant shows up with what it wants to do; Accept runs it and Reject denies it. Accept all in this session stops asking until LinceCAD is closed. Below is the log of every call.
- If you are in the middle of a command, changes wait: the API answers "busy".
- An internal error during a call is undone entirely and LinceCAD keeps running.
Without a window
lince --servidorserves the API with no visible window (for batch processes and servers).--canal NAMEchanges the channel name.lince --mcpis an MCP server over standard input and output, for assistants that start it themselves.
Both are the same LinceCAD with its window off-screen: same commands and same view (for captures). They open no dialogs and ask nothing; they honour the read-only mode and allowed folders of api.toml. On Linux they need a graphical session (or xvfb-run).
Connecting an AI assistant (MCP)
Claude Desktop: in %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"lince": { "command": "C:\\Program Files\\lince\\lince.exe", "args": ["--mcp"] }
}
}Claude Code (no window, in a project): claude mcp add --scope project lince -- "C:\Program Files\lince\lince.exe" --mcp
Claude Code with LinceCAD open (enable MCP server over HTTP on 127.0.0.1, port; the token is in api.toml): claude mcp add --transport http lince http://127.0.0.1:7341/mcp --header "Authorization: Bearer <token>"
The assistant sees the tools (open, query, create, dimension, insert blocks, plot to PDF, capture the view, undo…), the resources (summary, entities, layers and blocks of each open drawing, and these help pages as documentation) and three prompts: review the drawing, dimension a floor plan and clean the layers.
Python
There are two Python packages (Python 3.9 or newer):
lince(client): drives LinceCAD through the API.pip install lince. No dependencies.
import lince
with lince.iniciar() as s: # starts "lince --servidor" with no window
dib = s.nuevo()
dib.crear_capa("MUROS", color=1)
with dib.transaccion(): # a single undo step
dib.linea([0, 0], [100, 0], layer="MUROS")
dib.circulo([50, 50], 20)
dib.trazar_pdf("plan.pdf")
dib.guardar_como("plan.dwg")For a running instance (with automation enabled): s = lince.conectar(); dib = s.dibujo.
lince_nucleo(PyO3 wheel): read, modify, save and query DWG/DXF without opening LinceCAD (batch, servers, Jupyter).pip install lince-nucleo.
import lince_nucleo as ln
dib = ln.abrir("plan.dwg")
for e in dib.consultar(tipo="CIRCLE"):
print(e["handle"], e["radius"])
dib.guardar("out.dwg", "2018")Entities use the same typed format of §5.1. Examples in python/ejemplos of the source.
Your own programs (JSON-RPC)
Programs connect through the pipe \\.\pipe\lince-<user> (Windows) or the socket $XDG_RUNTIME_DIR/lince.sock (Linux) and send one JSON-RPC 2.0 message per line. The first one is session.hello with the token:
{"jsonrpc":"2.0","id":1,"method":"session.hello","params":{"token":"<token>"}}
{"jsonrpc":"2.0","id":2,"method":"entity.create","params":{"entity":{"type":"LINE","start":[0,0],"end":[100,0]}}}
{"jsonrpc":"2.0","id":3,"method":"document.saveAs","params":{"path":"C:\\drawings\\test.dwg"}}There are methods for drawings (document.*), commands (command.run), AutoLISP (lisp.eval), entities (entity.query/get/create/set/delete, as objects or as entget DXF lists), layers, blocks, styles, variables, selection, undo, plotting, view capture and events. The full specification is in docs/api.md of the source code.