Servicetitan Mcp Server — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Servicetitan Mcp Server (Agent Skill) and scored it 91/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 1 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
The text {match} is the classic direct prompt-injection phrasing. Placed in a skill body that the agent reads as trusted instructions, it tries to make the agent abandon its prior rules and follow whatever comes next — a full system-prompt override.
ignore/disregard/forget … previous instructions sentence.Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
A Model Context Protocol (MCP) server that connects Claude Desktop to your ServiceTitan account at American Leak Detection.
Ask Claude natural language questions about technician jobs and business performance — without exposing any customer personal information.
"How many jobs did Freddy do last week?"
"How much revenue did Tom bring in last week?"
"What was total business revenue last week?"
"Compare all technicians for last week — who brought in the most?"
"How many no-charge jobs were there last week?"
"What does Freddy's schedule look like this week?"
"Who had the most scheduled hours last week? Who started earliest?"
"What is the average revenue per job by job type trending over the last 90 days?"
"Show revenue trend by business unit for the last 3 months."
"List all active technicians."
"What job types does Freddy do? Break down his job mix for the last 90 days."
"Compare all technicians by job type for the last 90 days."
"How many cancellations were there last month? How many were late?"
"Show discount activity for last month."
"Show all recall jobs for the last 90 days."
"How many GO BACKs were true recalls vs Set Test jobs last month?"
"What is our recall rate by technician? Who is causing the most rework?"
"Show me all jobs tagged Set Test for the last 90 days."
"Search job summaries for 'FG going' for last month."Claude Desktop → MCP Server → ServiceTitan API (read-only)
All data is aggregated before being returned to Claude. Customer names, addresses, and contact information are never sent to Claude — only job counts, statuses, revenue totals, and technician names.
git clone <repo-url> servicetitan-mcp-server
cd servicetitan-mcp-server
python -m venv venv
venv\Scripts\activate
pip install -r requirements.txtCopy the example env file and fill in your ServiceTitan credentials:
copy .env.example .envEdit .env:
ST_CLIENT_ID=your_client_id_here
ST_CLIENT_SECRET=your_client_secret_here
ST_APP_KEY=your_app_key_here
ST_TENANT_ID=your_numeric_tenant_id
ST_AUTH_URL=https://auth.servicetitan.io/connect/token
ST_API_BASE=https://api.servicetitan.ioWhere to find these: ServiceTitan Developer Portal → Your App → Credentials. ST_TENANT_ID is the numeric ID visible in your ServiceTitan URL.python servicetitan_mcp_server.py --checkExpected output:
Connection OK — ServiceTitan authentication successful.
You can now add this server to Claude Desktop.If this fails, double-check your .env credentials.
Windows note: Claude Desktop is a Windows Store (UWP) app. The config file is not in the standard %APPDATA%\Claude\ folder — it's in the MSIX package location.%LOCALAPPDATA%\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\claude_desktop_config.jsonOpen that file in a text editor. Add the mcpServers block (update the paths to match your installation):
{
"mcpServers": {
"servicetitan": {
"command": "C:\\Users\\Tracy\\Projects\\servicetitan-mcp-server\\venv\\Scripts\\python.exe",
"args": [
"C:\\Users\\Tracy\\Projects\\servicetitan-mcp-server\\servicetitan_mcp_server.py"
]
}
}
}Use the full absolute path — Claude Desktop can launch this server from any working directory.
Fully quit and restart Claude Desktop after editing the config file.
In a new chat, you should see the tools indicator (⚡ or a hammer icon) confirming the server loaded.
#### list_technicians Lists all active technicians. Optionally filter by name.
Example: "List all technicians" or "Find technicians named Danny"
#### get_technician_jobs Shows job counts for a specific technician over a date range, broken down by status.
Parameters: technician_name, start_date, end_date
#### get_jobs_summary Shows job totals across all technicians for a date range.
Parameters: start_date, end_date
#### get_jobs_by_type Individual job-level records filtered by job type name, with all assigned technicians shown (primary + added). Optionally filter by technician or status.
Parameters: job_types (comma-separated names), start_date, end_date, technician_name (optional), status ("All", "Completed", or "Canceled")
#### get_technician_revenue Revenue breakdown for a specific technician — total revenue, billed vs no-charge, and revenue per job.
Parameters: technician_name, start_date, end_date
#### get_revenue_summary Business-wide revenue totals for a date range.
Parameters: start_date, end_date
#### get_no_charge_jobs Count and percentage of no-charge jobs in a date range.
Parameters: start_date, end_date
#### compare_technicians Leaderboard comparing all technicians: jobs, revenue, revenue per job, and no-charge count. Sorted by revenue descending.
Parameters: start_date, end_date
#### get_revenue_trend Average revenue per job by category (job type or business unit), broken down by month. Shows which categories are trending up or down. Best with a 60-90 day range.
Parameters: group_by ("job_type" or "business_unit"), start_date, end_date
#### get_technician_schedule Day-by-day appointment schedule for a specific technician, showing start/end times and status.
Parameters: technician_name, start_date, end_date
#### compare_technician_hours Compares all technicians by scheduled appointment hours and earliest start time. Sorted by hours descending.
Parameters: start_date, end_date
Note: Schedule tools show scheduled appointment hours — not actual clock-in/out times (clock data is not available via the ServiceTitan API).
#### get_technician_job_mix Break down a technician's jobs by job type — count, revenue, avg $/job per type. Shows what percentage of their work and revenue comes from each job type.
Parameters: technician_name, start_date, end_date
#### compare_technician_job_mix Company-wide matrix comparing all technicians across all job types. Shows who handles what work and how their $/job compares to the company average. Optionally filter to a single job type.
Parameters: job_type (optional), start_date, end_date
#### get_cancellations Canceled job records with timing analysis — how far in advance each was canceled and whether it was a late cancel (within 24 hours of the appointment). Tags shown as cancel reason proxy.
Parameters: technician_name (optional), late_only (optional), start_date, end_date
#### get_technician_discounts Discount and credit activity per technician from invoices. Detects discounts via negative line items. Shows discount count, total amount, and common SKUs.
Parameters: technician_name (optional), min_discount_amount (optional), start_date, end_date
#### get_recalls Jobs where recallForId is not null — these are true ServiceTitan recalls booked via the "Recall..." job action. Shows each recall with its original job (or notes if outside the date range), days between original and recall, and the job summary with a PII warning.
Parameters: technician_name (optional — filters by recall tech), business_unit (optional), start_date, end_date
#### get_callback_chains Groups recall jobs by their original job to show full callback chains. Shows how many truck rolls each chain required and the opportunity cost (recall visits × average revenue per job). Useful for identifying which jobs are generating repeat visits.
Parameters: technician_name (optional — filters by original job tech), min_chain_length (default 2 — minimum total visits to show), start_date, end_date
#### get_recall_summary Recall rate breakdown by technician, business unit, or job type — attributed to the original job's tech/BU (who caused the rework). Shows recall rate %, average days to recall, and opportunity cost. Includes a GO BACK classification block separating true recalls from Set Test jobs and unclassified GO BACKs.
Parameters: group_by ("technician", "business_unit", or "job_type"), start_date, end_date
#### get_jobs_by_tag Jobs filtered by tag name(s). Tag names are resolved to IDs client-side (case-insensitive). If a tag name isn't found, lists all available tags. Useful for finding "Set Test", "CC on FILE", or any other tagged jobs.
Parameters: tag_names (comma-separated names, required), technician_name (optional), start_date, end_date
#### search_job_summaries Case-insensitive text search across job summary notes. Always shows a PII warning — summaries are free-text entered by dispatchers and may contain customer names or contact info. Returns up to 50 matches.
Parameters: search_text (required, minimum 2 characters), technician_name (optional), job_type (optional), start_date, end_date
All date parameters default to last full Monday–Sunday week when omitted. Maximum date range is 90 days.
The server writes structured JSON logs to logs/mcp_server.log. Useful for debugging:
# Watch logs in real time (Git Bash / PowerShell)
Get-Content logs\mcp_server.log -Wait -Tail 20Logs never contain credentials, OAuth tokens, or customer personal information.
--check to verify credentials workThe name search is case-insensitive substring matching. Try a shorter fragment:
Run list_technicians to see exact names.
YYYY-MM-DD formatToken expires every 15 minutes but refreshes automatically. If you see auth errors, check that your ST_CLIENT_SECRET in .env is current. Credentials may need rotation in the ServiceTitan developer portal.
See CLAUDE.project.md → "Adding New Features" for the step-by-step process.
The general pattern:
@mcp.tool() function in the appropriate tools_*.py modulequery_validator.pyshared_helpers.py if needed# Activate environment
venv\Scripts\activate
# Format code
black .
ruff check --fix .
# Security audit
pip-audit
# Run tests (once tests/ is built)
pytest tests/ -v~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.