TypeScript MCP server exposing 18 tools for querying a Halo PSA instance via OAuth 2.0 Client Credentials: - Tickets / actions (list, get, time entries) - Clients / sites (list, get) - Contracts (list, get — recurring service agreements) - Invoices — both one-off (list, get) and recurring (list, get) - Projects (list, get) - Assets / configuration items (list, get) - Agents, reports (list) - revenue_breakdown — composite tool that cross-references contracts, recurring invoices, and one-off invoices to separate recurring (MRR) from non-recurring revenue per client Build artefacts verified: npm install clean (0 vulnerabilities, 107 pkgs), npm run build produces dist/*.js with no TS errors, server boots and announces 'Halo PSA MCP server running on stdio'. Shipping with Dockerfile (multi-stage, alpine), .env.example, README.md (user-facing), and CLAUDE.md (deployment briefing for downstream Claude Code setup on customer machines). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2.4 KiB
Halo PSA MCP Server — Deployment Briefing
You are setting up the Halo PSA MCP server on this machine. This MCP server connects you (Claude Code) to the customer's live Halo PSA instance so you can query their tickets, clients, contracts, invoices, projects, assets, and revenue data via natural language.
What this project is
An MCP server built in TypeScript that authenticates against the Halo PSA REST API using OAuth 2.0 Client Credentials and exposes 18 tools for querying business data. The key differentiator is the revenue_breakdown tool which cross-references contracts, recurring invoices, and one-off invoices to distinguish recurring from non-recurring revenue per customer.
Autonomous Setup Instructions
Follow these steps in order. Do NOT skip any step.
Step 1 — Clone and build
cd ~ git clone https://git.mineracks.com/mineracks/halo-psa-mcp.git cd halo-psa-mcp npm install npm run build
Verify the build succeeded (no TypeScript errors, dist/index.js exists).
Step 2 — Collect credentials
Ask the user for these three values. Do NOT proceed without them:
- HALO_INSTANCE_URL — Their Halo PSA URL (e.g. https://companyname.halopsa.com)
- HALO_CLIENT_ID — OAuth Client ID (GUID format)
- HALO_CLIENT_SECRET — OAuth Client Secret
Optional: 4. HALO_TENANT — Only needed for multi-tenant Halo instances
If the user hasn't created API credentials yet, walk them through it:
- Log into Halo PSA as admin
- Configuration > Integrations > Halo PSA API > View Applications > New
- Auth method: Client ID and Secret (Services)
- Grant read permissions: read:tickets, read:customers, read:contracts, read:invoices, read:projects, read:assets, read:crm
- Save, copy the Client ID and Secret
Step 3 — Create the .env file
Write a .env file in the project root with the credentials from Step 2.
Step 4 — Create a shell wrapper and register the MCP
Create ~/halo-psa-mcp/start.sh that sources the .env and execs node dist/index.js. chmod +x it, then run: claude mcp add halo-psa -- ~/halo-psa-mcp/start.sh
Step 5 — Verify
Restart Claude Code, then test with list_clients (page_size: 5) and list_tickets (page_size: 5, open_only: true).
Key Concept: Recurring vs Non-Recurring
- RECURRING = Contracts + Recurring Invoices (managed services, monthly/quarterly/annual billing)
- NON-RECURRING = Standard Invoices + Project charges (break-fix, ad-hoc, project work)
The revenue_breakdown tool automates this analysis.