@renanlido/tia-openness-mcp 1.4.0 → 1.4.1

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.
Files changed (3) hide show
  1. package/README.md +137 -133
  2. package/dist/index.js +1 -1
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,16 +1,18 @@
1
1
  # TIA Openness MCP server
2
2
 
3
- Servidor **MCP (stdio)** que é um **cliente HTTP puro** sobre a API `serve` do TIA Openness
4
- (veja `docs/API-HTTP.md` no repositório). Não referencia Openness / net48 / x64 — toda a
5
- complexidade (`AssemblyResolve`, worker serial MTA) vive no processo `serve`. Aqui só falamos **MCP de um
6
- lado** e **HTTP/JSON do outro**.
3
+ [![npm](https://img.shields.io/npm/v/%40renanlido%2Ftia-openness-mcp)](https://www.npmjs.com/package/@renanlido/tia-openness-mcp)
7
4
 
8
- **Cross-platform:** o MCP é Node puro (bundle ESM com shebang) e roda em **macOS / Linux / Windows**
9
- (Node ≥ 20). Só a **API `serve` é Windows-only** (net48/x64 + Openness) — por isso o arranjo canônico é
10
- **MCP no seu laptop (ex.: Mac) → `serve` num host/VM Windows**, apontado por env (veja abaixo).
5
+ An **MCP (stdio) server** that is a **pure HTTP client** of the TIA Openness `serve` API
6
+ (see `docs/API-HTTP.md` in the repository). It does not reference Openness / net48 / x64 — all of that
7
+ complexity (`AssemblyResolve`, serial MTA worker) lives in the `serve` process. Here we only speak **MCP on
8
+ one side** and **HTTP/JSON on the other**.
11
9
 
12
- Distribuído como **pacote npm bundled** (esbuild → 1 arquivo self-contained, sem `node_modules` em runtime),
13
- publicado no **npm público** via **semantic-release** — rode com um one-liner, **sem auth e sem `.npmrc`**:
10
+ **Cross-platform:** the MCP is pure Node (ESM bundle with shebang) and runs on **macOS / Linux / Windows**
11
+ (Node ≥ 20). Only the **`serve` API is Windows-only** (net48/x64 + Openness) — which is why the canonical
12
+ setup is **MCP on your laptop (e.g. a Mac) → `serve` on a Windows host/VM**, pointed at via env (see below).
13
+
14
+ Distributed as a **bundled npm package** (esbuild → 1 self-contained file, no `node_modules` at runtime),
15
+ published to the **public npm registry** via **semantic-release** — run it with a one-liner, **no auth, no `.npmrc`**:
14
16
 
15
17
  ```bash
16
18
  npx -y @renanlido/tia-openness-mcp
@@ -39,216 +41,218 @@ generated from `mcp/content/*.md` (the canonical source) into `src/content.gen.t
39
41
 
40
42
  ## Tools
41
43
 
42
- ### Diagnóstico + M1 read-only (classe R, auto-aprováveis)
43
- | Tool | Endpoint | Descrição |
44
+ ### Diagnostics + M1 read-only (class R, auto-approvable)
45
+ | Tool | Endpoint | Description |
44
46
  |---|---|---|
45
- | `tia_ping` | `GET /health` + `GET /readiness` | Diagnostica conectividade e ATIVAÇÃO do `serve`. `{ base, reachable, activated, latencyMs, hint }`. Ideal p/ Mac→VM. |
46
- | `tia_readiness` | `GET /readiness` | Prontidão do ambiente **no host do serve** (x64, grupo Windows, PublicAPI, registro, instâncias). |
47
+ | `tia_ping` | `GET /health` + `GET /readiness` | Diagnoses connectivity and ACTIVATION of the `serve`. `{ base, reachable, activated, latencyMs, hint }`. Ideal for Mac→VM. |
48
+ | `tia_readiness` | `GET /readiness` | Environment readiness **on the serve host** (x64, Windows group, PublicAPI, registry, instances). |
47
49
  | `tia_guide` | — (bundled content, no HTTP call) | Returns the operating guide (see "Operating guide embedded" above). Topics: `toc` (default) \| `full` \| `brief` \| `gates-guards` \| `gui-gates` \| `gotchas` \| `pipeline` \| `recipes` \| `spec-format`. Pure/offline — works with the `serve` down. |
48
50
 
49
- **M1 (read-only, 1:1 com os GET da API):** `tia_instances`, `tia_status`, `tia_projects`, `tia_project_info`,
51
+ **M1 (read-only, 1:1 with the API's GET endpoints):** `tia_instances`, `tia_status`, `tia_projects`, `tia_project_info`,
50
52
  `tia_project_languages`, `tia_plcs`, `tia_devices`, `tia_device_tree`, `tia_device_connections`,
51
53
  `tia_plc_blocks/types/tags/watchtables`, `tia_catalog`, `tia_connections_diagnose`, `tia_subnets`,
52
- `tia_obj_roots/get/items/info/creationinfos/services`. Nenhuma muta estado.
54
+ `tia_obj_roots/get/items/info/creationinfos/services`. None of them mutate state.
53
55
 
54
- ### M2 — ciclo de vida (classe M-off) + GATE de confiança (G1)
55
- | Tool | Endpoint | Descrição |
56
+ ### M2 — lifecycle (class M-off) + trust GATE (G1)
57
+ | Tool | Endpoint | Description |
56
58
  |---|---|---|
57
- | `tia_start` | `POST /tia/start` | Inicia/anexa o TIA **sem projeto** (`headless` opcional). |
58
- | `tia_show_ui` | `POST /tia/show-ui` | Relança o TIA headless como **visível** p/ renderizar o diálogo de confiança (habilita o G1). |
59
- | `tia_connect` | `POST /connect` | Abre/anexa um projeto. **Pode bloquear no GATE G1** → devolve um envelope `requires_human_action` (sem retry-storm) com `resumeToken`. UMAC (G6) só se um humano fornecer. |
60
- | `tia_disconnect` | `POST /disconnect` | Desconecta (Gd3: use `tia_project_close` p/ liberar o lock). |
61
- | `tia_project_create` | `POST /project/create` | Cria projeto (Gd4: diretório vazio → senão 409). |
62
- | `tia_project_save` / `tia_project_saveas` / `tia_project_close` / `tia_project_archive` | `POST /project/*` | Ciclo de vida do projeto. |
63
-
64
- **GATE de confiança (G1):** na 1ª conexão por processo `serve`, o TIA exige confirmação manual de um diálogo
65
- de segurança NO HOST. O fluxo proativo é **`tia_start` → `tia_show_ui` → (humano confirma) → `tia_connect`**.
66
- Se o `tia_connect` esbarra no diálogo, ele NÃO faz retry-storm: devolve `{ status:"requires_human_action",
67
- gate:"trust_dialog", youMustDo, resumeToken }`. Após o humano confirmar, re-chame `tia_connect` com o `resumeToken`.
68
-
69
- ### M3 — criação/autoria offline (classe M-off) + guards
70
- Superfície de **criação compliant-by-construction** (~28 tools), todas com `dryRun` (Gd11) e validação por schema (Gd13):
71
- - **Hardware/rede:** `tia_device_create`/`plug`/`unplug`, `tia_device_group_create`, `tia_subnet_create`, `tia_network_connect`/`address`/`disconnect`.
72
- - **Tags/constantes:** `tia_tagtable_create`, `tia_tag_create`/`delete`, `tia_constant_create`.
73
- - **Blocos/tipos:** `tia_fb_create`, `tia_instancedb_create`, `tia_block_delete`/`set_attribute`, `tia_block_group_create`, `tia_type_group_create`/`type_delete`.
74
- - **Código:** `tia_source_put` (SCL textual — Gd6), `tia_import_xml`/`tia_types_import` (SimaticML gráfico — Gd6/Gd7), `tia_export_xml`.
59
+ | `tia_start` | `POST /tia/start` | Starts/attaches TIA **without a project** (optional `headless`). |
60
+ | `tia_show_ui` | `POST /tia/show-ui` | Relaunches a headless TIA as **visible** to render the trust dialog (enables G1). |
61
+ | `tia_connect` | `POST /connect` | Opens/attaches a project. **May block on GATE G1** → returns a `requires_human_action` envelope (no retry storm) with a `resumeToken`. UMAC (G6) only if a human provides it. |
62
+ | `tia_disconnect` | `POST /disconnect` | Disconnects (Gd3: use `tia_project_close` to release the lock). |
63
+ | `tia_project_create` | `POST /project/create` | Creates a project (Gd4: empty directory → otherwise 409). |
64
+ | `tia_project_save` / `tia_project_saveas` / `tia_project_close` / `tia_project_archive` | `POST /project/*` | Project lifecycle. |
65
+
66
+ **Trust GATE (G1):** on the 1st connection per `serve` process, TIA requires manual confirmation of a security
67
+ dialog ON THE HOST. The proactive flow is **`tia_start` → `tia_show_ui` → (human confirms) → `tia_connect`**.
68
+ If `tia_connect` hits the dialog, it does NOT retry-storm: it returns `{ status:"requires_human_action",
69
+ gate:"trust_dialog", youMustDo, resumeToken }`. After the human confirms, call `tia_connect` again with the `resumeToken`.
70
+
71
+ ### M3 — offline creation/authoring (class M-off) + guards
72
+ A **compliant-by-construction** creation surface (~28 tools), all with `dryRun` (Gd11) and schema validation (Gd13):
73
+ - **Hardware/network:** `tia_device_create`/`plug`/`unplug`, `tia_device_group_create`, `tia_subnet_create`, `tia_network_connect`/`address`/`disconnect`.
74
+ - **Tags/constants:** `tia_tagtable_create`, `tia_tag_create`/`delete`, `tia_constant_create`.
75
+ - **Blocks/types:** `tia_fb_create`, `tia_instancedb_create`, `tia_block_delete`/`set_attribute`, `tia_block_group_create`, `tia_type_group_create`/`type_delete`.
76
+ - **Code:** `tia_source_put` (textual SCL — Gd6), `tia_import_xml`/`tia_types_import` (graphical SimaticML — Gd6/Gd7), `tia_export_xml`.
75
77
  - **Watch tables:** `tia_watchtable_create`/`delete`.
76
- - **Camada genérica de escrita:** `tia_obj_set_attributes`/`invoke`/`create`.
78
+ - **Generic write layer:** `tia_obj_set_attributes`/`invoke`/`create`.
77
79
 
78
- **Guards (client-side, antes de tocar o Openness):** **Gd5** — `typeIdentifier` deve usar `/V<fw>` (barra), nunca `:V`
79
- (rejeitado com `kind:"guard_violation"`; resolva o valor via `tia_catalog`). **Gd11** — `dryRun:true` valida os guards
80
- e retorna o **plano por nome SEM mutar** (`status:"plan_ok"`). **Gd6** (advisório) — linguagem textual (SCL) via
81
- `tia_source_put`, gráfica (LAD/FBD/GRAPH) via `tia_import_xml`; UDTs antes dos blocos. **Gd2** (advisório) — idempotência
82
- por nome (cheque a existência com as tools read-only do M1 antes de criar; o Openness não tem rollback).
80
+ **Guards (client-side, before touching Openness):** **Gd5** — `typeIdentifier` must use `/V<fw>` (slash), never `:V`
81
+ (rejected with `kind:"guard_violation"`; resolve the value via `tia_catalog`). **Gd11** — `dryRun:true` validates the guards
82
+ and returns the **plan by name WITHOUT mutating** (`status:"plan_ok"`). **Gd6** (advisory) — textual language (SCL) via
83
+ `tia_source_put`, graphical (LAD/FBD/GRAPH) via `tia_import_xml`; UDTs before blocks. **Gd2** (advisory) — idempotency
84
+ by name (check existence with the M1 read-only tools before creating; Openness has no rollback).
83
85
 
84
- ### M4 — verificação + deploy GATED (hardware)
85
- | Tool | Endpoint | Gate/classe |
86
+ ### M4 — verification + GATED deploy (hardware)
87
+ | Tool | Endpoint | Gate/class |
86
88
  |---|---|---|
87
- | `tia_compile` | `POST /plcs/{plc}/compile` | M-off — **o verificador**. Achata a árvore de mensagens + `verification:{compiled,errors,warnings}` + `nextHints` (Gd8: só ERRO bloqueia). |
88
- | `tia_connection_create` | `POST /connections` | M-off — conexão S7 (G2: exige ≥2 CPUs consistentes; falha anexa diagnóstico). |
89
- | `tia_download` | `POST /plcs/{plc}/download` | **GATE G3** — não baixa sem aprovação humana vinculada ao `planHash`. |
89
+ | `tia_compile` | `POST /plcs/{plc}/compile` | M-off — **the verifier**. Flattens the message tree + `verification:{compiled,errors,warnings}` + `nextHints` (Gd8: only ERRORs block). |
90
+ | `tia_connection_create` | `POST /connections` | M-off — S7 connection (G2: requires ≥2 consistent CPUs; failure attaches diagnostics). |
91
+ | `tia_download` | `POST /plcs/{plc}/download` | **GATE G3** — never downloads without human approval bound to the `planHash`. |
90
92
  | `tia_online` / `tia_offline` / `tia_online_state` | `POST /plcs/{plc}/online`·`/offline`·`GET …/state` | **G4** (online) / R (state). |
91
93
  | `tia_accessible_devices` | `POST /plcs/{plc}/online/accessibledevices` | **GATE G7** (net scan). |
92
- | `tia_mastersecret_set` / `tia_mastersecret_reset` | `…/online/mastersecret` | **GATE G6** (segredo vem do humano, nunca da IA). |
94
+ | `tia_mastersecret_set` / `tia_mastersecret_reset` | `…/online/mastersecret` | **GATE G6** (the secret comes from a human, never from the AI). |
93
95
 
94
- **GATE de download (G3):** `tia_download` NUNCA baixa sem aprovação. Fluxo: `tia_compile` (precondição Gd9: `errors=0`) →
95
- `tia_download dryRun:true` (devolve `plan` + `planHash`, sem baixar) → um humano aprova → `tia_download approved:true`
96
- com o **mesmo `planHash`**. Hash errado ou `approved` ausente → envelope `requires_human_action / download_approval`.
97
- **Limitação honesta:** o `serve` ainda **auto-confirma** StopAll/Overwrite (backlog C# **P0.5**); até isso ser
98
- re-externalizado, o "Load Preview" real não é exposto e o G3 é a salvaguarda da **camada do MCP** (não bypassável só por texto do LLM).
96
+ **Download GATE (G3):** `tia_download` NEVER downloads without approval. Flow: `tia_compile` (Gd9 precondition: `errors=0`) →
97
+ `tia_download dryRun:true` (returns `plan` + `planHash`, without downloading) → a human approves → `tia_download approved:true`
98
+ with the **same `planHash`**. Wrong hash or missing `approved` → `requires_human_action / download_approval` envelope.
99
+ **Honest limitation:** the `serve` still **auto-confirms** StopAll/Overwrite (C# backlog **P0.5**); until that is
100
+ re-externalized, the real "Load Preview" is not exposed and G3 is the safeguard of the **MCP layer** (not bypassable by LLM text alone).
99
101
 
100
- ### M5 — ingestão de project-spec (orquestra M1–M4)
101
- Aceita o **project-spec** estruturado (`docs/TIA-BEST-PRACTICES.md` §13.2; JSON Schema em `.claude-plugin/schemas/project-spec.schema.json`):
102
- - **`tia_spec_validate`** (R, determinístico, **sem serve**): valida forma + regras de campo cruzado — R-NAMES (nomes únicos), R-TYPEID (`OrderNumber:<MLFB>/V<fw>`), R-SUBNET (IP∈CIDR, CPU+IO na mesma subnet, 1 IO-system), R-LANGFAM (STL/GRAPH só S7-1500), R-MODLIMIT, e **G5** (`safety.required && autonomous ⇒ REJECT`).
103
- - **`tia_spec_plan`** (sem serve): transforma um spec válido na sequência ordenada de operações (subnets→devices→módulos→rede→tags→blocos→compile).
104
- - **`tia_spec_apply`**: orquestra o build OFFLINE num projeto aberto (valida → G5 → executa serial → compila), **para no 1º erro** e **nunca baixa** (download é o GATE G3, sempre humano). `dryRun:true` devolve o plano.
102
+ ### M5 — project-spec ingestion (orchestrates M1–M4)
103
+ Accepts the structured **project-spec** (`docs/TIA-BEST-PRACTICES.md` §13.2; JSON Schema at `.claude-plugin/schemas/project-spec.schema.json`):
104
+ - **`tia_spec_validate`** (R, deterministic, **no serve needed**): validates shape + cross-field rules — R-NAMES (unique names), R-TYPEID (`OrderNumber:<MLFB>/V<fw>`), R-SUBNET (IP∈CIDR, CPU+IO on the same subnet, 1 IO-system), R-LANGFAM (STL/GRAPH only on S7-1500), R-MODLIMIT, and **G5** (`safety.required && autonomous ⇒ REJECT`).
105
+ - **`tia_spec_plan`** (no serve needed): turns a valid spec into the ordered operation sequence (subnets→devices→modules→network→tags→blocks→compile).
106
+ - **`tia_spec_apply`**: orchestrates the OFFLINE build on an open project (validate → G5 → execute serially → compile), **stops at the 1st error** and **never downloads** (download is GATE G3, always human). `dryRun:true` returns the plan.
105
107
 
106
- > **MCP M0–M5 COMPLETO** (76 tools), **validado em runtime** contra um TIA Portal V21 real (incluindo **deploy em hardware** num S7-1200) e **publicado no npm**. Roadmap e marcos em `docs/ROADMAP.md` §3.
108
+ > **MCP M0–M5 COMPLETE** (76 tools), **runtime-validated** against a real TIA Portal V21 (including a
109
+ > **hardware deploy** to an S7-1200) and **published to npm**. Roadmap and milestones in `docs/ROADMAP.md` §3.
107
110
 
108
- ## Configuração (env)
111
+ ## Configuration (env)
109
112
 
110
- | Var | Default | Uso |
113
+ | Var | Default | Purpose |
111
114
  |---|---|---|
112
- | `TIA_API_BASE` | `http://localhost:5000` | Base URL da API `serve`. |
113
- | `TIA_API_TIMEOUT_MS` | `15000` | Timeout por request (falha rápido se o host/VM não responde). |
115
+ | `TIA_API_BASE` | `http://localhost:5000` | Base URL of the `serve` API. |
116
+ | `TIA_API_TIMEOUT_MS` | `15000` | Per-request timeout (fail fast if the host/VM does not respond). |
114
117
 
115
- > **O MCP não envia chave.** A API é **ativada por uma licença** configurada na GUI (aba "Licença") — quem
116
- > autoriza o servidor é a licença do host, não o cliente. O MCP é um cliente HTTP normal: só aponta a base.
118
+ > **The MCP sends no key.** The API is **activated by a license** configured in the GUI ("License" tab) — what
119
+ > authorizes the server is the host's license, not the client. The MCP is a plain HTTP client: it only points at the base URL.
117
120
 
118
- ## Cenário Mac → VM Windows (apontar o servidor)
121
+ ## Mac → Windows VM scenario (pointing at the server)
119
122
 
120
- 1. **Na VM Windows**, faça tudo pela **GUI de bandeja** (atalho "TIA Openness API"):
121
- - aba **"Licença"** → cole a chave de ativação → **"Validar"** → **"Salvar"** (a API só aceita
122
- conexões externas se estiver **ativada**);
123
- - aba **"API"** → **Host** = `0.0.0.0` (aceita conexões de fora; `localhost` só atende a própria VM),
124
- **Porta** = `5000` → **"Iniciar API"**. O status fica **verde** ("Rodando em http://0.0.0.0:5000/ …").
123
+ 1. **On the Windows VM**, do everything through the **tray GUI** ("TIA Openness API" shortcut):
124
+ - **"License"** tab → paste the activation key → **"Validate"** → **"Save"** (the API only accepts
125
+ external connections when it is **activated**);
126
+ - **"API"** tab → **Host** = `0.0.0.0` (accepts outside connections; `localhost` only serves the VM itself),
127
+ **Port** = `5000` → **"Start API"**. The status turns **green** ("Running at http://0.0.0.0:5000/ …").
125
128
 
126
- Libere a porta no firewall do Windows e garanta rede acessível (bridged ou NAT com port-forward). O
127
- controle de **quem** pode chamar é o firewall/VPN — a licença ativa o servidor, não autentica clientes.
129
+ Open the port in the Windows firewall and make sure the network is reachable (bridged, or NAT with port
130
+ forwarding). Controlling **who** can call is the firewall/VPN's job — the license activates the server, it
131
+ does not authenticate clients.
128
132
 
129
- <details><summary>Alternativa headless por linha de comando (avançado)</summary>
133
+ <details><summary>Headless command-line alternative (advanced)</summary>
130
134
 
131
135
  ```powershell
132
136
  .\bin\Debug\net48\TIAOpenness.exe serve 5000 --host 0.0.0.0 --license TIA1.xxxxx.yyyyy
133
137
  ```
134
138
  </details>
135
- 2. **No Mac**, aponte o MCP para a VM:
139
+ 2. **On the Mac**, point the MCP at the VM:
136
140
  ```bash
137
- export TIA_API_BASE="http://<ip-da-vm>:5000"
141
+ export TIA_API_BASE="http://<vm-ip>:5000"
138
142
  ```
139
- 3. **Diagnostique** com o tool `tia_ping`: `reachable:false` → IP/porta/firewall/VM; `activated:false` →
140
- licença ausente/inválida na VM; ambos `true` → pronto.
143
+ 3. **Diagnose** with the `tia_ping` tool: `reachable:false` → IP/port/firewall/VM; `activated:false` →
144
+ license missing/invalid on the VM; both `true` → ready.
141
145
 
142
146
  ## Build / bundle
143
147
 
144
148
  ```bash
145
- # garanta o Node (no Windows com nvm-windows: $env:Path = "C:\nvm4w\nodejs;" + $env:Path)
149
+ # make sure Node is available (on Windows with nvm-windows: $env:Path = "C:\nvm4w\nodejs;" + $env:Path)
146
150
  cd mcp
147
151
  npm install
148
152
  npm run build # typecheck + esbuild -> dist/index.js (self-contained)
149
153
  ```
150
154
 
151
- ## Instalação
155
+ ## Installation
152
156
 
153
- ### A) Do npm público (uso normal, Mac/Windows/Linux)
157
+ ### A) From public npm (normal use, Mac/Windows/Linux)
154
158
 
155
- Pacote **público** — **sem auth, sem `.npmrc`**. Use direto via `npx` ou instale o binário global:
159
+ **Public** package — **no auth, no `.npmrc`**. Use it directly via `npx` or install the global binary:
156
160
 
157
161
  ```bash
158
- npx -y @renanlido/tia-openness-mcp # roda sem instalar (recomendado p/ .mcp.json)
159
- # ou instale o binário `tia-openness-mcp` no PATH:
162
+ npx -y @renanlido/tia-openness-mcp # runs without installing (recommended for .mcp.json)
163
+ # or install the `tia-openness-mcp` binary on PATH:
160
164
  npm install -g @renanlido/tia-openness-mcp
161
165
  ```
162
166
 
163
- ### B) Local, sem publicar (dev nesta máquina)
167
+ ### B) Local, without publishing (dev on this machine)
164
168
 
165
169
  ```bash
166
170
  cd mcp
167
- npm install -g . # o prepack compila e instala o binário
168
- # ou: npm pack && npm install -g ./renanlido-tia-openness-mcp-*.tgz
171
+ npm install -g . # prepack builds and installs the binary
172
+ # or: npm pack && npm install -g ./renanlido-tia-openness-mcp-*.tgz
169
173
  ```
170
174
 
171
- ## Publicação (npm público + semantic-release)
175
+ ## Publishing (public npm + semantic-release)
172
176
 
173
- Versionamento **automático por commits convencionais** (`feat` → minor, `fix` → patch, `BREAKING CHANGE`
174
- → major). O workflow `.github/workflows/release-mcp.yml` dispara
175
- no push para `main` **quando algo em `mcp/` muda** (e `semantic-release-monorepo` filtra os commits por
176
- esse path), builda e publica no **npm público** (`registry.npmjs.org`, `publishConfig.access: public`).
177
+ **Automatic versioning by conventional commits** (`feat` → minor, `fix` → patch, `BREAKING CHANGE`
178
+ → major). The `.github/workflows/release-mcp.yml` workflow fires on pushes to `main` **when something under
179
+ `mcp/` changes** (and `semantic-release-monorepo` filters the commits by that path), builds and publishes to
180
+ **public npm** (`registry.npmjs.org`, `publishConfig.access: public`).
177
181
 
178
- Usa **dois tokens**: `NPM_TOKEN` (secret a configurar — token *Automation/Publish* do npmjs.org) para o
179
- **publish** via `@semantic-release/npm`, e o `GITHUB_TOKEN` nativo do Actions para criar a release/tag e
180
- commitar o `CHANGELOG`.
182
+ It uses **two tokens**: `NPM_TOKEN` (a repository secret — an *Automation/Publish* token from npmjs.org) for the
183
+ **publish** via `@semantic-release/npm`, and the native Actions `GITHUB_TOKEN` to create the release/tag and
184
+ commit the `CHANGELOG`.
181
185
 
182
- **Para ligar (passos com credencial, uma vez):**
183
- 1. Crie o repo no GitHub (`renanlido/TIAOpenness`) — ou ajuste `repository.url`/scope no `package.json` e
184
- o workflow se o owner for outro.
185
- 2. **Configure o secret `NPM_TOKEN`** no repositório (Settings → Secrets and variables → Actions): gere um
186
- token de *Automation* em npmjs.org com permissão de publish no pacote `@renanlido/tia-openness-mcp`.
186
+ **To wire it up (credential steps, one time):**
187
+ 1. Create the GitHub repo (`renanlido/TIAOpenness`) — or adjust `repository.url`/scope in `package.json` and
188
+ the workflow if the owner differs.
189
+ 2. **Configure the `NPM_TOKEN` secret** on the repository (Settings → Secrets and variables → Actions): generate an
190
+ *Automation* token on npmjs.org with publish permission on the `@renanlido/tia-openness-mcp` package.
187
191
  3. `git add . && git commit -m "feat: initial commit"` → `git branch -M main` →
188
192
  `git remote add origin <url>` → `git push -u origin main`.
189
- 4. A partir daí, **commits convencionais** na `main` disparam o release automaticamente.
193
+ 4. From then on, **conventional commits** on `main` trigger the release automatically.
190
194
 
191
- > Config validada localmente: versões dedupadas em `semantic-release@24`; o dry-run carregou config/plugins
192
- > e só parou por o repo remoto ainda não existir.
195
+ > Config validated locally: versions deduped at `semantic-release@24`; the dry-run loaded config/plugins
196
+ > and only stopped because the remote repo did not exist yet.
193
197
 
194
- ## Registro no Claude Code
198
+ ## Registering in Claude Code
195
199
 
196
- **Não precisa instalar nada** — o recomendado é o `npx`, que baixa e roda o pacote publicado. Um comando
197
- só (escopo de **usuário**):
200
+ **Nothing to install** — the recommended way is `npx`, which downloads and runs the published package. One
201
+ command (**user** scope):
198
202
 
199
203
  ```bash
200
204
  claude mcp add --transport stdio --env TIA_API_BASE=http://localhost:5000 --scope user tia -- npx -y @renanlido/tia-openness-mcp
201
205
  ```
202
206
 
203
- Confira com `claude mcp list` e `claude mcp get tia`. O equivalente por **`.mcp.json`** na raiz do projeto
204
- (escopo de **projeto**) — também via `npx`, sem instalar:
207
+ Check with `claude mcp list` and `claude mcp get tia`. The **`.mcp.json`** equivalent at the project root
208
+ (**project** scope) — also via `npx`, nothing installed:
205
209
 
206
210
  ```jsonc
207
211
  {
208
212
  "mcpServers": {
209
213
  "tia": {
210
- "command": "npx", // baixa e roda o pacote do npm — NADA instalado
214
+ "command": "npx", // downloads and runs the npm package — NOTHING installed
211
215
  "args": ["-y", "@renanlido/tia-openness-mcp"],
212
216
  "env": {
213
- "TIA_API_BASE": "${TIA_API_BASE:-http://localhost:5000}" // IP:porta do serve (use o IP da VM se remoto)
217
+ "TIA_API_BASE": "${TIA_API_BASE:-http://localhost:5000}" // serve IP:port (use the VM IP if remote)
214
218
  }
215
219
  }
216
220
  }
217
221
  }
218
222
  ```
219
223
 
220
- > **`tia-openness-mcp` NÃO é um arquivo do repositório** — é o nome do **bin** do pacote (`package.json` →
221
- > `"bin": { "tia-openness-mcp": "dist/index.js" }`). Esse atalho só fica no seu PATH **se** você instalar
222
- > global (`npm install -g @renanlido/tia-openness-mcp`); só então faria sentido
223
- > `"command": "tia-openness-mcp", "args": []`. O `npx` dispensa esse passo — por isso é o recomendado.
224
+ > **`tia-openness-mcp` is NOT a file in the repository** — it is the package's **bin** name (`package.json` →
225
+ > `"bin": { "tia-openness-mcp": "dist/index.js" }`). That shortcut only lands on your PATH **if** you install
226
+ > globally (`npm install -g @renanlido/tia-openness-mcp`); only then would
227
+ > `"command": "tia-openness-mcp", "args": []` make sense. `npx` skips that step — which is why it is the recommended way.
224
228
 
225
- **Outros clientes** (Claude Desktop, Codex, Gemini CLI, Cursor, VS Code, Windsurf): o guia canônico de
226
- instalação — com os formatos exatos de cada um e a pegadinha do `cmd /c npx` no Windows — está em
227
- `docs/INSTALL.md` no repositório.
229
+ **Other clients** (Claude Desktop, Codex, Gemini CLI, Cursor, VS Code, Windsurf): the canonical install
230
+ guide — with each client's exact format and the Windows `cmd /c npx` gotcha — is in
231
+ `docs/INSTALL.md` in the repository.
228
232
 
229
- **Envs opcionais** (default embutido no MCP — só defina para sobrescrever): `TIA_API_TIMEOUT_MS` (15000),
230
- `TIA_SLOW_TIMEOUT_MS` (120000), `TIA_CONNECT_TIMEOUT_MS` (30000). Ex.: `--env TIA_SLOW_TIMEOUT_MS=180000`
231
- no `claude mcp add`, ou a chave correspondente no `env` do `.mcp.json`.
233
+ **Optional envs** (defaults are built into the MCP — only set them to override): `TIA_API_TIMEOUT_MS` (15000),
234
+ `TIA_SLOW_TIMEOUT_MS` (120000), `TIA_CONNECT_TIMEOUT_MS` (30000). E.g. `--env TIA_SLOW_TIMEOUT_MS=180000`
235
+ on `claude mcp add`, or the corresponding key in the `.mcp.json` `env`.
232
236
 
233
- Como é servidor de **escopo de projeto**, o Claude Code pede **aprovação** na 1ª vez: `claude mcp list`
234
- (deve listar `tia`), rode `claude` no projeto e **aprove**, **recarregue** a sessão, e peça para chamar
237
+ Since it is a **project-scoped** server, Claude Code asks for **approval** the 1st time: `claude mcp list`
238
+ (should list `tia`), run `claude` in the project and **approve**, **reload** the session, and ask it to call
235
239
  `tia_ping` / `tia_readiness`.
236
240
 
237
241
  ## Smoke test
238
242
 
239
243
  ```bash
240
- npm run smoke # alvo = dist/index.js local
241
- # apontar para o binário global:
242
- MCP_COMMAND=tia-openness-mcp MCP_ARGS='[]' npm run smoke # (Windows: use o caminho do .cmd)
244
+ npm run smoke # target = local dist/index.js
245
+ # point at the global binary:
246
+ MCP_COMMAND=tia-openness-mcp MCP_ARGS='[]' npm run smoke # (Windows: use the .cmd path)
243
247
  ```
244
248
 
245
- ## Notas
249
+ ## Notes
246
250
 
247
- - **O MCP não envia chave/segredo.** A API é ativada por licença no host (GUI). Segredos (master secret /
248
- UMAC / senha de cert) nunca vão no `.mcp.json`.
249
- - **Serial-only**: o backend é um worker serial; o MCP nunca deve paralelizar tool calls (Gd1).
250
- - **stdout é do protocolo MCP** — logs vão para **stderr**.
251
- - O bundle é gerado por [scripts/build.mjs](scripts/build.mjs) (esbuild, ESM, shebang + `createRequire`,
252
- versão injetada). `dist/`, `node_modules/`, `*.tgz` são artefatos (gitignored).
253
- - Ao adicionar/alterar tools, **rebuild + reinstalar** o binário (`npm run build && npm i -g .`) para a
254
- instalação local refletir; em produção, o push para `main` republica.
251
+ - **The MCP sends no key/secret.** The API is activated by a license on the host (GUI). Secrets (master secret /
252
+ UMAC / cert password) never go in `.mcp.json`.
253
+ - **Serial-only**: the backend is a serial worker; the MCP must never parallelize tool calls (Gd1).
254
+ - **stdout belongs to the MCP protocol** — logs go to **stderr**.
255
+ - The bundle is produced by [scripts/build.mjs](scripts/build.mjs) (esbuild, ESM, shebang + `createRequire`,
256
+ injected version). `dist/`, `node_modules/`, `*.tgz` are artifacts (gitignored).
257
+ - When adding/changing tools, **rebuild + reinstall** the binary (`npm run build && npm i -g .`) so the local
258
+ install reflects it; in production, pushing to `main` republishes.
package/dist/index.js CHANGED
@@ -32551,7 +32551,7 @@ function registerGuideTool(server2) {
32551
32551
 
32552
32552
  // src/index.ts
32553
32553
  var server = new McpServer(
32554
- { name: "tia-openness", version: "1.4.0" },
32554
+ { name: "tia-openness", version: "1.4.1" },
32555
32555
  // Camada 1 (ambiente): o brief operacional viaja no handshake MCP — qualquer cliente
32556
32556
  // que honre `instructions` recebe gates/serial-only/pipeline sem instalar nada.
32557
32557
  { instructions: BRIEF }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@renanlido/tia-openness-mcp",
3
- "version": "1.4.0",
3
+ "version": "1.4.1",
4
4
  "description": "MCP server (stdio) — thin HTTP client over the TIA Openness `serve` API. Zero Openness/net48 references.",
5
5
  "license": "MIT",
6
6
  "type": "module",