Skip to main content
Glama
paulinholt

eplan-mcp-bridge

by paulinholt

EPLAN MCP Bridge

Give an LLM real access to the EPLAN Electric P8 data model — list pages, read devices and parts, copy a circuit, rename tags, fix texts — in plain language, through MCP.

Versão em português abaixo.

"Add motor circuit 04 to panel 02, same typical as 03"

  → model_pages("=PLANT+PANEL-02")          picks a free page number
  → model_devices("=PLANT+PANEL-02/0031")   reads the template circuit
  → model_replicate_typical(...)            copies, renames tags, fixes texts
  → model_devices("=PLANT+PANEL-02/0032")   verifies the result

Why this exists

EPLAN's API surface splits in two, and only one half is easy to reach.

Actions are the command surface — everything the menus do (export a PDF, update reports, run a check). They're reachable from a script, and most EPLAN automation stops there.

The data model is the other half: pages, devices, placements, properties. This is what you need to answer "which devices are on this page?" or to copy a circuit and rename it. No action exposes it.

The obvious approach — a C# script using Eplan.EplApi.DataModeldoes not work on EPLAN 2022/2023. EPLAN's built-in script compiler does not reference that assembly, so a script that merely mentions Project fails to compile. The failure is silent and misleading: the caller just times out waiting for a result file that never appears.

This is not a licensing problem. The assemblies are loaded in the EPLAN process; the script compiler simply does not reference them.

The fix is a small DLL compiled outside EPLAN with the right references. A generated script does reflection at exactly one point — load the DLL, call Run(command, args) — and everything inside is statically typed.

LLM  ──MCP──▶  server.py  ──▶  reflection script  ──▶  EplanBridge.dll  ──▶  DataModel

The DLL is loaded from bytes (Assembly.Load(byte[])), so the file stays unlocked and can be rebuilt without closing EPLAN. Every data-model access inside the bridge is wrapped in a LockingStep; without one EPLAN throws NoLockingStepException.

Related MCP server: revit-mcp

Requirements

  • Windows, EPLAN Electric P8 installed and running with a project open

  • Python 3.10+

  • .NET Framework 4.x C# compiler (csc.exe, ships with Windows)

Install

git clone https://github.com/<you>/eplan-mcp-bridge
cd eplan-mcp-bridge
pip install -r requirements.txt
.\bridge\build.ps1          # compiles EplanBridge.dll against your EPLAN

build.ps1 picks the newest EPLAN under C:\Program Files\EPLAN\Platform. Point it elsewhere with -EplanBin "...\Platform\2022.0.3\Bin".

Register the server with your MCP client:

{
  "mcpServers": {
    "eplan": {
      "command": "python",
      "args": ["C:/path/to/eplan-mcp-bridge/server/server.py"]
    }
  }
}

Then, from the LLM: eplan_connect()eplan_model_status(). If the bridge is not built, model_status says so instead of failing obscurely.

Tools

All data-model tools are registered with an eplan_ prefix (eplan_model_pages, …).

Connectioneplan_connect, eplan_status, eplan_ping, eplan_servers, eplan_versions, eplan_disconnect

Readingmodel_status, model_info, model_pages, model_devices, model_texts, model_page_props, model_placements, model_dump_placement, model_dump_page, model_find_value, model_changed_pages, model_members

Writingmodel_copy_page, model_rename_pattern, model_rename_device, model_replace_in_props, model_replace_text, model_set_prop, model_set_structure, model_set_name, model_remove_page

Graphicsmodel_clone_window, model_remove_area, model_new_column, model_geometry

Whole flowsmodel_replicate_typical, model_add_feeder

model_run is an escape hatch to any bridge command.

Replicating a typical circuit

model_replicate_typical is the flow "make me another circuit like that one". It chains copy → rename tags → replace texts, in the order that works:

model_replicate_typical(
    source="=PLANT+PANEL-02/0031",
    new_number="0032",
    description="CONVEYOR 04 - MAIN MOTOR (M04)",
    old="M03", new="M04",
    also="MOTOR 03=>MOTOR 04")

Two details that are easy to get wrong, and are baked in:

  • The copy uses NumerationMode.None. Number renumbers everything including busbar points (-L1/-L2/-L3), which must keep their names to stay matched with their potential. Duplicate device tags are resolved by the rename step instead.

  • Text substitutions run longest-first (MOTOR 03 before M03), otherwise the short form consumes part of the long one and the replacement comes out half-applied. That is what also is for: the other spellings of the same change, as from=>to pairs separated by ;.

What it deliberately does not do: PLC addresses are copied from the source page. Whether the new circuit shares that address or needs its own is an engineering decision, not something to guess. The result reports the devices it produced so you can check.

Things learned the hard way

Encoded in the code, collected here because they cost real time:

Symptom

Cause

Timeout waiting for script results

A type the script compiler cannot reference. Test with a script that uses no data-model type: if it compiles, the reference is the problem — not a licence, not a hung EPLAN.

NoLockingStepException

Data-model access outside an action context needs a LockingStep.

A copied page is born as 0000

PAGE_COUNTER determines the page number. PAGE_NAME alone is ignored.

Writing a device name silently mangles it

Function.Name with a full identifier is misparsed when the location contains -. Use model_set_structure.

S063113 refusing a tag write

FUNC_DEVICETAG_FULLNAME is not writable. Write Name instead.

A property stores the literal ??_??@value;

That property is not multi-language (e.g. PLC address 20400). Write a plain string first, fall back to MultiLangString.

A text replacement comes out half-applied

Overlapping substrings replaced shortest-first.

Page description reads empty

It is property 11011. 11015 exists but is empty in many projects.

Safety

The write tools change a real project, and MCP has no undo. model_remove_page and model_remove_area are destructive. Work on a copy, or take an EPLAN backup, before letting an LLM write.

Tests

python -m pytest tests/ -q

Offline — call is stubbed, so no EPLAN is needed. They cover the step order of replicate_typical, the NumerationMode choice, longest-first replacement, failure handling, and that arguments containing quotes cannot escape the generated C# string literal.

License

MIT


EPLAN MCP Bridge — português

Dá a uma LLM acesso real ao modelo de dados do EPLAN Electric P8 — listar páginas, ler dispositivos e peças, copiar um circuito, renomear tags, corrigir textos — em linguagem natural, via MCP.

"Inclua o circuito do motor 04 no painel 02, mesmo típico do 03"

  → model_pages("=PLANTA+PAINEL-02")          escolhe um número livre
  → model_devices("=PLANTA+PAINEL-02/0031")   lê o circuito modelo
  → model_replicate_typical(...)              copia, renomeia tags e textos
  → model_devices("=PLANTA+PAINEL-02/0032")   confere o resultado

Por que existe

A API do EPLAN se divide em duas metades, e só uma é fácil de alcançar.

Ações são a superfície de comando — tudo que os menus fazem (exportar PDF, atualizar relatórios, rodar verificação). São acessíveis por script, e é aí que a maioria das automações do EPLAN para.

O modelo de dados é a outra metade: páginas, dispositivos, colocações, propriedades. É o que você precisa para responder "quais dispositivos estão nesta página?" ou para copiar um circuito e renomeá-lo. Nenhuma ação expõe isso.

O caminho óbvio — um script C# usando Eplan.EplApi.DataModelnão funciona no EPLAN 2022/2023. O compilador de scripts do EPLAN não referencia esse assembly, então um script que apenas cita Project falha ao compilar. A falha é silenciosa e enganosa: quem chamou só vê um timeout esperando um arquivo de resultado que nunca aparece.

Isto não é falta de licença. Os assemblies estão carregados no processo do EPLAN; o compilador de scripts é que não os referencia.

A solução é uma DLL pequena, compilada fora do EPLAN com as referências corretas. Um script gerado faz reflexão em um único ponto — carrega a DLL e chama Run(comando, args) — e tudo lá dentro é tipado.

LLM  ──MCP──▶  server.py  ──▶  script de reflexão  ──▶  EplanBridge.dll  ──▶  DataModel

A DLL é carregada por bytes (Assembly.Load(byte[])), então o arquivo não fica travado e pode ser recompilado sem fechar o EPLAN. Todo acesso ao modelo dentro da ponte é envolvido por LockingStep; sem ele o EPLAN lança NoLockingStepException.

Requisitos

  • Windows, EPLAN Electric P8 instalado e aberto com um projeto

  • Python 3.10+

  • Compilador C# do .NET Framework 4.x (csc.exe, já vem no Windows)

Instalação

git clone https://github.com/<voce>/eplan-mcp-bridge
cd eplan-mcp-bridge
pip install -r requirements.txt
.\bridge\build.ps1          # compila a EplanBridge.dll contra o seu EPLAN

O build.ps1 pega o EPLAN mais novo em C:\Program Files\EPLAN\Platform. Para apontar outro, use -EplanBin "...\Platform\2022.0.3\Bin".

Registre o servidor no seu cliente MCP (JSON igual ao da seção em inglês) e, pela LLM: eplan_connect()eplan_model_status(). Se a ponte não estiver compilada, o model_status diz isso em vez de falhar de forma obscura.

Replicando um típico

model_replicate_typical(
    source="=PLANTA+PAINEL-02/0031",
    new_number="0032",
    description="TRANSPORTADOR 04 - MOTOR PRINCIPAL (M04)",
    old="M03", new="M04",
    also="MOTOR 03=>MOTOR 04")

Duas armadilhas já embutidas:

  • A cópia usa NumerationMode.None. O modo Number renumeraria tudo, inclusive os pontos de barramento (-L1/-L2/-L3), que precisam manter o nome para casar com o potencial. Os tags duplicados se resolvem no rename.

  • As substituições de texto vão da mais longa para a mais curta (MOTOR 03 antes de M03), senão a forma curta consome parte da longa e a troca sai pela metade. É para isso que serve o also.

O que ela não faz: endereços de CLP vêm copiados da página de origem. Se o circuito novo compartilha o endereço ou precisa do próprio é decisão de engenharia — o resultado lista os dispositivos criados para você conferir.

Segurança

As ferramentas de escrita alteram um projeto real, e o MCP não tem desfazer. model_remove_page e model_remove_area são destrutivas. Trabalhe numa cópia, ou faça backup pelo EPLAN, antes de deixar uma LLM escrever.

Licença

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    F
    maintenance
    Enables AI to interact with Revit via MCP, allowing data retrieval and element creation, modification, and deletion.
    13
    65 npm
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to read and modify Mendix application models through MCP tools for creating modules, entities, pages, microflows, deploying, and querying runtime data.
    1
    -
  • A
    license
    B
    quality
    B
    maintenance
    Enables LLM agents to create circuit schematics and diagrams in Microsoft Visio through MCP tools for managing documents, pages, stencils, shapes, wires, and exports, with measured pin geometry for accurate component connections.
    23
    1
    MIT