โ† Back to list
groeimetai

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.

โญ 42๐Ÿด 9๐Ÿ“… Jan 23, 2026

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

TablePurpose
wm_orderWork orders
wm_taskWork order tasks
wm_resourceField technicians
wm_schedule_entrySchedule entries
wm_territoryService 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

ToolPurpose
snow_query_tableQuery FSM tables
snow_execute_script_with_outputTest FSM scripts
snow_find_artifactFind 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

  1. Skills Matching - Match technician skills to requirements
  2. Territory Planning - Optimize service areas
  3. Route Optimization - Minimize travel time
  4. Mobile-First - Design for field use
  5. Real-Time Updates - GPS and status tracking
  6. Parts Management - Track inventory
  7. Time Tracking - Accurate time entries
  8. ES5 Only - No modern JavaScript syntax

Score

Total Score

75/100

Based on repository quality metrics

โœ“SKILL.md

SKILL.mdใƒ•ใ‚กใ‚คใƒซใŒๅซใพใ‚Œใฆใ„ใ‚‹

+20
โœ“LICENSE

ใƒฉใ‚คใ‚ปใƒณใ‚นใŒ่จญๅฎšใ•ใ‚Œใฆใ„ใ‚‹

+10
โœ“่ชฌๆ˜Žๆ–‡

100ๆ–‡ๅญ—ไปฅไธŠใฎ่ชฌๆ˜ŽใŒใ‚ใ‚‹

+10
โ—‹ไบบๆฐ—

GitHub Stars 100ไปฅไธŠ

0/15
โœ“ๆœ€่ฟ‘ใฎๆดปๅ‹•

1ใƒถๆœˆไปฅๅ†…ใซๆ›ดๆ–ฐ

+10
โ—‹ใƒ•ใ‚ฉใƒผใ‚ฏ

10ๅ›žไปฅไธŠใƒ•ใ‚ฉใƒผใ‚ฏใ•ใ‚Œใฆใ„ใ‚‹

0/5
โœ“Issue็ฎก็†

ใ‚ชใƒผใƒ—ใƒณIssueใŒ50ๆœชๆบ€

+5
โœ“่จ€่ชž

ใƒ—ใƒญใ‚ฐใƒฉใƒŸใƒณใ‚ฐ่จ€่ชžใŒ่จญๅฎšใ•ใ‚Œใฆใ„ใ‚‹

+5
โœ“ใ‚ฟใ‚ฐ

1ใคไปฅไธŠใฎใ‚ฟใ‚ฐใŒ่จญๅฎšใ•ใ‚Œใฆใ„ใ‚‹

+5

Reviews

๐Ÿ’ฌ

Reviews coming soon