Don’t want to read all this?
Just drop a link to https://xedant.com/agents/news/install.md or to https://xedant.com/llms.txt into any AI chat (Claude, ChatGPT, etc.) and ask it to generate the config files and commands. It will read the docs, ask you a few questions about your setup, and hand you a ready-to-use configuration. Save time — let the model do the reading for you.
You can also reach me on Telegram — I’m always glad to help. And that’s not just politeness — I genuinely enjoy talking to like-minded people, especially if you love coding as much as I do.
News Agent is a news desk on your server: the product walks your sources, collects material, merges repeats of the same story into one record, processes it with AI and sends you only what you yourself called important. It deploys as a single Docker container, and a separate database is not required: by default an embedded one is already inside. Next to it, optionally, sits your Xedant Agent — then you run the news by talking in chat, and without it everything except the chat works as usual.
What you will need
- A server or computer with Docker — Windows, Linux or macOS all work, and an inexpensive server is enough for permanent use.
- One free port for the interface (3979 in the examples below). A separate database is not needed: if you do not set a connection string, the product starts an embedded database by itself.
- Optionally, the address and key of your Xedant Agent. Without them everything works except the chat with the AI agent inside the product.
- A management key for the agent (
NEWSAGENT_MANAGEMENT_KEY) — if you want your AI agent to change the settings itself instead of you editing files by hand. Until the key is set, changes are refused, while observation in the interface keeps working.
Installing with Docker Compose
Create a compose.yml file with this content. There is one service here: it needs no database, so the whole product fits into one container.
services:
newsagent:
image: xedant/news-agent:min-latest
container_name: newsagent
ports:
- "3979:80"
volumes:
- newsagent-data:/apps/news
environment:
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://+:80
- NEWSAGENT_DATA=/apps/news
# NEWSAGENT_BASE_PATH=/news # serve from a first-level subfolder (see below)
restart: unless-stopped
sysctls:
fs.inotify.max_user_watches: "524288"
fs.inotify.max_user_instances: "512"
volumes:
newsagent-data:
Line by line, what this says and why:
image— the English build of the product with an English interface and the name “News Agent”.ports— the address the interface opens on:3979outside,80inside the container. The outside number can be any free port.volumes— the persistent folder/apps/news. The database, the archive of collected pages and the published material live in it, so without the volume all of that disappears when the container is recreated.NEWSAGENT_DATA— that same persistent folder inside the container, where the product keeps everything of its own; it is the folder mounted as the volume above.restart— restarting after a server reboot, so the news watching never stops.sysctls— two Linux kernel settings raising the file-watching limit: without them the product cannot follow changes in the settings and the archive at scale.
Now start it:
docker compose up -d
The interface appears on port 3979: http://<server-address>:3979.
Running with one command
If you would rather not keep a settings file, the same thing is done with one docker run command:
docker run -d \
--name newsagent \
-p 3979:80 \
-v newsagent-data:/apps/news \
-e ASPNETCORE_ENVIRONMENT=Production \
-e ASPNETCORE_URLS=http://+:80 \
-e NEWSAGENT_DATA=/apps/news \
--sysctl fs.inotify.max_user_watches=524288 \
--sysctl fs.inotify.max_user_instances=512 \
--restart unless-stopped \
xedant/news-agent:min-latest
The remaining variables are convenient to pass in a file with the --env-file .env flag — easier to change them without rewriting the long command.
Environment variables
Settings are passed through environment variables — you write them once into compose.yml and change them without touching the code. Almost all names start with NEWSAGENT_; for the chat with the agent, the names are the familiar ones — without the prefix.
| Variable | What it sets |
NEWSAGENT_DB | database choice. Not set — the product runs on the embedded SQLite database; set to a connection string — it runs on PostgreSQL |
NEWSAGENT_DATA | persistent data folder: database, archive, published material, settings backups, sign-in keys. Default /apps/news |
NEWSAGENT_BRAND | build brand: xedant is the English build (the default), pastukhov the Russian one with the Russian product name and interface |
NEWSAGENT_BASE_PATH | hosting in a subfolder of the site, for example /news; not set — runs at the domain root |
NEWSAGENT_MANAGEMENT_KEY | hash of the key your AI agent uses to manage the product over the API (these are the management addresses the agent calls). Stored as an irreversible SHA-256 sum; without it changes are refused, while observation keeps working |
NEWSAGENT_NEWS_CONFIG | a different settings folder. Default /project/apps/news — it sits next to the project and goes under version control |
NEWSAGENT_SSL | issuing an HTTPS certificate for a direct address like news.your-domain. If your proxy stands in front of the product, this variable does not need to be enabled |
AGENT_API_URL, AGENT_API_KEY | address and key of your Xedant Agent: with them the chat with the AI agent appears inside the product. Not set — the chat is hidden, everything else works |
Where the data lives
Everything collected and configured stays on your server and goes nowhere outside. In the persistent folder /apps/news:
data.db— the database: material, events, publications, delivery logs;archive/— the raw-page archive: every downloaded page is saved whole, so it is always visible where a fact came from;published/— published material and the reader feeds;config-backup/— copies of the settings taken before every edit made through the agent;auth/— sign-in keys: sessions are signed with them, so after moving the folder the old sign-ins keep working.
The settings are a separate folder, /project/apps/news, with plain-text files per section: settings, sources, monitors, rules, alerts, channels, digests, publishing. It is mounted as its own volume and is filled with ready examples on first start; moving to another server is simply copying the folder.
Two honest warnings. First: without the persistent volumes, recreating the container loses the database, the archive and the published material, and signing in has to be done again. Second: the settings copies hold real passwords and tokens, not masked ones, so the product deliberately does not show the config-backup/ folder through its own file manager.
First sign-in
Open the interface in a browser and register: the first person to register becomes the administrator, after which open registration closes — an outsider can no longer get into your installation. A sign-in session lives 90 days, so you will not have to log in every day. If the product stands behind your organization’s single sign-on (when an external system checks the login), users are created automatically on first visit.
Hosting in a subfolder
The product can be served not from the domain root but from a subfolder — for example, https://your-site/news. There are two ways, and they do not mix.
- Just name the folder. Set
NEWSAGENT_BASE_PATH=/news— the product strips the prefix itself and redirects the old addresses to the new form. The domain-check service addresses (/.well-known/) stay at the root. - Hand the folder to your proxy. In this case nothing needs changing inside the container: the proxy tells the product the prefix in the
X-Forwarded-Prefixheader. This is more convenient when you already have nginx or a similar server configured.
In the second case, do not forget the live updates: they ride a separate connection that needs the WebSocket upgrade headers, otherwise the updates quietly turn into rare polling.
# WebSocket upgrade (in the http {} block)
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 443 ssl;
server_name host.tld;
location /news/ {
proxy_pass http://newsagent:80/; # the trailing slash strips the subfolder prefix
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Prefix /news;
proxy_set_header X-Forwarded-Proto $scheme; # links in feeds and alerts are built from it
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; # live updates (SignalR)
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_buffering off;
}
}
One more detail worth knowing in advance: links inside alerts, digests and feeds are built by the product from its public address. If it works in the background (at night, with no browser open), the address must be set manually — with the settings.defaults.publicUrl setting, together with the subfolder prefix. Otherwise the links in letters and webhooks will point at the product’s own site, not at your server. Both ways are described in detail in the install/subfolder-hosting.md file next to the product.
Installing through Xedant MultiAgent
If you have several servers, it is more convenient to install the product from Xedant MultiAgent: it raises the container itself, provides a permanent address and HTTPS, and connects the database. News Agent is in the product catalogue (port 6090); the variables used are NEWSAGENT_SSL, NEWSAGENT_DB, NEWSAGENT_BASE_URL and NEWSAGENT_API_KEY, and a linked Xedant Agent connects to the chat — it will be the one running your news. More about MultiAgent itself is on the MultiAgent page.
License and updates
The trial period is 30 days free, with no limits inside. Prices are the same as the neighboring products: personal
Next, take a look at Getting Started — a short tour of how the product works and where to begin.