syryn
Bluetooth identity beacon for headless Linux devices.
The name comes from Сирин — a bird from Slavic mythology known for its voice. Syryn speaks when asked: it listens on a Bluetooth RFCOMM channel and responds with the device's hostname, mDNS address, and active network interfaces.
What it does
Run syryn on a headless mini-PC. From any nearby Bluetooth device, send STATUS — and get back:
hostname: panteon-john
mdns: panteon-john.local
eth0: 192.168.0.131
wlan0: 192.168.1.44
external_ip: 93.12.34.56
No display needed. No SSH session. No prior knowledge of the IP address.
Zero-touch: the IP is the Bluetooth name
You don't even need a terminal app. While syryn runs, the device's Bluetooth name is its current IP:
P:192.168.0.131
Open the ordinary Bluetooth settings on any phone or laptop and read it from the
scan list — no app, no pairing, no commands. The name follows the IP: when DHCP
hands out a new address, the name changes within --interval seconds (default 15).
| Where you look | What you see | How |
|---|---|---|
| Android — Settings → Bluetooth → pair new device | P:192.168.0.131 |
classic BR/EDR name (adapter alias) |
| iPhone / iPad — Settings → Bluetooth | P:192.168.0.131 |
BLE advertisement with the HID service UUID (iOS lists only "connectable kinds" of devices) |
| Windows 10/11 laptop nearby | pop-up toast "New Bluetooth device found: P:192.168.0.131" | Microsoft Swift Pair beacon |
| macOS / Linux — Bluetooth settings | P:192.168.0.131 |
classic name / BLE |
Notes:
- The prefix is
Pby default (--prefix Xto change,--prefix ""for the bare IP). - A BLE packet has room for ~15 name characters. If
P:+ a long IP (e.g.P:192.168.100.200) doesn't fit, the BLE name becomes the bare IP — never a truncated one. The classic name always has the full label. - The IP shown is the one on the LAN cable (wired Ethernet port:
eth0,enp3s0, USB-Ethernetenx…) — Wi-Fi, docker/veth bridges and VPN tunnels are ignored. With no cable / no DHCP lease the name isP:no-lan.--iface autouses the default-route interface instead (may be Wi-Fi);--iface wlan0pins a specific one. - Devices you already paired with may cache the old name; unpaired scans show the current one.
- Tapping the entry on iPhone/Windows tries to pair as a keyboard and fails harmlessly — you only need to read the name.
- Swift Pair pop-up appears only when the laptop is close (Windows uses a signal-strength threshold) and Settings → Bluetooth → "Show notifications to connect using Swift Pair" is on (default).
One-line install (starts on every boot)
curl -fsSL https://raw.githubusercontent.com/szholobetsky/syryn/main/install.sh | sudo sh
Installs BlueZ + D-Bus bindings, puts syryn into /opt/syryn, and registers a
systemd service. Do it once while you still have a screen or SSH; after that the
device announces its IP by itself on every boot. Logs: journalctl -u syryn -f.
If syryn is already installed via pip/pipx:
sudo "$(command -v syryn)" install # deps check + systemd unit + start
sudo "$(command -v syryn)" install --pin 1234 # flags are baked into the service
sudo "$(command -v syryn)" uninstall
syryn install --dry-run # preview, changes nothing
Install & quick start (manual)
1. System packages (one-time)
syryn uses the BlueZ D-Bus API directly — no PyBluez2 required.
Debian / Ubuntu / Xubuntu:
sudo apt install bluez python3-dbus python3-gi
Fedora / RHEL:
sudo dnf install bluez python3-dbus python3-gobject
2. Enable Bluetooth
sudo systemctl enable bluetooth --now # start and enable on boot
rfkill list # check if adapter is blocked
sudo rfkill unblock bluetooth # unblock if needed
bluetoothctl discoverable on # make device visible
To keep the device permanently discoverable, add DiscoverableTimeout = 0 to
/etc/bluetooth/main.conf and restart bluetooth.service.
3. Install syryn
syryn uses system D-Bus libraries. Install with --system-site-packages so pipx
can find them:
pipx install syryn --system-site-packages
Or without pipx:
pip install syryn
4. Run
syryn # auto-pairing, no PIN; name = P:<ip>
syryn --pin 1234 # hardcoded PIN for all incoming pairs
syryn -q # quiet mode, no log output
syryn status # print the STATUS text locally and exit
syryn --iface auto # name from the default-route interface instead of the LAN cable
syryn --no-name # keep the hostname as the Bluetooth name
syryn --no-ble # classic Bluetooth only (no iPhone visibility, no Windows pop-up)
syryn --no-swiftpair
Syryn registers a Serial Port Profile (SPP) via BlueZ and a pairing agent so
connecting devices are accepted automatically (no manual PIN prompt). The device
name visible to other devices is P:<ip> while syryn runs; on exit it reverts to
the system hostname (set via hostnamectl set-hostname <name>). With --no-name
the hostname is kept all the time.
5. Connect from another device
From any device with a Bluetooth terminal app (e.g. Serial Bluetooth Terminal on Android):
- Scan for Bluetooth devices — the headless device appears as
P:<ip>(or by hostname with--no-name) - Pair (accepted automatically by syryn)
- Connect to the Syryn service (Serial Port)
- Send
STATUS— receive hostname, mDNS, interfaces, external IP
Requirements
- Linux with BlueZ (
bluetoothdrunning) - Python 3.10+
python3-dbus+python3-gi(system packages) — BlueZ D-Bus interface and pairing agent- BLE name/pop-up: BlueZ 5.43+ with an LE-capable adapter (otherwise syryn falls back to the classic name only)
syryn install: systemdpsutil,requests(installed automatically via pip)
Part of the SIMARGL toolkit
syryn is one of ten tools that together form an intellectual development support system:
| Tool | Role |
|---|---|
| simargl | Task-to-code retrieval — given a task description, finds which files and modules are likely affected, using semantic similarity over git history |
| svitovyd | Project map — scans any codebase and produces a structural map of definitions and cross-file dependencies; queried from the CLI, a web UI with a layered map, or an MCP server |
| 1bcoder | AI coding assistant for small local models — surgical context management, agents, parallel inference, proc scripts |
| yasna | Session memory — indexes conversations from all AI agents so you can find what was discussed, when, and where |
| radogast | Context drift monitor — measures how far an AI agent's conversation has drifted from the original task |
| vyrii | Local AI web UI — chat, translate, web research, RAG and file management in the browser (Flask; Gradio optional); powered by Ollama or any OpenAI-compatible backend |
| syryn | Bluetooth identity beacon for headless devices — the device's IP is its Bluetooth name; hostname, mDNS and network interfaces on request |
| alkonost | Browser cockpit for 1bcoder's flows — the deepagent_* spec pipeline (plan tree → specs → task board) and the glossary (build, browse, search), tuned for small local models |
| gamayun | Statistical ontology without an LLM — builds triples of terms, identifiers, files and modules from task history or a folder of documents and code; every triple carries its significance test |
| mokosh | Dataset gathering — commits of a git repository and the tasks of its tracker (Jira, GitHub, GitLab, YouTrack) in one SQLite database that the other tools read |
- simargl finds the code related to a task by vector search over the task history (embeddings).
- svitovyd answers: how is the code structured and what depends on what?
- 1bcoder answers: how do I work with local models efficiently?
- yasna answers: where did I already discuss this?
- radogast answers: is the AI agent still on track toward the goal?
- vyrii answers: how do I access all of this through a browser?
- syryn answers: what is the address of this headless device?
- alkonost answers: how do I turn one task description into a reviewed, working plan — and see the project's glossary — without a big model or a big context window?
- gamayun finds the code related to a task through an ontology of significant links between words, files and modules (no LLM).
- mokosh prepares the initial dataset from version control and the issue tracker.
Together they cover the full development loop: understand the codebase, find relevant history, work with AI locally, remember what was decided, and verify the context stays on target.
(c) 2026 Stanislav Zholobetskyi, Oleh Andriichuk Institute for Information Recording, National Academy of Sciences of Ukraine, Kyiv PhD research: «Intelligent Technology for Software Development and Maintenance Support»
Metadata
Release files for syryn 0.1.10
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| syryn-0.1.10.tar.gz | 37.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| syryn-0.1.10-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 74.8 kB
Release files / syryn-0.1.10.tar.gz
| Download URL | syryn-0.1.10.tar.gz |
|---|---|
| Size | 37.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b469042a082528a62cc6286bf887b782ec173ec7653d205cc629ecc0ddf44e1d
|
|
BLAKE2b-256 checksum How to use checksums |
427b94c08a7a66e20aa288c149336dbb498693d1b718583640fb402155654427
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.9
|
Release files / syryn-0.1.10-py3-none-any.whl
| Download URL | syryn-0.1.10-py3-none-any.whl |
|---|---|
| Size | 37.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9d088b16f2d9cad7c6bf90f09252a1725de8c0daacc138dc33252b182fe0e5b0
|
|
BLAKE2b-256 checksum How to use checksums |
b3118d6b3875869e83033f0cf83913fca80a9bd46a3c3f5c784878b380e6c907
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.9
|