Service Fusion MCP
# Service Fusion MCP
An [MCP](https://modelcontextprotocol.io) server exposing the full documented [Service Fusion](https://servicefusion.com) REST API to AI agents — Claude Code, Claude Desktop, Codex, or any MCP-compatible client. Runs locally over stdio.
Built and maintained by [Sinthetix](https://github.com/SinthetikIndustries).
## Features
- Full coverage of the documented Service Fusion REST API: customers, jobs, estimates, invoices, calendar tasks, equipment, technicians, and reference data (categories, job statuses, sources, payment types)
- Read/create operations only — the Service Fusion API documents no `PUT`/`PATCH`/`DELETE` on any endpoint, so this server doesn't expose any
- Automatic OAuth 2.0 client-credentials token handling with caching and refresh
- Pagination handled transparently across all list endpoints
- Reacts to live `429`/rate-limit response headers rather than self-throttling against a guessed limit (Service Fusion does not publish a numeric rate limit)
- Fully typed (TypeScript), validated request/response schemas via [Zod](https://zod.dev)
- Test suite runs fully offline against mocked HTTP responses — no live credentials required to develop or verify changes
## Requirements
- Node.js 18 or later
- A Service Fusion account with API access (My Office > Developer Settings > API Credentials)
## Installation
Published on npm as [`@sinthetixai/service-fusion-mcp`](https://www.npmjs.com/package/@sinthetixai/service-fusion-mcp) — no clone/build needed, `npx` fetches and runs it on demand. Alternatively, clone and build from source:
```bash
git clone https://github.com/SinthetikIndustries/Service-Fusion-MCP.git
cd Service-Fusion-MCP
npm install
npm run build
cp .env.example .env
```
Edit `.env` and set `SF_CLIENT_ID` and `SF_CLIENT_SECRET` from your Service Fusion account (My Office > Developer Settings > API Credentials).
## Configuration
### Claude Code
```bash
claude mcp add service-fusion npx @sinthetixai/service-fusion-mcp \
-e SF_CLIENT_ID=your_client_id -e SF_CLIENT_SECRET=your_client_secret
```
Or, running from a local clone/build:
```bash
claude mcp add service-fusion node /absolute/path/to/Service-Fusion-MCP/build/index.js \
-e SF_CLIENT_ID=your_client_id -e SF_CLIENT_SECRET=your_client_secret
```
### Claude Desktop
Claude Desktop doesn't use the `claude mcp add` CLI — edit its config file directly:
| OS | Config path |
| ------- | ----------------------------------------------------------------- |
| Windows | `%APPDATA%\Claude\claude_desktop_config.json` |
| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |
| Linux | `~/.config/Claude/claude_desktop_config.json` |
Add a `service-fusion` entry under `mcpServers` (see [`claude_desktop_config.example.json`](./claude_desktop_config.example.json)):
```json
{
"mcpServers": {
"service-fusion": {
"command": "npx",
"args": ["@sinthetixai/service-fusion-mcp"],
"env": {
"SF_CLIENT_ID": "your_client_id_here",
"SF_CLIENT_SECRET": "your_client_secret_here"
}
}
}
}
```
Or, running from a local clone/build, replace `command`/`args` with `"node"` and `["/absolute/path/to/Service-Fusion-MCP/build/index.js"]` (see [`claude_desktop_config.example.json`](./claude_desktop_config.example.json)). On Windows, use a double-backslash path, e.g. `"C:\\Users\\you\\Service-Fusion-MCP\\build\\index.js"`. Restart Claude Desktop after saving — it spawns this server on demand, the same way Claude Code does; nothing runs in the background between sessions.
### Other MCP clients
Any client that supports a local stdio MCP server works the same way: point it at `npx @sinthetixai/service-fusion-mcp` (or `node /absolute/path/to/Service-Fusion-MCP/build/index.js` from a local build) with `SF_CLIENT_ID` and `SF_CLIENT_SECRET` set in its environment.
## Testing
```bash
npm test
```
Tests run fully offline against mocked HTTP responses (`undici`'s `MockAgent`) — no live Service Fusion credentials required.
## Scope
Read/create only. The Service Fusion API documents no update or delete operation on any resource, so this server exposes none. See [`service-fusion-api-reference.md`](./service-fusion-api-reference.md) for the underlying API reference this implementation was built against.
## Support
If this saved you some time, you can buy me a coffee on Cash App: [$Sinthetix](https://cash.app/$Sinthetix)
## License
[MIT](./LICENSE)
TDQS
Scored across 24 tools
Most tools map cleanly to a specific resource and action, such as search_customers vs get_customer_details or create_job vs get_job_details. The main ambiguity is among search_jobs, get_customer_jobs, and get_todays_jobs, which all return job lists, though their descriptions do clarify the intended use case.
Tool names consistently follow a get_/search_/create_ plus resource noun pattern in snake_case. Minor special cases like get_me, get_todays_jobs, and get_api_docs are still readable and do not break the overall naming system.
24 tools is on the heavy side and falls within the borderline 16-25 range. Many tools are justified by the breadth of Service Fusion resources, but some are conveniences that overlap with search_jobs, and the number of enum/getter endpoints adds bulk to the surface.
The set covers read and search operations across jobs, customers, estimates, invoices, calendar tasks, equipment, and techs, and supports creating jobs, customers, and estimates. However, there are no update or delete operations for most resources, no invoice creation, and no calendar task creation, leaving some workflows as dead ends.