Skip to main content
Glama
MTLHARRISON

IT Glue MCP Server

by MTLHARRISON
README.md
# IT Glue MCP Server

A Model Context Protocol (MCP) server that provides Claude with access to IT Glue documentation and asset management.

## One-Click Deployment

[![Deploy to DO](https://www.deploytodo.com/do-btn-blue.svg)](https://cloud.digitalocean.com/apps/new?repo=https://github.com/wyre-technology/itglue-mcp/tree/main)

[![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/wyre-technology/itglue-mcp)

> [!NOTE]
> Unlike the other Wyre MCP servers, this one talks to the IT Glue API directly and
> has **no private `@wyre-technology/*` runtime dependency**, so the one-click build
> does not need a GitHub Packages token — the cloud builder's `npm ci` only pulls
> public packages. (A `read:packages` token is only needed to install the published
> `@wyre-technology/itglue-mcp` package itself; see [Installation](#installation).)
> The DigitalOcean target builds the full Docker image and runs the complete MCP
> server over HTTP and is the recommended path; this repo does not ship a Workers
> entrypoint (`src/worker.ts`), so prefer DigitalOcean or the prebuilt container
> image (`ghcr.io/wyre-technology/itglue-mcp`).

## Installation

This package is published to the **GitHub Packages** npm registry, which requires a
token even for public packages. Authenticate npm once, then install:

```bash
# Authenticate npm to GitHub Packages (token needs the read:packages scope)
export NODE_AUTH_TOKEN=$(gh auth token)   # or a PAT with read:packages

npm install @wyre-technology/itglue-mcp
```

The repo's `.npmrc` already points the `@wyre-technology` scope at GitHub Packages and
reads the token from `NODE_AUTH_TOKEN`, so no further config is needed. The same applies
to `npx @wyre-technology/itglue-mcp`.

Or use the Docker image:

```bash
docker pull ghcr.io/wyre-technology/itglue-mcp:latest
```

## Configuration

The server accepts credentials via environment variables:

| Variable | Description | Required |
|----------|-------------|----------|
| `ITGLUE_API_KEY` | Your IT Glue API key (format: ITG.xxx) | Yes (env mode) |
| `ITGLUE_JWT` | A user-session JWT used as an optional **fallback** for document-folder operations on tenants whose API key cannot access the Document Folders resource yet. See [JWT fallback for document-folder operations](#jwt-fallback-for-document-folder-operations). | No |
| `ITGLUE_REGION` | API region: `us`, `eu`, or `au` (default: `us`) | No |
| `ITGLUE_BASE_URL` | Override the IT Glue API base URL (advanced) | No |
| `MCP_TRANSPORT` | Transport: `stdio` (local) or `http` (remote). Defaults to `stdio` when run via `npx`/`node`, and to `http` in the Docker image. | No |
| `MCP_HTTP_PORT` | Port for HTTP transport (default: `8080`) | No |
| `MCP_HTTP_HOST` | Bind address for HTTP transport (default: `0.0.0.0`) | No |
| `AUTH_MODE` | `env` (read credentials from environment) or `gateway` (read per-request credentials from HTTP headers). Default: `env`. | No |

Alternative: When `AUTH_MODE=gateway`, the MCP Gateway injects credentials per request via HTTP headers instead of environment variables. See [Remote Deployment](#remote-deployment-http-streamable).

### JWT fallback for document-folder operations

**A JWT is optional** — it is only needed if your tenant's API key can't access Document Folders yet. Every folder-related path tries your API key first:

- `search_documents` — defaults to a folder-inclusive listing (`filter[document_folder_id]=null` returns all documents, foldered ones included; each result carries its `documentFolderId`). If the tenant's API rejects that filter, the server retries the `[ne]` filter form and finally degrades to the legacy root-only listing, saying so in the result. No JWT is involved at any layer.
- `list_document_folders` — IT Glue's public (API-key) API now documents a Document Folders resource, which is rolling out across tenants through 2026. The server tries the API key first (on the organization-relationship path, then the top-level `/document_folders` path) and only falls back to a JWT if the key is rejected.
- `create_document` — the name-based folder picker uses the same API-key-first enumeration, then a configured JWT; if neither can list folders, it prompts for a folder URL / sibling-document URL / numeric folder ID as the last resort.

If you do need the JWT fallback, provide it in whichever way matches your deployment:

| Mode | How to supply the JWT |
|------|-----------------------|
| Local / env (`AUTH_MODE=env`) | Set the `ITGLUE_JWT` environment variable. |
| Remote gateway (`AUTH_MODE=gateway`) | Send the `X-ITGlue-JWT` request header. |
| Interactive clients (Claude Desktop/Code) | Leave it unset — the server prompts you to paste a JWT on first use and caches it for the session. |

> **Headless deployments (Docker, cloud):** there is no one to answer the interactive prompt, so if your tenant's API key cannot enumerate folders you must set `ITGLUE_JWT` (env mode) or send `X-ITGlue-JWT` (gateway mode) for folder enumeration to work.

**Retrieving a JWT from your browser:**

1. Sign in to IT Glue in your browser.
2. Open DevTools → **Network** tab.
3. Click any request to `itg-api-*.itglue.com`.
4. Copy the value of the `Authorization: Bearer <token>` request header — the `<token>` part is your JWT.

> **Expiry:** IT Glue JWTs are short-lived (~2 hours). A JWT placed in `ITGLUE_JWT` on a long-running container will go stale and the JWT fallback will start failing until it is refreshed. Interactive clients are simply re-prompted on expiry. API-key operations are unaffected.

## Available Tools

### Organizations

- **search_organizations** - Search for organizations with optional filtering by name, type, status, or PSA ID
- **get_organization** - Get a specific organization by ID

### Configurations (Devices/Assets)

- **search_configurations** - Search for configurations with filtering by organization, name, type, status, serial number, RMM ID, or PSA ID
- **get_configuration** - Get a specific configuration by ID

### Locations (Addresses/Sites)

- **search_locations** - Search an organization's locations (built-in address/site records), filtering by organization, name, city, region, or country. Results include the address fields and phone number.
- **get_location** - Get a specific location by ID, including its full address and phone number
- **create_location** - Create a new location for an organization (requires `name`, typically `country_id`)
- **update_location** - Update an existing location; only the fields you supply are changed

### Passwords

- **search_passwords** - Search for password entries (metadata only, no actual passwords in results)
- **get_password** - Get a specific password entry including the actual password value

### Documents

- **search_documents** - Search for documents with filtering by organization, name, or folder. Defaults to a folder-inclusive listing (each result carries its `documentFolderId`), degrading gracefully to a root-only listing on tenants whose API rejects the folder filter
- **get_document** - Get a specific document by ID, including its sectioned body. Renders as an interactive card in MCP Apps hosts — see [Interactive Document Card](#interactive-document-card-mcp-apps)
- **list_document_folders** - List an organization's document folders (names and IDs). Works with an API key on tenants where IT Glue exposes the Document Folders resource; falls back to a JWT otherwise — see [JWT fallback for document-folder operations](#jwt-fallback-for-document-folder-operations)

### Flexible Assets

- **search_flexible_assets** - Search for flexible assets (requires flexible_asset_type_id)

### Utility

- **itglue_health_check** - Verify connectivity to IT Glue API

### Interactive Document Card (MCP Apps)

`get_document` renders as an interactive card in MCP Apps hosts (Claude
Desktop/web) showing the document's name, organization, folder, key dates, and a
plain-text preview of its sections; plain-JSON behavior is unchanged in other
hosts. The card is read-only — neutral by default, brandable via
`window.__BRAND__` injection or `MCP_BRAND_*` env vars (`MCP_BRAND_NAME`,
`MCP_BRAND_LOGO_URL`, `MCP_BRAND_PRIMARY_COLOR`, `MCP_BRAND_ACCENT_COLOR`,
`MCP_BRAND_BG`, `MCP_BRAND_TEXT`) — no rebuild needed.

## Usage with Claude Code

Add to your `.mcp.json`:

```json
{
  "mcpServers": {
    "itglue": {
      "command": "npx",
      "args": ["@wyre-technology/itglue-mcp"],
      "env": {
        "ITGLUE_API_KEY": "${ITGLUE_API_KEY}",
        "ITGLUE_REGION": "us"
      }
    }
  }
}
```

Or with Docker (local stdio):

```json
{
  "mcpServers": {
    "itglue": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i",
        "-e", "MCP_TRANSPORT=stdio",
        "-e", "ITGLUE_API_KEY",
        "ghcr.io/wyre-technology/itglue-mcp:latest"
      ],
      "env": {
        "ITGLUE_API_KEY": "${ITGLUE_API_KEY}"
      }
    }
  }
}
```

> **Note:** The Docker image defaults to HTTP transport. The `-e MCP_TRANSPORT=stdio` above is required to run it as a local stdio server for Claude Desktop/Code. For server deployments, see [Remote Deployment](#remote-deployment-http-streamable) below.

## Remote Deployment (HTTP Streamable)

For server/cloud deployments, run the server with the HTTP Streamable transport. The Docker image already defaults to `MCP_TRANSPORT=http` on port `8080`, exposing two endpoints:

- `POST /mcp` — MCP Streamable HTTP endpoint (stateless: a fresh server is created per request)
- `GET /health` — unauthenticated health check

### Env mode (single tenant)

Credentials come from environment variables. Use this when one API key serves the deployment:

```bash
docker run -d \
  --name itglue-mcp \
  -p 8080:8080 \
  -e ITGLUE_API_KEY="ITG.xxxxxxxx" \
  -e ITGLUE_REGION="us" \
  --restart unless-stopped \
  ghcr.io/wyre-technology/itglue-mcp:latest

# Verify
curl http://localhost:8080/health
# {"status":"ok","transport":"http","authMode":"env",...}
```

Clients connect to `http://<host>:8080/mcp` using the MCP Streamable HTTP transport.

### Gateway mode (multi-tenant / hosted)

When deployed behind an MCP Gateway (e.g. `mcp.wyre.ai`), set `AUTH_MODE=gateway`. Credentials are then injected per request via HTTP headers rather than environment variables:

```bash
docker run -d \
  --name itglue-mcp \
  -p 8080:8080 \
  -e AUTH_MODE=gateway \
  --restart unless-stopped \
  ghcr.io/wyre-technology/itglue-mcp:latest
```

The gateway supplies credentials on each request via these headers:

| Header | Description | Required |
|--------|-------------|----------|
| `X-ITGlue-API-Key` (or `X-API-Key`) | IT Glue API key | One of API-Key or JWT |
| `X-ITGlue-JWT` | JWT for elevated-scope operations | One of API-Key or JWT |
| `X-ITGlue-Region` | API region: `us`, `eu`, or `au` (default: `us`) | No |
| `X-ITGlue-Base-URL` | Override the IT Glue API base URL | No |

Requests missing both `X-ITGlue-API-Key` and `X-ITGlue-JWT` receive a `401`. The `/health` endpoint reports `"authMode":"gateway"` in this mode.

### Running without Docker

The same transport works from an installed/built copy by setting `MCP_TRANSPORT=http`:

```bash
MCP_TRANSPORT=http MCP_HTTP_PORT=8080 ITGLUE_API_KEY="ITG.xxxxxxxx" \
  npx @wyre-technology/itglue-mcp
```

## Example Queries

Once configured, you can ask Claude:

- "Search for organizations containing 'Acme' in IT Glue"
- "Get the configuration details for device ID 12345"
- "Find all passwords for organization ID 100"
- "Search for flexible assets of type 54321"

## Security Notes

- Password search results do not include actual password values for security
- Use `get_password` with explicit ID to retrieve password values
- Store your API key securely using environment variables or a secrets manager
- The API key should have appropriate read permissions in IT Glue

## License

Apache-2.0

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

TDQS

A3.5/5.0

Scored across 24 tools

Disambiguation4/5

Most tools are clearly distinct by resource type (organizations, configurations, locations, passwords, documents, flexible assets) plus action (search/get/create/update/delete). A few potential confusions exist: get_password vs search_passwords are well-differentiated, but get_document/list_document_sections/list_document_folders could blur for an agent unfamiliar with IT Glue's section/folder vs full-document model. The location vs flexible_assets distinction is explicitly documented to avoid misselection.

Naming Consistency5/5

Tool names follow an extremely consistent verb_noun pattern throughout: get_*, search_*, create_*, update_*, delete_*, list_*, publish_*, archive_*/unarchive_*, plus one exception itglue_health_check. The prefix conventions are uniform and predictable across all 24 tools, making the intended action and resource immediately clear.

Tool Count4/5

With 24 tools, this borders the upper edge of reasonable for a broad IT Glue domain covering organizations, configurations, locations, passwords, documents, and flexible assets. Each tool maps to a meaningful operation, though the document-centric surface (10+ tools) is somewhat heavy relative to the thin coverage of other entity types. Still defensible given the domain breadth.

Completeness4/5

The surface covers organizations (search/get), locations (search/get/create/update), passwords (search/get), configurations (search/get), and a rich document lifecycle (search/get/folders/sections/publish/archive/unarchive/create). Notable gaps: no create/update/delete for organizations, configurations, passwords, or flexible assets — only read operations. Since several entity types lack write capabilities, the surface feels read-heavy for those, though document management is fully covered.