frely-cli 0.9.6 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +27 -5
  2. package/README.zh-CN.md +15 -4
  3. package/dist/agent-help.d.ts +102 -6
  4. package/dist/agent-help.js +16 -5
  5. package/dist/agent-help.js.map +1 -1
  6. package/dist/cloud.d.ts +11 -1
  7. package/dist/cloud.js +73 -1
  8. package/dist/cloud.js.map +1 -1
  9. package/dist/computer/command.d.ts +6 -0
  10. package/dist/computer/command.js +53 -0
  11. package/dist/computer/command.js.map +1 -0
  12. package/dist/computer/guard.d.ts +18 -0
  13. package/dist/computer/guard.js +82 -0
  14. package/dist/computer/guard.js.map +1 -0
  15. package/dist/computer/image.d.ts +22 -0
  16. package/dist/computer/image.js +183 -0
  17. package/dist/computer/image.js.map +1 -0
  18. package/dist/computer/ocu.d.ts +40 -0
  19. package/dist/computer/ocu.js +59 -0
  20. package/dist/computer/ocu.js.map +1 -0
  21. package/dist/computer/runtime.d.ts +22 -0
  22. package/dist/computer/runtime.js +85 -0
  23. package/dist/computer/runtime.js.map +1 -0
  24. package/dist/computer/server.d.ts +11 -0
  25. package/dist/computer/server.js +31 -0
  26. package/dist/computer/server.js.map +1 -0
  27. package/dist/computer/state.d.ts +11 -0
  28. package/dist/computer/state.js +17 -0
  29. package/dist/computer/state.js.map +1 -0
  30. package/dist/computer/toolset.d.ts +22 -0
  31. package/dist/computer/toolset.js +112 -0
  32. package/dist/computer/toolset.js.map +1 -0
  33. package/dist/device/protocol.d.ts +2 -0
  34. package/dist/device/protocol.js +7 -1
  35. package/dist/device/protocol.js.map +1 -1
  36. package/dist/device/relay-client.d.ts +3 -0
  37. package/dist/device/relay-client.js +7 -1
  38. package/dist/device/relay-client.js.map +1 -1
  39. package/dist/index.js +69 -8
  40. package/dist/index.js.map +1 -1
  41. package/dist/local-mcp-command.d.ts +10 -0
  42. package/dist/local-mcp-command.js +105 -0
  43. package/dist/local-mcp-command.js.map +1 -0
  44. package/dist/mcp-authorization.js +27 -2
  45. package/dist/mcp-authorization.js.map +1 -1
  46. package/dist/mcp-command.js +17 -1
  47. package/dist/mcp-command.js.map +1 -1
  48. package/dist/provider/control.d.ts +8 -2
  49. package/dist/provider/control.js.map +1 -1
  50. package/dist/runtime/local-mcp.d.ts +114 -0
  51. package/dist/runtime/local-mcp.js +448 -0
  52. package/dist/runtime/local-mcp.js.map +1 -0
  53. package/dist/runtime/mcp.d.ts +20 -0
  54. package/dist/runtime/mcp.js +29 -0
  55. package/dist/runtime/mcp.js.map +1 -1
  56. package/dist/runtime/relay-mcp.d.ts +3 -1
  57. package/dist/runtime/relay-mcp.js +5 -1
  58. package/dist/runtime/relay-mcp.js.map +1 -1
  59. package/dist/runtime/relay-session.d.ts +2 -2
  60. package/dist/runtime/relay-session.js +1 -1
  61. package/dist/runtime/relay-session.js.map +1 -1
  62. package/dist/runtime/sandbox.js +3 -0
  63. package/dist/runtime/sandbox.js.map +1 -1
  64. package/dist/skill/cloud-item.d.ts +38 -0
  65. package/dist/skill/cloud-item.js +151 -0
  66. package/dist/skill/cloud-item.js.map +1 -0
  67. package/dist/upgrade/maintenance.js +1 -1
  68. package/dist/upgrade/maintenance.js.map +1 -1
  69. package/dist/upgrade/service-refresh.js +1 -1
  70. package/dist/upgrade/service-refresh.js.map +1 -1
  71. package/dist/upgrade/update.js +2 -2
  72. package/dist/upgrade/update.js.map +1 -1
  73. package/package.json +1 -1
package/README.md CHANGED
@@ -79,6 +79,10 @@ frely mcp url --workspace /path/to/project
79
79
 
80
80
  `frely mcp url` is idempotent: once enabled it only prints the same URL, so run it again whenever you need the address. Prompts go to stderr, so stdout remains a single URL or, with `--json`, a JSON object. No URL is printed if approval or service installation fails. To expose more directories, use `frely mcp workspace add <path>`; `frely mcp workspace list` lists them. A command group run without a subcommand (for example `frely mcp workspace` or `frely agent`) prints the subcommands under it.
81
81
 
82
+ ### Local MCP servers on this computer
83
+
84
+ Remote MCP clients can also reach MCP servers that only run on this computer, such as a browser-extension server listening on `127.0.0.1`. Servers listening only on loopback are found automatically (`frely mcp local list`); add others with `frely mcp local add <name> --url http://127.0.0.1:<port>/mcp` or `frely mcp local add <name> [--env KEY=VALUE] -- <command> [args...]` (stdio). Every server stays off for remote clients until you turn it on, one by one, on the Frely connections page. Enabled servers are then reachable through two device tools, `local_mcp_list` and `local_mcp_call`, and run outside the command sandbox with your user account. Only loopback addresses are ever contacted; headers and environment values stay on this computer.
85
+
82
86
  Add the exact printed URL to a remote MCP client with OAuth support, choose OAuth and complete authorization. Keep the computer online. Verify the first connection by asking the client to list the top-level names in your selected workspace, without writing files or running shell commands — a returned result that matches the folder confirms connectivity.
83
87
 
84
88
  For Claude Code on the calling computer:
@@ -124,6 +128,16 @@ printf '%s' 'Your complete task' | \
124
128
 
125
129
  `frely agent status <distribution-id>` shows the installed Skill and, for API-key installs, the Key's budget. `frely agent remove <distribution-id>` removes the Skill and its saved key.
126
130
 
131
+ ### Install marketplace Prompts and Skills
132
+
133
+ ```sh
134
+ frely item install <item-id> --host claude-code
135
+ ```
136
+
137
+ `frely item install` downloads a Prompt or Skill through Frely Cloud (the first call opens a browser for Cloud authorization). A paid part is installed only when your account holds a pass; otherwise the command prints how to buy one. Skills go to the host's Skill folder, Prompts to `--dir` (default: current directory), and scripts are saved without execute permission. Frely never overwrites a folder it did not install or a file you edited.
138
+
139
+ Cloud MCPs you buy are not installed on the device: enable them for a connection on the Frely web console (Agents page) and their tools appear inside FrelyMCP.
140
+
127
141
  ## Local model sharing
128
142
 
129
143
  Publish a loopback OpenAI-compatible runtime as a Frely personal Provider. Ollama is the default driver:
@@ -142,10 +156,14 @@ frely provider share openai-compatible \
142
156
  --name "Local GPU"
143
157
  ```
144
158
 
145
- Requirements: Frely login, one empty active personal Provider slot, loopback HTTP, OpenAI-compatible `/v1` (default Ollama endpoint `http://127.0.0.1:11434/v1`). Model names cannot contain whitespace or `/`.
159
+ Requirements: Frely login, one empty active personal Provider slot (or a Creator plan, see below), loopback HTTP, OpenAI-compatible `/v1` (default Ollama endpoint `http://127.0.0.1:11434/v1`). Model names cannot contain whitespace or `/`.
146
160
 
147
161
  The command creates a server-managed `openai-compatible` personal Provider, stores the local endpoint in owner-only CLI state, starts the Device Relay service, signs a Provider credential with the device Ed25519 key, configures CPA, and enables the declared models. Existing Frely Access Point and API-key flows consume the Provider.
148
162
 
163
+ ### Use a local model as the base of your own Agent (Creator)
164
+
165
+ With no empty personal Provider slot, or with `--creator`, `frely provider share` creates a Creator Provider instead, counted against your Creator plan (Creator 3, Creator Plus 100). Its enabled models appear in Frely when you create an Agent. You do not sell the Provider: buyers call your Agent, which runs on your model. Keep this device online while the Agent is used, and make sure the local runtime returns `usage` in its responses.
166
+
149
167
  Provider inspection:
150
168
 
151
169
  ```sh
@@ -159,10 +177,10 @@ If setup stops after the Provider was prepared, run `frely provider share` again
159
177
  ```sh
160
178
  frely doctor # signed-in account, installation path, distribution, latest stable, MCP/service state
161
179
  frely doctor -v # + config paths, runtime details, authorization expiry, last heartbeat, sanitized errors
162
- frely upgrade # updates the running installation in place
180
+ frely update # updates the running installation in place
163
181
  ```
164
182
 
165
- `frely upgrade` never changes to a different installer, edits PATH or downgrades a newer installation. Standalone downloads are checksum-checked and tested before the installed executable is replaced. npm/Bun installations keep their original global directory. A matching, running Device Relay service is paused for maintenance, restarted and checked after installation; credentials, device identity, MCP URL, workspace and authorization expiry are preserved. On Windows, `upgrade` prints a PowerShell command for the detected installation to run in a local terminal.
183
+ `frely update` never changes to a different installer, edits PATH or downgrades a newer installation. Standalone downloads are checksum-checked and tested before the installed executable is replaced. npm/Bun installations keep their original global directory. A matching, running Device Relay service is paused for maintenance, restarted and checked after installation; credentials, device identity, MCP URL, workspace and authorization expiry are preserved. On Windows, `update` prints a PowerShell command for the detected installation to run in a local terminal.
166
184
 
167
185
  `frely doctor` is the single diagnostic entry point and never restarts the service. `Connected` means the matching account/device process has received a WebSocket heartbeat within 75 seconds and the MCP authorization and workspace match the running relay. Neither mode completes client OAuth authorization or executes a tool call through the client. `frely doctor --mcp` is the recommended way to check the protected credential and server state.
168
186
 
@@ -202,16 +220,20 @@ The public MCP URL is the canonical resource returned by Relay, `https://mcp.fre
202
220
  frely login [--relay <https-url>] [--no-browser]
203
221
  frely logout
204
222
  frely doctor [-v] [--json]
205
- frely upgrade
223
+ frely update
206
224
  frely mcp url [--workspace <path>] [--days 1..365] [--json]
207
225
  frely mcp workspace list [--json]
208
226
  frely mcp workspace add|remove <path>
227
+ frely mcp local list [--json]
228
+ frely mcp local add <name> (--url <address> | -- <command> [args...])
229
+ frely mcp local remove <name>
209
230
  frely mcp stop|start|remove
210
231
  frely agent install <distribution-id|manifest-url> [--host chatgpt|codex|claude-code|pi|generic] [--scope global|project] [--api-key-stdin] [--json]
211
232
  frely agent run <distribution-id> (--input <text>|--input-stdin) [--json]
212
233
  frely agent status (<distribution-id>|--api-key-stdin [--relay <url>]) [--json]
213
234
  frely agent remove <distribution-id> [--json]
214
- frely provider share [ollama|openai-compatible] [--url <loopback-v1-url>] [--models <a,b>] [--slot <slot-id>] [--name <name>]
235
+ frely item install <item-id> [--host chatgpt|codex|claude-code|pi|generic] [--scope global|project] [--dir <path>] [--json]
236
+ frely provider share [ollama|openai-compatible] [--url <loopback-v1-url>] [--models <a,b>] [--slot <slot-id> | --creator] [--name <name>]
215
237
  frely provider list [--json]
216
238
  frely cloud list|describe|call
217
239
  ```
package/README.zh-CN.md CHANGED
@@ -79,6 +79,10 @@ frely mcp url --workspace /path/to/project
79
79
 
80
80
  `frely mcp url` 是幂等的:启用后再次运行只打印同一个 URL,需要地址时直接再运行即可。提示走 stderr,stdout 保持单一 URL(或 `--json` 时一个 JSON 对象);批准或安装失败则不打印 URL。要开放更多目录,用 `frely mcp workspace add <path>`;`frely mcp workspace list` 列出所有目录。只输入命令组而不带子命令(如 `frely mcp workspace`、`frely agent`)时,会显示该组下可用的子命令。
81
81
 
82
+ ### 这台电脑上的本机 MCP 服务
83
+
84
+ 远程 MCP 客户端也能访问只在这台电脑上运行的 MCP 服务,例如只监听 `127.0.0.1` 的浏览器插件 MCP。只监听本机回环地址的服务会被自动发现(`frely mcp local list`);其他服务用 `frely mcp local add <name> --url http://127.0.0.1:<port>/mcp`,或 `frely mcp local add <name> [--env KEY=VALUE] -- <命令> [参数...]`(stdio)手动添加。每个服务默认对远程客户端关闭,需要在 Frely 连接页面逐个开启。开启后通过两个设备工具 `local_mcp_list` 和 `local_mcp_call` 访问,运行在命令沙箱之外,使用你的用户账号。只会连接回环地址;请求头和环境变量的值只保存在本机。
85
+
82
86
  把打印的完整 URL 添加到支持 OAuth 的远程 MCP 客户端,选择 OAuth 并完成授权。保持电脑在线。验证首次连接:让客户端只列出所选工作区的顶层名称,不写文件、不跑 shell 命令——返回与目录一致的结果即连通。
83
87
 
84
88
  调用端的 Claude Code:
@@ -146,6 +150,10 @@ frely provider share openai-compatible \
146
150
 
147
151
  该命令创建服务端管理的 `openai-compatible` 个人 Provider,把本地端点存入仅属主可读的 CLI 状态,启动 Device Relay 服务,用设备 Ed25519 key 签署 Provider 凭证,配置 CPA 并启用声明的模型。现有 Frely Access Point 与 API-key 流程即可消费该 Provider。
148
152
 
153
+ ### 用本地模型作为自己 Agent 的底座(Creator)
154
+
155
+ 没有空闲的个人 Provider 名额,或加上 `--creator` 时,`frely provider share` 会创建 Creator Provider,计入 Creator 套餐名额(Creator 3 个,Creator Plus 100 个)。它启用的模型会出现在 Frely 创建 Agent 的模型选择里。Provider 本身不对外售卖:买家调用的是你的 Agent,由你的模型驱动。Agent 被使用期间本机需保持在线,并且本地运行时的响应需包含 `usage`。
156
+
149
157
  Provider 检查:
150
158
 
151
159
  ```sh
@@ -159,10 +167,10 @@ frely provider list
159
167
  ```sh
160
168
  frely doctor # 当前账号、安装路径、发行形态、最新稳定版、MCP/服务状态
161
169
  frely doctor -v # 另加配置路径、运行时细节、授权到期、最近心跳、脱敏错误
162
- frely upgrade # 原地升级当前正在运行的安装
170
+ frely update # 原地升级当前正在运行的安装
163
171
  ```
164
172
 
165
- `frely upgrade` 永不换安装器、不改 PATH、不降级更新版本。standalone 下载会先校验 SHA-256 并做启动测试再替换可执行文件;npm/Bun 安装保持原全局目录。匹配的、正在运行的 Device Relay 服务会被暂停维护、重启并在安装后检查;凭证、设备身份、MCP URL、工作区与授权到期均保留。Windows 上 `upgrade` 打印检测到安装方式对应的 PowerShell 命令,请在本地终端执行。
173
+ `frely update` 永不换安装器、不改 PATH、不降级更新版本。standalone 下载会先校验 SHA-256 并做启动测试再替换可执行文件;npm/Bun 安装保持原全局目录。匹配的、正在运行的 Device Relay 服务会被暂停维护、重启并在安装后检查;凭证、设备身份、MCP URL、工作区与授权到期均保留。Windows 上 `update` 打印检测到安装方式对应的 PowerShell 命令,请在本地终端执行。
166
174
 
167
175
  `frely doctor` 是唯一诊断入口,永不重启服务。“Connected” 表示匹配的账号/设备进程在 75 秒内收到 WebSocket 心跳,且 MCP 授权与工作区与运行中的 relay 匹配。两种模式都不代替客户端完成 OAuth 授权,也不代替执行工具调用。`frely doctor --mcp` 是检查受保护凭证和服务端授权状态的推荐方式。
168
176
 
@@ -202,16 +210,19 @@ MCP 密钥使用 AES-256-GCM 文件,主密钥存 macOS Keychain、Windows 凭
202
210
  frely login [--relay <https-url>] [--no-browser]
203
211
  frely logout
204
212
  frely doctor [-v] [--json]
205
- frely upgrade
213
+ frely update
206
214
  frely mcp url [--workspace <path>] [--days 1..365] [--json]
207
215
  frely mcp workspace list [--json]
208
216
  frely mcp workspace add|remove <path>
217
+ frely mcp local list [--json]
218
+ frely mcp local add <name> (--url <address> | -- <command> [args...])
219
+ frely mcp local remove <name>
209
220
  frely mcp stop|start|remove
210
221
  frely agent install <distribution-id|manifest-url> [--host chatgpt|codex|claude-code|pi|generic] [--scope global|project] [--api-key-stdin] [--json]
211
222
  frely agent run <distribution-id> (--input <text>|--input-stdin) [--json]
212
223
  frely agent status (<distribution-id>|--api-key-stdin [--relay <url>]) [--json]
213
224
  frely agent remove <distribution-id> [--json]
214
- frely provider share [ollama|openai-compatible] [--url <loopback-v1-url>] [--models <a,b>] [--slot <slot-id>] [--name <name>]
225
+ frely provider share [ollama|openai-compatible] [--url <loopback-v1-url>] [--models <a,b>] [--slot <slot-id> | --creator] [--name <name>]
215
226
  frely provider list [--json]
216
227
  frely cloud list|describe|call
217
228
  ```
@@ -17,11 +17,11 @@ export declare const COMMANDS: readonly [{
17
17
  readonly effect: "diagnostic";
18
18
  readonly purpose: "Show the signed-in account, installation, available upgrades, MCP and connection status; -v verifies the account online and runs detailed diagnostics.";
19
19
  }, {
20
- readonly id: "upgrade";
21
- readonly usage: "frely upgrade";
20
+ readonly id: "update";
21
+ readonly usage: "frely update";
22
22
  readonly auth: "none";
23
23
  readonly effect: "local-write";
24
- readonly purpose: "Upgrade the current installation to the latest stable release. Windows prints a manual command; doctor checks versions.";
24
+ readonly purpose: "Update the current installation to the latest stable release. Windows prints a manual command; doctor checks versions.";
25
25
  }, {
26
26
  readonly id: "help";
27
27
  readonly usage: "frely help --agent --json";
@@ -52,6 +52,24 @@ export declare const COMMANDS: readonly [{
52
52
  readonly auth: "mcp";
53
53
  readonly effect: "local-write";
54
54
  readonly purpose: "Remove an additional workspace directory (the primary cannot be removed).";
55
+ }, {
56
+ readonly id: "mcp.local.list";
57
+ readonly usage: "frely mcp local list [--json]";
58
+ readonly auth: "none";
59
+ readonly effect: "read";
60
+ readonly purpose: "List MCP servers on this device that remote clients could use: loopback HTTP servers found automatically plus ones added by hand. Every server is off for remote clients until the owner turns it on in the web console.";
61
+ }, {
62
+ readonly id: "mcp.local.add";
63
+ readonly usage: "frely mcp local add <name> --url <http://127.0.0.1:port/path> [--header K=V] | frely mcp local add <name> [--env K=V] -- <command> [args...]";
64
+ readonly auth: "none";
65
+ readonly effect: "local-write";
66
+ readonly purpose: "Add a local MCP server by loopback URL or by the command that starts it (stdio). It is connected once to check it works; it stays off for remote clients until the owner turns it on in the web console.";
67
+ }, {
68
+ readonly id: "mcp.local.remove";
69
+ readonly usage: "frely mcp local remove <name>";
70
+ readonly auth: "none";
71
+ readonly effect: "local-write";
72
+ readonly purpose: "Remove a manually added local MCP server.";
55
73
  }, {
56
74
  readonly id: "mcp.stop";
57
75
  readonly usage: "frely mcp stop";
@@ -82,6 +100,12 @@ export declare const COMMANDS: readonly [{
82
100
  readonly auth: "account-and-mcp";
83
101
  readonly effect: "local-execution";
84
102
  readonly purpose: "Foreground Device Relay client; the background service runs this. Not needed for normal use.";
103
+ }, {
104
+ readonly id: "item.install";
105
+ readonly usage: "frely item install <item-id> [--host chatgpt|codex|claude-code|pi|generic] [--scope global|project] [--dir <path>] [--json]";
106
+ readonly auth: "cloud-oauth";
107
+ readonly effect: "local-write";
108
+ readonly purpose: "Install a download-install Prompt or Skill from the marketplace through Frely Cloud. The paid part is installed only with a valid pass; otherwise the command prints how to buy one. Skills go to the host Skill folder, Prompts to --dir (default: current directory). Scripts are saved without execute permission.";
85
109
  }, {
86
110
  readonly id: "agent.install";
87
111
  readonly usage: "frely agent install <distribution-id|manifest-url> [--host chatgpt|codex|claude-code|pi|generic] [--scope global|project] [--api-key-stdin] [--json]";
@@ -196,6 +220,30 @@ export declare const COMMANDS: readonly [{
196
220
  readonly auth: "local";
197
221
  readonly effect: "local-write";
198
222
  readonly purpose: "Uninstall the Frely App. Tasks, credentials and worktrees stay with frely-cli.";
223
+ }, {
224
+ readonly id: "computer.enable";
225
+ readonly usage: "frely computer enable";
226
+ readonly auth: "local";
227
+ readonly effect: "local-write";
228
+ readonly purpose: "Register computer use (desktop control by a remote MCP client) as the local MCP \"computer\" on this device. Run it only on a device you are sitting at. It still has to be turned on for remote clients on the Frely connections page; registering alone never exposes it.";
229
+ }, {
230
+ readonly id: "computer.disable";
231
+ readonly usage: "frely computer disable";
232
+ readonly auth: "local";
233
+ readonly effect: "local-write";
234
+ readonly purpose: "Remove the local MCP \"computer\" so computer use stops working on this device at once, whatever the web page says.";
235
+ }, {
236
+ readonly id: "computer.status";
237
+ readonly usage: "frely computer status [--json]";
238
+ readonly auth: "local";
239
+ readonly effect: "read";
240
+ readonly purpose: "Show whether computer use is registered locally, the runtime version it needs and whether it is installed.";
241
+ }, {
242
+ readonly id: "computer.mcp";
243
+ readonly usage: "frely computer mcp";
244
+ readonly auth: "local";
245
+ readonly effect: "local-execution";
246
+ readonly purpose: "Stdio MCP server for computer use; local MCP forwarding starts it. Not needed for normal use.";
199
247
  }, {
200
248
  readonly id: "network";
201
249
  readonly usage: "frely network setup|status|find|use|logout [--json]";
@@ -228,11 +276,11 @@ export declare function agentHelp(): {
228
276
  readonly effect: "diagnostic";
229
277
  readonly purpose: "Show the signed-in account, installation, available upgrades, MCP and connection status; -v verifies the account online and runs detailed diagnostics.";
230
278
  }, {
231
- readonly id: "upgrade";
232
- readonly usage: "frely upgrade";
279
+ readonly id: "update";
280
+ readonly usage: "frely update";
233
281
  readonly auth: "none";
234
282
  readonly effect: "local-write";
235
- readonly purpose: "Upgrade the current installation to the latest stable release. Windows prints a manual command; doctor checks versions.";
283
+ readonly purpose: "Update the current installation to the latest stable release. Windows prints a manual command; doctor checks versions.";
236
284
  }, {
237
285
  readonly id: "help";
238
286
  readonly usage: "frely help --agent --json";
@@ -263,6 +311,24 @@ export declare function agentHelp(): {
263
311
  readonly auth: "mcp";
264
312
  readonly effect: "local-write";
265
313
  readonly purpose: "Remove an additional workspace directory (the primary cannot be removed).";
314
+ }, {
315
+ readonly id: "mcp.local.list";
316
+ readonly usage: "frely mcp local list [--json]";
317
+ readonly auth: "none";
318
+ readonly effect: "read";
319
+ readonly purpose: "List MCP servers on this device that remote clients could use: loopback HTTP servers found automatically plus ones added by hand. Every server is off for remote clients until the owner turns it on in the web console.";
320
+ }, {
321
+ readonly id: "mcp.local.add";
322
+ readonly usage: "frely mcp local add <name> --url <http://127.0.0.1:port/path> [--header K=V] | frely mcp local add <name> [--env K=V] -- <command> [args...]";
323
+ readonly auth: "none";
324
+ readonly effect: "local-write";
325
+ readonly purpose: "Add a local MCP server by loopback URL or by the command that starts it (stdio). It is connected once to check it works; it stays off for remote clients until the owner turns it on in the web console.";
326
+ }, {
327
+ readonly id: "mcp.local.remove";
328
+ readonly usage: "frely mcp local remove <name>";
329
+ readonly auth: "none";
330
+ readonly effect: "local-write";
331
+ readonly purpose: "Remove a manually added local MCP server.";
266
332
  }, {
267
333
  readonly id: "mcp.stop";
268
334
  readonly usage: "frely mcp stop";
@@ -293,6 +359,12 @@ export declare function agentHelp(): {
293
359
  readonly auth: "account-and-mcp";
294
360
  readonly effect: "local-execution";
295
361
  readonly purpose: "Foreground Device Relay client; the background service runs this. Not needed for normal use.";
362
+ }, {
363
+ readonly id: "item.install";
364
+ readonly usage: "frely item install <item-id> [--host chatgpt|codex|claude-code|pi|generic] [--scope global|project] [--dir <path>] [--json]";
365
+ readonly auth: "cloud-oauth";
366
+ readonly effect: "local-write";
367
+ readonly purpose: "Install a download-install Prompt or Skill from the marketplace through Frely Cloud. The paid part is installed only with a valid pass; otherwise the command prints how to buy one. Skills go to the host Skill folder, Prompts to --dir (default: current directory). Scripts are saved without execute permission.";
296
368
  }, {
297
369
  readonly id: "agent.install";
298
370
  readonly usage: "frely agent install <distribution-id|manifest-url> [--host chatgpt|codex|claude-code|pi|generic] [--scope global|project] [--api-key-stdin] [--json]";
@@ -407,6 +479,30 @@ export declare function agentHelp(): {
407
479
  readonly auth: "local";
408
480
  readonly effect: "local-write";
409
481
  readonly purpose: "Uninstall the Frely App. Tasks, credentials and worktrees stay with frely-cli.";
482
+ }, {
483
+ readonly id: "computer.enable";
484
+ readonly usage: "frely computer enable";
485
+ readonly auth: "local";
486
+ readonly effect: "local-write";
487
+ readonly purpose: "Register computer use (desktop control by a remote MCP client) as the local MCP \"computer\" on this device. Run it only on a device you are sitting at. It still has to be turned on for remote clients on the Frely connections page; registering alone never exposes it.";
488
+ }, {
489
+ readonly id: "computer.disable";
490
+ readonly usage: "frely computer disable";
491
+ readonly auth: "local";
492
+ readonly effect: "local-write";
493
+ readonly purpose: "Remove the local MCP \"computer\" so computer use stops working on this device at once, whatever the web page says.";
494
+ }, {
495
+ readonly id: "computer.status";
496
+ readonly usage: "frely computer status [--json]";
497
+ readonly auth: "local";
498
+ readonly effect: "read";
499
+ readonly purpose: "Show whether computer use is registered locally, the runtime version it needs and whether it is installed.";
500
+ }, {
501
+ readonly id: "computer.mcp";
502
+ readonly usage: "frely computer mcp";
503
+ readonly auth: "local";
504
+ readonly effect: "local-execution";
505
+ readonly purpose: "Stdio MCP server for computer use; local MCP forwarding starts it. Not needed for normal use.";
410
506
  }, {
411
507
  readonly id: "network";
412
508
  readonly usage: "frely network setup|status|find|use|logout [--json]";
@@ -3,17 +3,21 @@ export const COMMANDS = [
3
3
  { id: "login", usage: "frely login [--relay <url>] [--no-browser] | frely login --email <address> [--invite <link>] [--mcp] [--workspace <path>] [--days <n>] then frely login --code <6-digit code>", auth: "browser-or-email", effect: "authorization", purpose: "Authorize the CLI for the user's Frely account. With --email, Frely emails a code; the user pastes it into `frely login --code`. Add --mcp to also enable device MCP for the workspace (default 90 days) once the code is verified; do this when the user is registering for the first time, and tell them before asking for the code." },
4
4
  { id: "logout", usage: "frely logout", auth: "none", effect: "local-write", purpose: "Remove login, revoke Cloud authorization and stop the MCP background service." },
5
5
  { id: "doctor", usage: "frely doctor [-v] [--json]", auth: "optional-account", effect: "diagnostic", purpose: "Show the signed-in account, installation, available upgrades, MCP and connection status; -v verifies the account online and runs detailed diagnostics." },
6
- { id: "upgrade", usage: "frely upgrade", auth: "none", effect: "local-write", purpose: "Upgrade the current installation to the latest stable release. Windows prints a manual command; doctor checks versions." },
6
+ { id: "update", usage: "frely update", auth: "none", effect: "local-write", purpose: "Update the current installation to the latest stable release. Windows prints a manual command; doctor checks versions." },
7
7
  { id: "help", usage: "frely help --agent --json", auth: "none", effect: "read", purpose: "Read this installed CLI's current Agent instructions." },
8
8
  { id: "mcp.url", usage: "frely mcp url [--workspace <path>] [--days 1..365] [--json]", auth: "account-and-browser-if-needed", effect: "authorization-if-needed", purpose: "Enable, renew or read device MCP. Unconfigured: request browser approval for --workspace (default: current directory) and install the background service. Expired or --days given: renew with browser approval; the MCP URL stays the same. Otherwise print the MCP URL unchanged. Prompts go to stderr; stdout holds only the URL, or JSON with HTTP transport and OAuth details." },
9
9
  { id: "mcp.workspace.list", usage: "frely mcp workspace list [--json]", auth: "mcp", effect: "read", purpose: "List workspace directories for this device; the primary is marked." },
10
10
  { id: "mcp.workspace.add", usage: "frely mcp workspace add <path>", auth: "mcp", effect: "local-write", purpose: "Add an additional workspace directory for this device." },
11
11
  { id: "mcp.workspace.remove", usage: "frely mcp workspace remove <path>", auth: "mcp", effect: "local-write", purpose: "Remove an additional workspace directory (the primary cannot be removed)." },
12
+ { id: "mcp.local.list", usage: "frely mcp local list [--json]", auth: "none", effect: "read", purpose: "List MCP servers on this device that remote clients could use: loopback HTTP servers found automatically plus ones added by hand. Every server is off for remote clients until the owner turns it on in the web console." },
13
+ { id: "mcp.local.add", usage: "frely mcp local add <name> --url <http://127.0.0.1:port/path> [--header K=V] | frely mcp local add <name> [--env K=V] -- <command> [args...]", auth: "none", effect: "local-write", purpose: "Add a local MCP server by loopback URL or by the command that starts it (stdio). It is connected once to check it works; it stays off for remote clients until the owner turns it on in the web console." },
14
+ { id: "mcp.local.remove", usage: "frely mcp local remove <name>", auth: "none", effect: "local-write", purpose: "Remove a manually added local MCP server." },
12
15
  { id: "mcp.stop", usage: "frely mcp stop", auth: "none", effect: "local-service", purpose: "Pause the local MCP background service. Supported upgrades restore running services without this command." },
13
16
  { id: "mcp.start", usage: "frely mcp start", auth: "none", effect: "local-service", purpose: "Resume the local MCP background service." },
14
17
  { id: "mcp.remove", usage: "frely mcp remove", auth: "account", effect: "remote-write", purpose: "Revoke device MCP for every connected client and uninstall the background service (kept running provider-only when local Providers exist)." },
15
18
  { id: "mcp.stdio", usage: "frely mcp stdio [--workspace <path>]", auth: "mcp", effect: "local-execution", purpose: "Serve authorized local tools over stdio for a local MCP client." },
16
19
  { id: "mcp.serve", usage: "frely mcp serve [--workspace <path>]", auth: "account-and-mcp", effect: "local-execution", purpose: "Foreground Device Relay client; the background service runs this. Not needed for normal use." },
20
+ { id: "item.install", usage: "frely item install <item-id> [--host chatgpt|codex|claude-code|pi|generic] [--scope global|project] [--dir <path>] [--json]", auth: "cloud-oauth", effect: "local-write", purpose: "Install a download-install Prompt or Skill from the marketplace through Frely Cloud. The paid part is installed only with a valid pass; otherwise the command prints how to buy one. Skills go to the host Skill folder, Prompts to --dir (default: current directory). Scripts are saved without execute permission." },
17
21
  { id: "agent.install", usage: "frely agent install <distribution-id|manifest-url> [--host chatgpt|codex|claude-code|pi|generic] [--scope global|project] [--api-key-stdin] [--json]", auth: "optional-api-key", effect: "local-write", purpose: "Install the public Agent's trigger Skill; an API key goes only through stdin to secure storage." },
18
22
  { id: "agent.run", usage: "frely agent run <distribution-id> (--input <text>|--input-stdin) [--json]", auth: "installed-api-key-or-account", effect: "remote-call", purpose: "Send the complete relevant user request to the installed Agent through model-scoped MCP. Usage may be billed." },
19
23
  { id: "agent.status", usage: "frely agent status (<distribution-id>|--api-key-stdin [--relay <url>]) [--json]", auth: "none-or-api-key", effect: "read", purpose: "Inspect an installed Agent Skill and, for API-key installs, its Key budget. With --api-key-stdin, read that Key's budget without installing or logging in." },
@@ -33,6 +37,10 @@ export const COMMANDS = [
33
37
  { id: "app.status", usage: "frely app status [--json]", auth: "local", effect: "read", purpose: "Show whether the Frely App is installed, its version, install path, running state and how it is managed." },
34
38
  { id: "app.update", usage: "frely app update [--json]", auth: "local", effect: "local-write", purpose: "Update the Frely App through Homebrew or by re-downloading the latest release." },
35
39
  { id: "app.uninstall", usage: "frely app uninstall", auth: "local", effect: "local-write", purpose: "Uninstall the Frely App. Tasks, credentials and worktrees stay with frely-cli." },
40
+ { id: "computer.enable", usage: "frely computer enable", auth: "local", effect: "local-write", purpose: "Register computer use (desktop control by a remote MCP client) as the local MCP \"computer\" on this device. Run it only on a device you are sitting at. It still has to be turned on for remote clients on the Frely connections page; registering alone never exposes it." },
41
+ { id: "computer.disable", usage: "frely computer disable", auth: "local", effect: "local-write", purpose: "Remove the local MCP \"computer\" so computer use stops working on this device at once, whatever the web page says." },
42
+ { id: "computer.status", usage: "frely computer status [--json]", auth: "local", effect: "read", purpose: "Show whether computer use is registered locally, the runtime version it needs and whether it is installed." },
43
+ { id: "computer.mcp", usage: "frely computer mcp", auth: "local", effect: "local-execution", purpose: "Stdio MCP server for computer use; local MCP forwarding starts it. Not needed for normal use." },
36
44
  { id: "network", usage: "frely network setup|status|find|use|logout [--json]", auth: "network", effect: "subcommand-dependent", purpose: "Access Frely Network (preview) using its separate setup and credentials." },
37
45
  ];
38
46
  export function agentHelp() {
@@ -59,9 +67,10 @@ export function agentHelp() {
59
67
  };
60
68
  }
61
69
  const GROUPS = [
62
- { title: "Account", ids: ["login", "logout", "doctor", "upgrade"] },
63
- { title: "Device MCP", ids: ["mcp.url", "mcp.workspace", "mcp.lifecycle"] },
70
+ { title: "Account", ids: ["login", "logout", "doctor", "update"] },
71
+ { title: "Device MCP", ids: ["mcp.url", "mcp.workspace", "mcp.local", "mcp.lifecycle"] },
64
72
  { title: "Agents", ids: ["agent.install", "agent.run", "agent.status", "agent.remove"] },
73
+ { title: "Marketplace items", ids: ["item.install"] },
65
74
  { title: "Providers", ids: ["provider.share", "provider.list"] },
66
75
  { title: "Cloud", ids: ["cloud"] },
67
76
  ];
@@ -73,10 +82,12 @@ const SHORT_USAGE = {
73
82
  login: "frely login [--no-browser]",
74
83
  logout: "frely logout",
75
84
  doctor: "frely doctor [-v] [--json]",
76
- upgrade: "frely upgrade",
85
+ update: "frely update",
77
86
  "mcp.url": "frely mcp url [--workspace <path>] [--days 1..365] [--json]",
78
87
  "mcp.workspace": "frely mcp workspace list|add <path>|remove <path>",
88
+ "mcp.local": "frely mcp local list|add <name> (--url <address>|-- <command>)|remove <name>",
79
89
  "mcp.lifecycle": "frely mcp stop|start|remove",
90
+ "item.install": "frely item install <item-id> [--host <host>]",
80
91
  "agent.install": "frely agent install <distribution-id> [--host <host>] [--api-key-stdin]",
81
92
  "agent.run": "frely agent run <distribution-id> (--input <text>|--input-stdin)",
82
93
  "agent.status": "frely agent status <distribution-id>",
@@ -107,7 +118,7 @@ export function subcommandUsage(group) {
107
118
  }
108
119
  export function mcpUsage() {
109
120
  return "Device MCP — use this computer from a remote MCP client.\n\nUsage:\n"
110
- + ["mcp.url", "mcp.workspace", "mcp.lifecycle"].map((id) => " " + SHORT_USAGE[id] + "\n").join("")
121
+ + ["mcp.url", "mcp.workspace", "mcp.local", "mcp.lifecycle"].map((id) => " " + SHORT_USAGE[id] + "\n").join("")
111
122
  + "\nStatus and diagnostics: frely doctor [-v] [--json]\n\n"
112
123
  + "Run frely mcp url on the computer to control. It asks for browser approval the first time (current directory, or --workspace) and when authorization has expired, installs the background service, and prints the MCP URL. Add that URL to ChatGPT, Claude Code on another computer, or another HTTP MCP client, then authorize with OAuth.\n"
113
124
  + "Prompts go to stderr; stdout contains only the URL or JSON. --days 1..365 renews now; the URL stays the same.\n"
@@ -1 +1 @@
1
- {"version":3,"file":"agent-help.js","sourceRoot":"","sources":["../src/agent-help.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent-help.js","sourceRoot":"","sources":["../src/agent-help.ts"],"names":[],"mappings":"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"}
package/dist/cloud.d.ts CHANGED
@@ -1,7 +1,17 @@
1
- export declare const CLOUD_USAGE = "Frely Cloud \u2014 call your Frely application.\n frely cloud list [--group <name>]\n frely cloud describe <tool>\n frely cloud call <tool> [--json '<object>' | --input <file>]\n\nResults are JSON. The first command opens a browser for Cloud authorization;\nfrely logout also revokes it. Cloud authorization is separate from device MCP.\nCalls may create resources or incur usage. Failed writes are never replayed automatically.\n";
1
+ /** Names this installation on the web console ("Frely CLI Cloud (host)"); the "Frely CLI" prefix selects per-device permissions on the server. */
2
+ export declare function cloudClientName(host?: string): string;
3
+ /** The server's `permission_required` or `confirmation_required` tool failure as a one-line hint, or null for any other result. */
4
+ export declare function permissionHint(result: object): string | null;
5
+ export declare const CLOUD_USAGE = "Frely Cloud \u2014 call your Frely application.\n frely cloud list [--group <name>]\n frely cloud describe <tool>\n frely cloud call <tool> [--json '<object>' | --input <file>]\n\nResults are JSON. The first command opens a browser for Cloud authorization;\nfrely logout also revokes it. Cloud authorization is separate from device MCP.\nCalls may create resources or incur usage. Failed writes are never replayed automatically.\nA new device may only read non-sensitive data; for anything else the error links to the web\nconsole page where you grant it (passkey or authenticator code required).\n";
2
6
  export declare function logoutCloud(): Promise<void>;
3
7
  export declare function runCloud(args: readonly string[]): Promise<{
4
8
  value?: unknown;
5
9
  text?: string;
6
10
  failed?: boolean;
7
11
  }>;
12
+ /**
13
+ * Call one Cloud tool for another command (for example skill install). The
14
+ * result is the tool's JSON; a failed call throws CloudToolError with the
15
+ * server's error code. Writes are never retried.
16
+ */
17
+ export declare function callCloudTool(name: string, input: Record<string, unknown>): Promise<Record<string, unknown>>;
package/dist/cloud.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { randomUUID } from "node:crypto";
2
+ import { hostname } from "node:os";
2
3
  import { createServer } from "node:http";
3
4
  import { readFile, stat } from "node:fs/promises";
4
5
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
@@ -7,7 +8,41 @@ import { UnauthorizedError } from "@modelcontextprotocol/sdk/client/auth.js";
7
8
  import { credentialStore } from "./credential-store.js";
8
9
  import { inspectAuth, normalizeRelayUrl, openVerificationUrl } from "./auth.js";
9
10
  import { VERSION } from "./version.js";
11
+ import { CloudToolError } from "./skill/cloud-item.js";
10
12
  const SERVICE = "frely-cli-cloud-v1";
13
+ /** Names this installation on the web console ("Frely CLI Cloud (host)"); the "Frely CLI" prefix selects per-device permissions on the server. */
14
+ export function cloudClientName(host = hostname()) {
15
+ const safe = host.replace(/[^A-Za-z0-9._ -]/g, "").trim().slice(0, 40);
16
+ return safe ? `Frely CLI Cloud (${safe})` : "Frely CLI Cloud";
17
+ }
18
+ /** The server's `permission_required` or `confirmation_required` tool failure as a one-line hint, or null for any other result. */
19
+ export function permissionHint(result) {
20
+ const { isError, content } = result;
21
+ if (isError !== true || !Array.isArray(content))
22
+ return null;
23
+ for (const part of content) {
24
+ const text = part.type === "text" ? part.text : undefined;
25
+ if (typeof text !== "string")
26
+ continue;
27
+ try {
28
+ const error = JSON.parse(text).error;
29
+ if (typeof error?.url !== "string" || (error.code !== "permission_required" && error.code !== "confirmation_required"))
30
+ continue;
31
+ const need = error.need === "write" ? "write access" : error.need === "sensitive" ? "sensitive read access" : "read access";
32
+ const url = new URL(error.url);
33
+ if (url.protocol !== "https:" && url.hostname !== "127.0.0.1" && url.hostname !== "localhost")
34
+ continue;
35
+ if (error.code === "confirmation_required") {
36
+ if (typeof error.confirmationId !== "string" || !/^[A-Za-z0-9_-]{1,80}$/.test(error.confirmationId))
37
+ continue;
38
+ return `${typeof error.summary === "string" ? error.summary + "\n" : ""}Approve this in your browser (passkey or authenticator code required): ${url.toString()}\nThen run the same call again with "confirmationId":"${error.confirmationId}" added to the input.`;
39
+ }
40
+ return `This device needs ${need}${typeof error.group === "string" ? " to " + error.group : ""}. Grant it in your browser (passkey or authenticator code required): ${url.toString()}`;
41
+ }
42
+ catch { /* Not a permission failure. */ }
43
+ }
44
+ return null;
45
+ }
11
46
  const SCOPE = "openid profile offline_access cloud:read cloud:write cloud:execute cloud:publish";
12
47
  export const CLOUD_USAGE = `Frely Cloud — call your Frely application.
13
48
  frely cloud list [--group <name>]
@@ -17,6 +52,8 @@ export const CLOUD_USAGE = `Frely Cloud — call your Frely application.
17
52
  Results are JSON. The first command opens a browser for Cloud authorization;
18
53
  frely logout also revokes it. Cloud authorization is separate from device MCP.
19
54
  Calls may create resources or incur usage. Failed writes are never replayed automatically.
55
+ A new device may only read non-sensitive data; for anything else the error links to the web
56
+ console page where you grant it (passkey or authenticator code required).
20
57
  `;
21
58
  async function cloudIdentity() {
22
59
  const account = await inspectAuth();
@@ -103,7 +140,7 @@ async function connectCloud() {
103
140
  const save = () => credentialStore.setPassword(SERVICE, identity.key, JSON.stringify(stored));
104
141
  const provider = {
105
142
  redirectUrl: stored.redirectUrl,
106
- clientMetadata: { client_name: "Frely CLI Cloud", redirect_uris: [stored.redirectUrl],
143
+ clientMetadata: { client_name: cloudClientName(), redirect_uris: [stored.redirectUrl],
107
144
  grant_types: ["authorization_code", "refresh_token"], response_types: ["code"], token_endpoint_auth_method: "none", scope: SCOPE },
108
145
  state: () => state,
109
146
  clientInformation: () => stored.client,
@@ -247,10 +284,45 @@ export async function runCloud(args) {
247
284
  if (action === "describe")
248
285
  return { value: tool };
249
286
  const result = await session.client.callTool({ name: name, arguments: input }, undefined, { timeout: 180000 });
287
+ const hint = permissionHint(result);
288
+ if (hint)
289
+ process.stderr.write(hint + "\n");
250
290
  return { value: result, failed: result.isError === true };
251
291
  }
252
292
  finally {
253
293
  await session.close();
254
294
  }
255
295
  }
296
+ /**
297
+ * Call one Cloud tool for another command (for example skill install). The
298
+ * result is the tool's JSON; a failed call throws CloudToolError with the
299
+ * server's error code. Writes are never retried.
300
+ */
301
+ export async function callCloudTool(name, input) {
302
+ const session = await connectCloud();
303
+ try {
304
+ const result = await session.client.callTool({ name, arguments: input }, undefined, { timeout: 180000 });
305
+ const hint = permissionHint(result);
306
+ if (hint)
307
+ process.stderr.write(hint + "\n");
308
+ const text = Array.isArray(result.content) ? result.content.find(part => part.type === "text")?.text : undefined;
309
+ if (result.isError === true) {
310
+ let code = "operation_failed";
311
+ try {
312
+ const parsed = JSON.parse(String(text)).error?.code;
313
+ if (typeof parsed === "string")
314
+ code = parsed;
315
+ }
316
+ catch { /* Keep the generic code. */ }
317
+ throw new CloudToolError(code);
318
+ }
319
+ const value = result.structuredContent ?? (typeof text === "string" ? JSON.parse(text) : null);
320
+ if (!value || typeof value !== "object" || Array.isArray(value))
321
+ throw new CloudToolError("invalid_operation_output");
322
+ return value;
323
+ }
324
+ finally {
325
+ await session.close();
326
+ }
327
+ }
256
328
  //# sourceMappingURL=cloud.js.map