A Model Context Protocol (MCP) server for Syncro MSP, implementing a decision tree architecture for efficient tool navigation.
- Decision Tree Architecture: Tools are organized by domain and loaded lazily
- Domain Navigation: Navigate between customers, tickets, assets, contacts, and invoices
- Lazy Loading: Domain handlers and the Syncro client are loaded on-demand
- Full Syncro API Coverage: Access to key Syncro MSP functionality
npm install @wyre-technology/syncro-mcpSet the following environment variables:
| Variable | Required | Description |
|---|---|---|
SYNCRO_API_KEY |
Yes | Your Syncro API key |
SYNCRO_SUBDOMAIN |
No | Your Syncro subdomain (if applicable) |
- Log in to your Syncro MSP account
- Navigate to Settings > API Tokens
- Generate a new API token with appropriate permissions
Add to your claude_desktop_config.json:
{
"mcpServers": {
"syncro": {
"command": "npx",
"args": ["@wyre-technology/syncro-mcp"],
"env": {
"SYNCRO_API_KEY": "your-api-key"
}
}
}
}docker build --secret id=npmrc,src=$HOME/.npmrc -t syncro-mcp .
docker run -e SYNCRO_API_KEY=your-api-key syncro-mcpThe server uses a hierarchical approach to tool discovery:
- Initial State: Only navigation and status tools are exposed
- After Navigation: Domain-specific tools become available
- Back Navigation: Return to the main menu to switch domains
This reduces cognitive load and improves LLM tool selection accuracy.
| Domain | Description | Tools |
|---|---|---|
customers |
Manage customer accounts | list, get, create, search |
tickets |
Manage support tickets | list, get, create, update, add_comment |
assets |
Manage configuration items | list, get, search |
contacts |
Manage customer contacts | list, get, create |
invoices |
View and manage billing | list, get, create, email |
Navigate to a domain to access its tools.
{
"domain": "customers" | "tickets" | "assets" | "contacts" | "invoices"
}Return to the main menu from any domain.
Show current navigation state and credential status.
List customers with optional filters.
{
"query": "search term",
"business_name": "Company Inc",
"email": "contact@example.com",
"include_disabled": false,
"page": 1,
"per_page": 25
}Get a specific customer by ID.
{
"customer_id": 123
}Create a new customer.
{
"business_name": "Acme Corp",
"firstname": "John",
"lastname": "Doe",
"email": "john@acme.com"
}Search customers by query string.
{
"query": "acme",
"limit": 25
}List tickets with optional filters.
{
"customer_id": 123,
"status": "Open",
"user_id": 456,
"resolved": false
}Get a specific ticket by ID.
{
"ticket_id": 789
}Create a new ticket.
{
"customer_id": 123,
"subject": "Network Issue",
"problem_type": "Network",
"comment_body": "Initial description"
}Update an existing ticket.
{
"ticket_id": 789,
"status": "Resolved",
"user_id": 456
}Add a comment to a ticket.
{
"ticket_id": 789,
"body": "Comment text",
"hidden": false
}List assets with optional filters.
{
"customer_id": 123,
"asset_type": "Desktop"
}Get a specific asset by ID.
{
"asset_id": 456
}Search assets by query or serial number.
{
"query": "workstation",
"asset_serial": "SN12345"
}List contacts with optional filters.
{
"customer_id": 123,
"query": "john"
}Get a specific contact by ID.
{
"contact_id": 789
}Create a new contact.
{
"customer_id": 123,
"name": "Jane Smith",
"email": "jane@example.com"
}List invoices with optional filters.
{
"customer_id": 123,
"status": "sent",
"since_date": "2024-01-01"
}Get a specific invoice by ID.
{
"invoice_id": 456
}Create a new invoice.
{
"customer_id": 123,
"due_date": "2024-02-01"
}Email an invoice to the customer.
{
"invoice_id": 456,
"subject": "Your Invoice"
}Syncro API has a rate limit of 180 requests per minute. The underlying @wyre-technology/node-syncro library handles rate limiting automatically.
# Install dependencies
npm install
# Build
npm run build
# Run in development
npm run dev
# Type check
npm run typecheck
# Lint
npm run lintApache-2.0