The desktop app for Chat, Work, Bots and Code, built on an agent engine that runs on your machine. It's for people who want to talk to models they choose, keep their sessions and keys local, and optionally sign in to Cortex Cloud for Bots and remote workspaces.
Documentation · Website · Getting started · Configuration · Architecture · Connection modes · Providers · Testing · Contributing · Security · License
Warning
Alpha, not stable. Cortex Desktop is under active development: screens, settings and stored data can change or break between commits, and nothing is guaranteed to be stable. Builds are unsigned (no code signing, no notarization). Do not use it in production or for anything you can't afford to lose.
Cortex Desktop is one Electron app. The agent engine lives in the app's main process, keeps sessions and settings in local SQLite (node:sqlite) and calls the model providers you configure. You don't need an account.
Three ideas hold it together:
- The engine is local. Sessions, tools, permissions, MCP servers and skills run on your machine. The renderer is sandboxed and only talks to the engine through a small preload bridge.
- Keys stay in the main process. Provider keys go into a separate credential store. They are write-only from the UI, and the renderer only ever sees the last four characters.
- Cloud is optional. Sign in to Cortex Cloud (or a self-hosted server) with an email code to use Bots and the signed-in Work, Chat and Code screens. Local mode keeps working without it.
The banner is a real screenshot of the app: an unedited native macOS window capture (screencapture -l on macOS 26.6.2, Electron 44, dark theme, English), taken as is with the native window shadow and no mockup or recomposition. The Bot conversation is live code, but the screenshot feeds it demo data: a made-up Bot named Nova and invented messages, instead of a real Cortex Cloud account. No keys, emails or private paths appear.
The renderer is a sandboxed React app. It never opens a socket and never sees a key: it calls window.cortex, a small preload bridge, which forwards requests over IPC (cortex:fetch) to the engine's route table in the main process, and events come back as a stream. Provider calls and the optional Cortex Cloud connection are made from the main process, and keys live in a separate credential store there. Details: docs/architecture.md.
In the Bot conversation (signed in), you send a message and the Bot runs a job while typing dots show. If a tool needs permission it waits as a pending approval in the thread: Allow once lets it run, Deny skips the tool. Only safe metadata crosses to the renderer. See AGENTS.md and docs/connection-modes.md for the exact contract.
What works today (see Status for the exact boundaries):
- Chat on the local engine, streaming, with reasoning and image input for models that support them.
- Work tasks and approvals.
- Bots with mascots and an iMessage-style conversation. These screens need a Cortex Cloud sign-in.
- Cortex Code on a local folder.
- Providers and models from the public models.dev catalog (Anthropic, OpenAI, Google and OpenAI-compatible endpoints).
- MCP servers, skills (a
summarizeskill ships inskills/) and optional computer use. - Eight locales (
en fr es de ja zh-Hans pt-BR ko), English by default, dark and light themes.
There are no signed releases yet. Build from source.
You need Bun 1.4 and Node 22 or newer.
git clone https://github.com/CortexLM/desktop.git
cd desktop
bun install
node node_modules/electron/install.js # Bun skips Electron's postinstall
bun run build
bun run startOn a Linux machine without a display, install Xvfb and run xvfb-run -a bun run start. Keep the Chromium sandbox on: if Electron refuses to start because chrome-sandbox is not set up, run sudo chown root node_modules/electron/dist/chrome-sandbox && sudo chmod 4755 node_modules/electron/dist/chrome-sandbox. Only the automated Linux end-to-end tests pass --no-sandbox (see tests/e2e/fixtures.ts); never use it for normal use.
bun run pack # unpacked app in dist/, current platform
bun run dist:mac # macOS dmg and zip (x64 and arm64)electron-builder.yml also defines Windows (NSIS installer and portable, x64) and Linux (AppImage and deb, x64) targets. CI builds unsigned packages only.
| Platform | Notes |
|---|---|
| macOS | Unsigned. Gatekeeper will block the first launch; right-click the app and choose Open, or run xattr -dr com.apple.quarantine /path/to/Cortex.app. |
| Windows | Unsigned installers show a SmartScreen warning. |
| Linux | AppImage and deb. Credential encryption needs a keyring; without one the app refuses to persist cloud sign-in. |
- Start the app (
bun run start). - Open Settings, Providers and models and pick a provider.
- Paste your API key. It is write-only: the app only keeps the last four characters for display.
- Choose a model and start a chat.
More in docs/getting-started.md.
- Providers: docs/providers.md.
- Connection modes (local, Cortex Cloud, self-hosted): docs/connection-modes.md. Pick one in Settings, Connection.
- Overview and environment variables: docs/configuration.md.
| Shortcut | Action |
|---|---|
Cmd/Ctrl+N |
New chat |
Cmd/Ctrl+K |
Command palette |
Cmd/Ctrl+B |
Toggle sidebar |
Cmd/Ctrl+, |
Settings |
Cmd/Ctrl+[ and Cmd/Ctrl+] |
Back and forward |
Cmd/Ctrl+/ |
Shortcuts |
| Package | Role |
|---|---|
packages/schema |
zod contracts, browser-safe |
packages/core |
Local engine: storage, providers, sessions, tools, permissions, agents, skills, MCP, bots, scheduler |
packages/protocol |
Hono route table and validation |
packages/server |
createServer(core), called as app.fetch |
packages/client |
Typed fetch client and SSE parser |
packages/i18n |
Catalogs per locale and namespace |
packages/app |
Renderer: React 19, Base UI, Vite 8 |
packages/desktop |
Electron 44 main and preload, credentials, menu, Cloud probe and sign-in |
vendor/ holds the vendored SDK tarballs, tests/ holds unit and Playwright suites, scripts/ holds the i18n audit, smoke tests and Mac capture tools. Details: docs/architecture.md.
bun run lint
bun run typecheck
bun run test
bun run audit:i18n
bun run build && bun run test:e2eRenderer only, in a browser:
bun run dev:api # engine on :5298, in-memory keys
bun run dev:app # Vite on :5299, proxies /apiRead AGENTS.md and .rules/ before you change code. Testing details: docs/testing.md.
- Live: Chat, Work tasks and approvals, Bots, Cortex Code on a local folder, Settings, Providers and models, connection selection with probing and email-code sign-in.
- Preview only: file viewers and other screens without engine wiring (open
#/galleryin a preview build). - Not built yet (waiting on design): Space, Scheduled, the Plugins and skills management screen, extra sign-in continuation screens. Remote prompt routing is pending.
- Sign-in lasts until Cortex closes. Prompts still use the local engine and the providers you configured.
- Acceptance is incomplete: see evidence/STATUS.md.
Start at docs/README.md. Highlights: Getting started, Configuration, Troubleshooting, FAQ, Architecture.
Is it safe to use for real work? It's alpha. Try it, don't depend on it. See the FAQ.
Do I need an account? No. Local mode works without one.
Where is my data? In the app's data directory, in local SQLite. Keys are in a separate credentials file with restricted permissions.
Why is the app unsigned? Release signing isn't set up yet.
Issues and pull requests are welcome. Read CONTRIBUTING.md and the Code of Conduct. Use the issue templates for bugs and features.
Report vulnerabilities privately, as described in SECURITY.md. Don't open a public issue for them.
- Issues for bugs and requests.
- CortexLM on GitHub for the other repositories.
Apache-2.0, see LICENSE and NOTICE. Copyright 2026 Cortex Foundation / CortexLM.