feat: Update naming of local gateway to computer use (#28111)

This commit is contained in:
Dimitri Lavrenük 2026-04-07 17:22:32 +02:00 committed by GitHub
parent 309a739271
commit b841c736df
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
82 changed files with 68 additions and 69 deletions

View file

@ -50,8 +50,8 @@
"watch": "turbo run watch --concurrency=64",
"webhook": "./packages/cli/bin/n8n webhook",
"worker": "./packages/cli/bin/n8n worker",
"dev:fs-proxy": "pnpm --filter @n8n/fs-proxy build && node packages/@n8n/fs-proxy/dist/cli.js serve",
"stop:fs-proxy": "lsof -ti :7655 | xargs kill 2>/dev/null; echo 'fs-proxy stopped'"
"dev:computer-use": "pnpm --filter @n8n/computer-use build && node packages/@n8n/computer-use/dist/cli.js serve",
"stop:computer-use": "lsof -ti :7655 | xargs kill 2>/dev/null; echo 'computer-use stopped'"
},
"devDependencies": {
"@babel/preset-env": "^7.26.0",

View file

@ -1,4 +1,4 @@
# @n8n/fs-proxy
# @n8n/computer-use
Local AI gateway for n8n Instance AI. Bridges a remote n8n instance with your
local machine — filesystem, shell, screenshots, mouse/keyboard, and browser
@ -32,13 +32,13 @@ automatically disabled when their platform requirements aren't met.
Zero-click mode — n8n auto-detects the daemon on `127.0.0.1:7655`:
```bash
npx @n8n/fs-proxy serve
npx @n8n/computer-use serve
# With a specific directory
npx @n8n/fs-proxy serve /path/to/project
npx @n8n/computer-use serve /path/to/project
# Disable browser and mouse/keyboard
npx @n8n/fs-proxy serve --no-browser --no-computer-mouse-keyboard
npx @n8n/computer-use serve --no-browser --no-computer-mouse-keyboard
```
### Direct mode
@ -47,10 +47,10 @@ Connect to a specific n8n instance with a gateway token:
```bash
# Positional syntax
npx @n8n/fs-proxy https://my-n8n.com abc123xyz /path/to/project
npx @n8n/computer-use https://my-n8n.com abc123xyz /path/to/project
# Flag syntax
npx @n8n/fs-proxy --url https://my-n8n.com --api-key abc123xyz --filesystem-dir /path/to/project
npx @n8n/computer-use --url https://my-n8n.com --api-key abc123xyz --filesystem-dir /path/to/project
```
## Configuration
@ -122,7 +122,7 @@ take precedence.
When using the gateway as a library, pass a config object to `GatewayClient`:
```typescript
import { GatewayClient } from '@n8n/fs-proxy';
import { GatewayClient } from '@n8n/computer-use';
const client = new GatewayClient({
url: 'https://my-n8n.com',
@ -254,8 +254,8 @@ For local browser modes, see the
On `npm install`, the package sets up platform-specific auto-start in daemon
mode:
- **macOS**: LaunchAgent at `~/Library/LaunchAgents/com.n8n.fs-proxy.plist`
- **Linux**: systemd user service at `~/.config/systemd/user/n8n-fs-proxy.service`
- **macOS**: LaunchAgent at `~/Library/LaunchAgents/com.n8n.computer-use.plist`
- **Linux**: systemd user service at `~/.config/systemd/user/n8n-computer-use.service`
- **Windows**: VBS script in Windows Startup folder
## Development

View file

@ -1,9 +1,9 @@
{
"name": "@n8n/fs-proxy",
"version": "0.1.0",
"name": "@n8n/computer-use",
"version": "0.2.0",
"description": "Local AI gateway for n8n Instance AI — filesystem, shell, screenshots, mouse/keyboard, and browser automation",
"bin": {
"n8n-fs-proxy": "dist/cli.js"
"n8n-computer-use": "dist/cli.js"
},
"scripts": {
"clean": "rimraf dist .turbo",

View file

@ -24,14 +24,14 @@
The local gateway involves three runtime processes:
- **n8n server** — hosts the REST/SSE endpoints and orchestrates the AI agent.
- **fs-proxy daemon or local-gateway app** — runs on the user's local machine; executes tool calls.
- **computer-use daemon or local-gateway app** — runs on the user's local machine; executes tool calls.
- **Browser (frontend)** — initiates the connection and displays gateway status.
```mermaid
graph LR
FE[Browser / Frontend]
SRV[n8n Server]
DAEMON[fs-proxy Daemon\nlocal machine]
DAEMON[computer-use Daemon\nlocal machine]
FE -- "POST /gateway/create-link\n(user auth)" --> SRV
FE -- "GET /gateway/status\n(user auth)" --> SRV
@ -117,7 +117,7 @@ All paths are prefixed with `/api/v1/instance-ai`.
```typescript
{
token: string; // gw_<nanoid(32)> — pairing token for /gateway/init
command: string; // "npx @n8n/fs-proxy <baseUrl> <token>"
command: string; // "npx @n8n/computer-use <baseUrl> <token>"
}
```
@ -169,10 +169,10 @@ Response: `{ ok: true }` when reconnecting with an active session key.
sequenceDiagram
participant FE as Browser
participant SRV as n8n Server
participant D as fs-proxy Daemon
participant D as computer-use Daemon
FE->>SRV: POST /gateway/create-link (user auth)
SRV-->>FE: { token: "gw_...", command: "npx @n8n/fs-proxy ..." }
SRV-->>FE: { token: "gw_...", command: "npx @n8n/computer-use ..." }
Note over FE: User runs the command on their machine
@ -194,7 +194,7 @@ On reconnect (e.g. after a transient network drop):
```mermaid
sequenceDiagram
participant D as fs-proxy Daemon
participant D as computer-use Daemon
participant SRV as n8n Server
D->>SRV: POST /gateway/init (x-gateway-key: sess_...)
@ -279,7 +279,7 @@ sequenceDiagram
participant A as AI Agent (Mastra tool)
participant GW as LocalGateway
participant SRV as Controller (SSE)
participant D as fs-proxy Daemon
participant D as computer-use Daemon
A->>GW: callTool({ name, args })
GW->>GW: generate requestId, create Promise (30 s timeout)
@ -313,7 +313,7 @@ sequenceDiagram
participant FE as Browser (Frontend)
participant SRV as n8n Server
participant DB as Database
participant D as fs-proxy Daemon
participant D as computer-use Daemon
Note over SRV: First invocation — tool execute() called by Mastra
SRV->>D: callTool({ name, args }) via LocalGateway

View file

@ -88,12 +88,12 @@ function shouldShowHelp(): boolean {
function printUsage(): void {
console.log(`
n8n-fs-proxy Local AI gateway for n8n Instance AI
n8n-computer-use Local AI gateway for n8n Instance AI
Usage:
npx @n8n/fs-proxy serve [directory] [options]
npx @n8n/fs-proxy <url> <token> [directory] [options]
npx @n8n/fs-proxy --url <url> --api-key <token> [options]
npx @n8n/computer-use serve [directory] [options]
npx @n8n/computer-use <url> <token> [directory] [options]
npx @n8n/computer-use --url <url> --api-key <token> [options]
Commands:
serve Start a local daemon that n8n auto-detects

View file

@ -58,7 +58,7 @@ graph TB
Service -->|auto-detect| FSProvider{Provider}
FSProvider -->|bare metal| LocalFS[LocalFilesystemProvider]
FSProvider -->|container/cloud| Gateway[LocalGateway]
Gateway -->|SSE + HTTP POST| Daemon["@n8n/fs-proxy daemon"]
Gateway -->|SSE + HTTP POST| Daemon["@n8n/computer-use daemon"]
end
subgraph n8n ["n8n Services"]

View file

@ -30,7 +30,7 @@ All Instance AI configuration is done via environment variables.
| Variable | Type | Default | Description |
|----------|------|---------|-------------|
| `N8N_INSTANCE_AI_FILESYSTEM_PATH` | string | `''` | Restrict local filesystem access to this directory. When empty, bare-metal installs can read any path the n8n process has access to. When set, `path.resolve()` + `fs.realpath()` containment prevents directory traversal and symlink escape. |
| `N8N_INSTANCE_AI_GATEWAY_API_KEY` | string | `''` | Static API key for the filesystem gateway. Used by the `@n8n/fs-proxy` daemon to authenticate SSE and HTTP POST requests. When empty, the dynamic pairing token flow is used instead. |
| `N8N_INSTANCE_AI_GATEWAY_API_KEY` | string | `''` | Static API key for the filesystem gateway. Used by the `@n8n/computer-use` daemon to authenticate SSE and HTTP POST requests. When empty, the dynamic pairing token flow is used instead. |
**Auto-detection** (no boolean flag needed):
1. `N8N_INSTANCE_AI_FILESYSTEM_PATH` explicitly set → local FS (restricted to that path)
@ -202,7 +202,7 @@ N8N_INSTANCE_AI_FILESYSTEM_PATH=/home/user/my-project
# With filesystem gateway (Docker/cloud — user runs daemon on their machine)
N8N_INSTANCE_AI_MODEL=anthropic/claude-sonnet-4-6
N8N_INSTANCE_AI_GATEWAY_API_KEY=my-secret-key
# User runs: npx @n8n/fs-proxy
# User runs: npx @n8n/computer-use
# With custom OpenAI-compatible endpoint (e.g. LM Studio, Ollama)
N8N_INSTANCE_AI_MODEL=custom/llama-3.1-70b

View file

@ -77,7 +77,7 @@ Agent calls readFile("src/index.ts")
→ Gateway resolves pending Promise → tool gets FileContent back
```
The `@n8n/fs-proxy` CLI daemon is one implementation of this protocol. Any
The `@n8n/computer-use` CLI daemon is one implementation of this protocol. Any
application that speaks SSE + HTTP POST can serve as a gateway — a Mac app,
an Electron desktop app, a VS Code extension, or a mobile companion.
@ -189,17 +189,17 @@ The `InstanceAiDirectoryShare` component has 3 states:
|-------|-----------|-----|
| **Connected** | `isGatewayConnected \|\| isLocalFilesystemEnabled` | Green indicator: "Files connected" |
| **Connecting** | `isDaemonConnecting` | Spinner: "Connecting..." |
| **Setup needed** | Default | `npx @n8n/fs-proxy` command + copy button + waiting spinner |
| **Setup needed** | Default | `npx @n8n/computer-use` command + copy button + waiting spinner |
### Auto-connect flow
The user runs `npx @n8n/fs-proxy` and everything connects automatically. No
The user runs `npx @n8n/computer-use` and everything connects automatically. No
URLs, no tokens, no buttons.
```mermaid
sequenceDiagram
participant UI as Frontend (browser)
participant Daemon as fs-proxy daemon (localhost:7655)
participant Daemon as computer-use daemon (localhost:7655)
participant Server as n8n Backend
UI->>Daemon: GET localhost:7655/health (polling every 5s)
@ -228,7 +228,7 @@ the agent reads the filesystem through local providers without any gateway,
daemon, or pairing.
- The UI immediately shows **"Connected"** (green indicator).
- No `npx @n8n/fs-proxy` needed.
- No `npx @n8n/computer-use` needed.
- If `N8N_INSTANCE_AI_FILESYSTEM_PATH` is set, access is sandboxed to that
directory. Otherwise it is unrestricted.
@ -243,11 +243,11 @@ machine. The gateway bridge is required.
```mermaid
sequenceDiagram
participant Browser as Browser (host)
participant Daemon as fs-proxy daemon (host:7655)
participant Daemon as computer-use daemon (host:7655)
participant Server as n8n server (container)
Note over Browser,Daemon: 1. User starts daemon
Daemon->>Daemon: npx @n8n/fs-proxy (scans project dir)
Daemon->>Daemon: npx @n8n/computer-use (scans project dir)
Note over Browser,Daemon: 2. Browser detects daemon
Browser->>Daemon: GET localhost:7655/health (polling every 5s)
@ -277,7 +277,7 @@ so the gateway bridge is required.
```mermaid
sequenceDiagram
participant Browser as Browser (user's machine)
participant Daemon as fs-proxy daemon (localhost:7655)
participant Daemon as computer-use daemon (localhost:7655)
participant Cloud as n8n Cloud server
Browser->>Daemon: GET localhost:7655/health
@ -300,8 +300,8 @@ firewall rules — SSE is a regular outbound connection.
| Deployment | Access path | Daemon needed? | User action |
|------------|-------------|----------------|-------------|
| Bare metal | Direct (local providers) | No | None — auto-detected |
| Docker / K8s | Gateway bridge | Yes | `npx @n8n/fs-proxy` on host |
| n8n Cloud | Gateway bridge | Yes | `npx @n8n/fs-proxy` on local machine |
| Docker / K8s | Gateway bridge | Yes | `npx @n8n/computer-use` on host |
| n8n Cloud | Gateway bridge | Yes | `npx @n8n/computer-use` on local machine |
Alternatively, setting `N8N_INSTANCE_AI_GATEWAY_API_KEY` on both the n8n
server and the daemon skips the pairing flow entirely — useful for permanent
@ -408,7 +408,7 @@ All key comparisons use `timingSafeEqual()` to prevent timing attacks.
## Extending the Gateway: Building Custom Clients
The gateway protocol is **client-agnostic**`@n8n/fs-proxy` is just one
The gateway protocol is **client-agnostic**`@n8n/computer-use` is just one
implementation. Any application that speaks the protocol can serve as a
filesystem provider: a desktop app (Electron, Tauri), a VS Code extension,
a Go binary, a mobile companion, etc.
@ -504,11 +504,11 @@ See `docs/configuration.md` for the full configuration reference.
|---------|----------------|
| `@n8n/instance-ai` | Agent core: service interfaces, tool definitions, data shapes. Framework-agnostic, zero n8n dependencies. |
| `packages/cli/.../instance-ai/` | n8n backend: HTTP endpoints, gateway singleton, local providers, auto-detect logic, event bus. |
| `@n8n/fs-proxy` | Reference gateway client: standalone CLI daemon. HTTP server, SSE client, local file reader, directory scanner. Independently installable via npx. |
| `@n8n/computer-use` | Reference gateway client: standalone CLI daemon. HTTP server, SSE client, local file reader, directory scanner. Independently installable via npx. |
### Tree scanner behavior
The reference daemon (`@n8n/fs-proxy`) scans the user's project directory on
The reference daemon (`@n8n/computer-use`) scans the user's project directory on
startup:
- **Algorithm**: Breadth-first, broad top-level coverage before descending

View file

@ -58,17 +58,16 @@ function getFilesystemSection(
? capabilityLines.join('\n')
: '- Local machine access capabilities';
return `
## Local Gateway (Not Connected)
## Computer Use (Not Connected)
A **Local Gateway** can connect this n8n instance to the user's local machine, providing:
A **Computer Use** can connect this n8n instance to the user's local machine, providing:
${capList}
The gateway is not currently connected. When the user asks for something that requires local machine access (reading files, browsing, etc.), let them know they can connect by either:
1. **Download the Local Gateway app** https://n8n.io/downloads/local-gateway
2. **Or run via CLI:** \`npx @n8n/fs-proxy serve\`
1. **Run via CLI:** \`npx @n8n/computer-use serve\`
Do NOT attempt to use filesystem tools they are not available until the gateway connects.`;
Do NOT attempt to use Computer Use tools they are not available until the gateway connects.`;
}
if (filesystemAccess) {
@ -96,7 +95,7 @@ function getBrowserSection(
## Browser Automation (Unavailable)
Browser tools require a connected Local Gateway. They are not available until the gateway connects.`;
Browser tools require a connected Computer Use. They are not available until your computer connects.`;
}
return '';
}

View file

@ -79,7 +79,7 @@ function tryParseGatewayConfirmationRequired(
/**
* Build Mastra tools dynamically from the MCP tools advertised by a connected
* local MCP server (e.g. the fs-proxy daemon).
* local MCP server (e.g. the computer-use daemon).
*
* Each tool's input schema is converted from the daemon's JSON Schema definition
* to a Zod schema so the LLM receives accurate parameter information. Falls back

View file

@ -565,7 +565,7 @@ export interface InstanceAiContext {
filesystemService?: InstanceAiFilesystemService;
workspaceService?: InstanceAiWorkspaceService;
/**
* Connected remote MCP server (e.g. fs-proxy daemon). When set, dynamic tools are created from its advertised capabilities. Takes precedence over `filesystemService`.
* Connected remote MCP server (e.g. computer-use daemon). When set, dynamic tools are created from its advertised capabilities. Takes precedence over `filesystemService`.
*/
localMcpServer?: LocalMcpServer;
/** Connection state of the local gateway — drives system prompt guidance. */
@ -842,7 +842,7 @@ export interface OrchestrationContext {
}>;
/** Chrome DevTools MCP config — only present when browser automation is enabled */
browserMcpConfig?: McpServerConfig;
/** Local MCP server (fs-proxy daemon) when connected and advertising browser_* tools,
/** Local MCP server (computer-use daemon) when connected and advertising browser_* tools,
* browser-credential-setup prefers these over chrome-devtools-mcp. */
localMcpServer?: LocalMcpServer;
/** MCP tools loaded from external servers — available for delegation to sub-agents */

View file

@ -93,4 +93,4 @@ src/renderer/ — Settings UI (plain HTML/CSS/TS, sandboxed)
src/shared/ — Types shared between main and renderer
```
The actual gateway daemon is provided by the `@n8n/fs-proxy` package and is managed by `DaemonController`, which starts/stops it and surfaces status (`stopped → starting → waiting → connected → disconnected`) to the tray menu and settings window via IPC.
The actual gateway daemon is provided by the `@n8n/computer-use` package and is managed by `DaemonController`, which starts/stops it and surfaces status (`stopped → starting → waiting → connected → disconnected`) to the tray menu and settings window via IPC.

View file

@ -23,7 +23,7 @@
"postinstall": "node node_modules/electron/install.js"
},
"dependencies": {
"@n8n/fs-proxy": "workspace:*",
"@n8n/computer-use": "workspace:*",
"electron-store": "^8.2.0"
},
"devDependencies": {

View file

@ -1,7 +1,7 @@
import type { GatewayConfig } from '@n8n/fs-proxy/config';
import type { DaemonOptions } from '@n8n/fs-proxy/daemon';
import { startDaemon } from '@n8n/fs-proxy/daemon';
import { logger } from '@n8n/fs-proxy/logger';
import type { GatewayConfig } from '@n8n/computer-use/config';
import type { DaemonOptions } from '@n8n/computer-use/daemon';
import { startDaemon } from '@n8n/computer-use/daemon';
import { logger } from '@n8n/computer-use/logger';
import { EventEmitter } from 'node:events';
import type * as http from 'node:http';

View file

@ -1,4 +1,4 @@
import { configure, logger } from '@n8n/fs-proxy/logger';
import { configure, logger } from '@n8n/computer-use/logger';
import { app, dialog } from 'electron';
import * as path from 'node:path';

View file

@ -1,4 +1,4 @@
import { configure, logger } from '@n8n/fs-proxy/logger';
import { configure, logger } from '@n8n/computer-use/logger';
import { ipcMain } from 'electron';
import type { DaemonController } from './daemon-controller';

View file

@ -1,5 +1,5 @@
import type { GatewayConfig } from '@n8n/fs-proxy/config';
import { logger } from '@n8n/fs-proxy/logger';
import type { GatewayConfig } from '@n8n/computer-use/config';
import { logger } from '@n8n/computer-use/logger';
import { app } from 'electron';
import Store from 'electron-store';
import * as os from 'node:os';

View file

@ -1,4 +1,4 @@
import { logger } from '@n8n/fs-proxy/logger';
import { logger } from '@n8n/computer-use/logger';
import { app, Menu, nativeImage, Tray } from 'electron';
import * as fs from 'node:fs';
import * as path from 'node:path';

View file

@ -691,7 +691,7 @@ describe('InstanceAiController', () => {
expect(result).toEqual({
token: 'pairing-token',
command: 'npx @n8n/fs-proxy http://localhost:5678 pairing-token',
command: 'npx @n8n/computer-use http://localhost:5678 pairing-token',
});
expect(instanceAiService.generatePairingToken).toHaveBeenCalledWith(USER_ID);
});

View file

@ -28,7 +28,7 @@ export interface LocalGatewayEvent {
}
/**
* Singleton MCP gateway for a connected local client (e.g. the fs-proxy daemon).
* Singleton MCP gateway for a connected local client (e.g. the computer-use daemon).
*
* The client advertises its capabilities as `McpTool[]` on connect; all tool
* calls are dispatched generically via the SSE channel. Tools are not limited

View file

@ -530,7 +530,7 @@ export class InstanceAiController {
async createGatewayLink(req: AuthenticatedRequest) {
const token = this.instanceAiService.generatePairingToken(req.user.id);
const baseUrl = this.instanceBaseUrl.replace(/\/$/, '');
const command = `npx @n8n/fs-proxy ${baseUrl} ${token}`;
const command = `npx @n8n/computer-use ${baseUrl} ${token}`;
return { token, command };
}

View file

@ -17,7 +17,7 @@ const isLocalGatewayDisabled = computed(() => {
});
const copied = ref(false);
const displayCommand = computed(() => store.setupCommand ?? 'npx @n8n/fs-proxy');
const displayCommand = computed(() => store.setupCommand ?? 'npx @n8n/computer-use');
async function copyCommand() {
if (!store.setupCommand) return;

View file

@ -1460,7 +1460,7 @@ importers:
specifier: 'catalog:'
version: 3.23.3(zod@3.25.67)
packages/@n8n/fs-proxy:
packages/@n8n/computer-use:
dependencies:
'@anthropic-ai/sandbox-runtime':
specifier: ^0.0.42
@ -1648,9 +1648,9 @@ importers:
packages/@n8n/local-gateway:
dependencies:
'@n8n/fs-proxy':
'@n8n/computer-use':
specifier: workspace:*
version: link:../fs-proxy
version: link:../computer-use
electron-store:
specifier: ^8.2.0
version: 8.2.0