Configuration Reference¶
Kunuleco has two configuration files. The node reads config.json, which the installer writes. The Urchin client
keeps its own settings in urchin_settings.cfg. A handful of environment variables override the node's file.
Rewritten 2026-09-30. The earlier version of this page described
core,transport,identity,persistenceandloggingkeys. No code reads them (Config.load()incore/config.pyis a stub), so they are gone.
The node's config.json¶
Where it is¶
| Platform | Path |
|---|---|
| Windows | %LOCALAPPDATA%\Kunuleco\config.json |
| Linux, and any other non-Windows system | ~/.local/share/kunuleco/config.json |
The node resolves this path in two places that agree (scripts/kunuleco.py at import, and
installer_config_path() in core/config.py). Neither has a macOS branch, so on macOS the node looks under
~/.local/share/kunuleco/. The client keeps its settings under ~/Library/Application Support/Kunuleco/ on macOS (see
below), so on that platform the two files are not side by side.
A node started without an installer runs without this file and uses the defaults and environment variables below.
What the installer writes¶
The installer writes it once, at install (installer/.../install/orchestrator.py). A typical file:
{
"version": "1.0",
"base_dir": "/home/alice/.local/share/kunuleco",
"data_dir": "/home/alice/.local/share/kunuleco/data",
"logs_dir": "/home/alice/.local/share/kunuleco/logs",
"config_dir": "/home/alice/.local/share/kunuleco/config",
"venv_dir": "/home/alice/.local/share/kunuleco/venv",
"ipfs": {
"binary": "/home/alice/.local/share/kunuleco/bin/ipfs",
"repo": "/home/alice/.local/share/kunuleco/data/ipfs",
"api_port": 15001,
"swarm_port": 14001,
"gateway_port": 18080
},
"tor": {
"binary": "/home/alice/.local/share/kunuleco/bin/tor",
"data_dir": "/home/alice/.local/share/kunuleco/data/tor",
"config": "/home/alice/.local/share/kunuleco/data/tor/torrc",
"socks_port": 19050,
"control_port": 19051
},
"veilid": {
"binary": "/home/alice/.local/share/kunuleco/bin/veilid-server",
"data_dir": "/home/alice/.local/share/kunuleco/data/veilid"
}
}
The paths depend on the platform and the install location. The ports are the installer's fixed values
(platform/paths.py), chosen so an installed node does not collide with a system IPFS or Tor.
What the node reads from it¶
| Key | Used for | Default without the file |
|---|---|---|
data_dir |
The node's data directory. Accounts, the database and keystores live here. KUNULECO_DATA_DIR overrides it. |
KUNULECO_DATA_DIR, else ./data if it exists, else ~/.kunuleco |
ipfs.api_port |
The kubo API the node talks to (http://localhost:<port>). IPFS_API_URL overrides it. |
5001 |
ipfs.binary, ipfs.repo |
Which kubo to start and its repository. The node sets IPFS_PATH for kubo from repo. |
none |
tor.binary |
Which Tor to start. It must be a file. | a Tor on the PATH |
tor.config, tor.socks_port, tor.control_port |
Tor's torrc and ports. The node exports the ports as TOR_SOCKS_PORT and TOR_CONTROL_PORT for the modules that read them. |
9050, 9051 |
veilid.binary, veilid.data_dir |
Which veilid-server to start and its data. VEILID_BINARY overrides the binary. |
none |
media_retention_days |
How many days a received media note stays pinned before it is unpinned. The one key the node itself writes, through media retention <days> (1 to 365). Absent until that command is used. |
3 |
The node reads the veilid API port from veilid.api_port when present, which the installer does not write, so an
installed node uses 15959 (and 5959 without the file). The other keys the installer writes (version, base_dir,
logs_dir, config_dir, venv_dir, ipfs.swarm_port, ipfs.gateway_port, tor.data_dir) are the installer's own
record. The node does not read them.
Changing it¶
Edit the file and restart the node. There is no command that edits it, apart from media retention, which writes its
one key and keeps every other key as it was (write_node_setting in core/config.py).
Environment variables¶
| Variable | Effect | Default |
|---|---|---|
KUNULECO_DATA_DIR |
The data directory. Takes precedence over config.json's data_dir. |
see data_dir above |
KUNULECO_CLIENT_PORT |
The TLS port clients connect to. | 8123 |
KUNULECO_CAPTP_PORT |
The CapTP port other nodes dial, on every transport, and the port mDNS advertises. A value that is not a port refuses to start rather than falling back. | 4243 |
IPFS_API_URL |
The kubo API URL. Takes precedence over ipfs.api_port. |
from ipfs.api_port |
VEILID_BINARY |
The veilid-server to start. Takes precedence over veilid.binary. |
from config.json |
TOR_CONTROL_PASSWORD |
Password for Tor's control port, when Tor is set up to ask for one. | (none) |
KUNULECO_KDF_PROFILE |
argon2id tier for NEW account records (DOS-12): moderate = username key INTERACTIVE / password key MODERATE; interactive = both INTERACTIVE; sensitive = both SENSITIVE (1 GiB per derivation — the pre-0.2.198 behaviour, which froze a 1 GB node for 15 minutes per login). Recorded per account and read back at login. Changing it later re-wraps every existing record that sits ABOVE the new tier at that account's next successful login (DOS-12 half 3: the login already holds both keys, so the re-wrap costs the two policy derivations and one row rewrite; the log line is [DOS-12] re-wrapped legacy record); a record already cheaper than the policy is never made dearer. Pre-0.2.198 accounts therefore pay SENSITIVE exactly once more, at the first login on this build. Unknown values refuse to start the derivation rather than defaulting. |
moderate |
TOR_SOCKS_PORT, TOR_CONTROL_PORT and VEILID_API_PORT are set by the node from config.json for its own modules.
Setting them in the shell has no lasting effect, so change config.json instead. The SSH endpoint listens on 8122,
which is fixed in scripts/ssh_server.py.
Precedence, for the node: an environment variable, then config.json, then the built-in default.
The client's urchin_settings.cfg¶
Where it is¶
| Platform | Path |
|---|---|
| Windows | %LOCALAPPDATA%\Kunuleco\config\urchin_settings.cfg |
| Linux | ~/.local/share/kunuleco/config/urchin_settings.cfg |
| macOS | ~/Library/Application Support/Kunuleco/config/urchin_settings.cfg |
| Android and anything else | the app's own data directory (OS.get_user_data_dir()), under config/ |
It is a Godot ConfigFile (an INI-like text file with [section] headers). The client writes it as you change
settings, so there is rarely a reason to edit it by hand. Close the client first if you do.
What it holds¶
| Section | Keys | What they are |
|---|---|---|
server |
host, port |
The node the client connects to. |
appearance |
avatar_id, skin, hair, eye, face_sharing |
Your avatar, and whether you said yes to sharing your face. |
audio |
microphone_enabled |
Whether the client may use the microphone. |
accessibility |
glow, motion, scanlines |
Visual effects you can turn down or off. |
display |
profile |
The display profile (comfortable unless changed). |
input |
default_mode |
The input mode the client starts in (cmd unless changed). |
friends |
archipelagos, home_group |
How your friends are grouped in the world view. |
world |
actions_collapsed |
Whether the world's action panel is collapsed. |
onboarding |
show_tutorial |
Whether to show the tutorial. |
tutorial |
completed_identities |
Which identities have finished the tutorial. |
debug |
logging |
Whether the client writes a debug log. |
The client owns this file and its sections change with the client. The list above is from client source on
2026-09-30 (scripts/core/urchin_singleton.gd and the scenes that call set_value).