moondesk 0.5.0 β†’ 0.5.1

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 (2) hide show
  1. package/README.md +135 -258
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,334 +1,211 @@
1
1
  # MoonDesk
2
2
 
3
- An open-source tool that lets you use ChatGPT Chat as a local coding agent. No reverse engineering, no API, no Codex, no Work mode. A ChatGPT Plus subscription is enough.
3
+ **Turn ChatGPT Chat into a local coding agent.**
4
4
 
5
- > [!NOTE]
6
- > MoonDesk is maintained by **Shattermoon** and is built around a lightweight local MCP architecture. Its companion, **ClippyMoon**, selects a bright hand-tuned pixel-art identity from a deterministic random seed.
5
+ MoonDesk is an open-source local MCP server that gives ChatGPT tools to read and edit files, run commands, manage long-running jobs, and control Chromium-based browsers β€” without using the OpenAI API.
7
6
 
8
- <p align="center">
9
- <img src="docs/images/moondesk_preview.gif" alt="MoonDesk in ChatGPT Web"><br>
10
- <em>MoonDesk in ChatGPT Web</em>
11
- </p>
12
-
13
- # Disclaimer
14
-
15
- This is an independent open-source project and is not affiliated with or endorsed by OpenAI. I built it as a personal tool and decided to open-source it. Some features are still buggy and may cause unexpected behavior. Use it at your own risk. I am not responsible for any loss caused by this tool. It is strongly recommended to run it inside a VM or container.
16
-
17
- # Why MoonDesk?
18
-
19
- Codex has a very generous weekly quota (reset usage frequently) compared to Antigravity (good at good morning) and Claude Code (RIP 5h quota πŸ’€), that's why I love OpenAI so much.
20
-
21
- <p align="center">
22
- <img src="docs/images/codex_2x_usage.png" alt="Codex reset usage frequentlyπŸ™" width="700"><br>
23
- <em>Codex reset usage frequentlyπŸ™</em>
24
- </p>
25
-
26
- However, the quota runs out very quickly if you work on a large project.
27
-
28
- <p align="center">
29
- <img src="docs/images/no_remaining_usage.png" alt="I used up my Codex quota on the first day after it reset" width="700"><br>
30
- <em>I used up my Codex quota on the first day after it reset</em>
31
- </p>
32
-
33
- Then you need to wait another 7 days. What are you going to do for the rest of the week?
34
-
35
- Here's the solution: most people with a Plus subscription do not use even 10% of their weekly thinking messages.
36
-
37
- **_So why not use your 3,000 weekly messages for coding?_**
38
-
39
- That's the idea behind MoonDesk! It gives ChatGPT Web tools like `write` and `run_command` to edit files on your computer.
40
-
41
- <p align="center">
42
- <img src="docs/images/thinking_usage_limits.png" alt="ChatGPT reasoning usage limits for GPT-5.5 and GPT-5.6" width="900"><br>
43
- <em>GPT-5.5: <a href="https://web.archive.org/web/20260519111010/https://help.openai.com/en/articles/11909943-gpt-55-in-chatgpt">3,000 messages/week</a>, GPT-5.6: <a href="https://help.openai.com/en/articles/20001354-gpt-56-in-chatgpt">unknown</a> but I have never hit the limit</em>
44
- </p>
7
+ ```bash
8
+ npm install -g moondesk
9
+ ```
45
10
 
46
- # How does this work?
11
+ > [!IMPORTANT]
12
+ > MoonDesk runs tools on your computer with your user account's permissions. Use a VM or container when you need strong isolation.
47
13
 
48
- 1. A ChatGPT Plus or above subscription is required.
49
- 2. MoonDesk runs as a local MCP server on your computer. It has the ability to run commands and edit files, just like Codex.
50
- 3. You can connect ChatGPT Web to MoonDesk using a Custom Connector, which is a feature available only to Plus and Pro users.
51
- 4. Done! Now ChatGPT Web can control your computer and code on it.
14
+ ## Why MoonDesk?
52
15
 
53
- In short,
16
+ MoonDesk lets you use the ChatGPT subscription you already have for local coding work. ChatGPT connects to MoonDesk through a Custom Connector, and MoonDesk exposes your project as a set of MCP tools.
54
17
 
55
18
  ```text
56
- ChatGPT Web + MoonDesk
57
- = a stripped-down version of Codex
58
- = OpenClaw without cron and other active utilities
19
+ ChatGPT Chat
20
+ β”‚
21
+ β”‚ Custom Connector
22
+ β–Ό
23
+ MoonDesk
24
+ β”œβ”€ Files
25
+ β”œβ”€ Shell jobs
26
+ β”œβ”€ Workspaces
27
+ └─ Browser / DevTools
59
28
  ```
60
29
 
61
- I tried this with GPT-5.2 before, and the results were poor. However, **GPT-5.4 Thinking is now really good at tool calling and computer use.** The first time I tried it with GPT-5.4, I was honestly surprised by how well it worked. GPT-5.5 and GPT-5.6 are even smoother, and GPT-5.6 is extremely good at using MoonDesk. It's also very fast.
62
-
63
- # Differences between ChatGPT Chat + MoonDesk, Codex, and the API (let's say Plus plan)
64
-
65
- | | ChatGPT Chat + MoonDesk | Codex | OpenAI API |
66
- | ----- | -------------------------------------------------- | ----------------------- | -------------------- |
67
- | Usage | 3,000 messages/week | Generous weekly quota | Pay as you go |
68
- | Pros | Stable, no extra fee, and nearly unlimited\* quota | Stable and no extra fee | Stable |
69
- | Cons | Not as smooth as native Codex | Runs out very quickly | Tokens are expensive |
70
-
71
- \*Let's say you sleep 6 hours a day and use MoonDesk every day. In that case, you can send 3,000 / (24 - 6) / 7 = 23.8 messages per hour. Since thinking and tool calls take time, it is very difficult to use up your weekly 3,000 message limit.
72
-
73
- # Who needs this?
74
-
75
- - People who used up their Codex quota on the first few day after it reset (meπŸ₯Ί)
76
- - People who are working on web development and crawlers. (MoonDesk enables ChatGPT Web to read elements and control your browser tab through chrome-devtools-mcp integration.)
77
-
78
- # Quickstart
79
-
80
- > [!CAUTION]
81
- > This tool is very powerful and can potentially wipe your whole disk or produce unexpected results.
82
- > Run it inside a VM or container (DevContainer is a good option).
83
- > Treat it like OpenClaw, keep it containerized and isolated.
84
-
85
- 1. Install MoonDesk globally with npm.
30
+ No reverse engineering. No API key. No separate agent service.
86
31
 
87
- ```bash
88
- npm install -g moondesk
89
- ```
32
+ ## Features
90
33
 
91
- MoonDesk does not rely on npm lifecycle/install scripts. On the first `moondesk` run, the small npm wrapper downloads the matching native binary from the GitHub Release, verifies it against that release's `SHA256SUMS`, and stores it in a versioned user cache under `~/.moondesk/npm-bin/`. This works with npm 12's default-deny install-script policy and also keeps the running native executable outside npm's `node_modules`, which makes Windows package upgrades less likely to hit locked-file errors.
34
+ - **Local file tools** β€” read, search, write, edit, and delete inside a workspace.
35
+ - **Shell commands** β€” run short commands or start background jobs with polling, preserved output, and cancellation.
36
+ - **Multiple workspaces** β€” serve several projects from one MoonDesk process, each with its own secret MCP URL.
37
+ - **Browser control** β€” connect ChatGPT to supported Chromium browsers through `chrome-devtools-mcp`.
38
+ - **Read-only mode** β€” expose only safe local read tools when mutation is unnecessary.
39
+ - **Cross-platform** β€” Windows, macOS, and Linux.
40
+ - **Native binary distribution** β€” install with npm; MoonDesk downloads and verifies the matching release binary on first run.
41
+ - **Self-update** β€” global npm installs can update and restart from the TUI after confirmation.
92
42
 
93
- Globally installed npm copies also check `moondesk@latest` in the background. When a newer stable release is available, the Status panel shows the current version and `[u] Update & Restart`. Pressing `u` always opens a confirmation modal first: make sure no ChatGPT/MCP session or command is running because MoonDesk will restart and the active connection will be interrupted. Press `Enter` to continue or `Esc` to abort. The wrapper then installs the exact version that was shown, verifies that npm really replaced the package with that version, restarts MoonDesk in the same working directory with the same arguments, and removes older verified native/update caches on subsequent startup. Multiple MoonDesk processes serialize global npm updates so they do not race each other. Local dependency or `npx` copies never offer in-app self-update.
43
+ ## Quickstart
94
44
 
95
- 2. Run MoonDesk from any terminal directory.
45
+ ### 1. Install
96
46
 
97
- ```bash
98
- moondesk
99
- ```
47
+ Node.js 18 or newer is required.
100
48
 
101
- When MoonDesk starts, choose `Control Computer`, `Control Browser`, or `Both`. If browser control is enabled, select a supported Chromium browser.
102
-
103
- On first launch, MoonDesk will ask you to enter your **ngrok authtoken** and **ngrok static domain** (e.g. `my-app.ngrok-free.dev`). You can get both from the [ngrok dashboard](https://dashboard.ngrok.com/get-started/setup). These are saved to `~/.moondesk/config.toml` and reused on subsequent launches.
49
+ ```bash
50
+ npm install -g moondesk
51
+ ```
104
52
 
105
- By default, MoonDesk listens on port `3200`. You can override it with `PORT`. On a first install (or when migrating the legacy single-workspace config), MoonDesk creates the first workspace from `WORKSPACE_ROOT` if it is set, otherwise from the directory where MoonDesk was launched. Once the multi-workspace registry exists, launching MoonDesk from a different directory never repoints an existing connector. If a MoonDesk host is already running on that port, running `moondesk` from another project directory securely attaches that directory as a new workspace to the existing host and exits; you can also add or change projects from the `[w] Workspaces` screen.
53
+ ### 2. Run
106
54
 
107
- On macOS Terminal.app, MoonDesk manages a dedicated `MoonDesk` Terminal profile automatically. If the current Terminal tab is not already using that profile, MoonDesk applies it, closes any temporary helper window, and asks you to run the same command again in that tab. It only starts immediately when the current tab is already using `MoonDesk`. Set `MOONDESK_SKIP_MACOS_TERMINAL_PROFILE=1` if you want to keep the current Terminal session untouched.
55
+ Start MoonDesk inside the project you want to use:
108
56
 
109
- 3. Wait for the TUI to connect ngrok. Press `[w] Workspaces` to see the registered projects. Select a workspace and reveal/copy its MCP URL. The first workspace is created automatically; existing users keep their old workspace slug during migration, so the already configured connector URL does not change.
57
+ ```bash
58
+ cd your-project
59
+ moondesk
60
+ ```
110
61
 
111
- 4. Open [ChatGPT connector settings](https://chatgpt.com/plugins#settings/Connectors?create-connector=true&redirectAfter=%2Fplugins).
62
+ Choose:
112
63
 
113
- 5. In the pop-up window, fill in the connector form:
114
- - Name: `MoonDesk Β· <workspace name>` (for example `MoonDesk Β· SiteAI`)
115
- - MCP Server URL: the URL for that specific workspace from `[w] Workspaces`
116
- - Authentication: `None`
64
+ - `Control Computer`
65
+ - `Control Browser`
66
+ - `Both`
117
67
 
118
- 6. Click `I understand and want to continue`.
68
+ On first launch, MoonDesk asks for your **ngrok authtoken** and **static domain**. These are stored in `~/.moondesk/config.toml`.
119
69
 
120
- 7. Click `Create`, then click `Connect`.
70
+ ### 3. Copy the workspace URL
121
71
 
122
- - Permission defaults to **Allow read actions**. For the smoothest experience, I recommend **Allow all actions** (equivalent to Codex's `--yolo`; use with caution).
72
+ Open `[w] Workspaces` in the TUI and copy the MCP URL for your project.
123
73
 
124
- 8. Add this to your ChatGPT `Custom instructions`:
74
+ Each workspace has its own secret URL, for example:
125
75
 
126
76
  ```text
127
- MoonDesk is a coding tool and a custom connector. Always use MoonDesk if the user wants to do anything related to file operations. Always call `moondesk_instruction` after `list_resources`, and follow the instructions it contains.
77
+ https://your-domain.ngrok-free.dev/<workspace-secret>/mcp
128
78
  ```
129
79
 
130
- 9. Start using the connector from ChatGPT Web. Some important tips:
131
-
132
- - I recommend let ChatGPT to decide which connector automatically. You can manually selecting the connector using `/` or `@`. This way, ChatGPT can only access the connector you selected, which may improve stability. However, the downside is, `web.search` and `web.open` will be disabled. Which means it can't search latest info. The `web` tool and a custom connector cannot be used at the same time.
133
-
134
- <table align="center">
135
- <tr>
136
- <td align="center">
137
- <img src="docs/images/connector_slash.png" alt="Select MoonDesk from the slash command menu" width="300"><br>
138
- <em>Select MoonDesk manually with <code>/</code></em>
139
- </td>
140
- <td align="center">
141
- <img src="docs/images/connector_at.png" alt="Select MoonDesk from the at-sign menu" width="300"><br>
142
- <em>Select MoonDesk manually with <code>@</code></em>
143
- </td>
144
- </tr>
145
- </table>
146
-
147
- - To improve performance and avoid high memory usage, I strongly recommend **opening a new session for every small feature**. If you need context, you can ask ChatGPT to create a handoff note and paste it into the new session. It will become extremely laggy after 50+ tool calls.
148
- <p align="center">
149
- <img src="docs/images/high_ram_usage.png" alt="3.9 GB Memory usageπŸ₯Ή" width="300"><br>
150
- <em>3.9 GB Memory usageπŸ₯Ή</em>
151
- </p>
152
-
153
-
154
- ## Working on multiple projects at the same time
155
-
156
- One MoonDesk process can host multiple project roots concurrently. It still uses one local server, one port, one ngrok tunnel/domain, and one shared browser/DevTools bridge. Each workspace gets its own stable internal ID and its own random secret MCP path.
80
+ ### 4. Create the ChatGPT connector
157
81
 
158
- Press `[w] Workspaces` to add, rename, inspect, reveal/copy, rotate, or remove projects. You can paste/type a path with `[a] Path`, open the native folder picker with `[b] Browse`, and click project rows plus the Reveal/Copy actions with the mouse. Create one ChatGPT connector per workspace and select the matching connector in each ChatGPT chat. The endpoint itself selects the project; MoonDesk does not add workspace metadata or a workspace argument to every tool call.
82
+ Open ChatGPT's Custom Connector settings and create a connector with:
159
83
 
160
84
  ```text
161
- one MoonDesk process / port 3200 / ngrok domain
162
- β”œβ”€β”€ MoonDesk Β· SiteAI -> /<secret-A>/mcp -> D:\SiteAI
163
- β”œβ”€β”€ MoonDesk Β· KUBA -> /<secret-B>/mcp -> D:\KUBA
164
- └── MoonDesk Β· MoonDesk -> /<secret-C>/mcp -> D:\CatDesk
85
+ Name: MoonDesk Β· <project name>
86
+ MCP Server URL: <URL copied from MoonDesk>
87
+ Authentication: None
165
88
  ```
166
89
 
167
- Important behavior:
168
-
169
- - A workspace keeps its own normal command/job/output and local-history allowances; one busy project does not consume another project's normal quota.
170
- - Browser control is intentionally shared. If two workspace connectors use Browser/Both mode, they control the same selected browser/DevTools bridge.
171
- - Rotating a workspace secret immediately invalidates only that workspace's old URL. Update that ChatGPT connector to the newly revealed URL; other workspace URLs are unchanged.
172
- - Removing a workspace first blocks new requests/jobs and lets already accepted foreground/file work drain safely. Only after the registry removal is durably saved does MoonDesk cancel that workspace's background jobs and purge retained state; an aborted/failed removal re-enables the workspace without killing its running jobs.
173
- - A missing workspace directory (for example an unplugged drive) stays registered and is shown as unavailable. It becomes usable again when the directory returns.
174
- - Duplicate and parent/child-overlapping workspace roots are rejected in V1 so two connectors cannot accidentally claim overlapping dedicated-file-tool authority.
175
- - Starting `moondesk` from another project directory while the normal host is already running does not create a second host. The new invocation securely attaches its current directory to the existing host as a workspace/session, then exits. The same project can also be added from `[w] Workspaces`.
176
-
177
- # Stack
178
-
179
- | Part | Stack |
180
- | --- | --- |
181
- | Core | Rust |
182
- | MCP server | Custom implementation (no SDK) |
183
- | MCP protocolVersion | `2025-11-25` |
184
- | Server | Axum + Tokio |
185
- | TUI | Ratatui |
186
- | Tunnel | ngrok |
187
- | Browser control | chrome-devtools-mcp |
188
- | Distribution | npm |
189
-
190
- # Tools
191
-
192
- MoonDesk has two local tool modes: `multi-tools` exposes 12 tools, and `read-only` exposes 3 tools.
193
-
194
- MoonDesk's local tools in `multi-tools` mode are:
195
-
196
- | Tool | Type | What it does |
197
- | --------------------- | ----- | -------------------------------------------------------------------------- |
198
- | `moondesk_instruction` | Guide | Returns MoonDesk usage instructions |
199
- | `read` | Read | Reads bounded line ranges or byte chunks from a workspace text file |
200
- | `search` | Read | Searches workspace text and returns compact bounded results |
201
- | `write` | Write | Creates or overwrites a file |
202
- | `edit` | Write | Replaces exact text inside a file |
203
- | `delete` | Write | Deletes a file or directory |
204
- | `run_command` | Shell | Runs a short shell command and waits for completion |
205
- | `start_command` | Job | Starts a long-running shell command and immediately returns a job ID |
206
- | `list_commands` | Read | Lists active (or retained completed) command jobs for this workspace |
207
- | `poll_command` | Job | Reads incremental output and status from a background command |
208
- | `read_command_output` | Read | Reads bounded chunks from complete preserved command stdout/stderr |
209
- | `cancel_command` | Job | Stops a background command and its child process tree |
210
-
211
- Long-running commands are deliberately decoupled from the lifetime of an MCP HTTP request. Builds, compilation, dependency installation, long test suites, development servers, and commands expected to produce large output should use `start_command`, then `poll_command`. Before starting work that may already be alive, `list_commands` lets an agent rediscover the workspace's active jobs after retries, long conversations, or context loss. `start_command` also reuses an exact running command in the same working directory by default instead of accidentally launching another copy; set `allow_duplicate: true` only when another concurrent copy is intentional. Active job listings include the owned root PID and, on supported platforms, the current process-tree size so multiple Node/compiler workers can be attributed to one logical command. The first poll uses `after: 0`; every later poll must pass the previous `nextCursor`, so each response contains only new output. Poll responses stay bounded. Complete stdout/stderr is also preserved locally for the MoonDesk session, so if a poll reports `outputTruncated`, `read_command_output` can recover either full stream in bounded byte chunks using the same job ID. `run_command` remains the simpler path for short commands; if its inline 1 MiB-per-stream capture is exceeded, it returns an `outputId` that `read_command_output` can use instead of permanently discarding the overflow.
212
-
213
- On wide terminals, the lower TUI is split into a compact Logs pane and a larger Shell Commands pane. Shell Commands is focused by default. `Tab`/`Shift+Tab` switches pane focus; arrow keys, Page Up/Down, and the mouse wheel select/scroll entries in the focused or pointed pane; Home/End jumps to the first/latest entry. Clicking a rendered row selects it. Long log messages and shell commands stay compact with an explicit ellipsis; press `Enter` or `Space` to expand the selected row and wrap its full locally stored text, then `Esc` to collapse it. Shell command entries always keep one blank line between executions for readability. Each pane keeps independent scroll/follow state, so inspecting command history no longer moves the Logs pane.
214
-
215
- On sufficiently wide terminals, the bottom of the MoonDesk TUI is split into `Logs` and `Shell Commands`. The command panel is local-only: it shows `run_command`/`start_command` immediately when the request arrives, then updates that command with bounded progress/result previews from later responses and polls. This does not add command data or result previews to ChatGPT's MCP responses.
216
-
217
- `read` defaults to 200 lines and exposes `nextStartLine` for normal pagination. If one line is too large for a single response, MoonDesk returns a bounded byte chunk and `nextStartByte`; continue with `start_byte`/`max_bytes` so minified files, source maps, and other long-line text remain fully inspectable without one huge tool result.
218
-
219
- If browser mode is enabled, MoonDesk can also expose extra browser/devtools tools. Those are provided by the browser bridge, so the exact list depends on your environment.
220
-
221
- `search` uses `rg` when it is available, falls back to `grep`, then falls back to MoonDesk's built-in scanner. Installing ripgrep is optional, but gives the best search performance and behavior.
90
+ For full coding-agent behavior, allow write actions only when you trust the current workspace and task.
222
91
 
223
- # Context window
92
+ ### 5. Add the recommended instruction
224
93
 
225
- According to [the blog](<https://help.openai.com/en/articles/11909943-gpt-53-and-gpt-54-in-chatgpt#:~:text=Thinking%20(GPT%E2%80%915.4%20Thinking)>) and [the code](https://github.com/openai/codex/blob/main/codex-rs/models-manager/src/model_info.rs#L85), the context window in ChatGPT web is different from Codex.
94
+ Add this to your ChatGPT custom instructions:
226
95
 
227
- | Tier | MoonDesk + ChatGPT Web (in + out = sum) | Codex CLI (sum) |
228
- | ---- | -------------------------------------- | ---------------------- |
229
- | Plus | 128K + 128K = 256K | 258K (1M experimental) |
230
- | Pro | 272K + 128K = 400K | 258K (1M experimental) |
231
-
232
- # FAQ
96
+ ```text
97
+ MoonDesk is a coding tool and a custom connector. Always use MoonDesk if the user wants to do anything related to file operations. Always call `moondesk_instruction` after `list_resources`, and follow the instructions it contains.
98
+ ```
233
99
 
234
- ### I've already connected. Why do I need to connect again and again?
100
+ That's it. Select the MoonDesk connector in a ChatGPT conversation and start working.
235
101
 
236
- There doesn't seem to be any obvious pattern for when the connector triggers `Connect`. I'm sure it's not triggered by the tool call count, but I don't know the exact reason.
102
+ ## Multiple projects
237
103
 
238
- <table align="center">
239
- <tr>
240
- <td align="center">
241
- <img src="docs/images/connect1.png" alt="Connector asks to connect again" width="700"><br>
242
- <em>Connector asks to connect again</em>
243
- </td>
244
- <td align="center">
245
- <img src="docs/images/connect2.png" alt="Connector asks to connect again (After you click Continue)" width="700"><br>
246
- <em>Connector asks to connect again (After you click Continue)</em>
247
- </td>
248
- </tr>
249
- </table>
104
+ One MoonDesk host can serve several project roots at once:
250
105
 
251
- I know it’s annoying. I’m trying to find a solution now.
106
+ ```text
107
+ one MoonDesk process
108
+ one local server :3200
109
+ one ngrok domain
252
110
 
253
- ### Can MoonDesk be used in other apps?
111
+ β”œβ”€β”€ Project A -> /<secret-A>/mcp -> D:\ProjectA
112
+ β”œβ”€β”€ Project B -> /<secret-B>/mcp -> D:\ProjectB
113
+ └── Project C -> /<secret-C>/mcp -> D:\ProjectC
114
+ ```
254
115
 
255
- Yes, in theory. MoonDesk may also work with other apps that support custom remote MCP servers, including Claude. (I don't think anyone will use MoonDesk with Claude though, since Claude Chat mode and Claude Code share the same usage limits.)
116
+ Each workspace keeps its own file boundary, command jobs, retained output, history, and secret connector URL.
256
117
 
257
- However, MoonDesk is built specifically for ChatGPT Chat and its Custom Connector (They renamed it to _Apps_, and now they renamed it again and call it _Plugins_, but to prevent confusion with _Application_, I still prefer call it _Connector_) flow. ChatGPT Chat is the environment MoonDesk is designed and tested for, so other apps may not work as smoothly.
118
+ Use `[w] Workspaces` to add, rename, inspect, copy, rotate, or remove projects. Launching `moondesk` from another project while a host is already running can attach that directory to the existing host instead of starting another server.
258
119
 
259
- ### How does the input/output token be calculated?
120
+ Browser control is shared by the host, so workspaces using browser mode control the same selected browser/DevTools bridge.
260
121
 
261
- MoonDesk does not get official token usage numbers from ChatGPT Web. It estimates them locally with `o200k_base`, the same tokenizer family used by GPT-5.5-style models, so the numbers are useful, but still only estimates.
122
+ ## Tools
262
123
 
263
- | Field | Symbol | What it means | Price |
264
- | -------------- | ------ | ---------------------------- | ----------------------------- |
265
- | `inputTokens` | `↓` | Tool input β‰ˆ LLM output | β‰ˆ `$30.00 / 1M` output tokens |
266
- | `outputTokens` | `↑` | Tool output β‰ˆ LLM input | β‰ˆ `$5.00 / 1M` input tokens |
267
- | `totalTokens` | `Ξ£` | `inputTokens + outputTokens` | `input price + output price` |
124
+ In `multi-tools` mode MoonDesk exposes 12 local tools:
268
125
 
269
- MoonDesk does not count:
126
+ | Tool | Purpose |
127
+ | --- | --- |
128
+ | `moondesk_instruction` | MoonDesk usage guidance |
129
+ | `read` | Read workspace files |
130
+ | `search` | Search workspace text |
131
+ | `write` | Create or overwrite files |
132
+ | `edit` | Replace exact text |
133
+ | `delete` | Delete files or directories |
134
+ | `run_command` | Run a short shell command |
135
+ | `start_command` | Start a background command |
136
+ | `list_commands` | List current and retained jobs |
137
+ | `poll_command` | Read incremental job output |
138
+ | `read_command_output` | Read preserved command output |
139
+ | `cancel_command` | Stop a job and its process tree |
270
140
 
271
- - the full ChatGPT conversation
272
- - hidden prompts or reasoning tokens
273
- - other internal tokens on OpenAI's side
141
+ Use `run_command` for short work. Use `start_command` + `poll_command` for builds, tests, package installs, dev servers, and other long-running commands.
274
142
 
275
- These estimates stay local to MoonDesk for its own counters and are not attached to MCP tool responses sent back to ChatGPT.
143
+ `read-only` mode exposes only the local guide/read tools.
276
144
 
277
- ### What is a workspace?
145
+ Browser mode can add DevTools tools depending on the selected browser and environment.
278
146
 
279
- A workspace is one registered project root served by MoonDesk. One running MoonDesk host can keep multiple workspaces active at the same time, and each workspace has its own secret MCP URL for its ChatGPT connector.
147
+ ## Workspace security
280
148
 
281
- On first install/legacy migration, the initial workspace comes from `WORKSPACE_ROOT` when explicitly set, otherwise from the launch directory. After the workspace registry has been created, changing the launch directory or `WORKSPACE_ROOT` does not silently repoint existing workspace URLs. Use `[w] Workspaces` to add or manage projects.
149
+ Dedicated file tools are confined to the selected workspace. MoonDesk rejects path traversal and symlink/junction escapes outside that root.
282
150
 
283
- A workspace connector URL is intentionally stable across MoonDesk restarts. MoonDesk persists both the ngrok static domain and each workspace's random secret path in `~/.moondesk/config.toml`, then reuses them on every later session. You should normally create the ChatGPT connector for a workspace once and keep using it. The URL changes only when you explicitly rotate that workspace's secret, change the configured ngrok domain, remove and re-add the workspace, or lose/delete the MoonDesk config file. Renaming a workspace, restarting MoonDesk/ngrok, launching MoonDesk from another directory, or upgrading MoonDesk does not rotate the URL. Legacy single-workspace installs keep their existing secret during migration.
151
+ Shell commands are different. `run_command` and `start_command` launch your normal developer shell with the workspace as its working directory. They inherit your normal environment, credentials, PATH, and OS permissions.
284
152
 
285
- Dedicated file tools use the selected endpoint's workspace as their base path and reject traversal, absolute paths outside that root, and symlink/junction escapes. `run_command` and `start_command` are intentionally different: they start the user's normal developer shell with the workspace as its working directory. The shell inherits the normal PATH, home directory, environment, developer configuration, credentials, and OS permissions so tools such as Git, package managers, SDKs, compilers, Docker, and development servers behave normally. CWD is **not an OS sandbox**: an absolute-path shell command can read or modify other paths allowed to the MoonDesk user. Use `read-only` mode when shell/write access should not be exposed, and use a VM/container when you need OS-level isolation.
153
+ **The working directory is not an OS sandbox.** A shell command can access anything your user account can access.
286
154
 
287
- ### Where to put my AGENTS.md?
155
+ Use:
288
156
 
289
- You can put it in 3 places.
157
+ - `read-only` mode when write/shell access is unnecessary;
158
+ - a VM or container when you need OS-level isolation;
159
+ - secret rotation from `[w] Workspaces` if a workspace MCP URL is ever exposed.
290
160
 
291
- 1. Workspace root
292
- 2. `~/.moondesk/AGENTS.md`
293
- 3. `~/.codex/AGENTS.md`
161
+ > [!CAUTION]
162
+ > Never share a workspace MCP URL. Treat it like a credential.
294
163
 
295
- MoonDesk checks these locations for `AGENTS.md` in this order. This happens every time `moondesk_instruction` is called. You can also manually choose which `AGENTS.md` to use.
164
+ ## Configuration
296
165
 
297
- <p align="center">
298
- <img src="docs/images/set_agents_md.png" alt="Set AGENTS.md manually" width="500"><br>
299
- <em>Set AGENTS.md manually</em>
300
- </p>
166
+ | Setting | Default / location |
167
+ | --- | --- |
168
+ | Config | `~/.moondesk/config.toml` |
169
+ | Port | `3200` |
170
+ | Port override | `PORT` |
171
+ | Initial workspace override | `WORKSPACE_ROOT` |
172
+ | Global instructions | `~/.moondesk/AGENTS.md` |
173
+ | Codex-compatible instructions | `~/.codex/AGENTS.md` |
301
174
 
302
- # Safety
175
+ MoonDesk also checks `AGENTS.md` in the current workspace. Workspace instructions take priority.
303
176
 
304
- > [!CAUTION]
305
- > Do **NOT** share any workspace's `MCP Server URL` with anyone. Each URL is a secret credential for that workspace and can expose powerful local tools.
177
+ On macOS Terminal.app, MoonDesk can manage a dedicated terminal profile. Set `MOONDESK_SKIP_MACOS_TERMINAL_PROFILE=1` to disable that behavior.
306
178
 
307
- A workspace URL is made of these parts:
179
+ ## Stack
308
180
 
309
- | Part | Example | What it means |
310
- | ------------ | ----------------------------- | -------------------------------------------------- |
311
- | Public URL | `https://xxxx.ngrok-free.dev` | The one ngrok static domain shared by the host |
312
- | Random path | `/Ab3kL9xQ2pTm7VhC` | A different random secret path for each workspace |
313
- | MCP endpoint | `/mcp` | The actual MCP endpoint |
181
+ | Part | Technology |
182
+ | --- | --- |
183
+ | Core | Rust |
184
+ | Async runtime / server | Tokio + Axum |
185
+ | TUI | Ratatui |
186
+ | Tunnel | ngrok |
187
+ | MCP server | Custom implementation |
188
+ | MCP protocol | `2025-11-25` |
189
+ | Browser bridge | `chrome-devtools-mcp` |
190
+ | Distribution | npm + native binaries |
314
191
 
315
- So one workspace URL looks like this:
192
+ ## Contributing
316
193
 
317
- ```text
318
- https://xxxx.ngrok-free.dev/Ab3kL9xQ2pTm7VhC/mcp
319
- ```
194
+ Contributions are welcome. See [`CONTRIBUTING.md`](CONTRIBUTING.md) for development setup, required checks, PR rules, and security-sensitive invariants.
320
195
 
321
- The domain and workspace registry are persisted in `~/.moondesk/config.toml`, so workspace URLs remain stable across launches. Upgrading an old single-workspace installation preserves its existing slug. If a workspace URL is exposed, rotate **that workspace's** secret from `[w] Workspaces`; its previous URL stops working immediately and the corresponding ChatGPT connector must be updated. Other workspaces are unaffected.
196
+ Release maintainers should also read [`docs/RELEASING.md`](docs/RELEASING.md).
322
197
 
323
- # About ClippyMoon
198
+ ## ClippyMoon
324
199
 
325
200
  <p align="center">
326
- <img src="docs/images/clippymoon.gif" alt="ClippyMoon!" width="500"><br>
201
+ <img src="docs/images/clippymoon.gif" alt="ClippyMoon" width="420"><br>
327
202
  <em>ClippyMoon!</em>
328
203
  </p>
329
204
 
330
- ClippyMoon is MoonDesk's hand-tuned pixel-art lunar companion. It is rendered entirely in Rust from a random 64-bit seed when MoonDesk starts; no image-generation model or bundled sprite sheet is used.
205
+ ## Disclaimer
206
+
207
+ MoonDesk is an independent open-source project and is not affiliated with or endorsed by OpenAI. It can execute powerful local actions. Review permissions carefully and use it at your own risk.
331
208
 
332
- A seed now selects from a curated library of known-good bright identities instead of independently randomizing every visual trait. Normal mascots use only quarter, gibbous, and full shapes, so a seed can no longer produce an almost-black new/crescent moon. The color families are pale ivory, silver, warm yellow, harvest orange, and coral red, with deliberately light same-hue shadow tones. Crater and star arrangements are hand-authored layouts rather than random placements, and per-pixel noise is avoided so every seed stays clean at terminal scale. Animation changes only temporary frame state such as blinking, subtle one-pixel bobbing, and star twinkling, so the same seed always recreates the same character.
209
+ ## License
333
210
 
334
- Normal MoonDesk startup keeps ClippyMoon entirely in memory: nothing is archived or persisted and each launch creates a fresh random moon. The current moon's 16-digit hexadecimal seed is written once to the TUI log so it can be reproduced without saving mascot state. Export is explicit and opt-in. Run `moondesk clippymoon export` to create `clippymoon.png` and `clippymoon.gif` in the current directory, or use `--seed <hex>` to reproduce a specific moon and `--out <directory>` to choose the destination. Both exports are 512Γ—512 pixel art; the GIF uses the same idle-animation sequence as the TUI and loops indefinitely. MoonDesk never writes these files unless the export command is invoked.
211
+ [MIT](LICENSE)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "moondesk",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "MoonDesk β€” use ChatGPT Chat as a local coding agent, by Shattermoon.",
5
5
  "author": "Shattermoon",
6
6
  "license": "MIT",