Veolia Capabilities

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

Sort
Expand

Uses the Anthropic API to summarize lengthy operational or regulatory documents and stores the summary in a SharePoint document library for team access.

naftiko: "0.5"
info:
  label: "Anthropic Document Summarization"
  description: "Uses the Anthropic API to summarize lengthy operational or regulatory documents and stores the summary in a SharePoint document library for team access."
  tags:
    - ai
    - document-processing
    - anthropic
    - sharepoint
    - automation
capability:
  exposes:
    - type: mcp
      namespace: ai-document-ops
      port: 8080
      tools:
        - name: summarize-and-store-document
          description: "Given document text and a SharePoint site and folder path, send the document to the Anthropic Claude API for summarization and save the result to SharePoint. Use for regulatory filings, audit reports, and technical specifications."
          inputParameters:
            - name: document_text
              in: body
              type: string
              description: "The full text of the document to summarize."
            - name: document_title
              in: body
              type: string
              description: "The title of the document for naming the SharePoint file."
            - name: sharepoint_site_id
              in: body
              type: string
              description: "The SharePoint site ID where the summary should be stored."
            - name: folder_path
              in: body
              type: string
              description: "The folder path within the SharePoint site (e.g., Documents/Summaries)."
          steps:
            - name: summarize
              type: call
              call: "anthropic.create-message"
              with:
                model: "claude-opus-4-5"
                max_tokens: 1024
                prompt: "Summarize the following document concisely, highlighting key findings, obligations, and action items: {{document_text}}"
            - name: store-summary
              type: call
              call: "sharepoint-docs.upload-file"
              with:
                site_id: "{{sharepoint_site_id}}"
                folder_path: "{{folder_path}}"
                file_name: "{{document_title}}_summary.txt"
                content: "{{summarize.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: sharepoint-docs
      baseUri: "https://graph.microsoft.com/v1.0/sites"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: files
          path: "/{{site_id}}/drive/root:/{{folder_path}}/{{file_name}}:/content"
          inputParameters:
            - name: site_id
              in: path
            - name: folder_path
              in: path
            - name: file_name
              in: path
          operations:
            - name: upload-file
              method: PUT

Identifies unused M365 licenses in Azure AD, creates a ServiceNow reclamation task, and notifies IT asset management on Teams.

naftiko: "0.5"
info:
  label: "Azure AD License Reclamation"
  description: "Identifies unused M365 licenses in Azure AD, creates a ServiceNow reclamation task, and notifies IT asset management on Teams."
  tags:
    - it-asset-management
    - azure-ad
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: license-mgmt
      port: 8080
      tools:
        - name: reclaim-licenses
          description: "Query for inactive users with licenses and create reclamation task."
          inputParameters:
            - name: days_inactive
              in: body
              type: string
              description: "Days of inactivity threshold."
          steps:
            - name: get-inactive
              type: call
              call: "msgraph.get-inactive-users"
              with:
                days_inactive: "{{days_inactive}}"
            - name: create-task
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "License reclamation: {{get-inactive.count}} users inactive {{days_inactive}}+ days"
                assignment_group: "IT_Assets"
            - name: notify
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_it_channel"
                text: "License reclamation: {{get-inactive.count}} inactive users | Task: {{create-task.number}}"
  consumes:
    - type: http
      namespace: msgraph
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: users
          path: "/users"
          operations:
            - name: get-inactive-users
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/it/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

When Azure cost exceeds budget threshold, fetches cost breakdown, creates a Jira optimization task, and notifies the FinOps team.

naftiko: "0.5"
info:
  label: "Azure Cloud Cost Alert to FinOps"
  description: "When Azure cost exceeds budget threshold, fetches cost breakdown, creates a Jira optimization task, and notifies the FinOps team."
  tags:
    - cloud
    - finops
    - azure
    - jira
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: cloud-finops
      port: 8080
      tools:
        - name: handle-cost-alert
          description: "Given a subscription with cost overrun, create optimization task and notify."
          inputParameters:
            - name: subscription_id
              in: body
              type: string
              description: "The Azure subscription ID."
            - name: current_spend
              in: body
              type: string
              description: "Current monthly spend."
            - name: budget_limit
              in: body
              type: string
              description: "Budget limit."
          steps:
            - name: get-cost-breakdown
              type: call
              call: "azure.get-cost-analysis"
              with:
                subscription_id: "{{subscription_id}}"
            - name: create-task
              type: call
              call: "jira.create-issue"
              with:
                project: "CLOUD"
                summary: "Cost overrun: Azure subscription {{subscription_id}}"
                description: "Spend: EUR {{current_spend}} / Budget: EUR {{budget_limit}}."
                issue_type: "Task"
            - name: notify-finops
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_finops_channel"
                text: "Azure Cost Alert: EUR {{current_spend}} / EUR {{budget_limit}} | Jira: {{create-task.key}}"
  consumes:
    - type: http
      namespace: azure
      baseUri: "https://management.azure.com"
      authentication:
        type: bearer
        token: "$secrets.azure_mgmt_token"
      resources:
        - name: cost
          path: "/subscriptions/{{subscription_id}}/providers/Microsoft.CostManagement/query?api-version=2023-03-01"
          inputParameters:
            - name: subscription_id
              in: path
          operations:
            - name: get-cost-analysis
              method: POST
    - type: http
      namespace: jira
      baseUri: "https://veolia.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/finops/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Detects Azure spend anomalies via the Azure Cost Management API and creates a ServiceNow task for the cloud finance team to review and respond.

naftiko: "0.5"
info:
  label: "Azure Cost Anomaly Responder"
  description: "Detects Azure spend anomalies via the Azure Cost Management API and creates a ServiceNow task for the cloud finance team to review and respond."
  tags:
    - cloud
    - finops
    - azure
    - servicenow
    - cost-management
capability:
  exposes:
    - type: mcp
      namespace: cloud-finops
      port: 8080
      tools:
        - name: handle-cost-anomaly
          description: "Given an Azure subscription ID and billing period, fetch actual vs. budgeted spend. If overage exceeds threshold, create a ServiceNow task for the cloud finance team."
          inputParameters:
            - name: subscription_id
              in: body
              type: string
              description: "The Azure subscription ID to check for cost anomalies."
            - name: billing_period
              in: body
              type: string
              description: "The billing period in YYYYMM format (e.g., 202503)."
            - name: overage_threshold_pct
              in: body
              type: number
              description: "Percentage overage above budget that triggers a task (e.g., 10 for 10%)."
          steps:
            - name: get-cost-summary
              type: call
              call: "azure-cost.get-usage-summary"
              with:
                subscription_id: "{{subscription_id}}"
                billing_period: "{{billing_period}}"
            - name: create-review-task
              type: call
              call: "servicenow-cloud.create-task"
              with:
                short_description: "Azure cost anomaly: subscription {{subscription_id}} — {{billing_period}}"
                description: "Actual spend: {{get-cost-summary.actual_cost}}. Budget: {{get-cost-summary.budget_amount}}. Overage exceeds {{overage_threshold_pct}}% threshold."
                assignment_group: "Cloud_FinOps"
  consumes:
    - type: http
      namespace: azure-cost
      baseUri: "https://management.azure.com/subscriptions/{{subscription_id}}/providers/Microsoft.Consumption"
      authentication:
        type: bearer
        token: "$secrets.azure_mgmt_token"
      resources:
        - name: usage-summary
          path: "/billingPeriods/{{billing_period}}/providers/Microsoft.Consumption/usageDetails"
          inputParameters:
            - name: subscription_id
              in: path
            - name: billing_period
              in: path
          operations:
            - name: get-usage-summary
              method: GET
    - type: http
      namespace: servicenow-cloud
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST

When an Azure DevOps build fails, fetches details, creates a Jira bug, and notifies the dev team on Teams.

naftiko: "0.5"
info:
  label: "Azure DevOps Build Failure Notification"
  description: "When an Azure DevOps build fails, fetches details, creates a Jira bug, and notifies the dev team on Teams."
  tags:
    - devops
    - azure-devops
    - jira
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: cicd
      port: 8080
      tools:
        - name: handle-build-failure
          description: "Given a failed build ID, create Jira bug and notify dev team."
          inputParameters:
            - name: project_name
              in: body
              type: string
              description: "Azure DevOps project name."
            - name: build_id
              in: body
              type: string
              description: "The failed build ID."
          steps:
            - name: get-build
              type: call
              call: "azdevops.get-build"
              with:
                project_name: "{{project_name}}"
                build_id: "{{build_id}}"
            - name: create-bug
              type: call
              call: "jira.create-issue"
              with:
                project: "DEV"
                summary: "Build failure: {{get-build.definition_name}} #{{build_id}}"
                issue_type: "Bug"
            - name: notify
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_dev_channel"
                text: "Build Failed: {{get-build.definition_name}} #{{build_id}} | Jira: {{create-bug.key}}"
  consumes:
    - type: http
      namespace: azdevops
      baseUri: "https://dev.azure.com/veolia"
      authentication:
        type: basic
        username: ""
        password: "$secrets.azdevops_pat"
      resources:
        - name: builds
          path: "/{{project_name}}/_apis/build/builds/{{build_id}}?api-version=7.0"
          inputParameters:
            - name: project_name
              in: path
            - name: build_id
              in: path
          operations:
            - name: get-build
              method: GET
    - type: http
      namespace: jira
      baseUri: "https://veolia.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/dev/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Lists all Azure resource groups in a subscription, returning names, locations, and tags for infrastructure inventory.

naftiko: "0.5"
info:
  label: "Azure Resource Group Listing"
  description: "Lists all Azure resource groups in a subscription, returning names, locations, and tags for infrastructure inventory."
  tags:
    - cloud
    - azure
capability:
  exposes:
    - type: mcp
      namespace: cloud-infra
      port: 8080
      tools:
        - name: list-resource-groups
          description: "List all Azure resource groups for the Veolia subscription."
          inputParameters:
            - name: subscription_id
              in: body
              type: string
              description: "The Azure subscription ID."
          call: "azure.list-resource-groups"
          with:
            subscription_id: "{{subscription_id}}"
          outputParameters:
            - name: resource_groups
              type: array
              mapping: "$.value[*].name"
  consumes:
    - type: http
      namespace: azure
      baseUri: "https://management.azure.com"
      authentication:
        type: bearer
        token: "$secrets.azure_mgmt_token"
      resources:
        - name: resource-groups
          path: "/subscriptions/{{subscription_id}}/resourcegroups?api-version=2021-04-01"
          inputParameters:
            - name: subscription_id
              in: path
          operations:
            - name: list-resource-groups
              method: GET

Processes an Azure infrastructure provisioning request, validates the request in ServiceNow, and provisions the resource via the Azure Management API.

naftiko: "0.5"
info:
  label: "Azure Resource Provisioning Request"
  description: "Processes an Azure infrastructure provisioning request, validates the request in ServiceNow, and provisions the resource via the Azure Management API."
  tags:
    - cloud
    - azure
    - servicenow
    - infrastructure
    - provisioning
capability:
  exposes:
    - type: mcp
      namespace: cloud-provisioning
      port: 8080
      tools:
        - name: provision-azure-resource
          description: "Given an approved ServiceNow request number and Azure resource specification, provision the cloud resource via Azure Management API. Use after change management approval is confirmed."
          inputParameters:
            - name: snow_request_number
              in: body
              type: string
              description: "The ServiceNow request number (RITM) approving the provisioning."
            - name: subscription_id
              in: body
              type: string
              description: "Azure subscription ID where the resource should be provisioned."
            - name: resource_group
              in: body
              type: string
              description: "Target Azure resource group name."
            - name: resource_type
              in: body
              type: string
              description: "Azure resource type (e.g., Microsoft.Compute/virtualMachines)."
            - name: resource_name
              in: body
              type: string
              description: "Name for the new Azure resource."
          steps:
            - name: validate-request
              type: call
              call: "servicenow-ritm.get-request"
              with:
                number: "{{snow_request_number}}"
            - name: provision-resource
              type: call
              call: "azure-mgmt.create-resource"
              with:
                subscription_id: "{{subscription_id}}"
                resource_group: "{{resource_group}}"
                resource_type: "{{resource_type}}"
                resource_name: "{{resource_name}}"
  consumes:
    - type: http
      namespace: servicenow-ritm
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: requests
          path: "/table/sc_req_item"
          operations:
            - name: get-request
              method: GET
    - type: http
      namespace: azure-mgmt
      baseUri: "https://management.azure.com/subscriptions/{{subscription_id}}/resourceGroups/{{resource_group}}/providers"
      authentication:
        type: bearer
        token: "$secrets.azure_mgmt_token"
      resources:
        - name: resources
          path: "/{{resource_type}}/{{resource_name}}"
          inputParameters:
            - name: resource_type
              in: path
            - name: resource_name
              in: path
          operations:
            - name: create-resource
              method: PUT

When a change request is submitted in ServiceNow for Veolia infrastructure, routes it through the SAP workflow approval chain and notifies stakeholders via Microsoft Teams.

naftiko: "0.5"
info:
  label: "Change Management Approval Workflow"
  description: "When a change request is submitted in ServiceNow for Veolia infrastructure, routes it through the SAP workflow approval chain and notifies stakeholders via Microsoft Teams."
  tags:
    - itsm
    - change-management
    - servicenow
    - microsoft-teams
    - approval
capability:
  exposes:
    - type: mcp
      namespace: change-management
      port: 8080
      tools:
        - name: submit-change-request
          description: "Given a change description, risk level, and scheduled window, create a ServiceNow change request and notify the CAB approval group via Microsoft Teams."
          inputParameters:
            - name: short_description
              in: body
              type: string
              description: "Brief description of the proposed change."
            - name: risk_level
              in: body
              type: string
              description: "Risk level of the change: low, medium, high, or critical."
            - name: scheduled_start
              in: body
              type: string
              description: "Planned start datetime in ISO 8601 format."
            - name: scheduled_end
              in: body
              type: string
              description: "Planned end datetime in ISO 8601 format."
            - name: cab_channel_id
              in: body
              type: string
              description: "Microsoft Teams channel ID for the Change Advisory Board."
          steps:
            - name: create-change
              type: call
              call: "servicenow-change.create-change-request"
              with:
                short_description: "{{short_description}}"
                risk: "{{risk_level}}"
                start_date: "{{scheduled_start}}"
                end_date: "{{scheduled_end}}"
            - name: notify-cab
              type: call
              call: "msteams-cab.post-message"
              with:
                channel_id: "{{cab_channel_id}}"
                text: "New Change Request {{create-change.number}} (Risk: {{risk_level}}) requires CAB review. Scheduled: {{scheduled_start}} to {{scheduled_end}}. Description: {{short_description}}"
  consumes:
    - type: http
      namespace: servicenow-change
      baseUri: "https://veolia.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-request
              method: POST
    - type: http
      namespace: msteams-cab
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

When a Concur expense report contains policy violations, flags the items, creates a ServiceNow review task, and notifies the employee's manager.

naftiko: "0.5"
info:
  label: "Concur Expense Policy Violation Workflow"
  description: "When a Concur expense report contains policy violations, flags the items, creates a ServiceNow review task, and notifies the employee's manager."
  tags:
    - finance
    - travel
    - sap-concur
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: expense-compliance
      port: 8080
      tools:
        - name: flag-expense-violation
          description: "Given a Concur report ID with violations, create review task and notify."
          inputParameters:
            - name: report_id
              in: body
              type: string
              description: "The Concur expense report ID."
          steps:
            - name: get-report
              type: call
              call: "concur.get-report"
              with:
                report_id: "{{report_id}}"
            - name: create-review
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "Expense violation: Report {{report_id}} by {{get-report.employee_name}}"
                description: "Total: {{get-report.total_amount}}. Violations: {{get-report.violation_count}}."
                assignment_group: "Finance_Expense_Review"
            - name: notify-manager
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_finance_channel"
                text: "Expense violation: {{get-report.employee_name}} report {{report_id}} | {{get-report.violation_count}} violations | Task: {{create-review.number}}"
  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/{{report_id}}"
          inputParameters:
            - name: report_id
              in: path
          operations:
            - name: get-report
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/finance/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

When an employee submits an expense report in SAP Concur, validates the total against policy limits and routes a ServiceNow approval task to the line manager.

naftiko: "0.5"
info:
  label: "Concur Expense Report Approval"
  description: "When an employee submits an expense report in SAP Concur, validates the total against policy limits and routes a ServiceNow approval task to the line manager."
  tags:
    - finance
    - expense-management
    - sap-concur
    - servicenow
    - approval
capability:
  exposes:
    - type: mcp
      namespace: expense-approval
      port: 8080
      tools:
        - name: process-expense-report
          description: "Given a Concur expense report ID, fetch the report details, validate against the expense policy, and create a ServiceNow approval task for the submitter's manager."
          inputParameters:
            - name: report_id
              in: body
              type: string
              description: "The SAP Concur expense report ID."
            - name: policy_limit
              in: body
              type: number
              description: "The expense policy limit in USD above which manager approval is required."
          steps:
            - name: get-report
              type: call
              call: "concur.get-expense-report"
              with:
                report_id: "{{report_id}}"
            - name: create-approval
              type: call
              call: "servicenow-expense.create-task"
              with:
                short_description: "Expense report approval: {{get-report.ReportName}} — {{get-report.Total}} {{get-report.CurrencyCode}}"
                description: "Employee {{get-report.OwnerName}} submitted expense report {{report_id}} for {{get-report.Total}} {{get-report.CurrencyCode}}. Exceeds policy limit of {{policy_limit}}."
                assignment_group: "Finance_Approvals"
  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/{{report_id}}"
          inputParameters:
            - name: report_id
              in: path
          operations:
            - name: get-expense-report
              method: GET
    - type: http
      namespace: servicenow-expense
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST

Fetches the content of a Confluence wiki page by page ID for knowledge base lookups.

naftiko: "0.5"
info:
  label: "Confluence Page Content Retrieval"
  description: "Fetches the content of a Confluence wiki page by page ID for knowledge base lookups."
  tags:
    - knowledge-management
    - confluence
capability:
  exposes:
    - type: mcp
      namespace: knowledge
      port: 8080
      tools:
        - name: get-confluence-page
          description: "Retrieve a Confluence page by ID. Returns title, body content, and last-modified date."
          inputParameters:
            - name: page_id
              in: body
              type: string
              description: "The Confluence page ID."
          call: "confluence.get-page"
          with:
            page_id: "{{page_id}}"
          outputParameters:
            - name: title
              type: string
              mapping: "$.title"
            - name: body
              type: string
              mapping: "$.body.storage.value"
  consumes:
    - type: http
      namespace: confluence
      baseUri: "https://veolia.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_api_token"
      resources:
        - name: pages
          path: "/content/{{page_id}}?expand=body.storage,version"
          inputParameters:
            - name: page_id
              in: path
          operations:
            - name: get-page
              method: GET

Generates a daily digest of Veolia infrastructure health metrics from Datadog and publishes the summary to a Microsoft Teams ops channel.

naftiko: "0.5"
info:
  label: "Datadog Infrastructure Health Digest"
  description: "Generates a daily digest of Veolia infrastructure health metrics from Datadog and publishes the summary to a Microsoft Teams ops channel."
  tags:
    - observability
    - reporting
    - datadog
    - microsoft-teams
    - monitoring
capability:
  exposes:
    - type: mcp
      namespace: infra-reporting
      port: 8080
      tools:
        - name: digest-infrastructure-health
          description: "Fetch the last 24 hours of host and monitor status from Datadog and post a formatted health digest to the specified Teams channel. Use for daily ops stand-up or automated reporting."
          inputParameters:
            - name: team_channel_id
              in: body
              type: string
              description: "Microsoft Teams channel ID where the digest should be posted."
            - name: environment_tag
              in: body
              type: string
              description: "Datadog environment tag to filter hosts (e.g., env:production)."
          steps:
            - name: get-host-status
              type: call
              call: "datadog-health.list-hosts"
              with:
                filter: "{{environment_tag}}"
            - name: get-monitor-summary
              type: call
              call: "datadog-health.get-monitor-summary"
              with:
                tags: "{{environment_tag}}"
            - name: post-digest
              type: call
              call: "msteams-digest.post-message"
              with:
                channel_id: "{{team_channel_id}}"
                text: "Infrastructure Health Digest: {{get-host-status.total_matching}} hosts checked. Monitors — OK: {{get-monitor-summary.ok_count}}, Warning: {{get-monitor-summary.warn_count}}, Critical: {{get-monitor-summary.critical_count}}."
  consumes:
    - type: http
      namespace: datadog-health
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: hosts
          path: "/hosts"
          operations:
            - name: list-hosts
              method: GET
        - name: monitor-summary
          path: "/monitor/summary"
          operations:
            - name: get-monitor-summary
              method: GET
    - type: http
      namespace: msteams-digest
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

Retrieves the current status and configuration of a Datadog monitor by ID for observability triage.

naftiko: "0.5"
info:
  label: "Datadog Monitor Status Check"
  description: "Retrieves the current status and configuration of a Datadog monitor by ID for observability triage."
  tags:
    - observability
    - datadog
capability:
  exposes:
    - type: mcp
      namespace: monitoring
      port: 8080
      tools:
        - name: get-monitor-status
          description: "Check the status of a Datadog monitor by ID. Returns overall state and name."
          inputParameters:
            - name: monitor_id
              in: body
              type: string
              description: "The Datadog monitor ID."
          call: "datadog.get-monitor"
          with:
            monitor_id: "{{monitor_id}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.overall_state"
            - name: name
              type: string
              mapping: "$.name"
  consumes:
    - type: http
      namespace: datadog
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: monitors
          path: "/monitor/{{monitor_id}}"
          inputParameters:
            - name: monitor_id
              in: path
          operations:
            - name: get-monitor
              method: GET

When a Datadog SLO breaches its error budget, creates a ServiceNow incident and notifies the SRE team on Teams with burn rate context.

naftiko: "0.5"
info:
  label: "Datadog SLO Breach to Incident"
  description: "When a Datadog SLO breaches its error budget, creates a ServiceNow incident and notifies the SRE team on Teams with burn rate context."
  tags:
    - observability
    - sla
    - datadog
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: sre-ops
      port: 8080
      tools:
        - name: handle-slo-breach
          description: "Given a Datadog SLO ID, create an incident and notify SRE."
          inputParameters:
            - name: slo_id
              in: body
              type: string
              description: "The Datadog SLO ID."
            - name: service_name
              in: body
              type: string
              description: "The affected service."
          steps:
            - name: get-slo
              type: call
              call: "datadog.get-slo"
              with:
                slo_id: "{{slo_id}}"
            - name: create-incident
              type: call
              call: "servicenow.create-incident"
              with:
                short_description: "SLO breach: {{get-slo.name}} — {{service_name}}"
                urgency: "2"
                description: "SLO target: {{get-slo.target}}. Current: {{get-slo.current}}. Error budget remaining: {{get-slo.error_budget}}."
            - name: notify-sre
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_sre_channel"
                text: "SLO Breach: {{get-slo.name}} | Service: {{service_name}} | Current: {{get-slo.current}} (target: {{get-slo.target}}) | Incident: {{create-incident.number}}"
  consumes:
    - type: http
      namespace: datadog
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: slos
          path: "/slo/{{slo_id}}"
          inputParameters:
            - name: slo_id
              in: path
          operations:
            - name: get-slo
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/sre/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Fetches Datadog SLO status for Veolia's digital services and publishes a weekly compliance report to the operations Microsoft Teams channel.

naftiko: "0.5"
info:
  label: "Datadog SLO Compliance Report"
  description: "Fetches Datadog SLO status for Veolia's digital services and publishes a weekly compliance report to the operations Microsoft Teams channel."
  tags:
    - observability
    - datadog
    - microsoft-teams
    - slo
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: slo-reporting
      port: 8080
      tools:
        - name: publish-slo-compliance-report
          description: "Fetch SLO summary data from Datadog for a given time window and post a formatted compliance report to the Teams operations channel. Use for weekly service reliability reporting."
          inputParameters:
            - name: slo_ids
              in: body
              type: string
              description: "Comma-separated list of Datadog SLO IDs to include in the report."
            - name: timeframe
              in: body
              type: string
              description: "Reporting timeframe: 7d, 30d, or 90d."
            - name: ops_channel_id
              in: body
              type: string
              description: "Microsoft Teams channel ID for the ops report."
          steps:
            - name: get-slo-summary
              type: call
              call: "datadog-slo.get-slo-history"
              with:
                ids: "{{slo_ids}}"
                timeframe: "{{timeframe}}"
            - name: post-report
              type: call
              call: "msteams-slo.post-message"
              with:
                channel_id: "{{ops_channel_id}}"
                text: "SLO Compliance Report ({{timeframe}}): {{get-slo-summary.compliant_count}} SLOs compliant, {{get-slo-summary.breached_count}} breached. Overall compliance: {{get-slo-summary.overall_pct}}%."
  consumes:
    - type: http
      namespace: datadog-slo
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: slo-history
          path: "/slo/history"
          operations:
            - name: get-slo-history
              method: GET
    - type: http
      namespace: msteams-slo
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

Pulls emissions data from Snowflake, generates a compliance report in Confluence, and alerts the sustainability team on Teams.

naftiko: "0.5"
info:
  label: "Emissions Reporting Workflow"
  description: "Pulls emissions data from Snowflake, generates a compliance report in Confluence, and alerts the sustainability team on Teams."
  tags:
    - sustainability
    - compliance
    - snowflake
    - confluence
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: emissions
      port: 8080
      tools:
        - name: generate-emissions-report
          description: "Given a facility and period, generate emissions compliance report."
          inputParameters:
            - name: facility_name
              in: body
              type: string
              description: "The facility name."
            - name: reporting_period
              in: body
              type: string
              description: "The reporting period."
          steps:
            - name: get-emissions
              type: call
              call: "snowflake.execute-query"
              with:
                statement: "SELECT emission_type, SUM(quantity) as total FROM ESG_DB.PUBLIC.EMISSIONS WHERE facility='{{facility_name}}' AND period='{{reporting_period}}' GROUP BY emission_type"
            - name: publish
              type: call
              call: "confluence.create-page"
              with:
                space_key: "ESG"
                title: "Emissions: {{facility_name}} — {{reporting_period}}"
                body: "{{get-emissions.results}}"
            - name: notify
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_sustainability_channel"
                text: "Emissions report: {{facility_name}} {{reporting_period}} | {{publish.url}}"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://veolia.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-query
              method: POST
    - type: http
      namespace: confluence
      baseUri: "https://veolia.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_api_token"
      resources:
        - name: pages
          path: "/content"
          operations:
            - name: create-page
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/sustainability/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

When an employee departure is recorded in SAP SuccessFactors, revokes Azure AD access, closes open ServiceNow tickets, and notifies the manager via Microsoft Teams.

naftiko: "0.5"
info:
  label: "Employee Offboarding Workflow"
  description: "When an employee departure is recorded in SAP SuccessFactors, revokes Azure AD access, closes open ServiceNow tickets, and notifies the manager via Microsoft Teams."
  tags:
    - hr
    - offboarding
    - sap-successfactors
    - azure-ad
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: hr-offboarding
      port: 8080
      tools:
        - name: trigger-offboarding
          description: "Given a SuccessFactors employee ID and last working day, revoke Azure AD access, close ServiceNow tickets, and notify the manager via Teams."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "The SAP SuccessFactors employee ID for the departing employee."
            - name: last_day
              in: body
              type: string
              description: "Last working day in YYYY-MM-DD format."
            - name: manager_upn
              in: body
              type: string
              description: "UPN of the departing employee's manager."
          steps:
            - name: get-employee
              type: call
              call: "successfactors-lookup.get-employee"
              with:
                employee_id: "{{employee_id}}"
            - name: disable-account
              type: call
              call: "azuread.disable-user"
              with:
                user_id: "{{get-employee.azure_object_id}}"
            - name: close-tickets
              type: call
              call: "servicenow-offboard.close-user-incidents"
              with:
                caller_email: "{{get-employee.work_email}}"
            - name: notify-manager
              type: call
              call: "msteams-notify.send-message"
              with:
                recipient_upn: "{{manager_upn}}"
                text: "Offboarding complete for {{get-employee.full_name}} (last day: {{last_day}}). Azure AD account disabled, open tickets closed."
  consumes:
    - type: http
      namespace: successfactors-lookup
      baseUri: "https://api4.successfactors.com/odata/v2"
      authentication:
        type: basic
        username: "$secrets.sf_user"
        password: "$secrets.sf_password"
      resources:
        - name: employees
          path: "/PerPerson('{{employee_id}}')"
          inputParameters:
            - name: employee_id
              in: path
          operations:
            - name: get-employee
              method: GET
    - type: http
      namespace: azuread
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: users
          path: "/users/{{user_id}}"
          inputParameters:
            - name: user_id
              in: path
          operations:
            - name: disable-user
              method: PATCH
    - type: http
      namespace: servicenow-offboard
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: close-user-incidents
              method: PATCH
    - type: http
      namespace: msteams-notify
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: messages
          path: "/users/{{recipient_upn}}/sendMail"
          inputParameters:
            - name: recipient_upn
              in: path
          operations:
            - name: send-message
              method: POST

On new hire creation in SAP SuccessFactors, opens a ServiceNow onboarding ticket, provisions a SharePoint folder, and sends a Microsoft Teams welcome message.

naftiko: "0.5"
info:
  label: "Employee Onboarding Orchestrator"
  description: "On new hire creation in SAP SuccessFactors, opens a ServiceNow onboarding ticket, provisions a SharePoint folder, and sends a Microsoft Teams welcome message."
  tags:
    - hr
    - onboarding
    - sap-successfactors
    - servicenow
    - sharepoint
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: hr-onboarding
      port: 8080
      tools:
        - name: trigger-onboarding
          description: "Given a SuccessFactors employee ID and start date, orchestrate the full onboarding sequence across ServiceNow, SharePoint, and Microsoft Teams."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "The SAP SuccessFactors employee ID for the new hire."
            - name: start_date
              in: body
              type: string
              description: "The employee start date in YYYY-MM-DD format."
            - name: business_unit
              in: body
              type: string
              description: "The Veolia business unit the new hire is joining (e.g., Water, Waste, Energy)."
          steps:
            - name: get-employee
              type: call
              call: "successfactors.get-employee"
              with:
                employee_id: "{{employee_id}}"
            - name: open-ticket
              type: call
              call: "servicenow.create-incident"
              with:
                short_description: "New hire onboarding: {{get-employee.full_name}}"
                category: "hr_onboarding"
                assigned_group: "IT_Onboarding"
                description: "Onboarding for {{get-employee.full_name}} starting {{start_date}} in {{business_unit}}."
            - name: provision-folder
              type: call
              call: "sharepoint.create-folder"
              with:
                site_id: "hr_onboarding_site"
                folder_path: "OnboardingDocs/{{get-employee.full_name}}_{{start_date}}"
            - name: send-welcome
              type: call
              call: "msteams.send-message"
              with:
                recipient_upn: "{{get-employee.work_email}}"
                text: "Welcome to Veolia, {{get-employee.first_name}}! Your IT onboarding ticket is {{open-ticket.number}}."
  consumes:
    - type: http
      namespace: successfactors
      baseUri: "https://api4.successfactors.com/odata/v2"
      authentication:
        type: basic
        username: "$secrets.sf_user"
        password: "$secrets.sf_password"
      resources:
        - name: employees
          path: "/PerPerson('{{employee_id}}')"
          inputParameters:
            - name: employee_id
              in: path
          operations:
            - name: get-employee
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: sharepoint
      baseUri: "https://graph.microsoft.com/v1.0/sites"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: drive-items
          path: "/{{site_id}}/drive/root:/{{folder_path}}"
          inputParameters:
            - name: site_id
              in: path
            - name: folder_path
              in: path
          operations:
            - name: create-folder
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: messages
          path: "/users/{{recipient_upn}}/sendMail"
          inputParameters:
            - name: recipient_upn
              in: path
          operations:
            - name: send-message
              method: POST

When Datadog detects abnormal energy consumption at a facility, queries historical data from Snowflake, creates a ServiceNow investigation, and alerts the energy management team.

naftiko: "0.5"
info:
  label: "Energy Consumption Anomaly Response"
  description: "When Datadog detects abnormal energy consumption at a facility, queries historical data from Snowflake, creates a ServiceNow investigation, and alerts the energy management team."
  tags:
    - energy
    - operations
    - datadog
    - snowflake
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: energy-ops
      port: 8080
      tools:
        - name: investigate-energy-anomaly
          description: "Given a facility and anomaly details, query history, create investigation, and notify."
          inputParameters:
            - name: facility_id
              in: body
              type: string
              description: "The facility identifier."
            - name: current_consumption
              in: body
              type: string
              description: "Current energy consumption reading."
            - name: expected_consumption
              in: body
              type: string
              description: "Expected normal consumption."
          steps:
            - name: get-history
              type: call
              call: "snowflake.execute-query"
              with:
                statement: "SELECT AVG(consumption) as avg_30d FROM ENERGY_DB.PUBLIC.CONSUMPTION WHERE facility_id='{{facility_id}}' AND reading_date >= DATEADD(day, -30, CURRENT_DATE())"
            - name: create-investigation
              type: call
              call: "servicenow.create-incident"
              with:
                short_description: "Energy anomaly: Facility {{facility_id}} — {{current_consumption}} vs expected {{expected_consumption}}"
                description: "30-day average: {{get-history.avg_30d}}. Current: {{current_consumption}}."
                category: "energy_management"
            - name: notify-energy-team
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_energy_channel"
                text: "Energy anomaly at {{facility_id}}: {{current_consumption}} (expected: {{expected_consumption}}, 30d avg: {{get-history.avg_30d}}) | Incident: {{create-investigation.number}}"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://veolia.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/energy/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Tracks environmental permit expiry dates in Snowflake, creates renewal tasks in ServiceNow, and notifies the regulatory affairs team on Teams.

naftiko: "0.5"
info:
  label: "Environmental Permit Renewal Workflow"
  description: "Tracks environmental permit expiry dates in Snowflake, creates renewal tasks in ServiceNow, and notifies the regulatory affairs team on Teams."
  tags:
    - compliance
    - environment
    - snowflake
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: regulatory
      port: 8080
      tools:
        - name: process-permit-renewal
          description: "Given a permit ID, check expiry, create renewal task, and notify regulatory affairs."
          inputParameters:
            - name: permit_id
              in: body
              type: string
              description: "The environmental permit ID."
            - name: facility_name
              in: body
              type: string
              description: "The facility name."
          steps:
            - name: get-permit-details
              type: call
              call: "snowflake.execute-query"
              with:
                statement: "SELECT permit_type, expiry_date, issuing_authority FROM COMPLIANCE_DB.PUBLIC.PERMITS WHERE permit_id='{{permit_id}}'"
            - name: create-renewal-task
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "Permit renewal: {{permit_id}} at {{facility_name}}"
                description: "Permit type: {{get-permit-details.permit_type}}. Expiry: {{get-permit-details.expiry_date}}. Authority: {{get-permit-details.issuing_authority}}."
                assignment_group: "Regulatory_Affairs"
            - name: notify-regulatory
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_regulatory_channel"
                text: "Permit renewal needed: {{permit_id}} at {{facility_name}} | Expiry: {{get-permit-details.expiry_date}} | Task: {{create-renewal-task.number}}"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://veolia.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/regulatory/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

When a GitHub Actions workflow fails on a protected branch, creates a ServiceNow incident and posts an alert to the engineering Teams channel.

naftiko: "0.5"
info:
  label: "GitHub CI/CD Pipeline Failure Handler"
  description: "When a GitHub Actions workflow fails on a protected branch, creates a ServiceNow incident and posts an alert to the engineering Teams channel."
  tags:
    - devops
    - cicd
    - github
    - servicenow
    - microsoft-teams
    - incident-response
capability:
  exposes:
    - type: mcp
      namespace: devops-cicd
      port: 8080
      tools:
        - name: handle-pipeline-failure
          description: "Given a GitHub Actions run ID and repository name, create a ServiceNow incident and alert the engineering Teams channel with failure context."
          inputParameters:
            - name: run_id
              in: body
              type: string
              description: "The GitHub Actions workflow run ID."
            - name: repository
              in: body
              type: string
              description: "The GitHub repository in owner/repo format."
            - name: branch
              in: body
              type: string
              description: "The branch name where the pipeline failed."
            - name: workflow_name
              in: body
              type: string
              description: "The name of the failed GitHub Actions workflow."
          steps:
            - name: get-run
              type: call
              call: "github.get-workflow-run"
              with:
                owner: "veolia"
                repo: "{{repository}}"
                run_id: "{{run_id}}"
            - name: create-incident
              type: call
              call: "servicenow-devops.create-incident"
              with:
                short_description: "[CI Failure] {{repository}} / {{branch}} — {{workflow_name}}"
                description: "GitHub Actions run {{run_id}} failed. Repo: {{repository}}, Branch: {{branch}}, Workflow: {{workflow_name}}. URL: {{get-run.html_url}}"
                category: "software"
            - name: notify-engineering
              type: call
              call: "msteams-eng.post-message"
              with:
                channel_id: "engineering-alerts"
                text: "Pipeline Failure: {{repository}} | Branch: {{branch}} | Workflow: {{workflow_name}} | ServiceNow: {{create-incident.number}} | Run: {{get-run.html_url}}"
  consumes:
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: workflow-runs
          path: "/repos/{{owner}}/{{repo}}/actions/runs/{{run_id}}"
          inputParameters:
            - name: owner
              in: path
            - name: repo
              in: path
            - name: run_id
              in: path
          operations:
            - name: get-workflow-run
              method: GET
    - type: http
      namespace: servicenow-devops
      baseUri: "https://veolia.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-eng
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

When a GitHub security scan finds critical vulnerabilities, creates a Jira ticket, a ServiceNow change request, and notifies the security team on Teams.

naftiko: "0.5"
info:
  label: "GitHub CI/CD Security Scan Remediation"
  description: "When a GitHub security scan finds critical vulnerabilities, creates a Jira ticket, a ServiceNow change request, and notifies the security team on Teams."
  tags:
    - security
    - devops
    - github
    - jira
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: devsecops
      port: 8080
      tools:
        - name: remediate-security-finding
          description: "Given a GitHub repo and alert number, create Jira ticket, CR, and notify security."
          inputParameters:
            - name: repo_name
              in: body
              type: string
              description: "The GitHub repository name."
            - name: alert_number
              in: body
              type: string
              description: "The security alert number."
            - name: severity
              in: body
              type: string
              description: "Alert severity."
          steps:
            - name: get-alert
              type: call
              call: "github.get-security-alert"
              with:
                repo_name: "{{repo_name}}"
                alert_number: "{{alert_number}}"
            - name: create-jira
              type: call
              call: "jira.create-issue"
              with:
                project: "SEC"
                summary: "Security: {{get-alert.package}} in {{repo_name}} ({{severity}})"
                description: "{{get-alert.description}}"
                issue_type: "Bug"
            - name: create-change
              type: call
              call: "servicenow.create-change"
              with:
                short_description: "Security patch: {{get-alert.package}} in {{repo_name}}"
                category: "security"
            - name: notify-security
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_security_channel"
                text: "Security finding: {{severity}} in {{repo_name}} | {{get-alert.package}} | Jira: {{create-jira.key}} | CR: {{create-change.number}}"
  consumes:
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: alerts
          path: "/repos/{{repo_name}}/dependabot/alerts/{{alert_number}}"
          inputParameters:
            - name: repo_name
              in: path
            - name: alert_number
              in: path
          operations:
            - name: get-security-alert
              method: GET
    - type: http
      namespace: jira
      baseUri: "https://veolia.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: changes
          path: "/table/change_request"
          operations:
            - name: create-change
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/security/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Monitors GitHub Dependabot alerts for critical dependency vulnerabilities across Veolia repositories and creates ServiceNow security incidents for remediation tracking.

naftiko: "0.5"
info:
  label: "GitHub Dependency Vulnerability Alert"
  description: "Monitors GitHub Dependabot alerts for critical dependency vulnerabilities across Veolia repositories and creates ServiceNow security incidents for remediation tracking."
  tags:
    - devops
    - security
    - github
    - servicenow
    - vulnerability
    - dependency-management
capability:
  exposes:
    - type: mcp
      namespace: dependency-security
      port: 8080
      tools:
        - name: handle-dependabot-alert
          description: "Given a GitHub repository and Dependabot alert number, fetch alert details and create a ServiceNow security incident for remediation. Use when critical dependency vulnerabilities are detected."
          inputParameters:
            - name: repository
              in: body
              type: string
              description: "GitHub repository in owner/repo format."
            - name: alert_number
              in: body
              type: integer
              description: "The Dependabot alert number."
          steps:
            - name: get-alert
              type: call
              call: "github-deps.get-dependabot-alert"
              with:
                repo: "{{repository}}"
                alert_number: "{{alert_number}}"
            - name: create-sec-incident
              type: call
              call: "servicenow-vuln.create-incident"
              with:
                short_description: "Dependabot vulnerability: {{get-alert.security_advisory.summary}} in {{repository}}"
                description: "CVE: {{get-alert.security_advisory.cve_id}}. Severity: {{get-alert.security_advisory.severity}}. Package: {{get-alert.dependency.package.name}}. Repository: {{repository}}."
                category: "security"
  consumes:
    - type: http
      namespace: github-deps
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: dependabot-alerts
          path: "/repos/{{repo}}/dependabot/alerts/{{alert_number}}"
          inputParameters:
            - name: repo
              in: path
            - name: alert_number
              in: path
          operations:
            - name: get-dependabot-alert
              method: GET
    - type: http
      namespace: servicenow-vuln
      baseUri: "https://veolia.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

When a GitHub Actions production deployment is requested, creates a ServiceNow change request and notifies the release channel on Teams.

naftiko: "0.5"
info:
  label: "GitHub Deployment Approval Gate"
  description: "When a GitHub Actions production deployment is requested, creates a ServiceNow change request and notifies the release channel on Teams."
  tags:
    - devops
    - github
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: release-mgmt
      port: 8080
      tools:
        - name: gate-deployment
          description: "Given a repo and workflow run, create a change request and notify."
          inputParameters:
            - name: repo_name
              in: body
              type: string
              description: "The GitHub repository."
            - name: run_id
              in: body
              type: string
              description: "The workflow run ID."
          steps:
            - name: get-run
              type: call
              call: "github.get-workflow-run"
              with:
                repo_name: "{{repo_name}}"
                run_id: "{{run_id}}"
            - name: create-cr
              type: call
              call: "servicenow.create-change"
              with:
                short_description: "Deployment: {{repo_name}} — {{get-run.head_sha}}"
                category: "deployment"
            - name: notify
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_release_channel"
                text: "Deployment gate: {{repo_name}} | CR: {{create-cr.number}} | Commit: {{get-run.head_sha}}"
  consumes:
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: runs
          path: "/repos/{{repo_name}}/actions/runs/{{run_id}}"
          inputParameters:
            - name: repo_name
              in: path
            - name: run_id
              in: path
          operations:
            - name: get-workflow-run
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: changes
          path: "/table/change_request"
          operations:
            - name: create-change
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/release/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

On a successful GitHub release, generates release notes using Anthropic and posts them to the Microsoft Teams engineering channel and updates the ServiceNow CMDB.

naftiko: "0.5"
info:
  label: "GitHub Deployment Release Notes"
  description: "On a successful GitHub release, generates release notes using Anthropic and posts them to the Microsoft Teams engineering channel and updates the ServiceNow CMDB."
  tags:
    - devops
    - release-management
    - github
    - anthropic
    - microsoft-teams
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: release-notes
      port: 8080
      tools:
        - name: publish-release-notes
          description: "Given a GitHub release tag and repository, generate AI-formatted release notes via Anthropic, post to the Teams engineering channel, and update the ServiceNow CMDB application record."
          inputParameters:
            - name: repository
              in: body
              type: string
              description: "GitHub repository in owner/repo format."
            - name: release_tag
              in: body
              type: string
              description: "The GitHub release tag (e.g., v2.3.0)."
            - name: teams_channel_id
              in: body
              type: string
              description: "Microsoft Teams channel ID for publishing release notes."
            - name: cmdb_app_id
              in: body
              type: string
              description: "ServiceNow CMDB application CI sys_id to update."
          steps:
            - name: get-release
              type: call
              call: "github-release.get-release"
              with:
                repo: "{{repository}}"
                tag: "{{release_tag}}"
            - name: generate-notes
              type: call
              call: "anthropic-notes.create-message"
              with:
                model: "claude-opus-4-5"
                max_tokens: 512
                prompt: "Format the following GitHub release body as clean, user-friendly release notes: {{get-release.body}}"
            - name: post-to-teams
              type: call
              call: "msteams-release.post-message"
              with:
                channel_id: "{{teams_channel_id}}"
                text: "Release {{release_tag}} for {{repository}} is live. {{generate-notes.content}}"
            - name: update-cmdb
              type: call
              call: "servicenow-cmdb.update-ci"
              with:
                sys_id: "{{cmdb_app_id}}"
                version: "{{release_tag}}"
                release_notes: "{{generate-notes.content}}"
  consumes:
    - type: http
      namespace: github-release
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: releases
          path: "/repos/{{repo}}/releases/tags/{{tag}}"
          inputParameters:
            - name: repo
              in: path
            - name: tag
              in: path
          operations:
            - name: get-release
              method: GET
    - type: http
      namespace: anthropic-notes
      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-release
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST
    - type: http
      namespace: servicenow-cmdb
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: cmdb-ci
          path: "/table/cmdb_ci_appl/{{sys_id}}"
          inputParameters:
            - name: sys_id
              in: path
          operations:
            - name: update-ci
              method: PATCH

Retrieves branch protection rules for a GitHub repository to verify compliance with security policies.

naftiko: "0.5"
info:
  label: "GitHub Repository Branch Protection Check"
  description: "Retrieves branch protection rules for a GitHub repository to verify compliance with security policies."
  tags:
    - security
    - github
capability:
  exposes:
    - type: mcp
      namespace: devsecops
      port: 8080
      tools:
        - name: get-branch-protection
          description: "Check branch protection rules on a GitHub repo."
          inputParameters:
            - name: repo_name
              in: body
              type: string
              description: "The GitHub repository name."
            - name: branch
              in: body
              type: string
              description: "The branch name to check."
          call: "github.get-branch-protection"
          with:
            repo_name: "{{repo_name}}"
            branch: "{{branch}}"
          outputParameters:
            - name: required_reviews
              type: integer
              mapping: "$.required_pull_request_reviews.required_approving_review_count"
  consumes:
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: branch-protection
          path: "/repos/{{repo_name}}/branches/{{branch}}/protection"
          inputParameters:
            - name: repo_name
              in: path
            - name: branch
              in: path
          operations:
            - name: get-branch-protection
              method: GET

When a GitHub Advanced Security scan completes, fetches vulnerability alerts for critical findings and creates ServiceNow security incidents for each critical or high severity result.

naftiko: "0.5"
info:
  label: "GitHub Security Scan Results Triage"
  description: "When a GitHub Advanced Security scan completes, fetches vulnerability alerts for critical findings and creates ServiceNow security incidents for each critical or high severity result."
  tags:
    - devops
    - security
    - github
    - servicenow
    - vulnerability
capability:
  exposes:
    - type: mcp
      namespace: security-triage
      port: 8080
      tools:
        - name: triage-security-alerts
          description: "Given a GitHub repository, fetch open code scanning alerts at critical or high severity and create a ServiceNow security incident for each finding. Use after automated security scans complete."
          inputParameters:
            - name: repository
              in: body
              type: string
              description: "GitHub repository in owner/repo format."
            - name: severity_filter
              in: body
              type: string
              description: "Minimum severity to triage: critical or high."
          steps:
            - name: get-alerts
              type: call
              call: "github-sec.list-code-scanning-alerts"
              with:
                repo: "{{repository}}"
                severity: "{{severity_filter}}"
            - name: create-security-incident
              type: call
              call: "servicenow-sec.create-incident"
              with:
                short_description: "Security scan findings in {{repository}} ({{severity_filter}})"
                description: "GitHub code scanning found {{get-alerts.total_count}} {{severity_filter}} alerts in {{repository}}. Review required."
                category: "security"
                urgency: "1"
  consumes:
    - type: http
      namespace: github-sec
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: code-scanning-alerts
          path: "/repos/{{repo}}/code-scanning/alerts"
          inputParameters:
            - name: repo
              in: path
          operations:
            - name: list-code-scanning-alerts
              method: GET
    - type: http
      namespace: servicenow-sec
      baseUri: "https://veolia.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

Tracks hazardous waste manifests from SAP, validates against regulatory thresholds in Snowflake, and creates compliance alerts in ServiceNow.

naftiko: "0.5"
info:
  label: "Hazardous Waste Manifest Tracking"
  description: "Tracks hazardous waste manifests from SAP, validates against regulatory thresholds in Snowflake, and creates compliance alerts in ServiceNow."
  tags:
    - compliance
    - waste-management
    - sap
    - snowflake
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: hazwaste
      port: 8080
      tools:
        - name: track-manifest
          description: "Given a manifest ID, validate against thresholds and create alert if needed."
          inputParameters:
            - name: manifest_id
              in: body
              type: string
              description: "The hazardous waste manifest ID."
            - name: facility_id
              in: body
              type: string
              description: "The generating facility."
          steps:
            - name: get-manifest
              type: call
              call: "sap.get-waste-manifest"
              with:
                manifest_id: "{{manifest_id}}"
            - name: check-threshold
              type: call
              call: "snowflake.execute-query"
              with:
                statement: "SELECT SUM(quantity) as ytd_total FROM COMPLIANCE_DB.PUBLIC.HAZWASTE WHERE facility_id='{{facility_id}}' AND waste_code='{{get-manifest.waste_code}}' AND YEAR(manifest_date)=YEAR(CURRENT_DATE())"
            - name: create-alert
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "Hazwaste tracking: {{get-manifest.waste_code}} at {{facility_id}}"
                description: "Manifest: {{manifest_id}}. Quantity: {{get-manifest.quantity}}. YTD total: {{check-threshold.ytd_total}}."
                assignment_group: "EHS_Compliance"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://veolia-s4.sap.com/sap/opu/odata/sap/API_WASTE_MANIFEST_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: manifests
          path: "/A_WasteManifest('{{manifest_id}}')"
          inputParameters:
            - name: manifest_id
              in: path
          operations:
            - name: get-waste-manifest
              method: GET
    - type: http
      namespace: snowflake
      baseUri: "https://veolia.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-query
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST

Retrieves current headcount by business unit and cost center from SAP SuccessFactors for use in workforce planning and finance reporting.

naftiko: "0.5"
info:
  label: "Headcount and Payroll Snapshot"
  description: "Retrieves current headcount by business unit and cost center from SAP SuccessFactors for use in workforce planning and finance reporting."
  tags:
    - hr
    - finance
    - reporting
    - sap-successfactors
    - headcount
capability:
  exposes:
    - type: mcp
      namespace: hr-reporting
      port: 8080
      tools:
        - name: get-headcount-snapshot
          description: "Returns a list of active employees grouped by business unit and cost center. Use for headcount planning, cost analysis, or period-end finance reporting."
          call: "successfactors-hc.list-employees"
          outputParameters:
            - name: employees
              type: array
              mapping: "$.d.results"
              items:
                - name: employee_id
                  type: string
                  mapping: "$.userId"
                - name: full_name
                  type: string
                  mapping: "$.displayName"
                - name: business_unit
                  type: string
                  mapping: "$.businessUnit"
                - name: cost_center
                  type: string
                  mapping: "$.costCenter"
                - name: employment_type
                  type: string
                  mapping: "$.employmentType"
  consumes:
    - type: http
      namespace: successfactors-hc
      baseUri: "https://api4.successfactors.com/odata/v2"
      authentication:
        type: basic
        username: "$secrets.sf_user"
        password: "$secrets.sf_password"
      resources:
        - name: employees
          path: "/User"
          operations:
            - name: list-employees
              method: GET

When a critical alert fires in Datadog for Veolia's water or waste management systems, creates a ServiceNow P1 incident and notifies the on-call team via Microsoft Teams.

naftiko: "0.5"
info:
  label: "IT Incident Response Handler"
  description: "When a critical alert fires in Datadog for Veolia's water or waste management systems, creates a ServiceNow P1 incident and notifies the on-call team via Microsoft Teams."
  tags:
    - itsm
    - incident-response
    - datadog
    - servicenow
    - microsoft-teams
    - operations
capability:
  exposes:
    - type: mcp
      namespace: itsm-ops
      port: 8080
      tools:
        - name: handle-critical-alert
          description: "Given a Datadog alert ID and monitor name, create a P1 ServiceNow incident and alert the on-call channel in Microsoft Teams. Use when a critical infrastructure or OT system alert is triggered."
          inputParameters:
            - name: alert_id
              in: body
              type: string
              description: "The Datadog alert or event ID."
            - name: monitor_name
              in: body
              type: string
              description: "The name of the Datadog monitor that fired."
            - name: affected_system
              in: body
              type: string
              description: "The affected system or service name (e.g., SCADA-Water-Paris)."
            - name: severity
              in: body
              type: string
              description: "Alert severity level: critical, high, medium, or low."
          steps:
            - name: get-alert
              type: call
              call: "datadog.get-event"
              with:
                event_id: "{{alert_id}}"
            - name: create-incident
              type: call
              call: "servicenow-incidents.create-incident"
              with:
                short_description: "[{{severity}}] {{monitor_name}} — {{affected_system}}"
                description: "Datadog alert {{alert_id}} triggered. Monitor: {{monitor_name}}. System: {{affected_system}}. Details: {{get-alert.text}}"
                urgency: "1"
                impact: "1"
            - name: notify-oncall
              type: call
              call: "msteams-ops.post-message"
              with:
                channel_id: "oncall-operations"
                text: "P1 Incident {{create-incident.number}}: {{monitor_name}} on {{affected_system}}. Severity: {{severity}}. Ticket: {{create-incident.sys_id}}"
  consumes:
    - type: http
      namespace: datadog
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: events
          path: "/events/{{event_id}}"
          inputParameters:
            - name: event_id
              in: path
          operations:
            - name: get-event
              method: GET
    - type: http
      namespace: servicenow-incidents
      baseUri: "https://veolia.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-ops
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

Retrieves the current status, assignee, and priority of a Jira issue by key.

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

At sprint close, fetches metrics from Jira, publishes to Confluence, and notifies the team on Teams.

naftiko: "0.5"
info:
  label: "Jira Sprint Report to Confluence"
  description: "At sprint close, fetches metrics from Jira, publishes to Confluence, and notifies the team on Teams."
  tags:
    - project-management
    - jira
    - confluence
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: agile
      port: 8080
      tools:
        - name: publish-sprint-report
          description: "Given a board and sprint ID, pull metrics and publish."
          inputParameters:
            - name: board_id
              in: body
              type: string
              description: "The Jira board ID."
            - name: sprint_id
              in: body
              type: string
              description: "The sprint ID."
          steps:
            - name: get-sprint
              type: call
              call: "jira.get-sprint-report"
              with:
                board_id: "{{board_id}}"
                sprint_id: "{{sprint_id}}"
            - name: publish
              type: call
              call: "confluence.create-page"
              with:
                space_key: "ENG"
                title: "Sprint: {{get-sprint.sprint_name}}"
                body: "Completed: {{get-sprint.completed_points}} | Incomplete: {{get-sprint.incomplete_points}}"
            - name: notify
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_eng_channel"
                text: "Sprint report: {{get-sprint.sprint_name}} | {{publish.url}}"
  consumes:
    - type: http
      namespace: jira
      baseUri: "https://veolia.atlassian.net/rest/agile/1.0"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: sprints
          path: "/board/{{board_id}}/sprint/{{sprint_id}}/report"
          inputParameters:
            - name: board_id
              in: path
            - name: sprint_id
              in: path
          operations:
            - name: get-sprint-report
              method: GET
    - type: http
      namespace: confluence
      baseUri: "https://veolia.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_api_token"
      resources:
        - name: pages
          path: "/content"
          operations:
            - name: create-page
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/eng/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Creates a LinkedIn job posting from a Workday requisition, creates a Jira recruiting task, and notifies the talent acquisition team.

naftiko: "0.5"
info:
  label: "LinkedIn Talent Outreach Workflow"
  description: "Creates a LinkedIn job posting from a Workday requisition, creates a Jira recruiting task, and notifies the talent acquisition team."
  tags:
    - hr
    - recruiting
    - linkedin
    - workday
    - jira
capability:
  exposes:
    - type: mcp
      namespace: talent
      port: 8080
      tools:
        - name: post-job-listing
          description: "Given a Workday requisition ID, create LinkedIn post and track in Jira."
          inputParameters:
            - name: requisition_id
              in: body
              type: string
              description: "The Workday requisition ID."
          steps:
            - name: get-req
              type: call
              call: "workday.get-requisition"
              with:
                requisition_id: "{{requisition_id}}"
            - name: create-post
              type: call
              call: "linkedin.create-job-post"
              with:
                title: "{{get-req.job_title}}"
                description: "{{get-req.job_description}}"
                location: "{{get-req.location}}"
            - name: create-task
              type: call
              call: "jira.create-issue"
              with:
                project: "RECRUIT"
                summary: "LinkedIn post: {{get-req.job_title}}"
                issue_type: "Task"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: requisitions
          path: "/veolia/jobRequisitions/{{requisition_id}}"
          inputParameters:
            - name: requisition_id
              in: path
          operations:
            - name: get-requisition
              method: GET
    - type: http
      namespace: linkedin
      baseUri: "https://api.linkedin.com/v2"
      authentication:
        type: bearer
        token: "$secrets.linkedin_token"
      resources:
        - name: jobs
          path: "/simpleJobPostings"
          operations:
            - name: create-job-post
              method: POST
    - type: http
      namespace: jira
      baseUri: "https://veolia.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST

Pulls new applicant activity from LinkedIn Recruiter for open Veolia positions and creates candidate records in SAP SuccessFactors Recruiting.

naftiko: "0.5"
info:
  label: "LinkedIn Talent Pipeline Digest"
  description: "Pulls new applicant activity from LinkedIn Recruiter for open Veolia positions and creates candidate records in SAP SuccessFactors Recruiting."
  tags:
    - hr
    - recruiting
    - linkedin
    - sap-successfactors
    - talent-acquisition
capability:
  exposes:
    - type: mcp
      namespace: talent-pipeline
      port: 8080
      tools:
        - name: sync-linkedin-candidates
          description: "Given a LinkedIn job posting ID and SuccessFactors requisition ID, fetch new applicants from LinkedIn and create or update candidate records in SuccessFactors. Use for daily recruiting pipeline sync."
          inputParameters:
            - name: linkedin_job_id
              in: body
              type: string
              description: "The LinkedIn job posting ID."
            - name: sf_requisition_id
              in: body
              type: string
              description: "The SAP SuccessFactors job requisition ID."
          steps:
            - name: get-applicants
              type: call
              call: "linkedin.get-job-applicants"
              with:
                job_id: "{{linkedin_job_id}}"
            - name: create-candidates
              type: call
              call: "successfactors-recruit.create-candidate"
              with:
                requisition_id: "{{sf_requisition_id}}"
                applicants: "{{get-applicants.elements}}"
  consumes:
    - type: http
      namespace: linkedin
      baseUri: "https://api.linkedin.com/v2"
      authentication:
        type: bearer
        token: "$secrets.linkedin_token"
      resources:
        - name: job-applicants
          path: "/jobApplications"
          operations:
            - name: get-job-applicants
              method: GET
    - type: http
      namespace: successfactors-recruit
      baseUri: "https://api4.successfactors.com/odata/v2"
      authentication:
        type: basic
        username: "$secrets.sf_user"
        password: "$secrets.sf_password"
      resources:
        - name: candidates
          path: "/Candidate"
          operations:
            - name: create-candidate
              method: POST

Fetches Microsoft 365 license utilization data via Microsoft Graph and posts an underutilization report to the IT management Teams channel for cost optimization review.

naftiko: "0.5"
info:
  label: "Microsoft 365 License Usage Report"
  description: "Fetches Microsoft 365 license utilization data via Microsoft Graph and posts an underutilization report to the IT management Teams channel for cost optimization review."
  tags:
    - it-operations
    - microsoft-365
    - cost-optimization
    - microsoft-teams
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: m365-reporting
      port: 8080
      tools:
        - name: report-license-utilization
          description: "Fetch Microsoft 365 license assignment and activity data from Microsoft Graph and post an underutilization summary to the IT management Teams channel."
          inputParameters:
            - name: report_period
              in: body
              type: string
              description: "Reporting period: D7, D30, D90, or D180."
            - name: it_channel_id
              in: body
              type: string
              description: "Microsoft Teams channel ID for the IT management team."
          steps:
            - name: get-license-report
              type: call
              call: "msgraph-licenses.get-office365-activations"
              with:
                period: "{{report_period}}"
            - name: post-utilization-report
              type: call
              call: "msteams-it.post-message"
              with:
                channel_id: "{{it_channel_id}}"
                text: "M365 License Utilization ({{report_period}}): {{get-license-report.assigned_count}} licenses assigned, {{get-license-report.active_count}} active. Review inactive licenses for cost savings."
  consumes:
    - type: http
      namespace: msgraph-licenses
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: office365-activations
          path: "/reports/getOffice365ActivationsUserDetail(period='{{period}}')"
          inputParameters:
            - name: period
              in: path
          operations:
            - name: get-office365-activations
              method: GET
    - type: http
      namespace: msteams-it
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

Posts a message to a specified Microsoft Teams channel using the Graph API.

naftiko: "0.5"
info:
  label: "Microsoft Teams Channel Message Post"
  description: "Posts a message to a specified Microsoft Teams channel using the Graph API."
  tags:
    - communications
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: comms
      port: 8080
      tools:
        - name: post-teams-message
          description: "Send a message to a Microsoft Teams channel."
          inputParameters:
            - name: team_id
              in: body
              type: string
              description: "The Teams team ID."
            - name: channel_id
              in: body
              type: string
              description: "The Teams channel ID."
            - name: message_text
              in: body
              type: string
              description: "The message content."
          call: "msteams.post-channel-message"
          with:
            team_id: "{{team_id}}"
            channel_id: "{{channel_id}}"
            text: "{{message_text}}"
          outputParameters:
            - name: message_id
              type: string
              mapping: "$.id"
  consumes:
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

On role assignment in SAP SuccessFactors, provisions the appropriate Azure AD group memberships and Microsoft 365 license for the new hire's job function.

naftiko: "0.5"
info:
  label: "New Hire Role-Based Access Provisioning"
  description: "On role assignment in SAP SuccessFactors, provisions the appropriate Azure AD group memberships and Microsoft 365 license for the new hire's job function."
  tags:
    - hr
    - identity
    - sap-successfactors
    - azure-ad
    - access-management
    - onboarding
capability:
  exposes:
    - type: mcp
      namespace: identity-provisioning
      port: 8080
      tools:
        - name: provision-role-based-access
          description: "Given a SuccessFactors employee ID and job role, assign the correct Azure AD security groups and Microsoft 365 license SKU for the role. Use during onboarding or role transitions."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "SAP SuccessFactors employee ID."
            - name: job_role
              in: body
              type: string
              description: "Job role or function (e.g., FieldEngineer, FinanceAnalyst, PlantManager)."
            - name: azure_group_id
              in: body
              type: string
              description: "Azure AD security group ID corresponding to the job role."
            - name: m365_sku_id
              in: body
              type: string
              description: "Microsoft 365 license SKU ID to assign (e.g., ENTERPRISEPACK)."
          steps:
            - name: get-employee-aad-id
              type: call
              call: "azuread-identity.get-user"
              with:
                upn: "{{employee_id}}@veolia.com"
            - name: add-to-group
              type: call
              call: "azuread-groups.add-member"
              with:
                group_id: "{{azure_group_id}}"
                user_id: "{{get-employee-aad-id.id}}"
            - name: assign-license
              type: call
              call: "azuread-license.assign-license"
              with:
                user_id: "{{get-employee-aad-id.id}}"
                sku_id: "{{m365_sku_id}}"
  consumes:
    - type: http
      namespace: azuread-identity
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: users
          path: "/users/{{upn}}"
          inputParameters:
            - name: upn
              in: path
          operations:
            - name: get-user
              method: GET
    - type: http
      namespace: azuread-groups
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: group-members
          path: "/groups/{{group_id}}/members/$ref"
          inputParameters:
            - name: group_id
              in: path
          operations:
            - name: add-member
              method: POST
    - type: http
      namespace: azuread-license
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: license-assignments
          path: "/users/{{user_id}}/assignLicense"
          inputParameters:
            - name: user_id
              in: path
          operations:
            - name: assign-license
              method: POST

When a firewall rule change is requested, creates a ServiceNow change request, validates with the network team, and applies the rule via Palo Alto API.

naftiko: "0.5"
info:
  label: "Palo Alto Firewall Policy Change Workflow"
  description: "When a firewall rule change is requested, creates a ServiceNow change request, validates with the network team, and applies the rule via Palo Alto API."
  tags:
    - security
    - network
    - palo-alto-networks
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: network-ops
      port: 8080
      tools:
        - name: process-firewall-change
          description: "Given a rule change request, create CR, validate, and notify."
          inputParameters:
            - name: rule_name
              in: body
              type: string
              description: "The firewall rule name."
            - name: action
              in: body
              type: string
              description: "The requested action (add, modify, delete)."
            - name: justification
              in: body
              type: string
              description: "Business justification."
          steps:
            - name: create-change
              type: call
              call: "servicenow.create-change"
              with:
                short_description: "Firewall change: {{action}} rule {{rule_name}}"
                description: "{{justification}}"
                category: "network"
            - name: notify-network
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_network_channel"
                text: "Firewall change request: {{action}} rule {{rule_name}} | CR: {{create-change.number}} | {{justification}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: changes
          path: "/table/change_request"
          operations:
            - name: create-change
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/network/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Retrieves a specific firewall rule from Palo Alto Networks by rule name for security audit review.

naftiko: "0.5"
info:
  label: "Palo Alto Firewall Rule Lookup"
  description: "Retrieves a specific firewall rule from Palo Alto Networks by rule name for security audit review."
  tags:
    - security
    - palo-alto-networks
capability:
  exposes:
    - type: mcp
      namespace: network-security
      port: 8080
      tools:
        - name: get-firewall-rule
          description: "Look up a Palo Alto firewall rule by name. Returns source, destination, and action."
          inputParameters:
            - name: rule_name
              in: body
              type: string
              description: "The firewall rule name."
          call: "paloalto.get-rule"
          with:
            rule_name: "{{rule_name}}"
          outputParameters:
            - name: action
              type: string
              mapping: "$.result.action"
            - name: source_zone
              type: string
              mapping: "$.result.from"
  consumes:
    - type: http
      namespace: paloalto
      baseUri: "https://veolia-fw.paloaltonetworks.com/restapi/v10.2"
      authentication:
        type: apikey
        key: "X-PAN-KEY"
        value: "$secrets.paloalto_api_key"
        placement: header
      resources:
        - name: rules
          path: "/Policies/SecurityRules?name={{rule_name}}"
          inputParameters:
            - name: rule_name
              in: query
          operations:
            - name: get-rule
              method: GET

Queries Palo Alto Networks for recent firewall policy changes, cross-references against the approved change list in ServiceNow, and flags unauthorized changes via Microsoft Teams.

naftiko: "0.5"
info:
  label: "Palo Alto Networks Firewall Policy Audit"
  description: "Queries Palo Alto Networks for recent firewall policy changes, cross-references against the approved change list in ServiceNow, and flags unauthorized changes via Microsoft Teams."
  tags:
    - security
    - palo-alto-networks
    - servicenow
    - microsoft-teams
    - compliance
    - firewall
capability:
  exposes:
    - type: mcp
      namespace: security-compliance
      port: 8080
      tools:
        - name: audit-firewall-changes
          description: "Fetch recent firewall policy changes from Palo Alto Networks and compare against approved ServiceNow change records. Post any unauthorized changes to the security Teams channel."
          inputParameters:
            - name: audit_start_time
              in: body
              type: string
              description: "Start of the audit window in ISO 8601 format."
            - name: security_channel_id
              in: body
              type: string
              description: "Microsoft Teams channel ID for the security operations team."
          steps:
            - name: get-fw-changes
              type: call
              call: "paloalto.get-audit-log"
              with:
                start_time: "{{audit_start_time}}"
            - name: check-approved-changes
              type: call
              call: "servicenow-security.list-approved-changes"
              with:
                start_date: "{{audit_start_time}}"
            - name: flag-unauthorized
              type: call
              call: "msteams-security.post-message"
              with:
                channel_id: "{{security_channel_id}}"
                text: "Firewall Audit: {{get-fw-changes.total}} changes detected since {{audit_start_time}}. Approved changes in ServiceNow: {{check-approved-changes.count}}. Review discrepancies immediately."
  consumes:
    - type: http
      namespace: paloalto
      baseUri: "https://veolia-fw.veolia.com/restapi/v10.1"
      authentication:
        type: apikey
        key: "X-PAN-KEY"
        value: "$secrets.paloalto_api_key"
        placement: header
      resources:
        - name: audit-logs
          path: "/log/audit"
          operations:
            - name: get-audit-log
              method: GET
    - type: http
      namespace: servicenow-security
      baseUri: "https://veolia.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: list-approved-changes
              method: GET
    - type: http
      namespace: msteams-security
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

When a Power BI data alert triggers on an operations KPI, posts a formatted summary to the operations Teams channel.

naftiko: "0.5"
info:
  label: "Power BI Operations Dashboard Alert"
  description: "When a Power BI data alert triggers on an operations KPI, posts a formatted summary to the operations Teams channel."
  tags:
    - analytics
    - power-bi
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: bi-alerts
      port: 8080
      tools:
        - name: forward-ops-alert
          description: "Given a Power BI alert, notify operations."
          inputParameters:
            - name: alert_id
              in: body
              type: string
              description: "The Power BI alert ID."
            - name: dashboard_id
              in: body
              type: string
              description: "The dashboard ID."
          steps:
            - name: get-alert
              type: call
              call: "powerbi.get-alert"
              with:
                alert_id: "{{alert_id}}"
                dashboard_id: "{{dashboard_id}}"
            - name: notify
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_ops_channel"
                text: "BI Alert: {{get-alert.title}} | Value: {{get-alert.current_value}} | Condition: {{get-alert.condition}}"
  consumes:
    - type: http
      namespace: powerbi
      baseUri: "https://api.powerbi.com/v1.0/myorg"
      authentication:
        type: bearer
        token: "$secrets.powerbi_token"
      resources:
        - name: alerts
          path: "/dashboards/{{dashboard_id}}/alerts/{{alert_id}}"
          inputParameters:
            - name: dashboard_id
              in: path
            - name: alert_id
              in: path
          operations:
            - name: get-alert
              method: GET
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Checks the export status of a Power BI report by export ID, returning completion state and download URL.

naftiko: "0.5"
info:
  label: "Power BI Report Export Status"
  description: "Checks the export status of a Power BI report by export ID, returning completion state and download URL."
  tags:
    - analytics
    - power-bi
capability:
  exposes:
    - type: mcp
      namespace: bi-reporting
      port: 8080
      tools:
        - name: get-export-status
          description: "Check a Power BI report export status."
          inputParameters:
            - name: group_id
              in: body
              type: string
              description: "The Power BI workspace ID."
            - name: report_id
              in: body
              type: string
              description: "The Power BI report ID."
            - name: export_id
              in: body
              type: string
              description: "The export operation ID."
          call: "powerbi.get-export"
          with:
            group_id: "{{group_id}}"
            report_id: "{{report_id}}"
            export_id: "{{export_id}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.status"
  consumes:
    - type: http
      namespace: powerbi
      baseUri: "https://api.powerbi.com/v1.0/myorg"
      authentication:
        type: bearer
        token: "$secrets.powerbi_token"
      resources:
        - name: exports
          path: "/groups/{{group_id}}/reports/{{report_id}}/exports/{{export_id}}"
          inputParameters:
            - name: group_id
              in: path
            - name: report_id
              in: path
            - name: export_id
              in: path
          operations:
            - name: get-export
              method: GET

Enriches Salesforce customer accounts with operational health scores derived from Veolia's service delivery data stored in Snowflake.

naftiko: "0.5"
info:
  label: "Salesforce Account Health Score Enrichment"
  description: "Enriches Salesforce customer accounts with operational health scores derived from Veolia's service delivery data stored in Snowflake."
  tags:
    - crm
    - salesforce
    - snowflake
    - customer-success
    - data-enrichment
capability:
  exposes:
    - type: mcp
      namespace: crm-enrichment
      port: 8080
      tools:
        - name: enrich-account-health-score
          description: "Given a Salesforce account ID, query Snowflake for the customer's service delivery KPIs and update the Salesforce account with a calculated health score."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "Salesforce account ID (18-character)."
            - name: customer_contract_ref
              in: body
              type: string
              description: "Internal contract reference used as Snowflake lookup key."
          steps:
            - name: get-kpis
              type: call
              call: "snowflake-kpi.execute-query"
              with:
                statement: "SELECT avg_response_time, sla_compliance_pct, incident_count FROM service_delivery.customer_kpis WHERE contract_ref = '{{customer_contract_ref}}'"
            - name: update-account
              type: call
              call: "salesforce-account.update-account"
              with:
                account_id: "{{account_id}}"
                health_score: "{{get-kpis.sla_compliance_pct}}"
                avg_response_time: "{{get-kpis.avg_response_time}}"
                incident_count: "{{get-kpis.incident_count}}"
  consumes:
    - type: http
      namespace: snowflake-kpi
      baseUri: "https://veolia.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-query
              method: POST
    - type: http
      namespace: salesforce-account
      baseUri: "https://veolia.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: update-account
              method: PATCH

Retrieves a Salesforce contact record by email address, returning name, account, title, and phone number.

naftiko: "0.5"
info:
  label: "Salesforce Contact Lookup"
  description: "Retrieves a Salesforce contact record by email address, returning name, account, title, and phone number."
  tags:
    - crm
    - salesforce
capability:
  exposes:
    - type: mcp
      namespace: crm
      port: 8080
      tools:
        - name: get-contact-by-email
          description: "Look up a Salesforce contact by email address. Returns full name, account, and title."
          inputParameters:
            - name: email
              in: body
              type: string
              description: "The contact email address."
          call: "salesforce.query-contact"
          with:
            email: "{{email}}"
          outputParameters:
            - name: name
              type: string
              mapping: "$.records[0].Name"
            - name: account_name
              type: string
              mapping: "$.records[0].Account.Name"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://veolia.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: contacts
          path: "/query?q=SELECT+Name,Account.Name,Title+FROM+Contact+WHERE+Email='{{email}}'"
          inputParameters:
            - name: email
              in: query
          operations:
            - name: query-contact
              method: GET

When a customer complaint is logged in Salesforce, creates a ServiceNow investigation task and notifies the operations team on Teams.

naftiko: "0.5"
info:
  label: "Salesforce Customer Complaint Routing"
  description: "When a customer complaint is logged in Salesforce, creates a ServiceNow investigation task and notifies the operations team on Teams."
  tags:
    - customer-service
    - salesforce
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: customer-ops
      port: 8080
      tools:
        - name: route-complaint
          description: "Given a Salesforce case ID, create investigation task and notify."
          inputParameters:
            - name: case_id
              in: body
              type: string
              description: "The Salesforce case ID."
          steps:
            - name: get-case
              type: call
              call: "salesforce.get-case"
              with:
                case_id: "{{case_id}}"
            - name: create-task
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "Customer complaint: {{get-case.subject}}"
                description: "Account: {{get-case.account_name}}. Priority: {{get-case.priority}}."
                assignment_group: "Operations_Support"
            - name: notify-ops
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_ops_channel"
                text: "Customer complaint: {{get-case.subject}} | Account: {{get-case.account_name}} | Task: {{create-task.number}}"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://veolia.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: cases
          path: "/sobjects/Case/{{case_id}}"
          inputParameters:
            - name: case_id
              in: path
          operations:
            - name: get-case
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Fetches NPS survey responses linked to Salesforce accounts and updates the account record with the latest score and comment for account management follow-up.

naftiko: "0.5"
info:
  label: "Salesforce Customer NPS Sync"
  description: "Fetches NPS survey responses linked to Salesforce accounts and updates the account record with the latest score and comment for account management follow-up."
  tags:
    - crm
    - customer-success
    - salesforce
    - nps
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: crm-nps
      port: 8080
      tools:
        - name: sync-nps-to-account
          description: "Given a Salesforce account ID and NPS score with comment, update the account record in Salesforce with the latest NPS data. Use after NPS survey results are received."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The Salesforce account ID (18-character)."
            - name: nps_score
              in: body
              type: integer
              description: "The NPS score (0–10)."
            - name: nps_comment
              in: body
              type: string
              description: "The verbatim NPS comment from the customer."
            - name: survey_date
              in: body
              type: string
              description: "Date of the NPS survey in YYYY-MM-DD format."
          call: "salesforce-nps.update-account"
          with:
            account_id: "{{account_id}}"
            nps_score: "{{nps_score}}"
            nps_comment: "{{nps_comment}}"
            nps_date: "{{survey_date}}"
  consumes:
    - type: http
      namespace: salesforce-nps
      baseUri: "https://veolia.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: update-account
              method: PATCH

When a new lead is created in Salesforce, enriches it with firmographic data and routes it to the appropriate Veolia sales territory based on industry and geography.

naftiko: "0.5"
info:
  label: "Salesforce Lead Qualification and Routing"
  description: "When a new lead is created in Salesforce, enriches it with firmographic data and routes it to the appropriate Veolia sales territory based on industry and geography."
  tags:
    - crm
    - sales
    - salesforce
    - lead-management
    - routing
capability:
  exposes:
    - type: mcp
      namespace: sales-lead-routing
      port: 8080
      tools:
        - name: qualify-and-route-lead
          description: "Given a new Salesforce lead ID, fetch lead details, update the lead record with territory assignment, and notify the responsible account executive via Teams."
          inputParameters:
            - name: lead_id
              in: body
              type: string
              description: "The Salesforce lead record ID (18-character)."
            - name: territory_mapping_rule
              in: body
              type: string
              description: "Territory assignment rule key (e.g., EMEA-Water, APAC-Waste)."
            - name: ae_upn
              in: body
              type: string
              description: "UPN of the account executive to assign and notify."
          steps:
            - name: get-lead
              type: call
              call: "salesforce-leads.get-lead"
              with:
                lead_id: "{{lead_id}}"
            - name: update-lead
              type: call
              call: "salesforce-leads.update-lead"
              with:
                lead_id: "{{lead_id}}"
                territory: "{{territory_mapping_rule}}"
                owner_upn: "{{ae_upn}}"
            - name: notify-ae
              type: call
              call: "msteams-sales.send-message"
              with:
                recipient_upn: "{{ae_upn}}"
                text: "New lead assigned to you: {{get-lead.Company}} ({{get-lead.Industry}}, {{get-lead.Country}}). Lead ID: {{lead_id}}. Check Salesforce for details."
  consumes:
    - type: http
      namespace: salesforce-leads
      baseUri: "https://veolia.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
            - name: update-lead
              method: PATCH
    - type: http
      namespace: msteams-sales
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: messages
          path: "/users/{{recipient_upn}}/sendMail"
          inputParameters:
            - name: recipient_upn
              in: path
          operations:
            - name: send-message
              method: POST

When a Salesforce lead reaches qualified status, converts to opportunity, creates a SAP business partner, and notifies the sales team.

naftiko: "0.5"
info:
  label: "Salesforce Lead Qualification Workflow"
  description: "When a Salesforce lead reaches qualified status, converts to opportunity, creates a SAP business partner, and notifies the sales team."
  tags:
    - sales
    - salesforce
    - sap
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: sales-pipeline
      port: 8080
      tools:
        - name: qualify-lead
          description: "Given a lead ID, convert and create SAP partner."
          inputParameters:
            - name: lead_id
              in: body
              type: string
              description: "The Salesforce lead ID."
          steps:
            - name: get-lead
              type: call
              call: "salesforce.get-lead"
              with:
                lead_id: "{{lead_id}}"
            - name: convert
              type: call
              call: "salesforce.convert-lead"
              with:
                lead_id: "{{lead_id}}"
            - name: create-bp
              type: call
              call: "sap.create-business-partner"
              with:
                name: "{{get-lead.company}}"
                country: "{{get-lead.country}}"
            - name: notify
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_sales_channel"
                text: "Lead converted: {{get-lead.company}} | Opp: {{convert.opportunity_id}} | SAP BP: {{create-bp.partner_id}}"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://veolia.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
            - name: convert-lead
              method: POST
    - type: http
      namespace: sap
      baseUri: "https://veolia-s4.sap.com/sap/opu/odata/sap/API_BUSINESS_PARTNER"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: partners
          path: "/A_BusinessPartner"
          operations:
            - name: create-business-partner
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/sales/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

When a municipal water services contract approaches renewal in Salesforce, creates a Jira task for the account team and notifies the business development channel on Teams.

naftiko: "0.5"
info:
  label: "Salesforce Municipal Contract Renewal Alert"
  description: "When a municipal water services contract approaches renewal in Salesforce, creates a Jira task for the account team and notifies the business development channel on Teams."
  tags:
    - sales
    - salesforce
    - jira
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: contract-mgmt
      port: 8080
      tools:
        - name: alert-contract-renewal
          description: "Given a Salesforce opportunity ID approaching renewal, create tasks and notify."
          inputParameters:
            - name: opportunity_id
              in: body
              type: string
              description: "The Salesforce opportunity ID."
          steps:
            - name: get-opportunity
              type: call
              call: "salesforce.get-opportunity"
              with:
                opportunity_id: "{{opportunity_id}}"
            - name: create-renewal-task
              type: call
              call: "jira.create-issue"
              with:
                project: "BD"
                summary: "Contract renewal: {{get-opportunity.account_name}} — ${{get-opportunity.amount}}"
                description: "Close date: {{get-opportunity.close_date}}. Owner: {{get-opportunity.owner_name}}."
                issue_type: "Task"
            - name: notify-bd
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_bd_channel"
                text: "Contract renewal: {{get-opportunity.account_name}} | ${{get-opportunity.amount}} | Due: {{get-opportunity.close_date}} | Jira: {{create-renewal-task.key}}"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://veolia.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: jira
      baseUri: "https://veolia.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/bd/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

When a Salesforce opportunity reaches Closed Won, creates a corresponding project entry in SAP S/4HANA and sends a Teams notification to the delivery team.

naftiko: "0.5"
info:
  label: "Salesforce Opportunity Sync to SAP"
  description: "When a Salesforce opportunity reaches Closed Won, creates a corresponding project entry in SAP S/4HANA and sends a Teams notification to the delivery team."
  tags:
    - crm
    - finance
    - salesforce
    - sap-s4hana
    - microsoft-teams
    - opportunity
capability:
  exposes:
    - type: mcp
      namespace: crm-erp-sync
      port: 8080
      tools:
        - name: sync-won-opportunity
          description: "Given a Salesforce opportunity ID, fetch deal details, create a project record in SAP S/4HANA, and notify the delivery team channel in Microsoft Teams."
          inputParameters:
            - name: opportunity_id
              in: body
              type: string
              description: "The Salesforce opportunity record ID (18-character Salesforce ID)."
            - name: delivery_channel_id
              in: body
              type: string
              description: "The Microsoft Teams channel ID for the delivery team notification."
          steps:
            - name: get-opportunity
              type: call
              call: "salesforce.get-opportunity"
              with:
                opportunity_id: "{{opportunity_id}}"
            - name: create-project
              type: call
              call: "sap-projects.create-project"
              with:
                project_name: "{{get-opportunity.Name}}"
                customer_id: "{{get-opportunity.AccountId}}"
                value: "{{get-opportunity.Amount}}"
                currency: "{{get-opportunity.CurrencyIsoCode}}"
            - name: notify-delivery
              type: call
              call: "msteams-delivery.post-message"
              with:
                channel_id: "{{delivery_channel_id}}"
                text: "New project created in SAP: {{get-opportunity.Name}} ({{get-opportunity.Amount}} {{get-opportunity.CurrencyIsoCode}}). SAP Project ID: {{create-project.project_id}}"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://veolia.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: opportunities
          path: "/sobjects/Opportunity/{{opportunity_id}}"
          inputParameters:
            - name: opportunity_id
              in: path
          operations:
            - name: get-opportunity
              method: GET
    - type: http
      namespace: sap-projects
      baseUri: "https://veolia-s4.sap.com/sap/opu/odata/sap/API_PROJECT_V2_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: projects
          path: "/A_Project"
          operations:
            - name: create-project
              method: POST
    - type: http
      namespace: msteams-delivery
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

When a Salesforce service case exceeds its response SLA, escalates it to a senior service manager and creates a high-priority ServiceNow task for executive tracking.

naftiko: "0.5"
info:
  label: "Salesforce Service Case Escalation"
  description: "When a Salesforce service case exceeds its response SLA, escalates it to a senior service manager and creates a high-priority ServiceNow task for executive tracking."
  tags:
    - customer-support
    - salesforce
    - servicenow
    - sla
    - escalation
capability:
  exposes:
    - type: mcp
      namespace: case-escalation
      port: 8080
      tools:
        - name: escalate-overdue-case
          description: "Given a Salesforce case ID that has breached its SLA, reassign it to the senior service manager and create a ServiceNow executive tracking task."
          inputParameters:
            - name: case_id
              in: body
              type: string
              description: "The Salesforce case record ID."
            - name: senior_manager_upn
              in: body
              type: string
              description: "UPN of the senior service manager to escalate to."
            - name: escalation_reason
              in: body
              type: string
              description: "Reason for escalation (e.g., SLA_breach, customer_complaint)."
          steps:
            - name: get-case
              type: call
              call: "salesforce-cases.get-case"
              with:
                case_id: "{{case_id}}"
            - name: update-case
              type: call
              call: "salesforce-cases.update-case"
              with:
                case_id: "{{case_id}}"
                escalated: "true"
                owner_upn: "{{senior_manager_upn}}"
            - name: create-exec-task
              type: call
              call: "servicenow-exec.create-task"
              with:
                short_description: "Executive escalation: Salesforce case {{get-case.CaseNumber}} — {{escalation_reason}}"
                description: "Case {{case_id}} ({{get-case.Subject}}) escalated due to {{escalation_reason}}. Customer: {{get-case.Account.Name}}. Assigned to {{senior_manager_upn}}."
                priority: "1"
  consumes:
    - type: http
      namespace: salesforce-cases
      baseUri: "https://veolia.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: cases
          path: "/sobjects/Case/{{case_id}}"
          inputParameters:
            - name: case_id
              in: path
          operations:
            - name: get-case
              method: GET
            - name: update-case
              method: PATCH
    - type: http
      namespace: servicenow-exec
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST

Queries SAP Ariba for contracts expiring within 90 days, creates ServiceNow renewal tasks, and notifies the procurement team via Microsoft Teams.

naftiko: "0.5"
info:
  label: "SAP Ariba Contract Expiry Alert"
  description: "Queries SAP Ariba for contracts expiring within 90 days, creates ServiceNow renewal tasks, and notifies the procurement team via Microsoft Teams."
  tags:
    - procurement
    - sap-ariba
    - servicenow
    - microsoft-teams
    - contract-management
capability:
  exposes:
    - type: mcp
      namespace: procurement-contracts
      port: 8080
      tools:
        - name: alert-expiring-contracts
          description: "Fetch contracts expiring within a given number of days from SAP Ariba, create renewal tasks in ServiceNow, and notify the procurement channel in Teams."
          inputParameters:
            - name: days_ahead
              in: body
              type: integer
              description: "Number of days ahead to check for contract expiry (e.g., 90)."
            - name: procurement_channel_id
              in: body
              type: string
              description: "Microsoft Teams channel ID for the procurement team."
          steps:
            - name: get-expiring-contracts
              type: call
              call: "sap-ariba-contracts.list-contracts"
              with:
                days_to_expiry: "{{days_ahead}}"
            - name: create-renewal-task
              type: call
              call: "servicenow-procurement.create-task"
              with:
                short_description: "Contract renewal required: {{get-expiring-contracts.count}} contracts expiring within {{days_ahead}} days"
                description: "Contracts due for renewal in the next {{days_ahead}} days. Review and initiate renewal in SAP Ariba."
                assignment_group: "Procurement_Team"
            - name: notify-procurement
              type: call
              call: "msteams-procurement.post-message"
              with:
                channel_id: "{{procurement_channel_id}}"
                text: "Contract Expiry Alert: {{get-expiring-contracts.count}} contracts expire within {{days_ahead}} days. ServiceNow task: {{create-renewal-task.number}}. Please review in SAP Ariba."
  consumes:
    - type: http
      namespace: sap-ariba-contracts
      baseUri: "https://openapi.ariba.com/api/contract-management/v1"
      authentication:
        type: bearer
        token: "$secrets.ariba_token"
      resources:
        - name: contracts
          path: "/contracts"
          operations:
            - name: list-contracts
              method: GET
    - type: http
      namespace: servicenow-procurement
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: msteams-procurement
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

Retrieves the status and key terms of an SAP Ariba contract by contract ID.

naftiko: "0.5"
info:
  label: "SAP Ariba Contract Status Lookup"
  description: "Retrieves the status and key terms of an SAP Ariba contract by contract ID."
  tags:
    - procurement
    - sap-ariba
capability:
  exposes:
    - type: mcp
      namespace: procurement-contracts
      port: 8080
      tools:
        - name: get-contract-status
          description: "Look up an SAP Ariba contract by ID. Returns status, expiry date, and total value."
          inputParameters:
            - name: contract_id
              in: body
              type: string
              description: "The SAP Ariba contract document ID."
          call: "ariba.get-contract"
          with:
            contract_id: "{{contract_id}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.status"
            - name: expiry_date
              type: string
              mapping: "$.expirationDate"
  consumes:
    - type: http
      namespace: ariba
      baseUri: "https://openapi.ariba.com/api/contract-management/v1"
      authentication:
        type: bearer
        token: "$secrets.ariba_token"
      resources:
        - name: contracts
          path: "/contracts/{{contract_id}}"
          inputParameters:
            - name: contract_id
              in: path
          operations:
            - name: get-contract
              method: GET

Creates an RFx event in Ariba, invites suppliers, and notifies procurement on Teams.

naftiko: "0.5"
info:
  label: "SAP Ariba RFx Creation Workflow"
  description: "Creates an RFx event in Ariba, invites suppliers, and notifies procurement on Teams."
  tags:
    - procurement
    - sourcing
    - sap-ariba
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: sourcing
      port: 8080
      tools:
        - name: create-rfx
          description: "Given procurement details, create an Ariba RFx and notify."
          inputParameters:
            - name: title
              in: body
              type: string
              description: "The RFx title."
            - name: category
              in: body
              type: string
              description: "The category."
            - name: budget_amount
              in: body
              type: string
              description: "The budget."
          steps:
            - name: create-event
              type: call
              call: "ariba.create-rfx"
              with:
                title: "{{title}}"
                category: "{{category}}"
                budget: "{{budget_amount}}"
            - name: invite
              type: call
              call: "ariba.invite-suppliers"
              with:
                rfx_id: "{{create-event.rfx_id}}"
                category: "{{category}}"
            - name: notify
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_procurement_channel"
                text: "RFx created: {{title}} | ID: {{create-event.rfx_id}} | Budget: EUR {{budget_amount}} | Suppliers: {{invite.count}}"
  consumes:
    - type: http
      namespace: ariba
      baseUri: "https://openapi.ariba.com/api/sourcing/v1"
      authentication:
        type: bearer
        token: "$secrets.ariba_token"
      resources:
        - name: rfx
          path: "/events"
          operations:
            - name: create-rfx
              method: POST
        - name: invitations
          path: "/events/{{rfx_id}}/invitations"
          inputParameters:
            - name: rfx_id
              in: path
          operations:
            - name: invite-suppliers
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/procurement/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

When a new supplier is approved in Ariba, creates the vendor master in SAP, a compliance task in ServiceNow, and notifies procurement on Teams.

naftiko: "0.5"
info:
  label: "SAP Ariba Supplier Onboarding Workflow"
  description: "When a new supplier is approved in Ariba, creates the vendor master in SAP, a compliance task in ServiceNow, and notifies procurement on Teams."
  tags:
    - procurement
    - sap-ariba
    - sap
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: supplier-mgmt
      port: 8080
      tools:
        - name: onboard-supplier
          description: "Given an Ariba supplier ID, create SAP vendor master and compliance task."
          inputParameters:
            - name: supplier_id
              in: body
              type: string
              description: "The Ariba supplier ID."
          steps:
            - name: get-supplier
              type: call
              call: "ariba.get-supplier"
              with:
                supplier_id: "{{supplier_id}}"
            - name: create-vendor
              type: call
              call: "sap.create-vendor"
              with:
                name: "{{get-supplier.name}}"
                country: "{{get-supplier.country}}"
            - name: create-compliance-task
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "Supplier compliance: {{get-supplier.name}}"
                assignment_group: "Supplier_Compliance"
            - name: notify
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_procurement_channel"
                text: "Supplier onboarded: {{get-supplier.name}} | SAP Vendor: {{create-vendor.vendor_number}} | Task: {{create-compliance-task.number}}"
  consumes:
    - type: http
      namespace: ariba
      baseUri: "https://openapi.ariba.com/api/supplier-management/v1"
      authentication:
        type: bearer
        token: "$secrets.ariba_token"
      resources:
        - name: suppliers
          path: "/suppliers/{{supplier_id}}"
          inputParameters:
            - name: supplier_id
              in: path
          operations:
            - name: get-supplier
              method: GET
    - type: http
      namespace: sap
      baseUri: "https://veolia-s4.sap.com/sap/opu/odata/sap/API_BUSINESS_PARTNER"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: vendors
          path: "/A_BusinessPartner"
          operations:
            - name: create-vendor
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/procurement/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Fetches overdue maintenance orders from SAP, creates scheduling tasks in ServiceNow, and notifies plant managers on Teams.

naftiko: "0.5"
info:
  label: "SAP Asset Maintenance Scheduling Workflow"
  description: "Fetches overdue maintenance orders from SAP, creates scheduling tasks in ServiceNow, and notifies plant managers on Teams."
  tags:
    - operations
    - maintenance
    - sap
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: maintenance-scheduling
      port: 8080
      tools:
        - name: schedule-overdue-maintenance
          description: "Given a plant code, find overdue orders, create scheduling tasks, and notify."
          inputParameters:
            - name: plant_code
              in: body
              type: string
              description: "The SAP plant code."
          steps:
            - name: get-overdue-orders
              type: call
              call: "sap.list-overdue-orders"
              with:
                plant_code: "{{plant_code}}"
            - name: create-scheduling-task
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "Overdue maintenance: {{get-overdue-orders.count}} orders at plant {{plant_code}}"
                assignment_group: "Plant_Maintenance"
            - name: notify-plant-manager
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_maintenance_channel"
                text: "Overdue maintenance: {{get-overdue-orders.count}} orders at plant {{plant_code}} | Task: {{create-scheduling-task.number}}"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://veolia-s4.sap.com/sap/opu/odata/sap/API_MAINTENANCEORDER_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: orders
          path: "/A_MaintenanceOrder"
          operations:
            - name: list-overdue-orders
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/maintenance/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Creates a SAP Plant Maintenance work order for a reported asset failure and links it to the corresponding ServiceNow incident for end-to-end tracking.

naftiko: "0.5"
info:
  label: "SAP Asset Maintenance Work Order"
  description: "Creates a SAP Plant Maintenance work order for a reported asset failure and links it to the corresponding ServiceNow incident for end-to-end tracking."
  tags:
    - asset-management
    - maintenance
    - sap-s4hana
    - servicenow
    - manufacturing
capability:
  exposes:
    - type: mcp
      namespace: asset-maintenance
      port: 8080
      tools:
        - name: create-maintenance-work-order
          description: "Given a ServiceNow incident number and SAP equipment ID, create a Plant Maintenance work order in SAP S/4HANA and link it back to the ServiceNow incident."
          inputParameters:
            - name: snow_incident_number
              in: body
              type: string
              description: "The ServiceNow incident number that triggered the maintenance request."
            - name: equipment_id
              in: body
              type: string
              description: "The SAP equipment ID for the asset requiring maintenance."
            - name: maintenance_type
              in: body
              type: string
              description: "Type of maintenance: breakdown, preventive, or predictive."
            - name: priority
              in: body
              type: string
              description: "Maintenance priority: 1 (immediate), 2 (urgent), 3 (normal)."
          steps:
            - name: create-work-order
              type: call
              call: "sap-pm.create-work-order"
              with:
                equipment_id: "{{equipment_id}}"
                maintenance_type: "{{maintenance_type}}"
                priority: "{{priority}}"
                description: "Maintenance triggered by ServiceNow incident {{snow_incident_number}}"
            - name: update-incident
              type: call
              call: "servicenow-assets.update-incident"
              with:
                number: "{{snow_incident_number}}"
                work_notes: "SAP Plant Maintenance work order {{create-work-order.order_number}} created for equipment {{equipment_id}}."
  consumes:
    - type: http
      namespace: sap-pm
      baseUri: "https://veolia-s4.sap.com/sap/opu/odata/sap/API_MAINTENANCEORDER_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: maintenance-orders
          path: "/MaintenanceOrder"
          operations:
            - name: create-work-order
              method: POST
    - type: http
      namespace: servicenow-assets
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: update-incident
              method: PATCH

When a fixed asset is flagged for retirement in SAP, creates a disposal task in ServiceNow and updates the register in Snowflake.

naftiko: "0.5"
info:
  label: "SAP Asset Retirement Workflow"
  description: "When a fixed asset is flagged for retirement in SAP, creates a disposal task in ServiceNow and updates the register in Snowflake."
  tags:
    - finance
    - asset-management
    - sap
    - servicenow
    - snowflake
capability:
  exposes:
    - type: mcp
      namespace: asset-lifecycle
      port: 8080
      tools:
        - name: retire-asset
          description: "Given a SAP asset number, process retirement and log."
          inputParameters:
            - name: asset_number
              in: body
              type: string
              description: "The SAP fixed asset number."
            - name: company_code
              in: body
              type: string
              description: "The company code."
          steps:
            - name: get-asset
              type: call
              call: "sap.get-fixed-asset"
              with:
                asset_number: "{{asset_number}}"
                company_code: "{{company_code}}"
            - name: create-disposal
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "Asset disposal: {{get-asset.description}} ({{asset_number}})"
                assignment_group: "Facilities"
            - name: update-register
              type: call
              call: "snowflake.execute-query"
              with:
                statement: "UPDATE FINANCE_DB.PUBLIC.ASSET_REGISTER SET status='RETIRED' WHERE asset_number='{{asset_number}}'"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://veolia-s4.sap.com/sap/opu/odata/sap/API_FIXEDASSET_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: assets
          path: "/A_FixedAsset(CompanyCode='{{company_code}}',MasterFixedAsset='{{asset_number}}')"
          inputParameters:
            - name: asset_number
              in: path
            - name: company_code
              in: path
          operations:
            - name: get-fixed-asset
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: snowflake
      baseUri: "https://veolia.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-query
              method: POST

When a capex request is submitted in SAP, validates budget, creates a ServiceNow approval, and notifies finance on Teams.

naftiko: "0.5"
info:
  label: "SAP Capital Expenditure Approval Workflow"
  description: "When a capex request is submitted in SAP, validates budget, creates a ServiceNow approval, and notifies finance on Teams."
  tags:
    - finance
    - sap
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: finance-capex
      port: 8080
      tools:
        - name: process-capex
          description: "Given an investment order, validate and route for approval."
          inputParameters:
            - name: investment_order
              in: body
              type: string
              description: "The SAP investment order number."
            - name: cost_center
              in: body
              type: string
              description: "The cost center."
          steps:
            - name: get-order
              type: call
              call: "sap.get-investment-order"
              with:
                investment_order: "{{investment_order}}"
            - name: create-approval
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "Capex approval: {{get-order.description}} — EUR {{get-order.amount}}"
                assignment_group: "Finance_Capex"
            - name: notify-finance
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_finance_channel"
                text: "Capex approval needed: {{get-order.description}} — EUR {{get-order.amount}} | Task: {{create-approval.number}}"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://veolia-s4.sap.com/sap/opu/odata/sap/API_INVESTMENTORDER_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: investment-orders
          path: "/A_InvestmentOrder('{{investment_order}}')"
          inputParameters:
            - name: investment_order
              in: path
          operations:
            - name: get-investment-order
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/finance/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

When water treatment chemical stock drops below threshold in SAP, creates a purchase requisition and notifies the procurement team on Teams.

naftiko: "0.5"
info:
  label: "SAP Chemical Inventory Reorder Alert"
  description: "When water treatment chemical stock drops below threshold in SAP, creates a purchase requisition and notifies the procurement team on Teams."
  tags:
    - supply-chain
    - sap
    - procurement
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: chemical-supply
      port: 8080
      tools:
        - name: trigger-chemical-reorder
          description: "Given a material and plant with low stock, create a purchase requisition and notify procurement."
          inputParameters:
            - name: material_number
              in: body
              type: string
              description: "The SAP material number."
            - name: plant_code
              in: body
              type: string
              description: "The plant code."
            - name: current_stock
              in: body
              type: string
              description: "Current stock level."
          steps:
            - name: get-material
              type: call
              call: "sap.get-material"
              with:
                material_number: "{{material_number}}"
            - name: create-requisition
              type: call
              call: "sap.create-purchase-requisition"
              with:
                material: "{{material_number}}"
                plant: "{{plant_code}}"
                quantity: "{{get-material.reorder_quantity}}"
            - name: notify-procurement
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_procurement_channel"
                text: "Chemical reorder: {{get-material.description}} at plant {{plant_code}} | Stock: {{current_stock}} | PR: {{create-requisition.pr_number}}"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://veolia-s4.sap.com/sap/opu/odata/sap/API_MATERIAL_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: materials
          path: "/A_Material('{{material_number}}')"
          inputParameters:
            - name: material_number
              in: path
          operations:
            - name: get-material
              method: GET
        - name: purchase-requisitions
          path: "/A_PurchaseRequisition"
          operations:
            - name: create-purchase-requisition
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/procurement/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Validates the original invoice in SAP, creates the credit memo, and notifies AR via ServiceNow and Teams.

naftiko: "0.5"
info:
  label: "SAP Credit Memo Processing"
  description: "Validates the original invoice in SAP, creates the credit memo, and notifies AR via ServiceNow and Teams."
  tags:
    - finance
    - accounts-receivable
    - sap
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: finance-ar
      port: 8080
      tools:
        - name: process-credit-memo
          description: "Given an invoice and credit amount, validate, create credit memo, and notify."
          inputParameters:
            - name: invoice_number
              in: body
              type: string
              description: "The original invoice number."
            - name: credit_amount
              in: body
              type: string
              description: "The credit amount."
            - name: reason_code
              in: body
              type: string
              description: "The reason code."
          steps:
            - name: validate
              type: call
              call: "sap.get-invoice"
              with:
                invoice_number: "{{invoice_number}}"
            - name: create-memo
              type: call
              call: "sap.create-credit-memo"
              with:
                reference: "{{invoice_number}}"
                amount: "{{credit_amount}}"
                reason: "{{reason_code}}"
            - name: create-task
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "Credit memo: {{create-memo.document_number}} for invoice {{invoice_number}}"
                assignment_group: "AR_Team"
            - name: notify
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_finance_channel"
                text: "Credit memo {{create-memo.document_number}} — EUR {{credit_amount}} against invoice {{invoice_number}}"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://veolia-s4.sap.com/sap/opu/odata/sap/API_BILLING_DOCUMENT_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: invoices
          path: "/A_BillingDocument('{{invoice_number}}')"
          inputParameters:
            - name: invoice_number
              in: path
          operations:
            - name: get-invoice
              method: GET
        - name: credit-memos
          path: "/A_BillingDocument"
          operations:
            - name: create-credit-memo
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/finance/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Retrieves the current balance of a general ledger account from SAP S/4HANA by company code and GL account number.

naftiko: "0.5"
info:
  label: "SAP GL Account Balance Lookup"
  description: "Retrieves the current balance of a general ledger account from SAP S/4HANA by company code and GL account number."
  tags:
    - finance
    - sap
capability:
  exposes:
    - type: mcp
      namespace: erp-finance
      port: 8080
      tools:
        - name: get-gl-balance
          description: "Look up a SAP GL account balance. Returns debit total, credit total, and net balance."
          inputParameters:
            - name: company_code
              in: body
              type: string
              description: "The SAP company code."
            - name: gl_account
              in: body
              type: string
              description: "The GL account number."
          call: "sap.get-gl-balance"
          with:
            company_code: "{{company_code}}"
            gl_account: "{{gl_account}}"
          outputParameters:
            - name: net_balance
              type: string
              mapping: "$.d.Balance"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://veolia-s4.sap.com/sap/opu/odata/sap/API_GLACCOUNTBALANCE_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: gl-balances
          path: "/A_GLAccountBalance(CompanyCode='{{company_code}}',GLAccount='{{gl_account}}')"
          inputParameters:
            - name: company_code
              in: path
            - name: gl_account
              in: path
          operations:
            - name: get-gl-balance
              method: GET

Fetches intercompany balances from SAP across entity codes, compares, and creates a ServiceNow task when discrepancies exist.

naftiko: "0.5"
info:
  label: "SAP Intercompany Reconciliation"
  description: "Fetches intercompany balances from SAP across entity codes, compares, and creates a ServiceNow task when discrepancies exist."
  tags:
    - finance
    - sap
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: finance-recon
      port: 8080
      tools:
        - name: reconcile-intercompany
          description: "Given two company codes, compare intercompany balances."
          inputParameters:
            - name: company_code_a
              in: body
              type: string
              description: "First company code."
            - name: company_code_b
              in: body
              type: string
              description: "Second company code."
          steps:
            - name: get-balance-a
              type: call
              call: "sap.get-ic-balance"
              with:
                company_code: "{{company_code_a}}"
                partner: "{{company_code_b}}"
            - name: get-balance-b
              type: call
              call: "sap.get-ic-balance"
              with:
                company_code: "{{company_code_b}}"
                partner: "{{company_code_a}}"
            - name: create-task
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "IC reconciliation: {{company_code_a}} vs {{company_code_b}}"
                description: "Balance A: {{get-balance-a.net_balance}}, Balance B: {{get-balance-b.net_balance}}"
                assignment_group: "Finance_IC"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://veolia-s4.sap.com/sap/opu/odata/sap/API_GLACCOUNTBALANCE_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: ic-balances
          path: "/A_GLAccountBalance"
          operations:
            - name: get-ic-balance
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST

Retrieves material master data from SAP S/4HANA by material number, returning description, unit of measure, and stock levels for water treatment chemicals and equipment.

naftiko: "0.5"
info:
  label: "SAP Material Master Lookup"
  description: "Retrieves material master data from SAP S/4HANA by material number, returning description, unit of measure, and stock levels for water treatment chemicals and equipment."
  tags:
    - supply-chain
    - sap
capability:
  exposes:
    - type: mcp
      namespace: erp-materials
      port: 8080
      tools:
        - name: get-material
          description: "Look up a SAP material master record by material number. Returns description, base unit, and plant-level stock."
          inputParameters:
            - name: material_number
              in: body
              type: string
              description: "The SAP material number."
          call: "sap.get-material"
          with:
            material_number: "{{material_number}}"
          outputParameters:
            - name: description
              type: string
              mapping: "$.d.MaterialDescription"
            - name: base_unit
              type: string
              mapping: "$.d.BaseUnit"
            - name: unrestricted_stock
              type: string
              mapping: "$.d.UnrestrictedStock"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://veolia-s4.sap.com/sap/opu/odata/sap/API_MATERIAL_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: materials
          path: "/A_Material('{{material_number}}')"
          inputParameters:
            - name: material_number
              in: path
          operations:
            - name: get-material
              method: GET

Orchestrates SAP financial period close by running balance checks, creating a ServiceNow checklist task, and posting status to the finance channel.

naftiko: "0.5"
info:
  label: "SAP Period Close Automation"
  description: "Orchestrates SAP financial period close by running balance checks, creating a ServiceNow checklist task, and posting status to the finance channel."
  tags:
    - finance
    - sap
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: finance-close
      port: 8080
      tools:
        - name: run-period-close
          description: "Given a company code and period, run balance checks, create checklist, and notify."
          inputParameters:
            - name: company_code
              in: body
              type: string
              description: "The SAP company code."
            - name: fiscal_period
              in: body
              type: string
              description: "The fiscal period."
          steps:
            - name: run-balance-check
              type: call
              call: "sap.get-trial-balance"
              with:
                company_code: "{{company_code}}"
                period: "{{fiscal_period}}"
            - name: create-checklist
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "Period close: {{company_code}} — {{fiscal_period}}"
                description: "Trial balance retrieved. Variance: {{run-balance-check.variance}}."
                assignment_group: "Finance_Close"
            - name: notify-finance
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_finance_channel"
                text: "Period close initiated: {{company_code}} {{fiscal_period}} | Variance: {{run-balance-check.variance}} | Task: {{create-checklist.number}}"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://veolia-s4.sap.com/sap/opu/odata/sap/API_GLACCOUNTBALANCE_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: trial-balance
          path: "/A_GLAccountBalance"
          operations:
            - name: get-trial-balance
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/finance/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

At the end of each accounting period, queries SAP S/4HANA for open items, generates a checklist in ServiceNow, and notifies the finance controller via Microsoft Teams.

naftiko: "0.5"
info:
  label: "SAP Period-Close Financial Checklist"
  description: "At the end of each accounting period, queries SAP S/4HANA for open items, generates a checklist in ServiceNow, and notifies the finance controller via Microsoft Teams."
  tags:
    - finance
    - period-close
    - sap-s4hana
    - servicenow
    - microsoft-teams
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: finance-period-close
      port: 8080
      tools:
        - name: run-period-close-checklist
          description: "Given a fiscal period and company code, retrieve open items from SAP S/4HANA, create a period-close task list in ServiceNow, and notify the controller via Teams."
          inputParameters:
            - name: fiscal_period
              in: body
              type: string
              description: "The fiscal period in YYYYMM format."
            - name: company_code
              in: body
              type: string
              description: "The SAP company code (4-character string)."
            - name: controller_upn
              in: body
              type: string
              description: "UPN of the finance controller to notify."
          steps:
            - name: get-open-items
              type: call
              call: "sap-fi.get-open-items"
              with:
                fiscal_period: "{{fiscal_period}}"
                company_code: "{{company_code}}"
            - name: create-checklist
              type: call
              call: "servicenow-period.create-task"
              with:
                short_description: "Period close checklist: {{company_code}} — {{fiscal_period}}"
                description: "Open items count: {{get-open-items.count}}. Total open value: {{get-open-items.total_amount}} {{get-open-items.currency}}."
                assignment_group: "Finance_Controllers"
            - name: notify-controller
              type: call
              call: "msteams-finance.send-message"
              with:
                recipient_upn: "{{controller_upn}}"
                text: "Period close checklist created for {{company_code}} / {{fiscal_period}}. Open items: {{get-open-items.count}}. ServiceNow task: {{create-checklist.number}}."
  consumes:
    - type: http
      namespace: sap-fi
      baseUri: "https://veolia-s4.sap.com/sap/opu/odata/sap/API_JOURNALENTRYITEM_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: open-items
          path: "/A_JournalEntryItem"
          operations:
            - name: get-open-items
              method: GET
    - type: http
      namespace: servicenow-period
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: msteams-finance
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: messages
          path: "/users/{{recipient_upn}}/sendMail"
          inputParameters:
            - name: recipient_upn
              in: path
          operations:
            - name: send-message
              method: POST

Retrieves a plant maintenance order from SAP by order number for water treatment facility equipment tracking.

naftiko: "0.5"
info:
  label: "SAP Plant Maintenance Order Lookup"
  description: "Retrieves a plant maintenance order from SAP by order number for water treatment facility equipment tracking."
  tags:
    - operations
    - sap
    - maintenance
capability:
  exposes:
    - type: mcp
      namespace: erp-maintenance
      port: 8080
      tools:
        - name: get-maintenance-order
          description: "Look up a SAP plant maintenance order. Returns status, equipment, and planned dates."
          inputParameters:
            - name: order_number
              in: body
              type: string
              description: "The SAP maintenance order number."
          call: "sap.get-pm-order"
          with:
            order_number: "{{order_number}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.d.OrderStatus"
            - name: equipment
              type: string
              mapping: "$.d.Equipment"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://veolia-s4.sap.com/sap/opu/odata/sap/API_MAINTENANCEORDER_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: maintenance-orders
          path: "/A_MaintenanceOrder('{{order_number}}')"
          inputParameters:
            - name: order_number
              in: path
          operations:
            - name: get-pm-order
              method: GET

Looks up a SAP S/4HANA purchase order by number and returns structured header status, vendor details, and open line items.

naftiko: "0.5"
info:
  label: "SAP Purchase Order Lookup"
  description: "Looks up a SAP S/4HANA purchase order by number and returns structured header status, vendor details, and open line items."
  tags:
    - finance
    - procurement
    - sap-s4hana
    - purchase-order
capability:
  exposes:
    - type: mcp
      namespace: erp-procurement
      port: 8080
      tools:
        - name: get-purchase-order
          description: "Look up a SAP S/4HANA purchase order by PO number. Returns header status, vendor name, total value, currency, and open line items. Use for procurement status checks."
          inputParameters:
            - name: po_number
              in: body
              type: string
              description: "The SAP purchase order number (10-digit numeric string)."
          call: "sap.get-po"
          with:
            po_number: "{{po_number}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.d.OverallStatus"
            - name: vendor
              type: string
              mapping: "$.d.Supplier.CompanyName"
            - name: total_value
              type: string
              mapping: "$.d.TotalAmount"
            - name: currency
              type: string
              mapping: "$.d.TransactionCurrency"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://veolia-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

Extracts regulatory reporting data from SAP, validates in ServiceNow, and publishes to SharePoint for submission.

naftiko: "0.5"
info:
  label: "SAP Regulatory Data Extraction"
  description: "Extracts regulatory reporting data from SAP, validates in ServiceNow, and publishes to SharePoint for submission."
  tags:
    - compliance
    - regulatory
    - sap
    - servicenow
    - sharepoint
capability:
  exposes:
    - type: mcp
      namespace: regulatory-reporting
      port: 8080
      tools:
        - name: extract-regulatory-data
          description: "Given a report type and period, extract, validate, and publish."
          inputParameters:
            - name: report_type
              in: body
              type: string
              description: "The regulatory report type."
            - name: period
              in: body
              type: string
              description: "The reporting period."
          steps:
            - name: extract
              type: call
              call: "sap.get-regulatory-data"
              with:
                report_type: "{{report_type}}"
                period: "{{period}}"
            - name: validate
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "Regulatory validation: {{report_type}} — {{period}}"
                description: "Records extracted: {{extract.record_count}}."
                assignment_group: "Regulatory"
            - name: publish
              type: call
              call: "sharepoint.upload-file"
              with:
                site_id: "$secrets.sharepoint_regulatory_site"
                folder: "Reports/{{period}}"
                file_name: "{{report_type}}_{{period}}.xlsx"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://veolia-s4.sap.com/sap/opu/odata/sap/API_JOURNAL_ENTRY_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: entries
          path: "/A_JournalEntry"
          operations:
            - name: get-regulatory-data
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: sharepoint
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: uploads
          path: "/sites/{{site_id}}/drive/root:/{{folder}}/{{file_name}}:/content"
          inputParameters:
            - name: site_id
              in: path
          operations:
            - name: upload-file
              method: PUT

Assigns mandatory compliance training in SAP SuccessFactors Learning based on an employee's role or location and tracks completion via a ServiceNow monitoring task.

naftiko: "0.5"
info:
  label: "SAP SuccessFactors Learning Assignment"
  description: "Assigns mandatory compliance training in SAP SuccessFactors Learning based on an employee's role or location and tracks completion via a ServiceNow monitoring task."
  tags:
    - hr
    - learning
    - compliance
    - sap-successfactors
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: hr-learning
      port: 8080
      tools:
        - name: assign-compliance-training
          description: "Given an employee ID and training course ID, assign the mandatory compliance course in SuccessFactors Learning and create a ServiceNow task to track completion within the required window."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "SAP SuccessFactors employee ID."
            - name: course_id
              in: body
              type: string
              description: "SuccessFactors Learning course ID to assign."
            - name: due_date
              in: body
              type: string
              description: "Training completion due date in YYYY-MM-DD format."
          steps:
            - name: assign-course
              type: call
              call: "successfactors-lms.assign-learning"
              with:
                userId: "{{employee_id}}"
                itemID: "{{course_id}}"
                dueDate: "{{due_date}}"
            - name: create-tracking-task
              type: call
              call: "servicenow-training.create-task"
              with:
                short_description: "Compliance training assigned: {{course_id}} for employee {{employee_id}}"
                description: "Course {{course_id}} assigned to employee {{employee_id}}. Due: {{due_date}}. Track completion in SuccessFactors Learning."
                due_date: "{{due_date}}"
  consumes:
    - type: http
      namespace: successfactors-lms
      baseUri: "https://api4.successfactors.com/learning/odatav4"
      authentication:
        type: basic
        username: "$secrets.sf_user"
        password: "$secrets.sf_password"
      resources:
        - name: learning-assignments
          path: "/LearningItemAssignment"
          operations:
            - name: assign-learning
              method: POST
    - type: http
      namespace: servicenow-training
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST

Initiates the annual performance review cycle in SuccessFactors, creates tracking tasks in ServiceNow, and notifies HR on Teams.

naftiko: "0.5"
info:
  label: "SAP SuccessFactors Performance Review Kickoff"
  description: "Initiates the annual performance review cycle in SuccessFactors, creates tracking tasks in ServiceNow, and notifies HR on Teams."
  tags:
    - hr
    - performance
    - sap-successfactors
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: hr-performance
      port: 8080
      tools:
        - name: kickoff-reviews
          description: "Given a review cycle, initiate and track."
          inputParameters:
            - name: review_cycle
              in: body
              type: string
              description: "The review cycle name."
            - name: department
              in: body
              type: string
              description: "The department."
          steps:
            - name: initiate-cycle
              type: call
              call: "successfactors.create-review-cycle"
              with:
                cycle_name: "{{review_cycle}}"
                department: "{{department}}"
            - name: create-tracking
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "Performance review: {{review_cycle}} — {{department}}"
                assignment_group: "HR_Performance"
            - name: notify-hr
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_hr_channel"
                text: "Performance review cycle initiated: {{review_cycle}} for {{department}} | Task: {{create-tracking.number}}"
  consumes:
    - type: http
      namespace: successfactors
      baseUri: "https://apisalesdemo8.successfactors.com/odata/v2"
      authentication:
        type: basic
        username: "$secrets.sf_user"
        password: "$secrets.sf_password"
      resources:
        - name: review-cycles
          path: "/PMReviewFormTemplate"
          operations:
            - name: create-review-cycle
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/hr/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Checks vendor invoice payment status in SAP S/4HANA, returning payment date, clearing document, and amount.

naftiko: "0.5"
info:
  label: "SAP Vendor Payment Status Check"
  description: "Checks vendor invoice payment status in SAP S/4HANA, returning payment date, clearing document, and amount."
  tags:
    - finance
    - sap
    - accounts-payable
capability:
  exposes:
    - type: mcp
      namespace: erp-ap
      port: 8080
      tools:
        - name: get-payment-status
          description: "Check vendor payment status in SAP by invoice reference."
          inputParameters:
            - name: invoice_reference
              in: body
              type: string
              description: "The SAP vendor invoice reference number."
            - name: company_code
              in: body
              type: string
              description: "The SAP company code."
          call: "sap.get-payment"
          with:
            invoice_reference: "{{invoice_reference}}"
            company_code: "{{company_code}}"
          outputParameters:
            - name: payment_date
              type: string
              mapping: "$.d.ClearingDate"
            - name: paid_amount
              type: string
              mapping: "$.d.AmountInCompanyCodeCurrency"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://veolia-s4.sap.com/sap/opu/odata/sap/API_SUPPLIERINVOICE_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: invoices
          path: "/A_SupplierInvoice(SupplierInvoice='{{invoice_reference}}',CompanyCode='{{company_code}}')"
          inputParameters:
            - name: invoice_reference
              in: path
            - name: company_code
              in: path
          operations:
            - name: get-payment
              method: GET

Retrieves the current status, priority, and assigned group of a ServiceNow incident by incident number.

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

When a P1 incident is created in ServiceNow, sets up a Teams meeting bridge and updates the incident with bridge details.

naftiko: "0.5"
info:
  label: "ServiceNow Major Incident Bridge"
  description: "When a P1 incident is created in ServiceNow, sets up a Teams meeting bridge and updates the incident with bridge details."
  tags:
    - itsm
    - incident-response
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: incident-bridge
      port: 8080
      tools:
        - name: setup-bridge
          description: "Given a P1 incident, create Teams bridge and update incident."
          inputParameters:
            - name: incident_number
              in: body
              type: string
              description: "The incident number."
          steps:
            - name: get-incident
              type: call
              call: "servicenow.get-incident"
              with:
                incident_number: "{{incident_number}}"
            - name: create-bridge
              type: call
              call: "msgraph.create-meeting"
              with:
                subject: "P1 Bridge: {{get-incident.short_description}}"
            - name: update-incident
              type: call
              call: "servicenow.update-incident"
              with:
                incident_number: "{{incident_number}}"
                work_notes: "Teams bridge: {{create-bridge.join_url}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.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
            - name: update-incident
              method: PATCH
    - type: http
      namespace: msgraph
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: meetings
          path: "/users/$secrets.service_account_upn/onlineMeetings"
          operations:
            - name: create-meeting
              method: POST

When a ServiceNow ticket approaches SLA breach, escalates priority, reassigns, and notifies management on Teams.

naftiko: "0.5"
info:
  label: "ServiceNow SLA Breach Escalation"
  description: "When a ServiceNow ticket approaches SLA breach, escalates priority, reassigns, and notifies management on Teams."
  tags:
    - itsm
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: itsm-sla
      port: 8080
      tools:
        - name: escalate-sla-breach
          description: "Given an incident near SLA breach, escalate and notify."
          inputParameters:
            - name: incident_number
              in: body
              type: string
              description: "The incident number."
          steps:
            - name: get-incident
              type: call
              call: "servicenow.get-incident"
              with:
                incident_number: "{{incident_number}}"
            - name: escalate
              type: call
              call: "servicenow.update-incident"
              with:
                incident_number: "{{incident_number}}"
                urgency: "1"
                assignment_group: "Lead_Resolvers"
            - name: notify-mgmt
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_service_delivery_channel"
                text: "SLA breach warning: {{incident_number}} — {{get-incident.short_description}} | Escalated to Lead Resolvers"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.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
            - name: update-incident
              method: PATCH
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/service-delivery/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Queries ServiceNow for incidents approaching or breaching SLA thresholds and sends escalation notifications to the responsible team via Microsoft Teams.

naftiko: "0.5"
info:
  label: "ServiceNow SLA Breach Monitor"
  description: "Queries ServiceNow for incidents approaching or breaching SLA thresholds and sends escalation notifications to the responsible team via Microsoft Teams."
  tags:
    - itsm
    - sla
    - servicenow
    - microsoft-teams
    - monitoring
    - escalation
capability:
  exposes:
    - type: mcp
      namespace: sla-monitoring
      port: 8080
      tools:
        - name: monitor-sla-breaches
          description: "Fetch incidents from ServiceNow that are within 30 minutes of or have already breached their SLA and send escalation messages to the responsible team channel in Teams."
          inputParameters:
            - name: assignment_group
              in: body
              type: string
              description: "The ServiceNow assignment group to check SLA status for."
            - name: escalation_channel_id
              in: body
              type: string
              description: "Microsoft Teams channel ID for SLA escalation notifications."
          steps:
            - name: get-at-risk-incidents
              type: call
              call: "servicenow-sla.list-at-risk-incidents"
              with:
                assignment_group: "{{assignment_group}}"
            - name: post-escalation
              type: call
              call: "msteams-sla.post-message"
              with:
                channel_id: "{{escalation_channel_id}}"
                text: "SLA Alert: {{get-at-risk-incidents.count}} incidents for {{assignment_group}} are at risk of breaching. Immediate attention required."
  consumes:
    - type: http
      namespace: servicenow-sla
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: list-at-risk-incidents
              method: GET
    - type: http
      namespace: msteams-sla
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

Retrieves metadata for a SharePoint document including title, author, and modification date.

naftiko: "0.5"
info:
  label: "SharePoint Document Metadata Lookup"
  description: "Retrieves metadata for a SharePoint document including title, author, and modification date."
  tags:
    - document-management
    - sharepoint
capability:
  exposes:
    - type: mcp
      namespace: doc-mgmt
      port: 8080
      tools:
        - name: get-document-metadata
          description: "Retrieve metadata for a SharePoint document by site and item ID."
          inputParameters:
            - name: site_id
              in: body
              type: string
              description: "The SharePoint site ID."
            - name: item_id
              in: body
              type: string
              description: "The document item ID."
          call: "sharepoint.get-item"
          with:
            site_id: "{{site_id}}"
            item_id: "{{item_id}}"
          outputParameters:
            - name: title
              type: string
              mapping: "$.name"
            - name: last_modified
              type: string
              mapping: "$.lastModifiedDateTime"
  consumes:
    - type: http
      namespace: sharepoint
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: items
          path: "/sites/{{site_id}}/drive/items/{{item_id}}"
          inputParameters:
            - name: site_id
              in: path
            - name: item_id
              in: path
          operations:
            - name: get-item
              method: GET

When a corporate policy document is updated in SharePoint, sends notification emails and creates a ServiceNow acknowledgment task.

naftiko: "0.5"
info:
  label: "SharePoint Policy Update Notification"
  description: "When a corporate policy document is updated in SharePoint, sends notification emails and creates a ServiceNow acknowledgment task."
  tags:
    - compliance
    - sharepoint
    - microsoft-outlook
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: policy-mgmt
      port: 8080
      tools:
        - name: notify-policy-update
          description: "Given a SharePoint document ID, notify affected users and create acknowledgment task."
          inputParameters:
            - name: site_id
              in: body
              type: string
              description: "The SharePoint site ID."
            - name: document_id
              in: body
              type: string
              description: "The document ID."
            - name: distribution_group
              in: body
              type: string
              description: "The email distribution group."
          steps:
            - name: get-doc
              type: call
              call: "sharepoint.get-item"
              with:
                site_id: "{{site_id}}"
                item_id: "{{document_id}}"
            - name: send-notification
              type: call
              call: "msgraph.send-mail"
              with:
                recipient: "{{distribution_group}}"
                subject: "Policy Updated: {{get-doc.title}}"
                body: "Please review the updated policy."
            - name: create-task
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "Policy acknowledgment: {{get-doc.title}}"
                assignment_group: "Compliance"
  consumes:
    - type: http
      namespace: sharepoint
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: items
          path: "/sites/{{site_id}}/drive/items/{{item_id}}"
          inputParameters:
            - name: site_id
              in: path
            - name: item_id
              in: path
          operations:
            - name: get-item
              method: GET
    - type: http
      namespace: msgraph
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: mail
          path: "/users/$secrets.service_account_upn/sendMail"
          operations:
            - name: send-mail
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST

Executes a Snowflake analytics query on a schedule, formats the result as a report, and delivers it to specified stakeholders via Microsoft Teams.

naftiko: "0.5"
info:
  label: "Snowflake BI Report Scheduler"
  description: "Executes a Snowflake analytics query on a schedule, formats the result as a report, and delivers it to specified stakeholders via Microsoft Teams."
  tags:
    - analytics
    - snowflake
    - microsoft-teams
    - reporting
    - scheduling
capability:
  exposes:
    - type: mcp
      namespace: bi-scheduler
      port: 8080
      tools:
        - name: run-and-deliver-report
          description: "Execute a named Snowflake analytics query and post the formatted results to a Microsoft Teams channel. Use for weekly or monthly operational reporting to leadership."
          inputParameters:
            - name: query_statement
              in: body
              type: string
              description: "The Snowflake SQL query to execute."
            - name: report_title
              in: body
              type: string
              description: "Human-readable title for the report."
            - name: teams_channel_id
              in: body
              type: string
              description: "Microsoft Teams channel ID to deliver the report to."
          steps:
            - name: run-query
              type: call
              call: "snowflake-bi.execute-query"
              with:
                statement: "{{query_statement}}"
            - name: deliver-report
              type: call
              call: "msteams-reports.post-message"
              with:
                channel_id: "{{teams_channel_id}}"
                text: "Report: {{report_title}}\nRows returned: {{run-query.numRows}}\nQuery completed at {{run-query.createdOn}}."
  consumes:
    - type: http
      namespace: snowflake-bi
      baseUri: "https://veolia.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-query
              method: POST
    - type: http
      namespace: msteams-reports
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

Runs data quality validation queries against Veolia's Snowflake data warehouse and creates a ServiceNow incident if anomalies exceed defined thresholds.

naftiko: "0.5"
info:
  label: "Snowflake Data Pipeline Quality Check"
  description: "Runs data quality validation queries against Veolia's Snowflake data warehouse and creates a ServiceNow incident if anomalies exceed defined thresholds."
  tags:
    - data
    - analytics
    - snowflake
    - servicenow
    - data-quality
    - monitoring
capability:
  exposes:
    - type: mcp
      namespace: data-quality
      port: 8080
      tools:
        - name: run-pipeline-quality-check
          description: "Given a Snowflake schema and table name, execute a row-count and null-rate check. If anomalies are found, create a ServiceNow data quality incident. Use for scheduled data pipeline validation."
          inputParameters:
            - name: schema_name
              in: body
              type: string
              description: "The Snowflake schema name to validate."
            - name: table_name
              in: body
              type: string
              description: "The Snowflake table name to validate."
            - name: threshold_pct
              in: body
              type: number
              description: "Acceptable null rate threshold as a percentage (e.g., 5.0 for 5%)."
          steps:
            - name: check-table
              type: call
              call: "snowflake.execute-query"
              with:
                statement: "SELECT COUNT(*) as row_count, SUM(CASE WHEN id IS NULL THEN 1 ELSE 0 END)*100.0/COUNT(*) as null_rate FROM {{schema_name}}.{{table_name}}"
            - name: raise-incident
              type: call
              call: "servicenow-dq.create-incident"
              with:
                short_description: "Data quality issue: {{schema_name}}.{{table_name}} null rate exceeded threshold"
                description: "Table {{schema_name}}.{{table_name}} has null_rate {{check-table.null_rate}}%, exceeding threshold of {{threshold_pct}}%. Row count: {{check-table.row_count}}."
                category: "data_quality"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://veolia.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: queries
          path: "/statements"
          operations:
            - name: execute-query
              method: POST
    - type: http
      namespace: servicenow-dq
      baseUri: "https://veolia.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

Runs data quality checks on Snowflake tables, creates Jira tickets for failures, and notifies the data governance team on Teams.

naftiko: "0.5"
info:
  label: "Snowflake Data Quality Alert"
  description: "Runs data quality checks on Snowflake tables, creates Jira tickets for failures, and notifies the data governance team on Teams."
  tags:
    - data
    - data-quality
    - snowflake
    - jira
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: data-quality
      port: 8080
      tools:
        - name: run-dq-check
          description: "Given a table and quality rule, run check and alert on failures."
          inputParameters:
            - name: table_name
              in: body
              type: string
              description: "The table to check."
            - name: quality_rule
              in: body
              type: string
              description: "The SQL quality check."
          steps:
            - name: run-check
              type: call
              call: "snowflake.execute-query"
              with:
                statement: "SELECT COUNT(*) as violations FROM {{table_name}} WHERE {{quality_rule}}"
            - name: create-jira
              type: call
              call: "jira.create-issue"
              with:
                project: "DQ"
                summary: "DQ violation: {{table_name}} — {{run-check.violations}} rows"
                issue_type: "Bug"
            - name: notify
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_data_governance_channel"
                text: "DQ Alert: {{table_name}} | {{run-check.violations}} violations | Jira: {{create-jira.key}}"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://veolia.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-query
              method: POST
    - type: http
      namespace: jira
      baseUri: "https://veolia.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/data-governance/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

When a Snowflake ETL pipeline fails, queries the error log, creates a Jira ticket, and notifies the data team on Teams.

naftiko: "0.5"
info:
  label: "Snowflake ETL Failure Remediation"
  description: "When a Snowflake ETL pipeline fails, queries the error log, creates a Jira ticket, and notifies the data team on Teams."
  tags:
    - data
    - snowflake
    - jira
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: data-ops
      port: 8080
      tools:
        - name: handle-etl-failure
          description: "Given a failed Snowflake task, query errors, create Jira, and notify."
          inputParameters:
            - name: task_name
              in: body
              type: string
              description: "The Snowflake task name."
          steps:
            - name: get-error
              type: call
              call: "snowflake.execute-query"
              with:
                statement: "SELECT * FROM TABLE(INFORMATION_SCHEMA.TASK_HISTORY(TASK_NAME=>'{{task_name}}')) ORDER BY SCHEDULED_TIME DESC LIMIT 1"
            - name: create-jira
              type: call
              call: "jira.create-issue"
              with:
                project: "DATA"
                summary: "ETL failure: {{task_name}}"
                description: "Error: {{get-error.error_message}}"
                issue_type: "Bug"
            - name: notify-data
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_data_channel"
                text: "ETL Failure: {{task_name}} | Jira: {{create-jira.key}}"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://veolia.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-query
              method: POST
    - type: http
      namespace: jira
      baseUri: "https://veolia.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/data/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Queries a Snowflake table to return the current row count for data pipeline completeness verification.

naftiko: "0.5"
info:
  label: "Snowflake Table Row Count Check"
  description: "Queries a Snowflake table to return the current row count for data pipeline completeness verification."
  tags:
    - data
    - snowflake
capability:
  exposes:
    - type: mcp
      namespace: data-ops
      port: 8080
      tools:
        - name: get-table-row-count
          description: "Execute a row count query against a Snowflake table for pipeline health checks."
          inputParameters:
            - name: database_name
              in: body
              type: string
              description: "The Snowflake database name."
            - name: table_name
              in: body
              type: string
              description: "The target table name."
          call: "snowflake.execute-query"
          with:
            statement: "SELECT COUNT(*) AS row_count FROM {{database_name}}.PUBLIC.{{table_name}}"
          outputParameters:
            - name: row_count
              type: integer
              mapping: "$.data[0].row_count"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://veolia.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-query
              method: POST

Triggers a Tableau workbook refresh for Veolia's operational KPI dashboards and notifies stakeholders via Microsoft Teams when the refresh is complete.

naftiko: "0.5"
info:
  label: "Tableau Operational Dashboard Refresh"
  description: "Triggers a Tableau workbook refresh for Veolia's operational KPI dashboards and notifies stakeholders via Microsoft Teams when the refresh is complete."
  tags:
    - analytics
    - reporting
    - tableau
    - microsoft-teams
    - dashboards
capability:
  exposes:
    - type: mcp
      namespace: analytics-reporting
      port: 8080
      tools:
        - name: refresh-operational-dashboard
          description: "Given a Tableau workbook ID, trigger a data refresh and notify the specified Teams channel upon completion. Use for scheduled or on-demand operational dashboard refreshes."
          inputParameters:
            - name: workbook_id
              in: body
              type: string
              description: "The Tableau workbook LUID to refresh."
            - name: site_id
              in: body
              type: string
              description: "The Tableau site ID."
            - name: notify_channel_id
              in: body
              type: string
              description: "Microsoft Teams channel ID to notify upon completion."
          steps:
            - name: trigger-refresh
              type: call
              call: "tableau.refresh-workbook"
              with:
                site_id: "{{site_id}}"
                workbook_id: "{{workbook_id}}"
            - name: notify-stakeholders
              type: call
              call: "msteams-analytics.post-message"
              with:
                channel_id: "{{notify_channel_id}}"
                text: "Tableau dashboard refresh completed for workbook {{workbook_id}}. Job ID: {{trigger-refresh.job_id}}. Status: {{trigger-refresh.status}}."
  consumes:
    - type: http
      namespace: tableau
      baseUri: "https://tableau.veolia.com/api/2.8"
      authentication:
        type: apikey
        key: "X-Tableau-Auth"
        value: "$secrets.tableau_token"
        placement: header
      resources:
        - name: workbook-refresh
          path: "/sites/{{site_id}}/workbooks/{{workbook_id}}/refresh"
          inputParameters:
            - name: site_id
              in: path
            - name: workbook_id
              in: path
          operations:
            - name: refresh-workbook
              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/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

Triggers a Tableau workbook refresh, verifies completion, and distributes the KPI dashboard link to operations leaders on Teams.

naftiko: "0.5"
info:
  label: "Tableau Operational KPI Refresh and Distribute"
  description: "Triggers a Tableau workbook refresh, verifies completion, and distributes the KPI dashboard link to operations leaders on Teams."
  tags:
    - analytics
    - tableau
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: bi-distribution
      port: 8080
      tools:
        - name: refresh-and-distribute
          description: "Given a Tableau workbook ID, refresh and distribute to stakeholders."
          inputParameters:
            - name: workbook_id
              in: body
              type: string
              description: "The Tableau workbook ID."
          steps:
            - name: trigger-refresh
              type: call
              call: "tableau.refresh-workbook"
              with:
                workbook_id: "{{workbook_id}}"
            - name: notify-leaders
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_ops_leaders_channel"
                text: "KPI Dashboard refreshed: {{trigger-refresh.workbook_name}} | View: {{trigger-refresh.view_url}}"
  consumes:
    - type: http
      namespace: tableau
      baseUri: "https://veolia-tableau.online.tableau.com/api/3.19"
      authentication:
        type: bearer
        token: "$secrets.tableau_token"
      resources:
        - name: workbooks
          path: "/sites/$secrets.tableau_site_id/workbooks/{{workbook_id}}/refresh"
          inputParameters:
            - name: workbook_id
              in: path
          operations:
            - name: refresh-workbook
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ops-leaders/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

When a vendor invoice arrives in SAP Ariba, validates it against the corresponding PO in SAP S/4HANA and creates a ServiceNow approval task for the finance team.

naftiko: "0.5"
info:
  label: "Vendor Invoice Processing"
  description: "When a vendor invoice arrives in SAP Ariba, validates it against the corresponding PO in SAP S/4HANA and creates a ServiceNow approval task for the finance team."
  tags:
    - finance
    - procurement
    - sap-ariba
    - sap-s4hana
    - servicenow
    - invoice
    - approval
capability:
  exposes:
    - type: mcp
      namespace: finance-invoicing
      port: 8080
      tools:
        - name: process-vendor-invoice
          description: "Given an Ariba invoice ID and PO number, fetch invoice details from SAP Ariba, validate against the SAP PO, and create a ServiceNow approval task for the finance team."
          inputParameters:
            - name: invoice_id
              in: body
              type: string
              description: "The SAP Ariba invoice document ID."
            - name: po_number
              in: body
              type: string
              description: "The associated SAP purchase order number."
            - name: approver_group
              in: body
              type: string
              description: "The ServiceNow assignment group for the invoice approval task."
          steps:
            - name: get-invoice
              type: call
              call: "sap-ariba.get-invoice"
              with:
                invoice_id: "{{invoice_id}}"
            - name: get-po-details
              type: call
              call: "sap-erp.get-po"
              with:
                po_number: "{{po_number}}"
            - name: create-approval-task
              type: call
              call: "servicenow-finance.create-task"
              with:
                short_description: "Invoice approval required: {{get-invoice.invoice_number}} against PO {{po_number}}"
                description: "Invoice amount: {{get-invoice.total_amount}} {{get-invoice.currency}}. PO total: {{get-po-details.total_value}}. Vendor: {{get-po-details.vendor}}."
                assignment_group: "{{approver_group}}"
  consumes:
    - type: http
      namespace: sap-ariba
      baseUri: "https://openapi.ariba.com/api/invoice-management/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-erp
      baseUri: "https://veolia-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
    - type: http
      namespace: servicenow-finance
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST

Performs three-way match between Ariba invoice, SAP purchase order, and goods receipt, creating a ServiceNow task when discrepancies are found.

naftiko: "0.5"
info:
  label: "Vendor Invoice Three-Way Match"
  description: "Performs three-way match between Ariba invoice, SAP purchase order, and goods receipt, creating a ServiceNow task when discrepancies are found."
  tags:
    - finance
    - procurement
    - sap-ariba
    - sap
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: finance-verification
      port: 8080
      tools:
        - name: verify-three-way-match
          description: "Given an invoice ID and PO number, verify the match and flag discrepancies."
          inputParameters:
            - name: invoice_id
              in: body
              type: string
              description: "The Ariba invoice ID."
            - name: po_number
              in: body
              type: string
              description: "The SAP purchase order number."
          steps:
            - name: get-invoice
              type: call
              call: "ariba.get-invoice"
              with:
                invoice_id: "{{invoice_id}}"
            - name: get-po
              type: call
              call: "sap.get-po"
              with:
                po_number: "{{po_number}}"
            - name: create-discrepancy-task
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "Three-way match review: Invoice {{invoice_id}} vs PO {{po_number}}"
                description: "Invoice amount: {{get-invoice.total_amount}}. PO amount: {{get-po.total_value}}. Vendor: {{get-po.vendor}}."
                assignment_group: "AP_Verification"
  consumes:
    - type: http
      namespace: ariba
      baseUri: "https://openapi.ariba.com/api/invoice-management/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://veolia-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
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST

Pulls operational route performance data from Snowflake and generates a weekly waste collection efficiency report delivered via Microsoft Teams to field operations managers.

naftiko: "0.5"
info:
  label: "Waste Collection Route Performance Report"
  description: "Pulls operational route performance data from Snowflake and generates a weekly waste collection efficiency report delivered via Microsoft Teams to field operations managers."
  tags:
    - operations
    - waste
    - snowflake
    - microsoft-teams
    - reporting
    - field-operations
capability:
  exposes:
    - type: mcp
      namespace: waste-ops-reporting
      port: 8080
      tools:
        - name: digest-route-performance
          description: "Given a reporting week and region code, query Snowflake for route completion rates and on-time performance, then post a summary to the field ops Teams channel."
          inputParameters:
            - name: reporting_week
              in: body
              type: string
              description: "The ISO week in YYYY-Www format (e.g., 2026-W12)."
            - name: region_code
              in: body
              type: string
              description: "The Veolia region code for filtering route data."
            - name: ops_channel_id
              in: body
              type: string
              description: "Microsoft Teams channel ID for the field operations team."
          steps:
            - name: get-route-data
              type: call
              call: "snowflake-routes.execute-query"
              with:
                statement: "SELECT region, COUNT(*) as routes, AVG(completion_pct) as avg_completion, AVG(on_time_pct) as avg_on_time FROM waste_ops.route_performance WHERE iso_week = '{{reporting_week}}' AND region = '{{region_code}}' GROUP BY region"
            - name: post-report
              type: call
              call: "msteams-field-ops.post-message"
              with:
                channel_id: "{{ops_channel_id}}"
                text: "Route Performance Report ({{reporting_week}}, Region: {{region_code}}): Avg completion {{get-route-data.avg_completion}}%, On-time {{get-route-data.avg_on_time}}%, Total routes: {{get-route-data.routes}}."
  consumes:
    - type: http
      namespace: snowflake-routes
      baseUri: "https://veolia.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-query
              method: POST
    - type: http
      namespace: msteams-field-ops
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: team_id
              in: path
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

When a waste collection vehicle reports a breakdown, creates a SAP maintenance order, dispatches a replacement via ServiceNow, and notifies the fleet team on Teams.

naftiko: "0.5"
info:
  label: "Waste Collection Vehicle Breakdown Response"
  description: "When a waste collection vehicle reports a breakdown, creates a SAP maintenance order, dispatches a replacement via ServiceNow, and notifies the fleet team on Teams."
  tags:
    - fleet-management
    - sap
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: fleet-ops
      port: 8080
      tools:
        - name: handle-vehicle-breakdown
          description: "Given a vehicle ID and location, create a maintenance order, dispatch replacement, and notify fleet."
          inputParameters:
            - name: vehicle_id
              in: body
              type: string
              description: "The fleet vehicle ID."
            - name: location
              in: body
              type: string
              description: "The breakdown location."
            - name: route_id
              in: body
              type: string
              description: "The collection route ID."
          steps:
            - name: create-maintenance-order
              type: call
              call: "sap.create-pm-order"
              with:
                equipment: "{{vehicle_id}}"
                description: "Vehicle breakdown at {{location}}"
                order_type: "PM02"
            - name: dispatch-replacement
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "Replacement vehicle needed: Route {{route_id}}"
                description: "Vehicle {{vehicle_id}} broken down at {{location}}. SAP order: {{create-maintenance-order.order_number}}."
                assignment_group: "Fleet_Dispatch"
            - name: notify-fleet
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_fleet_channel"
                text: "Vehicle breakdown: {{vehicle_id}} at {{location}} | Route: {{route_id}} | SAP: {{create-maintenance-order.order_number}} | Dispatch: {{dispatch-replacement.number}}"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://veolia-s4.sap.com/sap/opu/odata/sap/API_MAINTENANCEORDER_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: maintenance-orders
          path: "/A_MaintenanceOrder"
          operations:
            - name: create-pm-order
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/fleet/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Queries recycling rate data from Snowflake, publishes a monthly report to Confluence, and shares with the sustainability team on Teams.

naftiko: "0.5"
info:
  label: "Waste Recycling Rate Report Workflow"
  description: "Queries recycling rate data from Snowflake, publishes a monthly report to Confluence, and shares with the sustainability team on Teams."
  tags:
    - sustainability
    - waste-management
    - snowflake
    - confluence
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: sustainability
      port: 8080
      tools:
        - name: generate-recycling-report
          description: "Given a region and month, generate recycling rate report."
          inputParameters:
            - name: region
              in: body
              type: string
              description: "The operating region."
            - name: report_month
              in: body
              type: string
              description: "The report month (YYYY-MM)."
          steps:
            - name: get-recycling-data
              type: call
              call: "snowflake.execute-query"
              with:
                statement: "SELECT material_type, SUM(recycled_tons) as recycled, SUM(total_tons) as total FROM WASTE_DB.PUBLIC.COLLECTION_DATA WHERE region='{{region}}' AND month='{{report_month}}' GROUP BY material_type"
            - name: publish-report
              type: call
              call: "confluence.create-page"
              with:
                space_key: "SUSTAINABILITY"
                title: "Recycling Report: {{region}} — {{report_month}}"
                body: "Recycling data: {{get-recycling-data.results}}"
            - name: notify-sustainability
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_sustainability_channel"
                text: "Recycling report published: {{region}} {{report_month}} | {{publish-report.url}}"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://veolia.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-query
              method: POST
    - type: http
      namespace: confluence
      baseUri: "https://veolia.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_api_token"
      resources:
        - name: pages
          path: "/content"
          operations:
            - name: create-page
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/sustainability/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Pulls water quality data from Snowflake, generates a regulatory compliance report in Confluence, and notifies the EHS team via Teams.

naftiko: "0.5"
info:
  label: "Water Quality Compliance Report Generator"
  description: "Pulls water quality data from Snowflake, generates a regulatory compliance report in Confluence, and notifies the EHS team via Teams."
  tags:
    - compliance
    - water-treatment
    - snowflake
    - confluence
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: ehs-reporting
      port: 8080
      tools:
        - name: generate-water-quality-report
          description: "Given a plant ID and period, generate compliance report."
          inputParameters:
            - name: plant_id
              in: body
              type: string
              description: "The treatment plant ID."
            - name: reporting_period
              in: body
              type: string
              description: "The reporting period."
          steps:
            - name: get-quality-data
              type: call
              call: "snowflake.execute-query"
              with:
                statement: "SELECT parameter, AVG(value) as avg_value, MAX(value) as max_value FROM WATER_OPS.PUBLIC.SENSOR_READINGS WHERE plant_id='{{plant_id}}' AND period='{{reporting_period}}' GROUP BY parameter"
            - name: publish-report
              type: call
              call: "confluence.create-page"
              with:
                space_key: "EHS"
                title: "Water Quality: Plant {{plant_id}} — {{reporting_period}}"
                body: "Quality data for plant {{plant_id}}: {{get-quality-data.results}}"
            - name: notify-ehs
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_ehs_channel"
                text: "Water quality report published: Plant {{plant_id}} {{reporting_period}} | {{publish-report.url}}"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://veolia.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-query
              method: POST
    - type: http
      namespace: confluence
      baseUri: "https://veolia.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_api_token"
      resources:
        - name: pages
          path: "/content"
          operations:
            - name: create-page
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/ehs/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Retrieves the latest water quality sensor readings from Snowflake for a specific treatment plant and parameter.

naftiko: "0.5"
info:
  label: "Water Quality Sensor Reading Lookup"
  description: "Retrieves the latest water quality sensor readings from Snowflake for a specific treatment plant and parameter."
  tags:
    - operations
    - water-treatment
    - snowflake
capability:
  exposes:
    - type: mcp
      namespace: water-ops
      port: 8080
      tools:
        - name: get-sensor-reading
          description: "Query Snowflake for the latest water quality reading at a plant. Returns parameter value and timestamp."
          inputParameters:
            - name: plant_id
              in: body
              type: string
              description: "The water treatment plant identifier."
            - name: parameter_name
              in: body
              type: string
              description: "The quality parameter (e.g., pH, turbidity, chlorine)."
          call: "snowflake.execute-query"
          with:
            statement: "SELECT value, reading_time FROM WATER_OPS.PUBLIC.SENSOR_READINGS WHERE plant_id='{{plant_id}}' AND parameter='{{parameter_name}}' ORDER BY reading_time DESC LIMIT 1"
          outputParameters:
            - name: value
              type: string
              mapping: "$.data[0].value"
            - name: reading_time
              type: string
              mapping: "$.data[0].reading_time"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://veolia.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-query
              method: POST

When a water treatment plant alarm triggers in the SCADA system, creates a ServiceNow P1 incident and notifies the plant operations team on Teams.

naftiko: "0.5"
info:
  label: "Water Treatment Alarm to Incident Workflow"
  description: "When a water treatment plant alarm triggers in the SCADA system, creates a ServiceNow P1 incident and notifies the plant operations team on Teams."
  tags:
    - operations
    - water-treatment
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: plant-ops
      port: 8080
      tools:
        - name: handle-treatment-alarm
          description: "Given a plant alarm event, create a ServiceNow incident and notify operations."
          inputParameters:
            - name: plant_id
              in: body
              type: string
              description: "The treatment plant identifier."
            - name: alarm_type
              in: body
              type: string
              description: "The alarm type."
            - name: alarm_description
              in: body
              type: string
              description: "Description of the alarm condition."
          steps:
            - name: create-incident
              type: call
              call: "servicenow.create-incident"
              with:
                short_description: "Treatment alarm: {{alarm_type}} at plant {{plant_id}}"
                urgency: "1"
                impact: "1"
                description: "{{alarm_description}}"
                category: "operations"
            - name: notify-ops
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_plant_ops_channel"
                text: "ALARM: {{alarm_type}} at plant {{plant_id}} | {{alarm_description}} | Incident: {{create-incident.number}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/plant-ops/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

When a SCADA/OT threshold alert is received for a water treatment facility, creates a priority ServiceNow incident and escalates to the plant operations manager via Microsoft Teams.

naftiko: "0.5"
info:
  label: "Water Treatment Plant OT Alert Escalation"
  description: "When a SCADA/OT threshold alert is received for a water treatment facility, creates a priority ServiceNow incident and escalates to the plant operations manager via Microsoft Teams."
  tags:
    - ot
    - operations
    - water
    - servicenow
    - microsoft-teams
    - manufacturing
    - escalation
capability:
  exposes:
    - type: mcp
      namespace: plant-ops
      port: 8080
      tools:
        - name: escalate-ot-alert
          description: "Given a plant ID, alert type, and severity, create a priority ServiceNow incident and send an escalation message to the plant operations manager on Microsoft Teams."
          inputParameters:
            - name: plant_id
              in: body
              type: string
              description: "The Veolia plant or facility identifier."
            - name: alert_type
              in: body
              type: string
              description: "Type of OT alert (e.g., turbidity_high, pressure_low, pump_failure)."
            - name: severity
              in: body
              type: string
              description: "Alert severity: P1, P2, or P3."
            - name: manager_upn
              in: body
              type: string
              description: "UPN of the plant operations manager to notify."
            - name: sensor_value
              in: body
              type: string
              description: "The sensor reading that triggered the alert."
          steps:
            - name: create-incident
              type: call
              call: "servicenow-plant.create-incident"
              with:
                short_description: "[{{severity}}] OT Alert — {{alert_type}} at plant {{plant_id}}"
                description: "Sensor reading: {{sensor_value}}. Alert type: {{alert_type}}. Plant: {{plant_id}}. Severity: {{severity}}."
                urgency: "1"
                category: "ot_operations"
            - name: escalate-manager
              type: call
              call: "msteams-plant.send-message"
              with:
                recipient_upn: "{{manager_upn}}"
                text: "URGENT: OT Alert {{alert_type}} at plant {{plant_id}} (Severity: {{severity}}). Sensor value: {{sensor_value}}. Incident: {{create-incident.number}}. Immediate action required."
  consumes:
    - type: http
      namespace: servicenow-plant
      baseUri: "https://veolia.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-plant
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: messages
          path: "/users/{{recipient_upn}}/sendMail"
          inputParameters:
            - name: recipient_upn
              in: path
          operations:
            - name: send-message
              method: POST

Extracts compensation review data from Workday, stores summaries in Snowflake, and distributes review packets via SharePoint.

naftiko: "0.5"
info:
  label: "Workday Compensation Review Distribution"
  description: "Extracts compensation review data from Workday, stores summaries in Snowflake, and distributes review packets via SharePoint."
  tags:
    - hr
    - compensation
    - workday
    - snowflake
    - sharepoint
capability:
  exposes:
    - type: mcp
      namespace: hr-comp
      port: 8080
      tools:
        - name: distribute-comp-reviews
          description: "Given a review cycle and department, extract, summarize, and distribute."
          inputParameters:
            - name: review_cycle_id
              in: body
              type: string
              description: "The review cycle ID."
            - name: department
              in: body
              type: string
              description: "The department."
          steps:
            - name: get-data
              type: call
              call: "workday.get-comp-review"
              with:
                review_cycle_id: "{{review_cycle_id}}"
                department: "{{department}}"
            - name: store-summary
              type: call
              call: "snowflake.execute-query"
              with:
                statement: "INSERT INTO HR_DB.PUBLIC.COMP_REVIEWS (cycle_id, department, avg_increase) VALUES ('{{review_cycle_id}}', '{{department}}', '{{get-data.avg_increase}}')"
            - name: upload
              type: call
              call: "sharepoint.upload-file"
              with:
                site_id: "$secrets.sharepoint_hr_site"
                folder: "Comp Reviews/{{review_cycle_id}}"
                file_name: "{{department}}_review.pdf"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: comp
          path: "/veolia/compensationReviews/{{review_cycle_id}}"
          inputParameters:
            - name: review_cycle_id
              in: path
          operations:
            - name: get-comp-review
              method: GET
    - type: http
      namespace: snowflake
      baseUri: "https://veolia.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-query
              method: POST
    - type: http
      namespace: sharepoint
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: uploads
          path: "/sites/{{site_id}}/drive/root:/{{folder}}/{{file_name}}:/content"
          inputParameters:
            - name: site_id
              in: path
          operations:
            - name: upload-file
              method: PUT

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

naftiko: "0.5"
info:
  label: "Workday Employee Profile Lookup"
  description: "Fetches an employee profile from Workday by worker ID, returning name, department, manager, and job title."
  tags:
    - hr
    - workday
capability:
  exposes:
    - type: mcp
      namespace: hr-directory
      port: 8080
      tools:
        - name: get-employee-profile
          description: "Retrieve an employee profile from Workday by worker ID. Returns full name, department, job title, and manager."
          inputParameters:
            - name: worker_id
              in: body
              type: string
              description: "The Workday worker ID."
          call: "workday.get-worker"
          with:
            worker_id: "{{worker_id}}"
          outputParameters:
            - name: full_name
              type: string
              mapping: "$.worker.fullName"
            - name: department
              type: string
              mapping: "$.worker.department"
            - name: job_title
              type: string
              mapping: "$.worker.jobTitle"
  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: "/veolia/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET

When a new hire joins a field operations role in Workday, assigns mandatory safety training, creates a ServiceNow tracking task, and sends a welcome email.

naftiko: "0.5"
info:
  label: "Workday New Hire Safety Training Assignment"
  description: "When a new hire joins a field operations role in Workday, assigns mandatory safety training, creates a ServiceNow tracking task, and sends a welcome email."
  tags:
    - hr
    - safety
    - workday
    - servicenow
    - microsoft-outlook
capability:
  exposes:
    - type: mcp
      namespace: hr-safety
      port: 8080
      tools:
        - name: assign-safety-training
          description: "Given a worker ID for a new field hire, assign safety training and track."
          inputParameters:
            - name: worker_id
              in: body
              type: string
              description: "The Workday worker ID."
          steps:
            - name: get-employee
              type: call
              call: "workday.get-worker"
              with:
                worker_id: "{{worker_id}}"
            - name: create-training-task
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "Safety training: {{get-employee.full_name}} — field operations"
                assignment_group: "EHS_Training"
                description: "New hire {{get-employee.full_name}} in {{get-employee.department}} requires mandatory safety training."
            - name: send-welcome
              type: call
              call: "msgraph.send-mail"
              with:
                recipient: "{{get-employee.work_email}}"
                subject: "Welcome to Veolia — Required Safety Training"
                body: "Hi {{get-employee.first_name}}, your mandatory safety training has been assigned. Please complete within 30 days. Reference: {{create-training-task.number}}."
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/veolia/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: msgraph
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: mail
          path: "/users/$secrets.service_account_upn/sendMail"
          operations:
            - name: send-mail
              method: POST

When an org chart change is made in Workday, updates Salesforce reporting and notifies the department on Teams.

naftiko: "0.5"
info:
  label: "Workday Org Change Propagation"
  description: "When an org chart change is made in Workday, updates Salesforce reporting and notifies the department on Teams."
  tags:
    - hr
    - workday
    - salesforce
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: hr-org
      port: 8080
      tools:
        - name: propagate-org-change
          description: "Given a worker ID with a new manager, update downstream systems."
          inputParameters:
            - name: worker_id
              in: body
              type: string
              description: "The Workday worker ID."
            - name: new_manager_id
              in: body
              type: string
              description: "The new manager's worker ID."
          steps:
            - name: get-employee
              type: call
              call: "workday.get-worker"
              with:
                worker_id: "{{worker_id}}"
            - name: update-salesforce
              type: call
              call: "salesforce.update-user"
              with:
                user_email: "{{get-employee.work_email}}"
                manager_id: "{{new_manager_id}}"
            - name: notify-dept
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_hr_channel"
                text: "Org change: {{get-employee.full_name}} now reports to manager {{new_manager_id}}"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/veolia/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: salesforce
      baseUri: "https://veolia.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: users
          path: "/sobjects/User"
          operations:
            - name: update-user
              method: PATCH
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/hr/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

When a payroll variance is detected in Workday, pulls employee details, creates a ServiceNow task, and notifies HR on Teams.

naftiko: "0.5"
info:
  label: "Workday Payroll Discrepancy Investigation"
  description: "When a payroll variance is detected in Workday, pulls employee details, creates a ServiceNow task, and notifies HR on Teams."
  tags:
    - hr
    - payroll
    - workday
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: hr-payroll
      port: 8080
      tools:
        - name: investigate-payroll
          description: "Given a worker ID and pay period, create investigation task."
          inputParameters:
            - name: worker_id
              in: body
              type: string
              description: "The Workday worker ID."
            - name: pay_period
              in: body
              type: string
              description: "The pay period."
          steps:
            - name: get-employee
              type: call
              call: "workday.get-worker"
              with:
                worker_id: "{{worker_id}}"
            - name: create-task
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "Payroll discrepancy: {{get-employee.full_name}} — {{pay_period}}"
                assignment_group: "Payroll"
            - name: notify
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.teams_payroll_channel"
                text: "Payroll discrepancy: {{get-employee.full_name}} for {{pay_period}} | Task: {{create-task.number}}"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/veolia/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/payroll/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

When a termination event is detected in Workday, disables the Azure AD account, creates a ServiceNow offboarding task, and logs the action.

naftiko: "0.5"
info:
  label: "Workday Termination Access Revocation"
  description: "When a termination event is detected in Workday, disables the Azure AD account, creates a ServiceNow offboarding task, and logs the action."
  tags:
    - hr
    - security
    - workday
    - azure-ad
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: hr-offboarding
      port: 8080
      tools:
        - name: revoke-terminated-access
          description: "Given a worker ID, disable Azure AD, create offboarding task, and notify."
          inputParameters:
            - name: worker_id
              in: body
              type: string
              description: "The Workday worker ID."
          steps:
            - name: get-employee
              type: call
              call: "workday.get-worker"
              with:
                worker_id: "{{worker_id}}"
            - name: disable-account
              type: call
              call: "msgraph.disable-user"
              with:
                user_upn: "{{get-employee.work_email}}"
            - name: create-offboarding-task
              type: call
              call: "servicenow.create-task"
              with:
                short_description: "Offboarding: {{get-employee.full_name}} — access revoked"
                assignment_group: "IT_Security"
  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: "/veolia/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: msgraph
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: users
          path: "/users/{{user_upn}}"
          inputParameters:
            - name: user_upn
              in: path
          operations:
            - name: disable-user
              method: PATCH
    - type: http
      namespace: servicenow
      baseUri: "https://veolia.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST