SAP Capabilities

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

Sort
Expand

Loads review data.

naftiko: "0.5"
info:
  label: "Access Review to Snowflake"
  description: "Loads review data."
  tags:
    - security
    - compliance
    - okta
    - snowflake
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: access
      port: 8080
      tools:
        - name: access-review-to-snowflake
          description: "Loads review data."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "okta.get-data"
              with:
                id: "{{input_id}}"
            - name: create-record
              type: call
              call: "servicenow.create-record"
              with:
                short_description: "Access Review to Snowflake"
  consumes:
    - type: http
      namespace: okta
      baseUri: "https://okta.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.okta_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: records
          path: "/table/incident"
          operations:
            - name: create-record
              method: POST

Retrieves EC2 instance state.

naftiko: "0.5"
info:
  label: "AWS EC2 Instance Status"
  description: "Retrieves EC2 instance state."
  tags:
    - cloud
    - infrastructure
    - aws
capability:
  exposes:
    - type: mcp
      namespace: cloud-infra
      port: 8080
      tools:
        - name: get-ec2
          description: "Given instance ID, return state."
          inputParameters:
            - name: instance_id
              in: body
              type: string
              description: "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: "/"
          operations:
            - name: describe-instance
              method: GET

Creates FinOps ticket.

naftiko: "0.5"
info:
  label: "Azure Cost Anomaly to Jira"
  description: "Creates FinOps ticket."
  tags:
    - cloud
    - finops
    - azure
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: azure
      port: 8080
      tools:
        - name: azure-cost-anomaly-to-jira
          description: "Creates FinOps ticket."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "azure.get-data"
              with:
                id: "{{input_id}}"
            - name: create-issue
              type: call
              call: "jira.create-issue"
              with:
                summary: "Azure Cost Anomaly to Jira"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "Azure Cost Anomaly to Jira triggered"
  consumes:
    - type: http
      namespace: azure
      baseUri: "https://azure.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.azure_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: jira
      baseUri: "https://sap-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

Queries Azure cost for resource group.

naftiko: "0.5"
info:
  label: "Azure Cost Lookup"
  description: "Queries Azure cost for resource group."
  tags:
    - cloud
    - finops
    - azure
capability:
  exposes:
    - type: mcp
      namespace: finops
      port: 8080
      tools:
        - name: get-cost
          description: "Given subscription, return cost."
          inputParameters:
            - name: subscription_id
              in: body
              type: string
              description: "Subscription Id"
          call: azure-cost.get-cost
          with:
            subscription_id: "{{subscription_id}}"
  consumes:
    - type: http
      namespace: azure-cost
      baseUri: "https://management.azure.com"
      authentication:
        type: bearer
        token: "$secrets.azure_token"
      resources:
        - name: cost
          path: "/subscriptions/{{subscription_id}}/providers/Microsoft.CostManagement/query"
          operations:
            - name: get-cost
              method: POST

Reminds unenrolled employees.

naftiko: "0.5"
info:
  label: "Benefits Enrollment Reminder"
  description: "Reminds unenrolled employees."
  tags:
    - hr
    - workday
    - servicenow
    - slack
    - benefits
capability:
  exposes:
    - type: mcp
      namespace: benefits
      port: 8080
      tools:
        - name: benefits-enrollment-reminder
          description: "Reminds unenrolled employees."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "workday.get-data"
              with:
                id: "{{input_id}}"
            - name: create-record
              type: call
              call: "servicenow.create-record"
              with:
                short_description: "Benefits Enrollment Reminder"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "Benefits Enrollment Reminder triggered"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://workday.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: records
          path: "/table/incident"
          operations:
            - name: create-record
              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

Applies on approval.

naftiko: "0.5"
info:
  label: "Change to Terraform Apply"
  description: "Applies on approval."
  tags:
    - itsm
    - infrastructure
    - servicenow
    - terraform
capability:
  exposes:
    - type: mcp
      namespace: change
      port: 8080
      tools:
        - name: change-to-terraform-apply
          description: "Applies on approval."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "infrastructure.get-data"
              with:
                id: "{{input_id}}"
            - name: create-record
              type: call
              call: "servicenow.create-record"
              with:
                short_description: "Change to Terraform Apply"
  consumes:
    - type: http
      namespace: infrastructure
      baseUri: "https://infrastructure.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.infrastructure_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: records
          path: "/table/incident"
          operations:
            - name: create-record
              method: POST

Blocks and alerts.

naftiko: "0.5"
info:
  label: "Cloudflare Block to PagerDuty"
  description: "Blocks and alerts."
  tags:
    - security
    - networking
    - cloudflare
    - pagerduty
capability:
  exposes:
    - type: mcp
      namespace: cloudflare
      port: 8080
      tools:
        - name: cloudflare-block-to-pagerduty
          description: "Blocks and alerts."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "cloudflare.get-data"
              with:
                id: "{{input_id}}"
            - name: create-incident
              type: call
              call: "pagerduty.create-incident"
              with:
                title: "Cloudflare Block to PagerDuty"
  consumes:
    - type: http
      namespace: cloudflare
      baseUri: "https://cloudflare.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.cloudflare_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              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

Lists DNS records for zone.

naftiko: "0.5"
info:
  label: "Cloudflare DNS Records"
  description: "Lists DNS records for zone."
  tags:
    - networking
    - dns
    - cloudflare
capability:
  exposes:
    - type: mcp
      namespace: dns
      port: 8080
      tools:
        - name: list-records
          description: "Given zone ID, return records."
          inputParameters:
            - name: zone_id
              in: body
              type: string
              description: "Zone Id"
          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"
          operations:
            - name: list-records
              method: GET

Creates incident for alarms.

naftiko: "0.5"
info:
  label: "CloudWatch to ServiceNow"
  description: "Creates incident for alarms."
  tags:
    - cloud
    - itsm
    - aws
    - servicenow
    - slack
capability:
  exposes:
    - type: mcp
      namespace: cloudwatch
      port: 8080
      tools:
        - name: cloudwatch-alarm-to-incident
          description: "Creates incident for alarms."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "aws.get-data"
              with:
                id: "{{input_id}}"
            - name: create-record
              type: call
              call: "servicenow.create-record"
              with:
                short_description: "CloudWatch to ServiceNow"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "CloudWatch to ServiceNow triggered"
  consumes:
    - type: http
      namespace: aws
      baseUri: "https://aws.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.aws_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: records
          path: "/table/incident"
          operations:
            - name: create-record
              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

Compares Terraform and CMDB.

naftiko: "0.5"
info:
  label: "CMDB Drift Detection"
  description: "Compares Terraform and CMDB."
  tags:
    - itsm
    - infrastructure
    - servicenow
    - terraform
    - governance
capability:
  exposes:
    - type: mcp
      namespace: cmdb
      port: 8080
      tools:
        - name: cmdb-drift-detection
          description: "Compares Terraform and CMDB."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "infrastructure.get-data"
              with:
                id: "{{input_id}}"
            - name: create-record
              type: call
              call: "servicenow.create-record"
              with:
                short_description: "CMDB Drift Detection"
  consumes:
    - type: http
      namespace: infrastructure
      baseUri: "https://infrastructure.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.infrastructure_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: records
          path: "/table/incident"
          operations:
            - name: create-record
              method: POST

Refreshes dashboard.

naftiko: "0.5"
info:
  label: "Compensation to Power BI"
  description: "Refreshes dashboard."
  tags:
    - hr
    - analytics
    - workday
    - power-bi
    - slack
capability:
  exposes:
    - type: mcp
      namespace: comp
      port: 8080
      tools:
        - name: comp-review-to-power-bi
          description: "Refreshes dashboard."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "analytics.get-data"
              with:
                id: "{{input_id}}"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "Compensation to Power BI triggered"
  consumes:
    - type: http
      namespace: analytics
      baseUri: "https://analytics.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.analytics_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              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

Creates compliance task.

naftiko: "0.5"
info:
  label: "Concur Expense Violation"
  description: "Creates compliance task."
  tags:
    - finance
    - compliance
    - sap-concur
    - servicenow
    - slack
capability:
  exposes:
    - type: mcp
      namespace: concur
      port: 8080
      tools:
        - name: concur-expense-violation
          description: "Creates compliance task."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "sap-concur.get-data"
              with:
                id: "{{input_id}}"
            - name: create-record
              type: call
              call: "servicenow.create-record"
              with:
                short_description: "Concur Expense Violation"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "Concur Expense Violation triggered"
  consumes:
    - type: http
      namespace: sap-concur
      baseUri: "https://sap-concur.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.sap_concur_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: records
          path: "/table/incident"
          operations:
            - name: create-record
              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 Confluence page by title.

naftiko: "0.5"
info:
  label: "Confluence Page Search"
  description: "Retrieves Confluence page by title."
  tags:
    - knowledge
    - confluence
    - documentation
capability:
  exposes:
    - type: mcp
      namespace: knowledge
      port: 8080
      tools:
        - name: get-page
          description: "Given title, return page."
          inputParameters:
            - name: title
              in: body
              type: string
              description: "Title"
          call: confluence.get-page
          with:
            title: "{{title}}"
  consumes:
    - type: http
      namespace: confluence
      baseUri: "https://sap-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

Enrolls expiring contracts.

naftiko: "0.5"
info:
  label: "Contract to HubSpot Nurture"
  description: "Enrolls expiring contracts."
  tags:
    - crm
    - marketing
    - salesforce
    - hubspot
    - slack
capability:
  exposes:
    - type: mcp
      namespace: contract
      port: 8080
      tools:
        - name: contract-to-hubspot-nurture
          description: "Enrolls expiring contracts."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "salesforce.get-data"
              with:
                id: "{{input_id}}"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "Contract to HubSpot Nurture triggered"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://salesforce.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              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

Reads a customer record from SAP S/4HANA, enriches it with firmographic data from ZoomInfo, and updates the Salesforce account record.

naftiko: "0.5"
info:
  label: "Customer Master Data Enrichment"
  description: "Reads a customer record from SAP S/4HANA, enriches it with firmographic data from ZoomInfo, and updates the Salesforce account record."
  tags:
    - crm
    - sales
    - sap-s4hana
    - salesforce
    - zoominfo
    - data-enrichment
capability:
  exposes:
    - type: mcp
      namespace: crm-enrichment
      port: 8080
      tools:
        - name: enrich-customer-record
          description: "Given a SAP customer number and Salesforce account ID, fetch the customer from SAP, enrich with ZoomInfo firmographics, and update Salesforce. Use for data quality improvement workflows."
          inputParameters:
            - name: customer_number
              in: body
              type: string
              description: "SAP customer number to look up."
            - name: salesforce_account_id
              in: body
              type: string
              description: "Salesforce account ID to update with enriched data."
          steps:
            - name: get-customer
              type: call
              call: "sap-customer.get-customer"
              with:
                Customer: "{{customer_number}}"
            - name: enrich-firmographic
              type: call
              call: "zoominfo.search-company"
              with:
                companyName: "{{get-customer.CustomerName}}"
                website: "{{get-customer.WebsiteURL}}"
            - name: update-salesforce
              type: call
              call: "salesforce.update-account"
              with:
                accountId: "{{salesforce_account_id}}"
                employeeCount: "{{enrich-firmographic.employeeCount}}"
                revenue: "{{enrich-firmographic.revenue}}"
                industry: "{{enrich-firmographic.industry}}"
  consumes:
    - type: http
      namespace: sap-customer
      baseUri: "https://sap-s4.sap.com/sap/opu/odata/sap/API_BUSINESS_PARTNER"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: customers
          path: "/A_Customer('{{Customer}}')"
          inputParameters:
            - name: Customer
              in: path
          operations:
            - name: get-customer
              method: GET
    - type: http
      namespace: zoominfo
      baseUri: "https://api.zoominfo.com/search"
      authentication:
        type: bearer
        token: "$secrets.zoominfo_token"
      resources:
        - name: company-search
          path: "/company"
          operations:
            - name: search-company
              method: POST
    - type: http
      namespace: salesforce
      baseUri: "https://sap.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: accounts
          path: "/sobjects/Account/{{accountId}}"
          inputParameters:
            - name: accountId
              in: path
          operations:
            - name: update-account
              method: PATCH

Creates Jira for failures.

naftiko: "0.5"
info:
  label: "Databricks Failure to Jira"
  description: "Creates Jira for failures."
  tags:
    - data
    - devops
    - azure-databricks
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: databricks
      port: 8080
      tools:
        - name: databricks-failure-to-jira
          description: "Creates Jira for failures."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "data.get-data"
              with:
                id: "{{input_id}}"
            - name: create-issue
              type: call
              call: "jira.create-issue"
              with:
                summary: "Databricks Failure to Jira"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "Databricks Failure to Jira triggered"
  consumes:
    - type: http
      namespace: data
      baseUri: "https://data.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.data_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: jira
      baseUri: "https://sap-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

Creates PagerDuty incident and notifies Slack on critical.

naftiko: "0.5"
info:
  label: "Datadog Alert to PagerDuty and Slack"
  description: "Creates PagerDuty incident and notifies Slack on critical."
  tags:
    - observability
    - incident-response
    - datadog
    - pagerduty
    - slack
capability:
  exposes:
    - type: mcp
      namespace: datadog
      port: 8080
      tools:
        - name: datadog-alert-to-pagerduty-slack
          description: "Creates PagerDuty incident and notifies Slack on critical."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "observability.get-data"
              with:
                id: "{{input_id}}"
            - name: create-incident
              type: call
              call: "pagerduty.create-incident"
              with:
                title: "Datadog Alert to PagerDuty and Slack"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "Datadog Alert to PagerDuty and Slack triggered"
  consumes:
    - type: http
      namespace: observability
      baseUri: "https://observability.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.observability_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              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 fires a monitor alert for an SAP system, creates a ServiceNow incident and posts an alert to Microsoft Teams.

naftiko: "0.5"
info:
  label: "Datadog Alert to SAP Incident"
  description: "When Datadog fires a monitor alert for an SAP system, creates a ServiceNow incident and posts an alert to Microsoft Teams."
  tags:
    - itsm
    - monitoring
    - datadog
    - servicenow
    - microsoft-teams
    - incident-response
capability:
  exposes:
    - type: mcp
      namespace: sap-incident-ops
      port: 8080
      tools:
        - name: handle-datadog-sap-alert
          description: "Given a Datadog monitor ID and alert event, retrieve alert details, create a P1 ServiceNow incident, and post an ops alert to Teams."
          inputParameters:
            - name: monitor_id
              in: body
              type: string
              description: "Datadog monitor ID that fired."
            - name: alert_message
              in: body
              type: string
              description: "Short alert message describing the SAP system issue."
            - name: teams_channel_id
              in: body
              type: string
              description: "Teams channel ID for the ops alert."
          steps:
            - name: get-monitor
              type: call
              call: "datadog.get-monitor"
              with:
                monitor_id: "{{monitor_id}}"
            - name: create-incident
              type: call
              call: "servicenow-incident.create-incident"
              with:
                short_description: "SAP Alert: {{alert_message}}"
                urgency: "1"
                impact: "1"
                description: "Datadog monitor {{monitor_id}} ({{get-monitor.name}}) fired. Query: {{get-monitor.query}}"
            - name: alert-teams
              type: call
              call: "msteams-ops.send-channel-message"
              with:
                channelId: "{{teams_channel_id}}"
                text: "SAP Alert: {{alert_message}} | Monitor: {{get-monitor.name}} | Incident: {{create-incident.number}}"
  consumes:
    - type: http
      namespace: datadog
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: monitors
          path: "/monitor/{{monitor_id}}"
          inputParameters:
            - name: monitor_id
              in: path
          operations:
            - name: get-monitor
              method: GET
    - type: http
      namespace: servicenow-incident
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams-ops
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{teamId}}/channels/{{channelId}}/messages"
          inputParameters:
            - name: channelId
              in: path
          operations:
            - name: send-channel-message
              method: POST

Retrieves Datadog monitor status.

naftiko: "0.5"
info:
  label: "Datadog Monitor Lookup"
  description: "Retrieves Datadog monitor status."
  tags:
    - observability
    - datadog
    - monitoring
capability:
  exposes:
    - type: mcp
      namespace: monitoring
      port: 8080
      tools:
        - name: get-monitor
          description: "Given monitor ID, return status."
          inputParameters:
            - name: monitor_id
              in: body
              type: string
              description: "Monitor Id"
          call: datadog.get-monitor
          with:
            monitor_id: "{{monitor_id}}"
  consumes:
    - type: http
      namespace: datadog
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: monitors
          path: "/monitor/{{monitor_id}}"
          operations:
            - name: get-monitor
              method: GET

Creates task for vulnerabilities.

naftiko: "0.5"
info:
  label: "Dependabot to Jira Security"
  description: "Creates task for vulnerabilities."
  tags:
    - security
    - devops
    - github
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: dependabot
      port: 8080
      tools:
        - name: dependabot-to-jira-security
          description: "Creates task for vulnerabilities."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "github.get-data"
              with:
                id: "{{input_id}}"
            - name: create-issue
              type: call
              call: "jira.create-issue"
              with:
                summary: "Dependabot to Jira Security"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "Dependabot to Jira Security triggered"
  consumes:
    - type: http
      namespace: github
      baseUri: "https://github.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: jira
      baseUri: "https://sap-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

Creates incident for problems.

naftiko: "0.5"
info:
  label: "Dynatrace to ServiceNow"
  description: "Creates incident for problems."
  tags:
    - observability
    - itsm
    - dynatrace
    - servicenow
    - slack
capability:
  exposes:
    - type: mcp
      namespace: dynatrace
      port: 8080
      tools:
        - name: dynatrace-to-servicenow
          description: "Creates incident for problems."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "observability.get-data"
              with:
                id: "{{input_id}}"
            - name: create-record
              type: call
              call: "servicenow.create-record"
              with:
                short_description: "Dynatrace to ServiceNow"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "Dynatrace to ServiceNow triggered"
  consumes:
    - type: http
      namespace: observability
      baseUri: "https://observability.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.observability_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: records
          path: "/table/incident"
          operations:
            - name: create-record
              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

Reads new employee records from SAP SuccessFactors and creates corresponding user accounts in Microsoft Entra ID, then logs the sync in Jira.

naftiko: "0.5"
info:
  label: "Employee Master Data Sync"
  description: "Reads new employee records from SAP SuccessFactors and creates corresponding user accounts in Microsoft Entra ID, then logs the sync in Jira."
  tags:
    - hr
    - identity
    - sap-successfactors
    - microsoft-entra
    - jira
    - onboarding
capability:
  exposes:
    - type: mcp
      namespace: hr-identity
      port: 8080
      tools:
        - name: sync-employee-to-entra
          description: "Given a SuccessFactors employee ID, read their master data, provision an Entra ID account, and log the result in a Jira HR project."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "The SuccessFactors employee ID for the new hire."
            - name: jira_project_key
              in: body
              type: string
              description: "Jira project key to log the sync ticket, e.g. HR."
          steps:
            - name: get-employee
              type: call
              call: "successfactors.get-employee"
              with:
                employeeId: "{{employee_id}}"
            - name: create-entra-user
              type: call
              call: "entra.create-user"
              with:
                displayName: "{{get-employee.displayName}}"
                userPrincipalName: "{{get-employee.workEmail}}"
                department: "{{get-employee.department}}"
            - name: log-jira
              type: call
              call: "jira.create-issue"
              with:
                project_key: "{{jira_project_key}}"
                issuetype: "Task"
                summary: "Entra account provisioned for {{get-employee.displayName}}"
                description: "Employee ID: {{employee_id}}\nEntra UPN: {{get-employee.workEmail}}\nEntra Object ID: {{create-entra-user.id}}"
  consumes:
    - type: http
      namespace: successfactors
      baseUri: "https://api4.successfactors.com/odata/v2"
      authentication:
        type: bearer
        token: "$secrets.sf_token"
      resources:
        - name: employees
          path: "/PerPerson('{{employeeId}}')"
          inputParameters:
            - name: employeeId
              in: path
          operations:
            - name: get-employee
              method: GET
    - type: http
      namespace: entra
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: users
          path: "/users"
          operations:
            - name: create-user
              method: POST
    - type: http
      namespace: jira
      baseUri: "https://sap.atlassian.net/rest/api/3"
      authentication:
        type: bearer
        token: "$secrets.jira_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST

Suspends on risk.

naftiko: "0.5"
info:
  label: "Entra Risk to Okta Suspend"
  description: "Suspends on risk."
  tags:
    - security
    - identity
    - azure
    - okta
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: entra
      port: 8080
      tools:
        - name: entra-risk-to-okta-suspend
          description: "Suspends on risk."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "identity.get-data"
              with:
                id: "{{input_id}}"
            - name: create-record
              type: call
              call: "servicenow.create-record"
              with:
                short_description: "Entra Risk to Okta Suspend"
  consumes:
    - type: http
      namespace: identity
      baseUri: "https://identity.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.identity_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: records
          path: "/table/incident"
          operations:
            - name: create-record
              method: POST

Updates on completion.

naftiko: "0.5"
info:
  label: "Epic to Salesforce"
  description: "Updates on completion."
  tags:
    - devops
    - crm
    - jira
    - salesforce
    - slack
capability:
  exposes:
    - type: mcp
      namespace: epic
      port: 8080
      tools:
        - name: epic-to-salesforce
          description: "Updates on completion."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "jira.get-data"
              with:
                id: "{{input_id}}"
            - name: create-issue
              type: call
              call: "jira.create-issue"
              with:
                summary: "Epic to Salesforce"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "Epic to Salesforce triggered"
  consumes:
    - type: http
      namespace: jira
      baseUri: "https://jira.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.jira_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: jira
      baseUri: "https://sap-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

Triggers a GitHub Actions deployment workflow to push an application to SAP BTP Cloud Foundry and reports the deployment status back in a Jira release ticket.

naftiko: "0.5"
info:
  label: "GitHub Actions Deployment to SAP BTP Cloud Foundry"
  description: "Triggers a GitHub Actions deployment workflow to push an application to SAP BTP Cloud Foundry and reports the deployment status back in a Jira release ticket."
  tags:
    - devops
    - cicd
    - github
    - sap-btp
    - jira
    - deployment
capability:
  exposes:
    - type: mcp
      namespace: btp-deploy
      port: 8080
      tools:
        - name: trigger-btp-deployment
          description: "Given a GitHub repo, branch, and Jira release ticket key, trigger a GitHub Actions workflow to deploy to SAP BTP Cloud Foundry and update the Jira ticket with the deployment result."
          inputParameters:
            - name: github_repo
              in: body
              type: string
              description: "GitHub repository in owner/repo format."
            - name: branch
              in: body
              type: string
              description: "Branch name to deploy from."
            - name: jira_ticket_key
              in: body
              type: string
              description: "Jira release ticket key to update with deployment status."
          steps:
            - name: trigger-workflow
              type: call
              call: "github-deploy.trigger-workflow"
              with:
                repo: "{{github_repo}}"
                ref: "{{branch}}"
                workflow: "deploy-btp.yml"
            - name: update-jira-ticket
              type: call
              call: "jira-deploy.add-comment"
              with:
                issueKey: "{{jira_ticket_key}}"
                comment: "BTP deployment triggered from branch {{branch}}. GitHub run ID: {{trigger-workflow.runId}}"
  consumes:
    - type: http
      namespace: github-deploy
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: workflow-dispatches
          path: "/repos/{{repo}}/actions/workflows/{{workflow}}/dispatches"
          inputParameters:
            - name: repo
              in: path
            - name: workflow
              in: path
          operations:
            - name: trigger-workflow
              method: POST
    - type: http
      namespace: jira-deploy
      baseUri: "https://sap.atlassian.net/rest/api/3"
      authentication:
        type: bearer
        token: "$secrets.jira_token"
      resources:
        - name: issue-comments
          path: "/issue/{{issueKey}}/comment"
          inputParameters:
            - name: issueKey
              in: path
          operations:
            - name: add-comment
              method: POST

Posts failure to Slack.

naftiko: "0.5"
info:
  label: "GitHub Actions Failure"
  description: "Posts failure to Slack."
  tags:
    - devops
    - ci-cd
    - github
    - slack
capability:
  exposes:
    - type: mcp
      namespace: github
      port: 8080
      tools:
        - name: github-actions-failure-notify
          description: "Posts failure to Slack."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "github.get-data"
              with:
                id: "{{input_id}}"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "GitHub Actions Failure triggered"
  consumes:
    - type: http
      namespace: github
      baseUri: "https://github.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              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 GitHub pull request merges to main, creates a corresponding SAP transport request in the development landscape and assigns it to the developer.

naftiko: "0.5"
info:
  label: "GitHub PR Merge to SAP Transport"
  description: "When a GitHub pull request merges to main, creates a corresponding SAP transport request in the development landscape and assigns it to the developer."
  tags:
    - devops
    - cicd
    - github
    - sap-transport
    - change-management
capability:
  exposes:
    - type: mcp
      namespace: sap-devops
      port: 8080
      tools:
        - name: create-transport-from-pr
          description: "Given a merged GitHub pull request number and repo, create a SAP Workbench transport request and assign the developer. Use to automate ABAP change management from GitHub workflow events."
          inputParameters:
            - name: pr_number
              in: body
              type: integer
              description: "GitHub pull request number that was merged."
            - name: repo
              in: body
              type: string
              description: "GitHub repo in owner/repo format."
            - name: sap_developer_id
              in: body
              type: string
              description: "SAP user ID of the developer to assign the transport to."
          steps:
            - name: get-pr
              type: call
              call: "github.get-pull-request"
              with:
                repo: "{{repo}}"
                pull_number: "{{pr_number}}"
            - name: create-transport
              type: call
              call: "sap-cts.create-transport"
              with:
                description: "{{get-pr.title}} (PR #{{pr_number}})"
                owner: "{{sap_developer_id}}"
                targetSystem: "QAS"
  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/{{pull_number}}"
          inputParameters:
            - name: repo
              in: path
            - name: pull_number
              in: path
          operations:
            - name: get-pull-request
              method: GET
    - type: http
      namespace: sap-cts
      baseUri: "https://sap-s4.sap.com/sap/opu/odata/sap/CTS_API_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: transports
          path: "/TransportRequests"
          operations:
            - name: create-transport
              method: POST

Updates ServiceNow change on PR merge.

naftiko: "0.5"
info:
  label: "GitHub PR to ServiceNow Change"
  description: "Updates ServiceNow change on PR merge."
  tags:
    - devops
    - itsm
    - github
    - servicenow
    - slack
capability:
  exposes:
    - type: mcp
      namespace: github
      port: 8080
      tools:
        - name: github-pr-to-servicenow-change
          description: "Updates ServiceNow change on PR merge."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "github.get-data"
              with:
                id: "{{input_id}}"
            - name: create-record
              type: call
              call: "servicenow.create-record"
              with:
                short_description: "GitHub PR to ServiceNow Change"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "GitHub PR to ServiceNow Change triggered"
  consumes:
    - type: http
      namespace: github
      baseUri: "https://github.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: records
          path: "/table/incident"
          operations:
            - name: create-record
              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 GitHub repository metadata.

naftiko: "0.5"
info:
  label: "GitHub Repository Lookup"
  description: "Retrieves GitHub repository metadata."
  tags:
    - devops
    - github
    - code-management
capability:
  exposes:
    - type: mcp
      namespace: code-mgmt
      port: 8080
      tools:
        - name: get-repo
          description: "Given owner/repo, return metadata."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "Repo"
          call: github.get-repo
          with:
            repo: "{{repo}}"
  consumes:
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: repos
          path: "/repos/{{repo}}"
          operations:
            - name: get-repo
              method: GET

Creates incident with runbook.

naftiko: "0.5"
info:
  label: "Grafana to ServiceNow"
  description: "Creates incident with runbook."
  tags:
    - observability
    - itsm
    - grafana
    - servicenow
    - confluence
capability:
  exposes:
    - type: mcp
      namespace: grafana
      port: 8080
      tools:
        - name: grafana-alert-to-incident
          description: "Creates incident with runbook."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "observability.get-data"
              with:
                id: "{{input_id}}"
            - name: create-record
              type: call
              call: "servicenow.create-record"
              with:
                short_description: "Grafana to ServiceNow"
            - name: create-page
              type: call
              call: "confluence.create-page"
              with:
                title: "Grafana to ServiceNow"
  consumes:
    - type: http
      namespace: observability
      baseUri: "https://observability.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.observability_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: records
          path: "/table/incident"
          operations:
            - name: create-record
              method: POST
    - type: http
      namespace: confluence
      baseUri: "https://sap-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

Exports current headcount by cost center from SAP SuccessFactors and publishes the snapshot to a Power BI dataset for finance planning.

naftiko: "0.5"
info:
  label: "Headcount Planning Snapshot"
  description: "Exports current headcount by cost center from SAP SuccessFactors and publishes the snapshot to a Power BI dataset for finance planning."
  tags:
    - hr
    - finance
    - reporting
    - sap-successfactors
    - power-bi
capability:
  exposes:
    - type: mcp
      namespace: hr-reporting
      port: 8080
      tools:
        - name: publish-headcount-snapshot
          description: "Export headcount grouped by department and cost center from SuccessFactors and push the dataset to Power BI for workforce planning dashboards."
          inputParameters:
            - name: dataset_id
              in: body
              type: string
              description: "The Power BI dataset ID to push rows into."
            - name: table_name
              in: body
              type: string
              description: "The table name inside the Power BI dataset, e.g. Headcount."
          steps:
            - name: get-headcount
              type: call
              call: "successfactors-hc.get-headcount"
            - name: push-dataset
              type: call
              call: "powerbi.push-rows"
              with:
                datasetId: "{{dataset_id}}"
                tableName: "{{table_name}}"
                rows: "{{get-headcount.results}}"
  consumes:
    - type: http
      namespace: successfactors-hc
      baseUri: "https://api4.successfactors.com/odata/v2"
      authentication:
        type: bearer
        token: "$secrets.sf_token"
      resources:
        - name: headcount-query
          path: "/EmpJob"
          operations:
            - name: get-headcount
              method: GET
    - type: http
      namespace: powerbi
      baseUri: "https://api.powerbi.com/v1.0/myorg"
      authentication:
        type: bearer
        token: "$secrets.powerbi_token"
      resources:
        - name: dataset-rows
          path: "/datasets/{{datasetId}}/tables/{{tableName}}/rows"
          inputParameters:
            - name: datasetId
              in: path
            - name: tableName
              in: path
          operations:
            - name: push-rows
              method: POST

Searches HubSpot for contact by email.

naftiko: "0.5"
info:
  label: "HubSpot Contact Lookup"
  description: "Searches HubSpot for contact by email."
  tags:
    - crm
    - marketing
    - hubspot
capability:
  exposes:
    - type: mcp
      namespace: crm-marketing
      port: 8080
      tools:
        - name: search-contact
          description: "Given email, find contact."
          inputParameters:
            - name: email
              in: body
              type: string
              description: "Email"
          call: hubspot.search-contacts
          with:
            email: "{{email}}"
  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

Syncs leads to Salesforce.

naftiko: "0.5"
info:
  label: "HubSpot Lead to Salesforce"
  description: "Syncs leads to Salesforce."
  tags:
    - crm
    - marketing
    - hubspot
    - salesforce
    - slack
capability:
  exposes:
    - type: mcp
      namespace: hubspot
      port: 8080
      tools:
        - name: hubspot-lead-to-salesforce
          description: "Syncs leads to Salesforce."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "hubspot.get-data"
              with:
                id: "{{input_id}}"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "HubSpot Lead to Salesforce triggered"
  consumes:
    - type: http
      namespace: hubspot
      baseUri: "https://hubspot.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.hubspot_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              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

Creates ServiceNow problem for recurring bugs.

naftiko: "0.5"
info:
  label: "Jira Bug to ServiceNow Problem"
  description: "Creates ServiceNow problem for recurring bugs."
  tags:
    - devops
    - itsm
    - jira
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: jira
      port: 8080
      tools:
        - name: jira-bug-to-servicenow-problem
          description: "Creates ServiceNow problem for recurring bugs."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "jira.get-data"
              with:
                id: "{{input_id}}"
            - name: create-record
              type: call
              call: "servicenow.create-record"
              with:
                short_description: "Jira Bug to ServiceNow Problem"
  consumes:
    - type: http
      namespace: jira
      baseUri: "https://jira.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.jira_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: records
          path: "/table/incident"
          operations:
            - name: create-record
              method: POST

Retrieves Jira issue status and assignee.

naftiko: "0.5"
info:
  label: "Jira Issue Status Lookup"
  description: "Retrieves Jira issue status and assignee."
  tags:
    - devops
    - jira
    - project-management
capability:
  exposes:
    - type: mcp
      namespace: project-mgmt
      port: 8080
      tools:
        - name: get-issue
          description: "Given issue key, return status."
          inputParameters:
            - name: issue_key
              in: body
              type: string
              description: "Issue Key"
          call: jira.get-issue
          with:
            issue_key: "{{issue_key}}"
  consumes:
    - type: http
      namespace: jira
      baseUri: "https://sap-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}}"
          operations:
            - name: get-issue
              method: GET

Publishes release notes.

naftiko: "0.5"
info:
  label: "Jira Release to Confluence"
  description: "Publishes release notes."
  tags:
    - devops
    - documentation
    - jira
    - confluence
    - slack
capability:
  exposes:
    - type: mcp
      namespace: jira
      port: 8080
      tools:
        - name: jira-release-to-confluence
          description: "Publishes release notes."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "jira.get-data"
              with:
                id: "{{input_id}}"
            - name: create-issue
              type: call
              call: "jira.create-issue"
              with:
                summary: "Jira Release to Confluence"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "Jira Release to Confluence triggered"
  consumes:
    - type: http
      namespace: jira
      baseUri: "https://jira.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.jira_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: jira
      baseUri: "https://sap-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

Creates ticket for latency.

naftiko: "0.5"
info:
  label: "Latency Spike to Jira"
  description: "Creates ticket for latency."
  tags:
    - observability
    - devops
    - datadog
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: latency
      port: 8080
      tools:
        - name: latency-spike-to-jira
          description: "Creates ticket for latency."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "observability.get-data"
              with:
                id: "{{input_id}}"
            - name: create-issue
              type: call
              call: "jira.create-issue"
              with:
                summary: "Latency Spike to Jira"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "Latency Spike to Jira triggered"
  consumes:
    - type: http
      namespace: observability
      baseUri: "https://observability.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.observability_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: jira
      baseUri: "https://sap-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

Creates Slack channel and pages.

naftiko: "0.5"
info:
  label: "Major Incident Bridge"
  description: "Creates Slack channel and pages."
  tags:
    - itsm
    - incident-response
    - servicenow
    - pagerduty
    - slack
capability:
  exposes:
    - type: mcp
      namespace: major
      port: 8080
      tools:
        - name: major-incident-bridge
          description: "Creates Slack channel and pages."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "servicenow.get-data"
              with:
                id: "{{input_id}}"
            - name: create-record
              type: call
              call: "servicenow.create-record"
              with:
                short_description: "Major Incident Bridge"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "Major Incident Bridge triggered"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://servicenow.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: records
          path: "/table/incident"
          operations:
            - name: create-record
              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 app health from New Relic.

naftiko: "0.5"
info:
  label: "New Relic App Health"
  description: "Retrieves app health from New Relic."
  tags:
    - observability
    - new-relic
    - apm
capability:
  exposes:
    - type: mcp
      namespace: app-health
      port: 8080
      tools:
        - name: get-health
          description: "Given app name, return health."
          inputParameters:
            - name: app_name
              in: body
              type: string
              description: "App Name"
          call: newrelic.get-app
          with:
            name: "{{app_name}}"
  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"
          operations:
            - name: get-app
              method: GET

Creates Jira bug for errors.

naftiko: "0.5"
info:
  label: "New Relic Error to Jira"
  description: "Creates Jira bug for errors."
  tags:
    - observability
    - devops
    - new-relic
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: new
      port: 8080
      tools:
        - name: new-relic-error-to-jira
          description: "Creates Jira bug for errors."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "observability.get-data"
              with:
                id: "{{input_id}}"
            - name: create-issue
              type: call
              call: "jira.create-issue"
              with:
                summary: "New Relic Error to Jira"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "New Relic Error to Jira triggered"
  consumes:
    - type: http
      namespace: observability
      baseUri: "https://observability.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.observability_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: jira
      baseUri: "https://sap-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 MFA and closes ticket.

naftiko: "0.5"
info:
  label: "Okta MFA Reset with ServiceNow"
  description: "Resets MFA and closes ticket."
  tags:
    - security
    - identity
    - okta
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: okta
      port: 8080
      tools:
        - name: okta-mfa-reset-servicenow
          description: "Resets MFA and closes ticket."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "identity.get-data"
              with:
                id: "{{input_id}}"
            - name: create-record
              type: call
              call: "servicenow.create-record"
              with:
                short_description: "Okta MFA Reset with ServiceNow"
  consumes:
    - type: http
      namespace: identity
      baseUri: "https://identity.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.identity_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: records
          path: "/table/incident"
          operations:
            - name: create-record
              method: POST

Investigates and creates incident.

naftiko: "0.5"
info:
  label: "Okta Risky Login"
  description: "Investigates and creates incident."
  tags:
    - security
    - identity
    - okta
    - splunk
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: okta
      port: 8080
      tools:
        - name: okta-risky-login-investigation
          description: "Investigates and creates incident."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "identity.get-data"
              with:
                id: "{{input_id}}"
            - name: create-record
              type: call
              call: "servicenow.create-record"
              with:
                short_description: "Okta Risky Login"
  consumes:
    - type: http
      namespace: identity
      baseUri: "https://identity.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.identity_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: records
          path: "/table/incident"
          operations:
            - name: create-record
              method: POST

When an employee termination is recorded in SAP SuccessFactors, deactivates their Okta account and revokes all active Okta sessions.

naftiko: "0.5"
info:
  label: "Okta User Deprovisioning on SAP Termination"
  description: "When an employee termination is recorded in SAP SuccessFactors, deactivates their Okta account and revokes all active Okta sessions."
  tags:
    - hr
    - identity
    - security
    - sap-successfactors
    - okta
    - offboarding
capability:
  exposes:
    - type: mcp
      namespace: offboarding-ops
      port: 8080
      tools:
        - name: deprovision-terminated-employee
          description: "Given a SuccessFactors employee ID and their Okta user ID, confirm the termination in SuccessFactors, deactivate the Okta user, and clear all active sessions."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "SuccessFactors employee ID for the terminated employee."
            - name: okta_user_id
              in: body
              type: string
              description: "Okta user ID to deactivate."
          steps:
            - name: verify-termination
              type: call
              call: "sf-termination.get-employee-status"
              with:
                employeeId: "{{employee_id}}"
            - name: deactivate-okta
              type: call
              call: "okta.deactivate-user"
              with:
                userId: "{{okta_user_id}}"
            - name: clear-sessions
              type: call
              call: "okta-sessions.clear-user-sessions"
              with:
                userId: "{{okta_user_id}}"
  consumes:
    - type: http
      namespace: sf-termination
      baseUri: "https://api4.successfactors.com/odata/v2"
      authentication:
        type: bearer
        token: "$secrets.sf_token"
      resources:
        - name: employee-status
          path: "/EmpEmployment(personIdExternal='{{employeeId}}')"
          inputParameters:
            - name: employeeId
              in: path
          operations:
            - name: get-employee-status
              method: GET
    - type: http
      namespace: okta
      baseUri: "https://sap.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_token"
        placement: header
      resources:
        - name: users
          path: "/users/{{userId}}/lifecycle/deactivate"
          inputParameters:
            - name: userId
              in: path
          operations:
            - name: deactivate-user
              method: POST
    - type: http
      namespace: okta-sessions
      baseUri: "https://sap.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_token"
        placement: header
      resources:
        - name: user-sessions
          path: "/users/{{userId}}/sessions"
          inputParameters:
            - name: userId
              in: path
          operations:
            - name: clear-user-sessions
              method: DELETE

Lists Okta groups for a user.

naftiko: "0.5"
info:
  label: "Okta User Groups Lookup"
  description: "Lists Okta groups for a user."
  tags:
    - security
    - identity
    - okta
capability:
  exposes:
    - type: mcp
      namespace: identity
      port: 8080
      tools:
        - name: get-groups
          description: "Given email, return groups."
          inputParameters:
            - name: email
              in: body
              type: string
              description: "Email"
          call: okta.get-user-groups
          with:
            user_id: "{{email}}"
  consumes:
    - type: http
      namespace: okta
      baseUri: "https://sap.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "SSWS $secrets.okta_api_token"
        placement: header
      resources:
        - name: groups
          path: "/users/{{user_id}}/groups"
          operations:
            - name: get-user-groups
              method: GET

Loads invoices.

naftiko: "0.5"
info:
  label: "Oracle Invoice to Snowflake"
  description: "Loads invoices."
  tags:
    - finance
    - data
    - oracle
    - snowflake
capability:
  exposes:
    - type: mcp
      namespace: oracle
      port: 8080
      tools:
        - name: oracle-invoice-to-snowflake
          description: "Loads invoices."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "data.get-data"
              with:
                id: "{{input_id}}"
  consumes:
    - type: http
      namespace: data
      baseUri: "https://data.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.data_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET

Retrieves current on-call engineer.

naftiko: "0.5"
info:
  label: "PagerDuty On-Call Lookup"
  description: "Retrieves current on-call engineer."
  tags:
    - operations
    - pagerduty
    - incident-response
capability:
  exposes:
    - type: mcp
      namespace: ops
      port: 8080
      tools:
        - name: get-on-call
          description: "Given schedule ID, return on-call."
          inputParameters:
            - name: schedule_id
              in: body
              type: string
              description: "Schedule Id"
          call: pagerduty.get-on-call
          with:
            schedule_id: "{{schedule_id}}"
  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}}"
          operations:
            - name: get-on-call
              method: GET

Creates postmortem page.

naftiko: "0.5"
info:
  label: "PagerDuty to Confluence Postmortem"
  description: "Creates postmortem page."
  tags:
    - operations
    - documentation
    - pagerduty
    - confluence
    - slack
capability:
  exposes:
    - type: mcp
      namespace: pagerduty
      port: 8080
      tools:
        - name: pagerduty-to-confluence-postmortem
          description: "Creates postmortem page."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "pagerduty.get-data"
              with:
                id: "{{input_id}}"
            - name: create-incident
              type: call
              call: "pagerduty.create-incident"
              with:
                title: "PagerDuty to Confluence Postmortem"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "PagerDuty to Confluence Postmortem triggered"
  consumes:
    - type: http
      namespace: pagerduty
      baseUri: "https://pagerduty.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.pagerduty_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              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

Compares ADP vs Workday.

naftiko: "0.5"
info:
  label: "Payroll Audit"
  description: "Compares ADP vs Workday."
  tags:
    - hr
    - finance
    - adp
    - workday
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: payroll
      port: 8080
      tools:
        - name: payroll-audit
          description: "Compares ADP vs Workday."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "adp.get-data"
              with:
                id: "{{input_id}}"
            - name: create-record
              type: call
              call: "servicenow.create-record"
              with:
                short_description: "Payroll Audit"
  consumes:
    - type: http
      namespace: adp
      baseUri: "https://adp.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.adp_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: records
          path: "/table/incident"
          operations:
            - name: create-record
              method: POST

Refreshes and distributes.

naftiko: "0.5"
info:
  label: "Power BI Distribution"
  description: "Refreshes and distributes."
  tags:
    - analytics
    - reporting
    - power-bi
    - slack
capability:
  exposes:
    - type: mcp
      namespace: power
      port: 8080
      tools:
        - name: power-bi-distribution
          description: "Refreshes and distributes."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "analytics.get-data"
              with:
                id: "{{input_id}}"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "Power BI Distribution triggered"
  consumes:
    - type: http
      namespace: analytics
      baseUri: "https://analytics.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.analytics_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              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

Checks Power BI dataset refresh.

naftiko: "0.5"
info:
  label: "Power BI Refresh Status"
  description: "Checks Power BI dataset refresh."
  tags:
    - analytics
    - reporting
    - power-bi
capability:
  exposes:
    - type: mcp
      namespace: reporting
      port: 8080
      tools:
        - name: get-refresh
          description: "Given dataset ID, return status."
          inputParameters:
            - name: dataset_id
              in: body
              type: string
              description: "Dataset Id"
          call: powerbi.get-refresh
          with:
            dataset_id: "{{dataset_id}}"
  consumes:
    - type: http
      namespace: powerbi
      baseUri: "https://api.powerbi.com/v1.0/myorg"
      authentication:
        type: bearer
        token: "$secrets.powerbi_token"
      resources:
        - name: refreshes
          path: "/datasets/{{dataset_id}}/refreshes"
          operations:
            - name: get-refresh
              method: GET

Retrieves a SAP S/4HANA purchase order by number, returning header status, vendor details, and open line items for procurement review.

naftiko: "0.5"
info:
  label: "Purchase Order Lookup"
  description: "Retrieves a SAP S/4HANA purchase order by number, returning header status, vendor details, and open line items for procurement review."
  tags:
    - procurement
    - erp
    - sap-s4hana
capability:
  exposes:
    - type: mcp
      namespace: erp
      port: 8080
      tools:
        - name: get-purchase-order
          description: "Given a PO number, look up the SAP S/4HANA purchase order and return header status, vendor name, total value, currency, and open line items."
          inputParameters:
            - name: po_number
              in: body
              type: string
              description: "The SAP purchase order number, e.g. 4500001234."
          call: "sap-mm.get-po"
          with:
            po_number: "{{po_number}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.d.OverallStatus"
            - name: vendor
              type: string
              mapping: "$.d.Supplier.CompanyName"
            - name: total_value
              type: string
              mapping: "$.d.TotalAmount"
            - name: currency
              type: string
              mapping: "$.d.TransactionCurrency"
  consumes:
    - type: http
      namespace: sap-mm
      baseUri: "https://sap-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

Posts runbook to Slack.

naftiko: "0.5"
info:
  label: "Runbook from PagerDuty"
  description: "Posts runbook to Slack."
  tags:
    - operations
    - documentation
    - pagerduty
    - confluence
    - slack
capability:
  exposes:
    - type: mcp
      namespace: runbook
      port: 8080
      tools:
        - name: runbook-from-pagerduty
          description: "Posts runbook to Slack."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "pagerduty.get-data"
              with:
                id: "{{input_id}}"
            - name: create-incident
              type: call
              call: "pagerduty.create-incident"
              with:
                title: "Runbook from PagerDuty"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "Runbook from PagerDuty triggered"
  consumes:
    - type: http
      namespace: pagerduty
      baseUri: "https://pagerduty.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.pagerduty_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              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

Creates tasks for violations.

naftiko: "0.5"
info:
  label: "S3 Compliance Scan"
  description: "Creates tasks for violations."
  tags:
    - security
    - compliance
    - aws
    - servicenow
    - slack
capability:
  exposes:
    - type: mcp
      namespace: s3
      port: 8080
      tools:
        - name: s3-compliance-scan
          description: "Creates tasks for violations."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "aws.get-data"
              with:
                id: "{{input_id}}"
            - name: create-record
              type: call
              call: "servicenow.create-record"
              with:
                short_description: "S3 Compliance Scan"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "S3 Compliance Scan triggered"
  consumes:
    - type: http
      namespace: aws
      baseUri: "https://aws.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.aws_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: records
          path: "/table/incident"
          operations:
            - name: create-record
              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 Salesforce opportunity details.

naftiko: "0.5"
info:
  label: "Salesforce Opportunity Status"
  description: "Retrieves Salesforce opportunity details."
  tags:
    - crm
    - salesforce
    - sales
capability:
  exposes:
    - type: mcp
      namespace: crm
      port: 8080
      tools:
        - name: get-opportunity
          description: "Given ID, return stage and amount."
          inputParameters:
            - name: opp_id
              in: body
              type: string
              description: "Opp Id"
          call: salesforce.get-opportunity
          with:
            id: "{{opp_id}}"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://sap.my.salesforce.com/services/data/v59.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: opportunities
          path: "/sobjects/Opportunity/{{id}}"
          operations:
            - name: get-opportunity
              method: GET

When a Salesforce opportunity closes as won, creates a corresponding sales order in SAP S/4HANA and syncs the order number back to the Salesforce opportunity.

naftiko: "0.5"
info:
  label: "Salesforce Opportunity to SAP Sales Order"
  description: "When a Salesforce opportunity closes as won, creates a corresponding sales order in SAP S/4HANA and syncs the order number back to the Salesforce opportunity."
  tags:
    - sales
    - crm
    - erp
    - salesforce
    - sap-s4hana
    - order-management
capability:
  exposes:
    - type: mcp
      namespace: sales-ops
      port: 8080
      tools:
        - name: create-sales-order-from-opportunity
          description: "Given a Salesforce opportunity ID that has closed-won, fetch opportunity details and create a SAP S/4HANA sales order, then write the SAP order number back to Salesforce."
          inputParameters:
            - name: opportunity_id
              in: body
              type: string
              description: "Salesforce opportunity ID with Stage = Closed Won."
          steps:
            - name: get-opportunity
              type: call
              call: "salesforce-opp.get-opportunity"
              with:
                opportunityId: "{{opportunity_id}}"
            - name: create-so
              type: call
              call: "sap-sd.create-sales-order"
              with:
                soldToParty: "{{get-opportunity.AccountId}}"
                orderValue: "{{get-opportunity.Amount}}"
                currency: "{{get-opportunity.CurrencyIsoCode}}"
            - name: update-opportunity
              type: call
              call: "salesforce-update.update-opportunity"
              with:
                opportunityId: "{{opportunity_id}}"
                sapOrderNumber: "{{create-so.SalesOrder}}"
  consumes:
    - type: http
      namespace: salesforce-opp
      baseUri: "https://sap.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: opportunities
          path: "/sobjects/Opportunity/{{opportunityId}}"
          inputParameters:
            - name: opportunityId
              in: path
          operations:
            - name: get-opportunity
              method: GET
    - type: http
      namespace: sap-sd
      baseUri: "https://sap-s4.sap.com/sap/opu/odata/sap/API_SALES_ORDER_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: sales-orders
          path: "/A_SalesOrder"
          operations:
            - name: create-sales-order
              method: POST
    - type: http
      namespace: salesforce-update
      baseUri: "https://sap.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: opportunity-update
          path: "/sobjects/Opportunity/{{opportunityId}}"
          inputParameters:
            - name: opportunityId
              in: path
          operations:
            - name: update-opportunity
              method: PATCH

Creates Jira project on Closed-Won.

naftiko: "0.5"
info:
  label: "Salesforce Won to Jira Project"
  description: "Creates Jira project on Closed-Won."
  tags:
    - crm
    - devops
    - salesforce
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: salesforce
      port: 8080
      tools:
        - name: salesforce-won-to-jira-project
          description: "Creates Jira project on Closed-Won."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "salesforce.get-data"
              with:
                id: "{{input_id}}"
            - name: create-issue
              type: call
              call: "jira.create-issue"
              with:
                summary: "Salesforce Won to Jira Project"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "Salesforce Won to Jira Project triggered"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://salesforce.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: jira
      baseUri: "https://sap-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

Triggers a data model refresh for a specified SAP Analytics Cloud story and posts the completion status to a Microsoft Teams channel.

naftiko: "0.5"
info:
  label: "SAP Analytics Cloud Story Refresh"
  description: "Triggers a data model refresh for a specified SAP Analytics Cloud story and posts the completion status to a Microsoft Teams channel."
  tags:
    - analytics
    - reporting
    - sap-analytics-cloud
    - microsoft-teams
    - data-refresh
capability:
  exposes:
    - type: mcp
      namespace: analytics-ops
      port: 8080
      tools:
        - name: refresh-sac-story
          description: "Trigger a data refresh for an SAP Analytics Cloud story by model ID and notify a Teams channel when complete. Use for scheduled or on-demand BI data refreshes."
          inputParameters:
            - name: model_id
              in: body
              type: string
              description: "The SAP Analytics Cloud model ID to refresh."
            - name: teams_channel_id
              in: body
              type: string
              description: "Teams channel ID to notify on completion."
          steps:
            - name: trigger-refresh
              type: call
              call: "sac.trigger-model-refresh"
              with:
                modelId: "{{model_id}}"
            - name: notify-channel
              type: call
              call: "msteams-sac.send-channel-message"
              with:
                channelId: "{{teams_channel_id}}"
                text: "SAC model {{model_id}} refresh triggered. Job ID: {{trigger-refresh.jobId}}. Status: {{trigger-refresh.status}}"
  consumes:
    - type: http
      namespace: sac
      baseUri: "https://sap-analytics.cloud.sap/api/v1"
      authentication:
        type: bearer
        token: "$secrets.sac_token"
      resources:
        - name: model-refresh
          path: "/models/{{modelId}}/refresh"
          inputParameters:
            - name: modelId
              in: path
          operations:
            - name: trigger-model-refresh
              method: POST
    - type: http
      namespace: msteams-sac
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{teamId}}/channels/{{channelId}}/messages"
          inputParameters:
            - name: channelId
              in: path
          operations:
            - name: send-channel-message
              method: POST

Queries SAP Ariba for contracts expiring within a configurable window and sends expiry alerts to contract owners via Microsoft Teams.

naftiko: "0.5"
info:
  label: "SAP Ariba Contract Expiry Notification"
  description: "Queries SAP Ariba for contracts expiring within a configurable window and sends expiry alerts to contract owners via Microsoft Teams."
  tags:
    - procurement
    - contract-management
    - sap-ariba
    - microsoft-teams
    - monitoring
capability:
  exposes:
    - type: mcp
      namespace: contract-ops
      port: 8080
      tools:
        - name: notify-expiring-contracts
          description: "Query Ariba Contracts for agreements expiring within a given number of days and send a Teams notification to each contract owner. Use for automated contract renewal management."
          inputParameters:
            - name: days_to_expiry
              in: body
              type: integer
              description: "Number of days ahead to check for expiring contracts."
          steps:
            - name: get-contracts
              type: call
              call: "ariba-contracts.get-expiring-contracts"
              with:
                daysToExpiry: "{{days_to_expiry}}"
            - name: notify-owner
              type: call
              call: "msteams-contracts.send-message"
              with:
                recipient_upn: "{{get-contracts.ownerEmail}}"
                text: "Contract {{get-contracts.contractId}} ({{get-contracts.supplierName}}) expires on {{get-contracts.expiryDate}}. Please initiate renewal."
  consumes:
    - type: http
      namespace: ariba-contracts
      baseUri: "https://openapi.ariba.com/api/contract-management/v1"
      authentication:
        type: bearer
        token: "$secrets.ariba_token"
      resources:
        - name: contracts
          path: "/contracts"
          inputParameters:
            - name: daysToExpiry
              in: query
          operations:
            - name: get-expiring-contracts
              method: GET
    - type: http
      namespace: msteams-contracts
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: messages
          path: "/users/{{recipient_upn}}/sendMail"
          inputParameters:
            - name: recipient_upn
              in: path
          operations:
            - name: send-message
              method: POST

Polls SAP Ariba for sourcing events nearing deadline and creates reminder tasks in Jira for the procurement team.

naftiko: "0.5"
info:
  label: "SAP Ariba Sourcing Event Monitor"
  description: "Polls SAP Ariba for sourcing events nearing deadline and creates reminder tasks in Jira for the procurement team."
  tags:
    - procurement
    - sourcing
    - sap-ariba
    - jira
    - monitoring
capability:
  exposes:
    - type: mcp
      namespace: sourcing-ops
      port: 8080
      tools:
        - name: monitor-sourcing-deadlines
          description: "Query Ariba for open sourcing events with deadlines within a given number of days and create Jira reminder tasks for each. Use for automated procurement deadline tracking."
          inputParameters:
            - name: days_ahead
              in: body
              type: integer
              description: "Number of days ahead to look for upcoming sourcing deadlines."
            - name: jira_project_key
              in: body
              type: string
              description: "Jira project key for creating reminder tasks."
          steps:
            - name: get-events
              type: call
              call: "ariba-sourcing.get-sourcing-events"
              with:
                daysAhead: "{{days_ahead}}"
            - name: create-reminders
              type: call
              call: "jira-procurement.create-issue"
              with:
                project_key: "{{jira_project_key}}"
                issuetype: "Task"
                summary: "Sourcing deadline reminder: {{get-events.eventTitle}}"
                description: "Ariba event {{get-events.eventId}} closes on {{get-events.deadline}}."
  consumes:
    - type: http
      namespace: ariba-sourcing
      baseUri: "https://openapi.ariba.com/api/sourcing-projects/v1"
      authentication:
        type: bearer
        token: "$secrets.ariba_token"
      resources:
        - name: sourcing-events
          path: "/events"
          inputParameters:
            - name: daysAhead
              in: query
          operations:
            - name: get-sourcing-events
              method: GET
    - type: http
      namespace: jira-procurement
      baseUri: "https://sap.atlassian.net/rest/api/3"
      authentication:
        type: bearer
        token: "$secrets.jira_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST

Exports SAP S/4HANA audit log entries for a given date range to a Snowflake compliance table and notifies the security team via Microsoft Teams.

naftiko: "0.5"
info:
  label: "SAP Audit Log Compliance Export"
  description: "Exports SAP S/4HANA audit log entries for a given date range to a Snowflake compliance table and notifies the security team via Microsoft Teams."
  tags:
    - security
    - compliance
    - sap-s4hana
    - snowflake
    - microsoft-teams
    - audit
capability:
  exposes:
    - type: mcp
      namespace: compliance-ops
      port: 8080
      tools:
        - name: export-audit-logs
          description: "Export SAP S/4HANA audit log entries for a date range, insert them into a Snowflake compliance table, and notify the security team in Teams."
          inputParameters:
            - name: start_date
              in: body
              type: string
              description: "Start date for audit log export in YYYY-MM-DD format."
            - name: end_date
              in: body
              type: string
              description: "End date for audit log export in YYYY-MM-DD format."
            - name: snowflake_table
              in: body
              type: string
              description: "Fully qualified Snowflake table name to insert audit records."
            - name: teams_channel_id
              in: body
              type: string
              description: "Teams channel ID to notify on export completion."
          steps:
            - name: get-audit-logs
              type: call
              call: "sap-audit.get-audit-logs"
              with:
                startDate: "{{start_date}}"
                endDate: "{{end_date}}"
            - name: insert-snowflake
              type: call
              call: "snowflake-compliance.insert-rows"
              with:
                tableName: "{{snowflake_table}}"
                rows: "{{get-audit-logs.entries}}"
            - name: notify-security
              type: call
              call: "msteams-audit.send-channel-message"
              with:
                channelId: "{{teams_channel_id}}"
                text: "SAP audit log export complete. Records: {{get-audit-logs.count}}. Snowflake table: {{snowflake_table}}. Period: {{start_date}} to {{end_date}}"
  consumes:
    - type: http
      namespace: sap-audit
      baseUri: "https://sap-s4.sap.com/sap/opu/odata/sap/AUDITLOG_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: audit-logs
          path: "/AuditLogEntries"
          inputParameters:
            - name: startDate
              in: query
            - name: endDate
              in: query
          operations:
            - name: get-audit-logs
              method: GET
    - type: http
      namespace: snowflake-compliance
      baseUri: "https://sap.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: table-rows
          path: "/statements"
          operations:
            - name: insert-rows
              method: POST
    - type: http
      namespace: msteams-audit
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{teamId}}/channels/{{channelId}}/messages"
          inputParameters:
            - name: channelId
              in: path
          operations:
            - name: send-channel-message
              method: POST

Monitors SAP Business Technology Platform job runs and, on failure, opens a Jira incident and posts an alert to a Microsoft Teams channel.

naftiko: "0.5"
info:
  label: "SAP BTP Job Failure Alert"
  description: "Monitors SAP Business Technology Platform job runs and, on failure, opens a Jira incident and posts an alert to a Microsoft Teams channel."
  tags:
    - devops
    - monitoring
    - sap-btp
    - jira
    - microsoft-teams
    - incident-response
capability:
  exposes:
    - type: mcp
      namespace: btp-ops
      port: 8080
      tools:
        - name: handle-btp-job-failure
          description: "Given a failed BTP job run ID, retrieve job details, open a Jira incident, and alert the ops channel in Microsoft Teams."
          inputParameters:
            - name: job_id
              in: body
              type: string
              description: "The SAP BTP job scheduler job ID that failed."
            - name: run_id
              in: body
              type: string
              description: "The specific run ID of the failed job execution."
            - name: teams_channel_id
              in: body
              type: string
              description: "Microsoft Teams channel ID to post the alert to."
          steps:
            - name: get-job-run
              type: call
              call: "sap-btp.get-job-run"
              with:
                jobId: "{{job_id}}"
                runId: "{{run_id}}"
            - name: create-incident
              type: call
              call: "jira-ops.create-issue"
              with:
                project_key: "OPS"
                issuetype: "Bug"
                summary: "BTP job failure: {{job_id}} run {{run_id}}"
                description: "Job: {{get-job-run.jobName}}\nStatus: {{get-job-run.status}}\nError: {{get-job-run.errorMessage}}"
            - name: alert-teams
              type: call
              call: "msteams-btp.send-channel-message"
              with:
                channelId: "{{teams_channel_id}}"
                text: "BTP Job Failed: {{job_id}} | Run: {{run_id}} | Jira: {{create-incident.key}}"
  consumes:
    - type: http
      namespace: sap-btp
      baseUri: "https://jobscheduler.cfapps.sap.hana.ondemand.com/scheduler/jobs"
      authentication:
        type: bearer
        token: "$secrets.btp_token"
      resources:
        - name: job-runs
          path: "/{{jobId}}/runs/{{runId}}"
          inputParameters:
            - name: jobId
              in: path
            - name: runId
              in: path
          operations:
            - name: get-job-run
              method: GET
    - type: http
      namespace: jira-ops
      baseUri: "https://sap.atlassian.net/rest/api/3"
      authentication:
        type: bearer
        token: "$secrets.jira_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: msteams-btp
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{teamId}}/channels/{{channelId}}/messages"
          inputParameters:
            - name: channelId
              in: path
          operations:
            - name: send-channel-message
              method: POST

Queries Datadog for SAP BTP resource cost spikes, summarizes anomalies using OpenAI, and creates a Jira cost-review ticket with the AI summary.

naftiko: "0.5"
info:
  label: "SAP Cloud Cost Anomaly Detection"
  description: "Queries Datadog for SAP BTP resource cost spikes, summarizes anomalies using OpenAI, and creates a Jira cost-review ticket with the AI summary."
  tags:
    - cloud
    - cost-management
    - datadog
    - openai
    - sap-btp
    - jira
    - ai
capability:
  exposes:
    - type: mcp
      namespace: cost-anomaly
      port: 8080
      tools:
        - name: detect-cloud-cost-anomaly
          description: "Query Datadog metrics for BTP cost anomalies over a time window, generate a human-readable summary with OpenAI, and open a Jira ticket for finance review."
          inputParameters:
            - name: time_window_hours
              in: body
              type: integer
              description: "Hours of historical cost data to analyze for anomalies."
            - name: jira_project_key
              in: body
              type: string
              description: "Jira project key for the cost-review ticket."
          steps:
            - name: get-cost-metrics
              type: call
              call: "datadog-cost.query-metrics"
              with:
                query: "sum:btp.cost.total{*}"
                hours: "{{time_window_hours}}"
            - name: summarize-anomalies
              type: call
              call: "openai-cost.summarize-anomalies"
              with:
                metricsData: "{{get-cost-metrics.series}}"
            - name: create-review-ticket
              type: call
              call: "jira-cost.create-issue"
              with:
                project_key: "{{jira_project_key}}"
                issuetype: "Task"
                summary: "BTP cost anomaly detected — review required"
                description: "{{summarize-anomalies.summary}}"
  consumes:
    - type: http
      namespace: datadog-cost
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: metrics
          path: "/query"
          inputParameters:
            - name: query
              in: query
            - name: hours
              in: query
          operations:
            - name: query-metrics
              method: GET
    - type: http
      namespace: openai-cost
      baseUri: "https://api.openai.com/v1"
      authentication:
        type: bearer
        token: "$secrets.openai_token"
      resources:
        - name: chat-completions
          path: "/chat/completions"
          operations:
            - name: summarize-anomalies
              method: POST
    - type: http
      namespace: jira-cost
      baseUri: "https://sap.atlassian.net/rest/api/3"
      authentication:
        type: bearer
        token: "$secrets.jira_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST

Retrieves pending expense reports from SAP Concur, submits an approval decision, and posts a summary to the approver's Microsoft Teams channel.

naftiko: "0.5"
info:
  label: "SAP Concur Expense Report Approval"
  description: "Retrieves pending expense reports from SAP Concur, submits an approval decision, and posts a summary to the approver's Microsoft Teams channel."
  tags:
    - finance
    - expense-management
    - sap-concur
    - microsoft-teams
    - approval
capability:
  exposes:
    - type: mcp
      namespace: expense-ops
      port: 8080
      tools:
        - name: approve-expense-report
          description: "Given a Concur expense report ID and approval decision, post the decision to Concur and notify the approver in Teams. Use when an agent needs to automate the expense approval loop."
          inputParameters:
            - name: report_id
              in: body
              type: string
              description: "The SAP Concur expense report ID."
            - name: decision
              in: body
              type: string
              description: "Approval action: 'approve' or 'send_back'."
            - name: approver_upn
              in: body
              type: string
              description: "UPN of the approver to notify in Teams."
          steps:
            - name: get-report
              type: call
              call: "concur.get-expense-report"
              with:
                reportId: "{{report_id}}"
            - name: post-decision
              type: call
              call: "concur.approve-report"
              with:
                reportId: "{{report_id}}"
                action: "{{decision}}"
            - name: notify-teams
              type: call
              call: "msteams-notify.send-message"
              with:
                recipient_upn: "{{approver_upn}}"
                text: "Expense report {{report_id}} ({{get-report.name}}, {{get-report.total}}) has been {{decision}}d."
  consumes:
    - type: http
      namespace: concur
      baseUri: "https://www.concursolutions.com/api/v3.0"
      authentication:
        type: bearer
        token: "$secrets.concur_token"
      resources:
        - name: expense-reports
          path: "/expense/reportdigests/{{reportId}}"
          inputParameters:
            - name: reportId
              in: path
          operations:
            - name: get-expense-report
              method: GET
        - name: expense-approvals
          path: "/expense/reports/{{reportId}}/approve"
          inputParameters:
            - name: reportId
              in: path
          operations:
            - name: approve-report
              method: POST
    - type: http
      namespace: msteams-notify
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: messages
          path: "/users/{{recipient_upn}}/sendMail"
          inputParameters:
            - name: recipient_upn
              in: path
          operations:
            - name: send-message
              method: POST

Accepts a receipt image URL, submits it to an AI model for OCR and category extraction, and creates a SAP Concur quick expense entry.

naftiko: "0.5"
info:
  label: "SAP Concur Receipt OCR and Categorization"
  description: "Accepts a receipt image URL, submits it to an AI model for OCR and category extraction, and creates a SAP Concur quick expense entry."
  tags:
    - finance
    - ai
    - sap-concur
    - openai
    - expense-management
capability:
  exposes:
    - type: mcp
      namespace: expense-ai
      port: 8080
      tools:
        - name: process-receipt
          description: "Given a receipt image URL, use OpenAI vision to extract vendor, amount, date, and category, then create a Concur quick expense. Use for automated receipt processing from email or mobile captures."
          inputParameters:
            - name: receipt_image_url
              in: body
              type: string
              description: "Public URL to the receipt image (JPEG or PNG)."
            - name: employee_login
              in: body
              type: string
              description: "SAP Concur login ID of the employee submitting the expense."
          steps:
            - name: ocr-receipt
              type: call
              call: "openai.extract-receipt"
              with:
                imageUrl: "{{receipt_image_url}}"
            - name: create-expense
              type: call
              call: "concur-expense.create-quick-expense"
              with:
                loginId: "{{employee_login}}"
                vendor: "{{ocr-receipt.vendor}}"
                amount: "{{ocr-receipt.amount}}"
                expenseDate: "{{ocr-receipt.date}}"
                expenseCategory: "{{ocr-receipt.category}}"
  consumes:
    - type: http
      namespace: openai
      baseUri: "https://api.openai.com/v1"
      authentication:
        type: bearer
        token: "$secrets.openai_token"
      resources:
        - name: chat-completions
          path: "/chat/completions"
          operations:
            - name: extract-receipt
              method: POST
    - type: http
      namespace: concur-expense
      baseUri: "https://www.concursolutions.com/api/v3.0"
      authentication:
        type: bearer
        token: "$secrets.concur_token"
      resources:
        - name: quick-expenses
          path: "/expense/quickexpenses"
          operations:
            - name: create-quick-expense
              method: POST

Retrieves a pending travel request from SAP Concur, applies the policy check result, and notifies the traveler of the approval decision via Microsoft Teams.

naftiko: "0.5"
info:
  label: "SAP Concur Travel Booking Approval"
  description: "Retrieves a pending travel request from SAP Concur, applies the policy check result, and notifies the traveler of the approval decision via Microsoft Teams."
  tags:
    - finance
    - travel
    - sap-concur
    - microsoft-teams
    - approval
capability:
  exposes:
    - type: mcp
      namespace: travel-ops
      port: 8080
      tools:
        - name: approve-travel-request
          description: "Given a Concur travel request ID and approval decision, post the decision to Concur and notify the traveler in Teams. Use for automating travel approval workflows."
          inputParameters:
            - name: request_id
              in: body
              type: string
              description: "SAP Concur travel request ID."
            - name: decision
              in: body
              type: string
              description: "Approval decision: 'approve' or 'reject'."
            - name: traveler_upn
              in: body
              type: string
              description: "UPN of the traveler to notify."
          steps:
            - name: get-request
              type: call
              call: "concur-travel.get-travel-request"
              with:
                requestId: "{{request_id}}"
            - name: post-decision
              type: call
              call: "concur-travel.approve-travel-request"
              with:
                requestId: "{{request_id}}"
                decision: "{{decision}}"
            - name: notify-traveler
              type: call
              call: "msteams-travel.send-message"
              with:
                recipient_upn: "{{traveler_upn}}"
                text: "Your travel request {{request_id}} ({{get-request.name}}) has been {{decision}}d. Estimated cost: {{get-request.totalApprovedAmount}}"
  consumes:
    - type: http
      namespace: concur-travel
      baseUri: "https://www.concursolutions.com/api/v3.0"
      authentication:
        type: bearer
        token: "$secrets.concur_token"
      resources:
        - name: travel-requests
          path: "/travelrequest/requests/{{requestId}}"
          inputParameters:
            - name: requestId
              in: path
          operations:
            - name: get-travel-request
              method: GET
            - name: approve-travel-request
              method: POST
    - type: http
      namespace: msteams-travel
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: messages
          path: "/users/{{recipient_upn}}/sendMail"
          inputParameters:
            - name: recipient_upn
              in: path
          operations:
            - name: send-message
              method: POST

Updates with delivery status.

naftiko: "0.5"
info:
  label: "SAP Delivery to Salesforce"
  description: "Updates with delivery status."
  tags:
    - erp
    - crm
    - sap
    - salesforce
capability:
  exposes:
    - type: mcp
      namespace: sap
      port: 8080
      tools:
        - name: sap-delivery-to-salesforce
          description: "Updates with delivery status."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "erp.get-data"
              with:
                id: "{{input_id}}"
  consumes:
    - type: http
      namespace: erp
      baseUri: "https://erp.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.erp_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET

When a new contingent worker is approved in SAP Fieldglass, provisions their Microsoft Entra ID guest account and opens a ServiceNow onboarding task.

naftiko: "0.5"
info:
  label: "SAP Fieldglass Contingent Worker Onboarding"
  description: "When a new contingent worker is approved in SAP Fieldglass, provisions their Microsoft Entra ID guest account and opens a ServiceNow onboarding task."
  tags:
    - hr
    - contingent-workforce
    - sap-fieldglass
    - microsoft-entra
    - servicenow
    - onboarding
capability:
  exposes:
    - type: mcp
      namespace: contingent-hr
      port: 8080
      tools:
        - name: onboard-contingent-worker
          description: "Given a Fieldglass work order ID for an approved contingent worker, create an Entra guest account and a ServiceNow onboarding task. Use when automating external worker provisioning."
          inputParameters:
            - name: work_order_id
              in: body
              type: string
              description: "The SAP Fieldglass work order ID for the approved contingent worker."
          steps:
            - name: get-work-order
              type: call
              call: "fieldglass.get-work-order"
              with:
                workOrderId: "{{work_order_id}}"
            - name: create-guest
              type: call
              call: "entra-guest.create-guest-user"
              with:
                displayName: "{{get-work-order.workerName}}"
                email: "{{get-work-order.workerEmail}}"
            - name: create-onboarding-task
              type: call
              call: "servicenow-fg.create-ticket"
              with:
                short_description: "Contingent worker onboarding: {{get-work-order.workerName}}"
                category: "contingent_onboarding"
                assignment_group: "IT_Procurement"
  consumes:
    - type: http
      namespace: fieldglass
      baseUri: "https://www.fieldglass.net/api/v1"
      authentication:
        type: bearer
        token: "$secrets.fieldglass_token"
      resources:
        - name: work-orders
          path: "/workorders/{{workOrderId}}"
          inputParameters:
            - name: workOrderId
              in: path
          operations:
            - name: get-work-order
              method: GET
    - type: http
      namespace: entra-guest
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: guest-invitations
          path: "/invitations"
          operations:
            - name: create-guest-user
              method: POST
    - type: http
      namespace: servicenow-fg
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/sc_task"
          operations:
            - name: create-ticket
              method: POST

Submits a scanned document to SAP Document Information Extraction (DIE), extracts structured fields, and creates a Jira task with the extracted metadata for review.

naftiko: "0.5"
info:
  label: "SAP Intelligent Document Processing Intake"
  description: "Submits a scanned document to SAP Document Information Extraction (DIE), extracts structured fields, and creates a Jira task with the extracted metadata for review."
  tags:
    - ai
    - document-processing
    - sap-die
    - jira
    - automation
capability:
  exposes:
    - type: mcp
      namespace: doc-processing
      port: 8080
      tools:
        - name: process-document
          description: "Submit a document URL to SAP Document Information Extraction for field extraction (vendor, amount, dates), then create a Jira task for human review of the extracted data."
          inputParameters:
            - name: document_url
              in: body
              type: string
              description: "URL to the document to process (PDF or image)."
            - name: document_type
              in: body
              type: string
              description: "SAP DIE document type, e.g. invoice, purchase_order."
            - name: jira_project_key
              in: body
              type: string
              description: "Jira project key for the review task."
          steps:
            - name: submit-document
              type: call
              call: "sap-die.submit-document"
              with:
                documentUrl: "{{document_url}}"
                documentType: "{{document_type}}"
            - name: get-extraction
              type: call
              call: "sap-die.get-extraction-result"
              with:
                jobId: "{{submit-document.jobId}}"
            - name: create-review-task
              type: call
              call: "jira-doc.create-issue"
              with:
                project_key: "{{jira_project_key}}"
                issuetype: "Task"
                summary: "Document extraction review: {{document_type}}"
                description: "Extracted vendor: {{get-extraction.vendor}}\nAmount: {{get-extraction.amount}}\nDate: {{get-extraction.documentDate}}\nJob ID: {{submit-document.jobId}}"
  consumes:
    - type: http
      namespace: sap-die
      baseUri: "https://aiservices.cfapps.sap.hana.ondemand.com/document-information-extraction/v1"
      authentication:
        type: bearer
        token: "$secrets.sap_die_token"
      resources:
        - name: document-jobs
          path: "/document/jobs"
          operations:
            - name: submit-document
              method: POST
        - name: extraction-results
          path: "/document/jobs/{{jobId}}"
          inputParameters:
            - name: jobId
              in: path
          operations:
            - name: get-extraction-result
              method: GET
    - type: http
      namespace: jira-doc
      baseUri: "https://sap.atlassian.net/rest/api/3"
      authentication:
        type: bearer
        token: "$secrets.jira_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST

Posts a goods receipt in SAP S/4HANA for an incoming delivery and updates the corresponding Ariba purchase order status.

naftiko: "0.5"
info:
  label: "SAP Materials Management Goods Receipt"
  description: "Posts a goods receipt in SAP S/4HANA for an incoming delivery and updates the corresponding Ariba purchase order status."
  tags:
    - procurement
    - supply-chain
    - sap-s4hana
    - sap-ariba
    - goods-receipt
capability:
  exposes:
    - type: mcp
      namespace: supply-chain-ops
      port: 8080
      tools:
        - name: post-goods-receipt
          description: "Given a delivery number and PO number, post a goods receipt in SAP S/4HANA Materials Management and update the Ariba PO status to received."
          inputParameters:
            - name: delivery_number
              in: body
              type: string
              description: "SAP inbound delivery number."
            - name: po_number
              in: body
              type: string
              description: "Ariba purchase order number to update."
          steps:
            - name: post-gr
              type: call
              call: "sap-mm-gr.post-goods-receipt"
              with:
                deliveryNumber: "{{delivery_number}}"
            - name: update-ariba-po
              type: call
              call: "ariba-po.update-po-status"
              with:
                poNumber: "{{po_number}}"
                status: "received"
                materialDocNumber: "{{post-gr.materialDocument}}"
  consumes:
    - type: http
      namespace: sap-mm-gr
      baseUri: "https://sap-s4.sap.com/sap/opu/odata/sap/API_MATERIAL_DOCUMENT_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: goods-receipts
          path: "/A_MaterialDocumentHeader"
          operations:
            - name: post-goods-receipt
              method: POST
    - type: http
      namespace: ariba-po
      baseUri: "https://openapi.ariba.com/api/purchase-orders/v2"
      authentication:
        type: bearer
        token: "$secrets.ariba_token"
      resources:
        - name: po-status
          path: "/orders/{{poNumber}}/status"
          inputParameters:
            - name: poNumber
              in: path
          operations:
            - name: update-po-status
              method: PATCH

Retrieves the status of a running SAP payroll process for a given payroll area and notifies HR via Microsoft Teams when complete or if errors occur.

naftiko: "0.5"
info:
  label: "SAP Payroll Run Status Check"
  description: "Retrieves the status of a running SAP payroll process for a given payroll area and notifies HR via Microsoft Teams when complete or if errors occur."
  tags:
    - hr
    - payroll
    - sap-successfactors
    - microsoft-teams
    - monitoring
capability:
  exposes:
    - type: mcp
      namespace: payroll-monitoring
      port: 8080
      tools:
        - name: check-payroll-run-status
          description: "Given a SAP payroll area and period, fetch the payroll run status from SuccessFactors EC Payroll and post the result to the HR Teams channel."
          inputParameters:
            - name: payroll_area
              in: body
              type: string
              description: "SAP payroll area code, e.g. A1 for monthly US payroll."
            - name: pay_period
              in: body
              type: string
              description: "Pay period in YYYYMM format, e.g. 202603."
            - name: hr_channel_id
              in: body
              type: string
              description: "Teams channel ID for the HR payroll notification."
          steps:
            - name: get-payroll-status
              type: call
              call: "sf-payroll.get-payroll-run"
              with:
                payrollArea: "{{payroll_area}}"
                payPeriod: "{{pay_period}}"
            - name: notify-hr
              type: call
              call: "msteams-payroll.send-channel-message"
              with:
                channelId: "{{hr_channel_id}}"
                text: "Payroll run for area {{payroll_area}}, period {{pay_period}}: Status={{get-payroll-status.status}}, Errors={{get-payroll-status.errorCount}}, Employees={{get-payroll-status.employeeCount}}"
  consumes:
    - type: http
      namespace: sf-payroll
      baseUri: "https://api4.successfactors.com/odata/v2"
      authentication:
        type: bearer
        token: "$secrets.sf_token"
      resources:
        - name: payroll-runs
          path: "/PayrollRun"
          inputParameters:
            - name: payrollArea
              in: query
            - name: payPeriod
              in: query
          operations:
            - name: get-payroll-run
              method: GET
    - type: http
      namespace: msteams-payroll
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{teamId}}/channels/{{channelId}}/messages"
          inputParameters:
            - name: channelId
              in: path
          operations:
            - name: send-channel-message
              method: POST

Creates a SAP PM work order for an equipment breakdown reported via ServiceNow, assigns a technician, and notifies the maintenance team in Microsoft Teams.

naftiko: "0.5"
info:
  label: "SAP Plant Maintenance Work Order Creation"
  description: "Creates a SAP PM work order for an equipment breakdown reported via ServiceNow, assigns a technician, and notifies the maintenance team in Microsoft Teams."
  tags:
    - manufacturing
    - itsm
    - sap-pm
    - servicenow
    - microsoft-teams
    - maintenance
capability:
  exposes:
    - type: mcp
      namespace: maintenance-ops
      port: 8080
      tools:
        - name: create-work-order-from-incident
          description: "Given a ServiceNow incident ID for equipment failure, read the incident, create a SAP PM work order, and alert the maintenance team channel in Teams."
          inputParameters:
            - name: snow_incident_id
              in: body
              type: string
              description: "ServiceNow incident sys_id for the equipment breakdown."
            - name: equipment_number
              in: body
              type: string
              description: "SAP equipment number for the asset requiring maintenance."
            - name: teams_channel_id
              in: body
              type: string
              description: "Teams channel ID for the maintenance team notification."
          steps:
            - name: get-incident
              type: call
              call: "servicenow-pm.get-incident"
              with:
                incidentId: "{{snow_incident_id}}"
            - name: create-work-order
              type: call
              call: "sap-pm.create-work-order"
              with:
                equipment: "{{equipment_number}}"
                description: "{{get-incident.short_description}}"
                priority: "{{get-incident.priority}}"
            - name: notify-maintenance
              type: call
              call: "msteams-maint.send-channel-message"
              with:
                channelId: "{{teams_channel_id}}"
                text: "New PM work order {{create-work-order.WorkOrder}} created for equipment {{equipment_number}}. Incident: {{snow_incident_id}}"
  consumes:
    - type: http
      namespace: servicenow-pm
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.snow_user"
        password: "$secrets.snow_password"
      resources:
        - name: incidents
          path: "/table/incident/{{incidentId}}"
          inputParameters:
            - name: incidentId
              in: path
          operations:
            - name: get-incident
              method: GET
    - type: http
      namespace: sap-pm
      baseUri: "https://sap-s4.sap.com/sap/opu/odata/sap/API_MAINTENANCEORDER_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: maintenance-orders
          path: "/MaintenanceOrder"
          operations:
            - name: create-work-order
              method: POST
    - type: http
      namespace: msteams-maint
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{teamId}}/channels/{{channelId}}/messages"
          inputParameters:
            - name: channelId
              in: path
          operations:
            - name: send-channel-message
              method: POST

Fetches open production orders from SAP S/4HANA PP module and publishes a daily status digest to a SharePoint list for plant operations.

naftiko: "0.5"
info:
  label: "SAP Production Order Status Digest"
  description: "Fetches open production orders from SAP S/4HANA PP module and publishes a daily status digest to a SharePoint list for plant operations."
  tags:
    - manufacturing
    - erp
    - sap-s4hana
    - sharepoint
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: manufacturing-reporting
      port: 8080
      tools:
        - name: digest-production-orders
          description: "Fetch all open production orders for a given plant from SAP S/4HANA and write the status digest to a SharePoint list. Use for daily manufacturing status reporting."
          inputParameters:
            - name: plant
              in: body
              type: string
              description: "SAP plant code, e.g. 1000."
            - name: sharepoint_site_id
              in: body
              type: string
              description: "SharePoint site ID where the digest list resides."
            - name: list_id
              in: body
              type: string
              description: "SharePoint list ID to write digest items to."
          steps:
            - name: get-orders
              type: call
              call: "sap-pp.get-production-orders"
              with:
                Plant: "{{plant}}"
                SystemStatus: "REL"
            - name: write-digest
              type: call
              call: "sharepoint-mfg.create-list-item"
              with:
                siteId: "{{sharepoint_site_id}}"
                listId: "{{list_id}}"
                orderData: "{{get-orders.value}}"
  consumes:
    - type: http
      namespace: sap-pp
      baseUri: "https://sap-s4.sap.com/sap/opu/odata/sap/API_PRODUCTION_ORDER_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: production-orders
          path: "/A_ProductionOrder"
          inputParameters:
            - name: Plant
              in: query
            - name: SystemStatus
              in: query
          operations:
            - name: get-production-orders
              method: GET
    - type: http
      namespace: sharepoint-mfg
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: list-items
          path: "/sites/{{siteId}}/lists/{{listId}}/items"
          inputParameters:
            - name: siteId
              in: path
            - name: listId
              in: path
          operations:
            - name: create-list-item
              method: POST

Retrieves SAP PO status.

naftiko: "0.5"
info:
  label: "SAP Purchase Order Status"
  description: "Retrieves SAP PO status."
  tags:
    - finance
    - sap
    - procurement
capability:
  exposes:
    - type: mcp
      namespace: erp
      port: 8080
      tools:
        - name: get-po
          description: "Given PO number, return status."
          inputParameters:
            - name: po_number
              in: body
              type: string
              description: "Po Number"
          call: sap.get-po
          with:
            po_number: "{{po_number}}"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://sap-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: pos
          path: "/A_PurchaseOrder('{{po_number}}')"
          operations:
            - name: get-po
              method: GET

When a Qualtrics NPS survey response is submitted for a customer account, fetches the response, updates the Salesforce account NPS score, and logs the feedback in a Jira customer-success ticket.

naftiko: "0.5"
info:
  label: "SAP Qualtrics Survey Response to CRM"
  description: "When a Qualtrics NPS survey response is submitted for a customer account, fetches the response, updates the Salesforce account NPS score, and logs the feedback in a Jira customer-success ticket."
  tags:
    - crm
    - customer-success
    - qualtrics
    - salesforce
    - jira
    - nps
capability:
  exposes:
    - type: mcp
      namespace: cx-feedback
      port: 8080
      tools:
        - name: process-nps-response
          description: "Given a Qualtrics survey response ID and Salesforce account ID, fetch the NPS response, update the Salesforce account score, and log feedback in Jira. Use for closing the NPS feedback loop."
          inputParameters:
            - name: response_id
              in: body
              type: string
              description: "Qualtrics survey response ID."
            - name: survey_id
              in: body
              type: string
              description: "Qualtrics survey ID the response belongs to."
            - name: salesforce_account_id
              in: body
              type: string
              description: "Salesforce account ID to update with the NPS score."
          steps:
            - name: get-response
              type: call
              call: "qualtrics.get-response"
              with:
                surveyId: "{{survey_id}}"
                responseId: "{{response_id}}"
            - name: update-sf-nps
              type: call
              call: "salesforce-nps.update-account"
              with:
                accountId: "{{salesforce_account_id}}"
                npsScore: "{{get-response.npsScore}}"
                verbatim: "{{get-response.verbatim}}"
            - name: log-feedback
              type: call
              call: "jira-cx.create-issue"
              with:
                project_key: "CS"
                issuetype: "Task"
                summary: "NPS feedback received: score {{get-response.npsScore}}"
                description: "Account: {{salesforce_account_id}}\nScore: {{get-response.npsScore}}\nFeedback: {{get-response.verbatim}}"
  consumes:
    - type: http
      namespace: qualtrics
      baseUri: "https://sap.qualtrics.com/API/v3"
      authentication:
        type: apikey
        key: "X-API-TOKEN"
        value: "$secrets.qualtrics_token"
        placement: header
      resources:
        - name: survey-responses
          path: "/surveys/{{surveyId}}/responses/{{responseId}}"
          inputParameters:
            - name: surveyId
              in: path
            - name: responseId
              in: path
          operations:
            - name: get-response
              method: GET
    - type: http
      namespace: salesforce-nps
      baseUri: "https://sap.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: account-nps
          path: "/sobjects/Account/{{accountId}}"
          inputParameters:
            - name: accountId
              in: path
          operations:
            - name: update-account
              method: PATCH
    - type: http
      namespace: jira-cx
      baseUri: "https://sap.atlassian.net/rest/api/3"
      authentication:
        type: bearer
        token: "$secrets.jira_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST

Retrieves general ledger account balances for a given company code and fiscal period from SAP S/4HANA for finance period-close review.

naftiko: "0.5"
info:
  label: "SAP S/4HANA GL Account Balance Lookup"
  description: "Retrieves general ledger account balances for a given company code and fiscal period from SAP S/4HANA for finance period-close review."
  tags:
    - finance
    - erp
    - sap-s4hana
    - period-close
capability:
  exposes:
    - type: mcp
      namespace: finance-gl
      port: 8080
      tools:
        - name: get-gl-balance
          description: "Given a company code, GL account, and fiscal year/period, return the debit balance, credit balance, and net balance from SAP S/4HANA."
          inputParameters:
            - name: company_code
              in: body
              type: string
              description: "SAP company code, e.g. 1000."
            - name: gl_account
              in: body
              type: string
              description: "General ledger account number."
            - name: fiscal_year
              in: body
              type: string
              description: "Fiscal year, e.g. 2026."
            - name: fiscal_period
              in: body
              type: string
              description: "Fiscal period number, e.g. 03 for March."
          call: "sap-gl.get-gl-balance"
          with:
            CompanyCode: "{{company_code}}"
            GLAccount: "{{gl_account}}"
            FiscalYear: "{{fiscal_year}}"
            FiscalPeriod: "{{fiscal_period}}"
          outputParameters:
            - name: debit_balance
              type: string
              mapping: "$.d.DebitAmountInCoCodeCrcy"
            - name: credit_balance
              type: string
              mapping: "$.d.CreditAmountInCoCodeCrcy"
            - name: currency
              type: string
              mapping: "$.d.CompanyCodeCurrency"
  consumes:
    - type: http
      namespace: sap-gl
      baseUri: "https://sap-s4.sap.com/sap/opu/odata/sap/API_GL_ACCOUNT_LINE_ITEMS_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: gl-balances
          path: "/A_GLAccountBalance"
          inputParameters:
            - name: CompanyCode
              in: query
            - name: GLAccount
              in: query
            - name: FiscalYear
              in: query
            - name: FiscalPeriod
              in: query
          operations:
            - name: get-gl-balance
              method: GET

Alerts low stock.

naftiko: "0.5"
info:
  label: "SAP Stock Alert"
  description: "Alerts low stock."
  tags:
    - erp
    - supply-chain
    - sap
    - slack
capability:
  exposes:
    - type: mcp
      namespace: sap
      port: 8080
      tools:
        - name: sap-stock-alert-to-slack
          description: "Alerts low stock."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "erp.get-data"
              with:
                id: "{{input_id}}"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "SAP Stock Alert triggered"
  consumes:
    - type: http
      namespace: erp
      baseUri: "https://erp.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.erp_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              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

Enrolls an employee in a mandatory training course in SAP SuccessFactors Learning and sends a calendar invite via Microsoft 365.

naftiko: "0.5"
info:
  label: "SAP SuccessFactors Learning Enrollment"
  description: "Enrolls an employee in a mandatory training course in SAP SuccessFactors Learning and sends a calendar invite via Microsoft 365."
  tags:
    - hr
    - learning
    - sap-successfactors
    - microsoft-365
    - compliance
capability:
  exposes:
    - type: mcp
      namespace: learning-ops
      port: 8080
      tools:
        - name: enroll-employee-training
          description: "Given an employee ID and course ID, enroll the employee in SuccessFactors Learning and send an Outlook calendar event for the training session."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "SuccessFactors employee ID."
            - name: course_id
              in: body
              type: string
              description: "SuccessFactors Learning course ID."
            - name: training_date
              in: body
              type: string
              description: "ISO 8601 date for the training session, e.g. 2026-04-15."
          steps:
            - name: enroll
              type: call
              call: "sf-learning.enroll-user"
              with:
                userId: "{{employee_id}}"
                courseId: "{{course_id}}"
            - name: get-employee-email
              type: call
              call: "sf-hr.get-employee-email"
              with:
                employeeId: "{{employee_id}}"
            - name: send-calendar-invite
              type: call
              call: "m365.create-calendar-event"
              with:
                recipientEmail: "{{get-employee-email.email}}"
                subject: "Mandatory Training: {{enroll.courseTitle}}"
                startDate: "{{training_date}}"
  consumes:
    - type: http
      namespace: sf-learning
      baseUri: "https://api4.successfactors.com/learning/odatav4/public"
      authentication:
        type: bearer
        token: "$secrets.sf_token"
      resources:
        - name: enrollments
          path: "/enrollments"
          operations:
            - name: enroll-user
              method: POST
    - type: http
      namespace: sf-hr
      baseUri: "https://api4.successfactors.com/odata/v2"
      authentication:
        type: bearer
        token: "$secrets.sf_token"
      resources:
        - name: employee-emails
          path: "/PerEmail(personIdExternal='{{employeeId}}')"
          inputParameters:
            - name: employeeId
              in: path
          operations:
            - name: get-employee-email
              method: GET
    - type: http
      namespace: m365
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: calendar-events
          path: "/users/{{recipientEmail}}/events"
          inputParameters:
            - name: recipientEmail
              in: path
          operations:
            - name: create-calendar-event
              method: POST

Initiates a performance review cycle in SAP SuccessFactors for a given employee population and sends kick-off instructions to managers via Microsoft Teams.

naftiko: "0.5"
info:
  label: "SAP SuccessFactors Performance Review Kickoff"
  description: "Initiates a performance review cycle in SAP SuccessFactors for a given employee population and sends kick-off instructions to managers via Microsoft Teams."
  tags:
    - hr
    - performance
    - sap-successfactors
    - microsoft-teams
    - performance-management
capability:
  exposes:
    - type: mcp
      namespace: performance-hr
      port: 8080
      tools:
        - name: kickoff-performance-review
          description: "Launch a SuccessFactors performance review form for a list of employees and notify each manager in Teams with review instructions and due date."
          inputParameters:
            - name: review_template_id
              in: body
              type: string
              description: "SuccessFactors performance review template ID."
            - name: population_query
              in: body
              type: string
              description: "OData filter expression to select the employee population, e.g. department eq 'Engineering'."
            - name: due_date
              in: body
              type: string
              description: "Review due date in ISO 8601 format."
            - name: manager_teams_channel_id
              in: body
              type: string
              description: "Teams channel ID to notify managers."
          steps:
            - name: get-employees
              type: call
              call: "sf-perf.get-employee-population"
              with:
                filter: "{{population_query}}"
            - name: launch-reviews
              type: call
              call: "sf-perf.create-performance-review"
              with:
                templateId: "{{review_template_id}}"
                employeeIds: "{{get-employees.ids}}"
                dueDate: "{{due_date}}"
            - name: notify-managers
              type: call
              call: "msteams-perf.send-channel-message"
              with:
                channelId: "{{manager_teams_channel_id}}"
                text: "Performance review cycle launched for {{get-employees.count}} employees. Due: {{due_date}}. Please complete reviews in SuccessFactors by the deadline."
  consumes:
    - type: http
      namespace: sf-perf
      baseUri: "https://api4.successfactors.com/odata/v2"
      authentication:
        type: bearer
        token: "$secrets.sf_token"
      resources:
        - name: employee-population
          path: "/EmpJob"
          inputParameters:
            - name: filter
              in: query
          operations:
            - name: get-employee-population
              method: GET
        - name: performance-reviews
          path: "/PerformanceReview"
          operations:
            - name: create-performance-review
              method: POST
    - type: http
      namespace: msteams-perf
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{teamId}}/channels/{{channelId}}/messages"
          inputParameters:
            - name: channelId
              in: path
          operations:
            - name: send-channel-message
              method: POST

Processes an employee role change in SAP SuccessFactors, updates the corresponding Salesforce user profile permissions, and logs the change in a Jira HR ticket.

naftiko: "0.5"
info:
  label: "SAP SuccessFactors Role Change Workflow"
  description: "Processes an employee role change in SAP SuccessFactors, updates the corresponding Salesforce user profile permissions, and logs the change in a Jira HR ticket."
  tags:
    - hr
    - identity
    - sap-successfactors
    - salesforce
    - jira
    - role-change
capability:
  exposes:
    - type: mcp
      namespace: hr-role-change
      port: 8080
      tools:
        - name: process-role-change
          description: "Given a SuccessFactors employee ID and new job code, update the employee's role in SuccessFactors, sync their Salesforce profile permissions, and log the change in Jira."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "SuccessFactors employee ID undergoing the role change."
            - name: new_job_code
              in: body
              type: string
              description: "New job code to assign in SuccessFactors."
            - name: salesforce_user_id
              in: body
              type: string
              description: "Salesforce user ID to update profile permissions."
          steps:
            - name: update-job-code
              type: call
              call: "sf-emp.update-employee-job"
              with:
                employeeId: "{{employee_id}}"
                jobCode: "{{new_job_code}}"
            - name: update-sf-profile
              type: call
              call: "sf-crm.update-user-profile"
              with:
                userId: "{{salesforce_user_id}}"
                profileId: "{{update-job-code.newProfileId}}"
            - name: log-jira
              type: call
              call: "jira-hr.create-issue"
              with:
                project_key: "HR"
                issuetype: "Task"
                summary: "Role change processed for employee {{employee_id}}"
                description: "New job code: {{new_job_code}}\nSalesforce profile updated: {{salesforce_user_id}}"
  consumes:
    - type: http
      namespace: sf-emp
      baseUri: "https://api4.successfactors.com/odata/v2"
      authentication:
        type: bearer
        token: "$secrets.sf_token"
      resources:
        - name: employee-jobs
          path: "/EmpJob(employeeId='{{employeeId}}')"
          inputParameters:
            - name: employeeId
              in: path
          operations:
            - name: update-employee-job
              method: PATCH
    - type: http
      namespace: sf-crm
      baseUri: "https://sap.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: user-profiles
          path: "/sobjects/User/{{userId}}"
          inputParameters:
            - name: userId
              in: path
          operations:
            - name: update-user-profile
              method: PATCH
    - type: http
      namespace: jira-hr
      baseUri: "https://sap.atlassian.net/rest/api/3"
      authentication:
        type: bearer
        token: "$secrets.jira_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST

Aggregates supplier delivery and quality metrics from SAP S/4HANA QM, calculates a performance score, and publishes a scorecard to Power BI.

naftiko: "0.5"
info:
  label: "SAP Supplier Performance Scorecard"
  description: "Aggregates supplier delivery and quality metrics from SAP S/4HANA QM, calculates a performance score, and publishes a scorecard to Power BI."
  tags:
    - procurement
    - quality
    - sap-s4hana
    - power-bi
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: supplier-reporting
      port: 8080
      tools:
        - name: publish-supplier-scorecard
          description: "Fetch supplier quality inspection results and delivery performance from SAP S/4HANA QM module and push a computed scorecard to a Power BI dataset."
          inputParameters:
            - name: supplier_number
              in: body
              type: string
              description: "SAP supplier/vendor number to score."
            - name: powerbi_dataset_id
              in: body
              type: string
              description: "Power BI dataset ID for the supplier scorecard."
          steps:
            - name: get-quality-results
              type: call
              call: "sap-qm.get-inspection-lots"
              with:
                Vendor: "{{supplier_number}}"
            - name: push-scorecard
              type: call
              call: "powerbi-supplier.push-rows"
              with:
                datasetId: "{{powerbi_dataset_id}}"
                tableName: "SupplierScorecard"
                rows: "{{get-quality-results.value}}"
  consumes:
    - type: http
      namespace: sap-qm
      baseUri: "https://sap-s4.sap.com/sap/opu/odata/sap/API_INSPECTIONLOT_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: inspection-lots
          path: "/A_InspectionLot"
          inputParameters:
            - name: Vendor
              in: query
          operations:
            - name: get-inspection-lots
              method: GET
    - type: http
      namespace: powerbi-supplier
      baseUri: "https://api.powerbi.com/v1.0/myorg"
      authentication:
        type: bearer
        token: "$secrets.powerbi_token"
      resources:
        - name: scorecard-rows
          path: "/datasets/{{datasetId}}/tables/{{tableName}}/rows"
          inputParameters:
            - name: datasetId
              in: path
            - name: tableName
              in: path
          operations:
            - name: push-rows
              method: POST

Retrieves ServiceNow incident details.

naftiko: "0.5"
info:
  label: "ServiceNow Incident Status"
  description: "Retrieves ServiceNow incident details."
  tags:
    - itsm
    - servicenow
    - incident-management
capability:
  exposes:
    - type: mcp
      namespace: itsm
      port: 8080
      tools:
        - name: get-incident
          description: "Given number, return status."
          inputParameters:
            - name: number
              in: body
              type: string
              description: "Number"
          call: servicenow.get-incident
          with:
            number: "{{number}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: get-incident
              method: GET

Posts message to Slack channel.

naftiko: "0.5"
info:
  label: "Slack Message Poster"
  description: "Posts message to Slack channel."
  tags:
    - communication
    - slack
    - notifications
capability:
  exposes:
    - type: mcp
      namespace: messaging
      port: 8080
      tools:
        - name: post-message
          description: "Given channel and text, post."
          inputParameters:
            - name: channel
              in: body
              type: string
              description: "Channel"
          call: slack.post-message
          with:
            channel: "{{channel}}"
  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

Alerts on credit overage.

naftiko: "0.5"
info:
  label: "Snowflake Cost Alert"
  description: "Alerts on credit overage."
  tags:
    - data
    - finops
    - snowflake
    - servicenow
    - slack
capability:
  exposes:
    - type: mcp
      namespace: snowflake
      port: 8080
      tools:
        - name: snowflake-cost-to-finops
          description: "Alerts on credit overage."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "data.get-data"
              with:
                id: "{{input_id}}"
            - name: create-record
              type: call
              call: "servicenow.create-record"
              with:
                short_description: "Snowflake Cost Alert"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "Snowflake Cost Alert triggered"
  consumes:
    - type: http
      namespace: data
      baseUri: "https://data.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.data_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: records
          path: "/table/incident"
          operations:
            - name: create-record
              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

Creates Jira task for data anomalies.

naftiko: "0.5"
info:
  label: "Snowflake Data Quality to Jira"
  description: "Creates Jira task for data anomalies."
  tags:
    - data
    - quality
    - snowflake
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: snowflake
      port: 8080
      tools:
        - name: snowflake-quality-to-jira
          description: "Creates Jira task for data anomalies."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "data.get-data"
              with:
                id: "{{input_id}}"
            - name: create-issue
              type: call
              call: "jira.create-issue"
              with:
                summary: "Snowflake Data Quality to Jira"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "Snowflake Data Quality to Jira triggered"
  consumes:
    - type: http
      namespace: data
      baseUri: "https://data.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.data_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: jira
      baseUri: "https://sap-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 read-only SQL against Snowflake.

naftiko: "0.5"
info:
  label: "Snowflake Query Runner"
  description: "Executes read-only SQL against Snowflake."
  tags:
    - data
    - analytics
    - snowflake
capability:
  exposes:
    - type: mcp
      namespace: analytics
      port: 8080
      tools:
        - name: run-query
          description: "Given SQL, execute query."
          inputParameters:
            - name: sql
              in: body
              type: string
              description: "Sql"
          call: snowflake.execute-query
          with:
            statement: "{{sql}}"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://sap.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-query
              method: POST

Runs a Snowflake analytical query on SAP-replicated data, formats the result, and pushes it to Power BI as a streamed dataset.

naftiko: "0.5"
info:
  label: "Snowflake Query to SAP Reporting Export"
  description: "Runs a Snowflake analytical query on SAP-replicated data, formats the result, and pushes it to Power BI as a streamed dataset."
  tags:
    - analytics
    - data
    - snowflake
    - power-bi
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: data-reporting
      port: 8080
      tools:
        - name: run-sap-data-query
          description: "Execute a named Snowflake SQL query against SAP-replicated tables and push the results to a Power BI streaming dataset for real-time reporting."
          inputParameters:
            - name: query_name
              in: body
              type: string
              description: "Named query identifier in Snowflake to execute."
            - name: powerbi_dataset_id
              in: body
              type: string
              description: "Power BI dataset ID to stream results to."
          steps:
            - name: run-query
              type: call
              call: "snowflake.execute-query"
              with:
                queryName: "{{query_name}}"
            - name: push-results
              type: call
              call: "powerbi-stream.push-rows"
              with:
                datasetId: "{{powerbi_dataset_id}}"
                tableName: "QueryResults"
                rows: "{{run-query.results}}"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://sap.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: queries
          path: "/statements"
          operations:
            - name: execute-query
              method: POST
    - type: http
      namespace: powerbi-stream
      baseUri: "https://api.powerbi.com/v1.0/myorg"
      authentication:
        type: bearer
        token: "$secrets.powerbi_token"
      resources:
        - name: streaming-rows
          path: "/datasets/{{datasetId}}/tables/{{tableName}}/rows"
          inputParameters:
            - name: datasetId
              in: path
            - name: tableName
              in: path
          operations:
            - name: push-rows
              method: POST

Creates incident for down.

naftiko: "0.5"
info:
  label: "SolarWinds to PagerDuty"
  description: "Creates incident for down."
  tags:
    - networking
    - incident-response
    - solarwinds
    - pagerduty
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: solarwinds
      port: 8080
      tools:
        - name: solarwinds-to-pagerduty
          description: "Creates incident for down."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "solarwinds.get-data"
              with:
                id: "{{input_id}}"
            - name: create-record
              type: call
              call: "servicenow.create-record"
              with:
                short_description: "SolarWinds to PagerDuty"
  consumes:
    - type: http
      namespace: solarwinds
      baseUri: "https://solarwinds.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.solarwinds_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: records
          path: "/table/incident"
          operations:
            - name: create-record
              method: POST

Creates security incident from Splunk.

naftiko: "0.5"
info:
  label: "Splunk Alert to Security Incident"
  description: "Creates security incident from Splunk."
  tags:
    - security
    - siem
    - splunk
    - servicenow
    - slack
capability:
  exposes:
    - type: mcp
      namespace: splunk
      port: 8080
      tools:
        - name: splunk-alert-to-security-incident
          description: "Creates security incident from Splunk."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "splunk.get-data"
              with:
                id: "{{input_id}}"
            - name: create-record
              type: call
              call: "servicenow.create-record"
              with:
                short_description: "Splunk Alert to Security Incident"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "Splunk Alert to Security Incident triggered"
  consumes:
    - type: http
      namespace: splunk
      baseUri: "https://splunk.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.splunk_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: records
          path: "/table/incident"
          operations:
            - name: create-record
              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 Splunk SPL query.

naftiko: "0.5"
info:
  label: "Splunk Search Runner"
  description: "Executes Splunk SPL query."
  tags:
    - security
    - observability
    - splunk
capability:
  exposes:
    - type: mcp
      namespace: log-analysis
      port: 8080
      tools:
        - name: run-search
          description: "Given SPL query, execute."
          inputParameters:
            - name: query
              in: body
              type: string
              description: "Query"
          call: splunk.create-search
          with:
            search: "{{query}}"
  consumes:
    - type: http
      namespace: splunk
      baseUri: "https://splunk.sap.com:8089/services"
      authentication:
        type: bearer
        token: "$secrets.splunk_token"
      resources:
        - name: search-jobs
          path: "/search/jobs"
          operations:
            - name: create-search
              method: POST

Creates incident for failures.

naftiko: "0.5"
info:
  label: "Tableau to ServiceNow"
  description: "Creates incident for failures."
  tags:
    - analytics
    - itsm
    - tableau
    - servicenow
    - slack
capability:
  exposes:
    - type: mcp
      namespace: tableau
      port: 8080
      tools:
        - name: tableau-failure-to-incident
          description: "Creates incident for failures."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "analytics.get-data"
              with:
                id: "{{input_id}}"
            - name: create-record
              type: call
              call: "servicenow.create-record"
              with:
                short_description: "Tableau to ServiceNow"
            - name: notify-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "#alerts"
                text: "Tableau to ServiceNow triggered"
  consumes:
    - type: http
      namespace: analytics
      baseUri: "https://analytics.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.analytics_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: records
          path: "/table/incident"
          operations:
            - name: create-record
              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

Creates page from transcript.

naftiko: "0.5"
info:
  label: "Teams to Confluence"
  description: "Creates page from transcript."
  tags:
    - communication
    - documentation
    - microsoft-teams
    - confluence
capability:
  exposes:
    - type: mcp
      namespace: teams
      port: 8080
      tools:
        - name: teams-to-confluence
          description: "Creates page from transcript."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "microsoft-teams.get-data"
              with:
                id: "{{input_id}}"
            - name: create-page
              type: call
              call: "confluence.create-page"
              with:
                title: "Teams to Confluence"
  consumes:
    - type: http
      namespace: microsoft-teams
      baseUri: "https://microsoft-teams.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.microsoft_teams_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: confluence
      baseUri: "https://sap-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

Creates a new Terraform Cloud workspace for a SAP BTP subaccount and stores the workspace ID in a GitHub repository secret for CI/CD pipelines.

naftiko: "0.5"
info:
  label: "Terraform Cloud Workspace Provisioning for BTP"
  description: "Creates a new Terraform Cloud workspace for a SAP BTP subaccount and stores the workspace ID in a GitHub repository secret for CI/CD pipelines."
  tags:
    - cloud
    - infrastructure
    - terraform
    - sap-btp
    - github
    - devops
capability:
  exposes:
    - type: mcp
      namespace: infra-provisioning
      port: 8080
      tools:
        - name: provision-btp-workspace
          description: "Given a BTP subaccount name and GitHub repo, create a Terraform Cloud workspace scoped to the BTP subaccount and store the workspace ID as a GitHub Actions secret."
          inputParameters:
            - name: workspace_name
              in: body
              type: string
              description: "Name for the new Terraform Cloud workspace."
            - name: terraform_org
              in: body
              type: string
              description: "Terraform Cloud organization name."
            - name: github_repo
              in: body
              type: string
              description: "GitHub repo (owner/repo) to store the workspace ID secret."
          steps:
            - name: create-workspace
              type: call
              call: "terraform.create-workspace"
              with:
                orgName: "{{terraform_org}}"
                workspaceName: "{{workspace_name}}"
            - name: store-secret
              type: call
              call: "github-infra.create-repo-secret"
              with:
                repo: "{{github_repo}}"
                secretName: "TF_WORKSPACE_ID"
                secretValue: "{{create-workspace.workspaceId}}"
  consumes:
    - type: http
      namespace: terraform
      baseUri: "https://app.terraform.io/api/v2"
      authentication:
        type: bearer
        token: "$secrets.terraform_token"
      resources:
        - name: workspaces
          path: "/organizations/{{orgName}}/workspaces"
          inputParameters:
            - name: orgName
              in: path
          operations:
            - name: create-workspace
              method: POST
    - type: http
      namespace: github-infra
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: repo-secrets
          path: "/repos/{{repo}}/actions/secrets/{{secretName}}"
          inputParameters:
            - name: repo
              in: path
            - name: secretName
              in: path
          operations:
            - name: create-repo-secret
              method: PUT

Creates change for Terraform plan.

naftiko: "0.5"
info:
  label: "Terraform Plan to Change"
  description: "Creates change for Terraform plan."
  tags:
    - infrastructure
    - itsm
    - terraform
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: terraform
      port: 8080
      tools:
        - name: terraform-plan-to-change
          description: "Creates change for Terraform plan."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "infrastructure.get-data"
              with:
                id: "{{input_id}}"
            - name: create-record
              type: call
              call: "servicenow.create-record"
              with:
                short_description: "Terraform Plan to Change"
  consumes:
    - type: http
      namespace: infrastructure
      baseUri: "https://infrastructure.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.infrastructure_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: records
          path: "/table/incident"
          operations:
            - name: create-record
              method: POST

Retrieves Terraform workspace state.

naftiko: "0.5"
info:
  label: "Terraform Workspace Status"
  description: "Retrieves Terraform workspace state."
  tags:
    - infrastructure
    - terraform
    - cloud
capability:
  exposes:
    - type: mcp
      namespace: infra
      port: 8080
      tools:
        - name: get-workspace
          description: "Given workspace, return status."
          inputParameters:
            - name: workspace
              in: body
              type: string
              description: "Workspace"
          call: terraform.get-workspace
          with:
            workspace: "{{workspace}}"
  consumes:
    - type: http
      namespace: terraform
      baseUri: "https://app.terraform.io/api/v2"
      authentication:
        type: bearer
        token: "$secrets.terraform_token"
      resources:
        - name: workspaces
          path: "/organizations/sap/workspaces/{{workspace}}"
          operations:
            - name: get-workspace
              method: GET

Fetches an open vendor invoice from SAP Ariba, posts the approval decision back to SAP S/4HANA, and notifies the requester via Microsoft Teams.

naftiko: "0.5"
info:
  label: "Vendor Invoice Processing"
  description: "Fetches an open vendor invoice from SAP Ariba, posts the approval decision back to SAP S/4HANA, and notifies the requester via Microsoft Teams."
  tags:
    - finance
    - procurement
    - sap-ariba
    - sap-s4hana
    - microsoft-teams
    - approval
capability:
  exposes:
    - type: mcp
      namespace: finance-ops
      port: 8080
      tools:
        - name: approve-vendor-invoice
          description: "Given an Ariba invoice ID and approval decision, post the approval to SAP S/4HANA AP and notify the vendor contact via Microsoft Teams."
          inputParameters:
            - name: invoice_id
              in: body
              type: string
              description: "The Ariba invoice ID to approve or reject."
            - name: decision
              in: body
              type: string
              description: "Approval decision: 'approve' or 'reject'."
            - name: approver_upn
              in: body
              type: string
              description: "UPN of the approver for Teams notification."
          steps:
            - name: get-invoice
              type: call
              call: "ariba.get-invoice"
              with:
                invoiceId: "{{invoice_id}}"
            - name: post-approval
              type: call
              call: "sap-fi.post-invoice-approval"
              with:
                invoice_id: "{{invoice_id}}"
                decision: "{{decision}}"
                vendor_id: "{{get-invoice.vendorId}}"
            - name: notify-approver
              type: call
              call: "msteams.send-message"
              with:
                recipient_upn: "{{approver_upn}}"
                text: "Invoice {{invoice_id}} has been {{decision}}d. SAP posting: {{post-approval.documentNumber}}"
  consumes:
    - type: http
      namespace: ariba
      baseUri: "https://openapi.ariba.com/api/invoice/v1"
      authentication:
        type: bearer
        token: "$secrets.ariba_token"
      resources:
        - name: invoices
          path: "/invoices/{{invoiceId}}"
          inputParameters:
            - name: invoiceId
              in: path
          operations:
            - name: get-invoice
              method: GET
    - type: http
      namespace: sap-fi
      baseUri: "https://sap-s4.sap.com/sap/opu/odata/sap/API_SUPPLIER_INVOICE_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: invoice-approvals
          path: "/A_SupplierInvoice"
          operations:
            - name: post-invoice-approval
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: chat-messages
          path: "/users/{{recipient_upn}}/sendMail"
          inputParameters:
            - name: recipient_upn
              in: path
          operations:
            - name: send-message
              method: POST

Retrieves employee profile from Workday HCM.

naftiko: "0.5"
info:
  label: "Workday Employee Lookup"
  description: "Retrieves employee profile from Workday HCM."
  tags:
    - hr
    - workday
    - employee-data
capability:
  exposes:
    - type: mcp
      namespace: hr
      port: 8080
      tools:
        - name: get-employee
          description: "Given worker ID, return profile."
          inputParameters:
            - name: worker_id
              in: body
              type: string
              description: "Worker Id"
          call: workday.get-worker
          with:
            worker_id: "{{worker_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: "/sap/workers/{{worker_id}}"
          operations:
            - name: get-worker
              method: GET

Loads headcount snapshot.

naftiko: "0.5"
info:
  label: "Workday Headcount to Snowflake"
  description: "Loads headcount snapshot."
  tags:
    - hr
    - data
    - workday
    - snowflake
capability:
  exposes:
    - type: mcp
      namespace: workday
      port: 8080
      tools:
        - name: workday-headcount-to-snowflake
          description: "Loads headcount snapshot."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "data.get-data"
              with:
                id: "{{input_id}}"
  consumes:
    - type: http
      namespace: data
      baseUri: "https://data.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.data_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET

Provisions Okta for new hires.

naftiko: "0.5"
info:
  label: "Workday New Hire to Okta"
  description: "Provisions Okta for new hires."
  tags:
    - hr
    - security
    - workday
    - okta
    - onboarding
capability:
  exposes:
    - type: mcp
      namespace: workday
      port: 8080
      tools:
        - name: workday-new-hire-to-okta
          description: "Provisions Okta for new hires."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "workday.get-data"
              with:
                id: "{{input_id}}"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://workday.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET

Syncs groups on role change.

naftiko: "0.5"
info:
  label: "Workday Role to Okta Groups"
  description: "Syncs groups on role change."
  tags:
    - hr
    - security
    - workday
    - okta
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: workday
      port: 8080
      tools:
        - name: workday-role-to-okta-groups
          description: "Syncs groups on role change."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "workday.get-data"
              with:
                id: "{{input_id}}"
            - name: create-record
              type: call
              call: "servicenow.create-record"
              with:
                short_description: "Workday Role to Okta Groups"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://workday.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: records
          path: "/table/incident"
          operations:
            - name: create-record
              method: POST

Deactivates Okta user on Workday termination and creates ServiceNow task.

naftiko: "0.5"
info:
  label: "Workday Termination to Okta Deprovisioning"
  description: "Deactivates Okta user on Workday termination and creates ServiceNow task."
  tags:
    - hr
    - security
    - workday
    - okta
    - servicenow
    - offboarding
capability:
  exposes:
    - type: mcp
      namespace: workday
      port: 8080
      tools:
        - name: workday-termination-to-okta-deprovisioning
          description: "Deactivates Okta user on Workday termination and creates ServiceNow task."
          inputParameters:
            - name: input_id
              in: body
              type: string
              description: "Input identifier."
          steps:
            - name: get-data
              type: call
              call: "workday.get-data"
              with:
                id: "{{input_id}}"
            - name: create-record
              type: call
              call: "servicenow.create-record"
              with:
                short_description: "Workday Termination to Okta Deprovisioning"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://workday.sap.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: data
          path: "/data"
          operations:
            - name: get-data
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://sap.service-now.com/api/now"
      authentication:
        type: bearer
        token: "$secrets.servicenow_token"
      resources:
        - name: records
          path: "/table/incident"
          operations:
            - name: create-record
              method: POST