Skip to main content
Glama
README.md
# mcp-servicefusion

A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server exposing the [Service Fusion](https://www.servicefusion.com) REST API to AI agents. Enables AI-assisted field service management: job lookup, customer management, dispatch, invoicing, equipment tracking, and more.

> **Disclaimer:** This is an unofficial, community-built integration. Not affiliated with or endorsed by Service Fusion.

## Features

**Read tools:**
- `get_todays_jobs` — today's scheduled jobs with assigned techs
- `search_jobs` — flexible search with filters (status, customer, date range, etc.)
- `get_job_details` — full job record with expanded relations
- `get_customer_jobs` — all jobs for a given customer
- `search_customers` — by name, phone, email, or address
- `get_equipment` — customer equipment with custom fields
- `get_open_invoices` — outstanding invoices
- `get_techs` — technician list
- `get_job_statuses`, `get_job_categories`, `get_sources` — reference data
- `get_me` — current authenticated user

**Create tools:**
- `create_job`, `create_customer`, `create_estimate`

**API documentation:**
- `get_api_docs` — look up the Service Fusion API reference directly from the MCP connection. Sections: `index`, `jobs`, `customers`, `estimates`, `invoices`, `techs`, `data-types`, `authentication`, `known-issues`, `full`

## Prerequisites

- Node.js ≥ 18
- Service Fusion API credentials (My Office → Developer Settings → API Credentials)

## Setup (local / stdio transport)

```bash
git clone https://github.com/commair-tools/mcp-servicefusion-public.git mcp-servicefusion
cd mcp-servicefusion
npm install
npm run build
cp .env.example .env
# Edit .env and add SF_CLIENT_ID and SF_CLIENT_SECRET
```

### Claude Desktop

Add to your `claude_desktop_config.json` (see `claude_desktop_config.example.json`):

```json
{
  "mcpServers": {
    "service-fusion": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-servicefusion/build/index.js"],
      "env": {
        "SF_CLIENT_ID": "your_client_id_here",
        "SF_CLIENT_SECRET": "your_client_secret_here"
      }
    }
  }
}
```

### Claude Code CLI

```bash
claude mcp add service-fusion node /absolute/path/to/mcp-servicefusion/build/index.js \
  -e SF_CLIENT_ID=your_client_id -e SF_CLIENT_SECRET=your_client_secret
```

## Setup (remote / HTTP transport)

The server also supports Streamable HTTP transport for hosted deployments (Railway, Fly.io, Cloud Run, etc.) with OAuth 2.1 authentication.

### Environment variables

| Variable | Required | Description |
|---|---|---|
| `SF_CLIENT_ID` | Yes | Service Fusion OAuth client ID |
| `SF_CLIENT_SECRET` | Yes | Service Fusion OAuth client secret |
| `TRANSPORT` | Yes (for HTTP) | Set to `http` to enable HTTP transport |
| `PORT` | No | HTTP port (default: `3000`) |
| `BASE_URL` | Yes (for HTTP) | Public URL of your server, e.g. `https://mcp.example.com` — required for OAuth discovery |
| `MCP_OAUTH_PIN` | Recommended | PIN for browser-based OAuth approval (required by Claude.ai web) |
| `MCP_AUTH_TOKEN` | Optional | Static Bearer token for non-OAuth clients (e.g., Claude Code CLI) |
| `SF_API_BASE_URL` | No | Defaults to `https://api.servicefusion.com/v1` |
| `SF_TOKEN_URL` | No | Defaults to `https://api.servicefusion.com/oauth/access_token` |

### Deploying to Railway

1. Fork or import this repo on [Railway](https://railway.app)
2. Set the environment variables listed above
3. Railway auto-builds via `railway.toml` and exposes a public URL
4. Use that URL as your `BASE_URL`

### Authentication

**Claude.ai web** (OAuth flow): add the server URL (without trailing slash, e.g., `https://mcp.example.com/mcp`) as a remote MCP connector in Settings. Leave OAuth client ID/secret fields blank — the server advertises discovery metadata so Claude.ai handles the full OAuth handshake automatically. On first connect, you'll be redirected to a browser page to enter your `MCP_OAUTH_PIN`. After that, tokens auto-refresh for 30 days.

**Claude Code / CLI clients**: use the static token via the `Authorization: Bearer <MCP_AUTH_TOKEN>` header.

**No authentication**: if neither `MCP_OAUTH_PIN` nor `MCP_AUTH_TOKEN` is set, the server runs unauthenticated (not recommended for public-facing deployments).

## API Reference

The repo includes a complete Service Fusion API reference in [`service-fusion-api-reference.md`](./service-fusion-api-reference.md), auto-generated from the official RAML spec at [docs.servicefusion.com](https://docs.servicefusion.com). Agents can access it through the `get_api_docs` tool at runtime.

To regenerate it after Service Fusion updates their spec:

```bash
node scripts/update-api-docs.mjs
```

## Known Issues

### `/jobs` endpoint hangs without `sort` parameter

As of 2026-04-09, Service Fusion's `/jobs` list endpoint hangs indefinitely when queried without a `sort` parameter. This server works around it by defaulting all `/jobs` list queries to `sort=-start_date` in [src/client.ts](./src/client.ts). If you see hangs on other endpoints in the future, check whether they require a sort param too.

### Equipment is a nested resource

There is no top-level `/equipment` endpoint. Equipment must be fetched via `GET /customers/{customer-id}/equipment`. The `get_equipment` tool handles this by resolving `customer_name` to `customer_id` internally.

## API Limitations

Confirmed by Service Fusion support:
- No PUT, PATCH, or DELETE on any endpoint (read and create only)
- No native webhook/callback support
- No sandbox/test environment
- Rate limit: 60 requests/minute (server enforces backoff automatically)

## Tech Stack

- TypeScript + Node.js
- [`@modelcontextprotocol/sdk`](https://github.com/modelcontextprotocol/typescript-sdk) for MCP protocol
- Express for HTTP transport
- OAuth 2.1 with PKCE, Dynamic Client Registration, and resource indicators

## License

Business Source License 1.1 — see [LICENSE](./LICENSE)

**TL;DR:** Free to use, modify, and redistribute (including internally at HVAC businesses to manage your own operations). You may **not** resell it or offer it as a paid hosted service to third parties. On April 10, 2036 it automatically converts to the Apache License 2.0 (fully permissive).

TDQS

A4/5.0

Scored across 16 tools

Disambiguation5/5

Each tool targets a distinct resource or action (customer, job, estimate, invoice, equipment, tech, etc.) with no overlap in functionality. The create, get, and search prefixes clearly separate intents.

Naming Consistency5/5

All tools follow a consistent verb_noun pattern (e.g., create_customer, get_job_details, search_customers). Naming is uniform and predictable across the entire set.

Tool Count5/5

16 tools is appropriate for a field service management API covering customer, job, estimate, invoice, equipment, and lookup functions. Each tool serves a necessary purpose without bloat.

Completeness3/5

The tool set covers creation and retrieval for core entities but lacks update and delete operations for customers, jobs, estimates, and invoices. This is a notable gap for full lifecycle management.

Maintenance

ActivityInactive
ResponsivenessNo issues