Desktop Control logo

Desktop Control

Community
sagirimo
desktop-control

See and drive the user's desktop without vision - list and focus windows, read on-screen controls and text as JSON with coordinates (UI Automation on Windows, OCR elsewhere), then click, type, send hotkeys, open apps and paste tables into Excel/SPSS/GraphPad Prism/Zotero.

Overview

Publishersagirimo
RepositoryBioDSH
Skill namedesktop-control
Stars
65
Forks
2
Bundled files
3
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 3 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by sagirimo on GitHub. Read the source before you install it.

Installation

Install the Desktop Control AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/sagirimo/BioDSH/tree/main/biodsh-core/skills/desktop-control
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/sagirimo/BioDSH.git /tmp/BioDSH
mkdir -p .claude/skills
cp -r /tmp/BioDSH/biodsh-core/skills/desktop-control .claude/skills/desktop-control
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Desktop Control in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Desktop Control on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Desktop Control is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Desktop control (for text-only agents)

Use this skill when the user asks you to operate a program on their computer: "把这个表贴进 Excel 存成 xlsx", "打开 Zotero 把这篇 DOI 加进去", "在 Prism 里新建一个数据表", "帮我点一下那个按钮". You cannot see pixels, so you read the screen as text with coordinates and act on those coordinates. Every command prints one JSON object; on failure the exit code is 1 and the JSON has "ok": false, "error", "hint".

Run it with the BioDSH Python: python "<skill dir>/control.py" <subcommand> ... (Windows: bioenv\.venv\Scripts\python.exe). Screenshots go to ./desktop_control/ under the working directory unless --out is given.

Requires pyautogui, mss, pyperclip, pillow, pywinauto (Windows), plus rapidocr-onnxruntime for OCR and pandas for paste-table. The BioDSH app installs all of them through the env pack "电脑控制"; if a command reports a missing package, tell the user to install that pack (or run the uv pip install ... line from the hint) - do not try other tools.

The loop (always)

  1. windows - list open windows (title, process, pid, rect, minimized, foreground). Confirm the target app is there; if not, open <app> then wait 3 and list again.
  2. focus --window "<title substring>" - bring it to the front. Check the returned focused.title really is the app you meant (other_matches lists the other candidates; use a more specific substring if needed).
  3. inspect --window "<substring>" - primary way to see (Windows): every control's name, control_type, center x,y, enabled, auto_id, and value for edit boxes. Use --name "<text>" to filter, --max to widen. On macOS/Linux it returns unsupported: true - use screenshot --ocr --window "<substring>" instead, which gives text lines with center coordinates.
  4. Act: click x y, click-text "<label>", type "<text>", hotkey ctrl s, press enter, paste-table data.csv.
  5. inspect (or screenshot --ocr) again to verify the effect (new window title, dialog gone, edit box value now holds the text). Never assume an action worked.
  6. Finish with screenshot --out <job dir>/desktop_control/final.png and report its path to the user as evidence, together with what you did.
python "<skill dir>/control.py" windows
python "<skill dir>/control.py" focus --window "Zotero"
python "<skill dir>/control.py" inspect --window "Zotero" --name "Add"
python "<skill dir>/control.py" click-text "Add Item(s) by Identifier" --window "Zotero"
python "<skill dir>/control.py" type "10.1038/s41586-020-2649-2" --enter
python "<skill dir>/control.py" screenshot --ocr --window "Zotero"

Commands

CommandWhat it does
windows [--filter s]List visible top-level windows.
focus --window sRaise/restore the window whose title contains s.
inspect --window s [--depth 12] [--max 300] [--name s] [--all]UI Automation control tree (Windows).
screenshot [--out p] [--ocr] [--region x y w h] [--window s]Save PNG; --ocr adds ocr: [{text,x,y,rect,score}] sorted top-to-bottom.
find-text "s" [--window s] [--ocr]Locate text: UIA control names first, OCR fallback; best: {x,y}.
click x y [--button right] [--double], click-text "s", move x y, scroll -5 [--x --y]Mouse.
type "text" [--enter], hotkey ctrl shift s, press tab [--times 3]Keyboard. Non-ASCII text (Chinese) is pasted via the clipboard automatically.
open excel / open zotero / open prism / open C:\path\file.xlsx / open https://...Launch by alias, path or URL.
wait 2Sleep.
clipboard [--set "text"]Read or set the clipboard.
paste-table data.csv [--sep auto] [--no-header] [--no-paste]Load a CSV/TSV as tab-separated text onto the clipboard and press Ctrl+V - the fastest way to move data into Excel / SPSS / Prism grids.
infoScreen size, mouse position, which packages are installed.

Speed: batch your actions

Every tool call costs a model round-trip, so do NOT issue one command per click. Plan a short sequence, run it in ONE call with batch, and read the returned results:

bash
python "<skill dir>/control.py" batch '[["focus","--window","Excel"],["hotkey","ctrl","home"],["paste-table","table.csv"],["wait","1"],["screenshot","--ocr","--window","Excel"]]'

Shell quoting mangles inline JSON (PowerShell especially) — write the steps to a file in the workspace and pass @steps.json:

bash
python "<skill dir>/control.py" batch @steps.json

batch stops at the first failed step (add --continue-on-error to keep going) and returns each step's JSON. Typical rhythm: one batch to act + verify, look at the result, one more batch to finish. Call overlay once at the start of a task so the user sees that BioDSH is taking control.

Rules

  • --window also accepts process:<exe name> (e.g. --window process:EXCEL.EXE) — use it when several windows share a title (a project name shown by two apps).

  • Multi-monitor: focus / --window automatically move a window that opened on a second monitor onto the primary screen, because screenshots and coordinates are reasoned about on the primary screen. If a dialog still appears elsewhere, windows lists every window with its rect — negative or large coordinates mean another monitor.

  • Always pass --window <title> to click / click-text / type / hotkey / press / paste-table / scroll. The target app is often NOT in front (the user's chat window, a dialog, another app); with --window the command brings it to the front and refuses to act if it cannot, instead of clicking into the wrong program. Without it the result reports which window actually received the action.

  • Every mouse/keyboard command glides the cursor smoothly to its target and shows the BioDSH control overlay (a glass pill 「BioDSH 正在控制电脑」 at the top of the screen + a soft glow around the cursor; state lives in <workspace>/.biodsh_control/, which you may ignore). It disappears by itself ~25 s after the last action. Tell the user this is expected and that slamming the mouse into a screen corner aborts immediately.

  • open on Windows hands the launch to the Explorer shell, so the app starts outside the BioDSH sandbox with the user's normal permissions and keeps running after the command returns. Never start GUI apps with Start-Process / subprocess from a tool call instead: they inherit the write-restricted sandbox token (Excel then complains 「内存或磁盘空间不足」 on save) and are killed when the call ends. After open, wait 3–10 s, then windows / focus.

  • Big apps (Excel, Word, Prism) have huge control trees: use inspect --name <text> or --depth 4, and fall back to screenshot --ocr --window <title> if inspect is slow.

  • Verify the window title before every action. If focus returns a different app than intended, stop and pick a better substring; never click blind.

  • Prefer inspect control names over OCR; OCR is for canvases, images and non-Windows. Use the x,y from the JSON exactly; do not guess coordinates.

  • Ask the user before anything destructive: closing an app with unsaved work, overwriting a file, sending a message/email, confirming a dialog you did not expect. Report what the dialog says and wait.

  • Two tries, then stop. If a control or text cannot be found after two attempts (with an inspect/screenshot --ocr in between), stop and report what is on screen instead of trying random clicks.

  • Only do what the user asked; do not explore menus, open other apps or change settings on your own.

  • Keep the mouse away from screen corners (moving it into a corner aborts the tool - the user's emergency stop). If a command returns FailSafeException, stop and ask the user.

  • Windows coordinates are physical pixels (DPI-aware); pass them straight back to click.

Worked example: put a CSV into Excel and save as xlsx

open excel            -> wait 4 -> windows            # confirm a title containing "Excel"
focus --window "Excel"
inspect --window "Excel" --name "Blank workbook"       # start screen? then:
click-text "Blank workbook" --window "Excel"  ; wait 2
inspect --window "Excel" --name "A1"                   # cell A1 exists, sheet is ready
click <x> <y of A1>                                    # or press ctrl home
paste-table results.csv                                # tab-separated -> pastes into the grid
inspect --window "Excel" --name "B2"                   # verify: value of a cell matches the CSV
hotkey f12                                             # Save As dialog
inspect --window "Save As" --name "File name"          # find the Edit control, click it
type "C:\Users\me\Desktop\results.xlsx" --enter
wait 2 ; windows                                       # title now "results.xlsx - Excel"
screenshot --out desktop_control/excel-final.png       # report this path

If a "file already exists" dialog appears, do not confirm it - ask the user.

Worked example: add a paper to Zotero by DOI via the Zotero window

windows --filter Zotero          # if absent: open zotero ; wait 5
focus --window "Zotero"
inspect --window "Zotero" --name "Identifier"     # toolbar button "Add Item(s) by Identifier" (magic wand)
click-text "Add Item(s) by Identifier" --window "Zotero"
wait 1
type "10.1038/s41586-020-2649-2" --enter          # the popup Edit is focused after the click
wait 4
inspect --window "Zotero" --name "s41586"         # or search the article title; verify the new item row exists
screenshot --out desktop_control/zotero-final.png

Prefer the zotero-connect skill (local API) when it is available - it needs no clicking; use this GUI route only when that skill fails or the user asks for the GUI.

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Desktop Control AI skill do?

See and drive the user's desktop without vision - list and focus windows, read on-screen controls and text as JSON with coordinates (UI Automation on Windows, OCR elsewhere), then click, type, send hotkeys, open apps and paste tables into Excel/SPSS/GraphPad Prism/Zotero.

Why use Desktop Control on TypingMind?

Because you install it once and use it with any model. Desktop Control is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Desktop Control in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/sagirimo/BioDSH/tree/main/biodsh-core/skills/desktop-control. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Desktop Control?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Desktop Control?

As many as you like. As long as a model supports skills, you can use Desktop Control with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Desktop Control AI skill free?

Yes. It is published on GitHub by sagirimo under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇