Give her a name, an email, a username, a domain, or a photo. She opens a case, runs the target across the open web, reads the metadata, maps the infrastructure, and draws everything she finds into a knowledge graph that grows while you watch. Runs on macOS and Windows, powered by Claude, ChatGPT, Gemini, or a local model of your own.
Claude · ChatGPT and any OpenAI-compatible endpoint · Gemini · Ollama (fully local, nothing leaves your machine)
Seriously. Aether is for people and systems you're actually allowed to look into: your own exposure, folks who asked you to check theirs, and lab or CTF boxes you own. She only reads what's already public or shown by a platform. She won't break authentication, get past bot-detection, phish, or take over accounts, and those limits are baked into how she works. Point her at a stranger you have no business investigating and you're the baddie, not her. Be normal.
You hand Aether a selector and she gets to work, writing up what she finds rather than firing off chat replies.
Every tool she runs shows up as a numbered line in an evidence log that stays with the turn — so a finding has an
address you can cite later, like 02.1. The moment she finds something she writes it into the graph, then flips its
status as she confirms it or rules it out.
The graph encodes meaning rather than decorating with it. Shape is the selector type — circles for identity, squares for infrastructure, diamonds for artifacts, triangles for contact details. The ring is the status: a solid ring is confirmed, a ring broken at twelve o'clock is an open lead, dashed is a candidate, and an excluded node is hatched and struck through. Roman type is established, italic is provisional. All of it survives a greyscale screenshot, and all of it reads the same in either theme. Nodes carry real pictures too: a face on a person, the site's favicon on an account, the photo itself on a photo node.
Every turn is numbered and every tool call sub-numbered beneath it. Your words are kept verbatim in mono; her report is set in sans against a margin rule.
Selecting a node brackets it, draws a crosshair through it, lights its neighbourhood and drops everything else back a value step.
A first-class light theme, not an inverted dark one. The canvas is drawn from the same tokens as the rest of the app, so it repaints instantly when the theme changes.
At the default access level, Aether asks — whichever model is driving. The exact command is shown in full, never truncated, because a decision made on an ellipsis is not an informed one. The level itself sits in the chat next to the model; Shift+Tab toggles Safe and Ask.
One list, grouped by the question each capability answers. The switch says you want it — if it needs a program installed, turning it on installs that first.
First run asks one thing: which model. Claude, ChatGPT, Gemini or a local Ollama — set up whichever you pick right there, and the screen steps aside the moment that backend is reachable.
Run her on Claude, on ChatGPT, on Gemini, or fully local through Ollama. Same tools, same graph, same access rules, your choice of brain. Where a provider can list its models, the picker is that list.
A live knowledge graph. A force-directed canvas you can pan, zoom and drag. Marks are shaped by selector type, ringed by status, sized by how connected they are, and carry real pictures where there are any. A node written mid-turn pulses one expanding ring, so you can see which of the four things a tool just reported actually landed. It's the main workspace, and it updates as the case builds.
A transcript you can cite. Answers stream in as she writes them, and every tool call is a numbered line in an evidence log that is stored with the turn instead of vanishing when it finishes.
Light and dark, both first-class. One palette, defined twice, with every pairing contrast-checked. The graph canvas reads from the same tokens as the DOM, so switching theme repaints it with no reload.
Three access levels, and one of them asks. Safe is collection only — search, recon, the graph, and reading public pages, with no shell, no file writes and no installing. Full removes every prompt. The default is Ask: Aether can reach for the shell, fetch a URL it picked, run a command module, or install a bundled tool it needs, and each request goes to you with the exact command or URL shown in full. Refusing is an answer — it says what it would have done and carries on. "Don't ask again" lasts for the session and is never written to disk, and changing the level retires any grant made under the old one.
The level sits in the chat, next to the model — the way Claude Code keeps its permission mode at the prompt — and Shift+Tab in the message box toggles Safe and Ask, mid-investigation if you like; the next gated call sees the new answer. As in Claude Code, the no-prompts level is not on the key: Full is a deliberate pick from the picker or Settings, never a stray keystroke. It means the same thing on every brain: the ChatGPT, Gemini and Ollama runners put every tool call through the same policy the Claude path does, so Ask asks whichever model is driving.
Approval answers may Aether run a command, not may it go anywhere. The workspace fence, the credential deny-list and the OS sandbox all still apply to an approved command — the levels decide what it can reach for, not whether the boundary holds.
Modules that tell you the truth. Roughly twenty bundled modules drive a command-line program — maigret,
subfinder, nuclei, nmap and friends — and a module whose program is missing is a tool that always fails. So
install state and enable state are one thing: the switch says you want a capability, and turning it on installs
whatever it needs first, using whichever package manager you actually have (Homebrew, pipx, go install, gem;
Scoop and py -m pipx on Windows). If the first route fails it tries the next, and the row says what actually
went wrong — a missing package manager comes with the one line that installs it. First launch offers to do the
lot in one click; it's recommended, not required, and it doesn't appear at all if there's nothing to install.
Your own modules, with notes. Add a local command, an API with a fixed {input} template, or an API Aether
shapes requests against itself — path, method, query and body of its choosing, pinned to the host in your base URL.
Every module takes notes for Aether: your instructions, shown to the model right beside the tool. Try it
sends one request or runs the command once so you see what the model would get. A code connector you wrote
(private/connectors/*.mjs) is a module too, with its own switch, name and notes.
Two things it will not do: run anything as root, or install without a click. When the only route needs sudo,
you get the exact command to paste instead of a shrug. And because a GUI app inherits launchd's bare PATH
rather than your shell's, Aether repairs PATH at startup — Homebrew, ~/.local/bin, ~/go/bin, ~/.cargo/bin
and the rest — then asks your login shell for the real thing, so tools installed with a version manager are
found too. That single fix is the difference between "installed" and "command not found".
A built-in Sherlock. username_search checks a handle across dozens of platforms at once, no Python and no
setup, and tells you where a public profile exists.
Dozens of bundled tools. A big catalog of no-key OSINT and recon endpoints (GitHub, crt.sh, RDAP, DNS over HTTPS, Shodan InternetDB, RIPE, Wayback, urlscan, OTX, Hudson Rock and more), plus one-toggle wrappers for the usual recon CLIs (maigret, subfinder, httpx, nuclei, nmap). Add your own too: a local command, or any HTTP API called with your keys, which get encrypted on your machine and never leave it in plaintext.
Offensive-security playbooks. A bundled set of skills (network recon, web enumeration, foothold, privilege escalation, password attacks, an HTB methodology) the model loads when a lab or CTF task calls for it.
Aether isn't locked to one model. Pick your provider in Settings, and the model switch is right there in the chat, next to where you type — with the reasoning effort and the access level beside it.
| Provider | What it is | Needs |
|---|---|---|
| Claude | The default. Uses your Claude subscription through the Agent SDK. Fable 5.1, Opus 5, Sonnet 5, Haiku 4.5. | Sign in once |
| ChatGPT | OpenAI directly (the Responses API, so GPT-5.6 and GPT-6 reason and call tools), or any OpenAI-compatible endpoint — OpenRouter, Azure, LM Studio, vLLM. | Your API key |
| Gemini | The Gemini Developer API — Gemini 3.8 Flash by default, 3.1 Pro when it matters. | A Google AI Studio key (Flash has a free tier) |
| Ollama | A model running fully on your own machine. Nothing leaves the box. | ollama serve + a tool-capable model |
The graph, the tools, the access rules and the whole workflow are identical whichever you choose. Where a
provider can list what it serves, the picker is that list: a ChatGPT-compatible endpoint's GET /models, a
Gemini key's catalogue, and — for Ollama — every model you've pulled, marked with what it can do (tool calling,
thinking, vision), which one is loaded right now, and how much context it has. Local models without tool
calling are labelled as such: they will still chat but can't drive the graph. Good local choices are qwen3,
qwen3.5, gemma4, gpt-oss, llama3.1 and mistral-small3.2.
Ollama is driven over its native API rather than the OpenAI shim, for one reason that matters: context. Ollama
sizes a model's context by GPU memory — 4k tokens on most laptops — and Aether's brief plus its tool schemas
are bigger than that, so a freshly pulled model would silently lose its own instructions. Aether asks for 32k
(or the model's own baked num_ctx if that is larger; OLLAMA_NUM_CTX overrides it), and warns in the chat
when the model you picked can't call tools or can't hold that much context.
Step-by-step guides with pictures: macOS ·
Windows · choosing a model ·
modules, tools and access — the same pages are in docs/.
Installers for both are on Releases. From source — the desktop
app lives in app/:
git clone https://github.com/fknMega/Aether.git
cd Aether/app
npm install
npm run devThe first launch asks which model you want and sets it up right there: sign in to Claude (or run
npm run login), paste an OpenAI or Gemini key, or point at your local Ollama. You'll need Node 18+; there's no
database to run and no native toolchain to install, and state is a plain JSON file.
There's a flake in app/, so nix develop there gets you a shell with the right Node, the nixpkgs Electron
(no postinstall binary download), and — on Linux — the Chromium runtime libraries that otherwise fail at
window creation.
cd app
nix develop # dev shell, then: npm install && npm run dev
nix build # Linux package; see the note in flake.nix about npmDepsHashflake.lock is not committed — run nix flake lock once, or let nix develop generate it, so the pin is
yours rather than one baked in by whoever wrote the flake.
cd app
npm run dist:mac # .dmg and .zip, built on macOS
npm run dist:win # .exe installer, built on WindowsBuild each OS on that OS, since the claude binary ships as a per-platform package. Output lands in release/.
Auto-updates work on both Windows and macOS, and there's an Updates panel in Settings (check, status,
install, auto-check toggle). Aether reads the latest GitHub Release,
downloads the build in the background, and installs it: on Windows it runs the new installer, and on macOS it
swaps its own app bundle and relaunches (no code signature required, unlike the stock Electron updater). If the
app lives somewhere it can't write, it falls back to opening the .dmg for a quick drag. To publish a build,
create a Release with the .dmg / .exe assets attached (e.g. gh release create v2.0.2 release/* with a token
that has contents:write).
Does the AI get its own environment, or can it wreck my machine? It gets one. Command execution runs inside an OS-level sandbox — Seatbelt on macOS, Bubblewrap on Linux — and there are three more layers above it:
| Layer | What it does | Enforced by |
|---|---|---|
| OS sandbox | Isolates command execution from the rest of the account | the kernel |
| Read boundary | File reads cannot leave the workspace, in any permission mode | the Agent SDK |
| Policy | Refuses paths outside the workspace, a credential deny-list, fail-closed on anything it can't parse | src/main/permissions.ts |
| Tool removal | In safe mode the shell and write tools are stripped from the model's context entirely | the Agent SDK |
Safe mode is the default. Autonomy — the shell, file writes, and local-command modules — is off until you turn it on. With it off, Aether keeps search, recon, the graph and API modules, and cannot execute anything.
Some things stay off-limits whether or not autonomy is on: SSH, GPG, AWS, gcloud, Kubernetes and Docker
credentials; browser profiles, cookie stores and saved logins; shell history and .env files; and Aether's own
settings, module keys and sign-in tokens. The boundary is asserted by tests, not just described — see
permissions.test.ts and run npm test.
Prompt injection is the real threat here, and it is not hypothetical. Aether's whole job is reading content written by the people it investigates, so a target who expects to be looked at can plant instructions where Aether will read them. The system prompt tells the model that every byte returned by a tool is evidence and never an instruction, and to report an attempted injection as a finding. That plus the sandbox is a serious mitigation, not a solved problem — the layers exist precisely because the prompt alone is not enough.
What is still on you. Custom modules are trusted config: only add ones you wrote or trust, because a command module is a shell command you asked for. Keys, both for modules and for your AI provider, are encrypted at rest with the OS keychain and never sent to the renderer in plaintext.
On Linux the sandbox needs bubblewrap; with autonomy on, Aether refuses to start a turn rather than silently
run unsandboxed. On Windows there is no sandbox backend at all — autonomy there gets the read boundary, the
policy and tool removal, but not kernel isolation. That is a real gap, and it is stated here rather than
papered over: if you run with autonomy on Windows, the policy is the only thing between a hostile page and your
account.
None of this is a bug list. It's what the tool is, and open-sourcing it means you can read exactly what it does.
- Discord: discord.gg/zjawxkDZVP come say hi, share cases, ask for help.
- Sponsor: github.com/sponsors/fknMega if Aether is useful to you and you want to keep her fed.
MIT. See LICENSE.