AI Agent Framework for Self-Hosted LLMs β deploy on your infrastructure, keep data private.
π― Built for companies and developers who need:
- 100% on-premise AI agents (no data leaves your network)
- Any OpenAI-compatible LLM (vLLM, Ollama, llama.cpp, text-generation-webui)
- Production-ready security (battle-tested by 1500+ hackers)
- Simple deployment (
docker compose upand you're done)
Unlike cloud-dependent solutions, LocalTopSH runs entirely on your infrastructure:
| Problem | Cloud Solutions | LocalTopSH |
|---|---|---|
| Data Privacy | Data sent to external APIs | β Everything stays on-premise |
| Compliance | Hard to audit | β Full control, easy audit |
| API Access | Need OpenAI/Anthropic account | β Any OpenAI-compatible endpoint |
| Sanctions/Restrictions | Blocked in some regions | β Works anywhere |
| Cost at Scale | $0.01-0.03 per 1K tokens | β Only electricity costs |
| Backend | Example Models | Setup |
|---|---|---|
| vLLM | gpt-oss-120b, Qwen-72B, Llama-3-70B | vllm serve model --api-key dummy |
| Ollama | Llama 3, Mistral, Qwen, 100+ models | ollama serve |
| llama.cpp | Any GGUF model | llama-server -m model.gguf |
| text-generation-webui | Any HuggingFace model | Enable OpenAI API extension |
| LocalAI | Multiple backends | Docker compose included |
| LM Studio | Desktop-friendly | Built-in server mode |
| Solution | Daily Cost | Monthly Cost |
|---|---|---|
| OpenAI GPT-4 | ~$30 | ~$900 |
| Anthropic Claude | ~$15 | ~$450 |
| Self-hosted (LocalTopSH) | Electricity only | ~$50-100 (GPU power) |
- β Russia, Belarus, Iran β sanctions don't apply to self-hosted
- β China β no Great Firewall issues
- β Air-gapped networks β zero internet required
- β On-premise data centers β full compliance
# Option A: vLLM (recommended for production)
vllm serve gpt-oss-120b --api-key dummy --port 8000
# Option B: Ollama (easy setup)
ollama serve # Default port 11434
# Option C: llama.cpp (minimal resources)
llama-server -m your-model.gguf --port 8000git clone https://github.com/vakovalskii/topsha
cd topsha
# Run setup script (creates directories with correct permissions)
./setup.sh
# Edit secrets with your credentials
nano secrets/telegram_token.txt # Your bot token from @BotFather
nano secrets/base_url.txt # http://your-llm-server:8000/v1
nano secrets/api_key.txt # Your API key (or "dummy" if not needed)
nano secrets/model_name.txt # Model name (e.g. gpt-oss-120b)
nano secrets/zai_api_key.txt # Z.AI search key (optional)Alternative (manual setup):
# Create directories
mkdir -p secrets workspace workspace/_shared
chmod -R 777 workspace # Important: Docker containers need write access
# Create secrets
echo "your-telegram-token" > secrets/telegram_token.txt
echo "http://your-llm-server:8000/v1" > secrets/base_url.txt
echo "dummy" > secrets/api_key.txt
echo "changeme123" > secrets/admin_password.txt
chmod 600 secrets/*.txtdocker compose up -d
# Check status
docker compose ps
# View logs
docker compose logs -f- Telegram Bot: Message your bot
- Admin Panel: http://localhost:3000 (login: admin / password from
secrets/admin_password.txt) - API: http://localhost:4000/api
# Change default admin password (REQUIRED for production!)
echo "your-secure-password" > secrets/admin_password.txt
# Optionally change admin username via environment variable
# Edit docker-compose.yml and set ADMIN_USER=your_username
# Rebuild admin container
docker compose up -d --build admin
β οΈ Default credentials: admin / changeme123 β change them before exposing to network!
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β YOUR INFRASTRUCTURE β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β βββββββββββββββββββ βββββββββββββββββββ ββββββββββββββββββββββββββββββββ
β β Telegram β β LocalTopSH β β Your LLM Backend ββ
β β (optional) ββββββΆβ Agent Stack ββββββΆβ ββββββββββββββββββββββββ ββ
β βββββββββββββββββββ β β β vLLM / Ollama / llama.cpp ββ
β β βββββββββββββ β β gpt-oss-120b βοΏ½οΏ½οΏ½
β βββββββββββββββββββ β β core β β β Qwen-72B ββ
β β Admin Panel ββββββΆβ β (agent) β β β Llama-3-70B ββ
β β :3000 β β βββββββββββββ β β Mistral-22B ββ
β βββββββββββββββββββ β β β β Your fine-tuned model ββ
β β βΌ β ββββββββββββββββββββββββββββββββ
β β βββββββββββββ β β
β β β sandbox β β No data leaves your network! β
β β β (per-user)β β β
β β βββββββββββββ β β
β βββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π₯ Stress-tested by 1500+ hackers in @neuraldeepchat
Attack attempts: Token extraction, RAM exhaustion, container escapes
Result: 0 secrets leaked, 0 downtime
| Layer | Protection | Details |
|---|---|---|
| Access Control | DM Policy | admin/allowlist/pairing/public modes |
| Input Validation | Blocked patterns | 247 dangerous commands blocked |
| Injection Defense | Pattern matching | 19 prompt injection patterns |
| Sandbox Isolation | Docker per-user | 512MB RAM, 50% CPU, 100 PIDs |
| Secrets Protection | Proxy architecture | Agent never sees API keys |
# Run security doctor (46 checks)
python scripts/doctor.py
# Run E2E tests (10 checks)
python scripts/e2e_test.py --verbose| Category | Features |
|---|---|
| System | Shell execution, file operations, code execution |
| Web | Search (Z.AI), page fetching, link extraction |
| Memory | Persistent notes, task management, chat history |
| Automation | Scheduled tasks, background jobs |
| Telegram | Send files, DMs, message management |
| Feature | Description |
|---|---|
| Skills | Anthropic-compatible skill packages |
| MCP | Model Context Protocol for external tools |
| Tools API | Dynamic tool loading and management |
| Admin Panel | Web UI for configuration and monitoring |
| Container | Port | Role |
|---|---|---|
| core | 4000 | ReAct Agent, security, sandbox orchestration |
| bot | 4001 | Telegram Bot (aiogram) |
| proxy | 3200 | Secrets isolation, LLM proxy |
| tools-api | 8100 | Tool registry, MCP, skills |
| admin | 3000 | Web admin panel (React) |
| sandbox_{id} | 5000-5999 | Per-user isolated execution |
| Secret | Required | Description |
|---|---|---|
telegram_token.txt |
β | Bot token from @BotFather |
base_url.txt |
β | LLM API URL (e.g. http://vllm:8000/v1) |
api_key.txt |
β | LLM API key (use dummy if not required) |
model_name.txt |
β | Model name (e.g. gpt-oss-120b) |
zai_api_key.txt |
β | Z.AI search key |
admin_password.txt |
β | Admin panel password (default: changeme123) |
echo "http://vllm-server:8000/v1" > secrets/base_url.txt
echo "dummy" > secrets/api_key.txt
echo "gpt-oss-120b" > secrets/model_name.txtecho "http://ollama:11434/v1" > secrets/base_url.txt
echo "ollama" > secrets/api_key.txt
echo "llama3:70b" > secrets/model_name.txtecho "http://your-server:8000/v1" > secrets/base_url.txt
echo "your-api-key" > secrets/api_key.txt
echo "your-model-name" > secrets/model_name.txtWeb panel at :3000 for managing the system (protected by Basic Auth):
# Default credentials
Username: admin
Password: (from secrets/admin_password.txt, default: changeme123)
# Change password
echo "your-secure-password" > secrets/admin_password.txt
docker compose up -d --build admin
# Change username (optional)
# In docker-compose.yml, set environment variable:
# ADMIN_USER=your_username| Page | Features |
|---|---|
| Dashboard | Stats, active users, sandboxes |
| Services | Start/stop containers |
| Config | Agent settings, rate limits |
| Security | Blocked patterns management |
| Tools | Enable/disable tools |
| MCP | Manage MCP servers |
| Skills | Install/manage skills |
| Users | Sessions, chat history |
| Logs | Real-time service logs |
Admin panel is bound to 127.0.0.1:3000 for security. For remote access:
# On your local machine
ssh -L 3000:localhost:3000 user@your-server
# Then open http://localhost:3000 in browser| Feature | LocalTopSH | OpenClaw | LangChain |
|---|---|---|---|
| Self-hosted LLM | β Native | β Yes | |
| Security hardening | β 247 patterns | Basic | β None |
| Sandbox isolation | β Docker per-user | β Docker | β None |
| Admin panel | β React UI | β React UI | β None |
| Telegram integration | β Native | β Multi-channel | β None |
| Setup complexity | Simple | Complex | Code-only |
| OAuth/subscription abuse | β No | β Yes | β No |
| 100% on-premise | β Yes | β Yes |
- Internal AI assistant with full data privacy
- Code review bot that never leaks proprietary code
- Document analysis without sending files to cloud
- Experiment with open models (Llama, Mistral, Qwen)
- Fine-tuned model deployment with agent capabilities
- Reproducible AI workflows in isolated environments
- Russia/Belarus/Iran β no API access restrictions
- China β no Great Firewall issues
- Air-gapped networks β military, government, finance
- High-volume workloads β pay for GPU, not per-token
- Predictable costs β no surprise API bills
- Scale without limits β your hardware, your rules
Symptom: 500 Internal Server Error when changing access mode, or errors like:
Permission denied: '/workspace/_shared/admin_config.json'
Permission denied: '/workspace/123456789/'
Cause: Docker containers (running as root) can't write to bind-mounted workspace/ directory.
Solution:
# Fix permissions on host
chmod -R 777 workspace/
# Or run setup script again
./setup.shPrevention: Always use ./setup.sh for initial setup β it creates directories with correct permissions.
Symptom: Bot shows online but doesn't reply to messages.
Diagnosis:
- Check if
corecontainer is running:docker ps | grep core - Check logs:
docker logs core --tail 50 - Verify access mode: Admin panel β Config β Access
Common causes:
- Access mode set to
admin_onlybutADMIN_USER_IDnot configured - Bot token invalid or expired
- LLM API unreachable (check
base_urlin secrets)
Solution:
# Set admin user ID
echo "YOUR_TELEGRAM_ID" > .env
# Add line: ADMIN_USER_ID=123456789
# Or set access mode to public (for testing)
docker compose restart coreSymptom: docker ps shows containers constantly restarting.
Diagnosis:
docker logs core --tail 100
docker logs bot --tail 100Common causes:
- Missing or invalid secrets (telegram_token, api_key, base_url)
- LLM server not accessible
- Port conflicts (3000, 4000, 4001 already in use)
Solution:
- Verify all required secrets exist and are valid
- Test LLM connection:
curl http://your-llm-server:8000/v1/models - Check port availability:
netstat -tuln | grep -E '3000|4000|4001'
We believe in building real infrastructure, not hacks.
| Approach | LocalTopSH β | Subscription Abuse β |
|---|---|---|
| LLM Access | Your own models/keys | Stolen browser sessions |
| Cost Model | Pay for hardware | Violate ToS, risk bans |
| Reliability | 100% uptime (your infra) | Breaks when UI changes |
| Security | Full control | Cookies stored who-knows-where |
| Ethics | Transparent & legal | Gray area at best |
MIT
- Architecture: ARCHITECTURE.md β detailed system design
- Security: SECURITY.md β security model and patterns
- Telegram: @neuraldeepchat