dream-os
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@dream-osadd a clock gadget to my desktop"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Dream OS
A transparent, nestable desktop element layer for Windows — that Claude can build on.
Rainmeter-style widgets rendered in web tech, sitting on your desktop under your real windows. The difference: Dream OS ships an MCP server, so Claude can read the desktop, add gadgets, update them live, and capture your ideas — through a proper tool interface instead of you hand-editing config files.
Styled after the Freelancer (2003) HUD, because that game's UI is nested translucent frames — which is exactly what this is.
┌─ Claude ──┐ stdio ┌─ MCP server ─┐ HTTP ┌─ Dream OS ─┐
│ tools │ ────────► │ 8 tools │ ────────► │ desktop │
└───────────┘ └──────────────┘ :8787 └────────────┘What it does
Transparent full-desktop overlay with dynamic click-through — clicks pass to whatever is underneath, and the layer only becomes solid while your cursor is over a gadget.
Sits under your windows. It's a desktop layer, not an always-on-top nag.
Nestable elements. Drop a gadget into a group and it becomes a DOM child, so dragging the parent moves everything inside it with zero extra code.
Drag, resize, persist. Layout survives restarts.
Claude-drivable. Everything above is reachable over MCP.
Related MCP server: MCP Desktop Tools
The toolbag
Every gadget is one self-registering file in renderer/elementals/:
defineElemental('clock', {
label: 'Clock',
size: { w: 210, h: 120 },
render(node, ctx) { /* return an HTMLElement */ },
});Shipped elementals:
type | what it is |
| zero-friction idea box; Enter files a timestamped line |
| free text that persists |
| time + date readout |
| pure container — drag it, children follow |
| static label / paragraph |
| rendered markdown (safe subset, everything escaped) |
| bulleted or checkable list |
| labelled progress bars with tone colouring |
| named lamps: |
| simple data table with sticky headers |
| scrolling line feed |
| clickable shortcuts (URL or file path) |
A gadget reads everything from node.props, which is exactly what Claude writes over the API — so anything you can build by hand, Claude can build too.
MCP tools
tool | purpose |
| list what's on the desktop |
| list the toolbag and each type's props |
| add an element (optionally nested) |
| move / resize / retitle / patch props |
| delete an element and its children |
| re-parent an element |
| append to the capture log |
| read the capture log back |
The MCP server has zero dependencies — plain Node, newline-delimited JSON-RPC.
Install
npm install
npm startQuick launch
Dream OS.bat brings up the overlay and both local voice services in one go, and Stop Dream OS.bat shuts them all down. Running it twice is safe — anything already listening is skipped, so it doubles as a "make sure everything is up" command.
.\launch.ps1 # start whatever isn't already running
.\launch.ps1 -Stop # shut everything down
.\launch.ps1 -NoVoice # overlay only, skip the speech servicesCold start is about 20 seconds, most of it Kokoro loading its 325 MB model.
Register the MCP server with Claude Code (.mcp.json in your project, or your user config):
{
"mcpServers": {
"dream-os": {
"command": "node",
"args": ["C:/path/to/dream-os/mcp/server.js"]
}
}
}Dream OS must be running — the MCP server bridges to its control API and will say so plainly if it can't reach it.
Shortcuts
There's a tray icon too — left-click toggles the layer, right-click for the full menu (show/hide, edit, float on top, capture box, data folder, quit).
key | action |
| hide / show the layer |
| toggle edit mode (headers, drag handles, toolbar) |
| jump to the capture box |
| float above everything (toggle) |
| quit — the escape hatch |
Talking to Claude from the desktop
The claude elemental is a message box wired to the Claude desktop app. Type, press Enter: the text goes on the clipboard, Claude is focused, pasted and sent. The reply comes back by tailing Claude's own session transcript at ~/.claude/projects/<project>/<session-id>.jsonl.
It costs no extra tokens — it's the same conversation, just a different surface. Records in that transcript are typed, so filtering thinking / tool_use / tool_result from the visible text is the entire "cleaner". No OCR, no screen scraping.
Tag routing
A line beginning #dream:<id> in Claude's prose updates that element — no tool call at all:
#dream:console
All systems nominal.A JSON object payload is merged into the element's props; anything else becomes props.text. Guards: the element must already exist, the tag must start a line (so inline mentions are inert), and the element flashes gold when touched so the magic is at least visible.
Icon
build/gen-icon.js generates the icon as a real PNG with zero image dependencies — hand-rolled CRC32 and zlib chunks — so it can be re-themed from the same colour values as the CSS rather than living as a binary blob.
node build/gen-icon.jsWhere it sits (Wallpaper Engine, Fences, Rainmeter)
Windows has no arbitrary "layers". There is one z-order for normal windows, plus a wallpaper layer (WorkerW) beneath it where Wallpaper Engine and the Fences background live. Fences popups — and every application — are ordinary top-level windows.
So "above the wallpaper, below everything else" is exactly one call:
SetWindowPos(hwnd, HWND_BOTTOM, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE)Electron doesn't expose it, so zorder.js reaches it through koffi (prebuilt, no node-gyp). Dream OS parks at the bottom on startup and re-sinks on blur, so interacting with a gadget raises it briefly and it drops back afterwards. Ctrl+Alt+T pins it above everything when you want the HUD in front.
If koffi is unavailable the module degrades to no-ops and the app still runs — it just won't stay underneath.
Theming
One block at the top of renderer/style.css drives everything:
--h: 258; /* base hue — 210 blue · 288 purple · 160 green · 20 amber */
--lum: 27%; /* master darkness. lower = darker */Panels, insets, borders, text and glow all derive from those via hsl().
Control API
Loopback only, port 8787.
GET /health GET /state[?flat=1] POST /state
GET /elementals POST /elements GET /elements/:id
PATCH /elements/:id DELETE /elements/:id POST /elements/:id/move
GET /captures POST /capturesseed-desktop.js is a worked example that builds a whole desktop through it.
Development
renderer/app.js includes a shim: with no Electron preload it stubs the API and, if Dream OS is running, mirrors the live desktop over HTTP. So you can serve renderer/ as a static site and iterate on styling without relaunching the overlay.
python -m http.server 8757 --directory rendererNotes from the build
A few things worth knowing, found the hard way:
Elements are DOM children, not separate OS windows. One window per widget is the obvious Rainmeter-style approach, but then nesting means manually syncing window positions on every drag. As DOM nodes, nesting is free.
.dp-bodyneedsmin-height: 0. Flex items default tomin-height: auto, which lets content push the inset box out past the panel border.Don't use
setPointerCapturefor dragging. It routes events to the element and silently kills the whole drag if it throws. Window-level capture-phase listeners are robust, and survive a fast drag outrunning the cursor.Atomic save can fail on EFS-encrypted directories. Where
%APPDATA%carries the EFS attribute, Windows treats the encryption boundary as a device boundary: Node'sfs.renameSyncfails withEXDEVwithin a single folder, and .NET'sFile.Replacethrows access-denied. The store attempts the atomic path and falls back to a direct write plus a.bak.
License
MIT © minidraco711
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/MiniDraco/dream-os'
If you have feedback or need assistance with the MCP directory API, please join our Discord server