bridgerator 1.0.0 → 1.0.5

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/README.md CHANGED
@@ -1,96 +1,107 @@
1
- # Bridgerator
2
-
3
- Connect your Windows PC to ChatGPT. The assistant can read and edit files, search folders and run
4
- PowerShell commands on **your** computer — through a bridge that only makes an **outbound**
5
- connection. No inbound ports, no remote-desktop software.
6
-
7
- ```
8
- ChatGPT ──OAuth 2.1 + MCP (HTTPS)──► relay (mcp.bridgerator.recondeck.com) ──WebSocket──► bridgerator on your PC ──stdio──► bundled MCP engine
9
- ```
10
-
11
- This repository is the part that runs on your PC. It is small on purpose so you (or an AI agent
12
- installing it for you) can read all of it: `src/bridge.mjs` (forwarder), `src/policy.mjs` (access
13
- rules), `src/dc-isolate.mjs` (separate engine config), `src/cli.mjs` (setup/autostart), `install.ps1` (installer).
14
-
15
- ## Plans
16
-
17
- Free: 15,000 tool calls per month per account, any number of PCs. Pro: $15/month, unlimited.
18
- Details: https://bridgerator.recondeck.com/pricing
19
-
20
- ## Install (Windows)
21
-
22
- 1. Create an account and a device key at https://bridgerator.recondeck.com.
23
- 2. In PowerShell (no admin rights needed):
24
- ```powershell
25
- & ([scriptblock]::Create((irm https://bridgerator.recondeck.com/install.ps1))) -Token <device key>
26
- ```
27
- It installs Node.js LTS if missing (winget), installs this package and runs `bridgerator setup`.
28
- Prefer to read first? Download `install.ps1`, read it, run it with `-Token`.
29
- 3. In ChatGPT: Settings → Apps & Connectors → Advanced → Developer mode → Create → URL
30
- `https://mcp.bridgerator.recondeck.com/mcp`, authentication OAuth, sign in with your account.
31
-
32
- Manual install: `npm install -g github:s-lexer/bridgerator` then `bridgerator setup --token <key>`.
33
-
34
- ## Access rules — what the assistant can and cannot touch
35
-
36
- Config: `%APPDATA%\Bridgerator\config.json` (written by `setup`, edit and restart to change).
37
-
38
- | Key | Meaning | Default |
39
- |---|---|---|
40
- | `allowedDirectories` | File tools work only inside these folders (enforced by the engine). Empty = whole disk. | your user folder |
41
- | `deniedDirectories` | Folders excluded **inside** the allowed ones (enforced by Bridgerator, see below). | `~\.ssh`, `~\AppData` |
42
- | `blockedCommands` | Commands the engine refuses to run. Leave it out to keep the built-in list. | built-in list (`format`, `diskpart`, `reg`, `net`, `sc`, `runas`, `netsh`, `takeown`, …) |
43
- | `disabledTools` | Tools never shown to the assistant, e.g. `["start_process","interact_with_process"]` to turn the terminal off. | none |
44
-
45
- Full file, search and terminal toolset, including ChatGPT widgets (file preview,
46
- config view). Hidden: `set_config_value` (would let the assistant change its own limits), feedback and
47
- usage-stats tools.
48
-
49
- How exclusions work (`src/policy.mjs`): every path argument is resolved (symlinks and junctions
50
- included) and refused if it lies inside an excluded folder; result lines that mention an excluded
51
- path (search hits, recursive listings) are removed; `set_config_value` is never exposed, so the
52
- assistant cannot change these limits.
53
-
54
- ⚠ **The terminal is not a folder sandbox.** A shell command runs with your Windows user's rights
55
- and can read anything you can. Bridgerator refuses commands that literally name an excluded folder,
56
- but that is a courtesy, not a boundary. If folder limits must be strict, add the terminal tools to
57
- `disabledTools`.
58
-
59
- The bridge runs as **your** Windows user (hidden scheduled task at logon), never as SYSTEM.
60
-
61
- Bridgerator gives its bundled engine its **own** config folder (`%APPDATA%\Bridgerator\dc`, see `src/dc-isolate.mjs`): if you already run the same open-source MCP server for Claude or another app, its settings and folder limits are not touched. The engine keeps a local log of recent tool calls in that folder; it never leaves your PC.
62
-
63
- ## Commands
64
-
65
- ```
66
- bridgerator setup --token <key> [--allow <dir>]... [--deny <dir>]... # config + autostart + start
67
- bridgerator run # foreground (what autostart runs)
68
- bridgerator status # config (token masked) + log tail
69
- bridgerator uninstall # stop + remove autostart
70
- ```
71
- Log: `%APPDATA%\Bridgerator\bridge.log`. Stopping the bridge cuts access immediately.
72
-
73
- ## Privacy
74
-
75
- File contents and command output go to ChatGPT (OpenAI) as tool results; the relay forwards them
76
- in memory and does not store them. Engine telemetry, remote feature flags and any browser pop-ups are turned off by the bridge.
77
- Policy: https://bridgerator.recondeck.com/privacy
78
-
79
- ## Development
80
-
81
- `npm test` — policy unit tests plus an end-to-end run against the real bundled engine
82
- (throw-away folders; asserts that an existing config of the same engine stays byte-identical).
83
-
84
- ## License
85
-
86
- MIT. The bundled open-source MCP engine is MIT-licensed as well; its copyright notice is kept in
87
- `LICENSE` and the dependency is listed in `package.json`.
88
-
89
- ---
90
-
91
- ### По-русски коротко
92
- Bridgerator подключает ваш ПК к ChatGPT: файлы, поиск, терминал. Мост только исходящий, входящих
93
- портов нет. Установка — одна строка PowerShell с ключом устройства из кабинета (см. выше).
94
- Разрешённые папки — `allowedDirectories`, исключения внутри них — `deniedDirectories`
95
- (исключения обеспечивает сам Bridgerator). Терминал папками не
96
- ограничивается — для строгих границ выключите его через `disabledTools`.
1
+ # Bridgerator
2
+
3
+ Connect your Windows PC to ChatGPT. The assistant can read and edit files, search folders and run
4
+ PowerShell commands on **your** computer — through a bridge that only makes an **outbound**
5
+ connection. No inbound ports, no remote-desktop software.
6
+
7
+ ```
8
+ ChatGPT ──OAuth 2.1 + MCP (HTTPS)──► relay (mcp.bridgerator.recondeck.com) ──WebSocket──► bridgerator on your PC ──stdio──► bundled MCP engine
9
+ ```
10
+
11
+ This repository is the part that runs on your PC. It is small on purpose so you (or an AI agent
12
+ installing it for you) can read all of it: `src/bridge.mjs` (forwarder), `src/policy.mjs` (access
13
+ rules), `src/dc-isolate.mjs` (separate engine config), `src/cli.mjs` (setup/autostart), `install.ps1` (installer).
14
+
15
+ ## What people use it for
16
+
17
+ - "Sort my Downloads folder by type and month" — ChatGPT lists, plans and moves the files on your PC.
18
+ - "Find every invoice PDF in Documents and rename it by date" — search and rename in plain words.
19
+ - "Why is drive C almost full?" — disk usage, big folders, what is safe to delete.
20
+ - "Check the event log for errors since yesterday" / "Read the end of this log" — diagnostics.
21
+ - Work on code: "explain how D:\\Projects\\app is built and run its tests".
22
+
23
+ Everything runs as your Windows user and only inside the folders you allow.
24
+
25
+ ## Plans
26
+
27
+ Free: 15,000 tool calls per month per account, any number of PCs. Pro: $10/month, unlimited.
28
+ Details: https://bridgerator.recondeck.com/pricing
29
+
30
+ ## Install (Windows)
31
+
32
+ 1. Create an account and a device key at https://bridgerator.recondeck.com.
33
+ 2. In PowerShell (no admin rights needed):
34
+ ```powershell
35
+ & ([scriptblock]::Create((irm https://bridgerator.recondeck.com/install.ps1))) -Token <device key>
36
+ ```
37
+ It downloads portable Node.js LTS if missing (checksum-verified, no admin), installs this package and runs `bridgerator setup`.
38
+ Update later with the same line without `-Token` (the key and folder settings are kept).
39
+ Prefer to read first? Download `install.ps1`, read it, run it with `-Token`.
40
+ 3. In ChatGPT: Settings → Apps & Connectors → Advanced → Developer mode → Create → URL
41
+ `https://mcp.bridgerator.recondeck.com/mcp`, authentication OAuth, sign in with your account.
42
+
43
+ Manual install (PowerShell): `$env:PUPPETEER_SKIP_DOWNLOAD=1; npm install -g bridgerator`, then `bridgerator setup --token <key>`. The variable skips a ~700 MB Chrome download that only PDF export needs; PDF export fetches a browser itself on first use.
44
+
45
+ ## Access rules — what the assistant can and cannot touch
46
+
47
+ Config: `%APPDATA%\Bridgerator\config.json` (written by `setup`, edit and restart to change).
48
+
49
+ | Key | Meaning | Default |
50
+ |---|---|---|
51
+ | `allowedDirectories` | File tools work only inside these folders (enforced by the engine). Empty = whole disk. | your user folder |
52
+ | `deniedDirectories` | Folders excluded **inside** the allowed ones (enforced by Bridgerator, see below). | `~\.ssh`, `~\AppData` |
53
+ | `blockedCommands` | Commands the engine refuses to run. Leave it out to keep the built-in list. | built-in list (`format`, `diskpart`, `reg`, `net`, `sc`, `runas`, `netsh`, `takeown`, …) |
54
+ | `disabledTools` | Tools never shown to the assistant, e.g. `["start_process","interact_with_process"]` to turn the terminal off. | none |
55
+
56
+ Full file, search and terminal toolset, including ChatGPT widgets (file preview,
57
+ config view). Hidden: `set_config_value` (would let the assistant change its own limits), feedback and
58
+ usage-stats tools.
59
+
60
+ How exclusions work (`src/policy.mjs`): every path argument is resolved (symlinks and junctions
61
+ included) and refused if it lies inside an excluded folder; result lines that mention an excluded
62
+ path (search hits, recursive listings) are removed; `set_config_value` is never exposed, so the
63
+ assistant cannot change these limits.
64
+
65
+ ⚠ **The terminal is not a folder sandbox.** A shell command runs with your Windows user's rights
66
+ and can read anything you can. Bridgerator refuses commands that literally name an excluded folder,
67
+ but that is a courtesy, not a boundary. If folder limits must be strict, add the terminal tools to
68
+ `disabledTools`.
69
+
70
+ The bridge runs as **your** Windows user (hidden scheduled task at logon), never as SYSTEM.
71
+
72
+ Bridgerator gives its bundled engine its **own** config folder (`%APPDATA%\Bridgerator\dc`, see `src/dc-isolate.mjs`): if you already run the same open-source MCP server for Claude or another app, its settings and folder limits are not touched. The engine keeps a local log of recent tool calls in that folder; it never leaves your PC.
73
+
74
+ ## Commands
75
+
76
+ ```
77
+ bridgerator setup --token <key> [--allow <dir>]... [--deny <dir>]... # config + autostart + start
78
+ bridgerator run # foreground (what autostart runs)
79
+ bridgerator status # config (token masked) + log tail
80
+ bridgerator uninstall # stop + remove autostart
81
+ ```
82
+ Log: `%APPDATA%\Bridgerator\bridge.log`. Stopping the bridge cuts access immediately.
83
+
84
+ ## Privacy
85
+
86
+ File contents and command output go to ChatGPT (OpenAI) as tool results; the relay forwards them
87
+ in memory and does not store them. Engine telemetry, remote feature flags and any browser pop-ups are turned off by the bridge.
88
+ Policy: https://bridgerator.recondeck.com/privacy
89
+
90
+ ## Development
91
+
92
+ `npm test` — policy unit tests plus an end-to-end run against the real bundled engine
93
+ (throw-away folders; asserts that an existing config of the same engine stays byte-identical).
94
+
95
+ ## License
96
+
97
+ MIT. The bundled open-source MCP engine is MIT-licensed as well; its copyright notice is kept in
98
+ `LICENSE` and the dependency is listed in `package.json`.
99
+
100
+ ---
101
+
102
+ ### По-русски коротко
103
+ Bridgerator подключает ваш ПК к ChatGPT: файлы, поиск, терминал. Мост только исходящий, входящих
104
+ портов нет. Установка — одна строка PowerShell с ключом устройства из кабинета (см. выше).
105
+ Разрешённые папки — `allowedDirectories`, исключения внутри них — `deniedDirectories`
106
+ (исключения обеспечивает сам Bridgerator). Терминал папками не
107
+ ограничивается — для строгих границ выключите его через `disabledTools`.
package/install.ps1 CHANGED
@@ -1,17 +1,19 @@
1
- # Bridgerator installer for Windows (PowerShell 5.1+). Source: https://github.com/s-lexer/bridgerator
1
+ # Bridgerator installer for Windows (PowerShell 5.1+). Source: npm package "bridgerator" (https://www.npmjs.com/package/bridgerator)
2
2
  # Usage (one line, from your Bridgerator account page):
3
3
  # & ([scriptblock]::Create((irm https://bridgerator.recondeck.com/install.ps1))) -Token <device key>
4
+ # Update an installed bridge (keeps its key and folders): the same line without -Token.
4
5
  # What it does: installs Node.js LTS if missing (portable zip, no admin), installs the bridgerator npm package,
5
6
  # then runs `bridgerator setup` (config + hidden autostart at logon for THIS user, no admin rights),
6
7
  # then opens the welcome page in the default browser (skip with -NoBrowser).
7
8
  param(
8
- [Parameter(Mandatory = $true)][string]$Token,
9
+ [string]$Token,
9
10
  [string]$Package = 'https://bridgerator.recondeck.com/bridgerator.tgz',
10
11
  [string[]]$Allow,
11
12
  [string[]]$Deny,
12
13
  [switch]$NoBrowser
13
14
  )
14
15
  $ErrorActionPreference = 'Stop'
16
+ if (-not $Token -and -not (Test-Path (Join-Path $env:APPDATA 'Bridgerator\config.json'))) { throw 'Add -Token <device key> from your Bridgerator account page (https://bridgerator.recondeck.com/app).' }
15
17
 
16
18
  function Refresh-Path {
17
19
  $env:Path = [Environment]::GetEnvironmentVariable('Path', 'Machine') + ';' + [Environment]::GetEnvironmentVariable('Path', 'User')
@@ -61,7 +63,8 @@ Write-Host "Installing bridgerator from $Package ..."
61
63
  if ($LASTEXITCODE -ne 0) { throw 'npm install failed' }
62
64
  Refresh-Path
63
65
 
64
- $setupArgs = @('setup', '--token', $Token)
66
+ $setupArgs = @('setup')
67
+ if ($Token) { $setupArgs += @('--token', $Token) }
65
68
  foreach ($a in $Allow) { $setupArgs += @('--allow', $a) }
66
69
  foreach ($d in $Deny) { $setupArgs += @('--deny', $d) }
67
70
  & bridgerator @setupArgs
package/package.json CHANGED
@@ -1,33 +1,49 @@
1
- {
2
- "name": "bridgerator",
3
- "version": "1.0.0",
4
- "description": "Connect your Windows PC to ChatGPT: files, search and terminal through an outbound-only bridge. Bundles Desktop Commander and adds folder exclusions.",
5
- "license": "MIT",
6
- "type": "module",
7
- "bin": {
8
- "bridgerator": "src/cli.mjs"
9
- },
10
- "files": [
11
- "src",
12
- "install.ps1",
13
- "README.md",
14
- "LICENSE"
15
- ],
16
- "engines": {
17
- "node": ">=20"
18
- },
19
- "scripts": {
20
- "start": "node src/cli.mjs run",
21
- "test": "node --test"
22
- },
23
- "dependencies": {
24
- "@modelcontextprotocol/sdk": "^1.29.0",
25
- "@wonderwhy-er/desktop-commander": "0.2.52",
26
- "ws": "^8.20.0"
27
- },
28
- "repository": {
29
- "type": "git",
30
- "url": "git+https://github.com/s-lexer/bridgerator.git"
31
- },
32
- "homepage": "https://bridgerator.recondeck.com"
33
- }
1
+ {
2
+ "name": "bridgerator",
3
+ "version": "1.0.5",
4
+ "description": "Connect ChatGPT to your Windows PC: files, search and terminal through an outbound-only bridge with folder limits. No inbound ports, no admin rights.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "bin": {
8
+ "bridgerator": "src/cli.mjs"
9
+ },
10
+ "files": [
11
+ "src",
12
+ "install.ps1",
13
+ "README.md",
14
+ "LICENSE"
15
+ ],
16
+ "engines": {
17
+ "node": ">=20"
18
+ },
19
+ "scripts": {
20
+ "start": "node src/cli.mjs run",
21
+ "test": "node --test"
22
+ },
23
+ "dependencies": {
24
+ "@modelcontextprotocol/sdk": "^1.29.0",
25
+ "@wonderwhy-er/desktop-commander": "0.2.52",
26
+ "ws": "^8.20.0"
27
+ },
28
+ "homepage": "https://bridgerator.recondeck.com",
29
+ "keywords": [
30
+ "chatgpt",
31
+ "mcp",
32
+ "mcp-server",
33
+ "model-context-protocol",
34
+ "windows",
35
+ "chatgpt-connector",
36
+ "ai-assistant",
37
+ "remote-files",
38
+ "powershell",
39
+ "openai",
40
+ "apps-sdk",
41
+ "desktop-automation",
42
+ "local-files",
43
+ "bridge"
44
+ ],
45
+ "bugs": {
46
+ "url": "https://bridgerator.recondeck.com/support"
47
+ },
48
+ "author": "Bridgerator <info@recondeck.com>"
49
+ }
package/src/bridge.mjs CHANGED
@@ -9,6 +9,7 @@ import WebSocket from 'ws';
9
9
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
10
10
  import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
11
11
  import { createPolicy, debrand } from './policy.mjs';
12
+ import { showNotice } from './notice.mjs';
12
13
 
13
14
  const RECONNECT_MS = 5000;
14
15
  const DC_ENTRY = createRequire(import.meta.url).resolve('@wonderwhy-er/desktop-commander/dist/index.js');
@@ -70,6 +71,7 @@ export function connect(cfg, dc, log = console.log) {
70
71
  ws.on('message', async (raw) => {
71
72
  let msg; try { msg = JSON.parse(raw); } catch { return; }
72
73
  if (msg.type === 'welcome') { log(`[bridgerator] registered as "${msg.device}"`); return; }
74
+ if (msg.type === 'notice') { showNotice(msg, log); return; }
73
75
  if (msg.type === 'read_resource' && msg.callId) {
74
76
  const r = await dc.readResource(msg.uri);
75
77
  if (ws.readyState === ws.OPEN) ws.send(JSON.stringify({ type: 'result', callId: msg.callId, ...r }));
@@ -8,11 +8,14 @@
8
8
  // open-browser.js — no-ops: the bridge runs hidden and never opens a browser (the engine opens
9
9
  // its vendor's welcome page on first run).
10
10
  // index.js — no Chrome pre-download at start (~400 MB); PDF export still fetches it on demand.
11
+ // terminal-manager — PowerShell (the default shell) writes UTF-8: the engine decodes output as UTF-8,
12
+ // so on Russian & co. Windows (console code page 866/1251) text came out as garbage.
11
13
  const DIR_EXPR = "(process.env.BRIDGERATOR_DC_CONFIG_DIR || path.join(USER_HOME, '.claude-server-commander'))";
12
14
  const PATCHES = [
13
15
  { file: /[\\/]dist[\\/]config\.js$/, from: "const CONFIG_DIR = path.join(USER_HOME, '.claude-server-commander');", to: `const CONFIG_DIR = ${DIR_EXPR};` },
14
16
  { file: /[\\/]dist[\\/]utils[\\/]toolHistory\.js$/, from: "const historyDir = path.join(os.homedir(), '.claude-server-commander');", to: "const historyDir = process.env.BRIDGERATOR_DC_CONFIG_DIR || path.join(os.homedir(), '.claude-server-commander');" },
15
17
  { file: /[\\/]dist[\\/]utils[\\/]open-browser\.js$/, from: 'export async function openWelcomePage', replaceAll: 'export async function openBrowser() {}\nexport async function openWelcomePage() {}\n' },
18
+ { file: /[\\/]dist[\\/]terminal-manager\.js$/, from: "args: ['-Command', command],", to: "args: ['-Command', '[Console]::OutputEncoding=[Text.Encoding]::UTF8;' + command]," },
16
19
  { file: /[\\/]dist[\\/]index\.js$/, from: ' ensureChromeAvailable();\n', to: ' // bridgerator: no Chrome pre-download\n' },
17
20
  ];
18
21
  const ENGINE = /[\\/]@wonderwhy-er[\\/]desktop-commander[\\/]dist[\\/]/;
package/src/notice.mjs ADDED
@@ -0,0 +1,39 @@
1
+ // Plan notices from the relay (limit reached, Pro ending/ended) shown as a Windows notification with
2
+ // an "Open account" button. They never go into the ChatGPT chat (app rules: no upgrade links there).
3
+ // The link is fixed here — the relay only says which notice, not where to send the user.
4
+ import { execFile } from 'node:child_process';
5
+
6
+ export const ACCOUNT_URL = 'https://bridgerator.recondeck.com/app';
7
+ const day = (iso) => String(iso || '').slice(0, 10);
8
+ const xml = (s) => String(s).replace(/[<>&"']/g, (c) => ({ '<': '&lt;', '>': '&gt;', '&': '&amp;', '"': '&quot;', "'": '&apos;' }[c]));
9
+
10
+ // ponytail: English only for now (owner, 20.10); other languages later.
11
+ export function noticeText(n) {
12
+ const t = {
13
+ limit: ['Bridgerator: monthly limit reached', `${n.calls} of ${n.limit} tool calls used. ChatGPT can't use this PC until the 1st. Turn on Pro in your account.`],
14
+ expired: ['Bridgerator Pro has ended', "You're on Free now (15,000 tool calls a month). Renew Pro in your account."],
15
+ expiring: [`Bridgerator Pro ends on ${day(n.until)}`, 'Pay for 30 more days in your account to keep unlimited calls.'],
16
+ }[n.kind];
17
+ return t && { title: t[0], body: t[1], button: 'Open account' };
18
+ }
19
+
20
+ export function toastXml({ title, body, button }) {
21
+ return `<toast activationType="protocol" launch="${ACCOUNT_URL}"><visual><binding template="ToastGeneric"><text>${xml(title)}</text><text>${xml(body)}</text></binding></visual>`
22
+ + `<actions><action content="${xml(button)}" activationType="protocol" arguments="${ACCOUNT_URL}"/></actions></toast>`;
23
+ }
24
+
25
+ export function showNotice(n, log = console.log) {
26
+ const t = noticeText(n);
27
+ if (!t) return;
28
+ log(`[bridgerator] notice: ${t.title} — ${t.body} ${ACCOUNT_URL}`);
29
+ if (process.platform !== 'win32') return;
30
+ // Own app id under HKCU (no admin): the notification header reads "Bridgerator", not "Windows PowerShell".
31
+ const ps = `$k = 'HKCU:\\Software\\Classes\\AppUserModelId\\Bridgerator'
32
+ if (-not (Test-Path $k)) { New-Item $k -Force | Out-Null; New-ItemProperty $k -Name DisplayName -Value 'Bridgerator' -Force | Out-Null }
33
+ [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] > $null
34
+ [Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] > $null
35
+ $x = New-Object Windows.Data.Xml.Dom.XmlDocument
36
+ $x.LoadXml('${toastXml(t).replace(/'/g, "''")}')
37
+ [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier('Bridgerator').Show([Windows.UI.Notifications.ToastNotification]::new($x))`;
38
+ execFile('powershell', ['-NoProfile', '-NonInteractive', '-EncodedCommand', Buffer.from(ps, 'utf16le').toString('base64')], { windowsHide: true }, (e) => { if (e) log(`[bridgerator] notification failed: ${e.message}`); });
39
+ }