Salesforce Capabilities

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

Sort
Expand

When AWS Cost Explorer detects a spend anomaly, creates a Jira investigation ticket and alerts the FinOps team via Slack.

naftiko: "0.5"
info:
  label: "AWS Cost Spike Investigation"
  description: "When AWS Cost Explorer detects a spend anomaly, creates a Jira investigation ticket and alerts the FinOps team via Slack."
  tags:
    - finops
    - aws
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: cost-investigation
      port: 8080
      tools:
        - name: investigate-cost-spike
          description: "Given an AWS cost anomaly alert, create a Jira ticket and notify the FinOps team."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The AWS account ID."
            - name: service_name
              in: body
              type: string
              description: "The AWS service with the cost spike."
            - name: anomaly_amount
              in: body
              type: string
              description: "The anomalous spend amount."
          steps:
            - name: create-ticket
              type: call
              call: "jira-api.create-issue"
              with:
                project: "FINOPS"
                issuetype: "Task"
                summary: "[Cost Spike] ${{anomaly_amount}} on {{service_name}} in {{account_id}}"
                description: "AWS cost anomaly detected.\nAccount: {{account_id}}\nService: {{service_name}}\nAnomaly: ${{anomaly_amount}}"
            - name: notify-finops
              type: call
              call: "slack-api.post-message"
              with:
                channel: "finops"
                text: "AWS Cost Spike: ${{anomaly_amount}} on {{service_name}} in account {{account_id}} | Jira: {{create-ticket.key}}"
  consumes:
    - type: http
      namespace: jira-api
      baseUri: "https://salesforce.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

On a GitHub Actions pipeline failure in a protected branch, creates a Jira bug, posts a Datadog deployment marker, and alerts the engineering team in Slack.

naftiko: "0.5"
info:
  label: "CI/CD Pipeline Failure Response"
  description: "On a GitHub Actions pipeline failure in a protected branch, creates a Jira bug, posts a Datadog deployment marker, and alerts the engineering team in Slack."
  tags:
    - devops
    - cicd
    - github
    - jira
    - datadog
    - slack
    - incident-response
capability:
  exposes:
    - type: mcp
      namespace: devops-cicd
      port: 8080
      tools:
        - name: handle-pipeline-failure
          description: "Given a GitHub Actions pipeline failure, open a Jira bug, record a Datadog event, and alert the engineering Slack channel with full context."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "The GitHub repository full name (e.g., salesforce/einstein-platform)."
            - name: branch
              in: body
              type: string
              description: "The branch where the pipeline failed."
            - name: run_id
              in: body
              type: string
              description: "The GitHub Actions workflow run ID."
            - name: commit_sha
              in: body
              type: string
              description: "The commit SHA that triggered the pipeline."
            - name: job_name
              in: body
              type: string
              description: "The name of the failed job."
          steps:
            - name: create-bug
              type: call
              call: "jira-cicd.create-issue"
              with:
                project_key: "ENG"
                issuetype: "Bug"
                summary: "[CI Failure] {{repo}} / {{branch}} — {{job_name}}"
                description: "Run: {{run_id}}\nCommit: {{commit_sha}}"
            - name: post-event
              type: call
              call: "datadog-cicd.create-event"
              with:
                title: "CI Failure: {{repo}}"
                text: "Branch {{branch}} failed on job {{job_name}}"
                tags: "repo:{{repo}},branch:{{branch}}"
            - name: alert-eng
              type: call
              call: "slack-cicd.post-message"
              with:
                channel: "engineering-alerts"
                text: "Pipeline failure on {{repo}}/{{branch}} — Job: {{job_name}} | Jira: {{create-bug.key}} | Run: {{run_id}}"
  consumes:
    - type: http
      namespace: jira-cicd
      baseUri: "https://salesforce.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: datadog-cicd
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: events
          path: "/events"
          operations:
            - name: create-event
              method: POST
    - type: http
      namespace: slack-cicd
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When AWS spend anomalies are detected, creates a Jira investigation ticket and alerts the cloud FinOps team in Slack with account and service details.

naftiko: "0.5"
info:
  label: "Cloud Cost Anomaly Alert"
  description: "When AWS spend anomalies are detected, creates a Jira investigation ticket and alerts the cloud FinOps team in Slack with account and service details."
  tags:
    - cloud
    - finops
    - aws
    - jira
    - slack
    - cost-management
capability:
  exposes:
    - type: mcp
      namespace: cloud-finops
      port: 8080
      tools:
        - name: handle-cost-anomaly
          description: "Given an AWS account ID, service name, and anomaly spend amount, create a Jira cost investigation ticket and notify the FinOps Slack channel."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The AWS account ID where the anomaly was detected."
            - name: service_name
              in: body
              type: string
              description: "The AWS service with anomalous spend (e.g., EC2, Lambda)."
            - name: anomaly_amount
              in: body
              type: number
              description: "The unexpected spend amount in USD."
          steps:
            - name: create-jira-ticket
              type: call
              call: "jira-finops.create-issue"
              with:
                project_key: "FINOPS"
                issuetype: "Task"
                summary: "AWS cost anomaly: ${{anomaly_amount}} on {{service_name}} in {{account_id}}"
                description: "Investigate unexpected spend of ${{anomaly_amount}} on AWS {{service_name}} in account {{account_id}}."
            - name: alert-finops
              type: call
              call: "slack-finops.post-message"
              with:
                channel: "cloud-cost-ops"
                text: "Cost anomaly: {{service_name}} in {{account_id}} — ${{anomaly_amount}} | Jira: {{create-jira-ticket.key}}"
  consumes:
    - type: http
      namespace: jira-finops
      baseUri: "https://salesforce.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-finops
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves a Confluence page by ID and returns its title, body content, and last updated timestamp.

naftiko: "0.5"
info:
  label: "Confluence Page Content Lookup"
  description: "Retrieves a Confluence page by ID and returns its title, body content, and last updated timestamp."
  tags:
    - documentation
    - confluence
    - knowledge-base
capability:
  exposes:
    - type: mcp
      namespace: confluence-content
      port: 8080
      tools:
        - name: get-page
          description: "Given a Confluence page ID, return the page title, body content, and last modification date. Use for knowledge base lookups."
          inputParameters:
            - name: page_id
              in: body
              type: string
              description: "The Confluence page ID."
          call: "confluence-api.get-page"
          with:
            page_id: "{{page_id}}"
          outputParameters:
            - name: title
              type: string
              mapping: "$.title"
            - name: body
              type: string
              mapping: "$.body.storage.value"
            - name: last_updated
              type: string
              mapping: "$.version.when"
  consumes:
    - type: http
      namespace: confluence-api
      baseUri: "https://salesforce.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_token"
      resources:
        - name: content
          path: "/content/{{page_id}}?expand=body.storage,version"
          inputParameters:
            - name: page_id
              in: path
          operations:
            - name: get-page
              method: GET

Creates a new runbook page in Confluence from a template, links it to the relevant Jira epic, and notifies the team via Slack.

naftiko: "0.5"
info:
  label: "Confluence Runbook Publish and Notify"
  description: "Creates a new runbook page in Confluence from a template, links it to the relevant Jira epic, and notifies the team via Slack."
  tags:
    - documentation
    - confluence
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: runbook-publish
      port: 8080
      tools:
        - name: publish-runbook
          description: "Given runbook content and a Jira epic key, create a Confluence page, link it to the epic, and notify the team."
          inputParameters:
            - name: title
              in: body
              type: string
              description: "Runbook title."
            - name: content
              in: body
              type: string
              description: "Runbook content in storage format."
            - name: epic_key
              in: body
              type: string
              description: "The Jira epic key to link."
          steps:
            - name: create-page
              type: call
              call: "confluence-api.create-page"
              with:
                title: "{{title}}"
                content: "{{content}}"
                spaceKey: "RUNBOOKS"
            - name: link-to-jira
              type: call
              call: "jira-api.add-remote-link"
              with:
                issue_key: "{{epic_key}}"
                url: "{{create-page.url}}"
                title: "Runbook: {{title}}"
            - name: notify-team
              type: call
              call: "slack-api.post-message"
              with:
                channel: "platform-engineering"
                text: "New runbook published: {{title}} | Confluence: {{create-page.url}} | Epic: {{epic_key}}"
  consumes:
    - type: http
      namespace: confluence-api
      baseUri: "https://salesforce.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_token"
      resources:
        - name: content
          path: "/content"
          operations:
            - name: create-page
              method: POST
    - type: http
      namespace: jira-api
      baseUri: "https://salesforce.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: remote-links
          path: "/issue/{{issue_key}}/remotelink"
          inputParameters:
            - name: issue_key
              in: path
          operations:
            - name: add-remote-link
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a Datadog monitor triggers a critical alert, pages the on-call engineer via PagerDuty and creates a Slack incident channel.

naftiko: "0.5"
info:
  label: "Datadog Alert to PagerDuty Escalation"
  description: "When a Datadog monitor triggers a critical alert, pages the on-call engineer via PagerDuty and creates a Slack incident channel."
  tags:
    - observability
    - datadog
    - pagerduty
    - slack
    - incident-response
capability:
  exposes:
    - type: mcp
      namespace: alert-escalation
      port: 8080
      tools:
        - name: escalate-alert
          description: "Given a Datadog monitor alert, page the on-call engineer via PagerDuty and create a Slack incident channel."
          inputParameters:
            - name: monitor_name
              in: body
              type: string
              description: "The Datadog monitor name."
            - name: monitor_url
              in: body
              type: string
              description: "URL to the Datadog monitor."
            - name: severity
              in: body
              type: string
              description: "Alert severity: critical, error, or warning."
          steps:
            - name: page-oncall
              type: call
              call: "pagerduty-api.create-incident"
              with:
                title: "[{{severity}}] {{monitor_name}}"
                service_id: "$secrets.pagerduty_platform_service_id"
                urgency: "high"
            - name: create-incident-channel
              type: call
              call: "slack-api.create-channel"
              with:
                name: "inc-{{monitor_name}}"
            - name: post-context
              type: call
              call: "slack-api.post-message"
              with:
                channel: "{{create-incident-channel.channel.id}}"
                text: "Incident: {{monitor_name}} | Severity: {{severity}} | Monitor: {{monitor_url}} | PagerDuty: {{page-oncall.incident_url}}"
  consumes:
    - type: http
      namespace: pagerduty-api
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.pagerduty_token"
        placement: header
      resources:
        - name: incidents
          path: "/incidents"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: channels
          path: "/conversations.create"
          operations:
            - name: create-channel
              method: POST
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Returns the current health status and error rate of a service from Datadog APM for quick operational checks.

naftiko: "0.5"
info:
  label: "Datadog APM Service Status"
  description: "Returns the current health status and error rate of a service from Datadog APM for quick operational checks."
  tags:
    - observability
    - datadog
    - apm
capability:
  exposes:
    - type: mcp
      namespace: apm-status
      port: 8080
      tools:
        - name: get-service-status
          description: "Given a Datadog service name, return its current health status, error rate, and latency from APM. Use for operational status checks."
          inputParameters:
            - name: service_name
              in: body
              type: string
              description: "The Datadog APM service name."
          call: "datadog-apm.get-service"
          with:
            service_name: "{{service_name}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.data.attributes.status"
            - name: error_rate
              type: number
              mapping: "$.data.attributes.error_rate"
            - name: avg_latency_ms
              type: number
              mapping: "$.data.attributes.avg_latency"
  consumes:
    - type: http
      namespace: datadog-apm
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: services
          path: "/service_dependencies/{{service_name}}"
          inputParameters:
            - name: service_name
              in: path
          operations:
            - name: get-service
              method: GET

When a Datadog critical monitor fires, automatically opens a Jira P1 incident and notifies the on-call channel in Slack with monitor details.

naftiko: "0.5"
info:
  label: "Datadog Monitor Alert to Jira Incident"
  description: "When a Datadog critical monitor fires, automatically opens a Jira P1 incident and notifies the on-call channel in Slack with monitor details."
  tags:
    - observability
    - datadog
    - jira
    - slack
    - incident-response
    - itsm
capability:
  exposes:
    - type: mcp
      namespace: itsm-alerting
      port: 8080
      tools:
        - name: handle-monitor-alert
          description: "Given a Datadog monitor ID and alert context, create a Jira P1 incident and page the on-call Slack channel. Use when critical infrastructure monitors fire."
          inputParameters:
            - name: monitor_id
              in: body
              type: string
              description: "The Datadog monitor ID that fired."
            - name: monitor_name
              in: body
              type: string
              description: "The human-readable name of the Datadog monitor."
            - name: alert_body
              in: body
              type: string
              description: "The full alert message from Datadog."
          steps:
            - name: create-incident
              type: call
              call: "jira-alert.create-issue"
              with:
                project_key: "OPS"
                issuetype: "Incident"
                summary: "P1: Datadog Alert — {{monitor_name}}"
                description: "Monitor ID: {{monitor_id}}\n{{alert_body}}"
                priority: "Highest"
            - name: page-oncall
              type: call
              call: "slack-alert.post-message"
              with:
                channel: "incidents"
                text: "P1 Incident: {{monitor_name}} | Jira: {{create-incident.key}} | Monitor: {{monitor_id}}"
  consumes:
    - type: http
      namespace: jira-alert
      baseUri: "https://salesforce.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-alert
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves current SLO burn rates from Datadog and posts a weekly compliance digest to the engineering leadership Slack channel.

naftiko: "0.5"
info:
  label: "Datadog SLO Compliance Digest"
  description: "Retrieves current SLO burn rates from Datadog and posts a weekly compliance digest to the engineering leadership Slack channel."
  tags:
    - observability
    - datadog
    - slack
    - slo
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: observability-reporting
      port: 8080
      tools:
        - name: digest-slo-compliance
          description: "Retrieve all active SLO compliance percentages from Datadog and post a formatted weekly digest to the Slack engineering leadership channel."
          inputParameters:
            - name: slo_tag
              in: body
              type: string
              description: "A Datadog tag to filter SLOs by (e.g., team:platform)."
            - name: slack_channel
              in: body
              type: string
              description: "The Slack channel to post the digest to."
          steps:
            - name: get-slos
              type: call
              call: "datadog-slo.list-slos"
              with:
                tags_query: "{{slo_tag}}"
            - name: post-digest
              type: call
              call: "slack-slo.post-message"
              with:
                channel: "{{slack_channel}}"
                text: "Weekly SLO digest for {{slo_tag}}: {{get-slos.summary}}"
  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: slos
          path: "/slo"
          operations:
            - name: list-slos
              method: GET
    - type: http
      namespace: slack-slo
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a Datadog synthetic test fails, retrieves test results, creates a Jira incident ticket, and posts diagnostic details to the Slack ops channel.

naftiko: "0.5"
info:
  label: "Datadog Synthetics Failure Handler"
  description: "When a Datadog synthetic test fails, retrieves test results, creates a Jira incident ticket, and posts diagnostic details to the Slack ops channel."
  tags:
    - observability
    - datadog
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: synthetics-handler
      port: 8080
      tools:
        - name: handle-synthetic-failure
          description: "Given a failed Datadog synthetic test, retrieve results, create a Jira ticket, and notify ops."
          inputParameters:
            - name: test_id
              in: body
              type: string
              description: "The Datadog synthetic test ID."
            - name: test_name
              in: body
              type: string
              description: "The synthetic test name."
            - name: failure_message
              in: body
              type: string
              description: "The failure message."
          steps:
            - name: get-test-results
              type: call
              call: "datadog-api.get-test-results"
              with:
                test_id: "{{test_id}}"
            - name: create-ticket
              type: call
              call: "jira-api.create-issue"
              with:
                project: "OPS"
                issuetype: "Bug"
                summary: "[Synthetic Failure] {{test_name}}"
                description: "Synthetic test {{test_name}} ({{test_id}}) failed.\nError: {{failure_message}}"
            - name: notify-ops
              type: call
              call: "slack-api.post-message"
              with:
                channel: "platform-ops"
                text: "Synthetic failure: {{test_name}} | Error: {{failure_message}} | Jira: {{create-ticket.key}}"
  consumes:
    - type: http
      namespace: datadog-api
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: synthetics
          path: "/synthetics/tests/{{test_id}}/results"
          inputParameters:
            - name: test_id
              in: path
          operations:
            - name: get-test-results
              method: GET
    - type: http
      namespace: jira-api
      baseUri: "https://salesforce.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a DocuSign envelope is completed, updates the Salesforce opportunity to Closed Won and posts a notification to Slack.

naftiko: "0.5"
info:
  label: "DocuSign Contract to Salesforce Update"
  description: "When a DocuSign envelope is completed, updates the Salesforce opportunity to Closed Won and posts a notification to Slack."
  tags:
    - legal
    - docusign
    - salesforce
    - slack
capability:
  exposes:
    - type: mcp
      namespace: contract-close
      port: 8080
      tools:
        - name: handle-contract-signed
          description: "Given a completed DocuSign envelope, update the linked Salesforce opportunity to Closed Won and notify via Slack."
          inputParameters:
            - name: envelope_id
              in: body
              type: string
              description: "The DocuSign envelope ID."
            - name: opportunity_id
              in: body
              type: string
              description: "The linked Salesforce opportunity ID."
          steps:
            - name: get-envelope
              type: call
              call: "docusign-api.get-envelope"
              with:
                envelope_id: "{{envelope_id}}"
            - name: update-opp
              type: call
              call: "sfdc-api.update-opportunity"
              with:
                opportunity_id: "{{opportunity_id}}"
                StageName: "Closed Won"
                Contract_Signed_Date__c: "{{get-envelope.completedDateTime}}"
            - name: notify-sales
              type: call
              call: "slack-api.post-message"
              with:
                channel: "deal-wins"
                text: "Contract signed! Envelope {{envelope_id}} completed. Opportunity {{opportunity_id}} moved to Closed Won."
  consumes:
    - type: http
      namespace: docusign-api
      baseUri: "https://na4.docusign.net/restapi/v2.1"
      authentication:
        type: bearer
        token: "$secrets.docusign_token"
      resources:
        - name: envelopes
          path: "/accounts/$secrets.docusign_account_id/envelopes/{{envelope_id}}"
          inputParameters:
            - name: envelope_id
              in: path
          operations:
            - name: get-envelope
              method: GET
    - type: http
      namespace: sfdc-api
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: opportunities
          path: "/sobjects/Opportunity/{{opportunity_id}}"
          inputParameters:
            - name: opportunity_id
              in: path
          operations:
            - name: update-opportunity
              method: PATCH
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Returns the current status, sender, and recipient statuses of a DocuSign envelope by envelope ID.

naftiko: "0.5"
info:
  label: "DocuSign Envelope Status Lookup"
  description: "Returns the current status, sender, and recipient statuses of a DocuSign envelope by envelope ID."
  tags:
    - legal
    - docusign
    - contracts
capability:
  exposes:
    - type: mcp
      namespace: docusign-status
      port: 8080
      tools:
        - name: get-envelope-status
          description: "Given a DocuSign envelope ID, return its status, sender, and recipient completion statuses."
          inputParameters:
            - name: envelope_id
              in: body
              type: string
              description: "The DocuSign envelope ID."
          call: "docusign-api.get-envelope"
          with:
            envelope_id: "{{envelope_id}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.status"
            - name: sender
              type: string
              mapping: "$.sender.userName"
            - name: recipients
              type: array
              mapping: "$.recipients.signers"
  consumes:
    - type: http
      namespace: docusign-api
      baseUri: "https://na4.docusign.net/restapi/v2.1"
      authentication:
        type: bearer
        token: "$secrets.docusign_token"
      resources:
        - name: envelopes
          path: "/accounts/$secrets.docusign_account_id/envelopes/{{envelope_id}}"
          inputParameters:
            - name: envelope_id
              in: path
          operations:
            - name: get-envelope
              method: GET

When an employee departure is recorded in Workday, deactivates the Okta account, revokes GitHub org access, and posts an offboarding summary to the HR Slack channel.

naftiko: "0.5"
info:
  label: "Employee Offboarding Workflow"
  description: "When an employee departure is recorded in Workday, deactivates the Okta account, revokes GitHub org access, and posts an offboarding summary to the HR Slack channel."
  tags:
    - hr
    - offboarding
    - workday
    - okta
    - github
    - slack
capability:
  exposes:
    - type: mcp
      namespace: hr-offboarding
      port: 8080
      tools:
        - name: trigger-offboarding
          description: "Given a Workday employee ID and termination date, deactivate the Okta user, remove GitHub org memberships, and notify HR in Slack."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "The Workday worker ID of the departing employee."
            - name: termination_date
              in: body
              type: string
              description: "The employee's last working day in YYYY-MM-DD format."
          steps:
            - name: get-employee
              type: call
              call: "workday-off.get-worker"
              with:
                worker_id: "{{employee_id}}"
            - name: deactivate-okta
              type: call
              call: "okta-off.deactivate-user"
              with:
                userId: "{{get-employee.oktaId}}"
            - name: remove-github
              type: call
              call: "github-off.remove-org-member"
              with:
                org: "salesforce"
                username: "{{get-employee.githubUsername}}"
            - name: notify-hr
              type: call
              call: "slack-off.post-message"
              with:
                channel: "hr-ops"
                text: "Offboarding complete for {{get-employee.displayName}} ({{termination_date}}). Okta deactivated, GitHub access removed."
  consumes:
    - type: http
      namespace: workday-off
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/salesforce/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: okta-off
      baseUri: "https://salesforce.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_api_token"
        placement: header
      resources:
        - name: users
          path: "/users/{{userId}}/lifecycle/deactivate"
          inputParameters:
            - name: userId
              in: path
          operations:
            - name: deactivate-user
              method: POST
    - type: http
      namespace: github-off
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: org-members
          path: "/orgs/{{org}}/members/{{username}}"
          inputParameters:
            - name: org
              in: path
            - name: username
              in: path
          operations:
            - name: remove-org-member
              method: DELETE
    - type: http
      namespace: slack-off
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a GitHub Actions workflow completes, logs the deployment in ServiceNow CMDB, updates the Jira release ticket, and posts status to Slack.

naftiko: "0.5"
info:
  label: "GitHub CI/CD Deployment Tracker"
  description: "When a GitHub Actions workflow completes, logs the deployment in ServiceNow CMDB, updates the Jira release ticket, and posts status to Slack."
  tags:
    - devops
    - github
    - servicenow
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: deployment-tracker
      port: 8080
      tools:
        - name: track-deployment
          description: "Given a completed GitHub Actions run, log in ServiceNow CMDB, update Jira release, and notify Slack."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "The GitHub repository name."
            - name: run_id
              in: body
              type: string
              description: "The GitHub Actions workflow run ID."
            - name: release_ticket
              in: body
              type: string
              description: "The Jira release ticket key."
          steps:
            - name: get-run
              type: call
              call: "github-api.get-workflow-run"
              with:
                repo: "{{repo}}"
                run_id: "{{run_id}}"
            - name: log-to-cmdb
              type: call
              call: "servicenow-api.create-deployment"
              with:
                application: "{{repo}}"
                version: "{{get-run.head_sha}}"
                environment: "production"
                status: "{{get-run.conclusion}}"
            - name: update-jira
              type: call
              call: "jira-api.transition-issue"
              with:
                issue_key: "{{release_ticket}}"
                transition_id: "41"
            - name: notify-team
              type: call
              call: "slack-api.post-message"
              with:
                channel: "deployments"
                text: "Deployment: {{repo}} | SHA: {{get-run.head_sha}} | Status: {{get-run.conclusion}} | Release: {{release_ticket}}"
  consumes:
    - type: http
      namespace: github-api
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: workflow-runs
          path: "/repos/salesforce/{{repo}}/actions/runs/{{run_id}}"
          inputParameters:
            - name: repo
              in: path
            - name: run_id
              in: path
          operations:
            - name: get-workflow-run
              method: GET
    - type: http
      namespace: servicenow-api
      baseUri: "https://salesforce.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: deployments
          path: "/table/change_request"
          operations:
            - name: create-deployment
              method: POST
    - type: http
      namespace: jira-api
      baseUri: "https://salesforce.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: transitions
          path: "/issue/{{issue_key}}/transitions"
          inputParameters:
            - name: issue_key
              in: path
          operations:
            - name: transition-issue
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When GitHub code scanning finds a high-severity issue, creates a Jira security task, assigns it to the code owner, and notifies the AppSec team via Slack.

naftiko: "0.5"
info:
  label: "GitHub Code Scanning to Jira Workflow"
  description: "When GitHub code scanning finds a high-severity issue, creates a Jira security task, assigns it to the code owner, and notifies the AppSec team via Slack."
  tags:
    - security
    - github
    - jira
    - slack
    - appsec
capability:
  exposes:
    - type: mcp
      namespace: code-scanning
      port: 8080
      tools:
        - name: handle-code-scan-alert
          description: "Given a GitHub code scanning alert, create a Jira task, assign to the code owner, and notify AppSec."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "The GitHub repository name."
            - name: alert_number
              in: body
              type: string
              description: "The code scanning alert number."
          steps:
            - name: get-alert
              type: call
              call: "github-api.get-code-scanning-alert"
              with:
                repo: "{{repo}}"
                alert_number: "{{alert_number}}"
            - name: create-task
              type: call
              call: "jira-api.create-issue"
              with:
                project: "APPSEC"
                issuetype: "Bug"
                summary: "[CodeQL] {{get-alert.rule.description}} in {{repo}}"
                description: "Code scanning alert in {{repo}}.\nRule: {{get-alert.rule.id}}\nSeverity: {{get-alert.rule.security_severity_level}}\nFile: {{get-alert.most_recent_instance.location.path}}"
            - name: notify-appsec
              type: call
              call: "slack-api.post-message"
              with:
                channel: "appsec"
                text: "Code scan alert: {{get-alert.rule.description}} in {{repo}} | Severity: {{get-alert.rule.security_severity_level}} | Jira: {{create-task.key}}"
  consumes:
    - type: http
      namespace: github-api
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: code-scanning
          path: "/repos/salesforce/{{repo}}/code-scanning/alerts/{{alert_number}}"
          inputParameters:
            - name: repo
              in: path
            - name: alert_number
              in: path
          operations:
            - name: get-code-scanning-alert
              method: GET
    - type: http
      namespace: jira-api
      baseUri: "https://salesforce.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a GitHub pull request is merged, extracts the Jira issue key from the branch name, transitions the issue to Done, and posts a deployment note to Slack.

naftiko: "0.5"
info:
  label: "GitHub PR Merge to Jira Transition"
  description: "When a GitHub pull request is merged, extracts the Jira issue key from the branch name, transitions the issue to Done, and posts a deployment note to Slack."
  tags:
    - devops
    - github
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: pr-merge-workflow
      port: 8080
      tools:
        - name: handle-pr-merge
          description: "Given a merged GitHub PR number, extract the Jira key from the branch, transition the Jira issue to Done, and notify Slack."
          inputParameters:
            - name: pr_number
              in: body
              type: string
              description: "The GitHub pull request number."
            - name: repo
              in: body
              type: string
              description: "The GitHub repository name."
          steps:
            - name: get-pr
              type: call
              call: "github-api.get-pr"
              with:
                repo: "{{repo}}"
                pr_number: "{{pr_number}}"
            - name: transition-jira
              type: call
              call: "jira-api.transition-issue"
              with:
                issue_key: "{{get-pr.head.ref}}"
                transition_id: "31"
            - name: notify-deploy
              type: call
              call: "slack-api.post-message"
              with:
                channel: "deployments"
                text: "PR #{{pr_number}} merged in {{repo}} | Jira: {{get-pr.head.ref}} moved to Done | Author: {{get-pr.user.login}}"
  consumes:
    - type: http
      namespace: github-api
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: pulls
          path: "/repos/salesforce/{{repo}}/pulls/{{pr_number}}"
          inputParameters:
            - name: repo
              in: path
            - name: pr_number
              in: path
          operations:
            - name: get-pr
              method: GET
    - type: http
      namespace: jira-api
      baseUri: "https://salesforce.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: transitions
          path: "/issue/{{issue_key}}/transitions"
          inputParameters:
            - name: issue_key
              in: path
          operations:
            - name: transition-issue
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Queries GitHub for pull requests open beyond 48 hours without a review and sends a reminder to the PR author in Slack to follow up with reviewers.

naftiko: "0.5"
info:
  label: "GitHub Pull Request Code Review Reminder"
  description: "Queries GitHub for pull requests open beyond 48 hours without a review and sends a reminder to the PR author in Slack to follow up with reviewers."
  tags:
    - devops
    - github
    - slack
    - code-review
    - developer-productivity
capability:
  exposes:
    - type: mcp
      namespace: devops-review
      port: 8080
      tools:
        - name: remind-stale-prs
          description: "Given a GitHub repository and a staleness threshold in hours, find PRs without activity and send Slack reminders to the respective PR authors."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "The GitHub repository full name to check for stale PRs."
            - name: threshold_hours
              in: body
              type: integer
              description: "Number of hours without review before a PR is considered stale (e.g., 48)."
          steps:
            - name: get-prs
              type: call
              call: "github-review.list-open-prs"
              with:
                repo: "{{repo}}"
            - name: send-reminder
              type: call
              call: "slack-review.post-message"
              with:
                channel: "engineering"
                text: "Stale PRs in {{repo}} (open > {{threshold_hours}}h): {{get-prs.stalePrList}}. Please follow up with reviewers."
  consumes:
    - type: http
      namespace: github-review
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: pull-requests
          path: "/repos/{{repo}}/pulls"
          inputParameters:
            - name: repo
              in: path
          operations:
            - name: list-open-prs
              method: GET
    - type: http
      namespace: slack-review
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a new engineer is approved in Workday, provisions their Okta account and adds them to the correct GitHub org team with write permissions.

naftiko: "0.5"
info:
  label: "GitHub Repository Access Provisioning"
  description: "When a new engineer is approved in Workday, provisions their Okta account and adds them to the correct GitHub org team with write permissions."
  tags:
    - devops
    - identity
    - github
    - okta
    - workday
    - access-management
capability:
  exposes:
    - type: mcp
      namespace: devops-access
      port: 8080
      tools:
        - name: provision-engineer-access
          description: "Given a Workday employee ID and GitHub team slug, provision Okta account and add the engineer to the GitHub org team. Use for new engineering hire access setup."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "The Workday worker ID of the new engineer."
            - name: github_team_slug
              in: body
              type: string
              description: "The GitHub team slug to add the engineer to (e.g., platform-team)."
            - name: permission
              in: body
              type: string
              description: "The GitHub team permission: pull, push, or maintain."
          steps:
            - name: get-employee
              type: call
              call: "workday-eng.get-worker"
              with:
                worker_id: "{{employee_id}}"
            - name: provision-okta
              type: call
              call: "okta-eng.create-user"
              with:
                firstName: "{{get-employee.firstName}}"
                lastName: "{{get-employee.lastName}}"
                email: "{{get-employee.workEmail}}"
            - name: add-github-member
              type: call
              call: "github-eng.add-team-member"
              with:
                org: "salesforce"
                team_slug: "{{github_team_slug}}"
                username: "{{get-employee.githubUsername}}"
  consumes:
    - type: http
      namespace: workday-eng
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/salesforce/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: okta-eng
      baseUri: "https://salesforce.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_api_token"
        placement: header
      resources:
        - name: users
          path: "/users"
          operations:
            - name: create-user
              method: POST
    - type: http
      namespace: github-eng
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: team-members
          path: "/orgs/{{org}}/teams/{{team_slug}}/memberships/{{username}}"
          inputParameters:
            - name: org
              in: path
            - name: team_slug
              in: path
            - name: username
              in: path
          operations:
            - name: add-team-member
              method: PUT

Returns metadata for a GitHub repository including language, stars, open issues, and last push date.

naftiko: "0.5"
info:
  label: "GitHub Repository Info Lookup"
  description: "Returns metadata for a GitHub repository including language, stars, open issues, and last push date."
  tags:
    - devops
    - github
    - repository
capability:
  exposes:
    - type: mcp
      namespace: github-repo
      port: 8080
      tools:
        - name: get-repo-info
          description: "Given an org and repo name, return repository metadata including primary language, stars, open issues, and last push timestamp."
          inputParameters:
            - name: org
              in: body
              type: string
              description: "The GitHub organization name."
            - name: repo
              in: body
              type: string
              description: "The GitHub repository name."
          call: "github-api.get-repo"
          with:
            org: "{{org}}"
            repo: "{{repo}}"
          outputParameters:
            - name: language
              type: string
              mapping: "$.language"
            - name: stars
              type: number
              mapping: "$.stargazers_count"
            - name: open_issues
              type: number
              mapping: "$.open_issues_count"
            - name: last_push
              type: string
              mapping: "$.pushed_at"
  consumes:
    - type: http
      namespace: github-api
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: repos
          path: "/repos/{{org}}/{{repo}}"
          inputParameters:
            - name: org
              in: path
            - name: repo
              in: path
          operations:
            - name: get-repo
              method: GET

Scans GitHub repositories for open Dependabot security advisories and automatically creates Jira security tickets for critical and high severity findings.

naftiko: "0.5"
info:
  label: "GitHub Security Advisory to Jira Ticket"
  description: "Scans GitHub repositories for open Dependabot security advisories and automatically creates Jira security tickets for critical and high severity findings."
  tags:
    - security
    - github
    - jira
    - devops
    - vulnerability-management
capability:
  exposes:
    - type: mcp
      namespace: security-advisories
      port: 8080
      tools:
        - name: triage-security-advisories
          description: "Given a GitHub repository name, fetch open Dependabot advisories and create Jira security tickets for any critical or high severity findings."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "The GitHub repository full name to scan for advisories (e.g., salesforce/apex-libs)."
            - name: jira_project
              in: body
              type: string
              description: "The Jira project key to file security tickets in."
          steps:
            - name: get-advisories
              type: call
              call: "github-sec.list-dependabot-alerts"
              with:
                repo: "{{repo}}"
            - name: create-ticket
              type: call
              call: "jira-sec.create-issue"
              with:
                project_key: "{{jira_project}}"
                issuetype: "Security"
                summary: "Security advisory in {{repo}}: {{get-advisories.packageName}}"
                description: "Severity: {{get-advisories.severity}}\nAdvisory: {{get-advisories.advisoryUrl}}"
  consumes:
    - type: http
      namespace: github-sec
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: dependabot-alerts
          path: "/repos/{{repo}}/dependabot/alerts"
          inputParameters:
            - name: repo
              in: path
          operations:
            - name: list-dependabot-alerts
              method: GET
    - type: http
      namespace: jira-sec
      baseUri: "https://salesforce.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

When GitHub Advanced Security detects a critical vulnerability, creates a ServiceNow security incident, assigns the owning team, and alerts via Slack.

naftiko: "0.5"
info:
  label: "GitHub Security Alert to ServiceNow Incident"
  description: "When GitHub Advanced Security detects a critical vulnerability, creates a ServiceNow security incident, assigns the owning team, and alerts via Slack."
  tags:
    - security
    - github
    - servicenow
    - slack
capability:
  exposes:
    - type: mcp
      namespace: security-alert
      port: 8080
      tools:
        - name: handle-security-alert
          description: "Given a GitHub security alert for a critical vulnerability, create a ServiceNow incident and notify the security team via Slack."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "The GitHub repository name."
            - name: alert_number
              in: body
              type: string
              description: "The GitHub security alert number."
            - name: vulnerability
              in: body
              type: string
              description: "CVE or vulnerability identifier."
          steps:
            - name: get-alert
              type: call
              call: "github-api.get-alert"
              with:
                repo: "{{repo}}"
                alert_number: "{{alert_number}}"
            - name: create-incident
              type: call
              call: "servicenow-api.create-incident"
              with:
                short_description: "[Critical] {{vulnerability}} in {{repo}}"
                description: "GitHub security alert #{{alert_number}} in {{repo}}.\nVulnerability: {{vulnerability}}\nSeverity: {{get-alert.severity}}\nPackage: {{get-alert.dependency.package.name}}"
                category: "security"
                urgency: "1"
            - name: notify-security
              type: call
              call: "slack-api.post-message"
              with:
                channel: "security-ops"
                text: "Critical vulnerability: {{vulnerability}} in {{repo}} | SNOW: {{create-incident.number}} | Package: {{get-alert.dependency.package.name}}"
  consumes:
    - type: http
      namespace: github-api
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: alerts
          path: "/repos/salesforce/{{repo}}/dependabot/alerts/{{alert_number}}"
          inputParameters:
            - name: repo
              in: path
            - name: alert_number
              in: path
          operations:
            - name: get-alert
              method: GET
    - type: http
      namespace: servicenow-api
      baseUri: "https://salesforce.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: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Identifies stale branches in a GitHub repository older than 90 days, creates a Jira cleanup task, and notifies owners via Slack.

naftiko: "0.5"
info:
  label: "GitHub Stale Branch Cleanup Notification"
  description: "Identifies stale branches in a GitHub repository older than 90 days, creates a Jira cleanup task, and notifies owners via Slack."
  tags:
    - devops
    - github
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: branch-cleanup
      port: 8080
      tools:
        - name: notify-stale-branches
          description: "Given a GitHub repository, identify stale branches, create a cleanup task, and notify branch owners."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "The GitHub repository name."
          steps:
            - name: list-branches
              type: call
              call: "github-api.list-branches"
              with:
                repo: "{{repo}}"
            - name: create-task
              type: call
              call: "jira-api.create-issue"
              with:
                project: "DEVOPS"
                issuetype: "Task"
                summary: "[Cleanup] Stale branches in {{repo}}"
                description: "Repository {{repo}} has stale branches older than 90 days requiring cleanup."
            - name: notify-team
              type: call
              call: "slack-api.post-message"
              with:
                channel: "engineering"
                text: "Stale branch cleanup needed: {{repo}} | Jira: {{create-task.key}}"
  consumes:
    - type: http
      namespace: github-api
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: branches
          path: "/repos/salesforce/{{repo}}/branches?per_page=100"
          inputParameters:
            - name: repo
              in: path
          operations:
            - name: list-branches
              method: GET
    - type: http
      namespace: jira-api
      baseUri: "https://salesforce.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves a HubSpot contact by email and returns lifecycle stage, lead score, and company association.

naftiko: "0.5"
info:
  label: "HubSpot Contact Lookup"
  description: "Retrieves a HubSpot contact by email and returns lifecycle stage, lead score, and company association."
  tags:
    - crm
    - hubspot
    - marketing
capability:
  exposes:
    - type: mcp
      namespace: hubspot-contacts
      port: 8080
      tools:
        - name: get-contact
          description: "Given an email address, return the HubSpot contact's lifecycle stage, lead score, and associated company."
          inputParameters:
            - name: email
              in: body
              type: string
              description: "The contact's email address."
          call: "hubspot-api.get-contact-by-email"
          with:
            email: "{{email}}"
          outputParameters:
            - name: lifecycle_stage
              type: string
              mapping: "$.properties.lifecyclestage"
            - name: lead_score
              type: number
              mapping: "$.properties.hubspotscore"
            - name: company
              type: string
              mapping: "$.properties.company"
  consumes:
    - type: http
      namespace: hubspot-api
      baseUri: "https://api.hubapi.com"
      authentication:
        type: bearer
        token: "$secrets.hubspot_token"
      resources:
        - name: contacts
          path: "/crm/v3/objects/contacts/{{email}}?idProperty=email"
          inputParameters:
            - name: email
              in: path
          operations:
            - name: get-contact-by-email
              method: GET

Returns the current status, priority, assignee, and summary of a Jira issue by key for quick agent or developer triage.

naftiko: "0.5"
info:
  label: "Jira Issue Status Lookup"
  description: "Returns the current status, priority, assignee, and summary of a Jira issue by key for quick agent or developer triage."
  tags:
    - devops
    - jira
    - triage
capability:
  exposes:
    - type: mcp
      namespace: jira-lookup
      port: 8080
      tools:
        - name: get-issue-status
          description: "Given a Jira issue key, return its current status, priority, assignee, and summary. Use for agent-driven triage or pre-incident briefing."
          inputParameters:
            - name: issue_key
              in: body
              type: string
              description: "The Jira issue key (e.g., PLATFORM-789)."
          call: "jira-status.get-issue"
          with:
            issue_key: "{{issue_key}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.fields.status.name"
            - name: priority
              type: string
              mapping: "$.fields.priority.name"
            - name: assignee
              type: string
              mapping: "$.fields.assignee.displayName"
            - name: summary
              type: string
              mapping: "$.fields.summary"
  consumes:
    - type: http
      namespace: jira-status
      baseUri: "https://salesforce.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

Queries Jira for overdue tickets across all projects, generates a summary grouped by team, and posts to Slack leadership channel.

naftiko: "0.5"
info:
  label: "Jira Overdue Tickets Digest"
  description: "Queries Jira for overdue tickets across all projects, generates a summary grouped by team, and posts to Slack leadership channel."
  tags:
    - devops
    - jira
    - slack
    - project-management
capability:
  exposes:
    - type: mcp
      namespace: overdue-digest
      port: 8080
      tools:
        - name: generate-overdue-digest
          description: "Query Jira for overdue tickets, summarize by team, and post to Slack."
          inputParameters:
            - name: days_overdue
              in: body
              type: number
              description: "Minimum days overdue to include."
          steps:
            - name: query-overdue
              type: call
              call: "jira-api.search-issues"
              with:
                jql: "duedate < now() AND status != Done"
            - name: post-digest
              type: call
              call: "slack-api.post-message"
              with:
                channel: "engineering-leadership"
                text: "Overdue Tickets Digest: {{query-overdue.total}} tickets overdue by {{days_overdue}}+ days."
  consumes:
    - type: http
      namespace: jira-api
      baseUri: "https://salesforce.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: search
          path: "/search"
          operations:
            - name: search-issues
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves completed story points for the current and previous Jira sprints and posts a velocity summary to the engineering leadership Slack channel.

naftiko: "0.5"
info:
  label: "Jira Sprint Velocity Digest"
  description: "Retrieves completed story points for the current and previous Jira sprints and posts a velocity summary to the engineering leadership Slack channel."
  tags:
    - devops
    - reporting
    - jira
    - slack
    - agile
capability:
  exposes:
    - type: mcp
      namespace: devops-reporting
      port: 8080
      tools:
        - name: digest-sprint-velocity
          description: "Given a Jira board ID, retrieve sprint velocity data and post a formatted digest to the specified Slack engineering channel."
          inputParameters:
            - name: board_id
              in: body
              type: string
              description: "The Jira board ID to retrieve velocity data for."
            - name: slack_channel
              in: body
              type: string
              description: "The Slack channel to post the digest to."
          steps:
            - name: get-sprints
              type: call
              call: "jira-sprint.get-board-sprints"
              with:
                board_id: "{{board_id}}"
            - name: post-digest
              type: call
              call: "slack-sprint.post-message"
              with:
                channel: "{{slack_channel}}"
                text: "Sprint velocity for board {{board_id}}: {{get-sprints.summary}}"
  consumes:
    - type: http
      namespace: jira-sprint
      baseUri: "https://salesforce.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: board-sprints
          path: "/board/{{board_id}}/sprint"
          inputParameters:
            - name: board_id
              in: path
          operations:
            - name: get-board-sprints
              method: GET
    - type: http
      namespace: slack-sprint
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves approved job requisition details from Workday and publishes the job to LinkedIn, enabling faster external candidate sourcing.

naftiko: "0.5"
info:
  label: "LinkedIn Job Posting Publication"
  description: "Retrieves approved job requisition details from Workday and publishes the job to LinkedIn, enabling faster external candidate sourcing."
  tags:
    - hr
    - recruiting
    - linkedin
    - workday
    - talent-acquisition
capability:
  exposes:
    - type: mcp
      namespace: hr-recruiting
      port: 8080
      tools:
        - name: publish-job-to-linkedin
          description: "Given a Workday job requisition ID, fetch its details and publish a formatted job posting to Salesforce's LinkedIn company page."
          inputParameters:
            - name: requisition_id
              in: body
              type: string
              description: "The Workday job requisition ID to publish."
            - name: linkedin_company_id
              in: body
              type: string
              description: "The LinkedIn company page ID for Salesforce."
          steps:
            - name: get-requisition
              type: call
              call: "workday-jobs.get-job-requisition"
              with:
                requisition_id: "{{requisition_id}}"
            - name: post-job
              type: call
              call: "linkedin-jobs.create-job-posting"
              with:
                companyId: "{{linkedin_company_id}}"
                title: "{{get-requisition.jobTitle}}"
                description: "{{get-requisition.jobDescription}}"
                location: "{{get-requisition.location}}"
  consumes:
    - type: http
      namespace: workday-jobs
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: job-requisitions
          path: "/salesforce/jobRequisitions/{{requisition_id}}"
          inputParameters:
            - name: requisition_id
              in: path
          operations:
            - name: get-job-requisition
              method: GET
    - type: http
      namespace: linkedin-jobs
      baseUri: "https://api.linkedin.com/v2"
      authentication:
        type: bearer
        token: "$secrets.linkedin_token"
      resources:
        - name: job-postings
          path: "/jobPostings"
          operations:
            - name: create-job-posting
              method: POST

When a new job requisition is approved in Workday, publishes it to LinkedIn Jobs, creates a Jira recruiting task, and notifies the recruiter via Slack.

naftiko: "0.5"
info:
  label: "LinkedIn Job Posting to Workday Sync"
  description: "When a new job requisition is approved in Workday, publishes it to LinkedIn Jobs, creates a Jira recruiting task, and notifies the recruiter via Slack."
  tags:
    - hr
    - linkedin
    - workday
    - jira
    - slack
    - recruiting
capability:
  exposes:
    - type: mcp
      namespace: job-publishing
      port: 8080
      tools:
        - name: publish-job-posting
          description: "Given an approved Workday requisition, publish to LinkedIn Jobs, create a Jira task, and notify the recruiter."
          inputParameters:
            - name: requisition_id
              in: body
              type: string
              description: "The Workday job requisition ID."
          steps:
            - name: get-req
              type: call
              call: "workday-api.get-requisition"
              with:
                requisition_id: "{{requisition_id}}"
            - name: post-to-linkedin
              type: call
              call: "linkedin-api.create-job-posting"
              with:
                title: "{{get-req.title}}"
                description: "{{get-req.description}}"
                location: "{{get-req.location}}"
            - name: create-task
              type: call
              call: "jira-api.create-issue"
              with:
                project: "RECRUIT"
                issuetype: "Task"
                summary: "[Hiring] {{get-req.title}} — {{get-req.location}}"
            - name: notify-recruiter
              type: call
              call: "slack-api.post-message"
              with:
                channel: "talent-acquisition"
                text: "Job posted: {{get-req.title}} in {{get-req.location}} | LinkedIn: {{post-to-linkedin.url}} | Jira: {{create-task.key}}"
  consumes:
    - type: http
      namespace: workday-api
      baseUri: "https://wd5-services1.myworkday.com/ccx/service/salesforce"
      authentication:
        type: basic
        username: "$secrets.workday_user"
        password: "$secrets.workday_password"
      resources:
        - name: requisitions
          path: "/Recruiting/v40.1/requisitions/{{requisition_id}}"
          inputParameters:
            - name: requisition_id
              in: path
          operations:
            - name: get-requisition
              method: GET
    - type: http
      namespace: linkedin-api
      baseUri: "https://api.linkedin.com/v2"
      authentication:
        type: bearer
        token: "$secrets.linkedin_token"
      resources:
        - name: job-postings
          path: "/simpleJobPostings"
          operations:
            - name: create-job-posting
              method: POST
    - type: http
      namespace: jira-api
      baseUri: "https://salesforce.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Returns request count, average response time, and error rate for a MuleSoft managed API.

naftiko: "0.5"
info:
  label: "MuleSoft API Analytics Lookup"
  description: "Returns request count, average response time, and error rate for a MuleSoft managed API."
  tags:
    - integration
    - mulesoft
    - api-management
capability:
  exposes:
    - type: mcp
      namespace: mulesoft-analytics
      port: 8080
      tools:
        - name: get-api-metrics
          description: "Given a MuleSoft API ID, return its request count, average response time, and error rate for the last 24 hours."
          inputParameters:
            - name: api_id
              in: body
              type: string
              description: "The MuleSoft Anypoint API instance ID."
          call: "mulesoft-api.get-analytics"
          with:
            api_id: "{{api_id}}"
          outputParameters:
            - name: request_count
              type: number
              mapping: "$.data.requestCount"
            - name: avg_response_time_ms
              type: number
              mapping: "$.data.avgResponseTime"
            - name: error_rate
              type: number
              mapping: "$.data.errorRate"
  consumes:
    - type: http
      namespace: mulesoft-api
      baseUri: "https://anypoint.mulesoft.com/analytics/1.0"
      authentication:
        type: bearer
        token: "$secrets.mulesoft_token"
      resources:
        - name: api-analytics
          path: "/{{api_id}}/events?duration=24h"
          inputParameters:
            - name: api_id
              in: path
          operations:
            - name: get-analytics
              method: GET

When a MuleSoft API version is scheduled for deprecation, identifies active consumers, creates Jira tickets for migration, and notifies impacted teams via Slack.

naftiko: "0.5"
info:
  label: "MuleSoft API Deprecation Notification"
  description: "When a MuleSoft API version is scheduled for deprecation, identifies active consumers, creates Jira tickets for migration, and notifies impacted teams via Slack."
  tags:
    - integration
    - mulesoft
    - jira
    - slack
    - api-management
capability:
  exposes:
    - type: mcp
      namespace: api-deprecation
      port: 8080
      tools:
        - name: notify-deprecation
          description: "Given a MuleSoft API ID being deprecated, identify consumers, create migration tickets, and notify teams."
          inputParameters:
            - name: api_id
              in: body
              type: string
              description: "The MuleSoft API instance ID being deprecated."
            - name: deprecation_date
              in: body
              type: string
              description: "The deprecation date."
            - name: successor_api_id
              in: body
              type: string
              description: "The successor API instance ID."
          steps:
            - name: get-consumers
              type: call
              call: "mulesoft-api.get-contracts"
              with:
                api_id: "{{api_id}}"
            - name: create-migration-ticket
              type: call
              call: "jira-api.create-issue"
              with:
                project: "INTEGRATION"
                issuetype: "Task"
                summary: "[API Migration] {{api_id}} deprecating {{deprecation_date}}"
                description: "API {{api_id}} is being deprecated on {{deprecation_date}}. Migrate to {{successor_api_id}}. Active consumers: {{get-consumers.total}}"
            - name: notify-teams
              type: call
              call: "slack-api.post-message"
              with:
                channel: "api-platform"
                text: "API Deprecation: {{api_id}} retiring {{deprecation_date}} | Consumers: {{get-consumers.total}} | Migrate to: {{successor_api_id}} | Jira: {{create-migration-ticket.key}}"
  consumes:
    - type: http
      namespace: mulesoft-api
      baseUri: "https://anypoint.mulesoft.com/apimanager/api/v1"
      authentication:
        type: bearer
        token: "$secrets.mulesoft_token"
      resources:
        - name: contracts
          path: "/organizations/$secrets.mulesoft_org_id/environments/$secrets.mulesoft_env_id/apis/{{api_id}}/contracts"
          inputParameters:
            - name: api_id
              in: path
          operations:
            - name: get-contracts
              method: GET
    - type: http
      namespace: jira-api
      baseUri: "https://salesforce.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a new employee is created in Workday, provisions Okta SSO, sends a Slack welcome message, and opens a Jira onboarding task for IT setup.

naftiko: "0.5"
info:
  label: "New Hire Onboarding Orchestrator"
  description: "When a new employee is created in Workday, provisions Okta SSO, sends a Slack welcome message, and opens a Jira onboarding task for IT setup."
  tags:
    - hr
    - onboarding
    - workday
    - okta
    - slack
    - jira
capability:
  exposes:
    - type: mcp
      namespace: hr-onboarding
      port: 8080
      tools:
        - name: trigger-onboarding
          description: "Given a Workday employee ID and start date, orchestrate the full onboarding sequence: provision Okta identity, send a Slack welcome, and open a Jira IT setup task."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "The Workday worker ID for the new hire."
            - name: start_date
              in: body
              type: string
              description: "The employee's start date in YYYY-MM-DD format."
            - name: team_name
              in: body
              type: string
              description: "The team the new hire is joining."
          steps:
            - name: get-employee
              type: call
              call: "workday.get-worker"
              with:
                worker_id: "{{employee_id}}"
            - name: provision-okta
              type: call
              call: "okta.create-user"
              with:
                firstName: "{{get-employee.firstName}}"
                lastName: "{{get-employee.lastName}}"
                email: "{{get-employee.workEmail}}"
                department: "{{get-employee.department}}"
            - name: create-jira-task
              type: call
              call: "jira.create-issue"
              with:
                project_key: "IT"
                issuetype: "Task"
                summary: "IT Setup for new hire: {{get-employee.displayName}}"
                description: "Start date: {{start_date}} | Team: {{team_name}} | Okta ID: {{provision-okta.id}}"
            - name: send-welcome
              type: call
              call: "slack.post-message"
              with:
                channel: "welcome-new-hires"
                text: "Welcome to Salesforce, {{get-employee.firstName}}! We're thrilled to have you join {{team_name}}. Your IT setup ticket is {{create-jira-task.key}}."
  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: "/salesforce/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: okta
      baseUri: "https://salesforce.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_api_token"
        placement: header
      resources:
        - name: users
          path: "/users"
          operations:
            - name: create-user
              method: POST
    - type: http
      namespace: jira
      baseUri: "https://salesforce.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When an employee is terminated, deactivates their Okta account, revokes all application assignments, and logs the action in ServiceNow.

naftiko: "0.5"
info:
  label: "Okta Deactivation and Access Revocation"
  description: "When an employee is terminated, deactivates their Okta account, revokes all application assignments, and logs the action in ServiceNow."
  tags:
    - security
    - okta
    - servicenow
    - offboarding
capability:
  exposes:
    - type: mcp
      namespace: access-revocation
      port: 8080
      tools:
        - name: revoke-access
          description: "Given an Okta user ID for a terminated employee, deactivate the account, remove app assignments, and create a ServiceNow audit record."
          inputParameters:
            - name: user_id
              in: body
              type: string
              description: "The Okta user ID."
            - name: employee_name
              in: body
              type: string
              description: "The employee's display name."
          steps:
            - name: deactivate-user
              type: call
              call: "okta-api.deactivate-user"
              with:
                user_id: "{{user_id}}"
            - name: revoke-apps
              type: call
              call: "okta-api.clear-sessions"
              with:
                user_id: "{{user_id}}"
            - name: log-audit
              type: call
              call: "servicenow-api.create-record"
              with:
                short_description: "Access revoked for {{employee_name}}"
                description: "Okta account {{user_id}} deactivated and all sessions cleared for {{employee_name}}."
                category: "access_management"
  consumes:
    - type: http
      namespace: okta-api
      baseUri: "https://salesforce.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_token"
        placement: header
      resources:
        - name: user-lifecycle
          path: "/users/{{user_id}}/lifecycle/deactivate"
          inputParameters:
            - name: user_id
              in: path
          operations:
            - name: deactivate-user
              method: POST
        - name: user-sessions
          path: "/users/{{user_id}}/sessions"
          inputParameters:
            - name: user_id
              in: path
          operations:
            - name: clear-sessions
              method: DELETE
    - type: http
      namespace: servicenow-api
      baseUri: "https://salesforce.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: audit-records
          path: "/table/incident"
          operations:
            - name: create-record
              method: POST

When a user requests an MFA reset, verifies identity via Workday, resets MFA factors in Okta, sends confirmation via Slack, and logs in ServiceNow.

naftiko: "0.5"
info:
  label: "Okta MFA Reset Workflow"
  description: "When a user requests an MFA reset, verifies identity via Workday, resets MFA factors in Okta, sends confirmation via Slack, and logs in ServiceNow."
  tags:
    - security
    - okta
    - workday
    - slack
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: mfa-reset
      port: 8080
      tools:
        - name: reset-mfa
          description: "Given a user email requesting MFA reset, verify identity, reset factors, confirm via Slack, and log in ServiceNow."
          inputParameters:
            - name: user_email
              in: body
              type: string
              description: "The user's email address."
            - name: ticket_number
              in: body
              type: string
              description: "The support ticket number."
          steps:
            - name: verify-identity
              type: call
              call: "workday-api.get-worker-by-email"
              with:
                email: "{{user_email}}"
            - name: reset-factors
              type: call
              call: "okta-api.reset-factors"
              with:
                email: "{{user_email}}"
            - name: confirm-user
              type: call
              call: "slack-api.post-message"
              with:
                channel: "it-helpdesk"
                text: "MFA reset completed for {{user_email}} ({{verify-identity.name}}) | Ticket: {{ticket_number}}"
            - name: log-event
              type: call
              call: "servicenow-api.update-ticket"
              with:
                ticket_number: "{{ticket_number}}"
                work_notes: "MFA factors reset for {{user_email}}. Identity verified via Workday."
  consumes:
    - type: http
      namespace: workday-api
      baseUri: "https://wd5-services1.myworkday.com/ccx/service/salesforce"
      authentication:
        type: basic
        username: "$secrets.workday_user"
        password: "$secrets.workday_password"
      resources:
        - name: workers
          path: "/Human_Resources/v40.1/workers?email={{email}}"
          inputParameters:
            - name: email
              in: path
          operations:
            - name: get-worker-by-email
              method: GET
    - type: http
      namespace: okta-api
      baseUri: "https://salesforce.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_token"
        placement: header
      resources:
        - name: factors
          path: "/users/{{email}}/lifecycle/reset_factors"
          inputParameters:
            - name: email
              in: path
          operations:
            - name: reset-factors
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST
    - type: http
      namespace: servicenow-api
      baseUri: "https://salesforce.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tickets
          path: "/table/incident?sysparm_query=number={{ticket_number}}"
          inputParameters:
            - name: ticket_number
              in: path
          operations:
            - name: update-ticket
              method: PATCH

When Okta detects a suspicious login event, creates a Jira security incident and notifies the security operations Slack channel for immediate investigation.

naftiko: "0.5"
info:
  label: "Okta Suspicious Login Alert"
  description: "When Okta detects a suspicious login event, creates a Jira security incident and notifies the security operations Slack channel for immediate investigation."
  tags:
    - security
    - okta
    - jira
    - slack
    - identity
    - incident-response
capability:
  exposes:
    - type: mcp
      namespace: security-identity
      port: 8080
      tools:
        - name: handle-suspicious-login
          description: "Given an Okta user ID and suspicious event type, retrieve the event details, create a Jira security incident, and alert the SOC in Slack."
          inputParameters:
            - name: okta_user_id
              in: body
              type: string
              description: "The Okta user ID associated with the suspicious login."
            - name: event_type
              in: body
              type: string
              description: "The Okta system log event type (e.g., user.session.start)."
            - name: ip_address
              in: body
              type: string
              description: "The IP address of the suspicious login attempt."
          steps:
            - name: get-user
              type: call
              call: "okta-sec.get-user"
              with:
                userId: "{{okta_user_id}}"
            - name: create-incident
              type: call
              call: "jira-login.create-issue"
              with:
                project_key: "SEC"
                issuetype: "Security Incident"
                summary: "Suspicious login: {{get-user.login}} from {{ip_address}}"
                description: "User: {{get-user.login}}\nEvent: {{event_type}}\nIP: {{ip_address}}"
            - name: alert-soc
              type: call
              call: "slack-login.post-message"
              with:
                channel: "security-ops"
                text: "Suspicious login detected for {{get-user.login}} from {{ip_address}} ({{event_type}}) | Jira: {{create-incident.key}}"
  consumes:
    - type: http
      namespace: okta-sec
      baseUri: "https://salesforce.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_api_token"
        placement: header
      resources:
        - name: users
          path: "/users/{{userId}}"
          inputParameters:
            - name: userId
              in: path
          operations:
            - name: get-user
              method: GET
    - type: http
      namespace: jira-login
      baseUri: "https://salesforce.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-login
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Assigns a new Okta user to the appropriate application groups based on their Workday department and role, ensuring correct SSO access from day one.

naftiko: "0.5"
info:
  label: "Okta User Group Provisioning"
  description: "Assigns a new Okta user to the appropriate application groups based on their Workday department and role, ensuring correct SSO access from day one."
  tags:
    - identity
    - okta
    - workday
    - access-management
    - hr
capability:
  exposes:
    - type: mcp
      namespace: identity-provisioning
      port: 8080
      tools:
        - name: assign-okta-groups
          description: "Given a Workday employee ID and their department, assign the Okta user to the appropriate application access groups based on role profile."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "The Workday worker ID for the employee."
            - name: department
              in: body
              type: string
              description: "The employee's department name used to determine group assignments."
          steps:
            - name: get-employee
              type: call
              call: "workday-grp.get-worker"
              with:
                worker_id: "{{employee_id}}"
            - name: add-to-group
              type: call
              call: "okta-grp.add-user-to-group"
              with:
                userId: "{{get-employee.oktaId}}"
                groupId: "{{get-employee.defaultGroupId}}"
  consumes:
    - type: http
      namespace: workday-grp
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/salesforce/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: okta-grp
      baseUri: "https://salesforce.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_api_token"
        placement: header
      resources:
        - name: group-members
          path: "/groups/{{groupId}}/users/{{userId}}"
          inputParameters:
            - name: groupId
              in: path
            - name: userId
              in: path
          operations:
            - name: add-user-to-group
              method: PUT

Returns the current status and group memberships of an Okta user by email for identity verification.

naftiko: "0.5"
info:
  label: "Okta User Status Lookup"
  description: "Returns the current status and group memberships of an Okta user by email for identity verification."
  tags:
    - security
    - okta
    - identity
capability:
  exposes:
    - type: mcp
      namespace: okta-identity
      port: 8080
      tools:
        - name: get-user-status
          description: "Given a user email, return their Okta status and group memberships. Use for identity verification and access review."
          inputParameters:
            - name: email
              in: body
              type: string
              description: "The user's email address."
          call: "okta-api.get-user"
          with:
            email: "{{email}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.status"
            - name: display_name
              type: string
              mapping: "$.profile.displayName"
            - name: groups
              type: array
              mapping: "$.groups"
  consumes:
    - type: http
      namespace: okta-api
      baseUri: "https://salesforce.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_token"
        placement: header
      resources:
        - name: users
          path: "/users/{{email}}"
          inputParameters:
            - name: email
              in: path
          operations:
            - name: get-user
              method: GET

Returns the current on-call engineer for a PagerDuty escalation policy by service name.

naftiko: "0.5"
info:
  label: "PagerDuty On-Call Lookup"
  description: "Returns the current on-call engineer for a PagerDuty escalation policy by service name."
  tags:
    - operations
    - pagerduty
    - incident-management
capability:
  exposes:
    - type: mcp
      namespace: oncall-lookup
      port: 8080
      tools:
        - name: get-oncall
          description: "Given a PagerDuty service ID, return the current on-call engineer name, email, and escalation level."
          inputParameters:
            - name: service_id
              in: body
              type: string
              description: "The PagerDuty service ID."
          call: "pagerduty-api.get-oncall"
          with:
            service_id: "{{service_id}}"
          outputParameters:
            - name: oncall_name
              type: string
              mapping: "$.oncalls[0].user.name"
            - name: oncall_email
              type: string
              mapping: "$.oncalls[0].user.email"
            - name: escalation_level
              type: number
              mapping: "$.oncalls[0].escalation_level"
  consumes:
    - type: http
      namespace: pagerduty-api
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.pagerduty_token"
        placement: header
      resources:
        - name: oncalls
          path: "/oncalls?service_ids[]={{service_id}}"
          inputParameters:
            - name: service_id
              in: path
          operations:
            - name: get-oncall
              method: GET

Extracts KPI data from a Power BI dataset, updates custom KPI fields in Salesforce accounts, and posts a sync summary to Slack.

naftiko: "0.5"
info:
  label: "Power BI to Salesforce KPI Sync"
  description: "Extracts KPI data from a Power BI dataset, updates custom KPI fields in Salesforce accounts, and posts a sync summary to Slack."
  tags:
    - analytics
    - power-bi
    - salesforce
    - slack
capability:
  exposes:
    - type: mcp
      namespace: kpi-sync
      port: 8080
      tools:
        - name: sync-kpis
          description: "Given a Power BI dataset ID and Salesforce account segment, sync KPI values and notify via Slack."
          inputParameters:
            - name: dataset_id
              in: body
              type: string
              description: "The Power BI dataset ID."
            - name: account_segment
              in: body
              type: string
              description: "The Salesforce account segment to update."
          steps:
            - name: get-kpis
              type: call
              call: "powerbi-api.get-dataset"
              with:
                dataset_id: "{{dataset_id}}"
            - name: update-accounts
              type: call
              call: "sfdc-api.bulk-update"
              with:
                segment: "{{account_segment}}"
                kpi_data: "{{get-kpis.data}}"
            - name: notify-team
              type: call
              call: "slack-api.post-message"
              with:
                channel: "revenue-ops"
                text: "KPI sync complete | Dataset: {{dataset_id}} | Segment: {{account_segment}} | Accounts updated: {{update-accounts.count}}"
  consumes:
    - type: http
      namespace: powerbi-api
      baseUri: "https://api.powerbi.com/v1.0/myorg"
      authentication:
        type: bearer
        token: "$secrets.powerbi_token"
      resources:
        - name: datasets
          path: "/datasets/{{dataset_id}}/executeQueries"
          inputParameters:
            - name: dataset_id
              in: path
          operations:
            - name: get-dataset
              method: POST
    - type: http
      namespace: sfdc-api
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: composite
          path: "/composite/sobjects"
          operations:
            - name: bulk-update
              method: PATCH
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves detailed account information from Salesforce including industry, annual revenue, and owner for quick reference.

naftiko: "0.5"
info:
  label: "Salesforce Account Detail Lookup"
  description: "Retrieves detailed account information from Salesforce including industry, annual revenue, and owner for quick reference."
  tags:
    - crm
    - salesforce
    - account-management
capability:
  exposes:
    - type: mcp
      namespace: sfdc-accounts
      port: 8080
      tools:
        - name: get-account
          description: "Given a Salesforce account ID, return account name, industry, annual revenue, owner, and status. Use for account lookups and pre-call preparation."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The Salesforce account record ID."
          call: "sfdc-account.get-account"
          with:
            account_id: "{{account_id}}"
          outputParameters:
            - name: name
              type: string
              mapping: "$.Name"
            - name: industry
              type: string
              mapping: "$.Industry"
            - name: annual_revenue
              type: string
              mapping: "$.AnnualRevenue"
            - name: owner
              type: string
              mapping: "$.Owner.Name"
  consumes:
    - type: http
      namespace: sfdc-account
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: accounts
          path: "/sobjects/Account/{{account_id}}"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: get-account
              method: GET

Queries Salesforce CRM for account activity signals and updates each account's health score field based on recent case volume and opportunity pipeline.

naftiko: "0.5"
info:
  label: "Salesforce Account Health Score Update"
  description: "Queries Salesforce CRM for account activity signals and updates each account's health score field based on recent case volume and opportunity pipeline."
  tags:
    - crm
    - salesforce
    - customer-success
    - account-management
capability:
  exposes:
    - type: mcp
      namespace: crm-health
      port: 8080
      tools:
        - name: update-account-health
          description: "Given a Salesforce account ID, query recent case activity and open opportunities, compute a health score, and update the account record."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The Salesforce account record ID to update."
          steps:
            - name: get-account
              type: call
              call: "sfdc-health.get-account"
              with:
                account_id: "{{account_id}}"
            - name: get-cases
              type: call
              call: "sfdc-cases.list-cases"
              with:
                account_id: "{{account_id}}"
            - name: update-health-score
              type: call
              call: "sfdc-health.update-account"
              with:
                account_id: "{{account_id}}"
                Health_Score__c: "{{get-cases.healthScore}}"
  consumes:
    - type: http
      namespace: sfdc-health
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: accounts
          path: "/sobjects/Account/{{account_id}}"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: get-account
              method: GET
            - name: update-account
              method: PATCH
    - type: http
      namespace: sfdc-cases
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: cases
          path: "/sobjects/Case"
          operations:
            - name: list-cases
              method: GET

When duplicate accounts are detected, merges records in Salesforce, updates related contacts, and logs the merge in Snowflake for audit.

naftiko: "0.5"
info:
  label: "Salesforce Account Merge Deduplication"
  description: "When duplicate accounts are detected, merges records in Salesforce, updates related contacts, and logs the merge in Snowflake for audit."
  tags:
    - crm
    - salesforce
    - snowflake
    - data-quality
capability:
  exposes:
    - type: mcp
      namespace: account-dedup
      port: 8080
      tools:
        - name: merge-duplicate-accounts
          description: "Given a master and duplicate Salesforce account ID, merge the records and log to Snowflake for audit."
          inputParameters:
            - name: master_account_id
              in: body
              type: string
              description: "The master Salesforce account ID to keep."
            - name: duplicate_account_id
              in: body
              type: string
              description: "The duplicate Salesforce account ID to merge."
          steps:
            - name: get-master
              type: call
              call: "sfdc-api.get-account"
              with:
                account_id: "{{master_account_id}}"
            - name: merge-accounts
              type: call
              call: "sfdc-api.merge-records"
              with:
                master_id: "{{master_account_id}}"
                duplicate_id: "{{duplicate_account_id}}"
            - name: log-merge
              type: call
              call: "snowflake-api.run-query"
              with:
                master_id: "{{master_account_id}}"
                duplicate_id: "{{duplicate_account_id}}"
                master_name: "{{get-master.Name}}"
  consumes:
    - type: http
      namespace: sfdc-api
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: accounts
          path: "/sobjects/Account/{{account_id}}"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: get-account
              method: GET
        - name: merge
          path: "/sobjects/Account/{{master_id}}/merge"
          inputParameters:
            - name: master_id
              in: path
          operations:
            - name: merge-records
              method: POST
    - type: http
      namespace: snowflake-api
      baseUri: "https://salesforce.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST

Returns response rate, ROI, and member count for a Salesforce marketing campaign by campaign ID.

naftiko: "0.5"
info:
  label: "Salesforce Campaign Performance Lookup"
  description: "Returns response rate, ROI, and member count for a Salesforce marketing campaign by campaign ID."
  tags:
    - crm
    - salesforce
    - marketing
capability:
  exposes:
    - type: mcp
      namespace: sfdc-campaigns
      port: 8080
      tools:
        - name: get-campaign-performance
          description: "Given a Salesforce campaign ID, return its response rate, ROI, number of members, and status."
          inputParameters:
            - name: campaign_id
              in: body
              type: string
              description: "The Salesforce campaign record ID."
          call: "sfdc-campaign.get-campaign"
          with:
            campaign_id: "{{campaign_id}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.Status"
            - name: num_responses
              type: number
              mapping: "$.NumberOfResponses"
            - name: amount_won
              type: number
              mapping: "$.AmountWonOpportunities"
            - name: member_count
              type: number
              mapping: "$.NumberOfContacts"
  consumes:
    - type: http
      namespace: sfdc-campaign
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: campaigns
          path: "/sobjects/Campaign/{{campaign_id}}"
          inputParameters:
            - name: campaign_id
              in: path
          operations:
            - name: get-campaign
              method: GET

Returns the current status, priority, owner, and subject of a Salesforce service case by case number.

naftiko: "0.5"
info:
  label: "Salesforce Case Status Lookup"
  description: "Returns the current status, priority, owner, and subject of a Salesforce service case by case number."
  tags:
    - crm
    - salesforce
    - customer-service
capability:
  exposes:
    - type: mcp
      namespace: sfdc-cases
      port: 8080
      tools:
        - name: get-case-status
          description: "Given a Salesforce case number, return the case status, priority, owner, and subject for triage or customer inquiry."
          inputParameters:
            - name: case_number
              in: body
              type: string
              description: "The Salesforce case number."
          call: "sfdc-case.get-case"
          with:
            case_number: "{{case_number}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.Status"
            - name: priority
              type: string
              mapping: "$.Priority"
            - name: owner
              type: string
              mapping: "$.Owner.Name"
            - name: subject
              type: string
              mapping: "$.Subject"
  consumes:
    - type: http
      namespace: sfdc-case
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: cases
          path: "/sobjects/Case/{{case_number}}"
          inputParameters:
            - name: case_number
              in: path
          operations:
            - name: get-case
              method: GET

When a Salesforce support case is escalated as a product bug, creates a Jira bug ticket, links it back to the case, and notifies the engineering team via Slack.

naftiko: "0.5"
info:
  label: "Salesforce Case to Jira Bug"
  description: "When a Salesforce support case is escalated as a product bug, creates a Jira bug ticket, links it back to the case, and notifies the engineering team via Slack."
  tags:
    - crm
    - salesforce
    - jira
    - slack
    - customer-service
capability:
  exposes:
    - type: mcp
      namespace: case-to-bug
      port: 8080
      tools:
        - name: escalate-case-to-bug
          description: "Given a Salesforce case ID marked as a product bug, create a Jira bug, link it to the case, and notify engineering."
          inputParameters:
            - name: case_id
              in: body
              type: string
              description: "The Salesforce case record ID."
          steps:
            - name: get-case
              type: call
              call: "sfdc-case.get-case"
              with:
                case_id: "{{case_id}}"
            - name: create-jira-bug
              type: call
              call: "jira-api.create-issue"
              with:
                project: "PLATFORM"
                issuetype: "Bug"
                summary: "[Customer Bug] {{get-case.Subject}}"
                description: "Salesforce Case: {{case_id}}\nAccount: {{get-case.Account.Name}}\nPriority: {{get-case.Priority}}\n\n{{get-case.Description}}"
            - name: update-case
              type: call
              call: "sfdc-case.update-case"
              with:
                case_id: "{{case_id}}"
                Jira_Bug__c: "{{create-jira-bug.key}}"
            - name: notify-eng
              type: call
              call: "slack-api.post-message"
              with:
                channel: "engineering-bugs"
                text: "New customer bug: {{create-jira-bug.key}} | Case: {{case_id}} | Account: {{get-case.Account.Name}} | Priority: {{get-case.Priority}}"
  consumes:
    - type: http
      namespace: sfdc-case
      baseUri: "https://salesforce.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: jira-api
      baseUri: "https://salesforce.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a competitor is added to a Salesforce opportunity, retrieves competitive intelligence from Snowflake and alerts the sales enablement team via Slack.

naftiko: "0.5"
info:
  label: "Salesforce Competitive Deal Alert"
  description: "When a competitor is added to a Salesforce opportunity, retrieves competitive intelligence from Snowflake and alerts the sales enablement team via Slack."
  tags:
    - crm
    - salesforce
    - snowflake
    - slack
    - competitive-intelligence
capability:
  exposes:
    - type: mcp
      namespace: competitive-alert
      port: 8080
      tools:
        - name: handle-competitor-added
          description: "Given a Salesforce opportunity with a new competitor, retrieve competitive intel and alert the enablement team."
          inputParameters:
            - name: opportunity_id
              in: body
              type: string
              description: "The Salesforce opportunity ID."
            - name: competitor_name
              in: body
              type: string
              description: "The competitor name."
          steps:
            - name: get-opp
              type: call
              call: "sfdc-api.get-opportunity"
              with:
                opportunity_id: "{{opportunity_id}}"
            - name: get-intel
              type: call
              call: "snowflake-api.run-query"
              with:
                competitor: "{{competitor_name}}"
            - name: alert-enablement
              type: call
              call: "slack-api.post-message"
              with:
                channel: "sales-enablement"
                text: "Competitive deal alert: {{get-opp.Name}} (${{get-opp.Amount}}) | Competitor: {{competitor_name}} | Win rate: {{get-intel.data.win_rate}}% | Owner: {{get-opp.Owner.Name}}"
  consumes:
    - type: http
      namespace: sfdc-api
      baseUri: "https://salesforce.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: snowflake-api
      baseUri: "https://salesforce.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Looks up a Salesforce contact by ID and returns name, title, email, and associated account for quick reference.

naftiko: "0.5"
info:
  label: "Salesforce Contact Lookup"
  description: "Looks up a Salesforce contact by ID and returns name, title, email, and associated account for quick reference."
  tags:
    - crm
    - salesforce
    - contacts
capability:
  exposes:
    - type: mcp
      namespace: sfdc-contacts
      port: 8080
      tools:
        - name: get-contact
          description: "Given a Salesforce contact ID, return the contact's name, title, email, and account. Use for pre-meeting briefing or contact verification."
          inputParameters:
            - name: contact_id
              in: body
              type: string
              description: "The Salesforce contact record ID."
          call: "sfdc-contact.get-contact"
          with:
            contact_id: "{{contact_id}}"
          outputParameters:
            - name: name
              type: string
              mapping: "$.Name"
            - name: title
              type: string
              mapping: "$.Title"
            - name: email
              type: string
              mapping: "$.Email"
            - name: account_name
              type: string
              mapping: "$.Account.Name"
  consumes:
    - type: http
      namespace: sfdc-contact
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: contacts
          path: "/sobjects/Contact/{{contact_id}}"
          inputParameters:
            - name: contact_id
              in: path
          operations:
            - name: get-contact
              method: GET

Sixty days before contract expiration, retrieves contract details from Salesforce, creates a renewal opportunity, and notifies the account team via Slack.

naftiko: "0.5"
info:
  label: "Salesforce Contract Renewal Reminder"
  description: "Sixty days before contract expiration, retrieves contract details from Salesforce, creates a renewal opportunity, and notifies the account team via Slack."
  tags:
    - crm
    - salesforce
    - slack
    - renewals
capability:
  exposes:
    - type: mcp
      namespace: contract-renewals
      port: 8080
      tools:
        - name: trigger-renewal-reminder
          description: "Given a Salesforce contract ID approaching expiration, create a renewal opportunity and notify the account team via Slack."
          inputParameters:
            - name: contract_id
              in: body
              type: string
              description: "The Salesforce contract record ID."
          steps:
            - name: get-contract
              type: call
              call: "sfdc-contract.get-contract"
              with:
                contract_id: "{{contract_id}}"
            - name: create-renewal-opp
              type: call
              call: "sfdc-contract.create-opportunity"
              with:
                Name: "Renewal - {{get-contract.Account.Name}}"
                AccountId: "{{get-contract.AccountId}}"
                StageName: "Qualification"
                CloseDate: "{{get-contract.EndDate}}"
            - name: notify-team
              type: call
              call: "slack-api.post-message"
              with:
                channel: "renewals"
                text: "Contract renewal due: {{get-contract.Account.Name}} | Expires: {{get-contract.EndDate}} | Renewal Opp: {{create-renewal-opp.id}}"
  consumes:
    - type: http
      namespace: sfdc-contract
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: contracts
          path: "/sobjects/Contract/{{contract_id}}"
          inputParameters:
            - name: contract_id
              in: path
          operations:
            - name: get-contract
              method: GET
        - name: opportunities
          path: "/sobjects/Opportunity"
          operations:
            - name: create-opportunity
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a CPQ quote exceeds the discount threshold, routes for manager approval, updates the opportunity stage, and notifies deal desk via Slack.

naftiko: "0.5"
info:
  label: "Salesforce CPQ Quote Approval"
  description: "When a CPQ quote exceeds the discount threshold, routes for manager approval, updates the opportunity stage, and notifies deal desk via Slack."
  tags:
    - crm
    - salesforce
    - slack
    - sales
capability:
  exposes:
    - type: mcp
      namespace: cpq-approval
      port: 8080
      tools:
        - name: route-quote-approval
          description: "Given a Salesforce CPQ quote ID with a discount above threshold, route for approval and notify deal desk."
          inputParameters:
            - name: quote_id
              in: body
              type: string
              description: "The Salesforce CPQ quote record ID."
            - name: discount_pct
              in: body
              type: number
              description: "The discount percentage."
          steps:
            - name: get-quote
              type: call
              call: "sfdc-api.get-quote"
              with:
                quote_id: "{{quote_id}}"
            - name: submit-approval
              type: call
              call: "sfdc-api.submit-for-approval"
              with:
                record_id: "{{quote_id}}"
                comments: "Discount of {{discount_pct}}% exceeds threshold. Requires manager approval."
            - name: notify-deal-desk
              type: call
              call: "slack-api.post-message"
              with:
                channel: "deal-desk"
                text: "Quote approval needed: {{get-quote.Name}} | Account: {{get-quote.Account.Name}} | Discount: {{discount_pct}}% | Amount: ${{get-quote.TotalPrice}}"
  consumes:
    - type: http
      namespace: sfdc-api
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: quotes
          path: "/sobjects/SBQQ__Quote__c/{{quote_id}}"
          inputParameters:
            - name: quote_id
              in: path
          operations:
            - name: get-quote
              method: GET
        - name: approvals
          path: "/process/approvals"
          operations:
            - name: submit-for-approval
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a new lead is created in Salesforce CRM, enriches it with ZoomInfo firmographic data and updates the record with company size, industry, and revenue information.

naftiko: "0.5"
info:
  label: "Salesforce CRM Lead Enrichment"
  description: "When a new lead is created in Salesforce CRM, enriches it with ZoomInfo firmographic data and updates the record with company size, industry, and revenue information."
  tags:
    - crm
    - sales
    - salesforce
    - zoominfo
    - lead-enrichment
capability:
  exposes:
    - type: mcp
      namespace: crm-enrichment
      port: 8080
      tools:
        - name: enrich-lead
          description: "Given a Salesforce lead ID, retrieve ZoomInfo firmographic data for the lead's company and update the Salesforce record with enriched details. Use on new lead creation."
          inputParameters:
            - name: lead_id
              in: body
              type: string
              description: "The Salesforce lead record ID to enrich."
          steps:
            - name: get-lead
              type: call
              call: "sfdc-lead.get-lead"
              with:
                lead_id: "{{lead_id}}"
            - name: enrich-company
              type: call
              call: "zoominfo.search-company"
              with:
                companyName: "{{get-lead.Company}}"
                website: "{{get-lead.Website}}"
            - name: update-lead
              type: call
              call: "sfdc-lead.update-lead"
              with:
                lead_id: "{{lead_id}}"
                NumberOfEmployees: "{{enrich-company.employeeCount}}"
                Industry: "{{enrich-company.industry}}"
                AnnualRevenue: "{{enrich-company.revenue}}"
  consumes:
    - type: http
      namespace: sfdc-lead
      baseUri: "https://salesforce.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: zoominfo
      baseUri: "https://api.zoominfo.com/search"
      authentication:
        type: bearer
        token: "$secrets.zoominfo_token"
      resources:
        - name: companies
          path: "/company"
          operations:
            - name: search-company
              method: POST

Returns current status, stage, amount, and account details for a Salesforce CRM opportunity by ID. A quick lookup for agent and human sales review.

naftiko: "0.5"
info:
  label: "Salesforce CRM Opportunity Lookup"
  description: "Returns current status, stage, amount, and account details for a Salesforce CRM opportunity by ID. A quick lookup for agent and human sales review."
  tags:
    - crm
    - sales
    - salesforce
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: crm-lookup
      port: 8080
      tools:
        - name: get-opportunity
          description: "Given a Salesforce opportunity ID, return its current stage, amount, close date, account name, and owner. Use for pre-meeting briefing or opportunity health checks."
          inputParameters:
            - name: opportunity_id
              in: body
              type: string
              description: "The Salesforce opportunity record ID."
          call: "sfdc-lookup.get-opportunity"
          with:
            opp_id: "{{opportunity_id}}"
          outputParameters:
            - name: name
              type: string
              mapping: "$.Name"
            - name: stage
              type: string
              mapping: "$.StageName"
            - name: amount
              type: string
              mapping: "$.Amount"
            - name: close_date
              type: string
              mapping: "$.CloseDate"
            - name: account_name
              type: string
              mapping: "$.Account.Name"
  consumes:
    - type: http
      namespace: sfdc-lookup
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: opportunities
          path: "/sobjects/Opportunity/{{opp_id}}"
          inputParameters:
            - name: opp_id
              in: path
          operations:
            - name: get-opportunity
              method: GET

Enriches a Salesforce account with Snowflake usage analytics and ZoomInfo firmographic data to build a complete customer profile.

naftiko: "0.5"
info:
  label: "Salesforce Customer 360 Enrichment"
  description: "Enriches a Salesforce account with Snowflake usage analytics and ZoomInfo firmographic data to build a complete customer profile."
  tags:
    - crm
    - salesforce
    - snowflake
    - zoominfo
    - customer-success
capability:
  exposes:
    - type: mcp
      namespace: customer-360
      port: 8080
      tools:
        - name: enrich-customer-360
          description: "Given a Salesforce account ID, pull usage data from Snowflake, firmographics from ZoomInfo, and update the account profile."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The Salesforce account record ID."
          steps:
            - name: get-account
              type: call
              call: "sfdc-api.get-account"
              with:
                account_id: "{{account_id}}"
            - name: get-usage
              type: call
              call: "snowflake-api.run-query"
              with:
                account_id: "{{account_id}}"
            - name: get-firmographics
              type: call
              call: "zoominfo-api.search-company"
              with:
                companyName: "{{get-account.Name}}"
            - name: update-account
              type: call
              call: "sfdc-api.update-account"
              with:
                account_id: "{{account_id}}"
                Usage_Score__c: "{{get-usage.data.usage_score}}"
                Industry: "{{get-firmographics.industry}}"
                NumberOfEmployees: "{{get-firmographics.employeeCount}}"
  consumes:
    - type: http
      namespace: sfdc-api
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: accounts
          path: "/sobjects/Account/{{account_id}}"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: get-account
              method: GET
            - name: update-account
              method: PATCH
    - type: http
      namespace: snowflake-api
      baseUri: "https://salesforce.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: zoominfo-api
      baseUri: "https://api.zoominfo.com/search"
      authentication:
        type: bearer
        token: "$secrets.zoominfo_token"
      resources:
        - name: companies
          path: "/company"
          operations:
            - name: search-company
              method: POST

When a new audience segment is created in Data Cloud, activates it in Marketing Cloud, triggers a campaign, and reports activation metrics to Slack.

naftiko: "0.5"
info:
  label: "Salesforce Data Cloud Segment Activation"
  description: "When a new audience segment is created in Data Cloud, activates it in Marketing Cloud, triggers a campaign, and reports activation metrics to Slack."
  tags:
    - crm
    - salesforce
    - salesforce-marketing-cloud
    - slack
    - marketing
capability:
  exposes:
    - type: mcp
      namespace: segment-activation
      port: 8080
      tools:
        - name: activate-segment
          description: "Given a Data Cloud segment ID, activate in Marketing Cloud, trigger the campaign, and report to Slack."
          inputParameters:
            - name: segment_id
              in: body
              type: string
              description: "The Data Cloud segment ID."
            - name: campaign_name
              in: body
              type: string
              description: "The Marketing Cloud campaign name."
          steps:
            - name: get-segment
              type: call
              call: "sfdc-api.get-segment"
              with:
                segment_id: "{{segment_id}}"
            - name: activate-mc
              type: call
              call: "mc-api.activate-audience"
              with:
                segment_id: "{{segment_id}}"
                campaign_name: "{{campaign_name}}"
            - name: report-activation
              type: call
              call: "slack-api.post-message"
              with:
                channel: "marketing-ops"
                text: "Segment activated: {{segment_id}} | Audience: {{get-segment.memberCount}} | Campaign: {{campaign_name}} | Status: {{activate-mc.status}}"
  consumes:
    - type: http
      namespace: sfdc-api
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: segments
          path: "/connect/cdp/segments/{{segment_id}}"
          inputParameters:
            - name: segment_id
              in: path
          operations:
            - name: get-segment
              method: GET
    - type: http
      namespace: mc-api
      baseUri: "https://mcapi.salesforce.com/v1"
      authentication:
        type: bearer
        token: "$secrets.marketing_cloud_token"
      resources:
        - name: activations
          path: "/audiences/activate"
          operations:
            - name: activate-audience
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Triggers a Salesforce Analytics (Einstein) dataset refresh and notifies the sales operations team in Slack when the dashboard is ready.

naftiko: "0.5"
info:
  label: "Salesforce Einstein Analytics Dashboard Refresh"
  description: "Triggers a Salesforce Analytics (Einstein) dataset refresh and notifies the sales operations team in Slack when the dashboard is ready."
  tags:
    - analytics
    - salesforce
    - slack
    - reporting
    - sales-ops
capability:
  exposes:
    - type: mcp
      namespace: analytics-reporting
      port: 8080
      tools:
        - name: refresh-analytics-dataset
          description: "Trigger a Salesforce Analytics dataset refresh by dataset ID and notify the sales ops Slack channel when complete."
          inputParameters:
            - name: dataset_id
              in: body
              type: string
              description: "The Salesforce Analytics dataset API name or ID to refresh."
            - name: slack_channel
              in: body
              type: string
              description: "The Slack channel to notify on completion."
          steps:
            - name: trigger-refresh
              type: call
              call: "sfdc-analytics.refresh-dataset"
              with:
                dataset_id: "{{dataset_id}}"
            - name: notify-sales-ops
              type: call
              call: "slack-analytics.post-message"
              with:
                channel: "{{slack_channel}}"
                text: "Salesforce Analytics dataset {{dataset_id}} refresh has been triggered. Check back shortly for updated data."
  consumes:
    - type: http
      namespace: sfdc-analytics
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: dataset-jobs
          path: "/wave/dataflowjobs"
          operations:
            - name: refresh-dataset
              method: POST
    - type: http
      namespace: slack-analytics
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When an Einstein Bot conversation exceeds the frustration threshold, transfers to a live agent, creates a Salesforce case, and logs the interaction in Snowflake.

naftiko: "0.5"
info:
  label: "Salesforce Einstein Bot Escalation"
  description: "When an Einstein Bot conversation exceeds the frustration threshold, transfers to a live agent, creates a Salesforce case, and logs the interaction in Snowflake."
  tags:
    - crm
    - salesforce
    - salesforce-einstein
    - snowflake
    - customer-service
capability:
  exposes:
    - type: mcp
      namespace: bot-escalation
      port: 8080
      tools:
        - name: escalate-bot-conversation
          description: "Given a bot conversation ID with high frustration, escalate to live agent, create a case, and log the interaction."
          inputParameters:
            - name: conversation_id
              in: body
              type: string
              description: "The Einstein Bot conversation ID."
            - name: customer_id
              in: body
              type: string
              description: "The Salesforce contact ID."
            - name: frustration_score
              in: body
              type: number
              description: "The customer frustration score."
          steps:
            - name: get-conversation
              type: call
              call: "sfdc-api.get-conversation"
              with:
                conversation_id: "{{conversation_id}}"
            - name: create-case
              type: call
              call: "sfdc-api.create-case"
              with:
                ContactId: "{{customer_id}}"
                Subject: "Bot escalation — frustration score {{frustration_score}}"
                Priority: "High"
            - name: log-interaction
              type: call
              call: "snowflake-api.run-query"
              with:
                conversation_id: "{{conversation_id}}"
                frustration_score: "{{frustration_score}}"
  consumes:
    - type: http
      namespace: sfdc-api
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: conversations
          path: "/connect/conversations/{{conversation_id}}"
          inputParameters:
            - name: conversation_id
              in: path
          operations:
            - name: get-conversation
              method: GET
        - name: cases
          path: "/sobjects/Case"
          operations:
            - name: create-case
              method: POST
    - type: http
      namespace: snowflake-api
      baseUri: "https://salesforce.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST

Returns the Einstein prediction score and factors for a given Salesforce record for AI-driven decision support.

naftiko: "0.5"
info:
  label: "Salesforce Einstein Prediction Lookup"
  description: "Returns the Einstein prediction score and factors for a given Salesforce record for AI-driven decision support."
  tags:
    - crm
    - salesforce
    - salesforce-einstein
    - ai
capability:
  exposes:
    - type: mcp
      namespace: einstein-predictions
      port: 8080
      tools:
        - name: get-prediction
          description: "Given a Salesforce record ID and prediction definition ID, return the Einstein prediction score and contributing factors."
          inputParameters:
            - name: record_id
              in: body
              type: string
              description: "The Salesforce record ID to predict on."
            - name: prediction_id
              in: body
              type: string
              description: "The Einstein prediction definition ID."
          call: "einstein-api.get-prediction"
          with:
            record_id: "{{record_id}}"
            prediction_id: "{{prediction_id}}"
          outputParameters:
            - name: score
              type: number
              mapping: "$.prediction.score"
            - name: factors
              type: array
              mapping: "$.prediction.factors"
  consumes:
    - type: http
      namespace: einstein-api
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0/smartdatadiscovery"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: predictions
          path: "/predict"
          operations:
            - name: get-prediction
              method: POST

When a new event registration is received, creates a Salesforce campaign member, sends a confirmation via email, and posts registration stats to Slack.

naftiko: "0.5"
info:
  label: "Salesforce Event Registration Processor"
  description: "When a new event registration is received, creates a Salesforce campaign member, sends a confirmation via email, and posts registration stats to Slack."
  tags:
    - crm
    - salesforce
    - slack
    - events
capability:
  exposes:
    - type: mcp
      namespace: event-registration
      port: 8080
      tools:
        - name: process-registration
          description: "Given an event registration, create a campaign member in Salesforce and post stats to Slack."
          inputParameters:
            - name: contact_id
              in: body
              type: string
              description: "The Salesforce contact ID."
            - name: campaign_id
              in: body
              type: string
              description: "The Salesforce campaign ID for the event."
          steps:
            - name: get-contact
              type: call
              call: "sfdc-api.get-contact"
              with:
                contact_id: "{{contact_id}}"
            - name: add-member
              type: call
              call: "sfdc-api.create-campaign-member"
              with:
                CampaignId: "{{campaign_id}}"
                ContactId: "{{contact_id}}"
                Status: "Registered"
            - name: post-stats
              type: call
              call: "slack-api.post-message"
              with:
                channel: "events-team"
                text: "New registration: {{get-contact.Name}} ({{get-contact.Account.Name}}) for campaign {{campaign_id}}"
  consumes:
    - type: http
      namespace: sfdc-api
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: contacts
          path: "/sobjects/Contact/{{contact_id}}"
          inputParameters:
            - name: contact_id
              in: path
          operations:
            - name: get-contact
              method: GET
        - name: campaign-members
          path: "/sobjects/CampaignMember"
          operations:
            - name: create-campaign-member
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When community engagement drops below threshold, queries analytics from Snowflake, creates a Salesforce task for the community manager, and notifies via Slack.

naftiko: "0.5"
info:
  label: "Salesforce Experience Cloud Community Alert"
  description: "When community engagement drops below threshold, queries analytics from Snowflake, creates a Salesforce task for the community manager, and notifies via Slack."
  tags:
    - crm
    - salesforce
    - salesforce-experience-cloud
    - snowflake
    - slack
capability:
  exposes:
    - type: mcp
      namespace: community-alert
      port: 8080
      tools:
        - name: handle-engagement-drop
          description: "Given a community engagement drop alert, query analytics, create a follow-up task, and notify the community team."
          inputParameters:
            - name: community_id
              in: body
              type: string
              description: "The Experience Cloud community ID."
            - name: current_engagement
              in: body
              type: number
              description: "Current engagement score."
          steps:
            - name: query-analytics
              type: call
              call: "snowflake-api.run-query"
              with:
                community_id: "{{community_id}}"
            - name: create-task
              type: call
              call: "sfdc-api.create-task"
              with:
                Subject: "Community engagement drop: {{community_id}}"
                Priority: "High"
            - name: notify-team
              type: call
              call: "slack-api.post-message"
              with:
                channel: "community-ops"
                text: "Engagement drop: community {{community_id}} at {{current_engagement}} | Task: {{create-task.id}}"
  consumes:
    - type: http
      namespace: snowflake-api
      baseUri: "https://salesforce.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: sfdc-api
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: tasks
          path: "/sobjects/Task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

At the end of each quarter, aggregates opportunity data from Salesforce, generates a forecast summary in Snowflake, and posts the forecast to Slack.

naftiko: "0.5"
info:
  label: "Salesforce Forecast Submission Automation"
  description: "At the end of each quarter, aggregates opportunity data from Salesforce, generates a forecast summary in Snowflake, and posts the forecast to Slack."
  tags:
    - crm
    - salesforce
    - snowflake
    - slack
    - sales-analytics
capability:
  exposes:
    - type: mcp
      namespace: forecast-automation
      port: 8080
      tools:
        - name: generate-forecast
          description: "Given a fiscal quarter, aggregate opportunity data, generate a forecast summary, and post to Slack."
          inputParameters:
            - name: fiscal_quarter
              in: body
              type: string
              description: "The fiscal quarter (e.g., FY24Q4)."
          steps:
            - name: get-forecast-data
              type: call
              call: "snowflake-api.run-query"
              with:
                fiscal_quarter: "{{fiscal_quarter}}"
            - name: update-forecast
              type: call
              call: "sfdc-api.update-forecast"
              with:
                quarter: "{{fiscal_quarter}}"
                commit: "{{get-forecast-data.data.commit}}"
            - name: post-forecast
              type: call
              call: "slack-api.post-message"
              with:
                channel: "sales-leadership"
                text: "Forecast {{fiscal_quarter}} | Commit: ${{get-forecast-data.data.commit}} | Best Case: ${{get-forecast-data.data.best_case}} | Pipeline: ${{get-forecast-data.data.pipeline}}"
  consumes:
    - type: http
      namespace: snowflake-api
      baseUri: "https://salesforce.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: sfdc-api
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: forecasts
          path: "/sobjects/ForecastingItem"
          operations:
            - name: update-forecast
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Searches Salesforce Knowledge articles by keyword and returns the top matching article title, summary, and URL.

naftiko: "0.5"
info:
  label: "Salesforce Knowledge Article Search"
  description: "Searches Salesforce Knowledge articles by keyword and returns the top matching article title, summary, and URL."
  tags:
    - crm
    - salesforce
    - knowledge-base
capability:
  exposes:
    - type: mcp
      namespace: sfdc-knowledge
      port: 8080
      tools:
        - name: search-articles
          description: "Given a search keyword, return matching Salesforce Knowledge articles with title, summary, and URL. Use for support agent assist."
          inputParameters:
            - name: query
              in: body
              type: string
              description: "The search keyword or phrase."
          call: "sfdc-kb.search"
          with:
            query: "{{query}}"
          outputParameters:
            - name: articles
              type: array
              mapping: "$.searchRecords"
  consumes:
    - type: http
      namespace: sfdc-kb
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: search
          path: "/search?q=FIND+{{query}}+IN+ALL+FIELDS+RETURNING+KnowledgeArticleVersion"
          inputParameters:
            - name: query
              in: path
          operations:
            - name: search
              method: GET

Analyzes Salesforce case subjects against Knowledge articles to identify content gaps, creates Jira content tasks, and reports findings to Slack.

naftiko: "0.5"
info:
  label: "Salesforce Knowledge Gap Analyzer"
  description: "Analyzes Salesforce case subjects against Knowledge articles to identify content gaps, creates Jira content tasks, and reports findings to Slack."
  tags:
    - crm
    - salesforce
    - jira
    - slack
    - knowledge-base
capability:
  exposes:
    - type: mcp
      namespace: knowledge-gap
      port: 8080
      tools:
        - name: analyze-gaps
          description: "Given a date range, analyze case subjects vs. Knowledge articles to find gaps, create content tasks, and notify."
          inputParameters:
            - name: date_from
              in: body
              type: string
              description: "Start date for analysis."
            - name: date_to
              in: body
              type: string
              description: "End date for analysis."
          steps:
            - name: query-gaps
              type: call
              call: "snowflake-api.run-query"
              with:
                date_from: "{{date_from}}"
                date_to: "{{date_to}}"
            - name: create-task
              type: call
              call: "jira-api.create-issue"
              with:
                project: "CONTENT"
                issuetype: "Task"
                summary: "[KB Gap] {{query-gaps.data.top_gap_topic}} — {{query-gaps.data.case_count}} cases without articles"
            - name: notify-team
              type: call
              call: "slack-api.post-message"
              with:
                channel: "knowledge-management"
                text: "Knowledge gap found: {{query-gaps.data.top_gap_topic}} | Cases: {{query-gaps.data.case_count}} | Jira: {{create-task.key}}"
  consumes:
    - type: http
      namespace: snowflake-api
      baseUri: "https://salesforce.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: jira-api
      baseUri: "https://salesforce.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a new inbound lead is created, determines the next available rep using round-robin logic, assigns the lead, and notifies the rep via Slack.

naftiko: "0.5"
info:
  label: "Salesforce Lead Routing Round Robin"
  description: "When a new inbound lead is created, determines the next available rep using round-robin logic, assigns the lead, and notifies the rep via Slack."
  tags:
    - crm
    - salesforce
    - slack
    - lead-management
capability:
  exposes:
    - type: mcp
      namespace: lead-routing
      port: 8080
      tools:
        - name: route-lead
          description: "Given a new Salesforce lead ID, determine the next rep via round-robin, assign the lead, and notify the rep."
          inputParameters:
            - name: lead_id
              in: body
              type: string
              description: "The Salesforce lead record ID."
            - name: territory
              in: body
              type: string
              description: "The territory for routing."
          steps:
            - name: get-lead
              type: call
              call: "sfdc-api.get-lead"
              with:
                lead_id: "{{lead_id}}"
            - name: get-next-rep
              type: call
              call: "snowflake-api.run-query"
              with:
                territory: "{{territory}}"
            - name: assign-lead
              type: call
              call: "sfdc-api.update-lead"
              with:
                lead_id: "{{lead_id}}"
                OwnerId: "{{get-next-rep.data.rep_id}}"
            - name: notify-rep
              type: call
              call: "slack-api.post-message"
              with:
                channel: "{{get-next-rep.data.rep_slack_channel}}"
                text: "New lead assigned: {{get-lead.Name}} at {{get-lead.Company}} | Source: {{get-lead.LeadSource}} | Territory: {{territory}}"
  consumes:
    - type: http
      namespace: sfdc-api
      baseUri: "https://salesforce.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: snowflake-api
      baseUri: "https://salesforce.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a Salesforce lead scores above threshold, enriches with ZoomInfo data, qualifies as MQL, assigns to sales rep, and notifies via Slack.

naftiko: "0.5"
info:
  label: "Salesforce Lead to MQL Qualification"
  description: "When a Salesforce lead scores above threshold, enriches with ZoomInfo data, qualifies as MQL, assigns to sales rep, and notifies via Slack."
  tags:
    - crm
    - salesforce
    - zoominfo
    - slack
    - lead-management
capability:
  exposes:
    - type: mcp
      namespace: lead-qualification
      port: 8080
      tools:
        - name: qualify-lead
          description: "Given a Salesforce lead ID with a score above threshold, enrich with ZoomInfo, mark as MQL, assign to a rep, and notify via Slack."
          inputParameters:
            - name: lead_id
              in: body
              type: string
              description: "The Salesforce lead record ID."
            - name: lead_score
              in: body
              type: number
              description: "The current lead score."
          steps:
            - name: get-lead
              type: call
              call: "sfdc-lead.get-lead"
              with:
                lead_id: "{{lead_id}}"
            - name: enrich
              type: call
              call: "zoominfo-api.search-company"
              with:
                companyName: "{{get-lead.Company}}"
            - name: update-lead-mql
              type: call
              call: "sfdc-lead.update-lead"
              with:
                lead_id: "{{lead_id}}"
                Status: "MQL"
                Industry: "{{enrich.industry}}"
                NumberOfEmployees: "{{enrich.employeeCount}}"
            - name: notify-rep
              type: call
              call: "slack-api.post-message"
              with:
                channel: "sales-leads"
                text: "New MQL: {{get-lead.Name}} at {{get-lead.Company}} | Score: {{lead_score}} | Employees: {{enrich.employeeCount}} | Industry: {{enrich.industry}}"
  consumes:
    - type: http
      namespace: sfdc-lead
      baseUri: "https://salesforce.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: zoominfo-api
      baseUri: "https://api.zoominfo.com/search"
      authentication:
        type: bearer
        token: "$secrets.zoominfo_token"
      resources:
        - name: companies
          path: "/company"
          operations:
            - name: search-company
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a GitHub release is published for a Lightning Web Component, deploys to the Salesforce sandbox and notifies the dev team via Slack.

naftiko: "0.5"
info:
  label: "Salesforce Lightning Component Deployment"
  description: "When a GitHub release is published for a Lightning Web Component, deploys to the Salesforce sandbox and notifies the dev team via Slack."
  tags:
    - devops
    - github
    - salesforce
    - salesforce-lightning
    - slack
capability:
  exposes:
    - type: mcp
      namespace: lwc-deploy
      port: 8080
      tools:
        - name: deploy-lwc
          description: "Given a GitHub release tag for a Lightning Web Component, deploy to sandbox and notify the dev team."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "The GitHub repository name."
            - name: release_tag
              in: body
              type: string
              description: "The release tag to deploy."
          steps:
            - name: get-release
              type: call
              call: "github-api.get-release"
              with:
                repo: "{{repo}}"
                tag: "{{release_tag}}"
            - name: deploy-to-sandbox
              type: call
              call: "sfdc-tooling.deploy-metadata"
              with:
                source_url: "{{get-release.zipball_url}}"
            - name: notify-team
              type: call
              call: "slack-api.post-message"
              with:
                channel: "lwc-development"
                text: "LWC Deployed: {{repo}} {{release_tag}} to sandbox | Status: {{deploy-to-sandbox.status}} | Author: {{get-release.author.login}}"
  consumes:
    - type: http
      namespace: github-api
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: releases
          path: "/repos/salesforce/{{repo}}/releases/tags/{{tag}}"
          inputParameters:
            - name: repo
              in: path
            - name: tag
              in: path
          operations:
            - name: get-release
              method: GET
    - type: http
      namespace: sfdc-tooling
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0/tooling"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: deployments
          path: "/sobjects/MetadataContainer"
          operations:
            - name: deploy-metadata
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Syncs campaign engagement data from Salesforce Marketing Cloud to Salesforce CRM, updates campaign member statuses, and posts a performance summary to Slack.

naftiko: "0.5"
info:
  label: "Salesforce Marketing Cloud Campaign Sync"
  description: "Syncs campaign engagement data from Salesforce Marketing Cloud to Salesforce CRM, updates campaign member statuses, and posts a performance summary to Slack."
  tags:
    - crm
    - salesforce
    - salesforce-marketing-cloud
    - slack
    - marketing
capability:
  exposes:
    - type: mcp
      namespace: campaign-sync
      port: 8080
      tools:
        - name: sync-campaign-engagement
          description: "Given a Marketing Cloud campaign ID, sync engagement data to Salesforce CRM and post performance to Slack."
          inputParameters:
            - name: mc_campaign_id
              in: body
              type: string
              description: "The Marketing Cloud campaign ID."
            - name: sfdc_campaign_id
              in: body
              type: string
              description: "The Salesforce CRM campaign ID."
          steps:
            - name: get-mc-metrics
              type: call
              call: "mc-api.get-campaign-metrics"
              with:
                campaign_id: "{{mc_campaign_id}}"
            - name: update-sfdc-campaign
              type: call
              call: "sfdc-api.update-campaign"
              with:
                campaign_id: "{{sfdc_campaign_id}}"
                NumberSent: "{{get-mc-metrics.sentCount}}"
                NumberOfResponses: "{{get-mc-metrics.clickCount}}"
            - name: post-summary
              type: call
              call: "slack-api.post-message"
              with:
                channel: "marketing-ops"
                text: "Campaign sync complete | Sent: {{get-mc-metrics.sentCount}} | Opens: {{get-mc-metrics.openCount}} | Clicks: {{get-mc-metrics.clickCount}}"
  consumes:
    - type: http
      namespace: mc-api
      baseUri: "https://mcapi.salesforce.com/v1"
      authentication:
        type: bearer
        token: "$secrets.marketing_cloud_token"
      resources:
        - name: campaigns
          path: "/campaigns/{{campaign_id}}/metrics"
          inputParameters:
            - name: campaign_id
              in: path
          operations:
            - name: get-campaign-metrics
              method: GET
    - type: http
      namespace: sfdc-api
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: campaigns
          path: "/sobjects/Campaign/{{campaign_id}}"
          inputParameters:
            - name: campaign_id
              in: path
          operations:
            - name: update-campaign
              method: PATCH
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a customer submits a low NPS score, creates a follow-up task in Salesforce, notifies the CSM via Slack, and logs the feedback in Snowflake.

naftiko: "0.5"
info:
  label: "Salesforce NPS Survey Follow-Up"
  description: "When a customer submits a low NPS score, creates a follow-up task in Salesforce, notifies the CSM via Slack, and logs the feedback in Snowflake."
  tags:
    - crm
    - salesforce
    - slack
    - snowflake
    - customer-success
capability:
  exposes:
    - type: mcp
      namespace: nps-followup
      port: 8080
      tools:
        - name: handle-low-nps
          description: "Given a Salesforce account with a low NPS response, create a follow-up task, notify the CSM, and log to Snowflake."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The Salesforce account ID."
            - name: nps_score
              in: body
              type: number
              description: "The NPS score submitted."
            - name: feedback
              in: body
              type: string
              description: "Customer feedback text."
          steps:
            - name: get-account
              type: call
              call: "sfdc-api.get-account"
              with:
                account_id: "{{account_id}}"
            - name: create-task
              type: call
              call: "sfdc-api.create-task"
              with:
                Subject: "NPS Follow-Up: {{get-account.Name}} (Score: {{nps_score}})"
                WhatId: "{{account_id}}"
                Priority: "High"
            - name: notify-csm
              type: call
              call: "slack-api.post-message"
              with:
                channel: "customer-success"
                text: "Low NPS Alert: {{get-account.Name}} scored {{nps_score}} | Feedback: {{feedback}} | Task: {{create-task.id}}"
  consumes:
    - type: http
      namespace: sfdc-api
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: accounts
          path: "/sobjects/Account/{{account_id}}"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: get-account
              method: GET
        - name: tasks
          path: "/sobjects/Task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a Salesforce opportunity moves to Closed Won, posts a celebration to Slack and updates the account health score in Salesforce.

naftiko: "0.5"
info:
  label: "Salesforce Opportunity Close Notification"
  description: "When a Salesforce opportunity moves to Closed Won, posts a celebration to Slack and updates the account health score in Salesforce."
  tags:
    - crm
    - salesforce
    - slack
    - sales
capability:
  exposes:
    - type: mcp
      namespace: deal-close
      port: 8080
      tools:
        - name: handle-closed-won
          description: "Given a Salesforce opportunity ID that has moved to Closed Won, post a deal alert to Slack and update the account health score."
          inputParameters:
            - name: opportunity_id
              in: body
              type: string
              description: "The Salesforce opportunity record ID."
          steps:
            - name: get-opp
              type: call
              call: "sfdc-opp.get-opportunity"
              with:
                opportunity_id: "{{opportunity_id}}"
            - name: post-deal-alert
              type: call
              call: "slack-api.post-message"
              with:
                channel: "deal-wins"
                text: "Closed Won: {{get-opp.Name}} | ${{get-opp.Amount}} | Account: {{get-opp.Account.Name}} | Owner: {{get-opp.Owner.Name}}"
            - name: update-health-score
              type: call
              call: "sfdc-opp.update-account-health"
              with:
                account_id: "{{get-opp.AccountId}}"
                health_score: "95"
  consumes:
    - type: http
      namespace: sfdc-opp
      baseUri: "https://salesforce.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
        - name: account-health
          path: "/sobjects/Account/{{account_id}}"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: update-account-health
              method: PATCH
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Assesses opportunity risk by querying engagement data from Snowflake, updates the risk score in Salesforce, and alerts the sales manager via Slack.

naftiko: "0.5"
info:
  label: "Salesforce Opportunity Risk Assessment"
  description: "Assesses opportunity risk by querying engagement data from Snowflake, updates the risk score in Salesforce, and alerts the sales manager via Slack."
  tags:
    - crm
    - salesforce
    - snowflake
    - slack
    - sales-analytics
capability:
  exposes:
    - type: mcp
      namespace: opp-risk
      port: 8080
      tools:
        - name: assess-opportunity-risk
          description: "Given a Salesforce opportunity ID, query engagement signals from Snowflake, update the risk score, and alert the manager."
          inputParameters:
            - name: opportunity_id
              in: body
              type: string
              description: "The Salesforce opportunity record ID."
          steps:
            - name: get-opp
              type: call
              call: "sfdc-api.get-opportunity"
              with:
                opportunity_id: "{{opportunity_id}}"
            - name: get-engagement
              type: call
              call: "snowflake-api.run-query"
              with:
                opportunity_id: "{{opportunity_id}}"
            - name: update-risk
              type: call
              call: "sfdc-api.update-opportunity"
              with:
                opportunity_id: "{{opportunity_id}}"
                Risk_Score__c: "{{get-engagement.data.risk_score}}"
            - name: alert-manager
              type: call
              call: "slack-api.post-message"
              with:
                channel: "sales-managers"
                text: "At-risk deal: {{get-opp.Name}} (${{get-opp.Amount}}) | Risk score: {{get-engagement.data.risk_score}} | Last activity: {{get-engagement.data.last_activity_days}} days ago"
  consumes:
    - type: http
      namespace: sfdc-api
      baseUri: "https://salesforce.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
            - name: update-opportunity
              method: PATCH
    - type: http
      namespace: snowflake-api
      baseUri: "https://salesforce.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a Salesforce opportunity stage advances to Closed Won, posts a deal alert to the #wins Slack channel with deal value and account details.

naftiko: "0.5"
info:
  label: "Salesforce Opportunity to Slack Deal Alert"
  description: "When a Salesforce opportunity stage advances to Closed Won, posts a deal alert to the #wins Slack channel with deal value and account details."
  tags:
    - crm
    - sales
    - salesforce
    - slack
    - deal-tracking
capability:
  exposes:
    - type: mcp
      namespace: crm-deals
      port: 8080
      tools:
        - name: announce-closed-won
          description: "Given a Salesforce opportunity ID, retrieve deal details and post a formatted Closed Won announcement to the team Slack channel. Use when an opportunity is marked Closed Won."
          inputParameters:
            - name: opportunity_id
              in: body
              type: string
              description: "The Salesforce opportunity record ID."
            - name: slack_channel
              in: body
              type: string
              description: "The Slack channel name to post the deal announcement to."
          steps:
            - name: get-opportunity
              type: call
              call: "sfdc-opp.get-opportunity"
              with:
                opp_id: "{{opportunity_id}}"
            - name: post-announcement
              type: call
              call: "slack-deals.post-message"
              with:
                channel: "{{slack_channel}}"
                text: "Closed Won! {{get-opportunity.Name}} — ${{get-opportunity.Amount}} | Account: {{get-opportunity.AccountName}} | Owner: {{get-opportunity.OwnerName}}"
  consumes:
    - type: http
      namespace: sfdc-opp
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: opportunities
          path: "/sobjects/Opportunity/{{opp_id}}"
          inputParameters:
            - name: opp_id
              in: path
          operations:
            - name: get-opportunity
              method: GET
    - type: http
      namespace: slack-deals
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a new partner agreement is signed, creates a partner community user in Experience Cloud, provisions Okta access, and notifies via Slack.

naftiko: "0.5"
info:
  label: "Salesforce Partner Portal Provisioning"
  description: "When a new partner agreement is signed, creates a partner community user in Experience Cloud, provisions Okta access, and notifies via Slack."
  tags:
    - crm
    - salesforce
    - salesforce-experience-cloud
    - okta
    - slack
capability:
  exposes:
    - type: mcp
      namespace: partner-provisioning
      port: 8080
      tools:
        - name: provision-partner
          description: "Given a Salesforce partner account ID and contact, create a community user, provision Okta access, and send welcome message."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The Salesforce partner account ID."
            - name: contact_id
              in: body
              type: string
              description: "The partner contact ID."
          steps:
            - name: get-contact
              type: call
              call: "sfdc-api.get-contact"
              with:
                contact_id: "{{contact_id}}"
            - name: create-community-user
              type: call
              call: "sfdc-api.create-user"
              with:
                ContactId: "{{contact_id}}"
                ProfileId: "partner_community_user"
                Email: "{{get-contact.Email}}"
            - name: provision-okta
              type: call
              call: "okta-api.create-user"
              with:
                email: "{{get-contact.Email}}"
                firstName: "{{get-contact.FirstName}}"
                lastName: "{{get-contact.LastName}}"
            - name: welcome-message
              type: call
              call: "slack-api.post-message"
              with:
                channel: "partner-operations"
                text: "New partner provisioned: {{get-contact.Name}} from {{account_id}} | Community: {{create-community-user.id}} | Okta: {{provision-okta.id}}"
  consumes:
    - type: http
      namespace: sfdc-api
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: contacts
          path: "/sobjects/Contact/{{contact_id}}"
          inputParameters:
            - name: contact_id
              in: path
          operations:
            - name: get-contact
              method: GET
        - name: users
          path: "/sobjects/User"
          operations:
            - name: create-user
              method: POST
    - type: http
      namespace: okta-api
      baseUri: "https://salesforce.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_token"
        placement: header
      resources:
        - name: users
          path: "/users"
          operations:
            - name: create-user
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Generates a quarterly pipeline summary from Snowflake analytics, formats it as a report, and posts to the Slack sales-leadership channel.

naftiko: "0.5"
info:
  label: "Salesforce Quarterly Pipeline Digest"
  description: "Generates a quarterly pipeline summary from Snowflake analytics, formats it as a report, and posts to the Slack sales-leadership channel."
  tags:
    - crm
    - salesforce
    - snowflake
    - slack
    - sales-analytics
capability:
  exposes:
    - type: mcp
      namespace: pipeline-digest
      port: 8080
      tools:
        - name: generate-pipeline-digest
          description: "Given a fiscal quarter, query Snowflake for pipeline metrics and post a formatted summary to the Slack sales-leadership channel."
          inputParameters:
            - name: fiscal_quarter
              in: body
              type: string
              description: "Fiscal quarter (e.g., FY24Q3)."
          steps:
            - name: query-pipeline
              type: call
              call: "snowflake-pipeline.run-query"
              with:
                fiscal_quarter: "{{fiscal_quarter}}"
            - name: post-digest
              type: call
              call: "slack-api.post-message"
              with:
                channel: "sales-leadership"
                text: "Pipeline Digest {{fiscal_quarter}} | Total: ${{query-pipeline.data.total_pipeline}} | New: ${{query-pipeline.data.new_pipeline}} | Weighted: ${{query-pipeline.data.weighted_pipeline}} | Win Rate: {{query-pipeline.data.win_rate}}%"
  consumes:
    - type: http
      namespace: snowflake-pipeline
      baseUri: "https://salesforce.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Queries Snowflake for renewal pipeline health metrics, updates a Salesforce dashboard dataset, and posts a weekly summary to Slack.

naftiko: "0.5"
info:
  label: "Salesforce Renewal Health Dashboard"
  description: "Queries Snowflake for renewal pipeline health metrics, updates a Salesforce dashboard dataset, and posts a weekly summary to Slack."
  tags:
    - crm
    - salesforce
    - snowflake
    - slack
    - renewals
capability:
  exposes:
    - type: mcp
      namespace: renewal-health
      port: 8080
      tools:
        - name: refresh-renewal-health
          description: "Query renewal health metrics from Snowflake, update the Salesforce dashboard, and post a summary to Slack."
          inputParameters:
            - name: fiscal_quarter
              in: body
              type: string
              description: "The fiscal quarter for the report."
          steps:
            - name: get-metrics
              type: call
              call: "snowflake-api.run-query"
              with:
                fiscal_quarter: "{{fiscal_quarter}}"
            - name: update-dataset
              type: call
              call: "sfdc-api.update-dataset"
              with:
                dataset_name: "Renewal_Health"
                data: "{{get-metrics.data}}"
            - name: post-summary
              type: call
              call: "slack-api.post-message"
              with:
                channel: "customer-success-leadership"
                text: "Renewal Health {{fiscal_quarter}} | Up for renewal: ${{get-metrics.data.total_arr}} | At risk: ${{get-metrics.data.at_risk_arr}} | Renewed: ${{get-metrics.data.renewed_arr}}"
  consumes:
    - type: http
      namespace: snowflake-api
      baseUri: "https://salesforce.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: sfdc-api
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: datasets
          path: "/wave/datasets"
          operations:
            - name: update-dataset
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Queries Snowflake for account distribution metrics, updates territory assignments in Sales Cloud, and notifies affected reps via Slack.

naftiko: "0.5"
info:
  label: "Salesforce Sales Cloud Territory Rebalance"
  description: "Queries Snowflake for account distribution metrics, updates territory assignments in Sales Cloud, and notifies affected reps via Slack."
  tags:
    - crm
    - salesforce
    - salesforce-sales-cloud
    - snowflake
    - slack
capability:
  exposes:
    - type: mcp
      namespace: territory-rebalance
      port: 8080
      tools:
        - name: rebalance-territories
          description: "Given a territory model ID, query distribution metrics, update Sales Cloud assignments, and notify reps."
          inputParameters:
            - name: territory_model_id
              in: body
              type: string
              description: "The Salesforce territory model ID."
          steps:
            - name: get-metrics
              type: call
              call: "snowflake-api.run-query"
              with:
                territory_model_id: "{{territory_model_id}}"
            - name: apply-updates
              type: call
              call: "sfdc-api.update-territories"
              with:
                model_id: "{{territory_model_id}}"
                assignments: "{{get-metrics.data.new_assignments}}"
            - name: notify-reps
              type: call
              call: "slack-api.post-message"
              with:
                channel: "sales-operations"
                text: "Territory rebalance complete for model {{territory_model_id}} | Accounts moved: {{get-metrics.data.accounts_moved}} | Reps affected: {{get-metrics.data.reps_affected}}"
  consumes:
    - type: http
      namespace: snowflake-api
      baseUri: "https://salesforce.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: sfdc-api
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: territories
          path: "/sobjects/Territory2"
          operations:
            - name: update-territories
              method: PATCH
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a Salesforce Service Cloud case is open beyond SLA, escalates it to a senior agent, updates priority to Critical, and notifies the support lead in Slack.

naftiko: "0.5"
info:
  label: "Salesforce Service Case Escalation"
  description: "When a Salesforce Service Cloud case is open beyond SLA, escalates it to a senior agent, updates priority to Critical, and notifies the support lead in Slack."
  tags:
    - crm
    - customer-support
    - salesforce
    - slack
    - sla
    - escalation
capability:
  exposes:
    - type: mcp
      namespace: crm-support
      port: 8080
      tools:
        - name: escalate-overdue-case
          description: "Given a Salesforce case ID and escalation owner email, update the case priority to Critical, reassign it, and alert the support lead in Slack."
          inputParameters:
            - name: case_id
              in: body
              type: string
              description: "The Salesforce case record ID to escalate."
            - name: escalation_owner
              in: body
              type: string
              description: "The Salesforce user ID of the escalation owner."
          steps:
            - name: get-case
              type: call
              call: "sfdc-case.get-case"
              with:
                case_id: "{{case_id}}"
            - name: update-case
              type: call
              call: "sfdc-case.update-case"
              with:
                case_id: "{{case_id}}"
                Priority: "Critical"
                OwnerId: "{{escalation_owner}}"
            - name: notify-lead
              type: call
              call: "slack-support.post-message"
              with:
                channel: "support-escalations"
                text: "Case {{case_id}} escalated to Critical: {{get-case.Subject}} | Customer: {{get-case.AccountName}} | New owner: {{escalation_owner}}"
  consumes:
    - type: http
      namespace: sfdc-case
      baseUri: "https://salesforce.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: slack-support
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a high-priority case is created in Service Cloud, assigns it to the best available agent using Einstein and notifies the support lead in Slack.

naftiko: "0.5"
info:
  label: "Salesforce Service Cloud Case Routing"
  description: "When a high-priority case is created in Service Cloud, assigns it to the best available agent using Einstein and notifies the support lead in Slack."
  tags:
    - crm
    - salesforce
    - salesforce-service-cloud
    - slack
    - customer-service
capability:
  exposes:
    - type: mcp
      namespace: case-routing
      port: 8080
      tools:
        - name: route-high-priority-case
          description: "Given a new high-priority Service Cloud case, use Einstein for agent matching, assign the case, and notify the support lead."
          inputParameters:
            - name: case_id
              in: body
              type: string
              description: "The Salesforce case record ID."
          steps:
            - name: get-case
              type: call
              call: "sfdc-service.get-case"
              with:
                case_id: "{{case_id}}"
            - name: get-best-agent
              type: call
              call: "einstein-api.get-recommendation"
              with:
                case_id: "{{case_id}}"
                skill_required: "{{get-case.Type}}"
            - name: assign-case
              type: call
              call: "sfdc-service.update-case"
              with:
                case_id: "{{case_id}}"
                OwnerId: "{{get-best-agent.agentId}}"
            - name: notify-lead
              type: call
              call: "slack-api.post-message"
              with:
                channel: "support-leads"
                text: "P1 Case routed: {{case_id}} | Subject: {{get-case.Subject}} | Account: {{get-case.Account.Name}} | Assigned to: {{get-best-agent.agentName}}"
  consumes:
    - type: http
      namespace: sfdc-service
      baseUri: "https://salesforce.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: einstein-api
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0/smartdatadiscovery"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: recommendations
          path: "/predict"
          operations:
            - name: get-recommendation
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a Salesforce case approaches SLA breach, escalates to the support manager, creates a PagerDuty incident, and posts an alert to Slack.

naftiko: "0.5"
info:
  label: "Salesforce SLA Breach Escalation"
  description: "When a Salesforce case approaches SLA breach, escalates to the support manager, creates a PagerDuty incident, and posts an alert to Slack."
  tags:
    - crm
    - salesforce
    - pagerduty
    - slack
    - customer-service
capability:
  exposes:
    - type: mcp
      namespace: sla-escalation
      port: 8080
      tools:
        - name: escalate-sla-breach
          description: "Given a Salesforce case approaching SLA breach, escalate via PagerDuty and notify the support team."
          inputParameters:
            - name: case_id
              in: body
              type: string
              description: "The Salesforce case record ID."
            - name: minutes_remaining
              in: body
              type: number
              description: "Minutes remaining until SLA breach."
          steps:
            - name: get-case
              type: call
              call: "sfdc-api.get-case"
              with:
                case_id: "{{case_id}}"
            - name: page-manager
              type: call
              call: "pagerduty-api.create-incident"
              with:
                title: "SLA Breach Imminent: Case {{case_id}} — {{minutes_remaining}} min remaining"
                service_id: "$secrets.pagerduty_support_service_id"
                urgency: "high"
            - name: escalate-case
              type: call
              call: "sfdc-api.update-case"
              with:
                case_id: "{{case_id}}"
                Priority: "Critical"
                Escalated: "true"
            - name: notify-team
              type: call
              call: "slack-api.post-message"
              with:
                channel: "support-escalations"
                text: "SLA Breach Alert: Case {{case_id}} | Account: {{get-case.Account.Name}} | {{minutes_remaining}} min remaining | PD: {{page-manager.incident_url}}"
  consumes:
    - type: http
      namespace: sfdc-api
      baseUri: "https://salesforce.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: pagerduty-api
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.pagerduty_token"
        placement: header
      resources:
        - name: incidents
          path: "/incidents"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When usage analytics in Snowflake indicate a customer is exceeding their current tier, creates an upsell opportunity in Salesforce and notifies the account owner via Slack.

naftiko: "0.5"
info:
  label: "Salesforce Upsell Opportunity Generator"
  description: "When usage analytics in Snowflake indicate a customer is exceeding their current tier, creates an upsell opportunity in Salesforce and notifies the account owner via Slack."
  tags:
    - crm
    - salesforce
    - snowflake
    - slack
    - revenue-growth
capability:
  exposes:
    - type: mcp
      namespace: upsell-generator
      port: 8080
      tools:
        - name: generate-upsell
          description: "Given an account ID with high usage, create an upsell opportunity and notify the account owner."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The Salesforce account ID."
          steps:
            - name: get-usage
              type: call
              call: "snowflake-api.run-query"
              with:
                account_id: "{{account_id}}"
            - name: get-account
              type: call
              call: "sfdc-api.get-account"
              with:
                account_id: "{{account_id}}"
            - name: create-opp
              type: call
              call: "sfdc-api.create-opportunity"
              with:
                Name: "Upsell — {{get-account.Name}}"
                AccountId: "{{account_id}}"
                StageName: "Qualification"
                Type: "Existing Business"
            - name: notify-owner
              type: call
              call: "slack-api.post-message"
              with:
                channel: "account-growth"
                text: "Upsell opportunity created: {{get-account.Name}} | Usage: {{get-usage.data.usage_pct}}% of tier | Opp: {{create-opp.id}}"
  consumes:
    - type: http
      namespace: snowflake-api
      baseUri: "https://salesforce.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: sfdc-api
      baseUri: "https://salesforce.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: accounts
          path: "/sobjects/Account/{{account_id}}"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: get-account
              method: GET
        - name: opportunities
          path: "/sobjects/Opportunity"
          operations:
            - name: create-opportunity
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a ServiceNow change request is submitted, validates the change window, assigns approvers from the CMDB, and notifies the CAB via Slack.

naftiko: "0.5"
info:
  label: "ServiceNow Change Request Approval Workflow"
  description: "When a ServiceNow change request is submitted, validates the change window, assigns approvers from the CMDB, and notifies the CAB via Slack."
  tags:
    - operations
    - servicenow
    - slack
    - change-management
capability:
  exposes:
    - type: mcp
      namespace: change-approval
      port: 8080
      tools:
        - name: process-change-request
          description: "Given a ServiceNow change request number, validate the window, assign approvers, and notify the CAB."
          inputParameters:
            - name: change_number
              in: body
              type: string
              description: "The ServiceNow change request number."
          steps:
            - name: get-change
              type: call
              call: "servicenow-api.get-change"
              with:
                change_number: "{{change_number}}"
            - name: get-ci-owner
              type: call
              call: "servicenow-api.get-ci"
              with:
                ci_id: "{{get-change.cmdb_ci}}"
            - name: assign-approver
              type: call
              call: "servicenow-api.update-change"
              with:
                change_number: "{{change_number}}"
                assigned_to: "{{get-ci-owner.owned_by}}"
            - name: notify-cab
              type: call
              call: "slack-api.post-message"
              with:
                channel: "change-advisory-board"
                text: "Change Request: {{change_number}} | {{get-change.short_description}} | Approver: {{get-ci-owner.owned_by}}"
  consumes:
    - type: http
      namespace: servicenow-api
      baseUri: "https://salesforce.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: changes
          path: "/table/change_request?sysparm_query=number={{change_number}}"
          inputParameters:
            - name: change_number
              in: path
          operations:
            - name: get-change
              method: GET
            - name: update-change
              method: PATCH
        - name: ci
          path: "/table/cmdb_ci/{{ci_id}}"
          inputParameters:
            - name: ci_id
              in: path
          operations:
            - name: get-ci
              method: GET
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Returns the state, priority, assigned group, and short description of a ServiceNow incident by number.

naftiko: "0.5"
info:
  label: "ServiceNow Incident Status Lookup"
  description: "Returns the state, priority, assigned group, and short description of a ServiceNow incident by number."
  tags:
    - operations
    - servicenow
    - incident-management
capability:
  exposes:
    - type: mcp
      namespace: snow-incidents
      port: 8080
      tools:
        - name: get-incident
          description: "Given a ServiceNow incident number, return its state, priority, assignment group, and short description."
          inputParameters:
            - name: incident_number
              in: body
              type: string
              description: "The ServiceNow incident number (e.g., INC0012345)."
          call: "servicenow-api.get-incident"
          with:
            incident_number: "{{incident_number}}"
          outputParameters:
            - name: state
              type: string
              mapping: "$.result.state"
            - name: priority
              type: string
              mapping: "$.result.priority"
            - name: assignment_group
              type: string
              mapping: "$.result.assignment_group.display_value"
            - name: short_description
              type: string
              mapping: "$.result.short_description"
  consumes:
    - type: http
      namespace: servicenow-api
      baseUri: "https://salesforce.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: path
          operations:
            - name: get-incident
              method: GET

Retrieves recent messages from a Slack channel for context gathering and incident timeline review.

naftiko: "0.5"
info:
  label: "Slack Channel History Lookup"
  description: "Retrieves recent messages from a Slack channel for context gathering and incident timeline review."
  tags:
    - communications
    - slack
    - incident-response
capability:
  exposes:
    - type: mcp
      namespace: slack-history
      port: 8080
      tools:
        - name: get-channel-history
          description: "Given a Slack channel ID, return the last 20 messages for context gathering. Use during incident response or decision review."
          inputParameters:
            - name: channel_id
              in: body
              type: string
              description: "The Slack channel ID."
          call: "slack-api.get-history"
          with:
            channel_id: "{{channel_id}}"
          outputParameters:
            - name: messages
              type: array
              mapping: "$.messages"
  consumes:
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: conversations
          path: "/conversations.history?channel={{channel_id}}&limit=20"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: get-history
              method: GET

Generates a weekly Snowflake warehouse cost report, identifies top consumers, creates a Jira optimization task, and posts to Slack.

naftiko: "0.5"
info:
  label: "Snowflake Cost Governance Report"
  description: "Generates a weekly Snowflake warehouse cost report, identifies top consumers, creates a Jira optimization task, and posts to Slack."
  tags:
    - finops
    - snowflake
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: snowflake-costs
      port: 8080
      tools:
        - name: generate-cost-report
          description: "Generate a Snowflake cost governance report, flag over-budget warehouses, create optimization tasks, and post to Slack."
          inputParameters:
            - name: budget_threshold
              in: body
              type: number
              description: "The weekly budget threshold in credits."
          steps:
            - name: get-costs
              type: call
              call: "snowflake-api.run-query"
              with:
                budget_threshold: "{{budget_threshold}}"
            - name: create-task
              type: call
              call: "jira-api.create-issue"
              with:
                project: "FINOPS"
                issuetype: "Task"
                summary: "[Snowflake] Weekly cost review — {{get-costs.data.total_credits}} credits"
                description: "Over budget: {{get-costs.data.over_budget_count}} warehouses"
            - name: post-report
              type: call
              call: "slack-api.post-message"
              with:
                channel: "finops"
                text: "Snowflake Weekly Costs: {{get-costs.data.total_credits}} credits | Over budget: {{get-costs.data.over_budget_count}} warehouses | Jira: {{create-task.key}}"
  consumes:
    - type: http
      namespace: snowflake-api
      baseUri: "https://salesforce.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: jira-api
      baseUri: "https://salesforce.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Queries Snowflake for customer churn metrics by product line and time period.

naftiko: "0.5"
info:
  label: "Snowflake Customer Churn Query"
  description: "Queries Snowflake for customer churn metrics by product line and time period."
  tags:
    - analytics
    - snowflake
    - customer-success
capability:
  exposes:
    - type: mcp
      namespace: churn-analytics
      port: 8080
      tools:
        - name: get-churn-metrics
          description: "Given a product line and time period, return churn rate, at-risk account count, and net retention from Snowflake."
          inputParameters:
            - name: product_line
              in: body
              type: string
              description: "Product line name (e.g., Sales Cloud, Service Cloud)."
            - name: period
              in: body
              type: string
              description: "Time period (e.g., Q3_FY24)."
          call: "snowflake-churn.run-query"
          with:
            product_line: "{{product_line}}"
            period: "{{period}}"
          outputParameters:
            - name: churn_rate
              type: number
              mapping: "$.data[0].churn_rate"
            - name: at_risk_accounts
              type: number
              mapping: "$.data[0].at_risk_count"
            - name: net_retention
              type: number
              mapping: "$.data[0].net_retention_pct"
  consumes:
    - type: http
      namespace: snowflake-churn
      baseUri: "https://salesforce.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST

Queries Snowflake task execution history for failures in the last 24 hours and posts a pipeline health digest to the data engineering Slack channel.

naftiko: "0.5"
info:
  label: "Snowflake Data Pipeline Monitoring"
  description: "Queries Snowflake task execution history for failures in the last 24 hours and posts a pipeline health digest to the data engineering Slack channel."
  tags:
    - data
    - snowflake
    - slack
    - monitoring
    - analytics
capability:
  exposes:
    - type: mcp
      namespace: data-ops
      port: 8080
      tools:
        - name: check-pipeline-health
          description: "Query Snowflake task history for any failed or overdue pipeline steps in the past 24 hours and post a health summary to the data engineering Slack channel."
          inputParameters:
            - name: database
              in: body
              type: string
              description: "The Snowflake database to check pipeline health for."
            - name: hours_back
              in: body
              type: integer
              description: "Number of hours of history to check (e.g., 24)."
          steps:
            - name: get-task-history
              type: call
              call: "snowflake-ops.query-task-history"
              with:
                database: "{{database}}"
                hoursBack: "{{hours_back}}"
            - name: post-summary
              type: call
              call: "slack-data.post-message"
              with:
                channel: "data-engineering"
                text: "Snowflake pipeline health for {{database}} (last {{hours_back}}h): {{get-task-history.summary}}"
  consumes:
    - type: http
      namespace: snowflake-ops
      baseUri: "https://salesforce.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: task-history
          path: "/databases/{{database}}/tasks/history"
          inputParameters:
            - name: database
              in: path
          operations:
            - name: query-task-history
              method: GET
    - type: http
      namespace: slack-data
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a Snowflake data quality check fails, creates a Jira ticket for the data engineering team and posts alert details to Slack.

naftiko: "0.5"
info:
  label: "Snowflake Data Quality Alert Handler"
  description: "When a Snowflake data quality check fails, creates a Jira ticket for the data engineering team and posts alert details to Slack."
  tags:
    - data-engineering
    - snowflake
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: dq-alert
      port: 8080
      tools:
        - name: handle-dq-failure
          description: "Given a failed Snowflake data quality check, create a Jira ticket and alert the data engineering team via Slack."
          inputParameters:
            - name: table_name
              in: body
              type: string
              description: "The Snowflake table that failed the quality check."
            - name: check_name
              in: body
              type: string
              description: "Name of the data quality check."
            - name: failure_details
              in: body
              type: string
              description: "Details about the failure."
          steps:
            - name: create-ticket
              type: call
              call: "jira-api.create-issue"
              with:
                project: "DATA"
                issuetype: "Bug"
                summary: "[DQ Failure] {{check_name}} on {{table_name}}"
                description: "Data quality check failed.\nTable: {{table_name}}\nCheck: {{check_name}}\nDetails: {{failure_details}}"
            - name: alert-team
              type: call
              call: "slack-api.post-message"
              with:
                channel: "data-engineering"
                text: "DQ Alert: {{check_name}} failed on {{table_name}} | Jira: {{create-ticket.key}} | {{failure_details}}"
  consumes:
    - type: http
      namespace: jira-api
      baseUri: "https://salesforce.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Returns the status and row counts for a Snowflake data pipeline task execution.

naftiko: "0.5"
info:
  label: "Snowflake Pipeline Execution Status"
  description: "Returns the status and row counts for a Snowflake data pipeline task execution."
  tags:
    - data-engineering
    - snowflake
    - pipelines
capability:
  exposes:
    - type: mcp
      namespace: pipeline-status
      port: 8080
      tools:
        - name: get-task-status
          description: "Given a Snowflake task name, return the last execution status, rows processed, and completion time."
          inputParameters:
            - name: task_name
              in: body
              type: string
              description: "The Snowflake task name."
          call: "snowflake-tasks.get-task-history"
          with:
            task_name: "{{task_name}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.data[0].state"
            - name: rows_processed
              type: number
              mapping: "$.data[0].rows_produced"
            - name: completed_at
              type: string
              mapping: "$.data[0].completed_time"
  consumes:
    - type: http
      namespace: snowflake-tasks
      baseUri: "https://salesforce.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: get-task-history
              method: POST

Queries Snowflake for quarterly revenue breakdown by region for financial reporting.

naftiko: "0.5"
info:
  label: "Snowflake Revenue by Region Query"
  description: "Queries Snowflake for quarterly revenue breakdown by region for financial reporting."
  tags:
    - analytics
    - snowflake
    - finance
capability:
  exposes:
    - type: mcp
      namespace: finance-analytics
      port: 8080
      tools:
        - name: get-revenue-by-region
          description: "Given a fiscal quarter, return revenue broken down by region from Snowflake. Use for quarterly business reviews."
          inputParameters:
            - name: fiscal_quarter
              in: body
              type: string
              description: "Fiscal quarter in format FYQ (e.g., FY24Q3)."
          call: "snowflake-revenue.run-query"
          with:
            fiscal_quarter: "{{fiscal_quarter}}"
          outputParameters:
            - name: results
              type: object
              mapping: "$.data"
  consumes:
    - type: http
      namespace: snowflake-revenue
      baseUri: "https://salesforce.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST

Retrieves completed search job results from Splunk by job ID for log analysis and audit queries.

naftiko: "0.5"
info:
  label: "Splunk Search Results Lookup"
  description: "Retrieves completed search job results from Splunk by job ID for log analysis and audit queries."
  tags:
    - security
    - splunk
    - log-analytics
capability:
  exposes:
    - type: mcp
      namespace: splunk-search
      port: 8080
      tools:
        - name: get-search-results
          description: "Given a Splunk search job ID, return the results. Use for retrieving completed log analysis or audit query output."
          inputParameters:
            - name: job_id
              in: body
              type: string
              description: "The Splunk search job ID."
          call: "splunk-api.get-results"
          with:
            job_id: "{{job_id}}"
          outputParameters:
            - name: results
              type: array
              mapping: "$.results"
  consumes:
    - type: http
      namespace: splunk-api
      baseUri: "https://splunk.salesforce.com:8089/services"
      authentication:
        type: bearer
        token: "$secrets.splunk_token"
      resources:
        - name: search-results
          path: "/search/jobs/{{job_id}}/results"
          inputParameters:
            - name: job_id
              in: path
          operations:
            - name: get-results
              method: GET

When Splunk detects a suspicious login pattern, creates a ServiceNow security incident, enriches with Okta user data, and pages the security team.

naftiko: "0.5"
info:
  label: "Splunk SIEM Alert to Incident"
  description: "When Splunk detects a suspicious login pattern, creates a ServiceNow security incident, enriches with Okta user data, and pages the security team."
  tags:
    - security
    - splunk
    - servicenow
    - okta
    - pagerduty
capability:
  exposes:
    - type: mcp
      namespace: siem-incident
      port: 8080
      tools:
        - name: handle-siem-alert
          description: "Given a Splunk SIEM alert for suspicious activity, create a ServiceNow incident, enrich with Okta data, and page security."
          inputParameters:
            - name: alert_id
              in: body
              type: string
              description: "The Splunk alert ID."
            - name: user_email
              in: body
              type: string
              description: "The affected user's email address."
            - name: alert_type
              in: body
              type: string
              description: "Type of alert (e.g., impossible_travel, brute_force)."
          steps:
            - name: get-alert
              type: call
              call: "splunk-api.get-alert-results"
              with:
                alert_id: "{{alert_id}}"
            - name: get-user-info
              type: call
              call: "okta-api.get-user"
              with:
                email: "{{user_email}}"
            - name: create-incident
              type: call
              call: "servicenow-api.create-incident"
              with:
                short_description: "[SIEM] {{alert_type}} for {{user_email}}"
                description: "Splunk alert: {{alert_id}}\nUser: {{user_email}} ({{get-user-info.profile.department}})\nAlert type: {{alert_type}}"
                category: "security"
                urgency: "1"
            - name: page-security
              type: call
              call: "pagerduty-api.create-incident"
              with:
                title: "SIEM Alert: {{alert_type}} — {{user_email}}"
                service_id: "$secrets.pagerduty_security_service_id"
                urgency: "high"
  consumes:
    - type: http
      namespace: splunk-api
      baseUri: "https://splunk.salesforce.com:8089/services"
      authentication:
        type: bearer
        token: "$secrets.splunk_token"
      resources:
        - name: alerts
          path: "/search/jobs/{{alert_id}}/results"
          inputParameters:
            - name: alert_id
              in: path
          operations:
            - name: get-alert-results
              method: GET
    - type: http
      namespace: okta-api
      baseUri: "https://salesforce.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_token"
        placement: header
      resources:
        - name: users
          path: "/users/{{email}}"
          inputParameters:
            - name: email
              in: path
          operations:
            - name: get-user
              method: GET
    - type: http
      namespace: servicenow-api
      baseUri: "https://salesforce.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: pagerduty-api
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.pagerduty_token"
        placement: header
      resources:
        - name: incidents
          path: "/incidents"
          operations:
            - name: create-incident
              method: POST

Returns the last refresh time, status, and owner of a Tableau dashboard by workbook name.

naftiko: "0.5"
info:
  label: "Tableau Dashboard Status Check"
  description: "Returns the last refresh time, status, and owner of a Tableau dashboard by workbook name."
  tags:
    - analytics
    - tableau
    - dashboards
capability:
  exposes:
    - type: mcp
      namespace: tableau-status
      port: 8080
      tools:
        - name: get-dashboard-status
          description: "Given a Tableau workbook name, return its last refresh time, status, and owner. Use for dashboard health checks."
          inputParameters:
            - name: workbook_name
              in: body
              type: string
              description: "The Tableau workbook name."
          call: "tableau-api.get-workbook"
          with:
            workbook_name: "{{workbook_name}}"
          outputParameters:
            - name: last_refresh
              type: string
              mapping: "$.workbook.updatedAt"
            - name: status
              type: string
              mapping: "$.workbook.status"
            - name: owner
              type: string
              mapping: "$.workbook.owner.name"
  consumes:
    - type: http
      namespace: tableau-api
      baseUri: "https://tableau.salesforce.com/api/3.19"
      authentication:
        type: bearer
        token: "$secrets.tableau_token"
      resources:
        - name: workbooks
          path: "/sites/default/workbooks?filter=name:eq:{{workbook_name}}"
          inputParameters:
            - name: workbook_name
              in: path
          operations:
            - name: get-workbook
              method: GET

When a Tableau extract refresh fails, creates a Jira ticket for the analytics team, retries the refresh, and posts the failure to Slack.

naftiko: "0.5"
info:
  label: "Tableau Report Failure Alert"
  description: "When a Tableau extract refresh fails, creates a Jira ticket for the analytics team, retries the refresh, and posts the failure to Slack."
  tags:
    - analytics
    - tableau
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: tableau-failure
      port: 8080
      tools:
        - name: handle-refresh-failure
          description: "Given a failed Tableau extract refresh, create a Jira ticket, attempt retry, and notify the analytics team."
          inputParameters:
            - name: datasource_id
              in: body
              type: string
              description: "The Tableau datasource ID."
            - name: datasource_name
              in: body
              type: string
              description: "The datasource name."
            - name: error_message
              in: body
              type: string
              description: "The refresh error message."
          steps:
            - name: create-ticket
              type: call
              call: "jira-api.create-issue"
              with:
                project: "ANALYTICS"
                issuetype: "Bug"
                summary: "[Tableau] Extract refresh failed: {{datasource_name}}"
                description: "Datasource: {{datasource_name}} ({{datasource_id}})\nError: {{error_message}}"
            - name: retry-refresh
              type: call
              call: "tableau-api.refresh-datasource"
              with:
                datasource_id: "{{datasource_id}}"
            - name: notify-team
              type: call
              call: "slack-api.post-message"
              with:
                channel: "analytics-ops"
                text: "Tableau refresh failed: {{datasource_name}} | Error: {{error_message}} | Retry: {{retry-refresh.status}} | Jira: {{create-ticket.key}}"
  consumes:
    - type: http
      namespace: jira-api
      baseUri: "https://salesforce.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: tableau-api
      baseUri: "https://tableau.salesforce.com/api/3.19"
      authentication:
        type: bearer
        token: "$secrets.tableau_token"
      resources:
        - name: datasources
          path: "/sites/default/datasources/{{datasource_id}}/refresh"
          inputParameters:
            - name: datasource_id
              in: path
          operations:
            - name: refresh-datasource
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a Terraform Cloud run enters pending-approval state, fetches the plan summary and posts it to the platform engineering Slack channel for review.

naftiko: "0.5"
info:
  label: "Terraform Cloud Plan Review and Notification"
  description: "When a Terraform Cloud run enters pending-approval state, fetches the plan summary and posts it to the platform engineering Slack channel for review."
  tags:
    - cloud
    - infrastructure
    - terraform
    - slack
    - approval
    - devops
capability:
  exposes:
    - type: mcp
      namespace: infra-terraform
      port: 8080
      tools:
        - name: review-terraform-run
          description: "Given a Terraform Cloud run ID and workspace name, retrieve the plan diff summary and post it to the platform-engineering Slack channel for human approval."
          inputParameters:
            - name: run_id
              in: body
              type: string
              description: "The Terraform Cloud run ID pending review (e.g., run-XyZaBcDe)."
            - name: workspace
              in: body
              type: string
              description: "The Terraform Cloud workspace name."
          steps:
            - name: get-run
              type: call
              call: "terraform.get-run"
              with:
                run_id: "{{run_id}}"
            - name: post-review
              type: call
              call: "slack-tf.post-message"
              with:
                channel: "platform-engineering"
                text: "Terraform run {{run_id}} in {{workspace}} needs approval. Changes: {{get-run.resourceChanges}} | Status: {{get-run.status}}"
  consumes:
    - type: http
      namespace: terraform
      baseUri: "https://app.terraform.io/api/v2"
      authentication:
        type: bearer
        token: "$secrets.terraform_token"
      resources:
        - name: runs
          path: "/runs/{{run_id}}"
          inputParameters:
            - name: run_id
              in: path
          operations:
            - name: get-run
              method: GET
    - type: http
      namespace: slack-tf
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When Terraform Cloud detects infrastructure drift, creates a Jira ticket for review, notifies the platform team via Slack, and triggers a plan run.

naftiko: "0.5"
info:
  label: "Terraform Drift Detection and Remediation"
  description: "When Terraform Cloud detects infrastructure drift, creates a Jira ticket for review, notifies the platform team via Slack, and triggers a plan run."
  tags:
    - infrastructure
    - terraform
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: drift-remediation
      port: 8080
      tools:
        - name: handle-drift
          description: "Given a Terraform workspace with detected drift, create a Jira ticket, notify the platform team, and trigger a plan."
          inputParameters:
            - name: workspace_id
              in: body
              type: string
              description: "The Terraform Cloud workspace ID."
            - name: workspace_name
              in: body
              type: string
              description: "The Terraform Cloud workspace name."
            - name: drift_summary
              in: body
              type: string
              description: "Summary of detected drift."
          steps:
            - name: create-ticket
              type: call
              call: "jira-api.create-issue"
              with:
                project: "INFRA"
                issuetype: "Task"
                summary: "[Drift] {{workspace_name}}: {{drift_summary}}"
                description: "Terraform drift detected in workspace {{workspace_name}} ({{workspace_id}}).\n\nDrift: {{drift_summary}}"
            - name: notify-team
              type: call
              call: "slack-api.post-message"
              with:
                channel: "platform-engineering"
                text: "Drift detected in {{workspace_name}} | Jira: {{create-ticket.key}} | {{drift_summary}}"
            - name: trigger-plan
              type: call
              call: "terraform-api.create-run"
              with:
                workspace_id: "{{workspace_id}}"
  consumes:
    - type: http
      namespace: jira-api
      baseUri: "https://salesforce.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST
    - type: http
      namespace: terraform-api
      baseUri: "https://app.terraform.io/api/v2"
      authentication:
        type: bearer
        token: "$secrets.terraform_token"
      resources:
        - name: runs
          path: "/runs"
          operations:
            - name: create-run
              method: POST

During open enrollment, queries Workday for employees who have not enrolled, sends Slack reminders, and creates a tracking report in Snowflake.

naftiko: "0.5"
info:
  label: "Workday Benefits Enrollment Reminder"
  description: "During open enrollment, queries Workday for employees who have not enrolled, sends Slack reminders, and creates a tracking report in Snowflake."
  tags:
    - hr
    - workday
    - slack
    - snowflake
    - benefits
capability:
  exposes:
    - type: mcp
      namespace: benefits-enrollment
      port: 8080
      tools:
        - name: send-enrollment-reminders
          description: "Given an enrollment period, find unenrolled employees, send Slack reminders, and log to Snowflake."
          inputParameters:
            - name: enrollment_period
              in: body
              type: string
              description: "The benefit enrollment period identifier."
          steps:
            - name: get-unenrolled
              type: call
              call: "workday-api.get-unenrolled"
              with:
                period: "{{enrollment_period}}"
            - name: send-reminders
              type: call
              call: "slack-api.post-message"
              with:
                channel: "hr-announcements"
                text: "Benefits enrollment reminder: {{get-unenrolled.count}} employees have not yet enrolled for {{enrollment_period}}. Deadline approaching."
            - name: log-report
              type: call
              call: "snowflake-api.run-query"
              with:
                enrollment_period: "{{enrollment_period}}"
                unenrolled_count: "{{get-unenrolled.count}}"
  consumes:
    - type: http
      namespace: workday-api
      baseUri: "https://wd5-services1.myworkday.com/ccx/service/salesforce"
      authentication:
        type: basic
        username: "$secrets.workday_user"
        password: "$secrets.workday_password"
      resources:
        - name: benefits
          path: "/Benefits/v40.1/enrollment_status"
          operations:
            - name: get-unenrolled
              method: GET
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST
    - type: http
      namespace: snowflake-api
      baseUri: "https://salesforce.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST

Queries Workday for employees with overdue compliance training, creates a Jira task for HR follow-up, and sends reminders via Slack.

naftiko: "0.5"
info:
  label: "Workday Compliance Training Tracker"
  description: "Queries Workday for employees with overdue compliance training, creates a Jira task for HR follow-up, and sends reminders via Slack."
  tags:
    - hr
    - workday
    - jira
    - slack
    - compliance
capability:
  exposes:
    - type: mcp
      namespace: compliance-training
      port: 8080
      tools:
        - name: track-overdue-training
          description: "Find employees with overdue compliance training, create an HR task, and send reminders."
          inputParameters:
            - name: training_program
              in: body
              type: string
              description: "The compliance training program name."
          steps:
            - name: get-overdue
              type: call
              call: "workday-api.get-overdue-training"
              with:
                program: "{{training_program}}"
            - name: create-task
              type: call
              call: "jira-api.create-issue"
              with:
                project: "HR"
                issuetype: "Task"
                summary: "[Compliance] {{training_program}} — {{get-overdue.count}} employees overdue"
            - name: send-reminder
              type: call
              call: "slack-api.post-message"
              with:
                channel: "hr-compliance"
                text: "Compliance training overdue: {{training_program}} | Employees: {{get-overdue.count}} | Jira: {{create-task.key}}"
  consumes:
    - type: http
      namespace: workday-api
      baseUri: "https://wd5-services1.myworkday.com/ccx/service/salesforce"
      authentication:
        type: basic
        username: "$secrets.workday_user"
        password: "$secrets.workday_password"
      resources:
        - name: training
          path: "/Learning/v40.1/training_status"
          operations:
            - name: get-overdue-training
              method: GET
    - type: http
      namespace: jira-api
      baseUri: "https://salesforce.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Returns an employee's department, title, manager, and location from Workday by employee ID.

naftiko: "0.5"
info:
  label: "Workday Employee Profile Lookup"
  description: "Returns an employee's department, title, manager, and location from Workday by employee ID."
  tags:
    - hr
    - workday
    - employee-data
capability:
  exposes:
    - type: mcp
      namespace: workday-hr
      port: 8080
      tools:
        - name: get-employee
          description: "Given a Workday employee ID, return their department, title, manager, and location. Use for org chart lookups and access decisions."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "The Workday employee ID."
          call: "workday-api.get-worker"
          with:
            employee_id: "{{employee_id}}"
          outputParameters:
            - name: department
              type: string
              mapping: "$.department"
            - name: title
              type: string
              mapping: "$.jobTitle"
            - name: manager
              type: string
              mapping: "$.manager.name"
            - name: location
              type: string
              mapping: "$.location"
  consumes:
    - type: http
      namespace: workday-api
      baseUri: "https://wd5-services1.myworkday.com/ccx/service/salesforce"
      authentication:
        type: basic
        username: "$secrets.workday_user"
        password: "$secrets.workday_password"
      resources:
        - name: workers
          path: "/Human_Resources/v40.1/workers/{{employee_id}}"
          inputParameters:
            - name: employee_id
              in: path
          operations:
            - name: get-worker
              method: GET

Exports the current active headcount by department and cost center from Workday for workforce planning and financial reporting.

naftiko: "0.5"
info:
  label: "Workday Headcount Snapshot"
  description: "Exports the current active headcount by department and cost center from Workday for workforce planning and financial reporting."
  tags:
    - hr
    - finance
    - workday
    - reporting
    - headcount
capability:
  exposes:
    - type: mcp
      namespace: hr-reporting
      port: 8080
      tools:
        - name: get-headcount-snapshot
          description: "Returns active headcount grouped by department and cost center from Workday. Use for quarterly planning, budgeting, or workforce analytics."
          call: "workday-hc.get-workers"
          outputParameters:
            - name: employees
              type: array
              mapping: "$.data"
              items:
                - name: employee_id
                  type: string
                  mapping: "$.workdayId"
                - name: full_name
                  type: string
                  mapping: "$.name"
                - name: department
                  type: string
                  mapping: "$.department"
                - name: cost_center
                  type: string
                  mapping: "$.costCenter"
  consumes:
    - type: http
      namespace: workday-hc
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers-export
          path: "/salesforce/workers"
          operations:
            - name: get-workers
              method: GET

When Workday payroll processing shows a variance above threshold, queries Snowflake for historical comparison, creates a Jira ticket, and alerts finance via Slack.

naftiko: "0.5"
info:
  label: "Workday Payroll Variance Alert"
  description: "When Workday payroll processing shows a variance above threshold, queries Snowflake for historical comparison, creates a Jira ticket, and alerts finance via Slack."
  tags:
    - hr
    - workday
    - snowflake
    - jira
    - slack
    - finance
capability:
  exposes:
    - type: mcp
      namespace: payroll-variance
      port: 8080
      tools:
        - name: handle-payroll-variance
          description: "Given a Workday payroll variance alert, pull historical data from Snowflake, create a Jira ticket, and notify finance."
          inputParameters:
            - name: pay_period
              in: body
              type: string
              description: "The pay period identifier."
            - name: variance_pct
              in: body
              type: number
              description: "Variance percentage from expected."
            - name: variance_amount
              in: body
              type: string
              description: "Dollar amount of the variance."
          steps:
            - name: get-historical
              type: call
              call: "snowflake-api.run-query"
              with:
                pay_period: "{{pay_period}}"
            - name: create-ticket
              type: call
              call: "jira-api.create-issue"
              with:
                project: "FINANCE"
                issuetype: "Task"
                summary: "[Payroll Variance] {{pay_period}} — ${{variance_amount}} ({{variance_pct}}%)"
                description: "Payroll variance detected for {{pay_period}}.\nVariance: ${{variance_amount}} ({{variance_pct}}%)\nHistorical avg: ${{get-historical.data.avg_amount}}"
            - name: alert-finance
              type: call
              call: "slack-api.post-message"
              with:
                channel: "finance-ops"
                text: "Payroll Variance: {{pay_period}} | ${{variance_amount}} ({{variance_pct}}%) | Jira: {{create-ticket.key}}"
  consumes:
    - type: http
      namespace: snowflake-api
      baseUri: "https://salesforce.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - type: http
      namespace: jira-api
      baseUri: "https://salesforce.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a Workday role change is detected, updates the employee's Okta groups to match the new role and notifies their manager via Slack.

naftiko: "0.5"
info:
  label: "Workday Promotion to Okta Group Update"
  description: "When a Workday role change is detected, updates the employee's Okta groups to match the new role and notifies their manager via Slack."
  tags:
    - hr
    - workday
    - okta
    - slack
    - provisioning
capability:
  exposes:
    - type: mcp
      namespace: role-sync
      port: 8080
      tools:
        - name: sync-role-change
          description: "Given a Workday employee ID with a new role, update their Okta group memberships and notify the manager."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "The Workday employee ID."
            - name: new_role
              in: body
              type: string
              description: "The new role title."
          steps:
            - name: get-employee
              type: call
              call: "workday-api.get-worker"
              with:
                employee_id: "{{employee_id}}"
            - name: update-okta-groups
              type: call
              call: "okta-api.update-groups"
              with:
                user_email: "{{get-employee.email}}"
                groups: "{{new_role}}"
            - name: notify-manager
              type: call
              call: "slack-api.post-message"
              with:
                channel: "{{get-employee.manager.slackId}}"
                text: "Role change processed: {{get-employee.name}} promoted to {{new_role}}. Okta groups updated."
  consumes:
    - type: http
      namespace: workday-api
      baseUri: "https://wd5-services1.myworkday.com/ccx/service/salesforce"
      authentication:
        type: basic
        username: "$secrets.workday_user"
        password: "$secrets.workday_password"
      resources:
        - name: workers
          path: "/Human_Resources/v40.1/workers/{{employee_id}}"
          inputParameters:
            - name: employee_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: okta-api
      baseUri: "https://salesforce.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_token"
        placement: header
      resources:
        - name: group-memberships
          path: "/users/{{user_email}}/groups"
          inputParameters:
            - name: user_email
              in: path
          operations:
            - name: update-groups
              method: PUT
    - type: http
      namespace: slack-api
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When an employee's role changes in Workday, updates their Okta group memberships to reflect the new role's access profile and removes stale permissions.

naftiko: "0.5"
info:
  label: "Workday Role Change Access Sync"
  description: "When an employee's role changes in Workday, updates their Okta group memberships to reflect the new role's access profile and removes stale permissions."
  tags:
    - hr
    - identity
    - workday
    - okta
    - access-management
    - role-change
capability:
  exposes:
    - type: mcp
      namespace: hr-access-sync
      port: 8080
      tools:
        - name: sync-role-change-access
          description: "Given a Workday employee ID and new role, update Okta group memberships to match the new access profile and notify IT Ops in Slack."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "The Workday worker ID of the employee whose role changed."
            - name: new_role
              in: body
              type: string
              description: "The new job title or role name."
            - name: old_role
              in: body
              type: string
              description: "The previous job title or role name."
          steps:
            - name: get-employee
              type: call
              call: "workday-sync.get-worker"
              with:
                worker_id: "{{employee_id}}"
            - name: update-okta-groups
              type: call
              call: "okta-sync.update-user-profile"
              with:
                userId: "{{get-employee.oktaId}}"
                department: "{{get-employee.department}}"
                title: "{{new_role}}"
            - name: notify-it
              type: call
              call: "slack-sync.post-message"
              with:
                channel: "it-access-reviews"
                text: "Role change for {{get-employee.displayName}}: {{old_role}} → {{new_role}}. Okta profile updated."
  consumes:
    - type: http
      namespace: workday-sync
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/salesforce/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: okta-sync
      baseUri: "https://salesforce.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_api_token"
        placement: header
      resources:
        - name: users
          path: "/users/{{userId}}"
          inputParameters:
            - name: userId
              in: path
          operations:
            - name: update-user-profile
              method: POST
    - type: http
      namespace: slack-sync
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a time-off request is submitted in Workday, notifies the employee's manager in Slack so they can plan coverage without manual follow-up.

naftiko: "0.5"
info:
  label: "Workday Time-Off Request Notification"
  description: "When a time-off request is submitted in Workday, notifies the employee's manager in Slack so they can plan coverage without manual follow-up."
  tags:
    - hr
    - workday
    - slack
    - leave-management
capability:
  exposes:
    - type: mcp
      namespace: hr-leave
      port: 8080
      tools:
        - name: notify-timeoff-request
          description: "Given a Workday time-off request ID, retrieve the request details and send a notification to the employee's manager in Slack."
          inputParameters:
            - name: request_id
              in: body
              type: string
              description: "The Workday time-off request ID."
          steps:
            - name: get-request
              type: call
              call: "workday-leave.get-timeoff-request"
              with:
                request_id: "{{request_id}}"
            - name: notify-manager
              type: call
              call: "slack-leave.post-message"
              with:
                channel: "{{get-request.managerSlackId}}"
                text: "{{get-request.employeeName}} submitted a time-off request from {{get-request.startDate}} to {{get-request.endDate}}. Please review in Workday."
  consumes:
    - type: http
      namespace: workday-leave
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: timeoff-requests
          path: "/salesforce/timeOffRequests/{{request_id}}"
          inputParameters:
            - name: request_id
              in: path
          operations:
            - name: get-timeoff-request
              method: GET
    - type: http
      namespace: slack-leave
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Returns the topic, start time, duration, and participant count for a Zoom meeting by meeting ID.

naftiko: "0.5"
info:
  label: "Zoom Meeting Details Lookup"
  description: "Returns the topic, start time, duration, and participant count for a Zoom meeting by meeting ID."
  tags:
    - communications
    - zoom
    - meetings
capability:
  exposes:
    - type: mcp
      namespace: zoom-meetings
      port: 8080
      tools:
        - name: get-meeting-details
          description: "Given a Zoom meeting ID, return the topic, start time, duration, and participant count."
          inputParameters:
            - name: meeting_id
              in: body
              type: string
              description: "The Zoom meeting ID."
          call: "zoom-api.get-meeting"
          with:
            meeting_id: "{{meeting_id}}"
          outputParameters:
            - name: topic
              type: string
              mapping: "$.topic"
            - name: start_time
              type: string
              mapping: "$.start_time"
            - name: duration
              type: number
              mapping: "$.duration"
  consumes:
    - type: http
      namespace: zoom-api
      baseUri: "https://api.zoom.us/v2"
      authentication:
        type: bearer
        token: "$secrets.zoom_token"
      resources:
        - name: meetings
          path: "/meetings/{{meeting_id}}"
          inputParameters:
            - name: meeting_id
              in: path
          operations:
            - name: get-meeting
              method: GET