Servidor de referencia para integrar el ecosistema Model Context Protocol (MCP) con GLPI. Proporciona herramientas de gestion de tickets, cambios y sesion listas para usar en flujos de automatizacion, junto con utilidades para validacion y soporte.
- Implementacion MCP sobre stdio lista para Claude Desktop y otros clientes compatibles.
- Coleccion de herramientas GLPI para listar, crear, actualizar y relacionar tickets y cambios, ademas de operaciones de sesion del usuario logueado.
- Subida y descarga de archivos (Document de GLPI), y vinculo/desvinculo de documentos con tickets y cambios.
- Recurso MCP (
resources/list+resources/read) con una guia de uso de las herramientas de elementos/archivos GLPI, para que el cliente MCP la cargue como contexto de referencia. - Validacion de configuracion impulsada por Pydantic y uso de variables de entorno con
.env. - Respuestas normalizadas en JSON para facilitar integracion con clientes MCP y automatizaciones.
- Organizacion modular por paquetes (
tickets/,changes/,session/) para extender nuevas funcionalidades con menor acoplamiento. - Suite de pruebas unitarias (
pytest) que cubre el manejador de comandos, los helpers GLPI y la documentacion del repositorio.
- Clonar el repositorio y crear un entorno virtual:
python -m venv .venv .venv/Scripts/activate # Windows # source .venv/bin/activate # Linux/macOS
- Instalar dependencias:
pip install -e . - Configurar credenciales GLPI (tokens y URL):
- Definir las variables
GLPI_URL,GLPI_APP_TOKENyGLPI_USER_TOKENen el entorno. - Alternativamente, crear un archivo
.enven la raiz del proyecto con esos valores.
- Definir las variables
Las herramientas expuestas por GLPITools se registran automaticamente en el servidor MCP. Los nombres siguen la convencion elemento_funcion / elemento_subelemento_funcion (ver detalle y motivacion en la nota de documentacion Documentacion MCP-GLPI.md):
| Herramienta | Descripcion breve |
|---|---|
session_validate |
Muestra informacion de la sesion GLPI activa. |
profile_list |
Lista los perfiles del usuario logueado y las entidades asociadas. |
entity_list |
Lista las entidades GLPI disponibles para el usuario logueado (id, nombre). |
ticket_list |
Lista tickets con filtros, paginacion y distintos formatos. |
change_list |
Lista cambios con filtros, paginacion y distintos formatos. |
ticket_add |
Crea un ticket; soporta campos adicionales. |
change_add |
Crea un cambio; soporta campos adicionales. |
ticket_follow_add |
Agrega un comentario (seguimiento) a un ticket. |
ticket_follow_list |
Lista los comentarios (seguimientos, ITILFollowup) de un ticket. |
ticket_solution_add |
Registra una solucion de ticket. |
ticket_solution_list |
Lista las soluciones (ITILSolution) de un ticket. |
ticket_user_assign |
Asigna usuarios a un ticket. |
ticket_group_assign |
Asigna grupos a un ticket. |
change_follow_add |
Agrega un comentario (seguimiento) a un cambio. |
change_follow_list |
Lista los comentarios (seguimientos, ITILFollowup) de un cambio. |
change_solution_add |
Registra una solucion de cambio. |
change_solution_list |
Lista las soluciones (ITILSolution) de un cambio. |
change_user_assign |
Asigna usuarios a un cambio. |
change_group_assign |
Asigna grupos a un cambio. |
change_ticket_link |
Vincula un ticket existente a un cambio. |
ticket_change_link |
Vincula un cambio existente a un ticket. |
change_ticket_unlink |
Elimina la relacion Change_Ticket desde un cambio. |
ticket_change_unlink |
Elimina la relacion Change_Ticket desde un ticket. |
change_update |
Actualiza campos de un cambio. |
ticket_update |
Actualiza campos de un ticket. |
ticket_delete |
Elimina un ticket (papelera o purga definitiva). |
change_delete |
Elimina un cambio (papelera o purga definitiva). |
item_type_list |
Lista los itemtypes de GLPI soportados por item_list/item_get/item_subitem_list. |
item_subtype_list |
Lista los subtypes soportados por item_subitem_list (opcionalmente filtrados por itemtype). |
item_list |
Acceso generico de solo lectura: lista elementos de un itemtype soportado. |
item_get |
Acceso generico de solo lectura a un elemento puntual (por id) de un itemtype soportado. |
item_subitem_list |
Acceso generico de solo lectura a los sub-items de un elemento (itemtype/id/subtype soportados). |
item_delete |
Elimina un elemento de un itemtype soportado (papelera o purga definitiva). |
file_upload |
Sube un archivo local como Document de GLPI (multipart/form-data). |
file_download |
Descarga un Document de GLPI y lo escribe en una ruta local. |
file_link |
Vincula un Document existente a un ticket o cambio (Document_Item). |
file_unlink |
Elimina la relacion Document_Item entre un documento y el elemento al que estaba vinculado. |
ticket_follow_list/change_follow_list y ticket_solution_list/change_solution_list listan los sub-items (ITILFollowup/ITILSolution) de un ticket o cambio puntual. Aceptan ticket_id/change_id (obligatorio), limit, offset, sort_by, order, output (dict/table/raw), fields, y los mismos entity_id/profile_id opcionales descritos abajo. No soportan filters/expand_dropdowns/include_deleted porque la API de sub-items de GLPI no los expone.
Ademas de las herramientas especificas, hay herramientas de acceso generico a cualquier itemtype/subtype soportado, sin necesidad de una tool nueva por combinacion. Las tres primeras son de solo lectura; item_delete es la unica mutacion generica:
item_list(itemtype, ...): lista elementos del itemtype (equivalente aGET /{itemtype}), conlimit/offset/sort_by/order/filters/output/fields. No llevaid.item_get(itemtype, id, ...): obtiene un elemento puntual por id (GET /{itemtype}/{id}), confields/expand_dropdowns.ides obligatorio.item_subitem_list(itemtype, id, subtype, ...): lista sub-items de un elemento (GET /{itemtype}/{id}/{subtype}).item_delete(itemtype, id, ...): elimina un elemento (equivalente aDELETE /{itemtype}/{id}), conpurge/keep_historyigual queticket_delete/change_delete.item_type_list/item_subtype_list: devuelven los itemtypes/subtypes soportados, cada uno con una breve descripcion, para saber que valores son validos antes de llamar a las anteriores.
Los itemtypes/subtypes soportados son una lista blanca deliberada (hoy: Ticket, Change, Document, y sus sub-recursos ya cubiertos por las herramientas especificas — ITILFollowup, ITILSolution, Ticket_User, Group_Ticket, Change_User, Change_Group, Change_Ticket, Document_Item). Un itemtype/subtype fuera de esa lista (por ejemplo User, Config, Computer) devuelve un error de validacion en vez de ejecutarse — este servidor no expone datos de GLPI mas alla de tickets/cambios y sus relaciones, ni siquiera a traves de la ruta generica.
item_list(itemtype="Document", ...) / item_get(itemtype="Document", id=...) permiten buscar/consultar metadata de documentos (nombre, filename, mime, entidad, fecha), e item_subitem_list(itemtype="Ticket"|"Change", id=..., subtype="Document_Item") muestra que documentos ya estan vinculados a un ticket o cambio puntual — sin necesidad de una tool dedicada para listar/buscar documentos.
file_upload(file_path, ...): sube un archivo como Document de GLPI (POST Document/multipart/form-data).file_pathes una ruta local en el sistema de archivos de la maquina donde corre el servidor MCP;file_namepor defecto es el nombre base defile_path.file_download(document_id, destination_path, ...): descarga un Document (GET Document/:idconAccept: application/octet-stream) y escribe los bytes endestination_path(ruta local, se crean los directorios padre si hace falta).file_link(document_id, item_type, item_id, ...)/file_unlink(document_id, link_id, ...): crean/eliminan la relacionDocument_Itementre un documento y un ticket o cambio.item_typeesta restringido al mismoITEMTYPE_CATALOGque gobierna las herramientas genericas.
Las cuatro aceptan los mismos entity_id/profile_id opcionales que el resto de las herramientas.
Todas las herramientas que operan sobre un ticket o cambio (creacion, listados, comentarios, soluciones, asignaciones, enlaces, actualizacion y borrado) aceptan dos parametros opcionales:
entity_id: cambia la entidad activa de la sesion GLPI (viachangeActiveEntities) antes de ejecutar la operacion. El codigo0(entidad raiz de GLPI) es un valor valido. Useentity_listpara consultar los codigos disponibles.profile_id: cambia el perfil activo de la sesion GLPI (viachangeActiveProfile) antes de ejecutar la operacion. Useprofile_listpara consultar los codigos disponibles.
Si se omiten (o llegan vacios/null), se usan el perfil/entidad activos por defecto de la sesion sin fallar. Cuando se indican ambos en la misma llamada, el perfil se cambia primero y luego la entidad: el perfil activo determina los permisos (crear/leer/editar) con los que se ejecuta la operacion; la entidad activa solo determina sobre que registros se opera. En GLPI, las entidades a las que un usuario tiene acceso estan asociadas a sus perfiles (ver la respuesta de profile_list) — para operar correctamente sobre una entidad que pertenece a un perfil distinto al activo, pase tambien profile_id.
Ambos parametros tambien aceptan el nombre de la entidad/perfil (texto no numerico) en vez del id: se resuelve automaticamente consultando profile_list internamente, y si solo se da el nombre del perfil (sin entidad), se selecciona la primera entidad de ese perfil. La respuesta incluye un campo resolution_notes cuando esto ocurre. Un nombre ambiguo (coincide con mas de un perfil/entidad) o inexistente devuelve un error de validacion en vez de adivinar. Ver el recurso mcp-glpi://docs/glpi-entity-profile-resolution para el detalle completo.
Como cada llamada MCP abre y cierra su propia sesion GLPI, el cambio de entidad/perfil aplica solo a esa llamada puntual; no persiste para llamadas posteriores.
Importante: GLPI responde HTTP 200 con cuerpo false (no un error HTTP) cuando la entidad o el perfil indicados no son accesibles para el usuario/token, o no existen. Cualquier herramienta invocada con entity_id/profile_id detecta este caso y devuelve un error explicito en vez de fallar en silencio; si obtenes ese error, revisa que el entity_id/profile_id este entre los que devuelve entity_list/profile_list.
Nota de diseño: no hay herramientas dedicadas entity_switch/profile_switch — cada llamada MCP abre y cierra su propia sesion GLPI, asi que "cambiar de entidad/perfil" como operacion aislada no tendria ningun efecto persistente. Cambiar de entidad/perfil solo tiene sentido junto con la operacion real que se quiere ejecutar en esa entidad/perfil, por eso entity_id/profile_id son parametros de las herramientas de negocio (ticket_list, ticket_add, etc.), no tools independientes.
Las herramientas responden en JSON serializado dentro de TextContent. Por ejemplo, profile_list devuelve una lista simplificada de perfiles:
[
{
"id": 22,
"name": "Administrativo - Solicitante",
"entities": [
{
"id": 2,
"name": "Administrativo",
"is_recursive": true
}
]
}
]Ademas de las tools, el servidor expone la capacidad resources del protocolo MCP (resources/list / resources/read), para que un cliente MCP pueda cargar documentacion de referencia como contexto sin necesidad de invocar una tool.
src/mcp_glpi/resource_catalog.py: fuente unica de verdad de los recursos publicados (RESOURCE_SPECS:uri/name/description/mime_type/path), analogo aTOOL_SPECSentool_catalog.py.src/mcp_glpi/resources/: contenido real de los recursos (archivos.md), empaquetado dentro del wheel via[tool.setuptools.package-data]enpyproject.toml.src/mcp_glpi/server.py: registrahandle_list_resources/handle_read_resourcesobreself.app, leyendo el contenido conresource_catalog.read_resource_text(uri).
Recursos publicados hoy (separados por tema para poder cargar solo el que aplica):
| URI | Nombre | Contenido |
|---|---|---|
mcp-glpi://docs/glpi-items |
glpi-items |
Herramientas genericas: descubrir itemtype/subtype (item_type_list/item_subtype_list), listar/consultar/eliminar de forma generica (item_list/item_get/item_delete) y listar sub-elementos (item_subitem_list), con su matriz de rutas/capacidades. |
mcp-glpi://docs/glpi-tools |
glpi-tools |
Herramientas especificas de tickets/cambios (crear, actualizar, eliminar, seguimientos, soluciones, asignaciones, relaciones) y de archivos (file_upload/file_download/file_link/file_unlink), con su matriz de rutas/capacidades. |
mcp-glpi://docs/glpi-entity-profile-resolution |
glpi-entity-profile-resolution |
Que pasa cuando entity_id/profile_id se dan como nombre en vez de id: resolucion automatica, seleccion de la primera entidad de un perfil, y manejo de nombres ambiguos/inexistentes. |
Para agregar un recurso nuevo: colocar el archivo en src/mcp_glpi/resources/, agregar una entrada a RESOURCE_SPECS, y (si es un patron de archivo nuevo, ej. .json) ajustar el glob en [tool.setuptools.package-data].
Ejecutar en modo CLI:
python -m mcp_glpi.server
# o con logging detallado
python -m mcp_glpi.server --verbosePara integrarlo con Claude Desktop, utilice examples/claude_desktop_config.json como guia. Ajuste la ruta del ejecutable y el cwd segun su entorno.
- Instalar la herramienta de build (solo la primera vez):
python -m pip install build
- Generar el paquete wheel desde la raiz del repositorio:
Esto crea el archivo
python -m build --wheel
dist/mcp_glpi-3.0.0-py3-none-any.whllisto para distribuir. - Para instalarlo en otro entorno o servidor, copiar el wheel y ejecutar:
Si el archivo esta en otra ubicacion, ajustar la ruta en el comando anterior.
pip install dist/mcp_glpi-3.0.0-py3-none-any.whl
- Logging detallado: pasar
--verboseal comando principal para habilitar nivelDEBUG. - Inspector MCP: pruebe las herramientas disponibles sin cliente externo usando:
mcp-inspector C:/devIdeas/Repos-propios/mcp-glpi/.venv/Scripts/python.exe "src/mcp_glpi/server.py"
El inspector permite invocar list_tools y call_tool directamente para validar escenarios.
tambien puedes usar un archivo de configuracion
mcp-inspector --config .\examples\config-developer.json
- Sesion GLPI: las herramientas
session_validate,profile_listyentity_listpermiten validar credenciales y consultar el contexto disponible del usuario autenticado (codigos de perfil/entidad a usar conentity_id/profile_iden el resto de las herramientas).
La suite se ejecuta con pytest y esta localizada en tests/.
# Instalar dependencias de desarrollo opcionales
pip install -e .[dev]
# Ejecutar pruebas con el interprete del entorno virtual
.venv/Scripts/python.exe -m pytestLas pruebas cubren:
CommandHandlerpara uso y validacion de argumentos.- Helpers de tickets, cambios, sesion y archivos (
mcp_glpi.glpi.tickets,mcp_glpi.glpi.changes,mcp_glpi.glpi.session,mcp_glpi.glpi.files). - El wrapper HTTP de
glpi_client(tests/glpi_client/), incluyendo subida/descarga de documentos. - Validacion basica de
claude_desktop_config.jsony contenido Markdown.
La capa GLPI fue separada por dominio y responsabilidad:
src/mcp_glpi/glpi/tickets/: lectura, creacion, actualizacion, comentarios (agregar/listar), soluciones (agregar/listar), asignaciones, enlaces y borrado.src/mcp_glpi/glpi/changes/: lectura, creacion, actualizacion, comentarios (agregar/listar), soluciones (agregar/listar), asignaciones, enlaces y borrado.src/mcp_glpi/glpi/session/: lectura de sesion, perfiles (listado y cambio de perfil activo) y entidades (listado y cambio de entidad activa) del usuario logueado.src/mcp_glpi/glpi/files/: subida (file_upload), descarga (file_download) y vinculo/desvinculo (file_link/file_unlink, itemtypeDocument_Item) de documentos.src/mcp_glpi/glpi/generic.py: acceso generico a itemtypes/subtypes soportados (ITEMTYPE_CATALOG, la lista blanca — incluyeDocument/Document_Item), detras deitem_list/item_get/item_subitem_list/item_type_list/item_subtype_list(solo lectura) eitem_delete(la unica mutacion generica).src/mcp_glpi/glpi/shared.py: helpers comunes reutilizados por las entidades GLPI, incluyendofetch_paginated_items/fetch_paginated_subitems(paginacion, apertura de sesion, cambio de entidad/perfil) yEntityList.respond()(dispatch deoutput/fields) que compartenticket_list/change_list, los listados de seguimientos/soluciones, eitem_list/item_subitem_list.
- Archivo de configuracion:
examples/claude_desktop_config.json. - Variables de entorno soportadas: consulte
src/mcp_glpi/common/config.py.
¡Feliz automatizacion con MCP + GLPI!