Skip to main content

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

Metadata

Release files for merlya 0.8.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for merlya 0.8.5
File Size Uploaded
merlya-0.8.5.tar.gz 1.1 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for merlya 0.8.5
File Interpreter ABI Platform
merlya-0.8.5-py3-none-any.whl Python 3 none any Details

Total release size: 1.7 MB

Release files / merlya-0.8.5.tar.gz

Download URL merlya-0.8.5.tar.gz
Size 1.1 MB
Tags Source
SHA-256 checksum
How to use checksums
c49211e32e494485cbc692695fb9b5c641bbc4473a3008077d7d78afe3372d07
BLAKE2b-256 checksum
How to use checksums
5e89c27eaff71e98b7538f58e8f7066b91123d829bc7bf3fc7743117dbd35fec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 22, 2026.

Transparency log

Release files / merlya-0.8.5-py3-none-any.whl

Download URL merlya-0.8.5-py3-none-any.whl
Size 592.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cd664832f1281718d8901f59c6edda815d0e99caabbba340171f0281bfcf5bd9
BLAKE2b-256 checksum
How to use checksums
7d50bad815aa1ffa65153f1d6bffa57402f6e5db8ab010cc05b914bc38e0b572
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 22, 2026.

Transparency log
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page