easyeda-mcp-pro 0.3.2 → 0.5.2

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 (173) hide show
  1. package/README.md +369 -52
  2. package/dist/bom-quality/adapter.d.ts +90 -0
  3. package/dist/bom-quality/adapter.js +295 -0
  4. package/dist/bom-quality/adapter.js.map +1 -0
  5. package/dist/bom-quality/index.d.ts +10 -0
  6. package/dist/bom-quality/index.js +9 -0
  7. package/dist/bom-quality/index.js.map +1 -0
  8. package/dist/bom-quality/quality.d.ts +28 -0
  9. package/dist/bom-quality/quality.js +179 -0
  10. package/dist/bom-quality/quality.js.map +1 -0
  11. package/dist/bom-quality/types.d.ts +94 -0
  12. package/dist/bom-quality/types.js +12 -0
  13. package/dist/bom-quality/types.js.map +1 -0
  14. package/dist/bridge/manager.d.ts +41 -0
  15. package/dist/bridge/manager.js +334 -47
  16. package/dist/bridge/manager.js.map +1 -1
  17. package/dist/bridge/protocol.d.ts +48 -1
  18. package/dist/bridge/protocol.js +43 -1
  19. package/dist/bridge/protocol.js.map +1 -1
  20. package/dist/bridge/types.d.ts +6 -0
  21. package/dist/bridge/types.js +6 -0
  22. package/dist/bridge/types.js.map +1 -1
  23. package/dist/catalog/errors.d.ts +49 -0
  24. package/dist/catalog/errors.js +60 -0
  25. package/dist/catalog/errors.js.map +1 -0
  26. package/dist/catalog/index.d.ts +15 -0
  27. package/dist/catalog/index.js +17 -0
  28. package/dist/catalog/index.js.map +1 -0
  29. package/dist/catalog/schema.d.ts +268 -0
  30. package/dist/catalog/schema.js +245 -0
  31. package/dist/catalog/schema.js.map +1 -0
  32. package/dist/catalog/starter.d.ts +159 -0
  33. package/dist/catalog/starter.js +579 -0
  34. package/dist/catalog/starter.js.map +1 -0
  35. package/dist/catalog/validation.d.ts +48 -0
  36. package/dist/catalog/validation.js +263 -0
  37. package/dist/catalog/validation.js.map +1 -0
  38. package/dist/circuit/circuit-ir.d.ts +460 -0
  39. package/dist/circuit/circuit-ir.js +292 -0
  40. package/dist/circuit/circuit-ir.js.map +1 -0
  41. package/dist/circuit/compiler.d.ts +55 -0
  42. package/dist/circuit/compiler.js +197 -0
  43. package/dist/circuit/compiler.js.map +1 -0
  44. package/dist/circuit/design-intent.d.ts +94 -0
  45. package/dist/circuit/design-intent.js +118 -0
  46. package/dist/circuit/design-intent.js.map +1 -0
  47. package/dist/circuit/errors.d.ts +50 -0
  48. package/dist/circuit/errors.js +61 -0
  49. package/dist/circuit/errors.js.map +1 -0
  50. package/dist/circuit/index.d.ts +17 -0
  51. package/dist/circuit/index.js +18 -0
  52. package/dist/circuit/index.js.map +1 -0
  53. package/dist/circuit/types.d.ts +186 -0
  54. package/dist/circuit/types.js +123 -0
  55. package/dist/circuit/types.js.map +1 -0
  56. package/dist/cli/auto-setup.d.ts +5 -0
  57. package/dist/cli/auto-setup.js +355 -0
  58. package/dist/cli/auto-setup.js.map +1 -0
  59. package/dist/cli/client-definitions.d.ts +34 -0
  60. package/dist/cli/client-definitions.js +194 -0
  61. package/dist/cli/client-definitions.js.map +1 -0
  62. package/dist/cli/local-setup.d.ts +5 -1
  63. package/dist/cli/local-setup.js +40 -6
  64. package/dist/cli/local-setup.js.map +1 -1
  65. package/dist/config/env.d.ts +6 -1
  66. package/dist/config/env.js +93 -5
  67. package/dist/config/env.js.map +1 -1
  68. package/dist/config/profiles.js +4 -4
  69. package/dist/config/version.d.ts +1 -1
  70. package/dist/config/version.js +1 -1
  71. package/dist/export-manifest/errors.d.ts +55 -0
  72. package/dist/export-manifest/errors.js +69 -0
  73. package/dist/export-manifest/errors.js.map +1 -0
  74. package/dist/export-manifest/index.d.ts +10 -0
  75. package/dist/export-manifest/index.js +9 -0
  76. package/dist/export-manifest/index.js.map +1 -0
  77. package/dist/export-manifest/types.d.ts +170 -0
  78. package/dist/export-manifest/types.js +36 -0
  79. package/dist/export-manifest/types.js.map +1 -0
  80. package/dist/export-manifest/validation.d.ts +39 -0
  81. package/dist/export-manifest/validation.js +298 -0
  82. package/dist/export-manifest/validation.js.map +1 -0
  83. package/dist/index.js +20 -0
  84. package/dist/index.js.map +1 -1
  85. package/dist/net-validation/errors.d.ts +89 -0
  86. package/dist/net-validation/errors.js +69 -0
  87. package/dist/net-validation/errors.js.map +1 -0
  88. package/dist/net-validation/fixtures.d.ts +38 -0
  89. package/dist/net-validation/fixtures.js +215 -0
  90. package/dist/net-validation/fixtures.js.map +1 -0
  91. package/dist/net-validation/index.d.ts +10 -0
  92. package/dist/net-validation/index.js +9 -0
  93. package/dist/net-validation/index.js.map +1 -0
  94. package/dist/net-validation/schema.d.ts +118 -0
  95. package/dist/net-validation/schema.js +140 -0
  96. package/dist/net-validation/schema.js.map +1 -0
  97. package/dist/net-validation/validation.d.ts +45 -0
  98. package/dist/net-validation/validation.js +369 -0
  99. package/dist/net-validation/validation.js.map +1 -0
  100. package/dist/pcb-constraints/errors.d.ts +39 -0
  101. package/dist/pcb-constraints/errors.js +133 -0
  102. package/dist/pcb-constraints/errors.js.map +1 -0
  103. package/dist/pcb-constraints/index.d.ts +9 -0
  104. package/dist/pcb-constraints/index.js +9 -0
  105. package/dist/pcb-constraints/index.js.map +1 -0
  106. package/dist/pcb-constraints/types.d.ts +102 -0
  107. package/dist/pcb-constraints/types.js +7 -0
  108. package/dist/pcb-constraints/types.js.map +1 -0
  109. package/dist/pcb-constraints/validation.d.ts +70 -0
  110. package/dist/pcb-constraints/validation.js +309 -0
  111. package/dist/pcb-constraints/validation.js.map +1 -0
  112. package/dist/server/factory.js +2 -0
  113. package/dist/server/factory.js.map +1 -1
  114. package/dist/server/transports/http.d.ts +20 -1
  115. package/dist/server/transports/http.js +156 -34
  116. package/dist/server/transports/http.js.map +1 -1
  117. package/dist/storage/database.d.ts +25 -0
  118. package/dist/storage/database.js +126 -51
  119. package/dist/storage/database.js.map +1 -1
  120. package/dist/tools/{L0_diagnostics.d.ts → L0_diagnostics_api.d.ts} +2 -2
  121. package/dist/tools/L0_diagnostics_api.js +152 -0
  122. package/dist/tools/L0_diagnostics_api.js.map +1 -0
  123. package/dist/tools/L0_diagnostics_core.d.ts +6 -0
  124. package/dist/tools/{L0_diagnostics.js → L0_diagnostics_core.js} +50 -124
  125. package/dist/tools/L0_diagnostics_core.js.map +1 -0
  126. package/dist/tools/L1_board.js +20 -4
  127. package/dist/tools/L1_board.js.map +1 -1
  128. package/dist/tools/{L1_bom.d.ts → L1_bom_core.d.ts} +2 -2
  129. package/dist/tools/{L1_bom.js → L1_bom_core.js} +21 -101
  130. package/dist/tools/L1_bom_core.js.map +1 -0
  131. package/dist/tools/{L1_schematic.d.ts → L1_bom_sourcing.d.ts} +2 -2
  132. package/dist/tools/L1_bom_sourcing.js +265 -0
  133. package/dist/tools/L1_bom_sourcing.js.map +1 -0
  134. package/dist/tools/L1_drc_erc.js +15 -3
  135. package/dist/tools/L1_drc_erc.js.map +1 -1
  136. package/dist/tools/L1_export.js +20 -4
  137. package/dist/tools/L1_export.js.map +1 -1
  138. package/dist/tools/L1_pcb_constraints.d.ts +6 -0
  139. package/dist/tools/L1_pcb_constraints.js +234 -0
  140. package/dist/tools/L1_pcb_constraints.js.map +1 -0
  141. package/dist/tools/L1_pcb_write.js +26 -12
  142. package/dist/tools/L1_pcb_write.js.map +1 -1
  143. package/dist/tools/L1_schematic_read.d.ts +6 -0
  144. package/dist/tools/{L1_schematic.js → L1_schematic_read.js} +125 -190
  145. package/dist/tools/L1_schematic_read.js.map +1 -0
  146. package/dist/tools/L1_schematic_write.d.ts +6 -0
  147. package/dist/tools/L1_schematic_write.js +516 -0
  148. package/dist/tools/L1_schematic_write.js.map +1 -0
  149. package/dist/tools/register.js +15 -7
  150. package/dist/tools/register.js.map +1 -1
  151. package/dist/tools/registry.d.ts +41 -7
  152. package/dist/tools/registry.js +111 -12
  153. package/dist/tools/registry.js.map +1 -1
  154. package/dist/tools/types.d.ts +16 -0
  155. package/dist/utils/logger.d.ts +1 -1
  156. package/dist/utils/logger.js +1 -1
  157. package/dist/utils/logger.js.map +1 -1
  158. package/dist/vendors/base-http-client.d.ts +48 -0
  159. package/dist/vendors/base-http-client.js +75 -0
  160. package/dist/vendors/base-http-client.js.map +1 -0
  161. package/dist/vendors/digikey/client.js +10 -19
  162. package/dist/vendors/digikey/client.js.map +1 -1
  163. package/dist/vendors/jlcpcb/client.js +41 -70
  164. package/dist/vendors/jlcpcb/client.js.map +1 -1
  165. package/dist/vendors/lcsc/client.js +5 -18
  166. package/dist/vendors/lcsc/client.js.map +1 -1
  167. package/dist/vendors/mouser/client.js +4 -12
  168. package/dist/vendors/mouser/client.js.map +1 -1
  169. package/easyeda-bridge-extension.eext +0 -0
  170. package/package.json +41 -26
  171. package/dist/tools/L0_diagnostics.js.map +0 -1
  172. package/dist/tools/L1_bom.js.map +0 -1
  173. package/dist/tools/L1_schematic.js.map +0 -1
package/README.md CHANGED
@@ -11,29 +11,35 @@
11
11
 
12
12
  ## Quick Start
13
13
 
14
- ```bash
15
- npx easyeda-mcp-pro
16
- ```
14
+ The fastest way to install and configure `easyeda-mcp-pro` for your favorite AI assistant or IDE:
17
15
 
18
- Point your MCP client (Claude, Cursor, etc.) to the stdio transport. Create a `.env` file to configure suppliers and AI providers (see [Configuration](#configuration)).
16
+ 1. **Auto-configure your MCP client:**
19
17
 
20
- For the recommended no-terminal workflow, let your MCP client auto-start the server:
18
+ ```bash
19
+ npx easyeda-mcp-pro setup all
20
+ ```
21
21
 
22
- ```bash
23
- npx easyeda-mcp-pro --setup-local
24
- ```
22
+ _This detects and configures Claude Desktop, Cursor, VS Code, Windsurf, Cline, Gemini, Zed, etc. to run the MCP server automatically._
23
+ _(Or run for a specific client, e.g., `npx easyeda-mcp-pro setup claude`)_
24
+
25
+ 2. **Locate and install the EasyEDA Pro bridge extension:**
25
26
 
26
- The setup command prints:
27
+ ```bash
28
+ npx easyeda-mcp-pro extension --open
29
+ ```
27
30
 
28
- - the EasyEDA Pro extension package path (`easyeda-bridge-extension.eext`)
29
- - a local MCP client config that starts `dist/index.js` automatically
30
- - an npm/npx MCP client config for published package usage
31
+ _This opens the folder containing the extension package `easyeda-bridge-extension.eext`. Import it via **EasyEDA Pro → Settings → Extensions → Extension Manager**._
32
+
33
+ 3. **Connect the bridge:**
34
+ In EasyEDA Pro, click **MCP Bridge → Connect** in the menu bar.
35
+
36
+ For advanced configurations, manual instructions, and specific clients, see [Installation & Client Configuration](#installation--client-configuration).
31
37
 
32
38
  ---
33
39
 
34
40
  ## Overview
35
41
 
36
- easyeda-mcp-pro is a [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that bridges AI assistants with hardware design workflows in EasyEDA Pro. It exposes 34 profile-gated MCP tools for schematic inspection and editing, controlled EasyEDA Pro API calls, BOM management, design rule checks, PCB board analysis, fabrication exports, and supplier integration.
42
+ easyeda-mcp-pro is a [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that bridges AI assistants with hardware design workflows in EasyEDA Pro. It exposes 41 profile-gated MCP tools for schematic inspection and editing, controlled EasyEDA Pro API calls, BOM management, design rule checks, PCB board analysis, fabrication exports, and supplier integration.
37
43
 
38
44
  The server connects to EasyEDA Pro via a WebSocket bridge extension, enabling real-time access to open project data. It integrates with JLCPCB, LCSC, Mouser, and DigiKey for BOM sourcing and pricing.
39
45
 
@@ -59,40 +65,297 @@ The server connects to EasyEDA Pro via a WebSocket bridge extension, enabling re
59
65
 
60
66
  ---
61
67
 
62
- ## Installation
68
+ ## Installation & Client Configuration
69
+
70
+ You can configure `easyeda-mcp-pro` automatically or manually.
71
+
72
+ ### 1. Automatic Configuration (CLI)
63
73
 
64
- ### Via npm (recommended)
74
+ The CLI setup automates editing the configuration files for your client:
65
75
 
66
76
  ```bash
67
- npm install -g easyeda-mcp-pro
68
- easyeda-mcp-pro
77
+ # Configure all detected clients automatically
78
+ npx easyeda-mcp-pro setup all
79
+
80
+ # Or configure a specific client
81
+ npx easyeda-mcp-pro setup <client>
69
82
  ```
70
83
 
71
- ### Via npx
84
+ #### Supported Client Keys:
85
+
86
+ - `claude` (Claude Desktop)
87
+ - `cursor` (Cursor IDE)
88
+ - `vscode` (VS Code Copilot)
89
+ - `windsurf` (Windsurf)
90
+ - `cline` (Cline)
91
+ - `gemini` (Gemini CLI / Antigravity)
92
+ - `zed` (Zed Editor)
93
+ - `amazonq` (Amazon Q Developer)
94
+ - `continue` (Continue.dev)
95
+
96
+ #### Options:
97
+
98
+ - `--profile <name>`: Specify the tool profile. Options: `core` (default), `pro`, `full`, `dev`.
99
+ Example: `npx easyeda-mcp-pro setup cursor --profile full`
100
+
101
+ ### 2. Extension Installation
102
+
103
+ To bridge the MCP server with EasyEDA Pro:
72
104
 
73
105
  ```bash
74
- npx easyeda-mcp-pro
106
+ # Open the directory containing the .eext extension package in your file manager
107
+ npx easyeda-mcp-pro extension --open
108
+
109
+ # Or copy it to a specific directory
110
+ npx easyeda-mcp-pro extension --copy /path/to/destination
75
111
  ```
76
112
 
77
- ### From source
113
+ **Installation steps in EasyEDA Pro:**
114
+
115
+ 1. Open **EasyEDA Pro**.
116
+ 2. Go to **Settings** → **Extensions** → **Extension Manager**.
117
+ 3. Click **Import Extension** and select the `easyeda-bridge-extension.eext` file.
118
+ 4. Ensure **Allow External Interaction** is enabled for the extension.
119
+ 5. Click **MCP Bridge** → **Connect** in the menu bar.
120
+
121
+ ---
122
+
123
+ ### 3. Manual Client Configurations
124
+
125
+ If you prefer to configure your clients manually, add the following configuration to the respective settings files:
126
+
127
+ <details>
128
+ <summary>🟣 Claude Desktop</summary>
129
+
130
+ **Config Path:**
131
+
132
+ - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
133
+ - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
134
+ - Linux: `~/.config/Claude/claude_desktop_config.json`
135
+
136
+ ```json
137
+ {
138
+ "mcpServers": {
139
+ "easyeda-mcp-pro": {
140
+ "command": "npx",
141
+ "args": ["-y", "easyeda-mcp-pro@latest"],
142
+ "env": {
143
+ "TOOL_PROFILE": "core"
144
+ }
145
+ }
146
+ }
147
+ }
148
+ ```
149
+
150
+ </details>
151
+
152
+ <details>
153
+ <summary>🔵 Cursor IDE</summary>
154
+
155
+ **Config Path:** Project-specific `.cursor/mcp.json` or global `~/.cursor/mcp.json`
156
+
157
+ ```json
158
+ {
159
+ "mcpServers": {
160
+ "easyeda-mcp-pro": {
161
+ "command": "npx",
162
+ "args": ["-y", "easyeda-mcp-pro@latest"],
163
+ "env": {
164
+ "TOOL_PROFILE": "pro"
165
+ }
166
+ }
167
+ }
168
+ }
169
+ ```
170
+
171
+ </details>
172
+
173
+ <details>
174
+ <summary>🟢 VS Code (GitHub Copilot)</summary>
175
+
176
+ **Config Path:** `%APPDATA%\Code\User\mcp.json` (Windows), `~/Library/Application Support/Code/User/mcp.json` (macOS), or `~/.config/Code/User/mcp.json` (Linux)
177
+
178
+ ```json
179
+ {
180
+ "servers": {
181
+ "easyeda-mcp-pro": {
182
+ "command": "npx",
183
+ "args": ["-y", "easyeda-mcp-pro@latest"],
184
+ "env": {
185
+ "TOOL_PROFILE": "pro"
186
+ }
187
+ }
188
+ }
189
+ }
190
+ ```
191
+
192
+ </details>
193
+
194
+ <details>
195
+ <summary>🏄 Windsurf (Codeium)</summary>
196
+
197
+ **Config Path:** `~/.codeium/windsurf/mcp_config.json`
198
+
199
+ ```json
200
+ {
201
+ "mcpServers": {
202
+ "easyeda-mcp-pro": {
203
+ "command": "npx",
204
+ "args": ["-y", "easyeda-mcp-pro@latest"],
205
+ "env": {
206
+ "TOOL_PROFILE": "pro"
207
+ }
208
+ }
209
+ }
210
+ }
211
+ ```
212
+
213
+ </details>
214
+
215
+ <details>
216
+ <summary>🤖 Cline</summary>
217
+
218
+ **Config Path:** Cline VS Code extension global storage (`cline_mcp_settings.json`)
219
+
220
+ ```json
221
+ {
222
+ "mcpServers": {
223
+ "easyeda-mcp-pro": {
224
+ "command": "npx",
225
+ "args": ["-y", "easyeda-mcp-pro@latest"],
226
+ "env": {
227
+ "TOOL_PROFILE": "pro"
228
+ },
229
+ "disabled": false,
230
+ "autoApprove": []
231
+ }
232
+ }
233
+ }
234
+ ```
235
+
236
+ </details>
237
+
238
+ <details>
239
+ <summary>✨ Gemini CLI / Antigravity</summary>
240
+
241
+ **Config Path:** `~/.gemini/settings.json` or `~/.gemini/config/mcp_config.json`
242
+
243
+ ```json
244
+ {
245
+ "mcpServers": {
246
+ "easyeda-mcp-pro": {
247
+ "command": "npx",
248
+ "args": ["-y", "easyeda-mcp-pro@latest"],
249
+ "env": {
250
+ "TOOL_PROFILE": "pro"
251
+ }
252
+ }
253
+ }
254
+ }
255
+ ```
256
+
257
+ </details>
258
+
259
+ <details>
260
+ <summary>⚡ Zed Editor</summary>
261
+
262
+ **Config Path:** `~/.config/zed/settings.json`
263
+
264
+ ```json
265
+ {
266
+ "context_servers": {
267
+ "easyeda-mcp-pro": {
268
+ "command": {
269
+ "path": "npx",
270
+ "args": ["-y", "easyeda-mcp-pro@latest"]
271
+ },
272
+ "settings": {}
273
+ }
274
+ }
275
+ }
276
+ ```
277
+
278
+ </details>
279
+
280
+ <details>
281
+ <summary>🔄 Continue.dev</summary>
282
+
283
+ **Config Path:** `~/.continue/config.json`
284
+
285
+ ```json
286
+ {
287
+ "mcpServers": {
288
+ "easyeda-mcp-pro": {
289
+ "command": "npx",
290
+ "args": ["-y", "easyeda-mcp-pro@latest"],
291
+ "env": {
292
+ "TOOL_PROFILE": "pro"
293
+ }
294
+ }
295
+ }
296
+ }
297
+ ```
298
+
299
+ </details>
300
+
301
+ <details>
302
+ <summary>👑 Amazon Q Developer</summary>
303
+
304
+ **Config Path:** `~/.aws/amazonq/mcp.json`
305
+
306
+ ```json
307
+ {
308
+ "mcpServers": {
309
+ "easyeda-mcp-pro": {
310
+ "command": "npx",
311
+ "args": ["-y", "easyeda-mcp-pro@latest"],
312
+ "env": {
313
+ "TOOL_PROFILE": "pro"
314
+ }
315
+ }
316
+ }
317
+ }
318
+ ```
319
+
320
+ </details>
321
+
322
+ ---
323
+
324
+ ### 4. Running from Source (Development)
325
+
326
+ If you are developing or running a modified local build:
78
327
 
79
328
  ```bash
80
329
  git clone https://github.com/oaslananka/easyeda-mcp-pro.git
81
330
  cd easyeda-mcp-pro
82
331
  cp .env.example .env
83
332
  pnpm install
84
- pnpm setup:local
333
+
334
+ # Build the server and the bridge extension package
335
+ pnpm build
336
+ pnpm build:extension
337
+ ```
338
+
339
+ To configure your clients to use the local development build:
340
+
341
+ ```bash
342
+ # Print instructions and local config block pointing to dist/index.js
343
+ node dist/index.js --setup-local
85
344
  ```
86
345
 
87
- Install or reload the generated `easyeda-bridge-extension.eext` package in EasyEDA Pro. Then add the printed MCP config to your MCP client. After that, your MCP client starts the server automatically; do not keep a separate `node dist/index.js` terminal running.
346
+ ### Local Diagnostics & Health Check
88
347
 
89
- ### Local health check
348
+ You can diagnose your environment and bridge connectivity at any time:
90
349
 
91
350
  ```bash
92
351
  pnpm doctor
93
352
  ```
94
353
 
95
- The doctor command checks the Node.js runtime, built server entry, generated EasyEDA extension package, and local bridge port reachability. If the bridge server is offline, that is normal until your MCP client starts `easyeda-mcp-pro`.
354
+ This checks:
355
+
356
+ 1. Node.js version compatibility.
357
+ 2. Existence of build files and the `.eext` extension package.
358
+ 3. Bridge port availability. _Note: The bridge status will show as offline until an MCP client starts the server and connects to the EasyEDA Pro extension._
96
359
 
97
360
  ---
98
361
 
@@ -102,29 +365,36 @@ Copy `.env.example` to `.env` and edit. All variables have safe defaults — onl
102
365
 
103
366
  ### Essential
104
367
 
105
- | Variable | Default | Description |
106
- | -------------- | ------------- | ---------------------------------------------------------------------------- |
107
- | `NODE_ENV` | `development` | Set to `production` in production |
108
- | `LOG_LEVEL` | `info` | Pino log level: `trace`, `debug`, `info`, `warn`, `error`, `fatal`, `silent` |
109
- | `TOOL_PROFILE` | `core` | Tool set: `core`, `pro`, `full`, `dev`, `experimental` |
110
- | `TRANSPORT` | `stdio` | Server transport: `stdio` (default) or `http` |
368
+ | Variable | Default | Description |
369
+ | ---------------------- | ------------- | ---------------------------------------------------------------------------- |
370
+ | `NODE_ENV` | `development` | Set to `production` in production |
371
+ | `LOG_LEVEL` | `info` | Pino log level: `trace`, `debug`, `info`, `warn`, `error`, `fatal`, `silent` |
372
+ | `TOOL_PROFILE` | `core` | Tool set: `core`, `pro`, `full`, `dev`, `experimental` |
373
+ | `MCP_PROTOCOL_VERSION` | `2025-11-25` | MCP protocol version string |
374
+ | `TRANSPORT` | `stdio` | Server transport: `stdio` (default) or `http` |
111
375
 
112
376
  ### Bridge (EasyEDA Pro connection)
113
377
 
114
- | Variable | Default | Description |
115
- | --------------------- | ------------------- | -------------------------------- |
116
- | `BRIDGE_HOST` | `127.0.0.1` | Bridge WebSocket host |
117
- | `BRIDGE_PORT` | `18601` | Primary bridge port |
118
- | `BRIDGE_PORT_SCAN` | `18601,49620-49629` | Port scan spec (comma/range) |
119
- | `BRIDGE_TIMEOUT_MS` | `15000` | Bridge call timeout (ms) |
120
- | `BRIDGE_HEARTBEAT_MS` | `10000` | Heartbeat interval (ms) |
121
- | `BRIDGE_TOKEN` | `''` | Session token for extension auth |
378
+ | Variable | Default | Description |
379
+ | ------------------------------- | ------------- | ----------------------------------------- |
380
+ | `BRIDGE_HOST` | `127.0.0.1` | Bridge WebSocket host |
381
+ | `BRIDGE_PORT` | `49620` | Primary bridge port |
382
+ | `BRIDGE_PORT_SCAN` | `49620-49629` | Port scan spec (comma/range) |
383
+ | `BRIDGE_TIMEOUT_MS` | `15000` | Bridge call timeout (ms) |
384
+ | `BRIDGE_HEARTBEAT_MS` | `10000` | Heartbeat interval (ms) |
385
+ | `BRIDGE_RECONNECT_MAX_ATTEMPTS` | `0` | Max reconnect attempts (`0` = infinite) |
386
+ | `BRIDGE_WAIT_FOR_EDA_MS` | `30000` | Wait for EasyEDA Pro on startup (ms) |
387
+ | `BRIDGE_MAX_PAYLOAD_SIZE` | `1048576` | Max bridge payload (bytes, default 1 MiB) |
388
+ | `BRIDGE_TOKEN` | `''` | Session token for extension auth |
122
389
 
123
390
  ### Storage
124
391
 
125
- | Variable | Default | Description |
126
- | ---------- | ------------------ | ------------------------------------------- |
127
- | `DATA_DIR` | `.easyeda-mcp-pro` | Data directory (cache, database, artifacts) |
392
+ | Variable | Default | Description |
393
+ | -------------- | ----------------------------------------- | ------------------------------------------- |
394
+ | `DATA_DIR` | `.easyeda-mcp-pro` | Data directory (cache, database, artifacts) |
395
+ | `SQLITE_PATH` | `.easyeda-mcp-pro/easyeda-mcp-pro.sqlite` | SQLite database path |
396
+ | `ARTIFACT_DIR` | `.easyeda-mcp-pro/artifacts` | Artifact export directory |
397
+ | `CACHE_DIR` | `.easyeda-mcp-pro/cache` | Cache directory |
128
398
 
129
399
  ### Supplier integration
130
400
 
@@ -139,10 +409,14 @@ Enable suppliers by setting their credentials. All suppliers are disabled by def
139
409
 
140
410
  Configure an AI provider for LLM-assisted design review:
141
411
 
142
- | Variable | Default | Description |
143
- | ------------- | ------- | ----------------------------------------------- |
144
- | `AI_PROVIDER` | `none` | `anthropic`, `openai`, `openrouter`, or `local` |
145
- | `AI_MODEL` | `''` | Model name |
412
+ | Variable | Default | Description |
413
+ | --------------------------- | ------- | ----------------------------------------------- |
414
+ | `AI_PROVIDER` | `none` | `anthropic`, `openai`, `openrouter`, or `local` |
415
+ | `AI_MODEL` | `''` | Model name (e.g., `claude-sonnet-4-20250514`) |
416
+ | `AI_API_KEY` | `''` | AI provider API key |
417
+ | `AI_MAX_TOKENS` | `8000` | Max tokens per AI response |
418
+ | `AI_TIMEOUT_MS` | `60000` | AI request timeout in ms |
419
+ | `AI_ALLOW_DESIGN_MUTATIONS` | `false` | Allow AI to modify schematic/board designs |
146
420
 
147
421
  ### HTTP transport
148
422
 
@@ -152,6 +426,7 @@ When using `TRANSPORT=http`:
152
426
  | --------------------- | ----------- | ----------------------------------------- |
153
427
  | `HTTP_HOST` | `127.0.0.1` | Bind address (use `0.0.0.0` with caution) |
154
428
  | `HTTP_PORT` | `3000` | Port |
429
+ | `HTTP_AUTH_DISABLED` | `false` | Disable HTTP transport authentication |
155
430
  | `HTTP_RATE_LIMIT_MAX` | `100` | Max requests per minute per IP |
156
431
  | `CORS_ORIGIN` | `''` | Allowed CORS origin |
157
432
 
@@ -183,7 +458,7 @@ See `.env.example` for the complete list of configuration variables.
183
458
 
184
459
  ## MCP Tools
185
460
 
186
- The server currently registers 34 tools. Tools are filtered by the active `TOOL_PROFILE`: `core` exposes the normal workflow tools, `pro` adds manufacturing exports, `full` adds controlled documented EasyEDA API calls, and `dev` adds runtime probes for debugging.
461
+ The server currently registers 41 tools. Tools are filtered by the active `TOOL_PROFILE`: `core` exposes the normal workflow tools, `pro` adds manufacturing exports, `full` adds controlled documented EasyEDA API calls, and `dev` adds runtime probes for debugging.
187
462
 
188
463
  ### L0 — Diagnostics (core)
189
464
 
@@ -279,7 +554,7 @@ The schematic write APIs use EasyEDA Pro extension APIs that EasyEDA currently m
279
554
  │ (via Plugin) │ Protocol │ └───────────────┘ │
280
555
  └─────────────────┘ │ ┌───────────────┐ │
281
556
  │ │ ToolRegistry │ │
282
- │ │ (34 tools) │ │
557
+ │ │ (41 tools) │ │
283
558
  │ └───────────────┘ │
284
559
  │ ┌───────────────┐ │
285
560
  │ │ Storage │──┼──► SQLite
@@ -314,20 +589,34 @@ Installation: Open EasyEDA Pro → **Settings** → **Extensions** → **Extensi
314
589
 
315
590
  ## Development
316
591
 
592
+ ### Prerequisites
593
+
594
+ - **Node.js** >=24 <27
595
+ - **pnpm** >=11
596
+ - **Go Task** (optional, for Taskfile commands)
597
+
598
+ ### Quick Start
599
+
317
600
  ```bash
318
601
  # Setup
319
602
  pnpm install
320
603
  cp .env.example .env
321
604
 
322
- # Code quality
605
+ # All quality gates (lint + format + typecheck + test + build)
606
+ task verify
607
+
608
+ # Or use pnpm directly:
323
609
  pnpm format:check # Prettier
324
610
  pnpm typecheck # TypeScript
325
611
  pnpm lint # ESLint
326
612
 
327
613
  # Test
328
- pnpm test # Vitest (97 tests across 13 files)
614
+ pnpm test # Vitest (120+ tests across 18+ files)
329
615
  pnpm test:coverage # With coverage report
330
616
 
617
+ # Golden E2E fixture smoke tests are included in `pnpm test`
618
+ # See docs/golden-fixtures.md for fixture architecture
619
+
331
620
  # Build & run
332
621
  pnpm build # tsc -> dist/
333
622
  pnpm build:extension # Bundle EasyEDA Pro extension
@@ -339,6 +628,22 @@ pnpm start # Run compiled build
339
628
  pnpm inspector
340
629
  ```
341
630
 
631
+ ### Available Taskfile Commands
632
+
633
+ This project includes a `Taskfile.yml` with the following commands:
634
+
635
+ | Command | Description |
636
+ | ---------------- | ------------------------------- |
637
+ | `task install` | Install dependencies |
638
+ | `task lint` | Run ESLint |
639
+ | `task format` | Check formatting with Prettier |
640
+ | `task typecheck` | Run TypeScript type checking |
641
+ | `task test` | Run tests |
642
+ | `task build` | Build the project |
643
+ | `task verify` | Run all quality gates (CI gate) |
644
+
645
+ Install [Go Task](https://taskfile.dev/installation/) to use these commands.
646
+
342
647
  ### Project structure
343
648
 
344
649
  ```
@@ -354,7 +659,7 @@ src/
354
659
  │ └── transports/
355
660
  │ └── http.ts # HTTP/Streamable HTTP transport
356
661
  ├── storage/ # Node.js sqlite storage (cache, artifacts)
357
- ├── tools/ # 34 MCP tool definitions (6 groups)
662
+ ├── tools/ # 41 MCP tool definitions (6 groups)
358
663
  │ ├── register.ts, registry.ts, types.ts
359
664
  │ ├── L0_diagnostics.ts, L1_schematic.ts, L1_bom.ts
360
665
  │ ├── L1_drc_erc.ts, L1_board.ts, L1_export.ts
@@ -368,12 +673,14 @@ easyeda-bridge-extension/ # EasyEDA Pro bridge extension workspace package
368
673
 
369
674
  ## Security
370
675
 
676
+ See [Security Architecture & Threat Model](docs/security-architecture.md) for the complete security reference, including deployment modes, authentication, tool safety controls, secrets management, safe defaults, supplier API security, threat scenarios, and deployment checklists.
677
+
371
678
  - **Production safety**: Validates config at startup — rejects non-loopback HTTP without OAuth, blocks dangerous features in production
372
- - **OAuth/JWKS**: Optional Bearer token validation via JWKS endpoint for HTTP transport
679
+ - **OAuth/JWKS**: Bearer token validation via JWKS endpoint for HTTP transport (see [OAuth section](docs/security-architecture.md#21-oauth-20--openid-connect-http-transport))
373
680
  - **Rate limiting**: Per-IP sliding window rate limiter on HTTP transport (default 100 req/min)
374
681
  - **Path traversal protection**: All file export paths validated against `ARTIFACT_DIR`
375
682
  - **Secret redaction**: API keys, tokens, passwords are redacted from logs and diagnostic output
376
- - **Branch protection**: `main` branch requires review and up-to-date status checks
683
+ - **Branch protection**: Governance policy requires code reviews and status checks on the `main` branch (see [Repository Governance](docs/REPOSITORY_GOVERNANCE.md))
377
684
  - **Code scanning**: CodeQL analysis runs on every push and PR (security-extended + security-and-quality queries)
378
685
  - **Dependency management**: Renovate automatically updates dependencies with security patches
379
686
  - **Supply-chain hygiene**: pnpm workspace build, pinned GitHub Actions, and no native SQLite addon dependency
@@ -381,6 +688,16 @@ easyeda-bridge-extension/ # EasyEDA Pro bridge extension workspace package
381
688
 
382
689
  ---
383
690
 
691
+ ## Release & Dependency Automation
692
+
693
+ This repository uses automated workflows to manage dependencies and releases:
694
+
695
+ - **Renovate**: Automatically scans and updates dependencies based on rules configured in [.github/renovate.json](.github/renovate.json). For details on PR policies and automerging, see [Repository Governance](docs/REPOSITORY_GOVERNANCE.md).
696
+ - **Release Please**: Automatically bumps package versions, updates files (like `package.json`, `server.json`, `extension.json`), and generates `CHANGELOG.md` upon merging Release PRs. For the full release procedure and Conventional Commit conventions, see [Release Process](docs/RELEASE_PROCESS.md).
697
+ - **Secure Publishing**: The release workflow builds all assets (including `easyeda-bridge-extension.eext`), publishes to the NPM registry with cryptographic provenance, and uploads assets directly to the GitHub release.
698
+
699
+ ---
700
+
384
701
  ## License
385
702
 
386
703
  [MIT](LICENSE)
@@ -0,0 +1,90 @@
1
+ /**
2
+ * BOM quality — supplier adapter layer.
3
+ *
4
+ * Provides a common {@link SupplierAdapter} interface over each vendor
5
+ * client so quality checks can query any configured supplier uniformly.
6
+ *
7
+ * Each adapter:
8
+ * - normalises part data into {@link SupplierQueryResult}
9
+ * - records a query timestamp for provenance
10
+ * - wraps transient errors with an exponential-backoff retry
11
+ *
12
+ * @module
13
+ */
14
+ import { type LcscClient } from '../vendors/lcsc/client.js';
15
+ import { type MouserClient } from '../vendors/mouser/client.js';
16
+ import { type DigiKeyClient } from '../vendors/digikey/client.js';
17
+ import type { SupplierKind, SupplierQueryResult } from './types.js';
18
+ export interface SupplierAdapter {
19
+ /** Short supplier key (e.g. 'lcsc', 'mouser'). */
20
+ readonly kind: SupplierKind;
21
+ /** Human-readable supplier name. */
22
+ readonly displayName: string;
23
+ /** Whether this supplier is configured and available. */
24
+ isAvailable(): boolean;
25
+ /**
26
+ * Query a part by LCSC code or manufacturer part number.
27
+ * Returns `null` when the part is not found (not an error).
28
+ */
29
+ queryPart(identifier: {
30
+ lcsc?: string;
31
+ mpn?: string;
32
+ }): Promise<SupplierQueryResult | null>;
33
+ }
34
+ export declare class LcscAdapter implements SupplierAdapter {
35
+ readonly kind: SupplierKind;
36
+ readonly displayName = "LCSC";
37
+ private client;
38
+ private logger;
39
+ constructor(client: LcscClient | null);
40
+ isAvailable(): boolean;
41
+ private buildFoundResult;
42
+ queryPart(identifier: {
43
+ lcsc?: string;
44
+ mpn?: string;
45
+ }): Promise<SupplierQueryResult | null>;
46
+ }
47
+ export declare class MouserAdapter implements SupplierAdapter {
48
+ readonly kind: SupplierKind;
49
+ readonly displayName = "Mouser";
50
+ private client;
51
+ private logger;
52
+ constructor(client: MouserClient | null);
53
+ isAvailable(): boolean;
54
+ private buildFoundResult;
55
+ queryPart(identifier: {
56
+ lcsc?: string;
57
+ mpn?: string;
58
+ }): Promise<SupplierQueryResult | null>;
59
+ }
60
+ export declare class DigiKeyAdapter implements SupplierAdapter {
61
+ readonly kind: SupplierKind;
62
+ readonly displayName = "DigiKey";
63
+ private client;
64
+ private logger;
65
+ constructor(client: DigiKeyClient | null);
66
+ isAvailable(): boolean;
67
+ private buildFoundResult;
68
+ queryPart(identifier: {
69
+ lcsc?: string;
70
+ mpn?: string;
71
+ }): Promise<SupplierQueryResult | null>;
72
+ }
73
+ export interface AdapterMap {
74
+ lcsc: LcscAdapter;
75
+ mouser: MouserAdapter;
76
+ digikey: DigiKeyAdapter;
77
+ }
78
+ /**
79
+ * Build the adapter map from a ToolContext vendors object.
80
+ * Each adapter wraps the corresponding vendor client (or null if disabled).
81
+ */
82
+ export declare function createAdapters(vendors: {
83
+ lcsc: LcscClient | null;
84
+ mouser: MouserClient | null;
85
+ digikey: DigiKeyClient | null;
86
+ }): AdapterMap;
87
+ /**
88
+ * Return the subset of adapters that are currently configured / available.
89
+ */
90
+ export declare function availableAdapters(adapters: AdapterMap): SupplierAdapter[];