IBM Capabilities

Naftiko 0.5 capability definitions for IBM - 103 capabilities showing integration workflows and service orchestrations.

Sort
Expand

Fetches IBM campaign performance metrics from Adobe Analytics and posts a weekly summary report to Salesforce as an activity log on the relevant campaign record.

naftiko: "0.5"
info:
  label: "Adobe Analytics Campaign Performance Digest"
  description: "Fetches IBM campaign performance metrics from Adobe Analytics and posts a weekly summary report to Salesforce as an activity log on the relevant campaign record."
  tags:
    - marketing
    - analytics
    - adobe-analytics
    - salesforce
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: marketing-reporting
      port: 8080
      tools:
        - name: digest-campaign-performance
          description: "Given an Adobe Analytics report suite ID and a Salesforce campaign ID, retrieve key campaign metrics and log a performance summary on the Salesforce campaign record."
          inputParameters:
            - name: report_suite_id
              in: body
              type: string
              description: "Adobe Analytics report suite ID."
            - name: campaign_id
              in: body
              type: string
              description: "Salesforce campaign record ID."
            - name: date_range
              in: body
              type: string
              description: "Date range string for the report, e.g. 2025-01-01/2025-01-31."
          steps:
            - name: get-analytics
              type: call
              call: "adobe-analytics.get-report"
              with:
                rsid: "{{report_suite_id}}"
                dateRange: "{{date_range}}"
            - name: log-activity
              type: call
              call: "salesforce-campaign.create-activity"
              with:
                WhatId: "{{campaign_id}}"
                Subject: "Campaign Performance Digest — {{date_range}}"
                Description: "Visits: {{get-analytics.visits}} | Conversions: {{get-analytics.conversions}} | Revenue: {{get-analytics.revenue}}"
  consumes:
    - type: http
      namespace: adobe-analytics
      baseUri: "https://analytics.adobe.io/api/{{company_id}}/reports"
      authentication:
        type: bearer
        token: "$secrets.adobe_analytics_token"
      resources:
        - name: reports
          path: "/ranked"
          operations:
            - name: get-report
              method: POST
    - type: http
      namespace: salesforce-campaign
      baseUri: "https://ibm.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: activities
          path: "/sobjects/Task"
          operations:
            - name: create-activity
              method: POST

Compares ADP payroll totals against Workday compensation records and creates a ServiceNow task for any discrepancies found.

naftiko: "0.5"
info:
  label: "ADP Payroll Discrepancy to Workday Review"
  description: "Compares ADP payroll totals against Workday compensation records and creates a ServiceNow task for any discrepancies found."
  tags:
    - hr
    - finance
    - adp
    - workday
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: payroll-audit
      port: 8080
      tools:
        - name: audit-payroll
          description: "Given a payroll period, compare ADP run totals to Workday compensation and flag discrepancies."
          inputParameters:
            - name: payroll_period
              in: body
              type: string
              description: "Payroll period code, e.g. 2026-03."
          steps:
            - name: get-adp-totals
              type: call
              call: "adp.get-payroll-summary"
              with:
                period: "{{payroll_period}}"
            - name: get-workday-totals
              type: call
              call: "workday.get-comp-totals"
              with:
                period: "{{payroll_period}}"
            - name: create-review-task
              type: call
              call: "servicenow-payroll.create-task"
              with:
                short_description: "Payroll audit: ADP={{get-adp-totals.total}} vs Workday={{get-workday-totals.total}} for {{payroll_period}}"
                assignment_group: "HR_Payroll"
  consumes:
    - type: http
      namespace: adp
      baseUri: "https://api.adp.com"
      authentication:
        type: bearer
        token: "$secrets.adp_token"
      resources:
        - name: payroll
          path: "/payroll/v1/payroll-output"
          inputParameters:
            - name: period
              in: query
          operations:
            - name: get-payroll-summary
              method: GET
    - type: http
      namespace: workday
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: compensation
          path: "/ibm/compensation/totals"
          inputParameters:
            - name: period
              in: query
          operations:
            - name: get-comp-totals
              method: GET
    - type: http
      namespace: servicenow-payroll
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST

Lists IAM-granted access to IBM S3 buckets and flags any public or cross-account permissions. Creates a ServiceNow security task for each non-compliant bucket found.

naftiko: "0.5"
info:
  label: "Amazon S3 Data Lake Access Review"
  description: "Lists IAM-granted access to IBM S3 buckets and flags any public or cross-account permissions. Creates a ServiceNow security task for each non-compliant bucket found."
  tags:
    - cloud
    - security
    - aws
    - servicenow
    - access-review
capability:
  exposes:
    - type: mcp
      namespace: s3-access-review
      port: 8080
      tools:
        - name: review-s3-access
          description: "Given an AWS account ID, enumerate S3 bucket policies and ACLs for public or cross-account access. Create a ServiceNow security task for each non-compliant bucket."
          inputParameters:
            - name: aws_account_id
              in: body
              type: string
              description: "AWS account ID to review."
          steps:
            - name: list-buckets
              type: call
              call: "aws-s3.list-buckets"
              with:
                account_id: "{{aws_account_id}}"
            - name: create-security-task
              type: call
              call: "servicenow-s3.create-task"
              with:
                short_description: "S3 access review: {{aws_account_id}} — non-compliant buckets found"
                description: "Non-compliant buckets: {{list-buckets.non_compliant_count}}"
                assignment_group: "Cloud_Security"
  consumes:
    - type: http
      namespace: aws-s3
      baseUri: "https://s3.amazonaws.com"
      authentication:
        type: bearer
        token: "$secrets.aws_s3_token"
      resources:
        - name: buckets
          path: "/"
          operations:
            - name: list-buckets
              method: GET
    - type: http
      namespace: servicenow-s3
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST

When an AWS CloudWatch alarm enters ALARM state, creates a ServiceNow incident and notifies the infrastructure team via Slack.

naftiko: "0.5"
info:
  label: "AWS CloudWatch Alarm to ServiceNow Incident"
  description: "When an AWS CloudWatch alarm enters ALARM state, creates a ServiceNow incident and notifies the infrastructure team via Slack."
  tags:
    - cloud
    - itsm
    - aws
    - servicenow
    - slack
capability:
  exposes:
    - type: mcp
      namespace: cloud-ops
      port: 8080
      tools:
        - name: handle-cloudwatch-alarm
          description: "Given a CloudWatch alarm name, retrieve alarm details and create a ServiceNow incident with Slack notification."
          inputParameters:
            - name: alarm_name
              in: body
              type: string
              description: "CloudWatch alarm name."
          steps:
            - name: get-alarm
              type: call
              call: "cloudwatch.describe-alarm"
              with:
                alarm_name: "{{alarm_name}}"
            - name: create-incident
              type: call
              call: "servicenow-ops.create-incident"
              with:
                short_description: "CloudWatch alarm: {{alarm_name}} — {{get-alarm.StateReason}}"
                urgency: "2"
                impact: "2"
                assignment_group: "Cloud_Infrastructure"
            - name: notify-infra
              type: call
              call: "slack.post-message"
              with:
                channel: "#infra-alerts"
                text: "ServiceNow {{create-incident.number}} created for CloudWatch alarm {{alarm_name}}"
  consumes:
    - type: http
      namespace: cloudwatch
      baseUri: "https://monitoring.us-east-1.amazonaws.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.aws_sigv4_token"
        placement: header
      resources:
        - name: alarms
          path: "/?Action=DescribeAlarms&AlarmNames.member.1={{alarm_name}}"
          inputParameters:
            - name: alarm_name
              in: query
          operations:
            - name: describe-alarm
              method: GET
    - type: http
      namespace: servicenow-ops
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves the running state, instance type, and availability zone of an AWS EC2 instance by instance ID.

naftiko: "0.5"
info:
  label: "AWS EC2 Instance Status Lookup"
  description: "Retrieves the running state, instance type, and availability zone of an AWS EC2 instance by instance ID."
  tags:
    - cloud
    - infrastructure
    - aws
capability:
  exposes:
    - type: mcp
      namespace: cloud-infra
      port: 8080
      tools:
        - name: get-ec2-status
          description: "Given an EC2 instance ID, return the instance state, type, availability zone, and launch time."
          inputParameters:
            - name: instance_id
              in: body
              type: string
              description: "AWS EC2 instance ID."
          call: aws.describe-instance
          with:
            instance_id: "{{instance_id}}"
  consumes:
    - type: http
      namespace: aws
      baseUri: "https://ec2.us-east-1.amazonaws.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.aws_sigv4_token"
        placement: header
      resources:
        - name: instances
          path: "/?Action=DescribeInstances&InstanceId.1={{instance_id}}"
          inputParameters:
            - name: instance_id
              in: query
          operations:
            - name: describe-instance
              method: GET

Scans AWS S3 buckets for public access configuration and creates ServiceNow compliance tasks for any misconfigured buckets.

naftiko: "0.5"
info:
  label: "AWS S3 Compliance Scan to ServiceNow"
  description: "Scans AWS S3 buckets for public access configuration and creates ServiceNow compliance tasks for any misconfigured buckets."
  tags:
    - security
    - compliance
    - aws
    - servicenow
    - slack
capability:
  exposes:
    - type: mcp
      namespace: cloud-compliance
      port: 8080
      tools:
        - name: scan-s3-compliance
          description: "Given an AWS account, check S3 buckets for public access and create compliance tasks for violations."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "AWS account ID."
          steps:
            - name: list-buckets
              type: call
              call: "aws-s3.list-buckets"
              with:
                account_id: "{{account_id}}"
            - name: create-compliance-task
              type: call
              call: "servicenow-comp.create-task"
              with:
                short_description: "S3 compliance: {{list-buckets.public_bucket_count}} public buckets in account {{account_id}}"
                assignment_group: "Cloud_Security"
                priority: "1"
            - name: notify-security
              type: call
              call: "slack.post-message"
              with:
                channel: "#cloud-security"
                text: "S3 compliance scan: {{list-buckets.public_bucket_count}} public buckets found in account {{account_id}} — ServiceNow: {{create-compliance-task.number}}"
  consumes:
    - type: http
      namespace: aws-s3
      baseUri: "https://s3.amazonaws.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.aws_sigv4_token"
        placement: header
      resources:
        - name: buckets
          path: "/"
          operations:
            - name: list-buckets
              method: GET
    - type: http
      namespace: servicenow-comp
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When Azure AD Identity Protection flags a high-risk sign-in, suspends the user in Okta and creates a ServiceNow security incident.

naftiko: "0.5"
info:
  label: "Azure AD Risky Sign-In to Okta Suspension"
  description: "When Azure AD Identity Protection flags a high-risk sign-in, suspends the user in Okta and creates a ServiceNow security incident."
  tags:
    - security
    - identity
    - azure
    - okta
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: identity-threat
      port: 8080
      tools:
        - name: handle-risky-signin
          description: "Given an Azure AD risk event ID, retrieve the details, suspend the user in Okta, and create a security incident."
          inputParameters:
            - name: risk_event_id
              in: body
              type: string
              description: "Azure AD risk event ID."
          steps:
            - name: get-risk-event
              type: call
              call: "azure-ad.get-risk-detection"
              with:
                event_id: "{{risk_event_id}}"
            - name: suspend-okta-user
              type: call
              call: "okta.suspend-user"
              with:
                user_id: "{{get-risk-event.userPrincipalName}}"
            - name: create-sec-incident
              type: call
              call: "servicenow-sec.create-incident"
              with:
                short_description: "High-risk sign-in: {{get-risk-event.userPrincipalName}} from {{get-risk-event.ipAddress}}"
                severity: "1"
                category: "security"
                assignment_group: "SOC_Team"
  consumes:
    - type: http
      namespace: azure-ad
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.azure_graph_token"
      resources:
        - name: risk-detections
          path: "/identityProtection/riskDetections/{{event_id}}"
          inputParameters:
            - name: event_id
              in: path
          operations:
            - name: get-risk-detection
              method: GET
    - type: http
      namespace: okta
      baseUri: "https://ibm.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "SSWS $secrets.okta_api_token"
        placement: header
      resources:
        - name: users
          path: "/users/{{user_id}}/lifecycle/suspend"
          inputParameters:
            - name: user_id
              in: path
          operations:
            - name: suspend-user
              method: POST
    - type: http
      namespace: servicenow-sec
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: incidents
          path: "/table/sn_si_incident"
          operations:
            - name: create-incident
              method: POST

When Azure Cost Management detects a spend anomaly, creates a Jira FinOps ticket and notifies the cloud governance team.

naftiko: "0.5"
info:
  label: "Azure Cost Anomaly to FinOps Jira"
  description: "When Azure Cost Management detects a spend anomaly, creates a Jira FinOps ticket and notifies the cloud governance team."
  tags:
    - cloud
    - finops
    - azure
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: cloud-finops
      port: 8080
      tools:
        - name: handle-cost-anomaly
          description: "Given an Azure subscription and anomaly details, create a FinOps Jira ticket and notify the team."
          inputParameters:
            - name: subscription_id
              in: body
              type: string
              description: "Azure subscription ID."
            - name: anomaly_description
              in: body
              type: string
              description: "Description of the cost anomaly."
          steps:
            - name: get-cost-details
              type: call
              call: "azure-cost.get-cost-summary"
              with:
                subscription_id: "{{subscription_id}}"
            - name: create-finops-ticket
              type: call
              call: "jira.create-issue"
              with:
                project: "FINOPS"
                issuetype: "Task"
                summary: "Azure cost anomaly: {{anomaly_description}}"
                description: "Subscription: {{subscription_id}} | Current spend: {{get-cost-details.total_cost}}"
            - name: notify-governance
              type: call
              call: "slack.post-message"
              with:
                channel: "#cloud-governance"
                text: "Azure cost anomaly detected in subscription {{subscription_id}} — Jira: {{create-finops-ticket.key}}"
  consumes:
    - type: http
      namespace: azure-cost
      baseUri: "https://management.azure.com"
      authentication:
        type: bearer
        token: "$secrets.azure_token"
      resources:
        - name: cost-summary
          path: "/subscriptions/{{subscription_id}}/providers/Microsoft.CostManagement/query"
          inputParameters:
            - name: subscription_id
              in: path
          operations:
            - name: get-cost-summary
              method: POST
    - type: http
      namespace: jira
      baseUri: "https://ibm-jira.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When an Azure Databricks job fails, retrieves the error output and creates a Jira ticket for the data engineering team.

naftiko: "0.5"
info:
  label: "Azure Databricks Job Failure to Jira"
  description: "When an Azure Databricks job fails, retrieves the error output and creates a Jira ticket for the data engineering team."
  tags:
    - data
    - devops
    - azure-databricks
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: data-ops
      port: 8080
      tools:
        - name: handle-databricks-failure
          description: "Given a Databricks run ID, get the failure details and create a Jira ticket."
          inputParameters:
            - name: run_id
              in: body
              type: string
              description: "Databricks job run ID."
          steps:
            - name: get-run
              type: call
              call: "databricks.get-run"
              with:
                run_id: "{{run_id}}"
            - name: create-ticket
              type: call
              call: "jira.create-issue"
              with:
                project: "DATA"
                issuetype: "Bug"
                summary: "Databricks job failure: {{get-run.run_name}}"
                description: "Error: {{get-run.state.state_message}} | Cluster: {{get-run.cluster_instance.cluster_id}}"
            - name: notify-team
              type: call
              call: "slack.post-message"
              with:
                channel: "#data-engineering"
                text: "Databricks job {{get-run.run_name}} failed — Jira: {{create-ticket.key}}"
  consumes:
    - type: http
      namespace: databricks
      baseUri: "https://adb-ibm.azuredatabricks.net/api/2.1"
      authentication:
        type: bearer
        token: "$secrets.databricks_token"
      resources:
        - name: runs
          path: "/jobs/runs/get?run_id={{run_id}}"
          inputParameters:
            - name: run_id
              in: query
          operations:
            - name: get-run
              method: GET
    - type: http
      namespace: jira
      baseUri: "https://ibm-jira.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When an Azure DevOps pipeline fails, retrieves the failure details and creates a Jira bug ticket with the error logs.

naftiko: "0.5"
info:
  label: "Azure DevOps Pipeline Failure to Jira"
  description: "When an Azure DevOps pipeline fails, retrieves the failure details and creates a Jira bug ticket with the error logs."
  tags:
    - devops
    - ci-cd
    - azure-devops
    - jira
capability:
  exposes:
    - type: mcp
      namespace: ci-ops
      port: 8080
      tools:
        - name: handle-pipeline-failure
          description: "Given an Azure DevOps build ID and project, get the failure details and create a Jira bug."
          inputParameters:
            - name: project
              in: body
              type: string
              description: "Azure DevOps project name."
            - name: build_id
              in: body
              type: string
              description: "Failed build ID."
          steps:
            - name: get-build
              type: call
              call: "azdo.get-build"
              with:
                project: "{{project}}"
                build_id: "{{build_id}}"
            - name: create-bug
              type: call
              call: "jira.create-issue"
              with:
                project: "ENG"
                issuetype: "Bug"
                summary: "Pipeline failure: {{get-build.definition.name}} build #{{build_id}}"
                description: "Build status: {{get-build.result}} | Reason: {{get-build.failureReason}}"
  consumes:
    - type: http
      namespace: azdo
      baseUri: "https://dev.azure.com/ibm"
      authentication:
        type: basic
        username: "$secrets.azdo_user"
        password: "$secrets.azdo_pat"
      resources:
        - name: builds
          path: "/{{project}}/_apis/build/builds/{{build_id}}"
          inputParameters:
            - name: project
              in: path
            - name: build_id
              in: path
          operations:
            - name: get-build
              method: GET
    - type: http
      namespace: jira
      baseUri: "https://ibm-jira.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST

Queries Azure Log Analytics for error spikes on a given service and forwards alert payloads to New Relic as custom events. Used by SRE agents for cross-platform observability correlation.

naftiko: "0.5"
info:
  label: "Azure Log Analytics Alert to New Relic"
  description: "Queries Azure Log Analytics for error spikes on a given service and forwards alert payloads to New Relic as custom events. Used by SRE agents for cross-platform observability correlation."
  tags:
    - observability
    - cloud
    - azure-log-analytics
    - new-relic
    - monitoring
capability:
  exposes:
    - type: mcp
      namespace: cloud-obs
      port: 8080
      tools:
        - name: forward-log-alert
          description: "Given an Azure Log Analytics workspace ID and KQL query, run the query and forward matching log records as custom events to New Relic for unified alerting."
          inputParameters:
            - name: workspace_id
              in: body
              type: string
              description: "Azure Log Analytics workspace GUID."
            - name: kql_query
              in: body
              type: string
              description: "KQL query to run against the workspace, e.g. AzureDiagnostics | where Level == 'Error'."
          steps:
            - name: run-query
              type: call
              call: "azure-logs.run-query"
              with:
                workspaceId: "{{workspace_id}}"
                query: "{{kql_query}}"
            - name: post-events
              type: call
              call: "newrelic-events.post-events"
              with:
                eventType: "AzureLogAlert"
                attributes: "{{run-query.rows}}"
  consumes:
    - type: http
      namespace: azure-logs
      baseUri: "https://api.loganalytics.io/v1"
      authentication:
        type: bearer
        token: "$secrets.azure_log_analytics_token"
      resources:
        - name: query
          path: "/workspaces/{{workspaceId}}/query"
          inputParameters:
            - name: workspaceId
              in: path
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: newrelic-events
      baseUri: "https://insights-collector.newrelic.com/v1"
      authentication:
        type: apikey
        key: "X-Insert-Key"
        value: "$secrets.newrelic_insert_key"
        placement: header
      resources:
        - name: events
          path: "/accounts/{{account_id}}/events"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: post-events
              method: POST

Checks the deployment health of a registered Azure Machine Learning model endpoint and creates a ServiceNow incident if the endpoint is unhealthy or scoring latency is degraded.

naftiko: "0.5"
info:
  label: "Azure Machine Learning Model Deployment Monitor"
  description: "Checks the deployment health of a registered Azure Machine Learning model endpoint and creates a ServiceNow incident if the endpoint is unhealthy or scoring latency is degraded."
  tags:
    - ai
    - cloud
    - azure-machine-learning
    - servicenow
    - monitoring
capability:
  exposes:
    - type: mcp
      namespace: ml-ops
      port: 8080
      tools:
        - name: monitor-ml-endpoint
          description: "Given an Azure ML workspace name and endpoint name, check real-time endpoint health and latency metrics and open a ServiceNow incident if degraded."
          inputParameters:
            - name: workspace_name
              in: body
              type: string
              description: "Azure ML workspace name."
            - name: endpoint_name
              in: body
              type: string
              description: "Online endpoint name within the workspace."
            - name: latency_threshold_ms
              in: body
              type: integer
              description: "P99 latency threshold in milliseconds above which to alert."
          steps:
            - name: get-endpoint-status
              type: call
              call: "azure-ml.get-endpoint"
              with:
                workspaceName: "{{workspace_name}}"
                endpointName: "{{endpoint_name}}"
            - name: create-ml-incident
              type: call
              call: "servicenow-ml.create-incident"
              with:
                short_description: "ML endpoint degraded: {{endpoint_name}} in {{workspace_name}}"
                category: "AI_Operations"
                urgency: "2"
                description: "Endpoint state: {{get-endpoint-status.provisioningState}} | Traffic: {{get-endpoint-status.trafficRules}}"
  consumes:
    - type: http
      namespace: azure-ml
      baseUri: "https://management.azure.com/subscriptions/{{subscriptionId}}/resourceGroups/{{resourceGroup}}/providers/Microsoft.MachineLearningServices"
      authentication:
        type: bearer
        token: "$secrets.azure_ml_token"
      resources:
        - name: endpoints
          path: "/workspaces/{{workspaceName}}/onlineEndpoints/{{endpointName}}"
          inputParameters:
            - name: workspaceName
              in: path
            - name: endpointName
              in: path
          operations:
            - name: get-endpoint
              method: GET
    - type: http
      namespace: servicenow-ml
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST

Queries Azure Cost Management for the current month spend of a resource group, returning cost breakdown by service category.

naftiko: "0.5"
info:
  label: "Azure Resource Group Cost Lookup"
  description: "Queries Azure Cost Management for the current month spend of a resource group, returning cost breakdown by service category."
  tags:
    - cloud
    - finops
    - azure
capability:
  exposes:
    - type: mcp
      namespace: finops
      port: 8080
      tools:
        - name: get-resource-group-cost
          description: "Given an Azure subscription ID and resource group name, return the current month cost breakdown."
          inputParameters:
            - name: subscription_id
              in: body
              type: string
              description: "Azure subscription ID."
            - name: resource_group
              in: body
              type: string
              description: "Azure resource group name."
          call: azure-cost.get-cost-summary
          with:
            subscription_id: "{{subscription_id}}"
            resource_group: "{{resource_group}}"
  consumes:
    - type: http
      namespace: azure-cost
      baseUri: "https://management.azure.com"
      authentication:
        type: bearer
        token: "$secrets.azure_token"
      resources:
        - name: cost-summary
          path: "/subscriptions/{{subscription_id}}/resourceGroups/{{resource_group}}/providers/Microsoft.CostManagement/query"
          inputParameters:
            - name: subscription_id
              in: path
            - name: resource_group
              in: path
          operations:
            - name: get-cost-summary
              method: POST

When a Bitbucket pull request is merged to main, creates a ServiceNow change request for deployment tracking and attaches the PR diff summary.

naftiko: "0.5"
info:
  label: "Bitbucket PR Code Review to ServiceNow Change"
  description: "When a Bitbucket pull request is merged to main, creates a ServiceNow change request for deployment tracking and attaches the PR diff summary."
  tags:
    - devops
    - cicd
    - bitbucket
    - servicenow
    - change-management
capability:
  exposes:
    - type: mcp
      namespace: change-mgmt
      port: 8080
      tools:
        - name: create-deployment-change
          description: "Given a Bitbucket workspace, repository slug, and pull request ID, fetch the PR details and create a ServiceNow standard change request for the merged code."
          inputParameters:
            - name: workspace
              in: body
              type: string
              description: "Bitbucket workspace slug."
            - name: repo_slug
              in: body
              type: string
              description: "Bitbucket repository slug."
            - name: pr_id
              in: body
              type: integer
              description: "Bitbucket pull request ID."
          steps:
            - name: get-pr
              type: call
              call: "bitbucket.get-pr"
              with:
                workspace: "{{workspace}}"
                repo_slug: "{{repo_slug}}"
                pull_request_id: "{{pr_id}}"
            - name: create-change
              type: call
              call: "servicenow-std.create-change"
              with:
                short_description: "Deploy: {{get-pr.title}} ({{repo_slug}} PR#{{pr_id}})"
                type: "standard"
                description: "Author: {{get-pr.author.display_name}} | Merged: {{get-pr.updated_on}}"
  consumes:
    - type: http
      namespace: bitbucket
      baseUri: "https://api.bitbucket.org/2.0"
      authentication:
        type: bearer
        token: "$secrets.bitbucket_token"
      resources:
        - name: pull-requests
          path: "/repositories/{{workspace}}/{{repo_slug}}/pullrequests/{{pull_request_id}}"
          inputParameters:
            - name: workspace
              in: path
            - name: repo_slug
              in: path
            - name: pull_request_id
              in: path
          operations:
            - name: get-pr
              method: GET
    - type: http
      namespace: servicenow-std
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: changes
          path: "/table/change_request"
          operations:
            - name: create-change
              method: POST

Lists DNS records for a Cloudflare zone, returning record types, values, and TTL settings for network management queries.

naftiko: "0.5"
info:
  label: "Cloudflare DNS Record Lookup"
  description: "Lists DNS records for a Cloudflare zone, returning record types, values, and TTL settings for network management queries."
  tags:
    - networking
    - dns
    - cloudflare
capability:
  exposes:
    - type: mcp
      namespace: dns
      port: 8080
      tools:
        - name: list-dns-records
          description: "Given a Cloudflare zone ID, return all DNS records with type, name, content, and TTL."
          inputParameters:
            - name: zone_id
              in: body
              type: string
              description: "Cloudflare zone identifier."
          call: cloudflare.list-records
          with:
            zone_id: "{{zone_id}}"
  consumes:
    - type: http
      namespace: cloudflare
      baseUri: "https://api.cloudflare.com/client/v4"
      authentication:
        type: bearer
        token: "$secrets.cloudflare_token"
      resources:
        - name: dns-records
          path: "/zones/{{zone_id}}/dns_records"
          inputParameters:
            - name: zone_id
              in: path
          operations:
            - name: list-records
              method: GET

When Cloudflare rate limiting triggers for a zone, creates a PagerDuty incident and updates the Cloudflare WAF rule to block the source IP.

naftiko: "0.5"
info:
  label: "Cloudflare Rate Limit Breach to PagerDuty"
  description: "When Cloudflare rate limiting triggers for a zone, creates a PagerDuty incident and updates the Cloudflare WAF rule to block the source IP."
  tags:
    - security
    - networking
    - cloudflare
    - pagerduty
capability:
  exposes:
    - type: mcp
      namespace: waf-ops
      port: 8080
      tools:
        - name: handle-rate-limit-breach
          description: "Given a Cloudflare zone and source IP, block the IP and create a PagerDuty incident."
          inputParameters:
            - name: zone_id
              in: body
              type: string
              description: "Cloudflare zone ID."
            - name: source_ip
              in: body
              type: string
              description: "Offending source IP address."
          steps:
            - name: block-ip
              type: call
              call: "cloudflare.create-firewall-rule"
              with:
                zone_id: "{{zone_id}}"
                mode: "block"
                ip: "{{source_ip}}"
            - name: create-incident
              type: call
              call: "pagerduty.create-incident"
              with:
                service_id: "$secrets.pd_security_service_id"
                title: "Rate limit breach: {{source_ip}} blocked on zone {{zone_id}}"
                urgency: "high"
  consumes:
    - type: http
      namespace: cloudflare
      baseUri: "https://api.cloudflare.com/client/v4"
      authentication:
        type: bearer
        token: "$secrets.cloudflare_token"
      resources:
        - name: firewall-rules
          path: "/zones/{{zone_id}}/firewall/access_rules/rules"
          inputParameters:
            - name: zone_id
              in: path
          operations:
            - name: create-firewall-rule
              method: POST
    - type: http
      namespace: pagerduty
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "Token token=$secrets.pagerduty_token"
        placement: header
      resources:
        - name: incidents
          path: "/incidents"
          operations:
            - name: create-incident
              method: POST

Retrieves active threat indicators from Palo Alto Networks and creates or updates Cloudflare WAF custom rules to block matching IP ranges.

naftiko: "0.5"
info:
  label: "Cloudflare WAF Rule Update from Threat Intelligence"
  description: "Retrieves active threat indicators from Palo Alto Networks and creates or updates Cloudflare WAF custom rules to block matching IP ranges."
  tags:
    - security
    - cloudflare
    - palo-alto-networks
    - threat-intelligence
    - waf
capability:
  exposes:
    - type: mcp
      namespace: security-waf
      port: 8080
      tools:
        - name: update-waf-blocklist
          description: "Given a Palo Alto Networks threat feed type, fetch current malicious IP indicators and push blocking WAF rules to the specified Cloudflare zone."
          inputParameters:
            - name: threat_feed_type
              in: body
              type: string
              description: "Palo Alto threat feed category, e.g. command-and-control."
            - name: cloudflare_zone_id
              in: body
              type: string
              description: "Cloudflare zone ID to apply WAF rules to."
          steps:
            - name: get-indicators
              type: call
              call: "palo-alto-ti.get-threat-indicators"
              with:
                feed_type: "{{threat_feed_type}}"
            - name: update-waf-rule
              type: call
              call: "cloudflare.update-waf-rule"
              with:
                zone_id: "{{cloudflare_zone_id}}"
                ip_list: "{{get-indicators.ip_addresses}}"
                action: "block"
  consumes:
    - type: http
      namespace: palo-alto-ti
      baseUri: "https://autofocus.paloaltonetworks.com/api/v1.0"
      authentication:
        type: apikey
        key: "apiKey"
        value: "$secrets.paloalto_autofocus_key"
        placement: query
      resources:
        - name: threat-indicators
          path: "/samples/search"
          operations:
            - name: get-threat-indicators
              method: POST
    - type: http
      namespace: cloudflare
      baseUri: "https://api.cloudflare.com/client/v4"
      authentication:
        type: bearer
        token: "$secrets.cloudflare_token"
      resources:
        - name: waf-rules
          path: "/zones/{{zone_id}}/firewall/rules"
          inputParameters:
            - name: zone_id
              in: path
          operations:
            - name: update-waf-rule
              method: PUT

Retrieves a Confluence page by title and space key, returning the page content body, last modified date, and author.

naftiko: "0.5"
info:
  label: "Confluence Page Lookup"
  description: "Retrieves a Confluence page by title and space key, returning the page content body, last modified date, and author."
  tags:
    - knowledge
    - confluence
    - documentation
capability:
  exposes:
    - type: mcp
      namespace: knowledge
      port: 8080
      tools:
        - name: get-confluence-page
          description: "Given a space key and page title, return the Confluence page content, author, and last update timestamp."
          inputParameters:
            - name: space_key
              in: body
              type: string
              description: "Confluence space key."
            - name: page_title
              in: body
              type: string
              description: "Page title to search for."
          call: confluence.get-page
          with:
            spaceKey: "{{space_key}}"
            title: "{{page_title}}"
  consumes:
    - type: http
      namespace: confluence
      baseUri: "https://ibm-wiki.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_api_token"
      resources:
        - name: content
          path: "/content"
          inputParameters:
            - name: spaceKey
              in: query
            - name: title
              in: query
          operations:
            - name: get-page
              method: GET

When a PagerDuty incident fires, retrieves the corresponding Confluence runbook and posts the remediation steps to the incident Slack channel.

naftiko: "0.5"
info:
  label: "Confluence Runbook Trigger from PagerDuty"
  description: "When a PagerDuty incident fires, retrieves the corresponding Confluence runbook and posts the remediation steps to the incident Slack channel."
  tags:
    - operations
    - documentation
    - pagerduty
    - confluence
    - slack
capability:
  exposes:
    - type: mcp
      namespace: runbook-ops
      port: 8080
      tools:
        - name: fetch-runbook
          description: "Given a PagerDuty incident ID, look up the service, find the Confluence runbook, and post steps to Slack."
          inputParameters:
            - name: incident_id
              in: body
              type: string
              description: "PagerDuty incident ID."
            - name: runbook_space
              in: body
              type: string
              description: "Confluence space key for runbooks."
          steps:
            - name: get-incident
              type: call
              call: "pagerduty.get-incident"
              with:
                incident_id: "{{incident_id}}"
            - name: get-runbook
              type: call
              call: "confluence.get-page"
              with:
                spaceKey: "{{runbook_space}}"
                title: "Runbook: {{get-incident.service.summary}}"
            - name: post-runbook
              type: call
              call: "slack.post-message"
              with:
                channel: "#incident-{{incident_id}}"
                text: "Runbook for {{get-incident.service.summary}}:\n{{get-runbook.body.storage.value}}"
  consumes:
    - type: http
      namespace: pagerduty
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "Token token=$secrets.pagerduty_token"
        placement: header
      resources:
        - name: incidents
          path: "/incidents/{{incident_id}}"
          inputParameters:
            - name: incident_id
              in: path
          operations:
            - name: get-incident
              method: GET
    - type: http
      namespace: confluence
      baseUri: "https://ibm-wiki.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_api_token"
      resources:
        - name: content
          path: "/content"
          operations:
            - name: get-page
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a Datadog monitor triggers a critical alert, creates a PagerDuty incident and posts a summary to the Slack on-call channel.

naftiko: "0.5"
info:
  label: "Datadog Alert to PagerDuty Incident"
  description: "When a Datadog monitor triggers a critical alert, creates a PagerDuty incident and posts a summary to the Slack on-call channel."
  tags:
    - observability
    - incident-response
    - datadog
    - pagerduty
    - slack
capability:
  exposes:
    - type: mcp
      namespace: incident-ops
      port: 8080
      tools:
        - name: escalate-datadog-alert
          description: "Given a Datadog monitor ID, check the monitor status and if critical, create a PagerDuty incident and notify Slack."
          inputParameters:
            - name: monitor_id
              in: body
              type: string
              description: "Datadog monitor ID."
            - name: service_id
              in: body
              type: string
              description: "PagerDuty service ID for routing."
          steps:
            - name: get-monitor
              type: call
              call: "datadog.get-monitor"
              with:
                monitor_id: "{{monitor_id}}"
            - name: create-pd-incident
              type: call
              call: "pagerduty.create-incident"
              with:
                service_id: "{{service_id}}"
                title: "Datadog Critical: {{get-monitor.name}}"
                urgency: "high"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#oncall-alerts"
                text: "PagerDuty incident {{create-pd-incident.incident.id}} created for Datadog monitor {{get-monitor.name}}"
  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: pagerduty
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "Token token=$secrets.pagerduty_token"
        placement: header
      resources:
        - name: incidents
          path: "/incidents"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When Datadog APM detects a latency spike above threshold, creates a Jira performance ticket and sends a Slack alert to the platform team.

naftiko: "0.5"
info:
  label: "Datadog APM Latency Spike to Jira"
  description: "When Datadog APM detects a latency spike above threshold, creates a Jira performance ticket and sends a Slack alert to the platform team."
  tags:
    - observability
    - devops
    - datadog
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: perf-ops
      port: 8080
      tools:
        - name: handle-latency-spike
          description: "Given a Datadog service name and latency threshold, check current p99 latency and create a Jira ticket if exceeded."
          inputParameters:
            - name: service_name
              in: body
              type: string
              description: "Datadog service name."
            - name: latency_threshold_ms
              in: body
              type: number
              description: "P99 latency threshold in milliseconds."
          steps:
            - name: get-metrics
              type: call
              call: "datadog.get-service-metrics"
              with:
                service: "{{service_name}}"
            - name: create-perf-ticket
              type: call
              call: "jira.create-issue"
              with:
                project: "PERF"
                issuetype: "Task"
                summary: "Latency spike: {{service_name}} p99 at {{get-metrics.p99_latency}}ms"
                priority: "High"
            - name: alert-platform
              type: call
              call: "slack.post-message"
              with:
                channel: "#platform-eng"
                text: "Latency spike: {{service_name}} p99={{get-metrics.p99_latency}}ms (threshold: {{latency_threshold_ms}}ms) — Jira: {{create-perf-ticket.key}}"
  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: service-metrics
          path: "/metrics/query"
          operations:
            - name: get-service-metrics
              method: GET
    - type: http
      namespace: jira
      baseUri: "https://ibm-jira.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves the service dependency map from Datadog APM for a given service, showing upstream and downstream dependencies.

naftiko: "0.5"
info:
  label: "Datadog Service Map Lookup"
  description: "Retrieves the service dependency map from Datadog APM for a given service, showing upstream and downstream dependencies."
  tags:
    - observability
    - datadog
    - apm
capability:
  exposes:
    - type: mcp
      namespace: observability
      port: 8080
      tools:
        - name: get-service-dependencies
          description: "Given a Datadog service name, return the upstream and downstream service dependencies from the APM service map."
          inputParameters:
            - name: service_name
              in: body
              type: string
              description: "Datadog APM service name."
          call: datadog.get-service-dependencies
          with:
            service: "{{service_name}}"
  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: service-dependencies
          path: "/service_dependencies"
          inputParameters:
            - name: service
              in: query
          operations:
            - name: get-service-dependencies
              method: GET

Monitors Datadog SLO burn rate and, when a threshold is breached, automatically opens a P1 ServiceNow incident and notifies New Relic with a deployment marker.

naftiko: "0.5"
info:
  label: "Datadog SLO Breach to ServiceNow Incident"
  description: "Monitors Datadog SLO burn rate and, when a threshold is breached, automatically opens a P1 ServiceNow incident and notifies New Relic with a deployment marker."
  tags:
    - observability
    - itsm
    - datadog
    - new-relic
    - servicenow
    - incident-response
capability:
  exposes:
    - type: mcp
      namespace: slo-ops
      port: 8080
      tools:
        - name: handle-slo-breach
          description: "Given a Datadog SLO ID and service name, check the current error budget burn rate and open a P1 ServiceNow incident if the burn rate exceeds the threshold."
          inputParameters:
            - name: slo_id
              in: body
              type: string
              description: "Datadog SLO identifier."
            - name: service_name
              in: body
              type: string
              description: "Name of the service associated with the SLO."
            - name: burn_rate_threshold
              in: body
              type: number
              description: "Burn rate value above which to open an incident."
          steps:
            - name: get-slo
              type: call
              call: "datadog-slo.get-slo-history"
              with:
                slo_id: "{{slo_id}}"
            - name: open-incident
              type: call
              call: "servicenow-p1.create-incident"
              with:
                short_description: "SLO breach: {{service_name}} burn rate exceeded {{burn_rate_threshold}}"
                urgency: "1"
                impact: "1"
                assignment_group: "Platform_SRE"
            - name: mark-deployment
              type: call
              call: "newrelic.create-deployment"
              with:
                entity_name: "{{service_name}}"
                description: "SLO breach event — incident {{open-incident.number}}"
  consumes:
    - type: http
      namespace: datadog-slo
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: slo-history
          path: "/slo/{{slo_id}}/history"
          inputParameters:
            - name: slo_id
              in: path
          operations:
            - name: get-slo-history
              method: GET
    - type: http
      namespace: servicenow-p1
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: newrelic
      baseUri: "https://api.newrelic.com/v2"
      authentication:
        type: apikey
        key: "X-Api-Key"
        value: "$secrets.newrelic_api_key"
        placement: header
      resources:
        - name: deployments
          path: "/applications/deployments.json"
          operations:
            - name: create-deployment
              method: POST

When Dynatrace detects an application problem, creates a ServiceNow incident with root cause details and notifies the on-call team.

naftiko: "0.5"
info:
  label: "Dynatrace Problem to ServiceNow Incident"
  description: "When Dynatrace detects an application problem, creates a ServiceNow incident with root cause details and notifies the on-call team."
  tags:
    - observability
    - itsm
    - dynatrace
    - servicenow
    - slack
capability:
  exposes:
    - type: mcp
      namespace: apm-ops
      port: 8080
      tools:
        - name: handle-dynatrace-problem
          description: "Given a Dynatrace problem ID, retrieve the root cause analysis and create a ServiceNow incident."
          inputParameters:
            - name: problem_id
              in: body
              type: string
              description: "Dynatrace problem ID."
          steps:
            - name: get-problem
              type: call
              call: "dynatrace.get-problem"
              with:
                problem_id: "{{problem_id}}"
            - name: create-incident
              type: call
              call: "servicenow-ops.create-incident"
              with:
                short_description: "Dynatrace: {{get-problem.title}}"
                description: "Root cause: {{get-problem.rootCauseEntity.name}} | Impact: {{get-problem.impactLevel}}"
                urgency: "1"
                assignment_group: "Application_Support"
            - name: notify-oncall
              type: call
              call: "slack.post-message"
              with:
                channel: "#oncall-alerts"
                text: "Dynatrace problem {{problem_id}} — ServiceNow {{create-incident.number}} created"
  consumes:
    - type: http
      namespace: dynatrace
      baseUri: "https://ibm.live.dynatrace.com/api/v2"
      authentication:
        type: apikey
        key: "Authorization"
        value: "Api-Token $secrets.dynatrace_token"
        placement: header
      resources:
        - name: problems
          path: "/problems/{{problem_id}}"
          inputParameters:
            - name: problem_id
              in: path
          operations:
            - name: get-problem
              method: GET
    - type: http
      namespace: servicenow-ops
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a GitHub Actions workflow fails on a release branch, creates a ServiceNow change request and alerts via SolarWinds event. Used by DevOps agents for automated release governance.

naftiko: "0.5"
info:
  label: "GitHub Actions CI Failure to ServiceNow Change"
  description: "When a GitHub Actions workflow fails on a release branch, creates a ServiceNow change request and alerts via SolarWinds event. Used by DevOps agents for automated release governance."
  tags:
    - devops
    - cicd
    - github
    - servicenow
    - solarwinds
capability:
  exposes:
    - type: mcp
      namespace: devops
      port: 8080
      tools:
        - name: handle-pipeline-failure
          description: "Given a GitHub workflow run failure event, open a ServiceNow change request and send a SolarWinds alert event with failure context."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "GitHub repository full name, e.g. ibm/my-service."
            - name: run_id
              in: body
              type: string
              description: "GitHub Actions workflow run ID."
            - name: branch
              in: body
              type: string
              description: "Branch name where the failure occurred."
            - name: commit_sha
              in: body
              type: string
              description: "Full SHA of the failing commit."
          steps:
            - name: get-run
              type: call
              call: "github.get-workflow-run"
              with:
                owner: "ibm"
                repo: "{{repo}}"
                run_id: "{{run_id}}"
            - name: open-change
              type: call
              call: "servicenow-cr.create-change"
              with:
                short_description: "CI failure on {{branch}} — {{repo}} ({{commit_sha}})"
                type: "emergency"
                description: "Workflow run {{run_id}} failed. Conclusion: {{get-run.conclusion}}"
            - name: send-event
              type: call
              call: "solarwinds.create-event"
              with:
                message: "CI failure: {{repo}} / {{branch}} — Change: {{open-change.number}}"
                severity: "critical"
  consumes:
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: workflow-runs
          path: "/repos/{{owner}}/{{repo}}/actions/runs/{{run_id}}"
          inputParameters:
            - name: owner
              in: path
            - name: repo
              in: path
            - name: run_id
              in: path
          operations:
            - name: get-workflow-run
              method: GET
    - type: http
      namespace: servicenow-cr
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: change-requests
          path: "/table/change_request"
          operations:
            - name: create-change
              method: POST
    - type: http
      namespace: solarwinds
      baseUri: "https://api.solarwinds.com/v1"
      authentication:
        type: bearer
        token: "$secrets.solarwinds_token"
      resources:
        - name: events
          path: "/events"
          operations:
            - name: create-event
              method: POST

When a GitHub Actions workflow run fails tests, retrieves the failure logs and posts a summary to the engineering Slack channel.

naftiko: "0.5"
info:
  label: "GitHub Actions Test Failure to Slack"
  description: "When a GitHub Actions workflow run fails tests, retrieves the failure logs and posts a summary to the engineering Slack channel."
  tags:
    - devops
    - ci-cd
    - github
    - slack
capability:
  exposes:
    - type: mcp
      namespace: ci-notify
      port: 8080
      tools:
        - name: notify-test-failure
          description: "Given a GitHub repository and workflow run ID, retrieve the failure details and notify Slack."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "GitHub repository in owner/repo format."
            - name: run_id
              in: body
              type: string
              description: "GitHub Actions workflow run ID."
          steps:
            - name: get-run
              type: call
              call: "github.get-workflow-run"
              with:
                repo: "{{repo}}"
                run_id: "{{run_id}}"
            - name: notify-channel
              type: call
              call: "slack.post-message"
              with:
                channel: "#ci-cd"
                text: "Test failure in {{repo}}: {{get-run.name}} — Branch: {{get-run.head_branch}} | Commit: {{get-run.head_sha}} | Author: {{get-run.actor.login}}"
  consumes:
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: workflow-runs
          path: "/repos/{{repo}}/actions/runs/{{run_id}}"
          inputParameters:
            - name: repo
              in: path
            - name: run_id
              in: path
          operations:
            - name: get-workflow-run
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When GitHub Dependabot finds a critical vulnerability, creates a Jira security task and notifies the AppSec team via Slack.

naftiko: "0.5"
info:
  label: "GitHub Dependabot Alert to Jira Security Task"
  description: "When GitHub Dependabot finds a critical vulnerability, creates a Jira security task and notifies the AppSec team via Slack."
  tags:
    - security
    - devops
    - github
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: appsec
      port: 8080
      tools:
        - name: handle-dependabot-alert
          description: "Given a GitHub repository and alert number, retrieve vulnerability details, create a Jira security task, and notify AppSec."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "GitHub repository in owner/repo format."
            - name: alert_number
              in: body
              type: string
              description: "Dependabot alert number."
          steps:
            - name: get-alert
              type: call
              call: "github.get-dependabot-alert"
              with:
                repo: "{{repo}}"
                alert_number: "{{alert_number}}"
            - name: create-sec-task
              type: call
              call: "jira.create-issue"
              with:
                project: "SEC"
                issuetype: "Task"
                summary: "Dependabot: {{get-alert.security_advisory.summary}} in {{repo}}"
                priority: "Critical"
                description: "CVE: {{get-alert.security_advisory.cve_id}} | Severity: {{get-alert.security_advisory.severity}} | Package: {{get-alert.dependency.package.name}}"
            - name: notify-appsec
              type: call
              call: "slack.post-message"
              with:
                channel: "#appsec"
                text: "Critical vulnerability in {{repo}}: {{get-alert.security_advisory.summary}} — Jira: {{create-sec-task.key}}"
  consumes:
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: dependabot-alerts
          path: "/repos/{{repo}}/dependabot/alerts/{{alert_number}}"
          inputParameters:
            - name: repo
              in: path
            - name: alert_number
              in: path
          operations:
            - name: get-dependabot-alert
              method: GET
    - type: http
      namespace: jira
      baseUri: "https://ibm-jira.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a GitHub pull request is merged to main, creates a Datadog deployment event and updates the ServiceNow change request.

naftiko: "0.5"
info:
  label: "GitHub PR Merge to Datadog Deployment Marker"
  description: "When a GitHub pull request is merged to main, creates a Datadog deployment event and updates the ServiceNow change request."
  tags:
    - devops
    - observability
    - github
    - datadog
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: deploy-tracking
      port: 8080
      tools:
        - name: track-pr-merge
          description: "Given a merged PR number and repo, create a Datadog deployment marker and close the associated ServiceNow change request."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "GitHub repository in owner/repo format."
            - name: pr_number
              in: body
              type: string
              description: "Pull request number."
            - name: change_number
              in: body
              type: string
              description: "ServiceNow change request number."
          steps:
            - name: get-pr
              type: call
              call: "github.get-pull-request"
              with:
                repo: "{{repo}}"
                pr_number: "{{pr_number}}"
            - name: create-dd-event
              type: call
              call: "datadog.create-event"
              with:
                title: "Deployment: {{get-pr.title}}"
                text: "PR #{{pr_number}} merged by {{get-pr.merged_by.login}}"
                tags: "repo:{{repo}}"
            - name: close-change
              type: call
              call: "servicenow-chg.update-change"
              with:
                number: "{{change_number}}"
                state: "closed"
                close_notes: "Deployed via PR #{{pr_number}}"
  consumes:
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: pull-requests
          path: "/repos/{{repo}}/pulls/{{pr_number}}"
          inputParameters:
            - name: repo
              in: path
            - name: pr_number
              in: path
          operations:
            - name: get-pull-request
              method: GET
    - type: http
      namespace: datadog
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: events
          path: "/events"
          operations:
            - name: create-event
              method: POST
    - type: http
      namespace: servicenow-chg
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: changes
          path: "/table/change_request"
          operations:
            - name: update-change
              method: PATCH

Retrieves branch protection rules for a GitHub repository, returning required reviews, status checks, and enforcement settings.

naftiko: "0.5"
info:
  label: "GitHub Repository Branch Protection Lookup"
  description: "Retrieves branch protection rules for a GitHub repository, returning required reviews, status checks, and enforcement settings."
  tags:
    - devops
    - security
    - github
capability:
  exposes:
    - type: mcp
      namespace: code-governance
      port: 8080
      tools:
        - name: get-branch-protection
          description: "Given a GitHub repository and branch name, return the branch protection settings including required reviewers and status checks."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "Repository in owner/repo format."
            - name: branch
              in: body
              type: string
              description: "Branch name, e.g. main."
          call: github.get-branch-protection
          with:
            repo: "{{repo}}"
            branch: "{{branch}}"
  consumes:
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: branch-protection
          path: "/repos/{{repo}}/branches/{{branch}}/protection"
          inputParameters:
            - name: repo
              in: path
            - name: branch
              in: path
          operations:
            - name: get-branch-protection
              method: GET

Runs SonarQube quality gate checks against a GitHub repository and posts the scan summary as a ServiceNow change advisory board note.

naftiko: "0.5"
info:
  label: "GitHub Repository Security Scan Digest"
  description: "Runs SonarQube quality gate checks against a GitHub repository and posts the scan summary as a ServiceNow change advisory board note."
  tags:
    - devops
    - security
    - github
    - sonarqube
    - servicenow
    - code-quality
capability:
  exposes:
    - type: mcp
      namespace: devops-quality
      port: 8080
      tools:
        - name: digest-security-scan
          description: "Given a GitHub repository name and SonarQube project key, retrieve the latest quality gate result and post a scan digest as a ServiceNow advisory note."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "GitHub repository name within the ibm org."
            - name: sonar_project_key
              in: body
              type: string
              description: "SonarQube project key, e.g. ibm_my-service."
          steps:
            - name: get-quality-gate
              type: call
              call: "sonarqube.get-quality-gate"
              with:
                projectKey: "{{sonar_project_key}}"
            - name: get-repo-info
              type: call
              call: "github-scan.get-repo"
              with:
                owner: "ibm"
                repo: "{{repo}}"
            - name: post-advisory
              type: call
              call: "servicenow-cab.create-advisory"
              with:
                short_description: "Code scan: {{repo}} — Gate: {{get-quality-gate.status}}"
                description: "Bugs: {{get-quality-gate.bugs}} | Vulnerabilities: {{get-quality-gate.vulnerabilities}} | Coverage: {{get-quality-gate.coverage}}"
  consumes:
    - type: http
      namespace: sonarqube
      baseUri: "https://sonarqube.ibm.internal/api"
      authentication:
        type: basic
        username: "$secrets.sonar_token"
        password: ""
      resources:
        - name: quality-gate
          path: "/qualitygates/project_status"
          inputParameters:
            - name: projectKey
              in: query
          operations:
            - name: get-quality-gate
              method: GET
    - type: http
      namespace: github-scan
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: repos
          path: "/repos/{{owner}}/{{repo}}"
          inputParameters:
            - name: owner
              in: path
            - name: repo
              in: path
          operations:
            - name: get-repo
              method: GET
    - type: http
      namespace: servicenow-cab
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: advisories
          path: "/table/change_request"
          operations:
            - name: create-advisory
              method: POST

On a GitLab merge request to a protected branch, runs a SonarQube quality gate check and blocks the MR with a comment if vulnerabilities exceed the allowed threshold.

naftiko: "0.5"
info:
  label: "GitLab Merge Request Security Gate"
  description: "On a GitLab merge request to a protected branch, runs a SonarQube quality gate check and blocks the MR with a comment if vulnerabilities exceed the allowed threshold."
  tags:
    - devops
    - security
    - gitlab
    - sonarqube
    - code-quality
capability:
  exposes:
    - type: mcp
      namespace: mr-security-gate
      port: 8080
      tools:
        - name: gate-merge-request
          description: "Given a GitLab project ID, MR IID, and SonarQube project key, run a quality gate check and post a blocking comment on the MR if critical vulnerabilities are found."
          inputParameters:
            - name: gitlab_project_id
              in: body
              type: string
              description: "GitLab project ID (numeric)."
            - name: mr_iid
              in: body
              type: string
              description: "GitLab merge request internal ID."
            - name: sonar_project_key
              in: body
              type: string
              description: "SonarQube project key to check."
          steps:
            - name: get-quality-gate
              type: call
              call: "sonarqube-gate.get-quality-gate"
              with:
                projectKey: "{{sonar_project_key}}"
            - name: post-mr-comment
              type: call
              call: "gitlab.create-mr-note"
              with:
                project_id: "{{gitlab_project_id}}"
                merge_request_iid: "{{mr_iid}}"
                body: "Security Gate: {{get-quality-gate.status}} | Vulnerabilities: {{get-quality-gate.vulnerabilities}} | Blockers: {{get-quality-gate.blocker_violations}}"
  consumes:
    - type: http
      namespace: sonarqube-gate
      baseUri: "https://sonarqube.ibm.internal/api"
      authentication:
        type: basic
        username: "$secrets.sonar_token"
        password: ""
      resources:
        - name: quality-gate
          path: "/qualitygates/project_status"
          inputParameters:
            - name: projectKey
              in: query
          operations:
            - name: get-quality-gate
              method: GET
    - type: http
      namespace: gitlab
      baseUri: "https://gitlab.ibm.com/api/v4"
      authentication:
        type: bearer
        token: "$secrets.gitlab_token"
      resources:
        - name: mr-notes
          path: "/projects/{{project_id}}/merge_requests/{{merge_request_iid}}/notes"
          inputParameters:
            - name: project_id
              in: path
            - name: merge_request_iid
              in: path
          operations:
            - name: create-mr-note
              method: POST

Lists recently provisioned GCP resources in a project and creates a ServiceNow change record for each untracked resource detected during daily audit.

naftiko: "0.5"
info:
  label: "Google Cloud Platform Resource Provisioning Audit"
  description: "Lists recently provisioned GCP resources in a project and creates a ServiceNow change record for each untracked resource detected during daily audit."
  tags:
    - cloud
    - gcp
    - servicenow
    - governance
    - audit
capability:
  exposes:
    - type: mcp
      namespace: cloud-audit
      port: 8080
      tools:
        - name: audit-gcp-resources
          description: "Given a GCP project ID, list all compute and storage resources created in the last 24 hours and open ServiceNow change records for any resources not already tracked."
          inputParameters:
            - name: gcp_project_id
              in: body
              type: string
              description: "Google Cloud Platform project ID."
          steps:
            - name: list-resources
              type: call
              call: "gcp.list-assets"
              with:
                projectId: "{{gcp_project_id}}"
                assetTypes: "compute.googleapis.com/Instance,storage.googleapis.com/Bucket"
            - name: create-change-record
              type: call
              call: "servicenow-audit.create-change"
              with:
                short_description: "GCP resource audit: {{gcp_project_id}}"
                description: "New resources detected: {{list-resources.asset_count}}"
  consumes:
    - type: http
      namespace: gcp
      baseUri: "https://cloudasset.googleapis.com/v1"
      authentication:
        type: bearer
        token: "$secrets.gcp_token"
      resources:
        - name: assets
          path: "/projects/{{projectId}}/assets"
          inputParameters:
            - name: projectId
              in: path
            - name: assetTypes
              in: query
          operations:
            - name: list-assets
              method: GET
    - type: http
      namespace: servicenow-audit
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: changes
          path: "/table/change_request"
          operations:
            - name: create-change
              method: POST

When a Grafana alert fires, creates a ServiceNow incident and attaches the relevant Confluence runbook link for remediation.

naftiko: "0.5"
info:
  label: "Grafana Alert to ServiceNow with Runbook"
  description: "When a Grafana alert fires, creates a ServiceNow incident and attaches the relevant Confluence runbook link for remediation."
  tags:
    - observability
    - itsm
    - grafana
    - servicenow
    - confluence
capability:
  exposes:
    - type: mcp
      namespace: alert-mgmt
      port: 8080
      tools:
        - name: handle-grafana-alert
          description: "Given a Grafana alert rule name and service, create a ServiceNow incident and attach the Confluence runbook."
          inputParameters:
            - name: alert_name
              in: body
              type: string
              description: "Grafana alert rule name."
            - name: service_name
              in: body
              type: string
              description: "Affected service name."
          steps:
            - name: get-runbook
              type: call
              call: "confluence.get-page"
              with:
                spaceKey: "RUNBOOKS"
                title: "Runbook: {{service_name}}"
            - name: create-incident
              type: call
              call: "servicenow-ops.create-incident"
              with:
                short_description: "Grafana alert: {{alert_name}} on {{service_name}}"
                description: "Runbook: {{get-runbook.url}}"
                urgency: "2"
                assignment_group: "Platform_SRE"
  consumes:
    - type: http
      namespace: confluence
      baseUri: "https://ibm-wiki.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_api_token"
      resources:
        - name: content
          path: "/content"
          operations:
            - name: get-page
              method: GET
    - type: http
      namespace: servicenow-ops
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST

Searches HubSpot CRM for a contact by email address, returning company, lifecycle stage, and last activity date.

naftiko: "0.5"
info:
  label: "HubSpot Contact Lookup"
  description: "Searches HubSpot CRM for a contact by email address, returning company, lifecycle stage, and last activity date."
  tags:
    - crm
    - marketing
    - hubspot
capability:
  exposes:
    - type: mcp
      namespace: crm
      port: 8080
      tools:
        - name: lookup-contact
          description: "Given an email address, search HubSpot CRM for the matching contact and return company, lifecycle stage, and last activity."
          inputParameters:
            - name: email
              in: body
              type: string
              description: "Contact email address."
          call: hubspot.search-contacts
          with:
            email: "{{email}}"
          outputParameters:
            - name: company
              type: string
              mapping: "$.results[0].properties.company"
            - name: lifecycle_stage
              type: string
              mapping: "$.results[0].properties.lifecyclestage"
  consumes:
    - type: http
      namespace: hubspot
      baseUri: "https://api.hubapi.com"
      authentication:
        type: bearer
        token: "$secrets.hubspot_token"
      resources:
        - name: contacts
          path: "/crm/v3/objects/contacts/search"
          operations:
            - name: search-contacts
              method: POST

Retrieves high-scoring leads from HubSpot and creates corresponding Salesforce lead records with owner assignment and Slack notification.

naftiko: "0.5"
info:
  label: "HubSpot Lead Scoring to Salesforce Assignment"
  description: "Retrieves high-scoring leads from HubSpot and creates corresponding Salesforce lead records with owner assignment and Slack notification."
  tags:
    - crm
    - marketing
    - hubspot
    - salesforce
    - slack
capability:
  exposes:
    - type: mcp
      namespace: lead-ops
      port: 8080
      tools:
        - name: route-high-score-leads
          description: "Given a HubSpot lead score threshold, retrieve qualifying leads and create Salesforce records with routing."
          inputParameters:
            - name: score_threshold
              in: body
              type: number
              description: "Minimum lead score to qualify."
          steps:
            - name: get-leads
              type: call
              call: "hubspot.search-contacts"
              with:
                min_score: "{{score_threshold}}"
            - name: create-sf-lead
              type: call
              call: "salesforce.create-lead"
              with:
                FirstName: "{{get-leads.results[0].properties.firstname}}"
                LastName: "{{get-leads.results[0].properties.lastname}}"
                Company: "{{get-leads.results[0].properties.company}}"
                Email: "{{get-leads.results[0].properties.email}}"
            - name: notify-sales
              type: call
              call: "slack.post-message"
              with:
                channel: "#sales-leads"
                text: "High-score lead routed to Salesforce: {{get-leads.results[0].properties.firstname}} {{get-leads.results[0].properties.lastname}} (Score: {{get-leads.results[0].properties.hubspotscore}})"
  consumes:
    - type: http
      namespace: hubspot
      baseUri: "https://api.hubapi.com"
      authentication:
        type: bearer
        token: "$secrets.hubspot_token"
      resources:
        - name: contacts
          path: "/crm/v3/objects/contacts/search"
          operations:
            - name: search-contacts
              method: POST
    - type: http
      namespace: salesforce
      baseUri: "https://ibm.my.salesforce.com/services/data/v59.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: leads
          path: "/sobjects/Lead"
          operations:
            - name: create-lead
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a Jira bug is marked as a recurring defect, creates a ServiceNow problem record and links the Jira issue to the problem for root cause analysis.

naftiko: "0.5"
info:
  label: "Jira Bug to ServiceNow Problem"
  description: "When a Jira bug is marked as a recurring defect, creates a ServiceNow problem record and links the Jira issue to the problem for root cause analysis."
  tags:
    - devops
    - itsm
    - jira
    - servicenow
    - problem-management
capability:
  exposes:
    - type: mcp
      namespace: problem-mgmt
      port: 8080
      tools:
        - name: escalate-bug-to-problem
          description: "Given a Jira issue key for a recurring bug, create a ServiceNow problem record and update the Jira issue with the problem number."
          inputParameters:
            - name: issue_key
              in: body
              type: string
              description: "Jira issue key for the recurring bug."
          steps:
            - name: get-jira-bug
              type: call
              call: "jira.get-issue"
              with:
                issue_key: "{{issue_key}}"
            - name: create-problem
              type: call
              call: "servicenow-prob.create-problem"
              with:
                short_description: "Recurring defect: {{get-jira-bug.fields.summary}}"
                description: "Jira ref: {{issue_key}} | Priority: {{get-jira-bug.fields.priority.name}}"
                category: "software"
            - name: update-jira
              type: call
              call: "jira.add-comment"
              with:
                issue_key: "{{issue_key}}"
                body: "ServiceNow problem {{create-problem.number}} created for root cause analysis."
  consumes:
    - type: http
      namespace: jira
      baseUri: "https://ibm-jira.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
        - name: comments
          path: "/issue/{{issue_key}}/comment"
          inputParameters:
            - name: issue_key
              in: path
          operations:
            - name: add-comment
              method: POST
    - type: http
      namespace: servicenow-prob
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: problems
          path: "/table/problem"
          operations:
            - name: create-problem
              method: POST

When a Jira epic is completed, updates the corresponding Salesforce opportunity stage and notifies the account team.

naftiko: "0.5"
info:
  label: "Jira Epic Completion to Salesforce Update"
  description: "When a Jira epic is completed, updates the corresponding Salesforce opportunity stage and notifies the account team."
  tags:
    - devops
    - crm
    - jira
    - salesforce
    - slack
capability:
  exposes:
    - type: mcp
      namespace: delivery-crm
      port: 8080
      tools:
        - name: sync-epic-completion
          description: "Given a Jira epic key and Salesforce opportunity ID, update the opportunity delivery status and notify the team."
          inputParameters:
            - name: epic_key
              in: body
              type: string
              description: "Jira epic key."
            - name: opportunity_id
              in: body
              type: string
              description: "Salesforce opportunity ID."
          steps:
            - name: get-epic
              type: call
              call: "jira.get-issue"
              with:
                issue_key: "{{epic_key}}"
            - name: update-opportunity
              type: call
              call: "salesforce.update-opportunity"
              with:
                opportunity_id: "{{opportunity_id}}"
                StageName: "Delivered"
                Description: "Epic {{epic_key}} completed: {{get-epic.fields.summary}}"
            - name: notify-account
              type: call
              call: "slack.post-message"
              with:
                channel: "#account-team"
                text: "Epic {{epic_key}} delivered — Salesforce opportunity {{opportunity_id}} updated to Delivered"
  consumes:
    - type: http
      namespace: jira
      baseUri: "https://ibm-jira.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
    - type: http
      namespace: salesforce
      baseUri: "https://ibm.my.salesforce.com/services/data/v59.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
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves the current status, assignee, and priority of a Jira issue by key for project management and engineering queries.

naftiko: "0.5"
info:
  label: "Jira Issue Status Lookup"
  description: "Retrieves the current status, assignee, and priority of a Jira issue by key for project management and engineering queries."
  tags:
    - devops
    - jira
    - project-management
capability:
  exposes:
    - type: mcp
      namespace: project-mgmt
      port: 8080
      tools:
        - name: get-jira-issue
          description: "Given a Jira issue key, retrieve current status, assignee, priority, and summary."
          inputParameters:
            - name: issue_key
              in: body
              type: string
              description: "Jira issue key, e.g. PROJ-1234."
          call: jira.get-issue
          with:
            issue_key: "{{issue_key}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.fields.status.name"
            - name: assignee
              type: string
              mapping: "$.fields.assignee.displayName"
            - name: priority
              type: string
              mapping: "$.fields.priority.name"
  consumes:
    - type: http
      namespace: jira
      baseUri: "https://ibm-jira.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

Compiles completed Jira issues for a release version, generates a Confluence release notes page, and notifies stakeholders via Slack.

naftiko: "0.5"
info:
  label: "Jira Release Notes to Confluence"
  description: "Compiles completed Jira issues for a release version, generates a Confluence release notes page, and notifies stakeholders via Slack."
  tags:
    - devops
    - documentation
    - jira
    - confluence
    - slack
capability:
  exposes:
    - type: mcp
      namespace: release-mgmt
      port: 8080
      tools:
        - name: generate-release-notes
          description: "Given a Jira project and fix version, compile issues and create a Confluence release notes page."
          inputParameters:
            - name: project
              in: body
              type: string
              description: "Jira project key."
            - name: fix_version
              in: body
              type: string
              description: "Jira fix version name."
          steps:
            - name: get-issues
              type: call
              call: "jira.search-issues"
              with:
                jql: "project={{project}} AND fixVersion='{{fix_version}}' AND status=Done"
            - name: create-release-page
              type: call
              call: "confluence.create-page"
              with:
                space_key: "RELEASES"
                title: "Release Notes: {{project}} {{fix_version}}"
                body: "## Release {{fix_version}}\n\n### Issues Completed\n{{get-issues.summary_list}}"
            - name: notify-stakeholders
              type: call
              call: "slack.post-message"
              with:
                channel: "#releases"
                text: "Release notes published for {{project}} {{fix_version}}: {{create-release-page.url}}"
  consumes:
    - type: http
      namespace: jira
      baseUri: "https://ibm-jira.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: search
          path: "/search"
          operations:
            - name: search-issues
              method: POST
    - type: http
      namespace: confluence
      baseUri: "https://ibm-wiki.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_api_token"
      resources:
        - name: content
          path: "/content"
          operations:
            - name: create-page
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Lists all active routes and services registered in the Kong API Gateway and reconciles them against a ServiceNow CMDB API record baseline.

naftiko: "0.5"
info:
  label: "Kong API Gateway Route Audit"
  description: "Lists all active routes and services registered in the Kong API Gateway and reconciles them against a ServiceNow CMDB API record baseline."
  tags:
    - api
    - integration
    - kong
    - servicenow
    - governance
capability:
  exposes:
    - type: mcp
      namespace: api-governance
      port: 8080
      tools:
        - name: audit-kong-routes
          description: "List all Kong services and routes and compare against the ServiceNow CMDB. Create a CMDB update task for any unregistered API route detected."
          inputParameters:
            - name: kong_admin_url
              in: body
              type: string
              description: "Kong Admin API base URL."
          steps:
            - name: list-services
              type: call
              call: "kong.list-services"
              with:
                admin_url: "{{kong_admin_url}}"
            - name: create-cmdb-task
              type: call
              call: "servicenow-cmdb.create-task"
              with:
                short_description: "Kong API audit — unregistered routes detected"
                description: "Total services: {{list-services.total}} | Unregistered: {{list-services.unregistered_count}}"
                assignment_group: "API_Platform"
  consumes:
    - type: http
      namespace: kong
      baseUri: "https://kong-admin.ibm.internal:8001"
      authentication:
        type: apikey
        key: "Kong-Admin-Token"
        value: "$secrets.kong_admin_token"
        placement: header
      resources:
        - name: services
          path: "/services"
          operations:
            - name: list-services
              method: GET
    - type: http
      namespace: servicenow-cmdb
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST

Pulls new LinkedIn recruiter candidates for a given job requisition and creates candidate records in PeopleSoft HCM for recruiter review.

naftiko: "0.5"
info:
  label: "LinkedIn Talent Pipeline to PeopleSoft Candidate Record"
  description: "Pulls new LinkedIn recruiter candidates for a given job requisition and creates candidate records in PeopleSoft HCM for recruiter review."
  tags:
    - hr
    - recruiting
    - linkedin
    - peoplesoft
    - talent-acquisition
capability:
  exposes:
    - type: mcp
      namespace: talent-acquisition
      port: 8080
      tools:
        - name: sync-linkedin-candidates
          description: "Given a LinkedIn job posting ID and a PeopleSoft business unit, fetch newly applied candidates from LinkedIn Recruiter and create candidate profiles in PeopleSoft HCM."
          inputParameters:
            - name: linkedin_job_id
              in: body
              type: string
              description: "LinkedIn job posting ID."
            - name: business_unit
              in: body
              type: string
              description: "PeopleSoft HCM business unit code."
          steps:
            - name: get-candidates
              type: call
              call: "linkedin.get-applicants"
              with:
                jobId: "{{linkedin_job_id}}"
            - name: create-ps-candidates
              type: call
              call: "peoplesoft.create-candidate"
              with:
                business_unit: "{{business_unit}}"
                applicants: "{{get-candidates.applicants}}"
  consumes:
    - type: http
      namespace: linkedin
      baseUri: "https://api.linkedin.com/v2"
      authentication:
        type: bearer
        token: "$secrets.linkedin_token"
      resources:
        - name: applicants
          path: "/jobApplications"
          inputParameters:
            - name: jobId
              in: query
          operations:
            - name: get-applicants
              method: GET
    - type: http
      namespace: peoplesoft
      baseUri: "https://ibm-ps.internal/hcm/api/v1"
      authentication:
        type: basic
        username: "$secrets.peoplesoft_user"
        password: "$secrets.peoplesoft_password"
      resources:
        - name: candidates
          path: "/candidates"
          operations:
            - name: create-candidate
              method: POST

Retrieves a Microsoft Teams meeting transcript summary and publishes it as a Confluence page for team knowledge base.

naftiko: "0.5"
info:
  label: "Microsoft Teams Meeting Summary to Confluence"
  description: "Retrieves a Microsoft Teams meeting transcript summary and publishes it as a Confluence page for team knowledge base."
  tags:
    - communication
    - documentation
    - microsoft-teams
    - confluence
capability:
  exposes:
    - type: mcp
      namespace: meeting-notes
      port: 8080
      tools:
        - name: publish-meeting-notes
          description: "Given a Teams meeting ID and Confluence space, retrieve the transcript and create a Confluence page."
          inputParameters:
            - name: meeting_id
              in: body
              type: string
              description: "Microsoft Teams meeting ID."
            - name: space_key
              in: body
              type: string
              description: "Confluence space key."
          steps:
            - name: get-transcript
              type: call
              call: "teams.get-meeting-transcript"
              with:
                meeting_id: "{{meeting_id}}"
            - name: create-page
              type: call
              call: "confluence.create-page"
              with:
                space_key: "{{space_key}}"
                title: "Meeting Notes: {{get-transcript.subject}} — {{get-transcript.date}}"
                body: "## Attendees\n{{get-transcript.attendees}}\n\n## Summary\n{{get-transcript.summary}}"
  consumes:
    - type: http
      namespace: teams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.azure_graph_token"
      resources:
        - name: meetings
          path: "/me/onlineMeetings/{{meeting_id}}/transcripts"
          inputParameters:
            - name: meeting_id
              in: path
          operations:
            - name: get-meeting-transcript
              method: GET
    - type: http
      namespace: confluence
      baseUri: "https://ibm-wiki.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_api_token"
      resources:
        - name: content
          path: "/content"
          operations:
            - name: create-page
              method: POST

Retrieves the health status, response time, and error rate of an application monitored by New Relic APM.

naftiko: "0.5"
info:
  label: "New Relic Application Health Lookup"
  description: "Retrieves the health status, response time, and error rate of an application monitored by New Relic APM."
  tags:
    - observability
    - new-relic
    - apm
capability:
  exposes:
    - type: mcp
      namespace: app-health
      port: 8080
      tools:
        - name: get-app-health
          description: "Given a New Relic application name, return its health status, average response time, and error rate."
          inputParameters:
            - name: app_name
              in: body
              type: string
              description: "New Relic application name."
          call: newrelic.get-application
          with:
            name: "{{app_name}}"
          outputParameters:
            - name: health_status
              type: string
              mapping: "$.applications[0].health_status"
            - name: response_time
              type: number
              mapping: "$.applications[0].application_summary.response_time"
  consumes:
    - type: http
      namespace: newrelic
      baseUri: "https://api.newrelic.com/v2"
      authentication:
        type: apikey
        key: "X-Api-Key"
        value: "$secrets.newrelic_api_key"
        placement: header
      resources:
        - name: applications
          path: "/applications.json"
          inputParameters:
            - name: name
              in: query
          operations:
            - name: get-application
              method: GET

When New Relic detects an application error rate spike, creates a Jira bug ticket and notifies the engineering team via Slack.

naftiko: "0.5"
info:
  label: "New Relic Error Spike to Jira Bug"
  description: "When New Relic detects an application error rate spike, creates a Jira bug ticket and notifies the engineering team via Slack."
  tags:
    - observability
    - devops
    - new-relic
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: error-tracking
      port: 8080
      tools:
        - name: handle-error-spike
          description: "Given a New Relic application ID and error threshold, check the error rate, create a Jira bug if exceeded, and notify Slack."
          inputParameters:
            - name: app_id
              in: body
              type: string
              description: "New Relic application ID."
            - name: error_threshold
              in: body
              type: number
              description: "Error rate percentage threshold."
          steps:
            - name: get-app-metrics
              type: call
              call: "newrelic.get-app-metrics"
              with:
                app_id: "{{app_id}}"
            - name: create-bug
              type: call
              call: "jira.create-issue"
              with:
                project: "ENG"
                issuetype: "Bug"
                summary: "Error spike: {{get-app-metrics.app_name}} at {{get-app-metrics.error_rate}}%"
                priority: "High"
            - name: notify-team
              type: call
              call: "slack.post-message"
              with:
                channel: "#engineering"
                text: "Error spike detected for {{get-app-metrics.app_name}} — Jira: {{create-bug.key}}"
  consumes:
    - type: http
      namespace: newrelic
      baseUri: "https://api.newrelic.com/v2"
      authentication:
        type: apikey
        key: "X-Api-Key"
        value: "$secrets.newrelic_api_key"
        placement: header
      resources:
        - name: applications
          path: "/applications/{{app_id}}.json"
          inputParameters:
            - name: app_id
              in: path
          operations:
            - name: get-app-metrics
              method: GET
    - type: http
      namespace: jira
      baseUri: "https://ibm-jira.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Resets a user MFA factors in Okta based on an approved ServiceNow request, then updates the ticket with completion status.

naftiko: "0.5"
info:
  label: "Okta MFA Reset with ServiceNow Ticket"
  description: "Resets a user MFA factors in Okta based on an approved ServiceNow request, then updates the ticket with completion status."
  tags:
    - security
    - identity
    - okta
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: identity-ops
      port: 8080
      tools:
        - name: reset-mfa
          description: "Given a ServiceNow request number and user email, reset the user MFA in Okta and update the ServiceNow ticket."
          inputParameters:
            - name: request_number
              in: body
              type: string
              description: "ServiceNow request number."
            - name: user_email
              in: body
              type: string
              description: "User email for MFA reset."
          steps:
            - name: reset-okta-mfa
              type: call
              call: "okta.reset-factors"
              with:
                user_id: "{{user_email}}"
            - name: update-ticket
              type: call
              call: "servicenow-req.update-request"
              with:
                number: "{{request_number}}"
                state: "closed_complete"
                close_notes: "MFA factors reset for {{user_email}}"
  consumes:
    - type: http
      namespace: okta
      baseUri: "https://ibm.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "SSWS $secrets.okta_api_token"
        placement: header
      resources:
        - name: factors
          path: "/users/{{user_id}}/lifecycle/reset_factors"
          inputParameters:
            - name: user_id
              in: path
          operations:
            - name: reset-factors
              method: POST
    - type: http
      namespace: servicenow-req
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: requests
          path: "/table/sc_request"
          operations:
            - name: update-request
              method: PATCH

Generates a quarterly access review by pulling all Okta application assignments, loading to Snowflake, and creating a ServiceNow access review task.

naftiko: "0.5"
info:
  label: "Okta Quarterly Access Review Report"
  description: "Generates a quarterly access review by pulling all Okta application assignments, loading to Snowflake, and creating a ServiceNow access review task."
  tags:
    - security
    - compliance
    - okta
    - snowflake
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: access-review
      port: 8080
      tools:
        - name: run-access-review
          description: "Pull all Okta app assignments, load into Snowflake for analysis, and create a ServiceNow review task."
          inputParameters:
            - name: review_quarter
              in: body
              type: string
              description: "Quarter label, e.g. Q1-2026."
          steps:
            - name: get-app-assignments
              type: call
              call: "okta.list-app-users"
              with:
                limit: "200"
            - name: load-to-snowflake
              type: call
              call: "snowflake.execute-query"
              with:
                statement: "INSERT INTO SECURITY.ACCESS_REVIEWS (quarter, app_count) VALUES ('{{review_quarter}}', {{get-app-assignments.total}})"
            - name: create-review-task
              type: call
              call: "servicenow-sec.create-task"
              with:
                short_description: "Quarterly access review: {{review_quarter}} — {{get-app-assignments.total}} assignments"
                assignment_group: "IAM_Team"
  consumes:
    - type: http
      namespace: okta
      baseUri: "https://ibm.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "SSWS $secrets.okta_api_token"
        placement: header
      resources:
        - name: app-users
          path: "/apps"
          operations:
            - name: list-app-users
              method: GET
    - type: http
      namespace: snowflake
      baseUri: "https://ibm.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-query
              method: POST
    - type: http
      namespace: servicenow-sec
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST

When Okta flags a suspicious login event, triggers a Splunk investigation query and creates a ServiceNow security incident with findings.

naftiko: "0.5"
info:
  label: "Okta Suspicious Login to Splunk Investigation"
  description: "When Okta flags a suspicious login event, triggers a Splunk investigation query and creates a ServiceNow security incident with findings."
  tags:
    - security
    - identity
    - okta
    - splunk
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: threat-response
      port: 8080
      tools:
        - name: investigate-suspicious-login
          description: "Given an Okta event ID, retrieve the event details, run a Splunk correlation query, and create a security incident."
          inputParameters:
            - name: event_id
              in: body
              type: string
              description: "Okta system log event ID."
          steps:
            - name: get-okta-event
              type: call
              call: "okta.get-event"
              with:
                event_id: "{{event_id}}"
            - name: run-splunk-query
              type: call
              call: "splunk.create-search"
              with:
                search: "index=network src_ip={{get-okta-event.client.ipAddress}} earliest=-24h"
            - name: create-sec-incident
              type: call
              call: "servicenow-sec.create-incident"
              with:
                short_description: "Suspicious login: {{get-okta-event.actor.displayName}} from {{get-okta-event.client.ipAddress}}"
                category: "security"
                severity: "2"
                assignment_group: "SOC_Team"
  consumes:
    - type: http
      namespace: okta
      baseUri: "https://ibm.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "SSWS $secrets.okta_api_token"
        placement: header
      resources:
        - name: events
          path: "/logs/{{event_id}}"
          inputParameters:
            - name: event_id
              in: path
          operations:
            - name: get-event
              method: GET
    - type: http
      namespace: splunk
      baseUri: "https://splunk.ibm.com:8089/services"
      authentication:
        type: bearer
        token: "$secrets.splunk_token"
      resources:
        - name: search-jobs
          path: "/search/jobs"
          operations:
            - name: create-search
              method: POST
    - type: http
      namespace: servicenow-sec
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: incidents
          path: "/table/sn_si_incident"
          operations:
            - name: create-incident
              method: POST

Lists all Okta groups a user belongs to by email address for identity governance and access review queries.

naftiko: "0.5"
info:
  label: "Okta User Group Membership Lookup"
  description: "Lists all Okta groups a user belongs to by email address for identity governance and access review queries."
  tags:
    - security
    - identity
    - okta
capability:
  exposes:
    - type: mcp
      namespace: identity
      port: 8080
      tools:
        - name: get-user-groups
          description: "Given a user email, retrieve all Okta group memberships for the user."
          inputParameters:
            - name: user_email
              in: body
              type: string
              description: "User email address registered in Okta."
          call: okta.get-user-groups
          with:
            user_id: "{{user_email}}"
  consumes:
    - type: http
      namespace: okta
      baseUri: "https://ibm.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "SSWS $secrets.okta_api_token"
        placement: header
      resources:
        - name: user-groups
          path: "/users/{{user_id}}/groups"
          inputParameters:
            - name: user_id
              in: path
          operations:
            - name: get-user-groups
              method: GET

Queries Oracle Cloud cost management for daily spend anomalies above a configured threshold and creates a ServiceNow task for FinOps review.

naftiko: "0.5"
info:
  label: "Oracle Cloud Cost Anomaly Detection"
  description: "Queries Oracle Cloud cost management for daily spend anomalies above a configured threshold and creates a ServiceNow task for FinOps review."
  tags:
    - cloud
    - finops
    - oracle-cloud
    - servicenow
    - cost-management
capability:
  exposes:
    - type: mcp
      namespace: cloud-finops
      port: 8080
      tools:
        - name: detect-cost-anomaly
          description: "Given an Oracle Cloud compartment OCID and a daily spend threshold in USD, check the current day's cost and open a ServiceNow FinOps review task if the threshold is exceeded."
          inputParameters:
            - name: compartment_id
              in: body
              type: string
              description: "Oracle Cloud compartment OCID to analyze."
            - name: threshold_usd
              in: body
              type: number
              description: "Daily spend threshold in USD above which to trigger an alert."
          steps:
            - name: get-daily-cost
              type: call
              call: "oracle-cloud.get-usage-summary"
              with:
                compartmentId: "{{compartment_id}}"
            - name: create-review-task
              type: call
              call: "servicenow-finops.create-task"
              with:
                short_description: "Cost anomaly: {{compartment_id}} exceeded ${{threshold_usd}}"
                category: "finops"
                assignment_group: "Cloud_FinOps"
                description: "Daily cost: ${{get-daily-cost.total_amount_usd}}"
  consumes:
    - type: http
      namespace: oracle-cloud
      baseUri: "https://usageapi.us-ashburn-1.oraclecloud.com/20200107"
      authentication:
        type: bearer
        token: "$secrets.oracle_cloud_token"
      resources:
        - name: usage-summary
          path: "/usageSummary"
          inputParameters:
            - name: compartmentId
              in: query
          operations:
            - name: get-usage-summary
              method: POST
    - type: http
      namespace: servicenow-finops
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST

Retrieves general ledger journal entry details from Oracle E-Business Suite for a given period and ledger. Used by finance agents during period-close reconciliation.

naftiko: "0.5"
info:
  label: "Oracle E-Business Suite GL Journal Lookup"
  description: "Retrieves general ledger journal entry details from Oracle E-Business Suite for a given period and ledger. Used by finance agents during period-close reconciliation."
  tags:
    - finance
    - erp
    - oracle-ebs
    - general-ledger
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: gl-finance
      port: 8080
      tools:
        - name: get-gl-journal
          description: "Given a ledger ID and accounting period name, retrieve unposted journal entries from Oracle EBS for review and approval."
          inputParameters:
            - name: ledger_id
              in: body
              type: string
              description: "Oracle EBS ledger ID."
            - name: period_name
              in: body
              type: string
              description: "Accounting period name, e.g. JAN-2025."
          call: "oracle-ebs.get-journals"
          with:
            ledger_id: "{{ledger_id}}"
            period_name: "{{period_name}}"
          outputParameters:
            - name: journal_count
              type: string
              mapping: "$.count"
            - name: total_debit
              type: string
              mapping: "$.totalDebit"
            - name: total_credit
              type: string
              mapping: "$.totalCredit"
  consumes:
    - type: http
      namespace: oracle-ebs
      baseUri: "https://ibm-ebs.oracle.com/webservices/portal"
      authentication:
        type: basic
        username: "$secrets.oracle_ebs_user"
        password: "$secrets.oracle_ebs_password"
      resources:
        - name: journals
          path: "/GlJournalLookupService/getJournals"
          inputParameters:
            - name: ledger_id
              in: query
            - name: period_name
              in: query
          operations:
            - name: get-journals
              method: GET

Extracts accounts payable invoice data from Oracle E-Business Suite and loads it into Snowflake for finance analytics.

naftiko: "0.5"
info:
  label: "Oracle EBS AP Invoice to Snowflake Sync"
  description: "Extracts accounts payable invoice data from Oracle E-Business Suite and loads it into Snowflake for finance analytics."
  tags:
    - finance
    - data
    - oracle
    - snowflake
capability:
  exposes:
    - type: mcp
      namespace: finance-etl
      port: 8080
      tools:
        - name: sync-ap-invoices
          description: "Given a date range, extract AP invoices from Oracle EBS and load them into the Snowflake finance schema."
          inputParameters:
            - name: start_date
              in: body
              type: string
              description: "Start date for invoice extraction."
            - name: end_date
              in: body
              type: string
              description: "End date for invoice extraction."
          steps:
            - name: get-invoices
              type: call
              call: "oracle-ebs.get-ap-invoices"
              with:
                start_date: "{{start_date}}"
                end_date: "{{end_date}}"
            - name: load-to-snowflake
              type: call
              call: "snowflake.execute-query"
              with:
                statement: "INSERT INTO FINANCE.AP_INVOICES SELECT * FROM TABLE(RESULT_SCAN('{{get-invoices.query_id}}'))"
  consumes:
    - type: http
      namespace: oracle-ebs
      baseUri: "https://oracle-ebs.ibm.com/webservices/rest"
      authentication:
        type: basic
        username: "$secrets.oracle_ebs_user"
        password: "$secrets.oracle_ebs_password"
      resources:
        - name: ap-invoices
          path: "/ap/invoices"
          inputParameters:
            - name: start_date
              in: query
            - name: end_date
              in: query
          operations:
            - name: get-ap-invoices
              method: GET
    - type: http
      namespace: snowflake
      baseUri: "https://ibm.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-query
              method: POST

Monitors Oracle GoldenGate replication lag and, when threshold is exceeded, creates a ServiceNow incident and notifies the DBA team.

naftiko: "0.5"
info:
  label: "Oracle GoldenGate Replication Lag Alert"
  description: "Monitors Oracle GoldenGate replication lag and, when threshold is exceeded, creates a ServiceNow incident and notifies the DBA team."
  tags:
    - data
    - database
    - oracle
    - servicenow
    - slack
capability:
  exposes:
    - type: mcp
      namespace: db-replication
      port: 8080
      tools:
        - name: check-replication-lag
          description: "Given a GoldenGate process name and lag threshold, check the lag and alert if exceeded."
          inputParameters:
            - name: process_name
              in: body
              type: string
              description: "GoldenGate extract/replicat process name."
            - name: lag_threshold_seconds
              in: body
              type: number
              description: "Maximum acceptable lag in seconds."
          steps:
            - name: get-lag
              type: call
              call: "goldengate.get-process-status"
              with:
                process_name: "{{process_name}}"
            - name: create-incident
              type: call
              call: "servicenow-db.create-incident"
              with:
                short_description: "GoldenGate lag alert: {{process_name}} at {{get-lag.lag_seconds}}s"
                urgency: "2"
                assignment_group: "DBA_Team"
            - name: notify-dba
              type: call
              call: "slack.post-message"
              with:
                channel: "#dba-alerts"
                text: "GoldenGate replication lag: {{process_name}} = {{get-lag.lag_seconds}}s (threshold: {{lag_threshold_seconds}}s)"
  consumes:
    - type: http
      namespace: goldengate
      baseUri: "https://goldengate.ibm.com/api/v2"
      authentication:
        type: basic
        username: "$secrets.gg_user"
        password: "$secrets.gg_password"
      resources:
        - name: processes
          path: "/processes/{{process_name}}/status"
          inputParameters:
            - name: process_name
              in: path
          operations:
            - name: get-process-status
              method: GET
    - type: http
      namespace: servicenow-db
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Queries Oracle Integration Cloud for failed integration instances over the last hour and creates a Datadog event for each failure to enable unified alerting.

naftiko: "0.5"
info:
  label: "Oracle Integration Cloud Process Monitoring"
  description: "Queries Oracle Integration Cloud for failed integration instances over the last hour and creates a Datadog event for each failure to enable unified alerting."
  tags:
    - integration
    - observability
    - oracle-integration
    - datadog
    - monitoring
capability:
  exposes:
    - type: mcp
      namespace: integration-monitoring
      port: 8080
      tools:
        - name: monitor-oic-failures
          description: "Given an Oracle Integration Cloud base URL and lookback window in minutes, retrieve failed integration instances and post each as a Datadog event for monitoring."
          inputParameters:
            - name: oic_base_url
              in: body
              type: string
              description: "Oracle Integration Cloud instance base URL."
            - name: lookback_minutes
              in: body
              type: integer
              description: "Number of minutes to look back for failed instances."
          steps:
            - name: get-failures
              type: call
              call: "oracle-oic.get-failed-instances"
              with:
                baseUrl: "{{oic_base_url}}"
                lookbackMinutes: "{{lookback_minutes}}"
            - name: post-dd-events
              type: call
              call: "datadog-event.post-event"
              with:
                title: "OIC Integration Failure"
                text: "Failed instances: {{get-failures.failed_count}}"
                tags: "source:oracle_integration,env:prod"
  consumes:
    - type: http
      namespace: oracle-oic
      baseUri: "https://ibm-oic.integration.ocp.oraclecloud.com/ic/api/integration/v1"
      authentication:
        type: basic
        username: "$secrets.oic_user"
        password: "$secrets.oic_password"
      resources:
        - name: instances
          path: "/instances"
          inputParameters:
            - name: status
              in: query
          operations:
            - name: get-failed-instances
              method: GET
    - type: http
      namespace: datadog-event
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: events
          path: "/events"
          operations:
            - name: post-event
              method: POST

When a PagerDuty incident is resolved, generates a postmortem page in Confluence with incident timeline and notifies the SRE team.

naftiko: "0.5"
info:
  label: "PagerDuty Incident to Confluence Postmortem"
  description: "When a PagerDuty incident is resolved, generates a postmortem page in Confluence with incident timeline and notifies the SRE team."
  tags:
    - operations
    - documentation
    - pagerduty
    - confluence
    - slack
capability:
  exposes:
    - type: mcp
      namespace: postmortem
      port: 8080
      tools:
        - name: create-postmortem
          description: "Given a PagerDuty incident ID, retrieve the timeline, create a Confluence postmortem page, and notify the team."
          inputParameters:
            - name: incident_id
              in: body
              type: string
              description: "PagerDuty incident ID."
          steps:
            - name: get-incident
              type: call
              call: "pagerduty.get-incident"
              with:
                incident_id: "{{incident_id}}"
            - name: create-page
              type: call
              call: "confluence.create-page"
              with:
                space_key: "SRE"
                title: "Postmortem: {{get-incident.title}} — {{get-incident.created_at}}"
                body: "## Incident Summary\n- **Title:** {{get-incident.title}}\n- **Severity:** {{get-incident.urgency}}\n- **Duration:** {{get-incident.duration}}\n\n## Timeline\n{{get-incident.log_entries}}"
            - name: notify-sre
              type: call
              call: "slack.post-message"
              with:
                channel: "#sre-team"
                text: "Postmortem created for incident {{incident_id}}: {{create-page.url}}"
  consumes:
    - type: http
      namespace: pagerduty
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "Token token=$secrets.pagerduty_token"
        placement: header
      resources:
        - name: incidents
          path: "/incidents/{{incident_id}}"
          inputParameters:
            - name: incident_id
              in: path
          operations:
            - name: get-incident
              method: GET
    - type: http
      namespace: confluence
      baseUri: "https://ibm-wiki.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_api_token"
      resources:
        - name: content
          path: "/content"
          operations:
            - name: create-page
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves the current on-call engineer for a given PagerDuty schedule, returning name, contact, and escalation level.

naftiko: "0.5"
info:
  label: "PagerDuty On-Call Schedule Lookup"
  description: "Retrieves the current on-call engineer for a given PagerDuty schedule, returning name, contact, and escalation level."
  tags:
    - operations
    - pagerduty
    - incident-response
capability:
  exposes:
    - type: mcp
      namespace: ops
      port: 8080
      tools:
        - name: get-on-call
          description: "Given a PagerDuty schedule ID, return the current on-call engineer name and contact information."
          inputParameters:
            - name: schedule_id
              in: body
              type: string
              description: "PagerDuty schedule ID."
          call: pagerduty.get-on-call
          with:
            schedule_id: "{{schedule_id}}"
          outputParameters:
            - name: engineer_name
              type: string
              mapping: "$.schedule.final_schedule.rendered_schedule_entries[0].user.name"
            - name: engineer_email
              type: string
              mapping: "$.schedule.final_schedule.rendered_schedule_entries[0].user.email"
  consumes:
    - type: http
      namespace: pagerduty
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "Token token=$secrets.pagerduty_token"
        placement: header
      resources:
        - name: schedules
          path: "/schedules/{{schedule_id}}"
          inputParameters:
            - name: schedule_id
              in: path
          operations:
            - name: get-on-call
              method: GET

When a Palo Alto Networks firewall generates a critical threat alert, creates a ServiceNow security incident and enriches it with threat intelligence from the alert payload.

naftiko: "0.5"
info:
  label: "Palo Alto Networks Security Alert to ServiceNow Incident"
  description: "When a Palo Alto Networks firewall generates a critical threat alert, creates a ServiceNow security incident and enriches it with threat intelligence from the alert payload."
  tags:
    - security
    - itsm
    - palo-alto-networks
    - servicenow
    - incident-response
capability:
  exposes:
    - type: mcp
      namespace: security-ops
      port: 8080
      tools:
        - name: handle-firewall-alert
          description: "Given a Palo Alto Networks device hostname and threat log ID, retrieve the threat details and open a P2 ServiceNow security incident with full alert context."
          inputParameters:
            - name: device_hostname
              in: body
              type: string
              description: "Hostname or IP of the Palo Alto Networks firewall."
            - name: log_id
              in: body
              type: string
              description: "Threat log entry ID from Palo Alto Networks."
          steps:
            - name: get-threat-log
              type: call
              call: "palo-alto.get-threat-log"
              with:
                hostname: "{{device_hostname}}"
                log_id: "{{log_id}}"
            - name: create-sec-incident
              type: call
              call: "servicenow-sec.create-incident"
              with:
                short_description: "Firewall threat: {{get-threat-log.threat_name}} from {{get-threat-log.src_ip}}"
                category: "security"
                urgency: "2"
                impact: "2"
                work_notes: "Severity: {{get-threat-log.severity}} | Destination: {{get-threat-log.dst_ip}}"
  consumes:
    - type: http
      namespace: palo-alto
      baseUri: "https://{{device_hostname}}/restapi/v10.1"
      authentication:
        type: apikey
        key: "X-PAN-KEY"
        value: "$secrets.paloalto_api_key"
        placement: header
      resources:
        - name: threat-logs
          path: "/log/threat"
          inputParameters:
            - name: log_id
              in: query
          operations:
            - name: get-threat-log
              method: GET
    - type: http
      namespace: servicenow-sec
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST

When an employee termination is recorded in PeopleSoft, opens a ServiceNow offboarding task, revokes Salesforce access, and creates a GitHub access removal issue.

naftiko: "0.5"
info:
  label: "PeopleSoft Employee Termination and ServiceNow Offboarding"
  description: "When an employee termination is recorded in PeopleSoft, opens a ServiceNow offboarding task, revokes Salesforce access, and creates a GitHub access removal issue."
  tags:
    - hr
    - offboarding
    - peoplesoft
    - servicenow
    - salesforce
    - github
capability:
  exposes:
    - type: mcp
      namespace: hr-offboarding
      port: 8080
      tools:
        - name: trigger-offboarding
          description: "Given a PeopleSoft employee ID and termination date, open a ServiceNow offboarding task, remove the employee from Salesforce user list, and file a GitHub issue to revoke repo access."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "PeopleSoft employee ID."
            - name: termination_date
              in: body
              type: string
              description: "Effective termination date in YYYY-MM-DD format."
            - name: employee_email
              in: body
              type: string
              description: "Corporate email address of the departing employee."
          steps:
            - name: open-offboard-task
              type: call
              call: "servicenow-task.create-task"
              with:
                short_description: "Offboarding: {{employee_id}} effective {{termination_date}}"
                category: "hr_offboarding"
                assignment_group: "IT_Security"
            - name: deactivate-sf-user
              type: call
              call: "salesforce-user.deactivate-user"
              with:
                email: "{{employee_email}}"
            - name: file-github-issue
              type: call
              call: "github-offboard.create-issue"
              with:
                owner: "ibm"
                repo: "access-management"
                title: "Revoke access: {{employee_email}} (terminated {{termination_date}})"
                body: "Employee {{employee_id}} has been terminated. Please revoke all repository access."
  consumes:
    - type: http
      namespace: servicenow-task
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: salesforce-user
      baseUri: "https://ibm.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: users
          path: "/sobjects/User"
          operations:
            - name: deactivate-user
              method: PATCH
    - type: http
      namespace: github-offboard
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: issues
          path: "/repos/{{owner}}/{{repo}}/issues"
          inputParameters:
            - name: owner
              in: path
            - name: repo
              in: path
          operations:
            - name: create-issue
              method: POST

Syncs completed Pluralsight course data for an employee to their PeopleSoft HCM training record. Used by L&D agents for compliance tracking.

naftiko: "0.5"
info:
  label: "Pluralsight Learning Completion to PeopleSoft Training Record"
  description: "Syncs completed Pluralsight course data for an employee to their PeopleSoft HCM training record. Used by L&D agents for compliance tracking."
  tags:
    - hr
    - learning
    - pluralsight
    - peoplesoft
    - compliance
capability:
  exposes:
    - type: mcp
      namespace: learning-sync
      port: 8080
      tools:
        - name: sync-learning-completion
          description: "Given a Pluralsight user handle and a PeopleSoft employee ID, retrieve all completed courses from Pluralsight and upsert corresponding training records in PeopleSoft HCM."
          inputParameters:
            - name: pluralsight_handle
              in: body
              type: string
              description: "Pluralsight user handle or email."
            - name: employee_id
              in: body
              type: string
              description: "PeopleSoft employee ID."
          steps:
            - name: get-completions
              type: call
              call: "pluralsight.get-completions"
              with:
                handle: "{{pluralsight_handle}}"
            - name: upsert-training
              type: call
              call: "peoplesoft-training.upsert-training"
              with:
                employee_id: "{{employee_id}}"
                courses: "{{get-completions.courses}}"
  consumes:
    - type: http
      namespace: pluralsight
      baseUri: "https://api.pluralsight.com/v2"
      authentication:
        type: bearer
        token: "$secrets.pluralsight_token"
      resources:
        - name: completions
          path: "/users/{{handle}}/courses/completions"
          inputParameters:
            - name: handle
              in: path
          operations:
            - name: get-completions
              method: GET
    - type: http
      namespace: peoplesoft-training
      baseUri: "https://ibm-ps.internal/hcm/api/v1"
      authentication:
        type: basic
        username: "$secrets.peoplesoft_user"
        password: "$secrets.peoplesoft_password"
      resources:
        - name: training-records
          path: "/employees/{{employee_id}}/training"
          inputParameters:
            - name: employee_id
              in: path
          operations:
            - name: upsert-training
              method: PUT

Checks the last refresh status of a Power BI dataset, returning completion time and status for reporting readiness queries.

naftiko: "0.5"
info:
  label: "Power BI Dataset Refresh Status"
  description: "Checks the last refresh status of a Power BI dataset, returning completion time and status for reporting readiness queries."
  tags:
    - analytics
    - reporting
    - power-bi
capability:
  exposes:
    - type: mcp
      namespace: reporting
      port: 8080
      tools:
        - name: get-dataset-refresh-status
          description: "Given a Power BI group ID and dataset ID, return the last refresh status and end time."
          inputParameters:
            - name: group_id
              in: body
              type: string
              description: "Power BI workspace group ID."
            - name: dataset_id
              in: body
              type: string
              description: "Power BI dataset ID."
          call: powerbi.get-refresh-history
          with:
            group_id: "{{group_id}}"
            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: refreshes
          path: "/groups/{{group_id}}/datasets/{{dataset_id}}/refreshes"
          inputParameters:
            - name: group_id
              in: path
            - name: dataset_id
              in: path
          operations:
            - name: get-refresh-history
              method: GET

Triggers a Power BI dataset refresh, waits for completion, and posts the report link to designated Slack channels for stakeholder distribution.

naftiko: "0.5"
info:
  label: "Power BI Report Distribution via Slack"
  description: "Triggers a Power BI dataset refresh, waits for completion, and posts the report link to designated Slack channels for stakeholder distribution."
  tags:
    - analytics
    - reporting
    - power-bi
    - slack
capability:
  exposes:
    - type: mcp
      namespace: report-dist
      port: 8080
      tools:
        - name: distribute-report
          description: "Given a Power BI dataset ID and report URL, trigger a refresh and distribute to Slack."
          inputParameters:
            - name: dataset_id
              in: body
              type: string
              description: "Power BI dataset ID."
            - name: report_url
              in: body
              type: string
              description: "Power BI report URL."
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel for distribution."
          steps:
            - name: trigger-refresh
              type: call
              call: "powerbi.trigger-refresh"
              with:
                dataset_id: "{{dataset_id}}"
            - name: post-report
              type: call
              call: "slack.post-message"
              with:
                channel: "{{slack_channel}}"
                text: "Weekly report refreshed and ready: {{report_url}}"
  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: trigger-refresh
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Checks the health status of Red Hat OpenShift cluster nodes and pushes custom metrics to Datadog for unified monitoring dashboards.

naftiko: "0.5"
info:
  label: "Red Hat OpenShift Cluster Health to Datadog"
  description: "Checks the health status of Red Hat OpenShift cluster nodes and pushes custom metrics to Datadog for unified monitoring dashboards."
  tags:
    - infrastructure
    - observability
    - red-hat
    - datadog
    - slack
capability:
  exposes:
    - type: mcp
      namespace: k8s-health
      port: 8080
      tools:
        - name: check-cluster-health
          description: "Given an OpenShift cluster URL, check node readiness and push health metrics to Datadog."
          inputParameters:
            - name: cluster_url
              in: body
              type: string
              description: "OpenShift API server URL."
          steps:
            - name: get-nodes
              type: call
              call: "openshift.get-nodes"
              with:
                cluster_url: "{{cluster_url}}"
            - name: push-metrics
              type: call
              call: "datadog.submit-metrics"
              with:
                series_name: "openshift.node.ready_count"
                value: "{{get-nodes.ready_count}}"
                tags: "cluster:{{cluster_url}}"
            - name: notify-ops
              type: call
              call: "slack.post-message"
              with:
                channel: "#k8s-ops"
                text: "OpenShift cluster health: {{get-nodes.ready_count}}/{{get-nodes.total_count}} nodes ready"
  consumes:
    - type: http
      namespace: openshift
      baseUri: "{{cluster_url}}"
      authentication:
        type: bearer
        token: "$secrets.openshift_token"
      resources:
        - name: nodes
          path: "/api/v1/nodes"
          operations:
            - name: get-nodes
              method: GET
    - type: http
      namespace: datadog
      baseUri: "https://api.datadoghq.com/api/v2"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: metrics
          path: "/series"
          operations:
            - name: submit-metrics
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Lists all active Salesforce Flow and Process Builder automations and logs a governance snapshot to a Crystal Reports dataset for quarterly review.

naftiko: "0.5"
info:
  label: "Salesforce Automation Workflow Audit"
  description: "Lists all active Salesforce Flow and Process Builder automations and logs a governance snapshot to a Crystal Reports dataset for quarterly review."
  tags:
    - sales
    - governance
    - salesforce
    - crystal-reports
    - audit
capability:
  exposes:
    - type: mcp
      namespace: sf-governance
      port: 8080
      tools:
        - name: audit-sf-automations
          description: "List all active Salesforce Flows and Process Builder records and push the governance snapshot to a Crystal Reports data store for quarterly compliance review."
          inputParameters:
            - name: report_quarter
              in: body
              type: string
              description: "Report quarter label, e.g. Q1-2025."
          steps:
            - name: list-flows
              type: call
              call: "salesforce-flows.list-flows"
              with:
                status: "Active"
            - name: push-to-report
              type: call
              call: "crystal-gov.refresh-report"
              with:
                report_name: "SalesforceAutomationAudit"
                quarter: "{{report_quarter}}"
                data: "{{list-flows.records}}"
  consumes:
    - type: http
      namespace: salesforce-flows
      baseUri: "https://ibm.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: flows
          path: "/query"
          inputParameters:
            - name: q
              in: query
          operations:
            - name: list-flows
              method: GET
    - type: http
      namespace: crystal-gov
      baseUri: "https://ibm-bobj.internal/biprws/v1"
      authentication:
        type: bearer
        token: "$secrets.crystal_reports_token"
      resources:
        - name: reports
          path: "/reports/refresh"
          operations:
            - name: refresh-report
              method: POST

Retrieves the current status, owner, and priority of a Salesforce support case by case number.

naftiko: "0.5"
info:
  label: "Salesforce Case Status Lookup"
  description: "Retrieves the current status, owner, and priority of a Salesforce support case by case number."
  tags:
    - crm
    - support
    - salesforce
capability:
  exposes:
    - type: mcp
      namespace: support
      port: 8080
      tools:
        - name: get-case-status
          description: "Given a Salesforce case number, return the case status, owner, priority, and subject."
          inputParameters:
            - name: case_number
              in: body
              type: string
              description: "Salesforce case number."
          call: salesforce.get-case
          with:
            case_number: "{{case_number}}"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://ibm.my.salesforce.com/services/data/v59.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: cases
          path: "/query?q=SELECT+Id,Status,Priority,Owner.Name,Subject+FROM+Case+WHERE+CaseNumber='{{case_number}}'"
          inputParameters:
            - name: case_number
              in: query
          operations:
            - name: get-case
              method: GET

When a Salesforce opportunity moves to Closed-Won, creates a Jira project for delivery and posts the kickoff notification to Slack.

naftiko: "0.5"
info:
  label: "Salesforce Closed-Won to Jira Project"
  description: "When a Salesforce opportunity moves to Closed-Won, creates a Jira project for delivery and posts the kickoff notification to Slack."
  tags:
    - crm
    - devops
    - salesforce
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: deal-handoff
      port: 8080
      tools:
        - name: handle-closed-won
          description: "Given a Salesforce opportunity ID, retrieve deal details, create a Jira project, and notify the delivery team via Slack."
          inputParameters:
            - name: opportunity_id
              in: body
              type: string
              description: "Salesforce opportunity ID."
          steps:
            - name: get-opportunity
              type: call
              call: "salesforce.get-opportunity"
              with:
                opportunity_id: "{{opportunity_id}}"
            - name: create-jira-project
              type: call
              call: "jira.create-project"
              with:
                name: "{{get-opportunity.Name}}"
                key: "{{get-opportunity.ProjectKey}}"
                projectTypeKey: "software"
            - name: notify-delivery
              type: call
              call: "slack.post-message"
              with:
                channel: "#delivery-team"
                text: "New project created: {{get-opportunity.Name}} | Jira: {{create-jira-project.key}} | Value: {{get-opportunity.Amount}}"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://ibm.my.salesforce.com/services/data/v59.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: jira
      baseUri: "https://ibm-jira.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: projects
          path: "/project"
          operations:
            - name: create-project
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Identifies Salesforce contracts expiring within 90 days and enrolls the contacts in a HubSpot renewal nurture workflow.

naftiko: "0.5"
info:
  label: "Salesforce Contract Expiry to HubSpot Nurture"
  description: "Identifies Salesforce contracts expiring within 90 days and enrolls the contacts in a HubSpot renewal nurture workflow."
  tags:
    - crm
    - marketing
    - salesforce
    - hubspot
    - slack
capability:
  exposes:
    - type: mcp
      namespace: renewal-nurture
      port: 8080
      tools:
        - name: trigger-renewal-nurture
          description: "Given a Salesforce contract ID expiring soon, enroll the account contact in a HubSpot nurture workflow and notify the CSM."
          inputParameters:
            - name: contract_id
              in: body
              type: string
              description: "Salesforce contract ID."
          steps:
            - name: get-contract
              type: call
              call: "salesforce.get-contract"
              with:
                contract_id: "{{contract_id}}"
            - name: enroll-nurture
              type: call
              call: "hubspot.enroll-workflow"
              with:
                email: "{{get-contract.Contact.Email}}"
                workflow_id: "$secrets.hubspot_renewal_workflow_id"
            - name: notify-csm
              type: call
              call: "slack.post-message"
              with:
                channel: "#customer-success"
                text: "Contract {{contract_id}} for {{get-contract.Account.Name}} expires {{get-contract.EndDate}} — HubSpot nurture enrolled"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://ibm.my.salesforce.com/services/data/v59.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: contracts
          path: "/sobjects/Contract/{{contract_id}}"
          inputParameters:
            - name: contract_id
              in: path
          operations:
            - name: get-contract
              method: GET
    - type: http
      namespace: hubspot
      baseUri: "https://api.hubapi.com"
      authentication:
        type: bearer
        token: "$secrets.hubspot_token"
      resources:
        - name: workflows
          path: "/automation/v4/actions/workflows/{{workflow_id}}/enrollments"
          inputParameters:
            - name: workflow_id
              in: path
          operations:
            - name: enroll-workflow
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a Salesforce lead is converted, creates or updates the corresponding HubSpot contact with matched fields. Used by marketing operations agents to maintain CRM-MAP alignment.

naftiko: "0.5"
info:
  label: "Salesforce Lead to HubSpot Contact Sync"
  description: "When a Salesforce lead is converted, creates or updates the corresponding HubSpot contact with matched fields. Used by marketing operations agents to maintain CRM-MAP alignment."
  tags:
    - sales
    - marketing
    - salesforce
    - hubspot
    - crm
capability:
  exposes:
    - type: mcp
      namespace: crm-sync
      port: 8080
      tools:
        - name: sync-lead-to-hubspot
          description: "Given a Salesforce lead ID, fetch lead details and upsert the contact record in HubSpot CRM, aligning email, company, and lifecycle stage."
          inputParameters:
            - name: lead_id
              in: body
              type: string
              description: "Salesforce Lead ID (18-char)."
          steps:
            - name: get-lead
              type: call
              call: "salesforce-lead.get-lead"
              with:
                lead_id: "{{lead_id}}"
            - name: upsert-contact
              type: call
              call: "hubspot.upsert-contact"
              with:
                email: "{{get-lead.Email}}"
                firstname: "{{get-lead.FirstName}}"
                lastname: "{{get-lead.LastName}}"
                company: "{{get-lead.Company}}"
                lifecyclestage: "lead"
  consumes:
    - type: http
      namespace: salesforce-lead
      baseUri: "https://ibm.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: hubspot
      baseUri: "https://api.hubapi.com/crm/v3"
      authentication:
        type: bearer
        token: "$secrets.hubspot_token"
      resources:
        - name: contacts
          path: "/objects/contacts/batch/upsert"
          operations:
            - name: upsert-contact
              method: POST

Pulls open opportunities from Salesforce, filters by stage and close date, and posts a pipeline summary to ServiceNow as a knowledge article. Used weekly by sales operations agents.

naftiko: "0.5"
info:
  label: "Salesforce Opportunity Pipeline Digest"
  description: "Pulls open opportunities from Salesforce, filters by stage and close date, and posts a pipeline summary to ServiceNow as a knowledge article. Used weekly by sales operations agents."
  tags:
    - sales
    - crm
    - salesforce
    - servicenow
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: sales-reporting
      port: 8080
      tools:
        - name: digest-open-pipeline
          description: "Given a Salesforce stage filter and a close-date window (days), query open opportunities and post a pipeline digest to ServiceNow as a knowledge article draft."
          inputParameters:
            - name: stage_filter
              in: body
              type: string
              description: "Salesforce opportunity stage name to filter, e.g. Proposal/Price Quote."
            - name: close_days
              in: body
              type: integer
              description: "Number of days from today to use as the close-date upper bound."
          steps:
            - name: get-opportunities
              type: call
              call: "salesforce.query-opportunities"
              with:
                stage: "{{stage_filter}}"
                close_days: "{{close_days}}"
            - name: post-knowledge
              type: call
              call: "servicenow.create-kb-article"
              with:
                title: "Pipeline Digest — {{stage_filter}}"
                text: "{{get-opportunities.records}}"
                category: "sales_ops"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://ibm.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: opportunities
          path: "/query"
          inputParameters:
            - name: q
              in: query
          operations:
            - name: query-opportunities
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: kb-articles
          path: "/table/kb_knowledge"
          operations:
            - name: create-kb-article
              method: POST

Identifies at-risk Salesforce renewal opportunities and enrolls the account contacts into a HubSpot retention campaign.

naftiko: "0.5"
info:
  label: "Salesforce Renewal Risk to HubSpot Campaign"
  description: "Identifies at-risk Salesforce renewal opportunities and enrolls the account contacts into a HubSpot retention campaign."
  tags:
    - crm
    - marketing
    - salesforce
    - hubspot
capability:
  exposes:
    - type: mcp
      namespace: retention
      port: 8080
      tools:
        - name: handle-renewal-risk
          description: "Given a Salesforce opportunity ID flagged as at-risk, retrieve account contacts and enroll them in a HubSpot retention campaign."
          inputParameters:
            - name: opportunity_id
              in: body
              type: string
              description: "Salesforce opportunity ID."
            - name: campaign_id
              in: body
              type: string
              description: "HubSpot campaign ID for retention."
          steps:
            - name: get-opportunity
              type: call
              call: "salesforce.get-opportunity"
              with:
                opportunity_id: "{{opportunity_id}}"
            - name: enroll-contact
              type: call
              call: "hubspot.add-to-campaign"
              with:
                email: "{{get-opportunity.Contact.Email}}"
                campaign_id: "{{campaign_id}}"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://ibm.my.salesforce.com/services/data/v59.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: hubspot
      baseUri: "https://api.hubapi.com"
      authentication:
        type: bearer
        token: "$secrets.hubspot_token"
      resources:
        - name: campaigns
          path: "/email/public/v1/campaigns/{{campaign_id}}/contacts"
          inputParameters:
            - name: campaign_id
              in: path
          operations:
            - name: add-to-campaign
              method: POST

Retrieves SAP BRIM billing document totals for a given billing period and compares them against Salesforce contract ARR values to detect discrepancies.

naftiko: "0.5"
info:
  label: "SAP BRIM Subscription Billing Reconciliation"
  description: "Retrieves SAP BRIM billing document totals for a given billing period and compares them against Salesforce contract ARR values to detect discrepancies."
  tags:
    - finance
    - erp
    - sap-s4hana
    - salesforce
    - billing
    - reconciliation
capability:
  exposes:
    - type: mcp
      namespace: billing-finance
      port: 8080
      tools:
        - name: reconcile-brim-billing
          description: "Given a SAP BRIM billing period and a Salesforce contract ID, fetch billed amounts from SAP and compare against the contracted ARR in Salesforce, flagging discrepancies."
          inputParameters:
            - name: billing_period
              in: body
              type: string
              description: "SAP BRIM billing period in YYYYMM format."
            - name: contract_id
              in: body
              type: string
              description: "Salesforce contract record ID."
          steps:
            - name: get-brim-docs
              type: call
              call: "sap-brim.get-billing-docs"
              with:
                billing_period: "{{billing_period}}"
            - name: get-sf-contract
              type: call
              call: "salesforce-contract.get-contract"
              with:
                contract_id: "{{contract_id}}"
            - name: log-reconciliation
              type: call
              call: "salesforce-note.create-note"
              with:
                ParentId: "{{contract_id}}"
                Title: "BRIM Reconciliation {{billing_period}}"
                Body: "BRIM total: {{get-brim-docs.total_amount}} | SF ARR: {{get-sf-contract.annual_arr}}"
  consumes:
    - type: http
      namespace: sap-brim
      baseUri: "https://ibm-s4.sap.com/sap/opu/odata/sap/BRIM_BILLING_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: billing-docs
          path: "/BillingDocuments"
          inputParameters:
            - name: billing_period
              in: query
          operations:
            - name: get-billing-docs
              method: GET
    - type: http
      namespace: salesforce-contract
      baseUri: "https://ibm.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: contracts
          path: "/sobjects/Contract/{{contract_id}}"
          inputParameters:
            - name: contract_id
              in: path
          operations:
            - name: get-contract
              method: GET
    - type: http
      namespace: salesforce-note
      baseUri: "https://ibm.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: notes
          path: "/sobjects/Note"
          operations:
            - name: create-note
              method: POST

Triggers a SAP BW query refresh for a given InfoProvider and distributes the result set to a configured Crystal Reports dashboard.

naftiko: "0.5"
info:
  label: "SAP BW Report Refresh and Distribution"
  description: "Triggers a SAP BW query refresh for a given InfoProvider and distributes the result set to a configured Crystal Reports dashboard."
  tags:
    - data
    - analytics
    - sap-bw
    - crystal-reports
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: bw-reporting
      port: 8080
      tools:
        - name: refresh-bw-report
          description: "Given a SAP BW InfoProvider name and a Crystal Reports report name, trigger the BW query refresh and push the updated dataset to the Crystal Reports server."
          inputParameters:
            - name: info_provider
              in: body
              type: string
              description: "SAP BW InfoProvider technical name."
            - name: report_name
              in: body
              type: string
              description: "Crystal Reports report name to refresh."
          steps:
            - name: trigger-bw-refresh
              type: call
              call: "sap-bw.refresh-query"
              with:
                infoProvider: "{{info_provider}}"
            - name: push-to-crystal
              type: call
              call: "crystal-bw.refresh-report"
              with:
                report_name: "{{report_name}}"
                data: "{{trigger-bw-refresh.result_set}}"
  consumes:
    - type: http
      namespace: sap-bw
      baseUri: "https://ibm-bw.sap.com/sap/bw/ina/GetServerInfo"
      authentication:
        type: basic
        username: "$secrets.sap_bw_user"
        password: "$secrets.sap_bw_password"
      resources:
        - name: queries
          path: "/query/refresh"
          operations:
            - name: refresh-query
              method: POST
    - type: http
      namespace: crystal-bw
      baseUri: "https://ibm-bobj.internal/biprws/v1"
      authentication:
        type: bearer
        token: "$secrets.crystal_reports_token"
      resources:
        - name: reports
          path: "/reports/refresh"
          operations:
            - name: refresh-report
              method: POST

When SAP Concur flags an expense policy violation, creates a ServiceNow compliance task and notifies the finance team via Slack.

naftiko: "0.5"
info:
  label: "SAP Concur Expense Violation to ServiceNow"
  description: "When SAP Concur flags an expense policy violation, creates a ServiceNow compliance task and notifies the finance team via Slack."
  tags:
    - finance
    - compliance
    - sap-concur
    - servicenow
    - slack
capability:
  exposes:
    - type: mcp
      namespace: expense-compliance
      port: 8080
      tools:
        - name: handle-expense-violation
          description: "Given a Concur expense report ID with violations, create a ServiceNow compliance task and notify finance."
          inputParameters:
            - name: report_id
              in: body
              type: string
              description: "SAP Concur expense report ID."
          steps:
            - name: get-report
              type: call
              call: "concur.get-expense-report"
              with:
                report_id: "{{report_id}}"
            - name: create-compliance-task
              type: call
              call: "servicenow-comp.create-task"
              with:
                short_description: "Expense violation: Report {{report_id}} — {{get-report.OwnerName}}"
                description: "Total: {{get-report.Total}} | Violations: {{get-report.PolicyViolations}}"
                assignment_group: "Finance_Compliance"
            - name: notify-finance
              type: call
              call: "slack.post-message"
              with:
                channel: "#finance-compliance"
                text: "Expense policy violation flagged for {{get-report.OwnerName}} — ServiceNow: {{create-compliance-task.number}}"
  consumes:
    - type: http
      namespace: concur
      baseUri: "https://us.api.concursolutions.com/api/v3.0"
      authentication:
        type: bearer
        token: "$secrets.concur_token"
      resources:
        - name: expense-reports
          path: "/expense/reports/{{report_id}}"
          inputParameters:
            - name: report_id
              in: path
          operations:
            - name: get-expense-report
              method: GET
    - type: http
      namespace: servicenow-comp
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Queries SAP HANA system views for memory and CPU health metrics and creates a ServiceNow monitoring record when thresholds are breached.

naftiko: "0.5"
info:
  label: "SAP HANA Database Health Check"
  description: "Queries SAP HANA system views for memory and CPU health metrics and creates a ServiceNow monitoring record when thresholds are breached."
  tags:
    - data
    - database
    - sap-hana
    - servicenow
    - monitoring
capability:
  exposes:
    - type: mcp
      namespace: db-health
      port: 8080
      tools:
        - name: check-hana-health
          description: "Given a SAP HANA system host, retrieve memory usage and CPU load from system views. If usage exceeds thresholds, create a ServiceNow monitoring event."
          inputParameters:
            - name: hana_host
              in: body
              type: string
              description: "Hostname of the SAP HANA system."
            - name: memory_threshold_pct
              in: body
              type: number
              description: "Memory usage percentage above which to fire an alert."
          steps:
            - name: get-hana-metrics
              type: call
              call: "sap-hana.get-system-metrics"
              with:
                host: "{{hana_host}}"
            - name: create-monitoring-event
              type: call
              call: "servicenow-mon.create-event"
              with:
                source: "SAP HANA"
                node: "{{hana_host}}"
                type: "Memory"
                severity: "3"
                description: "HANA memory at {{get-hana-metrics.memory_pct}}% on {{hana_host}}"
  consumes:
    - type: http
      namespace: sap-hana
      baseUri: "https://{{hana_host}}:4300/sap/hana/xs/api/v1"
      authentication:
        type: basic
        username: "$secrets.hana_user"
        password: "$secrets.hana_password"
      resources:
        - name: system-metrics
          path: "/system/monitoring/host_information"
          operations:
            - name: get-system-metrics
              method: GET
    - type: http
      namespace: servicenow-mon
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: events
          path: "/table/em_event"
          operations:
            - name: create-event
              method: POST

Queries SAP S/4HANA for material stock availability and posts a summary to the Slack procurement channel when levels are below threshold.

naftiko: "0.5"
info:
  label: "SAP Material Availability Check to Slack"
  description: "Queries SAP S/4HANA for material stock availability and posts a summary to the Slack procurement channel when levels are below threshold."
  tags:
    - erp
    - supply-chain
    - sap
    - slack
capability:
  exposes:
    - type: mcp
      namespace: procurement
      port: 8080
      tools:
        - name: check-material-stock
          description: "Given a SAP material number and plant, check stock availability and notify Slack if below threshold."
          inputParameters:
            - name: material_number
              in: body
              type: string
              description: "SAP material number."
            - name: plant
              in: body
              type: string
              description: "SAP plant code."
          steps:
            - name: get-stock
              type: call
              call: "sap.get-material-stock"
              with:
                material: "{{material_number}}"
                plant: "{{plant}}"
            - name: notify-procurement
              type: call
              call: "slack.post-message"
              with:
                channel: "#procurement"
                text: "Material {{material_number}} at plant {{plant}}: Available stock = {{get-stock.available_quantity}} {{get-stock.unit}}"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://ibm-s4.sap.com/sap/opu/odata/sap/API_MATERIAL_STOCK_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: material-stock
          path: "/A_MatlStkInAcctMod(Material='{{material}}',Plant='{{plant}}')"
          inputParameters:
            - name: material
              in: path
            - name: plant
              in: path
          operations:
            - name: get-material-stock
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Pulls delivery status from SAP S/4HANA and updates the corresponding Salesforce opportunity with fulfillment progress.

naftiko: "0.5"
info:
  label: "SAP S/4HANA Delivery Status to Salesforce"
  description: "Pulls delivery status from SAP S/4HANA and updates the corresponding Salesforce opportunity with fulfillment progress."
  tags:
    - erp
    - crm
    - sap
    - salesforce
capability:
  exposes:
    - type: mcp
      namespace: fulfillment
      port: 8080
      tools:
        - name: sync-delivery-status
          description: "Given a SAP delivery number and Salesforce opportunity ID, update the opportunity with delivery progress."
          inputParameters:
            - name: delivery_number
              in: body
              type: string
              description: "SAP delivery document number."
            - name: opportunity_id
              in: body
              type: string
              description: "Salesforce opportunity ID."
          steps:
            - name: get-delivery
              type: call
              call: "sap.get-delivery"
              with:
                delivery: "{{delivery_number}}"
            - name: update-sf-opportunity
              type: call
              call: "salesforce.update-opportunity"
              with:
                opportunity_id: "{{opportunity_id}}"
                Description: "Delivery {{delivery_number}}: Status={{get-delivery.OverallStatus}}, Shipped={{get-delivery.ActualGoodsMovementDate}}"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://ibm-s4.sap.com/sap/opu/odata/sap/API_OUTBOUND_DELIVERY_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: deliveries
          path: "/A_OutbDeliveryHeader('{{delivery}}')"
          inputParameters:
            - name: delivery
              in: path
          operations:
            - name: get-delivery
              method: GET
    - type: http
      namespace: salesforce
      baseUri: "https://ibm.my.salesforce.com/services/data/v59.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

Retrieves the processing status of a vendor invoice from SAP S/4HANA. Used by finance teams and agents to check whether an invoice is pending, parked, or cleared.

naftiko: "0.5"
info:
  label: "SAP S/4HANA Invoice Processing Status"
  description: "Retrieves the processing status of a vendor invoice from SAP S/4HANA. Used by finance teams and agents to check whether an invoice is pending, parked, or cleared."
  tags:
    - finance
    - erp
    - sap-s4hana
    - accounts-payable
capability:
  exposes:
    - type: mcp
      namespace: erp-ap
      port: 8080
      tools:
        - name: get-invoice-status
          description: "Given a supplier invoice document number and fiscal year, return the posting status and clearing date from SAP S/4HANA."
          inputParameters:
            - name: invoice_doc
              in: body
              type: string
              description: "SAP supplier invoice document number."
            - name: fiscal_year
              in: body
              type: string
              description: "Four-digit fiscal year, e.g. 2025."
          call: "sap-fi.get-invoice"
          with:
            SupplierInvoice: "{{invoice_doc}}"
            FiscalYear: "{{fiscal_year}}"
          outputParameters:
            - name: posting_status
              type: string
              mapping: "$.d.PostingStatus"
            - name: clearing_date
              type: string
              mapping: "$.d.ClearingDate"
            - name: net_amount
              type: string
              mapping: "$.d.InvoiceGrossAmount"
  consumes:
    - type: http
      namespace: sap-fi
      baseUri: "https://ibm-s4.sap.com/sap/opu/odata/sap/API_SUPPLIERINVOICE_PROCESS_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: supplier-invoices
          path: "/A_SupplierInvoice(SupplierInvoice='{{SupplierInvoice}}',FiscalYear='{{FiscalYear}}')"
          inputParameters:
            - name: SupplierInvoice
              in: path
            - name: FiscalYear
              in: path
          operations:
            - name: get-invoice
              method: GET

Looks up a SAP S/4HANA purchase order by number and returns header status, vendor, and total value. Used by procurement agents to verify PO state before approvals or payments.

naftiko: "0.5"
info:
  label: "SAP S/4HANA Purchase Order Lookup"
  description: "Looks up a SAP S/4HANA purchase order by number and returns header status, vendor, and total value. Used by procurement agents to verify PO state before approvals or payments."
  tags:
    - finance
    - erp
    - sap-s4hana
    - procurement
capability:
  exposes:
    - type: mcp
      namespace: erp
      port: 8080
      tools:
        - name: get-purchase-order
          description: "Given a PO number, retrieve the purchase order header from SAP S/4HANA including status, vendor name, total amount, and currency."
          inputParameters:
            - name: po_number
              in: body
              type: string
              description: "SAP purchase order number, e.g. 4500001234."
          call: "sap-s4.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_amount
              type: string
              mapping: "$.d.TotalAmount"
            - name: currency
              type: string
              mapping: "$.d.TransactionCurrency"
  consumes:
    - type: http
      namespace: sap-s4
      baseUri: "https://ibm-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

Retrieves the fulfillment status of a SAP SD sales order by order number and updates the corresponding Salesforce opportunity with the latest delivery status.

naftiko: "0.5"
info:
  label: "SAP Sales and Distribution Order Status Check"
  description: "Retrieves the fulfillment status of a SAP SD sales order by order number and updates the corresponding Salesforce opportunity with the latest delivery status."
  tags:
    - sales
    - erp
    - sap-s4hana
    - salesforce
    - order-management
capability:
  exposes:
    - type: mcp
      namespace: order-mgmt
      port: 8080
      tools:
        - name: sync-sd-order-status
          description: "Given a SAP SD order number and a Salesforce opportunity ID, retrieve the delivery status from SAP S/4HANA SD and update the opportunity with fulfilment details."
          inputParameters:
            - name: sd_order_number
              in: body
              type: string
              description: "SAP SD sales order number."
            - name: opportunity_id
              in: body
              type: string
              description: "Salesforce opportunity ID to update."
          steps:
            - name: get-sd-order
              type: call
              call: "sap-sd.get-order"
              with:
                order_number: "{{sd_order_number}}"
            - name: update-opportunity
              type: call
              call: "salesforce-opp.update-opportunity"
              with:
                opportunity_id: "{{opportunity_id}}"
                delivery_status: "{{get-sd-order.OverallSDProcessStatus}}"
                requested_delivery: "{{get-sd-order.RequestedDeliveryDate}}"
  consumes:
    - type: http
      namespace: sap-sd
      baseUri: "https://ibm-s4.sap.com/sap/opu/odata/sap/API_SALES_ORDER_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: orders
          path: "/A_SalesOrder('{{order_number}}')"
          inputParameters:
            - name: order_number
              in: path
          operations:
            - name: get-order
              method: GET
    - type: http
      namespace: salesforce-opp
      baseUri: "https://ibm.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

When a ServiceNow change request is approved, triggers the Terraform Cloud run to apply and updates the change ticket with results.

naftiko: "0.5"
info:
  label: "ServiceNow Change Approval to Terraform Apply"
  description: "When a ServiceNow change request is approved, triggers the Terraform Cloud run to apply and updates the change ticket with results."
  tags:
    - itsm
    - infrastructure
    - servicenow
    - terraform
capability:
  exposes:
    - type: mcp
      namespace: change-deploy
      port: 8080
      tools:
        - name: apply-approved-change
          description: "Given a ServiceNow change number and Terraform run ID, confirm the run and update the change record."
          inputParameters:
            - name: change_number
              in: body
              type: string
              description: "ServiceNow change request number."
            - name: run_id
              in: body
              type: string
              description: "Terraform Cloud run ID to apply."
          steps:
            - name: apply-run
              type: call
              call: "terraform.apply-run"
              with:
                run_id: "{{run_id}}"
            - name: update-change
              type: call
              call: "servicenow-chg.update-change"
              with:
                number: "{{change_number}}"
                work_notes: "Terraform run {{run_id}} applied successfully"
                state: "implement"
  consumes:
    - type: http
      namespace: terraform
      baseUri: "https://app.terraform.io/api/v2"
      authentication:
        type: bearer
        token: "$secrets.terraform_token"
      resources:
        - name: runs
          path: "/runs/{{run_id}}/actions/apply"
          inputParameters:
            - name: run_id
              in: path
          operations:
            - name: apply-run
              method: POST
    - type: http
      namespace: servicenow-chg
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: changes
          path: "/table/change_request"
          operations:
            - name: update-change
              method: PATCH

Compares Terraform Cloud state against ServiceNow CMDB records and creates reconciliation tasks for any configuration drift detected.

naftiko: "0.5"
info:
  label: "ServiceNow CMDB Drift Detection"
  description: "Compares Terraform Cloud state against ServiceNow CMDB records and creates reconciliation tasks for any configuration drift detected."
  tags:
    - itsm
    - infrastructure
    - servicenow
    - terraform
    - governance
capability:
  exposes:
    - type: mcp
      namespace: cmdb-audit
      port: 8080
      tools:
        - name: detect-cmdb-drift
          description: "Given a Terraform workspace and ServiceNow CMDB class, compare resource counts and create tasks for discrepancies."
          inputParameters:
            - name: workspace_name
              in: body
              type: string
              description: "Terraform Cloud workspace name."
            - name: cmdb_class
              in: body
              type: string
              description: "ServiceNow CMDB class name."
          steps:
            - name: get-tf-resources
              type: call
              call: "terraform.get-workspace-resources"
              with:
                workspace: "{{workspace_name}}"
            - name: get-cmdb-records
              type: call
              call: "servicenow-cmdb.get-records"
              with:
                class_name: "{{cmdb_class}}"
            - name: create-recon-task
              type: call
              call: "servicenow-cmdb.create-task"
              with:
                short_description: "CMDB drift: Terraform has {{get-tf-resources.count}} resources vs CMDB {{get-cmdb-records.count}} records"
                assignment_group: "Configuration_Management"
  consumes:
    - type: http
      namespace: terraform
      baseUri: "https://app.terraform.io/api/v2"
      authentication:
        type: bearer
        token: "$secrets.terraform_token"
      resources:
        - name: workspace-resources
          path: "/organizations/ibm/workspaces/{{workspace}}/resources"
          inputParameters:
            - name: workspace
              in: path
          operations:
            - name: get-workspace-resources
              method: GET
    - type: http
      namespace: servicenow-cmdb
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: cmdb
          path: "/table/{{class_name}}"
          inputParameters:
            - name: class_name
              in: path
          operations:
            - name: get-records
              method: GET
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST

Retrieves the current state, priority, and assignment group of a ServiceNow incident by number.

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

When a ServiceNow incident is opened, retrieves correlated Datadog alerts for the affected service and updates the incident with alert IDs and metric snapshots.

naftiko: "0.5"
info:
  label: "ServiceNow Incident Triage and Datadog Correlation"
  description: "When a ServiceNow incident is opened, retrieves correlated Datadog alerts for the affected service and updates the incident with alert IDs and metric snapshots."
  tags:
    - itsm
    - observability
    - servicenow
    - datadog
    - incident-response
capability:
  exposes:
    - type: mcp
      namespace: itsm-ops
      port: 8080
      tools:
        - name: handle-incident-triage
          description: "Given a ServiceNow incident number and affected service name, fetch correlated Datadog alerts and enrich the incident record with alert context."
          inputParameters:
            - name: incident_number
              in: body
              type: string
              description: "ServiceNow incident number, e.g. INC0012345."
            - name: service_name
              in: body
              type: string
              description: "Name of the affected service as tagged in Datadog."
          steps:
            - name: get-incident
              type: call
              call: "servicenow-read.get-incident"
              with:
                number: "{{incident_number}}"
            - name: get-alerts
              type: call
              call: "datadog.list-alerts"
              with:
                service: "{{service_name}}"
            - name: update-incident
              type: call
              call: "servicenow-write.update-incident"
              with:
                sys_id: "{{get-incident.sys_id}}"
                work_notes: "Correlated Datadog alerts: {{get-alerts.alert_ids}}"
  consumes:
    - type: http
      namespace: servicenow-read
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: incidents
          path: "/table/incident"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-incident
              method: GET
    - type: http
      namespace: datadog
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: monitors
          path: "/monitor"
          inputParameters:
            - name: tags
              in: query
          operations:
            - name: list-alerts
              method: GET
    - type: http
      namespace: servicenow-write
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: incident-update
          path: "/table/incident/{{sys_id}}"
          inputParameters:
            - name: sys_id
              in: path
          operations:
            - name: update-incident
              method: PATCH

When a ServiceNow P1 incident is created, automatically sets up a Slack channel, pages the on-call via PagerDuty, and posts the bridge details.

naftiko: "0.5"
info:
  label: "ServiceNow Major Incident Bridge Setup"
  description: "When a ServiceNow P1 incident is created, automatically sets up a Slack channel, pages the on-call via PagerDuty, and posts the bridge details."
  tags:
    - itsm
    - incident-response
    - servicenow
    - pagerduty
    - slack
capability:
  exposes:
    - type: mcp
      namespace: major-incident
      port: 8080
      tools:
        - name: setup-incident-bridge
          description: "Given a ServiceNow incident number, create a Slack channel, page the on-call, and post bridge details."
          inputParameters:
            - name: incident_number
              in: body
              type: string
              description: "ServiceNow P1 incident number."
          steps:
            - name: get-incident
              type: call
              call: "servicenow.get-incident"
              with:
                number: "{{incident_number}}"
            - name: create-channel
              type: call
              call: "slack.create-channel"
              with:
                name: "inc-{{incident_number}}"
            - name: page-oncall
              type: call
              call: "pagerduty.create-incident"
              with:
                service_id: "$secrets.pd_p1_service_id"
                title: "P1 Major Incident: {{get-incident.short_description}}"
                urgency: "high"
            - name: post-bridge-info
              type: call
              call: "slack.post-message"
              with:
                channel: "inc-{{incident_number}}"
                text: "Major Incident Bridge\n- ServiceNow: {{incident_number}}\n- Summary: {{get-incident.short_description}}\n- PagerDuty: {{page-oncall.incident.id}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: get-incident
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: channels
          path: "/conversations.create"
          operations:
            - name: create-channel
              method: POST
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST
    - type: http
      namespace: pagerduty
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "Token token=$secrets.pagerduty_token"
        placement: header
      resources:
        - name: incidents
          path: "/incidents"
          operations:
            - name: create-incident
              method: POST

Posts a formatted message to a Slack channel for notifications, alerts, and team communication workflows.

naftiko: "0.5"
info:
  label: "Slack Channel Message Poster"
  description: "Posts a formatted message to a Slack channel for notifications, alerts, and team communication workflows."
  tags:
    - communication
    - slack
    - notifications
capability:
  exposes:
    - type: mcp
      namespace: messaging
      port: 8080
      tools:
        - name: post-slack-message
          description: "Given a Slack channel name and message text, post the message to the channel."
          inputParameters:
            - name: channel
              in: body
              type: string
              description: "Slack channel name or ID."
            - name: message
              in: body
              type: string
              description: "Message text to post."
          call: slack.post-message
          with:
            channel: "{{channel}}"
            text: "{{message}}"
  consumes:
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Queries Snowflake warehouse credit consumption and, when budget threshold is exceeded, creates a ServiceNow task and notifies the FinOps team.

naftiko: "0.5"
info:
  label: "Snowflake Cost Alert to FinOps Slack"
  description: "Queries Snowflake warehouse credit consumption and, when budget threshold is exceeded, creates a ServiceNow task and notifies the FinOps team."
  tags:
    - data
    - finops
    - snowflake
    - servicenow
    - slack
capability:
  exposes:
    - type: mcp
      namespace: data-finops
      port: 8080
      tools:
        - name: check-snowflake-cost
          description: "Given a Snowflake warehouse name and budget threshold, check credit usage and alert if exceeded."
          inputParameters:
            - name: warehouse_name
              in: body
              type: string
              description: "Snowflake warehouse name."
            - name: budget_credits
              in: body
              type: number
              description: "Monthly credit budget threshold."
          steps:
            - name: get-usage
              type: call
              call: "snowflake.execute-query"
              with:
                statement: "SELECT SUM(CREDITS_USED) as total_credits FROM SNOWFLAKE.ACCOUNT_USAGE.WAREHOUSE_METERING_HISTORY WHERE WAREHOUSE_NAME='{{warehouse_name}}' AND START_TIME >= DATE_TRUNC('MONTH', CURRENT_DATE())"
            - name: create-task
              type: call
              call: "servicenow-fin.create-task"
              with:
                short_description: "Snowflake cost alert: {{warehouse_name}} at {{get-usage.total_credits}} credits"
                assignment_group: "FinOps"
            - name: notify-finops
              type: call
              call: "slack.post-message"
              with:
                channel: "#finops"
                text: "Snowflake warehouse {{warehouse_name}} has consumed {{get-usage.total_credits}} credits (budget: {{budget_credits}})"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://ibm.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-query
              method: POST
    - type: http
      namespace: servicenow-fin
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Runs a Snowflake data quality check query and, if anomalies are detected, creates a Jira task for the data engineering team and notifies Slack.

naftiko: "0.5"
info:
  label: "Snowflake Data Quality to Jira Task"
  description: "Runs a Snowflake data quality check query and, if anomalies are detected, creates a Jira task for the data engineering team and notifies Slack."
  tags:
    - data
    - quality
    - snowflake
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: data-quality
      port: 8080
      tools:
        - name: check-data-quality
          description: "Given a Snowflake quality check query, execute it and create a Jira task if anomalies exceed the threshold."
          inputParameters:
            - name: quality_query
              in: body
              type: string
              description: "SQL query that returns anomaly count."
            - name: threshold
              in: body
              type: number
              description: "Anomaly count threshold to trigger a task."
          steps:
            - name: run-check
              type: call
              call: "snowflake.execute-query"
              with:
                statement: "{{quality_query}}"
            - name: create-jira-task
              type: call
              call: "jira.create-issue"
              with:
                project: "DATA"
                issuetype: "Task"
                summary: "Data quality anomaly detected — {{run-check.anomaly_count}} records"
                priority: "High"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#data-engineering"
                text: "Data quality alert: {{run-check.anomaly_count}} anomalies found. Jira: {{create-jira-task.key}}"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://ibm.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-query
              method: POST
    - type: http
      namespace: jira
      baseUri: "https://ibm-jira.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Executes a read-only SQL query against a Snowflake warehouse and returns the result set for analytics and reporting queries.

naftiko: "0.5"
info:
  label: "Snowflake Query Execution"
  description: "Executes a read-only SQL query against a Snowflake warehouse and returns the result set for analytics and reporting queries."
  tags:
    - data
    - analytics
    - snowflake
capability:
  exposes:
    - type: mcp
      namespace: analytics
      port: 8080
      tools:
        - name: run-snowflake-query
          description: "Given a SQL statement, execute it against the Snowflake warehouse and return the result set."
          inputParameters:
            - name: sql_statement
              in: body
              type: string
              description: "Read-only SQL query to execute."
            - name: warehouse
              in: body
              type: string
              description: "Snowflake warehouse name."
          call: snowflake.execute-query
          with:
            statement: "{{sql_statement}}"
            warehouse: "{{warehouse}}"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://ibm.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-query
              method: POST

When SolarWinds detects a network node as down, automatically opens a P1 ServiceNow network incident and creates a Datadog event for cross-platform correlation.

naftiko: "0.5"
info:
  label: "SolarWinds Network Node Down Alert to ServiceNow"
  description: "When SolarWinds detects a network node as down, automatically opens a P1 ServiceNow network incident and creates a Datadog event for cross-platform correlation."
  tags:
    - itsm
    - observability
    - solarwinds
    - servicenow
    - datadog
    - network
capability:
  exposes:
    - type: mcp
      namespace: network-ops
      port: 8080
      tools:
        - name: handle-node-down
          description: "Given a SolarWinds node ID and node name, verify the node status, open a P1 ServiceNow network incident, and post a Datadog alert event for unified NOC visibility."
          inputParameters:
            - name: node_id
              in: body
              type: string
              description: "SolarWinds node ID."
            - name: node_name
              in: body
              type: string
              description: "Display name of the affected network node."
          steps:
            - name: get-node-status
              type: call
              call: "solarwinds-query.get-node"
              with:
                node_id: "{{node_id}}"
            - name: open-network-incident
              type: call
              call: "servicenow-net.create-incident"
              with:
                short_description: "Network node down: {{node_name}}"
                category: "network"
                urgency: "1"
                impact: "1"
                description: "Node: {{node_name}} | Status: {{get-node-status.status}} | IP: {{get-node-status.ip_address}}"
            - name: post-dd-alert
              type: call
              call: "datadog-net.post-event"
              with:
                title: "Node Down: {{node_name}}"
                text: "SolarWinds node {{node_id}} is DOWN — Incident: {{open-network-incident.number}}"
                alert_type: "error"
  consumes:
    - type: http
      namespace: solarwinds-query
      baseUri: "https://ibm-solarwinds.internal:17778/SolarWinds/InformationService/v3/Json"
      authentication:
        type: basic
        username: "$secrets.solarwinds_user"
        password: "$secrets.solarwinds_password"
      resources:
        - name: nodes
          path: "/Query"
          operations:
            - name: get-node
              method: POST
    - type: http
      namespace: servicenow-net
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: datadog-net
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: events
          path: "/events"
          operations:
            - name: post-event
              method: POST

When SolarWinds detects a node down event, creates a PagerDuty incident and updates the ServiceNow CMDB with the outage status.

naftiko: "0.5"
info:
  label: "SolarWinds Node Down to PagerDuty"
  description: "When SolarWinds detects a node down event, creates a PagerDuty incident and updates the ServiceNow CMDB with the outage status."
  tags:
    - networking
    - incident-response
    - solarwinds
    - pagerduty
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: network-ops
      port: 8080
      tools:
        - name: handle-node-down
          description: "Given a SolarWinds node ID, retrieve the node details, create a PagerDuty incident, and update the CMDB."
          inputParameters:
            - name: node_id
              in: body
              type: string
              description: "SolarWinds node ID."
          steps:
            - name: get-node
              type: call
              call: "solarwinds.get-node"
              with:
                node_id: "{{node_id}}"
            - name: create-pd-incident
              type: call
              call: "pagerduty.create-incident"
              with:
                service_id: "$secrets.pd_network_service_id"
                title: "Node down: {{get-node.Caption}} ({{get-node.IPAddress}})"
                urgency: "high"
            - name: update-cmdb
              type: call
              call: "servicenow-cmdb.update-ci"
              with:
                name: "{{get-node.Caption}}"
                operational_status: "non-operational"
  consumes:
    - type: http
      namespace: solarwinds
      baseUri: "https://solarwinds.ibm.com:17778/SolarWinds/InformationService/v3/Json"
      authentication:
        type: basic
        username: "$secrets.solarwinds_user"
        password: "$secrets.solarwinds_password"
      resources:
        - name: nodes
          path: "/Query?query=SELECT+Caption,IPAddress,Status+FROM+Orion.Nodes+WHERE+NodeID={{node_id}}"
          inputParameters:
            - name: node_id
              in: query
          operations:
            - name: get-node
              method: GET
    - type: http
      namespace: pagerduty
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "Token token=$secrets.pagerduty_token"
        placement: header
      resources:
        - name: incidents
          path: "/incidents"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: servicenow-cmdb
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: cmdb
          path: "/table/cmdb_ci"
          operations:
            - name: update-ci
              method: PATCH

When Splunk detects a security anomaly, creates a ServiceNow security incident and notifies the SOC team via Slack.

naftiko: "0.5"
info:
  label: "Splunk Alert to ServiceNow Security Incident"
  description: "When Splunk detects a security anomaly, creates a ServiceNow security incident and notifies the SOC team via Slack."
  tags:
    - security
    - siem
    - splunk
    - servicenow
    - slack
capability:
  exposes:
    - type: mcp
      namespace: soc-ops
      port: 8080
      tools:
        - name: handle-splunk-alert
          description: "Given a Splunk alert ID and severity, create a ServiceNow security incident and send a Slack notification to the SOC channel."
          inputParameters:
            - name: alert_id
              in: body
              type: string
              description: "Splunk alert ID."
            - name: severity
              in: body
              type: string
              description: "Alert severity level."
            - name: alert_description
              in: body
              type: string
              description: "Description of the security event."
          steps:
            - name: create-sec-incident
              type: call
              call: "servicenow-sec.create-incident"
              with:
                short_description: "Splunk security alert: {{alert_description}}"
                severity: "{{severity}}"
                category: "security"
                assignment_group: "SOC_Team"
            - name: notify-soc
              type: call
              call: "slack.post-message"
              with:
                channel: "#soc-alerts"
                text: "Security incident {{create-sec-incident.number}} created from Splunk alert {{alert_id}} — Severity: {{severity}}"
  consumes:
    - type: http
      namespace: servicenow-sec
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: incidents
          path: "/table/sn_si_incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Executes a Splunk search query over a specified time range and returns matching log events for incident investigation.

naftiko: "0.5"
info:
  label: "Splunk Log Search"
  description: "Executes a Splunk search query over a specified time range and returns matching log events for incident investigation."
  tags:
    - security
    - observability
    - splunk
capability:
  exposes:
    - type: mcp
      namespace: log-analysis
      port: 8080
      tools:
        - name: search-splunk-logs
          description: "Given a Splunk search query and time range, execute the search and return matching events."
          inputParameters:
            - name: search_query
              in: body
              type: string
              description: "Splunk SPL search query."
            - name: earliest_time
              in: body
              type: string
              description: "Search start time, e.g. -24h."
          call: splunk.create-search
          with:
            search: "{{search_query}}"
            earliest_time: "{{earliest_time}}"
  consumes:
    - type: http
      namespace: splunk
      baseUri: "https://splunk.ibm.com:8089/services"
      authentication:
        type: bearer
        token: "$secrets.splunk_token"
      resources:
        - name: search-jobs
          path: "/search/jobs"
          operations:
            - name: create-search
              method: POST

When a Tableau extract refresh fails, creates a ServiceNow incident and notifies the BI team via Slack with the error details.

naftiko: "0.5"
info:
  label: "Tableau Dashboard Failure to ServiceNow"
  description: "When a Tableau extract refresh fails, creates a ServiceNow incident and notifies the BI team via Slack with the error details."
  tags:
    - analytics
    - itsm
    - tableau
    - servicenow
    - slack
capability:
  exposes:
    - type: mcp
      namespace: bi-ops
      port: 8080
      tools:
        - name: handle-tableau-failure
          description: "Given a Tableau datasource ID, check the last extract status and create an incident if failed."
          inputParameters:
            - name: datasource_id
              in: body
              type: string
              description: "Tableau datasource ID."
          steps:
            - name: get-extract-status
              type: call
              call: "tableau.get-datasource"
              with:
                datasource_id: "{{datasource_id}}"
            - name: create-incident
              type: call
              call: "servicenow-bi.create-incident"
              with:
                short_description: "Tableau extract failure: {{get-extract-status.name}}"
                urgency: "3"
                assignment_group: "BI_Team"
            - name: notify-bi
              type: call
              call: "slack.post-message"
              with:
                channel: "#bi-team"
                text: "Tableau extract failed for {{get-extract-status.name}} — ServiceNow: {{create-incident.number}}"
  consumes:
    - type: http
      namespace: tableau
      baseUri: "https://tableau.ibm.com/api/3.19"
      authentication:
        type: bearer
        token: "$secrets.tableau_token"
      resources:
        - name: datasources
          path: "/sites/ibm/datasources/{{datasource_id}}"
          inputParameters:
            - name: datasource_id
              in: path
          operations:
            - name: get-datasource
              method: GET
    - type: http
      namespace: servicenow-bi
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Runs a Teradata SQL query to extract slow-query statistics and publishes the results as a Crystal Reports data refresh. Used by data engineering agents for weekly reporting.

naftiko: "0.5"
info:
  label: "Teradata Query Performance Report to Crystal Reports"
  description: "Runs a Teradata SQL query to extract slow-query statistics and publishes the results as a Crystal Reports data refresh. Used by data engineering agents for weekly reporting."
  tags:
    - data
    - analytics
    - teradata
    - crystal-reports
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: data-reporting
      port: 8080
      tools:
        - name: publish-query-perf-report
          description: "Given a Teradata database name and a lookback period in hours, query slow-query logs and trigger a Crystal Reports refresh with the extracted performance data."
          inputParameters:
            - name: database_name
              in: body
              type: string
              description: "Teradata database name to analyze."
            - name: lookback_hours
              in: body
              type: integer
              description: "Number of hours to look back for slow queries."
          steps:
            - name: query-slow-queries
              type: call
              call: "teradata.run-query"
              with:
                database: "{{database_name}}"
                hours: "{{lookback_hours}}"
            - name: refresh-report
              type: call
              call: "crystal-reports.refresh-report"
              with:
                report_name: "QueryPerformanceWeekly"
                dataset: "{{query-slow-queries.rows}}"
  consumes:
    - type: http
      namespace: teradata
      baseUri: "https://ibm-teradata.internal/api/v1"
      authentication:
        type: basic
        username: "$secrets.teradata_user"
        password: "$secrets.teradata_password"
      resources:
        - name: queries
          path: "/query"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: crystal-reports
      baseUri: "https://ibm-bobj.internal/biprws/v1"
      authentication:
        type: bearer
        token: "$secrets.crystal_reports_token"
      resources:
        - name: reports
          path: "/reports/refresh"
          operations:
            - name: refresh-report
              method: POST

Checks all Terraform Cloud workspaces in an organization for configuration drift and creates ServiceNow change tasks for any workspaces with unapplied plan changes.

naftiko: "0.5"
info:
  label: "Terraform Cloud Workspace Drift Detection"
  description: "Checks all Terraform Cloud workspaces in an organization for configuration drift and creates ServiceNow change tasks for any workspaces with unapplied plan changes."
  tags:
    - cloud
    - infrastructure
    - terraform
    - servicenow
    - drift-detection
capability:
  exposes:
    - type: mcp
      namespace: infra-ops
      port: 8080
      tools:
        - name: detect-terraform-drift
          description: "Given a Terraform Cloud organization name, list all workspaces with pending or errored runs and create a ServiceNow change task for each drifted workspace."
          inputParameters:
            - name: org_name
              in: body
              type: string
              description: "Terraform Cloud organization name."
          steps:
            - name: list-workspaces
              type: call
              call: "terraform.list-workspaces"
              with:
                organization: "{{org_name}}"
            - name: create-drift-task
              type: call
              call: "servicenow-drift.create-task"
              with:
                short_description: "Terraform drift detected in org: {{org_name}}"
                description: "Workspaces with drift: {{list-workspaces.drifted_count}}"
                assignment_group: "Cloud_Platform"
  consumes:
    - type: http
      namespace: terraform
      baseUri: "https://app.terraform.io/api/v2"
      authentication:
        type: bearer
        token: "$secrets.terraform_token"
      resources:
        - name: workspaces
          path: "/organizations/{{organization}}/workspaces"
          inputParameters:
            - name: organization
              in: path
          operations:
            - name: list-workspaces
              method: GET
    - type: http
      namespace: servicenow-drift
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST

When a Terraform Cloud run produces a plan with resource changes, creates a ServiceNow change request for approval before applying.

naftiko: "0.5"
info:
  label: "Terraform Plan Approval to ServiceNow Change"
  description: "When a Terraform Cloud run produces a plan with resource changes, creates a ServiceNow change request for approval before applying."
  tags:
    - infrastructure
    - itsm
    - terraform
    - servicenow
    - governance
capability:
  exposes:
    - type: mcp
      namespace: infra-governance
      port: 8080
      tools:
        - name: create-change-for-plan
          description: "Given a Terraform run ID, retrieve the plan summary and create a ServiceNow change request for CAB approval."
          inputParameters:
            - name: run_id
              in: body
              type: string
              description: "Terraform Cloud run ID."
          steps:
            - name: get-run
              type: call
              call: "terraform.get-run"
              with:
                run_id: "{{run_id}}"
            - name: create-change
              type: call
              call: "servicenow-chg.create-change"
              with:
                short_description: "Terraform plan: {{get-run.plan_summary.resource_additions}} add, {{get-run.plan_summary.resource_changes}} change, {{get-run.plan_summary.resource_destructions}} destroy"
                type: "standard"
                category: "infrastructure"
                assignment_group: "Cloud_Platform"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#infra-changes"
                text: "Change {{create-change.number}} created for Terraform run {{run_id}}"
  consumes:
    - type: http
      namespace: terraform
      baseUri: "https://app.terraform.io/api/v2"
      authentication:
        type: bearer
        token: "$secrets.terraform_token"
      resources:
        - name: runs
          path: "/runs/{{run_id}}"
          inputParameters:
            - name: run_id
              in: path
          operations:
            - name: get-run
              method: GET
    - type: http
      namespace: servicenow-chg
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: changes
          path: "/table/change_request"
          operations:
            - name: create-change
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves the current state and last run status of a Terraform Cloud workspace for infrastructure management queries.

naftiko: "0.5"
info:
  label: "Terraform Workspace Status Lookup"
  description: "Retrieves the current state and last run status of a Terraform Cloud workspace for infrastructure management queries."
  tags:
    - infrastructure
    - terraform
    - cloud
capability:
  exposes:
    - type: mcp
      namespace: infra
      port: 8080
      tools:
        - name: get-workspace-status
          description: "Given a Terraform Cloud organization and workspace name, return the workspace status, last run state, and resource count."
          inputParameters:
            - name: organization
              in: body
              type: string
              description: "Terraform Cloud organization name."
            - name: workspace_name
              in: body
              type: string
              description: "Workspace name."
          call: terraform.get-workspace
          with:
            org: "{{organization}}"
            workspace: "{{workspace_name}}"
  consumes:
    - type: http
      namespace: terraform
      baseUri: "https://app.terraform.io/api/v2"
      authentication:
        type: bearer
        token: "$secrets.terraform_token"
      resources:
        - name: workspaces
          path: "/organizations/{{org}}/workspaces/{{workspace}}"
          inputParameters:
            - name: org
              in: path
            - name: workspace
              in: path
          operations:
            - name: get-workspace
              method: GET

Queries Veritas NetBackup for backup job status on a given policy and creates a ServiceNow incident if any jobs have failed in the last 24 hours.

naftiko: "0.5"
info:
  label: "Veritas NetBackup Job Status Check"
  description: "Queries Veritas NetBackup for backup job status on a given policy and creates a ServiceNow incident if any jobs have failed in the last 24 hours."
  tags:
    - itsm
    - backup
    - veritas
    - servicenow
    - monitoring
capability:
  exposes:
    - type: mcp
      namespace: backup-ops
      port: 8080
      tools:
        - name: check-backup-status
          description: "Given a Veritas NetBackup policy name, retrieve recent job results and open a ServiceNow incident for any failed backup jobs."
          inputParameters:
            - name: policy_name
              in: body
              type: string
              description: "Veritas NetBackup policy name to check."
          steps:
            - name: get-jobs
              type: call
              call: "netbackup.get-jobs"
              with:
                policy: "{{policy_name}}"
            - name: create-backup-incident
              type: call
              call: "servicenow-backup.create-incident"
              with:
                short_description: "Backup failure: policy {{policy_name}}"
                category: "backup"
                urgency: "2"
                description: "Failed jobs: {{get-jobs.failed_count}} | Policy: {{policy_name}}"
  consumes:
    - type: http
      namespace: netbackup
      baseUri: "https://ibm-nbmaster.internal/netbackup/jobs"
      authentication:
        type: bearer
        token: "$secrets.netbackup_token"
      resources:
        - name: jobs
          path: "/jobs"
          inputParameters:
            - name: policy
              in: query
          operations:
            - name: get-jobs
              method: GET
    - type: http
      namespace: servicenow-backup
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST

Queries Workday for employees who have not completed benefits enrollment and sends reminder notifications via Slack and creates ServiceNow follow-up tasks.

naftiko: "0.5"
info:
  label: "Workday Benefits Enrollment Reminder"
  description: "Queries Workday for employees who have not completed benefits enrollment and sends reminder notifications via Slack and creates ServiceNow follow-up tasks."
  tags:
    - hr
    - workday
    - servicenow
    - slack
    - benefits
capability:
  exposes:
    - type: mcp
      namespace: benefits-ops
      port: 8080
      tools:
        - name: send-enrollment-reminders
          description: "Given an enrollment deadline date, find unenrolled employees, notify them, and create HR follow-up tasks."
          inputParameters:
            - name: enrollment_deadline
              in: body
              type: string
              description: "Benefits enrollment deadline date."
          steps:
            - name: get-unenrolled
              type: call
              call: "workday.get-unenrolled-workers"
              with:
                deadline: "{{enrollment_deadline}}"
            - name: create-hr-task
              type: call
              call: "servicenow-hr.create-task"
              with:
                short_description: "Benefits enrollment follow-up: {{get-unenrolled.count}} employees pending"
                assignment_group: "HR_Benefits"
            - name: notify-hr
              type: call
              call: "slack.post-message"
              with:
                channel: "#hr-benefits"
                text: "Benefits enrollment reminder: {{get-unenrolled.count}} employees have not yet enrolled. Deadline: {{enrollment_deadline}}"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: unenrolled
          path: "/ibm/workers?unenrolled=true&deadline={{deadline}}"
          inputParameters:
            - name: deadline
              in: query
          operations:
            - name: get-unenrolled-workers
              method: GET
    - type: http
      namespace: servicenow-hr
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Extracts compensation band data from Workday and triggers a Power BI dataset refresh, then notifies HR leadership via Slack.

naftiko: "0.5"
info:
  label: "Workday Compensation Review to Power BI"
  description: "Extracts compensation band data from Workday and triggers a Power BI dataset refresh, then notifies HR leadership via Slack."
  tags:
    - hr
    - analytics
    - workday
    - power-bi
    - slack
capability:
  exposes:
    - type: mcp
      namespace: comp-analytics
      port: 8080
      tools:
        - name: refresh-comp-report
          description: "Given a Workday report URL, extract compensation data, trigger a Power BI refresh, and notify HR."
          inputParameters:
            - name: report_url
              in: body
              type: string
              description: "Workday custom report URL."
            - name: dataset_id
              in: body
              type: string
              description: "Power BI dataset ID."
          steps:
            - name: get-comp-data
              type: call
              call: "workday.get-report"
              with:
                report_url: "{{report_url}}"
            - name: refresh-dataset
              type: call
              call: "powerbi.trigger-refresh"
              with:
                dataset_id: "{{dataset_id}}"
            - name: notify-hr
              type: call
              call: "slack.post-message"
              with:
                channel: "#hr-leadership"
                text: "Compensation review dashboard refreshed — {{get-comp-data.record_count}} records processed"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: reports
          path: "/ibm/reports/{{report_url}}"
          inputParameters:
            - name: report_url
              in: path
          operations:
            - name: get-report
              method: GET
    - 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: trigger-refresh
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves employee profile details from Workday HCM by employee ID, returning name, department, title, and manager for HR and IT queries.

naftiko: "0.5"
info:
  label: "Workday Employee Directory Lookup"
  description: "Retrieves employee profile details from Workday HCM by employee ID, returning name, department, title, and manager for HR and IT queries."
  tags:
    - hr
    - workday
    - employee-data
capability:
  exposes:
    - type: mcp
      namespace: hr
      port: 8080
      tools:
        - name: get-employee-profile
          description: "Given a Workday employee ID, retrieve full name, department, job title, and direct manager from Workday HCM."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "Workday employee ID."
          call: workday.get-worker
          with:
            worker_id: "{{employee_id}}"
          outputParameters:
            - name: full_name
              type: string
              mapping: "$.worker.fullName"
            - name: department
              type: string
              mapping: "$.worker.department"
            - name: title
              type: string
              mapping: "$.worker.jobTitle"
            - name: manager
              type: string
              mapping: "$.worker.manager.fullName"
  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: "/ibm/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET

Extracts the monthly headcount snapshot from Workday and loads it into Snowflake for HR analytics and workforce planning dashboards.

naftiko: "0.5"
info:
  label: "Workday Headcount Report to Snowflake"
  description: "Extracts the monthly headcount snapshot from Workday and loads it into Snowflake for HR analytics and workforce planning dashboards."
  tags:
    - hr
    - data
    - workday
    - snowflake
capability:
  exposes:
    - type: mcp
      namespace: hr-analytics
      port: 8080
      tools:
        - name: sync-headcount
          description: "Given an as-of date, extract the Workday headcount snapshot and load into Snowflake."
          inputParameters:
            - name: as_of_date
              in: body
              type: string
              description: "Date for the headcount snapshot."
          steps:
            - name: get-headcount
              type: call
              call: "workday.get-headcount-report"
              with:
                effective_date: "{{as_of_date}}"
            - name: load-to-snowflake
              type: call
              call: "snowflake.execute-query"
              with:
                statement: "INSERT INTO HR.HEADCOUNT_SNAPSHOTS (snapshot_date, department, count) VALUES ('{{as_of_date}}', '{{get-headcount.department}}', {{get-headcount.count}})"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: headcount
          path: "/ibm/reports/headcount?effectiveDate={{effective_date}}"
          inputParameters:
            - name: effective_date
              in: query
          operations:
            - name: get-headcount-report
              method: GET
    - type: http
      namespace: snowflake
      baseUri: "https://ibm.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-query
              method: POST

When a new developer hire is detected in Workday, invites them to the GitHub organization and creates an Okta application assignment.

naftiko: "0.5"
info:
  label: "Workday New Hire to GitHub Org Invite"
  description: "When a new developer hire is detected in Workday, invites them to the GitHub organization and creates an Okta application assignment."
  tags:
    - hr
    - devops
    - workday
    - github
    - okta
    - onboarding
capability:
  exposes:
    - type: mcp
      namespace: dev-onboarding
      port: 8080
      tools:
        - name: onboard-developer
          description: "Given a Workday worker ID, retrieve the new hire details, invite them to the GitHub org, and assign Okta developer apps."
          inputParameters:
            - name: worker_id
              in: body
              type: string
              description: "Workday worker ID of the new hire."
          steps:
            - name: get-new-hire
              type: call
              call: "workday.get-worker"
              with:
                worker_id: "{{worker_id}}"
            - name: invite-to-github
              type: call
              call: "github.create-org-invitation"
              with:
                email: "{{get-new-hire.email}}"
                role: "member"
            - name: assign-okta-apps
              type: call
              call: "okta.assign-app"
              with:
                user_id: "{{get-new-hire.email}}"
                app_id: "$secrets.okta_github_app_id"
  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: "/ibm/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: org-invitations
          path: "/orgs/ibm/invitations"
          operations:
            - name: create-org-invitation
              method: POST
    - type: http
      namespace: okta
      baseUri: "https://ibm.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "SSWS $secrets.okta_api_token"
        placement: header
      resources:
        - name: app-users
          path: "/apps/{{app_id}}/users"
          inputParameters:
            - name: app_id
              in: path
          operations:
            - name: assign-app
              method: POST

When a Workday employee changes roles, updates their Okta group memberships to match the new department and creates a ServiceNow audit record.

naftiko: "0.5"
info:
  label: "Workday Role Change to Okta Group Sync"
  description: "When a Workday employee changes roles, updates their Okta group memberships to match the new department and creates a ServiceNow audit record."
  tags:
    - hr
    - security
    - workday
    - okta
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: role-sync
      port: 8080
      tools:
        - name: sync-role-groups
          description: "Given a worker ID and new department, update Okta group memberships and log the change in ServiceNow."
          inputParameters:
            - name: worker_id
              in: body
              type: string
              description: "Workday worker ID."
            - name: new_department
              in: body
              type: string
              description: "New department name."
          steps:
            - name: get-worker
              type: call
              call: "workday.get-worker"
              with:
                worker_id: "{{worker_id}}"
            - name: update-groups
              type: call
              call: "okta.update-groups"
              with:
                user_id: "{{get-worker.email}}"
                group_name: "{{new_department}}"
            - name: create-audit
              type: call
              call: "servicenow-audit.create-record"
              with:
                short_description: "Role change: {{get-worker.full_name}} moved to {{new_department}}"
                category: "access_management"
  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: "/ibm/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: okta
      baseUri: "https://ibm.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "SSWS $secrets.okta_api_token"
        placement: header
      resources:
        - name: groups
          path: "/groups"
          operations:
            - name: update-groups
              method: PUT
    - type: http
      namespace: servicenow-audit
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: records
          path: "/table/sys_audit"
          operations:
            - name: create-record
              method: POST

When a Workday employee termination event fires, deactivates the user in Okta and creates a ServiceNow HR task to confirm offboarding completion.

naftiko: "0.5"
info:
  label: "Workday Termination to Okta Deprovisioning"
  description: "When a Workday employee termination event fires, deactivates the user in Okta and creates a ServiceNow HR task to confirm offboarding completion."
  tags:
    - hr
    - security
    - workday
    - okta
    - servicenow
    - offboarding
capability:
  exposes:
    - type: mcp
      namespace: offboarding
      port: 8080
      tools:
        - name: handle-termination
          description: "Given a Workday worker ID, deactivate the corresponding Okta user and create a ServiceNow offboarding task."
          inputParameters:
            - name: worker_id
              in: body
              type: string
              description: "Workday worker ID of the terminated employee."
          steps:
            - name: get-worker
              type: call
              call: "workday.get-worker"
              with:
                worker_id: "{{worker_id}}"
            - name: deactivate-okta-user
              type: call
              call: "okta.deactivate-user"
              with:
                user_id: "{{get-worker.email}}"
            - name: create-offboarding-task
              type: call
              call: "servicenow-hr.create-task"
              with:
                short_description: "Offboarding: {{get-worker.full_name}} deprovisioned from Okta"
                assignment_group: "HR_Operations"
                category: "offboarding"
  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: "/ibm/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: okta
      baseUri: "https://ibm.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "SSWS $secrets.okta_api_token"
        placement: header
      resources:
        - name: users
          path: "/users/{{user_id}}/lifecycle/deactivate"
          inputParameters:
            - name: user_id
              in: path
          operations:
            - name: deactivate-user
              method: POST
    - type: http
      namespace: servicenow-hr
      baseUri: "https://ibm.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST