RepairDesk MCP Server
# RepairDesk MCP Server
An [MCP](https://modelcontextprotocol.io) (Model Context Protocol) server that gives any
MCP-compatible AI assistant — Claude Code, Claude Desktop, Codex CLI, OpenCode, Cursor,
Windsurf, or any other MCP client — direct, read/write access to your
[RepairDesk](https://www.repairdesk.co/) shop data. Point it at your store's API key and start
asking things like *"look up ticket T-15423"*, *"what's overdue on invoice 8821"*, or *"assign
the iPhone screen job to Dave"*.
Not an official RepairDesk product — an independent tool built by a RepairDesk shop for
RepairDesk shops. No warranty, use at your own risk (see [License](#license)) — but it's in
daily use running a real repair shop's ticket queue, not a proof of concept.
## Contents
- [What you can actually do with this](#what-you-can-actually-do-with-this)
- [Tools reference](#tools-reference)
- [What this is not](#what-this-is-not)
- [Quick start](#quick-start)
- [Manual setup](#manual-setup)
- [All configuration options](#all-configuration-options)
- [Troubleshooting](#troubleshooting)
- [FAQ](#faq)
- [Security](#security)
## What you can actually do with this
Once it's wired into your AI assistant, you can just talk to your RepairDesk data instead of
clicking through the web UI. Some real examples:
**Front counter / triage**
- *"Look up ticket T-15423"* — full ticket detail: customer, device, per-device status, notes.
- *"What's the status on Sarah Miller's phone?"* — searches tickets by customer name/keyword.
- *"Show me everything that's Pending or Waiting for Parts"* — filter tickets by status.
- *"What's assigned to Dave right now?"* — filter tickets by technician.
- *"Pull up John's contact details"* — customer lookup by name, phone, or email.
**Workflow / bench work**
- *"Add a diagnostic note to T-15423: replaced screen, battery tested OK"*
- *"Assign ticket T-15490 to Dave"*
- *"Mark T-15423 as Repaired"* — the server will ask you to confirm first, and flags that this
status auto-fires a customer SMS/email in RepairDesk.
- *"Create a ticket for this customer: iPhone 13, screen replacement"* — again, confirmation
required before it actually creates anything.
**Money / admin**
- *"Which invoices are still unpaid from last month?"*
- *"What's the outstanding balance on invoice 8821?"*
- *"Do we have an iPhone 13 battery in stock?"* — inventory search.
- *"List all our technicians"* / *"What payment methods do we have set up?"*
- *"What repair categories/device types do we have configured?"* — useful context when
building a ticket or diagnosing what a device model even is in your system.
Because this runs through an actual AI assistant rather than a fixed dashboard, you can chain
these naturally — *"find any overdue invoices for customers with a ticket still open"* — and the
assistant works it out across tools instead of you cross-referencing two screens by hand.
## Tools reference
| Tool | What it does |
|---|---|
| `repairdesk_tickets` | Search tickets by status/date/keyword/tech, or get one ticket's full detail (including per-device status) |
| `repairdesk_tickets_write` | Create tickets, update status/device fields, add internal or diagnostic notes, assign a technician |
| `repairdesk_customers` | Look up customers by name, phone, email, or ID |
| `repairdesk_invoices` | Search invoices, get one invoice, or check its outstanding/due amount |
| `repairdesk_inventory` | Search parts stock by keyword |
| `repairdesk_employees` | List employees/technicians |
| `repairdesk_shop_info` | Reference lookups: devices, categories, statuses, colors, networks, tax classes, payment methods, referral sources, repair/service types, locations, problems (by device), trade-ins, purchase orders |
**Safety rail:** `repairdesk_tickets_write` requires `confirmed: true` before applying a status
change, and warns when the target status is one RepairDesk auto-notifies the customer on
(Repaired, Ready for Pickup, Completed, Waiting on Customer, Waiting For Quote, Cancelled). You
don't need to do anything for this to work — just answer "yes" when your assistant relays the
confirmation prompt.
**Handy detail:** ticket lookups/writes accept either RepairDesk's order ID format (`T-15423`)
or the internal numeric ticket ID — you never need to know which one you have, the server
resolves it for you.
## What this is *not*
This covers the read side of RepairDesk plus core ticket workflow writes. It does **not** cover
estimates, appointment creation, POS/sales transactions, inventory writes, payment recording,
ticket image/attachment upload, or webhooks. PRs welcome if you need one of those.
## Quick start
You don't need to be a developer to run this — just comfortable typing a handful of commands
into a terminal. Total time: about 5 minutes.
### 1. Install Node.js (if you don't have it)
Download and install from [nodejs.org](https://nodejs.org/) — get the "LTS" version. This
installs both `node` and `npm`. To check it worked, open a terminal and run:
```bash
node --version
```
You should see something like `v20.x.x` (anything 18 or higher is fine).
### 2. Get the code
**If you have Git:**
```bash
git clone https://github.com/codeyoc/repairdesk-mcp.git
cd repairdesk-mcp
```
**If you don't:** click the green **Code** button on the GitHub repo page → **Download ZIP** →
unzip it somewhere → open a terminal in that folder.
### 3. Get your RepairDesk API key
In your RepairDesk admin: **Settings → API**. Copy the key shown there — the setup script asks
for it in the next step. Treat it like a password: it grants full read/write access to your
shop's data (see [Security](#security)).
### 4. Run the setup script
```bash
node setup.mjs
```
This is the fastest path and handles everything: it runs `npm install` for you if needed, asks
for your API key, asks which AI assistant you're using (Claude Code, Claude Desktop, Codex CLI,
or OpenCode), and writes the config for you automatically — backing up any existing config file
first. If you're on something else, it prints the config block to paste in yourself.
If you'd rather do it by hand — or your client isn't one of the four above — see
[Manual setup](#manual-setup) below instead. Either way, run `npm install` yourself first if you
skip the script.
### 5. Try it
Ask your assistant something like *"Using RepairDesk, list my 5 most recent tickets"*. If it
comes back with real ticket data, you're done.
## Manual setup
Skip this if `node setup.mjs` already worked for you. Otherwise, run `npm install` in this
folder first, then wire up your client by hand:
<details>
<summary><strong>Claude Code</strong></summary>
Run this from anywhere, replacing the path with the full path to where you unzipped/cloned the
folder, and the key with your real one:
```bash
claude mcp add repairdesk \
--env REPAIRDESK_API_KEY=your_key_here \
--env REPAIRDESK_USER_AGENT=YourShopName-MCP/1.0 \
-- node /full/path/to/repairdesk-mcp/server.mjs
```
</details>
<details>
<summary><strong>Claude Desktop</strong></summary>
Open (or create) the config file for your OS:
- **Mac:** `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
- **Linux:** `~/.config/Claude/claude_desktop_config.json`
Add this (merge it with anything already in `mcpServers` if the file isn't empty):
```json
{
"mcpServers": {
"repairdesk": {
"command": "node",
"args": ["/full/path/to/repairdesk-mcp/server.mjs"],
"env": {
"REPAIRDESK_API_KEY": "your_key_here",
"REPAIRDESK_USER_AGENT": "YourShopName-MCP/1.0"
}
}
}
}
```
Save the file, then **fully quit and reopen** Claude Desktop (not just close the window).
</details>
<details>
<summary><strong>Codex CLI (OpenAI)</strong></summary>
Edit (or create) `~/.codex/config.toml` and add:
```toml
[mcp_servers.repairdesk]
command = "node"
args = ["/full/path/to/repairdesk-mcp/server.mjs"]
[mcp_servers.repairdesk.env]
REPAIRDESK_API_KEY = "your_key_here"
REPAIRDESK_USER_AGENT = "YourShopName-MCP/1.0"
```
Start a new Codex session and run `/mcp` to confirm it connected. (Codex also has an interactive
`codex mcp add` command if you prefer that over editing the file — check `codex mcp add --help`
for the exact flags on your installed version.)
</details>
<details>
<summary><strong>OpenCode</strong></summary>
Open (or create) the config file for your OS:
- **Mac/Linux:** `~/.config/opencode/opencode.json`
- **Windows:** `%APPDATA%\opencode\opencode.json`
Add this (merge it with anything already in `mcp` if the file isn't empty):
```json
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"repairdesk": {
"type": "local",
"command": ["node", "/full/path/to/repairdesk-mcp/server.mjs"],
"enabled": true,
"environment": {
"REPAIRDESK_API_KEY": "your_key_here",
"REPAIRDESK_USER_AGENT": "YourShopName-MCP/1.0"
}
}
}
}
```
Restart OpenCode to pick it up.
</details>
<details>
<summary><strong>Any other MCP client (Cursor, Windsurf, etc.)</strong></summary>
The `command`/`args`/`env` shape used above (Claude Code/Desktop) is the de facto standard —
most MCP clients follow it, just in a different settings file. Check your client's docs for
where that file lives; the block itself should work as-is.
</details>
Use the **full, absolute path** to `server.mjs` (e.g. `/Users/you/repairdesk-mcp/server.mjs` or
`C:\Users\you\repairdesk-mcp\server.mjs`) — a relative path will fail because your AI client
doesn't run from inside this folder.
## All configuration options
Everything below goes in the `env`/`environment` block your client's config uses (`setup.mjs`
handles this for you) — not a `.env` file, since most MCP clients don't read one automatically.
`.env.example` in this repo lists the same variables for reference.
| Variable | Required | Default | Purpose |
|---|---|---|---|
| `REPAIRDESK_API_KEY` | Yes | — | Your RepairDesk API key |
| `REPAIRDESK_BASE_URL` | No | `https://api.repairdesk.co/api/web/v1` | Override the API base URL |
| `REPAIRDESK_USER_AGENT` | No | `RepairDesk-MCP/1.0` | User-Agent sent on every request. Set this to your own shop/tool name if you like — it just can't be empty (see [Troubleshooting](#troubleshooting)) |
| `REPAIRDESK_MIN_INTERVAL_MS` | No | `600` | Minimum ms between outbound API calls — see rate limiting below |
| `REPAIRDESK_LOG_DIR` | No | `./logs` | Where `mcp_audit.log` is written |
| `REPAIRDESK_CONFIG` | No | `./config.json` | Path to a JSON config file, if you'd rather use one than env vars (see below) |
**Alternative: config file instead of env vars.** If your setup makes env vars awkward, create a
`config.json` (gitignored) next to `server.mjs`:
```json
{
"repairdesk_api_key": "your_key_here",
"repairdesk_base_url": "https://api.repairdesk.co/api/web/v1"
}
```
It's re-read on every API call, so you can rotate the key without restarting the server.
Environment variables take priority over this file when both are present.
### Rate limiting — the 100/minute thing
RepairDesk's documented cap is **100 requests per minute per API key** (some plans allow up to
120 — check your own plan if you're unsure). This server handles that for you automatically:
- Every outbound call is queued through a single throttle that waits at least
`REPAIRDESK_MIN_INTERVAL_MS` (default 600ms ≈ 100/min) between requests — so asking for a big
batch of tickets won't itself trigger a rate-limit error.
- If RepairDesk still returns a 429 (rate limited) — e.g. another tool is also hammering the same
key — the server automatically waits and retries once before giving up.
- You don't need to configure anything for this to work. Only touch
`REPAIRDESK_MIN_INTERVAL_MS` if you're consistently seeing rate-limit errors (raise it) or you
know your plan allows a higher cap and want faster bulk lookups (lower it, carefully).
## Troubleshooting
**"RepairDesk API returned 401 Unauthorized" / "Unauthorized" in the response**
Your API key is wrong, was revoked, or wasn't picked up. Double-check the key in **Settings →
API** in RepairDesk, and that it's spelled correctly in your MCP client's config (not a stray
space, not still `YOUR_REPAIRDESK_API_KEY_HERE`). Fully restart your AI client after any config
change — most don't reload MCP config live.
**Requests fail immediately / look like they're being blocked, not authenticated**
RepairDesk's Cloudflare blocks requests with an empty or default-looking User-Agent. Don't set
`REPAIRDESK_USER_AGENT` to an empty string.
**"RepairDesk API rate limit hit twice in a row (429)"**
You're making requests faster than your key's limit even after the built-in retry. Raise
`REPAIRDESK_MIN_INTERVAL_MS` (try `1000`) in your config.
**"Ticket T-XXXXX not found — could not resolve to internal ID"**
Check the order ID is correct and exists in this RepairDesk store. If you have the internal
numeric ID instead, that works too — pass it directly.
**"RepairDesk API request timed out after 15000ms"**
Usually a network/firewall issue reaching `api.repairdesk.co`, or `REPAIRDESK_BASE_URL` is
wrong. Check you can reach that host from wherever this server is running.
**Your AI assistant doesn't see the tool at all**
- Confirm the path in `args` is absolute, not relative, and actually points at `server.mjs`.
- Confirm you ran `npm install` in that folder (missing `node_modules` = the server can't start).
- Fully quit and restart your AI client — don't just close the chat window.
- Run `node /full/path/to/server.mjs` directly in a terminal — if it errors, you'll see the
actual problem instead of a generic "tool not available" from your client.
**`node setup.mjs` says it couldn't find `claude`/`codex` on your PATH**
That's fine — it falls back to printing the config block for you to paste in by hand (see
[Manual setup](#manual-setup)). This just means that CLI isn't installed or isn't on your PATH;
it doesn't mean the MCP server itself is broken.
**Still stuck?** Open an issue on this repo with the error message (redact your API key first if
it appears anywhere in the output).
## FAQ
**Is this an official RepairDesk tool?**
No. It's independently built and maintained, using RepairDesk's public API. Use it at your own
discretion.
**Does this cost anything to run?**
No — it's just making the same API calls your RepairDesk plan already allows. There's no
additional fee from this project. (Your AI assistant subscription, e.g. Claude, is separate and
unrelated to this server.)
**Can I use this with something other than Claude?**
Yes — MCP is an open standard. `setup.mjs` configures Claude Code, Claude Desktop, Codex CLI, and
OpenCode directly; anything else that speaks MCP over stdio (Cursor, Windsurf, etc.) can use this
server too, via the manual config in [Manual setup](#manual-setup).
**Can I run this for multiple RepairDesk stores?**
Yes — register it multiple times under different names (e.g. `repairdesk-store1`,
`repairdesk-store2`) in your MCP client, each with its own `REPAIRDESK_API_KEY`.
**Will my AI assistant accidentally email/text my customers?**
Only `repairdesk_tickets_write` can trigger that, and only via a status change — which always
requires an explicit `confirmed: true` and is flagged in the tool description when the target
status is one of RepairDesk's notifying statuses. It won't happen silently.
## Security
Your `REPAIRDESK_API_KEY` grants full read/write access to your shop's customer and financial
data. Keep it in your MCP client's env config, never in a committed file. `config.json` and
`.env` are gitignored here for exactly that reason — use them locally if you prefer a file over
env vars, but don't commit a filled-in copy. Found a security issue? Please open an issue (or a
private report if your host supports it) rather than a public PR with exploit details.
## License
MIT — see [LICENSE](LICENSE). Provided as-is, no warranty — you're responsible for how you use
it against your own RepairDesk account.
TDQS
Scored across 7 tools
Each tool targets a distinct domain entity (tickets, customers, invoices, inventory, employees, reference data), with read and write operations clearly separated. There is no overlap or ambiguity between tool purposes.
All tools share a consistent 'repairdesk_' prefix and noun-based names (customers, invoices, inventory, etc.). The 'tickets' vs 'tickets_write' pair introduces a minor inconsistency, but overall the naming pattern is predictable and clear.
Seven tools is well-scoped for a repair shop management domain. Each tool covers a necessary function without redundancy, making the set compact and purposeful.
The surface provides full ticket lifecycle (search, create, update), customer lookup, invoice queries, inventory search, employee list, and reference data. Minor gaps like ticket deletion or invoice creation exist, but the core workflows are covered.