@k-msg/cli
v0.7.0
Published
k-msg CLI (prebuilt binaries via GitHub Releases)
Downloads
1,662
Readme
k-msg CLI (apps/cli)
This CLI is built with Bunli and uses the unified k-msg package (KMsg + Providers).
Install (recommended)
npm
npm install -g @k-msg/cli
# or: pnpm add -g @k-msg/cli
k-msg --helpNote: the npm package downloads a native binary from GitHub Releases on first run
(bunli build:all artifacts: k-msg-cli-<version>-<target>.tar.gz), verifies it
using checksums.txt, then extracts and caches it under your OS cache directory
(K_MSG_CLI_CACHE_DIR to override).
Env overrides:
K_MSG_CLI_BASE_URL: override GitHub release base URL (default:https://github.com/k-otp/k-msg/releases/download/cli-v<version>)K_MSG_CLI_CACHE_DIR: override where the extracted binary is cachedK_MSG_CLI_LOCAL_BINARY: copy a local binary instead of downloading (useful for local testing)
curl installer (GitHub Pages)
curl -fsSL https://k-otp.github.io/k-msg/cli/install.sh | bashInstaller environment variables:
K_MSG_CLI_VERSION: override target version (default: latest Pages script version)K_MSG_CLI_INSTALL_DIR: target directory (default:~/.local/bin)K_MSG_CLI_BASE_URL: override release base URL (default:https://github.com/k-otp/k-msg/releases/download/cli-v<version>)
GitHub Releases (manual)
The distribution workflow also publishes prebuilt binaries to GitHub Releases as:
k-msg-cli-<version>-darwin-arm64.tar.gzk-msg-cli-<version>-darwin-x64.tar.gzk-msg-cli-<version>-linux-arm64.tar.gzk-msg-cli-<version>-linux-x64.tar.gzk-msg-cli-<version>-windows-x64.tar.gz
After extracting, you'll find the binary at <target>/k-msg (or <target>/k-msg.exe).
macOS/Linux
tar -xzf k-msg-cli-<version>-<target>.tar.gz
sudo install -m 0755 <target>/k-msg /usr/local/bin/k-msg
# optional alias
sudo ln -sf /usr/local/bin/k-msg /usr/local/bin/kmsg
k-msg --helpWindows
Extract the archive and put k-msg.exe somewhere on your PATH.
Optionally copy it as kmsg.exe as an alias.
Run (local/dev)
# Generate command types
bun run --cwd apps/cli generate
# Build native binary
bun run --cwd apps/cli build
./apps/cli/dist/k-msg --help
# Build Bun-runtime JS bundle (optional)
bun run --cwd apps/cli build:js
bun --cwd apps/cli dist/k-msg.js --help
# Or run TS directly (dev)
bun --cwd apps/cli src/k-msg.ts --helpConfig (k-msg.config.json)
Default config path:
- macOS/Linux:
${XDG_CONFIG_HOME:-~/.config}/k-msg/k-msg.config.json - Windows:
%APPDATA%\\k-msg\\k-msg.config.json - Fallback:
./k-msg.config.json(used when home path file does not exist)
Override:
k-msg providers list --config /path/to/k-msg.config.jsonNote: --config is a subcommand option in the current CLI (for example: providers, sms, alimtalk).
Example file: apps/cli/k-msg.config.example.json
Schema URLs:
- Latest:
https://raw.githubusercontent.com/k-otp/k-msg/main/apps/cli/schemas/k-msg.config.schema.json - Versioned (
v1):https://raw.githubusercontent.com/k-otp/k-msg/main/apps/cli/schemas/k-msg.config.v1.schema.json
Initialize config:
# default: interactive wizard (TTY)
k-msg config init
# force full template (also auto-used in non-interactive environments)
k-msg config init --template full
# add providers incrementally
k-msg config provider add
k-msg config provider add iwinvenv: substitution
Any string value like "env:NAME" is replaced with the NAME environment variable at runtime.
If the env var is missing/empty, commands that need runtime providers will fail with exit code 2.
Provider send value guide
When you are unsure which values must be prepared before send, use this checklist:
- Configure provider credentials with
env:references. - Run
k-msg providers doctorto verify account/config readiness. - For AlimTalk, run
k-msg alimtalk preflightwith the provider/template/channel you will use. - Send only after preflight passes.
Credential examples:
# Aligo
export ALIGO_API_KEY="..."
export ALIGO_USER_ID="..."
export ALIGO_SENDER_KEY="..." # Kakao senderKey
export ALIGO_SENDER="029302266" # SMS/LMS sender
# IWINV
export IWINV_API_KEY="..." # AlimTalk key
export IWINV_SMS_API_KEY="..." # SMS/LMS/MMS key
export IWINV_SMS_AUTH_KEY="..." # SMS/LMS/MMS secret
export IWINV_SMS_COMPANY_ID="..." # status/balance context
export IWINV_SENDER_NUMBER="029302266"
# SOLAPI
export SOLAPI_API_KEY="..."
export SOLAPI_API_SECRET="..."
export SOLAPI_DEFAULT_FROM="029302266"
export SOLAPI_KAKAO_PF_ID="..." # Kakao profileId(pfId)Required values by provider/channel:
| Provider | Channel | Required config keys | Required send-time values | Notes |
| --- | --- | --- | --- | --- |
| aligo | SMS/LMS/MMS | apiKey, userId | to, text, sender (--from or aligo.config.sender) | MMS also needs image input |
| aligo | ALIMTALK | apiKey, userId | to, template-id, vars, senderKey (--sender-key/--channel alias/aligo.config.senderKey), sender (--from or aligo.config.sender) | preflight validates channel/template access |
| iwinv | SMS/LMS/MMS | apiKey, smsApiKey, smsAuthKey | to, text, sender (--from or iwinv.config.smsSenderNumber/senderNumber) | MMS requires image binary input |
| iwinv | ALIMTALK | apiKey | to, template-id, vars | If failover/reSend is enabled, sender callback is required (--from or sender number in config) |
| solapi | SMS/LMS/MMS | apiKey, apiSecret | to, text, sender (--from or solapi.config.defaultFrom) | MMS also needs image input |
| solapi | ALIMTALK | apiKey, apiSecret | to, template-id, vars, profileId/pfId (--sender-key/channel alias or solapi.config.kakaoPfId) | For preflight policy checks, set plusId via --plus-id or channel/default alias |
| mock | all | none | minimal message fields (to, text or template-id/vars) | Local test provider |
Commands
k-msg config init|show|validatek-msg config provider add [type]k-msg providers list|health|doctork-msg sms sendk-msg alimtalk preflight|sendk-msg send --input <json> | --file <path> | --stdin(advanced/raw JSON only)k-msg db schema print|generatek-msg kakao channel categories|list|auth|addk-msg kakao template list|get|create|update|delete|request
DB schema generator
Generate canonical SQL DDL and/or Drizzle schema source from the same
@k-msg/messaging/adapters/cloudflare schema utilities.
# Print both drizzle+sql to stdout
k-msg db schema print --dialect postgres
# Print only SQL for queue schema
k-msg db schema print --dialect postgres --target queue --format sql
# Generate both files in cwd
k-msg db schema generate --dialect postgres
# Generate SQL only to a custom path
k-msg db schema generate \
--dialect mysql \
--target tracking \
--format sql \
--out-dir ./db \
--sql-file tracking.sqlFlags:
--dialect <postgres|mysql|sqlite>: required--target <tracking|queue|both>: defaultboth--format <drizzle|sql|both>: defaultbothgenerateonly:--out-dir <path>default current directory--drizzle-file <name>defaultkmsg.schema.ts--sql-file <name>defaultkmsg.schema.sql--forcedefaultfalse(without it, generation fails if file exists)
Recommended AlimTalk flow
- Run provider-level diagnostics.
- Run AlimTalk preflight for the selected provider/channel/template.
- Run send after preflight passes.
k-msg providers doctor
k-msg alimtalk preflight --provider iwinv --template-id TPL_001 --channel main
k-msg alimtalk send --provider iwinv --template-id TPL_001 --to 01012345678 --vars '{"name":"Jane"}'Notes:
- For IWINV, Kakao channel onboarding is manual in vendor console. Keep the manual ack in config updated.
- For providers with
required_if_no_inference, preflight fails whenplusIdis missing and inference cannot resolve it.
Send
SMS
k-msg sms send --to 01012345678 --text "hello"AlimTalk
Terminology: the CLI uses Kakao Channel and senderKey (never “profile”).
k-msg alimtalk send \
--to 01012345678 \
--template-id TPL_001 \
--vars '{"name":"Jane"}' \
--channel main \
--plus-id @my_channelFailover options:
k-msg alimtalk send \
--to 01012345678 \
--template-id TPL_001 \
--vars '{"name":"Jane"}' \
--failover true \
--fallback-channel sms \
--fallback-content "Fallback SMS text" \
--fallback-title "Fallback LMS title"When providers return send warnings (for example failover partial/unsupported), CLI prints WARNING ... lines in text mode and includes them in --json output.
Preflight
k-msg alimtalk preflight \
--provider iwinv \
--template-id TPL_001 \
--channel main \
--sender-key your_sender_key \
--plus-id @my_channelpreflight runs onboarding checks (manual/config/capability/api probes) and template lookup before send.
Advanced JSON send
k-msg send is an advanced command for raw SendInput JSON (object or array).
For common workflows, prefer k-msg sms send and k-msg alimtalk send.
k-msg send --input '{"to":"01012345678","text":"hello"}'Single preview without sending:
k-msg send --input '{"to":"01012345678","text":"hello"}' --dry-runBatch preview without sending:
k-msg send --input '[{"to":"01011112222","text":"hello 1"},{"to":"01033334444","text":"hello 2"}]' --dry-runproviders doctor and send --dry-run have different roles:
k-msg providers doctor: provider/account/capability readiness checksk-msg send --dry-run: request payload preview/validation (no provider send)
Boolean flag semantics (applies to --json, --verbose, --dry-run, --stdin, --failover, --force):
--flag->true--flag true->true--flag false->false--no-flag->false- Invalid boolean values (for example
--dry-run maybe) fail with exit code2
Resolution precedence for overlapping values is:
CLI flag > environment variable > config file > built-in default
Kakao Channel (Aligo capability)
k-msg kakao channel categories
k-msg kakao channel list
k-msg kakao channel auth --plus-id @my_channel --phone 01012345678
k-msg kakao channel add \
--plus-id @my_channel \
--auth-num 123456 \
--phone 01012345678 \
--category-code 001001001 \
--save mainKakao Template (IWINV/Aligo)
Channel scope (Aligo): use --channel <alias> or --sender-key <value>.
k-msg kakao template list
k-msg kakao template get --template-id TPL_001
k-msg kakao template create --name "Welcome" --content "Hello #{name}" --channel main
k-msg kakao template update --template-id TPL_001 --name "Updated"
k-msg kakao template delete --template-id TPL_001
# inspection request is provider-dependent (supported by Aligo)
k-msg kakao template request --template-id TPL_001 --channel mainOutput / Exit Codes
--json: print machine-readable JSON- AI environments (Bunli
@bunli/plugin-ai-detect): JSON output is auto-enabled when an agent is detected (CLAUDECODE,CURSOR_AGENT,CODEX_CI/CODEX_SHELL/CODEX_THREAD_ID,MCP_SERVER_NAME/MCP_SESSION_ID/MCP_TOOL_NAME) - Force text output in AI environments with
--json false(or--no-json) - exit code:
0: success2: input/config error3: provider/network error4: unsupported capability (for example, provider does not supportbalance)
Manual Check Config Example
k-msg.config.json can store manual onboarding evidence used by doctor/preflight:
{
"onboarding": {
"manualChecks": {
"iwinv": {
"channel_registered_in_console": {
"done": true,
"checkedAt": "2026-02-16T09:00:00+09:00",
"note": "Approved in IWINV console",
"evidence": "internal-ticket-1234"
}
}
}
}
}