@node9/proxy 0.2.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 nadav-node9
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,389 @@
1
+ # πŸ›‘οΈ Node9 Proxy
2
+
3
+ ### The "Sudo" Command for AI Agents.
4
+
5
+ [![NPM Version](https://img.shields.io/npm/v/@node9/proxy.svg)](https://www.npmjs.com/package/@node9/proxy)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ **Node9** is the execution security layer for the Agentic Era. It intercepts AI agent actions β€” via native hooks (Claude Code, Gemini CLI, Cursor) or a JSON-RPC proxy (MCP servers, shell commands) β€” before they reach your production environment.
9
+
10
+ While others try to _guess_ if a prompt is malicious (Semantic Security), Node9 _intercepts_ the actual action (Execution Security).
11
+
12
+ ## πŸ—ΊοΈ Architecture
13
+
14
+ Node9 has two protection modes. The right one depends on your agent:
15
+
16
+ | Agent | Mode | How |
17
+ | -------------- | --------- | -------------------------------------------------------- |
18
+ | Claude Code | **Hook** | `node9 addto claude` β€” hooks fire before every tool call |
19
+ | Gemini CLI | **Hook** | `node9 addto gemini` β€” hooks fire before every tool call |
20
+ | Cursor | **Hook** | `node9 addto cursor` β€” hooks fire before every tool call |
21
+ | MCP Servers | **Proxy** | `node9 "npx <server>"` β€” JSON-RPC interceptor |
22
+ | Shell commands | **Proxy** | `node9 "rm -rf ./data"` β€” evaluates before running |
23
+
24
+ > ⚠️ **`node9 gemini` and `node9 claude` do NOT work** β€” interactive CLIs need a real TTY and communicate via their own hook system, not JSON-RPC. Use `node9 addto` for one-time setup, then run the agent normally.
25
+
26
+ ### Hook Mode (Claude Code, Gemini CLI, Cursor)
27
+
28
+ ```mermaid
29
+ sequenceDiagram
30
+ participant LLM as AI Model
31
+ participant Agent as Agent CLI
32
+ participant Hook as node9 check (PreToolUse hook)
33
+ participant OS as Local System/Shell
34
+
35
+ LLM->>Agent: "Delete the tmp folder"
36
+ Agent->>Hook: PreToolUse fires: Bash { command: "rm -rf ./tmp" }
37
+
38
+ Note over Hook: 🧠 Semantic Parser analyzes AST
39
+ Note over Hook: πŸ›‘οΈ Policy Engine checks rules
40
+
41
+ alt is dangerous & not allowed
42
+ Hook-->>Agent: ❌ exit 1 β€” action blocked
43
+ Agent-->>LLM: "Action blocked by security policy"
44
+ else is safe OR approved by user
45
+ Hook-->>Agent: βœ… exit 0 β€” proceed
46
+ Agent->>OS: Execute: rm -rf ./tmp
47
+ OS-->>Agent: Success
48
+ Agent-->>LLM: "Folder deleted"
49
+ end
50
+ ```
51
+
52
+ ### Proxy Mode (MCP Servers & shell commands)
53
+
54
+ ```mermaid
55
+ sequenceDiagram
56
+ participant Agent as Agent / Caller
57
+ participant Node9 as Node9 Proxy
58
+ participant MCP as MCP Server / Shell
59
+
60
+ Agent->>Node9: JSON-RPC tools/call { command: "rm -rf ./tmp" }
61
+
62
+ Note over Node9: 🧠 Semantic Parser analyzes AST
63
+ Note over Node9: πŸ›‘οΈ Policy Engine checks rules
64
+
65
+ alt is dangerous & not allowed
66
+ Node9-->>Agent: ❌ BLOCK: error response
67
+ else is safe OR approved by user
68
+ Node9->>MCP: Forward original request
69
+ MCP-->>Node9: Result
70
+ Node9-->>Agent: Tool Result: Success
71
+ end
72
+ ```
73
+
74
+ ---
75
+
76
+ ## πŸ›‘ The Problem: Agent Liability
77
+
78
+ In 2026, AI agents have "Write Access" to everything (GitHub, AWS, Stripe, Databases).
79
+
80
+ - **The Risk:** An agent hallucinating a `DROP DATABASE` or an unauthorized `aws.delete_instance`.
81
+ - **The Solution:** Node9 intercepts high-risk tool calls and pauses execution until a human provides a signature.
82
+
83
+ ## πŸš€ Key Features
84
+
85
+ - **Deterministic "Sudo" Mode:** Intercepts dangerous tool calls based on hardcoded policies.
86
+ - **Human-in-the-Loop (HITL):** Requires explicit approval via the **Terminal** (Local) or **Slack** (Cloud).
87
+ - **One-Command Setup:** `node9 addto claude` wires up full protection in seconds β€” no manual config editing.
88
+ - **MCP Native:** Deep-packet inspection of JSON-RPC traffic. Protects any Model Context Protocol server.
89
+ - **Hook Native:** Plugs into Claude Code, Gemini CLI, and Cursor's native hook systems to intercept built-in tools (Bash, Write, Edit) β€” not just MCP calls.
90
+ - **Global Config:** Store your security posture in a `node9.config.json` file in your project root.
91
+
92
+ ---
93
+
94
+ ## πŸ“¦ Installation
95
+
96
+ ```bash
97
+ npm install -g @node9/proxy
98
+ ```
99
+
100
+ ---
101
+
102
+ ## ⚑ Quick Start
103
+
104
+ Node9 provides two layers of protection depending on the agent you use:
105
+
106
+ ### 1. Hook-Based Protection (For Interactive Agents)
107
+
108
+ Interactive CLIs like **Gemini**, **Claude Code**, and **Cursor** require a real terminal. Use the `addto` command to wire up Node9's native hooks:
109
+
110
+ ```bash
111
+ # One-time setup
112
+ node9 addto gemini
113
+ node9 addto claude
114
+ node9 addto cursor
115
+
116
+ # Then run your agent normally! Node9 protection is now automatic.
117
+ gemini
118
+ claude
119
+ ```
120
+
121
+ ### 2. Proxy-Based Protection (For MCP & Shell)
122
+
123
+ For standalone MCP servers or one-off shell commands, use the **Smart Runner** prefix:
124
+
125
+ ```bash
126
+ # Intercepts 'rm -rf /' before starting
127
+ node9 "rm -rf /"
128
+
129
+ # Wraps an MCP server with a security proxy
130
+ node9 "npx @modelcontextprotocol/server-github"
131
+ ```
132
+
133
+ _Note: Always wrap the target command in quotes._
134
+
135
+ ---
136
+
137
+ ## πŸ›  Usage
138
+
139
+ ### 1. Connect to Node9 Cloud (Optional)
140
+
141
+ To route approvals to **Slack** when you are away from your terminal, login once with your API key:
142
+
143
+ ```bash
144
+ node9 login <your_api_key>
145
+ ```
146
+
147
+ _Your credentials are stored in `~/.node9/credentials.json` with `0o600` permissions (owner read/write only)._
148
+
149
+ ### 2. One-Command Agent Setup
150
+
151
+ `node9 addto <target>` wires up Node9 to your AI agent automatically:
152
+
153
+ | Target | MCP Servers | Built-in Tools (Bash, Write, Edit...) | Audit Log |
154
+ | -------- | :---------: | :-----------------------------------: | :-------: |
155
+ | `claude` | βœ… | βœ… via `PreToolUse` hook | βœ… |
156
+ | `gemini` | βœ… | βœ… via `BeforeTool` hook | βœ… |
157
+ | `cursor` | βœ… | βœ… via `preToolUse` hook | βœ… |
158
+
159
+ **What it does under the hood:**
160
+
161
+ - Wraps your existing MCP servers with `node9 proxy` (asks for confirmation first)
162
+ - Adds a pre-execution hook β†’ `node9 check` runs before every tool call
163
+ - Adds a post-execution hook β†’ `node9 log` writes every executed action to `~/.node9/audit.log`
164
+
165
+ ### 3. Local Approval Daemon (Browser UI)
166
+
167
+ For hook-based integrations, Node9 can auto-start a local browser UI to approve or deny dangerous actions without needing a Slack account.
168
+
169
+ ```bash
170
+ # Start manually and keep it running in the background
171
+ node9 daemon --background
172
+
173
+ # Check status / stop
174
+ node9 daemon status
175
+ node9 daemon stop
176
+ ```
177
+
178
+ **How it works:**
179
+
180
+ - When a dangerous tool call arrives and the daemon is running, Node9 routes it to `http://127.0.0.1:7391` and opens your browser.
181
+ - If the daemon is **not** running, Node9 auto-starts it and opens the browser automatically (default behaviour).
182
+ - If you **close the browser tab** without approving or denying, Node9 waits 2 seconds (to allow for an accidental refresh), then abandons the request and falls back to a terminal prompt.
183
+ - After a browser-close abandonment, the daemon shuts down automatically so the next command goes back to the same auto-start flow.
184
+
185
+ **Settings (in the browser UI βš™οΈ):**
186
+
187
+ | Setting | Default | Effect |
188
+ | ----------------- | ------- | ----------------------------------------------------------------------------------- |
189
+ | Auto-start daemon | **On** | Start the daemon + open browser automatically when no approval mechanism is running |
190
+
191
+ Turn "Auto-start daemon" **off** if you prefer to always be asked in the terminal, or if you want to control the daemon lifecycle manually.
192
+
193
+ You can also disable auto-start permanently via `~/.node9/config.json`:
194
+
195
+ ```json
196
+ {
197
+ "settings": {
198
+ "mode": "standard",
199
+ "autoStartDaemon": false
200
+ }
201
+ }
202
+ ```
203
+
204
+ ### 4. Manual Command & MCP Protection
205
+
206
+ To protect any command or MCP server manually:
207
+
208
+ **Protecting a direct command:**
209
+
210
+ ```bash
211
+ node9 "rm -rf ./data"
212
+ ```
213
+
214
+ **Protecting GitHub MCP Server:**
215
+
216
+ ```bash
217
+ node9 "npx @modelcontextprotocol/server-github"
218
+ ```
219
+
220
+ **Note:** Direct proxying (e.g. `node9 gemini`) is not supported for interactive agents. Use `node9 addto` instead.
221
+
222
+ ### 4. SDK β€” Protect Functions in Your Own Code
223
+
224
+ Wrap any async function with `protect()` to require human approval before it runs:
225
+
226
+ ```typescript
227
+ import { protect } from '@node9/proxy';
228
+
229
+ const deleteDatabase = protect('aws.rds.delete_database', async (name: string) => {
230
+ // ... actual deletion logic
231
+ });
232
+
233
+ // Node9 intercepts this and prompts for approval before running
234
+ await deleteDatabase('production-db-v1');
235
+ ```
236
+
237
+ ---
238
+
239
+ ## βš™οΈ Configuration (`node9.config.json`)
240
+
241
+ Add a `node9.config.json` to your project root or `~/.node9/config.json` for global use.
242
+
243
+ ```json
244
+ {
245
+ "settings": {
246
+ "mode": "standard"
247
+ },
248
+ "policy": {
249
+ "dangerousWords": ["delete", "drop", "terminate", "rm", "rmdir"],
250
+ "ignoredTools": ["list_*", "get_*", "read_*"],
251
+ "toolInspection": {
252
+ "bash": "command",
253
+ "shell": "command",
254
+ "run_shell_command": "command"
255
+ },
256
+ "rules": [
257
+ {
258
+ "action": "rm",
259
+ "allowPaths": ["**/node_modules/**", "dist/**", "build/**"]
260
+ }
261
+ ]
262
+ },
263
+ "environments": {
264
+ "production": {
265
+ "requireApproval": true,
266
+ "slackChannel": "#alerts-prod-security"
267
+ },
268
+ "development": {
269
+ "requireApproval": false
270
+ }
271
+ }
272
+ }
273
+ ```
274
+
275
+ **Modes:**
276
+
277
+ - `standard`: Allows everything except tools containing `dangerousWords`.
278
+ - `strict`: Blocks **everything** except tools listed in `ignoredTools`.
279
+
280
+ **Environment overrides** (keyed by `NODE_ENV`):
281
+
282
+ - `requireApproval: false` β€” auto-allow all actions in that environment (useful for local dev).
283
+ - `slackChannel` β€” route cloud approvals to a specific Slack channel for that environment.
284
+
285
+ ### πŸ”Œ Universal Tool Inspection (The "Universal Adapter")
286
+
287
+ Node9 can protect **any** tool, even if it's not Claude or Gemini. You can tell Node9 where to find the "dangerous" payload in any tool call.
288
+
289
+ Example: Protecting a custom "Stripe" MCP server:
290
+
291
+ ```json
292
+ "toolInspection": {
293
+ "stripe.send_refund": "amount",
294
+ "github.delete*": "params.repo_name"
295
+ }
296
+ ```
297
+
298
+ Now, whenever your agent calls `stripe.send_refund`, Node9 will extract the `amount` and check it against your global security policy.
299
+
300
+ ---
301
+
302
+ ## πŸ›‘οΈ How it Works
303
+
304
+ Node9 is **deterministic**. It doesn't use AI to check AI.
305
+
306
+ ### Hook Mode (via `node9 addto`)
307
+
308
+ ```
309
+ Claude wants to run Bash("rm -rf /data")
310
+ β”‚
311
+ PreToolUse hook fires
312
+ β†’ node9 check
313
+ β”‚
314
+ β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”
315
+ β”‚ BLOCKED β”‚ β†’ Claude is told the action was denied
316
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
317
+ OR
318
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
319
+ β”‚ APPROVED β”‚ β†’ Claude runs the command
320
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
321
+ β”‚
322
+ PostToolUse hook fires
323
+ β†’ node9 log β†’ appended to ~/.node9/audit.log
324
+ ```
325
+
326
+ ### Proxy Mode (via `node9 "<command>"`)
327
+
328
+ ```
329
+ 1. Intercept β€” catches the JSON-RPC tools/call request mid-flight
330
+ 2. Evaluate β€” checks against your local node9.config.json
331
+ 3. Suspend β€” execution is frozen in a PENDING state
332
+ 4. Authorize β€” Local: prompt in terminal / Cloud: button in Slack
333
+ 5. Release β€” command forwarded to the target only after approval
334
+ ```
335
+
336
+ ---
337
+
338
+ ## πŸ”§ Troubleshooting
339
+
340
+ **`node9 check` exits immediately / Claude Code is never blocked**
341
+
342
+ Node9 fails open by design β€” if it can't parse the hook payload it exits 0 rather than blocking your agent. Enable debug logging to see what's happening:
343
+
344
+ ```bash
345
+ NODE9_DEBUG=1 claude # logs every hook payload to ~/.node9/hook-debug.log
346
+ ```
347
+
348
+ **Browser opens on every single tool call**
349
+
350
+ The daemon opens the browser only when no tab is already connected. If your browser keeps opening, check that the previous tab is still open. If you'd prefer the terminal prompt instead, disable auto-start in the daemon UI (βš™οΈ Settings β†’ Auto-start daemon: Off).
351
+
352
+ **`node9 daemon stop` says "Not running" even though I see the process**
353
+
354
+ The daemon PID file may be stale. Run `rm ~/.node9/daemon.pid` and try again.
355
+
356
+ **Terminal prompt never appears β€” action is just blocked**
357
+
358
+ The terminal prompt only shows when `process.stdout` is a TTY (i.e. you're running directly in a terminal, not through a pipe). If you're using the hook system (`node9 check`), it runs headless. Start the daemon to get a browser prompt instead:
359
+
360
+ ```bash
361
+ node9 daemon --background
362
+ ```
363
+
364
+ **"Always Allow" / "Always Deny" not taking effect after restart**
365
+
366
+ Persistent decisions are stored in `~/.node9/decisions.json`. If a project `node9.config.json` overrides the `ignoredTools` list in a way that covers the tool, it may be allowed before the decisions file is checked. Look at the config precedence: project config β†’ global config β†’ defaults.
367
+
368
+ ---
369
+
370
+ ## πŸ“ˆ Roadmap
371
+
372
+ - [x] Local Terminal "Sudo" (OSS)
373
+ - [x] MCP JSON-RPC Interceptor
374
+ - [x] Slack Remote Approvals (Pro)
375
+ - [x] One-command setup (`node9 addto claude/gemini/cursor`)
376
+ - [x] Hook-native integration (PreToolUse / BeforeTool / preToolUse)
377
+ - [x] Audit log (`~/.node9/audit.log`)
378
+ - [ ] **Multi-Admin Quorum** (Approve only if 2 admins click)
379
+ - [ ] **SOC2 Tamper-proof Audit Logs** (Enterprise)
380
+
381
+ ---
382
+
383
+ ## 🏒 Enterprise & Commercial Use
384
+
385
+ The local proxy is free forever for individual developers. For teams requiring **Slack Integration**, **VPC Deployment**, and **Tamper-proof Audit Logs**, visit [node9.ai](https://node9.ai) or contact `support@node9.ai`.
386
+
387
+ ---
388
+
389
+ **Safe Agentic Automations Start with Node9.** πŸ›‘οΈπŸš€
package/dist/cli.d.mts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node