
field-service
by groeimetai
๐ค AI-powered ServiceNow development with 400+ MCP tools. Works with Claude, GPT, Gemini, Ollama & 75+ providers. Deploy widgets, manage incidents, automate workflows - all through natural language. Open-source Build Agent alternative.
SKILL.md
name: field-service description: This skill should be used when the user asks to "field service", "work order", "dispatch", "technician", "FSM", "mobile field", "scheduling", "route optimization", or any ServiceNow Field Service Management development. license: Apache-2.0 compatibility: Designed for Snow-Code and ServiceNow development metadata: author: groeimetai version: "1.0.0" category: servicenow tools:
- snow_query_table
- snow_execute_script_with_output
- snow_find_artifact
Field Service Management for ServiceNow
Field Service Management (FSM) manages work orders, technician dispatch, and mobile field operations.
FSM Architecture
Work Order (wm_order)
โโโ Work Order Tasks (wm_task)
โ โโโ Time Entries
โ โโโ Parts Used
โโโ Asset/CI
โโโ Location
Dispatch
โโโ Scheduling
โโโ Route Optimization
Key Tables
| Table | Purpose |
|---|---|
wm_order | Work orders |
wm_task | Work order tasks |
wm_resource | Field technicians |
wm_schedule_entry | Schedule entries |
wm_territory | Service territories |
Work Orders (ES5)
Create Work Order
// Create work order (ES5 ONLY!)
var workOrder = new GlideRecord('wm_order');
workOrder.initialize();
// Basic info
workOrder.setValue('short_description', 'HVAC repair - Building A');
workOrder.setValue('description', 'AC unit not cooling properly');
workOrder.setValue('priority', 2);
// Classification
workOrder.setValue('work_order_type', 'repair');
workOrder.setValue('category', 'hvac');
// Location
workOrder.setValue('location', locationSysId);
workOrder.setValue('cmdb_ci', hvacUnitCISysId);
// Customer/Contact
workOrder.setValue('account', customerAccountSysId);
workOrder.setValue('contact', contactSysId);
// Scheduling
var scheduledStart = new GlideDateTime();
scheduledStart.addDaysLocalTime(1);
workOrder.setValue('scheduled_start', scheduledStart);
// Assignment
workOrder.setValue('assignment_group', fieldServiceGroupSysId);
// SLA
workOrder.setValue('sla', slaDefinitionSysId);
workOrder.insert();
Work Order Tasks
// Create work order tasks (ES5 ONLY!)
function createWorkOrderTasks(workOrderSysId, tasks) {
var createdTasks = [];
for (var i = 0; i < tasks.length; i++) {
var task = new GlideRecord('wm_task');
task.initialize();
task.setValue('work_order', workOrderSysId);
task.setValue('short_description', tasks[i].description);
task.setValue('order', (i + 1) * 100);
// Estimated duration
task.setValue('estimated_duration', tasks[i].duration);
// Skills required
if (tasks[i].skills) {
task.setValue('skills', tasks[i].skills);
}
// Parts needed
if (tasks[i].parts) {
task.setValue('u_parts_required', tasks[i].parts);
}
var taskSysId = task.insert();
createdTasks.push({
sys_id: taskSysId,
number: task.getValue('number')
});
}
return createdTasks;
}
// Example
createWorkOrderTasks(workOrderSysId, [
{ description: 'Diagnose AC unit', duration: '01:00:00', skills: 'hvac_certified' },
{ description: 'Replace compressor', duration: '02:00:00', parts: 'COMP-AC-001' },
{ description: 'Test and verify', duration: '00:30:00' }
]);
Technician Management (ES5)
Create Resource Profile
// Create field technician profile (ES5 ONLY!)
var resource = new GlideRecord('wm_resource');
resource.initialize();
// Link to user
resource.setValue('user', userSysId);
// Skills
resource.setValue('skills', 'hvac_certified,electrical,plumbing');
// Territory
resource.setValue('territory', territorySysId);
// Availability
resource.setValue('work_schedule', scheduleId);
// Vehicle/Equipment
resource.setValue('vehicle', vehicleCISysId);
// Active
resource.setValue('active', true);
resource.insert();
Check Technician Availability
// Get available technicians for time slot (ES5 ONLY!)
function getAvailableTechnicians(scheduledStart, scheduledEnd, requiredSkills, territory) {
var available = [];
// Get all active technicians in territory
var resource = new GlideRecord('wm_resource');
resource.addQuery('active', true);
if (territory) {
resource.addQuery('territory', territory);
}
resource.query();
while (resource.next()) {
// Check skills
if (requiredSkills && !hasRequiredSkills(resource, requiredSkills)) {
continue;
}
// Check availability
if (!isAvailable(resource, scheduledStart, scheduledEnd)) {
continue;
}
var user = resource.user.getRefRecord();
available.push({
resource_sys_id: resource.getUniqueValue(),
user_sys_id: user.getUniqueValue(),
name: user.getDisplayValue(),
skills: resource.getValue('skills'),
territory: resource.territory.getDisplayValue()
});
}
return available;
}
function hasRequiredSkills(resource, requiredSkills) {
var techSkills = resource.getValue('skills').split(',');
var required = requiredSkills.split(',');
for (var i = 0; i < required.length; i++) {
if (techSkills.indexOf(required[i].trim()) === -1) {
return false;
}
}
return true;
}
function isAvailable(resource, start, end) {
// Check for conflicting assignments
var assignment = new GlideRecord('wm_schedule_entry');
assignment.addQuery('resource', resource.getUniqueValue());
assignment.addQuery('start', '<', end);
assignment.addQuery('end', '>', start);
assignment.query();
return !assignment.hasNext();
}
Dispatch & Scheduling (ES5)
Assign Work Order
// Dispatch work order to technician (ES5 ONLY!)
function dispatchWorkOrder(workOrderSysId, resourceSysId, scheduledStart, scheduledEnd) {
// Create schedule entry
var schedule = new GlideRecord('wm_schedule_entry');
schedule.initialize();
schedule.setValue('work_order', workOrderSysId);
schedule.setValue('resource', resourceSysId);
schedule.setValue('start', scheduledStart);
schedule.setValue('end', scheduledEnd);
schedule.setValue('state', 'scheduled');
schedule.insert();
// Update work order
var wo = new GlideRecord('wm_order');
if (wo.get(workOrderSysId)) {
wo.setValue('assigned_to', getResourceUser(resourceSysId));
wo.setValue('scheduled_start', scheduledStart);
wo.setValue('scheduled_end', scheduledEnd);
wo.setValue('state', 'assigned');
wo.update();
}
// Notify technician
gs.eventQueue('wm.work_order.assigned', wo, resourceSysId, '');
return schedule.getUniqueValue();
}
Auto-Dispatch
// Auto-dispatch to best available technician (ES5 ONLY!)
function autoDispatch(workOrderSysId) {
var wo = new GlideRecord('wm_order');
if (!wo.get(workOrderSysId)) {
return { success: false, message: 'Work order not found' };
}
// Get requirements
var scheduledStart = new GlideDateTime(wo.getValue('scheduled_start'));
var estimatedDuration = wo.getValue('estimated_duration') || '02:00:00';
var scheduledEnd = new GlideDateTime(scheduledStart);
var durationParts = estimatedDuration.split(':');
scheduledEnd.addSeconds(
parseInt(durationParts[0], 10) * 3600 +
parseInt(durationParts[1], 10) * 60 +
parseInt(durationParts[2], 10)
);
var requiredSkills = wo.getValue('u_required_skills');
var location = wo.location.getRefRecord();
var territory = location.getValue('u_territory');
// Find available technicians
var available = getAvailableTechnicians(
scheduledStart,
scheduledEnd,
requiredSkills,
territory
);
if (available.length === 0) {
return { success: false, message: 'No available technicians' };
}
// Select best match (first available, could add routing optimization)
var bestMatch = available[0];
// Dispatch
var scheduleId = dispatchWorkOrder(
workOrderSysId,
bestMatch.resource_sys_id,
scheduledStart,
scheduledEnd
);
return {
success: true,
technician: bestMatch.name,
schedule_id: scheduleId
};
}
Mobile Field Service (ES5)
Update Work Order Status (Mobile)
// Update from mobile app (ES5 ONLY!)
function updateWorkOrderFromMobile(workOrderSysId, statusUpdate) {
var wo = new GlideRecord('wm_order');
if (!wo.get(workOrderSysId)) {
return { success: false, message: 'Work order not found' };
}
// Update state
if (statusUpdate.state) {
wo.setValue('state', statusUpdate.state);
if (statusUpdate.state === 'work_in_progress') {
wo.setValue('actual_start', new GlideDateTime());
} else if (statusUpdate.state === 'closed_complete') {
wo.setValue('actual_end', new GlideDateTime());
}
}
// Add work notes
if (statusUpdate.notes) {
wo.work_notes = statusUpdate.notes;
}
// Update location (GPS)
if (statusUpdate.latitude && statusUpdate.longitude) {
wo.setValue('u_technician_latitude', statusUpdate.latitude);
wo.setValue('u_technician_longitude', statusUpdate.longitude);
}
wo.update();
return { success: true };
}
Record Time Entry
// Record technician time (ES5 ONLY!)
function recordTimeEntry(workOrderSysId, timeData) {
var entry = new GlideRecord('time_card');
entry.initialize();
entry.setValue('task', workOrderSysId);
entry.setValue('user', gs.getUserID());
entry.setValue('type', timeData.type); // work, travel, break
entry.setValue('start_time', timeData.startTime);
entry.setValue('end_time', timeData.endTime);
// Calculate duration
var start = new GlideDateTime(timeData.startTime);
var end = new GlideDateTime(timeData.endTime);
var duration = GlideDateTime.subtract(start, end);
entry.setValue('duration', duration);
// Notes
entry.setValue('comments', timeData.notes);
return entry.insert();
}
MCP Tool Integration
Available Tools
| Tool | Purpose |
|---|---|
snow_query_table | Query FSM tables |
snow_execute_script_with_output | Test FSM scripts |
snow_find_artifact | Find configurations |
Example Workflow
// 1. Query open work orders
await snow_query_table({
table: 'wm_order',
query: 'state!=closed_complete^state!=cancelled',
fields: 'number,short_description,location,scheduled_start,assigned_to'
});
// 2. Find available technicians
await snow_execute_script_with_output({
script: `
var available = getAvailableTechnicians(
new GlideDateTime(),
new GlideDateTime().addHours(2),
'hvac_certified',
null
);
gs.info(JSON.stringify(available));
`
});
// 3. Get technician schedule
await snow_query_table({
table: 'wm_schedule_entry',
query: 'resource.user=technician_user_id^startONToday',
fields: 'work_order,start,end,state'
});
Best Practices
- Skills Matching - Match technician skills to requirements
- Territory Planning - Optimize service areas
- Route Optimization - Minimize travel time
- Mobile-First - Design for field use
- Real-Time Updates - GPS and status tracking
- Parts Management - Track inventory
- Time Tracking - Accurate time entries
- ES5 Only - No modern JavaScript syntax
Score
Total Score
Based on repository quality metrics
SKILL.mdใใกใคใซใๅซใพใใฆใใ
ใฉใคใปใณในใ่จญๅฎใใใฆใใ
100ๆๅญไปฅไธใฎ่ชฌๆใใใ
GitHub Stars 100ไปฅไธ
1ใถๆไปฅๅ ใซๆดๆฐ
10ๅไปฅไธใใฉใผใฏใใใฆใใ
ใชใผใใณIssueใ50ๆชๆบ
ใใญใฐใฉใใณใฐ่จ่ชใ่จญๅฎใใใฆใใ
1ใคไปฅไธใฎใฟใฐใ่จญๅฎใใใฆใใ
Reviews
Reviews coming soon


