@renanlido/tia-openness-mcp 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +4 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -31025,6 +31025,8 @@ function hintFor(err) {
|
|
|
31025
31025
|
return "Start the API on the serve host: `TIAOpenness.exe serve 5000 --host 0.0.0.0` and check TIA_API_BASE.";
|
|
31026
31026
|
case "license_required":
|
|
31027
31027
|
return "Server not activated: configure the API key in the TIAOpenness GUI ('License' tab).";
|
|
31028
|
+
case "scope_required":
|
|
31029
|
+
return "The active license does not include the scope this route requires (see `requiredScope` in the error). Deploy-class tools (download/online/upload) need the 'deploy' scope (Pro tier); offline authoring needs 'author'. Upgrade the plan or activate a license that includes it \u2014 this is a licensing limit, not a fault.";
|
|
31028
31030
|
case "not_connected":
|
|
31029
31031
|
return "No project connected \u2014 connect/open a project before this operation.";
|
|
31030
31032
|
case "not_found":
|
|
@@ -32504,7 +32506,7 @@ var GATES_GUARDS = '# Gates vs guards\n\n## GATES vs GUARDS\n\n- **GATES (human-
|
|
|
32504
32506
|
var GUI_GATES = '# GUI gates \u2014 expected human interaction points\n\n## Human interaction points (GUI gates) \u2014 EXPECTED, not an error\n\nSome TIA settings are **not reachable via Openness** on the S7-1200/1500. The harness will hit a\nsignal that *looks* like an error but is actually a point where a **human must act in the TIA GUI**.\nWhen you see one of these, **do not treat it as a failure and do not retry blindly** \u2014 recognize it,\ntell the human the **exact GUI steps**, and resume after they confirm. A GUI gate is a *handoff*, not a *bug*.\n\n| # | Signal you\'ll see | Why it\'s expected | Tell the human (exact GUI steps) |\n|---|---|---|---|\n| **G1 trust** | `tia_connect` \u2192 `requires_human_action` (`trust_dialog`), or the **1st** connect per `serve` process hangs ~30 s | TIA shows a one-time security prompt the first time an Openness app attaches, **per process** | On the **serve host**, in TIA Portal, click **"Yes to all"** in the access dialog. *Caveat:* it can false-positive on a client timeout with **no** real dialog \u2014 check `tia_status` (`attached:true`) and just resume. |\n| **OPC UA license** | `tia_compile` **ERROR**: *"The selected OPC UA license is not sufficient\u2026"* | License selection is GUI-only (no Openness service); a fresh project **or a firmware change** leaves it unset | CPU \u2192 **Properties \u2192 General \u2192 Runtime licenses \u2192 OPC UA** \u2192 *Type of required license* \u2192 select **"SIMATIC OPC UA S7-1200 Basic"** (the 1214C option). Recompile. |\n| **OPC UA interface** | OPC UA client connects but the DB nodes aren\'t there (`ns=4` empty / no `ServerInterfaces`) | The **S7-1200 does NOT auto-expose DBs** (unlike the S7-1500) \u2014 a server interface must be created by hand | CPU \u2192 **OPC UA \u2192 Server interfaces \u2192 Add new server interface** \u2192 add/drag the DB (e.g. `ModbusData`) into it. Recompile; data appears under `ns=4`. |\n| **PUT/GET** | S7 client (`nodes7`/`snap7`) connects on port 102 but reads return access-denied (`ROSCTR=2` / "BAD") | *"Permit access with PUT/GET"* is a GUI-only protection setting | CPU \u2192 **Properties \u2192 Protection & Security \u2192 Connection mechanisms** \u2192 check **"Permit access with PUT/GET communication from remote partner"**. Compile + download (`hardware:true`). |\n| **FW-change reset** | After `tia_device_change_version`: OPC UA server off, the license error on compile, blocks `isConsistent:false` | `DeviceItem.ChangeType` **resets GUI-gated comm settings** (server activation + license); the interface & PUT/GET survive | `tia_project_archive` **before** the FW change. After: re-set `OpcUaServer:true` via `tia_obj_set_attributes` (scriptable), re-select the license (row above), recompile. |\n\n**Not a gate (now scriptable):** *activating* the OPC UA server \u2014 `tia_obj_set_attributes {OpcUaServer:true}`\non the "OPC UA" device-item (it auto-generates the server certificate). Only the **license** and the\n**server interface** stay GUI-only.\n';
|
|
32505
32507
|
var GOTCHAS = '# Hard-won gotchas (runtime-validated)\n\n## Hard-won gotchas\n\n1. **Always compile before deploy.** `tia_compile` aggregates **hardware + software**; a\n **clean** compile (`errors:0`) is the precondition for download and for S7 connections.\n2. **The serve is a SINGLE serial worker** \u2014 one Openness op at a time. Do **not** fire\n concurrent `tia_*` calls; a hung Openness op can stall the serve (may need a restart).\n3. **Changing an FB\'s interface (e.g. regenerating it via `tia_source_put`) leaves its\n instance DB inconsistent.** Recompile FIRST: a software-scope `tia_compile` regenerates\n the instance DB in most cases. Only if the DB still reports inconsistent after a compile,\n delete it (`tia_block_delete`), recreate it (`tia_instancedb_create`) and recompile.\n4. **Firmware rule: project FW \u2264 device FW.** Bump the project FW **in-place** with\n `tia_device_change_version` (`DeviceItem.ChangeType`), which preserves the **program** \u2014 never\n set the project higher than the physical CPU. **\u26A0\uFE0F It RESETS GUI-gated comm settings** (the\n **OPC UA server activation** + **runtime-license**; the server interface and PUT/GET survive):\n **archive first** (`tia_project_archive`) on a CPU with hand-configured OPC UA, recompile after\n (it marks blocks inconsistent), and re-verify. Same-version `ChangeType` is rejected.\n5. **Use a NON-optimized DB** for Modbus (`MB_HOLD_REG`) and S7 (absolute addressing); OPC UA\n works with optimized or not.\n6. **Order numbers use `/V<fw>`, not `:V<fw>`** (guard Gd5).\n\n## Prerequisites (environment)\n\n- The **`tia` serve must be running** (default `http://localhost:5000`, e.g.\n `TIAOpenness.exe serve 5000`). The MCP is a pure HTTP client; point it at the serve host via\n `TIA_API_BASE` if it runs elsewhere.\n- The Windows user must belong to the **"Siemens TIA Openness"** local group.\n- The **FIRST connection per serve process shows a trust dialog** that a **human must confirm**\n ("Yes to all") on the serve host \u2014 this **cannot be automated** (gate G1).\n';
|
|
32506
32508
|
var PIPELINE = '# The build pipeline (spec \u2192 verified project)\n\nStages in order \u2014 the class tells you what each stage may do:\n\n| # | Stage | Tool(s) | Class | What it does |\n|---|---|---|---|---|\n| 0 | Validate the spec | `tia_spec_validate` | R (pure) | JSON-Schema + cross-field engineering rules (unique names, same-subnet IPs, Gd5 order-number format, per-CPU module limits, language-by-family, the G5 safety rule). Needs no serve. |\n| 1 | Plan | `tia_spec_plan` | R (pure) | Turns a VALID spec into the ordered list of M-off operations. Nothing mutates. |\n| 2 | Scaffold | `tia_spec_apply` (or the M-off tools manually) | M-off | Creates the project content in dependency order (see below). Stops at every gate. |\n| 3 | Verify | `tia_compile` | M-off | THE offline verifier: aggregates hardware + software. Gd8: only ERRORs block. `errors:0` is the Gd9 precondition for any deploy. |\n| 4 | Handoff / deploy | `tia_download` | GATE G3 | `dryRun:true` \u2192 plan + `planHash` \u2192 a HUMAN approves \u2192 re-call with `approved:true` + the SAME `planHash`. Never self-approve. |\n\nScaffold order (dependency-correct): subnets \u2192 devices (CPUs first) \u2192 modules \u2192\nnetwork/IP/IO-system \u2192 protection recipe (`tia_guide {"topic":"recipes"}`) \u2192 tag\ntables \u2192 tags \u2192 constants \u2192 UDTs BEFORE dependent blocks \u2192 FB shells + instance DBs \u2192\nlogic (SCL/STL via `tia_source_put`; LAD/FBD/GRAPH via `tia_import_xml` \u2014 Gd6 format\nrouting) \u2192 `tia_compile`.\n\n## The approval envelope (what a gate handoff looks like)\n\nGated tools return `status:"requires_human_action"` with:\n\n- `gate` \u2014 which gate (e.g. `download_approval`, `go_online`, `trust_dialog`);\n- `youMustDo` \u2014 what the human must confirm, in plain words;\n- `plan` + `planHash` \u2014 exactly what would be executed (the hash binds the approval to\n this exact plan; a changed plan needs a new approval);\n- `nextSteps` \u2014 how to resume after the human\'s yes.\n\nRelay the envelope to the human, wait for an explicit yes, resume exactly as\ninstructed. The AI never approves, never invents a secret, never deploys F-logic.\n\n## After scaffolding\n\n- Re-run `tia_compile` after ANY authoring change.\n- `tia_project_save` regularly; `tia_project_archive` BEFORE risky operations\n (firmware change \u2014 see `tia_guide {"topic":"gotchas"}`).\n- Auditing an existing project is class R: read blocks/types/tags via `tia_plc_*` and\n check the engineering baseline (optimized access, 100% symbolic, UDT-typed\n interfaces, FB + instance-DB, uniform naming).\n';
|
|
32507
|
-
var RECIPES = '# Recipes (runtime-verified) & scaffold order\n\n## Pipeline order (dependency-correct)\n\n`tia_spec_apply` already encodes this; use it manually only when the spec maps imperfectly.\n\n1. **Subnets** (`tia_subnet_create`) \u2014 before connecting devices to them.\n2. **Devices** (`tia_device_create`, `OrderNumber:<MLFB>/V<fw>`) \u2014 CPUs first.\n3. **Modules** (`tia_device_plug`) \u2014 into existing devices, by slot.\n4. **Network** (`tia_network_connect`, IP, `createIoSystem`) \u2014 CPU + its IO-devices on the\n **same** subnet; exactly one `createIoSystem` per IO-system.\n5. **Protection recipe** (below) \u2014 so the CPU can compile clean.\n6. **Tag tables** (`tia_tagtable_create`) \u2192 **tags** (`tia_tag_create`) \u2192 **constants**.\n7. **UDTs first** (`tia_types_import`), **then** blocks that use them.\n8. **Blocks** \u2014 FB shells (`tia_fb_create`) + instance DBs (`tia_instancedb_create`);\n logic via `tia_source_put` (SCL) or `tia_import_xml` (LAD/FBD/GRAPH). Gd6 format routing.\n9. **Compile** (`tia_compile`) \u2014 the verifier; only `Error` blocks. It compiles the **software**\n scope (not just the CPU device item), so it makes freshly-generated blocks consistent and, in\n most cases, **regenerates** any instance DB left inconsistent by an FB interface change.\n **Recompile first**; only if the DB still reports inconsistent after a compile, delete it\n (`tia_block_delete`), recreate it (`tia_instancedb_create`) and recompile.\n\n## Recipe \u2014 unlock a freshly-created CPU so it compiles clean (VERIFIED, V21 / S7-1500 V2.9)\n\nA bare CPU added via Openness fails `compile` with **protection** errors (verified\n2026 against a real S7-1500 1516-3 V2.9 \u2014 3 errors): the *confidential-PLC-configuration-\ndata* password is unset, the *communication certificate* can\'t be generated without it,\nand the *access level* defaults to a protected level needing a password. Fix, in order:\n\n**(1) Confidential-data password \u2192 also auto-generates the certificate** (clears 2 of 3):\n\n```\n# find the CPU device-item handle:\ntia_obj_roots -> the device handle (role:"device")\ntia_obj_items { handle:<device>, composition:"DeviceItems" } -> the CPU item handle\n# acquire the service ON THE CPU MODULE (not the rack) and invoke Protect:\ntia_obj_service { handle:<cpu>, type:"Siemens.Engineering.HW.Features.PlcMasterSecretConfigurator" } -> <svc>\ntia_obj_invoke { handle:<svc>, name:"Protect", args:["<password>"] }\n```\n\n**(2) Access level \u2192 FullAccess** (clears the 3rd; the legacy model on FW < 3.1):\n\n```\ntia_obj_set_attributes { handle:<cpu>, attributes:{ "PlcProtectionAccessLevel":"FullAccess" } }\n```\n\nThen `tia_compile` \u2192 `state: Warning, errors: 0` (the 2 warnings \u2014 CPU-display password \u2014\nare benign and do **not** block; Gd8).\n\n> **CORRECTION for V21:** the older recipe `PlcAccessControlConfiguration="Disabled"` returns\n> **HTTP 500** on V21 (that attribute is not on the CPU item). Use `PlcProtectionAccessLevel`.\n>\n> **Requires the `tia_obj_service` tool** (acquire `GetService<T>` \u2192 handle). Without it the\n> MCP cannot run step 1.\n\n### Open policy \u2014 who supplies the confidential password\n\n`Protect()` sets an **offline project** password (it is not the online master secret / G6).\nThe repo docs treat it as offline authoring ("no human needed"), but it protects confidential\nconfig data \u2014 so this is a **harness policy decision**: either (a) the human/spec supplies it\n(`spec.security.confidentialPassword`), or (b) the harness uses a documented project default.\nDefault to asking the human if the spec doesn\'t carry it; never invent a *secret the user\nmust later know* silently. The online master secret (`tia_mastersecret_set`, G6) is **always**\nhuman-supplied.\n\n## S7 connection precondition (G2)\n\n`tia_connection_create` needs **\u2265 2 CONSISTENT CPUs** (both compile clean). Two *bare* CPUs\nnever form a valid S7 connection \u2014 apply the protection recipe + `tia_compile` to make each\nconsistent first, then create the connection. Use `tia_connections_diagnose` on failure.\n\n## Recipe \u2014 bump the project firmware **in-place** (keeps the program) (VERIFIED, V21 / S7-1200 1214C)\n\nBumped a project **V4.0 \u2192 V4.4** on a real S7-1200 1214C **without losing blocks or tags**\n(verified 2026-06-07). Use this for **auto-FW-match**: align the project to the firmware\nactually read from the CPU. `DeviceItem.ChangeType(typeIdentifier)` changes the item type\nin place and **preserves the software** \u2014 it does **not** require delete/recreate.\n\n```\n# find the CPU device-item handle:\ntia_obj_roots -> the device handle (role:"device")\ntia_obj_items { handle:<device>, composition:"DeviceItems" } -> the CPU item handle (not the rack)\n# change the CPU\'s type to the SAME MLFB with the target /V<fw> suffix:\ntia_obj_invoke { handle:<cpu>, name:"ChangeType",\n args:["OrderNumber:6ES7 214-1HG40-0XB0/V4.4"] }\n# then recompile \u2014 a regenerated FB may need a fresh compile before download:\ntia_compile { ... }\n```\n\n- **Rule: `project FW \u2264 device FW`** \u2014 never set the project firmware **higher** than the physical\n device\'s (download would be rejected). Bumping the project *up to* the device FW is the safe move.\n- Keep the **same MLFB**, swap only the `/V<fw>` suffix. The program (blocks/tags) survives.\n- After `ChangeType` the CPU/blocks can be inconsistent; **always recompile** before any handoff.\n- **\u26A0\uFE0F `ChangeType` RESETS GUI-gated comm settings** (runtime-validated on the 1214C): it **disabled\n the OPC UA server** (`OpcUaServer`\u2192`false`) and **cleared the OPC UA runtime-license** selection\n (the custom server interface and PUT/GET *survived*). So **`tia_project_archive` first** on a CPU\n with hand-configured OPC UA/PUT-GET, and **re-verify after**. Recovery: `tia_obj_set_attributes\n {OpcUaServer:true}` on the "OPC UA" device-item (it **is** writable; re-select the license in the\n GUI). `ChangeType` to the **same** version is rejected ("Cannot change the type of the device item").\n\n## Recipe \u2014 enable a **Modbus TCP server** (`MB_SERVER`) on the S7-1200 (VERIFIED, FW V4.0)\n\nLets an external client (e.g. a Node backend) read/write the CPU over **Modbus TCP, port 502**\n(verified 2026-06-07; full backend/app detail in `docs/COMM-SCENARIOS.md`).\n\n1. **Non-optimized DB with an `Array of Word`** for the holding-register block (`MB_HOLD_REG`).\n Modbus needs a byte-addressable (non-optimized) DB \u2014 optimized access won\'t map.\n2. **On FW V4.0 use `MB_SERVER` V1.x**, which takes **`CONNECT_ID` + `IP_PORT`** parameters\n (**not** `CONNECT`/`TCON`, which the newer instruction versions use). Pin the instruction\n version when generating the FB.\n3. Instantiate `MB_SERVER` as a **multi-instance inside an FB** (its instance lives in the FB\'s\n instance DB), call it cyclically.\n4. **Map a holding register \u2192 a command tag** (e.g. `MB_HOLD_REG[0]` \u2192 `LedCmd`), so writing the\n register drives the output.\n\n> **Instance-DB gotcha (the big one):** when you regenerate the FB via `tia_source_put`, the\n> existing **instance DB** can go inconsistent (its interface no longer matches the FB).\n> **Recompile first** \u2014 a software-scope `tia_compile` regenerates the instance DB in most cases.\n> Only if it still reports inconsistent after a compile (typical when the interface was edited via\n> source), delete + recreate it, then recompile:\n>\n> ```\n> tia_compile { ... } # try first\n> tia_block_delete { ... the stale instance DB ... } # only if still inconsistent\n> tia_instancedb_create { ... fresh instance DB for the FB ... }\n> tia_compile { ... }\n> ```\n>\n> (Matches the \xA7Pipeline note: recompile first, delete+recreate only as the fallback.)\n\n## Recipe \u2014 enable **S7 / PUT-GET** on the S7-1200 (port 102)\n\nLets an external S7 client (e.g. `nodes7`) read/write the CPU over **S7comm, port 102**.\n\n1. **GATE (human, GUI only):** enable PUT/GET \u2014 *Properties \u2192 Protection & Security \u2192\n Connection mechanisms \u2192 "Permit access with PUT/GET communication"*. **Not exposed by\n Openness** on this CPU/FW (we tried `PlcAccessLevelProvider` \u2014 no toggle). Mark it as a\n **human gate** and surface it in `tia.handoff`; do **not** attempt to script it.\n2. **Non-optimized DB** for the data the client touches (PUT/GET addresses absolute offsets, so\n the DB must be byte-addressable / non-optimized).\n3. Compile + download as usual; the client then reads/writes the DB by area+offset.\n\n## Recipe \u2014 enable **OPC UA** on the S7-1200 (port 4840)\n\nLets an external OPC UA client read/write the CPU over **OPC UA, port 4840**. This path is the\nmost gated \u2014 most of it is **human GUI steps**, not Openness.\n\n**Prerequisite \u2014 firmware \u2265 V4.4.** OPC UA server isn\'t available on V4.0. If the project is on\nan older FW, bump it in-place first (see *bump the project firmware in-place* above \u2014\n`ChangeType` to `.../V4.4`).\n\nThen the setup sequence. **Step 1 is scriptable; steps 2\u20133 are human/GUI** on this CPU/FW (for those two\nwe tried `CommunicationManagement` and `OpcUaUserManagement\u2192404`):\n\n1. **Activate the OPC UA server** \u2014 *Properties \u2192 OPC UA \u2192 Server* (enable). *(This step **is**\n scriptable via Openness: `tia_obj_set_attributes` `{OpcUaServer:true}` on the "OPC UA"\n device-item \u2014 it auto-generates the server certificate. Steps 2\u20133 stay GUI-only.)*\n2. **Select the runtime license** \u2014 *"SIMATIC OPC UA S7-1200 Basic"* (Runtime licenses).\n3. **Create a server interface** that **exposes the DB** \u2014 the **S7-1200 does NOT auto-expose**\n tags/DBs to OPC UA (unlike the S7-1500), so you must add a server interface and place the DB\n nodes in it manually.\n\n**Finding the node IDs (client side):** browse `ns=3;s=ServerInterfaces` with any OPC UA client;\nthe actual data nodes show up under **`ns=4`**. Use those node IDs from the backend.\n\n> What Openness *can* still do here: create the DB/blocks, compile, download \u2014 **and activate the OPC UA\n> server** (step 1: `tia_obj_set_attributes {OpcUaServer:true}`; do NOT gate it on a human). Only **three**\n> items are truly human/GUI: the **runtime license**, the **server interface** \u2014 and **PUT/GET** in the S7\n> recipe. See `docs/TIA-Openness-Casos-de-Uso.md` \xA78c for the full "GUI-only gates" table.\n\n## Where to stop\n\nEverything above is **offline (M-off)**. `tia_download` / `tia_online` (G3/G4) are **not**\npart of scaffold \u2014 they belong to `tia.handoff` and require explicit human approval.\n';
|
|
32509
|
+
var RECIPES = '# Recipes (runtime-verified) & scaffold order\n\n## Pipeline order (dependency-correct)\n\n`tia_spec_apply` already encodes this; use it manually only when the spec maps imperfectly.\n\n1. **Subnets** (`tia_subnet_create`) \u2014 before connecting devices to them.\n2. **Devices** (`tia_device_create`, `OrderNumber:<MLFB>/V<fw>`) \u2014 CPUs first.\n3. **Modules** (`tia_device_plug`) \u2014 into existing devices, by slot.\n4. **Network** (`tia_network_connect`, IP, `createIoSystem`) \u2014 CPU + its IO-devices on the\n **same** subnet; exactly one `createIoSystem` per IO-system.\n5. **Protection recipe** (below) \u2014 so the CPU can compile clean.\n6. **Tag tables** (`tia_tagtable_create`) \u2192 **tags** (`tia_tag_create`) \u2192 **constants**.\n7. **UDTs first** (`tia_types_import`), **then** blocks that use them.\n8. **Blocks** \u2014 FB shells (`tia_fb_create`) + instance DBs (`tia_instancedb_create`);\n logic via `tia_source_put` (SCL) or `tia_import_xml` (LAD/FBD/GRAPH). Gd6 format routing.\n9. **Compile** (`tia_compile`) \u2014 the verifier; only `Error` blocks. It compiles the **software**\n scope (not just the CPU device item), so it makes freshly-generated blocks consistent and, in\n most cases, **regenerates** any instance DB left inconsistent by an FB interface change.\n **Recompile first**; only if the DB still reports inconsistent after a compile, delete it\n (`tia_block_delete`), recreate it (`tia_instancedb_create`) and recompile.\n\n## Recipe \u2014 unlock a freshly-created CPU so it compiles clean (VERIFIED V21, firmware-dependent)\n\nA bare CPU added via Openness may fail `compile` with **protection** errors: the\n*confidential-PLC-configuration-data* password is unset, the *communication certificate*\ncan\'t be generated without it, and (on newer firmware) the *access control* defaults to a\nprotected level needing a password. **The recipe differs by CPU family/firmware \u2014 there is\nno single universal form.** Fix, in order:\n\n**(1) Confidential-data password \u2192 also auto-generates the certificate** (common to both\nfamilies):\n\n```\n# find the CPU device-item handle:\ntia_obj_roots -> the device handle (role:"device")\ntia_obj_items { handle:<device>, composition:"DeviceItems" } -> the CPU item handle\n# acquire the service ON THE CPU MODULE (not the rack) and invoke Protect:\ntia_obj_service { handle:<cpu>, type:"Siemens.Engineering.HW.Features.PlcMasterSecretConfigurator" } -> <svc>\ntia_obj_invoke { handle:<svc>, name:"Protect", args:["<password>"] }\n```\n\n**(2) Clear the access-control error \u2014 pick the variant for the CPU\'s family/firmware:**\n\n- **S7-1500 V2.9** (verified 2026 on real hardware \u2014 a 1516-3 V2.9, 3 errors \u2192 0): set\n `PlcProtectionAccessLevel = "FullAccess"` **on the CPU device item**:\n\n ```\n tia_obj_set_attributes { handle:<cpu>, attributes:{ "PlcProtectionAccessLevel":"FullAccess" } }\n ```\n\n- **S7-1200 V4.7** (new security model, FW \u2273 V4.5; per `docs/HARNESS-KNOWLEDGE.md` \xA72,\n runtime-observed): set `PlcAccessControlConfiguration = "Disabled"` on the\n **`PlcAccessControlConfigurationProvider`** SERVICE \u2014 not a direct attribute on the CPU\n item:\n\n ```\n tia_obj_service { handle:<cpu>, type:"Siemens.Engineering.HW.Features.PlcAccessControlConfigurationProvider" } -> <svc2>\n tia_obj_set_attributes { handle:<svc2>, attributes:{ "PlcAccessControlConfiguration":"Disabled" } }\n ```\n\n \u26A0\uFE0F **The two variants are mutually exclusive \u2014 the wrong one returns HTTP 500 on the\n other family:** `PlcAccessControlConfiguration` isn\'t on a 1500\'s CPU item, and\n `PlcProtectionAccessLevel` isn\'t the right model on a 1200 V4.7 item. Detect the\n family/FW \u2014 or the compile-error signature \u2014 before picking a variant.\n\n- **S7-1200 V4.0** (old security model): nothing to do here \u2014 the same bare-CPU condition\n is only a **WARNING**, not an error; a plain `tia_compile` already returns `errors: 0`.\n\nThen `tia_compile` \u2192 `state: Warning, errors: 0` (any remaining warnings \u2014 e.g. CPU-display\npassword \u2014 are benign and do **not** block; Gd8).\n\n> **Requires the `tia_obj_service` tool** (acquire `GetService<T>` \u2192 handle) for step 1 and\n> for the S7-1200 V4.7 variant of step 2. Without it the MCP cannot run either.\n\n### Open policy \u2014 who supplies the confidential password\n\n`Protect()` sets an **offline project** password (it is not the online master secret / G6).\nThe repo docs treat it as offline authoring ("no human needed"), but it protects confidential\nconfig data \u2014 so this is a **harness policy decision**: either (a) the human/spec supplies it\n(`spec.security.confidentialPassword`), or (b) the harness uses a documented project default.\nDefault to asking the human if the spec doesn\'t carry it; never invent a *secret the user\nmust later know* silently. The online master secret (`tia_mastersecret_set`, G6) is **always**\nhuman-supplied.\n\n## S7 connection precondition (G2)\n\n`tia_connection_create` needs **\u2265 2 CONSISTENT CPUs** (both compile clean). Two *bare* CPUs\nnever form a valid S7 connection \u2014 apply the protection recipe + `tia_compile` to make each\nconsistent first, then create the connection. Use `tia_connections_diagnose` on failure.\n\n## Recipe \u2014 bump the project firmware **in-place** (keeps the program) (VERIFIED, V21 / S7-1200 1214C)\n\nBumped a project **V4.0 \u2192 V4.4** on a real S7-1200 1214C **without losing blocks or tags**\n(verified 2026-06-07). Use this for **auto-FW-match**: align the project to the firmware\nactually read from the CPU. `DeviceItem.ChangeType(typeIdentifier)` changes the item type\nin place and **preserves the software** \u2014 it does **not** require delete/recreate.\n\n```\n# find the CPU device-item handle:\ntia_obj_roots -> the device handle (role:"device")\ntia_obj_items { handle:<device>, composition:"DeviceItems" } -> the CPU item handle (not the rack)\n# change the CPU\'s type to the SAME MLFB with the target /V<fw> suffix:\ntia_obj_invoke { handle:<cpu>, name:"ChangeType",\n args:["OrderNumber:6ES7 214-1HG40-0XB0/V4.4"] }\n# then recompile \u2014 a regenerated FB may need a fresh compile before download:\ntia_compile { ... }\n```\n\n- **Rule: `project FW \u2264 device FW`** \u2014 never set the project firmware **higher** than the physical\n device\'s (download would be rejected). Bumping the project *up to* the device FW is the safe move.\n- Keep the **same MLFB**, swap only the `/V<fw>` suffix. The program (blocks/tags) survives.\n- After `ChangeType` the CPU/blocks can be inconsistent; **always recompile** before any handoff.\n- **\u26A0\uFE0F `ChangeType` RESETS GUI-gated comm settings** (runtime-validated on the 1214C): it **disabled\n the OPC UA server** (`OpcUaServer`\u2192`false`) and **cleared the OPC UA runtime-license** selection\n (the custom server interface and PUT/GET *survived*). So **`tia_project_archive` first** on a CPU\n with hand-configured OPC UA/PUT-GET, and **re-verify after**. Recovery: `tia_obj_set_attributes\n {OpcUaServer:true}` on the "OPC UA" device-item (it **is** writable; re-select the license in the\n GUI). `ChangeType` to the **same** version is rejected ("Cannot change the type of the device item").\n\n## Recipe \u2014 enable a **Modbus TCP server** (`MB_SERVER`) on the S7-1200 (VERIFIED, FW V4.0)\n\nLets an external client (e.g. a Node backend) read/write the CPU over **Modbus TCP, port 502**\n(verified 2026-06-07; full backend/app detail in `docs/COMM-SCENARIOS.md`).\n\n1. **Non-optimized DB with an `Array of Word`** for the holding-register block (`MB_HOLD_REG`).\n Modbus needs a byte-addressable (non-optimized) DB \u2014 optimized access won\'t map.\n2. **On FW V4.0 use `MB_SERVER` V1.x**, which takes **`CONNECT_ID` + `IP_PORT`** parameters\n (**not** `CONNECT`/`TCON`, which the newer instruction versions use). Pin the instruction\n version when generating the FB.\n3. Instantiate `MB_SERVER` as a **multi-instance inside an FB** (its instance lives in the FB\'s\n instance DB), call it cyclically.\n4. **Map a holding register \u2192 a command tag** (e.g. `MB_HOLD_REG[0]` \u2192 `LedCmd`), so writing the\n register drives the output.\n\n> **Instance-DB gotcha (the big one):** when you regenerate the FB via `tia_source_put`, the\n> existing **instance DB** can go inconsistent (its interface no longer matches the FB).\n> **Recompile first** \u2014 a software-scope `tia_compile` regenerates the instance DB in most cases.\n> Only if it still reports inconsistent after a compile (typical when the interface was edited via\n> source), delete + recreate it, then recompile:\n>\n> ```\n> tia_compile { ... } # try first\n> tia_block_delete { ... the stale instance DB ... } # only if still inconsistent\n> tia_instancedb_create { ... fresh instance DB for the FB ... }\n> tia_compile { ... }\n> ```\n>\n> (Matches the \xA7Pipeline note: recompile first, delete+recreate only as the fallback.)\n\n## Recipe \u2014 enable **S7 / PUT-GET** on the S7-1200 (port 102)\n\nLets an external S7 client (e.g. `nodes7`) read/write the CPU over **S7comm, port 102**.\n\n1. **GATE (human, GUI only):** enable PUT/GET \u2014 *Properties \u2192 Protection & Security \u2192\n Connection mechanisms \u2192 "Permit access with PUT/GET communication"*. **Not exposed by\n Openness** on this CPU/FW (we tried `PlcAccessLevelProvider` \u2014 no toggle). Mark it as a\n **human gate** and surface it in `tia.handoff`; do **not** attempt to script it.\n2. **Non-optimized DB** for the data the client touches (PUT/GET addresses absolute offsets, so\n the DB must be byte-addressable / non-optimized).\n3. Compile + download as usual; the client then reads/writes the DB by area+offset.\n\n## Recipe \u2014 enable **OPC UA** on the S7-1200 (port 4840)\n\nLets an external OPC UA client read/write the CPU over **OPC UA, port 4840**. This path is the\nmost gated \u2014 most of it is **human GUI steps**, not Openness.\n\n**Prerequisite \u2014 firmware \u2265 V4.4.** OPC UA server isn\'t available on V4.0. If the project is on\nan older FW, bump it in-place first (see *bump the project firmware in-place* above \u2014\n`ChangeType` to `.../V4.4`).\n\nThen the setup sequence. **Step 1 is scriptable; steps 2\u20133 are human/GUI** on this CPU/FW (for those two\nwe tried `CommunicationManagement` and `OpcUaUserManagement\u2192404`):\n\n1. **Activate the OPC UA server** \u2014 *Properties \u2192 OPC UA \u2192 Server* (enable). *(This step **is**\n scriptable via Openness: `tia_obj_set_attributes` `{OpcUaServer:true}` on the "OPC UA"\n device-item \u2014 it auto-generates the server certificate. Steps 2\u20133 stay GUI-only.)*\n2. **Select the runtime license** \u2014 *"SIMATIC OPC UA S7-1200 Basic"* (Runtime licenses).\n3. **Create a server interface** that **exposes the DB** \u2014 the **S7-1200 does NOT auto-expose**\n tags/DBs to OPC UA (unlike the S7-1500), so you must add a server interface and place the DB\n nodes in it manually.\n\n**Finding the node IDs (client side):** browse `ns=3;s=ServerInterfaces` with any OPC UA client;\nthe actual data nodes show up under **`ns=4`**. Use those node IDs from the backend.\n\n> What Openness *can* still do here: create the DB/blocks, compile, download \u2014 **and activate the OPC UA\n> server** (step 1: `tia_obj_set_attributes {OpcUaServer:true}`; do NOT gate it on a human). Only **three**\n> items are truly human/GUI: the **runtime license**, the **server interface** \u2014 and **PUT/GET** in the S7\n> recipe. See `docs/TIA-Openness-Casos-de-Uso.md` \xA78c for the full "GUI-only gates" table.\n\n## Where to stop\n\nEverything above is **offline (M-off)**. `tia_download` / `tia_online` (G3/G4) are **not**\npart of scaffold \u2014 they belong to `tia.handoff` and require explicit human approval.\n';
|
|
32508
32510
|
var SPEC_FORMAT = '# The project-spec (input model)\n\nA project-spec is ONE JSON document describing the whole project. Always run it\nthrough the pipeline front door: `tia_spec_validate` (rung 0, pure) \u2192 `tia_spec_plan`\n(dry) \u2192 `tia_spec_apply` (M-off, stops at gates).\n\nRules the validator enforces (beyond the JSON Schema): unique device/tag/block names;\nevery network node IP inside the subnet CIDR (same-subnet rule); `OrderNumber:<MLFB>/V<fw>`\nformat with `/V` \u2014 never `:V` (Gd5); per-CPU module limits; language by family (e.g.\nS7-1200 has no GRAPH); and the G5 rule \u2014 a spec with safety content marked autonomous\nis REJECTED (F-logic is never autonomous).\n\nMinimal example:\n\n```json\n{\n "project": { "name": "Line2", "directory": "C:\\\\TIA\\\\Line2" },\n "conventions": {\n "namingScheme": "plcopen",\n "optimizedAccess": true,\n "symbolicOnly": true,\n "defaultLanguages": { "interlocks": "LAD", "algorithms": "SCL", "sequencers": "GRAPH" }\n },\n "devices": [\n {\n "name": "Line2_CPU",\n "typeIdentifier": "OrderNumber:6ES7 511-1AK02-0AB0/V2.9",\n "role": "cpu",\n "family": "S7-1500"\n }\n ],\n "network": {\n "subnet": { "type": "System:Subnet.Ethernet", "name": "PN_Line2", "cidr": "192.168.0.0/24" },\n "nodes": [{ "device": "Line2_CPU", "ip": "192.168.0.1", "createIoSystem": true }]\n },\n "dataTypes": [\n {\n "name": "UDT_Motor",\n "members": [\n { "name": "xStart", "dataType": "Bool", "comment": "Start command" },\n { "name": "rSpeed", "dataType": "Real", "comment": "Speed [%]" }\n ]\n }\n ],\n "tagTables": [{ "name": "IO", "purpose": "IO" }],\n "tags": [{ "table": "IO", "name": "Conv01_Run", "dataType": "Bool", "address": "%Q0.0" }]\n}\n```\n\nResolve every concrete MLFB + firmware via `tia_catalog` before building \u2014 never guess\nan order number. Project firmware must be \u2264 the physical device\'s firmware.\n';
|
|
32509
32511
|
var FULL_GUIDE = [BRIEF, GATES_GUARDS, GUI_GATES, GOTCHAS, PIPELINE, RECIPES, SPEC_FORMAT].join("\n---\n\n");
|
|
32510
32512
|
|
|
@@ -32549,7 +32551,7 @@ function registerGuideTool(server2) {
|
|
|
32549
32551
|
|
|
32550
32552
|
// src/index.ts
|
|
32551
32553
|
var server = new McpServer(
|
|
32552
|
-
{ name: "tia-openness", version: "1.
|
|
32554
|
+
{ name: "tia-openness", version: "1.4.0" },
|
|
32553
32555
|
// Camada 1 (ambiente): o brief operacional viaja no handshake MCP — qualquer cliente
|
|
32554
32556
|
// que honre `instructions` recebe gates/serial-only/pipeline sem instalar nada.
|
|
32555
32557
|
{ instructions: BRIEF }
|
package/package.json
CHANGED