A local-first, multi-model AI chat app. Bring your own API keys, talk to Claude, GPT, Gemini, Grok, or local models through an oMLX OpenAI-compatible endpoint. All conversations are stored as plain text files in a folder you choose.
Blog post · Download for macOS
Download the latest release from the releases page, or build from source:
npm install
npm run tauri devOn first launch, pick a vault folder and add at least one API key in settings. See SETUP.md for detailed instructions including Rust installation.
Everything lives in your vault folder as plain files:
~/alloy-vault/
├── config.yaml # API keys and settings
├── memory.md # Persistent context injected into system prompt
├── conversations/ # Chat history (YAML)
│ └── attachments/ # Image attachments
├── notes/ # AI-managed notes (Markdown)
├── tasks/ # Scheduled tasks (YAML; optional delivery conditions)
├── skills/ # Custom skills (Markdown)
└── riffs/ # Draft notes (Markdown)
Conversations are YAML files:
id: 2025-06-15-1750012200-bike-kickstand
created: 2025-06-15T11:30:00Z
model: anthropic/claude-opus-4-6
title: Kickstand won't stay tight
messages:
- role: user
timestamp: 2025-06-15T11:30:00Z
content: |
I bolted a new kickstand to my bike but it keeps
loosening after a few rides. Any ideas?
- role: assistant
timestamp: 2025-06-15T11:30:09Z
content: |
The bolt is probably vibrating loose. Clean the threads,
apply a drop of Loctite Blue (medium strength), and
re-tighten. It'll stay put but you can still remove it
with a wrench later if you need to.Skills are markdown files that teach the AI new behaviors and give it access to tools. Create a folder in $VAULT/skills/ with a SKILL.md:
---
name: memory
description: Remember things about the user across conversations
---
# Memory Skill
When you learn something important about the user, save it to `memory.md`
using `append_to_note`. Before answering, check `memory.md` for context.| Tool | Description |
|---|---|
read_file |
Read files from your vault |
write_file |
Create or update files |
append_to_note |
Append to notes with provenance tracking |
list_directory |
List files in vault directories |
search_directory |
Search files and content |
http_get |
Fetch data from URLs |
web_search |
Search the web (Serper or SearXNG) |
use_skill |
Load another skill on-demand |
spawn_subagent |
Run 1-3 parallel sub-agents |
The web_search tool requires one of:
- SearXNG (free, self-hosted) — Run a local instance via Docker with JSON format enabled. Set
SEARXNG_URLin your vault'sconfig.yaml(see SEARCH.md). - Serper (paid API) — Sign up for a key and add it as
serperApiKeyin your vault'sconfig.yaml.
All models are configured under a single providers: list in config v2
(version: 2). Local trust is explicit: only local: true grants the Local
badge and private-directory access; omission is treated as cloud.
- OpenRouter — one key for Claude, GPT, Gemini, Grok, Llama, and more (the cloud gateway)
- oMLX — local, on-device models through an OpenAI-compatible endpoint (mark
local: true; prompts stay on your machine/LAN) - Claude subscription — use your Claude Pro/Max plan instead of API credits (see below)
- Codex subscription — use your ChatGPT/Codex plan instead of API credits (see below)
Pick the models currently advertised by Claude Code, billed against your
Claude Pro/Max subscription rather than per-token API credits. Alloy reads
the same account- and policy-filtered model catalog as Claude Code's /model
picker through its structured control protocol. This includes resolved model
names and context variants such as 1M. It works by shelling out to the Claude
Code CLI (there is no subscription-billed HTTP API).
Enable it by adding a Claude CLI adapter to your vault's config.yaml:
providers:
- id: claude-cli
kind: cli
adapter: claude
# command: /opt/homebrew/bin/claude # only if auto-discovery fails
# oauthToken: sk-ant-oat-... # from `claude setup-token` (optional)Requires the claude CLI installed and logged
in to your subscription (run claude once to log in). These models pick up
Alloy's built-in tools — web search, reading/writing vault files, notes, skills —
just like every other provider.
Use Codex billed against your ChatGPT/Codex subscription rather than
per-token API credits. It works by shelling out to the OpenAI Codex CLI
(codex exec).
Enable it by adding a Codex CLI adapter to your vault's config.yaml:
providers:
- id: codex-cli
kind: cli
adapter: codex
# command: /opt/homebrew/bin/codex # only if auto-discovery failsRequires the codex CLI installed and logged
in to your subscription (run codex login). Alloy reads the authenticated Codex
model catalog, shows each exact model available to the account, and passes that
selection to codex exec --model. A separate Codex (default: model)
option shows and keeps Codex's current account/config-selected default. Unlike
Claude subscription mode, Codex is text-only for now — it answers prompts
but does not use Alloy's built-in tools (web search, vault files, skills). Codex
runs its own agent in a
read-only sandbox and sends prompts to OpenAI, so it is treated as cloud (no
access to private directories).
npm run tauri dev # Desktop app (requires Rust)
npm run dev # Web mode: frontend (:1420) + auto-rebuilding backend (:3030); vault from .env
npm run test:run # Run tests
npm run tauri build # Production buildSee DEV.md for architecture details.
- Tauri 2 (Rust backend, React frontend)
- React 19 + TypeScript + Vite
- Storage: YAML/Markdown in user-chosen directory
- Node.js v18+
- Rust (latest stable) —
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh - At least one API key, or an oMLX server running locally
Issues and PRs welcome.