# GLPI

The GLPI plugin connects Claude to a GLPI 11 instance, the open-source IT service management and asset platform. Like every Speedwave plugin, it is written, developed, and shipped exclusively by Speednet.

## What it does

GLPI holds your IT service management and asset data: tickets, changes, problems, computers and other assets, users, groups, the knowledge base, and projects. This plugin lets Claude read and write that data through 22 tools, covering the ticket lifecycle, asset lookups, and directory objects like users and groups. You ask in plain language, for example to list open tickets or find computers by name, and Claude picks the right tool.

## What it consists of

The plugin is a single stateless MCP worker: a Node 24 and TypeScript Express server that bridges Claude to GLPI's High-Level REST API v2 (`api.php`), not the legacy `apirest.php` v1. It targets GLPI 11 specifically. The worker holds no GLPI data between calls and keeps no session of its own beyond its OAuth token. The container runs with all capabilities dropped, no new privileges, a read-only filesystem, and a single read-only `/tokens` mount; it exposes no host port and is reached only through the MCP Hub on the project network.

The 22 tools sit in three layers: a discovery layer (status, session, endpoint listing, OpenAPI spec, read-only GraphQL), a universal CRUD layer that works against any HL API v2 resource path, and convenience wrappers for ITIL objects (tickets, changes, problems), assets (computers, monitors, and similar), and directory objects (users, groups, entities, profiles). One bundled skill ties these together; see below.

## Skills and commands

| Name | What it does |
| --- | --- |
| `glpi-operations` | Skill for working a GLPI instance: finds, reads, creates, and updates tickets, changes, and problems, browses and edits assets and users, and reaches any other resource by discovering endpoints on the fly. Creates and updates are destructive; Claude confirms before running them. |

The plugin ships no standalone commands, only this skill.

## Tools

The skill above calls these 22 tools. Discovery and read tools run without asking; create, update, and the escape-hatch request run after you confirm. `glpi_delete` is destructive and always asks first.

**Discovery**

| Tool | What it does |
| --- | --- |
| `glpi_status` | Checks that the GLPI instance and its API are reachable. |
| `glpi_session` | Shows who the current OAuth token is signed in as. |
| `glpi_list_endpoints` | Lists the resource namespaces the API exposes, as a starting point for exploration. |
| `glpi_get_openapi` | Fetches the instance's OpenAPI spec, optionally filtered to matching paths. |
| `glpi_graphql` | Runs a read-only GraphQL query for richer or more selective data than REST. |
| `glpi_graphql_schema` | Fetches the GraphQL schema so a query can be built correctly. |

**Universal CRUD**

| Tool | What it does |
| --- | --- |
| `glpi_list` | Lists items at any resource path, with filtering, sorting, and pagination. |
| `glpi_get` | Reads a single item at any resource path. |
| `glpi_create` | Creates an item at any resource path. |
| `glpi_update` | Changes fields on an existing item at any resource path. |
| `glpi_delete` | Deletes an item at any resource path. Destructive; Speedwave confirms before running it. |
| `glpi_request` | Escape hatch for any method and path not covered above, such as sub-resources or plugin actions. |

**Tickets, changes, and problems**

| Tool | What it does |
| --- | --- |
| `glpi_itil_list` | Lists tickets, changes, or problems. |
| `glpi_itil_get` | Reads one ticket, change, or problem by id. |
| `glpi_itil_create` | Opens a new ticket, change, or problem. |
| `glpi_itil_update` | Updates one, for example its status or assignment. |
| `glpi_itil_get_timeline` | Reads the timeline entries on one, optionally filtered to a type such as a followup or task. |
| `glpi_itil_add_timeline` | Adds a timeline entry, such as a followup note, task, approval request, or solution. |

**Assets and directory**

| Tool | What it does |
| --- | --- |
| `glpi_asset_list` | Lists assets of a given type, such as computers, monitors, or printers. |
| `glpi_asset_get` | Reads one asset by type and id. |
| `glpi_user_me` | Returns the record of the user the OAuth token belongs to. |
| `glpi_admin_list` | Lists directory objects: users, groups, entities, or profiles. |

## How it works

GLPI uses host-driven OAuth2 with the authorization-code grant. The host runs the browser sign-in flow and holds the refresh token and client secret off-mount, at `~/.speedwave/oauth/<project>/glpi.json`; only a short-lived access token is written into the worker's read-only `/tokens` mount. The worker reads the projected base URL from `/tokens/glpi_url` and the bearer token from `/tokens/access_token`, and never sees the client secret or refresh token itself.

At request time, resource calls go to `<base>/v2/<path>`, core calls (status, session, OpenAPI) go to the `api.php` root, and GraphQL posts to `<base>/GraphQL`. GLPI returns `400` instead of the standard `401` on an expired token, so the worker treats both as an auth failure: it asks the host OAuth worker to refresh, re-reads the rotated access token, and retries the request once. A lock serializes refreshes, so a burst of failures triggers one refresh, not many. Claude confirms with you before any create, update, or delete; reads (list, get, search, discovery, GraphQL) run without asking.

## Set it up

Setup runs through GLPI's OAuth client registration, then a sign-in from inside Speedwave.

1. In GLPI, go to **Setup → OAuth Clients** and create an OAuth client.
2. Register the redirect URI exactly as `http://127.0.0.1:9123/callback`. Use the literal `127.0.0.1`, not `localhost`.
3. In Speedwave, enter the API base URL (`api.php`), the client id, and the client secret, then **Save**.
4. Click **Sign in with GLPI** to run the OAuth flow. If you later hit an auth error, use **Reconnect**.

<DesktopFrame screen="plugins" />

See [Using plugins](/docs/plugins/using-plugins/) for how to install and enable a plugin in a project before this setup.
**Note:** The API base URL must use `https://` and point at your GLPI API base (`api.php`).

## Security boundaries

The worker only ever holds a short-lived, host-minted access token, mounted read-only. It never sees the OAuth client secret or the refresh token, both of which stay off-mount on the host. The container has no host-exposed ports, so it is reachable only through the MCP Hub, and its filesystem is read-only apart from that one token mount. See [How credentials are handled](/docs/security/credentials/) for how this fits Speedwave's wider isolation model.