For engineers
One binary. One folder of markdown.
HQ is one Rust binary around one folder of markdown. This page walks through each part in the order you would meet it, with the code paths to read. Everything here comes from the repository documentation. Where a document and the code could drift, the page points at the file.
hq chat
Daemon
Discord relay
Telegram relay
Web :5678
MCP mcp-serve
01
Process model and the single binary
The hq binary is built from the hq-cli crate. A release build is about
58 MB with LTO and symbol stripping. The same file runs the terminal chat, the daemon, the
Discord and Telegram relays, the web server and the MCP server. You pick the role with a
subcommand.
hq start all starts the long-lived components and hq ps lists the
managed processes. An MCP client does not need any of that: it launches
hq mcp-serve over stdio itself. hq chat runs the agent in process, so the
terminal works with nothing else running.
Configuration lives in ~/.hq/config.yaml, or the file named by
HQ_CONFIG_PATH. Any key can also come from an HQ_ environment variable,
with __ for nesting. The file and its backups are written owner-only.
~/.hq/config.yamlDefault file
HQ_CONFIG_PATHOverride path
HQ_SECTION__KEYEnv, __ nests
One config, owner-onlyLoaded
Full diagram and text description
Text description of this diagram
- One binary, hq, about 58 MB, built from the hq-cli crate.
- Five roles come out of it: terminal chat (hq chat), the daemon, the chat relays for Discord and Telegram, the web server that carries REST, the chat socket, the MCP endpoint and the PWA, and the MCP stdio server (hq mcp-serve).
- All five read and write the same vault: markdown files plus one SQLite database.
02
Crate map
The workspace is Rust edition 2024 with 24 crates and about 289,000 lines of Rust. Foundations
hold types, storage and the LLM clients. The agent crate holds the session loop, sub-agents,
governance and the context engine. Services wrap those for a transport, and
hq-backup writes and restores encrypted backups of the vault and its database.
hq-host and hq-sandbox run and confine coding agents, and
hq-gate is the signed TCP transport for the host gate over a private tunnel.
Four crates connect devices. hq-bridge pairs machines with a one-time QR code and
reconnects them by key. hq-edge is a blind public forwarder that routes by TLS server
name to a registered device. hq-net sets up a private WireGuard network, and
hq-tunnel is a userspace WireGuard peer for a phone. hq-cli ties them into
the binary, and hq-desktop holds the macOS desktop app's logic with no GUI dependency.
The stack, in short: Tokio for async, Axum and tower-http for the web server, rusqlite (bundled,
WAL mode) for storage, rmcp for MCP, serenity for Discord, teloxide for Telegram, clap for the CLI
and figment for configuration. LLM calls go through async-openai with a swappable base URL, which
is how OpenRouter, Ollama and other OpenAI-compatible backends plug in. A direct Anthropic Messages
client sits beside it, with prompt caching. Every call is priced in one place, and spend shows on
the /usage page.
hq-clihq-desktop
Host, network
hq-hosthq-sandboxhq-gatehq-bridgehq-edgehq-nethq-tunnel
Services
hq-webhq-relayhq-mcphq-daemonhq-updatehq-backup
Intelligence
hq-agenthq-toolshq-memoryhq-converthq-export
Foundations
hq-corehq-vaulthq-dbhq-llm
Full diagram and text description
Text description of this diagram
- Foundations: hq-core (types, config, errors, token counters), hq-vault (notes, tasks, frontmatter), hq-db (SQLite, FTS5, embeddings) and hq-llm (providers, backend chains, the direct Anthropic client).
- Intelligence: hq-agent (session loop, sub-agents, governance, context engine), hq-memory (consolidator, forgetter), hq-tools (about 100 tools), hq-convert (document conversion) and hq-export (native note export).
- Services: hq-mcp (the 2-tool gateway), hq-daemon, hq-relay (Discord and Telegram), hq-web (REST, WebSocket, PWA), hq-update (the signed updater) and hq-backup (encrypted backup and restore).
- Agent runtime: hq-host (the built-in host for long-lived coding agents), hq-sandbox (the process sandbox policy for one agent) and hq-gate (the signed transport to a host on another machine).
- Network: hq-bridge (pairing machines with a QR code), hq-edge (a self-hosted public forwarder), hq-net (the WireGuard private network) and hq-tunnel (a userspace WireGuard peer for a phone).
- Apps: hq-cli, which builds the hq binary, and hq-desktop, the logic behind the macOS desktop app (host lifecycle, pairing, Connect Claude).
03
The vault and the memory layers
The vault is a folder, .vault/, and it is the single source of truth. Notes, memory,
skills and conversation threads are markdown with YAML frontmatter. One SQLite file,
.vault/_data/vault.db in WAL mode, holds the indexes: FTS5 full-text search, embedding
vectors, link graphs and the registries the daemon and relays need. Delete the database and the
notes are still there.
Embeddings come from OpenRouter when a key is set, and from Ollama (nomic-embed-text
by default) when it is not. Memory, consolidation and skill review call the router under the
aliases dream, bulk and ingest. Point those at a local model
with a backends: block and they stay on your machine.
Memory
The hq-memory crate has an ingester, a consolidator, a querier, a forgetter and an
entity graph. The daemon runs consolidation, embedding, note tagging and forgetting on its memory
tier, so memory is something the vault does for itself over time, not a log that grows forever.
Context frames
Each turn, the context engine builds a token-budgeted frame from five layers: system, the user message, memory, thread and injections. Surplus tokens cascade between layers, with the thread getting 50 percent, injections 35 percent and memory 15 percent. Private tags are stripped from the memory layer, and older thread messages are compacted.
Who may see what
Notes and tasks can carry a label: private to named people, shared, public, or unmarked, which means owner only. A shared channel discloses only what every verified participant may see, and an unresolved identity is denied by default. The design note lists what is not covered yet.
Full diagram and text description
Text description of this diagram
- Vault: _system/ (SOUL, MEMORY, CRON-SCHEDULE and other system markdown), _threads/ (conversation history), Notebooks/ (notes, projects, knowledge), skills/ and _data/vault.db (SQLite in WAL mode, with FTS5 and embeddings).
- Context engine: five layers per frame. 1 System (SOUL plus harness instructions), 2 UserMessage (the current turn), 3 Memory (long-term facts), 4 Thread (recent messages, older ones compacted), 5 Injections (pinned notes and search results).
- Surplus tokens cascade between layers: thread 50 percent, injections 35 percent, memory 15 percent.
- The daemon memory tier runs consolidation, embeddings and note tagging, and forgetting, and writes the results back to the vault.
04
The daemon and its scheduled tasks
The daemon is a plain interval scheduler. It ticks every 5 seconds and runs whichever tasks are
due, one after another, each with a timeout derived from its interval tier. A missed task is
detected on the next start. After every tick it writes DAEMON-STATUS.md at the vault
root, so you can read what ran with cat.
The fast tier handles approvals, harness-session supervision, the heartbeat, value-bus delivery and the email poll. The memory tier handles consolidation, embeddings, note tagging and forgetting. The maintenance tier handles vault health, thread rotation, clean-up, a disk watchdog and SQLite vacuum. Beside the scheduler, an agent worker triages inbound events and email, and a machine profile records which CLIs the host has.
Recurring prompts are not daemon tasks. They are /watch rows, covered with the relays below.
Full diagram and text description
Text description of this diagram
- A scheduler tick fires every 5 seconds.
- Fast tier: approvals, harness-session supervision, heartbeat, value-bus delivery and email poll.
- Memory tier: consolidation, embeddings, note tagging and forgetting.
- Maintenance tier: vault health, thread rotation, clean-up, the disk watchdog and SQLite vacuum.
- Beside the scheduler run the agent worker, which triages inbound events and email, and the machine profile, which records the host CLIs in MACHINE.md.
- DAEMON-STATUS.md at the vault root is written after every tick.
05
Chat relays
Discord and Telegram are built into hq-relay as feature-gated bridges behind one
unified bot. They share commands and watch firing, so behavior matches. Send !cancel
in either and the agent stops at the next tool boundary and replies with a summary of turns and
files touched. A heartbeat message shows the turn count and the tool currently running.
Chat bridges are gated to an owner. Run hq pair, then send
/pair <code> in a private Telegram chat or !pair <code> in a
Discord DM. Earlier versions let the first sender become the owner. That was changed because it
hands the agent to whoever messages first.
Turns that outlive the chat
A turn has an ack window, 270 seconds by default. If the turn runs longer, the chat gets an
immediate acknowledgement and the session detaches into a persisted background_turns
table, then delivers its result when it finishes. A reconciler runs at daemon start and every 6
hours. It marks rows that were running when something died as interrupted, offers a
resume <id>, and retires rows older than five days.
/watch <minutes> [for <N>h] <prompt> stores a durable recurring
turn in the same table, so watches survive restarts. A reply containing WATCH_DONE
delivers once and stops the watch.
Session limits
Sessions have no turn-count ceiling. They end on completion, cancellation, an optional USD budget cap, or a wall-clock limit that defaults to five hours.
background_turns
Result delivered to the chat
Full diagram and text description
Text description of this diagram
- Discord and Telegram connect to the hq-relay crate, the unified bot, which handles cancel, background turns and watches.
- The web PWA connects to hq-web over a WebSocket and REST.
- The terminal chat (hq chat) runs the agent in process.
- All four paths reach one agent session in hq-agent, which reads and writes one vault holding the shared thread history and memory.
06
The web PWA
The Control Center is a React 19 app on TanStack Start and Vite, built to a static single-page
bundle. hq start all serves it from :5678 along with the REST API and the
chat socket, from web/dist next to the vault or the directory in
web_static_dir. There is no separate web server process.
It streams the agent live, browses and searches the vault, shows daemon status, runs the tasks views, lists and drives sessions, renders DOCX, XLSX and PDF, and takes push notifications. It installs on a phone like any PWA.
Auth in the browser
The server binds to 127.0.0.1 by default. With web_auth_token set, the
token is accepted only as a Bearer header, never in a URL. A browser cannot set headers on a
WebSocket, so the app asks POST /api/ws-ticket for a ticket that works once, lasts 30
seconds and opens only /ws. An origin guard refuses requests from origins that are not
loopback, not the server's own and not listed in web_allowed_origins, which also stops
DNS rebinding. The response CSP has no unsafe-eval and no script
unsafe-inline, and remote images are blocked on purpose, because an image URL is a way
to send data out of a rendered note. Details: web and MCP auth.
Bearer
TicketPOST /api/ws-ticket
Single use30 s
Chat socket/ws
07
The MCP server and the two-tool gateway
HQ is an MCP server so the agents you already use can reach your vault, tasks and sessions. A
client always sees exactly two tools. hq_discover searches the registry by keyword
and returns matching tools with their descriptions. hq_call runs a tool by name with
JSON input. The registry behind them holds about a hundred tools, and a client that calls
hq_discover at runtime always sees the live list.
hq mcp install --target claude-code writes the client config for Claude Code, Claude
Desktop, Cursor, VS Code, Copilot, OpenCode, Antigravity or a project file, and
hq mcp doctor checks the connection.
Keys and scopes
Over HTTP, /mcp refuses every call unless a key is configured. There are three scopes.
A full key sees everything. A read-only key sees an allowlist. A handoff key gets that read-only
set, minus session logs, plus filing tasks, starting sessions and asking questions in read-only
mode, and nothing else. The gateway sets the scope itself, so a client cannot claim a wider one.
Treat the handoff key as the power to start a coding agent anywhere you allow it, and set
agent_host.handoff_cwd_allow to bound where.
Both directions
HQ also bridges remote MCP servers. Each remote_mcp: entry becomes a
<name>_discover and <name>_call pair in the registry, kept out
of unattended sessions by default. From outside, hq_ask lets an MCP client put a
question to HQ's own chat agent, in an ordinary web thread you can open and continue
(docs).
hq_discoverhq_call
Registry, about 100 tools
Full diagram and text description
Text description of this diagram
- MCP clients such as Claude Code, Cursor, VS Code, Copilot and OpenCode connect over stdio (hq mcp-serve) or over HTTP at /mcp. HTTP needs an API key and refuses requests without one.
- The gateway exposes exactly two tools: hq_discover and hq_call.
- Behind it sits the tool registry of about 100 tools: vault, tasks, harness sessions, sub-agents, web and more.
- Remote MCP servers listed under remote_mcp in the config are bridged into the registry as name_discover and name_call.
08
The built-in host and supervised coding-agent sessions
HQ's built-in host (hq host) owns the terminals. It recognises which coding agent sits
in a pane and reports its state: idle, working, blocked on a dialog, or done. HQ drives it over a
local socket. Claude Code, Codex, Cursor, Pi, OpenCode, Copilot CLI, Kimi, Qwen and Antigravity are
supported harnesses, and you can define your own profiles. This replaced an earlier tmux runner
that could only guess state from screen text.
Personal agents
Hermes Agent and OpenClaw run in the same host as a second kind of harness, general-purpose agents.
Every session has a purpose (research, review, monitor or general), and a request to give one code
work is refused before anything starts. They get no HQ token and no MCP wiring: HQ types into them
and reads their screen as untrusted text. Named in a stack: block, each pulls the tasks
assigned to it and runs one as a single job, and the process ending puts the task into review. Setup
and removal are in the personal agents guide.
Hosts
A host is a machine running hq host. native is the machine HQ runs on. Any
other host is a machine you paired with hq host join and is reached over ssh with a
dedicated key that is pinned to one source address and to a forced command,
hq host gate, which accepts one request as JSON on stdin and refuses every method
outside an allowlist. Agents run in a process sandbox. The default profile, open, walls
off only HQ itself: the host's tokens, ~/.hq, other processes' environments, other
agents' logins and, unless you turn it off, your credential stores. strict adds an
egress allowlist and read and write allowlists. That is how HQ on a
VPS can run and watch agents on a laptop, whenever the laptop is on and reachable. Connections are
reused between calls, and a write is never retried because the gate may already have run it.
Spawning and watching
harness_session_spawn starts an agent and returns a session id. Send, wait, logs,
status, stop and resume sit beside it, and hq sessions mirrors them in the CLI. A
supervisor in the daemon polls every host once a minute. It alerts once when a session blocks and
once when an agent finishes a turn. A host that cannot be reached counts as unknown, never as
exited: a sleeping laptop leaves its sessions running and they are watched again when it answers.
HQ does not answer dialogs for you. Claude Code's workspace-trust prompt defaults to "No, exit", so pressing Enter would quit it. A blocked launch is reported with the screen, and you answer with explicit keys.
Sessions that work on a task
A session can be linked to a task. Each event leaves a task comment, and the task moves from in progress to ready for review or blocked as the session finishes or exits. By default HQ never marks a task complete, because an agent saying it is done is not verification. With task verification turned on (it is off by default), HQ completes a task only from evidence the agent could not have written, such as a merged pull request with green checks, and measures how often it is wrong. Comments never quote the pane, since pane text is untrusted input.
Handoff
harness_session_handoff lets an outside client, such as another agent over MCP, start
tracked work in one call. It files or reuses a task by an idempotency key, starts one linked
session with the acceptance criteria as its definition of done, and opens a chat thread that owns
the session. It is idempotent: the same key returns the same task, and a task that already has a
running session gets no second one.
Watching and driving from a web chat
A chat can watch a session. Watching posts short updates and never quotes the screen. Driving lets HQ act as the session's project manager: read the session, send the next instruction, approve a permission prompt or resume an exit, toward the linked task's goal. It asks you instead when a step is destructive, touches credentials, deploys or spends money. A new watch starts with Drive on only when the task gives it a usable goal, and observation-only otherwise. A turn that has read untrusted content starts new watches with Drive off, and a tool can never turn it back on once you switched it off. Mechanical limits cut it off without relying on the model: an instruction budget per session, a cap on key presses, a no-progress guard, and a cap on sessions driven at once. Each one switches Drive off and says why. The Sessions page shows every session with its task, host, goal and live state.
Full reference, including setup and troubleshooting: docs/AGENT_SESSIONS.md.
codex is waiting on a trust prompt. HQ tells you and never answers it for you.
claude-coderunningcodexblockedopencodedone
Full diagram and text description
Text description of this diagram
- On the HQ side: the harness_session tools start and steer sessions, the supervisor polls each host once a minute, the registry holds one row per session, and task comments and chat updates report what happens.
- Local host: HQ calls the host over its local socket. The host owns the panes where the coding agents run, for example Claude Code, Codex, OpenCode, Cursor, Copilot CLI, Kimi and Qwen.
- Remote host, for example a laptop: HQ connects over ssh with a dedicated key that is restricted to one forced command, the gate. The gate passes only the host API. The host then runs the agents in a sandbox.
- If a remote host sleeps or leaves the tailnet, its sessions stay running and watching resumes when it answers.
09
Tasks
Tasks are native, with no external tracker to mirror. The model is spaces, then initiatives, then
tasks, then comments, with sub-tasks, start dates and soft dependencies. One shared write surface
in hq-db backs the MCP tools (task_list, task_create,
task_update, task_comment_add and friends), the REST API with its
WebSocket broadcast, the web UI with list, board and timeline views, and hq task in the
CLI.
Tagging a task routes it to an agent mailbox synchronously. A person's tasks live in a private space that only that person's turns can read. See the design note, and docs/TASK_VERIFICATION.md for the opt-in verification.
10
Governance and the bash sandbox
The agent's bash tool runs model-written shell commands, so HQ does not rely on the
model refusing. A governance layer denies dangerous effects mechanically, before a tool runs, and it
applies in permissive modes too.
Credential files such as ~/.ssh, cloud credentials and the HQ config are unreachable
always. A session becomes tainted once a tool returns untrusted content: web fetch and search, mail,
converted documents, other agents' mailboxes, session logs, pane reads, vault reads and any remote
MCP result. Taint is shared with every sub-agent the session spawns, so delegating cannot launder
it. After taint, project secrets such as .env files and outbound network from bash
(curl, ssh, nc and similar) are denied.
For bash, three layers follow. Text checks catch honest mistakes and cheap tricks, but about 100
known obfuscation shapes are pinned in tests and some still get through, so they are speed bumps.
An environment allowlist starts the child with an empty environment and a short list of variables.
HQ's own keys are refused even if you list them. Then the OS sandbox: bubblewrap on Linux,
sandbox-exec on macOS. On Linux it gives a read-only root, a fresh /proc
in a new pid namespace, writable binds only for home, the working directory, temp and the vault, and
optionally no network. Config, env files and private SSH keys are masked.
governance.bash.sandbox takes off, best_effort or
required. After 0.9.0 the default is required: if no sandbox backend
works, every bash command is refused and hq doctor says so.
What this does not cover is on the security page.
Full diagram and text description
Text description of this diagram
- Row one, governance, runs for every tool call. 1 The model proposes a tool call, possibly steered by untrusted content. 2 Credential rules refuse SSH keys, cloud credentials and HQ config always. 3 The taint tracker marks a session once it has read untrusted content such as web pages, mail, documents or notes. 4 After taint, secret files and outbound network from bash are denied.
- Row two applies to the bash tool. 5 Text checks catch honest mistakes and cheap tricks but are not the boundary. 6 The environment allowlist starts the child with an empty environment plus a short list. 7 The OS sandbox is bubblewrap on Linux and sandbox-exec on macOS. 8 The command runs with secret files masked.
11
The signed release and pull-updater pipeline
A server instance pulls its updates. Nothing on the build side holds a credential for any instance, and instances hold only a public key.
Build side
Every merge to main runs tests, builds on an older Ubuntu image so the binary needs
only an older glibc, and publishes a signed prerelease named like 0.9.1-main.6. The job
that runs repository build code never sees the signing key: a separate sign job does. Each release
carries a binary archive per platform (Linux x86_64, Linux ARM, Apple Silicon and, since
0.9.1-main.243, Intel macOS), the web bundle,
SHA256SUMS, a manifest.json and its .minisig. Channel pointers
(channel-main, channel-stable) are small signed JSON files that say which
release a channel currently means. Promoting to stable signs a new pointer for an existing release.
Nothing is rebuilt.
Instance side
- A systemd timer fires every 10 minutes with a short random delay and runs
hq update --applyunder an exclusive lock. - It verifies the pointer signature, checks that the manifest URL lives under the configured repository, then verifies the manifest signature and its SHA-256, the schema and the minimum updater version.
- Equal or lower versions do nothing. A pointer with a lower sequence number than one already accepted is refused as a replay.
- It downloads with hard size caps, verifies each artifact's SHA-256 against the signed manifest, and unpacks with a strict tar reader that rejects links, devices, absolute and parent paths and duplicates.
- It snapshots the vault database with
VACUUM INTO, as the service user, never as root. - It runs the staged binary as the service user with
--versionand requires the exact build. This is the only downloaded code that runs before the swap. - It swaps the binary and web files by rename, keeping the last three binaries and one old web tree, restarts the service and polls
/healthuntil it reports the new git sha. - On success it runs
hq install --upgrade. On failure it rolls back, restores the database only if migrations ran, blocks that version for 24 hours and sends an alert. A crash mid-update is recovered from a journal on the next run.
Signatures are minisign (Ed25519), verified in process. The key is read from a root-owned file or compiled in, and cannot be overridden by an environment variable. Key rotation is a manual step. A compromised signing key and a stale-pointer freeze attack are listed as not mitigated. Read docs/UPDATE_SYSTEM.md for the contract.
- 1Timer fires every 10 minutes, under a lock
- 2Verify pointer and manifest signatures
- 3Refuse equal, lower or replayed versions
- 4Download with size caps, check SHA-256
- 5Snapshot the vault database
- 6Run the staged binary's --version
- 7Swap by rename, wait for /health
- 8Upgrade, or roll back and alert
Full diagram and text description
Text description of this diagram
- Build side: a merge to main triggers tests, then a build job with no secrets, then a sign job that is the only place the signing key lives, then a GitHub release with the binary, web files, manifest.json and its minisign signature, plus a signed channel pointer.
- Instance side, in order: a systemd timer starts the updater every 10 minutes. It verifies the channel pointer signature and the manifest signature and hash. It downloads artifacts and checks SHA-256 and archive safety. It snapshots the database with VACUUM INTO. It runs the staged binary with --version as the service user and checks the build. It swaps the binary and web files by rename. It restarts the service and polls /health for the new git sha.
- Outcome: on success it runs hq install --upgrade. On failure it rolls back the binary, web files and, if needed, the database, blocks that version for 24 hours and sends an alert.
- The instance pulls from the release over HTTPS. The build side never connects to the instance.
12
Deployment topologies
Laptop only. Run hq start all. The web server binds to loopback. Set
web_auth_token on a shared machine. This is the default and needs no network setup.
VPS plus Tailscale. Provision a Debian or Ubuntu box with
deploy/setup-vps.sh, install the signed updater with deploy/install.sh,
and keep HQ on loopback. Caddy bridges to tailscale serve, which terminates HTTPS on
your tailnet only, so the UI never touches the public internet. List every origin you serve the UI
from in web_allowed_origins. HQ on the VPS can then drive the host on a laptop over the
gated ssh key.
Docker. The image ghcr.io/calvinmagezi/hq is assembled from the same
signed release artifacts as the install script, for linux/amd64 and
linux/arm64, and runs as a non-root user with its state under /data. See
docs/DOCKER.md.
Windows. Full HQ runs inside WSL2. On a computer that blocks WSL2, HQ Lite runs natively as one program with no administrator rights: the web app, tasks, notes and search, without coding agents, chat bots or the sandbox. See docs/WINDOWS.md and docs/HQ_LITE.md.
An Android phone (developer preview). The mobile profile is Full HQ for
a machine with no shell sandbox, no git and no self-updater, plus a data saver. The APK
is one you build yourself from apps/android. It is not yet verified that a sleeping,
unplugged phone answers in time. See docs/HQ_MOBILE.md
and apps/android/README.md.
A device behind NAT, with hq edge. A public forwarder you run yourself
on a machine you control. It reads only the TLS server name, never decrypts, and passes the bytes
to the registered device over an iroh stream. TLS ends on the device, which holds its own
certificate. It is off by default and there is no project-run edge. See
docs/EDGE.md.
A private network, with hq net. A WireGuard hub on a Linux server and
your own devices as spokes, so the web UI, /mcp and the host gate are reachable only
from devices you admitted. Release builds do not include the root applier yet, so that step builds
it from source. See docs/PRIVATE_NETWORK.md.
Two shapes publish anything. A plain MCP endpoint goes through a proxy that exposes
/mcp and /health and nothing else, with an API key set. The claude.ai
connector publishes /mcp, /oauth/token, /oauth/revoke and the
/.well-known/oauth-* metadata documents, and the consent page stays private
(docs/CLAUDE_CONNECTOR.md,
deploy/Caddyfile.connector). /ws
and /api must never be public. A host runs one deploy path only: the pull updater, or a
manual build, not both. Steps are on the install page and in
deploy/README.md.
/mcp and /health with a key, or the connector's OAuth paths.
Full diagram and text description
Text description of this diagram
- Laptop only: a browser or terminal talks to hq bound to 127.0.0.1 on port 5678. hq reads and writes the vault on disk and drives the built-in host with coding agents.
- VPS plus Tailscale: a device on your tailnet reaches tailscale serve, which terminates HTTPS on the tailnet. It forwards to Caddy bound to 127.0.0.1:4749, which forwards to hq on 127.0.0.1:5678. The updater timer pulls signed releases. HQ can drive the host on a laptop over a restricted ssh key.
13
Source map
Where to start reading, relative to the repository.
| Area | Path |
|---|---|
| CLI binary | crates/hq-cli/src/main.rs |
| Agent session | crates/hq-agent/src/session/mod.rs |
| Context engine | crates/hq-agent/src/context/engine.rs |
| Daemon scheduler | crates/hq-cli/src/commands/start/daemon/mod.rs |
| MCP server | crates/hq-mcp/src/server.rs |
| The host driver | crates/hq-tools/src/agent_host/ |
| Harness sessions | crates/hq-tools/src/harness_session/ |
| Bash sandbox | crates/hq-agent/src/bash_sandbox.rs |
| Governance rules | crates/hq-agent/src/governance/ |
| Updater library | crates/hq-update/ |
| Web auth and origin guard | crates/hq-web/src/auth.rs |
| Native tasks | crates/hq-db/src/tasks.rs |