Skip to content
aoxborrowPublic

About

All your domains, from every registrar, in one open-source desktop or self-hosted app — with a built-in MCP server for AI agents.

Resources

Security policy

Stars

11 stars

Watchers

1 watching

Forks

Latest commit

 

History

912 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DomBot

Latest release License: AGPL-3.0-or-later Sponsor

All your domains, from every registrar, in one app + MCP.

DomBot pulls your whole domain portfolio — scattered across GoDaddy, Dynadot, Cloudflare, and more — into one desktop app, and serves the same portfolio to your AI agents through a built-in MCP server. It's free, open source, and local-first: your data and API keys stay on your machine.

Download for macOS, Windows, or Linux from dombot.ai or the Releases page, or try the live demo: the full app in your browser on an invented portfolio, no install and no account.

DomBot's Domains screen — every domain across all your registrars in one sortable, filterable table

What it does

  • One portfolio, every registrar. Aggregates all your domains across the registrars you configure into a single sortable, filterable table — search by name, filter by TLD / registrar / nameserver, and see registrar, creation and expiry dates, auto-renew, transfer lock, WHOIS privacy, and nameservers side by side. Expiry dates are color-coded by urgency, and at-risk domains (expired, grace, redemption, hold) get a status badge.
  • Renewal costs at a glance. A renewals dashboard forecasts your spend: yearly total, amount due in the next 90 days, a month-by-month renewal chart, and breakdowns by registrar and TLD. Prices come from registrar quotes where available and a base per-TLD price database otherwise, and you can enter a price by hand for anything still unpriced.
  • Export. One click exports the current (filtered, sorted) view to a spreadsheet-friendly CSV.
  • Instant, offline-friendly launch. The whole portfolio is cached on disk and painted the moment the app opens, with no network calls; you refresh on demand (it never auto-refreshes) and a timestamp flags when data is going stale.
  • Agent-ready. An embedded local MCP server lets AI agents (Claude Code, Claude Desktop, any MCP client) read and manage the same portfolio — see Connecting an AI agent.

Configuring registrars

DomBot currently supports GoDaddy, Cloudflare, Dynadot, NameSilo, Spaceship, Namecheap, Porkbun, Gandi, and NameBright, with more on the way.

Add each registrar in Settings → Registrars with an API key from that provider's account — DomBot shows where to find each one. Credentials are stored encrypted on your device via your OS keychain (Electron safeStorage) and are never sent anywhere but the registrar's own API. See SECURITY.md for the full trust model and how to verify it yourself.

After saving a registrar’s first account, use Add another account inside its card to connect more. An account selector appears only for registrars with multiple accounts; single-account registrars keep the original flow. See multiple registrar accounts for migration and MCP selection.

Connecting an AI agent

DomBot runs a local MCP server, bound to your machine only, so any MCP client can work with your portfolio. To connect Claude Code:

claude mcp add dombot --transport http http://127.0.0.1:4123/mcp

On first connect a browser page opens and DomBot's own window shows an Approve/Deny prompt with a matching confirmation code. Approve once and the client stays paired across restarts; manage or revoke paired clients in Settings → MCP Clients. The URL and a ready-to-paste connect command are also shown on the Home screen.

Claude Desktop (and other clients that can only launch a command) use the app itself as a stdio server. Copy the ready-made entry from Settings → MCP into claude_desktop_config.json; it looks like:

{
  "mcpServers": {
    "dombot": {
      "command": "/Applications/DomBot.app/Contents/MacOS/DomBot",
      "args": ["--mcp-stdio"]
    }
  }
}

No approval prompt is needed for this route — it runs as you, on your machine — and if DomBot isn't open when the client starts, it launches automatically.

Staying up to date

Once a week DomBot reads the list of releases at dombot.ai/releases.json. When there's a newer version, a green notification appears in the bell; dismiss it and it stays quiet until the next release. Nothing about you or your portfolio is sent, and you can turn the check off, or check by hand, in Settings → About.

On macOS and Windows, Update to … in Settings → About downloads the new version and Restart to update switches to it. Nothing downloads until you click. Linux packages, and copies run from somewhere other than an installed location, get a download link instead. Self-hosted instances link to how to update your setup.

Self-hosting in the browser

The same app runs as a private web app on your own Cloudflare account — a Worker plus one D1 database, encrypted under a key only you hold, with the MCP server reachable at https://<your-host>/mcp.

The recommended setup is to fork this repository and connect your fork in the Cloudflare dashboard; updating is then GitHub's Sync fork button. The Deploy button is faster to start, but updates are trickier, so it isn't recommended. Both, plus the CLI and putting it behind Cloudflare Access, are in docs/self-hosting.md.

Deploy to Cloudflare

Moving from the desktop app: Settings → Sync → Export data, then import the file on your instance.


Development

DomBot is a cross-platform desktop app built with Electron Forge, React 19, TypeScript (strict), and Vite, styled with Tailwind CSS v4 and Zustand for state. Registrar API support comes from @aoxborrow/registrar-client; agents connect through an embedded MCP server. Contributions welcome — use Node.js 22.13 or newer, clone the repo, npm install, and npm start to run the app with hot reload.

Scripts

Command Description
npm start Run the app with hot reload (Forge + Vite)
npm run package Package the app into an unpacked bundle
npm run make Build distributables (zip/deb/rpm/Squirrel)
npm run lint Lint .ts/.tsx files
npm run format Format the codebase with Prettier
npm run typecheck Type-check without emitting
npm run site:build Minify the landing page (site/src → site/dist)
npm run web:dev Run the self-hosted web app locally (wrangler dev)
npm run web:deploy Build and deploy the web app to Cloudflare

Credentials

Registrar credentials are entered in Settings → Registrars and stored encrypted via Electron safeStorage — in development and production alike. There is no .env/environment-variable fallback: credentials come only from the GUI store, so ambient vars from other tools can't silently shadow them (see resolveField and src/core/services/credentials.ts). The same saved credentials feed both the UI and the MCP server. For the full trust model and how to verify it, see SECURITY.md.

Embedded MCP server

The MCP server (see Connecting an AI agent) is a third adapter over the same services/ core the UI uses — see src/electron/mcp/.

  • Transport: Streamable HTTP, bound to 127.0.0.1 only. Never exposed off the machine.
  • Auth: OAuth 2.1 (dynamic client registration + PKCE), served by the app. The approval prompt lives in DomBot's own window; the issued token is persisted (userData/mcp-tokens.json) so clients stay paired across restarts. Env knobs: DOMBOT_MCP_PORT (default 4123), DOMBOT_MCP_ENABLED=0 to disable, DOMBOT_MCP_AUTOAPPROVE=1 to skip the approval prompt (dev/testing), DOMBOT_MCP_TOKEN for a static bearer token escape hatch (dev/testing). See src/core/mcp/oauth.ts.
  • stdio shim. DomBot --mcp-stdio runs the same binary headless as a stdin/stdout bridge to the HTTP server, for clients that can't dial a URL (Claude Desktop). It authenticates with a per-install token the app writes to userData/mcp-stdio.json, launches the app if it isn't running, and re-initializes its session transparently if the app restarts. stdout is the JSON-RPC channel, so all logging in that mode goes to stderr. See src/electron/mcp/stdio.ts. Dev builds aren't auto-launched — start the app first.
  • Tools. Named by scope, so a caller can tell at a glance what a tool acts on: portfolio_* take no scope params, registrar_* require a registrar id, and domain_* take a domain. For domain_* tools the registrar is optional — DomBot resolves it from the cached portfolio (you own the domain, so it knows who holds it), so an agent can act on a name without first looking up its registrar. Pass registrar to skip the lookup, or to act on a name not yet in the cache; if the cache can't resolve it, the tool says so and points at portfolio_sync, or says the name is in Archive.
    • Portfolio: registrar_list, portfolio_query, and portfolio_sync. portfolio_query is the primary way to read the portfolio: list, search, filter, sort, and page the cached portfolio and your imported names (by registrar, source, TLD, folder, name, nameserver, auto-renew/lock/privacy, status, and expiry), returning only the fields an agent needs (including what you paid, sold for, noted, and are asking, and the estimated renewal price) plus sync health (total, stale, and per-registrar errors). Like the Domains page it covers the names you own by default; ownership switches to Archive (sold, dropped, archived, or gone from your accounts) or both, and each row says which, and whether it's Hidden. With no filters it returns every name you own (paged), so it doubles as a plain list. It's a pure cache read (no registrar calls); portfolio_sync runs the live cross-registrar pass that refreshes the cache, returning a per-registrar summary. An agent syncs once (or when portfolio_query reports stale/empty), then reads cheaply.
    • Folders: folder_list (with domain counts, including the built-in Hidden folder), folder_create, folder_rename, folder_delete (its domains go back to no folder), and domain_set_folder (by folder name or id, or null to clear). They write the same folder store as the app, so an open window updates live.
    • History and review: domain_history (every event for a name, with alert status), portfolio_alerts (what the bell shows) and portfolio_alert_dismiss.
    • Money, notes and ownership: domain_purchase_set, domain_sale_set, domain_note_set, domain_asking_price_set, domain_renewal_price_set (your own yearly price, overriding the estimate), and domain_ownership_set (Dropped, Archived, or back to Owned). Each can answer an open alert with resolves where it fits. DomBot-local, no registrar calls; history they write is marked Agent in Activity.
    • Registrar accounts: registrar_set_enabled.
    • Registrar reads: registrar_test, registrar_domains, registrar_sync (targeted single-registrar refresh of the cache), registrar_check_availability, registrar_pricing.
    • Domain reads: domain_get, domain_contacts_get, domain_nameservers_get, domain_dns_get, domain_email_forwarding_get, domain_url_forwarding_get, domain_renewal_price (DomBot's own estimate, distinct from registrar_pricing). domain_get and domain_nameservers_get serve from the detail cache when fresh, fetch live and write through otherwise, and take refresh to force a live fetch.
    • Writes (non-money): domain_nameservers_set, domain_dns_set, domain_contacts_set, domain_email_forwarding_set, domain_url_forwarding_set, domain_set_autorenew, domain_set_lock, domain_set_privacy. Forwarding (email alias and URL redirect) is per-registrar — unsupported providers return an error.
    • Writes (money): registrar_register_domain, registrar_transfer_domain, domain_renew. Not gated behind extra per-call approval — the connection-level OAuth approval is the gate — and annotated non-idempotent.
    • Cache write-through. A successful write patches the local cache (the same cache the desktop UI reads) and pushes an update to any open window, so the Domains table reflects the change live — no manual Sync needed.
    • Cache freshness. Reads serve the local cache and report stale / fetchedAt; an agent refreshes explicitly with portfolio_sync / registrar_sync. The app also runs a periodic background sync so the cache stays warm for MCP-only use (no window ever opened). The interval is set in Settings → Sync (Every hour … 7 days, or Off; default 24h, applied live); large portfolios may prefer a longer interval or Off. DOMBOT_SYNC_INTERVAL_MINUTES overrides the setting for dev/testing (0 disables).
  • Credentials. Resolved the same way as the UI (see Credentials); a registrar is "configured" when all of its required fields are present.

License

DomBot is free and open source software: Copyright (C) 2026 Aaron Oxborrow, licensed under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later). You may use, study, share, and modify it; if you distribute a modified version, it must also be AGPL and ship its source.

Any paid data feeds are a separate, optional add-on service with their own terms — the app itself is and stays free. The registrar logic in @aoxborrow/registrar-client is a separate project under the MIT license.

About

All your domains, from every registrar, in one open-source desktop or self-hosted app — with a built-in MCP server for AI agents.

Resources

Security policy

Stars

11 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages