GitHunt
M-

m-kis/merlya

AI-powered infrastructure orchestration tool - Un DevOps IA qui agit avec tes droits SSH.

Merlya Logo

Merlya

AI-powered infrastructure assistant for DevOps & SysAdmins

PyPI Python Downloads License Documentation

Ruff mypy

Read in English


Aperçu

Merlya est un assistant CLI autonome qui comprend le contexte de votre infrastructure, planifie des actions intelligentes et les exécute en toute sécurité. Il combine un SmartExtractor (LLM + regex hybride) pour extraire les hosts des requêtes en langage naturel, un pool SSH sécurisé, et une gestion d'inventaire simplifiée.

Fonctionnalités clés

  • Commandes en langage naturel pour diagnostiquer et remédier vos environnements
  • Architecture spécialistes : MerlyaAgent délègue aux spécialistes (diagnostic, exécution, sécurité) selon la demande
  • Pool SSH async avec MFA/2FA, jump hosts et SFTP
  • Inventaire /hosts avec import intelligent (SSH config, /etc/hosts, Ansible, TOML, CSV)
  • Modèles brain/fast : brain pour le raisonnement complexe, fast pour les décisions rapides
  • Pipelines IaC : Ansible, Terraform, Kubernetes, Bash avec HITL obligatoire
  • Élévation explicite : configuration sudo/doas/su par host (pas d'auto-détection)
  • Sécurité by design : secrets dans le keyring, validation Pydantic, détection de boucles
  • Observabilité : métriques in-memory + circuit breaker / retry (/metrics)
  • i18n : français et anglais
  • Intégration MCP pour consommer des tools externes (GitHub, Slack, custom) via /mcp

Architecture

┌─────────────────────────────────────────────────────────────────────────────┐
│                              USER INPUT                                      │
│                    "Check disk on web-01 via bastion"                       │
└─────────────────────────────────────────────────────────────────────────────┘
                                      │
                                      ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                         SMART EXTRACTOR                                      │
│  ┌─────────────┐    ┌─────────────┐    ┌─────────────┐                      │
│  │ Fast Model  │───▶│   Regex     │───▶│   Hosts     │                      │
│  │ (semantic)  │    │  Patterns   │    │  Inventory  │                      │
│  └─────────────┘    └─────────────┘    └─────────────┘                      │
│  Output: hosts=[web-01], via=bastion, context injected                      │
└─────────────────────────────────────────────────────────────────────────────┘
                                      │
                                      ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                          MERLYA AGENT                                        │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │  System prompt guides delegation decision (no separate classifier)  │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│        │                    │                    │                    │      │
│        ▼                    ▼                    ▼                    ▼      │
│  ┌──────────┐        ┌──────────┐        ┌──────────┐        ┌──────────┐   │
│  │Diagnostic│        │Execution │        │Security  │        │ Query    │   │
│  │Specialist│        │Specialist│        │Specialist│        │Specialist│   │
│  │read-only │        │HITL+pipes│        │sec audits│        │inventory │   │
│  └──────────┘        └──────────┘        └──────────┘        └──────────┘   │
└─────────────────────────────────────────────────────────────────────────────┘
                                      │
                                      ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                           SECURITY LAYER                                     │
│  ┌─────────────┐    ┌─────────────┐    ┌─────────────┐                      │
│  │  Keyring    │    │  Elevation  │    │    Loop     │                      │
│  │  Secrets    │    │  Explicit   │    │  Detection  │                      │
│  │ @secret-ref │    │ (per-host)  │    │ (5+ repeat) │                      │
│  └─────────────┘    └─────────────┘    └─────────────┘                      │
└─────────────────────────────────────────────────────────────────────────────┘
                                      │
                                      ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                            SSH POOL                                          │
│  ┌─────────────┐    ┌─────────────┐    ┌─────────────┐                      │
│  │ Connection  │    │  Jump Host  │    │    MFA      │                      │
│  │   Reuse     │    │   Support   │    │   Support   │                      │
│  └─────────────┘    └─────────────┘    └─────────────┘                      │
└─────────────────────────────────────────────────────────────────────────────┘
                                      │
                                      ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                          PERSISTENCE                                         │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐       │
│  │  Hosts   │  │ Sessions │  │  Audit   │  │ Raw Logs │  │ Messages │       │
│  │ Inventory│  │ Context  │  │   Logs   │  │  (TTL)   │  │ History  │       │
│  └──────────┘  └──────────┘  └──────────┘  └──────────┘  └──────────┘       │
│                         SQLite + Keyring                                     │
└─────────────────────────────────────────────────────────────────────────────┘

Installation (utilisateurs finaux)

pip install merlya
merlya

Installation Docker

# Copier et configurer les variables d'environnement
cp .env.example .env
# Éditer .env avec vos clés API

# Lancer le conteneur
docker compose up -d

# Mode développement (code source monté)
docker compose --profile dev up -d

Configuration SSH pour Docker :

Le conteneur monte votre répertoire SSH local. Par défaut, il utilise $HOME/.ssh.

Dans les environnements CI/CD où $HOME peut ne pas être défini, vous devez explicitement définir SSH_DIR :

# Via variable d'environnement
SSH_DIR=/root/.ssh docker compose up -d

# Ou dans votre fichier .env
SSH_DIR=/home/jenkins/.ssh

Permissions requises :

  • Répertoire SSH : 700 (rwx pour propriétaire uniquement)
  • Clés privées : 600 (rw pour propriétaire uniquement)

Voir .env.example pour la documentation complète des variables.

Premier démarrage

  1. Sélection de la langue (fr/en)
  2. Configuration du provider LLM (clé stockée dans le keyring)
  3. Scan local et import d’hôtes (SSH config, /etc/hosts, inventaires Ansible)
  4. Health checks (RAM, disque, LLM, SSH, keyring, web search)

Exemples rapides

> Check disk usage on web-prod-01
> /hosts list
> /ssh exec db-01 "uptime"
> /model show
> /metrics
> /variable set region eu-west-1
> /mcp list

Syntaxe des targets :

  • @web-01 → lookup inventaire (hostname + username résolus depuis la base)
  • ubuntu@192.168.1.5 → utilisateur SSH explicite + IP
  • 192.168.1.5 → IP directe (username depuis l'inventaire si connu)
  • @db-password → référence secret dans le keyring (résolu à l'exécution)

Sécurité

Secrets — jamais exposés au LLM

Les secrets (mots de passe, tokens, clés API) sont stockés dans le keyring système (macOS Keychain, Linux Secret Service) et référencés par @nom-secret :

> Connect to MongoDB with @db-password
# Le LLM voit "@db-password", jamais la valeur réelle
# Résolution uniquement au moment de l'exécution
# Logs : "mongo -p ***", jamais la vraie valeur

HITL — confirmation obligatoire

Toute opération destructive (restart, écriture fichier, installation) requiert une confirmation explicite avant exécution. L'ExecutionSpecialist ne peut pas contourner ce mécanisme.

Élévation de privilèges

L'élévation (sudo, doas, su) est toujours explicite — jamais auto-détectée. Elle se configure par host et les mots de passe sont stockés dans le keyring sous elevation:hostname:password.

Détection de boucles

Le ToolCallTracker détecte les patterns répétitifs (même commande 3+ fois, alternance A-B-A-B) et stoppe l'exécution automatiquement.

Configuration

  • Fichier utilisateur : ~/.merlya/config.yaml (langue, modèle, timeouts SSH, UI).
  • Clés API : stockées dans le keyring. Fallback en mémoire avec avertissement.
  • Variables d'environnement utiles :
Variable Description
OPENROUTER_API_KEY Clé OpenRouter (provider par défaut)
ANTHROPIC_API_KEY Clé Anthropic
OPENAI_API_KEY Clé OpenAI
MISTRAL_API_KEY Clé Mistral
GROQ_API_KEY Clé Groq
MERLYA_ROUTER_FALLBACK Modèle LLM de fallback pour le routage

Installation pour contributeurs

git clone https://github.com/m-kis/merlya.git
cd merlya
python -m venv .venv
source .venv/bin/activate  # ou .venv\\Scripts\\activate sous Windows
pip install -e ".[dev]"    # Dépendances de dev

merlya --version
pytest tests/ -v

Qualité et scripts

Vérification Commande
Lint ruff check merlya/
Format (check) ruff format --check merlya/
Type check mypy merlya/
Tests + coverage pytest tests/ --cov=merlya --cov-report=term-missing
Sécurité (code) bandit -r merlya/ -c pyproject.toml
Sécurité (dépendances) pip-audit -r <(pip freeze)

Principes clés : DRY/KISS/YAGNI, SOLID, SoC, LoD, pas de fichiers > ~600 lignes, couverture ≥ 80%, commits conventionnels (cf. CONTRIBUTING.md).

CI/CD

  • .github/workflows/ci.yml : lint + format check + mypy + tests + sécurité (Bandit + pip-audit) sur runners GitHub pour chaque PR/push.
  • .github/workflows/release.yml : build + release GitHub + publication PyPI via trusted publishing, déclenché sur tag v* ou workflow_dispatch par un mainteneur (pas de secrets sur les PR externes).
  • Branche main protégée : merge via PR, CI requis, ≥1 review, squash merge recommandé.

Documentation

📚 Documentation complète : https://merlya.m-kis.fr/

Fichiers locaux :

Contribuer

  • Lisez CONTRIBUTING.md pour les conventions (commits, branches, limites de taille de fichiers/fonctions).
  • Respectez le CODE_OF_CONDUCT.md.
  • Les templates d’issues et de PR sont disponibles dans .github/.

Sécurité

Consultez SECURITY.md. Ne publiez pas de vulnérabilités en issue publique : écrivez à security@merlya.fr.

Licence

MIT avec Commons Clause. La Commons Clause interdit la vente du logiciel comme service hébergé tout en autorisant l’usage, la modification et la redistribution.


Made by M-KIS