Heineken Capabilities

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

Sort
Expand

Uses the Anthropic API to summarize a long-form document (contract, policy, or report) stored in SharePoint and posts the summary to a designated Teams channel.

naftiko: "0.5"
info:
  label: "AI Document Summarization"
  description: "Uses the Anthropic API to summarize a long-form document (contract, policy, or report) stored in SharePoint and posts the summary to a designated Teams channel."
  tags:
    - ai
    - automation
    - anthropic
    - sharepoint
    - microsoft-teams
    - document-management
capability:
  exposes:
    - type: mcp
      namespace: ai-docs
      port: 8080
      tools:
        - name: summarize-document
          description: "Given a SharePoint document URL and document text, call the Anthropic API to produce a structured summary and post it to a Teams channel. Use for rapid review of contracts, policies, or lengthy reports."
          inputParameters:
            - name: document_text
              in: body
              type: string
              description: "The full text content of the document to summarize."
            - name: document_title
              in: body
              type: string
              description: "The display name or title of the document."
            - name: target_channel_id
              in: body
              type: string
              description: "The Teams channel ID where the summary should be posted."
          steps:
            - name: generate-summary
              type: call
              call: "anthropic.create-message"
              with:
                model: "claude-3-5-sonnet-20241022"
                prompt: "Summarize the following document in 3-5 bullet points, highlighting key decisions, obligations, and dates: {{document_text}}"
            - name: post-summary
              type: call
              call: "msteams-ai.post-channel-message"
              with:
                channel_id: "{{target_channel_id}}"
                message: "Document Summary: {{document_title}}\n\n{{generate-summary.content}}"
  consumes:
    - type: http
      namespace: anthropic
      baseUri: "https://api.anthropic.com/v1"
      authentication:
        type: apikey
        key: "x-api-key"
        value: "$secrets.anthropic_api_key"
        placement: header
      resources:
        - name: messages
          path: "/messages"
          operations:
            - name: create-message
              method: POST
    - type: http
      namespace: msteams-ai
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{channel_id}}/channels/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Retrieves the state of a CloudWatch alarm monitoring brewery IoT systems.

naftiko: "0.5"
info:
  label: "AWS CloudWatch Brewery Alarm"
  description: "Retrieves the state of a CloudWatch alarm monitoring brewery IoT systems."
  tags:
    - monitoring
    - manufacturing
    - aws
    - cloudwatch
capability:
  exposes:
    - type: mcp
      namespace: brewery-ops
      port: 8080
      tools:
        - name: get-alarm-state
          description: "Given an alarm name, return the current state and reason."
          inputParameters:
            - name: alarm_name
              in: body
              type: string
              description: "CloudWatch alarm name."
          call: cloudwatch.describe-alarm
          with:
            alarm_name: "{{alarm_name}}"
          outputParameters:
            - name: state
              type: string
              mapping: "$.MetricAlarms[0].StateValue"
            - name: reason
              type: string
              mapping: "$.MetricAlarms[0].StateReason"
  consumes:
    - type: http
      namespace: cloudwatch
      baseUri: "https://monitoring.eu-west-1.amazonaws.com"
      authentication:
        type: aws-sigv4
        accessKeyId: "$secrets.aws_access_key"
        secretAccessKey: "$secrets.aws_secret_key"
      resources:
        - name: alarms
          path: "/"
          operations:
            - name: describe-alarm
              method: POST

Generates a pre-signed S3 URL for a data export and shares it via Microsoft Teams.

naftiko: "0.5"
info:
  label: "AWS S3 Data Lake Export"
  description: "Generates a pre-signed S3 URL for a data export and shares it via Microsoft Teams."
  tags:
    - data
    - cloud
    - amazon-s3
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: data-ops
      port: 8080
      tools:
        - name: share-data-export
          description: "Generate an S3 pre-signed URL and share via Teams."
          inputParameters:
            - name: bucket
              in: body
              type: string
              description: "S3 bucket."
            - name: key
              in: body
              type: string
              description: "S3 key."
            - name: teams_channel_id
              in: body
              type: string
              description: "Teams channel."
          steps:
            - name: generate-url
              type: call
              call: s3.get-presigned-url
              with:
                bucket: "{{bucket}}"
                key: "{{key}}"
            - name: share-link
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "{{teams_channel_id}}"
                text: "Data export ready: {{generate-url.url}}"
  consumes:
    - type: http
      namespace: s3
      baseUri: "https://s3.eu-west-1.amazonaws.com"
      authentication:
        type: aws-sigv4
        accessKeyId: "$secrets.aws_access_key"
        secretAccessKey: "$secrets.aws_secret_key"
      resources:
        - name: objects
          path: "/{{bucket}}/{{key}}"
          inputParameters:
            - name: bucket
              in: path
            - name: key
              in: path
          operations:
            - name: get-presigned-url
              method: GET
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Updates Azure AD group memberships when an employee changes teams in Workday.

naftiko: "0.5"
info:
  label: "Azure AD Group Sync"
  description: "Updates Azure AD group memberships when an employee changes teams in Workday."
  tags:
    - identity
    - hr
    - azure-active-directory
    - workday
capability:
  exposes:
    - type: mcp
      namespace: iam-ops
      port: 8080
      tools:
        - name: sync-ad-groups
          description: "Given an employee ID and new team, update Azure AD group memberships."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "Workday employee ID."
            - name: new_team
              in: body
              type: string
              description: "New team code."
          steps:
            - name: get-worker
              type: call
              call: workday.get-worker
              with:
                employee_id: "{{employee_id}}"
            - name: update-groups
              type: call
              call: azuread.update-membership
              with:
                user_email: "{{get-worker.email}}"
                team: "{{new_team}}"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd5-impl-services1.workday.com/ccx/service/heineken"
      authentication:
        type: basic
        username: "$secrets.workday_user"
        password: "$secrets.workday_password"
      resources:
        - name: workers
          path: "/Human_Resources/v40.0/Get_Workers"
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: azuread
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: groups
          path: "/groups"
          operations:
            - name: update-membership
              method: POST

When Azure Cost Management detects a spending anomaly, retrieves the anomaly details, creates a ServiceNow incident for the cloud team, and notifies the FinOps Teams channel.

naftiko: "0.5"
info:
  label: "Azure Cost Anomaly Responder"
  description: "When Azure Cost Management detects a spending anomaly, retrieves the anomaly details, creates a ServiceNow incident for the cloud team, and notifies the FinOps Teams channel."
  tags:
    - cloud
    - finops
    - azure
    - servicenow
    - microsoft-teams
    - cost-management
capability:
  exposes:
    - type: mcp
      namespace: cloud-finops
      port: 8080
      tools:
        - name: handle-cost-anomaly
          description: "Given an Azure subscription ID and anomaly alert details, create a ServiceNow incident and notify the FinOps Teams channel. Use when Azure Cost Management fires a budget or anomaly alert."
          inputParameters:
            - name: subscription_id
              in: body
              type: string
              description: "The Azure subscription ID where the cost anomaly was detected."
            - name: anomaly_description
              in: body
              type: string
              description: "Description of the cost anomaly, including affected service and estimated overage."
            - name: estimated_overage
              in: body
              type: string
              description: "Estimated cost overage amount in USD."
          steps:
            - name: create-incident
              type: call
              call: "servicenow-cloud.create-incident"
              with:
                short_description: "Azure cost anomaly in subscription {{subscription_id}}: {{anomaly_description}}"
                category: "cloud_cost"
                urgency: "2"
            - name: notify-finops
              type: call
              call: "msteams-finops.post-channel-message"
              with:
                channel_id: "$secrets.teams_finops_channel_id"
                message: "Cost anomaly detected in Azure subscription {{subscription_id}}. Estimated overage: {{estimated_overage}}. Incident: {{create-incident.number}}."
  consumes:
    - type: http
      namespace: servicenow-cloud
      baseUri: "https://heineken.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams-finops
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{channel_id}}/channels/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Retrieves weekly Azure cost data via Azure Cost Management API and posts to the FinOps Teams channel.

naftiko: "0.5"
info:
  label: "Azure Cost Report Weekly"
  description: "Retrieves weekly Azure cost data via Azure Cost Management API and posts to the FinOps Teams channel."
  tags:
    - finops
    - cloud
    - microsoft-azure
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: finops
      port: 8080
      tools:
        - name: post-weekly-cost
          description: "Fetch weekly Azure costs and post to the FinOps Teams channel."
          inputParameters:
            - name: subscription_id
              in: body
              type: string
              description: "Azure subscription ID."
          steps:
            - name: get-costs
              type: call
              call: azure.get-cost-usage
              with:
                subscription_id: "{{subscription_id}}"
                timeframe: "WeekToDate"
            - name: post-report
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "finops"
                text: "Weekly Azure cost: ${{get-costs.total}} for subscription {{subscription_id}}"
  consumes:
    - type: http
      namespace: azure
      baseUri: "https://management.azure.com"
      authentication:
        type: bearer
        token: "$secrets.azure_mgmt_token"
      resources:
        - name: costs
          path: "/subscriptions/{{subscription_id}}/providers/Microsoft.CostManagement/query"
          inputParameters:
            - name: subscription_id
              in: path
          operations:
            - name: get-cost-usage
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

When an Azure DevOps pipeline fails on a main branch, creates a ServiceNow incident and sends a Teams alert with pipeline details and a link to the failed run.

naftiko: "0.5"
info:
  label: "Azure DevOps Pipeline Failure Handler"
  description: "When an Azure DevOps pipeline fails on a main branch, creates a ServiceNow incident and sends a Teams alert with pipeline details and a link to the failed run."
  tags:
    - devops
    - cicd
    - azure
    - servicenow
    - microsoft-teams
    - incident-response
capability:
  exposes:
    - type: mcp
      namespace: devops-cicd
      port: 8080
      tools:
        - name: handle-pipeline-failure
          description: "Given an Azure DevOps pipeline run ID, project, and branch, create a ServiceNow incident and alert the engineering Teams channel. Use when a protected branch pipeline fails."
          inputParameters:
            - name: project_name
              in: body
              type: string
              description: "The Azure DevOps project name."
            - name: pipeline_id
              in: body
              type: string
              description: "The Azure DevOps pipeline definition ID."
            - name: run_id
              in: body
              type: string
              description: "The specific pipeline run ID that failed."
            - name: branch_name
              in: body
              type: string
              description: "The branch name, e.g. main or release/2025-q1."
            - name: run_url
              in: body
              type: string
              description: "Direct URL to the failed pipeline run."
          steps:
            - name: create-incident
              type: call
              call: "servicenow-devops.create-incident"
              with:
                short_description: "Pipeline failure: {{project_name}} / {{branch_name}} (Run {{run_id}})"
                category: "devops"
                urgency: "2"
            - name: alert-engineering
              type: call
              call: "msteams-devops.post-channel-message"
              with:
                channel_id: "$secrets.teams_engineering_channel_id"
                message: "Pipeline Failure | Project: {{project_name}} | Branch: {{branch_name}} | Run: {{run_id}} | Incident: {{create-incident.number}} | URL: {{run_url}}"
  consumes:
    - type: http
      namespace: servicenow-devops
      baseUri: "https://heineken.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams-devops
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{channel_id}}/channels/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Triggers an Azure DevOps pipeline and posts the run status to Microsoft Teams.

naftiko: "0.5"
info:
  label: "Azure DevOps Pipeline Trigger"
  description: "Triggers an Azure DevOps pipeline and posts the run status to Microsoft Teams."
  tags:
    - engineering
    - cicd
    - azure-devops
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: cicd-ops
      port: 8080
      tools:
        - name: trigger-pipeline
          description: "Given a project and pipeline ID, trigger a build and notify Teams."
          inputParameters:
            - name: project
              in: body
              type: string
              description: "Azure DevOps project."
            - name: pipeline_id
              in: body
              type: string
              description: "Pipeline ID."
          steps:
            - name: trigger-build
              type: call
              call: azdo.queue-build
              with:
                project: "{{project}}"
                definition_id: "{{pipeline_id}}"
            - name: notify-teams
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "engineering"
                text: "Pipeline {{pipeline_id}} triggered in {{project}}: build {{trigger-build.id}}"
  consumes:
    - type: http
      namespace: azdo
      baseUri: "https://dev.azure.com/heineken"
      authentication:
        type: basic
        username: ""
        password: "$secrets.azdo_pat"
      resources:
        - name: builds
          path: "/{{project}}/_apis/build/builds"
          inputParameters:
            - name: project
              in: path
          operations:
            - name: queue-build
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

When an Azure IoT Hub brewery sensor reading exceeds threshold, creates a ServiceNow incident and alerts the operations Microsoft Teams channel.

naftiko: "0.5"
info:
  label: "Azure IoT Brewery Sensor Alert"
  description: "When an Azure IoT Hub brewery sensor reading exceeds threshold, creates a ServiceNow incident and alerts the operations Microsoft Teams channel."
  tags:
    - manufacturing
    - iot
    - azure-monitor
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: brewery-ops
      port: 8080
      tools:
        - name: handle-sensor-alert
          description: "Given a sensor ID and reading value, create a ServiceNow incident and notify Teams."
          inputParameters:
            - name: sensor_id
              in: body
              type: string
              description: "IoT sensor ID."
            - name: reading_value
              in: body
              type: number
              description: "Sensor reading value."
            - name: threshold
              in: body
              type: number
              description: "Alert threshold."
          steps:
            - name: create-incident
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Brewery sensor alert: {{sensor_id}} reading {{reading_value}} exceeds {{threshold}}"
                category: "Manufacturing"
            - name: notify-ops
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "brewery-ops"
                text: "Sensor {{sensor_id}}: {{reading_value}} (threshold: {{threshold}}) | SNOW: {{create-incident.number}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://heineken.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Triggers a Terraform Cloud workspace run to provision or update Azure infrastructure, then reports run status and output to the platform engineering Teams channel.

naftiko: "0.5"
info:
  label: "Azure Terraform Infrastructure Provisioning"
  description: "Triggers a Terraform Cloud workspace run to provision or update Azure infrastructure, then reports run status and output to the platform engineering Teams channel."
  tags:
    - cloud
    - infrastructure
    - azure
    - terraform
    - devops
capability:
  exposes:
    - type: mcp
      namespace: platform-engineering
      port: 8080
      tools:
        - name: run-terraform-workspace
          description: "Given a Terraform Cloud workspace ID and optional message, trigger a plan-and-apply run and notify the platform engineering channel in Teams with the run ID and status."
          inputParameters:
            - name: workspace_id
              in: body
              type: string
              description: "The Terraform Cloud workspace ID to trigger a run in."
            - name: run_message
              in: body
              type: string
              description: "Human-readable message describing the purpose of this run."
          steps:
            - name: trigger-run
              type: call
              call: "terraform.create-run"
              with:
                workspace_id: "{{workspace_id}}"
                message: "{{run_message}}"
            - name: notify-platform
              type: call
              call: "msteams-platform.post-channel-message"
              with:
                channel_id: "$secrets.teams_platform_channel_id"
                message: "Terraform run triggered | Workspace: {{workspace_id}} | Message: {{run_message}} | Run ID: {{trigger-run.run_id}}"
  consumes:
    - type: http
      namespace: terraform
      baseUri: "https://app.terraform.io/api/v2"
      authentication:
        type: bearer
        token: "$secrets.terraform_token"
      resources:
        - name: runs
          path: "/runs"
          operations:
            - name: create-run
              method: POST
    - type: http
      namespace: msteams-platform
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{channel_id}}/channels/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Searches Confluence knowledge base by keyword.

naftiko: "0.5"
info:
  label: "Confluence Knowledge Article Search"
  description: "Searches Confluence knowledge base by keyword."
  tags:
    - documentation
    - collaboration
    - confluence
capability:
  exposes:
    - type: mcp
      namespace: docs-ops
      port: 8080
      tools:
        - name: search-kb
          description: "Search Confluence for knowledge articles by keyword."
          inputParameters:
            - name: keyword
              in: body
              type: string
              description: "Search keyword."
          call: confluence.search
          with:
            cql: "type=page AND text~'{{keyword}}'"
          outputParameters:
            - name: results
              type: array
              mapping: "$.results[*]"
  consumes:
    - type: http
      namespace: confluence
      baseUri: "https://heineken.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_token"
      resources:
        - name: search
          path: "/search"
          operations:
            - name: search
              method: GET

Retrieves the status of a Databricks ETL job run.

naftiko: "0.5"
info:
  label: "Databricks ETL Pipeline Status"
  description: "Retrieves the status of a Databricks ETL job run."
  tags:
    - data-engineering
    - analytics
    - databricks
capability:
  exposes:
    - type: mcp
      namespace: data-ops
      port: 8080
      tools:
        - name: get-etl-status
          description: "Given a run ID, return the Databricks job status."
          inputParameters:
            - name: run_id
              in: body
              type: string
              description: "Databricks run ID."
          call: databricks.get-run
          with:
            run_id: "{{run_id}}"
          outputParameters:
            - name: state
              type: string
              mapping: "$.state.life_cycle_state"
            - name: result
              type: string
              mapping: "$.state.result_state"
  consumes:
    - type: http
      namespace: databricks
      baseUri: "https://heineken.cloud.databricks.com/api/2.1"
      authentication:
        type: bearer
        token: "$secrets.databricks_token"
      resources:
        - name: runs
          path: "/jobs/runs/get"
          inputParameters:
            - name: run_id
              in: query
          operations:
            - name: get-run
              method: GET

Queries Datadog for brewery system metrics and returns current values.

naftiko: "0.5"
info:
  label: "Datadog Brewery Monitoring"
  description: "Queries Datadog for brewery system metrics and returns current values."
  tags:
    - monitoring
    - manufacturing
    - datadog
capability:
  exposes:
    - type: mcp
      namespace: brewery-ops
      port: 8080
      tools:
        - name: query-brewery-metrics
          description: "Given a Datadog metric query for brewery systems, return latest data points."
          inputParameters:
            - name: query
              in: body
              type: string
              description: "Datadog metric query."
          call: datadog.query-timeseries
          with:
            query: "{{query}}"
          outputParameters:
            - name: series
              type: array
              mapping: "$.series"
  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: query
          path: "/query"
          operations:
            - name: query-timeseries
              method: GET

When a Datadog monitor alert fires, creates a ServiceNow incident, posts a Teams notification to the on-call channel, and tags the affected host for investigation.

naftiko: "0.5"
info:
  label: "Datadog Infrastructure Alert Handler"
  description: "When a Datadog monitor alert fires, creates a ServiceNow incident, posts a Teams notification to the on-call channel, and tags the affected host for investigation."
  tags:
    - itsm
    - observability
    - datadog
    - servicenow
    - microsoft-teams
    - incident-response
capability:
  exposes:
    - type: mcp
      namespace: infra-ops
      port: 8080
      tools:
        - name: handle-infra-alert
          description: "Given a Datadog monitor ID and alert details, create a ServiceNow incident and notify the on-call Teams channel. Use when Datadog fires a P1 or P2 monitor alert requiring immediate response."
          inputParameters:
            - name: monitor_id
              in: body
              type: string
              description: "The Datadog monitor ID that triggered the alert."
            - name: alert_title
              in: body
              type: string
              description: "Human-readable alert title from Datadog."
            - name: affected_host
              in: body
              type: string
              description: "Hostname or IP address of the affected infrastructure."
            - name: severity
              in: body
              type: string
              description: "Alert severity: P1 or P2."
          steps:
            - name: create-incident
              type: call
              call: "servicenow-infra.create-incident"
              with:
                short_description: "[{{severity}}] {{alert_title}} on {{affected_host}}"
                urgency: "1"
                category: "infrastructure"
            - name: notify-oncall
              type: call
              call: "msteams-infra.post-channel-message"
              with:
                channel_id: "$secrets.teams_oncall_channel_id"
                message: "ALERT {{severity}}: {{alert_title}} | Host: {{affected_host}} | Monitor: {{monitor_id}} | Incident: {{create-incident.number}}"
  consumes:
    - type: http
      namespace: servicenow-infra
      baseUri: "https://heineken.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams-infra
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{channel_id}}/channels/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Mutes a set of Datadog monitors during a scheduled maintenance window and posts the mute schedule to the on-call Teams channel for visibility.

naftiko: "0.5"
info:
  label: "Datadog Monitor Mute During Maintenance"
  description: "Mutes a set of Datadog monitors during a scheduled maintenance window and posts the mute schedule to the on-call Teams channel for visibility."
  tags:
    - observability
    - maintenance
    - datadog
    - microsoft-teams
    - itsm
capability:
  exposes:
    - type: mcp
      namespace: maintenance-ops
      port: 8080
      tools:
        - name: mute-monitors-for-maintenance
          description: "Given a list of Datadog monitor IDs and a maintenance window duration, mute the monitors and notify the on-call channel in Teams. Use before planned infrastructure maintenance or deployments."
          inputParameters:
            - name: monitor_id
              in: body
              type: string
              description: "The Datadog monitor ID to mute during maintenance."
            - name: duration_seconds
              in: body
              type: integer
              description: "Duration of the mute in seconds, e.g. 3600 for one hour."
            - name: message
              in: body
              type: string
              description: "Reason for muting, e.g. Scheduled database maintenance."
          steps:
            - name: mute-monitor
              type: call
              call: "datadog-mute.mute-monitor"
              with:
                monitor_id: "{{monitor_id}}"
                duration: "{{duration_seconds}}"
            - name: notify-oncall
              type: call
              call: "msteams-maint.post-channel-message"
              with:
                channel_id: "$secrets.teams_oncall_channel_id"
                message: "Datadog monitor {{monitor_id}} muted for {{duration_seconds}}s. Reason: {{message}}. Alerts suppressed during maintenance window."
  consumes:
    - type: http
      namespace: datadog-mute
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: monitor-mute
          path: "/monitor/{{monitor_id}}/mute"
          inputParameters:
            - name: monitor_id
              in: path
          operations:
            - name: mute-monitor
              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/{{channel_id}}/channels/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Retrieves SLO compliance data from Datadog for a specified service, and publishes a weekly compliance digest to the engineering leadership Teams channel.

naftiko: "0.5"
info:
  label: "Datadog SLO Compliance Report"
  description: "Retrieves SLO compliance data from Datadog for a specified service, and publishes a weekly compliance digest to the engineering leadership Teams channel."
  tags:
    - observability
    - slo
    - datadog
    - microsoft-teams
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: observability-reporting
      port: 8080
      tools:
        - name: digest-slo-compliance
          description: "Given a Datadog SLO ID and time window, retrieve compliance percentage and error budget, then post a summary to the engineering leadership channel in Teams."
          inputParameters:
            - name: slo_id
              in: body
              type: string
              description: "The Datadog SLO ID to check compliance for."
            - name: time_window
              in: body
              type: string
              description: "SLO time window, e.g. 7d or 30d."
          steps:
            - name: get-slo
              type: call
              call: "datadog.get-slo-status"
              with:
                slo_id: "{{slo_id}}"
            - name: post-digest
              type: call
              call: "msteams-eng.post-channel-message"
              with:
                channel_id: "$secrets.teams_engineering_channel_id"
                message: "SLO Compliance Report | SLO: {{slo_id}} | Window: {{time_window}} | Data retrieved from Datadog. Review full details in Datadog dashboard."
  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: slos
          path: "/slo/{{slo_id}}/history"
          inputParameters:
            - name: slo_id
              in: path
          operations:
            - name: get-slo-status
              method: GET
    - type: http
      namespace: msteams-eng
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{channel_id}}/channels/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Retrieves the signing status of a DocuSign distributor agreement.

naftiko: "0.5"
info:
  label: "DocuSign Distributor Agreement Status"
  description: "Retrieves the signing status of a DocuSign distributor agreement."
  tags:
    - legal
    - distribution
    - docusign
capability:
  exposes:
    - type: mcp
      namespace: legal-ops
      port: 8080
      tools:
        - name: get-agreement-status
          description: "Given a DocuSign envelope ID, return signing status."
          inputParameters:
            - name: envelope_id
              in: body
              type: string
              description: "DocuSign envelope ID."
          call: docusign.get-envelope
          with:
            envelope_id: "{{envelope_id}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.status"
            - name: completed_date
              type: string
              mapping: "$.completedDateTime"
  consumes:
    - type: http
      namespace: docusign
      baseUri: "https://na4.docusign.net/restapi/v2.1/accounts/$secrets.docusign_account_id"
      authentication:
        type: bearer
        token: "$secrets.docusign_token"
      resources:
        - name: envelopes
          path: "/envelopes/{{envelope_id}}"
          inputParameters:
            - name: envelope_id
              in: path
          operations:
            - name: get-envelope
              method: GET

Searches the product catalog in Elasticsearch by keyword.

naftiko: "0.5"
info:
  label: "Elasticsearch Product Search"
  description: "Searches the product catalog in Elasticsearch by keyword."
  tags:
    - data
    - search
    - elasticsearch
capability:
  exposes:
    - type: mcp
      namespace: product-ops
      port: 8080
      tools:
        - name: search-products
          description: "Given a keyword, search the Elasticsearch product index."
          inputParameters:
            - name: query
              in: body
              type: string
              description: "Search query."
          call: elasticsearch.search
          with:
            index: "products"
            q: "{{query}}"
          outputParameters:
            - name: hits
              type: array
              mapping: "$.hits.hits[*]._source"
  consumes:
    - type: http
      namespace: elasticsearch
      baseUri: "https://heineken-es.azure.elastic-cloud.com"
      authentication:
        type: bearer
        token: "$secrets.elasticsearch_token"
      resources:
        - name: search
          path: "/products/_search"
          operations:
            - name: search
              method: POST

When a new hire is created in Workday, opens a ServiceNow onboarding ticket, provisions a SharePoint document folder, and sends a Microsoft Teams welcome message with role and start date details.

naftiko: "0.5"
info:
  label: "Employee Onboarding Orchestrator"
  description: "When a new hire is created in Workday, opens a ServiceNow onboarding ticket, provisions a SharePoint document folder, and sends a Microsoft Teams welcome message with role and start date details."
  tags:
    - hr
    - onboarding
    - workday
    - servicenow
    - sharepoint
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: hr-onboarding
      port: 8080
      tools:
        - name: trigger-onboarding
          description: "Given a Workday employee ID and start date, orchestrate the full onboarding sequence by opening a ServiceNow ticket, provisioning a SharePoint folder, and sending a Teams welcome message."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "The Workday worker ID for the new hire."
            - name: start_date
              in: body
              type: string
              description: "The employee's start date in YYYY-MM-DD format."
          steps:
            - name: get-worker
              type: call
              call: "workday.get-worker"
              with:
                worker_id: "{{employee_id}}"
            - name: create-ticket
              type: call
              call: "servicenow.create-incident"
              with:
                short_description: "New hire onboarding: {{get-worker.display_name}}"
                category: "hr_onboarding"
                assigned_to: "IT_Onboarding"
            - name: provision-folder
              type: call
              call: "sharepoint.create-folder"
              with:
                site_id: "heineken-hr-onboarding"
                folder_path: "OnboardingDocs/{{get-worker.display_name}}_{{start_date}}"
            - name: send-welcome
              type: call
              call: "msteams.send-message"
              with:
                recipient_upn: "{{get-worker.work_email}}"
                message: "Welcome to Heineken, {{get-worker.first_name}}! Your onboarding ticket is {{create-ticket.number}}. Start date: {{start_date}}."
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/heineken/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://heineken.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: sharepoint
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: drive-items
          path: "/sites/{{site_id}}/drive/root/children"
          inputParameters:
            - name: site_id
              in: path
          operations:
            - name: create-folder
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: chats
          path: "/users/{{recipient_upn}}/sendMail"
          inputParameters:
            - name: recipient_upn
              in: path
          operations:
            - name: send-message
              method: POST

Posts a packaging design review request to Microsoft Teams when a Figma file is updated.

naftiko: "0.5"
info:
  label: "Figma Packaging Design Review"
  description: "Posts a packaging design review request to Microsoft Teams when a Figma file is updated."
  tags:
    - design
    - brand
    - figma
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: design-ops
      port: 8080
      tools:
        - name: request-packaging-review
          description: "Fetch Figma file info and post a review request to Teams."
          inputParameters:
            - name: file_key
              in: body
              type: string
              description: "Figma file key."
          steps:
            - name: get-file
              type: call
              call: figma.get-file
              with:
                file_key: "{{file_key}}"
            - name: post-review
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "brand-design"
                text: "Packaging design review: {{get-file.name}} — https://www.figma.com/file/{{file_key}}"
  consumes:
    - type: http
      namespace: figma
      baseUri: "https://api.figma.com/v1"
      authentication:
        type: bearer
        token: "$secrets.figma_token"
      resources:
        - name: files
          path: "/files/{{file_key}}"
          inputParameters:
            - name: file_key
              in: path
          operations:
            - name: get-file
              method: GET
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Triggers a GitHub Actions workflow and notifies Microsoft Teams.

naftiko: "0.5"
info:
  label: "GitHub Actions Workflow Trigger"
  description: "Triggers a GitHub Actions workflow and notifies Microsoft Teams."
  tags:
    - engineering
    - cicd
    - github-actions
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: cicd-ops
      port: 8080
      tools:
        - name: trigger-workflow
          description: "Trigger a GitHub Actions workflow dispatch and notify Teams."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "GitHub repo."
            - name: workflow_id
              in: body
              type: string
              description: "Workflow file name."
            - name: ref
              in: body
              type: string
              description: "Git ref."
          steps:
            - name: dispatch
              type: call
              call: github.create-workflow-dispatch
              with:
                repo: "{{repo}}"
                workflow_id: "{{workflow_id}}"
                ref: "{{ref}}"
            - name: notify
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "engineering"
                text: "Workflow {{workflow_id}} triggered on {{repo}}"
  consumes:
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: dispatches
          path: "/repos/{{repo}}/actions/workflows/{{workflow_id}}/dispatches"
          inputParameters:
            - name: repo
              in: path
            - name: workflow_id
              in: path
          operations:
            - name: create-workflow-dispatch
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Fetches open Dependabot alerts and posts severity summary to the security Microsoft Teams channel.

naftiko: "0.5"
info:
  label: "GitHub Security Alert Digest"
  description: "Fetches open Dependabot alerts and posts severity summary to the security Microsoft Teams channel."
  tags:
    - security
    - engineering
    - github
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: appsec
      port: 8080
      tools:
        - name: digest-security-alerts
          description: "Given a GitHub repo, fetch alerts and post summary to Teams."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "GitHub repo in org/repo format."
          steps:
            - name: get-alerts
              type: call
              call: github.list-dependabot-alerts
              with:
                repo: "{{repo}}"
                state: "open"
            - name: post-digest
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "security"
                text: "Security alerts for {{repo}}: {{get-alerts.total}} open"
  consumes:
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: alerts
          path: "/repos/{{repo}}/dependabot/alerts"
          inputParameters:
            - name: repo
              in: path
          operations:
            - name: list-dependabot-alerts
              method: GET
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Retrieves e-commerce analytics from Google Analytics for the Heineken webshop and posts to Microsoft Teams.

naftiko: "0.5"
info:
  label: "Google Analytics E-commerce Report"
  description: "Retrieves e-commerce analytics from Google Analytics for the Heineken webshop and posts to Microsoft Teams."
  tags:
    - analytics
    - ecommerce
    - google-analytics
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: ecom-analytics
      port: 8080
      tools:
        - name: post-ecommerce-report
          description: "Fetch weekly e-commerce metrics and post to Teams."
          inputParameters:
            - name: property_id
              in: body
              type: string
              description: "GA property ID."
          steps:
            - name: get-report
              type: call
              call: ga.run-report
              with:
                property_id: "{{property_id}}"
                date_range: "last7days"
            - name: post-teams
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "ecommerce"
                text: "Webshop weekly: {{get-report.transactions}} transactions, {{get-report.revenue}} revenue"
  consumes:
    - type: http
      namespace: ga
      baseUri: "https://analyticsdata.googleapis.com/v1beta"
      authentication:
        type: bearer
        token: "$secrets.google_analytics_token"
      resources:
        - name: reports
          path: "/properties/{{property_id}}:runReport"
          inputParameters:
            - name: property_id
              in: path
          operations:
            - name: run-report
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Calculates the optimal delivery route between distributor locations using Google Maps Directions API.

naftiko: "0.5"
info:
  label: "Google Maps Distributor Route Optimization"
  description: "Calculates the optimal delivery route between distributor locations using Google Maps Directions API."
  tags:
    - logistics
    - distribution
    - google-maps
capability:
  exposes:
    - type: mcp
      namespace: logistics-ops
      port: 8080
      tools:
        - name: optimize-route
          description: "Given origin and destination addresses, calculate the optimal driving route."
          inputParameters:
            - name: origin
              in: body
              type: string
              description: "Origin address."
            - name: destination
              in: body
              type: string
              description: "Destination address."
          call: gmaps.get-directions
          with:
            origin: "{{origin}}"
            destination: "{{destination}}"
          outputParameters:
            - name: distance
              type: string
              mapping: "$.routes[0].legs[0].distance.text"
            - name: duration
              type: string
              mapping: "$.routes[0].legs[0].duration.text"
  consumes:
    - type: http
      namespace: gmaps
      baseUri: "https://maps.googleapis.com/maps/api"
      authentication:
        type: apikey
        key: "key"
        value: "$secrets.google_maps_api_key"
        placement: query
      resources:
        - name: directions
          path: "/directions/json"
          operations:
            - name: get-directions
              method: GET

Retrieves the state of a Grafana production monitoring alert rule.

naftiko: "0.5"
info:
  label: "Grafana Production Dashboard"
  description: "Retrieves the state of a Grafana production monitoring alert rule."
  tags:
    - monitoring
    - manufacturing
    - grafana
capability:
  exposes:
    - type: mcp
      namespace: brewery-ops
      port: 8080
      tools:
        - name: get-production-alert
          description: "Given a Grafana alert UID, return its firing state."
          inputParameters:
            - name: rule_uid
              in: body
              type: string
              description: "Grafana alert rule UID."
          call: grafana.get-alert-rule
          with:
            uid: "{{rule_uid}}"
          outputParameters:
            - name: state
              type: string
              mapping: "$.state"
  consumes:
    - type: http
      namespace: grafana
      baseUri: "https://grafana.heineken.com/api"
      authentication:
        type: bearer
        token: "$secrets.grafana_token"
      resources:
        - name: alert-rules
          path: "/v1/provisioning/alert-rules/{{uid}}"
          inputParameters:
            - name: uid
              in: path
          operations:
            - name: get-alert-rule
              method: GET

Fetches resolved Jira issues for a version and creates a Confluence release notes page.

naftiko: "0.5"
info:
  label: "Jira Release Notes Creation"
  description: "Fetches resolved Jira issues for a version and creates a Confluence release notes page."
  tags:
    - engineering
    - release-management
    - jira
    - confluence
capability:
  exposes:
    - type: mcp
      namespace: release-ops
      port: 8080
      tools:
        - name: create-release-notes
          description: "Given a project and version, create Confluence release notes."
          inputParameters:
            - name: project_key
              in: body
              type: string
              description: "Jira project key."
            - name: version
              in: body
              type: string
              description: "Fix version."
          steps:
            - name: get-issues
              type: call
              call: jira.search-issues
              with:
                jql: "project={{project_key}} AND fixVersion='{{version}}' AND status=Done"
            - name: create-page
              type: call
              call: confluence.create-content
              with:
                space_key: "RELEASES"
                title: "Release Notes — {{version}}"
                body: "{{get-issues.formatted}}"
  consumes:
    - type: http
      namespace: jira
      baseUri: "https://heineken.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_token"
      resources:
        - name: search
          path: "/search"
          operations:
            - name: search-issues
              method: POST
    - type: http
      namespace: confluence
      baseUri: "https://heineken.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_token"
      resources:
        - name: content
          path: "/content"
          operations:
            - name: create-content
              method: POST

Fetches Jira sprint completion data and posts velocity report to Microsoft Teams.

naftiko: "0.5"
info:
  label: "Jira Sprint Report to Teams"
  description: "Fetches Jira sprint completion data and posts velocity report to Microsoft Teams."
  tags:
    - engineering
    - project-management
    - jira
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: eng-ops
      port: 8080
      tools:
        - name: post-sprint-report
          description: "Given a Jira board ID, fetch sprint data and post to Teams."
          inputParameters:
            - name: board_id
              in: body
              type: string
              description: "Jira board ID."
          steps:
            - name: get-sprint
              type: call
              call: jira.get-active-sprint
              with:
                board_id: "{{board_id}}"
            - name: post-report
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "engineering"
                text: "Sprint report for board {{board_id}}: {{get-sprint.completedIssues}} completed, {{get-sprint.remainingIssues}} remaining"
  consumes:
    - type: http
      namespace: jira
      baseUri: "https://heineken.atlassian.net/rest/agile/1.0"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_token"
      resources:
        - name: sprints
          path: "/board/{{board_id}}/sprint"
          inputParameters:
            - name: board_id
              in: path
          operations:
            - name: get-active-sprint
              method: GET
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Fetches LinkedIn brand campaign analytics and posts the engagement digest to Microsoft Teams.

naftiko: "0.5"
info:
  label: "LinkedIn Brand Campaign Analytics"
  description: "Fetches LinkedIn brand campaign analytics and posts the engagement digest to Microsoft Teams."
  tags:
    - marketing
    - social-media
    - linkedin
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: social-ops
      port: 8080
      tools:
        - name: post-campaign-digest
          description: "Fetch LinkedIn campaign analytics and post to Teams."
          inputParameters:
            - name: campaign_id
              in: body
              type: string
              description: "LinkedIn campaign ID."
          steps:
            - name: get-analytics
              type: call
              call: linkedin.get-campaign-analytics
              with:
                campaign_id: "{{campaign_id}}"
            - name: post-digest
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "marketing"
                text: "LinkedIn campaign {{campaign_id}}: {{get-analytics.impressions}} impressions, {{get-analytics.clicks}} clicks"
  consumes:
    - type: http
      namespace: linkedin
      baseUri: "https://api.linkedin.com/v2"
      authentication:
        type: bearer
        token: "$secrets.linkedin_token"
      resources:
        - name: analytics
          path: "/adAnalyticsV2"
          operations:
            - name: get-campaign-analytics
              method: GET
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Retrieves engagement metrics for Heineken's LinkedIn sponsored content campaigns over the past 30 days and posts a digest summary to the marketing Teams channel.

naftiko: "0.5"
info:
  label: "LinkedIn Employer Brand Campaign Digest"
  description: "Retrieves engagement metrics for Heineken's LinkedIn sponsored content campaigns over the past 30 days and posts a digest summary to the marketing Teams channel."
  tags:
    - marketing
    - social
    - linkedin
    - microsoft-teams
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: marketing-reporting
      port: 8080
      tools:
        - name: digest-linkedin-campaigns
          description: "Retrieve LinkedIn campaign analytics for the last 30 days and post a digest of impressions, clicks, and engagement rates to the marketing channel in Teams."
          inputParameters:
            - name: campaign_group_id
              in: body
              type: string
              description: "The LinkedIn campaign group ID to pull metrics for."
          steps:
            - name: get-analytics
              type: call
              call: "linkedin.get-campaign-analytics"
              with:
                campaign_group_id: "{{campaign_group_id}}"
            - name: post-digest
              type: call
              call: "msteams-mktg.post-channel-message"
              with:
                channel_id: "$secrets.teams_marketing_channel_id"
                message: "LinkedIn Campaign Digest (last 30 days) | Campaign Group: {{campaign_group_id}} | Analytics retrieved. Review dashboard for full breakdown."
  consumes:
    - type: http
      namespace: linkedin
      baseUri: "https://api.linkedin.com/v2"
      authentication:
        type: bearer
        token: "$secrets.linkedin_token"
      resources:
        - name: campaign-analytics
          path: "/adAnalyticsV2"
          inputParameters:
            - name: campaign_group_id
              in: query
          operations:
            - name: get-campaign-analytics
              method: GET
    - type: http
      namespace: msteams-mktg
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{channel_id}}/channels/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Retrieves Instagram ad campaign metrics from Meta Ads API.

naftiko: "0.5"
info:
  label: "Meta Instagram Campaign Report"
  description: "Retrieves Instagram ad campaign metrics from Meta Ads API."
  tags:
    - marketing
    - advertising
    - meta
    - instagram
capability:
  exposes:
    - type: mcp
      namespace: paid-media
      port: 8080
      tools:
        - name: get-instagram-metrics
          description: "Given a campaign ID, return reach, impressions, and spend."
          inputParameters:
            - name: campaign_id
              in: body
              type: string
              description: "Meta campaign ID."
          call: meta-ads.get-insights
          with:
            campaign_id: "{{campaign_id}}"
          outputParameters:
            - name: reach
              type: integer
              mapping: "$.data[0].reach"
            - name: impressions
              type: integer
              mapping: "$.data[0].impressions"
            - name: spend
              type: string
              mapping: "$.data[0].spend"
  consumes:
    - type: http
      namespace: meta-ads
      baseUri: "https://graph.facebook.com/v18.0"
      authentication:
        type: bearer
        token: "$secrets.meta_ads_token"
      resources:
        - name: insights
          path: "/{{campaign_id}}/insights"
          inputParameters:
            - name: campaign_id
              in: path
          operations:
            - name: get-insights
              method: GET

Retrieves impression, reach, and engagement metrics for Heineken's Meta (Facebook/Instagram) ad campaigns and posts a weekly performance digest to the marketing Teams channel.

naftiko: "0.5"
info:
  label: "Meta Social Campaign Performance Digest"
  description: "Retrieves impression, reach, and engagement metrics for Heineken's Meta (Facebook/Instagram) ad campaigns and posts a weekly performance digest to the marketing Teams channel."
  tags:
    - marketing
    - social
    - meta
    - microsoft-teams
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: social-reporting
      port: 8080
      tools:
        - name: digest-meta-performance
          description: "Given a Meta ad account ID and date range, retrieve campaign performance metrics (impressions, reach, spend, CTR) and post a digest to the marketing Teams channel."
          inputParameters:
            - name: ad_account_id
              in: body
              type: string
              description: "The Meta ad account ID, e.g. act_123456789."
            - name: date_preset
              in: body
              type: string
              description: "Meta Insights date preset, e.g. last_7d or last_30d."
          steps:
            - name: get-insights
              type: call
              call: "meta.get-ad-insights"
              with:
                ad_account_id: "{{ad_account_id}}"
                date_preset: "{{date_preset}}"
            - name: post-digest
              type: call
              call: "msteams-social.post-channel-message"
              with:
                channel_id: "$secrets.teams_marketing_channel_id"
                message: "Meta Campaign Performance | Account: {{ad_account_id}} | Period: {{date_preset}} | Insights retrieved. Full data in marketing dashboard."
  consumes:
    - type: http
      namespace: meta
      baseUri: "https://graph.facebook.com/v18.0"
      authentication:
        type: bearer
        token: "$secrets.meta_access_token"
      resources:
        - name: ad-insights
          path: "/{{ad_account_id}}/insights"
          inputParameters:
            - name: ad_account_id
              in: path
            - name: date_preset
              in: query
          operations:
            - name: get-ad-insights
              method: GET
    - type: http
      namespace: msteams-social
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{channel_id}}/channels/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Retrieves Microsoft 365 license usage data.

naftiko: "0.5"
info:
  label: "Microsoft 365 License Report"
  description: "Retrieves Microsoft 365 license usage data."
  tags:
    - it-operations
    - license-management
    - microsoft-365
capability:
  exposes:
    - type: mcp
      namespace: it-ops
      port: 8080
      tools:
        - name: get-license-report
          description: "Retrieve M365 license usage data."
          inputParameters:
            - name: period
              in: body
              type: string
              description: "Report period (D7, D30)."
          call: msgraph.get-license-report
          with:
            period: "{{period}}"
          outputParameters:
            - name: data
              type: array
              mapping: "$.value"
  consumes:
    - type: http
      namespace: msgraph
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: reports
          path: "/reports/getOffice365ActiveUserDetail(period='{{period}}')"
          inputParameters:
            - name: period
              in: path
          operations:
            - name: get-license-report
              method: GET

Assigns an Okta user to an application and logs the action to ServiceNow.

naftiko: "0.5"
info:
  label: "Okta App Provisioning"
  description: "Assigns an Okta user to an application and logs the action to ServiceNow."
  tags:
    - identity
    - provisioning
    - okta
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: iam-ops
      port: 8080
      tools:
        - name: assign-app
          description: "Assign a user to an Okta app and log to ServiceNow."
          inputParameters:
            - name: user_id
              in: body
              type: string
              description: "Okta user ID."
            - name: app_id
              in: body
              type: string
              description: "Okta app ID."
          steps:
            - name: assign
              type: call
              call: okta.assign-app
              with:
                app_id: "{{app_id}}"
                user_id: "{{user_id}}"
            - name: log-audit
              type: call
              call: servicenow.create-record
              with:
                table: "u_access_audit"
                user_id: "{{user_id}}"
                app: "{{app_id}}"
  consumes:
    - type: http
      namespace: okta
      baseUri: "https://heineken.okta.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.okta_api_token"
      resources:
        - name: app-users
          path: "/apps/{{app_id}}/users"
          inputParameters:
            - name: app_id
              in: path
          operations:
            - name: assign-app
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://heineken.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: records
          path: "/table/{{table}}"
          inputParameters:
            - name: table
              in: path
          operations:
            - name: create-record
              method: POST

Retrieves all Okta group memberships for a user for quarterly access review.

naftiko: "0.5"
info:
  label: "Okta User Access Review"
  description: "Retrieves all Okta group memberships for a user for quarterly access review."
  tags:
    - identity
    - access-management
    - okta
capability:
  exposes:
    - type: mcp
      namespace: iam
      port: 8080
      tools:
        - name: get-user-groups
          description: "Given an Okta user ID, return all group memberships."
          inputParameters:
            - name: user_id
              in: body
              type: string
              description: "Okta user ID."
          call: okta.list-groups
          with:
            user_id: "{{user_id}}"
          outputParameters:
            - name: groups
              type: array
              mapping: "$.[*].profile.name"
  consumes:
    - type: http
      namespace: okta
      baseUri: "https://heineken.okta.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.okta_api_token"
      resources:
        - name: user-groups
          path: "/users/{{user_id}}/groups"
          inputParameters:
            - name: user_id
              in: path
          operations:
            - name: list-groups
              method: GET

Uses OpenAI to generate marketing product descriptions for new beer variants and stores them in Salesforce.

naftiko: "0.5"
info:
  label: "OpenAI Product Description Generation"
  description: "Uses OpenAI to generate marketing product descriptions for new beer variants and stores them in Salesforce."
  tags:
    - ai
    - marketing
    - openai
    - salesforce
capability:
  exposes:
    - type: mcp
      namespace: marketing-ai
      port: 8080
      tools:
        - name: generate-product-description
          description: "Given product attributes, generate a marketing description via OpenAI and store in Salesforce."
          inputParameters:
            - name: product_name
              in: body
              type: string
              description: "Product name."
            - name: style
              in: body
              type: string
              description: "Beer style."
            - name: abv
              in: body
              type: string
              description: "ABV percentage."
          steps:
            - name: generate
              type: call
              call: openai.create-completion
              with:
                model: "gpt-4"
                prompt: "Write a compelling 50-word marketing description for {{product_name}}, a {{style}} beer at {{abv}}% ABV."
            - name: store-in-sf
              type: call
              call: salesforce.update-product
              with:
                product_name: "{{product_name}}"
                description: "{{generate.text}}"
  consumes:
    - type: http
      namespace: openai
      baseUri: "https://api.openai.com/v1"
      authentication:
        type: bearer
        token: "$secrets.openai_api_key"
      resources:
        - name: completions
          path: "/chat/completions"
          operations:
            - name: create-completion
              method: POST
    - type: http
      namespace: salesforce
      baseUri: "https://heineken.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: products
          path: "/sobjects/Product2"
          operations:
            - name: update-product
              method: PATCH

Retrieves current headcount by department and cost center from Workday, returning employee counts and salary band data for workforce planning and finance reporting.

naftiko: "0.5"
info:
  label: "Payroll Headcount Snapshot"
  description: "Retrieves current headcount by department and cost center from Workday, returning employee counts and salary band data for workforce planning and finance reporting."
  tags:
    - hr
    - finance
    - reporting
    - workday
    - headcount
capability:
  exposes:
    - type: mcp
      namespace: hr-reporting
      port: 8080
      tools:
        - name: get-headcount-snapshot
          description: "Returns a headcount breakdown by department and cost center from Workday. Use for workforce planning, finance reconciliation, or headcount audits."
          call: "workday-hc.headcount-report"
          outputParameters:
            - name: employees
              type: array
              mapping: "$.Report_Entry"
              items:
                - name: employee_id
                  type: string
                  mapping: "$.Employee_ID"
                - name: full_name
                  type: string
                  mapping: "$.Employee_Name"
                - name: department
                  type: string
                  mapping: "$.Department"
                - name: cost_center
                  type: string
                  mapping: "$.Cost_Center"
                - name: employment_type
                  type: string
                  mapping: "$.Employment_Type"
  consumes:
    - type: http
      namespace: workday-hc
      baseUri: "https://wd2-impl-services1.workday.com/ccx/service/customreport2/heineken"
      authentication:
        type: basic
        username: "$secrets.workday_report_user"
        password: "$secrets.workday_report_password"
      resources:
        - name: headcount
          path: "/Headcount_By_Department"
          operations:
            - name: headcount-report
              method: GET
              outputRawFormat: json

Retrieves latest Postman API monitor run results.

naftiko: "0.5"
info:
  label: "Postman API Monitor Check"
  description: "Retrieves latest Postman API monitor run results."
  tags:
    - engineering
    - api-management
    - postman
capability:
  exposes:
    - type: mcp
      namespace: api-ops
      port: 8080
      tools:
        - name: get-monitor-status
          description: "Given a Postman monitor ID, return pass/fail counts."
          inputParameters:
            - name: monitor_id
              in: body
              type: string
              description: "Postman monitor ID."
          call: postman.get-monitor
          with:
            monitor_id: "{{monitor_id}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.monitor.lastRun.status"
  consumes:
    - type: http
      namespace: postman
      baseUri: "https://api.getpostman.com"
      authentication:
        type: apikey
        key: "X-Api-Key"
        value: "$secrets.postman_api_key"
        placement: header
      resources:
        - name: monitors
          path: "/monitors/{{monitor_id}}"
          inputParameters:
            - name: monitor_id
              in: path
          operations:
            - name: get-monitor
              method: GET

Triggers a Power BI dataset refresh for the commercial sales dashboard and posts a confirmation with the refresh timestamp to the sales leadership Teams channel.

naftiko: "0.5"
info:
  label: "Power BI Sales Dashboard Refresh"
  description: "Triggers a Power BI dataset refresh for the commercial sales dashboard and posts a confirmation with the refresh timestamp to the sales leadership Teams channel."
  tags:
    - data-analytics
    - reporting
    - power-bi
    - microsoft-teams
    - sales
capability:
  exposes:
    - type: mcp
      namespace: analytics-reporting
      port: 8080
      tools:
        - name: refresh-sales-dashboard
          description: "Given a Power BI dataset ID and workspace ID, trigger a dataset refresh and notify the sales leadership channel in Teams. Use at the start of each business day or after a data pipeline completes."
          inputParameters:
            - name: workspace_id
              in: body
              type: string
              description: "The Power BI workspace (group) ID containing the sales dataset."
            - name: dataset_id
              in: body
              type: string
              description: "The Power BI dataset ID to refresh."
          steps:
            - name: trigger-refresh
              type: call
              call: "powerbi.refresh-dataset"
              with:
                workspace_id: "{{workspace_id}}"
                dataset_id: "{{dataset_id}}"
            - name: notify-leadership
              type: call
              call: "msteams-analytics.post-channel-message"
              with:
                channel_id: "$secrets.teams_sales_leadership_channel_id"
                message: "Sales dashboard refresh triggered for dataset {{dataset_id}} in workspace {{workspace_id}}. Data is being updated."
  consumes:
    - type: http
      namespace: powerbi
      baseUri: "https://api.powerbi.com/v1.0/myorg"
      authentication:
        type: bearer
        token: "$secrets.powerbi_token"
      resources:
        - name: dataset-refreshes
          path: "/groups/{{workspace_id}}/datasets/{{dataset_id}}/refreshes"
          inputParameters:
            - name: workspace_id
              in: path
            - name: dataset_id
              in: path
          operations:
            - name: refresh-dataset
              method: POST
    - type: http
      namespace: msteams-analytics
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{channel_id}}/channels/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Triggers a Power BI dataset refresh for the supply chain analytics dashboard.

naftiko: "0.5"
info:
  label: "Power BI Supply Chain Dashboard"
  description: "Triggers a Power BI dataset refresh for the supply chain analytics dashboard."
  tags:
    - analytics
    - supply-chain
    - power-bi
capability:
  exposes:
    - type: mcp
      namespace: bi-ops
      port: 8080
      tools:
        - name: refresh-supply-chain-dataset
          description: "Trigger a Power BI supply chain dataset refresh."
          inputParameters:
            - name: dataset_id
              in: body
              type: string
              description: "Power BI dataset ID."
            - name: group_id
              in: body
              type: string
              description: "Power BI workspace ID."
          call: powerbi.refresh-dataset
          with:
            group_id: "{{group_id}}"
            dataset_id: "{{dataset_id}}"
          outputParameters:
            - name: request_id
              type: string
              mapping: "$.requestId"
  consumes:
    - type: http
      namespace: powerbi
      baseUri: "https://api.powerbi.com/v1.0/myorg"
      authentication:
        type: bearer
        token: "$secrets.powerbi_token"
      resources:
        - name: datasets
          path: "/groups/{{group_id}}/datasets/{{dataset_id}}/refreshes"
          inputParameters:
            - name: group_id
              in: path
            - name: dataset_id
              in: path
          operations:
            - name: refresh-dataset
              method: POST

Retrieves a Salesforce distributor account record and its recent opportunities to surface relationship health metrics for the commercial team.

naftiko: "0.5"
info:
  label: "Salesforce Account Health Check"
  description: "Retrieves a Salesforce distributor account record and its recent opportunities to surface relationship health metrics for the commercial team."
  tags:
    - sales
    - crm
    - salesforce
    - commercial
capability:
  exposes:
    - type: mcp
      namespace: crm-sales
      port: 8080
      tools:
        - name: get-account-health
          description: "Given a Salesforce account ID, retrieve account details and the five most recent opportunities. Use for distributor relationship reviews and account health monitoring."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The Salesforce account ID for the distributor or key customer."
          steps:
            - name: get-account
              type: call
              call: "salesforce.get-account"
              with:
                account_id: "{{account_id}}"
            - name: get-opportunities
              type: call
              call: "salesforce-opp.list-opportunities"
              with:
                account_id: "{{account_id}}"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://heineken.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: accounts
          path: "/sobjects/Account/{{account_id}}"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: get-account
              method: GET
    - type: http
      namespace: salesforce-opp
      baseUri: "https://heineken.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: opportunities
          path: "/query"
          inputParameters:
            - name: q
              in: query
          operations:
            - name: list-opportunities
              method: GET

Retrieves a Salesforce contact by email for distributor management.

naftiko: "0.5"
info:
  label: "Salesforce Contact Lookup"
  description: "Retrieves a Salesforce contact by email for distributor management."
  tags:
    - sales
    - crm
    - salesforce
capability:
  exposes:
    - type: mcp
      namespace: crm-ops
      port: 8080
      tools:
        - name: lookup-contact
          description: "Given an email, return the Salesforce contact record."
          inputParameters:
            - name: email
              in: body
              type: string
              description: "Contact email."
          call: salesforce.query
          with:
            q: "SELECT Name, Title, Account.Name FROM Contact WHERE Email = '{{email}}'"
          outputParameters:
            - name: name
              type: string
              mapping: "$.records[0].Name"
            - name: account
              type: string
              mapping: "$.records[0].Account.Name"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://heineken.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: query
          path: "/query"
          operations:
            - name: query
              method: GET

Retrieves a new distributor lead from Salesforce, enriches it with market data, and updates the record with qualified information for the commercial team.

naftiko: "0.5"
info:
  label: "Salesforce Distributor Lead Enrichment"
  description: "Retrieves a new distributor lead from Salesforce, enriches it with market data, and updates the record with qualified information for the commercial team."
  tags:
    - sales
    - crm
    - salesforce
    - lead-management
    - commercial
capability:
  exposes:
    - type: mcp
      namespace: crm-leads
      port: 8080
      tools:
        - name: enrich-distributor-lead
          description: "Given a Salesforce lead ID, retrieve the lead record and update it with enriched qualification data. Use when a new distributor lead is created and needs commercial qualification."
          inputParameters:
            - name: lead_id
              in: body
              type: string
              description: "The Salesforce Lead record ID to enrich."
            - name: segment
              in: body
              type: string
              description: "Distributor segment classification, e.g. on-trade, off-trade, or e-commerce."
            - name: annual_volume_hl
              in: body
              type: string
              description: "Estimated annual volume in hectoliters."
          steps:
            - name: get-lead
              type: call
              call: "salesforce-lead.get-lead"
              with:
                lead_id: "{{lead_id}}"
            - name: update-lead
              type: call
              call: "salesforce-lead-update.patch-lead"
              with:
                lead_id: "{{lead_id}}"
  consumes:
    - type: http
      namespace: salesforce-lead
      baseUri: "https://heineken.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: leads
          path: "/sobjects/Lead/{{lead_id}}"
          inputParameters:
            - name: lead_id
              in: path
          operations:
            - name: get-lead
              method: GET
    - type: http
      namespace: salesforce-lead-update
      baseUri: "https://heineken.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: leads
          path: "/sobjects/Lead/{{lead_id}}"
          inputParameters:
            - name: lead_id
              in: path
          operations:
            - name: patch-lead
              method: PATCH

Retrieves distributor order status from Salesforce by order ID.

naftiko: "0.5"
info:
  label: "Salesforce Distributor Order Status"
  description: "Retrieves distributor order status from Salesforce by order ID."
  tags:
    - sales
    - distribution
    - salesforce
capability:
  exposes:
    - type: mcp
      namespace: sales-ops
      port: 8080
      tools:
        - name: get-order-status
          description: "Given a Salesforce order ID, return status, distributor, and total value."
          inputParameters:
            - name: order_id
              in: body
              type: string
              description: "Salesforce order ID."
          call: salesforce.get-order
          with:
            order_id: "{{order_id}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.Status"
            - name: distributor
              type: string
              mapping: "$.Account.Name"
            - name: total
              type: number
              mapping: "$.TotalAmount"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://heineken.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: orders
          path: "/sobjects/Order/{{order_id}}"
          inputParameters:
            - name: order_id
              in: path
          operations:
            - name: get-order
              method: GET

After a Salesforce opportunity is closed, triggers an NPS survey task on the account and logs the planned survey date for the commercial excellence team.

naftiko: "0.5"
info:
  label: "Salesforce NPS Survey Trigger"
  description: "After a Salesforce opportunity is closed, triggers an NPS survey task on the account and logs the planned survey date for the commercial excellence team."
  tags:
    - sales
    - customer-success
    - salesforce
    - nps
    - commercial
capability:
  exposes:
    - type: mcp
      namespace: crm-nps
      port: 8080
      tools:
        - name: trigger-nps-survey
          description: "Given a Salesforce account ID and contact ID, create an NPS survey task on the account record and set the survey date. Use 30 days after a Closed Won opportunity to measure customer satisfaction."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The Salesforce account ID of the customer to survey."
            - name: contact_id
              in: body
              type: string
              description: "The Salesforce contact ID of the primary contact to survey."
            - name: survey_date
              in: body
              type: string
              description: "Planned survey date in YYYY-MM-DD format."
          call: "salesforce-task.create-task"
          with:
            account_id: "{{account_id}}"
            contact_id: "{{contact_id}}"
            subject: "NPS Survey — Customer Satisfaction"
            activity_date: "{{survey_date}}"
  consumes:
    - type: http
      namespace: salesforce-task
      baseUri: "https://heineken.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: tasks
          path: "/sobjects/Task"
          operations:
            - name: create-task
              method: POST

When a Salesforce opportunity is marked Closed Won, updates the SAP S/4HANA customer master record and creates a ServiceNow customer onboarding task.

naftiko: "0.5"
info:
  label: "Salesforce Opportunity Close Sync"
  description: "When a Salesforce opportunity is marked Closed Won, updates the SAP S/4HANA customer master record and creates a ServiceNow customer onboarding task."
  tags:
    - sales
    - crm
    - salesforce
    - sap
    - erp
    - customer-onboarding
capability:
  exposes:
    - type: mcp
      namespace: crm-erp-sync
      port: 8080
      tools:
        - name: sync-closed-opportunity
          description: "Given a Salesforce opportunity ID that has been marked Closed Won, retrieve opportunity details and create a ServiceNow onboarding task for the new customer. Use to ensure seamless hand-off from sales to operations."
          inputParameters:
            - name: opportunity_id
              in: body
              type: string
              description: "The Salesforce Opportunity record ID of the closed-won deal."
          steps:
            - name: get-opportunity
              type: call
              call: "salesforce-opp-sync.get-opportunity"
              with:
                opportunity_id: "{{opportunity_id}}"
            - name: create-onboarding-task
              type: call
              call: "servicenow-crm.create-incident"
              with:
                short_description: "Customer onboarding: {{get-opportunity.account_name}}"
                category: "customer_onboarding"
                description: "Opportunity {{opportunity_id}} closed won. Account: {{get-opportunity.account_name}}. Amount: {{get-opportunity.amount}}. Begin customer onboarding process."
  consumes:
    - type: http
      namespace: salesforce-opp-sync
      baseUri: "https://heineken.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: opportunities
          path: "/sobjects/Opportunity/{{opportunity_id}}"
          inputParameters:
            - name: opportunity_id
              in: path
          operations:
            - name: get-opportunity
              method: GET
    - type: http
      namespace: servicenow-crm
      baseUri: "https://heineken.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST

Queries Salesforce for current quarter pipeline and posts summary to Microsoft Teams.

naftiko: "0.5"
info:
  label: "Salesforce Quarterly Pipeline"
  description: "Queries Salesforce for current quarter pipeline and posts summary to Microsoft Teams."
  tags:
    - sales
    - reporting
    - salesforce
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: sales-ops
      port: 8080
      tools:
        - name: post-pipeline-summary
          description: "Run a Salesforce pipeline query and post to Teams."
          inputParameters:
            - name: teams_channel_id
              in: body
              type: string
              description: "Teams channel ID."
          steps:
            - name: query-pipeline
              type: call
              call: salesforce.query
              with:
                q: "SELECT StageName, SUM(Amount) total FROM Opportunity WHERE CloseDate = THIS_QUARTER GROUP BY StageName"
            - name: post-summary
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "{{teams_channel_id}}"
                text: "Pipeline: {{query-pipeline.records}}"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://heineken.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: query
          path: "/query"
          operations:
            - name: query
              method: GET
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Retrieves invoice details from SAP Ariba for reconciliation with SAP S/4HANA records.

naftiko: "0.5"
info:
  label: "SAP Ariba Invoice Reconciliation"
  description: "Retrieves invoice details from SAP Ariba for reconciliation with SAP S/4HANA records."
  tags:
    - finance
    - procurement
    - sap-ariba
    - sap
capability:
  exposes:
    - type: mcp
      namespace: finance-ops
      port: 8080
      tools:
        - name: reconcile-invoice
          description: "Given an Ariba invoice ID, fetch details and match against SAP."
          inputParameters:
            - name: invoice_id
              in: body
              type: string
              description: "SAP Ariba invoice ID."
          steps:
            - name: get-ariba-invoice
              type: call
              call: ariba.get-invoice
              with:
                invoice_id: "{{invoice_id}}"
            - name: get-sap-po
              type: call
              call: sap.get-po
              with:
                po_number: "{{get-ariba-invoice.po_number}}"
  consumes:
    - type: http
      namespace: ariba
      baseUri: "https://openapi.ariba.com/api/invoice-processing/v1"
      authentication:
        type: bearer
        token: "$secrets.ariba_token"
      resources:
        - name: invoices
          path: "/invoices/{{invoice_id}}"
          inputParameters:
            - name: invoice_id
              in: path
          operations:
            - name: get-invoice
              method: GET
    - type: http
      namespace: sap
      baseUri: "https://heineken-s4.sap.com/sap/opu/odata/sap/MM_PUR_PO_MAINT_V2_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: purchase-orders
          path: "/A_PurchaseOrder('{{po_number}}')"
          inputParameters:
            - name: po_number
              in: path
          operations:
            - name: get-po
              method: GET

Retrieves a purchase requisition from SAP Ariba by requisition ID.

naftiko: "0.5"
info:
  label: "SAP Ariba Purchase Requisition"
  description: "Retrieves a purchase requisition from SAP Ariba by requisition ID."
  tags:
    - procurement
    - sap-ariba
capability:
  exposes:
    - type: mcp
      namespace: procurement-ops
      port: 8080
      tools:
        - name: get-requisition
          description: "Given a requisition ID, return status, requester, and total amount."
          inputParameters:
            - name: req_id
              in: body
              type: string
              description: "Ariba requisition ID."
          call: ariba.get-requisition
          with:
            req_id: "{{req_id}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.status"
            - name: total
              type: number
              mapping: "$.totalAmount"
  consumes:
    - type: http
      namespace: ariba
      baseUri: "https://openapi.ariba.com/api/procurement/v1"
      authentication:
        type: bearer
        token: "$secrets.ariba_token"
      resources:
        - name: requisitions
          path: "/requisitions/{{req_id}}"
          inputParameters:
            - name: req_id
              in: path
          operations:
            - name: get-requisition
              method: GET

Retrieves category-level procurement spend data from SAP Ariba for the current quarter and posts a spend summary to the procurement leadership Teams channel.

naftiko: "0.5"
info:
  label: "SAP Ariba Spend Analytics Digest"
  description: "Retrieves category-level procurement spend data from SAP Ariba for the current quarter and posts a spend summary to the procurement leadership Teams channel."
  tags:
    - procurement
    - finance
    - sap-ariba
    - reporting
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: procurement-reporting
      port: 8080
      tools:
        - name: digest-procurement-spend
          description: "Given a spend category and quarter, retrieve Ariba spend analytics data and post a digest to the procurement leadership channel in Teams. Use for quarterly spend reviews and category management."
          inputParameters:
            - name: category
              in: body
              type: string
              description: "The spend category name, e.g. Raw Materials, Packaging, or Logistics."
            - name: quarter
              in: body
              type: string
              description: "The fiscal quarter, e.g. Q1-2025."
          steps:
            - name: get-spend
              type: call
              call: "ariba-analytics.get-spend-summary"
              with:
                category: "{{category}}"
            - name: post-digest
              type: call
              call: "msteams-procurement.post-channel-message"
              with:
                channel_id: "$secrets.teams_procurement_channel_id"
                message: "Procurement Spend Digest | Category: {{category}} | Quarter: {{quarter}} | Data retrieved from Ariba. Review full report in Power BI."
  consumes:
    - type: http
      namespace: ariba-analytics
      baseUri: "https://openapi.ariba.com/api/analytics-reporting-details/v1"
      authentication:
        type: apikey
        key: "apikey"
        value: "$secrets.ariba_api_key"
        placement: header
      resources:
        - name: spend-summary
          path: "/reports/spend"
          inputParameters:
            - name: category
              in: query
          operations:
            - name: get-spend-summary
              method: GET
    - type: http
      namespace: msteams-procurement
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{channel_id}}/channels/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

When a new supplier is approved in Ariba, creates a ServiceNow change request for vendor master data setup in SAP S/4HANA and notifies the procurement team via Microsoft Teams.

naftiko: "0.5"
info:
  label: "SAP Ariba Supplier Onboarding"
  description: "When a new supplier is approved in Ariba, creates a ServiceNow change request for vendor master data setup in SAP S/4HANA and notifies the procurement team via Microsoft Teams."
  tags:
    - procurement
    - supplier-management
    - sap-ariba
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: procurement-ops
      port: 8080
      tools:
        - name: onboard-supplier
          description: "Given an Ariba supplier ID, retrieve supplier details, open a ServiceNow change request for SAP vendor master creation, and notify the procurement channel in Teams."
          inputParameters:
            - name: supplier_id
              in: body
              type: string
              description: "The Ariba supplier ID for the newly approved vendor."
          steps:
            - name: get-supplier
              type: call
              call: "ariba.get-supplier"
              with:
                supplier_id: "{{supplier_id}}"
            - name: create-change
              type: call
              call: "servicenow-proc.create-change"
              with:
                short_description: "Vendor master setup for: {{get-supplier.name}}"
                category: "vendor_master"
                description: "New supplier {{get-supplier.name}} ({{supplier_id}}) approved in Ariba. Requires SAP S/4HANA vendor master creation."
            - name: notify-team
              type: call
              call: "msteams-proc.post-channel-message"
              with:
                channel_id: "$secrets.teams_procurement_channel_id"
                message: "New supplier onboarded: {{get-supplier.name}}. Change request: {{create-change.number}}. Please complete SAP vendor master setup."
  consumes:
    - type: http
      namespace: ariba
      baseUri: "https://openapi.ariba.com/api/supplier/v1"
      authentication:
        type: apikey
        key: "apikey"
        value: "$secrets.ariba_api_key"
        placement: header
      resources:
        - name: suppliers
          path: "/suppliers/{{supplier_id}}"
          inputParameters:
            - name: supplier_id
              in: path
          operations:
            - name: get-supplier
              method: GET
    - type: http
      namespace: servicenow-proc
      baseUri: "https://heineken.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: change-requests
          path: "/table/change_request"
          operations:
            - name: create-change
              method: POST
    - type: http
      namespace: msteams-proc
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{channel_id}}/channels/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Retrieves batch traceability data from SAP for a product batch, returning materials, production dates, and quality status for recall investigations.

naftiko: "0.5"
info:
  label: "SAP Batch Traceability Lookup"
  description: "Retrieves batch traceability data from SAP for a product batch, returning materials, production dates, and quality status for recall investigations."
  tags:
    - supply-chain
    - quality
    - sap
capability:
  exposes:
    - type: mcp
      namespace: quality-ops
      port: 8080
      tools:
        - name: trace-batch
          description: "Given a SAP batch number and material, return traceability data including production date and quality status."
          inputParameters:
            - name: batch_number
              in: body
              type: string
              description: "SAP batch number."
            - name: material
              in: body
              type: string
              description: "SAP material number."
          call: sap.get-batch
          with:
            batch: "{{batch_number}}"
            material: "{{material}}"
          outputParameters:
            - name: production_date
              type: string
              mapping: "$.d.ManufactureDate"
            - name: shelf_life_expiry
              type: string
              mapping: "$.d.ShelfLifeExpirationDate"
            - name: batch_status
              type: string
              mapping: "$.d.BatchStatus"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://heineken-s4.sap.com/sap/opu/odata/sap/API_BATCH_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: batches
          path: "/A_Batch(Material='{{material}}',Batch='{{batch}}')"
          inputParameters:
            - name: material
              in: path
            - name: batch
              in: path
          operations:
            - name: get-batch
              method: GET

Retrieves a billing document from SAP by document number.

naftiko: "0.5"
info:
  label: "SAP Billing Document Lookup"
  description: "Retrieves a billing document from SAP by document number."
  tags:
    - finance
    - erp
    - sap
capability:
  exposes:
    - type: mcp
      namespace: finance-ops
      port: 8080
      tools:
        - name: get-billing-doc
          description: "Given a billing document number, return customer, amount, and date."
          inputParameters:
            - name: doc_number
              in: body
              type: string
              description: "SAP billing document number."
          call: sap.get-billing
          with:
            doc: "{{doc_number}}"
          outputParameters:
            - name: customer
              type: string
              mapping: "$.d.SoldToParty"
            - name: amount
              type: number
              mapping: "$.d.TotalNetAmount"
            - name: billing_date
              type: string
              mapping: "$.d.BillingDocumentDate"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://heineken-s4.sap.com/sap/opu/odata/sap/API_BILLING_DOCUMENT_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: billing-docs
          path: "/A_BillingDocument('{{doc}}')"
          inputParameters:
            - name: doc
              in: path
          operations:
            - name: get-billing
              method: GET

Retrieves pending expense reports from SAP Concur awaiting manager approval, returning submitter details, amount, and expense categories for approval workflow.

naftiko: "0.5"
info:
  label: "SAP Concur Expense Report Approval"
  description: "Retrieves pending expense reports from SAP Concur awaiting manager approval, returning submitter details, amount, and expense categories for approval workflow."
  tags:
    - finance
    - expense-management
    - sap-concur
    - approval
capability:
  exposes:
    - type: mcp
      namespace: finance-expenses
      port: 8080
      tools:
        - name: get-pending-expense-reports
          description: "Retrieve all pending expense reports from SAP Concur awaiting approval, including submitter name, total amount, and primary expense categories. Use for manager approval queues and finance audit workflows."
          call: "concur.list-pending-reports"
          outputParameters:
            - name: reports
              type: array
              mapping: "$.Items"
              items:
                - name: report_id
                  type: string
                  mapping: "$.ID"
                - name: submitter
                  type: string
                  mapping: "$.OwnerName"
                - name: total_amount
                  type: string
                  mapping: "$.Total"
                - name: currency
                  type: string
                  mapping: "$.CurrencyCode"
                - name: submit_date
                  type: string
                  mapping: "$.SubmitDate"
  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/reports"
          inputParameters:
            - name: approvalStatusCode
              in: query
          operations:
            - name: list-pending-reports
              method: GET

Queries SAP Concur for pending expense reports and sends approval reminders via Microsoft Graph.

naftiko: "0.5"
info:
  label: "SAP Concur Travel Expense Approval"
  description: "Queries SAP Concur for pending expense reports and sends approval reminders via Microsoft Graph."
  tags:
    - finance
    - expense-management
    - sap-concur
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: finance-ops
      port: 8080
      tools:
        - name: remind-expense-approvals
          description: "Fetch pending expense reports and send approval reminders."
          inputParameters:
            - name: days_threshold
              in: body
              type: integer
              description: "Days pending threshold."
          steps:
            - name: get-pending
              type: call
              call: concur.list-reports
              with:
                status: "PENDING_APPROVAL"
                older_than_days: "{{days_threshold}}"
            - name: send-reminders
              type: call
              call: msgraph.send-mail
              with:
                recipients: "{{get-pending.approver_emails}}"
                subject: "Expense reports awaiting your approval"
                body: "You have expense reports pending approval for more than {{days_threshold}} days."
  consumes:
    - type: http
      namespace: concur
      baseUri: "https://us.api.concursolutions.com/api/v3.0"
      authentication:
        type: bearer
        token: "$secrets.concur_token"
      resources:
        - name: reports
          path: "/expense/reports"
          operations:
            - name: list-reports
              method: GET
    - type: http
      namespace: msgraph
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: mail
          path: "/me/sendMail"
          operations:
            - name: send-mail
              method: POST

Retrieves cost center budget vs actual from SAP for a given period.

naftiko: "0.5"
info:
  label: "SAP Cost Center Budget Check"
  description: "Retrieves cost center budget vs actual from SAP for a given period."
  tags:
    - finance
    - erp
    - sap
capability:
  exposes:
    - type: mcp
      namespace: finance-ops
      port: 8080
      tools:
        - name: check-budget
          description: "Given a cost center and period, return budget, actual spend, and variance."
          inputParameters:
            - name: cost_center
              in: body
              type: string
              description: "SAP cost center."
            - name: fiscal_year
              in: body
              type: string
              description: "Fiscal year."
          call: sap.get-budget
          with:
            cost_center: "{{cost_center}}"
            year: "{{fiscal_year}}"
          outputParameters:
            - name: budget
              type: number
              mapping: "$.d.PlannedAmount"
            - name: actual
              type: number
              mapping: "$.d.ActualAmount"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://heineken-s4.sap.com/sap/opu/odata/sap/API_COSTCENTER_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: budgets
          path: "/A_CostCenter('{{cost_center}}')"
          inputParameters:
            - name: cost_center
              in: path
          operations:
            - name: get-budget
              method: GET

Retrieves a credit memo from SAP by document number.

naftiko: "0.5"
info:
  label: "SAP Credit Memo Lookup"
  description: "Retrieves a credit memo from SAP by document number."
  tags:
    - finance
    - erp
    - sap
capability:
  exposes:
    - type: mcp
      namespace: finance-ops
      port: 8080
      tools:
        - name: get-credit-memo
          description: "Given a SAP credit memo number, return customer, amount, and reason."
          inputParameters:
            - name: doc_number
              in: body
              type: string
              description: "Credit memo document number."
          call: sap.get-credit-memo
          with:
            doc: "{{doc_number}}"
          outputParameters:
            - name: customer
              type: string
              mapping: "$.d.SoldToParty"
            - name: amount
              type: number
              mapping: "$.d.TotalNetAmount"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://heineken-s4.sap.com/sap/opu/odata/sap/API_CREDIT_MEMO_REQUEST_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: credit-memos
          path: "/A_CreditMemoRequest('{{doc}}')"
          inputParameters:
            - name: doc
              in: path
          operations:
            - name: get-credit-memo
              method: GET

Retrieves customer master data from SAP by customer number.

naftiko: "0.5"
info:
  label: "SAP Customer Master Lookup"
  description: "Retrieves customer master data from SAP by customer number."
  tags:
    - sales
    - erp
    - sap
capability:
  exposes:
    - type: mcp
      namespace: sales-ops
      port: 8080
      tools:
        - name: get-customer
          description: "Given a SAP customer number, return name, address, and credit limit."
          inputParameters:
            - name: customer_number
              in: body
              type: string
              description: "SAP customer number."
          call: sap.get-customer
          with:
            customer: "{{customer_number}}"
          outputParameters:
            - name: name
              type: string
              mapping: "$.d.CustomerName"
            - name: credit_limit
              type: number
              mapping: "$.d.CreditLimit"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://heineken-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

Retrieves a delivery note from SAP by document number, returning delivery date, quantities, and ship-to address.

naftiko: "0.5"
info:
  label: "SAP Delivery Note Lookup"
  description: "Retrieves a delivery note from SAP by document number, returning delivery date, quantities, and ship-to address."
  tags:
    - logistics
    - erp
    - sap
capability:
  exposes:
    - type: mcp
      namespace: logistics-ops
      port: 8080
      tools:
        - name: get-delivery-note
          description: "Given a SAP delivery document number, return delivery date, material, and ship-to."
          inputParameters:
            - name: delivery_number
              in: body
              type: string
              description: "SAP delivery document number."
          call: sap.get-delivery
          with:
            delivery: "{{delivery_number}}"
          outputParameters:
            - name: delivery_date
              type: string
              mapping: "$.d.DeliveryDate"
            - name: ship_to
              type: string
              mapping: "$.d.ShipToParty"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://heineken-s4.sap.com/sap/opu/odata/sap/API_OUTBOUND_DELIVERY_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: deliveries
          path: "/A_OutbDeliveryHeader('{{delivery}}')"
          inputParameters:
            - name: delivery
              in: path
          operations:
            - name: get-delivery
              method: GET

Retrieves demand planning forecast data from SAP for a material and plant, returning planned quantities by period.

naftiko: "0.5"
info:
  label: "SAP Demand Planning Forecast"
  description: "Retrieves demand planning forecast data from SAP for a material and plant, returning planned quantities by period."
  tags:
    - supply-chain
    - planning
    - sap
capability:
  exposes:
    - type: mcp
      namespace: scm-ops
      port: 8080
      tools:
        - name: get-demand-forecast
          description: "Given a material and plant, return the demand planning forecast."
          inputParameters:
            - name: material
              in: body
              type: string
              description: "SAP material number."
            - name: plant
              in: body
              type: string
              description: "SAP plant code."
          call: sap.get-forecast
          with:
            material: "{{material}}"
            plant: "{{plant}}"
          outputParameters:
            - name: forecast_qty
              type: number
              mapping: "$.d.PlannedQuantity"
            - name: period
              type: string
              mapping: "$.d.PlanningPeriod"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://heineken-s4.sap.com/sap/opu/odata/sap/API_MRP_MATERIALS_SRV_01"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: forecast
          path: "/A_MRPMaterial(Material='{{material}}',MRPPlant='{{plant}}')"
          inputParameters:
            - name: material
              in: path
            - name: plant
              in: path
          operations:
            - name: get-forecast
              method: GET

Retrieves a general ledger account balance from SAP for a given company code and period.

naftiko: "0.5"
info:
  label: "SAP GL Account Balance"
  description: "Retrieves a general ledger account balance from SAP for a given company code and period."
  tags:
    - finance
    - erp
    - sap
capability:
  exposes:
    - type: mcp
      namespace: finance-ops
      port: 8080
      tools:
        - name: get-gl-balance
          description: "Given a GL account and company code, return the balance."
          inputParameters:
            - name: gl_account
              in: body
              type: string
              description: "SAP GL account number."
            - name: company_code
              in: body
              type: string
              description: "SAP company code."
          call: sap.get-gl-balance
          with:
            account: "{{gl_account}}"
            company: "{{company_code}}"
          outputParameters:
            - name: balance
              type: number
              mapping: "$.d.EndingBalance"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://heineken-s4.sap.com/sap/opu/odata/sap/API_GLACCOUNTLINEITEM_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: gl-items
          path: "/A_GLAccountLineItem"
          operations:
            - name: get-gl-balance
              method: GET

Retrieves goods receipt data from SAP by document number for three-way match verification.

naftiko: "0.5"
info:
  label: "SAP Goods Receipt Verification"
  description: "Retrieves goods receipt data from SAP by document number for three-way match verification."
  tags:
    - procurement
    - erp
    - sap
capability:
  exposes:
    - type: mcp
      namespace: procurement-ops
      port: 8080
      tools:
        - name: get-goods-receipt
          description: "Given a goods receipt document number, return posting date, material, and quantity."
          inputParameters:
            - name: doc_number
              in: body
              type: string
              description: "Goods receipt document number."
          call: sap.get-gr
          with:
            doc: "{{doc_number}}"
          outputParameters:
            - name: posting_date
              type: string
              mapping: "$.d.PostingDate"
            - name: quantity
              type: number
              mapping: "$.d.Quantity"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://heineken-s4.sap.com/sap/opu/odata/sap/API_MATERIAL_DOCUMENT_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: material-docs
          path: "/A_MaterialDocumentHeader('{{doc}}')"
          inputParameters:
            - name: doc
              in: path
          operations:
            - name: get-gr
              method: GET

Retrieves current inventory levels from SAP S/4HANA for a material and plant.

naftiko: "0.5"
info:
  label: "SAP Inventory Level Check"
  description: "Retrieves current inventory levels from SAP S/4HANA for a material and plant."
  tags:
    - supply-chain
    - erp
    - sap
capability:
  exposes:
    - type: mcp
      namespace: scm-ops
      port: 8080
      tools:
        - name: check-inventory
          description: "Given a SAP material number and plant, return available stock quantity."
          inputParameters:
            - name: material
              in: body
              type: string
              description: "SAP material number."
            - name: plant
              in: body
              type: string
              description: "SAP plant code."
          call: sap.get-stock
          with:
            material: "{{material}}"
            plant: "{{plant}}"
          outputParameters:
            - name: available_qty
              type: number
              mapping: "$.d.AvailableQuantity"
            - name: unit
              type: string
              mapping: "$.d.BaseUnit"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://heineken-s4.sap.com/sap/opu/odata/sap/API_MATERIAL_STOCK_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: stock
          path: "/A_MatlStkInAcctMod(Material='{{material}}',Plant='{{plant}}')"
          inputParameters:
            - name: material
              in: path
            - name: plant
              in: path
          operations:
            - name: get-stock
              method: GET

Looks up an invoice in SAP S/4HANA by document number and returns payment status, due date, and vendor information for accounts payable follow-up.

naftiko: "0.5"
info:
  label: "SAP Invoice Processing Status"
  description: "Looks up an invoice in SAP S/4HANA by document number and returns payment status, due date, and vendor information for accounts payable follow-up."
  tags:
    - finance
    - accounts-payable
    - sap
    - erp
capability:
  exposes:
    - type: mcp
      namespace: finance-ap
      port: 8080
      tools:
        - name: get-invoice-status
          description: "Given a SAP invoice document number and fiscal year, retrieve payment status, due date, and vendor name from SAP S/4HANA. Use for accounts payable status checks and payment run planning."
          inputParameters:
            - name: invoice_number
              in: body
              type: string
              description: "The SAP accounts payable invoice document number."
            - name: fiscal_year
              in: body
              type: string
              description: "The fiscal year of the invoice, e.g. 2025."
          call: "sap-ap.get-invoice"
          with:
            invoice_number: "{{invoice_number}}"
            fiscal_year: "{{fiscal_year}}"
          outputParameters:
            - name: payment_status
              type: string
              mapping: "$.d.PaymentStatus"
            - name: due_date
              type: string
              mapping: "$.d.PaymentDueDate"
            - name: vendor_name
              type: string
              mapping: "$.d.SupplierName"
            - name: amount
              type: string
              mapping: "$.d.DocumentAmountInCompanyCodeCurrency"
  consumes:
    - type: http
      namespace: sap-ap
      baseUri: "https://heineken-s4.sap.com/sap/opu/odata/sap/API_SUPPLIER_INVOICE_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: supplier-invoices
          path: "/A_SupplierInvoice(FiscalYear='{{fiscal_year}}',SupplierInvoiceIDByInvcgParty='{{invoice_number}}')"
          inputParameters:
            - name: invoice_number
              in: path
            - name: fiscal_year
              in: path
          operations:
            - name: get-invoice
              method: GET
              outputRawFormat: xml

Retrieves material master data from SAP by material number, returning description, unit, and material group.

naftiko: "0.5"
info:
  label: "SAP Material Master Lookup"
  description: "Retrieves material master data from SAP by material number, returning description, unit, and material group."
  tags:
    - supply-chain
    - erp
    - sap
capability:
  exposes:
    - type: mcp
      namespace: scm-ops
      port: 8080
      tools:
        - name: get-material
          description: "Given a SAP material number, return description, base unit, and material group."
          inputParameters:
            - name: material
              in: body
              type: string
              description: "SAP material number."
          call: sap.get-material
          with:
            material: "{{material}}"
          outputParameters:
            - name: description
              type: string
              mapping: "$.d.MaterialDescription"
            - name: base_unit
              type: string
              mapping: "$.d.BaseUnit"
            - name: material_group
              type: string
              mapping: "$.d.MaterialGroup"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://heineken-s4.sap.com/sap/opu/odata/sap/API_PRODUCT_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: materials
          path: "/A_Product('{{material}}')"
          inputParameters:
            - name: material
              in: path
          operations:
            - name: get-material
              method: GET

Retrieves the status of financial period-close tasks in SAP S/4HANA for a given company code and fiscal period, surfacing open items for the finance controller.

naftiko: "0.5"
info:
  label: "SAP Period Close Checklist"
  description: "Retrieves the status of financial period-close tasks in SAP S/4HANA for a given company code and fiscal period, surfacing open items for the finance controller."
  tags:
    - finance
    - period-close
    - sap
    - erp
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: finance-close
      port: 8080
      tools:
        - name: get-period-close-status
          description: "Given an SAP company code and fiscal period, retrieve the list of period-close tasks and their completion status. Use during month-end and quarter-end financial close."
          inputParameters:
            - name: company_code
              in: body
              type: string
              description: "The SAP company code, e.g. HNK1 for Heineken Netherlands."
            - name: fiscal_period
              in: body
              type: string
              description: "The fiscal period in YYYYMM format, e.g. 202503."
          call: "sap-close.get-closing-tasks"
          with:
            company_code: "{{company_code}}"
            fiscal_period: "{{fiscal_period}}"
          outputParameters:
            - name: open_tasks
              type: array
              mapping: "$.d.results"
              items:
                - name: task_id
                  type: string
                  mapping: "$.TaskID"
                - name: description
                  type: string
                  mapping: "$.Description"
                - name: status
                  type: string
                  mapping: "$.Status"
  consumes:
    - type: http
      namespace: sap-close
      baseUri: "https://heineken-s4.sap.com/sap/opu/odata/sap/FAR_PERIOD_CLOSE_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: closing-tasks
          path: "/ClosingTaskSet"
          inputParameters:
            - name: company_code
              in: query
            - name: fiscal_period
              in: query
          operations:
            - name: get-closing-tasks
              method: GET
              outputRawFormat: xml

Retrieves a plant maintenance order from SAP for brewery equipment, returning status and scheduled date.

naftiko: "0.5"
info:
  label: "SAP Plant Maintenance Order"
  description: "Retrieves a plant maintenance order from SAP for brewery equipment, returning status and scheduled date."
  tags:
    - manufacturing
    - maintenance
    - sap
capability:
  exposes:
    - type: mcp
      namespace: mfg-ops
      port: 8080
      tools:
        - name: get-maintenance-order
          description: "Given a SAP maintenance order number, return status and scheduled dates."
          inputParameters:
            - name: order_number
              in: body
              type: string
              description: "SAP maintenance order number."
          call: sap.get-pm-order
          with:
            order: "{{order_number}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.d.OrderStatus"
            - name: scheduled_start
              type: string
              mapping: "$.d.ScheduledStartDate"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://heineken-s4.sap.com/sap/opu/odata/sap/API_MAINTORDER"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: maintenance-orders
          path: "/A_MaintenanceOrder('{{order}}')"
          inputParameters:
            - name: order
              in: path
          operations:
            - name: get-pm-order
              method: GET

Retrieves pricing conditions from SAP for a material and customer combination.

naftiko: "0.5"
info:
  label: "SAP Pricing Condition Lookup"
  description: "Retrieves pricing conditions from SAP for a material and customer combination."
  tags:
    - sales
    - pricing
    - sap
capability:
  exposes:
    - type: mcp
      namespace: sales-ops
      port: 8080
      tools:
        - name: get-pricing
          description: "Given a material and customer, return the applicable pricing conditions."
          inputParameters:
            - name: material
              in: body
              type: string
              description: "SAP material number."
            - name: customer
              in: body
              type: string
              description: "SAP customer number."
          call: sap.get-pricing-conditions
          with:
            material: "{{material}}"
            customer: "{{customer}}"
          outputParameters:
            - name: price
              type: number
              mapping: "$.d.ConditionRateValue"
            - name: currency
              type: string
              mapping: "$.d.ConditionCurrency"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://heineken-s4.sap.com/sap/opu/odata/sap/API_SLSPRICINGCONDITIONRECORD_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: conditions
          path: "/A_SlsPrcgCndnRecdValidity"
          operations:
            - name: get-pricing-conditions
              method: GET

Retrieves a production order from SAP S/4HANA, returning status, planned quantity, and actual output.

naftiko: "0.5"
info:
  label: "SAP Production Order Status"
  description: "Retrieves a production order from SAP S/4HANA, returning status, planned quantity, and actual output."
  tags:
    - manufacturing
    - erp
    - sap
capability:
  exposes:
    - type: mcp
      namespace: mfg-ops
      port: 8080
      tools:
        - name: get-production-order
          description: "Given a SAP production order number, return status, planned quantity, and actual quantity."
          inputParameters:
            - name: order_number
              in: body
              type: string
              description: "SAP production order number."
          call: sap.get-production-order
          with:
            order: "{{order_number}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.d.OrderStatus"
            - name: planned_qty
              type: number
              mapping: "$.d.PlannedQuantity"
            - name: actual_qty
              type: number
              mapping: "$.d.ActualQuantity"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://heineken-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('{{order}}')"
          inputParameters:
            - name: order
              in: path
          operations:
            - name: get-production-order
              method: GET

Looks up a Heineken SAP S/4HANA purchase order by number and returns header status, vendor details, total value, and currency for procurement review.

naftiko: "0.5"
info:
  label: "SAP Purchase Order Lookup"
  description: "Looks up a Heineken SAP S/4HANA purchase order by number and returns header status, vendor details, total value, and currency for procurement review."
  tags:
    - procurement
    - finance
    - sap
    - erp
capability:
  exposes:
    - type: mcp
      namespace: erp-procurement
      port: 8080
      tools:
        - name: get-purchase-order
          description: "Given a SAP purchase order number, retrieve its status, vendor name, total amount, and currency from SAP S/4HANA. Use for procurement status checks and approvals."
          inputParameters:
            - name: po_number
              in: body
              type: string
              description: "The SAP purchase order number, e.g. 4500012345."
          call: "sap-s4.get-po"
          with:
            po_number: "{{po_number}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.d.OverallStatus"
            - name: vendor
              type: string
              mapping: "$.d.Supplier.CompanyName"
            - name: total_value
              type: string
              mapping: "$.d.TotalAmount"
            - name: currency
              type: string
              mapping: "$.d.TransactionCurrency"
  consumes:
    - type: http
      namespace: sap-s4
      baseUri: "https://heineken-s4.sap.com/sap/opu/odata/sap/MM_PUR_PO_MAINT_V2_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: purchase-orders
          path: "/A_PurchaseOrder('{{po_number}}')"
          inputParameters:
            - name: po_number
              in: path
          operations:
            - name: get-po
              method: GET
              outputRawFormat: xml

Retrieves quality inspection lot results from SAP for brewery quality control, posting failures to Microsoft Teams.

naftiko: "0.5"
info:
  label: "SAP Quality Inspection Result"
  description: "Retrieves quality inspection lot results from SAP for brewery quality control, posting failures to Microsoft Teams."
  tags:
    - manufacturing
    - quality
    - sap
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: quality-ops
      port: 8080
      tools:
        - name: check-inspection-result
          description: "Given a SAP inspection lot number, fetch results and alert Teams if failures exist."
          inputParameters:
            - name: inspection_lot
              in: body
              type: string
              description: "SAP inspection lot number."
          steps:
            - name: get-result
              type: call
              call: sap.get-inspection-lot
              with:
                lot: "{{inspection_lot}}"
            - name: notify-quality
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "quality-control"
                text: "Inspection lot {{inspection_lot}}: result={{get-result.usage_decision}}, material={{get-result.material}}"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://heineken-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('{{lot}}')"
          inputParameters:
            - name: lot
              in: path
          operations:
            - name: get-inspection-lot
              method: GET
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Retrieves a returns order from SAP and creates a Salesforce case for the distributor follow-up.

naftiko: "0.5"
info:
  label: "SAP Returns Order Processing"
  description: "Retrieves a returns order from SAP and creates a Salesforce case for the distributor follow-up."
  tags:
    - sales
    - returns
    - sap
    - salesforce
capability:
  exposes:
    - type: mcp
      namespace: returns-ops
      port: 8080
      tools:
        - name: process-return
          description: "Given a SAP returns order, fetch details and create a Salesforce follow-up case."
          inputParameters:
            - name: returns_order
              in: body
              type: string
              description: "SAP returns order number."
          steps:
            - name: get-return
              type: call
              call: sap.get-returns-order
              with:
                order: "{{returns_order}}"
            - name: create-case
              type: call
              call: salesforce.create-case
              with:
                subject: "Returns order {{returns_order}}: {{get-return.material}}"
                description: "Quantity: {{get-return.quantity}}, Reason: {{get-return.reason}}"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://heineken-s4.sap.com/sap/opu/odata/sap/API_RETURNS_ORDER_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: returns
          path: "/A_ReturnsOrder('{{order}}')"
          inputParameters:
            - name: order
              in: path
          operations:
            - name: get-returns-order
              method: GET
    - type: http
      namespace: salesforce
      baseUri: "https://heineken.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: cases
          path: "/sobjects/Case"
          operations:
            - name: create-case
              method: POST

Retrieves a sales order from SAP S/4HANA by order number, returning customer, status, and total value.

naftiko: "0.5"
info:
  label: "SAP Sales Order Lookup"
  description: "Retrieves a sales order from SAP S/4HANA by order number, returning customer, status, and total value."
  tags:
    - sales
    - erp
    - sap
capability:
  exposes:
    - type: mcp
      namespace: sales-ops
      port: 8080
      tools:
        - name: get-sales-order
          description: "Given a SAP sales order number, return customer, status, and total."
          inputParameters:
            - name: order_number
              in: body
              type: string
              description: "SAP sales order number."
          call: sap.get-sales-order
          with:
            order: "{{order_number}}"
          outputParameters:
            - name: customer
              type: string
              mapping: "$.d.SoldToParty"
            - name: status
              type: string
              mapping: "$.d.OverallSDProcessStatus"
            - name: total
              type: number
              mapping: "$.d.TotalNetAmount"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://heineken-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('{{order}}')"
          inputParameters:
            - name: order
              in: path
          operations:
            - name: get-sales-order
              method: GET

Retrieves a transport order from SAP for shipment tracking, returning carrier, route, and estimated delivery.

naftiko: "0.5"
info:
  label: "SAP Transport Order Tracking"
  description: "Retrieves a transport order from SAP for shipment tracking, returning carrier, route, and estimated delivery."
  tags:
    - logistics
    - erp
    - sap
capability:
  exposes:
    - type: mcp
      namespace: logistics-ops
      port: 8080
      tools:
        - name: track-transport
          description: "Given a SAP transport order number, return carrier and ETA."
          inputParameters:
            - name: transport_order
              in: body
              type: string
              description: "SAP transport order number."
          call: sap.get-transport
          with:
            order: "{{transport_order}}"
          outputParameters:
            - name: carrier
              type: string
              mapping: "$.d.Carrier"
            - name: eta
              type: string
              mapping: "$.d.PlannedArrivalDate"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://heineken-s4.sap.com/sap/opu/odata/sap/API_FREIGHT_ORDER_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: transports
          path: "/A_FreightOrder('{{order}}')"
          inputParameters:
            - name: order
              in: path
          operations:
            - name: get-transport
              method: GET

Retrieves vendor master data from SAP by vendor number.

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

Retrieves warehouse bin stock from SAP Extended Warehouse Management.

naftiko: "0.5"
info:
  label: "SAP Warehouse Management Lookup"
  description: "Retrieves warehouse bin stock from SAP Extended Warehouse Management."
  tags:
    - supply-chain
    - warehouse
    - sap
capability:
  exposes:
    - type: mcp
      namespace: warehouse-ops
      port: 8080
      tools:
        - name: get-bin-stock
          description: "Given a warehouse and bin, return available quantity."
          inputParameters:
            - name: warehouse
              in: body
              type: string
              description: "Warehouse number."
            - name: bin
              in: body
              type: string
              description: "Bin location."
          call: sap.get-bin-stock
          with:
            warehouse: "{{warehouse}}"
            bin: "{{bin}}"
          outputParameters:
            - name: quantity
              type: number
              mapping: "$.d.AvailableQuantity"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://heineken-s4.sap.com/sap/opu/odata/sap/API_WAREHOUSE_STOCK_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: stock
          path: "/A_WarehouseStock"
          operations:
            - name: get-bin-stock
              method: GET

Retrieves a stock transfer order from SAP between warehouses, returning source, destination, and quantities.

naftiko: "0.5"
info:
  label: "SAP Warehouse Stock Transfer"
  description: "Retrieves a stock transfer order from SAP between warehouses, returning source, destination, and quantities."
  tags:
    - supply-chain
    - logistics
    - sap
capability:
  exposes:
    - type: mcp
      namespace: warehouse-ops
      port: 8080
      tools:
        - name: get-stock-transfer
          description: "Given a transfer order number, return source plant, destination plant, and material quantities."
          inputParameters:
            - name: transfer_order
              in: body
              type: string
              description: "SAP stock transfer order number."
          call: sap.get-transfer
          with:
            order: "{{transfer_order}}"
          outputParameters:
            - name: source_plant
              type: string
              mapping: "$.d.SupplyingPlant"
            - name: dest_plant
              type: string
              mapping: "$.d.ReceivingPlant"
            - name: quantity
              type: number
              mapping: "$.d.OrderQuantity"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://heineken-s4.sap.com/sap/opu/odata/sap/API_STOCK_TRANSFER_ORDER_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: transfers
          path: "/A_StockTransferOrder('{{order}}')"
          inputParameters:
            - name: order
              in: path
          operations:
            - name: get-transfer
              method: GET

Retrieves email delivery stats from SendGrid for marketing campaigns.

naftiko: "0.5"
info:
  label: "SendGrid Marketing Email Stats"
  description: "Retrieves email delivery stats from SendGrid for marketing campaigns."
  tags:
    - marketing
    - email
    - sendgrid
capability:
  exposes:
    - type: mcp
      namespace: email-ops
      port: 8080
      tools:
        - name: get-email-stats
          description: "Given a date range, return SendGrid delivery stats."
          inputParameters:
            - name: start_date
              in: body
              type: string
              description: "Start date (YYYY-MM-DD)."
            - name: end_date
              in: body
              type: string
              description: "End date (YYYY-MM-DD)."
          call: sendgrid.get-stats
          with:
            start_date: "{{start_date}}"
            end_date: "{{end_date}}"
          outputParameters:
            - name: delivered
              type: integer
              mapping: "$.stats[0].metrics.delivered"
            - name: opens
              type: integer
              mapping: "$.stats[0].metrics.opens"
  consumes:
    - type: http
      namespace: sendgrid
      baseUri: "https://api.sendgrid.com/v3"
      authentication:
        type: bearer
        token: "$secrets.sendgrid_api_key"
      resources:
        - name: stats
          path: "/stats"
          operations:
            - name: get-stats
              method: GET

Retrieves a ServiceNow change request and its approval status, returning structured data for change advisory board review and governance workflows.

naftiko: "0.5"
info:
  label: "ServiceNow Change Request Approval"
  description: "Retrieves a ServiceNow change request and its approval status, returning structured data for change advisory board review and governance workflows."
  tags:
    - itsm
    - change-management
    - servicenow
    - governance
capability:
  exposes:
    - type: mcp
      namespace: itsm-change
      port: 8080
      tools:
        - name: get-change-request
          description: "Given a ServiceNow change request number, retrieve its details, approval status, and risk level. Use for change advisory board workflows and change governance reviews."
          inputParameters:
            - name: change_number
              in: body
              type: string
              description: "The ServiceNow change request number, e.g. CHG0012345."
          call: "servicenow-change.get-change"
          with:
            change_number: "{{change_number}}"
          outputParameters:
            - name: state
              type: string
              mapping: "$.result.state"
            - name: risk
              type: string
              mapping: "$.result.risk"
            - name: approval
              type: string
              mapping: "$.result.approval"
            - name: short_description
              type: string
              mapping: "$.result.short_description"
  consumes:
    - type: http
      namespace: servicenow-change
      baseUri: "https://heineken.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: change-requests
          path: "/table/change_request"
          inputParameters:
            - name: change_number
              in: query
          operations:
            - name: get-change
              method: GET

Escalates a ServiceNow incident to P1 priority, reassigns it to the escalation group, and notifies the IT director via Teams when SLA breach is imminent.

naftiko: "0.5"
info:
  label: "ServiceNow Incident Escalation"
  description: "Escalates a ServiceNow incident to P1 priority, reassigns it to the escalation group, and notifies the IT director via Teams when SLA breach is imminent."
  tags:
    - itsm
    - incident-response
    - servicenow
    - microsoft-teams
    - sla
capability:
  exposes:
    - type: mcp
      namespace: itsm-escalation
      port: 8080
      tools:
        - name: escalate-incident
          description: "Given a ServiceNow incident number, escalate it to P1, reassign to the escalation group, and notify the IT director in Teams. Use when an incident is approaching SLA breach or has major business impact."
          inputParameters:
            - name: incident_number
              in: body
              type: string
              description: "The ServiceNow incident number, e.g. INC0023456."
            - name: escalation_reason
              in: body
              type: string
              description: "Reason for escalation and business impact description."
          steps:
            - name: update-incident
              type: call
              call: "servicenow-esc.patch-incident"
              with:
                incident_number: "{{incident_number}}"
                priority: "1"
                assignment_group: "IT_Escalation"
                work_notes: "Escalated to P1: {{escalation_reason}}"
            - name: notify-director
              type: call
              call: "msteams-esc.post-channel-message"
              with:
                channel_id: "$secrets.teams_it_director_channel_id"
                message: "ESCALATION P1 | Incident: {{incident_number}} | Reason: {{escalation_reason}} | Assigned to IT Escalation team. Immediate attention required."
  consumes:
    - type: http
      namespace: servicenow-esc
      baseUri: "https://heineken.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          inputParameters:
            - name: incident_number
              in: query
          operations:
            - name: patch-incident
              method: PATCH
    - type: http
      namespace: msteams-esc
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{channel_id}}/channels/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Creates a Jira ticket from a P1 ServiceNow incident and notifies Microsoft Teams.

naftiko: "0.5"
info:
  label: "ServiceNow Incident to Jira"
  description: "Creates a Jira ticket from a P1 ServiceNow incident and notifies Microsoft Teams."
  tags:
    - it-operations
    - incident-management
    - servicenow
    - jira
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: incident-ops
      port: 8080
      tools:
        - name: escalate-to-jira
          description: "Given a ServiceNow incident, create a Jira ticket and notify Teams."
          inputParameters:
            - name: incident_number
              in: body
              type: string
              description: "ServiceNow incident number."
          steps:
            - name: get-incident
              type: call
              call: servicenow.get-incident
              with:
                number: "{{incident_number}}"
            - name: create-jira
              type: call
              call: jira.create-issue
              with:
                project_key: "OPS"
                issuetype: "Bug"
                summary: "SNOW {{incident_number}}: {{get-incident.short_description}}"
            - name: notify
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "it-incidents"
                text: "P1 escalated: {{incident_number}} -> Jira {{create-jira.key}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://heineken.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: get-incident
              method: GET
    - type: http
      namespace: jira
      baseUri: "https://heineken.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Retrieves IT asset details from ServiceNow CMDB by asset tag.

naftiko: "0.5"
info:
  label: "ServiceNow IT Asset Lookup"
  description: "Retrieves IT asset details from ServiceNow CMDB by asset tag."
  tags:
    - it-operations
    - asset-management
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: it-ops
      port: 8080
      tools:
        - name: get-asset
          description: "Given an asset tag, return model, assigned user, and warranty status."
          inputParameters:
            - name: asset_tag
              in: body
              type: string
              description: "ServiceNow asset tag."
          call: servicenow.get-asset
          with:
            asset_tag: "{{asset_tag}}"
          outputParameters:
            - name: model
              type: string
              mapping: "$.result.model_id.display_value"
            - name: assigned_to
              type: string
              mapping: "$.result.assigned_to.display_value"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://heineken.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: assets
          path: "/table/alm_hardware"
          operations:
            - name: get-asset
              method: GET

Searches the SharePoint brand assets library for marketing materials by keyword.

naftiko: "0.5"
info:
  label: "SharePoint Brand Asset Search"
  description: "Searches the SharePoint brand assets library for marketing materials by keyword."
  tags:
    - marketing
    - brand
    - sharepoint
capability:
  exposes:
    - type: mcp
      namespace: brand-ops
      port: 8080
      tools:
        - name: search-brand-assets
          description: "Given a search keyword, find matching brand assets in SharePoint."
          inputParameters:
            - name: keyword
              in: body
              type: string
              description: "Search keyword."
          call: sharepoint.search
          with:
            query: "{{keyword}}"
          outputParameters:
            - name: files
              type: array
              mapping: "$.value"
  consumes:
    - type: http
      namespace: sharepoint
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: search
          path: "/sites/heineken.sharepoint.com/drive/root/search(q='{{query}}')"
          inputParameters:
            - name: query
              in: path
          operations:
            - name: search
              method: GET

Retrieves the version history of a SharePoint document and returns a structured list of versions with author and modification timestamps for compliance auditing.

naftiko: "0.5"
info:
  label: "SharePoint Document Version Audit"
  description: "Retrieves the version history of a SharePoint document and returns a structured list of versions with author and modification timestamps for compliance auditing."
  tags:
    - compliance
    - document-management
    - sharepoint
    - audit
capability:
  exposes:
    - type: mcp
      namespace: compliance-audit
      port: 8080
      tools:
        - name: get-document-versions
          description: "Given a SharePoint site ID and document item ID, retrieve the full version history including author, modification date, and version label. Use for compliance audits and document governance reviews."
          inputParameters:
            - name: site_id
              in: body
              type: string
              description: "The SharePoint site ID where the document resides."
            - name: item_id
              in: body
              type: string
              description: "The SharePoint drive item ID of the document."
          call: "sharepoint-audit.list-versions"
          with:
            site_id: "{{site_id}}"
            item_id: "{{item_id}}"
          outputParameters:
            - name: versions
              type: array
              mapping: "$.value"
              items:
                - name: version_id
                  type: string
                  mapping: "$.id"
                - name: modified_by
                  type: string
                  mapping: "$.lastModifiedBy.user.displayName"
                - name: modified_at
                  type: string
                  mapping: "$.lastModifiedDateTime"
  consumes:
    - type: http
      namespace: sharepoint-audit
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: item-versions
          path: "/sites/{{site_id}}/drive/items/{{item_id}}/versions"
          inputParameters:
            - name: site_id
              in: path
            - name: item_id
              in: path
          operations:
            - name: list-versions
              method: GET

Executes a SQL query against the Snowflake sales analytics warehouse.

naftiko: "0.5"
info:
  label: "Snowflake Sales Analytics Query"
  description: "Executes a SQL query against the Snowflake sales analytics warehouse."
  tags:
    - data
    - analytics
    - snowflake
capability:
  exposes:
    - type: mcp
      namespace: data-ops
      port: 8080
      tools:
        - name: run-sales-query
          description: "Given a SQL query, execute against Snowflake and return results."
          inputParameters:
            - name: sql
              in: body
              type: string
              description: "SQL query."
          call: snowflake.execute-statement
          with:
            statement: "{{sql}}"
            warehouse: "SALES_ANALYTICS_WH"
          outputParameters:
            - name: rows
              type: array
              mapping: "$.data"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://heineken.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-statement
              method: POST

Queries Snowflake for weekly business KPIs and posts to the leadership Microsoft Teams channel.

naftiko: "0.5"
info:
  label: "Snowflake Weekly KPI Report"
  description: "Queries Snowflake for weekly business KPIs and posts to the leadership Microsoft Teams channel."
  tags:
    - analytics
    - reporting
    - snowflake
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: analytics-ops
      port: 8080
      tools:
        - name: post-weekly-kpis
          description: "Fetch weekly KPIs from Snowflake and post to Teams."
          inputParameters:
            - name: teams_channel_id
              in: body
              type: string
              description: "Teams channel ID."
          steps:
            - name: fetch-kpis
              type: call
              call: snowflake.execute-statement
              with:
                statement: "SELECT metric, value FROM weekly_kpis WHERE report_date = CURRENT_DATE"
            - name: post-report
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "{{teams_channel_id}}"
                text: "Weekly KPIs: {{fetch-kpis.data}}"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://heineken.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-statement
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Runs a Splunk security search and creates a ServiceNow incident for findings.

naftiko: "0.5"
info:
  label: "Splunk Security Log Search"
  description: "Runs a Splunk security search and creates a ServiceNow incident for findings."
  tags:
    - security
    - siem
    - splunk
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: security-ops
      port: 8080
      tools:
        - name: search-security-logs
          description: "Run a Splunk saved search and create ServiceNow incidents for findings."
          inputParameters:
            - name: search_name
              in: body
              type: string
              description: "Splunk saved search name."
          steps:
            - name: run-search
              type: call
              call: splunk.dispatch-search
              with:
                name: "{{search_name}}"
            - name: create-incident
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Splunk finding: {{search_name}}"
                category: "Security"
  consumes:
    - type: http
      namespace: splunk
      baseUri: "https://heineken-splunk.splunkcloud.com:8089/servicesNS/admin/search"
      authentication:
        type: bearer
        token: "$secrets.splunk_token"
      resources:
        - name: saved-searches
          path: "/saved/searches/{{name}}/dispatch"
          inputParameters:
            - name: name
              in: path
          operations:
            - name: dispatch-search
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://heineken.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST

Retrieves the latest demand forecast from Salesforce for a product SKU and pushes the forecast data into SAP S/4HANA for production planning alignment.

naftiko: "0.5"
info:
  label: "Supply Chain Demand Forecast Sync"
  description: "Retrieves the latest demand forecast from Salesforce for a product SKU and pushes the forecast data into SAP S/4HANA for production planning alignment."
  tags:
    - supply-chain
    - salesforce
    - sap
    - erp
    - demand-planning
capability:
  exposes:
    - type: mcp
      namespace: supply-chain-planning
      port: 8080
      tools:
        - name: sync-demand-forecast
          description: "Given a product SKU and planning period, retrieve the demand forecast from Salesforce and create a planned independent requirement in SAP S/4HANA. Use for monthly supply-demand alignment and production planning."
          inputParameters:
            - name: sku
              in: body
              type: string
              description: "The product SKU code, e.g. HNK-LAGER-330ML."
            - name: planning_period
              in: body
              type: string
              description: "The planning period in YYYYMM format, e.g. 202504."
            - name: forecast_quantity_hl
              in: body
              type: string
              description: "Forecasted demand quantity in hectoliters."
          steps:
            - name: get-forecast
              type: call
              call: "salesforce-forecast.get-product-forecast"
              with:
                sku: "{{sku}}"
            - name: push-to-sap
              type: call
              call: "sap-pir.create-planned-requirement"
              with:
                material: "{{sku}}"
                planning_period: "{{planning_period}}"
                quantity: "{{forecast_quantity_hl}}"
  consumes:
    - type: http
      namespace: salesforce-forecast
      baseUri: "https://heineken.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: forecasts
          path: "/query"
          inputParameters:
            - name: q
              in: query
          operations:
            - name: get-product-forecast
              method: GET
    - type: http
      namespace: sap-pir
      baseUri: "https://heineken-s4.sap.com/sap/opu/odata/sap/API_PLND_INDEP_REQMT_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: planned-requirements
          path: "/A_PlannedIndepRqmt"
          operations:
            - name: create-planned-requirement
              method: POST

Triggers a Tableau extract refresh for the sales dashboard.

naftiko: "0.5"
info:
  label: "Tableau Sales Dashboard Refresh"
  description: "Triggers a Tableau extract refresh for the sales dashboard."
  tags:
    - analytics
    - sales
    - tableau
capability:
  exposes:
    - type: mcp
      namespace: bi-ops
      port: 8080
      tools:
        - name: refresh-sales-dashboard
          description: "Given a Tableau workbook ID, trigger an extract refresh."
          inputParameters:
            - name: workbook_id
              in: body
              type: string
              description: "Tableau workbook ID."
          call: tableau.refresh-workbook
          with:
            workbook_id: "{{workbook_id}}"
          outputParameters:
            - name: job_id
              type: string
              mapping: "$.job.id"
  consumes:
    - type: http
      namespace: tableau
      baseUri: "https://tableau.heineken.com/api/3.21"
      authentication:
        type: bearer
        token: "$secrets.tableau_token"
      resources:
        - name: workbooks
          path: "/sites/{{site_id}}/workbooks/{{workbook_id}}/refresh"
          inputParameters:
            - name: workbook_id
              in: path
          operations:
            - name: refresh-workbook
              method: POST

Triggers a Terraform Cloud apply run and notifies the infra team via Microsoft Teams.

naftiko: "0.5"
info:
  label: "Terraform Cloud Workspace Provision"
  description: "Triggers a Terraform Cloud apply run and notifies the infra team via Microsoft Teams."
  tags:
    - infrastructure
    - iac
    - terraform
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: infra-ops
      port: 8080
      tools:
        - name: provision-workspace
          description: "Trigger a Terraform apply and notify Teams."
          inputParameters:
            - name: workspace_id
              in: body
              type: string
              description: "Terraform workspace ID."
          steps:
            - name: create-run
              type: call
              call: terraform.create-run
              with:
                workspace_id: "{{workspace_id}}"
            - name: notify
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "infra-ops"
                text: "Terraform run triggered: {{workspace_id}}, run {{create-run.id}}"
  consumes:
    - type: http
      namespace: terraform
      baseUri: "https://app.terraform.io/api/v2"
      authentication:
        type: bearer
        token: "$secrets.terraform_token"
      resources:
        - name: runs
          path: "/runs"
          operations:
            - name: create-run
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Sends a WhatsApp template message to a distributor for order confirmations.

naftiko: "0.5"
info:
  label: "WhatsApp Distributor Notification"
  description: "Sends a WhatsApp template message to a distributor for order confirmations."
  tags:
    - communications
    - distribution
    - whatsapp
capability:
  exposes:
    - type: mcp
      namespace: distributor-comms
      port: 8080
      tools:
        - name: send-distributor-whatsapp
          description: "Send a WhatsApp template message to a distributor."
          inputParameters:
            - name: phone_number
              in: body
              type: string
              description: "Distributor phone in E.164."
            - name: template_name
              in: body
              type: string
              description: "Template name."
          call: whatsapp.send-template
          with:
            to: "{{phone_number}}"
            template: "{{template_name}}"
          outputParameters:
            - name: message_id
              type: string
              mapping: "$.messages[0].id"
  consumes:
    - type: http
      namespace: whatsapp
      baseUri: "https://graph.facebook.com/v18.0"
      authentication:
        type: bearer
        token: "$secrets.whatsapp_token"
      resources:
        - name: messages
          path: "/{{phone_number_id}}/messages"
          operations:
            - name: send-template
              method: POST

Retrieves PTO and sick leave balances from Workday.

naftiko: "0.5"
info:
  label: "Workday Absence Balance Lookup"
  description: "Retrieves PTO and sick leave balances from Workday."
  tags:
    - hr
    - leave-management
    - workday
capability:
  exposes:
    - type: mcp
      namespace: hr-ops
      port: 8080
      tools:
        - name: get-absence-balance
          description: "Given an employee ID, return PTO and sick leave balances."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "Workday employee ID."
          call: workday.get-balance
          with:
            employee_id: "{{employee_id}}"
          outputParameters:
            - name: pto_balance
              type: number
              mapping: "$.Worker.TimeOff.PTO_Balance"
            - name: sick_balance
              type: number
              mapping: "$.Worker.TimeOff.Sick_Balance"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd5-impl-services1.workday.com/ccx/service/heineken"
      authentication:
        type: basic
        username: "$secrets.workday_user"
        password: "$secrets.workday_password"
      resources:
        - name: absence
          path: "/Human_Resources/v40.0/Get_Workers"
          operations:
            - name: get-balance
              method: GET

Initiates the annual performance review cycle in Workday for a department by creating review tasks for all active employees and notifying managers via Teams.

naftiko: "0.5"
info:
  label: "Workday Annual Performance Review Kickoff"
  description: "Initiates the annual performance review cycle in Workday for a department by creating review tasks for all active employees and notifying managers via Teams."
  tags:
    - hr
    - performance-management
    - workday
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: hr-performance
      port: 8080
      tools:
        - name: kickoff-performance-reviews
          description: "Given a Workday department ID and review cycle name, retrieve active employees and notify their managers in Teams to begin the performance review process. Use to launch annual or mid-year review cycles."
          inputParameters:
            - name: department_id
              in: body
              type: string
              description: "The Workday department ID for which to kick off reviews."
            - name: review_cycle
              in: body
              type: string
              description: "The name of the review cycle, e.g. 2025 Annual Review."
            - name: deadline
              in: body
              type: string
              description: "Review submission deadline in YYYY-MM-DD format."
          steps:
            - name: get-employees
              type: call
              call: "workday-perf.list-workers"
              with:
                department_id: "{{department_id}}"
            - name: notify-managers
              type: call
              call: "msteams-perf.post-channel-message"
              with:
                channel_id: "$secrets.teams_hr_channel_id"
                message: "Performance Review Kickoff | Cycle: {{review_cycle}} | Department: {{department_id}} | Deadline: {{deadline}} | Please complete reviews in Workday by the deadline."
  consumes:
    - type: http
      namespace: workday-perf
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/heineken/workers"
          inputParameters:
            - name: department_id
              in: query
          operations:
            - name: list-workers
              method: GET
    - 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/{{channel_id}}/channels/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Queries Workday for employees with incomplete benefits enrollment and sends reminders.

naftiko: "0.5"
info:
  label: "Workday Benefits Enrollment"
  description: "Queries Workday for employees with incomplete benefits enrollment and sends reminders."
  tags:
    - hr
    - benefits
    - workday
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: hr-ops
      port: 8080
      tools:
        - name: send-enrollment-reminders
          description: "Fetch employees with pending enrollment and send reminders via Teams."
          inputParameters:
            - name: enrollment_period
              in: body
              type: string
              description: "Enrollment period."
          steps:
            - name: get-pending
              type: call
              call: workday.get-pending-enrollment
              with:
                period: "{{enrollment_period}}"
            - name: notify
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "hr-benefits"
                text: "{{get-pending.count}} employees have not completed benefits enrollment for {{enrollment_period}}"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd5-impl-services1.workday.com/ccx/service/heineken"
      authentication:
        type: basic
        username: "$secrets.workday_user"
        password: "$secrets.workday_password"
      resources:
        - name: benefits
          path: "/Benefits/v40.0"
          operations:
            - name: get-pending-enrollment
              method: GET
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

When a compensation change is approved, notifies HR via Microsoft Teams.

naftiko: "0.5"
info:
  label: "Workday Compensation Alert"
  description: "When a compensation change is approved, notifies HR via Microsoft Teams."
  tags:
    - hr
    - compensation
    - workday
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: hr-ops
      port: 8080
      tools:
        - name: notify-comp-change
          description: "Fetch compensation event details and notify HR Teams channel."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "Workday employee ID."
            - name: event_id
              in: body
              type: string
              description: "Comp event ID."
          steps:
            - name: get-event
              type: call
              call: workday.get-comp-event
              with:
                employee_id: "{{employee_id}}"
                event_id: "{{event_id}}"
            - name: notify
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "hr-notifications"
                text: "Comp change for {{employee_id}}: effective {{get-event.effective_date}}"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd5-impl-services1.workday.com/ccx/service/heineken"
      authentication:
        type: basic
        username: "$secrets.workday_user"
        password: "$secrets.workday_password"
      resources:
        - name: compensation
          path: "/Compensation/v40.0"
          operations:
            - name: get-comp-event
              method: GET
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Creates a position requisition in Workday and notifies HR via Microsoft Teams.

naftiko: "0.5"
info:
  label: "Workday New Position Requisition"
  description: "Creates a position requisition in Workday and notifies HR via Microsoft Teams."
  tags:
    - hr
    - recruiting
    - workday
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: recruiting-ops
      port: 8080
      tools:
        - name: create-requisition
          description: "Create a Workday requisition and notify HR Teams channel."
          inputParameters:
            - name: job_title
              in: body
              type: string
              description: "Job title."
            - name: department
              in: body
              type: string
              description: "Department."
          steps:
            - name: create-req
              type: call
              call: workday.create-requisition
              with:
                title: "{{job_title}}"
                department: "{{department}}"
            - name: notify-hr
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "recruiting"
                text: "New requisition: {{job_title}} in {{department}}"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd5-impl-services1.workday.com/ccx/service/heineken"
      authentication:
        type: basic
        username: "$secrets.workday_user"
        password: "$secrets.workday_password"
      resources:
        - name: requisitions
          path: "/Recruiting/v40.0"
          operations:
            - name: create-requisition
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

When an employee termination is initiated in Workday, creates a ServiceNow offboarding ticket to revoke access, archives their SharePoint folder, and sends an IT notification via Teams.

naftiko: "0.5"
info:
  label: "Workday Offboarding Orchestrator"
  description: "When an employee termination is initiated in Workday, creates a ServiceNow offboarding ticket to revoke access, archives their SharePoint folder, and sends an IT notification via Teams."
  tags:
    - hr
    - offboarding
    - workday
    - servicenow
    - sharepoint
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: hr-offboarding
      port: 8080
      tools:
        - name: trigger-offboarding
          description: "Given a Workday employee ID and termination date, orchestrate the offboarding sequence: open a ServiceNow access-revocation ticket, archive the SharePoint folder, and notify IT via Teams."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "The Workday worker ID of the departing employee."
            - name: termination_date
              in: body
              type: string
              description: "The employee's last working day in YYYY-MM-DD format."
          steps:
            - name: get-worker
              type: call
              call: "workday-off.get-worker"
              with:
                worker_id: "{{employee_id}}"
            - name: create-ticket
              type: call
              call: "servicenow-off.create-incident"
              with:
                short_description: "Offboarding access revocation: {{get-worker.display_name}}"
                category: "hr_offboarding"
                description: "Employee {{get-worker.display_name}} ({{employee_id}}) is terminating on {{termination_date}}. Please revoke all system access."
            - name: notify-it
              type: call
              call: "msteams-off.post-channel-message"
              with:
                channel_id: "$secrets.teams_it_channel_id"
                message: "Offboarding initiated for {{get-worker.display_name}}. Last day: {{termination_date}}. ServiceNow ticket: {{create-ticket.number}}. Please begin access revocation."
  consumes:
    - type: http
      namespace: workday-off
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/heineken/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: servicenow-off
      baseUri: "https://heineken.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams-off
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{channel_id}}/channels/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Retrieves manager and direct reports for a Workday employee.

naftiko: "0.5"
info:
  label: "Workday Org Chart Lookup"
  description: "Retrieves manager and direct reports for a Workday employee."
  tags:
    - hr
    - workforce
    - workday
capability:
  exposes:
    - type: mcp
      namespace: hr-ops
      port: 8080
      tools:
        - name: get-org-chart
          description: "Given an employee ID, return manager and direct reports."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "Workday employee ID."
          call: workday.get-worker
          with:
            employee_id: "{{employee_id}}"
          outputParameters:
            - name: manager
              type: string
              mapping: "$.Worker.Manager.Name"
            - name: direct_reports
              type: array
              mapping: "$.Worker.DirectReports[*].Name"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd5-impl-services1.workday.com/ccx/service/heineken"
      authentication:
        type: basic
        username: "$secrets.workday_user"
        password: "$secrets.workday_password"
      resources:
        - name: workers
          path: "/Human_Resources/v40.0/Get_Workers"
          operations:
            - name: get-worker
              method: GET

Retrieves the status of open job requisitions and candidate pipeline counts from Workday Recruiting for a given department, for talent acquisition reporting.

naftiko: "0.5"
info:
  label: "Workday Recruiting Pipeline Status"
  description: "Retrieves the status of open job requisitions and candidate pipeline counts from Workday Recruiting for a given department, for talent acquisition reporting."
  tags:
    - hr
    - recruiting
    - workday
    - talent-acquisition
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: hr-recruiting
      port: 8080
      tools:
        - name: get-recruiting-pipeline
          description: "Given a department ID, retrieve all open job requisitions and their candidate pipeline counts from Workday Recruiting. Use for talent acquisition reviews and hiring manager updates."
          inputParameters:
            - name: department_id
              in: body
              type: string
              description: "The Workday department ID to retrieve open requisitions for."
          call: "workday-rec.list-requisitions"
          with:
            department_id: "{{department_id}}"
          outputParameters:
            - name: requisitions
              type: array
              mapping: "$.data"
              items:
                - name: req_id
                  type: string
                  mapping: "$.id"
                - name: job_title
                  type: string
                  mapping: "$.jobTitle"
                - name: status
                  type: string
                  mapping: "$.status"
                - name: candidate_count
                  type: string
                  mapping: "$.candidateCount"
  consumes:
    - type: http
      namespace: workday-rec
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/recruiting/v3"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: job-requisitions
          path: "/jobRequisitions"
          inputParameters:
            - name: department_id
              in: query
          operations:
            - name: list-requisitions
              method: GET

When an employee's role changes in Workday, updates their ServiceNow access profile and notifies their new manager via Teams with the effective date and new responsibilities.

naftiko: "0.5"
info:
  label: "Workday Role Change Provisioning"
  description: "When an employee's role changes in Workday, updates their ServiceNow access profile and notifies their new manager via Teams with the effective date and new responsibilities."
  tags:
    - hr
    - access-management
    - workday
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: hr-role-change
      port: 8080
      tools:
        - name: provision-role-change
          description: "Given a Workday employee ID and new role details, create a ServiceNow access-update request and notify the new manager in Teams. Use when an employee is promoted or transfers to a new department."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "The Workday worker ID of the employee changing roles."
            - name: new_role
              in: body
              type: string
              description: "The new job title or role name."
            - name: effective_date
              in: body
              type: string
              description: "The effective date of the role change in YYYY-MM-DD format."
            - name: new_manager_upn
              in: body
              type: string
              description: "The UPN (email) of the new manager in Microsoft 365."
          steps:
            - name: get-worker
              type: call
              call: "workday-rc.get-worker"
              with:
                worker_id: "{{employee_id}}"
            - name: create-access-request
              type: call
              call: "servicenow-rc.create-incident"
              with:
                short_description: "Access update for role change: {{get-worker.display_name}} to {{new_role}}"
                category: "access_management"
            - name: notify-manager
              type: call
              call: "msteams-rc.send-message"
              with:
                recipient_upn: "{{new_manager_upn}}"
                message: "{{get-worker.display_name}} will join your team as {{new_role}} effective {{effective_date}}. ServiceNow access request: {{create-access-request.number}}."
  consumes:
    - type: http
      namespace: workday-rc
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/heineken/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: servicenow-rc
      baseUri: "https://heineken.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams-rc
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: mail
          path: "/users/{{recipient_upn}}/sendMail"
          inputParameters:
            - name: recipient_upn
              in: path
          operations:
            - name: send-message
              method: POST

Creates a Zoom meeting and posts the join link to a Microsoft Teams channel.

naftiko: "0.5"
info:
  label: "Zoom Meeting Scheduler"
  description: "Creates a Zoom meeting and posts the join link to a Microsoft Teams channel."
  tags:
    - collaboration
    - meetings
    - zoom
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: collab-ops
      port: 8080
      tools:
        - name: schedule-zoom-meeting
          description: "Create a Zoom meeting and share the link on Teams."
          inputParameters:
            - name: topic
              in: body
              type: string
              description: "Meeting topic."
            - name: duration
              in: body
              type: integer
              description: "Duration in minutes."
            - name: teams_channel_id
              in: body
              type: string
              description: "Teams channel ID."
          steps:
            - name: create-meeting
              type: call
              call: zoom.create-meeting
              with:
                topic: "{{topic}}"
                duration: "{{duration}}"
            - name: share-link
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "{{teams_channel_id}}"
                text: "Zoom meeting scheduled: {{topic}} — {{create-meeting.join_url}}"
  consumes:
    - type: http
      namespace: zoom
      baseUri: "https://api.zoom.us/v2"
      authentication:
        type: bearer
        token: "$secrets.zoom_token"
      resources:
        - name: meetings
          path: "/users/me/meetings"
          operations:
            - name: create-meeting
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST