@easonwumac/computer-linker 0.1.2
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 +230 -0
- package/LICENSE +21 -0
- package/README.md +539 -0
- package/SECURITY.md +48 -0
- package/dist/api.d.ts +2 -0
- package/dist/api.js +360 -0
- package/dist/audit.d.ts +70 -0
- package/dist/audit.js +102 -0
- package/dist/capabilities.d.ts +98 -0
- package/dist/capabilities.js +718 -0
- package/dist/capability-policy.d.ts +22 -0
- package/dist/capability-policy.js +103 -0
- package/dist/chatgpt.d.ts +167 -0
- package/dist/chatgpt.js +561 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +4621 -0
- package/dist/client-smoke.d.ts +44 -0
- package/dist/client-smoke.js +639 -0
- package/dist/client.d.ts +217 -0
- package/dist/client.js +357 -0
- package/dist/codex-runs.d.ts +35 -0
- package/dist/codex-runs.js +66 -0
- package/dist/computer-contract.d.ts +33 -0
- package/dist/computer-contract.js +384 -0
- package/dist/computer-operation-registry.d.ts +45 -0
- package/dist/computer-operation-registry.js +179 -0
- package/dist/config-diagnostics.d.ts +11 -0
- package/dist/config-diagnostics.js +185 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.js +69 -0
- package/dist/history-insights.d.ts +132 -0
- package/dist/history-insights.js +457 -0
- package/dist/http-auth.d.ts +3 -0
- package/dist/http-auth.js +15 -0
- package/dist/mcp-surface.d.ts +5 -0
- package/dist/mcp-surface.js +25 -0
- package/dist/oauth-provider.d.ts +52 -0
- package/dist/oauth-provider.js +325 -0
- package/dist/package-metadata.d.ts +7 -0
- package/dist/package-metadata.js +24 -0
- package/dist/permissions.d.ts +43 -0
- package/dist/permissions.js +150 -0
- package/dist/platform-shell.d.ts +28 -0
- package/dist/platform-shell.js +124 -0
- package/dist/processes.d.ts +50 -0
- package/dist/processes.js +178 -0
- package/dist/profile.d.ts +159 -0
- package/dist/profile.js +416 -0
- package/dist/screenshot.d.ts +47 -0
- package/dist/screenshot.js +302 -0
- package/dist/search.d.ts +34 -0
- package/dist/search.js +340 -0
- package/dist/security.d.ts +10 -0
- package/dist/security.js +108 -0
- package/dist/sensitive-files.d.ts +4 -0
- package/dist/sensitive-files.js +96 -0
- package/dist/server.d.ts +9 -0
- package/dist/server.js +713 -0
- package/dist/service.d.ts +125 -0
- package/dist/service.js +486 -0
- package/dist/sessions.d.ts +26 -0
- package/dist/sessions.js +34 -0
- package/dist/tunnels.d.ts +161 -0
- package/dist/tunnels.js +1243 -0
- package/dist/workspace-operations.d.ts +170 -0
- package/dist/workspace-operations.js +3219 -0
- package/dist/workspaces.d.ts +61 -0
- package/dist/workspaces.js +353 -0
- package/docs/agent-instructions.md +65 -0
- package/docs/alpha-evidence.example.json +54 -0
- package/docs/api-compatibility.md +56 -0
- package/docs/architecture.md +561 -0
- package/docs/chatgpt-setup.md +397 -0
- package/docs/client-recipes.md +98 -0
- package/docs/client-sdk.md +163 -0
- package/docs/computer-operation-v1.schema.json +143 -0
- package/docs/manual-test-plan.md +322 -0
- package/docs/product-spec.md +911 -0
- package/docs/release-checklist.md +285 -0
- package/docs/service-mode.md +99 -0
- package/examples/minimal-mcp-client.mjs +114 -0
- package/package.json +87 -0
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
# ChatGPT Setup
|
|
2
|
+
|
|
3
|
+
Computer Linker can be tested from ChatGPT as a remote MCP server when the
|
|
4
|
+
ChatGPT workspace supports custom MCP apps / developer mode.
|
|
5
|
+
|
|
6
|
+
ChatGPT cannot reach a server that only listens on `localhost` from your
|
|
7
|
+
computer. For cloud-hosted ChatGPT clients, expose Computer Linker through an
|
|
8
|
+
HTTPS URL. Cloudflare custom hostnames should be saved as `publicBaseUrl`
|
|
9
|
+
before OAuth client setup; Tailscale Funnel URLs are detected and saved by
|
|
10
|
+
`start C:\Projects\my-app --tunnel tailscale`.
|
|
11
|
+
|
|
12
|
+
## 1. Install
|
|
13
|
+
|
|
14
|
+
Commands below use the installed CLI:
|
|
15
|
+
|
|
16
|
+
```powershell
|
|
17
|
+
npm install -g @easonwumac/computer-linker
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
From this checkout, run `npm install` once and replace `computer-linker` with
|
|
21
|
+
`npm run dev --`.
|
|
22
|
+
|
|
23
|
+
## 2. Choose A Workspace
|
|
24
|
+
|
|
25
|
+
Pass the folder to `start`. Computer Linker creates the config, owner token,
|
|
26
|
+
and workspace entry automatically before the server starts:
|
|
27
|
+
|
|
28
|
+
```powershell
|
|
29
|
+
computer-linker start C:\Projects\my-app
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
If you want to configure without starting the server yet, use `setup`:
|
|
33
|
+
|
|
34
|
+
```powershell
|
|
35
|
+
computer-linker setup C:\Projects\my-app --show-token
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Permission meaning:
|
|
39
|
+
|
|
40
|
+
- `read`: list, read, search, inspect project/git metadata
|
|
41
|
+
- `write`: write, edit, patch, move, delete, stage, commit
|
|
42
|
+
- `shell`: run package scripts, commands, and managed shell processes
|
|
43
|
+
- `codex`: invoke the local `codex` CLI in this workspace
|
|
44
|
+
|
|
45
|
+
`start <folder>` and `setup <folder>` default to normal development access:
|
|
46
|
+
file edits plus approved project commands. Use `--read-only` when ChatGPT
|
|
47
|
+
should inspect without editing or running project commands. Add `--write`,
|
|
48
|
+
`--shell`, or `--codex` separately only when you need finer control.
|
|
49
|
+
|
|
50
|
+
When `start` or `setup` enables `--shell` or `--codex`, Computer Linker adds a
|
|
51
|
+
default execution policy. The default policy allows common project commands
|
|
52
|
+
such as `npm *`, `pnpm *`, `yarn *`, `bun *`, `node *`, `npx *`, and `git *`;
|
|
53
|
+
`codex *` is added only for Codex-enabled scopes. Runtime and output are capped.
|
|
54
|
+
|
|
55
|
+
Use `computer-linker status` for a quick check and `computer-linker doctor`
|
|
56
|
+
before exposing any workspace with `shell` or `codex`; those operations start
|
|
57
|
+
in the workspace but are not OS-level filesystem sandboxes.
|
|
58
|
+
|
|
59
|
+
## 3. Choose A Tunnel
|
|
60
|
+
|
|
61
|
+
Cloudflare Quick Tunnel:
|
|
62
|
+
|
|
63
|
+
```powershell
|
|
64
|
+
computer-linker start C:\Projects\my-app --tunnel cloudflare
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Tailscale Funnel:
|
|
68
|
+
|
|
69
|
+
```powershell
|
|
70
|
+
computer-linker start C:\Projects\my-app --tunnel tailscale
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
You do not need to know `https://<machine>.<tailnet>.ts.net` before setup.
|
|
74
|
+
Computer Linker detects that URL from `tailscale funnel` output or Tailscale
|
|
75
|
+
status, prints the public MCP URL, and saves the detected origin as
|
|
76
|
+
`publicBaseUrl`.
|
|
77
|
+
The `*.ts.net` hostname is public only when Tailscale reports Funnel as enabled;
|
|
78
|
+
plain Tailscale DNS or Serve remains tailnet-only.
|
|
79
|
+
|
|
80
|
+
OpenAI Secure MCP Tunnel:
|
|
81
|
+
|
|
82
|
+
```powershell
|
|
83
|
+
$env:CONTROL_PLANE_API_KEY = "sk-..."
|
|
84
|
+
computer-linker start C:\Projects\my-app --tunnel openai --tunnel-id tunnel_...
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
This mode does not create a public MCP URL and does not need `publicBaseUrl`.
|
|
88
|
+
In ChatGPT connector settings, choose **Tunnel** and select or paste the
|
|
89
|
+
`tunnel_...` id. Do not paste the Computer Linker bearer token into ChatGPT
|
|
90
|
+
Tunnel mode; the local `tunnel-client` forwards the owner token to the private
|
|
91
|
+
local MCP server. Computer Linker downloads the official OpenAI
|
|
92
|
+
`tunnel-client` release into its config directory on first use, verifies the
|
|
93
|
+
asset with `SHA256SUMS.txt`, and then reuses that managed binary. It does not
|
|
94
|
+
search the Desktop for `tunnel-client.exe`; pass `--tunnel-client` or set
|
|
95
|
+
`COMPUTER_LINKER_OPENAI_TUNNEL_CLIENT` only when you intentionally want a
|
|
96
|
+
pinned executable.
|
|
97
|
+
|
|
98
|
+
If ChatGPT or the tunnel control plane returns `401 Access denied: this tunnel
|
|
99
|
+
requires an active organization context`, the local Computer Linker server is
|
|
100
|
+
usually not the failing component. Check that the API key belongs to the
|
|
101
|
+
Platform organization that owns or can use the tunnel, that the organization
|
|
102
|
+
has Tunnels Read + Use permission, and that the tunnel is associated with the
|
|
103
|
+
target ChatGPT workspace when testing from ChatGPT. If you are using an API
|
|
104
|
+
surface that supports explicit organization selection, send the matching
|
|
105
|
+
OpenAI organization context for the tunnel owner.
|
|
106
|
+
|
|
107
|
+
If you run the HTTP server and tunnel separately:
|
|
108
|
+
|
|
109
|
+
```powershell
|
|
110
|
+
computer-linker start C:\Projects\my-app --url https://your-public-origin.example.com
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
When a running tunnel reports a public URL, persist that HTTPS origin with:
|
|
114
|
+
|
|
115
|
+
```powershell
|
|
116
|
+
computer-linker config set-public-url https://your-public-origin.example.com
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
You can still use `COMPUTER_LINKER_PUBLIC_BASE_URL` as a temporary override,
|
|
120
|
+
but `config set-public-url` is easier for repeated ChatGPT testing.
|
|
121
|
+
|
|
122
|
+
For Cloudflare, Tailscale Funnel, or a custom HTTPS reverse proxy, the public
|
|
123
|
+
MCP endpoint is:
|
|
124
|
+
|
|
125
|
+
```text
|
|
126
|
+
https://your-public-origin.example.com/mcp
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## 4. Verify Readiness
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
computer-linker status
|
|
133
|
+
computer-linker status --details
|
|
134
|
+
computer-linker status --json
|
|
135
|
+
computer-linker doctor
|
|
136
|
+
computer-linker doctor --json
|
|
137
|
+
computer-linker doctor --fix
|
|
138
|
+
computer-linker client chatgpt url
|
|
139
|
+
computer-linker client chatgpt smoke
|
|
140
|
+
computer-linker client chatgpt verify --mode coding
|
|
141
|
+
computer-linker client chatgpt verify --mode coding --json
|
|
142
|
+
computer-linker client chatgpt profile --mode coding
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The capabilities endpoint should report:
|
|
146
|
+
|
|
147
|
+
- `name: computer-linker`
|
|
148
|
+
- `exposure.readyForTunnel: true`
|
|
149
|
+
- no critical security findings
|
|
150
|
+
- `connectionProfile.http.publicMcpUrl` equal to your HTTPS `/mcp` URL
|
|
151
|
+
|
|
152
|
+
The CLI `status` command prints the short daily readiness view: connection mode,
|
|
153
|
+
local MCP URL, workspace/tunnel summary, readiness, and the next few actions.
|
|
154
|
+
Use `status --details` when you need the full workspace list, warnings, running
|
|
155
|
+
tunnel rows, and all next actions. `doctor` prints the full diagnostic view, including
|
|
156
|
+
`publicMcpUrl`, JSON API URLs, security findings, startup readiness, local tool
|
|
157
|
+
paths, missing
|
|
158
|
+
required/recommended tools, and suggested next actions.
|
|
159
|
+
Use `doctor --json` when a script or another model needs to verify readiness
|
|
160
|
+
without parsing terminal text. The `toolReadiness` block gives ChatGPT a compact
|
|
161
|
+
way to explain whether `rg`, `git`, `codex`, Node package managers, or shell
|
|
162
|
+
tools are available and how to install the missing required/recommended ones on
|
|
163
|
+
the current platform. The `startup` block lists CLI-first foreground HTTP,
|
|
164
|
+
stdio, and OS service startup modes plus service profile and install dry-run
|
|
165
|
+
commands.
|
|
166
|
+
Use `tunnel status --json` when the setup flow only needs tunnel provider
|
|
167
|
+
contracts, available commands, and the currently configured or detected public
|
|
168
|
+
URL.
|
|
169
|
+
|
|
170
|
+
`client chatgpt verify` is the ChatGPT-specific readiness gate. It checks the HTTPS
|
|
171
|
+
public base URL, `/mcp` URL, owner-token auth, the minimal four-tool surface,
|
|
172
|
+
workspace availability, security findings, tunnel hints, and whether workspace
|
|
173
|
+
permissions match the intended mode:
|
|
174
|
+
|
|
175
|
+
- `safe`: read/search/history/git-read style access only
|
|
176
|
+
- `coding`: write access is acceptable; shell/Codex access is reported as a
|
|
177
|
+
warning that must be reviewed
|
|
178
|
+
- `full`: write/shell/Codex are allowed but still called out as warnings
|
|
179
|
+
|
|
180
|
+
Use `client chatgpt verify --json` for automated setup checks or when another agent
|
|
181
|
+
needs a structured report before attempting connection.
|
|
182
|
+
|
|
183
|
+
`client chatgpt url` is the shortest path when you only need the fields to paste into
|
|
184
|
+
ChatGPT. It prints the MCP server URL, the bearer Authorization header shape,
|
|
185
|
+
the effective public URL source (`configured` or `running-tunnel`), warnings,
|
|
186
|
+
and the next action if no public HTTPS URL is configured. Use
|
|
187
|
+
`client chatgpt url --show-token` only on a trusted setup screen.
|
|
188
|
+
|
|
189
|
+
`client chatgpt smoke` performs a live connection check against the configured
|
|
190
|
+
`publicBaseUrl` or a URL passed with `--url`. For public HTTPS URLs it validates
|
|
191
|
+
MCP `/mcp` initialize, tools/list, `get_computer_info`, and one read-only
|
|
192
|
+
`computer_operation` using the owner token, which matches the default MCP-only
|
|
193
|
+
public exposure. For local loopback testing with `--allow-http`, it also
|
|
194
|
+
validates `/healthz`, authenticated `/api/v1/capabilities`,
|
|
195
|
+
`get_computer_info`, and one read-only `computer_operation` `file.list`. Use
|
|
196
|
+
`client chatgpt smoke --json` for scripts. Use `--allow-http` only for local
|
|
197
|
+
loopback testing:
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
computer-linker client chatgpt smoke --url http://127.0.0.1:3939/mcp --allow-http
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Use `status`, `doctor`, `tunnel status`, `history`, and `client chatgpt smoke`
|
|
204
|
+
for local readiness checks. Use `client chatgpt profile`, `manifest`,
|
|
205
|
+
`connector`, or `files` to export the exact fields to paste into ChatGPT: app
|
|
206
|
+
name, server URL, connection type, auth type, bearer-token guidance, OAuth
|
|
207
|
+
metadata URLs, model instructions, and workflow recipes.
|
|
208
|
+
|
|
209
|
+
`client chatgpt profile` prints a stable JSON setup profile for ChatGPT or
|
|
210
|
+
another hosted MCP client. It includes the MCP server URL, auth options,
|
|
211
|
+
recommended tool flow, operation envelope example, `modelGuide`,
|
|
212
|
+
`workflowRecipes`, model instructions, and warnings when the current config is
|
|
213
|
+
not reachable from ChatGPT.
|
|
214
|
+
|
|
215
|
+
Raw JSON clients should use the generic setup action before selecting client-
|
|
216
|
+
specific exports:
|
|
217
|
+
|
|
218
|
+
```json
|
|
219
|
+
{
|
|
220
|
+
"action": "client_setup"
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
The ChatGPT profile export includes `connectProfile`, a redacted ready-to-paste
|
|
225
|
+
setup block with `appName`, `serverUrl`, auth guidance, smoke commands, export
|
|
226
|
+
commands, and the first prompt. It also includes `wizard.overallStatus`, `wizard.currentStepId`,
|
|
227
|
+
`wizard.effectiveMcpServerUrl`, `wizard.detectedPublicUrl`, and ordered setup
|
|
228
|
+
steps so a UI or hosted model can show the next required action without
|
|
229
|
+
reimplementing readiness checks. `wizard.detectedPublicUrl` is populated from
|
|
230
|
+
currently running Computer Linker tunnel processes, even before that URL is
|
|
231
|
+
saved as `publicBaseUrl`. A detected HTTPS tunnel URL can make bearer-token
|
|
232
|
+
ChatGPT setup ready immediately; OAuth discovery remains disabled until the
|
|
233
|
+
same origin is saved as `publicBaseUrl`.
|
|
234
|
+
|
|
235
|
+
Use the same mode in `client chatgpt verify` and `client chatgpt profile`:
|
|
236
|
+
|
|
237
|
+
- `safe`: generated instructions stay read-only, even if a workspace exposes
|
|
238
|
+
elevated operations
|
|
239
|
+
- `coding`: generated instructions allow file edits and coding workflows, while
|
|
240
|
+
treating shell/Codex as higher-risk operations
|
|
241
|
+
- `full`: generated instructions allow write/shell/process/package/git/Codex
|
|
242
|
+
workflows when `allowedOperations` permits them, with warnings for destructive
|
|
243
|
+
or external actions
|
|
244
|
+
|
|
245
|
+
Local JSON API check:
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
curl http://127.0.0.1:3939/api/v1/capabilities \
|
|
249
|
+
-H "Authorization: Bearer <ownerToken>"
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## 6. Add To ChatGPT
|
|
253
|
+
|
|
254
|
+
Generate the connector profile:
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
computer-linker client chatgpt url
|
|
258
|
+
computer-linker client chatgpt profile --mode coding
|
|
259
|
+
computer-linker client chatgpt profile --mode coding --url https://your-public-origin.example.com
|
|
260
|
+
computer-linker client chatgpt manifest --mode coding
|
|
261
|
+
computer-linker client chatgpt connector --mode coding
|
|
262
|
+
computer-linker client chatgpt files ./chatgpt-config --mode coding
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
The output directory contains `chatgpt-profile.json`,
|
|
266
|
+
`chatgpt-app-manifest.json`, `chatgpt-connector-config.json`,
|
|
267
|
+
`operation-registry.json`, and `chatgpt-index.json`. Give GPT-style clients the
|
|
268
|
+
operation registry when they need exact operation names, permissions, payload
|
|
269
|
+
fields, and safety boundaries instead of guessing function shapes.
|
|
270
|
+
|
|
271
|
+
Use `--url https://...` when `tunnel status` detected a running tunnel URL but
|
|
272
|
+
you do not want to write it to config yet. This changes the exported MCP URL
|
|
273
|
+
only; save the same origin as `publicBaseUrl` before relying on OAuth discovery
|
|
274
|
+
metadata. When a Computer Linker-managed tunnel is running, the CLI exports use
|
|
275
|
+
the detected tunnel origin for the exported MCP URL and include a warning if the
|
|
276
|
+
origin is not saved.
|
|
277
|
+
|
|
278
|
+
Use these fields in ChatGPT developer mode / custom MCP app setup:
|
|
279
|
+
|
|
280
|
+
- App name: `appManifest.appName`, or `appName` from `--format manifest`
|
|
281
|
+
- MCP server URL: `mcpServerUrl`
|
|
282
|
+
- Auth: OAuth when the client supports MCP OAuth discovery, or bearer token
|
|
283
|
+
from `auth.bearer.header` / `auth.bearerHeader` when the client allows custom
|
|
284
|
+
headers
|
|
285
|
+
- Model instructions: use `modelGuide` for the entrypoint and operation-choice
|
|
286
|
+
rules, and `workflowRecipes` for common coding flows
|
|
287
|
+
|
|
288
|
+
For bearer-token clients:
|
|
289
|
+
|
|
290
|
+
```text
|
|
291
|
+
Authorization: Bearer <ownerToken>
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
or:
|
|
295
|
+
|
|
296
|
+
```text
|
|
297
|
+
x-computer-linker-token: <ownerToken>
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
The default output redacts the owner token. For a trusted local setup screen,
|
|
301
|
+
print the full token explicitly:
|
|
302
|
+
|
|
303
|
+
```bash
|
|
304
|
+
computer-linker client chatgpt profile --mode coding --show-token
|
|
305
|
+
computer-linker client chatgpt connector --mode coding --show-token
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## First Prompt To Test
|
|
309
|
+
|
|
310
|
+
Ask ChatGPT:
|
|
311
|
+
|
|
312
|
+
```text
|
|
313
|
+
Call get_computer_info, choose the app scope if present, run computer_operation op=code.context, then call get_operation_history with view=last.
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
Expected flow:
|
|
317
|
+
|
|
318
|
+
1. `get_computer_info`
|
|
319
|
+
2. `computer_operation` with `scope: "app"` and `op: "code.context"`
|
|
320
|
+
3. `get_operation_history` with `view: "last"`
|
|
321
|
+
|
|
322
|
+
The default MCP surface intentionally exposes only `get_computer_info`,
|
|
323
|
+
`computer_operation`, and `get_operation_history`. Older clients can opt in to
|
|
324
|
+
the legacy workspace tools with
|
|
325
|
+
`COMPUTER_LINKER_MCP_TOOL_SURFACE=compatibility`; that mode exposes
|
|
326
|
+
`get_capabilities`, `list_workspaces`, `open_workspace`,
|
|
327
|
+
`workspace_operation`, `read`, `ls`, `grep`, `glob`, and `create_file`.
|
|
328
|
+
|
|
329
|
+
The generated profile also includes:
|
|
330
|
+
|
|
331
|
+
- `modelGuide.mcpEntrypoint`: the MCP tool name, currently
|
|
332
|
+
`computer_operation`
|
|
333
|
+
- `modelGuide.jsonApiEntrypoint`: the local/trusted-private JSON API fallback,
|
|
334
|
+
`POST /api/v1/control` with `action: "computer_operation"`; default public
|
|
335
|
+
tunnel exposure is MCP-only, so public tunnel URLs block this route unless
|
|
336
|
+
the operator deliberately exposes the JSON API through a private route
|
|
337
|
+
- `operation_registry`: optional JSON API discovery action for a smaller,
|
|
338
|
+
filterable generic `computer_operation` contract when a client does not want
|
|
339
|
+
to parse all capabilities. Use `workspace_operation_registry` or
|
|
340
|
+
`operation_registry` with `contract: "workspace"` only for compatibility
|
|
341
|
+
clients that still call `workspace_operation`
|
|
342
|
+
- `modelGuide.operationSelection`: short intent-to-op guidance for GPT clients
|
|
343
|
+
- `workflowRecipes`: ready-made flows such as `connect_and_orient`,
|
|
344
|
+
`search_and_read`, `implement_and_verify`, and `codex_assisted_change`
|
|
345
|
+
|
|
346
|
+
For a coding task, ChatGPT can then use `computer_operation` with ops such as
|
|
347
|
+
`code.context`, `code.search_symbols`, `file.search`, `file.read`,
|
|
348
|
+
`file.patch`, `git.diff`, `package.run`, `command.run`, and, only when enabled
|
|
349
|
+
for that workspace, `codex.run` or `codex.start`. When a run fails or the
|
|
350
|
+
conversation loses context, ask it to call
|
|
351
|
+
`get_operation_history` with `view: "last"` first, then `view: "timeline"`,
|
|
352
|
+
`view: "connections"` for tunnel/session/request correlation,
|
|
353
|
+
`view: "failed_replay"`, `view: "sessions"` for compact session grouping, or
|
|
354
|
+
`view: "debug_bundle"` before retrying. In `failed_replay`, ChatGPT can submit
|
|
355
|
+
`replayable: true` request templates directly; when `requiresInput` is present,
|
|
356
|
+
it must ask for or reconstruct the missing command or Codex prompt before
|
|
357
|
+
retrying. After using `codex.run` or `codex.start`, ChatGPT can call
|
|
358
|
+
`codex.read` with the returned workflow id to inspect the stored run summary
|
|
359
|
+
later.
|
|
360
|
+
|
|
361
|
+
If the connector is not reachable yet, use the same history insight locally:
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
computer-linker history --view last
|
|
365
|
+
computer-linker history --view debug_bundle --workspace app --json --output ./computer-linker-debug-bundle.json
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
Tell GPT-style clients to prefer this generic operation envelope:
|
|
369
|
+
|
|
370
|
+
```json
|
|
371
|
+
{
|
|
372
|
+
"scope": "app",
|
|
373
|
+
"op": "file.search",
|
|
374
|
+
"target": ".",
|
|
375
|
+
"input": { "query": "TODO", "glob": "*.ts" },
|
|
376
|
+
"options": { "maxResults": 20 }
|
|
377
|
+
}
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
## Troubleshooting
|
|
381
|
+
|
|
382
|
+
- If ChatGPT cannot connect, confirm the `/mcp` URL is HTTPS and reachable from
|
|
383
|
+
outside your machine.
|
|
384
|
+
- If ChatGPT shows the connector but never calls tools, try a different
|
|
385
|
+
ChatGPT model/lane and check `computer-linker history --view last` or tunnel
|
|
386
|
+
metrics before changing tunnel settings. Some ChatGPT accounts or model lanes
|
|
387
|
+
can show the app while not routing actions to MCP tools.
|
|
388
|
+
- If OAuth metadata is wrong, restart HTTP mode after changing `publicBaseUrl`
|
|
389
|
+
or owner-token state.
|
|
390
|
+
- If operations are missing, call `get_computer_info`; each scope includes
|
|
391
|
+
`allowedOperations` and the generic `operationRegistry`.
|
|
392
|
+
- If a write, shell, or Codex action is blocked, inspect
|
|
393
|
+
`get_computer_info.scopes[].allowedOperations` and
|
|
394
|
+
`get_computer_info.operationRegistry` before retrying.
|
|
395
|
+
- If ChatGPT refuses broad writes, shell commands, or remote Git operations,
|
|
396
|
+
treat it as a host safety decision. Prefer `file.create`, `file.patch`, and
|
|
397
|
+
local terminal follow-up for publishing or remote service changes.
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# MCP Client Recipes
|
|
2
|
+
|
|
3
|
+
Use `computer-linker client setup` as the source of truth for the current
|
|
4
|
+
connection details. Use `--show-token` only on a trusted local screen.
|
|
5
|
+
|
|
6
|
+
## Local MCP Clients
|
|
7
|
+
|
|
8
|
+
Start Computer Linker:
|
|
9
|
+
|
|
10
|
+
```powershell
|
|
11
|
+
computer-linker start C:\Projects\my-app
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Configure the client:
|
|
15
|
+
|
|
16
|
+
- URL: `http://127.0.0.1:3939/mcp`
|
|
17
|
+
- Auth: `Authorization: Bearer <ownerToken>`
|
|
18
|
+
- Agent instructions: [agent-instructions.md](agent-instructions.md)
|
|
19
|
+
|
|
20
|
+
Verify:
|
|
21
|
+
|
|
22
|
+
```powershell
|
|
23
|
+
computer-linker diagnose client --local
|
|
24
|
+
computer-linker client smoke --allow-http --url http://127.0.0.1:3939/mcp
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## OpenAI Secure MCP Tunnel
|
|
28
|
+
|
|
29
|
+
Create the tunnel in OpenAI Platform, then start Computer Linker:
|
|
30
|
+
|
|
31
|
+
```powershell
|
|
32
|
+
$env:CONTROL_PLANE_API_KEY = "sk-..."
|
|
33
|
+
computer-linker start C:\Projects\my-app --tunnel openai --tunnel-id tunnel_...
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
In the client, choose Tunnel mode and select or paste the `tunnel_...` id. Do
|
|
37
|
+
not paste the Computer Linker bearer token into OpenAI Tunnel mode; the local
|
|
38
|
+
tunnel client forwards it to the local MCP server.
|
|
39
|
+
|
|
40
|
+
Verify:
|
|
41
|
+
|
|
42
|
+
```powershell
|
|
43
|
+
computer-linker diagnose client
|
|
44
|
+
computer-linker history --view connections
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Tailscale Funnel
|
|
48
|
+
|
|
49
|
+
```powershell
|
|
50
|
+
computer-linker start C:\Projects\my-app --tunnel tailscale
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Computer Linker detects the Funnel HTTPS origin and saves it as
|
|
54
|
+
`publicBaseUrl`. Configure the client with the printed HTTPS URL plus `/mcp`
|
|
55
|
+
and the bearer header from:
|
|
56
|
+
|
|
57
|
+
```powershell
|
|
58
|
+
computer-linker client setup --show-token
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Cloudflare
|
|
62
|
+
|
|
63
|
+
Quick tunnel:
|
|
64
|
+
|
|
65
|
+
```powershell
|
|
66
|
+
computer-linker start C:\Projects\my-app --tunnel cloudflare
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Owned hostname:
|
|
70
|
+
|
|
71
|
+
```powershell
|
|
72
|
+
computer-linker start C:\Projects\my-app --url https://mcp.your-domain.com --tunnel cloudflare
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Configure the client with `https://mcp.your-domain.com/mcp` and the bearer
|
|
76
|
+
header from `computer-linker client setup --show-token`.
|
|
77
|
+
|
|
78
|
+
## Minimal SDK Client
|
|
79
|
+
|
|
80
|
+
With Computer Linker already running:
|
|
81
|
+
|
|
82
|
+
```powershell
|
|
83
|
+
$env:COMPUTER_LINKER_MCP_URL = "http://127.0.0.1:3939/mcp"
|
|
84
|
+
$env:COMPUTER_LINKER_TOKEN = "<ownerToken>"
|
|
85
|
+
node examples/minimal-mcp-client.mjs
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The example initializes MCP, lists tools, calls `get_computer_info`, and runs a
|
|
89
|
+
read-only `computer_operation`.
|
|
90
|
+
|
|
91
|
+
## Agent Prompt
|
|
92
|
+
|
|
93
|
+
Use [agent-instructions.md](agent-instructions.md) when the client accepts a
|
|
94
|
+
system or instruction prompt. The short version:
|
|
95
|
+
|
|
96
|
+
```text
|
|
97
|
+
First call get_computer_info. Use computer_operation with {scope, op, target, input, options}. Stay inside configured scopes. Prefer read-only context/search/diff before write or command operations.
|
|
98
|
+
```
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# Client SDK Contract
|
|
2
|
+
|
|
3
|
+
Computer Linker exposes a small TypeScript client for MCP hosts, local
|
|
4
|
+
automation, and compatibility connectors. Prefer the generic
|
|
5
|
+
computer contract for new integrations:
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { ComputerLinkerClient } from "@easonwumac/computer-linker";
|
|
9
|
+
|
|
10
|
+
const client = new ComputerLinkerClient({
|
|
11
|
+
baseUrl: "http://127.0.0.1:3939/api/v1",
|
|
12
|
+
ownerToken: process.env.COMPUTER_LINKER_TOKEN,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
await client.getComputerInfo();
|
|
16
|
+
await client.clientSetup();
|
|
17
|
+
await client.smoke();
|
|
18
|
+
const result = await client.computerOperation<{ ok: boolean; data?: unknown }>({
|
|
19
|
+
scope: "app",
|
|
20
|
+
op: "file.search",
|
|
21
|
+
target: "src",
|
|
22
|
+
input: { query: "TODO" },
|
|
23
|
+
options: { maxResults: 20 },
|
|
24
|
+
});
|
|
25
|
+
if (result.ok) console.log(result.data);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The SDK talks to the JSON API under `/api/v1`. Treat that API as a local or
|
|
29
|
+
trusted-private automation surface. Public tunnels created by `computer-linker
|
|
30
|
+
start --tunnel ...` and `computer-linker expose ...` default to MCP-only, so
|
|
31
|
+
public hosts expose `/mcp` but return 404 for `/api` and `/healthz`.
|
|
32
|
+
Use the SDK against `connectionProfile.http.localApiUrl`, or against a
|
|
33
|
+
deliberately private reverse proxy where you have chosen to expose the JSON API.
|
|
34
|
+
|
|
35
|
+
The outer shape stays stable:
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
{
|
|
39
|
+
scope: "app",
|
|
40
|
+
op: "code.context" | "file.read" | "file.search" | "git.diff" | "package.run" | "command.run" | "codex.run" | "screen.list",
|
|
41
|
+
target: "src/index.ts",
|
|
42
|
+
input: {},
|
|
43
|
+
options: {}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
For raw JSON clients using the single control endpoint, use the same envelope at
|
|
48
|
+
the top level with `action: "computer_operation"`:
|
|
49
|
+
|
|
50
|
+
```json
|
|
51
|
+
{
|
|
52
|
+
"action": "computer_operation",
|
|
53
|
+
"scope": "app",
|
|
54
|
+
"op": "file.read",
|
|
55
|
+
"target": "README.md",
|
|
56
|
+
"input": {},
|
|
57
|
+
"options": { "maxBytes": 65536 }
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Use `input` for operation data and `options` for limits, filters, and runtime
|
|
62
|
+
controls. The response is always a standard operation result envelope with
|
|
63
|
+
`ok`, `operationId`, `scope`, `op`, `startedAt`, `durationMs`, `data` on
|
|
64
|
+
success, and `error` on failure. Computer Linker still enforces the configured
|
|
65
|
+
workspace boundary on the server side.
|
|
66
|
+
Use `getComputerInfo()` to discover `computerOperationRegistry`; new clients
|
|
67
|
+
should prefer its dotted op names such as `code.context`, `file.read`,
|
|
68
|
+
`file.search`, `git.diff`, `package.run`, `command.run`, `process.start`,
|
|
69
|
+
`codex.run`, `screen.capture`, and `history.last`.
|
|
70
|
+
The registry is current-machine aware for screen capture: it only advertises
|
|
71
|
+
display, window, or process capture operations that the local provider reports
|
|
72
|
+
as supported.
|
|
73
|
+
The stable request/result bundle is also published as JSON Schema at
|
|
74
|
+
`docs/computer-operation-v1.schema.json` for clients that validate contracts
|
|
75
|
+
outside TypeScript.
|
|
76
|
+
|
|
77
|
+
Common helpers are wrappers around the same envelope:
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
await client.getComputerInfo();
|
|
81
|
+
await client.clientSetup();
|
|
82
|
+
await client.smoke();
|
|
83
|
+
await client.computerOperation({ scope: "app", op: "file.read", target: "README.md" });
|
|
84
|
+
await client.getOperationHistory({ scope: "app", view: "last", limit: 20 });
|
|
85
|
+
await client.listWorkspaces();
|
|
86
|
+
await client.connectReadiness({ registry: { category: "search" } });
|
|
87
|
+
await client.chatGptSetup("coding");
|
|
88
|
+
await client.read("app", "README.md", { maxBytes: 65536 });
|
|
89
|
+
await client.search("app", "runWorkspaceOperation", { glob: "src/**/*.ts" });
|
|
90
|
+
await client.write("app", "notes/todo.md", "- ship\n");
|
|
91
|
+
await client.command("app", "npm test", { timeoutSeconds: 120 });
|
|
92
|
+
await client.screenList("app");
|
|
93
|
+
await client.screenCapture("app", "primary", { returnMode: "fileRef" });
|
|
94
|
+
await client.git("app", "git_diff", { paths: ["src/client.ts"] });
|
|
95
|
+
await client.codex("app", "Fix the failing tests");
|
|
96
|
+
await client.operationRegistry({ category: "search", query: "ripgrep" });
|
|
97
|
+
await client.workspaceOperationRegistry({ category: "search", query: "ripgrep" });
|
|
98
|
+
await client.historyLast({ workspaceId: "app", limit: 20 });
|
|
99
|
+
await client.workspaceHistoryInsight("app", { view: "timeline", maxResults: 20 });
|
|
100
|
+
await client.historySessions({ workspaceId: "app", limit: 20 });
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
`workspaceOperation()` is kept for older integrations that already send the MCP
|
|
104
|
+
style nested envelope. `operation()` is kept for older JSON clients using
|
|
105
|
+
workspace operation names. New JSON clients should use `computerOperation()` or
|
|
106
|
+
`action: "computer_operation"`.
|
|
107
|
+
|
|
108
|
+
For generic MCP/client integrations, the recommended flow is:
|
|
109
|
+
|
|
110
|
+
1. `getComputerInfo()`
|
|
111
|
+
2. `clientSetup()` when URL/auth setup details are needed
|
|
112
|
+
3. `smoke()` when validating that the local or trusted-private HTTP API and MCP
|
|
113
|
+
endpoint are reachable from the SDK process
|
|
114
|
+
4. `computerOperation({ scope, op, target, input, options })`
|
|
115
|
+
5. `getOperationHistory({ scope, view })` when auditing actions
|
|
116
|
+
6. compatibility only: `getCapabilities()`, `workspaceOperationRegistry()`,
|
|
117
|
+
`operation()`, or `workspaceOperation()`
|
|
118
|
+
|
|
119
|
+
This keeps clients from learning many endpoints while still covering file
|
|
120
|
+
operations, search, git, commands, Codex workflows, and audit history.
|
|
121
|
+
`connectReadiness()` is a client-side aggregate over generic MCP client setup,
|
|
122
|
+
workspace list, and operation registry contracts. It
|
|
123
|
+
returns `ready`, `status`, `blockingReasons`, `warnings`, `nextActions`,
|
|
124
|
+
`recommendedWorkspace`, and the source payloads so GPT clients can decide
|
|
125
|
+
whether to connect, show setup steps, or continue with coding operations.
|
|
126
|
+
`smoke()` is the SDK equivalent of `computer-linker client smoke` for local or
|
|
127
|
+
trusted-private integrations. It checks `/healthz`, `/api/v1/capabilities`,
|
|
128
|
+
authenticated `get_computer_info`, one read-only `computer_operation`
|
|
129
|
+
`file.list` in a readable scope, and an MCP SDK flow on `/mcp`: initialize,
|
|
130
|
+
tools/list, `get_computer_info`, and one read-only `computer_operation`.
|
|
131
|
+
It then returns a `computer-linker-client-smoke` report with `ready`, `checks`,
|
|
132
|
+
`blockingReasons`, `warnings`, and `nextActions`. Public tunnel smoke remains
|
|
133
|
+
MCP-only by default because public hosts expose `/mcp` and intentionally block
|
|
134
|
+
the JSON API, but the MCP tool flow still runs. The CLI and SDK use the same
|
|
135
|
+
generic smoke contract;
|
|
136
|
+
ChatGPT-specific smoke helpers remain compatibility commands layered beside it.
|
|
137
|
+
`clientSetup()` separates local and remote readiness: `localReady`/`ready` cover
|
|
138
|
+
stdio or loopback MCP usage, while `remoteReady` and `remoteBlockingReasons`
|
|
139
|
+
describe what remains before a cloud or tunnel client can connect. It also
|
|
140
|
+
returns `firstPrompt` and `agentInstructions`, which are the same generic
|
|
141
|
+
copy-pasteable MCP agent guidance printed by
|
|
142
|
+
`computer-linker client setup --details`.
|
|
143
|
+
`operationRegistry()` returns the stable `computer_operation` contract,
|
|
144
|
+
filtered dotted operation metadata, required capabilities, permissions,
|
|
145
|
+
boundaries, schemas, and examples. `workspaceOperationRegistry()` returns the
|
|
146
|
+
older workspace-operation registry for clients that still call
|
|
147
|
+
`workspace_operation` or the JSON `operation` compatibility action.
|
|
148
|
+
`chatGptSetup()` is a compatibility helper for ChatGPT-specific setup screens.
|
|
149
|
+
It returns the same redacted client-specific setup status used by CLI/API clients,
|
|
150
|
+
including `connectProfile.serverUrl`, redacted auth guidance, first prompt,
|
|
151
|
+
profile commands, smoke commands, `wizard.currentStepId`, and ordered setup
|
|
152
|
+
steps for product UIs.
|
|
153
|
+
|
|
154
|
+
ChatGPT connector profiles add two higher-level guidance fields on top of the
|
|
155
|
+
same envelope:
|
|
156
|
+
|
|
157
|
+
- `modelGuide`: explains that MCP clients call `computer_operation`, while
|
|
158
|
+
local or trusted-private raw JSON clients call `POST /api/v1/control` with
|
|
159
|
+
`action: "computer_operation"`; default public tunnel exposure is MCP-only
|
|
160
|
+
and blocks JSON API routes. Legacy JSON clients can still use
|
|
161
|
+
`action: "operation"` or `workspace_operation`
|
|
162
|
+
- `workflowRecipes`: gives ready-made flows for orientation, search/read,
|
|
163
|
+
implementation, verification, history, and Codex-assisted coding
|