GSCTL(1) GSCTL(1)

NAME

gsctl — GNOME settings,
searchable and undoable.

A command-line interface to GSettings/dconf, built for AI agents and usable by people. Find the key that controls something, see its type and allowed values, change it with validation and --dry-run, and undo anything from a journal. JSON for agents, text for people.

# paste this into Claude Code, Codex, Cursor or any coding agent

Read https://junoddev.github.io/gsctl/agents.md and set up gsctl on this machine.

# it installs gsctl, checks the session, adds the skill and offers a permission gate. read the file

v0.1.2 · MIT OR Apache-2.0 · Linux + GNOME

SYNOPSIS

gsctl search words…              # ranked search over keys, summaries, descriptions
gsctl schema schema [key]         # type, default, value, allowed values
gsctl get|set|reset schema key [value] [--dry-run] [--yes]
gsctl changed                      # only what differs from defaults
gsctl history | revert id|last     # every write is journaled
gsctl keys find|list|conflicts|add|remove
gsctl ext list|info|enable|disable
gsctl export | apply [--prune]       # per-area JSON for your dotfiles
gsctl watch | doctor | man | completions shell

DESCRIPTION

On a desktop like Omarchy, every piece reads a plain-text file in ~/.config, so an agent can read the setup, edit a line and reload. GNOME can't work that way: Shell, Mutter and the apps keep their settings in one binary dconf database, described by thousands of typed keys, with no file to read or edit.

gsettings has the metadata but no search, no JSON, no error an agent can act on and no record of what changed. dconf dump is thousands of lines of preferences mixed with machine state. gsctl gives GNOME what Omarchy gets from plain files: a settings surface an agent can read, search and change safely. It's a proxy over dconf, not a copy, so Settings, gsettings and gsctl always agree.

  • search — ranked over schema ids, key names, summaries, descriptions and installed extensions
  • validate — type and range checks before anything is written; writes are read back
  • dry-run — every write command shows exactly what it would change
  • undo — a journal of old values; revert last walks back like an undo stack
  • shortcuts — all five keybinding schemas, custom bindings and extension shortcuts in one place
  • extensions — their settings included, enabled state by GNOME Shell's own rules

EXAMPLES

$ gsctl search "screen timeout" --limit 1 --format text
  org.gnome.desktop.session  idle-delay  0  # Time before session is considered idle  (seconds of inactivity before the screen blanks; 0 = never)
149 matches (showing 1 of 149; use --limit for more)

$ gsctl set org.gnome.desktop.interface color-scheme sideways --dry-run
error: "sideways" is not one of the allowed values: default, prefer-dark, prefer-light
hint: see `gsctl schema org.gnome.desktop.interface color-scheme`

$ gsctl set org.gnome.desktop.interface color-scheme prefer-dark --format text
set org.gnome.desktop.interface color-scheme: 'default' -> 'prefer-dark'

$ gsctl revert last --format text
reverted org.gnome.desktop.interface color-scheme: 'prefer-dark' -> 'default'

$ gsctl keys add Terminal '<Super>Return' ptyxis --dry-run --format text
would add 'Terminal' at /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/: <Super>Return runs 'ptyxis'  (guarded: needs --yes)

AGENTS

JSON on stdout by default. When stderr isn't a terminal, errors are JSON too, with a stable code, an exit_code, a hint, and for bad values the allowed range: enough to fix the call without another lookup.

$ gsctl set org.gnome.desktop.interface color-scheme sideways --dry-run
{"error":{"code":"invalid_value","exit_code":4,
  "message":"\"sideways\" is not one of the allowed values: default, prefer-dark, prefer-light",
  "schema":"org.gnome.desktop.interface","key":"color-scheme","type":"s",
  "range":{"kind":"enum","choices":["default","prefer-dark","prefer-light"]},
  "hint":"see `gsctl schema org.gnome.desktop.interface color-scheme`; ..."}}
EXIT STATUS
0ok4invalid value
1internal error5not writable or no session
2usage6guarded key, needs --yes
3not found7conflict

Machine-readable docs, served as plain files:

  • agents.md — setup instructions: install, verify, add the skill, add a permission gate
  • skill/SKILL.md — the operating manual: search → schema → dry-run → set → verify
  • llms.txt — index for crawlers and agents

SAFETY

gsctl trusts you. It makes changes visible (--dry-run, the journal) and undoable (revert), and asks for --yes only on keys that can lock you out, cut off remote access or make GNOME run a command. Secrets are redacted in output. It isn't a sandbox: anything running as you can call dconf write, so for an agent the real gate is the agent's own permissions. In Claude Code:

{
  "permissions": {
    "ask": ["Bash(gsctl * --yes)", "Bash(gsctl * --yes *)"],
    "deny": [
      "Bash(dconf write *)", "Bash(dconf load *)", "Bash(dconf reset *)",
      "Bash(gsettings set *)", "Bash(gsettings reset *)", "Bash(gsettings reset-recursively *)"
    ]
  }
}

Every --yes asks you first, and writes go through gsctl, where they're validated and journaled. See SECURITY.md.

TESTED ON

Ubuntu 26.04 and Fedora 44 (GNOME 50). Every push builds and runs the test suite on Ubuntu 22.04 and 24.04, Fedora and Arch; each release also passes a 96-case regression suite in a live GNOME session. x86_64 and aarch64 binaries need glibc 2.35 or newer.

SEE ALSO