ServiceNow Capabilities

Naftiko 0.5 capability definitions for ServiceNow - 100 capabilities showing integration workflows and service orchestrations.

Sort
Expand

Queries Azure cost management for spending anomalies, creates a ServiceNow request for financial review, and posts the anomaly details to a Slack channel.

naftiko: "0.5"
info:
  label: "Azure Cloud Cost Anomaly to ServiceNow"
  description: "Queries Azure cost management for spending anomalies, creates a ServiceNow request for financial review, and posts the anomaly details to a Slack channel."
  tags:
    - cloud
    - cost-management
    - azure
    - servicenow
    - slack
    - monitoring
capability:
  exposes:
    - type: mcp
      namespace: cloud-cost-ops
      port: 8080
      tools:
        - name: handle-azure-cost-anomaly
          description: "Given an Azure subscription ID, query Azure cost management for anomalies, create a ServiceNow financial review request, and notify the cloud cost Slack channel."
          inputParameters:
            - name: subscription_id
              in: body
              type: string
              description: "Azure subscription ID to check for cost anomalies."
            - name: budget_threshold_usd
              in: body
              type: number
              description: "Cost threshold in USD above which to flag an anomaly."
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel to notify of the cost anomaly."
          steps:
            - name: get-cost-data
              type: call
              call: "azure-cost.get-cost-summary"
              with:
                subscriptionId: "{{subscription_id}}"
            - name: create-review-request
              type: call
              call: "snow-cost.create-request"
              with:
                short_description: "Azure cost anomaly: subscription {{subscription_id}}"
                description: "Current spend: {{get-cost-data.totalCost}} USD\nThreshold: {{budget_threshold_usd}} USD\nPeriod: {{get-cost-data.billingPeriod}}"
                category: "cloud_cost_review"
            - name: notify-cost-team
              type: call
              call: "slack-cost.post-message"
              with:
                channel: "{{slack_channel}}"
                text: "Azure cost anomaly on subscription {{subscription_id}}: ${{get-cost-data.totalCost}} vs threshold ${{budget_threshold_usd}} | Request: {{create-review-request.number}}"
  consumes:
    - type: http
      namespace: azure-cost
      baseUri: "https://management.azure.com"
      authentication:
        type: bearer
        token: "$secrets.azure_mgmt_token"
      resources:
        - name: cost-summary
          path: "/subscriptions/{{subscriptionId}}/providers/Microsoft.CostManagement/query"
          inputParameters:
            - name: subscriptionId
              in: path
          operations:
            - name: get-cost-summary
              method: POST
    - type: http
      namespace: snow-cost
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: requests
          path: "/table/sc_request"
          operations:
            - name: create-request
              method: POST
    - type: http
      namespace: slack-cost
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Creates a ServiceNow change request for a proposed infrastructure change, assigns approvers from Workday, and posts a review link to Microsoft Teams.

naftiko: "0.5"
info:
  label: "Change Request Approval Workflow"
  description: "Creates a ServiceNow change request for a proposed infrastructure change, assigns approvers from Workday, and posts a review link to Microsoft Teams."
  tags:
    - itsm
    - change-management
    - servicenow
    - workday
    - microsoft-teams
    - approval
capability:
  exposes:
    - type: mcp
      namespace: change-ops
      port: 8080
      tools:
        - name: create-change-request
          description: "Create a ServiceNow change request with risk assessment, look up the approval group from Workday, and notify approvers in Microsoft Teams."
          inputParameters:
            - name: change_title
              in: body
              type: string
              description: "Short description of the proposed change."
            - name: risk_level
              in: body
              type: string
              description: "Risk level: low, medium, or high."
            - name: implementation_date
              in: body
              type: string
              description: "Planned implementation date in ISO 8601 format."
            - name: approver_employee_id
              in: body
              type: string
              description: "Workday employee ID of the change approver."
          steps:
            - name: get-approver
              type: call
              call: "workday.get-worker"
              with:
                workerId: "{{approver_employee_id}}"
            - name: create-cr
              type: call
              call: "snow-change.create-change-request"
              with:
                short_description: "{{change_title}}"
                risk: "{{risk_level}}"
                start_date: "{{implementation_date}}"
                assigned_to: "{{get-approver.userName}}"
            - name: notify-approver
              type: call
              call: "msteams.send-message"
              with:
                recipient_upn: "{{get-approver.workEmail}}"
                text: "Change request {{create-cr.number}} requires your approval. Risk: {{risk_level}}. Planned: {{implementation_date}}."
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/workers/{{workerId}}"
          inputParameters:
            - name: workerId
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: snow-change
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: change-requests
          path: "/table/change_request"
          operations:
            - name: create-change-request
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: messages
          path: "/users/{{recipient_upn}}/sendMail"
          inputParameters:
            - name: recipient_upn
              in: path
          operations:
            - name: send-message
              method: POST

On a GitHub Actions pipeline failure on a protected branch, creates a ServiceNow incident, adds a Datadog deployment marker, and alerts the on-call channel in Slack.

naftiko: "0.5"
info:
  label: "CI/CD Pipeline Failure to ServiceNow Incident"
  description: "On a GitHub Actions pipeline failure on a protected branch, creates a ServiceNow incident, adds a Datadog deployment marker, and alerts the on-call channel in Slack."
  tags:
    - devops
    - cicd
    - github
    - servicenow
    - datadog
    - slack
    - incident-response
capability:
  exposes:
    - type: mcp
      namespace: pipeline-ops
      port: 8080
      tools:
        - name: handle-pipeline-failure
          description: "Given a GitHub workflow run ID and repository, fetch the failure details, create a ServiceNow incident, mark the deployment in Datadog, and alert Slack. Use when CI/CD automation detects a protected-branch failure."
          inputParameters:
            - name: github_repo
              in: body
              type: string
              description: "GitHub repository in owner/repo format."
            - name: run_id
              in: body
              type: integer
              description: "GitHub Actions workflow run ID."
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel for the failure alert."
          steps:
            - name: get-run
              type: call
              call: "github-ci.get-workflow-run"
              with:
                repo: "{{github_repo}}"
                runId: "{{run_id}}"
            - name: create-incident
              type: call
              call: "snow-cicd.create-incident"
              with:
                short_description: "CI/CD failure: {{get-run.name}} on {{get-run.head_branch}}"
                urgency: "2"
                description: "Repo: {{github_repo}}\nRun: {{run_id}}\nBranch: {{get-run.head_branch}}\nCommit: {{get-run.head_sha}}"
            - name: create-dd-marker
              type: call
              call: "datadog-ci.create-event"
              with:
                title: "Pipeline failure: {{github_repo}}/{{get-run.head_branch}}"
                text: "Run {{run_id}} failed. Incident: {{create-incident.number}}"
                tags: "repo:{{github_repo}},branch:{{get-run.head_branch}}"
            - name: alert-slack
              type: call
              call: "slack-ci.post-message"
              with:
                channel: "{{slack_channel}}"
                text: "Pipeline failure in {{github_repo}} ({{get-run.head_branch}}) | Incident: {{create-incident.number}} | Run: {{run_id}}"
  consumes:
    - type: http
      namespace: github-ci
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: workflow-runs
          path: "/repos/{{repo}}/actions/runs/{{runId}}"
          inputParameters:
            - name: repo
              in: path
            - name: runId
              in: path
          operations:
            - name: get-workflow-run
              method: GET
    - type: http
      namespace: snow-cicd
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: datadog-ci
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: events
          path: "/events"
          operations:
            - name: create-event
              method: POST
    - type: http
      namespace: slack-ci
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When CrowdStrike detects a threat on an endpoint, creates a ServiceNow security incident, isolates the host via CrowdStrike, and alerts the security team in Slack.

naftiko: "0.5"
info:
  label: "CrowdStrike Detection to ServiceNow Security Incident"
  description: "When CrowdStrike detects a threat on an endpoint, creates a ServiceNow security incident, isolates the host via CrowdStrike, and alerts the security team in Slack."
  tags:
    - security
    - endpoint
    - crowdstrike
    - servicenow
    - slack
    - incident-response
capability:
  exposes:
    - type: mcp
      namespace: edr-ops
      port: 8080
      tools:
        - name: respond-to-crowdstrike-detection
          description: "Given a CrowdStrike detection ID, fetch the alert details, create a ServiceNow security incident, isolate the affected host, and notify the security Slack channel."
          inputParameters:
            - name: detection_id
              in: body
              type: string
              description: "CrowdStrike detection ID from the Falcon alert."
            - name: security_slack_channel
              in: body
              type: string
              description: "Slack channel for the security team."
          steps:
            - name: get-detection
              type: call
              call: "crowdstrike.get-detection"
              with:
                detectionId: "{{detection_id}}"
            - name: create-security-incident
              type: call
              call: "snow-edr.create-incident"
              with:
                short_description: "CrowdStrike detection: {{get-detection.behavior.scenario}}"
                severity: "1"
                description: "Host: {{get-detection.device.hostname}}\nUser: {{get-detection.behavior.user_name}}\nDetection: {{detection_id}}\nSeverity: {{get-detection.max_severity_displayname}}"
            - name: isolate-host
              type: call
              call: "crowdstrike-action.contain-host"
              with:
                deviceId: "{{get-detection.device.device_id}}"
            - name: alert-security
              type: call
              call: "slack-edr.post-message"
              with:
                channel: "{{security_slack_channel}}"
                text: "CrowdStrike threat detected on {{get-detection.device.hostname}} | Host isolated | Incident: {{create-security-incident.number}} | Detection: {{detection_id}}"
  consumes:
    - type: http
      namespace: crowdstrike
      baseUri: "https://api.crowdstrike.com"
      authentication:
        type: bearer
        token: "$secrets.crowdstrike_token"
      resources:
        - name: detections
          path: "/detects/entities/detect/v2"
          inputParameters:
            - name: detectionId
              in: query
          operations:
            - name: get-detection
              method: GET
    - type: http
      namespace: snow-edr
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: security-incidents
          path: "/table/sn_si_incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: crowdstrike-action
      baseUri: "https://api.crowdstrike.com"
      authentication:
        type: bearer
        token: "$secrets.crowdstrike_token"
      resources:
        - name: device-actions
          path: "/devices/entities/devices-actions/v2"
          operations:
            - name: contain-host
              method: POST
    - type: http
      namespace: slack-edr
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When Datadog detects an anomaly monitor trigger, creates a ServiceNow problem record with RCA details and notifies the on-call team via PagerDuty.

naftiko: "0.5"
info:
  label: "Datadog Anomaly to ServiceNow Problem"
  description: "When Datadog detects an anomaly monitor trigger, creates a ServiceNow problem record with RCA details and notifies the on-call team via PagerDuty."
  tags:
    - itsm
    - monitoring
    - datadog
    - servicenow
    - pagerduty
    - incident-response
capability:
  exposes:
    - type: mcp
      namespace: observability-ops
      port: 8080
      tools:
        - name: handle-datadog-anomaly
          description: "Given a Datadog monitor ID and anomaly event, fetch the monitor details, create a ServiceNow problem record, and page the on-call team via PagerDuty."
          inputParameters:
            - name: monitor_id
              in: body
              type: string
              description: "Datadog monitor ID that fired the anomaly."
            - name: event_message
              in: body
              type: string
              description: "Anomaly event message from Datadog."
            - name: pagerduty_service_id
              in: body
              type: string
              description: "PagerDuty service ID for the on-call escalation."
          steps:
            - name: get-monitor
              type: call
              call: "datadog.get-monitor"
              with:
                monitorId: "{{monitor_id}}"
            - name: create-problem
              type: call
              call: "snow-problem.create-problem"
              with:
                short_description: "Anomaly detected: {{get-monitor.name}}"
                description: "Monitor: {{monitor_id}}\nQuery: {{get-monitor.query}}\nEvent: {{event_message}}"
                category: "availability"
            - name: page-oncall
              type: call
              call: "pagerduty-ops.create-incident"
              with:
                title: "Datadog anomaly: {{get-monitor.name}}"
                severity: "high"
                serviceId: "{{pagerduty_service_id}}"
                details: "ServiceNow problem: {{create-problem.number}} | Monitor ID: {{monitor_id}}"
  consumes:
    - type: http
      namespace: datadog
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: monitors
          path: "/monitor/{{monitorId}}"
          inputParameters:
            - name: monitorId
              in: path
          operations:
            - name: get-monitor
              method: GET
    - type: http
      namespace: snow-problem
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: problems
          path: "/table/problem"
          operations:
            - name: create-problem
              method: POST
    - type: http
      namespace: pagerduty-ops
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.pagerduty_token"
        placement: header
      resources:
        - name: incidents
          path: "/incidents"
          operations:
            - name: create-incident
              method: POST

On new hire creation in Workday, opens a ServiceNow onboarding task, provisions a Microsoft Entra ID account, and sends a Teams welcome message.

naftiko: "0.5"
info:
  label: "Employee Onboarding Orchestrator"
  description: "On new hire creation in Workday, opens a ServiceNow onboarding task, provisions a Microsoft Entra ID account, and sends a Teams welcome message."
  tags:
    - hr
    - onboarding
    - servicenow
    - workday
    - microsoft-entra
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: hr-onboarding
      port: 8080
      tools:
        - name: trigger-onboarding
          description: "Given a Workday employee ID and start date, open a ServiceNow onboarding task, provision Entra ID, and send a Teams welcome message. Use when a new hire record is created."
          inputParameters:
            - name: workday_employee_id
              in: body
              type: string
              description: "Workday worker ID for the new hire."
            - name: start_date
              in: body
              type: string
              description: "Employee start date in ISO 8601 format."
          steps:
            - name: get-employee
              type: call
              call: "workday-hr.get-worker"
              with:
                workerId: "{{workday_employee_id}}"
            - name: create-onboarding-task
              type: call
              call: "snow-onboard.create-ticket"
              with:
                short_description: "New hire onboarding: {{get-employee.displayName}}"
                category: "hr_onboarding"
                assignment_group: "IT_Onboarding"
            - name: provision-entra
              type: call
              call: "entra.create-user"
              with:
                displayName: "{{get-employee.displayName}}"
                userPrincipalName: "{{get-employee.workEmail}}"
                department: "{{get-employee.department}}"
            - name: send-welcome
              type: call
              call: "msteams-onboard.send-message"
              with:
                recipient_upn: "{{get-employee.workEmail}}"
                text: "Welcome to ServiceNow, {{get-employee.firstName}}! Your onboarding ticket is {{create-onboarding-task.number}}."
  consumes:
    - type: http
      namespace: workday-hr
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/workers/{{workerId}}"
          inputParameters:
            - name: workerId
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: snow-onboard
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-ticket
              method: POST
    - type: http
      namespace: entra
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: users
          path: "/users"
          operations:
            - name: create-user
              method: POST
    - type: http
      namespace: msteams-onboard
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: messages
          path: "/users/{{recipient_upn}}/sendMail"
          inputParameters:
            - name: recipient_upn
              in: path
          operations:
            - name: send-message
              method: POST

When a GitHub Dependabot or code scanning alert fires, creates a ServiceNow security incident and posts a notification to the security Slack channel.

naftiko: "0.5"
info:
  label: "GitHub Vulnerability Alert to ServiceNow Security Incident"
  description: "When a GitHub Dependabot or code scanning alert fires, creates a ServiceNow security incident and posts a notification to the security Slack channel."
  tags:
    - security
    - devops
    - github
    - servicenow
    - slack
    - vulnerability
capability:
  exposes:
    - type: mcp
      namespace: security-ops
      port: 8080
      tools:
        - name: create-security-incident-from-github-alert
          description: "Given a GitHub repository and vulnerability alert number, fetch the alert details, create a ServiceNow security incident, and notify the security Slack channel."
          inputParameters:
            - name: github_repo
              in: body
              type: string
              description: "GitHub repository in owner/repo format."
            - name: alert_number
              in: body
              type: integer
              description: "GitHub Dependabot or code scanning alert number."
            - name: security_slack_channel
              in: body
              type: string
              description: "Slack channel for the security team notification."
          steps:
            - name: get-alert
              type: call
              call: "github.get-dependabot-alert"
              with:
                repo: "{{github_repo}}"
                alertNumber: "{{alert_number}}"
            - name: create-sec-incident
              type: call
              call: "snow-sec.create-incident"
              with:
                short_description: "Vulnerability: {{get-alert.securityAdvisory.summary}}"
                severity: "{{get-alert.securityAdvisory.severity}}"
                description: "Repo: {{github_repo}}\nPackage: {{get-alert.dependency.package.name}}\nCVSS: {{get-alert.securityAdvisory.cvss_score}}\nAlert: {{alert_number}}"
            - name: notify-security
              type: call
              call: "slack-sec.post-message"
              with:
                channel: "{{security_slack_channel}}"
                text: "GitHub vulnerability in {{github_repo}}: {{get-alert.securityAdvisory.summary}} ({{get-alert.securityAdvisory.severity}}) | Incident: {{create-sec-incident.number}}"
  consumes:
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: dependabot-alerts
          path: "/repos/{{repo}}/dependabot/alerts/{{alertNumber}}"
          inputParameters:
            - name: repo
              in: path
            - name: alertNumber
              in: path
          operations:
            - name: get-dependabot-alert
              method: GET
    - type: http
      namespace: snow-sec
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: security-incidents
          path: "/table/sn_si_incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: slack-sec
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves a ServiceNow incident by number, evaluates priority against SLA thresholds, and escalates to PagerDuty with a Slack alert if the SLA is at risk.

naftiko: "0.5"
info:
  label: "Incident Triage and Escalation"
  description: "Retrieves a ServiceNow incident by number, evaluates priority against SLA thresholds, and escalates to PagerDuty with a Slack alert if the SLA is at risk."
  tags:
    - itsm
    - incident-response
    - servicenow
    - pagerduty
    - slack
    - sla
capability:
  exposes:
    - type: mcp
      namespace: incident-ops
      port: 8080
      tools:
        - name: triage-incident
          description: "Given a ServiceNow incident number, check its priority and SLA remaining time, trigger a PagerDuty alert if critical, and post an escalation notice to Slack."
          inputParameters:
            - name: incident_number
              in: body
              type: string
              description: "ServiceNow incident number, e.g. INC0012345."
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel name or ID to post the escalation notice."
          steps:
            - name: get-incident
              type: call
              call: "servicenow.get-incident"
              with:
                number: "{{incident_number}}"
            - name: trigger-pagerduty
              type: call
              call: "pagerduty.create-incident"
              with:
                title: "SLA at risk: {{get-incident.short_description}}"
                severity: "critical"
                serviceId: "$secrets.pagerduty_service_id"
                details: "Incident: {{incident_number}} | Priority: {{get-incident.priority}} | Assigned to: {{get-incident.assigned_to}}"
            - name: post-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "{{slack_channel}}"
                text: "Escalation: {{incident_number}} — {{get-incident.short_description}} | PagerDuty ID: {{trigger-pagerduty.id}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-incident
              method: GET
    - type: http
      namespace: pagerduty
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.pagerduty_token"
        placement: header
      resources:
        - name: incidents
          path: "/incidents"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a critical Jira bug is created in an engineering project, creates a linked ServiceNow incident and posts a cross-team alert to a Slack channel.

naftiko: "0.5"
info:
  label: "Jira Bug to ServiceNow Incident Sync"
  description: "When a critical Jira bug is created in an engineering project, creates a linked ServiceNow incident and posts a cross-team alert to a Slack channel."
  tags:
    - devops
    - itsm
    - jira
    - servicenow
    - slack
    - incident-response
capability:
  exposes:
    - type: mcp
      namespace: eng-itsm-sync
      port: 8080
      tools:
        - name: sync-jira-bug-to-incident
          description: "Given a Jira issue key for a critical bug, fetch the issue details, create a corresponding ServiceNow incident, and notify the engineering alert Slack channel."
          inputParameters:
            - name: jira_issue_key
              in: body
              type: string
              description: "Jira issue key, e.g. ENG-4521."
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel to notify of the new incident."
          steps:
            - name: get-jira-issue
              type: call
              call: "jira.get-issue"
              with:
                issueKey: "{{jira_issue_key}}"
            - name: create-incident
              type: call
              call: "snow-sync.create-incident"
              with:
                short_description: "Jira {{jira_issue_key}}: {{get-jira-issue.summary}}"
                urgency: "1"
                impact: "1"
                description: "{{get-jira-issue.description}}\n\nJira link: {{get-jira-issue.url}}"
            - name: notify-slack
              type: call
              call: "slack-eng.post-message"
              with:
                channel: "{{slack_channel}}"
                text: "Critical bug synced to ServiceNow. Jira: {{jira_issue_key}} | Incident: {{create-incident.number}}"
  consumes:
    - type: http
      namespace: jira
      baseUri: "https://servicenow.atlassian.net/rest/api/3"
      authentication:
        type: bearer
        token: "$secrets.jira_token"
      resources:
        - name: issues
          path: "/issue/{{issueKey}}"
          inputParameters:
            - name: issueKey
              in: path
          operations:
            - name: get-issue
              method: GET
    - type: http
      namespace: snow-sync
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: slack-eng
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When Okta detects a suspicious authentication event (impossible travel or new device), creates a ServiceNow security incident and alerts the user and security team via Slack.

naftiko: "0.5"
info:
  label: "Okta Suspicious Login to ServiceNow Alert"
  description: "When Okta detects a suspicious authentication event (impossible travel or new device), creates a ServiceNow security incident and alerts the user and security team via Slack."
  tags:
    - security
    - identity
    - okta
    - servicenow
    - slack
    - threat-detection
capability:
  exposes:
    - type: mcp
      namespace: identity-security
      port: 8080
      tools:
        - name: handle-suspicious-login
          description: "Given an Okta system log event ID for a suspicious login, fetch event details, create a ServiceNow security incident, and notify both the affected user and security team in Slack."
          inputParameters:
            - name: okta_event_id
              in: body
              type: string
              description: "Okta system log event UUID for the suspicious login."
            - name: security_slack_channel
              in: body
              type: string
              description: "Slack channel for the security team notification."
          steps:
            - name: get-okta-event
              type: call
              call: "okta-log.get-log-event"
              with:
                eventId: "{{okta_event_id}}"
            - name: create-sec-incident
              type: call
              call: "snow-okta.create-incident"
              with:
                short_description: "Suspicious Okta login: {{get-okta-event.actor.displayName}}"
                severity: "2"
                description: "User: {{get-okta-event.actor.displayName}}\nIP: {{get-okta-event.client.ipAddress}}\nLocation: {{get-okta-event.client.geographicalContext.city}}\nEvent: {{okta_event_id}}"
            - name: alert-security-slack
              type: call
              call: "slack-okta.post-message"
              with:
                channel: "{{security_slack_channel}}"
                text: "Suspicious login detected for {{get-okta-event.actor.displayName}} from {{get-okta-event.client.geographicalContext.city}} | Incident: {{create-sec-incident.number}}"
  consumes:
    - type: http
      namespace: okta-log
      baseUri: "https://servicenow.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_token"
        placement: header
      resources:
        - name: log-events
          path: "/logs"
          inputParameters:
            - name: eventId
              in: query
          operations:
            - name: get-log-event
              method: GET
    - type: http
      namespace: snow-okta
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: security-incidents
          path: "/table/sn_si_incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: slack-okta
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a PagerDuty alert fires, creates a corresponding ServiceNow incident with alert details and posts a correlation link to Slack.

naftiko: "0.5"
info:
  label: "PagerDuty Alert to ServiceNow Incident"
  description: "When a PagerDuty alert fires, creates a corresponding ServiceNow incident with alert details and posts a correlation link to Slack."
  tags:
    - itsm
    - incident-management
    - servicenow
    - pagerduty
    - slack
capability:
  exposes:
    - type: mcp
      namespace: pd-to-snow
      port: 8080
      tools:
        - name: create-incident-from-alert
          description: "Given a PagerDuty alert ID, fetch alert details, create a ServiceNow incident, and post a cross-reference to Slack."
          inputParameters:
            - name: alert_id
              in: body
              type: string
              description: "PagerDuty alert ID."
          steps:
            - name: get-pd-alert
              type: call
              call: "pagerduty.get-alert"
              with:
                alert_id: "{{alert_id}}"
            - name: create-snow-incident
              type: call
              call: "servicenow.create-incident"
              with:
                short_description: "PD Alert: {{get-pd-alert.summary}}"
                urgency: "{{get-pd-alert.severity}}"
                description: "PagerDuty Alert ID: {{alert_id}}\nService: {{get-pd-alert.service_name}}\nDetails: {{get-pd-alert.details}}"
            - name: post-correlation
              type: call
              call: "slack.post-message"
              with:
                channel: "incidents"
                text: "PagerDuty alert {{alert_id}} linked to ServiceNow {{create-snow-incident.number}} — {{get-pd-alert.summary}}"
  consumes:
    - type: http
      namespace: pagerduty
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.pagerduty_token"
        placement: header
      resources:
        - name: alerts
          path: "/alerts/{{alert_id}}"
          inputParameters:
            - name: alert_id
              in: path
          operations:
            - name: get-alert
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a high-priority Salesforce Service Cloud case is escalated, creates a matching ServiceNow incident and assigns it to the ITSM team, keeping both records linked.

naftiko: "0.5"
info:
  label: "Salesforce Case to ServiceNow Incident Bridge"
  description: "When a high-priority Salesforce Service Cloud case is escalated, creates a matching ServiceNow incident and assigns it to the ITSM team, keeping both records linked."
  tags:
    - itsm
    - crm
    - customer-support
    - salesforce
    - servicenow
    - escalation
capability:
  exposes:
    - type: mcp
      namespace: case-bridge
      port: 8080
      tools:
        - name: escalate-case-to-incident
          description: "Given a Salesforce case ID, fetch the case details, create a ServiceNow incident, and update the Salesforce case with the incident number for cross-system tracking."
          inputParameters:
            - name: salesforce_case_id
              in: body
              type: string
              description: "Salesforce Service Cloud case ID to escalate."
          steps:
            - name: get-case
              type: call
              call: "salesforce.get-case"
              with:
                caseId: "{{salesforce_case_id}}"
            - name: create-incident
              type: call
              call: "snow-case.create-incident"
              with:
                short_description: "Escalated from Salesforce Case: {{get-case.CaseNumber}} — {{get-case.Subject}}"
                urgency: "1"
                description: "Customer: {{get-case.Account.Name}}\nDescription: {{get-case.Description}}\nSalesforce Case: {{salesforce_case_id}}"
            - name: update-case
              type: call
              call: "salesforce-update.update-case"
              with:
                caseId: "{{salesforce_case_id}}"
                snowIncidentNumber: "{{create-incident.number}}"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://servicenow.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: cases
          path: "/sobjects/Case/{{caseId}}"
          inputParameters:
            - name: caseId
              in: path
          operations:
            - name: get-case
              method: GET
    - type: http
      namespace: snow-case
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: salesforce-update
      baseUri: "https://servicenow.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: case-updates
          path: "/sobjects/Case/{{caseId}}"
          inputParameters:
            - name: caseId
              in: path
          operations:
            - name: update-case
              method: PATCH

Processes a ServiceNow service catalog request, provisions the requested cloud resource via Terraform Cloud, and updates the request item with the provisioning result.

naftiko: "0.5"
info:
  label: "Service Catalog Request Fulfillment"
  description: "Processes a ServiceNow service catalog request, provisions the requested cloud resource via Terraform Cloud, and updates the request item with the provisioning result."
  tags:
    - itsm
    - service-catalog
    - servicenow
    - terraform
    - cloud
    - provisioning
capability:
  exposes:
    - type: mcp
      namespace: catalog-fulfillment
      port: 8080
      tools:
        - name: fulfill-catalog-request
          description: "Given a ServiceNow catalog request item sys_id, read the request, trigger a Terraform Cloud workspace run to provision the resource, and update the RITM with the result."
          inputParameters:
            - name: ritm_sys_id
              in: body
              type: string
              description: "ServiceNow RITM (request item) sys_id to fulfill."
            - name: terraform_workspace_id
              in: body
              type: string
              description: "Terraform Cloud workspace ID to run."
          steps:
            - name: get-ritm
              type: call
              call: "snow-catalog.get-ritm"
              with:
                sysId: "{{ritm_sys_id}}"
            - name: run-terraform
              type: call
              call: "terraform.create-run"
              with:
                workspaceId: "{{terraform_workspace_id}}"
                message: "Provisioning for RITM {{get-ritm.number}}: {{get-ritm.short_description}}"
            - name: update-ritm
              type: call
              call: "snow-catalog.update-ritm"
              with:
                sysId: "{{ritm_sys_id}}"
                workNotes: "Terraform run started. Run ID: {{run-terraform.runId}}. Status: {{run-terraform.status}}"
  consumes:
    - type: http
      namespace: snow-catalog
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: request-items
          path: "/table/sc_req_item/{{sysId}}"
          inputParameters:
            - name: sysId
              in: path
          operations:
            - name: get-ritm
              method: GET
            - name: update-ritm
              method: PATCH
    - type: http
      namespace: terraform
      baseUri: "https://app.terraform.io/api/v2"
      authentication:
        type: bearer
        token: "$secrets.terraform_token"
      resources:
        - name: runs
          path: "/runs"
          operations:
            - name: create-run
              method: POST

Retrieves application details from the CMDB by name, returning owner, support group, and business criticality.

naftiko: "0.5"
info:
  label: "ServiceNow Application Lookup"
  description: "Retrieves application details from the CMDB by name, returning owner, support group, and business criticality."
  tags:
    - itsm
    - cmdb
    - servicenow
    - application-management
capability:
  exposes:
    - type: mcp
      namespace: snow-app
      port: 8080
      tools:
        - name: get-application
          description: "Given an application name, return its owner, support group, and business criticality from the CMDB."
          inputParameters:
            - name: app_name
              in: body
              type: string
              description: "Application name to look up."
          call: "servicenow.get-application"
          with:
            name: "{{app_name}}"
          outputParameters:
            - name: owner
              type: string
              mapping: "$.result[0].owned_by.display_value"
            - name: support_group
              type: string
              mapping: "$.result[0].support_group.display_value"
            - name: criticality
              type: string
              mapping: "$.result[0].busines_criticality.display_value"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: applications
          path: "/table/cmdb_ci_appl"
          inputParameters:
            - name: name
              in: query
          operations:
            - name: get-application
              method: GET

Runs a ServiceNow Discovery scan, compares the results to the existing CMDB, and creates Jira tasks for unreconciled assets requiring review.

naftiko: "0.5"
info:
  label: "ServiceNow Asset Discovery Reconciliation"
  description: "Runs a ServiceNow Discovery scan, compares the results to the existing CMDB, and creates Jira tasks for unreconciled assets requiring review."
  tags:
    - itsm
    - cmdb
    - servicenow
    - jira
    - asset-management
    - discovery
capability:
  exposes:
    - type: mcp
      namespace: discovery-ops
      port: 8080
      tools:
        - name: reconcile-discovery-results
          description: "Trigger a ServiceNow Discovery schedule, retrieve unreconciled CIs from the results, and create Jira tasks for each CI requiring manual review."
          inputParameters:
            - name: discovery_schedule_id
              in: body
              type: string
              description: "ServiceNow Discovery schedule sys_id to run."
            - name: jira_project_key
              in: body
              type: string
              description: "Jira project key to create reconciliation tasks in."
          steps:
            - name: trigger-discovery
              type: call
              call: "snow-discovery.run-schedule"
              with:
                scheduleId: "{{discovery_schedule_id}}"
            - name: get-unreconciled
              type: call
              call: "snow-discovery.get-unreconciled-cis"
              with:
                runId: "{{trigger-discovery.runId}}"
            - name: create-reconcile-tasks
              type: call
              call: "jira-discovery.create-issue"
              with:
                project_key: "{{jira_project_key}}"
                issuetype: "Task"
                summary: "CMDB reconciliation needed: {{get-unreconciled.ciName}}"
                description: "Unreconciled CI: {{get-unreconciled.ipAddress}} | Class: {{get-unreconciled.class}} | Discovery run: {{trigger-discovery.runId}}"
  consumes:
    - type: http
      namespace: snow-discovery
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: discovery-schedules
          path: "/table/discovery_schedule/{{scheduleId}}/run"
          inputParameters:
            - name: scheduleId
              in: path
          operations:
            - name: run-schedule
              method: POST
        - name: unreconciled-cis
          path: "/table/cmdb_ci"
          inputParameters:
            - name: runId
              in: query
          operations:
            - name: get-unreconciled-cis
              method: GET
    - type: http
      namespace: jira-discovery
      baseUri: "https://servicenow.atlassian.net/rest/api/3"
      authentication:
        type: bearer
        token: "$secrets.jira_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST

Retrieves details for a ServiceNow assignment group by name, returning manager, member count, and active status.

naftiko: "0.5"
info:
  label: "ServiceNow Assignment Group Lookup"
  description: "Retrieves details for a ServiceNow assignment group by name, returning manager, member count, and active status."
  tags:
    - itsm
    - team-management
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: snow-groups
      port: 8080
      tools:
        - name: get-assignment-group
          description: "Given an assignment group name, return the group manager, member count, and whether the group is active."
          inputParameters:
            - name: group_name
              in: body
              type: string
              description: "Name of the ServiceNow assignment group."
          call: "servicenow.get-group"
          with:
            name: "{{group_name}}"
          outputParameters:
            - name: sys_id
              type: string
              mapping: "$.result[0].sys_id"
            - name: manager
              type: string
              mapping: "$.result[0].manager.display_value"
            - name: active
              type: string
              mapping: "$.result[0].active"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: groups
          path: "/table/sys_user_group"
          inputParameters:
            - name: name
              in: query
          operations:
            - name: get-group
              method: GET

Processes a password reset request from ServiceNow, triggers the reset in Okta, updates the request status, and notifies the user via Slack.

naftiko: "0.5"
info:
  label: "ServiceNow Automated Password Reset"
  description: "Processes a password reset request from ServiceNow, triggers the reset in Okta, updates the request status, and notifies the user via Slack."
  tags:
    - itsm
    - identity-management
    - servicenow
    - okta
    - slack
capability:
  exposes:
    - type: mcp
      namespace: pwd-reset
      port: 8080
      tools:
        - name: process-password-reset
          description: "Given a ServiceNow request item number, look up the user, reset their password in Okta, close the request, and notify the user."
          inputParameters:
            - name: ritm_number
              in: body
              type: string
              description: "ServiceNow request item number, e.g. RITM0012345."
          steps:
            - name: get-request
              type: call
              call: "servicenow.get-ritm"
              with:
                number: "{{ritm_number}}"
            - name: reset-okta-password
              type: call
              call: "okta.reset-password"
              with:
                user_id: "{{get-request.requested_for_email}}"
            - name: close-request
              type: call
              call: "servicenow.update-ritm"
              with:
                sys_id: "{{get-request.sys_id}}"
                state: "closed_complete"
            - name: notify-user
              type: call
              call: "slack.post-message"
              with:
                channel: "{{get-request.requested_for_slack_id}}"
                text: "Your password has been reset. Check your email for instructions. Request {{ritm_number}} is now closed."
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: request-items
          path: "/table/sc_req_item"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-ritm
              method: GET
        - name: request-item-update
          path: "/table/sc_req_item/{{sys_id}}"
          inputParameters:
            - name: sys_id
              in: path
          operations:
            - name: update-ritm
              method: PATCH
    - type: http
      namespace: okta
      baseUri: "https://servicenow.okta.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.okta_api_token"
      resources:
        - name: users
          path: "/users/{{user_id}}/lifecycle/reset_password"
          inputParameters:
            - name: user_id
              in: path
          operations:
            - name: reset-password
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves recent business rule execution logs from ServiceNow for auditing and compliance review.

naftiko: "0.5"
info:
  label: "ServiceNow Business Rule Audit Log"
  description: "Retrieves recent business rule execution logs from ServiceNow for auditing and compliance review."
  tags:
    - itsm
    - compliance
    - servicenow
    - audit
capability:
  exposes:
    - type: mcp
      namespace: snow-audit
      port: 8080
      tools:
        - name: get-business-rule-logs
          description: "Given a table name and time range, return recent business rule execution logs for audit purposes."
          inputParameters:
            - name: table_name
              in: body
              type: string
              description: "ServiceNow table name to audit."
          call: "servicenow.get-audit-logs"
          with:
            tablename: "{{table_name}}"
          outputParameters:
            - name: record_count
              type: string
              mapping: "$.result.length"
            - name: last_execution
              type: string
              mapping: "$.result[0].sys_created_on"
            - name: rule_name
              type: string
              mapping: "$.result[0].name"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: audit-logs
          path: "/table/sys_audit"
          inputParameters:
            - name: tablename
              in: query
          operations:
            - name: get-audit-logs
              method: GET

Aggregates team workload data from ServiceNow tasks and incidents, calculates utilization rates, and posts a capacity summary to Slack.

naftiko: "0.5"
info:
  label: "ServiceNow Capacity Planning Report"
  description: "Aggregates team workload data from ServiceNow tasks and incidents, calculates utilization rates, and posts a capacity summary to Slack."
  tags:
    - itsm
    - capacity-planning
    - servicenow
    - slack
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: capacity-report
      port: 8080
      tools:
        - name: generate-capacity-report
          description: "Given an assignment group name, aggregate open tasks and incidents, calculate utilization, and post a capacity report to Slack."
          inputParameters:
            - name: group_name
              in: body
              type: string
              description: "ServiceNow assignment group name."
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel for the report."
          steps:
            - name: get-open-tasks
              type: call
              call: "servicenow.query-tasks"
              with:
                sysparm_query: "assignment_group.name={{group_name}}^stateINnew,in_progress"
            - name: get-open-incidents
              type: call
              call: "servicenow.query-incidents"
              with:
                sysparm_query: "assignment_group.name={{group_name}}^stateINnew,in_progress"
            - name: post-report
              type: call
              call: "slack.post-message"
              with:
                channel: "{{slack_channel}}"
                text: "Capacity Report for {{group_name}}: {{get-open-tasks.result_count}} open tasks, {{get-open-incidents.result_count}} open incidents. Review workload distribution."
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: tasks
          path: "/table/task"
          inputParameters:
            - name: sysparm_query
              in: query
          operations:
            - name: query-tasks
              method: GET
        - name: incidents
          path: "/table/incident"
          inputParameters:
            - name: sysparm_query
              in: query
          operations:
            - name: query-incidents
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves a service catalog item by name, returning category, price, and availability status.

naftiko: "0.5"
info:
  label: "ServiceNow Catalog Item Lookup"
  description: "Retrieves a service catalog item by name, returning category, price, and availability status."
  tags:
    - itsm
    - service-catalog
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: snow-catalog
      port: 8080
      tools:
        - name: get-catalog-item
          description: "Given a catalog item name, return its category, price, availability, and short description."
          inputParameters:
            - name: item_name
              in: body
              type: string
              description: "Name of the service catalog item to look up."
          call: "servicenow.get-catalog-item"
          with:
            name: "{{item_name}}"
          outputParameters:
            - name: sys_id
              type: string
              mapping: "$.result[0].sys_id"
            - name: category
              type: string
              mapping: "$.result[0].category.display_value"
            - name: price
              type: string
              mapping: "$.result[0].price"
            - name: availability
              type: string
              mapping: "$.result[0].availability"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: catalog-items
          path: "/table/sc_cat_item"
          inputParameters:
            - name: name
              in: query
          operations:
            - name: get-catalog-item
              method: GET

Exports upcoming scheduled changes from ServiceNow, creates Google Calendar events, and posts a weekly change calendar to Slack.

naftiko: "0.5"
info:
  label: "ServiceNow Change Calendar Export"
  description: "Exports upcoming scheduled changes from ServiceNow, creates Google Calendar events, and posts a weekly change calendar to Slack."
  tags:
    - itsm
    - change-management
    - servicenow
    - google-calendar
    - slack
capability:
  exposes:
    - type: mcp
      namespace: change-calendar
      port: 8080
      tools:
        - name: export-change-calendar
          description: "Query upcoming changes for the next 7 days, create Google Calendar events, and post a calendar summary to Slack."
          inputParameters:
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel for the calendar summary."
          steps:
            - name: query-upcoming-changes
              type: call
              call: "servicenow.query-changes"
              with:
                sysparm_query: "stateINscheduled^start_dateRELATIVELT@day@ahead@7"
            - name: post-calendar
              type: call
              call: "slack.post-message"
              with:
                channel: "{{slack_channel}}"
                text: "Change Calendar (next 7 days): {{query-upcoming-changes.result_count}} changes scheduled. Review at https://servicenow.service-now.com/change_calendar"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: change-requests
          path: "/table/change_request"
          inputParameters:
            - name: sysparm_query
              in: query
          operations:
            - name: query-changes
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Checks for scheduling conflicts between change requests targeting the same CIs, flags overlaps, and notifies the change manager via Slack.

naftiko: "0.5"
info:
  label: "ServiceNow Change Conflict Detector"
  description: "Checks for scheduling conflicts between change requests targeting the same CIs, flags overlaps, and notifies the change manager via Slack."
  tags:
    - itsm
    - change-management
    - servicenow
    - slack
capability:
  exposes:
    - type: mcp
      namespace: change-conflict
      port: 8080
      tools:
        - name: detect-change-conflicts
          description: "Given a change request number, check for overlapping changes on the same CIs and alert the change manager."
          inputParameters:
            - name: change_number
              in: body
              type: string
              description: "ServiceNow change request number."
          steps:
            - name: get-change
              type: call
              call: "servicenow.get-change"
              with:
                number: "{{change_number}}"
            - name: check-conflicts
              type: call
              call: "servicenow.query-changes"
              with:
                sysparm_query: "stateINscheduled,implement^cmdb_ci={{get-change.cmdb_ci}}^number!=={{change_number}}"
            - name: notify-change-manager
              type: call
              call: "slack.post-message"
              with:
                channel: "change-management"
                text: "Change Conflict Alert: {{change_number}} has {{check-conflicts.result_count}} overlapping changes on the same CI. Review before approval."
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: change-requests
          path: "/table/change_request"
          inputParameters:
            - name: number
              in: query
            - name: sysparm_query
              in: query
          operations:
            - name: get-change
              method: GET
            - name: query-changes
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

After a change is implemented, checks Datadog for anomalies, updates the change record with results, and posts a PIR summary to Slack.

naftiko: "0.5"
info:
  label: "ServiceNow Change Post-Implementation Review"
  description: "After a change is implemented, checks Datadog for anomalies, updates the change record with results, and posts a PIR summary to Slack."
  tags:
    - itsm
    - change-management
    - servicenow
    - datadog
    - slack
capability:
  exposes:
    - type: mcp
      namespace: change-pir
      port: 8080
      tools:
        - name: run-post-implementation-review
          description: "Given a change number, verify no anomalies detected in Datadog post-implementation, update the change record, and post PIR to Slack."
          inputParameters:
            - name: change_number
              in: body
              type: string
              description: "ServiceNow change request number."
          steps:
            - name: get-change
              type: call
              call: "servicenow.get-change"
              with:
                number: "{{change_number}}"
            - name: check-anomalies
              type: call
              call: "datadog.get-events"
              with:
                tags: "change:{{change_number}}"
                priority: "normal"
            - name: update-change
              type: call
              call: "servicenow.update-change"
              with:
                sys_id: "{{get-change.sys_id}}"
                close_notes: "PIR complete. Anomalies detected: {{check-anomalies.event_count}}"
            - name: post-pir
              type: call
              call: "slack.post-message"
              with:
                channel: "change-management"
                text: "PIR for {{change_number}}: {{get-change.short_description}} | Anomalies: {{check-anomalies.event_count}} | Status: complete"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: change-requests
          path: "/table/change_request"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-change
              method: GET
        - name: change-update
          path: "/table/change_request/{{sys_id}}"
          inputParameters:
            - name: sys_id
              in: path
          operations:
            - name: update-change
              method: PATCH
    - type: http
      namespace: datadog
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: events
          path: "/events"
          inputParameters:
            - name: tags
              in: query
            - name: priority
              in: query
          operations:
            - name: get-events
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves a change request record by number, returning type, risk, state, and planned dates.

naftiko: "0.5"
info:
  label: "ServiceNow Change Request Lookup"
  description: "Retrieves a change request record by number, returning type, risk, state, and planned dates."
  tags:
    - itsm
    - change-management
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: snow-change
      port: 8080
      tools:
        - name: get-change-request
          description: "Given a change request number, return the change type, risk level, current state, and planned start/end dates."
          inputParameters:
            - name: change_number
              in: body
              type: string
              description: "ServiceNow change request number, e.g. CHG0012345."
          call: "servicenow.get-change"
          with:
            number: "{{change_number}}"
          outputParameters:
            - name: sys_id
              type: string
              mapping: "$.result[0].sys_id"
            - name: type
              type: string
              mapping: "$.result[0].type.display_value"
            - name: risk
              type: string
              mapping: "$.result[0].risk.display_value"
            - name: state
              type: string
              mapping: "$.result[0].state.display_value"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: change-requests
          path: "/table/change_request"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-change
              method: GET

Evaluates a change request against CMDB impact data, calculates risk score, updates the change record, and notifies the CAB via Microsoft Teams.

naftiko: "0.5"
info:
  label: "ServiceNow Change Risk Assessment"
  description: "Evaluates a change request against CMDB impact data, calculates risk score, updates the change record, and notifies the CAB via Microsoft Teams."
  tags:
    - itsm
    - change-management
    - servicenow
    - microsoft-teams
    - risk-management
capability:
  exposes:
    - type: mcp
      namespace: change-risk
      port: 8080
      tools:
        - name: assess-change-risk
          description: "Given a change request number, query impacted CIs, compute risk score, update the change record, and notify the CAB in Teams."
          inputParameters:
            - name: change_number
              in: body
              type: string
              description: "ServiceNow change request number."
          steps:
            - name: get-change
              type: call
              call: "servicenow.get-change"
              with:
                number: "{{change_number}}"
            - name: get-impacted-cis
              type: call
              call: "servicenow.get-affected-cis"
              with:
                task: "{{get-change.sys_id}}"
            - name: update-risk
              type: call
              call: "servicenow.update-change"
              with:
                sys_id: "{{get-change.sys_id}}"
                risk: "{{get-impacted-cis.risk_score}}"
            - name: notify-cab
              type: call
              call: "teams.post-message"
              with:
                channel_id: "$secrets.teams_cab_channel_id"
                text: "Change {{change_number}} risk assessed: {{get-impacted-cis.risk_score}} | Impacted CIs: {{get-impacted-cis.count}} | Review required before approval."
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: change-requests
          path: "/table/change_request"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-change
              method: GET
        - name: affected-cis
          path: "/table/task_ci"
          inputParameters:
            - name: task
              in: query
          operations:
            - name: get-affected-cis
              method: GET
        - name: change-update
          path: "/table/change_request/{{sys_id}}"
          inputParameters:
            - name: sys_id
              in: path
            - name: risk
              in: body
          operations:
            - name: update-change
              method: PATCH
    - type: http
      namespace: teams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.teams_token"
      resources:
        - name: channel-messages
          path: "/teams/$secrets.teams_team_id/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

Analyzes upstream and downstream configuration item relationships in the ServiceNow CMDB to determine the blast radius of a proposed change or outage.

naftiko: "0.5"
info:
  label: "ServiceNow CI Relationship Impact Analysis"
  description: "Analyzes upstream and downstream configuration item relationships in the ServiceNow CMDB to determine the blast radius of a proposed change or outage."
  tags:
    - servicenow
    - cmdb
    - impact-analysis
    - change-management
capability:
  exposes:
    - type: mcp
      namespace: ci-impact-analysis
      port: 8080
      tools:
        - name: analyze-ci-impact
          description: "Determine the blast radius of a change by analyzing CI relationships for a given configuration item."
          inputParameters:
            - name: ci_sys_id
              in: body
              type: string
              description: "Sys ID of the configuration item to analyze."
            - name: depth
              in: body
              type: number
              description: "Relationship traversal depth (default 2)."
          call: "servicenow.get-ci-relationships"
          with:
            ci_sys_id: "{{ci_sys_id}}"
            depth: "{{depth}}"
          outputParameters:
            - name: affected_cis
              type: array
              mapping: "$.result.affected_items"
            - name: total_impacted
              type: number
              mapping: "$.result.total_count"
            - name: critical_services
              type: array
              mapping: "$.result.critical_services"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://{{instance}}.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: ci-relationships
          path: "/cmdb/instance/relations/{{ci_sys_id}}?depth={{depth}}"
          inputParameters:
            - name: ci_sys_id
              in: path
            - name: depth
              in: query
          operations:
            - name: get-ci-relationships
              method: GET

Retrieves cloud instance details from the ServiceNow CMDB, returning instance type, region, and associated application.

naftiko: "0.5"
info:
  label: "ServiceNow Cloud Instance Lookup"
  description: "Retrieves cloud instance details from the ServiceNow CMDB, returning instance type, region, and associated application."
  tags:
    - itsm
    - cmdb
    - servicenow
    - cloud
capability:
  exposes:
    - type: mcp
      namespace: snow-cloud
      port: 8080
      tools:
        - name: get-cloud-instance
          description: "Given a cloud instance ID, return its type, region, state, and associated application from the CMDB."
          inputParameters:
            - name: instance_id
              in: body
              type: string
              description: "Cloud instance ID."
          call: "servicenow.get-cloud-instance"
          with:
            object_id: "{{instance_id}}"
          outputParameters:
            - name: instance_type
              type: string
              mapping: "$.result[0].size"
            - name: region
              type: string
              mapping: "$.result[0].region"
            - name: state
              type: string
              mapping: "$.result[0].state"
            - name: application
              type: string
              mapping: "$.result[0].application.display_value"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: cloud-instances
          path: "/table/cmdb_ci_vm_instance"
          inputParameters:
            - name: object_id
              in: query
          operations:
            - name: get-cloud-instance
              method: GET

Queries AWS for untagged resources, creates a ServiceNow compliance incident, and notifies the cloud governance team via Slack.

naftiko: "0.5"
info:
  label: "ServiceNow Cloud Resource Tagging Compliance"
  description: "Queries AWS for untagged resources, creates a ServiceNow compliance incident, and notifies the cloud governance team via Slack."
  tags:
    - itsm
    - cloud-governance
    - servicenow
    - aws
    - slack
    - compliance
capability:
  exposes:
    - type: mcp
      namespace: tag-compliance
      port: 8080
      tools:
        - name: check-tagging-compliance
          description: "Scan AWS for untagged resources, create a ServiceNow compliance incident, and alert the governance team."
          inputParameters:
            - name: aws_region
              in: body
              type: string
              description: "AWS region to scan."
          steps:
            - name: scan-untagged
              type: call
              call: "aws.get-untagged-resources"
              with:
                region: "{{aws_region}}"
            - name: create-compliance-incident
              type: call
              call: "servicenow.create-incident"
              with:
                short_description: "Tagging compliance: {{scan-untagged.count}} untagged resources in {{aws_region}}"
                category: "compliance"
                assignment_group: "cloud-governance"
            - name: notify-governance
              type: call
              call: "slack.post-message"
              with:
                channel: "cloud-governance"
                text: "Tagging Compliance Alert: {{scan-untagged.count}} untagged resources in {{aws_region}}. Incident: {{create-compliance-incident.number}}"
  consumes:
    - type: http
      namespace: aws
      baseUri: "https://resourcegroupstaggingapi.{{region}}.amazonaws.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.aws_auth_header"
        placement: header
      resources:
        - name: resources
          path: "/GetResources"
          inputParameters:
            - name: region
              in: path
          operations:
            - name: get-untagged-resources
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves a configuration item (CI) from the ServiceNow CMDB by name or IP, returning class, relationships, and assigned owner.

naftiko: "0.5"
info:
  label: "ServiceNow CMDB Asset Lookup"
  description: "Retrieves a configuration item (CI) from the ServiceNow CMDB by name or IP, returning class, relationships, and assigned owner."
  tags:
    - itsm
    - cmdb
    - servicenow
    - asset-management
capability:
  exposes:
    - type: mcp
      namespace: cmdb
      port: 8080
      tools:
        - name: get-configuration-item
          description: "Given a CI name or IP address, look up the asset in the ServiceNow CMDB and return its class, operational status, assigned owner, and relationship count."
          inputParameters:
            - name: ci_name
              in: body
              type: string
              description: "Configuration item name or IP address to look up in the CMDB."
          call: "snow-cmdb.get-ci"
          with:
            name: "{{ci_name}}"
          outputParameters:
            - name: sys_id
              type: string
              mapping: "$.result[0].sys_id"
            - name: ci_class
              type: string
              mapping: "$.result[0].sys_class_name.display_value"
            - name: status
              type: string
              mapping: "$.result[0].operational_status.display_value"
            - name: owned_by
              type: string
              mapping: "$.result[0].owned_by.display_value"
  consumes:
    - type: http
      namespace: snow-cmdb
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: cmdb-items
          path: "/table/cmdb_ci"
          inputParameters:
            - name: name
              in: query
          operations:
            - name: get-ci
              method: GET

Runs a CMDB health check, identifies stale configuration items, generates an audit report, and posts findings to a Slack channel.

naftiko: "0.5"
info:
  label: "ServiceNow CMDB Health Audit"
  description: "Runs a CMDB health check, identifies stale configuration items, generates an audit report, and posts findings to a Slack channel."
  tags:
    - itsm
    - cmdb
    - servicenow
    - slack
    - compliance
capability:
  exposes:
    - type: mcp
      namespace: cmdb-audit
      port: 8080
      tools:
        - name: audit-cmdb-health
          description: "Query the CMDB for stale CIs not updated in the given number of days, generate a summary report, and post findings to Slack."
          inputParameters:
            - name: stale_days
              in: body
              type: string
              description: "Number of days since last update to consider a CI stale."
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel for posting audit results."
          steps:
            - name: query-stale-cis
              type: call
              call: "servicenow.query-cmdb"
              with:
                sysparm_query: "sys_updated_onRELATIVELT@dayofweek@ago@{{stale_days}}"
            - name: post-audit-report
              type: call
              call: "slack.post-message"
              with:
                channel: "{{slack_channel}}"
                text: "CMDB Health Audit: Found {{query-stale-cis.result_count}} CIs not updated in {{stale_days}} days. Review required for compliance."
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: cmdb-items
          path: "/table/cmdb_ci"
          inputParameters:
            - name: sysparm_query
              in: query
          operations:
            - name: query-cmdb
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves upstream and downstream CI relationships for a given configuration item in the ServiceNow CMDB.

naftiko: "0.5"
info:
  label: "ServiceNow CMDB Relationship Lookup"
  description: "Retrieves upstream and downstream CI relationships for a given configuration item in the ServiceNow CMDB."
  tags:
    - itsm
    - cmdb
    - servicenow
    - dependency-mapping
capability:
  exposes:
    - type: mcp
      namespace: snow-cmdb-rel
      port: 8080
      tools:
        - name: get-ci-relationships
          description: "Given a CI sys_id, return its upstream and downstream relationships including type and related CI names."
          inputParameters:
            - name: ci_sys_id
              in: body
              type: string
              description: "The sys_id of the configuration item."
          call: "servicenow.get-relationships"
          with:
            parent: "{{ci_sys_id}}"
          outputParameters:
            - name: relationship_type
              type: string
              mapping: "$.result[0].type.display_value"
            - name: child_ci
              type: string
              mapping: "$.result[0].child.display_value"
            - name: parent_ci
              type: string
              mapping: "$.result[0].parent.display_value"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: cmdb-relationships
          path: "/table/cmdb_rel_ci"
          inputParameters:
            - name: parent
              in: query
          operations:
            - name: get-relationships
              method: GET

Retrieves server details from the CMDB by hostname, returning OS, IP address, location, and operational status.

naftiko: "0.5"
info:
  label: "ServiceNow CMDB Server Lookup"
  description: "Retrieves server details from the CMDB by hostname, returning OS, IP address, location, and operational status."
  tags:
    - itsm
    - cmdb
    - servicenow
    - infrastructure
capability:
  exposes:
    - type: mcp
      namespace: snow-server
      port: 8080
      tools:
        - name: get-server
          description: "Given a hostname, return the server's OS, IP address, location, and operational status from the CMDB."
          inputParameters:
            - name: hostname
              in: body
              type: string
              description: "Server hostname to look up."
          call: "servicenow.get-server"
          with:
            name: "{{hostname}}"
          outputParameters:
            - name: ip_address
              type: string
              mapping: "$.result[0].ip_address"
            - name: os
              type: string
              mapping: "$.result[0].os.display_value"
            - name: location
              type: string
              mapping: "$.result[0].location.display_value"
            - name: status
              type: string
              mapping: "$.result[0].operational_status.display_value"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: servers
          path: "/table/cmdb_ci_server"
          inputParameters:
            - name: name
              in: query
          operations:
            - name: get-server
              method: GET

Queries ServiceNow GRC for active compliance exceptions nearing expiry, creates renewal tasks, and alerts the compliance team.

naftiko: "0.5"
info:
  label: "ServiceNow Compliance Exception Tracker"
  description: "Queries ServiceNow GRC for active compliance exceptions nearing expiry, creates renewal tasks, and alerts the compliance team."
  tags:
    - itsm
    - compliance
    - servicenow
    - slack
    - governance
capability:
  exposes:
    - type: mcp
      namespace: compliance-exceptions
      port: 8080
      tools:
        - name: track-compliance-exceptions
          description: "Query for compliance exceptions expiring within a given number of days and create renewal tasks."
          inputParameters:
            - name: days_until_expiry
              in: body
              type: string
              description: "Days before expiry to flag exceptions."
          steps:
            - name: query-exceptions
              type: call
              call: "servicenow.query-exceptions"
              with:
                sysparm_query: "expiration_dateRELATIVELT@day@ahead@{{days_until_expiry}}^active=true"
            - name: create-renewal-tasks
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "Compliance exception renewal: {{query-exceptions.result_count}} exceptions expiring within {{days_until_expiry}} days"
                assignment_group: "compliance"
            - name: notify-compliance
              type: call
              call: "slack.post-message"
              with:
                channel: "compliance"
                text: "Exception Expiry Alert: {{query-exceptions.result_count}} compliance exceptions expiring within {{days_until_expiry}} days. Task: {{create-renewal-tasks.number}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: exceptions
          path: "/table/sn_compliance_exception"
          inputParameters:
            - name: sysparm_query
              in: query
          operations:
            - name: query-exceptions
              method: GET
        - name: tasks
          path: "/table/task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When an incident is created, searches Confluence for matching runbooks and attaches the link to the incident work notes.

naftiko: "0.5"
info:
  label: "ServiceNow Confluence Runbook Linker"
  description: "When an incident is created, searches Confluence for matching runbooks and attaches the link to the incident work notes."
  tags:
    - itsm
    - knowledge-management
    - servicenow
    - confluence
capability:
  exposes:
    - type: mcp
      namespace: runbook-linker
      port: 8080
      tools:
        - name: link-runbook-to-incident
          description: "Given an incident number, search Confluence for relevant runbooks and attach the best match to the incident."
          inputParameters:
            - name: incident_number
              in: body
              type: string
              description: "ServiceNow incident number."
          steps:
            - name: get-incident
              type: call
              call: "servicenow.get-incident"
              with:
                number: "{{incident_number}}"
            - name: search-runbooks
              type: call
              call: "confluence.search"
              with:
                cql: "label = runbook AND text ~ \"{{get-incident.category}}\""
            - name: update-work-notes
              type: call
              call: "servicenow.update-incident"
              with:
                sys_id: "{{get-incident.sys_id}}"
                work_notes: "Suggested runbook: {{search-runbooks.results[0].title}} — {{search-runbooks.results[0].url}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-incident
              method: GET
        - name: incident-update
          path: "/table/incident/{{sys_id}}"
          inputParameters:
            - name: sys_id
              in: path
          operations:
            - name: update-incident
              method: PATCH
    - type: http
      namespace: confluence
      baseUri: "https://servicenow-corp.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_api_token"
      resources:
        - name: search
          path: "/search"
          inputParameters:
            - name: cql
              in: query
          operations:
            - name: search
              method: GET

Retrieves cost center details by name or code, returning manager, department, and budget allocation.

naftiko: "0.5"
info:
  label: "ServiceNow Cost Center Lookup"
  description: "Retrieves cost center details by name or code, returning manager, department, and budget allocation."
  tags:
    - itsm
    - financial-management
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: snow-costcenter
      port: 8080
      tools:
        - name: get-cost-center
          description: "Given a cost center name, return its code, manager, department, and parent cost center."
          inputParameters:
            - name: cost_center_name
              in: body
              type: string
              description: "Cost center name."
          call: "servicenow.get-cost-center"
          with:
            name: "{{cost_center_name}}"
          outputParameters:
            - name: code
              type: string
              mapping: "$.result[0].account_number"
            - name: manager
              type: string
              mapping: "$.result[0].manager.display_value"
            - name: parent
              type: string
              mapping: "$.result[0].parent.display_value"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: cost-centers
          path: "/table/cmn_cost_center"
          inputParameters:
            - name: name
              in: query
          operations:
            - name: get-cost-center
              method: GET

After incident resolution, sends a CSAT survey link via Slack DM and records the survey dispatch in the incident work notes.

naftiko: "0.5"
info:
  label: "ServiceNow Customer Satisfaction Survey"
  description: "After incident resolution, sends a CSAT survey link via Slack DM and records the survey dispatch in the incident work notes."
  tags:
    - itsm
    - customer-satisfaction
    - servicenow
    - slack
capability:
  exposes:
    - type: mcp
      namespace: csat-survey
      port: 8080
      tools:
        - name: send-csat-survey
          description: "Given a resolved incident number, send a satisfaction survey to the caller via Slack and log it in ServiceNow."
          inputParameters:
            - name: incident_number
              in: body
              type: string
              description: "ServiceNow incident number."
          steps:
            - name: get-incident
              type: call
              call: "servicenow.get-incident"
              with:
                number: "{{incident_number}}"
            - name: send-survey
              type: call
              call: "slack.post-message"
              with:
                channel: "{{get-incident.caller_slack_id}}"
                text: "Your incident {{incident_number}} has been resolved. Please rate your experience: https://servicenow.service-now.com/survey?id={{get-incident.sys_id}}"
            - name: update-work-notes
              type: call
              call: "servicenow.update-incident"
              with:
                sys_id: "{{get-incident.sys_id}}"
                work_notes: "CSAT survey sent to caller via Slack"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-incident
              method: GET
        - name: incident-update
          path: "/table/incident/{{sys_id}}"
          inputParameters:
            - name: sys_id
              in: path
          operations:
            - name: update-incident
              method: PATCH
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves database CI details from the CMDB by name, returning type, version, hosting server, and capacity.

naftiko: "0.5"
info:
  label: "ServiceNow Database Lookup"
  description: "Retrieves database CI details from the CMDB by name, returning type, version, hosting server, and capacity."
  tags:
    - itsm
    - cmdb
    - servicenow
    - database
capability:
  exposes:
    - type: mcp
      namespace: snow-db
      port: 8080
      tools:
        - name: get-database-ci
          description: "Given a database name, return its type, version, hosting server, and storage capacity."
          inputParameters:
            - name: db_name
              in: body
              type: string
              description: "Database name to look up."
          call: "servicenow.get-database"
          with:
            name: "{{db_name}}"
          outputParameters:
            - name: type
              type: string
              mapping: "$.result[0].type.display_value"
            - name: version
              type: string
              mapping: "$.result[0].version"
            - name: hosting_server
              type: string
              mapping: "$.result[0].host.display_value"
            - name: capacity_gb
              type: string
              mapping: "$.result[0].disk_space"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: databases
          path: "/table/cmdb_ci_database"
          inputParameters:
            - name: name
              in: query
          operations:
            - name: get-database
              method: GET

Fetches performance metrics from Datadog for a host, enriches the corresponding ServiceNow CMDB CI with current health data.

naftiko: "0.5"
info:
  label: "ServiceNow Datadog Metric to CI Enrichment"
  description: "Fetches performance metrics from Datadog for a host, enriches the corresponding ServiceNow CMDB CI with current health data."
  tags:
    - itsm
    - cmdb
    - servicenow
    - datadog
    - observability
capability:
  exposes:
    - type: mcp
      namespace: dd-ci-enrich
      port: 8080
      tools:
        - name: enrich-ci-with-metrics
          description: "Given a hostname, fetch Datadog metrics and update the CMDB CI with performance health attributes."
          inputParameters:
            - name: hostname
              in: body
              type: string
              description: "Hostname to fetch metrics for."
          steps:
            - name: get-dd-metrics
              type: call
              call: "datadog.get-host-metrics"
              with:
                filter: "host:{{hostname}}"
            - name: get-ci
              type: call
              call: "servicenow.get-ci"
              with:
                name: "{{hostname}}"
            - name: update-ci
              type: call
              call: "servicenow.update-ci"
              with:
                sys_id: "{{get-ci.sys_id}}"
                attributes: "cpu_usage:{{get-dd-metrics.cpu_pct}},memory_usage:{{get-dd-metrics.mem_pct}}"
  consumes:
    - type: http
      namespace: datadog
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: hosts
          path: "/hosts"
          inputParameters:
            - name: filter
              in: query
          operations:
            - name: get-host-metrics
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: cmdb-items
          path: "/table/cmdb_ci"
          inputParameters:
            - name: name
              in: query
          operations:
            - name: get-ci
              method: GET
        - name: cmdb-update
          path: "/table/cmdb_ci/{{sys_id}}"
          inputParameters:
            - name: sys_id
              in: path
          operations:
            - name: update-ci
              method: PATCH

Retrieves department details from ServiceNow by name, returning head count, manager, and cost center.

naftiko: "0.5"
info:
  label: "ServiceNow Department Lookup"
  description: "Retrieves department details from ServiceNow by name, returning head count, manager, and cost center."
  tags:
    - itsm
    - organization
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: snow-dept
      port: 8080
      tools:
        - name: get-department
          description: "Given a department name, return the department head, cost center, and business unit."
          inputParameters:
            - name: dept_name
              in: body
              type: string
              description: "Department name to look up."
          call: "servicenow.get-department"
          with:
            name: "{{dept_name}}"
          outputParameters:
            - name: head
              type: string
              mapping: "$.result[0].dept_head.display_value"
            - name: cost_center
              type: string
              mapping: "$.result[0].cost_center.display_value"
            - name: business_unit
              type: string
              mapping: "$.result[0].business_unit.display_value"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: departments
          path: "/table/cmn_department"
          inputParameters:
            - name: name
              in: query
          operations:
            - name: get-department
              method: GET

Uses AI to compare a new incident against recent open incidents, identifies potential duplicates, and suggests merging via Slack.

naftiko: "0.5"
info:
  label: "ServiceNow Duplicate Incident Detector"
  description: "Uses AI to compare a new incident against recent open incidents, identifies potential duplicates, and suggests merging via Slack."
  tags:
    - itsm
    - incident-management
    - servicenow
    - anthropic
    - slack
capability:
  exposes:
    - type: mcp
      namespace: dup-detect
      port: 8080
      tools:
        - name: detect-duplicate-incidents
          description: "Given a new incident number, compare its description against recent open incidents using AI, and flag potential duplicates."
          inputParameters:
            - name: incident_number
              in: body
              type: string
              description: "New incident number to check for duplicates."
          steps:
            - name: get-new-incident
              type: call
              call: "servicenow.get-incident"
              with:
                number: "{{incident_number}}"
            - name: query-recent
              type: call
              call: "servicenow.query-incidents"
              with:
                sysparm_query: "stateINnew,in_progress^opened_atRELATIVEGE@day@ago@7^number!=={{incident_number}}"
            - name: ai-compare
              type: call
              call: "anthropic.create-message"
              with:
                model: "claude-sonnet-4-20250514"
                max_tokens: 512
                system: "You are a duplicate incident detector. Compare the new incident against the list and return potential duplicates with confidence scores."
                content: "New incident: {{get-new-incident.short_description}}\n\nRecent incidents: {{query-recent.descriptions}}"
            - name: post-findings
              type: call
              call: "slack.post-message"
              with:
                channel: "service-desk"
                text: "Duplicate check for {{incident_number}}: {{ai-compare.content}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          inputParameters:
            - name: number
              in: query
            - name: sysparm_query
              in: query
          operations:
            - name: get-incident
              method: GET
            - name: query-incidents
              method: GET
    - type: http
      namespace: anthropic
      baseUri: "https://api.anthropic.com/v1"
      authentication:
        type: apikey
        key: "x-api-key"
        value: "$secrets.anthropic_api_key"
        placement: header
      resources:
        - name: messages
          path: "/messages"
          operations:
            - name: create-message
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Creates an emergency change request, auto-approves it, triggers PagerDuty for on-call engineer, and notifies the CAB retrospectively.

naftiko: "0.5"
info:
  label: "ServiceNow Emergency Change Fast Track"
  description: "Creates an emergency change request, auto-approves it, triggers PagerDuty for on-call engineer, and notifies the CAB retrospectively."
  tags:
    - itsm
    - change-management
    - servicenow
    - pagerduty
    - slack
capability:
  exposes:
    - type: mcp
      namespace: emergency-change
      port: 8080
      tools:
        - name: create-emergency-change
          description: "Given an emergency description, create and auto-approve a change, page the on-call engineer, and notify the CAB."
          inputParameters:
            - name: description
              in: body
              type: string
              description: "Description of the emergency change."
            - name: affected_service
              in: body
              type: string
              description: "Name of the affected service."
          steps:
            - name: create-change
              type: call
              call: "servicenow.create-change"
              with:
                short_description: "EMERGENCY: {{description}}"
                type: "emergency"
                risk: "high"
                cmdb_ci: "{{affected_service}}"
            - name: page-oncall
              type: call
              call: "pagerduty.create-incident"
              with:
                title: "Emergency change: {{description}}"
                service_id: "$secrets.pagerduty_service_id"
                urgency: "high"
            - name: notify-cab
              type: call
              call: "slack.post-message"
              with:
                channel: "cab-retrospective"
                text: "Emergency change {{create-change.number}} created and fast-tracked. Service: {{affected_service}} | PD: {{page-oncall.incident_url}} | Retrospective review required."
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: change-requests
          path: "/table/change_request"
          operations:
            - name: create-change
              method: POST
    - type: http
      namespace: pagerduty
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.pagerduty_token"
        placement: header
      resources:
        - name: incidents
          path: "/incidents"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Pulls employee role data from Okta, cross-references with ServiceNow access records, identifies orphaned accounts, and creates remediation tasks.

naftiko: "0.5"
info:
  label: "ServiceNow Employee Access Review"
  description: "Pulls employee role data from Okta, cross-references with ServiceNow access records, identifies orphaned accounts, and creates remediation tasks."
  tags:
    - itsm
    - identity-management
    - servicenow
    - okta
    - compliance
capability:
  exposes:
    - type: mcp
      namespace: access-review
      port: 8080
      tools:
        - name: review-employee-access
          description: "Given a department name, pull Okta users, compare with ServiceNow access records, and create tasks for orphaned accounts."
          inputParameters:
            - name: department
              in: body
              type: string
              description: "Department name to audit."
          steps:
            - name: get-okta-users
              type: call
              call: "okta.list-users"
              with:
                filter: "profile.department eq \"{{department}}\""
            - name: get-snow-access
              type: call
              call: "servicenow.query-access"
              with:
                sysparm_query: "department={{department}}"
            - name: create-review-task
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "Access review: {{department}} — {{get-okta-users.count}} Okta users vs {{get-snow-access.result_count}} ServiceNow records"
                assignment_group: "identity-governance"
  consumes:
    - type: http
      namespace: okta
      baseUri: "https://servicenow.okta.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.okta_api_token"
      resources:
        - name: users
          path: "/users"
          inputParameters:
            - name: filter
              in: query
          operations:
            - name: list-users
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: access-records
          path: "/table/sys_user_has_role"
          inputParameters:
            - name: sysparm_query
              in: query
          operations:
            - name: query-access
              method: GET
        - name: tasks
          path: "/table/task"
          operations:
            - name: create-task
              method: POST

Routes a facilities request to the building management team, creates a work order, and notifies the requester via Slack.

naftiko: "0.5"
info:
  label: "ServiceNow Facilities Request Fulfillment"
  description: "Routes a facilities request to the building management team, creates a work order, and notifies the requester via Slack."
  tags:
    - itsm
    - facilities-management
    - servicenow
    - slack
capability:
  exposes:
    - type: mcp
      namespace: facilities
      port: 8080
      tools:
        - name: fulfill-facilities-request
          description: "Given a facilities request number, create a work order, assign it to building management, and notify the requester."
          inputParameters:
            - name: request_number
              in: body
              type: string
              description: "ServiceNow facilities request number."
          steps:
            - name: get-request
              type: call
              call: "servicenow.get-request"
              with:
                number: "{{request_number}}"
            - name: create-work-order
              type: call
              call: "servicenow.create-work-order"
              with:
                short_description: "{{get-request.short_description}}"
                assignment_group: "building-management"
                location: "{{get-request.location}}"
            - name: notify-requester
              type: call
              call: "slack.post-message"
              with:
                channel: "{{get-request.requester_slack_id}}"
                text: "Your facilities request {{request_number}} has been assigned. Work order: {{create-work-order.number}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: requests
          path: "/table/sc_request"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-request
              method: GET
        - name: work-orders
          path: "/table/wm_order"
          operations:
            - name: create-work-order
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a GitHub pull request is merged to main, creates a ServiceNow change request for tracking and posts the linkage to Slack.

naftiko: "0.5"
info:
  label: "ServiceNow GitHub PR to Change Request"
  description: "When a GitHub pull request is merged to main, creates a ServiceNow change request for tracking and posts the linkage to Slack."
  tags:
    - itsm
    - change-management
    - servicenow
    - github
    - slack
capability:
  exposes:
    - type: mcp
      namespace: pr-to-change
      port: 8080
      tools:
        - name: create-change-from-pr
          description: "Given a GitHub repository and PR number, fetch PR details, create a ServiceNow change request, and post linkage to Slack."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "GitHub repository in owner/repo format."
            - name: pr_number
              in: body
              type: string
              description: "Pull request number."
          steps:
            - name: get-pr
              type: call
              call: "github.get-pull-request"
              with:
                repo: "{{repo}}"
                pull_number: "{{pr_number}}"
            - name: create-change
              type: call
              call: "servicenow.create-change"
              with:
                short_description: "Deploy: {{get-pr.title}}"
                type: "normal"
                description: "PR: {{repo}}#{{pr_number}}\nAuthor: {{get-pr.user}}\nMerged: {{get-pr.merged_at}}\n\n{{get-pr.body}}"
            - name: post-link
              type: call
              call: "slack.post-message"
              with:
                channel: "deployments"
                text: "Change {{create-change.number}} created from PR {{repo}}#{{pr_number}}: {{get-pr.title}}"
  consumes:
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: pulls
          path: "/repos/{{repo}}/pulls/{{pull_number}}"
          inputParameters:
            - name: repo
              in: path
            - name: pull_number
              in: path
          operations:
            - name: get-pull-request
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: change-requests
          path: "/table/change_request"
          operations:
            - name: create-change
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Queries the CMDB for hardware assets approaching end-of-life, creates replacement requests in the service catalog, and alerts the IT procurement team via Slack.

naftiko: "0.5"
info:
  label: "ServiceNow Hardware Lifecycle Tracker"
  description: "Queries the CMDB for hardware assets approaching end-of-life, creates replacement requests in the service catalog, and alerts the IT procurement team via Slack."
  tags:
    - itsm
    - asset-management
    - servicenow
    - slack
    - procurement
capability:
  exposes:
    - type: mcp
      namespace: hw-lifecycle
      port: 8080
      tools:
        - name: track-hardware-eol
          description: "Query CMDB for hardware nearing end-of-life within a given number of months, create catalog replacement requests, and notify procurement."
          inputParameters:
            - name: months_until_eol
              in: body
              type: string
              description: "Number of months before end-of-life to flag assets."
          steps:
            - name: query-eol-assets
              type: call
              call: "servicenow.query-hardware-eol"
              with:
                sysparm_query: "install_statusINoperational^end_of_lifeRELATIVELT@month@ahead@{{months_until_eol}}"
            - name: create-replacement-request
              type: call
              call: "servicenow.create-catalog-request"
              with:
                cat_item: "hardware-replacement"
                description: "EOL hardware replacement needed for {{query-eol-assets.result_count}} assets"
            - name: notify-procurement
              type: call
              call: "slack.post-message"
              with:
                channel: "it-procurement"
                text: "Hardware EOL Alert: {{query-eol-assets.result_count}} assets reaching end-of-life within {{months_until_eol}} months. Replacement request: {{create-replacement-request.number}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: hardware
          path: "/table/cmdb_ci_hardware"
          inputParameters:
            - name: sysparm_query
              in: query
          operations:
            - name: query-hardware-eol
              method: GET
        - name: catalog-requests
          path: "/table/sc_request"
          operations:
            - name: create-catalog-request
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Uses Anthropic Claude to analyze incident descriptions, auto-categorize and assign priority, then updates the incident record and notifies the appropriate team.

naftiko: "0.5"
info:
  label: "ServiceNow Incident AI Categorization"
  description: "Uses Anthropic Claude to analyze incident descriptions, auto-categorize and assign priority, then updates the incident record and notifies the appropriate team."
  tags:
    - itsm
    - ai
    - servicenow
    - anthropic
    - automation
capability:
  exposes:
    - type: mcp
      namespace: ai-categorize
      port: 8080
      tools:
        - name: categorize-incident
          description: "Given an incident number, use AI to determine the correct category and priority, update the incident, and notify the assigned team."
          inputParameters:
            - name: incident_number
              in: body
              type: string
              description: "ServiceNow incident number to categorize."
          steps:
            - name: get-incident
              type: call
              call: "servicenow.get-incident"
              with:
                number: "{{incident_number}}"
            - name: ai-classify
              type: call
              call: "anthropic.create-message"
              with:
                model: "claude-sonnet-4-20250514"
                max_tokens: 256
                system: "You are an ITSM classifier. Return JSON with category, subcategory, and priority fields."
                content: "Classify this incident: {{get-incident.short_description}} — {{get-incident.description}}"
            - name: update-incident
              type: call
              call: "servicenow.update-incident"
              with:
                sys_id: "{{get-incident.sys_id}}"
                category: "{{ai-classify.category}}"
                priority: "{{ai-classify.priority}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-incident
              method: GET
        - name: incident-update
          path: "/table/incident/{{sys_id}}"
          inputParameters:
            - name: sys_id
              in: path
          operations:
            - name: update-incident
              method: PATCH
    - type: http
      namespace: anthropic
      baseUri: "https://api.anthropic.com/v1"
      authentication:
        type: apikey
        key: "x-api-key"
        value: "$secrets.anthropic_api_key"
        placement: header
      resources:
        - name: messages
          path: "/messages"
          operations:
            - name: create-message
              method: POST

Retrieves an unassigned incident, looks up the appropriate assignment group based on category, assigns the incident, and notifies the group via Slack.

naftiko: "0.5"
info:
  label: "ServiceNow Incident Auto-Assignment"
  description: "Retrieves an unassigned incident, looks up the appropriate assignment group based on category, assigns the incident, and notifies the group via Slack."
  tags:
    - itsm
    - incident-management
    - servicenow
    - slack
    - automation
capability:
  exposes:
    - type: mcp
      namespace: incident-assign
      port: 8080
      tools:
        - name: auto-assign-incident
          description: "Given an incident number, determine the correct assignment group by category, update the incident, and notify the team in Slack."
          inputParameters:
            - name: incident_number
              in: body
              type: string
              description: "ServiceNow incident number to auto-assign."
          steps:
            - name: get-incident
              type: call
              call: "servicenow.get-incident"
              with:
                number: "{{incident_number}}"
            - name: assign-incident
              type: call
              call: "servicenow.update-incident"
              with:
                sys_id: "{{get-incident.sys_id}}"
                assignment_group: "{{get-incident.category}}-support"
            - name: notify-team
              type: call
              call: "slack.post-message"
              with:
                channel: "{{get-incident.category}}-support"
                text: "New incident assigned: {{incident_number}} — {{get-incident.short_description}} | Priority: {{get-incident.priority}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-incident
              method: GET
        - name: incident-update
          path: "/table/incident/{{sys_id}}"
          inputParameters:
            - name: sys_id
              in: path
            - name: assignment_group
              in: body
          operations:
            - name: update-incident
              method: PATCH
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves a ServiceNow incident record by number, returning priority, state, assignment group, and short description.

naftiko: "0.5"
info:
  label: "ServiceNow Incident Lookup"
  description: "Retrieves a ServiceNow incident record by number, returning priority, state, assignment group, and short description."
  tags:
    - itsm
    - incident-management
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: snow-incident
      port: 8080
      tools:
        - name: get-incident
          description: "Given a ServiceNow incident number, return the incident priority, state, assigned group, and short description."
          inputParameters:
            - name: incident_number
              in: body
              type: string
              description: "ServiceNow incident number, e.g. INC0012345."
          call: "servicenow.get-incident"
          with:
            number: "{{incident_number}}"
          outputParameters:
            - name: sys_id
              type: string
              mapping: "$.result[0].sys_id"
            - name: priority
              type: string
              mapping: "$.result[0].priority.display_value"
            - name: state
              type: string
              mapping: "$.result[0].state.display_value"
            - name: assignment_group
              type: string
              mapping: "$.result[0].assignment_group.display_value"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-incident
              method: GET

Links a child incident to a parent major incident, updates both records, and notifies the incident commander via Slack.

naftiko: "0.5"
info:
  label: "ServiceNow Incident Parent-Child Link"
  description: "Links a child incident to a parent major incident, updates both records, and notifies the incident commander via Slack."
  tags:
    - itsm
    - incident-management
    - servicenow
    - slack
capability:
  exposes:
    - type: mcp
      namespace: incident-link
      port: 8080
      tools:
        - name: link-child-incident
          description: "Given a child incident and parent major incident number, link them and notify the incident commander."
          inputParameters:
            - name: child_number
              in: body
              type: string
              description: "Child incident number."
            - name: parent_number
              in: body
              type: string
              description: "Parent major incident number."
          steps:
            - name: get-parent
              type: call
              call: "servicenow.get-incident"
              with:
                number: "{{parent_number}}"
            - name: update-child
              type: call
              call: "servicenow.update-incident"
              with:
                number: "{{child_number}}"
                parent_incident: "{{get-parent.sys_id}}"
            - name: notify-commander
              type: call
              call: "slack.post-message"
              with:
                channel: "major-incidents"
                text: "Child incident {{child_number}} linked to major incident {{parent_number}} — {{get-parent.short_description}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-incident
              method: GET
            - name: update-incident
              method: PATCH
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Detects recently reopened incidents, creates a quality review task, and alerts the service desk manager via Slack.

naftiko: "0.5"
info:
  label: "ServiceNow Incident Reopen Detector"
  description: "Detects recently reopened incidents, creates a quality review task, and alerts the service desk manager via Slack."
  tags:
    - itsm
    - quality-assurance
    - servicenow
    - slack
capability:
  exposes:
    - type: mcp
      namespace: reopen-detect
      port: 8080
      tools:
        - name: detect-reopened-incidents
          description: "Query for incidents reopened in the last 24 hours, create a quality review task, and notify the service desk manager."
          inputParameters:
            - name: hours
              in: body
              type: string
              description: "Number of hours to look back for reopened incidents."
          steps:
            - name: query-reopened
              type: call
              call: "servicenow.query-incidents"
              with:
                sysparm_query: "reopened=true^sys_updated_onRELATIVEGE@hour@ago@{{hours}}"
            - name: create-review-task
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "Quality review: {{query-reopened.result_count}} reopened incidents in last {{hours}} hours"
                assignment_group: "service-desk-management"
            - name: notify-manager
              type: call
              call: "slack.post-message"
              with:
                channel: "service-desk-mgmt"
                text: "Reopen Alert: {{query-reopened.result_count}} incidents reopened in the last {{hours}} hours. Review task: {{create-review-task.number}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          inputParameters:
            - name: sysparm_query
              in: query
          operations:
            - name: query-incidents
              method: GET
        - name: tasks
          path: "/table/task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Reads open incident descriptions from ServiceNow, runs sentiment analysis via Anthropic Claude, and flags negative-sentiment incidents for priority review.

naftiko: "0.5"
info:
  label: "ServiceNow Incident Sentiment Analysis"
  description: "Reads open incident descriptions from ServiceNow, runs sentiment analysis via Anthropic Claude, and flags negative-sentiment incidents for priority review."
  tags:
    - itsm
    - ai
    - servicenow
    - anthropic
    - triage
capability:
  exposes:
    - type: mcp
      namespace: incident-ai
      port: 8080
      tools:
        - name: analyze-incident-sentiment
          description: "Given a ServiceNow incident number, extract the description, use Anthropic Claude to assess customer sentiment, and update the incident with a sentiment tag for triage prioritization."
          inputParameters:
            - name: incident_number
              in: body
              type: string
              description: "ServiceNow incident number to analyze, e.g. INC0012345."
          steps:
            - name: get-incident
              type: call
              call: "snow-ai.get-incident"
              with:
                number: "{{incident_number}}"
            - name: analyze-sentiment
              type: call
              call: "anthropic.analyze-sentiment"
              with:
                text: "{{get-incident.description}}"
            - name: update-incident
              type: call
              call: "snow-ai.update-incident"
              with:
                sysId: "{{get-incident.sys_id}}"
                sentiment: "{{analyze-sentiment.sentiment}}"
                sentimentScore: "{{analyze-sentiment.score}}"
  consumes:
    - type: http
      namespace: snow-ai
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-incident
              method: GET
        - name: incident-updates
          path: "/table/incident/{{sysId}}"
          inputParameters:
            - name: sysId
              in: path
          operations:
            - name: update-incident
              method: PATCH
    - type: http
      namespace: anthropic
      baseUri: "https://api.anthropic.com/v1"
      authentication:
        type: apikey
        key: "x-api-key"
        value: "$secrets.anthropic_api_key"
        placement: header
      resources:
        - name: messages
          path: "/messages"
          operations:
            - name: analyze-sentiment
              method: POST

Converts a ServiceNow incident into a Jira bug ticket with full context, links them bidirectionally, and posts a confirmation to Slack.

naftiko: "0.5"
info:
  label: "ServiceNow Incident to Jira Bug"
  description: "Converts a ServiceNow incident into a Jira bug ticket with full context, links them bidirectionally, and posts a confirmation to Slack."
  tags:
    - itsm
    - incident-management
    - servicenow
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: incident-to-bug
      port: 8080
      tools:
        - name: create-bug-from-incident
          description: "Given a ServiceNow incident number and Jira project key, create a bug ticket in Jira with incident details and post confirmation to Slack."
          inputParameters:
            - name: incident_number
              in: body
              type: string
              description: "ServiceNow incident number."
            - name: project_key
              in: body
              type: string
              description: "Jira project key for the bug ticket."
          steps:
            - name: get-incident
              type: call
              call: "servicenow.get-incident"
              with:
                number: "{{incident_number}}"
            - name: create-jira-bug
              type: call
              call: "jira.create-issue"
              with:
                project_key: "{{project_key}}"
                issuetype: "Bug"
                summary: "SNOW {{incident_number}}: {{get-incident.short_description}}"
                description: "Priority: {{get-incident.priority}}\nCategory: {{get-incident.category}}\nAssigned to: {{get-incident.assigned_to}}"
            - name: post-confirmation
              type: call
              call: "slack.post-message"
              with:
                channel: "engineering"
                text: "Bug created from incident {{incident_number}}: {{create-jira-bug.key}} — {{get-incident.short_description}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-incident
              method: GET
    - type: http
      namespace: jira
      baseUri: "https://servicenow-corp.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Analyzes incident trends over a period, identifies top categories and assignment groups, and posts a trend report to Slack.

naftiko: "0.5"
info:
  label: "ServiceNow Incident Trend Analysis"
  description: "Analyzes incident trends over a period, identifies top categories and assignment groups, and posts a trend report to Slack."
  tags:
    - itsm
    - analytics
    - servicenow
    - slack
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: incident-trends
      port: 8080
      tools:
        - name: analyze-incident-trends
          description: "Query incidents for a given period, aggregate by category, and post a trend analysis to Slack."
          inputParameters:
            - name: days
              in: body
              type: string
              description: "Number of days to analyze."
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel for the trend report."
          steps:
            - name: query-incidents
              type: call
              call: "servicenow.query-incidents"
              with:
                sysparm_query: "opened_atRELATIVEGE@day@ago@{{days}}"
            - name: post-trends
              type: call
              call: "slack.post-message"
              with:
                channel: "{{slack_channel}}"
                text: "Incident Trend Report ({{days}} days): {{query-incidents.result_count}} total incidents | Top category: {{query-incidents.top_category}} | Top group: {{query-incidents.top_group}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          inputParameters:
            - name: sysparm_query
              in: query
          operations:
            - name: query-incidents
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Aggregates IT costs from ServiceNow ITFM by cost center, generates allocation summary, and distributes via Slack to finance leadership.

naftiko: "0.5"
info:
  label: "ServiceNow IT Cost Allocation Report"
  description: "Aggregates IT costs from ServiceNow ITFM by cost center, generates allocation summary, and distributes via Slack to finance leadership."
  tags:
    - itsm
    - financial-management
    - servicenow
    - slack
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: cost-allocation
      port: 8080
      tools:
        - name: generate-cost-allocation-report
          description: "Query IT cost data by period, aggregate by cost center, and post allocation summary to Slack."
          inputParameters:
            - name: fiscal_period
              in: body
              type: string
              description: "Fiscal period, e.g. 2026-Q1."
          steps:
            - name: query-costs
              type: call
              call: "servicenow.query-costs"
              with:
                sysparm_query: "fiscal_period={{fiscal_period}}"
            - name: post-report
              type: call
              call: "slack.post-message"
              with:
                channel: "finance-leadership"
                text: "IT Cost Allocation Report for {{fiscal_period}}: Total spend: {{query-costs.total_cost}} | Top cost center: {{query-costs.top_cost_center}} ({{query-costs.top_cost_amount}})"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: cost-items
          path: "/table/fm_ci_cost"
          inputParameters:
            - name: sysparm_query
              in: query
          operations:
            - name: query-costs
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Aggregates open incident counts, SLA breach rates, and change success rates from ServiceNow and publishes a daily ops digest to a Slack channel.

naftiko: "0.5"
info:
  label: "ServiceNow IT Operations Dashboard Digest"
  description: "Aggregates open incident counts, SLA breach rates, and change success rates from ServiceNow and publishes a daily ops digest to a Slack channel."
  tags:
    - itsm
    - reporting
    - servicenow
    - slack
    - monitoring
capability:
  exposes:
    - type: mcp
      namespace: ops-digest
      port: 8080
      tools:
        - name: publish-ops-digest
          description: "Gather current open incident counts, SLA breach counts, and change success rates from ServiceNow aggregate APIs and post a formatted digest to the specified Slack channel."
          inputParameters:
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel to post the daily ops digest."
          steps:
            - name: get-incident-stats
              type: call
              call: "snow-stats.get-incident-stats"
            - name: get-change-stats
              type: call
              call: "snow-stats.get-change-stats"
            - name: post-digest
              type: call
              call: "slack-digest.post-message"
              with:
                channel: "{{slack_channel}}"
                text: "Daily IT Ops Digest: Open Incidents={{get-incident-stats.openCount}} | SLA Breached={{get-incident-stats.slaBreached}} | Changes Today={{get-change-stats.total}} | Success Rate={{get-change-stats.successRate}}%"
  consumes:
    - type: http
      namespace: snow-stats
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incident-stats
          path: "/stats/incident"
          operations:
            - name: get-incident-stats
              method: GET
        - name: change-stats
          path: "/stats/change_request"
          operations:
            - name: get-change-stats
              method: GET
    - type: http
      namespace: slack-digest
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Routes a high-value IT request through a multi-level approval chain, notifying each approver via Slack and updating ServiceNow at each stage.

naftiko: "0.5"
info:
  label: "ServiceNow IT Request Approval Chain"
  description: "Routes a high-value IT request through a multi-level approval chain, notifying each approver via Slack and updating ServiceNow at each stage."
  tags:
    - itsm
    - approval-workflow
    - servicenow
    - slack
    - governance
capability:
  exposes:
    - type: mcp
      namespace: request-approval
      port: 8080
      tools:
        - name: route-approval-chain
          description: "Given a request item number, look up the request details, notify the first approver via Slack, and update the approval state in ServiceNow."
          inputParameters:
            - name: ritm_number
              in: body
              type: string
              description: "ServiceNow request item number."
          steps:
            - name: get-request
              type: call
              call: "servicenow.get-ritm"
              with:
                number: "{{ritm_number}}"
            - name: get-approver
              type: call
              call: "servicenow.get-approval"
              with:
                sysapproval: "{{get-request.sys_id}}"
            - name: notify-approver
              type: call
              call: "slack.post-message"
              with:
                channel: "{{get-approver.approver_slack_id}}"
                text: "Approval needed: {{ritm_number}} — {{get-request.short_description}} | Cost: {{get-request.price}} | Approve at: https://servicenow.service-now.com/nav_to.do?uri=sc_req_item.do?sys_id={{get-request.sys_id}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: request-items
          path: "/table/sc_req_item"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-ritm
              method: GET
        - name: approvals
          path: "/table/sysapproval_approver"
          inputParameters:
            - name: sysapproval
              in: query
          operations:
            - name: get-approval
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Aggregates IT satisfaction survey results from ServiceNow, calculates NPS and satisfaction scores, and posts a summary to Slack.

naftiko: "0.5"
info:
  label: "ServiceNow IT Survey Results Digest"
  description: "Aggregates IT satisfaction survey results from ServiceNow, calculates NPS and satisfaction scores, and posts a summary to Slack."
  tags:
    - itsm
    - customer-satisfaction
    - servicenow
    - slack
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: survey-digest
      port: 8080
      tools:
        - name: generate-survey-digest
          description: "Query recent survey responses, compute satisfaction metrics, and post a digest to Slack."
          inputParameters:
            - name: days
              in: body
              type: string
              description: "Number of days of survey data to aggregate."
          steps:
            - name: query-surveys
              type: call
              call: "servicenow.query-surveys"
              with:
                sysparm_query: "sys_created_onRELATIVEGE@day@ago@{{days}}"
            - name: post-digest
              type: call
              call: "slack.post-message"
              with:
                channel: "it-leadership"
                text: "IT Survey Digest ({{days}} days): Responses: {{query-surveys.result_count}} | Avg satisfaction: {{query-surveys.avg_score}} | NPS: {{query-surveys.nps_score}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: surveys
          path: "/table/asmt_assessment_instance"
          inputParameters:
            - name: sysparm_query
              in: query
          operations:
            - name: query-surveys
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Searches the ServiceNow knowledge base for articles matching a query, returning title, body excerpt, and view count.

naftiko: "0.5"
info:
  label: "ServiceNow Knowledge Article Lookup"
  description: "Searches the ServiceNow knowledge base for articles matching a query, returning title, body excerpt, and view count."
  tags:
    - itsm
    - knowledge-management
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: snow-kb
      port: 8080
      tools:
        - name: search-knowledge
          description: "Given a search query, return matching knowledge base articles with title, excerpt, and view count."
          inputParameters:
            - name: query
              in: body
              type: string
              description: "Search string to look up in the ServiceNow knowledge base."
          call: "servicenow.search-kb"
          with:
            text: "{{query}}"
          outputParameters:
            - name: article_id
              type: string
              mapping: "$.result[0].number"
            - name: title
              type: string
              mapping: "$.result[0].short_description"
            - name: view_count
              type: string
              mapping: "$.result[0].sys_view_count"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: knowledge-articles
          path: "/table/kb_knowledge"
          inputParameters:
            - name: text
              in: query
          operations:
            - name: search-kb
              method: GET

Drafts a knowledge article in ServiceNow from an incident post-mortem stored in Confluence and publishes it to the internal knowledge base.

naftiko: "0.5"
info:
  label: "ServiceNow Knowledge Article Publication"
  description: "Drafts a knowledge article in ServiceNow from an incident post-mortem stored in Confluence and publishes it to the internal knowledge base."
  tags:
    - itsm
    - knowledge-management
    - servicenow
    - confluence
    - ai
capability:
  exposes:
    - type: mcp
      namespace: knowledge-ops
      port: 8080
      tools:
        - name: publish-knowledge-article
          description: "Given a Confluence page ID containing an incident post-mortem, extract content using OpenAI to format it as a KB article, and publish it to ServiceNow Knowledge."
          inputParameters:
            - name: confluence_page_id
              in: body
              type: string
              description: "Confluence page ID of the post-mortem document."
            - name: snow_kb_category
              in: body
              type: string
              description: "ServiceNow knowledge base category sys_id."
          steps:
            - name: get-page
              type: call
              call: "confluence.get-page"
              with:
                pageId: "{{confluence_page_id}}"
            - name: format-kb-article
              type: call
              call: "openai.format-kb-content"
              with:
                content: "{{get-page.body}}"
                sourceUrl: "{{get-page.url}}"
            - name: create-kb-article
              type: call
              call: "snow-kb.create-article"
              with:
                short_description: "{{format-kb-article.title}}"
                text: "{{format-kb-article.body}}"
                kb_category: "{{snow_kb_category}}"
                workflow_state: "published"
  consumes:
    - type: http
      namespace: confluence
      baseUri: "https://servicenow.atlassian.net/wiki/rest/api"
      authentication:
        type: bearer
        token: "$secrets.confluence_token"
      resources:
        - name: pages
          path: "/content/{{pageId}}"
          inputParameters:
            - name: pageId
              in: path
          operations:
            - name: get-page
              method: GET
    - type: http
      namespace: openai
      baseUri: "https://api.openai.com/v1"
      authentication:
        type: bearer
        token: "$secrets.openai_token"
      resources:
        - name: chat-completions
          path: "/chat/completions"
          operations:
            - name: format-kb-content
              method: POST
    - type: http
      namespace: snow-kb
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: knowledge-articles
          path: "/table/kb_knowledge"
          operations:
            - name: create-article
              method: POST

Analyzes recent incidents for recurring categories without matching knowledge articles, creates KB draft tasks, and alerts the knowledge management team.

naftiko: "0.5"
info:
  label: "ServiceNow Knowledge Gap Detector"
  description: "Analyzes recent incidents for recurring categories without matching knowledge articles, creates KB draft tasks, and alerts the knowledge management team."
  tags:
    - itsm
    - knowledge-management
    - servicenow
    - slack
    - automation
capability:
  exposes:
    - type: mcp
      namespace: kb-gap
      port: 8080
      tools:
        - name: detect-knowledge-gaps
          description: "Query recent incidents, identify categories with no matching KB articles, and create KB authoring tasks."
          inputParameters:
            - name: days
              in: body
              type: string
              description: "Number of days of incidents to analyze."
          steps:
            - name: query-incidents
              type: call
              call: "servicenow.query-incidents"
              with:
                sysparm_query: "opened_atRELATIVEGE@day@ago@{{days}}"
            - name: search-kb
              type: call
              call: "servicenow.search-kb"
              with:
                category: "{{query-incidents.top_unresolved_category}}"
            - name: create-kb-task
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "KB Gap: Write article for {{query-incidents.top_unresolved_category}}"
                assignment_group: "knowledge-management"
            - name: notify-km-team
              type: call
              call: "slack.post-message"
              with:
                channel: "knowledge-management"
                text: "Knowledge gap detected: {{query-incidents.top_unresolved_category}} — {{query-incidents.unresolved_count}} incidents with no matching KB. Task: {{create-kb-task.number}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          inputParameters:
            - name: sysparm_query
              in: query
          operations:
            - name: query-incidents
              method: GET
        - name: knowledge
          path: "/table/kb_knowledge"
          inputParameters:
            - name: category
              in: query
          operations:
            - name: search-kb
              method: GET
        - name: tasks
          path: "/table/task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Queries ServiceNow software asset management for license overuse, generates a compliance report, creates a remediation task, and emails the IT asset manager.

naftiko: "0.5"
info:
  label: "ServiceNow License Compliance Audit"
  description: "Queries ServiceNow software asset management for license overuse, generates a compliance report, creates a remediation task, and emails the IT asset manager."
  tags:
    - itsm
    - asset-management
    - servicenow
    - compliance
    - automation
capability:
  exposes:
    - type: mcp
      namespace: license-audit
      port: 8080
      tools:
        - name: audit-license-compliance
          description: "Check software license entitlements against actual installations, flag overuse, create a remediation task, and notify the asset manager."
          inputParameters:
            - name: software_name
              in: body
              type: string
              description: "Name of the software product to audit."
          steps:
            - name: get-entitlements
              type: call
              call: "servicenow.get-entitlements"
              with:
                software_name: "{{software_name}}"
            - name: get-installations
              type: call
              call: "servicenow.get-installations"
              with:
                software_name: "{{software_name}}"
            - name: create-remediation-task
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "License overuse: {{software_name}} — {{get-installations.count}} installed vs {{get-entitlements.count}} entitled"
                assignment_group: "it-asset-management"
            - name: notify-manager
              type: call
              call: "slack.post-message"
              with:
                channel: "it-asset-management"
                text: "License audit: {{software_name}} — {{get-installations.count}} installations vs {{get-entitlements.count}} entitlements. Task: {{create-remediation-task.number}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: entitlements
          path: "/table/alm_entitlement"
          inputParameters:
            - name: software_name
              in: query
          operations:
            - name: get-entitlements
              method: GET
        - name: installations
          path: "/table/cmdb_sam_sw_install"
          inputParameters:
            - name: software_name
              in: query
          operations:
            - name: get-installations
              method: GET
        - name: tasks
          path: "/table/task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves location details by name, returning address, timezone, and parent location.

naftiko: "0.5"
info:
  label: "ServiceNow Location Lookup"
  description: "Retrieves location details by name, returning address, timezone, and parent location."
  tags:
    - itsm
    - location-management
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: snow-location
      port: 8080
      tools:
        - name: get-location
          description: "Given a location name, return its full address, timezone, and parent location."
          inputParameters:
            - name: location_name
              in: body
              type: string
              description: "Location name to look up."
          call: "servicenow.get-location"
          with:
            name: "{{location_name}}"
          outputParameters:
            - name: full_name
              type: string
              mapping: "$.result[0].full_name"
            - name: street
              type: string
              mapping: "$.result[0].street"
            - name: city
              type: string
              mapping: "$.result[0].city"
            - name: time_zone
              type: string
              mapping: "$.result[0].time_zone"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: locations
          path: "/table/cmn_location"
          inputParameters:
            - name: name
              in: query
          operations:
            - name: get-location
              method: GET

When a ServiceNow incident is promoted to Major Incident, creates a Zoom meeting, posts the join link to Slack, and assigns an Jira P0 tracking ticket.

naftiko: "0.5"
info:
  label: "ServiceNow Major Incident War Room"
  description: "When a ServiceNow incident is promoted to Major Incident, creates a Zoom meeting, posts the join link to Slack, and assigns an Jira P0 tracking ticket."
  tags:
    - itsm
    - incident-response
    - servicenow
    - zoom
    - slack
    - jira
    - major-incident
capability:
  exposes:
    - type: mcp
      namespace: major-incident-ops
      port: 8080
      tools:
        - name: open-war-room
          description: "Given a ServiceNow major incident number, create a Zoom war room meeting, post the join link to the incidents Slack channel, and open a Jira P0 tracking ticket."
          inputParameters:
            - name: incident_number
              in: body
              type: string
              description: "ServiceNow incident number promoted to Major Incident."
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel to post the war room link."
            - name: jira_project_key
              in: body
              type: string
              description: "Jira project key for the P0 tracking ticket."
          steps:
            - name: get-incident
              type: call
              call: "snow-mi.get-incident"
              with:
                number: "{{incident_number}}"
            - name: create-zoom
              type: call
              call: "zoom.create-meeting"
              with:
                topic: "War Room: {{get-incident.short_description}}"
                duration: 120
            - name: post-war-room
              type: call
              call: "slack-mi.post-message"
              with:
                channel: "{{slack_channel}}"
                text: "MAJOR INCIDENT: {{incident_number}} — {{get-incident.short_description}} | War Room: {{create-zoom.join_url}}"
            - name: create-jira-p0
              type: call
              call: "jira-mi.create-issue"
              with:
                project_key: "{{jira_project_key}}"
                issuetype: "Bug"
                summary: "P0: {{get-incident.short_description}}"
                description: "ServiceNow Incident: {{incident_number}}\nZoom: {{create-zoom.join_url}}"
  consumes:
    - type: http
      namespace: snow-mi
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-incident
              method: GET
    - type: http
      namespace: zoom
      baseUri: "https://api.zoom.us/v2"
      authentication:
        type: bearer
        token: "$secrets.zoom_token"
      resources:
        - name: meetings
          path: "/users/me/meetings"
          operations:
            - name: create-meeting
              method: POST
    - type: http
      namespace: slack-mi
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST
    - type: http
      namespace: jira-mi
      baseUri: "https://servicenow.atlassian.net/rest/api/3"
      authentication:
        type: bearer
        token: "$secrets.jira_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST

Processes a mobile device enrollment request, registers the device in Microsoft Intune, updates the ServiceNow CMDB, and notifies the user.

naftiko: "0.5"
info:
  label: "ServiceNow Mobile Device Enrollment Workflow"
  description: "Processes a mobile device enrollment request, registers the device in Microsoft Intune, updates the ServiceNow CMDB, and notifies the user."
  tags:
    - itsm
    - device-management
    - servicenow
    - microsoft-intune
    - slack
capability:
  exposes:
    - type: mcp
      namespace: mdm-enroll
      port: 8080
      tools:
        - name: enroll-mobile-device
          description: "Given a request item number, register the device in Intune, create a CMDB record, and notify the user."
          inputParameters:
            - name: ritm_number
              in: body
              type: string
              description: "ServiceNow request item number."
          steps:
            - name: get-request
              type: call
              call: "servicenow.get-ritm"
              with:
                number: "{{ritm_number}}"
            - name: register-device
              type: call
              call: "intune.register-device"
              with:
                device_name: "{{get-request.device_name}}"
                user_principal: "{{get-request.requested_for_email}}"
            - name: create-cmdb-ci
              type: call
              call: "servicenow.create-ci"
              with:
                name: "{{get-request.device_name}}"
                sys_class_name: "cmdb_ci_mobile_device"
                assigned_to: "{{get-request.requested_for}}"
            - name: notify-user
              type: call
              call: "slack.post-message"
              with:
                channel: "{{get-request.requested_for_slack_id}}"
                text: "Your mobile device {{get-request.device_name}} has been enrolled. Request {{ritm_number}} complete."
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: request-items
          path: "/table/sc_req_item"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-ritm
              method: GET
        - name: cmdb-items
          path: "/table/cmdb_ci"
          operations:
            - name: create-ci
              method: POST
    - type: http
      namespace: intune
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.intune_token"
      resources:
        - name: devices
          path: "/deviceManagement/managedDevices"
          operations:
            - name: register-device
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Aggregates cloud cost data from AWS and Azure, stores the summary in ServiceNow ITFM, and sends a cost optimization alert to Slack.

naftiko: "0.5"
info:
  label: "ServiceNow Multi-Cloud Cost Aggregator"
  description: "Aggregates cloud cost data from AWS and Azure, stores the summary in ServiceNow ITFM, and sends a cost optimization alert to Slack."
  tags:
    - itsm
    - financial-management
    - servicenow
    - aws
    - slack
    - cloud-governance
capability:
  exposes:
    - type: mcp
      namespace: cloud-cost
      port: 8080
      tools:
        - name: aggregate-cloud-costs
          description: "Pull cost data from AWS Cost Explorer, store aggregated totals in ServiceNow ITFM, and alert finance via Slack."
          inputParameters:
            - name: month
              in: body
              type: string
              description: "Month to aggregate costs for, e.g. 2026-03."
          steps:
            - name: get-aws-costs
              type: call
              call: "aws-ce.get-cost"
              with:
                time_period_start: "{{month}}-01"
                time_period_end: "{{month}}-31"
                granularity: "MONTHLY"
            - name: store-in-snow
              type: call
              call: "servicenow.create-cost-record"
              with:
                provider: "AWS"
                amount: "{{get-aws-costs.total}}"
                period: "{{month}}"
            - name: notify-finance
              type: call
              call: "slack.post-message"
              with:
                channel: "cloud-finops"
                text: "Cloud Cost Report for {{month}}: AWS: ${{get-aws-costs.total}} | Stored in ServiceNow ITFM. Review at https://servicenow.service-now.com/itfm"
  consumes:
    - type: http
      namespace: aws-ce
      baseUri: "https://ce.us-east-1.amazonaws.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.aws_auth_header"
        placement: header
      resources:
        - name: costs
          path: "/GetCostAndUsage"
          operations:
            - name: get-cost
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: cost-records
          path: "/table/fm_ci_cost"
          operations:
            - name: create-cost-record
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves network device details from the CMDB by name, returning device type, firmware version, and management IP.

naftiko: "0.5"
info:
  label: "ServiceNow Network Device Lookup"
  description: "Retrieves network device details from the CMDB by name, returning device type, firmware version, and management IP."
  tags:
    - itsm
    - cmdb
    - servicenow
    - networking
capability:
  exposes:
    - type: mcp
      namespace: snow-network
      port: 8080
      tools:
        - name: get-network-device
          description: "Given a network device name, return its type, firmware version, management IP, and operational status."
          inputParameters:
            - name: device_name
              in: body
              type: string
              description: "Name of the network device."
          call: "servicenow.get-network-device"
          with:
            name: "{{device_name}}"
          outputParameters:
            - name: device_type
              type: string
              mapping: "$.result[0].sys_class_name.display_value"
            - name: firmware
              type: string
              mapping: "$.result[0].firmware_version"
            - name: management_ip
              type: string
              mapping: "$.result[0].ip_address"
            - name: status
              type: string
              mapping: "$.result[0].operational_status.display_value"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: network-devices
          path: "/table/cmdb_ci_netgear"
          inputParameters:
            - name: name
              in: query
          operations:
            - name: get-network-device
              method: GET

Provisions a new hire by creating Okta account, requesting laptop from ServiceNow catalog, granting GitHub access, and notifying IT ops via Slack.

naftiko: "0.5"
info:
  label: "ServiceNow New Hire IT Provisioning"
  description: "Provisions a new hire by creating Okta account, requesting laptop from ServiceNow catalog, granting GitHub access, and notifying IT ops via Slack."
  tags:
    - itsm
    - onboarding
    - servicenow
    - okta
    - github
    - slack
capability:
  exposes:
    - type: mcp
      namespace: it-provisioning
      port: 8080
      tools:
        - name: provision-new-hire
          description: "Given employee details from Workday, create Okta account, submit ServiceNow catalog requests for equipment, add to GitHub org, and notify IT."
          inputParameters:
            - name: employee_name
              in: body
              type: string
              description: "Full name of the new hire."
            - name: employee_email
              in: body
              type: string
              description: "Corporate email address."
            - name: department
              in: body
              type: string
              description: "Department name."
            - name: github_username
              in: body
              type: string
              description: "GitHub username for org access."
          steps:
            - name: create-okta-user
              type: call
              call: "okta.create-user"
              with:
                firstName: "{{employee_name}}"
                email: "{{employee_email}}"
                groupIds: "{{department}}-users"
            - name: create-laptop-request
              type: call
              call: "servicenow.create-catalog-request"
              with:
                cat_item: "standard-laptop"
                requested_for: "{{employee_email}}"
                description: "New hire laptop for {{employee_name}} — {{department}}"
            - name: add-to-github
              type: call
              call: "github.add-org-member"
              with:
                username: "{{github_username}}"
                role: "member"
            - name: notify-it
              type: call
              call: "slack.post-message"
              with:
                channel: "it-ops"
                text: "New hire provisioned: {{employee_name}} | Okta: created | Laptop: {{create-laptop-request.number}} | GitHub: {{github_username}} added"
  consumes:
    - type: http
      namespace: okta
      baseUri: "https://servicenow.okta.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.okta_api_token"
      resources:
        - name: users
          path: "/users"
          operations:
            - name: create-user
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: catalog-requests
          path: "/table/sc_request"
          operations:
            - name: create-catalog-request
              method: POST
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: org-members
          path: "/orgs/servicenow/memberships/{{username}}"
          inputParameters:
            - name: username
              in: path
          operations:
            - name: add-org-member
              method: PUT
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Detects expiring OAuth tokens in ServiceNow credential store, rotates them, creates a change record for audit, and notifies the security team.

naftiko: "0.5"
info:
  label: "ServiceNow OAuth Token Rotation Workflow"
  description: "Detects expiring OAuth tokens in ServiceNow credential store, rotates them, creates a change record for audit, and notifies the security team."
  tags:
    - itsm
    - security
    - servicenow
    - slack
    - credential-management
capability:
  exposes:
    - type: mcp
      namespace: token-rotation
      port: 8080
      tools:
        - name: rotate-expiring-tokens
          description: "Query for OAuth tokens nearing expiry, initiate rotation, create a change record, and alert security."
          inputParameters:
            - name: days_until_expiry
              in: body
              type: string
              description: "Days before expiry to trigger rotation."
          steps:
            - name: query-expiring-tokens
              type: call
              call: "servicenow.query-credentials"
              with:
                sysparm_query: "expiration_dateRELATIVELT@day@ahead@{{days_until_expiry}}^type=oauth"
            - name: create-change
              type: call
              call: "servicenow.create-change"
              with:
                short_description: "OAuth token rotation: {{query-expiring-tokens.result_count}} tokens expiring within {{days_until_expiry}} days"
                type: "standard"
                assignment_group: "security-ops"
            - name: notify-security
              type: call
              call: "slack.post-message"
              with:
                channel: "secops"
                text: "Token Rotation: {{query-expiring-tokens.result_count}} OAuth tokens expiring within {{days_until_expiry}} days. Change: {{create-change.number}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: credentials
          path: "/table/oauth_credential"
          inputParameters:
            - name: sysparm_query
              in: query
          operations:
            - name: query-credentials
              method: GET
        - name: change-requests
          path: "/table/change_request"
          operations:
            - name: create-change
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a major incident is declared, creates a status page update, sends mass notification via email, posts to Slack, and updates the ServiceNow incident timeline.

naftiko: "0.5"
info:
  label: "ServiceNow Outage Communication Orchestrator"
  description: "When a major incident is declared, creates a status page update, sends mass notification via email, posts to Slack, and updates the ServiceNow incident timeline."
  tags:
    - itsm
    - incident-management
    - servicenow
    - slack
    - communications
capability:
  exposes:
    - type: mcp
      namespace: outage-comms
      port: 8080
      tools:
        - name: orchestrate-outage-comms
          description: "Given a major incident number, publish status page update, broadcast to Slack, and record communication in the incident work notes."
          inputParameters:
            - name: incident_number
              in: body
              type: string
              description: "ServiceNow major incident number."
            - name: status_message
              in: body
              type: string
              description: "Status update message for stakeholders."
          steps:
            - name: get-incident
              type: call
              call: "servicenow.get-incident"
              with:
                number: "{{incident_number}}"
            - name: post-slack-broadcast
              type: call
              call: "slack.post-message"
              with:
                channel: "company-status"
                text: "SERVICE ALERT: {{get-incident.short_description}} | Status: {{status_message}} | Tracking: {{incident_number}}"
            - name: update-work-notes
              type: call
              call: "servicenow.update-incident"
              with:
                sys_id: "{{get-incident.sys_id}}"
                work_notes: "Outage communication sent: {{status_message}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-incident
              method: GET
        - name: incident-update
          path: "/table/incident/{{sys_id}}"
          inputParameters:
            - name: sys_id
              in: path
          operations:
            - name: update-incident
              method: PATCH
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Queries ServiceNow for servers with overdue patches, cross-references with Datadog host inventory, and creates Jira tasks for the infrastructure team to remediate.

naftiko: "0.5"
info:
  label: "ServiceNow Patch Compliance Check"
  description: "Queries ServiceNow for servers with overdue patches, cross-references with Datadog host inventory, and creates Jira tasks for the infrastructure team to remediate."
  tags:
    - security
    - compliance
    - servicenow
    - datadog
    - jira
    - patch-management
capability:
  exposes:
    - type: mcp
      namespace: patch-compliance
      port: 8080
      tools:
        - name: check-patch-compliance
          description: "Fetch overdue patch records from ServiceNow, validate host status in Datadog, and create Jira remediation tasks for each non-compliant host."
          inputParameters:
            - name: days_overdue
              in: body
              type: integer
              description: "Minimum days overdue to flag a host as non-compliant."
            - name: jira_project_key
              in: body
              type: string
              description: "Jira project key for remediation tasks."
          steps:
            - name: get-overdue-patches
              type: call
              call: "snow-patch.get-overdue-patches"
              with:
                daysOverdue: "{{days_overdue}}"
            - name: validate-host-status
              type: call
              call: "datadog-patch.get-host-metrics"
              with:
                hostName: "{{get-overdue-patches.hostname}}"
            - name: create-remediation-task
              type: call
              call: "jira-patch.create-issue"
              with:
                project_key: "{{jira_project_key}}"
                issuetype: "Task"
                summary: "Patch overdue on {{get-overdue-patches.hostname}}"
                description: "Host: {{get-overdue-patches.hostname}}\nPatch: {{get-overdue-patches.patchName}}\nDays overdue: {{days_overdue}}\nDatadog status: {{validate-host-status.status}}"
  consumes:
    - type: http
      namespace: snow-patch
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: patch-records
          path: "/table/sn_vul_vulnerable_item"
          inputParameters:
            - name: daysOverdue
              in: query
          operations:
            - name: get-overdue-patches
              method: GET
    - type: http
      namespace: datadog-patch
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: hosts
          path: "/hosts"
          inputParameters:
            - name: hostName
              in: query
          operations:
            - name: get-host-metrics
              method: GET
    - type: http
      namespace: jira-patch
      baseUri: "https://servicenow.atlassian.net/rest/api/3"
      authentication:
        type: bearer
        token: "$secrets.jira_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST

When a ServiceNow problem is resolved, generates a structured post-mortem document using Anthropic Claude and saves it to Confluence.

naftiko: "0.5"
info:
  label: "ServiceNow Problem Post-Mortem Generator"
  description: "When a ServiceNow problem is resolved, generates a structured post-mortem document using Anthropic Claude and saves it to Confluence."
  tags:
    - itsm
    - ai
    - servicenow
    - anthropic
    - confluence
    - post-mortem
capability:
  exposes:
    - type: mcp
      namespace: postmortem-ops
      port: 8080
      tools:
        - name: generate-post-mortem
          description: "Given a resolved ServiceNow problem record number, extract the timeline and resolution data, generate a structured post-mortem using Anthropic Claude, and save the document to Confluence."
          inputParameters:
            - name: problem_number
              in: body
              type: string
              description: "ServiceNow problem record number, e.g. PRB0000123."
            - name: confluence_space_key
              in: body
              type: string
              description: "Confluence space key to publish the post-mortem page."
            - name: confluence_parent_page_id
              in: body
              type: string
              description: "Confluence parent page ID under which to create the post-mortem."
          steps:
            - name: get-problem
              type: call
              call: "snow-postmortem.get-problem"
              with:
                number: "{{problem_number}}"
            - name: generate-doc
              type: call
              call: "anthropic-pm.generate-postmortem"
              with:
                title: "{{get-problem.short_description}}"
                timeline: "{{get-problem.work_notes}}"
                rootCause: "{{get-problem.cause_notes}}"
                resolution: "{{get-problem.fix_notes}}"
            - name: save-confluence
              type: call
              call: "confluence-pm.create-page"
              with:
                spaceKey: "{{confluence_space_key}}"
                parentId: "{{confluence_parent_page_id}}"
                title: "Post-Mortem: {{get-problem.short_description}}"
                content: "{{generate-doc.markdown}}"
  consumes:
    - type: http
      namespace: snow-postmortem
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: problems
          path: "/table/problem"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-problem
              method: GET
    - type: http
      namespace: anthropic-pm
      baseUri: "https://api.anthropic.com/v1"
      authentication:
        type: apikey
        key: "x-api-key"
        value: "$secrets.anthropic_api_key"
        placement: header
      resources:
        - name: messages
          path: "/messages"
          operations:
            - name: generate-postmortem
              method: POST
    - type: http
      namespace: confluence-pm
      baseUri: "https://servicenow.atlassian.net/wiki/rest/api"
      authentication:
        type: bearer
        token: "$secrets.confluence_token"
      resources:
        - name: pages
          path: "/content"
          operations:
            - name: create-page
              method: POST

Retrieves a problem record by number, returning root cause, state, and related incident count.

naftiko: "0.5"
info:
  label: "ServiceNow Problem Record Lookup"
  description: "Retrieves a problem record by number, returning root cause, state, and related incident count."
  tags:
    - itsm
    - problem-management
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: snow-problem
      port: 8080
      tools:
        - name: get-problem
          description: "Given a problem number, return the root cause, current state, priority, and number of related incidents."
          inputParameters:
            - name: problem_number
              in: body
              type: string
              description: "ServiceNow problem number, e.g. PRB0012345."
          call: "servicenow.get-problem"
          with:
            number: "{{problem_number}}"
          outputParameters:
            - name: sys_id
              type: string
              mapping: "$.result[0].sys_id"
            - name: root_cause
              type: string
              mapping: "$.result[0].cause_notes"
            - name: state
              type: string
              mapping: "$.result[0].state.display_value"
            - name: priority
              type: string
              mapping: "$.result[0].priority.display_value"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: problems
          path: "/table/problem"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-problem
              method: GET

Coordinates a release by creating a release record, linking associated change requests, and notifying stakeholders via Slack and Microsoft Teams.

naftiko: "0.5"
info:
  label: "ServiceNow Release Management Orchestrator"
  description: "Coordinates a release by creating a release record, linking associated change requests, and notifying stakeholders via Slack and Microsoft Teams."
  tags:
    - itsm
    - release-management
    - servicenow
    - slack
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: release-mgmt
      port: 8080
      tools:
        - name: orchestrate-release
          description: "Given a release name and linked change numbers, create the release record, associate changes, and broadcast to stakeholders."
          inputParameters:
            - name: release_name
              in: body
              type: string
              description: "Name of the release."
            - name: change_numbers
              in: body
              type: string
              description: "Comma-separated list of change request numbers."
            - name: release_date
              in: body
              type: string
              description: "Planned release date."
          steps:
            - name: create-release
              type: call
              call: "servicenow.create-release"
              with:
                short_description: "{{release_name}}"
                planned_start_date: "{{release_date}}"
                description: "Changes included: {{change_numbers}}"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "release-management"
                text: "Release planned: {{release_name}} on {{release_date}} | Changes: {{change_numbers}} | Tracking: {{create-release.number}}"
            - name: notify-teams
              type: call
              call: "teams.post-message"
              with:
                channel_id: "$secrets.teams_release_channel_id"
                text: "Release {{create-release.number}}: {{release_name}} scheduled for {{release_date}}. Changes: {{change_numbers}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: releases
          path: "/table/rm_release"
          operations:
            - name: create-release
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST
    - type: http
      namespace: teams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.teams_token"
      resources:
        - name: channel-messages
          path: "/teams/$secrets.teams_team_id/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

Accepts a structured service request submitted via a Slack slash command, creates a ServiceNow request item, and confirms back to the requester in Slack.

naftiko: "0.5"
info:
  label: "ServiceNow Request Intake from Slack"
  description: "Accepts a structured service request submitted via a Slack slash command, creates a ServiceNow request item, and confirms back to the requester in Slack."
  tags:
    - itsm
    - service-catalog
    - servicenow
    - slack
    - automation
capability:
  exposes:
    - type: mcp
      namespace: slack-intake
      port: 8080
      tools:
        - name: submit-request-from-slack
          description: "Given a Slack user ID, request category, and description, create a ServiceNow service catalog request item and post a confirmation with the request number back to the Slack user."
          inputParameters:
            - name: slack_user_id
              in: body
              type: string
              description: "Slack user ID of the person submitting the request."
            - name: request_category
              in: body
              type: string
              description: "ServiceNow catalog item category, e.g. hardware, software, access."
            - name: request_description
              in: body
              type: string
              description: "Short description of what is being requested."
          steps:
            - name: create-request
              type: call
              call: "snow-request.create-request"
              with:
                short_description: "{{request_description}}"
                category: "{{request_category}}"
                opened_by: "{{slack_user_id}}"
            - name: confirm-slack
              type: call
              call: "slack-confirm.post-message"
              with:
                channel: "{{slack_user_id}}"
                text: "Your request has been submitted: {{create-request.number}}. Category: {{request_category}}. We'll update you as it progresses."
  consumes:
    - type: http
      namespace: snow-request
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: requests
          path: "/table/sc_request"
          operations:
            - name: create-request
              method: POST
    - type: http
      namespace: slack-confirm
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves the status of a service catalog request item by number, returning state, approvals, and estimated delivery date.

naftiko: "0.5"
info:
  label: "ServiceNow Request Item Status Lookup"
  description: "Retrieves the status of a service catalog request item by number, returning state, approvals, and estimated delivery date."
  tags:
    - itsm
    - service-catalog
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: snow-ritm
      port: 8080
      tools:
        - name: get-request-item-status
          description: "Given a request item number, return its current state, approval status, and estimated delivery date."
          inputParameters:
            - name: ritm_number
              in: body
              type: string
              description: "ServiceNow request item number, e.g. RITM0012345."
          call: "servicenow.get-ritm"
          with:
            number: "{{ritm_number}}"
          outputParameters:
            - name: state
              type: string
              mapping: "$.result[0].state.display_value"
            - name: approval
              type: string
              mapping: "$.result[0].approval.display_value"
            - name: due_date
              type: string
              mapping: "$.result[0].due_date"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: request-items
          path: "/table/sc_req_item"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-ritm
              method: GET

Generates a ServiceNow report on open incidents by priority, exports it, and distributes via email and Slack to leadership.

naftiko: "0.5"
info:
  label: "ServiceNow Scheduled Report Distribution"
  description: "Generates a ServiceNow report on open incidents by priority, exports it, and distributes via email and Slack to leadership."
  tags:
    - itsm
    - reporting
    - servicenow
    - slack
    - automation
capability:
  exposes:
    - type: mcp
      namespace: report-dist
      port: 8080
      tools:
        - name: distribute-incident-report
          description: "Generate an open incidents report, post summary to Slack, and email the full report to the distribution list."
          inputParameters:
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel for report summary."
          steps:
            - name: query-open-incidents
              type: call
              call: "servicenow.query-incidents"
              with:
                sysparm_query: "stateINnew,in_progress,on_hold"
            - name: post-summary
              type: call
              call: "slack.post-message"
              with:
                channel: "{{slack_channel}}"
                text: "Weekly Incident Report: {{query-open-incidents.result_count}} open incidents. P1: {{query-open-incidents.p1_count}} | P2: {{query-open-incidents.p2_count}} | P3: {{query-open-incidents.p3_count}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          inputParameters:
            - name: sysparm_query
              in: query
          operations:
            - name: query-incidents
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Upon security incident creation, disables the affected user account in Okta, quarantines the endpoint via CrowdStrike, and updates the security incident with containment actions.

naftiko: "0.5"
info:
  label: "ServiceNow Security Incident Containment"
  description: "Upon security incident creation, disables the affected user account in Okta, quarantines the endpoint via CrowdStrike, and updates the security incident with containment actions."
  tags:
    - itsm
    - security
    - servicenow
    - okta
    - crowdstrike
    - incident-response
capability:
  exposes:
    - type: mcp
      namespace: sec-containment
      port: 8080
      tools:
        - name: contain-security-incident
          description: "Given a security incident number, disable the affected user in Okta, contain the endpoint via CrowdStrike Falcon, and update the incident."
          inputParameters:
            - name: incident_number
              in: body
              type: string
              description: "ServiceNow security incident number."
          steps:
            - name: get-sec-incident
              type: call
              call: "servicenow.get-sec-incident"
              with:
                number: "{{incident_number}}"
            - name: disable-okta-user
              type: call
              call: "okta.suspend-user"
              with:
                user_id: "{{get-sec-incident.affected_user_email}}"
            - name: contain-endpoint
              type: call
              call: "crowdstrike.contain-host"
              with:
                hostname: "{{get-sec-incident.affected_host}}"
            - name: update-incident
              type: call
              call: "servicenow.update-sec-incident"
              with:
                sys_id: "{{get-sec-incident.sys_id}}"
                work_notes: "Containment actions: Okta account suspended, endpoint {{get-sec-incident.affected_host}} network-contained via CrowdStrike"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: security-incidents
          path: "/table/sn_si_incident"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-sec-incident
              method: GET
        - name: sec-incident-update
          path: "/table/sn_si_incident/{{sys_id}}"
          inputParameters:
            - name: sys_id
              in: path
          operations:
            - name: update-sec-incident
              method: PATCH
    - type: http
      namespace: okta
      baseUri: "https://servicenow.okta.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.okta_api_token"
      resources:
        - name: users
          path: "/users/{{user_id}}/lifecycle/suspend"
          inputParameters:
            - name: user_id
              in: path
          operations:
            - name: suspend-user
              method: POST
    - type: http
      namespace: crowdstrike
      baseUri: "https://api.crowdstrike.com"
      authentication:
        type: bearer
        token: "$secrets.falcon_oauth_token"
      resources:
        - name: hosts
          path: "/devices/entities/host-actions/v2"
          operations:
            - name: contain-host
              method: POST

Orchestrates server decommissioning by updating the CMDB status, revoking DNS entries, creating a change record, and notifying the infrastructure team.

naftiko: "0.5"
info:
  label: "ServiceNow Server Decommission Workflow"
  description: "Orchestrates server decommissioning by updating the CMDB status, revoking DNS entries, creating a change record, and notifying the infrastructure team."
  tags:
    - itsm
    - cmdb
    - servicenow
    - infrastructure
    - slack
capability:
  exposes:
    - type: mcp
      namespace: server-decommission
      port: 8080
      tools:
        - name: decommission-server
          description: "Given a CI name, update its CMDB status to retired, create a change record for tracking, and notify the infra team."
          inputParameters:
            - name: ci_name
              in: body
              type: string
              description: "Configuration item name of the server to decommission."
            - name: reason
              in: body
              type: string
              description: "Reason for decommissioning."
          steps:
            - name: get-ci
              type: call
              call: "servicenow.get-ci"
              with:
                name: "{{ci_name}}"
            - name: update-ci-status
              type: call
              call: "servicenow.update-ci"
              with:
                sys_id: "{{get-ci.sys_id}}"
                install_status: "retired"
            - name: create-change
              type: call
              call: "servicenow.create-change"
              with:
                short_description: "Server decommission: {{ci_name}}"
                description: "Reason: {{reason}}\nCI: {{ci_name}}\nClass: {{get-ci.sys_class_name}}"
                type: "standard"
            - name: notify-infra
              type: call
              call: "slack.post-message"
              with:
                channel: "infrastructure"
                text: "Server {{ci_name}} decommissioned. Change: {{create-change.number}} | Reason: {{reason}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: cmdb-items
          path: "/table/cmdb_ci"
          inputParameters:
            - name: name
              in: query
          operations:
            - name: get-ci
              method: GET
        - name: cmdb-update
          path: "/table/cmdb_ci/{{sys_id}}"
          inputParameters:
            - name: sys_id
              in: path
          operations:
            - name: update-ci
              method: PATCH
        - name: change-requests
          path: "/table/change_request"
          operations:
            - name: create-change
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Aggregates service health from ServiceNow and Datadog, compiles a unified dashboard digest, and posts to Slack.

naftiko: "0.5"
info:
  label: "ServiceNow Service Health Dashboard"
  description: "Aggregates service health from ServiceNow and Datadog, compiles a unified dashboard digest, and posts to Slack."
  tags:
    - itsm
    - observability
    - servicenow
    - datadog
    - slack
capability:
  exposes:
    - type: mcp
      namespace: svc-health
      port: 8080
      tools:
        - name: generate-health-dashboard
          description: "Aggregate open incidents per service from ServiceNow and Datadog monitor states, then post a unified health summary to Slack."
          inputParameters:
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel for the dashboard digest."
          steps:
            - name: get-snow-health
              type: call
              call: "servicenow.query-incidents"
              with:
                sysparm_query: "stateINnew,in_progress^priority<=2"
            - name: get-dd-monitors
              type: call
              call: "datadog.get-monitors"
              with:
                monitor_tags: "env:production"
            - name: post-dashboard
              type: call
              call: "slack.post-message"
              with:
                channel: "{{slack_channel}}"
                text: "Service Health Dashboard: SNOW P1/P2 incidents: {{get-snow-health.result_count}} | DD alerting monitors: {{get-dd-monitors.alert_count}} | Review: https://servicenow.service-now.com/dashboards"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          inputParameters:
            - name: sysparm_query
              in: query
          operations:
            - name: query-incidents
              method: GET
    - type: http
      namespace: datadog
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: monitors
          path: "/monitor"
          inputParameters:
            - name: monitor_tags
              in: query
          operations:
            - name: get-monitors
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves the service map for an application service, returning dependent CIs, hosting infrastructure, and connection details.

naftiko: "0.5"
info:
  label: "ServiceNow Service Map Lookup"
  description: "Retrieves the service map for an application service, returning dependent CIs, hosting infrastructure, and connection details."
  tags:
    - itsm
    - cmdb
    - servicenow
    - service-mapping
capability:
  exposes:
    - type: mcp
      namespace: snow-svcmap
      port: 8080
      tools:
        - name: get-service-map
          description: "Given an application service name, return the service map including dependent CIs and infrastructure details."
          inputParameters:
            - name: service_name
              in: body
              type: string
              description: "Name of the application service."
          call: "servicenow.get-service-map"
          with:
            name: "{{service_name}}"
          outputParameters:
            - name: sys_id
              type: string
              mapping: "$.result[0].sys_id"
            - name: ci_count
              type: string
              mapping: "$.result[0].ci_count"
            - name: hosting_server
              type: string
              mapping: "$.result[0].hosting_server.display_value"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: app-services
          path: "/table/cmdb_ci_service"
          inputParameters:
            - name: name
              in: query
          operations:
            - name: get-service-map
              method: GET

Queries ServiceNow for incidents that have breached their SLA in the past 24 hours and publishes the report to Power BI for leadership review.

naftiko: "0.5"
info:
  label: "ServiceNow SLA Breach Report"
  description: "Queries ServiceNow for incidents that have breached their SLA in the past 24 hours and publishes the report to Power BI for leadership review."
  tags:
    - itsm
    - reporting
    - servicenow
    - power-bi
    - sla
capability:
  exposes:
    - type: mcp
      namespace: sla-reporting
      port: 8080
      tools:
        - name: publish-sla-breach-report
          description: "Fetch all incidents that breached SLA in the past N hours from ServiceNow and push the list to a Power BI streaming dataset. Use for daily SLA reporting workflows."
          inputParameters:
            - name: hours_back
              in: body
              type: integer
              description: "Number of hours to look back for SLA breaches."
            - name: powerbi_dataset_id
              in: body
              type: string
              description: "Power BI dataset ID to push breach data to."
          steps:
            - name: get-breaches
              type: call
              call: "snow-sla.get-sla-breaches"
              with:
                hoursBack: "{{hours_back}}"
            - name: push-report
              type: call
              call: "powerbi.push-rows"
              with:
                datasetId: "{{powerbi_dataset_id}}"
                tableName: "SLABreaches"
                rows: "{{get-breaches.result}}"
  consumes:
    - type: http
      namespace: snow-sla
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: sla-breaches
          path: "/table/incident"
          inputParameters:
            - name: hoursBack
              in: query
          operations:
            - name: get-sla-breaches
              method: GET
    - type: http
      namespace: powerbi
      baseUri: "https://api.powerbi.com/v1.0/myorg"
      authentication:
        type: bearer
        token: "$secrets.powerbi_token"
      resources:
        - name: dataset-rows
          path: "/datasets/{{datasetId}}/tables/{{tableName}}/rows"
          inputParameters:
            - name: datasetId
              in: path
            - name: tableName
              in: path
          operations:
            - name: push-rows
              method: POST

Retrieves SLA definition details by name, returning target duration, schedule, and associated table.

naftiko: "0.5"
info:
  label: "ServiceNow SLA Definition Lookup"
  description: "Retrieves SLA definition details by name, returning target duration, schedule, and associated table."
  tags:
    - itsm
    - sla
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: snow-sla-def
      port: 8080
      tools:
        - name: get-sla-definition
          description: "Given an SLA definition name, return the target duration, schedule, and associated table."
          inputParameters:
            - name: sla_name
              in: body
              type: string
              description: "Name of the SLA definition."
          call: "servicenow.get-sla-def"
          with:
            name: "{{sla_name}}"
          outputParameters:
            - name: duration
              type: string
              mapping: "$.result[0].duration"
            - name: schedule
              type: string
              mapping: "$.result[0].schedule.display_value"
            - name: table
              type: string
              mapping: "$.result[0].collection"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: sla-definitions
          path: "/table/contract_sla"
          inputParameters:
            - name: name
              in: query
          operations:
            - name: get-sla-def
              method: GET

Detects incidents approaching SLA breach, escalates priority, creates a PagerDuty alert, and notifies the service owner via Slack.

naftiko: "0.5"
info:
  label: "ServiceNow SLA Violation Escalation"
  description: "Detects incidents approaching SLA breach, escalates priority, creates a PagerDuty alert, and notifies the service owner via Slack."
  tags:
    - itsm
    - sla
    - servicenow
    - pagerduty
    - slack
capability:
  exposes:
    - type: mcp
      namespace: sla-escalate
      port: 8080
      tools:
        - name: escalate-sla-violations
          description: "Query incidents approaching SLA breach, escalate them, page the on-call, and notify service owners."
          inputParameters:
            - name: breach_threshold_pct
              in: body
              type: string
              description: "Percentage of SLA elapsed to trigger escalation (e.g., 80)."
          steps:
            - name: query-at-risk
              type: call
              call: "servicenow.query-sla-at-risk"
              with:
                sysparm_query: "percentage>={{breach_threshold_pct}}^has_breached=false"
            - name: page-oncall
              type: call
              call: "pagerduty.create-incident"
              with:
                title: "SLA at risk: {{query-at-risk.result_count}} incidents approaching breach"
                service_id: "$secrets.pagerduty_service_id"
                urgency: "high"
            - name: notify-owners
              type: call
              call: "slack.post-message"
              with:
                channel: "service-owners"
                text: "SLA Escalation: {{query-at-risk.result_count}} incidents at >{{breach_threshold_pct}}% SLA. PagerDuty alert created. Immediate action required."
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: sla-tasks
          path: "/table/task_sla"
          inputParameters:
            - name: sysparm_query
              in: query
          operations:
            - name: query-sla-at-risk
              method: GET
    - type: http
      namespace: pagerduty
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.pagerduty_token"
        placement: header
      resources:
        - name: incidents
          path: "/incidents"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a Snowflake pipeline fails, creates a ServiceNow incident, correlates with affected downstream reports, and notifies the data engineering team.

naftiko: "0.5"
info:
  label: "ServiceNow Snowflake Data Incident Correlator"
  description: "When a Snowflake pipeline fails, creates a ServiceNow incident, correlates with affected downstream reports, and notifies the data engineering team."
  tags:
    - itsm
    - data-engineering
    - servicenow
    - snowflake
    - slack
capability:
  exposes:
    - type: mcp
      namespace: data-incident
      port: 8080
      tools:
        - name: create-data-incident
          description: "Given a Snowflake task failure, create a ServiceNow incident with pipeline context and alert the data team."
          inputParameters:
            - name: task_name
              in: body
              type: string
              description: "Snowflake task name that failed."
            - name: error_message
              in: body
              type: string
              description: "Error message from the failed task."
          steps:
            - name: create-incident
              type: call
              call: "servicenow.create-incident"
              with:
                short_description: "Snowflake pipeline failure: {{task_name}}"
                category: "data-platform"
                urgency: "2"
                description: "Task: {{task_name}}\nError: {{error_message}}"
            - name: notify-data-team
              type: call
              call: "slack.post-message"
              with:
                channel: "data-engineering"
                text: "Snowflake pipeline {{task_name}} failed. Incident: {{create-incident.number}} | Error: {{error_message}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves software installation records by product name, returning installed version, host, and compliance status.

naftiko: "0.5"
info:
  label: "ServiceNow Software Install Lookup"
  description: "Retrieves software installation records by product name, returning installed version, host, and compliance status."
  tags:
    - itsm
    - software-asset
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: snow-sw
      port: 8080
      tools:
        - name: get-software-installs
          description: "Given a software product name, return installations with version, host, and compliance status."
          inputParameters:
            - name: software_name
              in: body
              type: string
              description: "Software product name."
          call: "servicenow.get-installs"
          with:
            display_name: "{{software_name}}"
          outputParameters:
            - name: version
              type: string
              mapping: "$.result[0].version"
            - name: host
              type: string
              mapping: "$.result[0].installed_on.display_value"
            - name: install_date
              type: string
              mapping: "$.result[0].install_date"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: software-installs
          path: "/table/cmdb_sam_sw_install"
          inputParameters:
            - name: display_name
              in: query
          operations:
            - name: get-installs
              method: GET

Identifies incidents idle for more than 30 days, adds a reminder comment, and notifies assigned users via Slack to take action or close.

naftiko: "0.5"
info:
  label: "ServiceNow Stale Incident Cleanup"
  description: "Identifies incidents idle for more than 30 days, adds a reminder comment, and notifies assigned users via Slack to take action or close."
  tags:
    - itsm
    - incident-management
    - servicenow
    - slack
    - automation
capability:
  exposes:
    - type: mcp
      namespace: stale-cleanup
      port: 8080
      tools:
        - name: cleanup-stale-incidents
          description: "Query for incidents with no activity in a given number of days, add work notes, and notify assignees."
          inputParameters:
            - name: idle_days
              in: body
              type: string
              description: "Number of idle days to flag incidents."
          steps:
            - name: query-stale
              type: call
              call: "servicenow.query-incidents"
              with:
                sysparm_query: "stateINin_progress,on_hold^sys_updated_onRELATIVELT@day@ago@{{idle_days}}"
            - name: post-reminder
              type: call
              call: "slack.post-message"
              with:
                channel: "service-desk"
                text: "Stale Incident Alert: {{query-stale.result_count}} incidents idle for >{{idle_days}} days. Please update or close them."
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          inputParameters:
            - name: sysparm_query
              in: query
          operations:
            - name: query-incidents
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves storage volume details from the CMDB by name, returning capacity, usage, and associated server.

naftiko: "0.5"
info:
  label: "ServiceNow Storage Volume Lookup"
  description: "Retrieves storage volume details from the CMDB by name, returning capacity, usage, and associated server."
  tags:
    - itsm
    - cmdb
    - servicenow
    - storage
capability:
  exposes:
    - type: mcp
      namespace: snow-storage
      port: 8080
      tools:
        - name: get-storage-volume
          description: "Given a storage volume name, return its capacity, usage percentage, and associated server."
          inputParameters:
            - name: volume_name
              in: body
              type: string
              description: "Storage volume name."
          call: "servicenow.get-volume"
          with:
            name: "{{volume_name}}"
          outputParameters:
            - name: capacity_gb
              type: string
              mapping: "$.result[0].disk_space"
            - name: used_pct
              type: string
              mapping: "$.result[0].used_percent"
            - name: server
              type: string
              mapping: "$.result[0].computer.display_value"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: volumes
          path: "/table/cmdb_ci_storage_volume"
          inputParameters:
            - name: name
              in: query
          operations:
            - name: get-volume
              method: GET

Retrieves a generic task record by number, returning state, assigned to, and due date.

naftiko: "0.5"
info:
  label: "ServiceNow Task Record Lookup"
  description: "Retrieves a generic task record by number, returning state, assigned to, and due date."
  tags:
    - itsm
    - task-management
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: snow-task
      port: 8080
      tools:
        - name: get-task
          description: "Given a task number, return the task state, assigned user, priority, and due date."
          inputParameters:
            - name: task_number
              in: body
              type: string
              description: "ServiceNow task number."
          call: "servicenow.get-task"
          with:
            number: "{{task_number}}"
          outputParameters:
            - name: state
              type: string
              mapping: "$.result[0].state.display_value"
            - name: assigned_to
              type: string
              mapping: "$.result[0].assigned_to.display_value"
            - name: priority
              type: string
              mapping: "$.result[0].priority.display_value"
            - name: due_date
              type: string
              mapping: "$.result[0].due_date"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: tasks
          path: "/table/task"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-task
              method: GET

Retrieves a ServiceNow user record by user ID, returning name, email, department, and active status.

naftiko: "0.5"
info:
  label: "ServiceNow User Record Lookup"
  description: "Retrieves a ServiceNow user record by user ID, returning name, email, department, and active status."
  tags:
    - itsm
    - user-management
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: snow-user
      port: 8080
      tools:
        - name: get-user
          description: "Given a ServiceNow user ID, return the user's full name, email, department, and whether the account is active."
          inputParameters:
            - name: user_id
              in: body
              type: string
              description: "ServiceNow user_name or sys_id."
          call: "servicenow.get-user"
          with:
            user_name: "{{user_id}}"
          outputParameters:
            - name: full_name
              type: string
              mapping: "$.result[0].name"
            - name: email
              type: string
              mapping: "$.result[0].email"
            - name: department
              type: string
              mapping: "$.result[0].department.display_value"
            - name: active
              type: string
              mapping: "$.result[0].active"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: users
          path: "/table/sys_user"
          inputParameters:
            - name: user_name
              in: query
          operations:
            - name: get-user
              method: GET

Queries ServiceNow for vendor contracts expiring within a specified window, creates renewal tasks, and alerts procurement via Slack.

naftiko: "0.5"
info:
  label: "ServiceNow Vendor Contract Expiry Alert"
  description: "Queries ServiceNow for vendor contracts expiring within a specified window, creates renewal tasks, and alerts procurement via Slack."
  tags:
    - itsm
    - vendor-management
    - servicenow
    - slack
    - procurement
capability:
  exposes:
    - type: mcp
      namespace: contract-expiry
      port: 8080
      tools:
        - name: alert-expiring-contracts
          description: "Query for vendor contracts expiring within a given number of days, create renewal tasks, and notify procurement."
          inputParameters:
            - name: days_until_expiry
              in: body
              type: string
              description: "Number of days before expiry to flag contracts."
          steps:
            - name: query-expiring-contracts
              type: call
              call: "servicenow.query-contracts"
              with:
                sysparm_query: "endsRELATIVELT@dayofweek@ahead@{{days_until_expiry}}"
            - name: create-renewal-task
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "Contract renewal: {{query-expiring-contracts.result_count}} contracts expiring within {{days_until_expiry}} days"
                assignment_group: "procurement"
            - name: notify-procurement
              type: call
              call: "slack.post-message"
              with:
                channel: "procurement"
                text: "Contract Expiry Alert: {{query-expiring-contracts.result_count}} vendor contracts expiring within {{days_until_expiry}} days. Renewal task: {{create-renewal-task.number}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: contracts
          path: "/table/ast_contract"
          inputParameters:
            - name: sysparm_query
              in: query
          operations:
            - name: query-contracts
              method: GET
        - name: tasks
          path: "/table/task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When the ServiceNow Virtual Agent cannot resolve a user query, creates an incident with conversation context and routes to a live agent via Slack.

naftiko: "0.5"
info:
  label: "ServiceNow Virtual Agent Conversation Handoff"
  description: "When the ServiceNow Virtual Agent cannot resolve a user query, creates an incident with conversation context and routes to a live agent via Slack."
  tags:
    - itsm
    - virtual-agent
    - servicenow
    - slack
    - customer-service
capability:
  exposes:
    - type: mcp
      namespace: va-handoff
      port: 8080
      tools:
        - name: handoff-to-live-agent
          description: "Given a conversation ID and user query, create an incident with conversation context and notify the support team via Slack for live agent handoff."
          inputParameters:
            - name: conversation_id
              in: body
              type: string
              description: "Virtual Agent conversation ID."
            - name: user_query
              in: body
              type: string
              description: "The user's unresolved query."
            - name: caller_id
              in: body
              type: string
              description: "ServiceNow sys_id of the calling user."
          steps:
            - name: create-incident
              type: call
              call: "servicenow.create-incident"
              with:
                short_description: "VA Handoff: {{user_query}}"
                caller_id: "{{caller_id}}"
                description: "Virtual Agent conversation {{conversation_id}} could not resolve: {{user_query}}"
                category: "inquiry"
            - name: notify-support
              type: call
              call: "slack.post-message"
              with:
                channel: "live-support"
                text: "Live agent needed: {{create-incident.number}} — {{user_query}} | Conversation: {{conversation_id}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Processes a VPN access request, verifies user identity in Okta, provisions VPN profile, closes the ServiceNow request, and notifies the user.

naftiko: "0.5"
info:
  label: "ServiceNow VPN Access Request Workflow"
  description: "Processes a VPN access request, verifies user identity in Okta, provisions VPN profile, closes the ServiceNow request, and notifies the user."
  tags:
    - itsm
    - access-management
    - servicenow
    - okta
    - slack
capability:
  exposes:
    - type: mcp
      namespace: vpn-access
      port: 8080
      tools:
        - name: process-vpn-request
          description: "Given a request item number, verify the user in Okta, provision VPN access, close the request, and notify via Slack."
          inputParameters:
            - name: ritm_number
              in: body
              type: string
              description: "ServiceNow request item number."
          steps:
            - name: get-request
              type: call
              call: "servicenow.get-ritm"
              with:
                number: "{{ritm_number}}"
            - name: verify-user
              type: call
              call: "okta.get-user"
              with:
                id: "{{get-request.requested_for_email}}"
            - name: close-request
              type: call
              call: "servicenow.update-ritm"
              with:
                sys_id: "{{get-request.sys_id}}"
                state: "closed_complete"
                close_notes: "VPN access provisioned for {{verify-user.profile.email}}"
            - name: notify-user
              type: call
              call: "slack.post-message"
              with:
                channel: "{{get-request.requested_for_slack_id}}"
                text: "Your VPN access request {{ritm_number}} has been fulfilled. Follow setup instructions at https://wiki.servicenow.com/vpn-setup"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: request-items
          path: "/table/sc_req_item"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-ritm
              method: GET
        - name: ritm-update
          path: "/table/sc_req_item/{{sys_id}}"
          inputParameters:
            - name: sys_id
              in: path
          operations:
            - name: update-ritm
              method: PATCH
    - type: http
      namespace: okta
      baseUri: "https://servicenow.okta.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.okta_api_token"
      resources:
        - name: users
          path: "/users/{{id}}"
          inputParameters:
            - name: id
              in: path
          operations:
            - name: get-user
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Takes a security vulnerability finding, creates a change request for remediation, assigns it to the owning team, and notifies the security operations channel.

naftiko: "0.5"
info:
  label: "ServiceNow Vulnerability to Change Request"
  description: "Takes a security vulnerability finding, creates a change request for remediation, assigns it to the owning team, and notifies the security operations channel."
  tags:
    - itsm
    - security
    - servicenow
    - change-management
    - slack
capability:
  exposes:
    - type: mcp
      namespace: vuln-to-change
      port: 8080
      tools:
        - name: create-change-from-vulnerability
          description: "Given a vulnerability record sys_id, create a change request for remediation and notify the security ops team."
          inputParameters:
            - name: vuln_sys_id
              in: body
              type: string
              description: "ServiceNow vulnerability record sys_id."
          steps:
            - name: get-vulnerability
              type: call
              call: "servicenow.get-vulnerability"
              with:
                sys_id: "{{vuln_sys_id}}"
            - name: create-change
              type: call
              call: "servicenow.create-change"
              with:
                short_description: "Remediate: {{get-vulnerability.cve_id}} on {{get-vulnerability.host}}"
                type: "standard"
                risk: "{{get-vulnerability.severity}}"
                description: "CVE: {{get-vulnerability.cve_id}}\nCVSS: {{get-vulnerability.cvss_score}}\nHost: {{get-vulnerability.host}}"
            - name: notify-secops
              type: call
              call: "slack.post-message"
              with:
                channel: "secops"
                text: "Change request {{create-change.number}} created for {{get-vulnerability.cve_id}} remediation on {{get-vulnerability.host}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: vulnerabilities
          path: "/table/sn_vul_vulnerability/{{sys_id}}"
          inputParameters:
            - name: sys_id
              in: path
          operations:
            - name: get-vulnerability
              method: GET
        - name: change-requests
          path: "/table/change_request"
          operations:
            - name: create-change
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When an employee is terminated in Workday, disables their Okta account, revokes ServiceNow access, and creates an audit trail task.

naftiko: "0.5"
info:
  label: "ServiceNow Workday Termination to Access Revoke"
  description: "When an employee is terminated in Workday, disables their Okta account, revokes ServiceNow access, and creates an audit trail task."
  tags:
    - itsm
    - offboarding
    - servicenow
    - workday
    - okta
    - slack
capability:
  exposes:
    - type: mcp
      namespace: term-revoke
      port: 8080
      tools:
        - name: revoke-terminated-access
          description: "Given a Workday worker ID for a terminated employee, disable Okta account, deactivate ServiceNow user, and create an audit task."
          inputParameters:
            - name: worker_id
              in: body
              type: string
              description: "Workday worker ID of the terminated employee."
          steps:
            - name: get-worker
              type: call
              call: "workday.get-worker"
              with:
                worker_id: "{{worker_id}}"
            - name: disable-okta
              type: call
              call: "okta.deactivate-user"
              with:
                user_id: "{{get-worker.email}}"
            - name: deactivate-snow-user
              type: call
              call: "servicenow.update-user"
              with:
                user_name: "{{get-worker.email}}"
                active: "false"
            - name: create-audit-task
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "Termination access revocation: {{get-worker.full_name}}"
                assignment_group: "identity-governance"
                description: "Employee: {{get-worker.full_name}} | Okta: disabled | ServiceNow: deactivated"
            - name: notify-security
              type: call
              call: "slack.post-message"
              with:
                channel: "secops"
                text: "Termination processed: {{get-worker.full_name}} — Okta disabled, SNOW deactivated. Audit task: {{create-audit-task.number}}"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/servicenow/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: okta
      baseUri: "https://servicenow.okta.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.okta_api_token"
      resources:
        - name: users
          path: "/users/{{user_id}}/lifecycle/deactivate"
          inputParameters:
            - name: user_id
              in: path
          operations:
            - name: deactivate-user
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: users
          path: "/table/sys_user"
          inputParameters:
            - name: user_name
              in: query
          operations:
            - name: update-user
              method: PATCH
        - name: tasks
          path: "/table/task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Exports current active employee headcount from Workday and pushes the structured data to a ServiceNow HR module table for workforce visibility.

naftiko: "0.5"
info:
  label: "ServiceNow Workforce Headcount Sync"
  description: "Exports current active employee headcount from Workday and pushes the structured data to a ServiceNow HR module table for workforce visibility."
  tags:
    - hr
    - reporting
    - workday
    - servicenow
    - workforce-planning
capability:
  exposes:
    - type: mcp
      namespace: workforce-sync
      port: 8080
      tools:
        - name: sync-headcount-to-snow
          description: "Export active worker records from Workday and upsert them into the ServiceNow HR employee table for cross-platform headcount visibility."
          inputParameters:
            - name: workday_org_id
              in: body
              type: string
              description: "Workday organization ID to export headcount for."
          steps:
            - name: get-workers
              type: call
              call: "workday-wf.get-workers"
              with:
                orgId: "{{workday_org_id}}"
            - name: upsert-snow-hr
              type: call
              call: "snow-hr.upsert-employee"
              with:
                employees: "{{get-workers.workers}}"
  consumes:
    - type: http
      namespace: workday-wf
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/workers"
          inputParameters:
            - name: orgId
              in: query
          operations:
            - name: get-workers
              method: GET
    - type: http
      namespace: snow-hr
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: hr-employees
          path: "/table/sn_hr_core_employee"
          operations:
            - name: upsert-employee
              method: POST

Retrieves workspace allocation details from ServiceNow facilities management by floor or building.

naftiko: "0.5"
info:
  label: "ServiceNow Workspace Lookup"
  description: "Retrieves workspace allocation details from ServiceNow facilities management by floor or building."
  tags:
    - itsm
    - facilities-management
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: snow-workspace
      port: 8080
      tools:
        - name: get-workspace
          description: "Given a building or floor identifier, return workspace allocation details including capacity and occupancy."
          inputParameters:
            - name: building
              in: body
              type: string
              description: "Building name or identifier."
          call: "servicenow.get-workspace"
          with:
            building: "{{building}}"
          outputParameters:
            - name: total_capacity
              type: string
              mapping: "$.result[0].capacity"
            - name: occupied
              type: string
              mapping: "$.result[0].occupied_count"
            - name: available
              type: string
              mapping: "$.result[0].available_count"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: workspaces
          path: "/table/fm_space"
          inputParameters:
            - name: building
              in: query
          operations:
            - name: get-workspace
              method: GET

Monitors Snowflake data pipeline quality metrics and creates a ServiceNow incident when row counts or freshness thresholds are violated.

naftiko: "0.5"
info:
  label: "Snowflake Data Quality Alert to ServiceNow"
  description: "Monitors Snowflake data pipeline quality metrics and creates a ServiceNow incident when row counts or freshness thresholds are violated."
  tags:
    - data
    - analytics
    - snowflake
    - servicenow
    - monitoring
    - data-quality
capability:
  exposes:
    - type: mcp
      namespace: data-quality-ops
      port: 8080
      tools:
        - name: monitor-data-quality
          description: "Execute a Snowflake data quality check query and, if thresholds are violated, create a ServiceNow incident and alert the data engineering team in Slack."
          inputParameters:
            - name: quality_check_query
              in: body
              type: string
              description: "Snowflake SQL query that returns a quality_score indicating data health."
            - name: threshold
              in: body
              type: number
              description: "Minimum acceptable quality score. Below this triggers an incident."
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel for data quality alerts."
          steps:
            - name: run-quality-check
              type: call
              call: "snowflake-dq.execute-query"
              with:
                statement: "{{quality_check_query}}"
            - name: create-incident
              type: call
              call: "snow-dq.create-incident"
              with:
                short_description: "Data quality below threshold: score {{run-quality-check.quality_score}}"
                urgency: "2"
                description: "Quality score: {{run-quality-check.quality_score}} (threshold: {{threshold}})\nFailing tables: {{run-quality-check.failing_tables}}"
            - name: alert-data-team
              type: call
              call: "slack-dq.post-message"
              with:
                channel: "{{slack_channel}}"
                text: "Data quality alert: score {{run-quality-check.quality_score}} below threshold {{threshold}} | Incident: {{create-incident.number}}"
  consumes:
    - type: http
      namespace: snowflake-dq
      baseUri: "https://servicenow.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: queries
          path: "/statements"
          operations:
            - name: execute-query
              method: POST
    - type: http
      namespace: snow-dq
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: slack-dq
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When Terraform Cloud detects configuration drift, creates a ServiceNow incident for infrastructure remediation and alerts the cloud ops team via Slack.

naftiko: "0.5"
info:
  label: "Terraform Drift to ServiceNow Incident"
  description: "When Terraform Cloud detects configuration drift, creates a ServiceNow incident for infrastructure remediation and alerts the cloud ops team via Slack."
  tags:
    - itsm
    - infrastructure
    - servicenow
    - terraform
    - slack
capability:
  exposes:
    - type: mcp
      namespace: tf-drift-incident
      port: 8080
      tools:
        - name: create-drift-incident
          description: "Given Terraform workspace details and drift summary, create a ServiceNow incident and notify cloud ops."
          inputParameters:
            - name: workspace_name
              in: body
              type: string
              description: "Terraform Cloud workspace name."
            - name: drift_summary
              in: body
              type: string
              description: "Summary of detected configuration drift."
          steps:
            - name: create-incident
              type: call
              call: "servicenow.create-incident"
              with:
                short_description: "Terraform drift: {{workspace_name}}"
                category: "infrastructure"
                urgency: "2"
                description: "Configuration drift detected in workspace {{workspace_name}}:\n{{drift_summary}}"
            - name: notify-cloud-ops
              type: call
              call: "slack.post-message"
              with:
                channel: "cloud-ops"
                text: "Terraform Drift Detected: {{workspace_name}} | Incident: {{create-incident.number}} | {{drift_summary}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When an employee termination is recorded in Workday, creates a ServiceNow offboarding task, revokes their Okta access, and confirms via Slack.

naftiko: "0.5"
info:
  label: "Workday Offboarding to ServiceNow Access Revocation"
  description: "When an employee termination is recorded in Workday, creates a ServiceNow offboarding task, revokes their Okta access, and confirms via Slack."
  tags:
    - hr
    - offboarding
    - workday
    - servicenow
    - okta
    - slack
    - identity
capability:
  exposes:
    - type: mcp
      namespace: offboarding-hr
      port: 8080
      tools:
        - name: trigger-offboarding
          description: "Given a Workday employee ID and their Okta user ID, confirm termination in Workday, create a ServiceNow offboarding task, deactivate Okta, and post a confirmation to Slack."
          inputParameters:
            - name: workday_employee_id
              in: body
              type: string
              description: "Workday worker ID for the departing employee."
            - name: okta_user_id
              in: body
              type: string
              description: "Okta user ID to deactivate."
            - name: hr_slack_channel
              in: body
              type: string
              description: "Slack channel for HR offboarding confirmation."
          steps:
            - name: get-employee
              type: call
              call: "workday-off.get-worker"
              with:
                workerId: "{{workday_employee_id}}"
            - name: create-offboarding-task
              type: call
              call: "snow-off.create-ticket"
              with:
                short_description: "Employee offboarding: {{get-employee.displayName}}"
                category: "hr_offboarding"
                assignment_group: "IT_Offboarding"
            - name: deactivate-okta
              type: call
              call: "okta.deactivate-user"
              with:
                userId: "{{okta_user_id}}"
            - name: confirm-slack
              type: call
              call: "slack-hr.post-message"
              with:
                channel: "{{hr_slack_channel}}"
                text: "Offboarding initiated for {{get-employee.displayName}}. ServiceNow task: {{create-offboarding-task.number}}. Okta access revoked."
  consumes:
    - type: http
      namespace: workday-off
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/workers/{{workerId}}"
          inputParameters:
            - name: workerId
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: snow-off
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-ticket
              method: POST
    - type: http
      namespace: okta
      baseUri: "https://servicenow.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_token"
        placement: header
      resources:
        - name: user-lifecycle
          path: "/users/{{userId}}/lifecycle/deactivate"
          inputParameters:
            - name: userId
              in: path
          operations:
            - name: deactivate-user
              method: POST
    - type: http
      namespace: slack-hr
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a Zoom meeting recording is processed, fetches the transcript, summarizes it with Anthropic Claude, and creates a ServiceNow knowledge article.

naftiko: "0.5"
info:
  label: "Zoom Meeting Recording to ServiceNow Knowledge"
  description: "When a Zoom meeting recording is processed, fetches the transcript, summarizes it with Anthropic Claude, and creates a ServiceNow knowledge article."
  tags:
    - knowledge-management
    - ai
    - zoom
    - servicenow
    - anthropic
capability:
  exposes:
    - type: mcp
      namespace: meeting-knowledge
      port: 8080
      tools:
        - name: capture-meeting-knowledge
          description: "Given a Zoom meeting ID, download the recording transcript, generate a structured meeting summary with Anthropic Claude, and publish it as a ServiceNow knowledge article."
          inputParameters:
            - name: zoom_meeting_id
              in: body
              type: string
              description: "Zoom meeting ID with an available recording transcript."
            - name: snow_kb_category
              in: body
              type: string
              description: "ServiceNow knowledge base category sys_id for the article."
          steps:
            - name: get-recording
              type: call
              call: "zoom-rec.get-recording"
              with:
                meetingId: "{{zoom_meeting_id}}"
            - name: summarize-transcript
              type: call
              call: "anthropic-zoom.summarize-transcript"
              with:
                transcript: "{{get-recording.transcript}}"
                meetingTopic: "{{get-recording.topic}}"
            - name: create-kb-article
              type: call
              call: "snow-zoom.create-article"
              with:
                short_description: "Meeting Summary: {{get-recording.topic}}"
                text: "{{summarize-transcript.summary}}"
                kb_category: "{{snow_kb_category}}"
                workflow_state: "review"
  consumes:
    - type: http
      namespace: zoom-rec
      baseUri: "https://api.zoom.us/v2"
      authentication:
        type: bearer
        token: "$secrets.zoom_token"
      resources:
        - name: recordings
          path: "/meetings/{{meetingId}}/recordings"
          inputParameters:
            - name: meetingId
              in: path
          operations:
            - name: get-recording
              method: GET
    - type: http
      namespace: anthropic-zoom
      baseUri: "https://api.anthropic.com/v1"
      authentication:
        type: apikey
        key: "x-api-key"
        value: "$secrets.anthropic_api_key"
        placement: header
      resources:
        - name: messages
          path: "/messages"
          operations:
            - name: summarize-transcript
              method: POST
    - type: http
      namespace: snow-zoom
      baseUri: "https://servicenow.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: knowledge-articles
          path: "/table/kb_knowledge"
          operations:
            - name: create-article
              method: POST