MCP server for Kaseya Autotask PSA — companies, tickets, projects, time entries, and more.
The MCP server for Kaseya Autotask PSA enables model-context access to entities such as companies, tickets, projects, time entries, and more, facilitating integrated AI workflows with Autotask data.
🛠️ Key Features
Provides a Model Context Protocol (MCP) server interface for Autotask data
Connects to companies, tickets, projects, time entries, and related records
Intended for AI assistants and MSP workflows requiring PSA context
Open-source with Apache 2.0 license and Node.js >= 18
🚀 Use Cases
AI-assisted support ticket handling with real-time Autotask context
Project and time-entry lookup for automated reporting
Contextual data access for MSP workflows and client communications
⚡ Developer Benefits
Clear MCP-based data access layer for Autotask entities
Reusable for AI copilots and agents needing PSA context
OSS repository with CI/CD and testing badges referenced in readme
⚠️ Limitations
Source material provides high-level description; implementation specifics are not enumerated here
Data coverage focuses on Autotask PSA entities; other Autotask modules may not be included
Availability and compatibility dependent on external Autotask APIs and credentials
Give your AI assistant direct access to Autotask. Search tickets, create time entries, look up companies, manage projects — all through natural language. No more copy-pasting between browser tabs and chat windows.
This is a Model Context Protocol (MCP) server that connects Claude (or any MCP-compatible AI) to your Autotask PSA environment. Your AI assistant gets 101 tools covering the operations MSP teams use daily: ticket triage, time logging, company lookups, project management, billing review, and more.
If you run an MSP on Autotask and you're tired of the context-switching tax, this is for you.
Note — no GitHub Packages token required. Unlike most WYRE MCP servers,
autotask-mcp does not depend on a private @wyre-technology/* package on
GitHub Packages. Its only WYRE dependency is the autotask-node SDK, declared
as a git dependency on the publicwyre-technology/autotask-node repo, which
npm install resolves anonymously. The DigitalOcean one-click deploy therefore
works without any NODE_AUTH_TOKEN/GITHUB_TOKEN build variable.
See Installation for Docker and from-source methods.
Features
🔌 MCP Protocol Compliance: Full support for MCP resources and tools
🎴 Interactive Ticket Card (MCP Apps): autotask_get_ticket_details renders as an interactive card in MCP Apps hosts (Claude Desktop/web) with an in-card "Add note" round-trip; neutral theme by default, brandable via MCP_BRAND_* env vars; plain-JSON behavior is unchanged in other hosts
🛠️ Comprehensive API Coverage: 101 tools spanning companies, contacts, tickets, projects, billing items, time entries, notes, attachments, and more
🔍 Advanced Search: Powerful search capabilities with filters across all entities
Valid Autotask API credentials (API user email, secret, integration code)
MCP-compatible client (Claude Desktop, Claude Code, etc.)
Docker (for Option 2) or Node.js 18+ (for Option 3)
Configuration
Environment Variables
Create a .env file with your configuration:
bash
# Required Autotask API credentials (Local Mode)
AUTOTASK_USERNAME=your-api-user@example.com
AUTOTASK_SECRET=your-secret-key
AUTOTASK_INTEGRATION_CODE=your-integration-code
# Optional configuration# AUTOTASK_API_URL is auto-detected from AUTOTASK_USERNAME via Autotask's# unauthenticated zoneInformation endpoint on first connect. Only set this# explicitly to override auto-detection (e.g. for an on-prem proxy).# AUTOTASK_API_URL=https://webservices2.autotask.net/atservicesrest/
MCP_SERVER_NAME=autotask-mcp
# Authentication mode
AUTH_MODE=env# env (local), gateway (hosted)# Transport (stdio for local/desktop, http for remote/Docker)
MCP_TRANSPORT=stdio # stdio, http
MCP_HTTP_PORT=8080 # HTTP transport port (only used when MCP_TRANSPORT=http)
MCP_HTTP_HOST=0.0.0.0 # HTTP transport bind address# Logging
LOG_LEVEL=info # error, warn, info, debug
LOG_FORMAT=simple # simple, json# Search-result name enrichment# Max concurrent Autotask API calls used to resolve company/resource names on# search results. Kept low to stay under Autotask's per-integration# concurrent-thread limit (raising it risks HTTP 429 "thread threshold").
AUTOTASK_ENHANCE_CONCURRENCY=3
# Environment
NODE_ENV=production
Gateway Mode
When deployed behind an MCP Gateway (e.g., mcp.wyre.ai), the server operates in gateway mode where credentials are injected via HTTP headers on each request.
# Start the MCP server (stdio transport, for piping to an MCP client)
node dist/entry.js
# Start with HTTP transport
MCP_TRANSPORT=http node dist/index.js
// Search for companies
{
"name": "autotask_search_companies",
"arguments": {
"searchTerm": "Acme Corp",
"isActive": true,
"pageSize": 10
}
}
// Create a new ticket
{
"name": "autotask_create_ticket",
"arguments": {
"companyID": 12345,
"title": "Server maintenance request",
"description": "Need to perform monthly server maintenance",
"priority": 2,
"status": 1
}
}
ID-to-Name Mapping
The Autotask MCP server includes intelligent ID-to-name mapping that automatically resolves company and resource IDs to human-readable names, making API responses much more useful for AI assistants and human users.
Automatic Enhancement
All search and detail tools automatically include an _enhanced field with resolved names:
ID-to-name mapping is applied automatically to all search and detail tool results. No additional tools are needed — the _enhanced field is added transparently to every response that contains company or resource IDs.
Performance Features
Smart Caching: Names are cached for 30 minutes to reduce API calls
Bulk Operations: Efficient batch lookups for multiple IDs
Graceful Fallback: Returns "Unknown Company (123)" if lookup fails
# Clone repository
git clone https://github.com/wyre-technology/autotask-mcp.git
cd autotask-mcp
# Create environment filecp .env.example .env# Edit .env with your credentials# Start with docker-compose
docker compose up -d
Production Deployment
bash
# Build production image locally
docker build -t autotask-mcp:latest .
# Run container
docker run -d \
--name autotask-mcp \
--env-file .env \
--restart unless-stopped \
autotask-mcp:latest
Development Mode
bash
# Start development environment with hot reload
docker compose --profile dev up autotask-mcp-dev
Development
Setup
bash
git clone https://github.com/wyre-technology/autotask-mcp.git
cd autotask-mcp
npm install
Available Scripts
bash
npm run dev # Start development server with hot reload
npm run build # Build for production
npm run test# Run test suite
npm run test:watch # Run tests in watch mode
npm run test:coverage # Run tests with coverage
npm run lint # Run ESLint
npm run lint:fix # Fix ESLint issues
# Run all tests
npm test# Run with coverage
npm run test:coverage
# Run in watch mode
npm run test:watch
# Run specific test file
npm test -- tests/autotask-service.test.ts
Test Categories
Unit Tests: Service layer and utility functions
Integration Tests: MCP protocol compliance
API Tests: Autotask API integration (requires credentials)
Coverage Requirements
Minimum 80% coverage for all metrics
100% coverage for critical paths (authentication, data handling)
Configuration Reference
Environment Variables
Variable
Required
Default
Description
AUTOTASK_USERNAME
✅
-
Autotask API username (email)
AUTOTASK_SECRET
✅
-
Autotask API secret key
AUTOTASK_INTEGRATION_CODE
✅
-
Autotask integration code
AUTOTASK_API_URL
❌
Auto-detected
Autotask API endpoint URL
MCP_SERVER_NAME
❌
autotask-mcp
MCP server name
MCP_TRANSPORT
❌
stdio
Transport type (stdio or http)
MCP_HTTP_PORT
❌
8080
HTTP transport port
MCP_HTTP_HOST
❌
0.0.0.0
HTTP transport bind address
LOG_LEVEL
❌
info
Logging level
LOG_FORMAT
❌
simple
Log output format
AUTOTASK_ENHANCE_CONCURRENCY
❌
3
Max concurrent Autotask API calls used to resolve company/resource names on search results. Kept low to stay under Autotask's concurrent-thread limit.
NODE_ENV
❌
development
Node.js environment
Logging Levels
error: Only error messages
warn: Warnings and errors
info: General information, warnings, and errors
debug: Detailed debugging information
Log Formats
simple: Human-readable console output
json: Structured JSON output (recommended for production)
Rate Limits
Autotask enforces per-integration-code API thresholds on a rolling 1-hour window:
~20,000 req/hr (hard) — sustained HTTP 429 until the window rolls
LLM-driven workflows fan out easily — "status report on all open projects with notes" can issue hundreds of requests across a few minutes. The server tries to make this safer:
429 responses are surfaced as structured errors. Tool results carry error_type: "rate_limited" and a retry_after_seconds field parsed from Autotask's Retry-After header. The error message explicitly tells the LLM not to retry and to ask the user to scope the query — this prevents repeated retries from extending the cooldown.
Fan-out tool descriptions include rate-limit tips. Tools that are commonly looped over (autotask_search_ticket_notes, autotask_search_project_notes, autotask_search_company_notes, autotask_search_time_entries, autotask_search_ticket_attachments) include a hint reminding the LLM to scope the parent record list before iterating.
Raising the limit
Per-integration thresholds can be increased in Autotask:
Autotask Admin → Resources/Users (HR) → Resources
Edit the dedicated API user → Workflow Rules → API Tracking Identifier
Adjust the threshold for the integration code your MCP server uses
This is the right answer when a single integration code is shared between Claude/Copilot/etc. and other tooling. For LLM-heavy workloads, dedicate a separate API user (and integration code) so a fan-out from one client doesn't starve others.
Patterns that help
Always scope by date range when searching notes, time entries, attachments. Even a 30-day window can drop call count by an order of magnitude.
Cache parent lookups. If you're iterating over 100 tickets, fetch the ticket list once and reuse it across follow-up queries; don't re-search per child.
Use autotask_get_field_info to discover picklist values once per session rather than refetching them per call.
If you're seeing threshold warnings from Autotask but the server seems fine, the LLM driver is probably issuing fan-out patterns. Tighten the prompt to scope before iterating.
Troubleshooting
Common Issues
Authentication Errors
code
Error: Missing required Autotask credentials
Solution: Ensure all required environment variables are set correctly.
Connection Timeouts
code
Error: Connection to Autotask API failed
Solutions:
Check network connectivity
Verify API endpoint URL
Confirm API user has proper permissions
Permission Denied
code
Error: User does not have permission to access this resource
Solution: Review Autotask API user permissions and security level settings.
Debug Mode
Enable debug logging for detailed troubleshooting:
bash
LOG_LEVEL=debug npm start
Health Checks
Test server connectivity:
bash
# Run test suite
npm run test# For HTTP transport, check the health endpoint
curl http://localhost:8080/health
# Returns: {"status":"ok"}# Test API connection with debug logging
LOG_LEVEL=debug npm start
Autotask API Rate Limits
Problem: 429 Too Many Requests or "thread limit exceeded" errors when Claude queries aggressively
Autotask enforces 3 concurrent threads per endpoint per API tracking identifier. When an LLM issues multiple tool calls simultaneously (e.g., searching tickets, companies, and contacts at once), requests can pile up and hit this limit.
Built-in mitigation: The underlying autotask-node SDK automatically queues excess requests rather than failing immediately. Requests wait for a slot to free up, so you generally won't see 429 errors — but you may notice slower responses under heavy load.
Critical for team/multi-user deployments: If multiple users or the MCP Gateway share the same API credentials, they compete for the same 3-thread budget. This can cause noticeable slowdowns and, in severe cases, queued requests that time out.
Solution — one API key per team: Create a dedicated Autotask API user per team or integration. Each user has an independent integrationCode with its own thread budget:
Set AUTOTASK_USERNAME, AUTOTASK_SECRET, and AUTOTASK_INTEGRATION_CODE per team
code
Support Team → AUTOTASK_INTEGRATION_CODE=SUPPORT_TEAM_CODE (3 threads)
Projects Team → AUTOTASK_INTEGRATION_CODE=PROJECTS_TEAM_CODE (3 threads, independent)
Additionally, Autotask limits 10,000 total requests per hour across all integrations hitting your tenant. If you hit this limit, all integrations will start receiving 429s — another reason to use targeted queries with appropriate filters.
MCP Client Issues
Problem: MCP server not appearing in Claude Desktop
Solutions:
Check configuration file syntax (valid JSON)
Verify file path in the configuration
Ensure environment variables are set correctly
Restart Claude Desktop completely
Problem: "Invalid JSON-RPC message: [dotenv@...] injecting env" / Server disconnected
Cause: The autotask-node library calls dotenv.config() at module load time. dotenv v17+ writes status messages via console.log to stdout, which corrupts the MCP stdio JSON-RPC channel.
Solution: Ensure you're using dist/entry.js (not dist/index.js) as the entry point. The entry wrapper redirects console.log to stderr before any libraries load.
Problem: Slow responses
Solutions:
Check network connectivity to Autotask API
Enable debug logging (LOG_LEVEL=debug) to identify bottlenecks
The server caches company/resource names for 30 minutes automatically
Security Best Practices
Store credentials in environment variables, not directly in config files
Limit Autotask API user permissions to the minimum required
Rotate API credentials regularly
For Docker deployments, use secrets management rather than plain environment variables
Contributing
Fork the repository
Create a feature branch (git checkout -b feature/amazing-feature)
Commit your changes (git commit -m 'Add amazing feature')
Push to the branch (git push origin feature/amazing-feature)
Open a Pull Request
Development Guidelines
Follow TypeScript best practices
Maintain test coverage above 80%
Use conventional commit messages
Update documentation for API changes
Add tests for new features
License
This project is licensed under the Apache License 2.0. See the LICENSE file for details.
Contributor License Agreement
By submitting a pull request, you agree to the terms of our Contributor License Agreement. This ensures that contributions can be properly licensed and that you have the right to submit the code.