machine-bridge-mcp 1.2.8 → 1.2.10

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.
Files changed (57) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/CONTRIBUTING.md +16 -5
  3. package/README.md +115 -416
  4. package/SECURITY.md +2 -0
  5. package/browser-extension/manifest.json +2 -2
  6. package/docs/ARCHITECTURE.md +19 -9
  7. package/docs/AUDIT.md +20 -0
  8. package/docs/ENGINEERING.md +2 -2
  9. package/docs/LOGGING.md +1 -1
  10. package/docs/MULTI_ACCOUNT.md +2 -2
  11. package/docs/OPERATIONS.md +2 -2
  12. package/docs/OVERVIEW.md +113 -0
  13. package/docs/PROJECT_STANDARDS.md +4 -4
  14. package/docs/RELEASING.md +25 -12
  15. package/docs/TESTING.md +12 -8
  16. package/docs/THREAT_MODEL.md +142 -0
  17. package/package.json +10 -3
  18. package/scripts/check-plan.mjs +91 -0
  19. package/scripts/coverage-check.mjs +22 -0
  20. package/scripts/github-push.mjs +1 -1
  21. package/scripts/github-release.mjs +1 -1
  22. package/scripts/local-release-acceptance.mjs +56 -6
  23. package/scripts/release-acceptance.mjs +15 -3
  24. package/scripts/release-state.mjs +1 -1
  25. package/scripts/run-checks.mjs +29 -0
  26. package/scripts/start-release-candidate.mjs +113 -0
  27. package/src/local/agent-context-projection.mjs +158 -0
  28. package/src/local/agent-context.mjs +23 -332
  29. package/src/local/agent-skill-discovery.mjs +230 -0
  30. package/src/local/agent-text-file.mjs +41 -0
  31. package/src/local/browser-bridge-http.mjs +48 -0
  32. package/src/local/browser-bridge.mjs +48 -222
  33. package/src/local/browser-broker-routes.mjs +136 -0
  34. package/src/local/browser-broker-server.mjs +59 -0
  35. package/src/local/browser-request-registry.mjs +67 -0
  36. package/src/local/managed-job-lock.mjs +99 -0
  37. package/src/local/managed-job-projection.mjs +68 -0
  38. package/src/local/managed-job-runner.mjs +73 -0
  39. package/src/local/managed-job-storage.mjs +93 -0
  40. package/src/local/managed-jobs.mjs +12 -297
  41. package/src/local/relay-call-recovery.mjs +148 -0
  42. package/src/local/relay-connection.mjs +5 -0
  43. package/src/local/runtime-paths.mjs +107 -0
  44. package/src/local/runtime-relay.mjs +89 -0
  45. package/src/local/runtime-tool-handlers.mjs +66 -0
  46. package/src/local/runtime.mjs +80 -242
  47. package/src/local/windows-launcher.mjs +57 -0
  48. package/src/local/windows-service.mjs +7 -56
  49. package/src/worker/daemon-sockets.ts +10 -1
  50. package/src/worker/index.ts +51 -124
  51. package/src/worker/mcp-jsonrpc.ts +94 -0
  52. package/src/worker/oauth-authorization-page.ts +70 -0
  53. package/src/worker/oauth-controller.ts +9 -58
  54. package/src/worker/pending-call-contract.ts +26 -0
  55. package/src/worker/pending-calls.ts +41 -25
  56. package/src/worker/websocket-protocol.ts +24 -0
  57. package/tsconfig.local.json +7 -1
package/README.md CHANGED
@@ -1,87 +1,58 @@
1
1
  # machine-bridge-mcp
2
2
 
3
- `machine-bridge-mcp` exposes a selected local workspace to MCP clients through one shared, policy-controlled runtime.
3
+ `machine-bridge-mcp` exposes one local workspace to MCP clients through a shared, policy-controlled runtime. Hosted clients connect through an OAuth-protected Cloudflare Worker relay; local clients may launch the same runtime over stdio.
4
4
 
5
5
  > [!WARNING]
6
- > The default `full` profile can read and modify local-user-accessible files, run shell commands, control the existing browser profile, and inherit the parent environment. It is not an operating-system sandbox. Use `review`, `edit`, or `agent`, or an isolated OS account/VM, when any client or repository is not fully trusted.
6
+ > The default `full` profile can read and modify any file available to the local OS user, run shell commands, inherit the parent environment, and control the Chromium profile containing the packaged extension. It is **not** an operating-system sandbox. Use a narrower profile or an isolated OS account, VM, or container for untrusted clients, repositories, or instructions.
7
7
 
8
- ## Start here
8
+ ## Choose a path
9
9
 
10
- Machine Bridge requires **Node.js 26+ and npm 12+**. Older runtimes and obsolete MCP protocol versions are not supported.
11
-
12
- 1. Follow [Installation and first use](docs/GETTING_STARTED.md).
13
- 2. Run `machine-mcp doctor`.
14
- 3. Start `machine-mcp` in the workspace you intend to expose.
15
- 4. Connect the printed remote MCP URL, or configure [local stdio](#optional-local-stdio-mcp).
16
- 5. For browser control, load and pair the packaged extension, then reload it after every package upgrade.
10
+ | Goal | Start here |
11
+ |---|---|
12
+ | Install and connect a hosted client | [Getting started](docs/GETTING_STARTED.md) |
13
+ | Add a local stdio client | [Client integration](docs/CLIENTS.md) |
14
+ | Understand components and authority | [System overview](docs/OVERVIEW.md) |
15
+ | Review security assumptions | [Threat model](docs/THREAT_MODEL.md) and [security policy](SECURITY.md) |
16
+ | Operate or troubleshoot a deployment | [Operations](docs/OPERATIONS.md) |
17
+ | Contribute code | [Contributing](CONTRIBUTING.md) |
17
18
 
18
- Choose the documentation path that matches the task:
19
+ Support boundaries are defined in [SUPPORT.md](SUPPORT.md). Repository participation follows [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md).
19
20
 
20
- | Role | Start with |
21
- |---|---|
22
- | New user | [Getting started](docs/GETTING_STARTED.md) |
23
- | Upgrading an installation | [Upgrading](docs/UPGRADING.md) |
24
- | MCP client integrator | [Clients](docs/CLIENTS.md) |
25
- | Operator or incident responder | [Operations](docs/OPERATIONS.md) |
26
- | Security reviewer | [Security policy](SECURITY.md) and [Architecture](docs/ARCHITECTURE.md) |
27
- | Contributor or maintainer | [Contributing](CONTRIBUTING.md), [Engineering](docs/ENGINEERING.md), and [Governance](GOVERNANCE.md) |
21
+ ## What it provides
28
22
 
29
- Support boundaries and safe diagnostic requirements are in [SUPPORT.md](SUPPORT.md). Project participation follows [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md).
23
+ - one transport-independent local runtime for remote OAuth and local stdio clients;
24
+ - policy profiles with shared local/Worker enforcement contracts;
25
+ - bounded file, patch, Git, process, diagnostic, application, browser, and managed-job tools;
26
+ - account roles whose authority is intersected with the connected daemon policy;
27
+ - structured, privacy-conscious lifecycle events and stable error codes;
28
+ - fail-closed state, lock, release, package, and supply-chain checks.
30
29
 
31
- It supports two transports:
30
+ The remote Worker authenticates and relays requests. It cannot directly read local files or start local processes. Local-user authority remains in the daemon process.
32
31
 
33
32
  ```text
34
- Remote clients such as ChatGPT, Claude, and Copilot Studio
35
- HTTPS + OAuth 2.1 / PKCE
36
- |
37
- Cloudflare Worker + Durable Object
38
- ^
39
- | outbound authenticated WebSocket
40
- |
41
- local runtime
42
-
43
- Local clients such as Claude Desktop, Cursor, and Codex CLI
44
- |
45
- stdio
46
- |
47
- local runtime
33
+ Hosted MCP client
34
+ -> HTTPS + OAuth 2.1 / PKCE
35
+ -> Cloudflare Worker + Durable Object
36
+ -> authenticated outbound WebSocket
37
+ -> local runtime
38
+
39
+ Local MCP client
40
+ -> stdio
41
+ -> local runtime
48
42
  ```
49
43
 
50
- The remote Worker authenticates and relays calls. It cannot directly read local files or start local processes. File, Git, image, patch, process, diagnostic, and managed-job operations execute in the local runtime.
51
-
52
- Remote readiness is end-to-end: a daemon is advertised only after a Worker probe returns through the same local dispatch and session-bound result path used by real tools. A replacement is verified before it displaces the current healthy daemon.
53
-
54
- New users should follow the end-to-end [installation and first-use guide](docs/GETTING_STARTED.md). Before sharing a deployment or connecting several accounts, read [multi-client, multi-account, and tenancy architecture](docs/MULTI_ACCOUNT.md).
44
+ The complete component and trust-boundary diagram is in [docs/OVERVIEW.md](docs/OVERVIEW.md).
55
45
 
56
- ## Default behavior and policy profiles
46
+ ## Requirements
57
47
 
58
- A newly selected workspace starts with the maximum-permission `full` profile for low-friction operation:
59
-
60
- - all read, write, edit, patch, image, Git, diagnostic, direct-process, process-session, managed-job, and shell tools are available;
61
- - direct filesystem tools may use paths outside the selected workspace;
62
- - tool results may return absolute paths;
63
- - child processes inherit the complete parent environment.
64
-
65
- Policy state records whether it came from the default, an explicit named profile, or custom overrides. Named profiles are canonical contracts: a stored `full` profile always enables writes, shell execution, unrestricted paths, the full parent environment, absolute path output, and the complete tool catalog. Any explicit per-capability narrowing is stored as `custom`. Policy revision 5 is the only accepted persisted policy format and applies compound tool requirements consistently in the local daemon and Worker.
66
-
67
- | Profile | File edits | Direct argv processes | Shell commands | Filesystem scope | Process environment |
68
- |---|---:|---:|---:|---|---|
69
- | `full` | Yes | Yes | Yes | Unrestricted | Full parent environment |
70
- | `agent` | Yes | Yes | No | Selected workspace | Isolated environment |
71
- | `edit` | Yes | No | No | Selected workspace | Isolated environment |
72
- | `review` | No | No | No | Selected workspace | Isolated environment |
48
+ - Node.js 26 or newer
49
+ - npm 12 or newer
73
50
 
74
- This default prioritizes usability, not least privilege. `run_process` and process sessions avoid command-shell parsing, but they are **not an operating-system sandbox**. `exec_command` additionally permits shell syntax and expansion. Use `--profile review`, `edit`, or `agent`, or use a container, VM, or dedicated low-privilege OS account when the client, repository, or instructions are not fully trusted.
51
+ The project intentionally follows one current runtime baseline rather than carrying compatibility branches for older Node/npm behavior. Node 26 provides the tested process, module, permission, and platform semantics used by the release gates; npm 12 provides the installation-script controls used by the documented global install. `.node-version`, `.nvmrc`, `packageManager`, strict engines, local checks, and CI keep that baseline consistent.
75
52
 
76
53
  ## Install
77
54
 
78
- For prerequisites, first remote deployment, hosted-client connection, stdio configuration, browser pairing, upgrades, troubleshooting, and removal, follow [Installation and first use](docs/GETTING_STARTED.md). The commands below are the compact installation reference.
79
-
80
- Version 1 supports only MCP protocol `2025-11-25`. Existing current-schema local state upgrades in place, but clients must reconnect and the unpacked browser extension must be reloaded after package upgrade.
81
-
82
- Node.js 26 or newer and npm 12 or newer are required. The repository pins the active development versions in `.node-version`, `.nvmrc`, and `packageManager`; project installs fail on older Node runtimes.
83
-
84
- Use a new temporary directory for the bootstrap. The existing `npm`/`npx` front-end may inspect nearby project metadata before it launches the requested npm version; starting from an empty directory prevents an unrelated outdated `devEngines` declaration from blocking the bootstrap. The actual installation is then executed by the pinned npm 12 CLI rather than whichever npm happens to be first on `PATH`.
55
+ Use an empty temporary directory so an unrelated nearby project cannot affect npm bootstrap parsing.
85
56
 
86
57
  macOS/Linux:
87
58
 
@@ -97,7 +68,7 @@ npm --version
97
68
  machine-mcp doctor
98
69
  ```
99
70
 
100
- Windows Command Prompt (`cmd.exe`):
71
+ Windows Command Prompt:
101
72
 
102
73
  ```bat
103
74
  set "MBM_INSTALL_DIR=%TEMP%\machine-bridge-mcp-install-%RANDOM%-%RANDOM%"
@@ -111,168 +82,62 @@ npm --version
111
82
  machine-mcp doctor
112
83
  ```
113
84
 
114
- `Unknown cli config "--allow-scripts"` proves the Machine Bridge install was executed by npm 11 or older rather than the required npm 12. `Invalid property "node"` or `Invalid property "devEngines.node"` means that npm parsed an outdated `devEngines` object; the npm debug log is required to identify which package supplied it. The empty-directory, pinned-npm procedure avoids relying on that old parser. If `npm --version` still reports an older version after the bootstrap, reopen the terminal and rerun `machine-mcp doctor`.
115
-
116
- Recent npm releases may otherwise warn that Wrangler's native dependencies (`esbuild`, `workerd`, and `sharp`) have install scripts awaiting approval. The scoped command approves the reviewed native script names that npm 12 evaluates during global resolution while `--omit=optional` keeps optional `fsevents` out of the installed runtime. `fsevents` is used for development-time filesystem watching rather than Machine Bridge runtime or deployment. Omitting `--omit=optional` can therefore produce a harmless blocked-script warning for `fsevents@2.3.3`; use the documented command rather than changing global npm policy. `machine-mcp doctor` remains the authoritative runtime check.
85
+ `Unknown cli config "--allow-scripts"` means the package installation ran under npm 11 or older. `Invalid property "node"` or `Invalid property "devEngines.node"` means an older npm parser inspected incompatible nearby project metadata. Repeat the empty-directory procedure and reopen the terminal if `npm --version` still resolves to an older executable.
117
86
 
118
- From a source checkout, the checked-in exact-version `allowScripts` policy approves the reviewed native dependencies:
87
+ For a source checkout:
119
88
 
120
89
  ```sh
121
- npm install
90
+ npm ci
122
91
  ./mbm # macOS/Linux
123
92
  .\mbm.cmd # Windows cmd
124
93
  ```
125
94
 
126
- ## Remote MCP for hosted clients
127
-
128
- After a global installation, `machine-mcp` can be launched from any Command Prompt or terminal; the package installation directory is not the workspace. On the first interactive Windows start, the CLI asks:
129
-
130
- ```text
131
- Workspace folder [C:\Users\Alice\MachineBridge] (press Enter to use the default):
132
- ```
95
+ ## Remote MCP quick start
133
96
 
134
- Press Enter to create and remember `%USERPROFILE%\MachineBridge`. No `cd` command or directory selection is required. Enter another folder when desired; an interactively selected Windows folder is created if it does not yet exist. Later starts reuse the remembered workspace. Advanced users and automation may still select an existing workspace explicitly:
97
+ Run the CLI in the workspace to expose:
135
98
 
136
99
  ```sh
137
100
  machine-mcp --workspace /path/to/project
138
101
  ```
139
102
 
140
- On first remote start, the CLI:
141
-
142
- 1. canonicalizes and remembers the workspace;
143
- 2. creates independent credentials and state for that workspace;
144
- 3. signs in to Cloudflare Wrangler when needed;
145
- 4. deploys a per-workspace Worker;
146
- 5. installs a platform-native login service unless `--no-autostart` is used;
147
- 6. starts an outbound-only daemon connection;
148
- 7. creates the initial `owner` account when needed and prints its password once;
149
- 8. prints the Remote MCP URL.
150
-
151
- Worker deployment is convergent rather than append-only. Each workspace retains one stable Worker name. After Wrangler reports a successful upload, Machine Bridge records the Worker URL, package/secret fingerprint, and deployed version before performing the independent `/healthz` verification. A proxy, TLS, network, timeout, or temporary service failure therefore does not erase the successful deployment evidence or cause the next start to upload again. Only a bounded health result proving that the recorded Worker is stale causes an automatic redeploy under the same name.
152
-
153
- Do not append suffixes such as `-r2` to work around a health timeout: a different `--worker-name` is a different Cloudflare Worker. Changing an initialized workspace's Worker name is rejected unless the same command also supplies `--force-worker`, which makes the replacement intentional and keeps the prior name in uninstall inventory.
154
-
155
- A normal `machine-mcp` invocation is a foreground start: it remains attached to the terminal and prints `info` logs. Startup and other state-changing operations use an owner-token/process-identity lock and wait up to 30 seconds for an ordinary concurrent startup to finish instead of failing on a brief launchd/systemd race. After a global package upgrade, the CLI unloads the platform service and also checks the workspace lock for a detached/orphan `--daemon-only` process that the service manager no longer tracks. It terminates only a process whose PID, process start time, entrypoint, canonical workspace, canonical state root, and daemon-only arguments all match, waits up to 15 seconds for the PID and lock to disappear, and then starts the installed version in the foreground. A genuine foreground or unverifiable conflict is left untouched and reported with actionable guidance. To run only in the background, use `machine-mcp service start`; inspect its owner-only logs under `~/.local/state/machine-bridge-mcp/logs/`.
156
-
157
- Recommended upgrade sequence: repeat the package-free temporary-directory installation above, then run:
158
-
159
- ```sh
160
- machine-mcp --verbose
161
- ```
103
+ On first remote start, Machine Bridge creates workspace-scoped state, signs in to Wrangler when needed, deploys one stable Worker, creates the initial `owner` account, installs user-level autostart unless disabled, starts the outbound daemon connection, and prints the MCP URL and one-time owner password.
162
104
 
163
- The global install replaces files on disk but cannot hot-reload an already running Node process; the foreground command performs the bounded service and orphan-daemon takeover. Keep `--omit=optional` in the installation step to prevent the development-only optional `fsevents` package from producing a blocked-install-script warning. If takeover fails, run `machine-mcp service status` first; it reports the platform service and workspace daemon separately. Then run `machine-mcp service stop` and retry.
164
-
165
- Use the printed URL in the MCP client:
105
+ Use the printed endpoint in the hosted client:
166
106
 
167
107
  ```text
168
- MCP Server URL: https://<worker>.<account>.workers.dev/mcp
108
+ https://<worker>.<account>.workers.dev/mcp
169
109
  ```
170
110
 
171
- During OAuth authorization, enter the name and password of a Machine Bridge account. The first start creates `owner` and prints its generated password once. Additional accounts are managed with `machine-mcp account`. The authorization flow exposes protected-resource and authorization-server discovery, dynamic client registration, PKCE S256, exact redirect/resource binding, `offline_access`, expiring hashed access and refresh-token records, public-client refresh-token rotation, per-account version checks, and a deployment-wide token version for emergency bulk revocation.
172
-
173
- The same `/mcp` endpoint supports the current hosted-client paths documented by their vendors:
174
-
175
- - ChatGPT and Grok can use the public Streamable HTTP endpoint and browser OAuth flow.
176
- - Claude custom connectors can add the exact `/mcp` URL and use dynamic client registration. The hosted Claude callback `https://claude.ai/api/mcp/auth_callback`, `offline_access`, form-encoded token exchange, proactive/reactive refresh, and one-time refresh-token rotation are covered by the Worker integration contract.
177
- - Microsoft Copilot Studio can use **Tools > Add a tool > New tool > Model Context Protocol**, select **OAuth 2.0 > Dynamic discovery**, and point **Server URL** at the exact `/mcp` endpoint. Machine Bridge advertises the Streamable transport, discovery metadata, DCR, access tokens, and rotating refresh tokens expected by that path.
178
-
179
- These are protocol and integration-contract claims, not evidence that every external tenant, plan, administrator policy, or host-side tool filter has been tested. Claude remote connectors originate from Anthropic's cloud, and Copilot Studio reaches MCP servers through Power Platform connectivity; neither requires adding a browser origin to Machine Bridge's CORS list.
180
-
181
- The Worker grants browser CORS response access to the exact first-party origins used by ChatGPT (`https://chatgpt.com` and the legacy `https://chat.openai.com`) and Grok (`https://grok.com` and its X-hosted surface at `https://x.com`). Users do not need to run Wrangler or edit Cloudflare variables. `MBM_ALLOWED_ORIGINS` remains an operator-only, comma-separated extension point for other exact browser origins; it is additive and does not replace the built-in set. Wildcards and `null` do not receive CORS permission. Actual OAuth navigations and form submissions are not rejected solely because a browser container supplies an opaque or client-specific `Origin`; authorization still depends on exact redirect/resource binding, PKCE, account authentication, and bearer-token validation. The consent page CSP permits form navigation only to the Worker itself and the validated redirect origin for that request. When the validated callback belongs to Microsoft `consent.azure-apim.net`, it additionally permits HTTPS subdomains of that same Microsoft consent domain and the exact `https://copilotstudio.microsoft.com` origin. This lets Power Platform hand the global callback to its regional endpoint and then return to Copilot Studio without granting arbitrary form destinations.
182
-
183
- ### Multiple clients and accounts
184
-
185
- One Worker supports several named accounts and OAuth clients. Accounts have independent passwords, roles, active state, versions, authorization codes, access tokens, and refresh tokens. The roles are `reviewer`, `editor`, `operator`, and `owner`; their effective authority is intersected with the connected daemon policy and enforced in both the Worker and local runtime. Role changes, suspension, password rotation, and removal revoke only the affected account.
186
-
187
- For remote connections, `server_info.authorization.effective_policy` and `server_info.authorization.effective_tools` are the authoritative account-permission fields. `server_info.daemon.policy` and `server_info.daemon.tools` describe only the local daemon capability ceiling before account-role filtering. Remote `project_overview` likewise places the effective account policy/tools in `policy` and `tools`, while preserving the daemon ceiling separately as `daemonPolicy` and `daemonTools`.
111
+ Remote readiness is end-to-end. A daemon becomes available only after a Worker probe traverses the same authenticated local dispatch and session-bound result path used by real tool calls. A replacement daemon is verified before it displaces a healthy incumbent.
188
112
 
189
- This is application-level authorization, not kernel or browser-profile isolation. All accounts reach one daemon running as one OS user. Use separate Workers and preferably separate low-privilege OS accounts, containers, or VMs for mutually untrusted users or hard tenant isolation. See [Multi-account authorization and tenancy](docs/MULTI_ACCOUNT.md).
113
+ For account roles, OAuth lifecycle, supported callback behavior, and tenancy limits, read [docs/GETTING_STARTED.md](docs/GETTING_STARTED.md) and [docs/MULTI_ACCOUNT.md](docs/MULTI_ACCOUNT.md).
190
114
 
191
- ## Optional local stdio MCP
115
+ ## Local stdio quick start
192
116
 
193
- stdio is a local transport, not a model provider. Claude Desktop, Cursor, Codex CLI, ChatGPT Desktop, or another MCP host supplies its own model/session and launches `machine-bridge-mcp` as a subprocess. The MCP server only exposes tools and returns their results; it does not borrow the model running in ChatGPT web.
194
-
195
- Many coding clients already have strong native filesystem and terminal tools, so configuring this stdio server is optional. It is useful when you want the same Machine Bridge tool schemas, patch behavior, process sessions, policy profiles, and logs across several clients, or when you want local access without deploying Cloudflare. If the client's built-in tools already meet your needs, there is no reason to add this server.
196
-
197
- Generate ready-to-paste configuration:
117
+ Generate client configuration:
198
118
 
199
119
  ```sh
200
120
  machine-mcp client-config --client all --workspace /path/to/project
201
121
  ```
202
122
 
203
- Or run stdio directly:
123
+ Or launch stdio directly:
204
124
 
205
125
  ```sh
206
126
  machine-mcp stdio --workspace /path/to/project
207
127
  ```
208
128
 
209
- The stdio server writes only JSON-RPC messages to stdout and operational logs to stderr. See [docs/CLIENTS.md](docs/CLIENTS.md) for the host/model distinction and transport trade-offs.
210
-
211
- ## Session instructions, local skills, commands, apps, and browser
212
-
213
- Machine Bridge now starts with useful agent guidance even when the user has not created `MODEL.md`, `AGENTS.md`, or `.machine-bridge/agent.json`.
214
-
215
- Two lower-precedence virtual sources are generated in memory:
216
-
217
- - `machine-bridge://defaults/working-agreements` supplies conservative cross-project rules for inspection, scoped changes, preservation of unrelated work, validation, security, Git discipline, and explicit authorization for deployment/publication/destructive operations.
218
- - `machine-bridge://project-context/current` derives bounded facts from the active repository: target path, common project/build files, package-manager declarations and lockfiles, package script names, runtime constraints, documentation files, and CI entrypoints. It never injects package-script bodies or source contents and does not claim commands were validated.
219
-
220
- No files are created or modified by this bootstrap. Explicit user and repository instructions load later and therefore override the defaults. `session_bootstrap` supplies the chain during MCP initialization; `agent_context` exposes every source and hash; `resolve_task_capabilities` refreshes project facts, instructions, skills, commands, and installed-application matches for the current task. `server_info` and `project_overview` expose whether bootstrap and task resolution actually reached the local runtime without retaining raw task text.
221
-
222
- Optional user-global preferences still live in `~/.config/machine-bridge-mcp/agent.json`:
223
-
224
- ```json
225
- {
226
- "version": 1,
227
- "model_instructions_file": "~/.config/machine-bridge-mcp/MODEL.md"
228
- }
229
- ```
230
-
231
- Use `MODEL.md` for preferences not covered by the baseline, such as default language or organization-specific review rules. Repository-specific rules belong in `AGENTS.md`/`AGENTS.override.md`; deeper files take precedence. Keep secrets out of every instruction file.
232
-
233
- To disable either automatic layer globally:
234
-
235
- ```json
236
- {
237
- "version": 1,
238
- "builtin_instructions": false,
239
- "automatic_project_context": false
240
- }
241
- ```
242
-
243
- Repositories cannot disable these user-level controls. Editing instruction files or project metadata does not require a daemon restart; start a new MCP conversation or reconnect when initialization-time injection must be guaranteed from the beginning.
244
-
245
- Skill discovery follows Codex-style progressive disclosure. Default project roots include target-to-project `.agents/skills` and `.codex/skills`; unrestricted policy also enables `~/.agents/skills`, `CODEX_HOME/skills` (normally `~/.codex/skills`), and the Unix admin root. Newly added or edited skills are found on the next resolver/list call without restarting the daemon. Safe root `package.json` script names are also exposed as `package.*` command aliases with bounded deterministic English/Chinese workflow-intent terms; explicit `.machine-bridge/agent.json` commands can override or delete them. Package-script bodies are never injected, but invoking one still runs repository-controlled code with the active local policy. See [Session instructions, defaults, skills, commands, and capability discovery](docs/AGENT_CONTEXT.md).
246
-
247
- Under canonical `full`, Machine Bridge also exposes structured local automation:
248
-
249
- - installed application discovery/opening and macOS Accessibility inspection/actions;
250
- - a packaged Chromium extension that controls the profile into which the user loads it, including that profile's tabs, login state, and windows; Machine Bridge does not launch a separate browser process;
251
- - current DOM source and frame/open-Shadow-DOM inspection, stable semantic element references, actionability waits, fixed trusted mouse/keyboard input, explicit browser waits, tab management, complex multi-field forms, resource-backed secret fields, resource-backed file uploads, and screenshots.
252
-
253
- One-time browser setup:
254
-
255
- ```sh
256
- machine-mcp browser setup
257
- machine-mcp browser status
258
- ```
259
-
260
- Load the printed unpacked-extension directory in the Chromium profile you actually use; Machine Bridge does not install it into Playwright or a separate automation profile. After every Machine Bridge upgrade, reload the unpacked extension and accept any new browser permission. `machine-mcp browser status` reports both the expected packaged extension build and the authenticated connected build/protocol, and states that Machine Bridge did not launch the browser. It cannot infer whether the extension was loaded into a daily or isolated profile; that is determined by where the user installed it. Trusted input uses the Chromium `debugger` permission only for fixed, short-lived DevTools Input commands. The badge shows `ON` only after the broker acknowledges the version/capability handshake. The local pairing token remains in owner-only state and non-cacheable loopback HTML; it is not returned through MCP. For a mass-market release, distribute the same extension as a signed browser-store build rather than asking end users to enable Developer mode. See [Local application and browser automation](docs/LOCAL_AUTOMATION.md).
261
-
262
- Machine Bridge can discover, refresh, rank, and load capabilities automatically. The MCP host still owns tool selection and approval, so the server cannot force a host to expose or invoke a recommended skill, command, app, or browser operation. Check `server_info.observability.capability_routing` or `project_overview.capabilityRouting` to distinguish “the host never called the resolver” from “the resolver ran but found no relevant capability.”
129
+ stdio is only a transport. The MCP host supplies the model and session; Machine Bridge supplies tools and executes them locally. See [docs/CLIENTS.md](docs/CLIENTS.md).
263
130
 
131
+ ## Policy profiles
264
132
 
265
- ## Runtime lifecycle and observability
266
-
267
- Every tool call passes through one execution pipeline: bounded call registration and deadline/cancellation ownership, structured observability, shared policy authorization, then the typed handler. Errors use stable codes and retryability metadata instead of transport-specific message parsing. `server_info` exposes the local lifecycle state, in-flight calls, active process ownership, per-tool outcomes, durations, error-code counts, enforced execution limits, and explicit `not-enforced` CPU/memory/network-isolation fields. The Worker adds pending internal/request-key indexes, daemon candidate/socket counters, and Worker-side per-tool outcomes.
268
-
269
- Foreground logging defaults to human-readable text. Installed background services use warning-level JSON events by default. Use `--log-format json` for machine-readable foreground logs; arguments, outputs, credentials, resource contents, and local paths remain excluded or redacted.
270
-
271
- ## Policy controls
272
-
273
- Policy revision 5 is defined once in `src/shared/policy-contract.json`. The local runtime, Worker advertisement filter, manager-level defense-in-depth checks, tests, and generated [policy reference](docs/POLICY_REFERENCE.md) consume that same contract. A custom policy is authorized by capabilities rather than its display name; compound classes such as `write+direct-exec` require every capability.
133
+ | Profile | File edits | Direct argv | Shell | Filesystem | Environment |
134
+ |---|---:|---:|---:|---|---|
135
+ | `full` | Yes | Yes | Yes | local-user accessible | parent environment |
136
+ | `agent` | Yes | Yes | No | selected workspace | isolated |
137
+ | `edit` | Yes | No | No | selected workspace | isolated |
138
+ | `review` | No | No | No | selected workspace | isolated |
274
139
 
275
- The default is `full`. Narrow or customize it with explicit flags:
140
+ The default is intentionally `full` for owner-operated local automation. This is a usability choice, not a least-privilege claim. Narrow it explicitly:
276
141
 
277
142
  ```text
278
143
  --profile full|agent|edit|review
@@ -282,279 +147,115 @@ The default is `full`. Narrow or customize it with explicit flags:
282
147
  --full-env
283
148
  --unrestricted-paths
284
149
  --absolute-paths
285
- --log-level error|warn|info|debug
286
- --log-format text|json
287
- --verbose
288
- --quiet
289
- ```
290
-
291
- Important distinctions:
292
-
293
- - The default `full` profile already enables unrestricted paths, absolute path output, and the complete parent environment.
294
- - `--unrestricted-paths=false`, `--absolute-paths=false`, and `--full-env=false` can narrow those individual settings.
295
- - `--absolute-paths` changes returned path metadata; it does not independently grant additional access.
296
- - In isolated-environment profiles, commands receive private HOME, temp, and cache directories plus a small set of platform variables.
297
- - The server has no filename blacklist. Under `full`, direct read tools may read any UTF-8 regular file that the local OS user can access, including files outside the workspace and names such as `.env`, `passwords.txt`, or private-key files.
298
- - Maximum local policy does not override operating-system permissions, macOS TCC/SIP, Windows ACLs, container boundaries, or independent safety rules imposed by the MCP host/platform. `full` means the local daemon and relay advertise the complete catalog; a connector may still expose only a subset to a particular session. Machine Bridge cannot observe or override that host-side subset. A host-generated “sensitive file” denial is outside this server's enforcement layer.
299
-
300
- ## Diagnose host, bridge, and local execution failures
301
-
302
- A displayed `full` policy proves only that Machine Bridge has enabled its own capabilities. Execution can still be denied by the MCP host/connector, macOS TCC/SIP, Unix permissions, Windows ACLs, shell policy, or endpoint-security software.
303
-
304
- Use:
305
-
306
- ```text
307
- diagnose_runtime
308
150
  ```
309
151
 
310
- or locally:
152
+ The shared source of truth is `src/shared/policy-contract.json`. The generated matrix is in [docs/POLICY_REFERENCE.md](docs/POLICY_REFERENCE.md).
311
153
 
312
- ```sh
313
- machine-mcp doctor
314
- ```
154
+ For remote calls, `server_info.authorization.effective_policy` and `effective_tools` are authoritative. Daemon policy and tools describe only the local capability ceiling before account-role and host-side filtering.
315
155
 
316
- A successful `diagnose_runtime` response proves that request reached the local daemon. It then reports fixed probes for Machine Bridge policy, private filesystem access, direct process spawning, shell execution, managed-job storage, and registered resources. If the host blocks the tool call before any structured response, the server cannot diagnose that request because it never received it.
156
+ ## Browser and application automation
317
157
 
318
- Run a real local acceptance test for the canonical `full` contract:
158
+ Under canonical `full`, Machine Bridge can discover and operate supported local applications and can control the Chromium profile into which the packaged extension is loaded.
319
159
 
320
160
  ```sh
321
- machine-mcp full-test --workspace /path/to/project
161
+ machine-mcp browser setup
162
+ machine-mcp browser status
322
163
  ```
323
164
 
324
- The test uses a temporary sandbox to perform an outside-workspace read/write, direct process, shell command, parent-environment inheritance, Ed25519 generation, temporary `authorized_keys` write, SSH client check, Google Cloud OS Login command availability check, non-mutating `sudo -n true` probe, and detached managed-job/finally lifecycle. It does not add a cloud key, contact a remote maintenance host, modify a user account, or retain the generated key.
165
+ Load the printed unpacked-extension directory into the intended Chromium profile. Reload the extension after every Machine Bridge upgrade. The broker validates a versioned capability handshake, keeps pairing state local and owner-only, and does not return the pairing token through MCP.
325
166
 
326
- ## Managed jobs and local resources
167
+ Machine Bridge does not launch or identify a separate browser profile. It controls whichever profile contains the extension, including that profile's tabs and login state. Read [docs/LOCAL_AUTOMATION.md](docs/LOCAL_AUTOMATION.md) before enabling it.
327
168
 
328
- Long, remote, multi-step, or cleanup-sensitive work should not depend on a sequence of later MCP calls remaining available. `start_job` durably accepts ordered argv steps plus `finally_steps`, then launches an independent local runner. It continues after MCP disconnects or later host-side tool refusals.
169
+ ## Durable work and local resources
329
170
 
330
- When the host blocks execution-class tools but still permits state mutation, `stage_job` stores the same validated plan without starting any process. The operator can review it with `machine-mcp job inspect JOB_ID` and explicitly authorize execution with `machine-mcp job approve JOB_ID`. Cancelling a staged plan does not run main or finally steps.
171
+ Interactive process sessions end with the daemon connection. Long, cleanup-sensitive, or remotely initiated workflows should use managed jobs, which persist ordered argv steps and `finally_steps` under owner-only local state.
331
172
 
332
- Register credential/key files locally without sending their contents through MCP:
173
+ Credentials and files can be registered by alias without returning their contents through MCP:
333
174
 
334
175
  ```sh
335
- chmod 600 ~/.ssh/example_maintenance_ed25519
336
176
  machine-mcp resource add maintenance-key ~/.ssh/example_maintenance_ed25519
337
- machine-mcp resource list # paths omitted by default
338
- machine-mcp resource list --show-paths # explicit local-only path disclosure
339
- ```
340
-
341
- Generate an Ed25519 key and register its private file in one operation:
342
-
343
- ```sh
344
- machine-mcp resource generate-ssh-key maintenance-key ~/.ssh/machine-mcp-example-maint-ed25519
345
- ```
346
-
347
- Under canonical `full`, an authorized MCP host can invoke `generate_ssh_key_resource` with the same semantics. The tool is idempotent, verifies that existing public/private files match, enforces local file modes where supported, and returns the public fingerprint, key type, and registration status—not private key bytes or local paths. Pass `expose_paths=true` only when the caller genuinely needs those paths.
348
-
349
- A job refers to the alias rather than the value:
350
-
351
- ```json
352
- {
353
- "name": "remote maintenance",
354
- "steps": [
355
- {
356
- "argv": [
357
- "ssh",
358
- "-i",
359
- "{{resource:maintenance-key}}",
360
- "admin@server.example",
361
- "sh",
362
- "-s"
363
- ],
364
- "stdin": "set -eu\n# remote repair commands\n"
365
- }
366
- ],
367
- "finally_steps": [
368
- {
369
- "argv": ["ssh", "-i", "{{resource:maintenance-key}}", "admin@server.example", "rm", "-f", "/tmp/helper"],
370
- "allow_failure": true
371
- }
372
- ]
373
- }
374
- ```
375
-
376
- Prefer sending a remote script through stdin so no remote helper file is created. For local helpers, use job-scoped `temporary_files` and `{{temp:name}}`; the private job runtime is removed after cleanup.
377
-
378
- Resources can be injected by private copied path (`{{resource:name}}`), `stdin_resource`, or `env_resources`. Use `capture_output: "discard"` for commands that may echo credentials. Exact resource values and common exact encodings are redacted from retained results, but transformed or partial-secret detection is not guaranteed.
379
-
380
- If the MCP host later blocks all execution tools, use the local fallback:
381
-
382
- ```sh
383
- machine-mcp job list
384
- machine-mcp job read JOB_ID
385
- machine-mcp job cancel JOB_ID
177
+ machine-mcp resource list
386
178
  machine-mcp job submit plan.json
387
179
  ```
388
180
 
389
- Finally steps and restart recovery are best effort and should be idempotent. See [docs/MANAGED_JOBS.md](docs/MANAGED_JOBS.md) for lifecycle, security limits, plan format, and diagnosis guidance.
390
-
391
- ## Tools
392
-
393
- The exact `tools/list` response reflects the active local policy. Definitions come from one shared catalog used by both Worker and stdio transports.
394
-
395
- ### Workspace and content
396
-
397
- - `server_info`
398
- - `project_overview`
399
- - `session_bootstrap` — built-in defaults, automatic project facts, explicit instructions, and refresh metadata
400
- - `agent_context` — complete default/explicit instruction precedence, skill summaries, and registered commands for a target path
401
- - `resolve_task_capabilities` — live skill/command ranking and local automation recommendations
402
- - `list_local_skills`
403
- - `load_local_skill` — load instructions and file inventory without implicit execution
404
- - `list_local_commands`
405
- - `list_roots`
406
- - `list_dir`
407
- - `list_files`
408
- - `read_file` — whole UTF-8 files or bounded line ranges
409
- - `view_image` — bounded PNG, JPEG, GIF, or WebP as native MCP image content
410
- - `search_text`
411
-
412
- ### Local applications and browser (`full`)
413
-
414
- - `list_local_applications`
415
- - `open_local_application`
416
- - `inspect_local_application` — bounded macOS Accessibility tree
417
- - `operate_local_application` — structured Accessibility action, no arbitrary script source
418
- - `browser_status`
419
- - `pair_browser_extension`
420
- - `browser_list_tabs`
421
- - `browser_manage_tabs` — create, activate, or close tabs
422
- - `browser_get_source` — bounded current DOM HTML with one aggregate byte budget across up to 64 accessible frames
423
- - `browser_inspect_page` — semantic controls, bounded LRU refs, state, geometry, and explicit frame/node/ref truncation metadata
424
- - `browser_wait` — bounded URL/load/text/element-state waits
425
- - `browser_action` — actionability checks plus `auto`, `trusted`, or `dom` input mode; ambiguous post-dispatch failures are never replayed through DOM
426
- - `browser_fill_form`
427
- - `browser_upload_files` — registered local resources to file inputs
428
- - `browser_screenshot` — restores the prior active tab and does not focus another window
429
-
430
-
431
- ### Mutation
432
-
433
- - `write_file` — atomic whole-file write with create-only and SHA-256 checks
434
- - `edit_file` — exact text replacement with ambiguity rejection
435
- - `apply_patch` — bounded multi-file add/update/move/delete transaction with rollback
436
-
437
- ### Git
438
-
439
- - `git_status`
440
- - `git_diff` — working tree or staged
441
- - `git_log` — structured commits; author email omitted unless explicitly requested
442
- - `git_show`
443
-
444
- Repository-configured external diff, text conversion, and filesystem-monitor helpers are disabled for bridge Git inspection.
181
+ See [docs/MANAGED_JOBS.md](docs/MANAGED_JOBS.md) for integrity checks, recovery, redaction, cleanup, and residual risks.
445
182
 
446
- ### Diagnostics and durable work
183
+ ## Operations
447
184
 
448
- - `diagnose_runtime` — fixed layered probes; no user-controlled command input
449
- - `list_local_resources` — aliases and validation status without paths or values
450
- - `generate_ssh_key_resource` — canonical-full-only Ed25519 generation and private-file registration; private bytes and local paths are omitted by default
451
- - `stage_job` — persist a validated plan for later local approval without executing it
452
- - `start_job` — detached ordered argv steps, private temporary files, and finally steps
453
- - `list_jobs`
454
- - `read_job`
455
- - `cancel_job`
456
-
457
- Managed jobs are non-interactive and persist independently of the MCP connection. Process sessions remain interactive and memory-only.
458
-
459
- ### Processes
460
-
461
- - `run_local_command` — fixed argv execution of an explicit or automatic package-script command
462
- - `run_process` — one-shot argv execution without a shell
463
- - `start_process`
464
- - `read_process`
465
- - `write_process`
466
- - `kill_process`
467
- - `exec_command` — shell execution, available only in `shell` mode
468
-
469
- 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.
470
-
471
- ## Path and write behavior
472
-
473
- When workspace confinement is enabled (`agent`, `edit`, `review`, or an explicit override), 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. The default `full` profile permits direct filesystem paths outside the workspace.
474
-
475
- 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.
476
-
477
- The default `full` profile returns absolute paths. The `agent`, `edit`, and `review` profiles return workspace-relative paths to reduce unnecessary disclosure of usernames and local directory layouts.
478
-
479
- ## Commands
185
+ Common commands:
480
186
 
481
187
  ```text
482
- machine-mcp [start options]
483
- machine-mcp stdio [options]
484
- machine-mcp client-config [all|claude|cursor|codex|generic]
485
- machine-mcp workspace show|set|reset
486
- machine-mcp service status|install|start|stop|uninstall
188
+ machine-mcp
487
189
  machine-mcp status
488
190
  machine-mcp doctor
489
- machine-mcp rotate-secrets
490
- machine-mcp resource add|list|check|remove
191
+ machine-mcp workspace show|set|reset
192
+ machine-mcp service status|install|start|stop|uninstall
491
193
  machine-mcp account list|add|role|enable|disable|rotate-password|remove
492
194
  machine-mcp browser status|setup|pair|path
195
+ machine-mcp resource add|list|check|remove
493
196
  machine-mcp job submit|inspect|approve|list|read|cancel
494
- machine-mcp uninstall [--keep-worker] [--yes]
495
- ```
496
-
497
- Each canonical workspace has an independent profile, Worker name, credential set, state file, startup lock, and daemon lock. Supplying a genuinely different `--workspace` therefore selects or creates a different Worker; junctions and symbolic links are canonicalized before the workspace identity is hashed. Use `machine-mcp workspace show` and `machine-mcp status` before treating two Worker names as duplicates.
498
-
499
- ## Autostart
500
-
501
- Remote mode supports:
502
-
503
- - macOS user LaunchAgent;
504
- - Linux `systemd --user`, with best-effort lingering;
505
- - Windows Scheduled Task at logon.
506
-
507
- The service definition contains neither Worker/account credentials nor a duplicate policy. It loads the selected policy from owner-only local state and uses the documented `full` default if policy state is absent. launchd/systemd definitions persist a sanitized absolute-only PATH captured during installation, including the stable Node/CLI directories, so background `full` mode does not lose Homebrew or other developer command locations. A private, allowlisted service-environment snapshot preserves proxy and custom-CA variables needed by a background daemon; status reports only configured key names, never values. Re-run `machine-mcp service install` after changing those variables. Custom Windows state paths used for autostart must also remain within the Task Scheduler path limit and must not contain a literal `%`.
508
-
509
- Windows uses a short private launcher instead of putting the full Node command in Task Scheduler's bounded `/TR` field. The launcher routes output to the normal service logs and restarts a nonzero daemon exit after a delay. The task runs with least privilege when that Windows user signs in. Thus a reboot followed by normal user sign-in needs no command, but the default installation deliberately does not claim pre-login availability and does not store a Windows password or run as `SYSTEM`. Background services run at log level `warn` with JSON output: relay, protocol, and service problems are retained as bounded structured events, while all per-tool success/failure/cancellation/timing events remain debug-only. Logs are owner-only where supported and bounded by tail trimming.
510
-
511
- ## Secret rotation
512
-
513
- ```sh
514
197
  machine-mcp rotate-secrets
198
+ machine-mcp uninstall [--keep-worker] [--yes]
515
199
  ```
516
200
 
517
- Rotation stops the installed service, refuses to proceed while another foreground daemon owns the workspace lock, and rotates the account-administration secret, daemon secret, and deployment-wide OAuth token version. It invalidates every account access and refresh token and requires all clients to authorize again. Use `machine-mcp account rotate-password NAME` for targeted password rotation without affecting other accounts.
518
-
519
- ## State and observability
520
-
521
- Default state roots:
201
+ Autostart uses a macOS LaunchAgent, Linux `systemd --user`, or a least-privilege Windows logon task. State and logs are owner-only where the platform supports it. Structured events exclude arguments, results, credential values, and raw local paths by default. Read [docs/OPERATIONS.md](docs/OPERATIONS.md) and [docs/LOGGING.md](docs/LOGGING.md).
522
202
 
523
- - macOS/Linux: `~/.local/state/machine-bridge-mcp`
524
- - Linux with `XDG_STATE_HOME`: `$XDG_STATE_HOME/machine-bridge-mcp`
525
- - Windows: `%APPDATA%\machine-bridge-mcp`
203
+ ## Tool reference
526
204
 
527
- State/config writes use owner-only temporary files, `fsync`, and atomic replacement. Exclusive locks are fully written before a same-directory hard-link claim becomes visible; lock ownership includes a token and process start time so PID reuse and lock replacement cannot silently transfer ownership. Only successfully read but invalid JSON is retained as a bounded corrupt backup; permission, symbolic-link, size, encoding, and I/O failures remain explicit. A custom state root must not equal, contain, or be contained by the selected workspace. Resource source paths are redacted from `status` output. Active managed-job plans are owner-only and are deleted after a terminal result; bounded redacted results are retained temporarily. Uninstall first acquires a state-root maintenance lock that blocks new profile/state operations and state-backed operations from already constructed managed-job/browser managers, stops the platform service and all verified workspace daemons before removing definitions, rechecks jobs and locks, then validates markers, canonical paths, workspace/source exclusions, and known contents before recursive deletion.
205
+ The exact tool set depends on the effective policy and account role. Both transports consume the same catalog in `src/shared/tool-catalog.json`; the generated reference is [docs/TOOL_REFERENCE.md](docs/TOOL_REFERENCE.md).
528
206
 
529
- Remote Worker health probes and the relay honor standard `HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY` environment routing. Invalid or unsupported proxy configuration fails fast. Browser-broker health is strictly loopback-direct and does not rely on `NO_PROXY`. Health and relay diagnostics report only coarse `direct`, `proxy`, or invalid-route state and never proxy URLs or credentials.
207
+ Major groups include:
530
208
 
531
- Default foreground logs report authenticated relay readiness, readable persistent-degradation summaries, and recovery rather than raw WebSocket callbacks or JSON field dumps. Brief self-healing disconnects and close codes/reasons are debug-only. Stalled connection attempts have a deadline, and sustained-outage reminders use autonomous exponential backoff. Every per-tool event—including success, failure, cancellation, and slow-call timing—also appears only at `--log-level debug` or `--verbose`. Background services use `warn`, so ordinary tool outcomes and brief network changes do not fill daemon logs. Log messages and structured fields are bounded, secret-like keys and known token formats are redacted, and tool arguments/results are not written. See [docs/LOGGING.md](docs/LOGGING.md) and [docs/OPERATIONS.md](docs/OPERATIONS.md).
209
+ - workspace reads, writes, exact edits, and transactional patches;
210
+ - Git status, diff, log, and show with helper suppression and privacy bounds;
211
+ - direct argv execution, shell execution, and interactive process sessions;
212
+ - runtime diagnostics and structured project/capability discovery;
213
+ - managed jobs and registered local resources;
214
+ - supported application and browser operations.
532
215
 
533
216
  ## Development and verification
534
217
 
535
218
  ```sh
536
219
  npm ci
537
- npm run check
220
+ npm run check:fast # local feedback: static, unit, architecture, policy, lifecycle
221
+ npm run check # complete suite, equivalent to check:full
538
222
  npm run worker:dry-run
539
223
  npm audit --audit-level=high
540
224
  npm audit --omit=dev --audit-level=high
541
225
  npm pack --dry-run
542
226
  ```
543
227
 
544
- `npm run check` covers privacy and package-impact gates, local-release-acceptance hash logic, architecture/link invariants, generated Worker types, TypeScript, recursively discovered JavaScript syntax, semantic undefined-identifier checks, catalog-to-runtime handler parity, deterministic relay lifecycle and secure-file tests, concurrent lock/atomic-replacement/PID-reuse fixtures, fail-closed service lifecycle tests, descendant process-tree termination, local path/write/state/log/service invariants, Ed25519/RSA generation and key-pair validation, real-machine `full` sandbox acceptance, a clean npm package-manifest/mode/sensitive-artifact check, an isolated installation of the actual packed tarball whose zero-argument CLI startup must reach a controlled Worker-deployment boundary, managed-job integrity/redaction/finally/cancellation/recovery, a live stdio MCP flow, a live local OAuth/Worker/WebSocket/MCP flow covering discovery, Claude callback routing, rotating refresh tokens, replay rejection, and account-targeted refresh revocation, plus a real Chromium negative/positive test for CSP-governed OAuth callback navigation. GitHub Actions runs the complete suite on Linux, macOS, and Windows with the pinned Node 26/npm 12 baseline.
228
+ The check plan is explicit in `scripts/check-plan.mjs`. macOS and Windows CI run the platform plan plus the installed-package smoke test. Linux CI runs the complete plan, including coverage, browser broker, package/install, stdio, Worker/OAuth, and real-browser navigation tests. Package audit, CodeQL, dependency review, governance, and OpenSSF Scorecard remain separate fail-closed jobs.
545
229
 
546
- For an npm-package release, automated checks are followed by a separate repository-owner acceptance boundary:
230
+ Testing details and design rules are in [docs/TESTING.md](docs/TESTING.md). Engineering invariants are in [docs/ENGINEERING.md](docs/ENGINEERING.md).
231
+
232
+ ## Release boundary
233
+
234
+ A package change requires a version bump, matching changelog section, complete verification, and interactive verification of the exact candidate tarball:
547
235
 
548
236
  ```sh
549
237
  npm run release:candidate
550
- # Test the exact .release-candidate/*.tgz artifact locally.
551
- npm run release:accept -- --confirm "I TESTED machine-bridge-mcp <version> LOCALLY AND IT WORKS"
552
- npm run github:push
238
+ # The repository owner runs this and leaves the candidate in the foreground:
239
+ npm run release:candidate:start -- --allow-worker-deploy
240
+ # The coding agent verifies the live candidate, records acceptance, pushes, merges, then runs:
241
+ npm run release
553
242
  ```
554
243
 
555
- The coding agent must stop before the first GitHub push until the owner tests the exact tarball. The acceptance record stores package hashes, not machine paths or logs, and any packaged-file change invalidates it. See [docs/RELEASING.md](docs/RELEASING.md).
244
+ The owner action is to explicitly authorize and start the exact candidate, including an in-place update of the configured same-name Worker when required. The coding agent must observe the deployed Worker version/hash, remote health, relay readiness, connected candidate version, and representative functionality before recording acceptance; automated checks alone are insufficient. npm publication and Worker deployment remain separate owner-operated live actions. See [docs/RELEASING.md](docs/RELEASING.md).
556
245
 
557
- The cross-cutting 0.12.0 review, corrected failure modes, and residual OS-level limits are recorded in [docs/AUDIT.md](docs/AUDIT.md). See also [docs/GETTING_STARTED.md](docs/GETTING_STARTED.md), [docs/MULTI_ACCOUNT.md](docs/MULTI_ACCOUNT.md), [docs/AGENT_CONTEXT.md](docs/AGENT_CONTEXT.md), [docs/LOCAL_AUTOMATION.md](docs/LOCAL_AUTOMATION.md), [docs/MANAGED_JOBS.md](docs/MANAGED_JOBS.md), [docs/TESTING.md](docs/TESTING.md), [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md), [docs/ENGINEERING.md](docs/ENGINEERING.md), [docs/PROJECT_STANDARDS.md](docs/PROJECT_STANDARDS.md), the generated [MCP tool reference](docs/TOOL_REFERENCE.md), and [SECURITY.md](SECURITY.md).
246
+ ## Documentation
247
+
248
+ - [System overview](docs/OVERVIEW.md)
249
+ - [Architecture](docs/ARCHITECTURE.md)
250
+ - [Threat model](docs/THREAT_MODEL.md)
251
+ - [Security policy](SECURITY.md)
252
+ - [Getting started](docs/GETTING_STARTED.md)
253
+ - [Operations](docs/OPERATIONS.md)
254
+ - [Testing](docs/TESTING.md)
255
+ - [Engineering](docs/ENGINEERING.md)
256
+ - [Project standards](docs/PROJECT_STANDARDS.md)
257
+ - [Audit record](docs/AUDIT.md)
258
+ - [Privacy hygiene](docs/PRIVACY.md)
558
259
 
559
260
  ## Uninstall
560
261
 
@@ -563,10 +264,8 @@ machine-mcp uninstall
563
264
  npm uninstall -g machine-bridge-mcp
564
265
  ```
565
266
 
566
- Use `--keep-worker` to retain deployed Workers while removing local state and autostart. Uninstall is fail-closed: if the platform service, a verified daemon, a managed job, an unreadable lock, or a service-definition removal cannot be resolved safely, service definitions and local state are retained for diagnosis instead of being partially deleted.
267
+ Use `--keep-worker` to retain deployed Workers while removing local state. Removal is fail-closed when service, daemon, job, lock, or state ownership cannot be verified safely.
567
268
 
568
269
  ## License
569
270
 
570
271
  MIT
571
-
572
- See [repository privacy hygiene](docs/PRIVACY.md) and [contribution/release discipline](CONTRIBUTING.md) before committing. Every npm-package change requires a new version, an owner-tested exact tarball, a matching acceptance record, and a matching npm release. GitHub-only infrastructure changes may remain source-only when package bytes are unchanged.