local-bridge
by tianshu-ai
README.md
# local-bridge
`@tianshu-ai/local-bridge` — a lightweight local client that connects
your machine's tools (browser, and more) into a
[tianshu](https://github.com/tianshu-ai/tianshu) server via
**reverse-MCP**.
tianshu runs on a server. This bridge runs on **your** computer, dials
out to the server over a WebSocket, and registers itself as an MCP
server. The server-side agent can then drive your local tools — as if
they were built in — but scoped to your own sessions only.
```
your machine tianshu server
┌──────────────┐ outbound WSS ┌──────────────────┐
│ local-bridge │ ────────────────▶ │ /ws (Local Bridge │
│ • browser │ register tools │ plugin) │
│ tools │ ◀──── tools/call ─│ → agent uses │
└──────────────┘ ──── result ─────▶ │ your tools │
└──────────────────┘
```
## Install & run
Install globally, then use the short `tsbridge` command:
```bash
npm i -g @tianshu-ai/local-bridge
tsbridge --server wss://your-tianshu.example.com/ws --token ***
```
Or run one-off with `npx` (no install):
```bash
npx @tianshu-ai/local-bridge --server wss://your-tianshu.example.com/ws --token ***
```
The **Local Bridge** panel in tianshu shows a ready-to-copy command with
your server URL + token filled in.
### macOS menu-bar app
Prefer a UI? Build a tiny native menu-bar app (no Electron) that wraps
the CLI — a menu-bar icon with Start/Stop + Settings (server / token /
browser engine / headless):
```bash
npm i -g @tianshu-ai/local-bridge
tsbridge install-app --run
```
That installs `Tianshu Bridge.app` to `~/Applications` (menu-bar only, no
Dock icon) and launches it. Click the bolt icon → Settings to configure,
then Start. Requires Xcode command line tools (`xcode-select --install`)
for the one-time `swiftc` build. First launch: right-click → Open
(unsigned local build).
(`app/install-app.sh` is also available for a clone-based build.)
For a local dev server with auth off, the token is optional:
```bash
tsbridge --server ws://localhost:3110/ws
```
> The `tsbridge` and `tianshu-local-bridge` commands are equivalent.
### Keeping it updated
```bash
tsbridge update # update to the latest version if newer (default)
tsbridge update --check # just check; exit 1 if an update is available
tsbridge update --dry-run # print the npm command without running it
tsbridge update --tag next # target a non-`latest` dist-tag
tsbridge version # print the installed version
```
(Same semantics as `tianshu update`.)
### Flags
| flag | meaning |
|---|---|
| `--server <url>` | tianshu chat WS endpoint (required), e.g. `wss://host/ws` |
| `--token <token>` | connection token from the Local Bridge panel |
| `--device <id>` | stable device id (default: hostname) |
| `--label <name>` | human label shown in the panel |
| `--no-browser` | don't expose browser tools |
| `--shell` | expose the shell exec + file sync tools (OFF by default) |
| `--shell-root <dir>` | fixed root dir that jails `exec` + `sync_up`/`sync_down` (default: `~/.tianshu_shell`) |
| `--headless` | run the browser without a window (default: headful) |
| `--cdp <url>` | connect to an already-running Chrome's CDP endpoint (default probe `http://127.0.0.1:9222`; `off` to skip) |
| `--chrome-channel <ch>` | which installed browser to launch: `chrome` (default), `msedge`, … |
| `--user-data-dir <dir>` | reuse a Chrome profile dir so logins carry over |
**No Chromium download.** The bridge uses *your* Chrome:
1. If a Chrome is already running with `--remote-debugging-port=9222`,
it connects to that (your real browser — real cookies + session).
2. Otherwise it launches your system-installed Google Chrome via
Playwright's `channel: "chrome"`. Pass `--user-data-dir` to reuse
your logged-in profile.
To expose your everyday browser, start Chrome with a debugging port:
```bash
# macOS
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --remote-debugging-port=9222
```
## Tools
Both engines expose the **full Playwright-MCP toolset** (navigate,
snapshot, click, type, fill_form, evaluate, tabs, screenshot, …). Only
the underlying browser differs:
- **own** — `@playwright/mcp` pointed at *your* Chrome: connects over CDP
to a Chrome already running with `--remote-debugging-port`, else
launches your system Chrome (`--browser chrome`). Real cookies +
fingerprint, no Chromium download.
- **stealth** — `cloakbrowser-mcp`: the same toolset on CloakBrowser
stealth Chromium (source-level anti-bot-detection patches).
### Shell + file sync
When `--shell` is passed, the bridge also exposes three **native**
tools that run directly on your machine. Their names, parameters and
result shapes mirror tianshu's server-side `openshell` plugin, so an
agent written against openshell works unchanged against a bridge device.
**All three are jailed to a single fixed root directory**
(`~/.tianshu_shell` by default, override with `--shell-root`). `exec`'s
cwd + `workdir`, `sync_up`'s read base, and `sync_down`'s write dest all
resolve *inside* that root; any path that escapes it is rejected.
- **`exec`** — run a shell command via `bash -c`, cwd inside the root.
Params: `command`, optional `workdir` (relative to the root, defaults
to the root itself), optional `timeout_ms` (default 300s, cap 1800s).
Output is truncated at 200 lines / 8000 bytes per stream. Returns
`{ ok, exit_code, stdout, stderr, truncated, duration_ms, timed_out }`.
- **`sync_up`** — read files/dirs under the root and return their bytes
(base64) *up* to the agent. Params: `paths[]` (relative to the root,
directories walked recursively). Per-file cap 8 MiB, ≤500 files/call.
- **`sync_down`** — receive files (base64) from the agent and write them
*down* under the root. Params: `files: [{ path, base64 }]`. Parent
dirs are created; existing files overwritten.
Transport is base64-in-args over the existing reverse-MCP `tools/call`
channel — no protocol changes.
> **Security:** `exec` runs commands with your user's permissions, but
> is confined to the `--shell-root` directory (default `~/.tianshu_shell`)
> — the agent can't `cd` or read/write outside it via these tools. It is
> not a kernel sandbox (a determined command could still reach the wider
> fs), so only connect a bridge to a tianshu server you trust. Because of
> this, shell is **off by default** — add `--shell` only when you want the
> agent to run commands + move files on your machine.
## Protocol
The bridge speaks the reverse-MCP protocol defined authoritatively in the
server repo: `plugins/reverse-mcp/PROTOCOL.md`. It's a thin envelope
around standard MCP JSON-RPC over the authenticated chat WebSocket. This
client imports no tianshu package.
## Develop
```bash
npm install
npm run build
node dist/index.js --server ws://localhost:3110/ws --no-browser
```
Repo: <https://github.com/tianshu-ai/local-bridge>
Apache-2.0.
This server cannot be deployed
Maintenance
ActivityActive
ResponsivenessNo issues