@tkfka1/hkclaw
v1.2.12
Published
Personal Claude assistant. Lightweight, secure, customizable.
Readme
HKClaw
Dual-agent AI staff platform for Discord. HKClaw runs multiple Claude Code and Codex workers from one repository, one database, and one host, then exposes an admin web for staffing, routing, and service operations.
Korean version: README.kr.md
Originally derived from qwibitai/nanoclaw. Prompt design was also influenced by Q00/ouroboros.
What HKClaw Is
HKClaw treats each bot as a managed "staff member".
- One running bot = one service process.
- Each service has a unique
SERVICE_ID. - Each service chooses one model family with
SERVICE_AGENT_TYPE. - Each service declares one usage role with
SERVICE_ROLE. - All services share the same codebase and SQLite database, but runtime state is partitioned by
SERVICE_ID.
That lets you run layouts such as:
hkclaw: the primary assistanthkclaw-codex: a separate Codex workerhkclaw-dashboard: a dashboard-only operator servicehkclaw-ops,hkclaw-finance,hkclaw-map,hkclaw-dev: additional role-specific bots
For a lower-level service model reference, see docs/service-concepts.md.
Core Runtime Model
HKClaw has three main axes:
SERVICE_ID: concrete runtime identity, state partition key, and service name suffixSERVICE_AGENT_TYPE: model family, currentlyclaude-codeorcodexSERVICE_ROLE: operational role, with one hard split betweendashboardand normal interactive workers
Practical consequences:
- Two Claude-based bots can run side by side without sharing session history.
- A dashboard service is operationally different from a chat worker.
- Admin-facing labels such as
chatandassistantare accepted, but current runtime normalizes them to the normal worker role. - Voice is not a separate role. Voice is a capability enabled by
DISCORD_VOICE_*. - Every service is generated from
.envplus one overlay file.
Install and Operating Account
Recommended Host
HKClaw is designed for:
- Linux, including WSL Ubuntu on Windows
- macOS
Windows-native service management is not a first-class target. If you are on Windows, run HKClaw inside WSL Ubuntu.
Which OS Account Should Install It
Install and run HKClaw from a dedicated operating-system account whenever possible.
Examples:
- personal lab: your own non-admin Linux or macOS account
- shared machine: a dedicated
hkclaworops-botaccount - Windows host: a dedicated WSL user
Do not think of the bots as isolated from the installing account. They are not.
Security Boundary: Host Account
All generated services run as the installing OS user:
- Linux:
systemctl --user - macOS: user
LaunchAgents - fallback Linux without systemd: repo-local
nohupwrappers
That means every HKClaw bot inherits that user's machine-level access:
- files readable by that OS account
- SSH keys and Git credentials available to that OS account
~/.claudeand~/.claude-accounts/*~/.codexand.codex-accounts/*- network access available to that OS account
- any shell commands the bot is allowed to execute
If you install HKClaw under a powerful personal account, every bot effectively operates with that account's machine permissions.
Recommended rule:
- use a dedicated, low-privilege OS account for HKClaw
- do not install under
rootunless you intentionally want system-wide privilege - keep sensitive host files outside the reach of the HKClaw account when possible
Security Boundary: Discord Bot Identity
Discord permissions are separate from host permissions.
- Host-side permissions come from the OS account that runs HKClaw.
- Discord-side permissions come from the bot token used by each service.
Important consequences:
- if two services reuse the same
DISCORD_BOT_TOKEN, they are the same Discord bot identity - if you want strict Discord permission separation, create a separate Discord application and bot token per service
- a service can only see and act in Discord where its bot token has been invited and granted permission
Installation
Prerequisites
- Node.js 20+ supported
.nvmrccurrently pins Node22- build tools for native modules (
gcc/makeon Linux, Xcode Command Line Tools on macOS) - Claude Code CLI
- Codex CLI
- Bun 1.0+ for browser-related workflows
Recommended First Boot: Admin-First
The recommended onboarding flow is:
- clone and build the repo
- start the bootstrap admin web
- open the admin page
- create Discord bot services from the admin UI
- let HKClaw write the env overlays and reconcile services for you
This means you do not need to hand-author .env.primary or .env.agent.* before first boot.
1. Clone and Build
git clone https://gitlab.com/el-psy/hkclaw.git
cd hkclaw
npm ci
npm run build:runners
npm run build2. Optional Minimal .env for Admin Bind Only
For admin-first boot, .env is optional.
If you want to control the bind address or port, create a minimal .env like this:
HKCLAW_ADMIN_HOST=0.0.0.0
HKCLAW_ADMIN_PORT=4622If you want the admin web to require a browser login, add bootstrap credentials:
HKCLAW_ADMIN_USERNAME=admin
HKCLAW_ADMIN_PASSWORD=change-this-before-exposing-the-portHKClaw uses these values to create or update the first admin account in SQLite, then signs in through the web login form with a session cookie. If HKCLAW_ADMIN_PASSWORD is unset, no admin account is bootstrapped.
If you skip .env, HKClaw still boots the admin service with defaults.
By default it binds the admin web on 0.0.0.0:4622, so you can also reach it from another machine at http://<host-ip>:4622/ if the host firewall/network allows it.
3. Start the Bootstrap Admin Service
npm run setup -- --step serviceIf no dashboard service is configured yet, HKClaw automatically creates a bootstrap admin service called hkclaw-admin.
What that bootstrap service does:
- serves the local admin web
- lets you create the first real services from inside the UI
- exists only until you create a real
dashboardservice
Generated targets:
- Linux user mode:
~/.config/systemd/user/hkclaw-admin.service - macOS user mode:
~/Library/LaunchAgents/com.hkclaw-admin.plist - Linux without systemd:
start-hkclaw-admin.sh
4. Open the Admin Web
By default:
http://localhost:4622/- external access:
http://<host-ip>:4622/
You can now do initial setup from the internal web instead of manually writing service files.
5. Prepare Auth and Bot Identities Under the Same OS Account
Before creating real worker services in admin, prepare the credentials that those services will use.
Discord side:
- create one Discord application per HKClaw service when you want strict separation
- generate a bot token for each one
- invite those bots only where needed
Claude side:
Claude services refresh tokens by reading that account's credential files:
~/.claude/.credentials.json~/.claude-accounts/{index}/.credentials.json
Typical setup:
claude setup-tokenFor additional Claude accounts:
CLAUDE_CONFIG_DIR=~/.claude-accounts/1 claude setup-token
CLAUDE_CONFIG_DIR=~/.claude-accounts/2 claude setup-tokenThen store access tokens per service with:
CLAUDE_CODE_OAUTH_TOKENCLAUDE_CODE_OAUTH_TOKENS
Codex side:
Codex uses OAuth-style auth materialized into session-local .codex/auth.json.
Per service, HKClaw resolves Codex auth in this order:
CODEX_AUTH_JSON_B64from the service overlay- the active rotated Codex account file
~/.codex/auth.jsonfrom the installing OS account
If you want full separation, give each service its own CODEX_AUTH_JSON_B64. If you do not, the service inherits the installing account's Codex login context.
Recommended Discord capabilities:
- text rooms:
View Channel,Send Messages,Read Message History,Attach Files - voice rooms:
View Channel,Connect,Speak - gateway intents:
Guilds,GuildMessages,GuildVoiceStates,DirectMessages Message Contentintent is strongly recommended for natural text handling
HKClaw will retry without the Message Content intent if Discord rejects it, but the normal operating mode expects it.
6. Create Real Services from the Admin Web
From the admin page:
- create a worker or dashboard service
- paste the Discord bot token
- set Claude or Codex auth values
- choose the model family
- optionally configure voice listen / speak settings
- save the service
When you save from admin, HKClaw:
- writes
.env.primaryor.env.agent.<service_id> - synchronizes the initial assignment if a team channel is provided
- reruns service discovery
- rewrites service-manager units
- starts or restarts the affected services
This is the important point:
- the admin UI is the recommended authoring surface
- env overlays are still the underlying source of truth for service identity and secrets
- the database is not the secret store
7. Assign Teams and Channels from the Admin Web
After services exist:
- use
Team Chartto map Discord rooms to services - use office teams for organization-level teams such as HR, management, or general affairs
- use Discord-linked teams for project rooms
- use
HKClaw Officeto verify placement and status visually
8. Optional: Replace Bootstrap Admin with a Real Dashboard Service
If you create a real service with SERVICE_ROLE=dashboard, that service becomes the long-term admin and dashboard owner.
At the next reconcile:
- the bootstrap
hkclaw-adminservice is no longer needed - the real dashboard service takes over the admin web and status rendering
9. Useful Commands
Useful commands:
systemctl --user status hkclaw-admin
systemctl --user restart hkclaw-admin
systemctl --user status hkclaw hkclaw-codex hkclaw-dashboard
systemctl --user restart hkclaw hkclaw-codex hkclaw-dashboard
journalctl --user -u hkclaw-admin -f
journalctl --user -u hkclaw -f
journalctl --user -u hkclaw-codex -f
journalctl --user -u hkclaw-dashboard -fIs .env Required?
Short answer:
.envis not required just to boot the admin web.env.primaryand.env.agent.*are not required before first boot- but HKClaw is not a DB-only configuration model
What lives where:
- env / process env: service identity bot tokens Claude / Codex auth provider keys voice and TTS settings
- SQLite database: chats messages team definitions channel assignments sessions scheduled tasks dashboard state
In other words:
- the database stores runtime and organizational state
- env overlays store secrets and process boot configuration
- the admin UI creates those env overlays for you
Optional Manual Overlay Management
If you prefer to manage services by hand instead of using admin-first setup, HKClaw still supports manual overlay files.
Examples:
# .env.primary
ASSISTANT_NAME=claude
SERVICE_ID=claude
SERVICE_AGENT_TYPE=claude-code
SERVICE_ROLE=assistant
DISCORD_BOT_TOKEN=
CLAUDE_CODE_OAUTH_TOKEN=
CLAUDE_CODE_OAUTH_TOKENS=
# .env.agent.codex
ASSISTANT_NAME=codex
SERVICE_ID=codex
SERVICE_AGENT_TYPE=codex
SERVICE_ROLE=chat
DISCORD_BOT_TOKEN=
CODEX_AUTH_JSON_B64=
CODEX_MODEL=gpt-5.4
CODEX_EFFORT=high
OPENAI_API_KEY=
GROQ_API_KEY=Env layering:
.env: shared defaults.env.primary: primary service.env.agent.<service_id>: additional services.env.codex: legacy compatibility overlay
Role note:
dashboardis the only special execution role- admin labels such as
chatandassistantcurrently normalize to the normal worker runtime
Admin Web and "HR" Menus
The dashboard service exposes the local admin web. In practice, this is the operations and staffing console.
The main sections are:
Hiring Board: create and update servicesTeam Chart: map Discord channels to servicesHKClaw Office: visualize teams, staff placement, and status
Hiring Board Categories
Think of the service form as an HR-plus-ops form. These settings belong to six logical buckets.
| Category | Main fields / env keys | Purpose |
| --- | --- | --- |
| Identity and topology | ASSISTANT_NAME, SERVICE_ID, SERVICE_AGENT_TYPE, SERVICE_ROLE, STATUS_CHANNEL_ID, USAGE_DASHBOARD | Defines what the service is and whether it behaves like a worker or dashboard |
| Discord identity | DISCORD_BOT_TOKEN | Chooses which Discord bot account the service uses |
| Listen / speech-to-text | DISCORD_VOICE_CHANNEL_IDS, DISCORD_VOICE_TARGET_JID, DISCORD_VOICE_SESSION_JID, DISCORD_VOICE_ROUTE_MAP, DISCORD_VOICE_GROUP_FOLDER, DISCORD_VOICE_GROUP_NAME, DISCORD_VOICE_RECONNECT_DELAY_MS, DISCORD_LIVE_VOICE_SILENCE_MS, DISCORD_LIVE_VOICE_MIN_PCM_BYTES, DISCORD_GROQ_TRANSCRIPTION_MODEL, DISCORD_OPENAI_TRANSCRIPTION_MODEL, DISCORD_TRANSCRIPTION_LANGUAGE | Controls voice room auto-join, live listening, transcript routing, and STT provider behavior |
| Speak / text-to-speech | DISCORD_EDGE_TTS_RATE, DISCORD_EDGE_TTS_VOICE, DISCORD_EDGE_TTS_LANG, DISCORD_EDGE_TTS_OUTPUT_FORMAT, DISCORD_EDGE_TTS_TIMEOUT_MS, DISCORD_EDGE_TTS_MAX_CHARS, DISCORD_VOICE_OUTPUT_BITRATE | Controls how the bot speaks back into voice rooms |
| LLM auth and provider | ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN, CLAUDE_CODE_OAUTH_TOKEN, CLAUDE_CODE_OAUTH_TOKENS, CODEX_AUTH_JSON_B64, OPENAI_API_KEY, GROQ_API_KEY, CODEX_MODEL, CODEX_EFFORT | Controls model login and provider-specific runtime behavior |
| Fallback and resilience | FALLBACK_ENABLED, FALLBACK_PROVIDER_NAME, FALLBACK_BASE_URL, FALLBACK_AUTH_TOKEN, FALLBACK_MODEL, FALLBACK_SMALL_MODEL, FALLBACK_COOLDOWN_MS | Lets Claude services fall through to another provider after rate limits or provider failures |
Team Chart
Team Chart is the staffing matrix.
- Rows are Discord rooms.
- Columns are services.
- Assigning a cell creates or removes a
registered_groupfor that service and room. - Dashboard services do not take normal team assignments.
- Status-dashboard assignment is special and comes from
STATUS_CHANNEL_ID.
This is where a project room becomes an actual working room for a bot.
HKClaw Office
HKClaw Office is the visual floor map.
- services are rendered like workers
- mapped or active Discord rooms appear like teams or desks
- stopped services move to the offsite area
- idle services move to the lounge
- new service creation is represented as hiring
This view is operational, not merely decorative. It summarizes staffing and room activity from discovered services and assignments.
Office Map Assets
The office map system stores assets in admin-assets/.
Relevant files:
- office map
.tmj - Tiled project file
- tileset image
- generated metadata in
admin-assets/hkclaw-office-map-meta.json
This area is a good fit for a "General Affairs" or map-management team.
Team Model
HKClaw supports two practical team concepts.
1. Base Teams
Base teams are manually defined office teams. They are organizational units first, Discord bindings second.
Typical examples:
management: executive or leadership roomsgeneral-affairs: office layout, map assets, naming, room presentationhr: hiring, retirement, staffing changesdevops: CI, deployment, operations roomsfinance,legal,sales,support: domain teams as needed
These names are operating conventions, not hardcoded system roles.
2. Project Teams
Project teams are Discord-linked working rooms.
In code terms, a project team is usually a team with a linkedJid, or an auto-derived channel-backed team inferred from active assignments.
Examples:
- a Discord text channel for a live product project
- an operations war room
- a voice room mirrored into a text room
- a client-specific working channel
Recommended Organizational Pattern
One practical pattern is:
Management: owns high-trust planning and decision channelsGeneral Affairs: owns office map, room naming, and dashboard presentationHR: owns service creation, bot retirement, and assignment changesProject teams: own the day-to-day Discord working rooms
Again, this is a recommended operating model. HKClaw does not force these names.
How Team Creation Works
Manual Team Creation
When you create a manual office team, HKClaw stores:
teamId- display name
- optional
linkedJid - optional group folder
- whether mention is required
- optional layout and color
Manual teams are the right model for base organizational teams such as management, general affairs, and HR.
Discord-Linked Team Creation
When a team is linked to a Discord room:
linkedJidbecomes the channel binding- the team folder can become the default runtime folder for assigned groups
requiresMentioncan be pushed into all existing assignments on that room- if the linked room changes, assignments can move with it
Auto-Derived Channel Teams
If a Discord room has active assignments or active service presence but no explicit manual team, HKClaw can still surface it as a channel-backed team in admin state.
This is useful for project rooms created from actual work before formal org modeling is added.
How Service Creation Works
When you create or update a bot from admin:
- HKClaw validates the request.
- It normalizes
SERVICE_ID,SERVICE_AGENT_TYPE, andSERVICE_ROLE. - It writes
.env.primaryor.env.agent.<service_id>. - If an initial team channel is provided, it creates or syncs the service assignment.
- It synchronizes the expected trigger, usually
@<assistantName>. - It runs topology reconcile.
- Topology reconcile calls
npm run setup -- --step service. - Service discovery rescans
.env.primary,.env.agent.*, and legacy.env.codex. - HKClaw rewrites service-manager units and starts or restarts the affected services.
Important service rules:
- dashboard services require
STATUS_CHANNEL_ID - dashboard services do not hold normal team assignments
- renaming an existing
SERVICE_IDis not supported in place; create a new service instead
Voice Model: Listen and Speak
HKClaw treats voice as an extension of the normal message pipeline.
Listen
Voice listening is controlled by the DISCORD_VOICE_* and transcription settings.
Flow:
- a configured voice room becomes active
- the Discord client joins that room
- voice packets are buffered
- silence detection cuts a segment
- STT runs through Groq or OpenAI
- the transcript is turned into a synthetic text message
- the normal worker pipeline continues
Speak
Voice speaking is controlled by the DISCORD_EDGE_TTS_* settings.
Flow:
- a worker finishes a response
- HKClaw decides whether the room expects voice playback
- Edge TTS synthesizes audio
- ffmpeg converts it into Discord-friendly output
- the service plays the spoken reply in the voice room
Authentication and Provider Notes
Claude
- per-service env:
CLAUDE_CODE_OAUTH_TOKEN,CLAUDE_CODE_OAUTH_TOKENS - refresh source: the installing OS user's
~/.claude*credentials - auto-refresh writes refreshed access tokens back into that service overlay
Codex
- per-service env:
CODEX_AUTH_JSON_B64 - if not set, HKClaw inherits the installing OS user's active Codex auth
- host
~/.codex/config.tomlandconfig.jsonare copied into session-local.codex/
Transcription Providers
- primary STT can come from
GROQ_API_KEY - fallback STT can come from
OPENAI_API_KEY - language can be pinned with
DISCORD_TRANSCRIPTION_LANGUAGE
Provider Fallback
Claude-oriented services can fail over to another Anthropic-compatible endpoint with FALLBACK_* values.
Development
npm run build
npm run build:runners
npm run dev
npm testLicense
MIT
