Run Katzenpost client daemon
kpclientd on Android devices.
Copyright (C) 2026-present, Bernd Fix >Y<
'kpclientd-android' is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
'kpclientd-android' is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see http:www.gnu.org/licenses/.
SPDX-License-Identifier: AGPL3.0-or-later
THIS IS WORK-IN-PROGRESS AT A VERY EARLY STATE. DON'T EXPECT ANY COMPLETE DOCUMENTATION OR COMPILABLE, RUNNABLE OR EVEN OPERATIONAL SOURCE CODE.
- arm64-based device with Android 13+ (recommended: Android 16)
- rooted device (command
suis available and usable within apps); this usually requiresmagiskto be installed on the device. - a cloned Katzenpost repo
- Go 1.26+
- Java 17+
- Android SDK and NDK installed
- Gradle
The app contains two separate parts:
-
the
kpclientddaemon that connect to the Katzenpost mixnet and serves client requests over an interface (Unix socket, TCP). -
the GUI where the daemon can be started / stopped.
If your cloned Katzenpost repo
is not located at /usr/local/src/katzenpost or you use a different version
of the Android NDK (not 28.0.13004108), you need to change the build
script for the daemon. Copy mk_daemon to mk_daemon_local and edit the
lines KATZENPOST_REPO=... and ASDK=....
To build the program, run:
./mk_daemon_localThe command displays the resulting file properties at the end of the build. The file size should be around 31MB.
You need gradle 9.5.0 to build the app. To install the gradle wrapper:
cd ./apk/
mv settings.gradle settings.gradle.x
mv build.gradle build.gradle.x
gradle wrapper --gradle-version 9.5.0
mv settings.gradle.x settings.gradle
mv build.gradle.x build.gradle
cd ..If you need to customize settings in mk_apk, copy mk_apk to mk_apk_local
and edit it:
ASDK=/usr/lib/android-sdk/build-tools/34.0.0
KEYSTORE=/usr/local/src/keystore.jks
KEY=devIf you have no keystore yet (to store keys required to sign APKs), create one in a folder of your choice and set the location in the file above:
keytool -genkey -v \
-keystore <folder>/keystore.jks -alias dev \
-keyalg RSA -keysize 2048 -validity 10000You also need to create an output folder:
mkdir ./apk/deployTo build the APK, run the following commands:
./mk_apk_localAfter a successful build the APK will be signed with the dev key
in the Java keystore.
You can add the +deploy argument if you want the build script to upload
the resulting binaries (kpclientd.apk and kpclientd-debug.apk) to the
Download folder on a device:
./mk_apk_local +deployInstall the kpclientd.apk on your device, but don't open it yet.
The daemon requires a configuration file (usually called client.toml) to
successfully connect to the Katzenpost mixnet. A config file is built-in,
but it may be outdated the time you want to run the daemon.
Because this file is currently not public (it resides in a private repository
github.com/katzenpost/namenlos) you need to contact the Katzenpost project
and ask for a new version. Copy the new client.toml to the /sdcard/Download
folder on your device, where the daemon will pick it up at start time.
Click on the app icon to open the GUI. Below the title line you see a line like
Configuration: ... where either built-in or custom is specified.
If the app is started it will display the first of the following screens:
![]() |
![]() |
![]() |
There are two buttons to start and stop the daemon and the elapsed time in either state is displayed below (format "<hrs>:<mins>").
You can toggle the log view with the chevron button above the window.


