staff-mcp 1.3.0 → 2.0.0
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/CHANGELOG.md +29 -0
- package/README.md +152 -55
- package/README_zh.md +155 -53
- package/dist/src/data/HttpDataSession.d.ts +22 -0
- package/dist/src/data/HttpDataSession.js +925 -0
- package/dist/src/data/HttpDataSession.js.map +1 -0
- package/dist/src/data/node.d.ts +4 -0
- package/dist/src/data/node.js +93 -0
- package/dist/src/data/node.js.map +1 -0
- package/dist/src/data/types.d.ts +54 -0
- package/dist/src/data/types.js +2 -0
- package/dist/src/data/types.js.map +1 -0
- package/dist/src/data-stdio-docker.d.ts +10 -0
- package/dist/src/data-stdio-docker.js +140 -0
- package/dist/src/data-stdio-docker.js.map +1 -0
- package/dist/src/docker-proxy.d.ts +6 -1
- package/dist/src/docker-proxy.js +324 -147
- package/dist/src/docker-proxy.js.map +1 -1
- package/dist/src/extensions/apps.d.ts +12 -0
- package/dist/src/extensions/apps.js +85 -0
- package/dist/src/extensions/apps.js.map +1 -0
- package/dist/src/extensions/config.d.ts +27 -0
- package/dist/src/extensions/config.js +91 -0
- package/dist/src/extensions/config.js.map +1 -0
- package/dist/src/extensions/protocol.d.ts +35 -0
- package/dist/src/extensions/protocol.js +47 -0
- package/dist/src/extensions/protocol.js.map +1 -0
- package/dist/src/extensions/runtime.d.ts +16 -0
- package/dist/src/extensions/runtime.js +266 -0
- package/dist/src/extensions/runtime.js.map +1 -0
- package/dist/src/file-manager/extension.d.ts +21 -0
- package/dist/src/file-manager/extension.js +514 -0
- package/dist/src/file-manager/extension.js.map +1 -0
- package/dist/src/file-manager/file-core.d.ts +128 -0
- package/dist/src/file-manager/file-core.js +750 -0
- package/dist/src/file-manager/file-core.js.map +1 -0
- package/dist/src/file-manager/transfers.d.ts +423 -0
- package/dist/src/file-manager/transfers.js +540 -0
- package/dist/src/file-manager/transfers.js.map +1 -0
- package/dist/src/file-manager/ui/index.html +81 -0
- package/dist/src/index.js +276 -131
- package/dist/src/index.js.map +1 -1
- package/dist/src/reverse/SseTransport.d.ts +34 -0
- package/dist/src/reverse/SseTransport.js +215 -0
- package/dist/src/reverse/SseTransport.js.map +1 -0
- package/dist/src/reverse/http.d.ts +7 -0
- package/dist/src/reverse/http.js +85 -0
- package/dist/src/reverse/http.js.map +1 -0
- package/dist/src/server.d.ts +4 -2
- package/dist/src/server.js +80 -18
- package/dist/src/server.js.map +1 -1
- package/dist/src/terminal/extension.d.ts +4 -0
- package/dist/src/terminal/extension.js +108 -0
- package/dist/src/terminal/extension.js.map +1 -0
- package/dist/src/terminal/pty.d.ts +14 -0
- package/dist/src/terminal/pty.js +121 -0
- package/dist/src/terminal/pty.js.map +1 -0
- package/dist/src/terminal/session.d.ts +136 -0
- package/dist/src/terminal/session.js +422 -0
- package/dist/src/terminal/session.js.map +1 -0
- package/dist/src/terminal/ui/index.html +183 -0
- package/dist/src/tools/file-tools.d.ts +2 -1
- package/dist/src/tools/file-tools.js +19 -7
- package/dist/src/tools/file-tools.js.map +1 -1
- package/dist/src/tools/mcp-client-tools.js +243 -103
- package/dist/src/tools/mcp-client-tools.js.map +1 -1
- package/dist/src/tools/shell-tools.js +1 -1
- package/dist/src/tools/shell-tools.js.map +1 -1
- package/dist/src/tools/skills.js +26 -1
- package/dist/src/tools/skills.js.map +1 -1
- package/dist/src/transports/http.d.ts +15 -2
- package/dist/src/transports/http.js +244 -65
- package/dist/src/transports/http.js.map +1 -1
- package/dist/src/transports/reverse.d.ts +23 -19
- package/dist/src/transports/reverse.js +130 -74
- package/dist/src/transports/reverse.js.map +1 -1
- package/dist/src/transports/stdio.d.ts +5 -2
- package/dist/src/transports/stdio.js +130 -20
- package/dist/src/transports/stdio.js.map +1 -1
- package/dist/src/utils/proxy.d.ts +2 -2
- package/dist/src/utils/proxy.js +84 -62
- package/dist/src/utils/proxy.js.map +1 -1
- package/dist/src/utils/server-activity.d.ts +6 -0
- package/dist/src/utils/server-activity.js +46 -0
- package/dist/src/utils/server-activity.js.map +1 -0
- package/dist/src/utils/server-lifecycle.d.ts +5 -0
- package/dist/src/utils/server-lifecycle.js +51 -0
- package/dist/src/utils/server-lifecycle.js.map +1 -0
- package/docs/file-manager.md +179 -0
- package/docs/terminal.md +66 -0
- package/package.json +28 -6
- package/dist/src/transports/fte-lifecycle.d.ts +0 -13
- package/dist/src/transports/fte-lifecycle.js +0 -76
- package/dist/src/transports/fte-lifecycle.js.map +0 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 2.0.0 — 2026-10-26
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- Opt-in file workspace with version-checked editing, attachments and prepared uploads/downloads, independent of model tools.
|
|
8
|
+
- Opt-in human terminal with Linux PTY support and rendering-consumption acknowledgements; terminal bytes stay out of model context and chat history.
|
|
9
|
+
- Shared raw HTTP data sessions for files and streams across supported stdio, Docker, HTTP and reverse connections.
|
|
10
|
+
|
|
11
|
+
### Fixes
|
|
12
|
+
|
|
13
|
+
- Preserve Windows drive/UNC roots during file-path validation without relaxing junction, symlink or workspace boundaries.
|
|
14
|
+
- Keep Docker tool caches writable for same-uid non-root containers and isolated from host-native binaries.
|
|
15
|
+
- Isolate unavailable or incompatible optional extensions from healthy standard MCP tools/resources/prompts; all extensions remain off by default.
|
|
16
|
+
- Tighten HTTP authentication, session capacity/idle expiry and owned-resource cleanup; surface uncertain file publication and potentially incomplete terminal output without automatic replay.
|
|
17
|
+
|
|
18
|
+
### Breaking changes
|
|
19
|
+
|
|
20
|
+
- Reverse and extensions require chat-ai commit `66461d16090456d6f1fee21ce19088dceefd6658` or a later compatible version, including matching host/descriptors/UI assets.
|
|
21
|
+
- The old reverse handshake is incompatible even with extensions disabled. There is no old-protocol compatibility mode, legacy data fallback or automatic transfer/input resumption after disconnect.
|
|
22
|
+
- Node.js **22.22.2 or newer** is required, including in Docker. Linux/local Linux Docker are the primary full-extension environments. Windows native standard MCP (stdio/HTTP) and Windows Docker standard MCP have been validated; non-Linux Docker launchers disable extensions. macOS is untested.
|
|
23
|
+
- Standard stdio/Streamable HTTP tools, resources and prompts remain supported. No Chat8/schema9/format7/share protocol2 data migration is required.
|
|
24
|
+
|
|
25
|
+
### Upgrade
|
|
26
|
+
|
|
27
|
+
1. Finish in-flight operations and back up normal configuration; no data migration is needed.
|
|
28
|
+
2. Upgrade the matching chat-ai host first, then staff-mcp 2.0.0, coordinating downtime for reverse connections.
|
|
29
|
+
3. Reconnect MCP, reopen Apps and explicitly enable the extensions you want (`--extensions files`, `--extensions terminal`, or `--extensions files,terminal`).
|
package/README.md
CHANGED
|
@@ -8,25 +8,56 @@ It provides secure file management, shell execution, LSP-powered code intelligen
|
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
+
## 2.0.0 compatibility and upgrade
|
|
12
|
+
|
|
13
|
+
**Breaking release:** reverse connections and optional extensions require a matching chat-ai host: commit `66461d16090456d6f1fee21ce19088dceefd6658` or a later compatible version. Upgrade the host, staff-mcp, descriptors and UI assets together.
|
|
14
|
+
|
|
15
|
+
Standard stdio/Streamable HTTP tools, resources and prompts remain supported. Extensions are **all off by default**; unavailable or incompatible optional capabilities must not break an otherwise healthy standard MCP connection. The old reverse handshake itself is incompatible, even with extensions disabled: extension degradation cannot replace the paired reverse upgrade. There is no old-protocol compatibility mode, automatic transfer resumption or input replay after disconnect.
|
|
16
|
+
|
|
17
|
+
No Chat8/schema9/format7/share protocol2 data migration is required.
|
|
18
|
+
|
|
19
|
+
1. Finish in-flight operations and back up your normal configuration; no data conversion is needed.
|
|
20
|
+
2. Upgrade the matching chat-ai host first, then staff-mcp 2.0.0, coordinating downtime for reverse connections.
|
|
21
|
+
3. Reconnect MCP, reopen Apps and explicitly enable only the extensions you want.
|
|
22
|
+
|
|
23
|
+
See [CHANGELOG](CHANGELOG.md) for the release summary.
|
|
24
|
+
|
|
11
25
|
## 🚀 Quick Start
|
|
12
26
|
|
|
13
|
-
Requires **Node.js 22.22.2 or newer
|
|
27
|
+
Requires **Node.js 22.22.2 or newer**, including inside Docker images.
|
|
28
|
+
|
|
29
|
+
Linux and Linux-host local Docker Engine are the primary full-extension environments, subject to the prerequisites below. Windows native standard MCP (stdio and HTTP) and Windows Docker standard MCP have been validated, not full extensions. Non-Linux Docker launchers disable optional extensions. **macOS has not been tested**; path translation is not a claim of platform support.
|
|
30
|
+
|
|
31
|
+
Run the published package directly with an explicit version:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npx --yes staff-mcp@2.0.0 --working-dir /path/to/your/project
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
For a source checkout of staff-mcp 2.0.0, install dependencies and build before using the absolute entrypoint in the examples:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm ci
|
|
41
|
+
npm run build
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Replace `/path/to/staff-mcp` with that checkout/build directory. Docker read-only mounts still require a compatible Node/native ABI/libc; in particular an optional PTY built for a different system is not guaranteed to work inside the image.
|
|
14
45
|
|
|
15
46
|
### 1. Standard Host Mode
|
|
16
47
|
Run directly on your physical machine or virtual environment.
|
|
17
48
|
```bash
|
|
18
|
-
|
|
49
|
+
node /path/to/staff-mcp/dist/src/index.js --working-dir /path/to/your/project
|
|
19
50
|
```
|
|
20
51
|
|
|
21
52
|
### 2. Docker Transparent Proxy Mode (Cyber-Shell)
|
|
22
|
-
|
|
53
|
+
Run staff-mcp inside a compatible Docker image while keeping standard MCP control connected to the host. The wrapper mounts the project and package; image startup, Node/native ABI/libc and mount permissions still apply. Linux host + local Docker Engine is the full-extension path. Non-Linux Docker launchers disable optional Apps/files/terminal extensions with a warning; Windows Docker standard MCP has been validated, while macOS is untested; base Docker connectivity still requires a reachable daemon and valid bind mounts.
|
|
23
54
|
|
|
24
55
|
```bash
|
|
25
56
|
# Debug a Node.js project inside a pure Alpine container
|
|
26
|
-
|
|
57
|
+
node /path/to/staff-mcp/dist/src/index.js --docker node:22-alpine
|
|
27
58
|
|
|
28
59
|
# Perform security analysis inside a custom reverse-engineering image
|
|
29
|
-
|
|
60
|
+
node /path/to/staff-mcp/dist/src/index.js --docker chineseastar/security:latest --profile android-reverse
|
|
30
61
|
```
|
|
31
62
|
|
|
32
63
|
### 3. Claude Desktop Configuration
|
|
@@ -36,10 +67,9 @@ Add the following to your `claude_desktop_config.json`:
|
|
|
36
67
|
{
|
|
37
68
|
"mcpServers": {
|
|
38
69
|
"staff-mcp": {
|
|
39
|
-
"command": "
|
|
70
|
+
"command": "node",
|
|
40
71
|
"args": [
|
|
41
|
-
"-
|
|
42
|
-
"staff-mcp@latest",
|
|
72
|
+
"/path/to/staff-mcp/dist/src/index.js",
|
|
43
73
|
"--working-dir",
|
|
44
74
|
"/path/to/your/project"
|
|
45
75
|
]
|
|
@@ -49,66 +79,117 @@ Add the following to your `claude_desktop_config.json`:
|
|
|
49
79
|
```
|
|
50
80
|
|
|
51
81
|
### 4. Reverse MCP Mode (Intranet Penetration)
|
|
52
|
-
Connect
|
|
82
|
+
Connect outward from behind NAT/firewalls to chat-ai's existing Web entrypoint, without an inbound listener on staff. Control uses SSE + POST; remote-initiated raw HTTP GET/PUT carries file/terminal bytes on that same Web port. The administrator explicitly configures `MCP_REVERSE_URL` on chat-ai; it is not guessed from a private port. Reconnect creates fresh sessions and never replays tool calls, transfer handles or terminal input.
|
|
53
83
|
|
|
54
84
|
```bash
|
|
55
|
-
|
|
56
|
-
--ru https://chat.
|
|
85
|
+
node /path/to/staff-mcp/dist/src/index.js -t reverse \
|
|
86
|
+
--ru https://chat.example.com/api/mcp/reverse \
|
|
57
87
|
--rt your_secure_token_here \
|
|
58
|
-
--rn my-
|
|
88
|
+
--rn my-workstation
|
|
59
89
|
```
|
|
60
90
|
|
|
61
91
|
### 5. Authenticated HTTP Mode
|
|
62
92
|
|
|
63
|
-
HTTP authentication is optional
|
|
93
|
+
HTTP authentication is optional. Set `--ht` / `--http-token`
|
|
64
94
|
to a strong, random token to require authentication:
|
|
65
95
|
|
|
66
96
|
```bash
|
|
67
|
-
|
|
97
|
+
node /path/to/staff-mcp/dist/src/index.js -t http -p 3000 \
|
|
68
98
|
--http-token your_secure_token_here --working-dir /path/to/your/project
|
|
69
99
|
```
|
|
70
100
|
|
|
71
|
-
When a token is configured, clients must send `Authorization: Bearer <token>` on every request.
|
|
101
|
+
When a token is configured, clients must send `Authorization: Bearer <token>` on every MCP control request.
|
|
72
102
|
For a full Authorization-header field, enter `Bearer <token>`; for a Bearer-token
|
|
73
103
|
field, enter only the token. Raw tokens without the `Bearer` scheme are rejected.
|
|
74
104
|
Missing or incorrect credentials return HTTP 401, including requests with an
|
|
75
105
|
existing `mcp-session-id`. Authentication covers `/mcp` and the legacy `/sse` and
|
|
76
106
|
`/messages` routes. CORS `OPTIONS` preflight remains public and cannot invoke MCP.
|
|
107
|
+
The raw `/mcp/data/...` routes use their own negotiated, connection-bound data
|
|
108
|
+
Bearer token plus `X-Data-Binding`, not the shared MCP control token.
|
|
77
109
|
|
|
78
|
-
Omitting `--http-token`
|
|
110
|
+
Omitting `--http-token` leaves MCP control on the HTTP listener unauthenticated.
|
|
79
111
|
Anyone who can reach such a server can invoke its tools, so use this mode only
|
|
80
112
|
on trusted networks. An explicitly empty token or one containing whitespace is
|
|
81
113
|
rejected at startup. `--docker` forwards `--http-token` to the container command
|
|
82
114
|
only when provided.
|
|
83
115
|
Command-line tokens may be visible in shell history and process listings; keep
|
|
84
|
-
access to those restricted. Stdio and reverse
|
|
116
|
+
access to those restricted. Stdio and reverse use separate authentication paths;
|
|
85
117
|
`--reverse-token` does not configure HTTP auth.
|
|
86
118
|
Use HTTPS through a reverse proxy for remote access, since plain HTTP does not
|
|
87
119
|
protect the token in transit. This is a shared server token, not an OAuth flow.
|
|
88
120
|
|
|
89
121
|
---
|
|
90
122
|
|
|
91
|
-
## Reverse
|
|
123
|
+
## Reverse v1 and protocol boundary
|
|
124
|
+
|
|
125
|
+
The authoritative custom protocol is `chat-ai/docs/protocol/README.md` at the compatible host version specified above. chat-ai, staff-mcp and third parties can implement it independently; no extension SDK is required. The official MCP SDK, standard stdio/Streamable HTTP and tools/resources/prompts remain unchanged. There is no old FTE chunk or WS fallback, and no chat database migration.
|
|
126
|
+
|
|
127
|
+
Reverse GETs `<base>/sse` with `Authorization: Bearer <token>` and `X-MCP-Server-Name`; an SSE endpoint event supplies the POST message URL. SSE message events contain ordinary MCP JSON-RPC, not a private envelope. Explicit HTTP and HTTPS are accepted; HTTP logs one plaintext warning per start and does not protect tokens or payloads. Use HTTPS on untrusted networks; HTTPS verifies CA and target identity without automatic downgrade. The configured base URL has no credentials, query or fragment. No WebSocket upgrade, gateway process, launcher or private host leg is required. SDK initialization, data-session readiness and current user authorization remain separate checks; short-lived connections do not reset exponential backoff.
|
|
92
128
|
|
|
93
|
-
|
|
129
|
+
Optional CLI timeouts (milliseconds, forwarded in Docker mode):
|
|
94
130
|
|
|
95
|
-
|
|
131
|
+
- `--reverse-connect-timeout`: 15000; 0 disables only the SSE connection deadline.
|
|
132
|
+
- `--reverse-initialization-timeout`: 15000; must be positive. Starts after the SSE connection and endpoint are established, not while waiting to connect; remains active when the connection deadline is disabled.
|
|
133
|
+
- `--reverse-read-timeout`: 45000; heartbeat liveness, not tool execution duration.
|
|
134
|
+
- `--reverse-stable-time`: 30000; stable lifetime before retry reset (0 resets immediately).
|
|
96
135
|
|
|
97
|
-
|
|
98
|
-
- `--reverse-initialization-timeout`: 15000; must be positive.
|
|
99
|
-
- `--reverse-read-timeout`: 45000; liveness monitoring, not tool execution duration.
|
|
100
|
-
- `--reverse-stable-time`: 30000; lifetime required before resetting the retry cycle (0 restores immediate reset).
|
|
136
|
+
`skill` / `read_skill_file` continue returning `_meta: { persistent: true }`. chat-ai consumes this host metadata hint, not `structuredContent.persistent`; it is not an MCP storage option. This does not relax the new reverse/extension compatibility requirement or change Chat8/schema9/format7/share protocol2.
|
|
101
137
|
|
|
102
|
-
`
|
|
138
|
+
The two reverse transport sources (`src/reverse/SseTransport.ts` and chat-ai's `ReverseSseTransport.ts`) can later be extracted into MCP Client (host)/Server (remote) SDKs: SDK/standard-library imports plus injected URL/endpoint, headers and fetch, with transparent JSON-RPC and no data-protocol interception. No SDK package is being split out now. `src/reverse/http.ts` (Undici/TLS/proxy policy), `src/transports/reverse.ts` (server factory, extension/data setup, initialization and reconnect backoff), and host Web auth/management stay in integration, outside the pure transport boundary. The endpoint uses `session`, with no old `sessionId` compatibility or replay.
|
|
103
139
|
|
|
104
140
|
## 🛠️ Core Capabilities
|
|
105
141
|
|
|
142
|
+
Extensions are **all off by default**. Use `--extensions files`, `--extensions terminal`, or `--extensions files,terminal`; apps/data dependencies and terminal's streams v1 manifest are added automatically, not selected separately. Disabled features advertise no manifest entry and register no corresponding UI Resource or business handler. With both off there is no extension manifest or application data listener/session; ordinary MCP tools and non-UI Resources remain. HTTP mode still opens its normal MCP listener.
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
# Files only, with the default main root at --working-dir
|
|
146
|
+
node /path/to/staff-mcp/dist/src/index.js --extensions files -w /workspace
|
|
147
|
+
# Terminal only; does not enable the file app
|
|
148
|
+
node /path/to/staff-mcp/dist/src/index.js --extensions terminal --shell /bin/bash
|
|
149
|
+
# Both apps, with explicit file roots replacing the default main root
|
|
150
|
+
node /path/to/staff-mcp/dist/src/index.js --extensions files,terminal -w /workspace \
|
|
151
|
+
--file-root main=/workspace --file-root assets=/srv/assets
|
|
152
|
+
# Explicit full-filesystem file access on a suitable Linux host (not a default)
|
|
153
|
+
node /path/to/staff-mcp/dist/src/index.js --extensions files --file-root system=/
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
`--file-root id=path` may repeat; IDs must be unique lowercase letters/digits/hyphens, and relative paths resolve from the launching process cwd. Explicit roots replace, rather than append to, the default `main`. They affect the file app and its standard file Resources only when files is enabled, not the standard tools' `--working-dir` / `--allowed-dir` scope or terminal's default workspace cwd. Selecting `/` explicitly exposes the filesystem visible to the staff identity; it does not elevate privileges or create an OS security boundary. The library accepts [`ExtensionOptions`](src/extensions/config.ts): `{enabled?:('files'|'terminal')[],fileRoots?:{rootId:string,directory:string}[],shell?:string}`, with `enabled` defaulting to `[]`.
|
|
157
|
+
|
|
158
|
+
### Independent file workspace
|
|
159
|
+
|
|
160
|
+
With `--extensions files`, the file manager is discovered under `experimental["cc.qqxing/extensions"]` (apps/files/data v1), then `cc.qqxing/apps/v1/list`, independently of model Tools. File CRUD, drafts, attachments and explicit download saving retain their existing behavior. The app and `transfer_file` share files v1 and the same public HTTP dataSession used by terminal: `cc.qqxing/data/v1/configure {binding}`, then `open` binds a prepared resource. Local stdio lazily opens loopback, local Docker stdio maps it automatically, direct HTTP shares the MCP port, and reverse actively GETs/PUTs the host Web port. Raw binary and cumulative consumption ACKs use a 256 KiB sliding window, not Base64 or per-chunk stop-and-wait. Clients that do not negotiate apps can still use ordinary tools and non-UI Resources. File roots do not broaden tool permissions; no FTE fallback. See [File manager contract and UI build](docs/file-manager.md) for exact methods, lifecycle, limits and packaging.
|
|
161
|
+
|
|
162
|
+
New Apps reusing supported RPC/Resources, files or streams need only their own descriptor, business handlers and UI, not host-core business branches. Truly new host permissions/capabilities require explicit registration at the host discovery/validation, server resource-module and browser-bridge composition roots. Unknown capabilities hide that App; malformed known ones remain validation errors.
|
|
163
|
+
|
|
164
|
+
### Human terminal (explicit extension opt-in)
|
|
165
|
+
|
|
166
|
+
`--extensions terminal` needs Linux, a loadable optional `node-pty`, an executable shell and negotiated streams/data v1 with a usable duplex dataSession over local stdio/Docker, direct HTTP or reverse. If Linux/native PTY/shell requirements are unavailable, staff warns on stderr and omits terminal/streams from discovery; standard MCP and an available files extension remain usable. The default disabled state never loads the native PTY. `--shell` accepts an absolute executable path; otherwise a valid absolute executable `$SHELL` is used, falling back to `/bin/bash`. The interactive shell honors normal startup files and inherits staff's environment except exact internal control keys documented in the [terminal contract](docs/terminal.md). chat-ai uses the existing current-chat MCP grant and same-origin browser requests, with no extra terminal permission switch or high-risk confirmation. Terminal follows the host site's HTTP/HTTPS deployment policy without a terminal-specific TLS gate or origin allowlist. HTTPS is recommended for the entire site to protect login sessions, tool calls and terminal traffic; allowing HTTP does not encrypt those requests.
|
|
167
|
+
|
|
168
|
+
The PTY starts at the staff workspace (`main`) by default, independently of file roots, and runs as the staff process uid: its starting root/cwd is **not a sandbox** and shell filesystem/network effects are not restricted by file-tool path checks. Terminal bytes never enter model context or chat history. Each stream uses one same-origin browser-to-chat-ai WebSocket at `/api/mcp/app-stream` (`chat-app-stream-v1`) for input, output, resize, presence and real xterm consumption ACKs. The backend remains the shared HTTP dataSession. Browser presence refreshes every 10 seconds with a separate 120-second host deadline; the host generic stream module schedules remote renewal from each returned lease (staff defaults to 30 seconds). Opening the Shell App starts one PTY without another open button or confirmation. Exit, PTY failure or disconnection leaves the app shell for manual reconnect; ordinary hidden views keep read/ACK/presence but reject new input and resize. Actual page exit, close, revocation or expiry cleans up; descendant cleanup is best effort, not rollback.
|
|
169
|
+
|
|
170
|
+
Current descriptors and iframe assets keep **bridge v1** with explicit `scope:"workspace"` for files and `scope:"chat"` for terminal. The file App declares `capabilities.files:{version:1,upload:true,download:true}`; terminal declares `capabilities.streams:{version:1,purpose,create,renew,status,close,commands}` and requires streams/data v1. Its business RPC and data purpose remain `cc.qqxing/terminal`; host lifecycle methods use generic envelopes and opaque metadata, not PTY fields. The 2.0.0 extension contract requires matching host/descriptors/assets; deploy them together and reopen Apps, with no legacy compatibility path. Files-v1 adds its own `stat` for force-copy version checks, independent of the file-manager App; byte budgets owned by chat-ai are not remote business limits. See the [host/bridge boundary](docs/file-manager.md#host-boundary-and-bridge-v1).
|
|
171
|
+
|
|
172
|
+
Backpressured PTY exit may have incomplete output. Current source reports remote `status.error:{code:"OUTPUT_INCOMPLETE",message:string}` and host generic stream frame `incomplete?:boolean` / `error?:{code:string,message:string}` for abnormal close/status, with UI warning handling. The generic boolean is `incomplete`; the app-local terminal adapter maps it to its own presentation warning. It is not a remote status field. These diagnostics detect possible loss; they do not recover missing bytes or guarantee lossless output, even with exit code 0 or EOF. See [Terminal UI contract](docs/terminal.md).
|
|
173
|
+
|
|
106
174
|
### 1. Seamless Containerization (`--docker`)
|
|
107
175
|
Never pollute your host machine again. By simply appending `--docker <image>`, `staff-mcp`:
|
|
108
176
|
- Instantly injects itself into the container via read-only bind mounts (no `npm install` inside the container).
|
|
109
177
|
- Automatically translates Windows/Mac paths to Linux container paths.
|
|
110
178
|
- Names containers after their launch context (e.g. `staff-mcp-myproj-3000-a1b2c3` = workspace `myproj`, HTTP port `3000`, random suffix `a1b2c3`), so multiple sessions are easy to tell apart in `docker ps`.
|
|
111
|
-
-
|
|
179
|
+
- Mounts a dedicated Docker tools cache (`<staff-global>/tools/docker`) at `/opt/.staff/tools`, alongside the existing skills/profiles mounts. A matching non-root uid can write tools without creating directories in the image, and container-installed tools do not overwrite the host tool cache. Existing mount permissions still apply; no automatic chown or chmod.
|
|
180
|
+
- Allows `--docker-args` for compatible hardware/environment settings (e.g., ADB USB debugging or GPUs). Unsupported stdio data topologies disable optional extensions, not the MCP control connection; overrides of managed bootstrap/mapping and container lifecycle controls remain errors.
|
|
181
|
+
|
|
182
|
+
For **supported Linux local Docker stdio with at least one effective extension enabled**, the existing wrapper reserves a private container port published to a random **127.0.0.1** host port and inspects only its own cidfile container. A read-only mount of a host **0600 metadata file** supplies the reachable base URL without rewriting stdin/stdout or asking users to discover container IPs. The application listener remains lazy until `data/v1/configure`. With all extensions off, `dataAuto` is false: no application-data port publication, metadata mount or bootstrap is created. Ordinary workspace/package mounts are unchanged. Non-Docker stdio also has no application listener before configure. HTTP/reverse add no such publication; disabled extensions create no dataSession, while HTTP retains its MCP listener.
|
|
183
|
+
|
|
184
|
+
When files is enabled, each explicit Docker `--file-root id=path` bind-mounts that host path at `/opt/staff-file-roots/<id>`. Thus `--file-root system=/` explicitly binds the host root there, rather than referring only to the container root. This is a deliberate wide filesystem exposure, not automatic host privilege acquisition or a claim of support across all platforms; actual OS/container permissions and Docker topology still apply. Default file `main` and terminal cwd use the existing workspace mount.
|
|
185
|
+
|
|
186
|
+
This application-data path requires a local daemon and the host client/wrapper sharing reachable loopback, with compatible bridge/port publication. Non-Linux Docker launchers and incompatible stdio data topologies (remote/TCP/SSH daemon or host/container networking) warn and omit optional extensions; they retain ordinary MCP control/tools when Docker itself can start. HTTP/reverse do not need this stdio mapping. A failed data bootstrap or unavailable data configuration must not terminate an otherwise healthy MCP connection: data-dependent Apps stay unavailable, with no legacy byte fallback or operation replay. Loopback publication is not isolation from hostile containers. Metadata stays 0600 and must be readable by the container uid; workspace/global-directory permissions and PTY ABI/libc still apply. No automatic chown, permission relaxation or browser-user identity switch is performed. Normal exit/signals still clean the owned container, publication and metadata; no cross-restart resource recovery is promised.
|
|
187
|
+
|
|
188
|
+
### Optional extensions do not define MCP connectivity
|
|
189
|
+
|
|
190
|
+
Availability is determined separately for files, terminal and the per-connection data channel. A missing terminal runtime disables terminal only; an unavailable configured file root disables the optional file extension while preserving the standard workspace tools/resources. Unknown or incompatible extension versions do not enable their handlers or Apps. chat-ai keeps successfully initialized standard tools/resources/prompts if optional Apps discovery or data configuration fails. Warnings go to stderr, never stdio JSON-RPC stdout.
|
|
191
|
+
|
|
192
|
+
This is not an authentication or lifecycle bypass: malformed CLI arguments, Docker launch failure, invalid credentials, and failed standard MCP transport/initialization remain errors. Workspace/global-mount access errors still fail the affected startup or file/tool operation; optional-extension degradation does not grant access or promise that every directory is prevalidated. Old/new incompatible reverse control protocols still require paired upgrades; optional capability degradation does not make those wire protocols compatible. No failed or uncertain file commit/tool/terminal input is automatically retried.
|
|
112
193
|
|
|
113
194
|
### 2. Skill & Profile Ecosystem (`--profile`)
|
|
114
195
|
`staff-mcp` acts as an "AI Workspace Configurator". It uses a **5-tier Cascade Resolution** architecture to load role-specific skills (SOPs & Prompts) dynamically, all under the unified `.staff` directory convention:
|
|
@@ -127,10 +208,36 @@ Only the project-level `.staff/skills/` directory is live-watched. The directory
|
|
|
127
208
|
|
|
128
209
|
Switch roles on the fly:
|
|
129
210
|
```bash
|
|
130
|
-
|
|
131
|
-
|
|
211
|
+
node /path/to/staff-mcp/dist/src/index.js --profile default
|
|
212
|
+
node /path/to/staff-mcp/dist/src/index.js --profile android-reverse
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### HTTP session capacity and idle expiry
|
|
216
|
+
|
|
217
|
+
Each HTTP listener admits at most **64 sessions** by default. Starting sessions and sessions whose cleanup is still pending or failed count toward that limit. A full listener returns HTTP **429** for new initialization without evicting an existing session; successful cleanup frees the slot. Use `--http-max-sessions <positive integer>` to configure it. This is independent of `--max-mcp-sessions`, which limits managed child MCP servers.
|
|
218
|
+
|
|
219
|
+
An HTTP session becomes eligible for cleanup after **30 minutes of observed inactivity** (`--http-session-idle-ms <milliseconds>`, 1..2147483647). A single sweep runs at most once per minute (or at the shorter configured timeout). A valid incoming MCP control message restarts the idle grace. Idle GET/SSE connections, server notifications, invalid HTTP requests and unauthenticated data attempts do not keep a session alive.
|
|
220
|
+
|
|
221
|
+
Running request handlers (even after HTTP disconnect/cancellation), file preparation/valid leases/in-flight writes or commits, pending data setup/open channels, and owned PTYs or output/exit draining prevent idle eviction. These facts come from their existing owners; the idle policy does not renew business leases or equate cancellation with completion. After activity settles, the next idle observation starts a full grace interval. Completed result records and an empty configured data session alone do not pin the connection.
|
|
222
|
+
|
|
223
|
+
An expired session ID returns HTTP **404**, including with an initialize body. Reconnect explicitly without the old ID; no tool, file commit or terminal input is replayed. Keeping an App iframe or an unsaved browser draft open does not pin an otherwise inactive server connection. The draft stays client-owned, but server operations require a new connection/App after expiry. This timeout applies only to HTTP listener sessions, not stdio or reverse. Docker HTTP forwards both flags. It is not a global quota for process-owned background commands, nested MCP sessions or LSP servers, and genuinely unsettled work/failed cleanup can continue occupying a slot.
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
node /path/to/staff-mcp/dist/src/index.js -t http -p 3000 \
|
|
227
|
+
--http-token your_secure_token_here \
|
|
228
|
+
--http-max-sessions 64 --http-session-idle-ms 1800000
|
|
132
229
|
```
|
|
133
230
|
|
|
231
|
+
### Session shutdown
|
|
232
|
+
|
|
233
|
+
Normal SDK close, stdio EOF, and CLI SIGINT/SIGTERM/SIGHUP close session resources before process exit. Docker host-pipe EOF follows the same path. Cleanup fences new work immediately, closes skills watchers and debounce timers, and waits for file staging, accepted commits, data listeners and owned PTY exit. Repeated close waits the same cleanup; failures are reported rather than called successful. Synchronous exit cleanup remains a fallback until asynchronous cleanup finishes. SIGKILL/crashes and daemonized descendants are not guaranteed cleanups, and an unsettled underlying operation can delay graceful exit.
|
|
234
|
+
|
|
235
|
+
A new HTTP session requires a POST initialize request without an MCP session ID. Unknown or closed IDs return HTTP 404; GET/DELETE/malformed requests do not create replacement sessions. Failed initialization releases its resources. Listener shutdown closes active and initializing sessions. Reverse reconnect creates a fresh server after the previous session cleanup completes; it never reuses closed watchers or replays operations. HTTP listener capacity and idle expiry follow the policy above; stdio and reverse are not idle-evicted.
|
|
236
|
+
|
|
237
|
+
### Managed child MCP sessions
|
|
238
|
+
|
|
239
|
+
`manage_mcp_session` reserves its session ID and capacity before asynchronous startup. A starting session can be stopped; late connection completion cannot restore it. Stopping attempts owned HTTP process-group cleanup even when SDK close fails, and reports incomplete cleanup as an error while retaining the session for retry. Connection/process exits no longer leave a ready session. These sessions expose standard nested tools, not a transparent Apps/data proxy or per-chat OS sandbox.
|
|
240
|
+
|
|
134
241
|
### 3. Built-in `skill-manager`
|
|
135
242
|
Out of the box, the AI assistant knows how to manage its own skills! You can simply ask it to:
|
|
136
243
|
> *"Install the official Anthropic canvas-design skill into my project."*
|
|
@@ -140,7 +247,7 @@ It will securely download, configure, and reload the skill without you lifting a
|
|
|
140
247
|
- **Unified Shell Execution**: A single `execute_command` entry point for everything — quick commands, builds, and dev servers. If a command outlives its wait window (default 10s), it is NOT killed: it moves to the background and returns a task ID with its recent output. Follow up via `manage_background_task` (`logs` with optional blocking `wait`, `stop` kills the whole process group, `list`). Auto-detects and upgrades to `/bin/bash` if available, supporting complex pipelines.
|
|
141
248
|
- **LSP Integration**: Extract symbols, get diagnostics, go to definitions, and find references for TypeScript, Python, and more.
|
|
142
249
|
- TypeScript/JavaScript LSP keeps a local TypeScript 5.9.3 fallback toolchain. A usable workspace TypeScript is preferred; TypeScript 7 workspaces fall back because the current LSP ecosystem still depends on the tsserver API.
|
|
143
|
-
- **
|
|
250
|
+
- **File path boundary**: File operations check configured roots and protected paths. This is not an OS sandbox for shell commands or the optional PTY; use separately configured OS/container isolation for that boundary.
|
|
144
251
|
|
|
145
252
|
---
|
|
146
253
|
|
|
@@ -148,8 +255,8 @@ It will securely download, configure, and reload the skill without you lifting a
|
|
|
148
255
|
|
|
149
256
|
| Option | Description | Default |
|
|
150
257
|
| :--- | :--- | :--- |
|
|
151
|
-
| `-w, --working-dir` |
|
|
152
|
-
| `-d, --allowed-dir` | Extra directories
|
|
258
|
+
| `-w, --working-dir` | Staff workspace and default file root / terminal cwd; not an OS sandbox | `process.cwd()` |
|
|
259
|
+
| `-d, --allowed-dir` | Extra directories for standard tools; does not add file-app roots | `[]` |
|
|
153
260
|
| `-r, --profile` | The active profile for skills (e.g., android-reverse) | `default` |
|
|
154
261
|
| `--enable-lsp` | Enable LSP capabilities (disabled by default) | `false` |
|
|
155
262
|
| `--docker` | Run inside a Docker container using this image | `undefined` |
|
|
@@ -158,47 +265,37 @@ It will securely download, configure, and reload the skill without you lifting a
|
|
|
158
265
|
| `-p, --port` | Port for HTTP server | `3000` |
|
|
159
266
|
| `-h, --host` | Host for HTTP server | `127.0.0.1` |
|
|
160
267
|
| `--ht, --http-token` | Optional bearer token for HTTP transport | `undefined` (no authentication) |
|
|
161
|
-
| `--ru, --reverse-url` |
|
|
268
|
+
| `--ru, --reverse-url` | Explicit HTTP(S) Web `/api/mcp/reverse` base endpoint | `undefined` |
|
|
162
269
|
| `--rt, --reverse-token` | Security token for Reverse MCP | `undefined` |
|
|
163
270
|
| `--rn, --reverse-name` | Server name for Reverse MCP | `undefined` |
|
|
164
|
-
| `--
|
|
271
|
+
| `--extensions` | Comma-separated `files`, `terminal`, or both; apps/data dependencies are automatic | `[]` (all off) |
|
|
272
|
+
| `--file-root` | Repeatable `id=path`; explicit file roots replace the default and apply only when files is enabled | `main=<working-dir>` |
|
|
273
|
+
| `--shell` | Absolute executable PTY shell path | Valid absolute `$SHELL`, otherwise `/bin/bash` |
|
|
274
|
+
| `--proxy` | HTTP(S) proxy for supported HTTP clients and reverse control/data HTTP requests | `undefined` |
|
|
165
275
|
|
|
166
276
|
### 🌐 Proxy Support (Corporate Networks)
|
|
167
277
|
|
|
168
|
-
staff-mcp
|
|
169
|
-
|
|
170
|
-
```bash
|
|
171
|
-
export HTTPS_PROXY=http://proxy.company.com:8080
|
|
172
|
-
export NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,.internal.example.com
|
|
173
|
-
# NO_PROXY supports: exact hosts/IPs, domain suffixes (.example.com or bare example.com),
|
|
174
|
-
# "*" wildcard, host:port qualifiers, and IPv4/IPv6 CIDR ranges (e.g. 172.16.0.0/12, fd00::/8)
|
|
175
|
-
npx -y staff-mcp@latest -t reverse --ru https://chat.example.com/api/mcp/reverse --rt <token> --rn myserver
|
|
176
|
-
```
|
|
278
|
+
staff-mcp configures its Undici HTTP clients from `HTTP_PROXY` / `HTTPS_PROXY` (and lowercase equivalents), with `NO_PROXY` matching for exact hosts/IPs, domain suffixes, `*`, host:port and IPv4/IPv6 CIDRs. Explicit `--proxy` takes precedence for those clients and reverse connections, bypassing `NO_PROXY`.
|
|
177
279
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
```bash
|
|
181
|
-
npx -y staff-mcp@latest --proxy http://proxy.company.com:8080 ...
|
|
182
|
-
```
|
|
280
|
+
Reverse control and data share an injected Undici HTTP pool. Without explicit `--proxy`, `selectProxyForOrigin` selects HTTP(S) environment proxies and applies target `NO_PROXY`; HTTPS uses `HTTPS_PROXY` with `HTTP_PROXY` fallback, including lowercase variants. An explicit proxy overrides that selection. Proxy and target certificate verification remain enabled and redirects are not followed. This does not replace proxy authentication, CA trust, DNS or target reachability. Validate corporate WAN streaming/SSE and cancellation in the target network; local results do not establish that path's availability.
|
|
183
281
|
|
|
184
|
-
In `--docker` mode the
|
|
282
|
+
In `--docker` mode the HTTP-client and reverse proxy settings are evaluated inside the container; Docker environment injection or explicit `--proxy` can supply them. For TLS interception, `NODE_EXTRA_CA_CERTS=/path/to/ca.pem` adds trust rather than disabling certificate verification; certificate files must be visible inside the container, and native ABI/libc compatibility remains a deployment requirement.
|
|
185
283
|
|
|
186
284
|
### Hardware Pass-through Example (Android Reverse Engineering)
|
|
187
|
-
If you need the AI to interact with an Android device connected via USB while running inside a container,
|
|
285
|
+
If you need the AI to interact with an Android device connected via USB while running inside a container, network-based ADB can be configured separately. These examples do not verify Docker Desktop stdio data mapping or device access; restrict ADB exposure to trusted peers:
|
|
188
286
|
|
|
189
287
|
```bash
|
|
190
288
|
# 1. Start ADB Server on the host machine listening on all interfaces:
|
|
191
289
|
# adb kill-server && adb -a nodaemon server start
|
|
192
290
|
|
|
193
291
|
# 2. Start staff-mcp with the ADB_SERVER_SOCKET environment variable injected
|
|
194
|
-
# On Mac/Windows:
|
|
195
|
-
|
|
292
|
+
# On Mac/Windows, if this hostname and the local Docker topology are available:
|
|
293
|
+
node /path/to/staff-mcp/dist/src/index.js --docker chineseastar/security:latest -D "-e ADB_SERVER_SOCKET=tcp:host.docker.internal:5037"
|
|
196
294
|
|
|
197
|
-
# On Native Linux
|
|
198
|
-
|
|
295
|
+
# On Native Linux, use the actual reachable bridge address (example only):
|
|
296
|
+
node /path/to/staff-mcp/dist/src/index.js --docker chineseastar/security:latest -D "-e ADB_SERVER_SOCKET=tcp:172.17.0.1:5037"
|
|
199
297
|
|
|
200
|
-
#
|
|
201
|
-
npx -y staff-mcp@latest --docker chineseastar/security:latest -D "--network host"
|
|
298
|
+
# stdio automatic data publication does not support --network host.
|
|
202
299
|
```
|
|
203
300
|
|
|
204
301
|
---
|