A Model Context Protocol (MCP) server that provides AI assistants with structured access to Kaseya Autotask PSA data and operations.
Note: This is the opinkerfi fork of wyre-technology/autotask-mcp, extended with 8 workflow tools for automated ticket management and GitHub integration.
Claude Desktop — download, open, done:
- Download
autotask-mcp.mcpbfrom the latest release - Open the file (double-click or drag into Claude Desktop)
- Enter your Autotask credentials when prompted (Username, Secret, Integration Code)
No terminal, no JSON editing, no Node.js install required.
Claude Code (CLI):
claude mcp add autotask-mcp \
-e AUTOTASK_USERNAME=your-user@company.com \
-e AUTOTASK_SECRET=your-secret \
-e AUTOTASK_INTEGRATION_CODE=your-code \
-- npx -y github:opinkerfi/autotask-mcpSee Installation for Docker and from-source methods.
- 🔌 MCP Protocol Compliance: Full support for MCP resources and tools
- 🛠️ Comprehensive API Coverage: 39 tools spanning companies, contacts, tickets, projects, billing items, time entries, notes, attachments, and more
- 🔍 Advanced Search: Powerful search capabilities with filters across all entities
- 📝 CRUD Operations: Create, read, update operations for core Autotask entities
- 🔄 ID-to-Name Mapping: Automatic resolution of company and resource IDs to human-readable names
- ⚡ Intelligent Caching: Smart caching system for improved performance and reduced API calls
- 🔒 Secure Authentication: Enterprise-grade API security with Autotask credentials
- 🌐 Dual Transport: Supports both stdio (local) and HTTP Streamable (remote/Docker) transports
- 📦 MCPB Packaging: One-click installation via MCP Bundle for desktop clients
- 🐳 Docker Ready: Containerized deployment with HTTP transport and health checks
- 📊 Structured Logging: Comprehensive logging with configurable levels and formats
- 🧪 Test Coverage: Comprehensive test suite with 80%+ coverage
This fork adds 8 workflow tools (prefixed ok_) for automating ticket management in opinkerfi's development workflow:
| Tool | Description |
|---|---|
ok_find_ticket |
Multi-strategy search by issue number, title keywords, or ticket number |
ok_create_ticket |
Create company, project, or internal-dev tickets from GitHub issues |
ok_link_issue_to_ticket |
Add GitHub issue URL as a note on an Autotask ticket (idempotent) |
ok_link_ticket_to_issue |
Add Autotask ticket URL to a GitHub issue body (idempotent) |
ok_get_repo_config |
Read Autotask configuration from a repo's CLAUDE.md |
ok_save_repo_config |
Write/update Autotask configuration in a repo's CLAUDE.md |
ok_list_project_phases |
List phases for an Autotask project |
ok_get_ticket_status |
Quick status lookup by ticket ID or number |
See SETUP.md for opinkerfi-specific setup instructions.
- Installation
- Configuration
- Usage
- API Reference
- ID-to-Name Mapping
- HTTP Transport
- Docker Deployment
- Migration Guide
- Development
- Testing
- Troubleshooting
- Contributing
- Contributors
- License
The simplest method — no terminal, no JSON editing, no Node.js install required.
- Download
autotask-mcp.mcpbfrom the latest release - Open the file (double-click or drag into Claude Desktop)
- Enter your Autotask credentials when prompted (Username, Secret, Integration Code)
For Claude Code (CLI), one command:
claude mcp add autotask-mcp \
-e AUTOTASK_USERNAME=your-user@company.com \
-e AUTOTASK_SECRET=your-secret \
-e AUTOTASK_INTEGRATION_CODE=your-code \
-- npx -y github:opinkerfi/autotask-mcpLocal (stdio — for Claude Desktop or Claude Code):
{
"mcpServers": {
"autotask": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"-e", "MCP_TRANSPORT=stdio",
"-e", "AUTOTASK_USERNAME=your-user@company.com",
"-e", "AUTOTASK_SECRET=your-secret",
"-e", "AUTOTASK_INTEGRATION_CODE=your-code",
"--entrypoint", "node",
"ghcr.io/wyre-technology/autotask-mcp:latest",
"dist/entry.js"
]
}
}
}Remote (HTTP Streamable — for server deployments):
docker run -d \
--name autotask-mcp \
-p 8080:8080 \
-e AUTOTASK_USERNAME="your-user@company.com" \
-e AUTOTASK_SECRET="your-secret" \
-e AUTOTASK_INTEGRATION_CODE="your-code" \
--restart unless-stopped \
ghcr.io/wyre-technology/autotask-mcp:latest
# Verify
curl http://localhost:8080/healthClients connect to http://host:8080/mcp using MCP Streamable HTTP transport.
Gateway Mode (for MCP Gateway deployments):
When deploying behind an MCP Gateway that injects credentials via HTTP headers:
docker run -d \
--name autotask-mcp \
-p 8080:8080 \
-e AUTH_MODE=gateway \
--restart unless-stopped \
ghcr.io/wyre-technology/autotask-mcp:latestThe gateway injects credentials via headers:
X-API-Key: Autotask usernameX-API-Secret: Autotask secretX-Integration-Code: Autotask integration code
See Gateway Mode for details.
git clone https://github.com/opinkerfi/autotask-mcp.git
cd autotask-mcp
npm ci && npm run buildThen point your MCP client at dist/entry.js:
{
"mcpServers": {
"autotask": {
"command": "node",
"args": ["/path/to/autotask-mcp/dist/entry.js"],
"env": {
"AUTOTASK_USERNAME": "your-user@company.com",
"AUTOTASK_SECRET": "your-secret",
"AUTOTASK_INTEGRATION_CODE": "your-code"
}
}
}
}- 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)
Create a .env file with your configuration:
# 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=https://webservices.autotask.net/atservices/1.6/atws.asmx
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
# Environment
NODE_ENV=productionWhen 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.
Enable Gateway Mode:
AUTH_MODE=gateway
MCP_TRANSPORT=httpExpected Headers:
| Header | Description |
|---|---|
X-API-Key |
Autotask API username (email) |
X-API-Secret |
Autotask API secret key |
X-Integration-Code |
Autotask integration code |
X-API-URL |
(Optional) Custom Autotask API URL |
Health Check Response (Gateway Mode):
{
"status": "ok",
"transport": "http",
"authMode": "gateway",
"timestamp": "2026-02-05T10:00:00.000Z"
}For detailed migration instructions, see the Migration Guide.
💡 Pro Tip: Copy the above content to a .env file in your project root.
- Create API User: In Autotask, create a dedicated API user with appropriate permissions
- Generate Secret: Generate an API secret for the user
- Integration Code: Obtain your integration code from Autotask
- Permissions: Ensure the API user has read/write access to required entities
For detailed setup instructions, see the Autotask API documentation.
# 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.jsSee Installation for all setup methods.
Resources provide read-only access to Autotask data:
autotask://companies- List all companiesautotask://companies/{id}- Get specific companyautotask://contacts- List all contactsautotask://contacts/{id}- Get specific contactautotask://tickets- List all ticketsautotask://tickets/{id}- Get specific ticketautotask://time-entries- List time entries
The server provides 39 tools for interacting with Autotask:
autotask_search_companies- Search companies with filtersautotask_create_company- Create new companyautotask_update_company- Update existing company
autotask_search_contacts- Search contacts with filtersautotask_create_contact- Create new contact
autotask_search_tickets- Search tickets with filtersautotask_get_ticket_details- Get full ticket details by IDautotask_create_ticket- Create new ticket
autotask_create_time_entry- Log time entryautotask_search_time_entries- Search time entries with filters (resource, ticket, project, date range)
autotask_search_billing_items- Search approved and posted billing itemsautotask_get_billing_item- Get specific billing item by IDautotask_search_billing_item_approval_levels- Search multi-level approval records for time entries
autotask_search_projects- Search projects with filtersautotask_create_project- Create new project
autotask_search_resources- Search resources (technicians/users)
autotask_get_ticket_note/autotask_search_ticket_notes/autotask_create_ticket_noteautotask_get_project_note/autotask_search_project_notes/autotask_create_project_noteautotask_get_company_note/autotask_search_company_notes/autotask_create_company_note
autotask_get_ticket_attachment- Get ticket attachmentautotask_search_ticket_attachments- Search ticket attachments
autotask_get_expense_report/autotask_search_expense_reports/autotask_create_expense_reportautotask_get_quote/autotask_search_quotes/autotask_create_quoteautotask_search_invoices- Search invoicesautotask_search_contracts- Search contracts
autotask_search_configuration_items- Search configuration items (assets)
autotask_search_tasks- Search project tasksautotask_create_task- Create project task
autotask_test_connection- Test API connectivity
// 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
}
}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.
All search and detail tools automatically include an _enhanced field with resolved names:
{
"id": 12345,
"title": "Sample Ticket",
"companyID": 678,
"assignedResourceID": 90,
"_enhanced": {
"companyName": "Acme Corporation",
"assignedResourceName": "John Smith"
}
}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.
- 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
- Parallel Processing: Multiple mappings resolved simultaneously
Test the mapping functionality:
npm run test:mappingFor detailed mapping documentation, see docs/mapping.md.
The server supports the MCP Streamable HTTP transport for remote deployments (e.g., Docker, cloud hosting). Set MCP_TRANSPORT=http to enable it.
# Start with HTTP transport
MCP_TRANSPORT=http MCP_HTTP_PORT=8080 node dist/index.jsThe HTTP transport exposes:
POST /mcp— MCP Streamable HTTP endpointGET /health— Health check (returns{"status":"ok"})
Clients must send requests to /mcp with Accept: application/json, text/event-stream headers per the MCP Streamable HTTP specification.
The Docker image uses HTTP transport by default (port 8080) with a built-in health check.
The Docker image defaults to HTTP transport on port 8080 — suitable for remote/server deployments where clients connect over the network.
# Pull the latest image
docker pull ghcr.io/wyre-technology/autotask-mcp:latest
# Run container with HTTP transport (default)
docker run -d \
--name autotask-mcp \
-p 8080:8080 \
-e AUTOTASK_USERNAME="your-api-user@example.com" \
-e AUTOTASK_SECRET="your-secret-key" \
-e AUTOTASK_INTEGRATION_CODE="your-integration-code" \
--restart unless-stopped \
ghcr.io/wyre-technology/autotask-mcp:latest
# Verify it's running
curl http://localhost:8080/healthFor stdio usage with Claude Desktop, see Installation Option 2.
# Clone repository
git clone https://github.com/opinkerfi/autotask-mcp.git
cd autotask-mcp
# Create environment file
cp .env.example .env
# Edit .env with your credentials
# Start with docker-compose
docker compose up -d# 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# Start development environment with hot reload
docker compose --profile dev up autotask-mcp-devgit clone https://github.com/opinkerfi/autotask-mcp.git
cd autotask-mcp
npm installnpm 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 issuesautotask-mcp/
├── src/
│ ├── handlers/ # MCP request handlers
│ ├── mcp/ # MCP server implementation
│ ├── services/ # Autotask service layer
│ ├── types/ # TypeScript type definitions
│ ├── utils/ # Utility functions (config, logger, cache)
│ ├── entry.ts # Entry point (stdout guard + .env loader)
│ └── index.ts # Server bootstrap (config, logger, server init)
├── tests/ # Test files
├── scripts/ # Build and packaging scripts
│ └── pack-mcpb.js # MCPB bundle creation
├── manifest.json # MCPB manifest for desktop distribution
├── Dockerfile # Container definition (HTTP transport)
├── docker-compose.yml # Multi-service orchestration
└── package.json # Project configuration
# 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- Unit Tests: Service layer and utility functions
- Integration Tests: MCP protocol compliance
- API Tests: Autotask API integration (requires credentials)
- Minimum 80% coverage for all metrics
- 100% coverage for critical paths (authentication, data handling)
| 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 |
NODE_ENV |
❌ | development |
Node.js environment |
error: Only error messageswarn: Warnings and errorsinfo: General information, warnings, and errorsdebug: Detailed debugging information
simple: Human-readable console outputjson: Structured JSON output (recommended for production)
Error: Missing required Autotask credentials
Solution: Ensure all required environment variables are set correctly.
Error: Connection to Autotask API failed
Solutions:
- Check network connectivity
- Verify API endpoint URL
- Confirm API user has proper permissions
Error: User does not have permission to access this resource
Solution: Review Autotask API user permissions and security level settings.
Enable debug logging for detailed troubleshooting:
LOG_LEVEL=debug npm startTest server connectivity:
# 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 startProblem: 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:
- Admin > Resources (Users) > Resources/Users → Add Resource
- Set Security Level to API User
- Note the username, secret, and integration code
- Set
AUTOTASK_USERNAME,AUTOTASK_SECRET, andAUTOTASK_INTEGRATION_CODEper team
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.
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
- 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
- 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
- Follow TypeScript best practices
- Maintain test coverage above 80%
- Use conventional commit messages
- Update documentation for API changes
- Add tests for new features
This project is licensed under the Apache License 2.0. See the LICENSE file for details.
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.
| Avatar | Name | Contributions |
|---|---|---|
![]() |
@asachs01 | Maintainer |
![]() |
@Baphomet480 | CLI bin fix |
- Model Context Protocol by Anthropic
- Autotask REST API by Kaseya
- autotask-node library
Built with ❤️ for the Autotask and AI community

