Halo ITSM MCP Server
Enables AI assistants to manage tickets, users, clients, assets, and more in Halo ITSM through the Model Context Protocol.
README
Halo ITSM MCP Server
A Model Context Protocol (MCP) server that provides AI assistants with access to the Halo ITSM/PSA/CRM REST API. This enables Large Language Models (LLMs) like Claude, GPT, and others to interact with your Halo instance through a standardized protocol.
Table of Contents
- Overview
- Features
- Prerequisites
- Installation
- Configuration
- Usage
- Available Tools
- Architecture
- Development
- Troubleshooting
- License
Overview
The Model Context Protocol (MCP) is an open standard that allows AI applications to securely connect to external data sources and tools. This server implements MCP for Halo ITSM, enabling AI assistants to:
- Query tickets, users, clients, and other entities from your Halo instance
- Create and update tickets programmatically
- Manage assets, projects, appointments, and more
- Run reports and retrieve business intelligence data
What is Halo ITSM?
Halo ITSM (also known as HaloPSA and HaloCRM) is a comprehensive IT Service Management platform used by MSPs, IT departments, and service organizations. It provides ticketing, asset management, project management, invoicing, and CRM capabilities through a unified platform.
What is MCP?
The Model Context Protocol is an open protocol that standardizes how AI applications connect to external data sources and tools. It enables:
- Tool calling: AI can invoke specific functions with parameters
- Secure authentication: Credentials are managed by the MCP server, not exposed to the AI
- Structured data exchange: Responses are formatted for optimal AI consumption
Features
18 Resource Groups with 60+ Tools
This MCP server provides comprehensive coverage of the Halo ITSM API:
| Resource | Tools | Description |
|---|---|---|
| Tickets | 4 | List, get, create, update tickets |
| Actions | 4 | List, get, create, delete ticket actions/notes |
| Users | 4 | List, get, find by email, get current user |
| Clients | 4 | List, get, create, update clients |
| Agents | 2 | List, get agents |
| Teams | 2 | List, get teams |
| Status | 2 | List, get ticket statuses |
| Ticket Types | 2 | List, get ticket types |
| Assets | 4 | List, get, create, delete assets |
| Sites | 4 | List, get, create, update sites |
| Projects | 4 | List, get, create, update projects |
| Opportunities | 4 | List, get, create, update opportunities |
| Appointments | 3 | List, get, create, delete appointments |
| Attachments | 3 | List, get, delete attachments |
| Items | 3 | List, get, create catalog items |
| Invoices | 3 | List, get, void invoices |
| Suppliers | 4 | List, get, create, update suppliers |
| Reports | 3 | List, get, run reports |
Two Transport Modes
- stdio Mode: For local usage via command line (npx, direct execution)
- SSE Mode: HTTP server with Server-Sent Events for remote/web deployments
Authentication Support
- Client Credentials Flow: Machine-to-machine authentication (recommended)
- Password Grant Flow: Username/password authentication (fallback)
- Automatic Token Management: Tokens are cached and refreshed automatically
Prerequisites
- Node.js v18.0.0 or higher
- Halo ITSM instance with API access enabled
- API credentials (Client ID + Client Secret, or Username + Password)
Obtaining Halo API Credentials
- Log into your Halo ITSM instance as an administrator
- Navigate to Configuration → Integrations → Halo API
- Create a new API application:
- Choose Client Credentials for server-to-server integration
- Note the Client ID and Client Secret
- Configure appropriate API permissions for the application
Installation
From Source
# Clone the repository
git clone https://github.com/your-org/halo-mcp.git
cd halo-mcp
# Install dependencies
npm install
# Build the TypeScript code
npm run build
Using npx (Coming Soon)
npx halo-mcp
Configuration
The server is configured via environment variables. Create a .env file or set them in your shell:
Required Variables
| Variable | Description | Example |
|---|---|---|
HALO_BASE_URL |
Your Halo instance URL | https://yourcompany.halopsa.com |
HALO_CLIENT_ID |
API Client ID | abc123-def456-... |
Authentication Variables (choose one set)
Option A: Client Credentials (Recommended)
| Variable | Description |
|---|---|
HALO_CLIENT_SECRET |
API Client Secret |
Option B: Password Grant
| Variable | Description |
|---|---|
HALO_USERNAME |
Halo username |
HALO_PASSWORD |
Halo password |
Optional Variables
| Variable | Description | Default |
|---|---|---|
HALO_TENANT |
Tenant identifier (for hosted/multi-tenant) | (none) |
HALO_SCOPE |
OAuth scope | all |
PORT |
HTTP server port (SSE mode only) | 3000 |
Example .env File
# Halo Instance
HALO_BASE_URL=https://yourcompany.halopsa.com
HALO_TENANT=yourcompany
# Client Credentials Auth (recommended)
HALO_CLIENT_ID=your-client-id
HALO_CLIENT_SECRET=your-client-secret
# OR Password Grant Auth
# HALO_CLIENT_ID=your-client-id
# HALO_USERNAME=your-username
# HALO_PASSWORD=your-password
# Optional
HALO_SCOPE=all
PORT=3000
Usage
stdio Mode (Local)
The stdio mode is ideal for local development and direct integration with MCP clients like Claude Desktop.
Running Directly
# Development (with hot reload)
npm run dev
# Production
npm run build
npm start
With MCP Inspector
The MCP Inspector is useful for testing:
npx @modelcontextprotocol/inspector node dist/index.js
Claude Desktop Configuration
Add to your Claude Desktop config (claude_desktop_config.json):
{
"mcpServers": {
"halo-itsm": {
"command": "node",
"args": ["/path/to/halo-mcp/dist/index.js"],
"env": {
"HALO_BASE_URL": "https://yourcompany.halopsa.com",
"HALO_CLIENT_ID": "your-client-id",
"HALO_CLIENT_SECRET": "your-client-secret"
}
}
}
}
SSE Mode (Remote/HTTP)
The SSE (Server-Sent Events) mode runs an HTTP server, enabling remote access and browser-based MCP clients.
Running the SSE Server
# Development
npm run dev:sse
# Production
npm run build
npm run start:sse
The server starts on http://localhost:3000 by default (configurable via PORT env var).
Endpoints
| Endpoint | Method | Description |
|---|---|---|
/sse |
GET | SSE connection endpoint (establish session) |
/messages |
POST | JSON-RPC message endpoint |
Connecting with MCP Inspector (SSE)
npx @modelcontextprotocol/inspector
Then connect to: http://localhost:3000/sse
Architecture for SSE Mode
┌─────────────────┐ GET /sse ┌──────────────────┐
│ MCP Client │ ─────────────────→│ │
│ (Inspector, │ SSE Stream │ Halo MCP SSE │
│ Browser, etc) │ ←─────────────────│ Server │
│ │ │ (Express.js) │
│ │ POST /messages │ │
│ │ ─────────────────→│ │
└─────────────────┘ └────────┬─────────┘
│
│ HTTPS
▼
┌──────────────────┐
│ Halo ITSM API │
│ (Your Instance) │
└──────────────────┘
Available Tools
Tickets
| Tool | Description |
|---|---|
halo_list_tickets |
List tickets with filters (search, client, status, agent, pagination) |
halo_get_ticket |
Get a single ticket by ID with full details |
halo_create_ticket |
Create a new ticket |
halo_update_ticket |
Update an existing ticket |
Actions (Ticket Notes)
| Tool | Description |
|---|---|
halo_list_actions |
List actions/notes on tickets |
halo_get_action |
Get a single action by ID |
halo_create_action |
Add a note/action to a ticket |
halo_delete_action |
Delete an action |
Users
| Tool | Description |
|---|---|
halo_list_users |
List users with filters |
halo_get_user |
Get a user by ID |
halo_find_user_by_email |
Find a user by email address |
halo_get_me |
Get the current authenticated user |
Clients
| Tool | Description |
|---|---|
halo_list_clients |
List clients/customers |
halo_get_client |
Get a client by ID |
halo_create_client |
Create a new client |
halo_update_client |
Update an existing client |
Agents
| Tool | Description |
|---|---|
halo_list_agents |
List all agents |
halo_get_agent |
Get an agent by ID |
Teams
| Tool | Description |
|---|---|
halo_list_teams |
List all teams |
halo_get_team |
Get a team by ID |
Status
| Tool | Description |
|---|---|
halo_list_statuses |
List all ticket statuses |
halo_get_status |
Get a status by ID |
Ticket Types
| Tool | Description |
|---|---|
halo_list_ticket_types |
List all ticket types |
halo_get_ticket_type |
Get a ticket type by ID |
Assets
| Tool | Description |
|---|---|
halo_list_assets |
List assets with filters |
halo_get_asset |
Get an asset by ID |
halo_create_asset |
Create a new asset |
halo_delete_asset |
Delete an asset |
Sites
| Tool | Description |
|---|---|
halo_list_sites |
List sites |
halo_get_site |
Get a site by ID |
halo_create_site |
Create a new site |
halo_update_site |
Update an existing site |
Projects
| Tool | Description |
|---|---|
halo_list_projects |
List projects |
halo_get_project |
Get a project by ID |
halo_create_project |
Create a new project |
halo_update_project |
Update an existing project |
Opportunities (Sales/CRM)
| Tool | Description |
|---|---|
halo_list_opportunities |
List sales opportunities |
halo_get_opportunity |
Get an opportunity by ID |
halo_create_opportunity |
Create a new opportunity |
halo_update_opportunity |
Update an existing opportunity |
Appointments
| Tool | Description |
|---|---|
halo_list_appointments |
List appointments |
halo_get_appointment |
Get an appointment by ID |
halo_create_appointment |
Create a new appointment |
halo_delete_appointment |
Delete an appointment |
Attachments
| Tool | Description |
|---|---|
halo_list_attachments |
List attachments for a ticket |
halo_get_attachment |
Get attachment metadata by ID |
halo_delete_attachment |
Delete an attachment |
Items (Catalog)
| Tool | Description |
|---|---|
halo_list_items |
List catalog items |
halo_get_item |
Get an item by ID |
halo_create_item |
Create a new catalog item |
Invoices
| Tool | Description |
|---|---|
halo_list_invoices |
List invoices |
halo_get_invoice |
Get an invoice by ID |
halo_void_invoice |
Void an invoice |
Suppliers
| Tool | Description |
|---|---|
halo_list_suppliers |
List suppliers |
halo_get_supplier |
Get a supplier by ID |
halo_create_supplier |
Create a new supplier |
halo_update_supplier |
Update an existing supplier |
Reports
| Tool | Description |
|---|---|
halo_list_reports |
List available reports |
halo_get_report |
Get report metadata by ID |
halo_run_report |
Execute a report and get results |
Architecture
Project Structure
halo-mcp/
├── src/
│ ├── index.ts # stdio mode entry point
│ ├── httpServer.ts # SSE mode entry point
│ ├── config.ts # Configuration loader
│ ├── auth/
│ │ └── haloAuth.ts # OAuth authentication client
│ ├── api/
│ │ ├── httpClient.ts # HTTP client with auth injection
│ │ ├── tickets.ts # Tickets API wrapper
│ │ ├── users.ts # Users API wrapper
│ │ ├── teams.ts # Teams API wrapper
│ │ ├── agents.ts # Agents API wrapper
│ │ ├── status.ts # Status API wrapper
│ │ ├── actions.ts # Actions API wrapper
│ │ ├── appointments.ts # Appointments API wrapper
│ │ ├── assets.ts # Assets API wrapper
│ │ ├── attachments.ts # Attachments API wrapper
│ │ ├── clients.ts # Clients API wrapper
│ │ ├── invoices.ts # Invoices API wrapper
│ │ ├── items.ts # Items API wrapper
│ │ ├── opportunities.ts # Opportunities API wrapper
│ │ ├── projects.ts # Projects API wrapper
│ │ ├── reports.ts # Reports API wrapper
│ │ ├── sites.ts # Sites API wrapper
│ │ ├── suppliers.ts # Suppliers API wrapper
│ │ └── ticketTypes.ts # Ticket Types API wrapper
│ └── mcp/
│ ├── server.ts # MCP server setup
│ └── tools/
│ ├── ticketsTools.ts
│ ├── usersTools.ts
│ ├── teamsTools.ts
│ ├── agentsTools.ts
│ ├── statusTools.ts
│ ├── actionsTools.ts
│ ├── appointmentsTools.ts
│ ├── assetsTools.ts
│ ├── attachmentsTools.ts
│ ├── clientsTools.ts
│ ├── invoicesTools.ts
│ ├── itemsTools.ts
│ ├── opportunitiesTools.ts
│ ├── projectsTools.ts
│ ├── reportsTools.ts
│ ├── sitesTools.ts
│ ├── suppliersTools.ts
│ └── ticketTypesTools.ts
├── dist/ # Compiled JavaScript
├── Documentation/
│ └── HaloApiDocs/ # Halo API reference documentation
├── package.json
├── tsconfig.json
└── README.md
Component Layers
┌─────────────────────────────────────────────────────────────────┐
│ MCP Transport Layer │
│ ┌─────────────────────┐ ┌──────────────────────────────┐ │
│ │ stdio Transport │ │ SSE Transport (HTTP) │ │
│ │ (index.ts) │ │ (httpServer.ts) │ │
│ └─────────────────────┘ └──────────────────────────────┘ │
└───────────────────────────────┬─────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ MCP Server Layer │
│ (mcp/server.ts) │
│ - Tool registration │
│ - Request routing │
│ - Response formatting │
└───────────────────────────────┬─────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Tools Layer │
│ (mcp/tools/*.ts) │
│ - Input validation │
│ - Parameter mapping │
│ - Response transformation │
└───────────────────────────────┬─────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ API Wrappers Layer │
│ (api/*.ts) │
│ - Resource-specific methods │
│ - Type definitions │
│ - Query building │
└───────────────────────────────┬─────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ HTTP Client Layer │
│ (api/httpClient.ts) │
│ - Request execution │
│ - Error handling │
│ - Query serialization │
└───────────────────────────────┬─────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Authentication Layer │
│ (auth/haloAuth.ts) │
│ - Token acquisition │
│ - Token caching │
│ - Automatic refresh │
└─────────────────────────────────────────────────────────────────┘
Authentication Flow
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ MCP Tool │ │ Auth Client │ │ Halo API │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
│ 1. Request (needs auth) │ │
│─────────────────────────────────→│ │
│ │ │
│ │ 2. Check cached token │
│ │────────┐ │
│ │ │ │
│ │←───────┘ │
│ │ │
│ │ 3. Token expired? │
│ │ POST /auth/token │
│ │─────────────────────────────────→│
│ │ │
│ │ 4. New access_token │
│ │←─────────────────────────────────│
│ │ │
│ │ 5. Cache token │
│ │────────┐ │
│ │ │ │
│ │←───────┘ │
│ │ │
│ 6. Return access token │ │
│←─────────────────────────────────│ │
│ │ │
│ 7. API request with Bearer token │
│────────────────────────────────────────────────────────────────────→│
│ │ │
│ 8. API response │
│←────────────────────────────────────────────────────────────────────│
Development
Scripts
| Script | Description |
|---|---|
npm run build |
Compile TypeScript to JavaScript |
npm run dev |
Run stdio server in development mode |
npm run dev:sse |
Run SSE server in development mode |
npm start |
Run stdio server (production) |
npm run start:sse |
Run SSE server (production) |
npm run typecheck |
Run TypeScript type checking |
Adding a New Resource
-
Create API wrapper in
src/api/<resource>.ts:export class ResourceApi { constructor(private http: HaloHttpClient) {} async list(params?: ListParams): Promise<Resource[]> { return this.http.get<Resource[]>("/Resource", params); } async getById(id: number): Promise<Resource> { return this.http.get<Resource>(`/Resource/${id}`); } } -
Create tool definitions in
src/mcp/tools/<resource>Tools.ts:export const listResourceTool = { name: "halo_list_resources", description: "List resources with optional filters", inputSchema: { type: "object" as const, properties: { // Define input properties }, additionalProperties: false, }, handler: async (input, api) => { const results = await api.list(input); return { resources: results }; }, }; -
Register in server (
src/mcp/server.ts):- Import the API class and tools
- Create API instance
- Add tools to
allToolsarray
Testing with MCP Inspector
# stdio mode
npx @modelcontextprotocol/inspector node dist/index.js
# SSE mode
npm run dev:sse
# Then in another terminal:
npx @modelcontextprotocol/inspector
# Connect to http://localhost:3000/sse
Troubleshooting
Authentication Errors
"Auth failed (401)"
- Verify your
HALO_CLIENT_IDandHALO_CLIENT_SECRETare correct - Check that the API application has appropriate permissions in Halo
- Ensure the API is enabled on your Halo instance
"Missing credentials"
- Provide either
HALO_CLIENT_SECRETOR bothHALO_USERNAMEandHALO_PASSWORD
Connection Issues
"ECONNREFUSED"
- Verify
HALO_BASE_URLis correct and accessible - Check for firewall or network restrictions
- Ensure the URL doesn't have a trailing slash
SSE connection closes immediately
- Ensure
req.bodyis passed tohandlePostMessage()(fixed in latest version) - Check browser console for CORS errors
Tool Errors
"Unknown tool: <name>"
- Verify the tool is registered in
src/mcp/server.ts - Rebuild with
npm run build
Empty results
- Check that your API credentials have permission to access the resource
- Verify filters are correct (e.g.,
statusIdvsstatus_id)
Debug Mode
Enable verbose logging by checking the server console output. Each SSE connection and message is logged.
Authors
- Michel Braga Guimaraes - Lead Developer
- Claude Code (Anthropic) - AI Pair Programmer
License
MIT License
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
Resources
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.