Sigmo is a modern, self-hosted web UI and API for managing ModemManager-based cellular modems. It ships as a single binary with an embedded Vue 3 frontend, designed to be lightweight and easy to deploy.
Sigmo focuses on advanced eSIM operations, eSIM Quick Transfer, SMS management, Wi-Fi Calling (VoWiFi), and network control.
- π± eSIM Management: List, download (SM-DP+), enable, rename, and delete eSIM profiles.
- π eSIM Quick Transfer: Transfer supported physical SIM or eSIM lines from another modem or CCID reader to the target eUICC through TS.43 carrier flows.
- π© SMS Center: Full conversational view for SMS, send/delete capability, and USSD session support.
- πΆ Wi-Fi Calling (VoWiFi): Connect supported profiles to carrier IMS over Wi-Fi, complete carrier websheets, and route SMS, USSD, and calls through Wi-Fi Calling when available.
- βοΈ Modem Control: SIM slot switching, network scanning, manual registration, and preference configuration (Alias, MSS).
- π Secure Access: OTP-based login system via Telegram, HTTP, Email, and more.
- π Notifications: Forward incoming SMS and login tokens to Telegram, Bark, Gotify, Email, etc.
- π Portable: Single Go binary with no external runtime dependencies (except ModemManager).
Support the project and get reliable hardware for your setup.
-
Need an eUICC? We recommend eSTK.me. It is highly reliable for iOS profile downloads.
π Use code
esimcyoufor 10% off. -
Need more storage? If you require >1MB storage to install multiple eSIM profiles, we recommend 9eSIM.
π Use code
DAMONfor 10% off.
Architecture:
- Backend: Go serving
/api/v1and static assets. - Frontend: Vue 3 + Vite (Embedded in the binary).
System Requirements:
- OS: Linux.
- Service:
ModemManagerrunning on the system D-Bus when using the binary directly. The Docker image includesModemManagerand starts it inside the container. - Permissions: Root access or proper
udevrules to access modem device nodes. - eSIM Quick Transfer: Requires a build with the
esim_transferfeature, a target modem with eUICC support, a separate source modem or CCID reader, and carrier TS.43 transfer support for the source line. - Wi-Fi Calling: Requires a build with the
wifi_callingfeature, an active SIM/eSIM profile with carrier VoWiFi support, a reachable carrier ePDG/IMS service, and modem SIM access through QMI, MBIM, or AT ports.
Sigmo is distributed as a static binary. You do not need to install Node.js or Go to run it.
Grab the latest release for your architecture from the GitHub Releases.
# Example for Linux AMD64
curl -LO https://github.com/damonto/sigmo/releases/latest/download/sigmo-linux-amd64
chmod +x sigmo-linux-amd64
sudo install -m 0755 sigmo-linux-amd64 /usr/local/bin/sigmoSigmo uses command-line flags for startup settings and stores runtime settings in SQLite. On first start, login OTP is disabled so you can open the Web UI and configure notification channels and authentication.
Start the service.
/usr/local/bin/sigmo --listen-address=0.0.0.0:9527 --db-path=/var/lib/sigmo/sigmo.dbVisit http://localhost:9527 to access the UI.
The Docker image includes the embedded Vue frontend and installs dbus, ModemManager, qmi-utils for QMI proxy support, and libmbim-tools in the runtime image.
-
Data:
The compose setup mounts
./datato the container data directory. Sigmo stores application settings, messages, calls, internet preferences, and network preferences in SQLite. -
Start:
docker compose pull docker compose up -d
-
Open UI: Visit
http://localhost:9527, or pass--listen-addressto choose another address.
The compose setup uses network_mode: host because Sigmo's internet connection feature configures the modem network interface and host routes. Docker port publishing is disabled in this mode; use --listen-address to choose the listening address and port.
The container runs with privileged: true so Sigmo and ModemManager can access modem devices. /run is mounted as tmpfs so stale D-Bus sockets cannot survive container restarts. On hosts with strict Docker or udev policies, keep /dev, /run/udev, and /sys mounted as shown in compose.yaml.
Sigmo stores Internet Always On settings, modem network Mode/Bands preferences, and manual network registration preferences in SQLite so they can be restored after modem reloads, program restarts, and system reboots.
eSIM Quick Transfer is exposed only when the running build reports the
esimTransfer capability from /api/v1/capabilities. Private builds enable it
with the esim_transfer Go build tag.
What it adds:
- A transfer entry in the eSIM install dialog.
- Source discovery from other connected modems and CCID readers.
- Transferable line discovery for supported physical SIM and eSIM sources.
- Carrier TS.43 transfer progress, including user prompts, carrier Websheets, SM-DS discovery, profile download, profile enablement, and completion.
- Source profile deletion confirmation when the carrier requires it.
Usage flow:
- Open the target modem's eSIM page and choose Transfer from another device.
- Select a source modem or CCID reader. CCID sources require the original device IMEI.
- Load transferable lines and select the line to transfer.
- Confirm the transfer warning. The original SIM or eSIM may become invalid after the carrier accepts the transfer.
- Keep both source and target devices connected until Sigmo finishes downloading and enabling the transferred profile.
The source and target must be different devices. If the carrier does not expose a TS.43 transfer entitlement for that line, Sigmo marks it as unsupported before the transfer starts.
Wi-Fi Calling is exposed only when the running build reports the wifiCalling
capability from /api/v1/capabilities. Private builds enable it with the
wifi_calling Go build tag.
What it adds:
- Per-profile Wi-Fi Calling settings in the modem settings page.
- Carrier setup through an embedded Websheet when the carrier requires entitlement confirmation.
- Wi-Fi Calling status on modem cards and SIM/profile selectors.
- SMS, USSD, and voice calls over Wi-Fi Calling when the profile is connected.
- A preference toggle to use Wi-Fi Calling for messages, USSD, and calls when it is available.
Usage flow:
- Open the modem's settings page.
- Enable Wi-Fi Calling for the active SIM/eSIM profile.
- If Sigmo shows that carrier setup is required, open the carrier Websheet and complete the flow.
- Wait for the status to become connected.
- Send SMS, run USSD, or place calls as usual. When the preference toggle is enabled and Wi-Fi Calling is connected, Sigmo routes those actions through Wi-Fi Calling.
Wi-Fi Calling settings are stored per profile in Sigmo's application database.
Startup configuration is provided through flags:
| Flag | Default | Description |
|---|---|---|
--listen-address |
0.0.0.0:9527 |
HTTP bind address. |
--db-path |
$XDG_DATA_HOME/sigmo/sigmo.db |
SQLite database path. |
--debug |
false |
Enable debug logging and internal API errors. |
--version |
false |
Print the build version and exit. |
Runtime settings are managed in the Web UI and stored in SQLite:
- Login OTP policy and auth providers.
- Notification channels: Telegram, Bark, Gotify, ServerChan, HTTP webhook, and Email.
- Internet proxy listener and password.
- Modem alias, compatibility mode, and APDU MSS.
- Internet APN preferences and Always On state.
- Network mode, bands, and manual registration preferences.
To run Sigmo as a background service, use Systemd.
- Install Unit File:
sudo install -m 0644 init/systemd/sigmo.service /etc/systemd/system/sigmo.service
- Enable & Start:
sudo systemctl daemon-reload sudo systemctl enable --now sigmo
Note: The default service runs as
rootto ensure access to ModemManager. If running as a non-root user, verifyudevrules for the modem and write permissions for the SQLite database path.
If you wish to contribute or modify the source:
-
Prerequisites: Go 1.25+, Bun (for Vue).
-
Build Frontend:
cd web && bun install && bun run build
-
Run Backend:
go run ./ --listen-address=0.0.0.0:9527 --db-path=./sigmo.db --debug
Or for frontend hot-reload:
cd web && bun run dev -
Private feature build:
The public module does not build eSIM Transfer or Wi-Fi Calling by default. Private builds use
go.private.modand download the private TS.43 and VoWiFi modules through normal Go module auth:export GOPRIVATE=github.com/damonto/* source scripts/private-features.env go run -tags="${PRIVATE_GO_TAGS}" -modfile="${PRIVATE_GO_MODFILE}" . --db-path=./sigmo.db --debug
To use SSH for private modules locally:
export GOPRIVATE=github.com/damonto/* git config --global url."git@github.com:damonto/".insteadOf "https://github.com/damonto/" source scripts/private-features.env go build -tags="${PRIVATE_GO_TAGS}" -modfile="${PRIVATE_GO_MODFILE}" -o sigmo . sudo ./sigmo --db-path=/var/lib/sigmo/sigmo.db
Prefer building as your normal user and running the binary with
sudo. Runningsudo go runmakes Go and Git use root's module cache and Git/SSH configuration, which is why it may prompt for a GitHub username.This repository also includes a local helper that uses
/home/user/.ssh/id_ed25519over SSH, builds with your normal user's Go cache, and starts the temporarygo runbinary withsudo:./scripts/dev.sh
Use the private tags and modfile from
scripts/private-features.envfor private builds and tests. It currently enablesesim_transfer,wifi_calling. Future private features should use their own build tag and register a capability so the frontend can discover them from/api/v1/capabilities.GitHub Actions enables private features only when the repository variable
SIGMO_PRIVATE_FEATURESis set totrue. Private Go module access uses the repository secretSIGMO_PRIVATE_MODULE_TOKEN.Pull requests from branches in this repository that update
go.modorgo.sumautomatically syncgo.private.modandgo.private.sumwhen private features are enabled. Fork pull requests are skipped so private module credentials are not exposed.To sync the private manifest locally after changing public dependencies:
./scripts/sync-private-go-mod.sh
-
Build Docker Image:
docker build -t sigmo:local .
Released under the MIT License.