🌐 Translations: 🇺🇦 Українська
A Telegram bot for interacting with leading language models — Gemini, ChatGPT, and Claude — through a single unified interface. Each user configures their own API key and system prompt.
- Support for four AI providers: Google Gemini, OpenAI ChatGPT, Anthropic Claude, and Lapathoniia
- Per-user personalized settings (API key + system prompt)
- Settings stored in Firebase Firestore, PostgreSQL, or MongoDB (configurable)
- State caching in Redis
- API keys stored encrypted (AES-128 via Fernet)
- Automatic sending of long responses as a file (bypasses Telegram message limits)
- FSM-based step-by-step bot configuration flow
- Multi-language interface support (🇺🇦 Ukrainian, 🇬🇧 English, 🇵🇱 Polish)
- Docker-ready — run the entire stack with a single
docker compose up -d
User API keys are encrypted before being saved to the database (AES-128 via Fernet). The plaintext key exists only in memory during requests to the AI provider.
| Command | Description |
|---|---|
/start |
Start the bot |
/setup |
Step-by-step setup of model, key, and prompt |
/model |
Change the language model |
/locale |
Change the interface language |
/status |
Check current settings |
/help |
Help with obtaining API keys |
- Python 3.14+
- aiogram 3 — Telegram Bot framework
- aiogram-i18n — i18n support (Fluent)
- Firebase Admin SDK — user data storage (default)
- SQLAlchemy + asyncpg — PostgreSQL support (alternative)
- PyMongo — MongoDB support (alternative)
- Redis — FSM state storage
- anthropic / openai / google-genai — AI clients (including custom OpenAI-compatible endpoints)
- cryptography — API key encryption
- pydantic-settings — configuration via
.env - uv — dependency manager
git clone https://github.com/BogdanovychA/nexus-shell
cd nexus-shellmv .env.example .env
nano .envpython -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"Add the result to .env:
CRYPTOGRAPHY__SECRET_KEY=your_generated_keyPlace the firebase-admin_sdk.json file in the following directory:
src/secret/firebase-admin_sdk.json
uv run python src/main.pyBy default the bot uses Firebase Firestore. As an alternative, you can switch to PostgreSQL or MongoDB.
In your .env file, change the storage setting:
# Default — Firebase
MAIN__GLOBAL_STORAGE=Firebase
# Alternative — PostgreSQL
MAIN__GLOBAL_STORAGE=PostgreSQLThen fill in the PostgreSQL credentials in the same .env file:
POSTGRES_SERVER=
POSTGRES_PORT=
POSTGRES_USER=
POSTGRES_PASSWORD=
POSTGRES_DB=Initialize the database schema (creates all tables):
uv run python src/storage/sql_alchemy/models.pyFor convenience, a docker-compose.yml is included that starts PostgreSQL, pgAdmin, Redis, and RedisInsight with a single command:
docker compose up -d| Service | URL | Description |
|---|---|---|
| PostgreSQL | localhost:${POSTGRES_PORT} |
Main database |
| pgAdmin | http://localhost:8033 |
PostgreSQL web UI |
| Redis | localhost:${REDIS__PORT} |
FSM state storage |
| RedisInsight | http://localhost:5541 |
Redis web UI |
Note: Firebase credentials are still required when
MAIN__GLOBAL_STORAGE=Firebase(the default). If you switch to PostgreSQL, thefirebase-admin_sdk.jsonfile and Firebase Admin SDK are not needed.
In your .env file, change the storage setting:
MAIN__GLOBAL_STORAGE=MongoDBMongoDB supports two connection modes depending on where your database is hosted.
Fill in the individual connection fields:
MONGO_INITDB_ROOT_SERVER=localhost
MONGO_INITDB_ROOT_PORT=27017
MONGO_INITDB_ROOT_USERNAME=your_username
MONGO_INITDB_ROOT_PASSWORD=your_passwordLeave MONGO_INITDB_ROOT_URI commented out — if it is set, it takes priority over the individual fields.
Set the connection string directly via MONGO_INITDB_ROOT_URI:
MONGO_INITDB_ROOT_URI="mongodb+srv://your_username:your_password@your_cluster.your_server/?appName=your_app_name"The individual fields (SERVER, PORT, USERNAME, PASSWORD) are ignored when URI is provided.
docker compose up -d| Service | URL | Description |
|---|---|---|
| MongoDB | localhost:${MONGO_INITDB_ROOT_PORT} |
Main database |
| Mongo Express | http://localhost:8082 |
MongoDB web UI |
| Redis | localhost:${REDIS__PORT} |
FSM state storage |
| RedisInsight | http://localhost:5541 |
Redis web UI |
To log in to Mongo Express, use the ME_CONFIG_BASICAUTH_USERNAME / ME_CONFIG_BASICAUTH_PASSWORD values from your .env file.
Note: When using a cloud database, there is no need to start the MongoDB container. You can bring up only the Redis services:
docker compose up db-redis redisinsight -d.
The docker-compose.yml includes a bot service that builds and runs the bot alongside all infrastructure (Redis, PostgreSQL / MongoDB).
mv .env.example .env
nano .envPlace the firebase-admin_sdk.json file in:
docker_data/secret/firebase-admin_sdk.json
It will be mounted into the container at src/secret/firebase-admin_sdk.json automatically.
If you use PostgreSQL or MongoDB as storage, this file is not needed.
docker compose up -d --build| Service | URL | Description |
|---|---|---|
| Bot | — | Telegram bot |
| PostgreSQL | localhost:${POSTGRES_PORT} |
Main database (PostgreSQL) |
| pgAdmin | http://localhost:8033 |
PostgreSQL web UI |
| MongoDB | localhost:${MONGO_INITDB_ROOT_PORT} |
Main database (MongoDB) |
| Mongo Express | http://localhost:8082 |
MongoDB web UI |
| Redis | localhost:${REDIS__PORT} |
FSM state storage |
| RedisInsight | http://localhost:5541 |
Redis web UI |
You don't need to start all services at once. For example, if you use PostgreSQL, the MongoDB container can be left unused — it won't affect the bot.
docker compose logs -f bot[Unit]
Description=Telegram Bot | Nexus Shell AI Agent
After=network.target
[Service]
User=your_user
WorkingDirectory=/path/to/nexus-shell
ExecStart=/home/your_user/.local/bin/uv run python src/main.py
Restart=always
RestartSec=5
StandardOutput=append:/var/log/nexus-shell.log
StandardError=append:/var/log/nexus-shell.log
[Install]
WantedBy=multi-user.targetsystemctl daemon-reload
systemctl enable nexus-shell
systemctl start nexus-shell
journalctl -u nexus-shell -f- Gemini — Google AI Studio
- ChatGPT — OpenAI Platform
- Claude — Anthropic Console
- Lapathoniia — Lapathoniia
If you use this software in your research or project, please cite it using the metadata from the CITATION.cff file.