Skip to main content
Glama
GLPI MCP

GLPI MCP

by USONDIG

GLPI MCP

Déploiement distant : Render gratuit avec MCP Streamable HTTP authentifié.

License: Unlicense

🇫🇷 Français | 🇬🇧 English


Français

Serveur MCP (Model Context Protocol) permettant à un assistant IA — comme Claude — d'interagir directement avec votre instance GLPI via son API REST.

Compatible GLPI 10 (endpoint apirest.php) et GLPI 11 (endpoint api.php/v1).

Une fois configuré, Claude peut consulter, créer et mettre à jour des tickets, ajouter des suivis et des tâches, poster des solutions, gérer la base de connaissances, tenir le registre des fournisseurs, contacts et contrats, et produire des statistiques, le tout en langage naturel depuis votre conversation.


Prérequis

1. GLPI

  • GLPI 10.x ou 11.x (l'API REST est activée par défaut)

  • L'API REST doit être activée : Configuration → Générale → API → Activer l'API Rest → Oui

  • Un App-Token créé dans GLPI : Configuration → Générale → API → Ajouter un client API

  • Un User-Token associé à votre compte : Mon profil → API → Régénérer

⚠️ Le compte associé au User-Token doit avoir les droits suffisants sur les tickets dans GLPI (lecture, écriture, suppression selon l'usage souhaité).

2. Python

  • Python 3.12 ou supérieur

  • uv (recommandé)

# Vérifier la version Python
python --version

# Installer uv si nécessaire
pip install uv

3. Claude Desktop

  • Claude Desktop installé sur votre machine

  • Un compte Claude avec accès aux intégrations MCP (plan Pro ou supérieur)


Related MCP server: glpi-mcp

Installation

1. Cloner le dépôt

git clone https://github.com/svtica/glpi-mcp.git
cd glpi-mcp

2. Installer les dépendances

uv sync

Configuration (par utilisateur)

Le serveur lit ses credentials depuis un fichier config.json situé dans le même dossier que server.py. Ce fichier est individuel à chaque utilisateur et ne doit jamais être versionné (il est dans .gitignore).

Créer votre config.json

Copiez le fichier exemple et renseignez vos valeurs :

cp config.example.json config.json

Les valeurs doivent être encodées en base64 :

PowerShell :

[Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("https://glpi.monentreprise.ca"))

Linux / macOS :

echo -n "https://glpi.monentreprise.ca" | base64

Renseignez ensuite les champs dans config.json :

Champ

Description

GLPI_URL

URL de base de votre instance GLPI (sans / final)

GLPI_APP_TOKEN

App-Token créé dans la configuration API GLPI

GLPI_USER_TOKEN

User-Token de votre compte GLPI

LANG

Langue des libellés : fr (défaut) ou en — non encodé en base64

GLPI_VERSION

Version GLPI : 10 (défaut) ou 11 — non encodé en base64

VERIFY_TLS

Validation du certificat TLS de GLPI : false (défaut) ou true — booléen simple, non encodé en base64

Vous pouvez aussi utiliser des variables d'environnement (GLPI_URL, GLPI_APP_TOKEN, GLPI_USER_TOKEN, GLPI_LANG, GLPI_VERSION, GLPI_VERIFY_TLS) à la place du fichier config.json.

⚠️ VERIFY_TLS vaut false par défaut, ce qui désactive la validation du certificat de votre instance GLPI. C'est le réglage prévu pour un GLPI intranet derrière un certificat auto-signé ou une AC privée absente du magasin certifi de Python. Passez à true dès que l'AC interne est distribuée à certifi : sur un GLPI accessible hors du réseau interne, laisser false expose la connexion — et donc vos jetons d'API — à une interception.

Versions GLPI supportées

Version

Endpoint API

Authentification

GLPI 10

apirest.php

App-Token + User-Token → Session-Token

GLPI 11

api.php/v1

App-Token + User-Token → Session-Token (même mécanisme)

Le champ GLPI_VERSION détermine quel préfixe d'endpoint est utilisé. Les deux versions utilisent la même authentification par session (initSession). Tous les outils sont compatibles avec les deux versions.


Intégration avec Claude Desktop

Méthode 1 — Claude Extensions (recommandée)

Copiez le contenu du projet dans votre dossier Claude Extensions :

%APPDATA%\Claude\Claude Extensions\ant.dir.svtica.glpi-mcp\

Créez-y votre config.json personnel avec vos credentials (voir section précédente).

Le dossier doit contenir un fichier manifest.json :

{
  "manifest_version": "0.2",
  "name": "GLPI-MCP",
  "version": "0.1.0",
  "description": "Serveur MCP pour l'integration GLPI",
  "author": { "name": "Votre Nom", "url": "" },
  "server": {
    "type": "python",
    "entry_point": "server.py",
    "mcp_config": {
      "command": "uv",
      "args": ["--directory", "${__dirname}", "run", "python", "server.py"]
    }
  }
}

Redémarrez Claude Desktop. Chaque utilisateur de la machine copie ses propres fichiers dans son dossier %APPDATA% avec son propre config.json.

Méthode 2 — claude_desktop_config.json (manuelle)

Ouvrez le fichier de configuration de Claude Desktop :

  • Windows : %APPDATA%\Claude\claude_desktop_config.json

  • macOS : ~/Library/Application Support/Claude/claude_desktop_config.json

Ajoutez la section mcpServers :

Windows

{
  "mcpServers": {
    "glpi": {
      "command": "uv",
      "args": [
        "--directory",
        "C:\\Chemin\\vers\\glpi-mcp",
        "run",
        "python",
        "server.py"
      ]
    }
  },
  "preferences": {
    "coworkScheduledTasksEnabled": false,
    "sidebarMode": "code"
  }
}

macOS / Linux

{
  "mcpServers": {
    "glpi": {
      "command": "uv",
      "args": [
        "--directory",
        "/chemin/vers/glpi-mcp",
        "run",
        "python",
        "server.py"
      ]
    }
  }
}

⚠️ Assurez-vous que le JSON est valide — une accolade ou une virgule manquante suffit à empêcher Claude Desktop de charger la configuration. Utilisez un validateur JSON si nécessaire.

Redémarrez Claude Desktop. Si la configuration est correcte, une icône 🔌 apparaîtra dans la barre d'outils de Claude indiquant que le serveur MCP est connecté.


Outils disponibles

🔐 Session

Outil

Description

kill_session

Ferme proprement la session GLPI active

🎫 Tickets

Outil

Description

list_tickets

Liste les tickets avec pagination et filtres (statut, type)

get_ticket

Détail complet d'un ticket avec libellés lisibles

search_tickets

Recherche avancée par mots-clés, statut, type, catégorie, assigné

create_ticket

Crée un nouveau ticket

update_ticket

Modifie les champs d'un ticket existant

delete_ticket

Supprime un ticket

link_tickets

Lie deux tickets entre eux (lié, doublon, enfant, parent)

list_ticket_links

Liste tous les liens d'un ticket

merge_tickets

Fusionne des tickets source vers un ticket cible (copie suivis, lie comme doublon, ferme les sources)

💬 Suivis

Outil

Description

list_followups

Liste tous les suivis d'un ticket

get_followup

Détail d'un suivi

add_followup

Ajoute un suivi (public ou privé)

update_followup

Modifie un suivi existant (contenu, visibilité)

delete_followup

Supprime un suivi — destructif, retire la pièce de la piste d'audit

✅ Tâches

Outil

Description

list_tasks

Liste les tâches d'un ticket

add_task

Crée une tâche sur un ticket

update_task

Modifie une tâche (statut, durée, assigné)

delete_task

Supprime une tâche

💡 Solutions

Outil

Description

get_solution

Lit la solution d'un ticket

add_solution

Poste une solution (clôture le ticket selon la config GLPI)

📊 Statistiques

Outil

Description

stats_by_status

Nombre de tickets par statut

stats_by_type

Répartition Incidents / Demandes de service

stats_by_priority

Tickets ouverts par priorité

stats_by_category

Nombre de tickets par catégorie ITIL

stats_by_assignee

Tickets par technicien assigné

stats_resolution_time

Délai moyen de résolution des tickets

stats_overdue

Tickets en retard par rapport au SLA

📚 Base de connaissances

Outil

Description

list_kb_articles

Liste les articles avec pagination. Si range_start > 60 et range_limit > 10, range_limit est auto-clampé à 10 (les contenus HTML complets dans la réponse JSON dépassent souvent le memory_limit PHP-FPM côté GLPI au-delà). Quand le clamp s'applique, la réponse est un dict {"_clamped_range_limit": 10, "_warning": "...", "items": [...]} au lieu d'une liste.

get_kb_article

Détail complet d'un article

search_kb_articles

Recherche par mots-clés (titre par défaut ; passer search_content=True pour inclure le corps HTML — lent sans index FULLTEXT MySQL sur knowbaseitems.answer)

create_kb_article

Crée un nouvel article (titre, contenu HTML, catégorie, FAQ)

update_kb_article

Met à jour un article existant

list_kb_categories

Liste les catégories de la base de connaissances

get_kb_article_visibility

Lit les règles de visibilité d'un article (profils, groupes, utilisateurs, entités)

add_kb_article_visibility_profile

Ajoute un profil à la visibilité d'un article

add_kb_article_visibility_group

Ajoute un groupe à la visibilité d'un article

update_kb_article_visibility_profile

Modifie une règle de visibilité par profil existante

update_kb_article_visibility_group

Modifie une règle de visibilité par groupe existante

Note : La suppression de règles de visibilité n'est pas exposée volontairement afin de conserver un historique des procédures même obsolètes.

📋 Référentiels

Outil

Description

list_itil_categories

Liste les catégories ITIL disponibles

get_users

Liste les utilisateurs GLPI

get_groups

Liste les groupes GLPI

🏢 Fournisseurs, contacts et contrats

Outil

Description

list_suppliers

Liste les fournisseurs (filtre name_contains, only_active, pagination)

create_supplier

Crée un fournisseur (name obligatoire, coordonnées optionnelles)

create_contact

Crée un contact ; rattachement optionnel à un fournisseur via supplier_id

create_contract

Crée un contrat ; rattachement optionnel à un fournisseur via supplier_id

update_supplier

Met à jour un fournisseur (update_fields : champs à modifier uniquement)

update_contact

Met à jour un contact

update_contract

Met à jour un contrat

delete_supplier

Met un fournisseur à la corbeille ; purge=True pour supprimer définitivement

delete_contact

Met un contact à la corbeille ; purge=True pour supprimer définitivement

delete_contract

Met un contrat à la corbeille ; purge=True pour supprimer définitivement

Note : list_suppliers filtre sur les fournisseurs actifs par défaut. Passer only_active=False pour inclure les fournisseurs désactivés.

Note : Pour create_contract, les champs duration, notice, periodicity et billing s'expriment en mois (convention GLPI), et begin_date au format AAAA-MM-JJ.

Note : Quand supplier_id est fourni, l'entrée de liaison (Contact_Supplier / Contract_Supplier) est créée dans un second appel et son résultat est retourné sous la clé _supplier_link. Si la création du contact ou du contrat échoue, aucune liaison n'est tentée.

⚠️ Suppression — corbeille par défaut, purge sur demande. Sans argument, delete_* place l'élément à la corbeille GLPI (is_deleted = 1) : il reste rattaché à ses contrats, contacts, matériels et tickets, et se restaure avec l'outil update_* correspondant et {"is_deleted": 0}. Avec purge=True, la suppression est définitive et irréversible et casse ces rattachements. Réserver la purge aux doublons et aux saisies erronées.

🖥️ Matériel / Assets

Tool

Description

list_assets

Liste les actifs par type avec pagination et filtre optionnel sur le nom

get_asset

Lit un actif précis par type et ID

search_assets

Recherche un actif par nom via l'API de recherche GLPI et les listSearchOptions dynamiques

create_asset

Crée un actif à partir de champs GLPI

update_asset

Modifie uniquement les champs fournis

delete_asset

Met l'actif à la corbeille par défaut ; purge=True force une suppression définitive

Types pris en charge : Computer, Monitor, NetworkEquipment, Printer, Peripheral, Phone. Le type AllAssets est disponible en lecture/recherche uniquement.

Sécurité : utilisez purge=True uniquement lorsqu'une suppression définitive et irréversible est explicitement demandée. Pour les créations et modifications, les dictionnaires fields sont transmis comme champs GLPI : n'inventez pas les IDs de références (locations_id, states_id, manufacturers_id, users_id, etc.).


Exemples d'utilisation avec Claude

« Montre-moi tous les incidents ouverts en haute priorité »

« Crée un ticket de demande de service pour l'installation d'Adobe Acrobat pour Marie Tremblay »

« Ajoute un suivi sur le ticket #4521 pour informer l'utilisateur que le problème est en cours d'investigation »

« Fusionne les tickets #4530 et #4531 vers le ticket #4521 »

« Lie le ticket #4530 au ticket #4521 comme doublon »

« Quelles sont les statistiques de tickets par statut ? »

« Quel est le délai moyen de résolution des tickets ? »

« Montre-moi les tickets en retard par rapport au SLA »

« Cherche dans la base de connaissances une solution pour les problèmes VPN »

« Qui peut voir l'article #120 de la base de connaissances ? »

« Ajoute le groupe Techniciens à la visibilité de l'article #120 »

« Quels fournisseurs avons-nous pour la téléphonie ? »

« Ajoute Acme Télécom au registre des fournisseurs, puis crée le contrat d'entretien CT-2026-014 qui débute le 1er avril pour 36 mois »

« Désactive le fournisseur Acme Télécom — on ne fait plus affaire avec eux, mais garde l'historique des contrats »

« Clôture le ticket #4102 avec comme solution : redémarrage du service résolvant le problème »


Mappings de référence

Statuts

Code

Libellé

1

Nouveau

2

En cours (attribué)

3

En cours (planifié)

4

En attente

5

Résolu

6

Clos

Types

Code

Libellé

1

Incident

2

Demande de service

Priorités / Urgences / Impacts

Code

Libellé

1

Très basse

2

Basse

3

Moyenne

4

Haute

5

Très haute

6

Majeure

Types de liens entre tickets

Code

Libellé

1

Lié à

2

Duplique

3

Enfant de

4

Parent de


Dépannage

Le serveur n'apparaît pas dans Claude Desktop

  • Vérifiez la syntaxe JSON du fichier de configuration (pas de virgule manquante ou en trop, pas d'accolade en trop)

  • Vérifiez que le chemin vers le dossier est correct et absolu

  • Redémarrez complètement Claude Desktop

  • Assurez-vous que le dossier %APPDATA%\Claude\connectors\ existe (créez-le si nécessaire)

Erreur 401 à chaque appel

  • Vérifiez que GLPI_APP_TOKEN et GLPI_USER_TOKEN sont corrects dans votre config.json

  • Vérifiez que l'API REST est bien activée dans GLPI

  • Vérifiez que le client API dans GLPI est actif et que l'IP est autorisée

Erreur de connexion / timeout

  • Vérifiez que GLPI_URL est accessible depuis la machine qui exécute le serveur

  • Vérifiez qu'aucun pare-feu ne bloque la connexion

  • Toutes les requêtes HTTP ont un délai maximal de 30 secondes (10 s pour la connexion). Au-delà, l'outil retourne un dict structuré avec les clés error et detail (libellés tirés de la table LANG) au lieu de pendre — par défaut en français : {"error": "Timeout HTTP", "detail": "Requête > 30s — voir GLPI logs"}. Si vous obtenez ce message de façon répétée, vérifiez les logs PHP-FPM/MySQL côté GLPI : la requête sous-jacente est probablement trop coûteuse (souvent une recherche full-text sans index).

Environnement corporatif — Proxy SSL intercepteur (Zscaler, Forcepoint, etc.)

En environnement d'entreprise, un proxy SSL peut intercepter les connexions HTTPS et remplacer les certificats par un certificat interne. Cela provoque l'erreur suivante lors de l'installation des dépendances par uv :

× Failed to download `python-dotenv==X.X.X`
╰─▶ invalid peer certificate: UnknownIssuer

Solution : Forcer uv à utiliser le magasin de certificats Windows avec la variable d'environnement UV_NATIVE_TLS.

Pour tester manuellement dans PowerShell :

$env:UV_NATIVE_TLS=1
uv run python server.py

Pour que Claude Desktop passe automatiquement cette variable au démarrage du serveur, ajoutez une section env dans votre claude_desktop_config.json :

{
  "mcpServers": {
    "glpi": {
      "command": "uv",
      "args": [
        "--directory",
        "C:\\Chemin\\vers\\glpi-mcp",
        "run",
        "python",
        "server.py"
      ],
      "env": {
        "UV_NATIVE_TLS": "1"
      }
    }
  }
}

Environnement corporatif — Antivirus / EDR bloquant uv (Riskware)

Certains antivirus ou solutions EDR d'entreprise peuvent catégoriser uv.exe comme Riskware car il télécharge des exécutables et des packages depuis Internet. Si uv est bloqué par votre solution de sécurité :

  • Contactez votre équipe TI pour qu'elle ajoute une exception pour uv.exe (situé dans %USERPROFILE%\.local\bin\uv.exe)

  • Demandez également d'autoriser les domaines : pypi.org, files.pythonhosted.org, astral.sh

En alternative, demandez à un collègue ayant uv fonctionnel de vous transmettre le dossier .venv déjà généré, ce qui évite tout téléchargement.

Alléger les dépendances

Le projet dépend de mcp[cli] qui inclut l'extra [cli] (typer, rich, click, shellingham, pygments, markdown-it-py…). Cet extra fournit les commandes de développement mcp dev et mcp inspect, utiles pour le débogage.

Si vous souhaitez réduire l'empreinte en production (environ 8 packages en moins), modifiez pyproject.toml :

# Avant (avec outillage CLI)
dependencies = ["mcp[cli]>=1.9.4", "httpx>=0.27"]

# Après (sans outillage CLI — production allégée)
dependencies = ["mcp>=1.9.4", "httpx>=0.27"]

Puis relancez uv sync pour mettre à jour l'environnement.



English

MCP (Model Context Protocol) server that allows an AI assistant — such as Claude — to interact directly with your GLPI instance via its REST API.

Compatible with GLPI 10 (endpoint apirest.php) and GLPI 11 (endpoint api.php/v1).

Once configured, Claude can view, create and update tickets, add followups and tasks, post solutions, manage the knowledge base, maintain the supplier, contact and contract registry, and generate statistics, all in natural language from your conversation.


Prerequisites

1. GLPI

  • GLPI 10.x or 11.x (REST API is enabled by default)

  • REST API must be enabled: Setup → General → API → Enable Rest API → Yes

  • An App-Token created in GLPI: Setup → General → API → Add an API client

  • A User-Token associated with your account: My profile → API → Regenerate

⚠️ The account associated with the User-Token must have sufficient permissions on tickets in GLPI (read, write, delete as needed).

2. Python

  • Python 3.12 or higher

  • uv (recommended)

# Check Python version
python --version

# Install uv if needed
pip install uv

3. Claude Desktop

  • Claude Desktop installed on your machine

  • A Claude account with access to MCP integrations (Pro plan or higher)


Installation

1. Clone the repository

git clone https://github.com/svtica/glpi-mcp.git
cd glpi-mcp

2. Install dependencies

uv sync

Configuration (per user)

The server reads its credentials from a config.json file located in the same folder as server.py. This file is individual to each user and must never be version-controlled (it is in .gitignore).

Create your config.json

Copy the example file and fill in your values:

cp config.example.json config.json

Values must be encoded in base64:

PowerShell:

[Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("https://glpi.mycompany.com"))

Linux / macOS:

echo -n "https://glpi.mycompany.com" | base64

Then fill in the fields in config.json:

Field

Description

GLPI_URL

Base URL of your GLPI instance (without trailing /)

GLPI_APP_TOKEN

App-Token created in GLPI API configuration

GLPI_USER_TOKEN

User-Token from your GLPI account

LANG

Label language: fr (default) or en — not base64-encoded

GLPI_VERSION

GLPI version: 10 (default) or 11 — not base64-encoded

VERIFY_TLS

Validate the GLPI TLS certificate: false (default) or true — plain boolean, not base64-encoded

You can also use environment variables (GLPI_URL, GLPI_APP_TOKEN, GLPI_USER_TOKEN, GLPI_LANG, GLPI_VERSION, GLPI_VERIFY_TLS) instead of the config.json file.

⚠️ VERIFY_TLS defaults to false, which disables certificate validation for your GLPI instance. That is the intended setting for an intranet GLPI behind a self-signed certificate or a private CA missing from Python's certifi bundle. Switch it to true as soon as the internal CA is distributed to certifi: on a GLPI reachable from outside the internal network, leaving it false exposes the connection — and therefore your API tokens — to interception.

Supported GLPI versions

Version

API Endpoint

Authentication

GLPI 10

apirest.php

App-Token + User-Token → Session-Token

GLPI 11

api.php/v1

App-Token + User-Token → Session-Token (same mechanism)

The GLPI_VERSION field determines which endpoint prefix is used. Both versions use the same session-based authentication (initSession). All tools are compatible with both versions.


Integration with Claude Desktop

Copy the project contents to your Claude Extensions folder:

%APPDATA%\Claude\Claude Extensions\ant.dir.svtica.glpi-mcp\

Create your personal config.json with your credentials (see previous section).

The folder must contain a manifest.json file:

{
  "manifest_version": "0.2",
  "name": "GLPI-MCP",
  "version": "0.1.0",
  "description": "MCP server for GLPI integration",
  "author": { "name": "Your Name", "url": "" },
  "server": {
    "type": "python",
    "entry_point": "server.py",
    "mcp_config": {
      "command": "uv",
      "args": ["--directory", "${__dirname}", "run", "python", "server.py"]
    }
  }
}

Restart Claude Desktop. Each user on the machine copies their own files to their %APPDATA% folder with their own config.json.

Method 2 — claude_desktop_config.json (manual)

Open the Claude Desktop configuration file:

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

Add the mcpServers section:

Windows

{
  "mcpServers": {
    "glpi": {
      "command": "uv",
      "args": [
        "--directory",
        "C:\\Path\\to\\glpi-mcp",
        "run",
        "python",
        "server.py"
      ]
    }
  },
  "preferences": {
    "coworkScheduledTasksEnabled": false,
    "sidebarMode": "code"
  }
}

macOS / Linux

{
  "mcpServers": {
    "glpi": {
      "command": "uv",
      "args": [
        "--directory",
        "/path/to/glpi-mcp",
        "run",
        "python",
        "server.py"
      ]
    }
  }
}

⚠️ Make sure the JSON is valid — a missing brace or comma is enough to prevent Claude Desktop from loading the configuration. Use a JSON validator if needed.

Restart Claude Desktop. If the configuration is correct, a 🔌 icon will appear in the Claude toolbar indicating the MCP server is connected.


Available tools

🔐 Session

Tool

Description

kill_session

Gracefully closes the active GLPI session

🎫 Tickets

Tool

Description

list_tickets

List tickets with pagination and filters (status, type)

get_ticket

Full ticket details with readable labels

search_tickets

Advanced search by keywords, status, type, category, assignee

create_ticket

Create a new ticket

update_ticket

Update fields of an existing ticket

delete_ticket

Delete a ticket

link_tickets

Link two tickets (linked, duplicate, child, parent)

list_ticket_links

List all links for a ticket

merge_tickets

Merge source tickets into a target (copies followups, links as duplicate, closes sources)

💬 Followups

Tool

Description

list_followups

List all followups for a ticket

get_followup

Followup details

add_followup

Add a followup (public or private)

update_followup

Update an existing followup (content, visibility)

delete_followup

Delete a followup — destructive, removes it from the audit trail

✅ Tasks

Tool

Description

list_tasks

List tasks for a ticket

add_task

Create a task on a ticket

update_task

Update a task (status, duration, assignee)

delete_task

Delete a task

💡 Solutions

Tool

Description

get_solution

Read the solution for a ticket

add_solution

Post a solution (closes the ticket per GLPI config)

📊 Statistics

Tool

Description

stats_by_status

Ticket count by status

stats_by_type

Incidents vs Service Requests breakdown

stats_by_priority

Open tickets by priority

stats_by_category

Ticket count by ITIL category

stats_by_assignee

Tickets per assigned technician

stats_resolution_time

Average ticket resolution time

stats_overdue

Tickets overdue against SLA

📚 Knowledge Base

Tool

Description

list_kb_articles

List articles with pagination. If range_start > 60 and range_limit > 10, range_limit is auto-clamped to 10 (full HTML article bodies in the JSON response often exceed the GLPI PHP-FPM memory_limit beyond that). When clamping kicks in, the response is a dict {"_clamped_range_limit": 10, "_warning": "...", "items": [...]} instead of a list.

get_kb_article

Full article details

search_kb_articles

Search by keywords (title only by default ; pass search_content=True to also match the HTML body — slow without a MySQL FULLTEXT index on knowbaseitems.answer)

create_kb_article

Create a new article (title, HTML content, category, FAQ)

update_kb_article

Update an existing article

list_kb_categories

List knowledge base categories

get_kb_article_visibility

Read visibility rules for an article (profiles, groups, users, entities)

add_kb_article_visibility_profile

Add a profile to an article's visibility

add_kb_article_visibility_group

Add a group to an article's visibility

update_kb_article_visibility_profile

Update an existing profile visibility rule

update_kb_article_visibility_group

Update an existing group visibility rule

Note: Deleting visibility rules is intentionally not exposed in order to preserve a history of procedures, even obsolete ones.

📋 Reference data

Tool

Description

list_itil_categories

List available ITIL categories

get_users

List GLPI users

get_groups

List GLPI groups

🏢 Suppliers, contacts and contracts

Tool

Description

list_suppliers

List suppliers (name_contains and only_active filters, pagination)

create_supplier

Create a supplier (name required, contact details optional)

create_contact

Create a contact; optionally attach it to a supplier via supplier_id

create_contract

Create a contract; optionally attach it to a supplier via supplier_id

update_supplier

Update a supplier (update_fields: changed fields only)

update_contact

Update a contact

update_contract

Update a contract

delete_supplier

Move a supplier to the trash; purge=True to delete permanently

delete_contact

Move a contact to the trash; purge=True to delete permanently

delete_contract

Move a contract to the trash; purge=True to delete permanently

Note: list_suppliers returns active suppliers only by default. Pass only_active=False to include disabled ones.

Note: For create_contract, the duration, notice, periodicity and billing fields are expressed in months (GLPI convention), and begin_date uses the YYYY-MM-DD format.

Note: When supplier_id is provided, the junction entry (Contact_Supplier / Contract_Supplier) is created in a second call and its result is returned under the _supplier_link key. If the contact or contract creation fails, no link is attempted.

⚠️ Deletion — trash by default, purge on request. With no argument, delete_* moves the item to the GLPI trash (is_deleted = 1): it stays attached to its contracts, contacts, assets and tickets, and can be restored with the matching update_* tool and {"is_deleted": 0}. With purge=True, deletion is permanent and irreversible and breaks those attachments. Reserve purging for duplicates and data-entry mistakes.

🖥️ Hardware / Assets

Tool

Description

list_assets

List assets by itemtype with pagination and an optional name filter

get_asset

Read one asset by concrete itemtype and ID

search_assets

Search asset names through GLPI search with dynamic listSearchOptions

create_asset

Create an asset from raw GLPI fields

update_asset

Update only the supplied fields

delete_asset

Move the asset to trash by default; purge=True permanently purges it

Supported itemtypes: Computer, Monitor, NetworkEquipment, Printer, Peripheral, Phone. AllAssets is available for read/search only.

Safety: use purge=True only when permanent, irreversible deletion was explicitly requested. The fields dictionaries are passed through as GLPI fields, so do not invent reference IDs such as locations_id, states_id, manufacturers_id or users_id.


Usage examples with Claude

"Show me all open high-priority incidents"

"Create a service request ticket for installing Adobe Acrobat for Jane Smith"

"Add a followup to ticket #4521 to inform the user that the issue is being investigated"

"Merge tickets #4530 and #4531 into ticket #4521"

"Link ticket #4530 to ticket #4521 as a duplicate"

"What are the ticket statistics by status?"

"What is the average ticket resolution time?"

"Show me tickets that are overdue against the SLA"

"Search the knowledge base for VPN troubleshooting solutions"

"Who can see knowledge base article #120?"

"Add the Technicians group to the visibility of article #120"

"Which suppliers do we have for telephony?"

"Add Acme Telecom to the supplier registry, then create maintenance contract CT-2026-014 starting April 1st for 36 months"

"Deactivate the Acme Telecom supplier — we no longer do business with them, but keep the contract history"

"Close ticket #4102 with the solution: service restart resolved the issue"


Reference mappings

Statuses

Code

Label (fr)

Label (en)

1

Nouveau

New

2

En cours (attribué)

In progress (assigned)

3

En cours (planifié)

In progress (planned)

4

En attente

Pending

5

Résolu

Solved

6

Clos

Closed

Types

Code

Label (fr)

Label (en)

1

Incident

Incident

2

Demande de service

Service request

Priorities / Urgencies / Impacts

Code

Label (fr)

Label (en)

1

Très basse

Very low

2

Basse

Low

3

Moyenne

Medium

4

Haute

High

5

Très haute

Very high

6

Majeure

Major

Code

Label (fr)

Label (en)

1

Lié à

Linked to

2

Duplique

Duplicates

3

Enfant de

Child of

4

Parent de

Parent of


Troubleshooting

Server does not appear in Claude Desktop

  • Check the JSON syntax of the configuration file (no missing or extra commas/braces)

  • Verify the folder path is correct and absolute

  • Fully restart Claude Desktop

  • Make sure the %APPDATA%\Claude\connectors\ folder exists (create it if needed)

401 error on every call

  • Verify that GLPI_APP_TOKEN and GLPI_USER_TOKEN are correct in your config.json

  • Check that the REST API is enabled in GLPI

  • Verify that the API client in GLPI is active and the IP is authorized

Connection error / timeout

  • Verify that GLPI_URL is reachable from the machine running the server

  • Check that no firewall is blocking the connection

  • All HTTP requests have a hard ceiling of 30 seconds (10 s for connect). Beyond that, the tool returns a structured dict with error and detail (labels taken from the LANG table) instead of hanging — in English: {"error": "HTTP timeout", "detail": "Request > 30s — see GLPI logs"}. If you hit this repeatedly, inspect the PHP-FPM/MySQL logs on the GLPI side: the underlying query is likely too expensive (typically a full-text search without an index).

Corporate environment — SSL-intercepting proxy (Zscaler, Forcepoint, etc.)

In corporate environments, an SSL proxy may intercept HTTPS connections and replace certificates with an internal certificate. This causes the following error when installing dependencies with uv:

× Failed to download `python-dotenv==X.X.X`
╰─▶ invalid peer certificate: UnknownIssuer

Solution: Force uv to use the Windows certificate store with the UV_NATIVE_TLS environment variable.

To test manually in PowerShell:

$env:UV_NATIVE_TLS=1
uv run python server.py

To have Claude Desktop automatically pass this variable when starting the server, add an env section to your claude_desktop_config.json:

{
  "mcpServers": {
    "glpi": {
      "command": "uv",
      "args": [
        "--directory",
        "C:\\Path\\to\\glpi-mcp",
        "run",
        "python",
        "server.py"
      ],
      "env": {
        "UV_NATIVE_TLS": "1"
      }
    }
  }
}

Corporate environment — Antivirus / EDR blocking uv (Riskware)

Some corporate antivirus or EDR solutions may categorize uv.exe as Riskware because it downloads executables and packages from the Internet. If uv is blocked by your security solution:

  • Contact your IT team to add an exception for uv.exe (located at %USERPROFILE%\.local\bin\uv.exe)

  • Also request authorization for the domains: pypi.org, files.pythonhosted.org, astral.sh

As an alternative, ask a colleague with a working uv to share the .venv folder, which avoids any downloads.

Reducing dependencies

The project depends on mcp[cli] which includes the [cli] extra (typer, rich, click, shellingham, pygments, markdown-it-py…). This extra provides the development commands mcp dev and mcp inspect, useful for debugging.

If you want to reduce the footprint in production (about 8 fewer packages), modify pyproject.toml:

# Before (with CLI tooling)
dependencies = ["mcp[cli]>=1.9.4", "httpx>=0.27"]

# After (without CLI tooling — lightweight production)
dependencies = ["mcp>=1.9.4", "httpx>=0.27"]

Then run uv sync again to update the environment.

Available Tools

52 tools
add_followupA

Ajoute un suivi à un ticket.

  • is_private : True pour un suivi visible uniquement par les techniciens

Inputs: content (required), ticket_id (required), is_private.

add_kb_article_visibility_groupC

Ajoute un groupe dans la visibilité d'un article KB.

  • groups_id : ID du groupe GLPI

Inputs: groups_id (required), article_id (required), entities_id, is_recursive.

add_kb_article_visibility_profileB

Ajoute un profil dans la visibilité d'un article KB.

  • profiles_id : ID du profil GLPI

  • entities_id : 0 = entité racine

  • is_recursive : appliquer aux sous-entités

Inputs: article_id (required), profiles_id (required), entities_id, is_recursive.

add_solutionA

Poste une solution sur un ticket (le clôture automatiquement selon la config GLPI).

  • solution_type_id : ID du type de solution si applicable

Inputs: content (required), ticket_id (required), solution_type_id.

add_taskB

Crée une tâche sur un ticket.

  • status : 1=À faire 2=Terminée

  • duration_seconds : durée en secondes (ex. 3600 = 1h)

Inputs: content (required), ticket_id (required), status, is_private, +2 more.

create_contactA

Crée un contact (personne-ressource chez un fournisseur).

  • name : nom de famille (seul champ obligatoire)

  • contact_type_id : ID d'un ContactType existant (optionnel)

  • supplier_id : si fourni, le contact est rattaché à ce fournisseur via Contact_Supplier. Le résultat contient alors la clé "_supplier_link".

  • comment : texte libre, en HTML compatible GLPI (jamais de Markdown)

Inputs: name (required), fax, town, email, +10 more.

create_contractA

Crée un contrat.

  • name : intitulé du contrat (seul champ obligatoire)

  • num : numéro de contrat chez le fournisseur

  • begin_date : date de début, format AAAA-MM-JJ

  • duration / notice / periodicity / billing : en MOIS (convention GLPI)

  • supplier_id : si fourni, le contrat est rattaché à ce fournisseur via Contract_Supplier. Le résultat contient alors la clé "_supplier_link".

  • comment : texte libre, en HTML compatible GLPI (jamais de Markdown)

Inputs: name (required), num, notice, billing, +7 more.

create_kb_articleB

Crée un nouvel article dans la base de connaissances.

  • name : titre de l'article

  • answer : contenu / solution (HTML accepté)

  • category_id : ID de la catégorie KB (optionnel)

  • is_faq : True pour publier dans la FAQ publique

Inputs: name (required), answer (required), is_faq, category_id.

create_supplierC

Crée un fournisseur.

  • name : raison sociale (seul champ obligatoire)

  • supplier_type_id : ID d'un SupplierType existant (optionnel)

  • comment : texte libre, en HTML compatible GLPI (jamais de Markdown)

Inputs: name (required), fax, town, email, +9 more.

create_ticketB

Crée un nouveau ticket.

  • type : 1=Incident 2=Demande de service

  • priority : 1 (très basse) → 6 (majeure)

Inputs: name (required), content (required), type, priority, +3 more.

delete_contactA

Supprime un contact.

  • purge=False (défaut) : mise à la corbeille, réversible via update_contact(contact_id, {"is_deleted": 0})

  • purge=True : suppression définitive et IRRÉVERSIBLE.

Inputs: contact_id (required), purge.

delete_contractA

Supprime un contrat.

  • purge=False (défaut) : mise à la corbeille, réversible via update_contract(contract_id, {"is_deleted": 0})

  • purge=True : suppression définitive et IRRÉVERSIBLE, qui retire aussi les rattachements du contrat à ses matériels et à son fournisseur.

Inputs: contract_id (required), purge.

delete_followupA

Supprime un suivi.

ATTENTION : opération destructive et non réversible depuis cet outil — le suivi disparaît de la piste d'audit du ticket. Ne l'utiliser que sur un suivi publié par erreur (mauvais ticket, doublon). Pour corriger un contenu, utiliser update_followup ; pour nuancer une conclusion, add_followup.

Inputs: followup_id (required).

delete_supplierA

Supprime un fournisseur.

  • purge=False (défaut) : mise à la corbeille, réversible via update_supplier(supplier_id, {"is_deleted": 0})

  • purge=True : suppression définitive et IRRÉVERSIBLE, qui retire aussi les rattachements du fournisseur à ses contrats, contacts, matériels et tickets. À n'utiliser que sur un doublon ou une saisie erronée.

Inputs: supplier_id (required), purge.

delete_taskC

Supprime une tâche.

Inputs: task_id (required).

delete_ticketB

Supprime un ticket par son ID.

Inputs: ticket_id (required).

get_followupB

Retourne le détail d'un suivi spécifique.

Inputs: followup_id (required).

get_groupsA

Liste les groupes GLPI.

Inputs: no named parameters.

get_kb_articleC

Retourne le détail complet d'un article de la base de connaissances.

Inputs: article_id (required).

get_kb_article_visibilityB

Retourne les règles de visibilité d'un article KB : profils, groupes, utilisateurs et entités ayant accès.

Inputs: article_id (required). Returns: result

get_solutionC

Retourne la solution d'un ticket.

Inputs: ticket_id (required).

get_ticketB

Retourne le détail complet d'un ticket, avec libellés lisibles.

Inputs: ticket_id (required). Returns: result

get_usersB

Liste les utilisateurs GLPI.

Inputs: no named parameters.

kill_sessionA

Ferme proprement la session GLPI active.

Inputs: no named parameters. Returns: result

list_followupsB

Liste tous les suivis d'un ticket.

Inputs: ticket_id (required).

list_itil_categoriesA

Liste toutes les catégories ITIL disponibles (Incident, Demande, Changement, Problème).

Inputs: no named parameters.

list_kb_articlesA

List GLPI knowledge base articles with pagination.

Each KnowbaseItem returned by the API embeds the full HTML answer. On large KBs this makes the JSON response heavy: in production we observed that range_start > 60 combined with range_limit > 10 is enough to exceed PHP-FPM memory_limit on the GLPI side and the request fails. To stay below that ceiling, range_limit is auto-clamped to 10 when range_start > 60. When clamping kicks in the response is wrapped in a dict carrying _clamped_range_limit and _warning so callers can detect the change. Behaviour is unchanged for range_start <= 60.

Inputs: range_limit, range_start.

list_kb_categoriesB

Liste toutes les catégories de la base de connaissances.

Inputs: no named parameters.

list_suppliersB

Liste les fournisseurs enregistrés dans GLPI.

  • name_contains : filtre optionnel sur le nom (recherche partielle)

  • only_active : n'inclure que les fournisseurs actifs (is_active = 1)

  • range_start / range_limit : pagination

Inputs: only_active, range_limit, range_start, name_contains.

list_tasksA

Liste toutes les tâches d'un ticket.

Inputs: ticket_id (required).

list_ticketsC

Liste les tickets avec pagination optionnelle.

  • status : 1=Nouveau 2=En cours(attribué) 3=En cours(planifié) 4=En attente 5=Résolu 6=Clos

  • type : 1=Incident 2=Demande de service

  • range_start / range_limit : pagination

Inputs: status, range_limit, range_start, ticket_type. Returns: result

merge_ticketsA

Fusionne un ou plusieurs tickets source vers un ticket cible.

  • Lie chaque ticket source au ticket cible comme doublon (link_type=2)

  • Copie les suivis des tickets source vers le ticket cible (si add_followups=True)

  • Ferme les tickets source avec un suivi explicatif (si close_source=True)

Paramètres :

  • target_ticket_id : ID du ticket cible (celui qui reste ouvert)

  • source_ticket_ids : liste des IDs de tickets à fusionner dans le cible

  • add_followups : copier les suivis des tickets source vers le cible

  • close_source : fermer les tickets source après la fusion

Inputs: target_ticket_id (required), source_ticket_ids (required), close_source, add_followups. Returns: result

search_kb_articlesA

Search knowledge base articles by keyword.

By default the search runs only against the title column, which is fast on any GLPI instance. Set search_content=True to also match against the full HTML body. On a GLPI instance that has no MySQL FULLTEXT index on knowbaseitems.answer, that branch produces a LIKE '%keyword%' scan on the answer column which routinely exceeds the 30 second client timeout on KBs with sizeable HTML payloads.

Field IDs are discovered at runtime via listSearchOptions/KnowbaseItem and looked up by column name ("name", "answer") so the tool works on both GLPI 10 and GLPI 11 (where numeric IDs may differ). When discovery fails the legacy GLPI 10 IDs (6 for title, 7 for body) are used as a fallback.

Parameters:

  • keywords: text to search for

  • range_start, range_limit: pagination

  • search_content: also match against the article body (default False). Only enable when the GLPI database has a FULLTEXT index on knowbaseitems.answer, otherwise the request will be slow.

Inputs: keywords (required), range_limit, range_start, search_content.

search_ticketsA

Recherche avancée de tickets via l'API GLPI /search/Ticket. Tous les paramètres sont optionnels et combinables (combinés en ET).

Trois portées de recherche textuelle, à ne pas confondre :

  • keywords : le titre seulement. Rapide, mais aveugle au corps du ticket et aux suivis. C'est la portée historique de cet outil.

  • content_keywords : la description du ticket (corps initial).

  • followup_keywords : le contenu des suivis. Indispensable pour l'analyse historique : sur la plupart des instances, l'essentiel de la connaissance d'investigation vit dans les suivis, pas dans les titres. Le nom d'un outil ou d'un correctif mentionné uniquement en cours de diagnostic ne se trouve que par cette portée.

Note de performance : content_keywords et followup_keywords produisent un LIKE '%motif%' côté MySQL. Sans index FULLTEXT, ces recherches sont sensiblement plus lentes que par titre — les combiner avec status, category_id ou ticket_type pour réduire l'ensemble balayé.

Inputs: status, keywords, category_id, range_limit, +5 more.

stats_by_assigneeA

Retourne le nombre de tickets par technicien assigné.

Inputs: no named parameters. Returns: result

stats_by_categoryA

Retourne le nombre de tickets par catégorie ITIL.

Inputs: no named parameters. Returns: result

stats_by_priorityA

Retourne le nombre de tickets ouverts par priorité.

Inputs: no named parameters. Returns: result

stats_by_statusA

Retourne le nombre de tickets ouverts par statut.

Inputs: no named parameters. Returns: result

stats_by_typeA

Retourne le nombre de tickets par type (Incident / Demande de service).

Inputs: no named parameters. Returns: result

stats_overdueA

Retourne les tickets en retard (date d'échéance dépassée et non résolus). Utilise le champ time_to_resolve de GLPI.

Inputs: no named parameters. Returns: result

stats_resolution_timeA

Retourne le délai moyen de résolution des tickets résolus ou clos.

Inputs: no named parameters. Returns: result

update_contactB

Met à jour un contact. Passer uniquement les champs à modifier. Exemples de champs : name, firstname, contacttypes_id, phone, mobile, email, comment Pour restaurer un contact mis à la corbeille : {"is_deleted": 0}

Inputs: contact_id (required), update_fields (required).

update_contractB

Met à jour un contrat. Passer uniquement les champs à modifier. Exemples de champs : name, num, contracttypes_id, begin_date, duration, notice, periodicity, billing, accounting_number, comment Les durées sont en MOIS et begin_date au format AAAA-MM-JJ. Pour restaurer un contrat mis à la corbeille : {"is_deleted": 0}

Inputs: contract_id (required), update_fields (required).

update_followupA

Met à jour un suivi existant. Exemples de champs : content, is_private.

Le champ content doit être en HTML compatible GLPI, jamais en Markdown (cf. instructions du serveur).

Note : un suivi est une pièce horodatée et signée du dossier. Corriger le contenu d'un suivi déjà publié réécrit l'historique visible par l'équipe — à réserver aux corrections d'erreurs factuelles récentes. Pour un changement de fond, préférer l'ajout d'un nouveau suivi via add_followup, qui conserve la trace du raisonnement antérieur.

Inputs: followup_id (required), update_fields (required).

update_kb_articleC

Met à jour un article de la base de connaissances. Exemples de champs : name, answer, is_faq, knowbaseitemcategories_id

Inputs: article_id (required), update_fields (required).

update_kb_article_visibility_groupA

Met à jour une règle de visibilité par groupe d'un article KB.

  • visibility_id : ID de l'entrée KnowbaseItem_Group (obtenu via get_kb_article_visibility)

  • update_fields : champs à modifier, ex: {"entities_id": 1, "is_recursive": 1}

Inputs: update_fields (required), visibility_id (required).

update_kb_article_visibility_profileB

Met à jour une règle de visibilité par profil d'un article KB.

  • visibility_id : ID de l'entrée KnowbaseItem_Profile (obtenu via get_kb_article_visibility)

  • update_fields : champs à modifier, ex: {"entities_id": 1, "is_recursive": 1}

Inputs: update_fields (required), visibility_id (required).

update_supplierA

Met à jour un fournisseur. Passer uniquement les champs à modifier. Exemples de champs : name, suppliertypes_id, address, town, phonenumber, email, website, comment, is_active Pour restaurer un fournisseur mis à la corbeille : {"is_deleted": 0}

Inputs: supplier_id (required), update_fields (required).

update_taskA

Met à jour une tâche. Exemples : state (1/2), content, actiontime, users_id_tech

Inputs: task_id (required), update_fields (required).

update_ticketA

Met à jour un ticket. Passer uniquement les champs à modifier. Exemples de champs : status, priority, name, content, itilcategories_id

Inputs: ticket_id (required), update_fields (required).

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.3/5.0

    Scored across 52 tools

    Disambiguation4/5

    Each tool has a clearly distinct purpose, with resource+action naming that separates e.g. list_tickets vs search_tickets and profile vs group visibility tools. A few tools (stats_by_*) follow similar patterns but target different metrics, so confusion is unlikely.

    Naming Consistency5/5

    All tool names follow a consistent snake_case verb_noun pattern (list_tickets, add_followup, update_supplier), with only minor deviations like stats_resolution_time and kill_session. No mixed conventions are present.

    Tool Count2/5

    52 tools is far above the typical 3–15 range; while GLPI is a broad domain, the granular CRUD for each entity could be consolidated. The count is excessive and likely burdens tool selection.

    Completeness3/5

    Core ticketing, followups, tasks, and KB articles have near-complete lifecycles, but there are notable gaps: no list/get for contacts and contracts, no update/delete for solutions, no asset/problem/change management, and KB category CRUD is missing. These gaps limit the server's coverage of GLPI.

    Maintenance

    ActivitySlowing
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Connects AI assistants to GLPI IT Service Management, enabling ticket management, asset search, and ITIL processes via natural language.
      11 npm
      3
      MIT
    • A
      license
      C
      quality
      D
      maintenance
      Enables AI assistants to manage GLPI inventory, tickets, and CIA security fields via its REST API.
      9
      14 npm
      1
      ISC
    • A
      license
      Not graded
      quality
      B
      maintenance
      Connects AI assistants to GLPI through the Model Context Protocol, enabling management of tickets, ITIL objects, assets, projects, tasks, documents, sessions, entities and massive actions via the legacy REST API. It supports GLPI 10 and 11 with safe defaults such as read-only mode, disabled destructive operations and masked secrets.
      MIT
    • A
      license
      B
      quality
      B
      maintenance
      Connects AI assistants to GLPI service desks so they can manage tickets, ITIL objects (problems and changes), assets, knowledge base articles, users, rules and webhooks through natural language. Works with GLPI 10 and 11 via REST API v1 and the GLPI 11 API v2, with read-only and delete guards, idempotent creates, and support for both local (stdio/HTTP) and hosted OAuth deployments.
      111
      1
      MIT