SkillAgentSearch skills...

Thefeed

DNS-based feed reader and lite messenger for environments where only DNS queries work. Read Telegram channels and public X accounts, and exchange end-to-end-encrypted messages with other users — all over DNS.

Install / Use

npx skills add sartoopjj/thefeed

Installs into whichever agent you are using.

About this skill

Quality Score

0/100

Supported Platforms

Universal

README

thefeed

DNS-based feed reader and lite messenger for networks where only DNS gets through. Read Telegram channels and public X accounts, and exchange end-to-end-encrypted messages with other users — all over plain DNS.

English · فارسی · 简体中文 · Русский

Google Play TestFlight Latest release

Contents: Install the app · Run a server · Messenger · How it works · Security · Build from source · Reference · Links

Screenshots

<table align="center"> <tr> <td align="center"><img src="docs/screenshots/mainfeed.jpg" width="170" alt="Main feed"><br><sub>Main feed</sub></td> <td align="center"><img src="docs/screenshots/feed-post.jpg" width="170" alt="Reading a post"><br><sub>Reading a post</sub></td> <td align="center"><img src="docs/screenshots/telemirror.jpg" width="170" alt="Telemirror"><br><sub>Telemirror</sub></td> <td align="center"><img src="docs/screenshots/chat.jpg" width="170" alt="Messenger"><br><sub>Messenger</sub></td> </tr> <tr> <td align="center"><img src="docs/screenshots/chat-list.jpg" width="170" alt="Chats"><br><sub>Chats</sub></td> <td align="center"><img src="docs/screenshots/scanner.jpg" width="170" alt="Resolver scanner"><br><sub>Resolver scanner</sub></td> <td align="center"><img src="docs/screenshots/resolver-bank.jpg" width="170" alt="Resolver bank"><br><sub>Resolver bank</sub></td> <td align="center"><img src="docs/screenshots/settings.jpg" width="170" alt="Settings"><br><sub>Settings</sub></td> </tr> </table>

Install the app

For anyone who just wants to read feeds and chat — you don't need a server, just import a config into the client.

Download the client for your platform from the latest release — pick the mirror that's reachable for you: GitHub · GitLab.

| Platform | Notes | |----------|-------| | Android (7.0+) | Easiest: Google Play — installs and updates itself. Otherwise the APK. Pick arm64-v8a (phones since ~2017) or armeabi-v7a (older 32-bit only). Installing the wrong ABI installs but won't run. | | iOS (13+) | Install via TestFlight. App Store build is planned; you can also build from source under ios/ — see Build from source. | | Windows (10/11) | The .exe is unsigned, so SmartScreen shows "Windows protected your PC" and Defender may quarantine it — a known false positive for DNS-tunneling tools, not malware. Click More info → Run anyway; restore from Defender → Protection history if removed; verify the SHA-256 from the release page if unsure. | | macOS | Universal .dmg (Intel + Apple Silicon), drag-installs Thefeed.app. Unsigned, so on first launch either right-click → Open, or run xattr -dr com.apple.quarantine /Applications/Thefeed.app. | | Linux / Termux | thefeed-client binary — run it and open http://127.0.0.1:8080. |

Then open Settings → Configs and import a config (or paste your domain + passphrase). DNS resolvers are managed in the Resolver tab — a shared Bank used by all configs, plus a Scanner to find more.

Public configs to try: @thefeedconfig.


Run a server

For operators who host feeds for others. The server runs outside the censored network, pulls from Telegram / X, and answers encrypted DNS queries. Setup is two steps: (1) DNS records, then (2) install.

1. DNS records

You need one A record and one NS delegation. Example: your server IP is 203.0.113.10 and your domain is example.com.

| # | Type | Name | Value | Purpose | |---|------|------|-------|---------| | 1 | A | ns.example.com | 203.0.113.10 | Point a hostname at your server | | 2 | NS | t.example.com | ns.example.com | Delegate the feed subdomain to your server | | 3 (optional) | NS | c.example.com | ns.example.com | Delegate a messenger subdomain — only if you enable chat |

Records 1–2 are required for the feed. Record 3 is only needed for the optional messenger, which must use a separate subdomain from the feed (e.g. c.example.com).

2. Install the server

With DNS in place, install with the script or with Docker.

Option A — install script (Linux + systemd)

The one-liner auto-detects a reachable mirror (GitHub first, then GitLab); pass --gitlab to force GitLab.

# GitHub mirror
sudo bash -c "$(curl -Ls https://raw.githubusercontent.com/sartoopjj/thefeed/main/scripts/install.sh)"

# GitLab mirror (use while the GitHub account is unavailable)
sudo bash -c "$(curl -Ls https://gitlab.com/sartoopjj/thefeed/-/raw/main/scripts/install.sh)" -- --gitlab

The script downloads the latest binary, asks for your domain / passphrase / channels / X accounts, asks whether to use Telegram login (recommended: No — public channels work without it), and sets up a systemd service. Re-run it any time to update.

Other actions (pipe the script to sudo bash -s -- <flag>):

| Flag | Action | |------|--------| | --version v0.9.2 (or -v) | Install a specific tag (rollback) | | --pre | Install the newest pre-release (beta / rc) | | --list | List recent releases | | --login | Re-run Telegram login | | --config | Print the import URI (domain, key, sk= server key, bootstrap resolvers) | | --uninstall | Remove the service |

Option B — Docker

No Go toolchain needed. Base image alpine:3.21 (~23 MB), runs as non-root thefeed (UID 1000).

# 1. Configure — set THEFEED_DOMAIN and THEFEED_KEY (uncomment Telegram vars if you need private channels)
cp .env.example .env && nano .env

# 2. Add your channels
mkdir -p data
cp configs/channels.txt data/
cp configs/x_accounts.txt data/   # optional

# 3. Build and run (listens on :5300/udp inside the container)
docker compose up -d
docker compose logs -f

# 4. Print the client import config (the thefeed:// URI — domain, key, server key sk=,
#    resolvers) to hand to your users, just like the script prints at the end:
docker compose run --rm server --print-config --data-dir /data --domain YOUR_DOMAIN --key YOUR_KEY

Then set up the port 53 redirect below. For private channels, do a one-time interactive login first:

docker compose run -it --rm server --login-only --data-dir /data \
  --domain YOUR_DOMAIN --key YOUR_KEY \
  --api-id YOUR_API_ID --api-hash YOUR_HASH --phone YOUR_PHONE
# then remove --no-telegram from docker-compose.yml, add the Telegram flags, and `docker compose up -d`

Port 53

The server must receive external DNS on UDP 53, but binding :53 directly conflicts with systemd-resolved. So it listens on an unprivileged port (:5300) and you redirect external :53 to it with iptables. Local DNS on the host keeps working — only packets arriving on the external interface are redirected.

# Replace eth0 with your interface (check: ip a)
sudo iptables  -I INPUT -p udp --dport 5300 -j ACCEPT
sudo iptables  -t nat -I PREROUTING -i eth0 -p udp --dport 53 -j REDIRECT --to-ports 5300
sudo ip6tables -I INPUT -p udp --dport 5300 -j ACCEPT
sudo ip6tables -t nat -I PREROUTING -i eth0 -p udp --dport 53 -j REDIRECT --to-ports 5300

# Persist across reboots (Debian/Ubuntu)
sudo apt install -y iptables-persistent && sudo netfilter-persistent save

Undo instantly if anything breaks:

sudo iptables -t nat -D PREROUTING -i eth0 -p udp --dport 53 -j REDIRECT --to-ports 5300
sudo iptables -D INPUT -p udp --dport 5300 -j ACCEPT
sudo netfilter-persistent save

Quick sanity checks: ss -ulnp | grep ':53 ' (expect only systemd-resolved on 127.0.0.53), dig +short google.com @127.0.0.53 (local DNS still works), iptables -t nat -L PREROUTING -n | grep 5300 (redirect active).

Managing the service

systemctl status thefeed-server
systemctl restart thefeed-server
journalctl -u thefeed-server -f

sudo vi /opt/thefeed/data/channels.txt   # edit channels, then:
sudo systemctl restart thefeed-server

The server also renders a terminal dashboard from its hourly reports (<data-dir>/dns_hourly.jsonl) — serves nothing on the network, just reads the data dir:

thefeed-server --data-dir /srv/thefeed --report                 # snapshot
thefeed-server --data-dir /srv/thefeed --report --report-refresh 5s   # live

It shows total / channel-fetch / metadata / media / chat query counts, per-channel and per-domain aggregates, and chat stats.

Server flags

Key flags (also settable via env vars, e.g. THEFEED_DOMAIN, THEFEED_KEY, THEFEED_ALLOW_MANAGE):

| Flag | Default | Description | |------|---------|-------------| | --data-dir | ./data | Data directory (channels, session, cache, config) | | --domain | | DNS feed domain (required) | | --key | | Encryption passphrase (required) | | --extra-domains | | Comma-separated extra feed sub-domains (load spread + resilience) | | --chat-domains | | Enable the messenger on these sub-domains (separate from feed) | | --no-telegram | false | Run w

Related Skills

View on GitHub
GitHub Stars1.5k
CategoryDevelopment
Updated4h ago
Forks84

Languages

Go

Security Score

100/100

Audited on Aug 8, 2026

No findings