Johnson Controls Capabilities

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

Sort
Expand

Uses Anthropic Claude to analyze building fault patterns from Snowflake and posts diagnosis to engineering team.

naftiko: "0.5"
info:
  label: "AI-Assisted Building Fault Diagnosis"
  description: "Uses Anthropic Claude to analyze building fault patterns from Snowflake and posts diagnosis to engineering team."
  tags:
    - building-automation
    - anthropic
    - snowflake
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: ai_assisted_building_fault_diagnosis
          description: "Uses Anthropic Claude to analyze building fault patterns from Snowflake and posts diagnosis to engineering team."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "AI-Assisted Building Fault Diagnosis: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "AI-Assisted Building Fault Diagnosis for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

When a new ServiceNow incident is created, sends the description to Anthropic Claude for intelligent classification and priority recommendation, then updates the incident with the AI-suggested category.

naftiko: "0.5"
info:
  label: "Anthropic-Powered Service Desk Triage"
  description: "When a new ServiceNow incident is created, sends the description to Anthropic Claude for intelligent classification and priority recommendation, then updates the incident with the AI-suggested category."
  tags:
    - ai
    - itsm
    - servicenow
    - anthropic
    - automation
    - incident-response
capability:
  exposes:
    - type: mcp
      namespace: ai-triage
      port: 8080
      tools:
        - name: triage-incident-with-ai
          description: "Given a ServiceNow incident ID and description, classify the incident using Anthropic Claude and update the incident with the recommended category and priority."
          inputParameters:
            - name: incident_id
              in: body
              type: string
              description: "The ServiceNow incident sys_id to triage."
            - name: incident_description
              in: body
              type: string
              description: "The full incident description text to classify."
          steps:
            - name: classify-incident
              type: call
              call: "anthropic.create-message"
              with:
                model: "claude-3-5-sonnet-20241022"
                prompt: "Classify this Johnson Controls IT incident and recommend a category (HVAC, BAS, Network, Software, Hardware, Facilities) and priority (1-4): {{incident_description}}"
            - name: update-incident
              type: call
              call: "servicenow.update-incident"
              with:
                incident_id: "{{incident_id}}"
                ai_classification: "{{classify-incident.content}}"
  consumes:
    - 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: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident/{{incident_id}}"
          inputParameters:
            - name: incident_id
              in: path
          operations:
            - name: update-incident
              method: PATCH

When Azure spend exceeds a budget threshold, creates a ServiceNow FinOps task and notifies the cloud infrastructure team via Microsoft Teams.

naftiko: "0.5"
info:
  label: "Azure Cloud Cost Anomaly Responder"
  description: "When Azure spend exceeds a budget threshold, creates a ServiceNow FinOps task and notifies the cloud infrastructure team via Microsoft Teams."
  tags:
    - cloud
    - finops
    - azure
    - servicenow
    - microsoft-teams
    - cost-management
capability:
  exposes:
    - type: mcp
      namespace: cloud-finops
      port: 8080
      tools:
        - name: respond-to-azure-cost-anomaly
          description: "Given an Azure cost anomaly alert (subscription, service, overage amount), create a ServiceNow FinOps review task and alert the cloud team in Microsoft Teams."
          inputParameters:
            - name: subscription_id
              in: body
              type: string
              description: "The Azure subscription ID with the cost anomaly."
            - name: service_name
              in: body
              type: string
              description: "The Azure service responsible for the anomaly."
            - name: anomaly_amount
              in: body
              type: number
              description: "The overage amount in USD."
          steps:
            - name: create-finops-task
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "Azure cost anomaly: {{service_name}} — ${{anomaly_amount}} overage in {{subscription_id}}"
                category: "finops"
                assigned_group: "Cloud_FinOps"
            - name: notify-cloud-team
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_cloud_channel_id"
                text: "Azure Cost Alert: Subscription {{subscription_id}} | Service: {{service_name}} | Overage: ${{anomaly_amount}} | Task: {{create-finops-task.number}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Provisions new IoT devices in Azure IoT Hub, registers in ServiceNow CMDB, and notifies IoT platform team.

naftiko: "0.5"
info:
  label: "Azure IoT Hub Device Provisioning"
  description: "Provisions new IoT devices in Azure IoT Hub, registers in ServiceNow CMDB, and notifies IoT platform team."
  tags:
    - iot
    - azure
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: azure_iot_hub_device_provisioning
          description: "Provisions new IoT devices in Azure IoT Hub, registers in ServiceNow CMDB, and notifies IoT platform team."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Azure IoT Hub Device Provisioning: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Azure IoT Hub Device Provisioning for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Triggers a rolling AKS deployment for a building automation microservice, monitors error rate during rollout via Datadog, and reports completion to the platform engineering Teams channel.

naftiko: "0.5"
info:
  label: "Azure Kubernetes Deployment Rollout"
  description: "Triggers a rolling AKS deployment for a building automation microservice, monitors error rate during rollout via Datadog, and reports completion to the platform engineering Teams channel."
  tags:
    - devops
    - cloud
    - kubernetes
    - azure
    - datadog
    - microsoft-teams
    - deployment
capability:
  exposes:
    - type: mcp
      namespace: platform-engineering
      port: 8080
      tools:
        - name: deploy-aks-workload
          description: "Given an AKS cluster name, namespace, deployment name, and image tag, trigger a rolling update, monitor error rates in Datadog, and report completion to the platform Teams channel."
          inputParameters:
            - name: cluster_name
              in: body
              type: string
              description: "The Azure Kubernetes Service cluster name."
            - name: namespace
              in: body
              type: string
              description: "The Kubernetes namespace for the deployment."
            - name: deployment_name
              in: body
              type: string
              description: "The name of the Kubernetes deployment to update."
            - name: image_tag
              in: body
              type: string
              description: "The new container image tag to deploy."
          steps:
            - name: trigger-deployment
              type: call
              call: "aks.update-deployment"
              with:
                cluster_name: "{{cluster_name}}"
                namespace: "{{namespace}}"
                deployment_name: "{{deployment_name}}"
                image_tag: "{{image_tag}}"
            - name: check-error-rate
              type: call
              call: "datadog.query-metrics"
              with:
                query: "avg:trace.error.rate{service:{{deployment_name}}}"
            - name: notify-platform-team
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_platform_channel_id"
                text: "Deployment complete: {{deployment_name}} → {{image_tag}} on {{cluster_name}}/{{namespace}} | Error rate: {{check-error-rate.value}}"
  consumes:
    - type: http
      namespace: aks
      baseUri: "https://management.azure.com"
      authentication:
        type: bearer
        token: "$secrets.azure_mgmt_token"
      resources:
        - name: deployments
          path: "/subscriptions/{{subscription_id}}/resourceGroups/{{resource_group}}/providers/Microsoft.ContainerService/managedClusters/{{cluster_name}}/agentPools"
          inputParameters:
            - name: subscription_id
              in: path
            - name: resource_group
              in: path
            - name: cluster_name
              in: path
          operations:
            - name: update-deployment
              method: PUT
    - 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: metrics
          path: "/query"
          operations:
            - name: query-metrics
              method: GET
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Retrieves cost data for a specific Azure resource group, returning current month spend.

naftiko: "0.5"
info:
  label: "Azure Resource Cost Lookup"
  description: "Retrieves cost data for a specific Azure resource group, returning current month spend."
  tags:
    - cloud
    - azure
    - finops
capability:
  exposes:
    - type: mcp
      namespace: cloud-cost
      port: 8080
      tools:
        - name: get-resource-cost
          description: "Look up Azure resource group costs."
          inputParameters:
            - name: resource_group
              type: string
              description: "Azure resource group name."
          call: azure.get-cost
          with:
            resource_group: "{{resource_group}}"
          outputParameters:
            - name: current_spend
              type: string
              mapping: "$.properties.rows[0][0]"
  consumes:
    - type: http
      namespace: azure
      baseUri: "https://management.azure.com"
      authentication:
        type: bearer
        token: "$secrets.azure_token"
      resources:
        - name: cost-management
          path: "/subscriptions/$secrets.azure_subscription_id/resourceGroups/{{resource_group}}/providers/Microsoft.CostManagement/query"
          inputParameters:
            - name: resource_group
              in: path
          operations:
            - name: get-cost
              method: POST

When an access control anomaly is detected, queries Okta for user context, creates a ServiceNow security incident, and alerts security operations.

naftiko: "0.5"
info:
  label: "Building Access Control Anomaly"
  description: "When an access control anomaly is detected, queries Okta for user context, creates a ServiceNow security incident, and alerts security operations."
  tags:
    - security
    - access-control
    - okta
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: physical-security
      port: 8080
      tools:
        - name: handle-access-anomaly
          description: "Given an access anomaly, verify user identity and create security incident."
          inputParameters:
            - name: building_id
              type: string
              description: "Building identifier."
            - name: badge_id
              type: string
              description: "Badge or credential ID."
            - name: event_type
              type: string
              description: "Event type (tailgating, forced_entry, invalid_credential)."
            - name: user_email
              type: string
              description: "Associated user email."
          steps:
            - name: get-user-context
              type: call
              call: okta.get-user
              with:
                email: "{{user_email}}"
            - name: create-incident
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Access anomaly: {{event_type}} at building {{building_id}}"
                category: "security"
                urgency: "2"
            - name: alert-security
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_security_ops_channel"
                text: "Access anomaly: {{event_type}} at {{building_id}} | Badge: {{badge_id}} | User: {{user_email}} ({{get-user-context.status}}) | SNOW: {{create-incident.number}}"
  consumes:
    - type: http
      namespace: okta
      baseUri: "https://johnsoncontrols.okta.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.okta_api_token"
      resources:
        - name: users
          path: "/users/{{email}}"
          inputParameters:
            - name: email
              in: path
          operations:
            - name: get-user
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/security-ops/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Coordinates BMS firmware updates with ServiceNow change requests, maintenance windows, and building team notification.

naftiko: "0.5"
info:
  label: "Building BMS Firmware Update Workflow"
  description: "Coordinates BMS firmware updates with ServiceNow change requests, maintenance windows, and building team notification."
  tags:
    - building-automation
    - bms
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: building_bms_firmware_update_workflow
          description: "Coordinates BMS firmware updates with ServiceNow change requests, maintenance windows, and building team notification."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Building BMS Firmware Update Workflow: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Building BMS Firmware Update Workflow for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Pulls commissioning punch list items from Jira, validates completion, and posts status to project team.

naftiko: "0.5"
info:
  label: "Building Commissioning Punch List Tracking"
  description: "Pulls commissioning punch list items from Jira, validates completion, and posts status to project team."
  tags:
    - commissioning
    - jira
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: building_commissioning_punch_list_tracking
          description: "Pulls commissioning punch list items from Jira, validates completion, and posts status to project team."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Building Commissioning Punch List Tracking: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Building Commissioning Punch List Tracking for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

When a new building system is commissioned, retrieves commissioning test results from ServiceNow, validates completeness, and posts the commissioning sign-off summary to the project team via Microsoft Teams.

naftiko: "0.5"
info:
  label: "Building Commissioning Quality Check"
  description: "When a new building system is commissioned, retrieves commissioning test results from ServiceNow, validates completeness, and posts the commissioning sign-off summary to the project team via Microsoft Teams."
  tags:
    - field-service
    - quality
    - servicenow
    - microsoft-teams
    - building-automation
    - commissioning
capability:
  exposes:
    - type: mcp
      namespace: commissioning-ops
      port: 8080
      tools:
        - name: validate-commissioning-results
          description: "Given a ServiceNow commissioning project number, retrieve all test results and system checks, validate completeness, and post the commissioning sign-off summary to the project Teams channel."
          inputParameters:
            - name: project_number
              in: body
              type: string
              description: "The ServiceNow project number for the building commissioning work."
            - name: building_id
              in: body
              type: string
              description: "The building or site identifier being commissioned."
          steps:
            - name: get-test-results
              type: call
              call: "servicenow.get-project-tasks"
              with:
                project_number: "{{project_number}}"
            - name: post-signoff-summary
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_commissioning_channel_id"
                text: "Commissioning Summary: Building {{building_id}} | Project: {{project_number}} | Tasks retrieved: {{get-test-results.task_count}} | Ready for sign-off review."
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: project-tasks
          path: "/table/pm_project_task"
          operations:
            - name: get-project-tasks
              method: GET
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Queries Snowflake for daily energy consumption data across a portfolio of managed buildings, computes efficiency scores, and posts an energy digest to the sustainability Microsoft Teams channel.

naftiko: "0.5"
info:
  label: "Building Energy Consumption Snowflake Report"
  description: "Queries Snowflake for daily energy consumption data across a portfolio of managed buildings, computes efficiency scores, and posts an energy digest to the sustainability Microsoft Teams channel."
  tags:
    - data
    - analytics
    - snowflake
    - microsoft-teams
    - sustainability
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: energy-analytics
      port: 8080
      tools:
        - name: digest-building-energy
          description: "Given a building portfolio ID and date range, query Snowflake for energy consumption metrics and post an efficiency digest to the sustainability Teams channel."
          inputParameters:
            - name: portfolio_id
              in: body
              type: string
              description: "The building portfolio or customer account ID."
            - name: start_date
              in: body
              type: string
              description: "The start of the reporting period in YYYY-MM-DD format."
            - name: end_date
              in: body
              type: string
              description: "The end of the reporting period in YYYY-MM-DD format."
          steps:
            - name: query-energy-data
              type: call
              call: "snowflake.execute-statement"
              with:
                statement: "SELECT building_id, SUM(kwh_consumed) as total_kwh, AVG(efficiency_score) as avg_efficiency FROM PROD.ENERGY.CONSUMPTION WHERE portfolio_id = '{{portfolio_id}}' AND reading_date BETWEEN '{{start_date}}' AND '{{end_date}}' GROUP BY 1"
            - name: post-digest
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_sustainability_channel_id"
                text: "Energy Report: Portfolio {{portfolio_id}} | Period: {{start_date}} to {{end_date}} | Buildings: {{query-energy-data.row_count}}"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://jci.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-statement
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Queries Snowflake for building energy consumption patterns, applies AI analysis via Anthropic for optimization recommendations, and posts report to the sustainability team.

naftiko: "0.5"
info:
  label: "Building Energy Optimization Workflow"
  description: "Queries Snowflake for building energy consumption patterns, applies AI analysis via Anthropic for optimization recommendations, and posts report to the sustainability team."
  tags:
    - sustainability
    - energy
    - snowflake
    - anthropic
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: energy-optimization
      port: 8080
      tools:
        - name: optimize-building-energy
          description: "Given a building, analyze energy patterns and generate optimization recommendations."
          inputParameters:
            - name: building_id
              type: string
              description: "Building identifier."
            - name: period
              type: string
              description: "Analysis period."
          steps:
            - name: get-energy-data
              type: call
              call: snowflake.query-energy-data
              with:
                building_id: "{{building_id}}"
                period: "{{period}}"
            - name: ai-optimize
              type: call
              call: anthropic.analyze-energy
              with:
                prompt: "Analyze building energy data and recommend optimizations: {{get-energy-data.results}}"
            - name: post-recommendations
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_sustainability_channel"
                text: "Energy optimization {{building_id}} ({{period}}): {{get-energy-data.total_kwh}} kWh | {{ai-optimize.response}}"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: query-energy-data
              method: POST
    - 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-energy
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/sustainability/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Calculates Energy Star scores from Snowflake utility data, updates portfolio dashboard, and posts to sustainability.

naftiko: "0.5"
info:
  label: "Building Energy Star Score Calculation"
  description: "Calculates Energy Star scores from Snowflake utility data, updates portfolio dashboard, and posts to sustainability."
  tags:
    - sustainability
    - energy
    - snowflake
    - power-bi
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: building_energy_star_score_calculation
          description: "Calculates Energy Star scores from Snowflake utility data, updates portfolio dashboard, and posts to sustainability."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Building Energy Star Score Calculation: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Building Energy Star Score Calculation for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Queries Snowflake for thermal performance data, generates report, and posts to engineering team.

naftiko: "0.5"
info:
  label: "Building Envelope Performance Report"
  description: "Queries Snowflake for thermal performance data, generates report, and posts to engineering team."
  tags:
    - building-performance
    - snowflake
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: building_envelope_performance_report
          description: "Queries Snowflake for thermal performance data, generates report, and posts to engineering team."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Building Envelope Performance Report: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Building Envelope Performance Report for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

When the OpenBlue IoT platform detects an HVAC anomaly or threshold breach in a managed building, creates a ServiceNow field service incident and dispatches a technician notification via Microsoft Teams.

naftiko: "0.5"
info:
  label: "Building HVAC System Alert to ServiceNow"
  description: "When the OpenBlue IoT platform detects an HVAC anomaly or threshold breach in a managed building, creates a ServiceNow field service incident and dispatches a technician notification via Microsoft Teams."
  tags:
    - iot
    - building-automation
    - servicenow
    - microsoft-teams
    - field-service
    - monitoring
capability:
  exposes:
    - type: mcp
      namespace: building-ops
      port: 8080
      tools:
        - name: handle-hvac-alert
          description: "Given an HVAC anomaly event from OpenBlue with building ID, equipment ID, and fault code, create a ServiceNow P2 field service incident and notify the facilities team via Microsoft Teams."
          inputParameters:
            - name: building_id
              in: body
              type: string
              description: "The OpenBlue building or site identifier."
            - name: equipment_id
              in: body
              type: string
              description: "The equipment or device ID reporting the fault."
            - name: fault_code
              in: body
              type: string
              description: "The HVAC fault code identifier."
            - name: fault_description
              in: body
              type: string
              description: "Human-readable description of the fault condition."
          steps:
            - name: create-field-incident
              type: call
              call: "servicenow.create-incident"
              with:
                short_description: "HVAC fault: {{fault_code}} at building {{building_id}} on {{equipment_id}}"
                category: "facilities"
                urgency: "2"
            - name: notify-facilities-team
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_facilities_channel_id"
                text: "HVAC Alert: Building {{building_id}} | Equipment: {{equipment_id}} | Fault: {{fault_code}} — {{fault_description}} | Incident: {{create-field-incident.number}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Pulls occupancy data from Snowflake, refreshes the Power BI dashboard, and posts weekly digest to property management.

naftiko: "0.5"
info:
  label: "Building Occupancy Analytics Digest"
  description: "Pulls occupancy data from Snowflake, refreshes the Power BI dashboard, and posts weekly digest to property management."
  tags:
    - building-analytics
    - snowflake
    - power-bi
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: building_occupancy_analytics_digest
          description: "Pulls occupancy data from Snowflake, refreshes the Power BI dashboard, and posts weekly digest to property management."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Building Occupancy Analytics Digest: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Building Occupancy Analytics Digest for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Tracks building permit deadlines in Jira, validates compliance status, and sends escalation notifications.

naftiko: "0.5"
info:
  label: "Building Permit Compliance Tracker"
  description: "Tracks building permit deadlines in Jira, validates compliance status, and sends escalation notifications."
  tags:
    - compliance
    - regulatory
    - jira
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: building_permit_compliance_tracker
          description: "Tracks building permit deadlines in Jira, validates compliance status, and sends escalation notifications."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Building Permit Compliance Tracker: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Building Permit Compliance Tracker for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Tracks sustainability certifications in Jira, validates documentation in SharePoint, and posts to team.

naftiko: "0.5"
info:
  label: "Building Sustainability Certification Tracker"
  description: "Tracks sustainability certifications in Jira, validates documentation in SharePoint, and posts to team."
  tags:
    - sustainability
    - jira
    - sharepoint
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: building_sustainability_certification_tracker
          description: "Tracks sustainability certifications in Jira, validates documentation in SharePoint, and posts to team."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Building Sustainability Certification Tracker: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Building Sustainability Certification Tracker for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

When a water leak sensor triggers, creates a ServiceNow P1 incident, dispatches plumber, and alerts building ops.

naftiko: "0.5"
info:
  label: "Building Water Leak Detection Response"
  description: "When a water leak sensor triggers, creates a ServiceNow P1 incident, dispatches plumber, and alerts building ops."
  tags:
    - facilities
    - iot
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: building_water_leak_detection_response
          description: "When a water leak sensor triggers, creates a ServiceNow P1 incident, dispatches plumber, and alerts building ops."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Building Water Leak Detection Response: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Building Water Leak Detection Response for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Pulls capital project status from SAP, queries Snowflake for spend variance, and posts digest.

naftiko: "0.5"
info:
  label: "Capital Project Budget Variance Report"
  description: "Pulls capital project status from SAP, queries Snowflake for spend variance, and posts digest."
  tags:
    - finance
    - capital-projects
    - sap
    - snowflake
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: capital_project_budget_variance_report
          description: "Pulls capital project status from SAP, queries Snowflake for spend variance, and posts digest."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Capital Project Budget Variance Report: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Capital Project Budget Variance Report for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Queries Snowflake for chiller plant efficiency data, compares against targets, and posts optimization report to the mechanical team.

naftiko: "0.5"
info:
  label: "Chiller Plant Optimization Report"
  description: "Queries Snowflake for chiller plant efficiency data, compares against targets, and posts optimization report to the mechanical team."
  tags:
    - hvac
    - optimization
    - snowflake
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: chiller_plant_optimization_report
          description: "Queries Snowflake for chiller plant efficiency data, compares against targets, and posts optimization report to the mechanical team."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Chiller Plant Optimization Report: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Chiller Plant Optimization Report for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

On a GitHub Actions pipeline failure on a protected branch, creates a ServiceNow incident and posts a failure alert to the engineering Microsoft Teams channel.

naftiko: "0.5"
info:
  label: "CI/CD Pipeline Failure Observability Chain"
  description: "On a GitHub Actions pipeline failure on a protected branch, creates a ServiceNow incident and posts a failure alert to the engineering Microsoft Teams channel."
  tags:
    - devops
    - cicd
    - github-actions
    - servicenow
    - microsoft-teams
    - incident-response
capability:
  exposes:
    - type: mcp
      namespace: devops-ops
      port: 8080
      tools:
        - name: handle-pipeline-failure
          description: "Given a GitHub Actions pipeline failure event, open a ServiceNow software incident and alert the engineering Teams channel with repository, branch, and workflow context."
          inputParameters:
            - name: repository
              in: body
              type: string
              description: "The GitHub repository in owner/repo format."
            - name: workflow_name
              in: body
              type: string
              description: "The name of the failed GitHub Actions workflow."
            - name: branch
              in: body
              type: string
              description: "The branch on which the pipeline failed."
            - name: run_id
              in: body
              type: string
              description: "The GitHub Actions run ID for the failed run."
          steps:
            - name: create-incident
              type: call
              call: "servicenow.create-incident"
              with:
                short_description: "[CI Failure] {{repository}} / {{branch}} — {{workflow_name}}"
                category: "software"
                urgency: "2"
            - name: post-alert
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_engineering_channel_id"
                text: "Pipeline Failure: {{repository}} | Branch: {{branch}} | Workflow: {{workflow_name}} | Run: {{run_id}} | Incident: {{create-incident.number}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Queries Workday for overdue compliance training, creates ServiceNow compliance ticket, and notifies managers.

naftiko: "0.5"
info:
  label: "Compliance Training Overdue Alert"
  description: "Queries Workday for overdue compliance training, creates ServiceNow compliance ticket, and notifies managers."
  tags:
    - hr
    - compliance
    - workday
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: compliance_training_overdue_alert
          description: "Queries Workday for overdue compliance training, creates ServiceNow compliance ticket, and notifies managers."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Compliance Training Overdue Alert: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Compliance Training Overdue Alert for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Retrieves a Confluence wiki page by ID, returning title and body content for building system documentation.

naftiko: "0.5"
info:
  label: "Confluence Page Lookup"
  description: "Retrieves a Confluence wiki page by ID, returning title and body content for building system documentation."
  tags:
    - collaboration
    - confluence
capability:
  exposes:
    - type: mcp
      namespace: wiki
      port: 8080
      tools:
        - name: get-page
          description: "Retrieve a Confluence page by ID."
          inputParameters:
            - name: page_id
              type: string
              description: "Confluence page ID."
          call: confluence.get-page
          with:
            page_id: "{{page_id}}"
          outputParameters:
            - name: title
              type: string
              mapping: "$.title"
            - name: body
              type: string
              mapping: "$.body.storage.value"
  consumes:
    - type: http
      namespace: confluence
      baseUri: "https://johnsoncontrols.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_api_token"
      resources:
        - name: pages
          path: "/content/{{page_id}}?expand=body.storage"
          inputParameters:
            - name: page_id
              in: path
          operations:
            - name: get-page
              method: GET

Verifies contractor safety certs in SAP, provisions site access via Okta, and notifies safety team.

naftiko: "0.5"
info:
  label: "Contractor Safety Certification Check"
  description: "Verifies contractor safety certs in SAP, provisions site access via Okta, and notifies safety team."
  tags:
    - ehs
    - contractor-management
    - sap
    - okta
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: contractor_safety_certification_check
          description: "Verifies contractor safety certs in SAP, provisions site access via Okta, and notifies safety team."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Contractor Safety Certification Check: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Contractor Safety Certification Check for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Onboards a new customer site by creating Salesforce account, provisioning OpenBlue access, and notifying delivery.

naftiko: "0.5"
info:
  label: "Customer Site Onboarding Workflow"
  description: "Onboards a new customer site by creating Salesforce account, provisioning OpenBlue access, and notifying delivery."
  tags:
    - customer-onboarding
    - salesforce
    - okta
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: customer_site_onboarding_workflow
          description: "Onboards a new customer site by creating Salesforce account, provisioning OpenBlue access, and notifying delivery."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Customer Site Onboarding Workflow: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Customer Site Onboarding Workflow for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

When a Snowflake ETL pipeline fails, queries error logs, creates a Jira ticket, and notifies data engineering.

naftiko: "0.5"
info:
  label: "Data Pipeline Failure Recovery"
  description: "When a Snowflake ETL pipeline fails, queries error logs, creates a Jira ticket, and notifies data engineering."
  tags:
    - data-engineering
    - snowflake
    - jira
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: data_pipeline_failure_recovery
          description: "When a Snowflake ETL pipeline fails, queries error logs, creates a Jira ticket, and notifies data engineering."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Data Pipeline Failure Recovery: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Data Pipeline Failure Recovery for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

When Datadog detects a production infrastructure anomaly, creates a ServiceNow P1 incident and pages the on-call SRE team via Microsoft Teams.

naftiko: "0.5"
info:
  label: "Datadog Infrastructure Monitoring Alert"
  description: "When Datadog detects a production infrastructure anomaly, creates a ServiceNow P1 incident and pages the on-call SRE team via Microsoft Teams."
  tags:
    - observability
    - incident-response
    - datadog
    - servicenow
    - microsoft-teams
    - monitoring
capability:
  exposes:
    - type: mcp
      namespace: sre-ops
      port: 8080
      tools:
        - name: handle-datadog-alert
          description: "Given a Datadog monitor alert with service and host context, create a ServiceNow P1 incident and page the on-call SRE team via Microsoft Teams."
          inputParameters:
            - name: monitor_id
              in: body
              type: string
              description: "The Datadog monitor ID that fired."
            - name: monitor_name
              in: body
              type: string
              description: "Human-readable name of the Datadog monitor."
            - name: affected_service
              in: body
              type: string
              description: "The service or host affected by the alert."
          steps:
            - name: get-monitor
              type: call
              call: "datadog.get-monitor"
              with:
                monitor_id: "{{monitor_id}}"
            - name: create-incident
              type: call
              call: "servicenow.create-incident"
              with:
                short_description: "Datadog alert: {{monitor_name}} on {{affected_service}}"
                category: "infrastructure"
                urgency: "1"
            - name: page-oncall
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_oncall_channel_id"
                text: "ALERT: {{monitor_name}} | Service: {{affected_service}} | Incident: {{create-incident.number}}"
  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/{{monitor_id}}"
          inputParameters:
            - name: monitor_id
              in: path
          operations:
            - name: get-monitor
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Retrieves the current status of a Datadog monitor by ID for building system observability.

naftiko: "0.5"
info:
  label: "Datadog Monitor Status Lookup"
  description: "Retrieves the current status of a Datadog monitor by ID for building system observability."
  tags:
    - observability
    - datadog
capability:
  exposes:
    - type: mcp
      namespace: monitoring
      port: 8080
      tools:
        - name: get-monitor-status
          description: "Look up a Datadog monitor by ID."
          inputParameters:
            - name: monitor_id
              type: string
              description: "Datadog monitor ID."
          call: datadog.get-monitor
          with:
            monitor_id: "{{monitor_id}}"
          outputParameters:
            - name: name
              type: string
              mapping: "$.name"
            - name: overall_state
              type: string
              mapping: "$.overall_state"
  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/{{monitor_id}}"
          inputParameters:
            - name: monitor_id
              in: path
          operations:
            - name: get-monitor
              method: GET

Validates digital twin data sync between OpenBlue and Snowflake, identifies discrepancies, and posts report.

naftiko: "0.5"
info:
  label: "Digital Twin Sync Validation"
  description: "Validates digital twin data sync between OpenBlue and Snowflake, identifies discrepancies, and posts report."
  tags:
    - iot
    - digital-twin
    - snowflake
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: digital_twin_sync_validation
          description: "Validates digital twin data sync between OpenBlue and Snowflake, identifies discrepancies, and posts report."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Digital Twin Sync Validation: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Digital Twin Sync Validation for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Pulls elevator maintenance schedules from SAP, creates ServiceNow work orders, and notifies facilities team.

naftiko: "0.5"
info:
  label: "Elevator Maintenance Scheduling Workflow"
  description: "Pulls elevator maintenance schedules from SAP, creates ServiceNow work orders, and notifies facilities team."
  tags:
    - field-service
    - elevator
    - sap
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: elevator_maintenance_scheduling_workflow
          description: "Pulls elevator maintenance schedules from SAP, creates ServiceNow work orders, and notifies facilities team."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Elevator Maintenance Scheduling Workflow: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Elevator Maintenance Scheduling Workflow for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Pulls generator test schedules from SAP, creates ServiceNow work orders, and notifies facilities team.

naftiko: "0.5"
info:
  label: "Emergency Generator Test Scheduling"
  description: "Pulls generator test schedules from SAP, creates ServiceNow work orders, and notifies facilities team."
  tags:
    - facilities
    - generator
    - sap
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: emergency_generator_test_scheduling
          description: "Pulls generator test schedules from SAP, creates ServiceNow work orders, and notifies facilities team."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Emergency Generator Test Scheduling: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Emergency Generator Test Scheduling for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

When an employee departs, revokes Okta access, closes Workday record, and notifies IT and HR via Teams.

naftiko: "0.5"
info:
  label: "Employee Offboarding Workflow"
  description: "When an employee departs, revokes Okta access, closes Workday record, and notifies IT and HR via Teams."
  tags:
    - hr
    - offboarding
    - workday
    - okta
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: employee_offboarding_workflow
          description: "When an employee departs, revokes Okta access, closes Workday record, and notifies IT and HR via Teams."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Employee Offboarding Workflow: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Employee Offboarding Workflow for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

When a new hire is created in Workday, opens a ServiceNow onboarding ticket, provisions a SharePoint folder, and sends a Microsoft Teams welcome message to the new employee.

naftiko: "0.5"
info:
  label: "Employee Onboarding Orchestrator"
  description: "When a new hire is created in Workday, opens a ServiceNow onboarding ticket, provisions a SharePoint folder, and sends a Microsoft Teams welcome message to the new employee."
  tags:
    - hr
    - onboarding
    - workday
    - servicenow
    - sharepoint
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: hr-onboarding
      port: 8080
      tools:
        - name: trigger-onboarding
          description: "Given a Workday employee ID and start date, orchestrate the full onboarding sequence across ServiceNow, SharePoint, and Microsoft Teams for a new Johnson Controls employee."
          inputParameters:
            - name: workday_employee_id
              in: body
              type: string
              description: "The Workday worker ID for the new hire."
            - name: start_date
              in: body
              type: string
              description: "The employee start date in YYYY-MM-DD format."
            - name: business_unit
              in: body
              type: string
              description: "The business unit the employee is joining (e.g., Building Solutions, Global Products)."
          steps:
            - name: get-employee
              type: call
              call: "workday.get-worker"
              with:
                worker_id: "{{workday_employee_id}}"
            - name: open-ticket
              type: call
              call: "servicenow.create-incident"
              with:
                short_description: "New hire onboarding: {{get-employee.full_name}}"
                category: "hr_onboarding"
                assigned_group: "IT_Onboarding"
            - name: provision-folder
              type: call
              call: "sharepoint.create-folder"
              with:
                site_id: "hr_onboarding_site"
                folder_path: "OnboardingDocs/{{get-employee.full_name}}_{{start_date}}"
            - name: send-welcome
              type: call
              call: "msteams.send-message"
              with:
                recipient_upn: "{{get-employee.work_email}}"
                text: "Welcome to Johnson Controls, {{get-employee.first_name}}! Your IT onboarding ticket is {{open-ticket.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: "/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: sharepoint
      baseUri: "https://graph.microsoft.com/v1.0/sites"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: drive-items
          path: "/{{site_id}}/drive/root:/{{folder_path}}"
          inputParameters:
            - name: site_id
              in: path
            - name: folder_path
              in: path
          operations:
            - name: create-folder
              method: PUT
    - 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

Optimizes field technician dispatch by querying Snowflake for open work orders, matching skills, and notifying via Teams.

naftiko: "0.5"
info:
  label: "Field Technician Dispatch Optimization"
  description: "Optimizes field technician dispatch by querying Snowflake for open work orders, matching skills, and notifying via Teams."
  tags:
    - field-service
    - snowflake
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: field_technician_dispatch_optimization
          description: "Optimizes field technician dispatch by querying Snowflake for open work orders, matching skills, and notifying via Teams."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Field Technician Dispatch Optimization: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Field Technician Dispatch Optimization for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

When a fire alarm panel reports an alert, creates a ServiceNow P1 incident, dispatches a technician via Teams, and logs the event in Snowflake.

naftiko: "0.5"
info:
  label: "Fire Alarm Panel Alert Response"
  description: "When a fire alarm panel reports an alert, creates a ServiceNow P1 incident, dispatches a technician via Teams, and logs the event in Snowflake."
  tags:
    - fire-safety
    - building-automation
    - servicenow
    - microsoft-teams
    - snowflake
capability:
  exposes:
    - type: mcp
      namespace: fire-safety
      port: 8080
      tools:
        - name: handle-fire-alarm
          description: "Given a fire alarm event, create incident, dispatch technician, and log event."
          inputParameters:
            - name: building_id
              type: string
              description: "Building identifier."
            - name: panel_id
              type: string
              description: "Fire alarm panel ID."
            - name: zone
              type: string
              description: "Alarm zone."
            - name: alarm_type
              type: string
              description: "Alarm type (smoke, heat, manual_pull)."
          steps:
            - name: create-incident
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Fire alarm: {{alarm_type}} at building {{building_id}} zone {{zone}}"
                urgency: "1"
                impact: "1"
            - name: notify-technician
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_fire_safety_channel"
                text: "FIRE ALARM: Building {{building_id}} | Panel: {{panel_id}} | Zone: {{zone}} | Type: {{alarm_type}} | Incident: {{create-incident.number}}"
            - name: log-event
              type: call
              call: snowflake.log-alarm-event
              with:
                building_id: "{{building_id}}"
                event_type: "{{alarm_type}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/fire-safety/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: log-alarm-event
              method: POST

Pulls fire suppression inspection schedules from SAP, creates ServiceNow work orders, and notifies fire safety team.

naftiko: "0.5"
info:
  label: "Fire Suppression System Inspection Tracker"
  description: "Pulls fire suppression inspection schedules from SAP, creates ServiceNow work orders, and notifies fire safety team."
  tags:
    - fire-safety
    - sap
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: fire_suppression_inspection_tracker
          description: "Pulls fire suppression inspection schedules from SAP, creates ServiceNow work orders, and notifies fire safety team."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Fire Suppression System Inspection Tracker: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Fire Suppression System Inspection Tracker for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

When Dependabot finds a vulnerability, creates Jira ticket, opens change request, and alerts security.

naftiko: "0.5"
info:
  label: "GitHub Dependabot Vulnerability Triage"
  description: "When Dependabot finds a vulnerability, creates Jira ticket, opens change request, and alerts security."
  tags:
    - security
    - github
    - jira
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: github_dependabot_vulnerability_triage
          description: "When Dependabot finds a vulnerability, creates Jira ticket, opens change request, and alerts security."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "GitHub Dependabot Vulnerability Triage: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "GitHub Dependabot Vulnerability Triage for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Retrieves the CI/CD status for the latest commit on a repository.

naftiko: "0.5"
info:
  label: "GitHub Repository Status Lookup"
  description: "Retrieves the CI/CD status for the latest commit on a repository."
  tags:
    - devops
    - github
capability:
  exposes:
    - type: mcp
      namespace: source-control
      port: 8080
      tools:
        - name: get-repo-status
          description: "Look up the CI/CD status for a repository."
          inputParameters:
            - name: repo
              type: string
              description: "Repository name in org/repo format."
          call: github.get-status
          with:
            repo: "{{repo}}"
          outputParameters:
            - name: state
              type: string
              mapping: "$.state"
  consumes:
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: commit-status
          path: "/repos/{{repo}}/commits/HEAD/status"
          inputParameters:
            - name: repo
              in: path
          operations:
            - name: get-status
              method: GET

When GitHub Advanced Security detects a critical vulnerability in a production repository, creates a ServiceNow security incident and notifies the security engineering team via Microsoft Teams.

naftiko: "0.5"
info:
  label: "GitHub Security Vulnerability Triage"
  description: "When GitHub Advanced Security detects a critical vulnerability in a production repository, creates a ServiceNow security incident and notifies the security engineering team via Microsoft Teams."
  tags:
    - devops
    - security
    - github
    - servicenow
    - microsoft-teams
    - vulnerability-management
capability:
  exposes:
    - type: mcp
      namespace: security-ops
      port: 8080
      tools:
        - name: triage-security-alert
          description: "Given a GitHub security alert with repository, alert number, and severity, create a ServiceNow security incident and notify the security engineering team in Microsoft Teams."
          inputParameters:
            - name: repository
              in: body
              type: string
              description: "The GitHub repository in owner/repo format."
            - name: alert_number
              in: body
              type: integer
              description: "The GitHub security alert number."
            - name: severity
              in: body
              type: string
              description: "Severity: critical, high, medium, or low."
          steps:
            - name: get-alert
              type: call
              call: "github.get-code-scanning-alert"
              with:
                repository: "{{repository}}"
                alert_number: "{{alert_number}}"
            - name: create-sec-incident
              type: call
              call: "servicenow.create-incident"
              with:
                short_description: "[Security] {{severity}} vulnerability in {{repository}}"
                category: "security"
                urgency: "1"
            - name: notify-security-team
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_security_channel_id"
                text: "Security Alert: {{severity}} in {{repository}} | Incident: {{create-sec-incident.number}} | Details: {{get-alert.html_url}}"
  consumes:
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: code-scanning-alerts
          path: "/repos/{{repository}}/code-scanning/alerts/{{alert_number}}"
          inputParameters:
            - name: repository
              in: path
            - name: alert_number
              in: path
          operations:
            - name: get-code-scanning-alert
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Analyzes HVAC telemetry from Snowflake to predict failures, creates SAP maintenance notifications, and alerts field service.

naftiko: "0.5"
info:
  label: "HVAC Predictive Maintenance Alert"
  description: "Analyzes HVAC telemetry from Snowflake to predict failures, creates SAP maintenance notifications, and alerts field service."
  tags:
    - hvac
    - predictive-maintenance
    - snowflake
    - sap
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: hvac_predictive_maintenance_alert
          description: "Analyzes HVAC telemetry from Snowflake to predict failures, creates SAP maintenance notifications, and alerts field service."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "HVAC Predictive Maintenance Alert: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "HVAC Predictive Maintenance Alert for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

When IAQ sensors detect poor conditions, creates a ServiceNow incident and notifies building management team.

naftiko: "0.5"
info:
  label: "Indoor Air Quality Alert Response"
  description: "When IAQ sensors detect poor conditions, creates a ServiceNow incident and notifies building management team."
  tags:
    - building-automation
    - air-quality
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: indoor_air_quality_alert_response
          description: "When IAQ sensors detect poor conditions, creates a ServiceNow incident and notifies building management team."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Indoor Air Quality Alert Response: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Indoor Air Quality Alert Response for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

When GitHub finds a critical vulnerability, creates a Jira ticket, opens ServiceNow change request, and alerts security.

naftiko: "0.5"
info:
  label: "IT Security Vulnerability Remediation"
  description: "When GitHub finds a critical vulnerability, creates a Jira ticket, opens ServiceNow change request, and alerts security."
  tags:
    - security
    - github
    - jira
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: it_security_vulnerability_remediation
          description: "When GitHub finds a critical vulnerability, creates a Jira ticket, opens ServiceNow change request, and alerts security."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "IT Security Vulnerability Remediation: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "IT Security Vulnerability Remediation for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Retrieves a Jira issue by key, returning summary, status, assignee, and priority.

naftiko: "0.5"
info:
  label: "Jira Issue Lookup"
  description: "Retrieves a Jira issue by key, returning summary, status, assignee, and priority."
  tags:
    - project-management
    - jira
capability:
  exposes:
    - type: mcp
      namespace: project-mgmt
      port: 8080
      tools:
        - name: get-jira-issue
          description: "Look up a Jira issue by key."
          inputParameters:
            - name: issue_key
              type: string
              description: "Jira issue key."
          call: jira.get-issue
          with:
            issue_key: "{{issue_key}}"
          outputParameters:
            - name: summary
              type: string
              mapping: "$.fields.summary"
            - name: status
              type: string
              mapping: "$.fields.status.name"
  consumes:
    - type: http
      namespace: jira
      baseUri: "https://johnsoncontrols.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue/{{issue_key}}"
          inputParameters:
            - name: issue_key
              in: path
          operations:
            - name: get-issue
              method: GET

When Datadog detects a pod crash loop, gathers Splunk logs, creates ServiceNow incident, and alerts platform team.

naftiko: "0.5"
info:
  label: "Kubernetes Pod Failure Escalation"
  description: "When Datadog detects a pod crash loop, gathers Splunk logs, creates ServiceNow incident, and alerts platform team."
  tags:
    - devops
    - kubernetes
    - datadog
    - splunk
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: kubernetes_pod_failure_escalation
          description: "When Datadog detects a pod crash loop, gathers Splunk logs, creates ServiceNow incident, and alerts platform team."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Kubernetes Pod Failure Escalation: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Kubernetes Pod Failure Escalation for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

When a lighting control system fails, creates ServiceNow field service order and notifies electrical team.

naftiko: "0.5"
info:
  label: "Lighting System Failure Response"
  description: "When a lighting control system fails, creates ServiceNow field service order and notifies electrical team."
  tags:
    - facilities
    - lighting
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: lighting_system_failure_response
          description: "When a lighting control system fails, creates ServiceNow field service order and notifies electrical team."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Lighting System Failure Response: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Lighting System Failure Response for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Publishes a new job opening from Workday recruiting to the Johnson Controls LinkedIn company page and syncs the LinkedIn post URL back to the Workday requisition.

naftiko: "0.5"
info:
  label: "LinkedIn Job Posting Publisher"
  description: "Publishes a new job opening from Workday recruiting to the Johnson Controls LinkedIn company page and syncs the LinkedIn post URL back to the Workday requisition."
  tags:
    - hr
    - recruiting
    - linkedin
    - workday
    - social
    - talent-acquisition
capability:
  exposes:
    - type: mcp
      namespace: talent-acquisition
      port: 8080
      tools:
        - name: publish-job-to-linkedin
          description: "Given a Workday job requisition ID, retrieve the job details and publish the opening to the Johnson Controls LinkedIn company page. Write the LinkedIn post URL back to the Workday requisition."
          inputParameters:
            - name: requisition_id
              in: body
              type: string
              description: "The Workday job requisition ID to publish."
          steps:
            - name: get-requisition
              type: call
              call: "workday.get-job-requisition"
              with:
                requisition_id: "{{requisition_id}}"
            - name: post-to-linkedin
              type: call
              call: "linkedin.create-job-posting"
              with:
                title: "{{get-requisition.job_title}}"
                description: "{{get-requisition.job_description}}"
                location: "{{get-requisition.location}}"
                company_id: "$secrets.linkedin_company_id"
            - name: update-requisition
              type: call
              call: "workday.update-job-requisition"
              with:
                requisition_id: "{{requisition_id}}"
                linkedin_post_url: "{{post-to-linkedin.post_url}}"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: job-requisitions
          path: "/jobRequisitions/{{requisition_id}}"
          inputParameters:
            - name: requisition_id
              in: path
          operations:
            - name: get-job-requisition
              method: GET
            - name: update-job-requisition
              method: PATCH
    - type: http
      namespace: linkedin
      baseUri: "https://api.linkedin.com/v2"
      authentication:
        type: bearer
        token: "$secrets.linkedin_token"
      resources:
        - name: job-postings
          path: "/jobPostings"
          operations:
            - name: create-job-posting
              method: POST

Pulls open positions from Workday, creates LinkedIn job postings, and posts campaign summary to talent team.

naftiko: "0.5"
info:
  label: "LinkedIn Talent Acquisition Campaign"
  description: "Pulls open positions from Workday, creates LinkedIn job postings, and posts campaign summary to talent team."
  tags:
    - hr
    - talent-acquisition
    - workday
    - linkedin
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: linkedin_talent_acquisition_campaign
          description: "Pulls open positions from Workday, creates LinkedIn job postings, and posts campaign summary to talent team."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "LinkedIn Talent Acquisition Campaign: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "LinkedIn Talent Acquisition Campaign for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Posts a notification message to a Microsoft Teams channel for building operations alerts and status updates.

naftiko: "0.5"
info:
  label: "Microsoft Teams Channel Notification"
  description: "Posts a notification message to a Microsoft Teams channel for building operations alerts and status updates."
  tags:
    - collaboration
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: notifications
      port: 8080
      tools:
        - name: post-teams-message
          description: "Post a message to a Microsoft Teams channel."
          inputParameters:
            - name: channel_id
              type: string
              description: "Teams channel ID."
            - name: message
              type: string
              description: "Message text."
          call: msteams.post-channel-message
          with:
            channel_id: "{{channel_id}}"
            text: "{{message}}"
  consumes:
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/building-ops/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Queries Okta for users without MFA, creates ServiceNow compliance ticket, and notifies IT security.

naftiko: "0.5"
info:
  label: "Okta MFA Non-Compliance Escalation"
  description: "Queries Okta for users without MFA, creates ServiceNow compliance ticket, and notifies IT security."
  tags:
    - security
    - identity
    - okta
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: okta_mfa_non_compliance_escalation
          description: "Queries Okta for users without MFA, creates ServiceNow compliance ticket, and notifies IT security."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Okta MFA Non-Compliance Escalation: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Okta MFA Non-Compliance Escalation for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Retrieves an Okta user profile by login email, returning status and last login timestamp.

naftiko: "0.5"
info:
  label: "Okta User Status Lookup"
  description: "Retrieves an Okta user profile by login email, returning status and last login timestamp."
  tags:
    - identity
    - okta
capability:
  exposes:
    - type: mcp
      namespace: identity
      port: 8080
      tools:
        - name: get-okta-user
          description: "Look up an Okta user by email."
          inputParameters:
            - name: email
              type: string
              description: "User login email."
          call: okta.get-user
          with:
            email: "{{email}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.status"
            - name: last_login
              type: string
              mapping: "$.lastLogin"
  consumes:
    - type: http
      namespace: okta
      baseUri: "https://johnsoncontrols.okta.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.okta_api_token"
      resources:
        - name: users
          path: "/users/{{email}}"
          inputParameters:
            - name: email
              in: path
          operations:
            - name: get-user
              method: GET

Queries OpenBlue IoT platform for device health, identifies offline devices, and creates ServiceNow incidents.

naftiko: "0.5"
info:
  label: "OpenBlue IoT Device Health Check"
  description: "Queries OpenBlue IoT platform for device health, identifies offline devices, and creates ServiceNow incidents."
  tags:
    - iot
    - openblue
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: openblue_iot_device_health_check
          description: "Queries OpenBlue IoT platform for device health, identifies offline devices, and creates ServiceNow incidents."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "OpenBlue IoT Device Health Check: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "OpenBlue IoT Device Health Check for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Retrieves a PagerDuty incident by ID, returning status, urgency, and assigned responders.

naftiko: "0.5"
info:
  label: "PagerDuty Incident Lookup"
  description: "Retrieves a PagerDuty incident by ID, returning status, urgency, and assigned responders."
  tags:
    - itsm
    - pagerduty
capability:
  exposes:
    - type: mcp
      namespace: on-call
      port: 8080
      tools:
        - name: get-pd-incident
          description: "Look up a PagerDuty incident by ID."
          inputParameters:
            - name: incident_id
              type: string
              description: "PagerDuty incident ID."
          call: pagerduty.get-incident
          with:
            incident_id: "{{incident_id}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.incident.status"
            - name: urgency
              type: string
              mapping: "$.incident.urgency"
  consumes:
    - type: http
      namespace: pagerduty
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: bearer
        token: "$secrets.pagerduty_token"
      resources:
        - name: incidents
          path: "/incidents/{{incident_id}}"
          inputParameters:
            - name: incident_id
              in: path
          operations:
            - name: get-incident
              method: GET

When CO levels exceed threshold, creates ServiceNow P1 incident and alerts building operations.

naftiko: "0.5"
info:
  label: "Parking Garage Ventilation Alert"
  description: "When CO levels exceed threshold, creates ServiceNow P1 incident and alerts building operations."
  tags:
    - facilities
    - ventilation
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: parking_garage_ventilation_alert
          description: "When CO levels exceed threshold, creates ServiceNow P1 incident and alerts building operations."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Parking Garage Ventilation Alert: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Parking Garage Ventilation Alert for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Triggers a Power BI dataset refresh for the building energy performance dashboard and posts the refresh status to the sustainability Microsoft Teams channel.

naftiko: "0.5"
info:
  label: "Power BI Building Performance Dashboard Refresh"
  description: "Triggers a Power BI dataset refresh for the building energy performance dashboard and posts the refresh status to the sustainability Microsoft Teams channel."
  tags:
    - data
    - analytics
    - power-bi
    - microsoft-teams
    - reporting
    - sustainability
capability:
  exposes:
    - type: mcp
      namespace: bi-reporting
      port: 8080
      tools:
        - name: refresh-building-performance-dashboard
          description: "Given a Power BI workspace ID and dataset ID, trigger a dataset refresh for the building performance dashboard and notify the sustainability Teams channel."
          inputParameters:
            - name: workspace_id
              in: body
              type: string
              description: "The Power BI workspace ID containing the building performance dataset."
            - name: dataset_id
              in: body
              type: string
              description: "The Power BI dataset ID to refresh."
          steps:
            - name: trigger-refresh
              type: call
              call: "powerbi.refresh-dataset"
              with:
                workspace_id: "{{workspace_id}}"
                dataset_id: "{{dataset_id}}"
            - name: post-status
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_sustainability_channel_id"
                text: "Building Performance dashboard refresh triggered: dataset {{dataset_id}}. Updated data will be available shortly."
  consumes:
    - type: http
      namespace: powerbi
      baseUri: "https://api.powerbi.com/v1.0/myorg"
      authentication:
        type: bearer
        token: "$secrets.powerbi_token"
      resources:
        - name: datasets
          path: "/groups/{{workspace_id}}/datasets/{{dataset_id}}/refreshes"
          inputParameters:
            - name: workspace_id
              in: path
            - name: dataset_id
              in: path
          operations:
            - name: refresh-dataset
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Queries Snowflake for portfolio metrics, refreshes Power BI executive dashboard, and posts summary.

naftiko: "0.5"
info:
  label: "Power BI Building Portfolio Dashboard Refresh"
  description: "Queries Snowflake for portfolio metrics, refreshes Power BI executive dashboard, and posts summary."
  tags:
    - reporting
    - snowflake
    - power-bi
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: power_bi_building_portfolio_refresh
          description: "Queries Snowflake for portfolio metrics, refreshes Power BI executive dashboard, and posts summary."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Power BI Building Portfolio Dashboard Refresh: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Power BI Building Portfolio Dashboard Refresh for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Triggers a refresh on a Power BI dataset by dataset ID for building performance reporting.

naftiko: "0.5"
info:
  label: "Power BI Dataset Refresh Trigger"
  description: "Triggers a refresh on a Power BI dataset by dataset ID for building performance reporting."
  tags:
    - reporting
    - power-bi
capability:
  exposes:
    - type: mcp
      namespace: bi-reporting
      port: 8080
      tools:
        - name: refresh-dataset
          description: "Trigger a Power BI dataset refresh."
          inputParameters:
            - name: dataset_id
              type: string
              description: "Power BI dataset ID."
          call: powerbi.refresh-dataset
          with:
            dataset_id: "{{dataset_id}}"
  consumes:
    - type: http
      namespace: powerbi
      baseUri: "https://api.powerbi.com/v1.0/myorg"
      authentication:
        type: bearer
        token: "$secrets.powerbi_token"
      resources:
        - name: datasets
          path: "/datasets/{{dataset_id}}/refreshes"
          inputParameters:
            - name: dataset_id
              in: path
          operations:
            - name: refresh-dataset
              method: POST

Prepares QBR by pulling Salesforce pipeline data, Snowflake service metrics, and refreshing Power BI dashboards.

naftiko: "0.5"
info:
  label: "Quarterly Business Review Preparation"
  description: "Prepares QBR by pulling Salesforce pipeline data, Snowflake service metrics, and refreshing Power BI dashboards."
  tags:
    - sales
    - salesforce
    - snowflake
    - power-bi
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: quarterly_business_review_preparation
          description: "Prepares QBR by pulling Salesforce pipeline data, Snowflake service metrics, and refreshing Power BI dashboards."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Quarterly Business Review Preparation: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Quarterly Business Review Preparation for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Coordinates quarterly close with SAP tasks, Snowflake validation, and finance team status notifications.

naftiko: "0.5"
info:
  label: "Quarterly Financial Close Orchestration"
  description: "Coordinates quarterly close with SAP tasks, Snowflake validation, and finance team status notifications."
  tags:
    - finance
    - sap
    - snowflake
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: quarterly_financial_close_orchestration
          description: "Coordinates quarterly close with SAP tasks, Snowflake validation, and finance team status notifications."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Quarterly Financial Close Orchestration: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Quarterly Financial Close Orchestration for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

When a refrigerant leak is detected, creates ServiceNow environmental incident, logs in Snowflake, and alerts EHS.

naftiko: "0.5"
info:
  label: "Refrigerant Leak Detection Workflow"
  description: "When a refrigerant leak is detected, creates ServiceNow environmental incident, logs in Snowflake, and alerts EHS."
  tags:
    - ehs
    - environmental
    - servicenow
    - snowflake
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: refrigerant_leak_detection_workflow
          description: "When a refrigerant leak is detected, creates ServiceNow environmental incident, logs in Snowflake, and alerts EHS."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Refrigerant Leak Detection Workflow: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Refrigerant Leak Detection Workflow for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Coordinates regulatory inspections by pulling Jira schedules, creating ServiceNow work orders, and notifying inspectors.

naftiko: "0.5"
info:
  label: "Regulatory Compliance Inspection Workflow"
  description: "Coordinates regulatory inspections by pulling Jira schedules, creating ServiceNow work orders, and notifying inspectors."
  tags:
    - compliance
    - regulatory
    - jira
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: regulatory_compliance_inspection_workflow
          description: "Coordinates regulatory inspections by pulling Jira schedules, creating ServiceNow work orders, and notifying inspectors."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Regulatory Compliance Inspection Workflow: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Regulatory Compliance Inspection Workflow for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Retrieves a Salesforce account by name, returning account type, industry, annual revenue, and owner.

naftiko: "0.5"
info:
  label: "Salesforce Account Lookup"
  description: "Retrieves a Salesforce account by name, returning account type, industry, annual revenue, and owner."
  tags:
    - sales
    - crm
    - salesforce
capability:
  exposes:
    - type: mcp
      namespace: crm
      port: 8080
      tools:
        - name: get-account
          description: "Look up a Salesforce account by name."
          inputParameters:
            - name: account_name
              type: string
              description: "Account name."
          call: salesforce.query-account
          with:
            name: "{{account_name}}"
          outputParameters:
            - name: account_type
              type: string
              mapping: "$.records[0].Type"
            - name: industry
              type: string
              mapping: "$.records[0].Industry"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://johnsoncontrols.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: accounts
          path: "/query?q=SELECT+Name,Type,Industry+FROM+Account+WHERE+Name='{{name}}'"
          inputParameters:
            - name: name
              in: query
          operations:
            - name: query-account
              method: GET

When a Salesforce opportunity for a building solutions project reaches Closed Won, creates a SAP project order and updates the Salesforce opportunity with the SAP project number.

naftiko: "0.5"
info:
  label: "Salesforce Building Solutions Opportunity Sync to SAP"
  description: "When a Salesforce opportunity for a building solutions project reaches Closed Won, creates a SAP project order and updates the Salesforce opportunity with the SAP project number."
  tags:
    - sales
    - crm
    - salesforce
    - sap
    - erp
    - building-solutions
capability:
  exposes:
    - type: mcp
      namespace: sales-erp-sync
      port: 8080
      tools:
        - name: sync-won-opportunity-to-sap
          description: "Given a Salesforce Closed Won opportunity ID for a building solutions project, create a SAP project order and write the SAP project number back to the Salesforce record."
          inputParameters:
            - name: opportunity_id
              in: body
              type: string
              description: "The Salesforce opportunity ID at Closed Won stage."
          steps:
            - name: get-opportunity
              type: call
              call: "salesforce-read.get-opportunity"
              with:
                opportunity_id: "{{opportunity_id}}"
            - name: create-sap-project
              type: call
              call: "sap-ps.create-project-order"
              with:
                customer_id: "{{get-opportunity.account_external_id}}"
                amount: "{{get-opportunity.amount}}"
                project_name: "{{get-opportunity.name}}"
            - name: update-opportunity
              type: call
              call: "salesforce-write.update-opportunity"
              with:
                opportunity_id: "{{opportunity_id}}"
                sap_project_number: "{{create-sap-project.project_number}}"
  consumes:
    - type: http
      namespace: salesforce-read
      baseUri: "https://johnsoncontrols.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: opportunities
          path: "/sobjects/Opportunity/{{opportunity_id}}"
          inputParameters:
            - name: opportunity_id
              in: path
          operations:
            - name: get-opportunity
              method: GET
    - type: http
      namespace: sap-ps
      baseUri: "https://jci-s4.sap.com/sap/opu/odata/sap/API_PROJECT_V2_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: projects
          path: "/Project"
          operations:
            - name: create-project-order
              method: POST
    - type: http
      namespace: salesforce-write
      baseUri: "https://johnsoncontrols.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: opportunities
          path: "/sobjects/Opportunity/{{opportunity_id}}"
          inputParameters:
            - name: opportunity_id
              in: path
          operations:
            - name: update-opportunity
              method: PATCH

Syncs Salesforce installed product base with SAP asset records and posts discrepancies to service ops.

naftiko: "0.5"
info:
  label: "Salesforce Install Base Asset Sync"
  description: "Syncs Salesforce installed product base with SAP asset records and posts discrepancies to service ops."
  tags:
    - sales
    - salesforce
    - sap
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: salesforce_install_base_asset_sync
          description: "Syncs Salesforce installed product base with SAP asset records and posts discrepancies to service ops."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Salesforce Install Base Asset Sync: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Salesforce Install Base Asset Sync for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

When a new building controls prospect lead is created in Salesforce, enriches it with firmographic data and routes it to the correct regional sales team based on geography.

naftiko: "0.5"
info:
  label: "Salesforce Lead Enrichment and Assignment"
  description: "When a new building controls prospect lead is created in Salesforce, enriches it with firmographic data and routes it to the correct regional sales team based on geography."
  tags:
    - sales
    - crm
    - salesforce
    - enrichment
    - building-solutions
capability:
  exposes:
    - type: mcp
      namespace: lead-management
      port: 8080
      tools:
        - name: enrich-and-assign-lead
          description: "Given a Salesforce lead ID for a building controls prospect, retrieve the lead, determine the regional sales team, and update the lead with the assigned owner."
          inputParameters:
            - name: lead_id
              in: body
              type: string
              description: "The Salesforce lead ID to enrich and assign."
          steps:
            - name: get-lead
              type: call
              call: "salesforce-read.get-lead"
              with:
                lead_id: "{{lead_id}}"
            - name: assign-lead
              type: call
              call: "salesforce-write.update-lead"
              with:
                lead_id: "{{lead_id}}"
                status: "Assigned"
                lead_source: "Inbound"
  consumes:
    - type: http
      namespace: salesforce-read
      baseUri: "https://johnsoncontrols.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: leads
          path: "/sobjects/Lead/{{lead_id}}"
          inputParameters:
            - name: lead_id
              in: path
          operations:
            - name: get-lead
              method: GET
    - type: http
      namespace: salesforce-write
      baseUri: "https://johnsoncontrols.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: leads
          path: "/sobjects/Lead/{{lead_id}}"
          inputParameters:
            - name: lead_id
              in: path
          operations:
            - name: update-lead
              method: PATCH

When an opportunity closes, creates a Jira project board, provisions team in Okta, and notifies delivery.

naftiko: "0.5"
info:
  label: "Salesforce Opportunity to Project Handoff"
  description: "When an opportunity closes, creates a Jira project board, provisions team in Okta, and notifies delivery."
  tags:
    - sales
    - salesforce
    - jira
    - okta
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: salesforce_opportunity_to_project_handoff
          description: "When an opportunity closes, creates a Jira project board, provisions team in Okta, and notifies delivery."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Salesforce Opportunity to Project Handoff: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Salesforce Opportunity to Project Handoff for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

When a Salesforce Service Cloud case for a building controls customer exceeds its SLA threshold, creates a ServiceNow escalation incident and notifies the customer success team via Microsoft Teams.

naftiko: "0.5"
info:
  label: "Salesforce Service Case SLA Escalation"
  description: "When a Salesforce Service Cloud case for a building controls customer exceeds its SLA threshold, creates a ServiceNow escalation incident and notifies the customer success team via Microsoft Teams."
  tags:
    - customer-support
    - salesforce
    - servicenow
    - microsoft-teams
    - sla
    - escalation
capability:
  exposes:
    - type: mcp
      namespace: customer-support-ops
      port: 8080
      tools:
        - name: escalate-sla-breach
          description: "Given a Salesforce case ID that has breached SLA, create a ServiceNow escalation incident and notify the customer success Teams channel with case context."
          inputParameters:
            - name: case_id
              in: body
              type: string
              description: "The Salesforce Service Cloud case ID that breached SLA."
            - name: hours_overdue
              in: body
              type: number
              description: "Number of hours the case is past its SLA deadline."
          steps:
            - name: get-case
              type: call
              call: "salesforce.get-case"
              with:
                case_id: "{{case_id}}"
            - name: create-escalation
              type: call
              call: "servicenow.create-incident"
              with:
                short_description: "SLA breach: Salesforce case {{case_id}} for {{get-case.account_name}}"
                category: "customer_support"
                urgency: "1"
            - name: notify-cs-team
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_customer_success_channel_id"
                text: "SLA Breach: Case {{case_id}} | Customer: {{get-case.account_name}} | {{hours_overdue}}h overdue | Incident: {{create-escalation.number}}"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://johnsoncontrols.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: cases
          path: "/sobjects/Case/{{case_id}}"
          inputParameters:
            - name: case_id
              in: path
          operations:
            - name: get-case
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

When a service contract nears renewal, creates a Jira task, notifies account manager, and updates contract tracker.

naftiko: "0.5"
info:
  label: "Salesforce Service Contract Renewal Alert"
  description: "When a service contract nears renewal, creates a Jira task, notifies account manager, and updates contract tracker."
  tags:
    - sales
    - salesforce
    - jira
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: salesforce_service_contract_renewal_alert
          description: "When a service contract nears renewal, creates a Jira task, notifies account manager, and updates contract tracker."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Salesforce Service Contract Renewal Alert: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Salesforce Service Contract Renewal Alert for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Onboards a subcontractor in SAP Ariba, provisions Okta access, and notifies project manager via Teams.

naftiko: "0.5"
info:
  label: "SAP Ariba Subcontractor Onboarding"
  description: "Onboards a subcontractor in SAP Ariba, provisions Okta access, and notifies project manager via Teams."
  tags:
    - procurement
    - sap-ariba
    - okta
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: sap_ariba_subcontractor_onboarding
          description: "Onboards a subcontractor in SAP Ariba, provisions Okta access, and notifies project manager via Teams."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "SAP Ariba Subcontractor Onboarding: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "SAP Ariba Subcontractor Onboarding for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

When a new supplier is approved in SAP Ariba, creates the vendor master record in SAP S/4HANA and notifies the procurement team in Microsoft Teams.

naftiko: "0.5"
info:
  label: "SAP Ariba Supplier Onboarding"
  description: "When a new supplier is approved in SAP Ariba, creates the vendor master record in SAP S/4HANA and notifies the procurement team in Microsoft Teams."
  tags:
    - procurement
    - sap-ariba
    - sap
    - microsoft-teams
    - supplier-management
capability:
  exposes:
    - type: mcp
      namespace: supplier-ops
      port: 8080
      tools:
        - name: onboard-approved-supplier
          description: "Given a SAP Ariba supplier ID, retrieve the approved supplier profile and create the vendor master record in SAP S/4HANA. Notify the procurement team via Microsoft Teams."
          inputParameters:
            - name: ariba_supplier_id
              in: body
              type: string
              description: "The SAP Ariba supplier ID of the newly approved supplier."
          steps:
            - name: get-supplier
              type: call
              call: "ariba.get-supplier"
              with:
                supplier_id: "{{ariba_supplier_id}}"
            - name: create-vendor
              type: call
              call: "sap.create-vendor"
              with:
                vendor_name: "{{get-supplier.name}}"
                tax_id: "{{get-supplier.tax_id}}"
                country: "{{get-supplier.country}}"
            - name: notify-procurement
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_procurement_channel_id"
                text: "New supplier onboarded: {{get-supplier.name}} (Ariba ID: {{ariba_supplier_id}}, SAP vendor: {{create-vendor.vendor_id}})"
  consumes:
    - type: http
      namespace: ariba
      baseUri: "https://openapi.ariba.com/api/supplier-profile/v1"
      authentication:
        type: bearer
        token: "$secrets.ariba_token"
      resources:
        - name: suppliers
          path: "/suppliers/{{supplier_id}}"
          inputParameters:
            - name: supplier_id
              in: path
          operations:
            - name: get-supplier
              method: GET
    - type: http
      namespace: sap
      baseUri: "https://jci-s4.sap.com/sap/opu/odata/sap/API_BUSINESS_PARTNER"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: vendors
          path: "/A_Supplier"
          operations:
            - name: create-vendor
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

When an expense report is submitted in SAP Concur, retrieves the report details and routes the approval notification to the designated approver via Microsoft Teams.

naftiko: "0.5"
info:
  label: "SAP Concur Expense Report Approval"
  description: "When an expense report is submitted in SAP Concur, retrieves the report details and routes the approval notification to the designated approver via Microsoft Teams."
  tags:
    - finance
    - expense-management
    - sap-concur
    - microsoft-teams
    - approval
capability:
  exposes:
    - type: mcp
      namespace: finance-expense
      port: 8080
      tools:
        - name: process-expense-report
          description: "Given a SAP Concur expense report ID, retrieve the report details and route the approval notification to the designated approver via Microsoft Teams."
          inputParameters:
            - name: report_id
              in: body
              type: string
              description: "The SAP Concur expense report ID to process."
          steps:
            - name: get-report
              type: call
              call: "concur.get-expense-report"
              with:
                report_id: "{{report_id}}"
            - name: notify-approver
              type: call
              call: "msteams.send-message"
              with:
                recipient_upn: "{{get-report.approver_email}}"
                text: "Expense report {{report_id}} from {{get-report.submitter_name}} for {{get-report.total_amount}} {{get-report.currency}} requires your approval in SAP Concur."
  consumes:
    - type: http
      namespace: concur
      baseUri: "https://www.concursolutions.com/api/v3.0"
      authentication:
        type: bearer
        token: "$secrets.concur_token"
      resources:
        - name: expense-reports
          path: "/expense/reportdetails/{{report_id}}"
          inputParameters:
            - name: report_id
              in: path
          operations:
            - name: get-expense-report
              method: GET
    - 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

Retrieves a general ledger account balance from SAP by company code and GL account number.

naftiko: "0.5"
info:
  label: "SAP GL Account Balance Lookup"
  description: "Retrieves a general ledger account balance from SAP by company code and GL account number."
  tags:
    - finance
    - sap
capability:
  exposes:
    - type: mcp
      namespace: erp-finance
      port: 8080
      tools:
        - name: get-gl-balance
          description: "Look up an SAP GL account balance."
          inputParameters:
            - name: company_code
              type: string
              description: "SAP company code."
            - name: gl_account
              type: string
              description: "GL account number."
          call: sap.get-gl-balance
          with:
            company_code: "{{company_code}}"
            gl_account: "{{gl_account}}"
          outputParameters:
            - name: balance
              type: string
              mapping: "$.d.EndingBalanceAmtInCoCodeCrcy"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://jci-s4.sap.com/sap/opu/odata/sap/API_JOURNALENTRYITEMBASIC_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: gl-accounts
          path: "/A_GLAccountBalance(CompanyCode='{{company_code}}',GLAccount='{{gl_account}}')"
          inputParameters:
            - name: company_code
              in: path
            - name: gl_account
              in: path
          operations:
            - name: get-gl-balance
              method: GET

Processes goods receipt in SAP for building materials, updates Snowflake inventory, and notifies warehouse.

naftiko: "0.5"
info:
  label: "SAP Goods Receipt for Building Materials"
  description: "Processes goods receipt in SAP for building materials, updates Snowflake inventory, and notifies warehouse."
  tags:
    - supply-chain
    - sap
    - snowflake
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: sap_goods_receipt_building_materials
          description: "Processes goods receipt in SAP for building materials, updates Snowflake inventory, and notifies warehouse."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "SAP Goods Receipt for Building Materials: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "SAP Goods Receipt for Building Materials for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Performs three-way match between SAP PO, goods receipt, and invoice, posting exceptions to AP team.

naftiko: "0.5"
info:
  label: "SAP Invoice Three-Way Match"
  description: "Performs three-way match between SAP PO, goods receipt, and invoice, posting exceptions to AP team."
  tags:
    - finance
    - procurement
    - sap
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: sap_invoice_three_way_match
          description: "Performs three-way match between SAP PO, goods receipt, and invoice, posting exceptions to AP team."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "SAP Invoice Three-Way Match: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "SAP Invoice Three-Way Match for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

At month-end, retrieves all open AP invoices from SAP for a given company code and fiscal period, creates a ServiceNow finance task, and posts the reconciliation summary to the Finance Teams channel.

naftiko: "0.5"
info:
  label: "SAP Period Close AP Reconciliation"
  description: "At month-end, retrieves all open AP invoices from SAP for a given company code and fiscal period, creates a ServiceNow finance task, and posts the reconciliation summary to the Finance Teams channel."
  tags:
    - finance
    - erp
    - sap
    - servicenow
    - microsoft-teams
    - period-close
capability:
  exposes:
    - type: mcp
      namespace: finance-close
      port: 8080
      tools:
        - name: run-ap-period-close
          description: "Given a SAP company code and fiscal period, retrieve open AP invoices, open a ServiceNow finance reconciliation task, and post the summary to the Finance Teams channel."
          inputParameters:
            - name: company_code
              in: body
              type: string
              description: "The SAP company code for the legal entity being closed."
            - name: fiscal_period
              in: body
              type: string
              description: "The fiscal period in YYYYMM format."
          steps:
            - name: get-open-invoices
              type: call
              call: "sap.list-open-invoices"
              with:
                company_code: "{{company_code}}"
                fiscal_period: "{{fiscal_period}}"
            - name: create-close-task
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "AP period close: {{company_code}} / {{fiscal_period}}"
                category: "finance"
                assigned_group: "Finance_AP"
            - name: post-summary
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_finance_channel_id"
                text: "AP Close: {{company_code}} / {{fiscal_period}} | Open invoices: {{get-open-invoices.invoice_count}} | Task: {{create-close-task.number}}"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://jci-s4.sap.com/sap/opu/odata/sap/API_SUPPLIER_INVOICE_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: supplier-invoices
          path: "/A_SupplierInvoice"
          operations:
            - name: list-open-invoices
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Orchestrates month-end close by pulling SAP GL balances, running Snowflake variance analysis, and posting to finance.

naftiko: "0.5"
info:
  label: "SAP Period Close Reconciliation"
  description: "Orchestrates month-end close by pulling SAP GL balances, running Snowflake variance analysis, and posting to finance."
  tags:
    - finance
    - sap
    - snowflake
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: sap_period_close_reconciliation
          description: "Orchestrates month-end close by pulling SAP GL balances, running Snowflake variance analysis, and posting to finance."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "SAP Period Close Reconciliation: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "SAP Period Close Reconciliation for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Pulls project cost data from SAP, validates against Snowflake budget forecasts, and posts variance report to the project controls team.

naftiko: "0.5"
info:
  label: "SAP Project Cost Tracking"
  description: "Pulls project cost data from SAP, validates against Snowflake budget forecasts, and posts variance report to the project controls team."
  tags:
    - finance
    - capital-projects
    - sap
    - snowflake
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: project-finance
      port: 8080
      tools:
        - name: track-project-costs
          description: "Given a project code, pull costs from SAP, validate against budget, and report."
          inputParameters:
            - name: project_code
              type: string
              description: "SAP project code."
            - name: period
              type: string
              description: "Reporting period."
          steps:
            - name: get-costs
              type: call
              call: sap.get-project-costs
              with:
                project: "{{project_code}}"
                period: "{{period}}"
            - name: get-budget
              type: call
              call: snowflake.query-budget
              with:
                project: "{{project_code}}"
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_project_controls_channel"
                text: "Project {{project_code}} ({{period}}): Actual: ${{get-costs.total}} | Budget: ${{get-budget.budget}} | Variance: {{get-budget.variance_pct}}%"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://jci-s4.sap.com/sap/opu/odata/sap/API_PROJECT_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: projects
          path: "/A_Project"
          operations:
            - name: get-project-costs
              method: GET
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: query-budget
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/project-controls/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Looks up a SAP S/4HANA purchase order by number and returns the header status, supplier name, total value, and delivery schedule for procurement visibility.

naftiko: "0.5"
info:
  label: "SAP Purchase Order Status Lookup"
  description: "Looks up a SAP S/4HANA purchase order by number and returns the header status, supplier name, total value, and delivery schedule for procurement visibility."
  tags:
    - finance
    - procurement
    - sap
    - erp
capability:
  exposes:
    - type: mcp
      namespace: erp-procurement
      port: 8080
      tools:
        - name: get-purchase-order
          description: "Look up a SAP purchase order by PO number. Returns status, supplier, total value, and delivery schedule. Use for procurement status checks and AP reconciliation."
          inputParameters:
            - name: po_number
              in: body
              type: string
              description: "The SAP purchase order number to look up."
          call: "sap.get-po"
          with:
            po_number: "{{po_number}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.d.OverallStatus"
            - name: vendor
              type: string
              mapping: "$.d.Supplier.CompanyName"
            - name: total_value
              type: string
              mapping: "$.d.TotalAmount"
            - name: currency
              type: string
              mapping: "$.d.TransactionCurrency"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://jci-s4.sap.com/sap/opu/odata/sap/MM_PUR_PO_MAINT_V2_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: purchase-orders
          path: "/A_PurchaseOrder('{{po_number}}')"
          inputParameters:
            - name: po_number
              in: path
          operations:
            - name: get-po
              method: GET
              outputRawFormat: xml

Retrieves vendor master data from SAP by vendor number, returning company name and payment terms.

naftiko: "0.5"
info:
  label: "SAP Vendor Master Lookup"
  description: "Retrieves vendor master data from SAP by vendor number, returning company name and payment terms."
  tags:
    - procurement
    - sap
capability:
  exposes:
    - type: mcp
      namespace: erp-vendors
      port: 8080
      tools:
        - name: get-vendor
          description: "Look up an SAP vendor by number."
          inputParameters:
            - name: vendor_number
              type: string
              description: "SAP vendor number."
          call: sap.get-vendor
          with:
            vendor_number: "{{vendor_number}}"
          outputParameters:
            - name: name
              type: string
              mapping: "$.d.SupplierName"
            - name: payment_terms
              type: string
              mapping: "$.d.PaymentTerms"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://jci-s4.sap.com/sap/opu/odata/sap/API_BUSINESS_PARTNER"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: suppliers
          path: "/A_Supplier('{{vendor_number}}')"
          inputParameters:
            - name: vendor_number
              in: path
          operations:
            - name: get-vendor
              method: GET

Processes warranty claims in SAP, creates Salesforce service cases, and notifies warranty team via Teams.

naftiko: "0.5"
info:
  label: "SAP Warranty Claim Processing"
  description: "Processes warranty claims in SAP, creates Salesforce service cases, and notifies warranty team via Teams."
  tags:
    - warranty
    - sap
    - salesforce
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: sap_warranty_claim_processing
          description: "Processes warranty claims in SAP, creates Salesforce service cases, and notifies warranty team via Teams."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "SAP Warranty Claim Processing: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "SAP Warranty Claim Processing for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Checks camera system health via Datadog, creates ServiceNow incidents for offline cameras, and notifies security.

naftiko: "0.5"
info:
  label: "Security Camera System Health Check"
  description: "Checks camera system health via Datadog, creates ServiceNow incidents for offline cameras, and notifies security."
  tags:
    - security
    - datadog
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: security_camera_system_health_check
          description: "Checks camera system health via Datadog, creates ServiceNow incidents for offline cameras, and notifies security."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Security Camera System Health Check: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Security Camera System Health Check for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

When an SLA is breached, creates ServiceNow escalation, notifies account team, and updates Salesforce.

naftiko: "0.5"
info:
  label: "Service Level Agreement Breach Escalation"
  description: "When an SLA is breached, creates ServiceNow escalation, notifies account team, and updates Salesforce."
  tags:
    - itsm
    - sla
    - servicenow
    - salesforce
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: service_level_agreement_breach_escalation
          description: "When an SLA is breached, creates ServiceNow escalation, notifies account team, and updates Salesforce."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Service Level Agreement Breach Escalation: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Service Level Agreement Breach Escalation for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Retrieves a configuration item from ServiceNow CMDB by asset tag, returning model, status, and location.

naftiko: "0.5"
info:
  label: "ServiceNow CMDB Asset Lookup"
  description: "Retrieves a configuration item from ServiceNow CMDB by asset tag, returning model, status, and location."
  tags:
    - itsm
    - asset-management
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: cmdb
      port: 8080
      tools:
        - name: get-cmdb-asset
          description: "Look up a CMDB configuration item by asset tag."
          inputParameters:
            - name: asset_tag
              type: string
              description: "Asset tag identifier."
          call: servicenow.get-ci
          with:
            asset_tag: "{{asset_tag}}"
          outputParameters:
            - name: model
              type: string
              mapping: "$.result[0].model_id.display_value"
            - name: status
              type: string
              mapping: "$.result[0].install_status"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: cmdb
          path: "/table/cmdb_ci?sysparm_query=asset_tag={{asset_tag}}"
          inputParameters:
            - name: asset_tag
              in: query
          operations:
            - name: get-ci
              method: GET

Creates and dispatches a ServiceNow field service work order for building equipment maintenance, assigns to the nearest available technician, and sends dispatch confirmation via Microsoft Teams.

naftiko: "0.5"
info:
  label: "ServiceNow Field Service Work Order Dispatch"
  description: "Creates and dispatches a ServiceNow field service work order for building equipment maintenance, assigns to the nearest available technician, and sends dispatch confirmation via Microsoft Teams."
  tags:
    - field-service
    - servicenow
    - microsoft-teams
    - building-automation
    - maintenance
capability:
  exposes:
    - type: mcp
      namespace: field-service-ops
      port: 8080
      tools:
        - name: dispatch-work-order
          description: "Given a building ID, equipment type, fault description, and priority, create a ServiceNow field service work order and notify the dispatch team via Microsoft Teams."
          inputParameters:
            - name: building_id
              in: body
              type: string
              description: "The building or site identifier requiring service."
            - name: equipment_type
              in: body
              type: string
              description: "The type of equipment requiring maintenance (e.g., chiller, AHU, BAS controller)."
            - name: fault_description
              in: body
              type: string
              description: "Description of the fault or maintenance required."
            - name: priority
              in: body
              type: string
              description: "Work order priority: emergency, urgent, or routine."
          steps:
            - name: create-work-order
              type: call
              call: "servicenow.create-work-order"
              with:
                short_description: "{{equipment_type}} maintenance: {{fault_description}} at {{building_id}}"
                priority: "{{priority}}"
                location: "{{building_id}}"
            - name: notify-dispatch
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_field_service_channel_id"
                text: "Work order created: {{priority}} | Building: {{building_id}} | Equipment: {{equipment_type}} | WO: {{create-work-order.number}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: work-orders
          path: "/table/wm_order"
          operations:
            - name: create-work-order
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

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

naftiko: "0.5"
info:
  label: "ServiceNow Incident Lookup"
  description: "Retrieves a ServiceNow incident by number, returning state, priority, and assignment group."
  tags:
    - itsm
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: itsm
      port: 8080
      tools:
        - name: get-incident
          description: "Look up a ServiceNow incident by number."
          inputParameters:
            - name: incident_number
              type: string
              description: "ServiceNow incident number."
          call: servicenow.get-incident
          with:
            number: "{{incident_number}}"
          outputParameters:
            - name: state
              type: string
              mapping: "$.result[0].state"
            - name: priority
              type: string
              mapping: "$.result[0].priority"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident?sysparm_query=number={{number}}"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-incident
              method: GET

Searches SharePoint Online for documents matching a keyword query, returning file names and URLs.

naftiko: "0.5"
info:
  label: "SharePoint Document Search"
  description: "Searches SharePoint Online for documents matching a keyword query, returning file names and URLs."
  tags:
    - collaboration
    - sharepoint
capability:
  exposes:
    - type: mcp
      namespace: documents
      port: 8080
      tools:
        - name: search-documents
          description: "Search SharePoint for documents by keyword."
          inputParameters:
            - name: query
              type: string
              description: "Search keyword."
          call: sharepoint.search
          with:
            query: "{{query}}"
          outputParameters:
            - name: results
              type: string
              mapping: "$.value"
  consumes:
    - type: http
      namespace: sharepoint
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: search
          path: "/search/query"
          operations:
            - name: search
              method: POST

Queries Snowflake for building IoT telemetry data by building ID, returning temperature, humidity, and occupancy metrics.

naftiko: "0.5"
info:
  label: "Snowflake Building Telemetry Query"
  description: "Queries Snowflake for building IoT telemetry data by building ID, returning temperature, humidity, and occupancy metrics."
  tags:
    - iot
    - building-automation
    - snowflake
capability:
  exposes:
    - type: mcp
      namespace: building-analytics
      port: 8080
      tools:
        - name: query-building-telemetry
          description: "Query building telemetry data from Snowflake."
          inputParameters:
            - name: building_id
              type: string
              description: "Building identifier."
          call: snowflake.run-query
          with:
            building_id: "{{building_id}}"
          outputParameters:
            - name: avg_temperature
              type: string
              mapping: "$.data[0].AVG_TEMP"
            - name: occupancy
              type: string
              mapping: "$.data[0].OCCUPANCY"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST

When a Snowflake ETL pipeline fails, retrieves error details, creates Jira ticket, and notifies data team.

naftiko: "0.5"
info:
  label: "Snowflake ETL Pipeline Failure Response"
  description: "When a Snowflake ETL pipeline fails, retrieves error details, creates Jira ticket, and notifies data team."
  tags:
    - data-engineering
    - snowflake
    - jira
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: snowflake_etl_pipeline_failure_response
          description: "When a Snowflake ETL pipeline fails, retrieves error details, creates Jira ticket, and notifies data team."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Snowflake ETL Pipeline Failure Response: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Snowflake ETL Pipeline Failure Response for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

When Splunk detects a BMS security event, creates ServiceNow incident, queries Okta for context, and alerts SOC.

naftiko: "0.5"
info:
  label: "Splunk BMS Security Event Triage"
  description: "When Splunk detects a BMS security event, creates ServiceNow incident, queries Okta for context, and alerts SOC."
  tags:
    - security
    - splunk
    - servicenow
    - okta
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: splunk_bms_security_event_triage
          description: "When Splunk detects a BMS security event, creates ServiceNow incident, queries Okta for context, and alerts SOC."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Splunk BMS Security Event Triage: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Splunk BMS Security Event Triage for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Executes a Splunk search query against building management system logs and returns matching events.

naftiko: "0.5"
info:
  label: "Splunk Log Search"
  description: "Executes a Splunk search query against building management system logs and returns matching events."
  tags:
    - observability
    - splunk
capability:
  exposes:
    - type: mcp
      namespace: logging
      port: 8080
      tools:
        - name: search-logs
          description: "Run a Splunk search query and return results."
          inputParameters:
            - name: search_query
              type: string
              description: "SPL search query string."
          call: splunk.run-search
          with:
            search: "{{search_query}}"
          outputParameters:
            - name: results
              type: string
              mapping: "$.results"
  consumes:
    - type: http
      namespace: splunk
      baseUri: "https://splunk.johnsoncontrols.com:8089/services"
      authentication:
        type: bearer
        token: "$secrets.splunk_token"
      resources:
        - name: search-jobs
          path: "/search/jobs"
          operations:
            - name: run-search
              method: POST

When a tenant submits a comfort complaint, creates ServiceNow incident, queries telemetry, and dispatches technician.

naftiko: "0.5"
info:
  label: "Tenant Comfort Complaint Workflow"
  description: "When a tenant submits a comfort complaint, creates ServiceNow incident, queries telemetry, and dispatches technician."
  tags:
    - facilities
    - comfort
    - servicenow
    - snowflake
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: tenant_comfort_complaint_workflow
          description: "When a tenant submits a comfort complaint, creates ServiceNow incident, queries telemetry, and dispatches technician."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Tenant Comfort Complaint Workflow: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Tenant Comfort Complaint Workflow for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Analyzes thermal comfort data from Snowflake, adjusts HVAC setpoints via OpenBlue, and posts report.

naftiko: "0.5"
info:
  label: "Thermal Comfort Optimization Workflow"
  description: "Analyzes thermal comfort data from Snowflake, adjusts HVAC setpoints via OpenBlue, and posts report."
  tags:
    - building-automation
    - hvac
    - snowflake
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: thermal_comfort_optimization_workflow
          description: "Analyzes thermal comfort data from Snowflake, adjusts HVAC setpoints via OpenBlue, and posts report."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Thermal Comfort Optimization Workflow: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Thermal Comfort Optimization Workflow for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

When a vendor contract approaches expiry, creates a Jira task, notifies category manager, and logs in Snowflake.

naftiko: "0.5"
info:
  label: "Vendor Contract Renewal Workflow"
  description: "When a vendor contract approaches expiry, creates a Jira task, notifies category manager, and logs in Snowflake."
  tags:
    - procurement
    - jira
    - microsoft-teams
    - snowflake
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: vendor_contract_renewal_workflow
          description: "When a vendor contract approaches expiry, creates a Jira task, notifies category manager, and logs in Snowflake."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Vendor Contract Renewal Workflow: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Vendor Contract Renewal Workflow for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Launches annual review by pulling headcount from Workday, creating Jira tracking epic, and notifying HR partners.

naftiko: "0.5"
info:
  label: "Workday Annual Review Cycle Launch"
  description: "Launches annual review by pulling headcount from Workday, creating Jira tracking epic, and notifying HR partners."
  tags:
    - hr
    - performance
    - workday
    - jira
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: workday_annual_review_cycle_launch
          description: "Launches annual review by pulling headcount from Workday, creating Jira tracking epic, and notifying HR partners."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Workday Annual Review Cycle Launch: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Workday Annual Review Cycle Launch for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Queries Workday for incomplete benefits enrollments and sends reminders via Teams.

naftiko: "0.5"
info:
  label: "Workday Benefits Enrollment Reminder"
  description: "Queries Workday for incomplete benefits enrollments and sends reminders via Teams."
  tags:
    - hr
    - benefits
    - workday
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: workday_benefits_enrollment_reminder
          description: "Queries Workday for incomplete benefits enrollments and sends reminders via Teams."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Workday Benefits Enrollment Reminder: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Workday Benefits Enrollment Reminder for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Validates budget in SAP for a Workday compensation change, notifies manager, and logs approval in ServiceNow.

naftiko: "0.5"
info:
  label: "Workday Compensation Change Approval"
  description: "Validates budget in SAP for a Workday compensation change, notifies manager, and logs approval in ServiceNow."
  tags:
    - hr
    - workday
    - sap
    - microsoft-teams
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: workday_compensation_change_approval
          description: "Validates budget in SAP for a Workday compensation change, notifies manager, and logs approval in ServiceNow."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Workday Compensation Change Approval: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Workday Compensation Change Approval for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Retrieves an employee profile from Workday by worker ID, returning name, title, department, and manager.

naftiko: "0.5"
info:
  label: "Workday Employee Profile Lookup"
  description: "Retrieves an employee profile from Workday by worker ID, returning name, title, department, and manager."
  tags:
    - hr
    - workday
capability:
  exposes:
    - type: mcp
      namespace: hr-profiles
      port: 8080
      tools:
        - name: get-employee-profile
          description: "Look up a Workday employee by worker ID."
          inputParameters:
            - name: worker_id
              type: string
              description: "Workday worker ID."
          call: workday.get-worker
          with:
            worker_id: "{{worker_id}}"
          outputParameters:
            - name: full_name
              type: string
              mapping: "$.worker.legalName.fullName"
            - name: title
              type: string
              mapping: "$.worker.position.title"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1/johnson-controls"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET

When a new hire is confirmed in Workday, creates Okta account, provisions access, and notifies IT support.

naftiko: "0.5"
info:
  label: "Workday New Hire IT Provisioning"
  description: "When a new hire is confirmed in Workday, creates Okta account, provisions access, and notifies IT support."
  tags:
    - hr
    - workday
    - okta
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: jci-ops
      port: 8080
      tools:
        - name: workday_new_hire_it_provisioning
          description: "When a new hire is confirmed in Workday, creates Okta account, provisions access, and notifies IT support."
          inputParameters:
            - name: entity_id
              type: string
              description: "Primary entity identifier." 
            - name: context
              type: string
              description: "Additional context for the workflow." 
          steps:
            - name: gather-data
              type: call
              call: snowflake.run-query
              with:
                entity_id: "{{entity_id}}" 
                context: "{{context}}" 
            - name: create-action
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Workday New Hire IT Provisioning: {{entity_id}}" 
                description: "Data: {{gather-data.results}}" 
            - name: notify-team
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "$secrets.teams_ops_channel" 
                text: "Workday New Hire IT Provisioning for {{entity_id}} | Action: {{create-action.number}}" 
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://johnsoncontrols.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: sql-statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          operations:
            - name: post-channel-message
              method: POST

Retrieves an employee time off balance from Workday by worker ID.

naftiko: "0.5"
info:
  label: "Workday Time Off Balance Lookup"
  description: "Retrieves an employee time off balance from Workday by worker ID."
  tags:
    - hr
    - workday
capability:
  exposes:
    - type: mcp
      namespace: hr-time
      port: 8080
      tools:
        - name: get-time-off-balance
          description: "Look up time off balance by worker ID."
          inputParameters:
            - name: worker_id
              type: string
              description: "Workday worker ID."
          call: workday.get-time-off
          with:
            worker_id: "{{worker_id}}"
          outputParameters:
            - name: vacation_balance
              type: string
              mapping: "$.timeOffBalance.vacation"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1/johnson-controls"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: time-off
          path: "/workers/{{worker_id}}/timeOffBalance"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-time-off
              method: GET

Checks Workday for mandatory safety training completion rates by site and flags non-compliant sites via a ServiceNow task and Microsoft Teams notification to site managers.

naftiko: "0.5"
info:
  label: "Workday Training Compliance Alert"
  description: "Checks Workday for mandatory safety training completion rates by site and flags non-compliant sites via a ServiceNow task and Microsoft Teams notification to site managers."
  tags:
    - hr
    - compliance
    - workday
    - servicenow
    - microsoft-teams
    - safety
capability:
  exposes:
    - type: mcp
      namespace: safety-compliance
      port: 8080
      tools:
        - name: check-safety-training-compliance
          description: "Given a mandatory safety training course ID and completion threshold, check Workday completion rates by site and alert site managers for non-compliant sites via Microsoft Teams."
          inputParameters:
            - name: course_id
              in: body
              type: string
              description: "The Workday safety training course ID to check."
            - name: completion_threshold_pct
              in: body
              type: number
              description: "Required completion percentage to be compliant (e.g., 100)."
          steps:
            - name: get-completion-rates
              type: call
              call: "workday.get-course-completion-rates"
              with:
                course_id: "{{course_id}}"
            - name: create-compliance-task
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "Safety training compliance gap: course {{course_id}}"
                category: "safety_compliance"
                assigned_group: "EHS_Compliance"
            - name: alert-hr
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_ehs_channel_id"
                text: "Safety Compliance Alert: Course {{course_id}} — sites below {{completion_threshold_pct}}% threshold | Task: {{create-compliance-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: course-completions
          path: "/learningCourseCompletions"
          operations:
            - name: get-course-completion-rates
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://johnsoncontrols.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST