This repository now targets one clear goal: run a stable MCP server for EPLAN 2026 Update 3 on Windows, using EPLAN Remoting as the transport layer, with a tool surface that is safe for OpenClaw and other LLM clients.
The server does not expose arbitrary action execution. Every supported action is explicitly registered, version-scoped, and validated before execution.
- Stable target: EPLAN 2026 Update 3
- Transport: EPLAN Remoting / gRPC
- Runtime assumption: EPLAN is already running and Allow local access is enabled
The first stage exposes only the following MCP tools:
connect_to_eplandisconnect_from_eplanreconnect_to_eplanget_connection_statusping_eplanopen_projectget_current_project_infosearch_objectsopen_pageget_selectionrun_checkrun_reportsrun_renumberexport_projectexport_to_graphicsprint_projectget_project_propertyset_project_propertyget_page_propertyset_page_propertyexecute_script
These tools only use documented official actions that are registered in mcp_server/remoting/action_registry.py.
In addition to the stable action-backed tools, the server now exposes experimental typed DataModel tools:
create_pageCreates a new page through the official.NETDataModel adapter. This path does not rely on undocumented action names, but it is still experimental and should be validated on a project copy before production use.insert_symbolInserts one symbol variant into an existing EPLAN page through the official.NETDataModel adapter. The implementation uses a locking step plus transaction commit so the placement persists after the project is closed and reopened, but it should still be validated on a project copy before production use.create_deviceCreates one logical device-backed function on an existing EPLAN page through the official.NETDataModel adapter. The current implementation requires an explicit logical symbol variant, explicit device tag, and explicit coordinates.create_connectionCreates one logical connection between two existing placed functions through the official.NETDataModel adapter. The current implementation creates the connection object in project data only; it does not place a graphical connection definition point.
Typed graphical placement of ConnectionDefinitionPoint is still blocked. The repository now
contains an explicit future interface and blocker instead of a fake implementation. Official
EPLAN 2026 Update 3 paths were investigated, but they did not yet yield a stable update of
Connection.ConnectionDefPoints. See docs/graphical_cdp_findings.md.
When a stable tool accepts an explicit project_name, the server now prefers the official ProjectAction wrapper internally so the action can be bound to the requested project path instead of depending on whichever project is currently active in the GUI.
Context-sensitive tools such as get_current_project_info, get_selection, get_project_property, set_project_property, get_page_property, and set_page_property still operate on the active or selected GUI context.
The following capabilities are intentionally excluded from the stable surface:
- automatic complex drawing
- raw arbitrary action passthrough
- any workflow relying on undocumented or unstable actions such as
XPrjActionPageNew
These remain future work and require a typed DataModel adapter. See mcp_server/services/datamodel/placeholders.py.
Graphical ConnectionDefinitionPoint placement is a special case: it has already been
investigated through public .NET DataModel and HEServices APIs, but it remains blocked
until a stable logical-binding path is verified. See mcp_server/services/datamodel/graphical_placeholders.py
and docs/graphical_cdp_findings.md.
The new server is split into clear layers:
mcp_server/remotingResponsibilities: CLR loading, EPLAN discovery, connect/disconnect/reconnect/ping, remoting calling context handling, whitelisted action execution.mcp_server/servicesResponsibilities: stable business capabilities such as connection, project, navigation, property, report, export, script, and health services.mcp_server/toolsResponsibilities: MCP tool definitions only. No business logic and no direct action string construction.mcp_server/coreResponsibilities: error types, response formatting, shared models, validators.
The old implementation under Eplan_2026_RAG_mcp/mcp_server is now legacy reference material, not the primary runtime entry point.
- Windows host
- Python 3.10+
- EPLAN 2026 Update 3 installed
pythonnetmcp- EPLAN already running with remoting enabled
Install dependencies:
pip install -r requirements.txtConfiguration is loaded in this order:
- built-in defaults
eplan_mcp.config.json- environment variable overrides
Current default connection target:
- host:
192.168.101.50 - port:
49152(fallback only)
When auto_detect_server is true, the server will prefer the actual listening remoting port discovered from the running EPLAN process. In a real EPLAN 2026 Update 3 session this may differ from the placeholder value in the config file, for example 49153 instead of 49152.
Example config file:
{
"host": "192.168.101.50",
"port": 49152,
"target_version": "2026 Update 3",
"log_level": "INFO",
"timeout_seconds": 10,
"auto_detect_server": true,
"allow_unsafe_actions": false,
"file_logging_enabled": false,
"log_file_path": "logs/eplan_mcp_server.log"
}Supported environment overrides:
EPLAN_MCP_HOSTEPLAN_MCP_PORTEPLAN_MCP_TARGET_VERSIONEPLAN_MCP_LOG_LEVELEPLAN_MCP_TIMEOUT_SECONDSEPLAN_MCP_AUTO_DETECT_SERVEREPLAN_MCP_ALLOW_UNSAFE_ACTIONSEPLAN_MCP_FILE_LOGGING_ENABLEDEPLAN_MCP_LOG_FILE_PATHEPLAN_MCP_CONFIG_FILE
Inside EPLAN:
- Open
File > Settings - Go to
Workstation > Interfaces > Remote access - Enable
Allow local access
If you start EPLAN from the command line, do not use /NoRemoting.
First check which port the running EPLAN process is actually listening on:
$pids = @(Get-Process | Where-Object { $_.ProcessName -eq 'EPLAN' } | Select-Object -ExpandProperty Id)
Get-NetTCPConnection -State Listen | Where-Object { $pids -contains $_.OwningProcess } | Select-Object LocalAddress,LocalPort,OwningProcessThen test the discovered port:
Test-NetConnection 192.168.101.50 -Port 49153For local Windows excluded port ranges:
netsh int ipv4 show excludedportrange protocol=tcpIf EPLAN is local and the default remoting port is blocked by Windows NAT state, restarting winnat may help:
net stop winnat
net start winnatRun directly:
python mcp_server\server.pyThe primary entry point is mcp_server/server.py.
The repository-level MCP config has been updated in .mcp.json to point to the local OpenClaw deployment launcher.
Current command:
{
"mcpServers": {
"eplan": {
"command": "cmd",
"args": [
"/c",
"C:\\Users\\Sloan\\Documents\\Eplan_2026_IA_MCP_scripts\\deploy\\openclaw_local\\start_openclaw_eplan_server.cmd"
]
}
}
}For OpenClaw, use the bundle in deploy/openclaw_local/:
- launcher:
deploy/openclaw_local/start_openclaw_eplan_server.cmd - fixed config:
deploy/openclaw_local/eplan_mcp.openclaw.config.json - setup guide:
deploy/openclaw_local/README.md
Install only the runtime dependencies with:
powershell -ExecutionPolicy Bypass -File C:\Users\Sloan\Documents\Eplan_2026_IA_MCP_scripts\deploy\openclaw_local\install_openclaw_runtime.ps1Do not rely on legacy raw-action workflows.
Console logging is always enabled.
Optional file logging is controlled by:
file_logging_enabledlog_file_path
Default file path:
logs/eplan_mcp_server.log
Each registered action execution logs:
- action name
- sanitized parameters
- duration
- success/failure
Run the stage 1 test suite:
pytest tests -qCurrent test coverage includes:
- validators
- action registry
- response formatter
- service layer behavior with a mock remoting client
Check these first:
- EPLAN is running
Allow local accessis enabled- the target host is correct
- the actual listening EPLAN remoting port matches the port you are testing
- no firewall or network rule is blocking the discovered listening port
- EPLAN was not started with
/NoRemoting
If connect_to_eplan succeeds but the connected server_port differs from your config value, trust the returned server_port. The config port is only a fallback when discovery cannot find a live EPLAN listener.
If you see UnsupportedActionError, the action is not in the stable registry. This is by design.
These tools depend on remoting CallingContext output parameters. Verify that the action is supported in your target EPLAN build and that the selected object context inside EPLAN is valid.
open_project now returns a verification block. If the status is opened_not_active, EPLAN acknowledged the target project but did not switch the GUI-active project within the verification window.
For tools that accept an explicit project_name, pass that path so the server can route the action through ProjectAction instead of relying on the active GUI context.
Use the root-level server path, not the legacy path under Eplan_2026_RAG_mcp/mcp_server.
-
create_pageStatus: implemented as an experimental.NET DataModeladapter inmcp_server/adapters/dotnet/datamodel_adapter.pyCurrent scope: create a new page with explicit page type, structure parts, page counter, optional description, page format, plot frame, and optional template-page copy Safety rule: refuses to overwrite an existing page Limitations: validate on a project copy first; this path uses an external DataModel session instead of remoting actions -
insert_symbolStatus: implemented as an experimental.NET DataModeladapter inmcp_server/adapters/dotnet/datamodel_adapter.pyCurrent scope: insert one symbol variant into an existing page at explicit coordinates Current behavior: triesFunction.Create(...)first for logical symbols and falls back toSymbolReference.Create(...)for graphical symbols, both inside one locking step plus transaction Safety rule: validate on a project copy first; no bulk insertion, no connection creation, and no device-tag automation in this phase -
create_deviceStatus: implemented as an experimental.NET DataModeladapter inmcp_server/adapters/dotnet/datamodel_adapter.pyCurrent scope: create one logical function placement on an existing page, assign an explicit full device tag, and optionally set a visible name Current behavior: usesFunction.Create(...)inside one locking step plus transaction, then writesNameand optionalVisibleNameSafety rule: validate on a project copy first; no part assignment, no article automation, and no macro expansion in this phase -
create_connectionStatus: implemented as an experimental.NET DataModeladapter inmcp_server/adapters/dotnet/datamodel_adapter.pyCurrent scope: create one logical connection between two existing placed functions using explicit page-local device tags and explicit pin indices Current behavior: usesConnection(Project, PinBase, PinBase)inside one locking step plus transaction Safety rule: validate on a project copy first; this phase creates logical connections only and does not place a graphical connection definition point
ProjectOpenProjectActionsearcheditselectionsetcheckreportsrenumberexportexportToGraphicsprintXEsGetProjectPropertyActionXEsSetProjectPropertyActionXEsGetPagePropertyActionXEsSetPagePropertyActionExecuteScript
- none enabled by default in stage 1
- typed graphical editing
These will require a dedicated typed adapter layer under:
mcp_server/services/datamodelmcp_server/adapters/dotnet
Compared with the legacy implementation:
- raw action passthrough was removed
- action execution is now registry-gated
- response format is unified
- configuration is centralized
- logging is structured
- services and tools are separated
- the new runtime entry point is at the repository root
Official EPLAN 2026 action references used for the stage 1 stable surface are stored under:
Eplan_2026_RAG_mcp/Eplan_DOCS/Api/Actions
This repository intentionally uses those local docs as the source of truth for stable action inclusion.