machine-bridge-mcp 0.2.5 → 0.4.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 ADDED
@@ -0,0 +1,94 @@
1
+ # Changelog
2
+
3
+ ## 0.4.0 - 2026-07-10
4
+
5
+ ### Architecture and compatibility
6
+
7
+ - Refactor the project into one transport-independent local runtime shared by the existing OAuth-protected Cloudflare relay and a new local MCP stdio server.
8
+ - Update MCP negotiation to `2025-11-25` while retaining compatibility with `2025-06-18` and `2025-03-26`; validate protocol-version headers and implement cancellation in both transports.
9
+ - Add ready-to-paste stdio configuration generation for Claude Desktop, Cursor, Codex CLI, and generic MCP clients.
10
+ - Replace duplicated Worker/runtime tool declarations with one schema-and-annotation catalog, tested for drift and policy consistency.
11
+
12
+ ### Security and privacy
13
+
14
+ - Make the least-privilege `review` profile the default for newly selected workspaces; preserve stored pre-0.4 permissions during upgrade.
15
+ - Add explicit `review`, `edit`, `agent`, and `full` profiles plus `off`, direct-argv, and shell execution modes.
16
+ - Return workspace-relative paths by default, redact canonical/platform-alias paths from tool errors, omit Git author email unless requested, and reduce operational failures to coarse error classes.
17
+ - Replace the previous minimal environment with isolated HOME, temp, and cache directories; retain full parent environment only through explicit opt-in.
18
+ - Reject duplicate in-flight JSON-RPC IDs, canonical patch-path collisions, stale edits, unsupported image signatures, oversized session data, and ambiguous patch context.
19
+ - Make create-only writes atomic against concurrent destination creation and strengthen multi-file patch staging, revalidation, rollback, and mutation serialization.
20
+
21
+ ### Tools and runtime
22
+
23
+ - Add bounded line-range reads, native MCP raster-image results, exact text editing, and structured multi-file add/update/move/delete patches.
24
+ - Add staged diffs, structured Git log, bounded Git show, and privacy-aware author metadata.
25
+ - Add direct argv execution and bounded interactive process sessions with retained offsets, stdin, output/exit waits, cancellation, tree termination, and disconnect cleanup.
26
+ - Return structured tool content alongside text compatibility output and expose tool annotations for client planning.
27
+
28
+ ### Reliability, testing, and operations
29
+
30
+ - Add live stdio integration coverage for initialization, tool discovery, structured/image content, edits, patches, direct execution, sessions, cancellation, and post-cancellation health.
31
+ - Expand Worker integration coverage for latest protocol negotiation, disconnected tool advertisement, rich content, exact daemon tool sets, and remote cancellation.
32
+ - Add catalog, policy-profile, canonical-collision, no-partial-patch, Git privacy, path-redaction, isolated-environment, and session tests.
33
+ - Add a Linux/macOS/Windows GitHub Actions template, Node 22/24 coverage, package/audit checks, and Dependabot configuration.
34
+ - Rewrite architecture, security, client, operations, and testing documentation around explicit trust boundaries and non-goals.
35
+
36
+ ## 0.3.3 - 2026-07-10
37
+
38
+ ### Security
39
+
40
+ - Add an exact-version npm `allowScripts` policy for the reviewed Wrangler runtime/build binaries (`esbuild@0.28.1`, `sharp@0.34.5`, and `workerd@1.20260708.1`) and explicitly deny the optional `fsevents` install script. Dependency upgrades therefore require renewed script approval.
41
+
42
+ ### Changed
43
+
44
+ - Exclude the development-only Worker integration test from the published npm package while retaining it in the repository and CI.
45
+ - Add a fail-closed release command that synchronizes `main`, the version tag, the GitHub Release, and its npm tarball; block `npm publish` when those artifacts do not match.
46
+
47
+ ## 0.3.2 - 2026-07-10
48
+
49
+ ### Fixed
50
+
51
+ - Keep the healthy daemon active until a replacement connection completes its authenticated `hello` handshake; enforce the candidate deadline with a Durable Object alarm so it survives WebSocket hibernation, and reject stale or non-handshaking candidates without disrupting the active connection.
52
+ - Send the candidate acknowledgement before closing the previous daemon, expire failed acknowledgements, clean up duplicate authenticated sockets on subsequent handshakes, and reject pre-handshake messages without changing active tool metadata.
53
+
54
+ ## 0.3.1 - 2026-07-10
55
+
56
+ ### Security
57
+
58
+ - Replace reversible unsalted source-address hashes used for OAuth registration limits and password throttling with deployment-keyed HMAC identifiers; stop persisting User-Agent-derived identities, remove legacy unsalted identifiers during store migration, and fail closed if no identity key is configured.
59
+
60
+ ### Fixed
61
+
62
+ - Preserve timeout escalation after the direct child exits so a process-group `SIGKILL` still removes descendants that ignore `SIGTERM`; add a regression test for the orphan-process boundary.
63
+ - Replace legacy unsalted source-identity hashes with deployment-keyed HMAC identifiers, prune legacy stored identifiers, and add integration coverage for registration quotas and login throttling.
64
+
65
+ ## 0.3.0 - 2026-07-10
66
+
67
+ ### Security
68
+
69
+ - Confine filesystem tools to the canonical workspace by default; add explicit `--unrestricted-paths` opt-in and symbolic-link escape protection.
70
+ - Make `write_file` bounded and atomic, reject symbolic-link/non-regular destinations, and enforce optimistic hashes consistently.
71
+ - Add recursive log-field and token redaction, control-character neutralization, owner-only service logs, and bounded log trimming.
72
+ - Harden OAuth with strict PKCE/resource/client/redirect validation, validated client disclosure on the consent page, password-failure throttling, bounded dynamic registration, per-source and per-client limits, inactive-client cleanup, strict HTTP methods/UTF-8 handling, and security response headers.
73
+ - Minimize unauthenticated and relay metadata disclosure: remove workspace name/path hash/process ID from the daemon handshake, reduce default observability sampling, and bind pending calls to their originating daemon socket.
74
+ - Bound Worker/daemon request sizes and concurrency; serialize OAuth mutations; isolate WebSocket generations; serialize per-workspace startup/deploy/rotation operations; terminate timed-out or disconnected child processes and bound Wrangler subprocesses.
75
+
76
+ ### Changed
77
+
78
+ - Raise the minimum Node.js version to 22 because the current Wrangler release no longer runs on Node 20; require the installed Wrangler dependency instead of falling back to an implicit network `npx` execution.
79
+ - Remove the experimental local OpenAI-compatible `/v1` API and MCP sampling proxy.
80
+ - Detect nested Git repositories for `git_status` and `git_diff`, while disabling repository-configured external diff, text conversion, and filesystem-monitor hooks for bridge Git operations.
81
+ - Use atomic local state/config writes, bounded corrupt-state backups, strict adoption/migration of dedicated state roots, and guarded state-root deletion during uninstall, including refusal while active daemon/startup locks remain.
82
+ - Reject unknown, duplicate, malformed, and command-inapplicable CLI options; fix boolean options consuming positional workspaces.
83
+ - Verify the expected Worker version before accepting a deployment hash.
84
+ - Reduce the default Worker request-body limit to 8 MiB; bound command length, directory results, recursive traversal, and path-result payloads; provide exact-origin CORS while rejecting implicit loopback browser origins.
85
+ - Update Wrangler to 4.110.x, TypeScript to 5.9.x, and Node type definitions to the supported Node 22 API line.
86
+
87
+ ### Tests and documentation
88
+
89
+ - Expand self-tests across path boundaries, symlinks, writes, UTF-8, nested Git, environment isolation, locking, CLI parsing, state recovery/removal guards, logging, service logs, and Worker hardening invariants.
90
+ - Add a live local Worker OAuth/MCP integration test, verified Node 22/24 compatibility, a Worker build dry-run, dependency audit, security policy, and architecture document.
91
+
92
+ ## 0.2.5
93
+
94
+ - Previous release.
package/README.md CHANGED
@@ -1,238 +1,217 @@
1
1
  # machine-bridge-mcp
2
2
 
3
- `machine-bridge-mcp` turns your machine into a Remote MCP server through a small hosted relay and a local outbound daemon.
3
+ `machine-bridge-mcp` exposes a selected local workspace to MCP clients through one shared, policy-controlled runtime.
4
4
 
5
- The recommended deployment command is short and stable for autostart:
5
+ It supports two transports:
6
6
 
7
- ```zsh
8
- npm install -g machine-bridge-mcp@latest && machine-mcp
9
- ```
10
-
11
- No-global-install alternative:
7
+ ```text
8
+ Remote clients such as ChatGPT
9
+ HTTPS + OAuth 2.1 / PKCE
10
+ |
11
+ Cloudflare Worker + Durable Object
12
+ ^
13
+ | outbound authenticated WebSocket
14
+ |
15
+ local runtime
12
16
 
13
- ```zsh
14
- npx machine-bridge-mcp@latest
17
+ Local clients such as Claude Desktop, Cursor, and Codex CLI
18
+ |
19
+ stdio
20
+ |
21
+ local runtime
15
22
  ```
16
23
 
17
- Source checkout:
24
+ The remote Worker authenticates and relays calls. It cannot directly read local files or start local processes. File, Git, image, patch, and process operations execute in the local runtime.
18
25
 
19
- ```zsh
20
- ./mbm # macOS/Linux
21
- .\mbm.cmd # Windows cmd
22
- ```
26
+ ## Security posture first
23
27
 
24
- ## What it does on first run
28
+ A new workspace starts with the `review` profile:
25
29
 
26
- 1. Asks for a workspace path. Press Enter to use the current directory.
27
- 2. Remembers that workspace for later runs.
28
- 3. Generates a stable MCP connection password and daemon secret.
29
- 4. Checks `wrangler whoami`; if needed, opens `wrangler login`.
30
- 5. Deploys the hosted Worker relay with `wrangler deploy --secrets-file`.
31
- 6. Installs login autostart for the local daemon and default local API.
32
- 7. Starts the local daemon and local OpenAI-compatible API.
33
- 8. Prints MCP connection details on first run, plus local API settings:
30
+ - read-only filesystem and Git tools;
31
+ - no file mutation;
32
+ - no process execution;
33
+ - workspace-confined filesystem access;
34
+ - relative paths in tool results;
35
+ - no parent shell environment inherited by commands.
34
36
 
35
- ```text
36
- MCP Server URL: https://<worker>.<account>.workers.dev/mcp
37
- MCP connection password: mcp_password_...
38
- API Base URL: http://127.0.0.1:8765/v1
39
- API key: local_api_key_...
40
- ```
37
+ Existing pre-0.4 workspace profiles keep their saved permissions during upgrade. Select a profile explicitly to change them.
41
38
 
42
- Keep the foreground process running for the current session. The installed autostart entry keeps the daemon and local API available after future logins.
39
+ | Profile | File edits | Direct argv processes | Shell commands | Intended use |
40
+ |---|---:|---:|---:|---|
41
+ | `review` | No | No | No | Inspection and review |
42
+ | `edit` | Yes | No | No | Controlled file changes |
43
+ | `agent` | Yes | Yes | No | Coding agents and test commands |
44
+ | `full` | Yes | Yes | Yes | Deliberate full local automation |
43
45
 
44
- The command is safe to run repeatedly:
46
+ `run_process` and process sessions avoid command-shell parsing, but they are **not an operating-system sandbox**. An allowed executable can still access anything available to the local user. `exec_command` is more exposed because it additionally permits shell syntax and expansion. Use a container, VM, or dedicated low-privilege OS account for hostile repositories or untrusted instructions.
45
47
 
46
- ```zsh
47
- npm install -g machine-bridge-mcp@latest && machine-mcp
48
- ```
48
+ ## Install
49
49
 
50
- On repeat runs, the CLI reuses existing state and secrets unless you request rotation, skips Worker redeploys when the deployed Worker is healthy and Worker source/config/secrets are unchanged, refreshes the autostart entry, stops any currently loaded autostart daemon before starting the foreground daemon, and refuses to start a second daemon for the same workspace if another foreground instance is already running. Local-only package, CLI, logging, and local API changes do not by themselves force a Worker redeploy.
50
+ Node.js 22 or newer is required.
51
51
 
52
- MCP connection details are printed on first run, after secret rotation, when the MCP URL changes, or when you explicitly pass `--print-mcp-credentials`. Routine runs print that MCP details are unchanged.
53
-
54
- ## Local OpenAI-compatible API
55
-
56
- The project exposes two connected integration surfaces:
57
-
58
- - **ChatGPT web / ChatGPT apps:** use the Remote MCP Server URL and MCP connection password printed by `machine-mcp`. In this mode, ChatGPT calls tools on your machine through the Worker + local daemon bridge.
59
- - **Desktop clients such as Cherry Studio, Chatbox, or Continue:** use the optional local OpenAI-compatible `/v1` API. `POST /v1/chat/completions` is backed by MCP sampling: the local API asks the hosted Worker to send `sampling/createMessage` to the already-connected ChatGPT MCP client, then wraps the MCP sampling result as an OpenAI-compatible chat completion response.
60
-
61
- No separate model API setup is required or used in this path; the local API never asks for a model base URL or model API key. Generation depends on the ChatGPT-side MCP client actually being connected and able to receive server-to-client sampling requests. If ChatGPT is not connected, has no open MCP stream for server-to-client messages, or did not advertise the MCP `sampling` capability, generation returns an explicit OpenAI-shaped error saying that the missing piece is the MCP client stream or sampling capability.
52
+ ```sh
53
+ npm install -g machine-bridge-mcp@latest
54
+ ```
62
55
 
63
- Start the normal daemon and local API:
56
+ From a source checkout:
64
57
 
65
- ```zsh
66
- machine-mcp
58
+ ```sh
59
+ npm install
60
+ ./mbm # macOS/Linux
61
+ .\mbm.cmd # Windows cmd
67
62
  ```
68
63
 
69
- Start only the local API from remembered state:
64
+ ## Remote MCP for ChatGPT
65
+
66
+ Start the bridge from the project directory or select a workspace explicitly:
70
67
 
71
- ```zsh
72
- machine-mcp api
68
+ ```sh
69
+ machine-mcp --workspace /path/to/project --profile review
73
70
  ```
74
71
 
75
- Disable the default local API for a daemon run:
72
+ On first remote start, the CLI:
76
73
 
77
- ```zsh
78
- machine-mcp --no-api
79
- ```
74
+ 1. canonicalizes and remembers the workspace;
75
+ 2. creates independent credentials and state for that workspace;
76
+ 3. signs in to Cloudflare Wrangler when needed;
77
+ 4. deploys a per-workspace Worker;
78
+ 5. installs a platform-native login service unless `--no-autostart` is used;
79
+ 6. starts an outbound-only daemon connection;
80
+ 7. prints the Remote MCP URL and connection password.
80
81
 
81
- When the API is running, the CLI prints client settings like:
82
+ Use the printed values in the MCP client:
82
83
 
83
84
  ```text
84
- API Base URL: http://127.0.0.1:8765/v1
85
- API key: local_api_key_...
86
- Client type: OpenAI-compatible
87
- Model: chatgpt-mcp
88
- Backend: ChatGPT MCP sampling via the connected ChatGPT app
85
+ MCP Server URL: https://<worker>.<account>.workers.dev/mcp
86
+ MCP connection password: mcp_password_...
89
87
  ```
90
88
 
91
- Use the API Base URL, API key, and model in your desktop client. Separately, connect ChatGPT to the printed MCP Server URL/password so the Worker has an MCP client stream that can receive `sampling/createMessage`.
89
+ The remote authorization flow uses an authorization code, PKCE S256, exact redirect/resource binding, expiring access tokens stored as hashes, and a token-version value for bulk revocation.
92
90
 
93
- If port `8765` conflicts with another local app, choose a different port explicitly:
94
-
95
- ```zsh
96
- machine-mcp --api-port 8766
97
- machine-mcp api --api-port 8766
98
- ```
91
+ ## Local stdio MCP for Claude, Cursor, Codex, and compatible clients
99
92
 
100
- `--port` is also accepted on the `api` command:
93
+ Generate ready-to-paste configuration:
101
94
 
102
- ```zsh
103
- machine-mcp api --port 8766
95
+ ```sh
96
+ machine-mcp client-config --client all --workspace /path/to/project --profile agent
104
97
  ```
105
98
 
106
- By default, the local API binds to `127.0.0.1`, starts with `machine-mcp`, and stores a per-workspace local API key in the same owner-only state profile used by the MCP credentials. Explicit `--api-host`, `--api-port`, and `--api-model` values are persisted for the workspace so autostart uses the same API settings. `--api-model` only controls the local model id advertised by `GET /v1/models`; the actual model is chosen by the connected MCP client, and any different `model` value in a chat-completions request is passed as an MCP model preference hint.
99
+ Or run stdio directly:
107
100
 
108
- Rotate the local desktop-client API key with:
109
-
110
- ```zsh
111
- machine-mcp api --rotate-api-key
101
+ ```sh
102
+ machine-mcp stdio --workspace /path/to/project --profile agent
112
103
  ```
113
104
 
114
- Environment variables supported for the current process: `MBM_API_HOST`, `MBM_API_PORT`, `MBM_API_KEY`, and `MBM_API_MODEL`. Environment overrides are not persisted to state; use `--api-host`, `--api-port`, `--api-key`, or `--api-model` when you want a setting saved for future runs and autostart.
115
-
116
- Supported local API routes:
105
+ The stdio server writes only JSON-RPC messages to stdout. Operational logs go to stderr. It supports MCP initialization/version negotiation, tool discovery, calls, cancellation, structured tool output, native image content, and process sessions.
117
106
 
118
- - `GET /health` without authentication
119
- - `GET /v1/models` with `Authorization: Bearer <local_api_key>` or `x-api-key`
120
- - `POST /v1/chat/completions`
107
+ See [docs/CLIENTS.md](docs/CLIENTS.md) for client-specific configuration and remote/local trade-offs.
121
108
 
122
- `POST /v1/responses`, `POST /v1/completions`, and `POST /v1/embeddings` return `501 unsupported_endpoint`; MCP sampling is a chat-message path and does not expose embeddings or the full Responses API. Logs record route, status, latency, and safe configuration metadata; request and response bodies and API keys are not logged.
109
+ ## Policy controls
123
110
 
124
- ## Re-select workspace
125
-
126
- ```zsh
127
- machine-mcp workspace set
128
- ```
111
+ Profiles can be narrowed with explicit flags:
129
112
 
130
- Or provide it directly:
131
-
132
- ```zsh
133
- machine-mcp workspace set /path/to/new/default
113
+ ```text
114
+ --profile review|edit|agent|full
115
+ --exec-mode off|direct|shell
116
+ --no-write
117
+ --no-exec
118
+ --full-env
119
+ --unrestricted-paths
120
+ --absolute-paths
134
121
  ```
135
122
 
136
- Show the remembered workspace:
123
+ Important distinctions:
137
124
 
138
- ```zsh
139
- machine-mcp workspace show
140
- ```
125
+ - `--unrestricted-paths` expands direct filesystem tools beyond the selected workspace.
126
+ - `--absolute-paths` changes returned path metadata; it does not grant additional access.
127
+ - `--full-env` passes the complete parent environment to processes. Without it, commands receive an isolated HOME, temp directory, and cache directories plus a small set of platform variables.
128
+ - Files with sensitive-looking names are not automatically blocked inside the workspace. A workspace `.env` remains readable when read tools are enabled.
141
129
 
142
- ## Autostart service
130
+ ## Tools
143
131
 
144
- Supported platforms:
132
+ The exact `tools/list` response reflects the active local policy. Definitions come from one shared catalog used by both Worker and stdio transports.
145
133
 
146
- - macOS: user LaunchAgent
147
- - Linux: `systemd --user` with best-effort `loginctl enable-linger`
148
- - Windows: Scheduled Task at logon
134
+ ### Workspace and content
149
135
 
150
- Commands:
136
+ - `server_info`
137
+ - `project_overview`
138
+ - `list_roots`
139
+ - `list_dir`
140
+ - `list_files`
141
+ - `read_file` — whole UTF-8 files or bounded line ranges
142
+ - `view_image` — bounded PNG, JPEG, GIF, or WebP as native MCP image content
143
+ - `search_text`
151
144
 
152
- ```zsh
153
- machine-mcp service status
154
- machine-mcp service install
155
- machine-mcp service start
156
- machine-mcp service stop
157
- machine-mcp service uninstall
158
- ```
145
+ ### Mutation
159
146
 
160
- `start` installs autostart by default. Skip that behavior with:
147
+ - `write_file` atomic whole-file write with create-only and SHA-256 checks
148
+ - `edit_file` — exact text replacement with ambiguity rejection
149
+ - `apply_patch` — bounded multi-file add/update/move/delete transaction with rollback
161
150
 
162
- ```zsh
163
- machine-mcp --no-autostart
164
- ```
151
+ ### Git
165
152
 
166
- Autostart runs the daemon with `--daemon-only --no-print-credentials`, so service logs do not contain the MCP connection password. If you start with `--no-write`, `--no-exec`, or `--full-env`, those policy flags are preserved in the autostart entry. macOS/Linux service definitions restart only on process failure; a normal duplicate-instance exit is not treated as a crash loop.
153
+ - `git_status`
154
+ - `git_diff` — working tree or staged
155
+ - `git_log` — structured commits; author email omitted unless explicitly requested
156
+ - `git_show`
167
157
 
168
- ## Secrets rotation
158
+ Repository-configured external diff, text conversion, and filesystem-monitor helpers are disabled for bridge Git inspection.
169
159
 
170
- ```zsh
171
- machine-mcp rotate-secrets
172
- machine-mcp
173
- ```
160
+ ### Processes
174
161
 
175
- `rotate-secrets` creates a new MCP connection password, daemon secret, and OAuth token version. The next deploy rejects previously issued OAuth access tokens.
162
+ - `run_process` one-shot argv execution without a shell
163
+ - `start_process`
164
+ - `read_process`
165
+ - `write_process`
166
+ - `kill_process`
167
+ - `exec_command` — shell execution, available only in `shell` mode
176
168
 
177
- ## Uninstall
169
+ Process sessions retain bounded stdout/stderr, support offsets and short waits, accept stdin, and are killed when the daemon connection is lost or replaced. They are pipe-based and do not emulate a terminal/PTY.
178
170
 
179
- Delete known deployed Worker(s), remove autostart entries, and remove local state:
171
+ ## Path and write behavior
180
172
 
181
- ```zsh
182
- machine-mcp uninstall
183
- ```
173
+ By default, existing paths are resolved with `realpath` and must remain inside the canonical workspace. New write paths validate the nearest existing ancestor, preventing missing-path writes through escaping symbolic-link directories.
184
174
 
185
- Non-interactive:
175
+ Writes use same-directory temporary files and atomic commit. Create-only writes use an atomic hard-link commit so a concurrent file cannot be silently overwritten. Patch operations are prevalidated, serialized, staged, rechecked, committed with backups, and rolled back on failure.
186
176
 
187
- ```zsh
188
- machine-mcp uninstall --yes
189
- ```
177
+ Returned paths are workspace-relative by default. This reduces unnecessary disclosure of usernames and local directory layouts. Enable `--absolute-paths` only when a client genuinely needs absolute paths.
190
178
 
191
- Keep the deployed Worker but remove local state/autostart:
179
+ ## Commands
192
180
 
193
- ```zsh
194
- machine-mcp uninstall --keep-worker
181
+ ```text
182
+ machine-mcp [start options]
183
+ machine-mcp stdio [options]
184
+ machine-mcp client-config [all|claude|cursor|codex|generic]
185
+ machine-mcp workspace show|set|reset
186
+ machine-mcp service status|install|start|stop|uninstall
187
+ machine-mcp status
188
+ machine-mcp doctor
189
+ machine-mcp rotate-secrets
190
+ machine-mcp uninstall [--keep-worker] [--yes]
195
191
  ```
196
192
 
197
- If installed globally, remove the npm package afterwards:
193
+ Each canonical workspace has an independent profile, Worker name, credential set, state file, startup lock, and daemon lock.
198
194
 
199
- ```zsh
200
- npm uninstall -g machine-bridge-mcp
201
- ```
195
+ ## Autostart
202
196
 
203
- ## Defaults and permissions
197
+ Remote mode supports:
204
198
 
205
- This project optimizes for easy use with official Remote MCP clients:
199
+ - macOS user LaunchAgent;
200
+ - Linux `systemd --user`, with best-effort lingering;
201
+ - Windows Scheduled Task at logon.
206
202
 
207
- - `write_file` is enabled by default.
208
- - `exec_command` is enabled by default.
209
- - Absolute paths are allowed.
210
- - Parent-directory paths such as `../other-project/file.ts` are allowed.
211
- - Sensitive-looking files such as `.env`, private keys, token files, and dot-directories are not hidden by default.
212
- - Relative paths use the selected workspace as cwd.
213
- - Shell commands run with a minimal environment by default; use `--full-env` to pass the parent process environment.
203
+ The service definition contains neither credentials nor a duplicate policy. It loads the selected policy from owner-only local state and fails closed to the `review` profile if policy state is absent. Service logs are owner-only where supported and trimmed before daemon startup.
214
204
 
215
- Narrower session:
205
+ ## Secret rotation
216
206
 
217
- ```zsh
218
- machine-mcp --no-write --no-exec
207
+ ```sh
208
+ machine-mcp rotate-secrets --no-print-credentials
209
+ machine-mcp
219
210
  ```
220
211
 
221
- ## MCP tools
212
+ Rotation stops the installed service, refuses to proceed while another foreground daemon owns the workspace lock, rotates the MCP password, daemon secret, and OAuth token version, and requires redeployment. Previously issued access tokens then fail validation.
222
213
 
223
- - `server_info`
224
- - `project_overview`
225
- - `list_roots`
226
- - `list_dir`
227
- - `list_files`
228
- - `read_file`
229
- - `write_file`
230
- - `search_text`
231
- - `git_status`
232
- - `git_diff`
233
- - `exec_command`
234
-
235
- ## State and logs
214
+ ## State and observability
236
215
 
237
216
  Default state roots:
238
217
 
@@ -240,54 +219,33 @@ Default state roots:
240
219
  - Linux with `XDG_STATE_HOME`: `$XDG_STATE_HOME/machine-bridge-mcp`
241
220
  - Windows: `%APPDATA%\machine-bridge-mcp`
242
221
 
243
- State contains the MCP password, daemon secret, and local API key. Status/doctor output redacts secrets. The normal foreground `start` command prints the MCP password only when a ChatGPT app is likely to need reconnection: first run, secret rotation, MCP URL changes, or `--print-mcp-credentials`. The local API base URL and API key print on normal foreground starts because desktop AI clients need them. Use `--no-print-credentials` to redact console credentials. State files, temporary Worker secret files, lock files, and log directories are created under the user state root with owner-only permissions where the platform supports POSIX modes.
244
-
245
- The Worker rejects browser requests with an `Origin` header unless the origin is the Worker itself or a loopback HTTP origin. To allow additional browser-based MCP clients, set `MBM_ALLOWED_ORIGINS` to a comma-separated list of exact origins in `wrangler.jsonc` or Cloudflare Worker settings.
222
+ State/config writes use owner-only temporary files, flushes, and atomic rename. Malformed state is retained as a bounded corrupt backup before reconstruction. Uninstall validates markers, canonical paths, active locks, workspace/source exclusions, and known contents before recursive deletion.
246
223
 
247
- Override state root:
224
+ Operational logs record bounded metadata such as component, tool name, shortened call ID, duration, outcome, and error class. They do not intentionally log file contents, patch bodies, command strings, stdin, OAuth passwords, access tokens, or daemon secrets. See [docs/OPERATIONS.md](docs/OPERATIONS.md).
248
225
 
249
- ```zsh
250
- machine-mcp --state-dir /path/to/state
251
- ```
226
+ ## Development and verification
252
227
 
253
- ## Architecture
254
-
255
- ```mermaid
256
- flowchart LR
257
- C["ChatGPT / MCP client"] -- "HTTPS /mcp + OAuth" --> W["Hosted Worker relay"]
258
- C -- "GET SSE stream for server-to-client MCP" --> W
259
- W --> DO["Durable Object broker"]
260
- D["Local daemon"] -- "outbound WebSocket" --> W
261
- D --> M["Local filesystem and shell"]
262
- API["Local /v1/chat/completions"] -- "POST /api/mcp/sampling" --> W
263
- DO -- "sampling/createMessage" --> C
264
- CLI["machine-mcp CLI"] --> API
265
- CLI --> W
266
- CLI --> D
267
- CLI --> S["Autostart service"]
228
+ ```sh
229
+ npm ci
230
+ npm run check
231
+ npm run worker:dry-run
232
+ npm audit --omit=dev --audit-level=high
233
+ npm pack --dry-run
268
234
  ```
269
235
 
270
- Why this architecture:
236
+ `npm run check` covers generated Worker types, TypeScript, JavaScript syntax, the shared tool catalog, local path/write/process/state/log/service invariants, a live stdio MCP flow, and a live local OAuth/Worker/WebSocket/MCP flow. A ready-to-enable GitHub Actions template is included at `docs/examples/github-actions-ci.yml` for Linux, macOS, and Windows with supported Node versions. Activating it requires a GitHub credential authorized to modify workflow files.
271
237
 
272
- - No inbound local port is exposed to the internet.
273
- - No local tunnel process is required.
274
- - The public MCP URL is stable after deployment.
275
- - The Worker stores OAuth client/code/token metadata and relays tool calls.
276
- - The local daemon is the only process touching files or executing commands.
277
- - The local `/v1` API binds to loopback by default, starts automatically with the daemon, and can be disabled with `--no-api`.
278
- - Autostart keeps the daemon and local API alive across logins without requiring MCP clients to change URLs.
238
+ See [docs/TESTING.md](docs/TESTING.md), [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md), and [SECURITY.md](SECURITY.md).
279
239
 
280
- ## Development
240
+ ## Uninstall
281
241
 
282
- ```zsh
283
- npm install
284
- npm run check
242
+ ```sh
243
+ machine-mcp uninstall
244
+ npm uninstall -g machine-bridge-mcp
285
245
  ```
286
246
 
287
- `npm run check` generates Worker runtime types, type-checks the Worker, checks local JS syntax, and runs daemon self-tests.
247
+ Use `--keep-worker` to retain deployed Workers while removing local state and autostart.
288
248
 
289
- Worker build dry-run:
249
+ ## License
290
250
 
291
- ```zsh
292
- npx wrangler deploy --dry-run
293
- ```
251
+ MIT