Adobe Capabilities

Naftiko 0.5 capability definitions for Adobe - 109 capabilities showing integration workflows and service orchestrations.

Sort
Expand

Exports an Adobe Analytics segment audience to a CSV in Amazon S3 for downstream activation in marketing platforms.

naftiko: "0.5"
info:
  label: "Adobe Analytics Segment Export"
  description: "Exports an Adobe Analytics segment audience to a CSV in Amazon S3 for downstream activation in marketing platforms."
  tags:
    - analytics
    - adobe-analytics
    - amazon-s3
capability:
  exposes:
    - type: mcp
      namespace: analytics-ops
      port: 8080
      tools:
        - name: export-analytics-segment
          description: "Given an Adobe Analytics segment ID, export the audience to a CSV file in S3. Use when marketing needs a fresh audience list for campaign targeting."
          inputParameters:
            - name: segment_id
              in: body
              type: string
              description: "Adobe Analytics segment ID."
            - name: s3_bucket
              in: body
              type: string
              description: "Target S3 bucket name."
          steps:
            - name: fetch-segment
              type: call
              call: adobe-analytics.get-segment
              with:
                segment_id: "{{segment_id}}"
            - name: upload-csv
              type: call
              call: s3.put-object
              with:
                bucket: "{{s3_bucket}}"
                key: "segments/{{segment_id}}/export.csv"
                body: "{{fetch-segment.data}}"
  consumes:
    - type: http
      namespace: adobe-analytics
      baseUri: "https://analytics.adobe.io/api"
      authentication:
        type: bearer
        token: "$secrets.adobe_analytics_token"
      resources:
        - name: segments
          path: "/segments/{{segment_id}}"
          inputParameters:
            - name: segment_id
              in: path
          operations:
            - name: get-segment
              method: GET
    - type: http
      namespace: s3
      baseUri: "https://s3.amazonaws.com"
      authentication:
        type: aws-sigv4
        accessKeyId: "$secrets.aws_access_key"
        secretAccessKey: "$secrets.aws_secret_key"
      resources:
        - name: objects
          path: "/{{bucket}}/{{key}}"
          inputParameters:
            - name: bucket
              in: path
            - name: key
              in: path
          operations:
            - name: put-object
              method: PUT

Retrieves delivery statistics for an Adobe Campaign email delivery, returning sent count, open rate, and bounce rate.

naftiko: "0.5"
info:
  label: "Adobe Campaign Delivery Report"
  description: "Retrieves delivery statistics for an Adobe Campaign email delivery, returning sent count, open rate, and bounce rate."
  tags:
    - marketing
    - email
    - adobe-campaign
capability:
  exposes:
    - type: mcp
      namespace: campaign-ops
      port: 8080
      tools:
        - name: get-delivery-report
          description: "Given an Adobe Campaign delivery ID, return sent count, open rate, click rate, and bounce rate."
          inputParameters:
            - name: delivery_id
              in: body
              type: string
              description: "Adobe Campaign delivery ID."
          call: campaign.get-delivery
          with:
            delivery_id: "{{delivery_id}}"
          outputParameters:
            - name: sent
              type: integer
              mapping: "$.sent"
            - name: open_rate
              type: number
              mapping: "$.openRate"
            - name: bounce_rate
              type: number
              mapping: "$.bounceRate"
  consumes:
    - type: http
      namespace: campaign
      baseUri: "https://mc.adobe.io/adobe/campaign"
      authentication:
        type: bearer
        token: "$secrets.adobe_campaign_token"
      resources:
        - name: deliveries
          path: "/profileAndServicesExt/delivery/{{delivery_id}}"
          inputParameters:
            - name: delivery_id
              in: path
          operations:
            - name: get-delivery
              method: GET

Retrieves a unified customer profile from Adobe Experience Platform by identity, returning segments, attributes, and last activity.

naftiko: "0.5"
info:
  label: "Adobe Experience Platform Profile Lookup"
  description: "Retrieves a unified customer profile from Adobe Experience Platform by identity, returning segments, attributes, and last activity."
  tags:
    - customer-data
    - personalization
    - adobe-experience-cloud
capability:
  exposes:
    - type: mcp
      namespace: cdp-ops
      port: 8080
      tools:
        - name: get-profile
          description: "Given a customer identity namespace and value, return the unified profile with segment memberships, key attributes, and last activity date."
          inputParameters:
            - name: namespace
              in: body
              type: string
              description: "Identity namespace (e.g., Email, ECID)."
            - name: identity_value
              in: body
              type: string
              description: "Identity value."
          call: aep.get-profile
          with:
            namespace: "{{namespace}}"
            value: "{{identity_value}}"
          outputParameters:
            - name: segments
              type: array
              mapping: "$.segmentMembership"
            - name: attributes
              type: object
              mapping: "$.record"
            - name: last_activity
              type: string
              mapping: "$.lastActivityDate"
  consumes:
    - type: http
      namespace: aep
      baseUri: "https://platform.adobe.io/data/core/ups"
      authentication:
        type: bearer
        token: "$secrets.aep_token"
      resources:
        - name: profiles
          path: "/access/entities"
          operations:
            - name: get-profile
              method: GET

Publishes an Adobe Launch (Experience Platform Tags) library to production and notifies the analytics team via Slack.

naftiko: "0.5"
info:
  label: "Adobe Launch Rule Deployment"
  description: "Publishes an Adobe Launch (Experience Platform Tags) library to production and notifies the analytics team via Slack."
  tags:
    - marketing
    - tag-management
    - adobe
    - slack
capability:
  exposes:
    - type: mcp
      namespace: martech-ops
      port: 8080
      tools:
        - name: deploy-launch-library
          description: "Given an Adobe Launch property ID and library ID, publish the library to production and notify the analytics Slack channel."
          inputParameters:
            - name: property_id
              in: body
              type: string
              description: "Adobe Launch property ID."
            - name: library_id
              in: body
              type: string
              description: "Adobe Launch library ID to publish."
          steps:
            - name: publish-library
              type: call
              call: launch.publish-library
              with:
                property_id: "{{property_id}}"
                library_id: "{{library_id}}"
            - name: notify-team
              type: call
              call: slack.post-message
              with:
                channel: "analytics-ops"
                text: "Adobe Launch library {{library_id}} published to production for property {{property_id}}"
  consumes:
    - type: http
      namespace: launch
      baseUri: "https://reactor.adobe.io"
      authentication:
        type: bearer
        token: "$secrets.adobe_launch_token"
      resources:
        - name: libraries
          path: "/properties/{{property_id}}/libraries/{{library_id}}/publish"
          inputParameters:
            - name: property_id
              in: path
            - name: library_id
              in: path
          operations:
            - name: publish-library
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves the signing status of an Adobe Sign agreement by agreement ID, returning signer details and completion percentage.

naftiko: "0.5"
info:
  label: "Adobe Sign Document Status"
  description: "Retrieves the signing status of an Adobe Sign agreement by agreement ID, returning signer details and completion percentage."
  tags:
    - legal
    - document-signing
    - adobe
capability:
  exposes:
    - type: mcp
      namespace: legal-ops
      port: 8080
      tools:
        - name: get-agreement-status
          description: "Given an Adobe Sign agreement ID, return the current status, list of signers, and completion percentage. Use for contract tracking."
          inputParameters:
            - name: agreement_id
              in: body
              type: string
              description: "Adobe Sign agreement ID."
          call: adobe-sign.get-agreement
          with:
            agreement_id: "{{agreement_id}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.status"
            - name: signers
              type: array
              mapping: "$.participantSetsInfo[*].memberInfos[*].email"
            - name: completion_pct
              type: number
              mapping: "$.completionPercentage"
  consumes:
    - type: http
      namespace: adobe-sign
      baseUri: "https://api.na1.adobesign.com/api/rest/v6"
      authentication:
        type: bearer
        token: "$secrets.adobe_sign_token"
      resources:
        - name: agreements
          path: "/agreements/{{agreement_id}}"
          inputParameters:
            - name: agreement_id
              in: path
          operations:
            - name: get-agreement
              method: GET

Activates an Adobe Target A/B test activity by activity ID and logs the activation event to Snowflake for tracking.

naftiko: "0.5"
info:
  label: "Adobe Target Experience Activation"
  description: "Activates an Adobe Target A/B test activity by activity ID and logs the activation event to Snowflake for tracking."
  tags:
    - personalization
    - experimentation
    - adobe
    - snowflake
capability:
  exposes:
    - type: mcp
      namespace: cx-ops
      port: 8080
      tools:
        - name: activate-ab-test
          description: "Given an Adobe Target activity ID, activate the A/B test and log the event to Snowflake."
          inputParameters:
            - name: activity_id
              in: body
              type: string
              description: "Adobe Target activity ID."
          steps:
            - name: activate-activity
              type: call
              call: target.update-activity
              with:
                activity_id: "{{activity_id}}"
                state: "approved"
            - name: log-activation
              type: call
              call: snowflake.insert-row
              with:
                table: "AB_TEST_ACTIVATIONS"
                values:
                  activity_id: "{{activity_id}}"
                  activated_at: "{{activate-activity.modifiedAt}}"
  consumes:
    - type: http
      namespace: target
      baseUri: "https://mc.adobe.io/adobe/target"
      authentication:
        type: bearer
        token: "$secrets.adobe_target_token"
      resources:
        - name: activities
          path: "/activities/ab/{{activity_id}}/state"
          inputParameters:
            - name: activity_id
              in: path
          operations:
            - name: update-activity
              method: PUT
    - type: http
      namespace: snowflake
      baseUri: "https://adobe.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: insert-row
              method: POST

Retrieves a payroll preview from ADP Workforce Now for a given pay period, returning gross pay, deductions, and net pay totals.

naftiko: "0.5"
info:
  label: "ADP Payroll Preview Lookup"
  description: "Retrieves a payroll preview from ADP Workforce Now for a given pay period, returning gross pay, deductions, and net pay totals."
  tags:
    - hr
    - payroll
    - adp
capability:
  exposes:
    - type: mcp
      namespace: payroll-ops
      port: 8080
      tools:
        - name: get-payroll-preview
          description: "Given an ADP pay period ID, return the payroll preview with gross pay, total deductions, and net pay."
          inputParameters:
            - name: pay_period_id
              in: body
              type: string
              description: "ADP pay period identifier."
          call: adp.get-payroll-preview
          with:
            pay_period_id: "{{pay_period_id}}"
          outputParameters:
            - name: gross_pay
              type: number
              mapping: "$.payrollPreview.grossPay.amount"
            - name: deductions
              type: number
              mapping: "$.payrollPreview.totalDeductions.amount"
            - name: net_pay
              type: number
              mapping: "$.payrollPreview.netPay.amount"
  consumes:
    - type: http
      namespace: adp
      baseUri: "https://api.adp.com/hr/v2"
      authentication:
        type: bearer
        token: "$secrets.adp_token"
      resources:
        - name: payroll
          path: "/payroll-previews/{{pay_period_id}}"
          inputParameters:
            - name: pay_period_id
              in: path
          operations:
            - name: get-payroll-preview
              method: GET

When a complex ServiceNow support ticket arrives, sends the ticket description to Anthropic Claude for an intelligent triage summary and routes it to the correct team.

naftiko: "0.5"
info:
  label: "AI-Assisted Customer Support Ticket Summarization"
  description: "When a complex ServiceNow support ticket arrives, sends the ticket description to Anthropic Claude for an intelligent triage summary and routes it to the correct team."
  tags:
    - ai
    - customer-service
    - servicenow
    - anthropic
    - triage
capability:
  exposes:
    - type: mcp
      namespace: ai-support
      port: 8080
      tools:
        - name: triage-support-ticket
          description: "Given a ServiceNow incident ID, retrieve the full ticket description, send it to Anthropic Claude for intelligent triage and routing recommendation, then update the ServiceNow ticket with the AI summary and recommended assignment group. Use for complex support tickets requiring expert triage."
          inputParameters:
            - name: incident_id
              in: body
              type: string
              description: "ServiceNow incident sys_id to triage."
            - name: support_channel_id
              in: body
              type: string
              description: "Support Teams channel ID for triage summaries."
          steps:
            - name: get-ticket
              type: call
              call: servicenow-triage.get-incident
              with:
                sys_id: "{{incident_id}}"
            - name: generate-summary
              type: call
              call: anthropic.create-message
              with:
                model: "claude-opus-4-5"
                prompt: "Analyze this Adobe support ticket and provide: 1) a 2-sentence summary, 2) the recommended team to assign it to (Creative Cloud, Document Cloud, or Experience Cloud), 3) estimated priority. Ticket: {{get-ticket.description}}"
            - name: update-ticket
              type: call
              call: servicenow-triage-update.update-incident
              with:
                sys_id: "{{incident_id}}"
                ai_summary: "{{generate-summary.content[0].text}}"
            - name: notify-support
              type: call
              call: msteams-support.post-channel-message
              with:
                channel_id: "{{support_channel_id}}"
                text: "AI Triage for INC {{incident_id}}: {{generate-summary.content[0].text}}"
  consumes:
    - type: http
      namespace: servicenow-triage
      baseUri: "https://adobe.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident/{{sys_id}}"
          inputParameters:
            - name: sys_id
              in: path
          operations:
            - name: get-incident
              method: GET
    - type: http
      namespace: anthropic
      baseUri: "https://api.anthropic.com/v1"
      authentication:
        type: apikey
        key: "x-api-key"
        value: "$secrets.anthropic_api_key"
        placement: header
      resources:
        - name: messages
          path: "/messages"
          operations:
            - name: create-message
              method: POST
    - type: http
      namespace: servicenow-triage-update
      baseUri: "https://adobe.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident/{{sys_id}}"
          inputParameters:
            - name: sys_id
              in: path
          operations:
            - name: update-incident
              method: PATCH
    - type: http
      namespace: msteams-support
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Executes a SQL query against Amazon Redshift and returns the result set for data warehouse lookups.

naftiko: "0.5"
info:
  label: "Amazon Redshift Query Execution"
  description: "Executes a SQL query against Amazon Redshift and returns the result set for data warehouse lookups."
  tags:
    - data
    - analytics
    - amazon-redshift
capability:
  exposes:
    - type: mcp
      namespace: data-ops
      port: 8080
      tools:
        - name: run-redshift-query
          description: "Given a SQL statement and Redshift cluster identifier, execute the query and return the results."
          inputParameters:
            - name: sql
              in: body
              type: string
              description: "SQL query to execute."
            - name: cluster_id
              in: body
              type: string
              description: "Redshift cluster identifier."
            - name: database
              in: body
              type: string
              description: "Database name."
          call: redshift.execute-statement
          with:
            sql: "{{sql}}"
            cluster_id: "{{cluster_id}}"
            database: "{{database}}"
          outputParameters:
            - name: statement_id
              type: string
              mapping: "$.Id"
  consumes:
    - type: http
      namespace: redshift
      baseUri: "https://redshift-data.us-east-1.amazonaws.com"
      authentication:
        type: aws-sigv4
        accessKeyId: "$secrets.aws_access_key"
        secretAccessKey: "$secrets.aws_secret_key"
      resources:
        - name: statements
          path: "/"
          operations:
            - name: execute-statement
              method: POST

Checks the message count in an Amazon SQS dead letter queue and, if above threshold, creates a PagerDuty alert and posts to Slack.

naftiko: "0.5"
info:
  label: "Amazon SQS Dead Letter Queue Monitor"
  description: "Checks the message count in an Amazon SQS dead letter queue and, if above threshold, creates a PagerDuty alert and posts to Slack."
  tags:
    - engineering
    - messaging
    - amazon-sqs
    - pagerduty
    - slack
capability:
  exposes:
    - type: mcp
      namespace: platform-ops
      port: 8080
      tools:
        - name: monitor-dlq
          description: "Given an SQS DLQ URL and message threshold, check the queue depth. If above threshold, trigger a PagerDuty alert and Slack notification."
          inputParameters:
            - name: queue_url
              in: body
              type: string
              description: "SQS dead letter queue URL."
            - name: threshold
              in: body
              type: integer
              description: "Message count threshold."
          steps:
            - name: get-queue-attrs
              type: call
              call: sqs.get-queue-attributes
              with:
                queue_url: "{{queue_url}}"
                attribute_names: "ApproximateNumberOfMessages"
            - name: alert-pd
              type: call
              call: pagerduty.create-event
              with:
                routing_key: "$secrets.pagerduty_routing_key"
                summary: "DLQ depth {{get-queue-attrs.ApproximateNumberOfMessages}} exceeds threshold {{threshold}}"
                severity: "error"
            - name: notify-slack
              type: call
              call: slack.post-message
              with:
                channel: "platform-alerts"
                text: "SQS DLQ alert: {{get-queue-attrs.ApproximateNumberOfMessages}} messages in queue (threshold: {{threshold}})"
  consumes:
    - type: http
      namespace: sqs
      baseUri: "https://sqs.us-east-1.amazonaws.com"
      authentication:
        type: aws-sigv4
        accessKeyId: "$secrets.aws_access_key"
        secretAccessKey: "$secrets.aws_secret_key"
      resources:
        - name: queues
          path: "/"
          operations:
            - name: get-queue-attributes
              method: POST
    - type: http
      namespace: pagerduty
      baseUri: "https://events.pagerduty.com/v2"
      authentication:
        type: none
      resources:
        - name: events
          path: "/enqueue"
          operations:
            - name: create-event
              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

Fetches the latest status update from an Asana project and posts it to the project's Microsoft Teams channel.

naftiko: "0.5"
info:
  label: "Asana Project Status Sync"
  description: "Fetches the latest status update from an Asana project and posts it to the project's Microsoft Teams channel."
  tags:
    - project-management
    - collaboration
    - asana
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: pm-ops
      port: 8080
      tools:
        - name: sync-project-status
          description: "Given an Asana project GID, fetch the latest status update and post it to a Teams channel."
          inputParameters:
            - name: project_gid
              in: body
              type: string
              description: "Asana project GID."
            - name: teams_channel_id
              in: body
              type: string
              description: "Microsoft Teams channel ID."
          steps:
            - name: get-status
              type: call
              call: asana.get-project-status
              with:
                project_gid: "{{project_gid}}"
            - name: post-teams
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "{{teams_channel_id}}"
                text: "Asana project status: {{get-status.color}} — {{get-status.text}}"
  consumes:
    - type: http
      namespace: asana
      baseUri: "https://app.asana.com/api/1.0"
      authentication:
        type: bearer
        token: "$secrets.asana_token"
      resources:
        - name: project-statuses
          path: "/projects/{{project_gid}}/project_statuses"
          inputParameters:
            - name: project_gid
              in: path
          operations:
            - name: get-project-status
              method: GET
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Retrieves the running status, instance type, and uptime for an AWS EC2 instance by instance ID.

naftiko: "0.5"
info:
  label: "AWS EC2 Instance Status Check"
  description: "Retrieves the running status, instance type, and uptime for an AWS EC2 instance by instance ID."
  tags:
    - cloud
    - infrastructure
    - aws
    - ec2
capability:
  exposes:
    - type: mcp
      namespace: cloud-ops
      port: 8080
      tools:
        - name: get-ec2-status
          description: "Given an EC2 instance ID, return the instance state, type, availability zone, and launch time. Use for infrastructure health checks."
          inputParameters:
            - name: instance_id
              in: body
              type: string
              description: "AWS EC2 instance ID."
          call: aws-ec2.describe-instance
          with:
            instance_id: "{{instance_id}}"
          outputParameters:
            - name: state
              type: string
              mapping: "$.Reservations[0].Instances[0].State.Name"
            - name: instance_type
              type: string
              mapping: "$.Reservations[0].Instances[0].InstanceType"
            - name: availability_zone
              type: string
              mapping: "$.Reservations[0].Instances[0].Placement.AvailabilityZone"
  consumes:
    - type: http
      namespace: aws-ec2
      baseUri: "https://ec2.amazonaws.com"
      authentication:
        type: aws-sigv4
        accessKeyId: "$secrets.aws_access_key"
        secretAccessKey: "$secrets.aws_secret_key"
      resources:
        - name: instances
          path: "/"
          inputParameters:
            - name: instance_id
              in: query
          operations:
            - name: describe-instance
              method: GET

Invokes an AWS Lambda function with a JSON payload and returns the function response.

naftiko: "0.5"
info:
  label: "AWS Lambda Function Invoke"
  description: "Invokes an AWS Lambda function with a JSON payload and returns the function response."
  tags:
    - cloud
    - serverless
    - aws
    - aws-lambda
capability:
  exposes:
    - type: mcp
      namespace: serverless-ops
      port: 8080
      tools:
        - name: invoke-lambda
          description: "Given an AWS Lambda function name and JSON payload, invoke the function synchronously and return the response. Use for ad-hoc serverless task execution."
          inputParameters:
            - name: function_name
              in: body
              type: string
              description: "Lambda function name or ARN."
            - name: payload
              in: body
              type: string
              description: "JSON payload for the function."
          call: lambda.invoke-function
          with:
            function_name: "{{function_name}}"
            payload: "{{payload}}"
          outputParameters:
            - name: status_code
              type: integer
              mapping: "$.StatusCode"
            - name: response
              type: string
              mapping: "$.Payload"
  consumes:
    - type: http
      namespace: lambda
      baseUri: "https://lambda.us-east-1.amazonaws.com/2015-03-31"
      authentication:
        type: aws-sigv4
        accessKeyId: "$secrets.aws_access_key"
        secretAccessKey: "$secrets.aws_secret_key"
      resources:
        - name: functions
          path: "/functions/{{function_name}}/invocations"
          inputParameters:
            - name: function_name
              in: path
          operations:
            - name: invoke-function
              method: POST

Fetches the bucket policy for an S3 bucket, checks for public access, and posts a security finding to Slack if detected.

naftiko: "0.5"
info:
  label: "AWS S3 Bucket Policy Audit"
  description: "Fetches the bucket policy for an S3 bucket, checks for public access, and posts a security finding to Slack if detected."
  tags:
    - security
    - cloud
    - aws
    - amazon-s3
    - slack
capability:
  exposes:
    - type: mcp
      namespace: cloud-security
      port: 8080
      tools:
        - name: audit-s3-bucket-policy
          description: "Given an S3 bucket name, retrieve the bucket policy, check for public access statements, and alert the security Slack channel if found."
          inputParameters:
            - name: bucket_name
              in: body
              type: string
              description: "S3 bucket name."
            - name: slack_channel
              in: body
              type: string
              description: "Security Slack channel."
          steps:
            - name: get-policy
              type: call
              call: s3.get-bucket-policy
              with:
                bucket: "{{bucket_name}}"
            - name: alert-security
              type: call
              call: slack.post-message
              with:
                channel: "{{slack_channel}}"
                text: "S3 bucket policy audit for {{bucket_name}}: {{get-policy.public_access_detected}}"
  consumes:
    - type: http
      namespace: s3
      baseUri: "https://s3.amazonaws.com"
      authentication:
        type: aws-sigv4
        accessKeyId: "$secrets.aws_access_key"
        secretAccessKey: "$secrets.aws_secret_key"
      resources:
        - name: bucket-policy
          path: "/{{bucket}}?policy"
          inputParameters:
            - name: bucket
              in: path
          operations:
            - name: get-bucket-policy
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When an employee changes teams in Workday, updates their Azure Active Directory group memberships to match the new role.

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

Retrieves the latest build status for an Azure DevOps pipeline and returns the result, duration, and commit SHA.

naftiko: "0.5"
info:
  label: "Azure DevOps Build Status Check"
  description: "Retrieves the latest build status for an Azure DevOps pipeline and returns the result, duration, and commit SHA."
  tags:
    - engineering
    - cicd
    - azure-devops
capability:
  exposes:
    - type: mcp
      namespace: cicd-ops
      port: 8080
      tools:
        - name: get-build-status
          description: "Given an Azure DevOps project and pipeline ID, return the latest build result, duration, and source commit. Use for deployment readiness checks."
          inputParameters:
            - name: project
              in: body
              type: string
              description: "Azure DevOps project name."
            - name: pipeline_id
              in: body
              type: string
              description: "Pipeline definition ID."
          call: azdo.get-latest-build
          with:
            project: "{{project}}"
            definition_id: "{{pipeline_id}}"
          outputParameters:
            - name: result
              type: string
              mapping: "$.value[0].result"
            - name: duration
              type: string
              mapping: "$.value[0].duration"
            - name: commit
              type: string
              mapping: "$.value[0].sourceVersion"
  consumes:
    - type: http
      namespace: azdo
      baseUri: "https://dev.azure.com/adobe"
      authentication:
        type: basic
        username: ""
        password: "$secrets.azdo_pat"
      resources:
        - name: builds
          path: "/{{project}}/_apis/build/builds"
          inputParameters:
            - name: project
              in: path
            - name: definition_id
              in: query
          operations:
            - name: get-latest-build
              method: GET

When an Azure Monitor metric alert fires, creates a ServiceNow incident and notifies the cloud ops Microsoft Teams channel.

naftiko: "0.5"
info:
  label: "Azure Monitor Metric Alert Handler"
  description: "When an Azure Monitor metric alert fires, creates a ServiceNow incident and notifies the cloud ops Microsoft Teams channel."
  tags:
    - cloud
    - monitoring
    - azure-monitor
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: cloud-ops
      port: 8080
      tools:
        - name: handle-azure-alert
          description: "Given an Azure Monitor alert rule name and resource ID, create a ServiceNow incident and notify the cloud ops Teams channel."
          inputParameters:
            - name: alert_rule
              in: body
              type: string
              description: "Azure Monitor alert rule name."
            - name: resource_id
              in: body
              type: string
              description: "Azure resource ID that triggered the alert."
            - name: severity
              in: body
              type: string
              description: "Alert severity (Sev0-Sev4)."
          steps:
            - name: create-snow-incident
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Azure alert: {{alert_rule}} on {{resource_id}}"
                severity: "{{severity}}"
                category: "Cloud Infrastructure"
            - name: notify-teams
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "cloud-ops"
                text: "Azure alert fired: {{alert_rule}} | Resource: {{resource_id}} | Severity: {{severity}} | SNOW: {{create-snow-incident.number}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://adobe.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Retrieves a Box file's metadata classification and, if marked confidential, restricts external sharing and logs the action to Splunk.

naftiko: "0.5"
info:
  label: "Box File Classification Sync"
  description: "Retrieves a Box file's metadata classification and, if marked confidential, restricts external sharing and logs the action to Splunk."
  tags:
    - data-governance
    - security
    - box
    - splunk
capability:
  exposes:
    - type: mcp
      namespace: data-governance
      port: 8080
      tools:
        - name: enforce-file-classification
          description: "Given a Box file ID, check its classification metadata. If confidential, remove external sharing and log to Splunk."
          inputParameters:
            - name: file_id
              in: body
              type: string
              description: "Box file ID."
          steps:
            - name: get-classification
              type: call
              call: box.get-file-metadata
              with:
                file_id: "{{file_id}}"
            - name: log-action
              type: call
              call: splunk.send-event
              with:
                source: "box-dlp"
                event: "Classification enforcement on file {{file_id}}: {{get-classification.classification}}"
  consumes:
    - type: http
      namespace: box
      baseUri: "https://api.box.com/2.0"
      authentication:
        type: bearer
        token: "$secrets.box_token"
      resources:
        - name: file-metadata
          path: "/files/{{file_id}}/metadata/enterprise/securityClassification-6VMVochwUWo"
          inputParameters:
            - name: file_id
              in: path
          operations:
            - name: get-file-metadata
              method: GET
    - type: http
      namespace: splunk
      baseUri: "https://adobe-splunk.splunkcloud.com:8088"
      authentication:
        type: bearer
        token: "$secrets.splunk_hec_token"
      resources:
        - name: events
          path: "/services/collector/event"
          operations:
            - name: send-event
              method: POST

When AWS Cost Anomaly Detection raises a critical alert, creates a Datadog event, opens a Jira FinOps ticket, and posts to the cloud-finops Teams channel.

naftiko: "0.5"
info:
  label: "Cloud Cost Anomaly Response"
  description: "When AWS Cost Anomaly Detection raises a critical alert, creates a Datadog event, opens a Jira FinOps ticket, and posts to the cloud-finops Teams channel."
  tags:
    - finops
    - cloud
    - aws
    - datadog
    - jira
capability:
  exposes:
    - type: mcp
      namespace: cloud-finops
      port: 8080
      tools:
        - name: handle-cost-anomaly
          description: "Given an AWS cost anomaly ID, service, and estimated overage, create a Datadog warning event, open a Jira FinOps task, and alert the cloud-finops Teams channel. Use when AWS Cost Anomaly Detection triggers above threshold."
          inputParameters:
            - name: anomaly_id
              in: body
              type: string
              description: "AWS Cost Anomaly Detection anomaly ID."
            - name: service_name
              in: body
              type: string
              description: "AWS service generating the anomaly."
            - name: estimated_overage_usd
              in: body
              type: number
              description: "Estimated cost overage in USD."
            - name: finops_channel_id
              in: body
              type: string
              description: "FinOps Teams channel ID."
          steps:
            - name: create-dd-event
              type: call
              call: datadog-finops.create-event
              with:
                title: "AWS Cost Anomaly: {{service_name}}"
                text: "Anomaly {{anomaly_id}} — overage ${{estimated_overage_usd}}"
                alert_type: "warning"
            - name: open-jira
              type: call
              call: jira-finops.create-issue
              with:
                project_key: "FINOPS"
                issuetype: "Task"
                summary: "Cost anomaly: {{service_name}} +${{estimated_overage_usd}}"
                description: "Anomaly {{anomaly_id}}. Datadog: {{create-dd-event.id}}"
            - name: alert-finops
              type: call
              call: msteams-finops.post-channel-message
              with:
                channel_id: "{{finops_channel_id}}"
                text: "AWS Cost Anomaly on {{service_name}}: +${{estimated_overage_usd}} | Jira: {{open-jira.key}} | Datadog: {{create-dd-event.url}}"
  consumes:
    - type: http
      namespace: datadog-finops
      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: jira-finops
      baseUri: "https://adobe.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: msteams-finops
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Retrieves DNS records for a Cloudflare zone by record type and name.

naftiko: "0.5"
info:
  label: "Cloudflare DNS Record Lookup"
  description: "Retrieves DNS records for a Cloudflare zone by record type and name."
  tags:
    - infrastructure
    - networking
    - cloudflare
capability:
  exposes:
    - type: mcp
      namespace: infra-ops
      port: 8080
      tools:
        - name: get-dns-records
          description: "Given a Cloudflare zone ID and record name, return matching DNS records with type, content, and TTL."
          inputParameters:
            - name: zone_id
              in: body
              type: string
              description: "Cloudflare zone ID."
            - name: record_name
              in: body
              type: string
              description: "DNS record name to look up."
          call: cloudflare.list-dns-records
          with:
            zone_id: "{{zone_id}}"
            name: "{{record_name}}"
          outputParameters:
            - name: records
              type: array
              mapping: "$.result[*]"
  consumes:
    - type: http
      namespace: cloudflare
      baseUri: "https://api.cloudflare.com/client/v4"
      authentication:
        type: bearer
        token: "$secrets.cloudflare_token"
      resources:
        - name: dns-records
          path: "/zones/{{zone_id}}/dns_records"
          inputParameters:
            - name: zone_id
              in: path
            - name: name
              in: query
          operations:
            - name: list-dns-records
              method: GET

When a Jira bug is marked resolved, auto-generates a Confluence knowledge base article with the resolution details and posts it to the support Teams channel.

naftiko: "0.5"
info:
  label: "Confluence Knowledge Base Article Creation from Jira"
  description: "When a Jira bug is marked resolved, auto-generates a Confluence knowledge base article with the resolution details and posts it to the support Teams channel."
  tags:
    - devops
    - jira
    - confluence
    - knowledge-management
    - customer-service
capability:
  exposes:
    - type: mcp
      namespace: kb-ops
      port: 8080
      tools:
        - name: create-kb-article-from-bug
          description: "Given a resolved Jira issue key and Confluence space key, retrieve the issue resolution details, create a Confluence knowledge base article documenting the fix, and post a link to the support Teams channel. Use when a significant customer-facing bug is resolved."
          inputParameters:
            - name: jira_issue_key
              in: body
              type: string
              description: "Resolved Jira issue key, e.g. 'CC-1234'."
            - name: confluence_space_key
              in: body
              type: string
              description: "Confluence space key for the knowledge base."
            - name: support_channel_id
              in: body
              type: string
              description: "Support Teams channel ID."
          steps:
            - name: get-issue
              type: call
              call: jira-kb.get-issue
              with:
                issue_key: "{{jira_issue_key}}"
            - name: create-article
              type: call
              call: confluence-kb.create-page
              with:
                space_key: "{{confluence_space_key}}"
                title: "KB: {{get-issue.summary}}"
                body: "Issue: {{jira_issue_key}}\n\nSummary: {{get-issue.summary}}\n\nResolution: {{get-issue.resolution}}\n\nWorkaround: {{get-issue.workaround}}"
            - name: notify-support
              type: call
              call: msteams-kb.post-channel-message
              with:
                channel_id: "{{support_channel_id}}"
                text: "New KB article created from {{jira_issue_key}}: {{get-issue.summary}} | Confluence: {{create-article.url}}"
  consumes:
    - type: http
      namespace: jira-kb
      baseUri: "https://adobe.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_token"
      resources:
        - name: issues
          path: "/issue/{{issue_key}}"
          inputParameters:
            - name: issue_key
              in: path
          operations:
            - name: get-issue
              method: GET
    - type: http
      namespace: confluence-kb
      baseUri: "https://adobe.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_token"
      resources:
        - name: pages
          path: "/content"
          operations:
            - name: create-page
              method: POST
    - type: http
      namespace: msteams-kb
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Creates a new Confluence page in a given space using a predefined template and notifies the author via Slack.

naftiko: "0.5"
info:
  label: "Confluence Page Creation from Template"
  description: "Creates a new Confluence page in a given space using a predefined template and notifies the author via Slack."
  tags:
    - documentation
    - collaboration
    - confluence
    - slack
capability:
  exposes:
    - type: mcp
      namespace: docs-ops
      port: 8080
      tools:
        - name: create-page-from-template
          description: "Given a Confluence space key, template name, and page title, create a new page and notify the author on Slack."
          inputParameters:
            - name: space_key
              in: body
              type: string
              description: "Confluence space key."
            - name: template_name
              in: body
              type: string
              description: "Template name to use for the new page."
            - name: page_title
              in: body
              type: string
              description: "Title for the new Confluence page."
            - name: author_slack_id
              in: body
              type: string
              description: "Slack user ID of the page author."
          steps:
            - name: create-page
              type: call
              call: confluence.create-content
              with:
                space_key: "{{space_key}}"
                title: "{{page_title}}"
                template: "{{template_name}}"
            - name: notify-author
              type: call
              call: slack.post-message
              with:
                channel: "{{author_slack_id}}"
                text: "Your Confluence page '{{page_title}}' has been created: {{create-page.url}}"
  consumes:
    - type: http
      namespace: confluence
      baseUri: "https://adobe.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_token"
      resources:
        - name: content
          path: "/content"
          operations:
            - name: create-content
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a Creative Cloud enterprise subscription is approaching renewal, enriches the Salesforce account from ZoomInfo, creates a renewal opportunity, and alerts the account manager in Teams.

naftiko: "0.5"
info:
  label: "Creative Cloud Subscription Renewal Outreach"
  description: "When a Creative Cloud enterprise subscription is approaching renewal, enriches the Salesforce account from ZoomInfo, creates a renewal opportunity, and alerts the account manager in Teams."
  tags:
    - sales
    - crm
    - salesforce
    - creative-cloud
    - renewal
capability:
  exposes:
    - type: mcp
      namespace: renewal-ops
      port: 8080
      tools:
        - name: trigger-renewal-outreach
          description: "Given a Salesforce account ID and contract end date, enrich the account with ZoomInfo data, create a renewal opportunity in Salesforce, and send a Teams alert to the account manager. Use when contract end dates are within 90 days."
          inputParameters:
            - name: salesforce_account_id
              in: body
              type: string
              description: "Salesforce account ID for the renewing customer."
            - name: contract_end_date
              in: body
              type: string
              description: "Contract expiration date in YYYY-MM-DD format."
            - name: account_manager_upn
              in: body
              type: string
              description: "Account manager Teams UPN."
            - name: zoominfo_company_id
              in: body
              type: string
              description: "ZoomInfo company ID for enrichment."
          steps:
            - name: enrich-account
              type: call
              call: zoominfo.get-company
              with:
                company_id: "{{zoominfo_company_id}}"
            - name: update-sf-account
              type: call
              call: salesforce-acct.update-account
              with:
                account_id: "{{salesforce_account_id}}"
                employees: "{{enrich-account.employee_count}}"
                annual_revenue: "{{enrich-account.revenue}}"
            - name: create-renewal-opp
              type: call
              call: salesforce-opp.create-opportunity
              with:
                account_id: "{{salesforce_account_id}}"
                name: "Renewal — {{enrich-account.company_name}} — {{contract_end_date}}"
                stage_name: "Renewal Outreach"
                close_date: "{{contract_end_date}}"
            - name: alert-account-manager
              type: call
              call: msteams-renewal.send-message
              with:
                recipient_upn: "{{account_manager_upn}}"
                text: "Renewal alert: {{enrich-account.company_name}} contract ends {{contract_end_date}}. Renewal opportunity created: {{create-renewal-opp.id}}. Employees: {{enrich-account.employee_count}}"
  consumes:
    - type: http
      namespace: zoominfo
      baseUri: "https://api.zoominfo.com/search"
      authentication:
        type: bearer
        token: "$secrets.zoominfo_token"
      resources:
        - name: companies
          path: "/company/{{company_id}}"
          inputParameters:
            - name: company_id
              in: path
          operations:
            - name: get-company
              method: GET
    - type: http
      namespace: salesforce-acct
      baseUri: "https://adobe.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: accounts
          path: "/sobjects/Account/{{account_id}}"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: update-account
              method: PATCH
    - type: http
      namespace: salesforce-opp
      baseUri: "https://adobe.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: opportunities
          path: "/sobjects/Opportunity"
          operations:
            - name: create-opportunity
              method: POST
    - type: http
      namespace: msteams-renewal
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: messages
          path: "/users/{{recipient_upn}}/sendMail"
          inputParameters:
            - name: recipient_upn
              in: path
          operations:
            - name: send-message
              method: POST

Retrieves the status of a Databricks job run by run ID, returning state, start time, and duration.

naftiko: "0.5"
info:
  label: "Databricks Job Run Status"
  description: "Retrieves the status of a Databricks job run by run ID, returning state, start time, and duration."
  tags:
    - data-engineering
    - analytics
    - databricks
capability:
  exposes:
    - type: mcp
      namespace: data-ops
      port: 8080
      tools:
        - name: get-job-run-status
          description: "Given a Databricks run ID, return the run state, start time, and duration in seconds. Use for pipeline monitoring."
          inputParameters:
            - name: run_id
              in: body
              type: string
              description: "Databricks job run ID."
          call: databricks.get-run
          with:
            run_id: "{{run_id}}"
          outputParameters:
            - name: state
              type: string
              mapping: "$.state.life_cycle_state"
            - name: result_state
              type: string
              mapping: "$.state.result_state"
            - name: start_time
              type: number
              mapping: "$.start_time"
  consumes:
    - type: http
      namespace: databricks
      baseUri: "https://adobe.cloud.databricks.com/api/2.1"
      authentication:
        type: bearer
        token: "$secrets.databricks_token"
      resources:
        - name: runs
          path: "/jobs/runs/get"
          inputParameters:
            - name: run_id
              in: query
          operations:
            - name: get-run
              method: GET

Takes a snapshot of a Datadog dashboard and posts the image URL to a Microsoft Teams channel for stakeholder review.

naftiko: "0.5"
info:
  label: "Datadog Dashboard Snapshot"
  description: "Takes a snapshot of a Datadog dashboard and posts the image URL to a Microsoft Teams channel for stakeholder review."
  tags:
    - monitoring
    - reporting
    - datadog
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: observability
      port: 8080
      tools:
        - name: snapshot-dashboard
          description: "Given a Datadog dashboard ID, take a PNG snapshot and post the image link to a Teams channel."
          inputParameters:
            - name: dashboard_id
              in: body
              type: string
              description: "Datadog dashboard ID."
            - name: teams_channel_id
              in: body
              type: string
              description: "Microsoft Teams channel ID."
          steps:
            - name: take-snapshot
              type: call
              call: datadog.create-snapshot
              with:
                graph_def: "{{dashboard_id}}"
            - name: post-teams
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "{{teams_channel_id}}"
                text: "Datadog dashboard snapshot: {{take-snapshot.snapshot_url}}"
  consumes:
    - type: http
      namespace: datadog
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: snapshots
          path: "/graph/snapshot"
          operations:
            - name: create-snapshot
              method: GET
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Retrieves Datadog SLO compliance metrics for Adobe's core services, publishes to Power BI, and emails the SLO report to engineering leadership.

naftiko: "0.5"
info:
  label: "Datadog SLO Compliance Report"
  description: "Retrieves Datadog SLO compliance metrics for Adobe's core services, publishes to Power BI, and emails the SLO report to engineering leadership."
  tags:
    - observability
    - datadog
    - slo
    - reporting
    - engineering
capability:
  exposes:
    - type: mcp
      namespace: slo-reporting
      port: 8080
      tools:
        - name: publish-slo-report
          description: "Given a time window and Power BI dataset ID, fetch SLO compliance metrics for all monitored services from Datadog, trigger a Power BI refresh, and email the SLO summary to engineering leadership. Use weekly for reliability review meetings."
          inputParameters:
            - name: from_ts
              in: body
              type: integer
              description: "Unix timestamp for the start of the SLO measurement period."
            - name: to_ts
              in: body
              type: integer
              description: "Unix timestamp for the end of the SLO measurement period."
            - name: pbi_dataset_id
              in: body
              type: string
              description: "Power BI dataset ID for the SLO dashboard."
            - name: engineering_email
              in: body
              type: string
              description: "Engineering leadership email for the SLO report."
          steps:
            - name: get-slos
              type: call
              call: datadog-slo.get-slo-history
              with:
                from_ts: "{{from_ts}}"
                to_ts: "{{to_ts}}"
            - name: refresh-pbi-slo
              type: call
              call: powerbi-slo.trigger-refresh
              with:
                dataset_id: "{{pbi_dataset_id}}"
            - name: send-slo-report
              type: call
              call: msgraph-slo.send-email
              with:
                to: "{{engineering_email}}"
                subject: "SLO Compliance Report"
                body: "Services meeting SLO: {{get-slos.compliant_count}} | Services breaching SLO: {{get-slos.breaching_count}} | Dashboard refreshed."
  consumes:
    - type: http
      namespace: datadog-slo
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: slo-history
          path: "/slo/history"
          inputParameters:
            - name: from_ts
              in: query
            - name: to_ts
              in: query
          operations:
            - name: get-slo-history
              method: GET
    - type: http
      namespace: powerbi-slo
      baseUri: "https://api.powerbi.com/v1.0/myorg"
      authentication:
        type: bearer
        token: "$secrets.powerbi_token"
      resources:
        - name: dataset-refreshes
          path: "/datasets/{{dataset_id}}/refreshes"
          inputParameters:
            - name: dataset_id
              in: path
          operations:
            - name: trigger-refresh
              method: POST
    - type: http
      namespace: msgraph-slo
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: send-mail
          path: "/users/{{sender}}/sendMail"
          operations:
            - name: send-email
              method: POST

Retrieves the status of a DocuSign envelope by envelope ID, returning signer status and completion date.

naftiko: "0.5"
info:
  label: "DocuSign Envelope Status Check"
  description: "Retrieves the status of a DocuSign envelope by envelope ID, returning signer status and completion date."
  tags:
    - legal
    - document-signing
    - docusign
capability:
  exposes:
    - type: mcp
      namespace: legal-ops
      port: 8080
      tools:
        - name: get-envelope-status
          description: "Given a DocuSign envelope ID, return the envelope status, list of signer statuses, and completion timestamp."
          inputParameters:
            - name: envelope_id
              in: body
              type: string
              description: "DocuSign envelope ID."
          call: docusign.get-envelope
          with:
            envelope_id: "{{envelope_id}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.status"
            - name: signers
              type: array
              mapping: "$.recipients.signers[*].status"
            - name: completed_date
              type: string
              mapping: "$.completedDateTime"
  consumes:
    - type: http
      namespace: docusign
      baseUri: "https://na4.docusign.net/restapi/v2.1/accounts/$secrets.docusign_account_id"
      authentication:
        type: bearer
        token: "$secrets.docusign_token"
      resources:
        - name: envelopes
          path: "/envelopes/{{envelope_id}}"
          inputParameters:
            - name: envelope_id
              in: path
          operations:
            - name: get-envelope
              method: GET

When Dynatrace detects a problem, creates a Jira operations ticket and posts the root cause analysis to a Microsoft Teams channel.

naftiko: "0.5"
info:
  label: "Dynatrace Problem Notification"
  description: "When Dynatrace detects a problem, creates a Jira operations ticket and posts the root cause analysis to a Microsoft Teams channel."
  tags:
    - monitoring
    - incident-management
    - dynatrace
    - jira
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: observability-ops
      port: 8080
      tools:
        - name: handle-dynatrace-problem
          description: "Given a Dynatrace problem ID, fetch root cause details, create a Jira ticket, and notify the Teams operations channel."
          inputParameters:
            - name: problem_id
              in: body
              type: string
              description: "Dynatrace problem ID."
          steps:
            - name: get-problem
              type: call
              call: dynatrace.get-problem
              with:
                problem_id: "{{problem_id}}"
            - name: create-jira
              type: call
              call: jira.create-issue
              with:
                project_key: "OPS"
                issuetype: "Bug"
                summary: "Dynatrace: {{get-problem.title}}"
                description: "Root cause: {{get-problem.rootCauseEntity}} | Impact: {{get-problem.impactLevel}}"
            - name: notify-teams
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "ops-incidents"
                text: "Dynatrace problem: {{get-problem.title}} | Jira: {{create-jira.key}}"
  consumes:
    - type: http
      namespace: dynatrace
      baseUri: "https://adobe.live.dynatrace.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.dynatrace_token"
      resources:
        - name: problems
          path: "/problems/{{problem_id}}"
          inputParameters:
            - name: problem_id
              in: path
          operations:
            - name: get-problem
              method: GET
    - type: http
      namespace: jira
      baseUri: "https://adobe.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Checks the health status of an Elasticsearch index, returning shard count, document count, and store size, then posts critical findings to Slack.

naftiko: "0.5"
info:
  label: "Elasticsearch Index Health Check"
  description: "Checks the health status of an Elasticsearch index, returning shard count, document count, and store size, then posts critical findings to Slack."
  tags:
    - data
    - search
    - elasticsearch
    - slack
capability:
  exposes:
    - type: mcp
      namespace: search-ops
      port: 8080
      tools:
        - name: check-index-health
          description: "Given an Elasticsearch index name, fetch health metrics and post any red-status findings to the platform Slack channel."
          inputParameters:
            - name: index_name
              in: body
              type: string
              description: "Elasticsearch index name."
          steps:
            - name: get-index-stats
              type: call
              call: elasticsearch.get-index-stats
              with:
                index: "{{index_name}}"
            - name: alert-if-unhealthy
              type: call
              call: slack.post-message
              with:
                channel: "platform-alerts"
                text: "Elasticsearch index {{index_name}}: status={{get-index-stats.health}}, docs={{get-index-stats.docs_count}}, size={{get-index-stats.store_size}}"
  consumes:
    - type: http
      namespace: elasticsearch
      baseUri: "https://adobe-es.es.amazonaws.com"
      authentication:
        type: aws-sigv4
        accessKeyId: "$secrets.aws_access_key"
        secretAccessKey: "$secrets.aws_secret_key"
      resources:
        - name: indices
          path: "/_cat/indices/{{index}}"
          inputParameters:
            - name: index
              in: path
          operations:
            - name: get-index-stats
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When an employee termination is processed in Workday, deactivates their Okta account, closes open ServiceNow access requests, and deactivates the Salesforce user license.

naftiko: "0.5"
info:
  label: "Employee Offboarding Deprovisioning"
  description: "When an employee termination is processed in Workday, deactivates their Okta account, closes open ServiceNow access requests, and deactivates the Salesforce user license."
  tags:
    - hr
    - offboarding
    - okta
    - workday
    - identity
capability:
  exposes:
    - type: mcp
      namespace: hr-offboarding
      port: 8080
      tools:
        - name: deprovision-terminated-employee
          description: "Given a terminated employee's Workday ID, Okta user ID, and Salesforce user ID, deactivate their Okta account, close open ServiceNow access requests, and deactivate their Salesforce license. Use immediately upon processing a termination in Workday."
          inputParameters:
            - name: workday_employee_id
              in: body
              type: string
              description: "Workday worker ID of the terminated employee."
            - name: okta_user_id
              in: body
              type: string
              description: "Okta user ID to deactivate."
            - name: salesforce_user_id
              in: body
              type: string
              description: "Salesforce user ID to deactivate."
          steps:
            - name: deactivate-okta
              type: call
              call: okta-offboard.deactivate-user
              with:
                user_id: "{{okta_user_id}}"
            - name: close-requests
              type: call
              call: servicenow-offboard.close-user-requests
              with:
                employee_id: "{{workday_employee_id}}"
            - name: deactivate-sf
              type: call
              call: salesforce-offboard.update-user
              with:
                user_id: "{{salesforce_user_id}}"
                is_active: "false"
  consumes:
    - type: http
      namespace: okta-offboard
      baseUri: "https://adobe.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
    - type: http
      namespace: servicenow-offboard
      baseUri: "https://adobe.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: requests
          path: "/table/sc_request"
          operations:
            - name: close-user-requests
              method: PATCH
    - type: http
      namespace: salesforce-offboard
      baseUri: "https://adobe.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: users
          path: "/sobjects/User/{{user_id}}"
          inputParameters:
            - name: user_id
              in: path
          operations:
            - name: update-user
              method: PATCH

When a Workday role change is approved, updates Okta group memberships, adjusts the Salesforce user profile, and creates an IT ServiceNow follow-up task.

naftiko: "0.5"
info:
  label: "Employee Role Change Provisioning"
  description: "When a Workday role change is approved, updates Okta group memberships, adjusts the Salesforce user profile, and creates an IT ServiceNow follow-up task."
  tags:
    - hr
    - identity
    - workday
    - okta
    - provisioning
capability:
  exposes:
    - type: mcp
      namespace: role-provisioning
      port: 8080
      tools:
        - name: process-role-change
          description: "Given a Workday employee ID, new role, and Okta group changes, update Okta group membership, update the Salesforce user profile, and create a ServiceNow IT task for access follow-up. Use when an employee's role or department changes."
          inputParameters:
            - name: workday_employee_id
              in: body
              type: string
              description: "Workday worker ID of the employee."
            - name: new_role
              in: body
              type: string
              description: "New job title or role."
            - name: okta_add_group_id
              in: body
              type: string
              description: "Okta group ID to add the employee to."
            - name: salesforce_user_id
              in: body
              type: string
              description: "Salesforce user ID to update."
          steps:
            - name: get-worker
              type: call
              call: workday-rc.get-worker
              with:
                worker_id: "{{workday_employee_id}}"
            - name: add-to-okta-group
              type: call
              call: okta-role.add-user-to-group
              with:
                group_id: "{{okta_add_group_id}}"
                user_email: "{{get-worker.work_email}}"
            - name: update-sf-user
              type: call
              call: salesforce-rc.update-user
              with:
                user_id: "{{salesforce_user_id}}"
                title: "{{new_role}}"
            - name: create-it-task
              type: call
              call: servicenow-rc.create-task
              with:
                short_description: "Role change: {{get-worker.full_name}} → {{new_role}}"
                category: "access_management"
                assigned_group: "IT_Access"
  consumes:
    - type: http
      namespace: workday-rc
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: okta-role
      baseUri: "https://adobe.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_token"
        placement: header
      resources:
        - name: group-users
          path: "/groups/{{group_id}}/users"
          inputParameters:
            - name: group_id
              in: path
          operations:
            - name: add-user-to-group
              method: PUT
    - type: http
      namespace: salesforce-rc
      baseUri: "https://adobe.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: users
          path: "/sobjects/User/{{user_id}}"
          inputParameters:
            - name: user_id
              in: path
          operations:
            - name: update-user
              method: PATCH
    - type: http
      namespace: servicenow-rc
      baseUri: "https://adobe.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST

After a customer completes an NPS survey, updates their Salesforce account with the score, creates a follow-up task for low scores, and logs the response in Snowflake.

naftiko: "0.5"
info:
  label: "Experience Cloud Customer NPS Survey Sync"
  description: "After a customer completes an NPS survey, updates their Salesforce account with the score, creates a follow-up task for low scores, and logs the response in Snowflake."
  tags:
    - crm
    - customer-service
    - salesforce
    - nps
    - analytics
capability:
  exposes:
    - type: mcp
      namespace: nps-ops
      port: 8080
      tools:
        - name: process-nps-response
          description: "Given a customer NPS score and Salesforce account ID, update the account record with the NPS score, create a follow-up task in Salesforce if the score is below 7 (detractor), and log the response to Snowflake for analytics. Use when NPS survey responses are received."
          inputParameters:
            - name: salesforce_account_id
              in: body
              type: string
              description: "Salesforce account ID of the respondent."
            - name: nps_score
              in: body
              type: integer
              description: "NPS score from 0–10."
            - name: respondent_email
              in: body
              type: string
              description: "Respondent email address."
            - name: survey_date
              in: body
              type: string
              description: "Survey completion date in YYYY-MM-DD format."
          steps:
            - name: update-sf-account
              type: call
              call: salesforce-nps.update-account
              with:
                account_id: "{{salesforce_account_id}}"
                nps_score: "{{nps_score}}"
                last_nps_date: "{{survey_date}}"
            - name: create-followup-task
              type: call
              call: salesforce-nps-task.create-task
              with:
                account_id: "{{salesforce_account_id}}"
                subject: "NPS Detractor Follow-up — Score: {{nps_score}}"
                description: "Customer scored {{nps_score}}. Contact to understand issues and recover."
            - name: log-to-snowflake
              type: call
              call: snowflake-nps.insert-record
              with:
                account_id: "{{salesforce_account_id}}"
                email: "{{respondent_email}}"
                score: "{{nps_score}}"
                survey_date: "{{survey_date}}"
  consumes:
    - type: http
      namespace: salesforce-nps
      baseUri: "https://adobe.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: accounts
          path: "/sobjects/Account/{{account_id}}"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: update-account
              method: PATCH
    - type: http
      namespace: salesforce-nps-task
      baseUri: "https://adobe.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: snowflake-nps
      baseUri: "https://adobe.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: nps-records
          path: "/databases/CX_ANALYTICS/schemas/PUBLIC/tables/NPS_RESPONSES/rows"
          operations:
            - name: insert-record
              method: POST

Triggers a customer journey in Adobe Experience Cloud based on a Salesforce opportunity stage change and logs the event to Snowflake.

naftiko: "0.5"
info:
  label: "Experience Cloud Journey Trigger"
  description: "Triggers a customer journey in Adobe Experience Cloud based on a Salesforce opportunity stage change and logs the event to Snowflake."
  tags:
    - marketing
    - customer-experience
    - adobe-experience-cloud
    - salesforce
    - snowflake
capability:
  exposes:
    - type: mcp
      namespace: cx-orchestration
      port: 8080
      tools:
        - name: trigger-customer-journey
          description: "Given a Salesforce opportunity ID and new stage, trigger the corresponding Adobe Experience Cloud journey and log the event to Snowflake for analytics."
          inputParameters:
            - name: opportunity_id
              in: body
              type: string
              description: "Salesforce opportunity ID."
            - name: new_stage
              in: body
              type: string
              description: "New opportunity stage name."
            - name: customer_email
              in: body
              type: string
              description: "Customer email for journey entry."
          steps:
            - name: trigger-journey
              type: call
              call: aec.trigger-journey
              with:
                email: "{{customer_email}}"
                journey_stage: "{{new_stage}}"
                source: "salesforce-opp-{{opportunity_id}}"
            - name: log-event
              type: call
              call: snowflake.insert-row
              with:
                table: "CX_JOURNEY_EVENTS"
                values:
                  opportunity_id: "{{opportunity_id}}"
                  stage: "{{new_stage}}"
                  journey_id: "{{trigger-journey.journey_run_id}}"
  consumes:
    - type: http
      namespace: aec
      baseUri: "https://platform.adobe.io/journey"
      authentication:
        type: bearer
        token: "$secrets.aec_token"
      resources:
        - name: journeys
          path: "/triggers"
          operations:
            - name: trigger-journey
              method: POST
    - type: http
      namespace: snowflake
      baseUri: "https://adobe.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: insert-row
              method: POST

When a Figma file is updated, posts a review request to the design team Slack channel with a link to the file.

naftiko: "0.5"
info:
  label: "Figma Design Review Notification"
  description: "When a Figma file is updated, posts a review request to the design team Slack channel with a link to the file."
  tags:
    - design
    - collaboration
    - figma
    - slack
capability:
  exposes:
    - type: mcp
      namespace: design-ops
      port: 8080
      tools:
        - name: notify-design-review
          description: "Given a Figma file key and reviewer channel, fetch file metadata and post a review request to Slack."
          inputParameters:
            - name: file_key
              in: body
              type: string
              description: "Figma file key."
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel for design reviews."
          steps:
            - name: get-file
              type: call
              call: figma.get-file
              with:
                file_key: "{{file_key}}"
            - name: post-review
              type: call
              call: slack.post-message
              with:
                channel: "{{slack_channel}}"
                text: "Design review requested: {{get-file.name}} — https://www.figma.com/file/{{file_key}}"
  consumes:
    - type: http
      namespace: figma
      baseUri: "https://api.figma.com/v1"
      authentication:
        type: bearer
        token: "$secrets.figma_token"
      resources:
        - name: files
          path: "/files/{{file_key}}"
          inputParameters:
            - name: file_key
              in: path
          operations:
            - name: get-file
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a Gainsight customer health score drops below threshold, creates a Salesforce task for the CSM and alerts the customer-success Slack channel.

naftiko: "0.5"
info:
  label: "Gainsight Health Score Alert"
  description: "When a Gainsight customer health score drops below threshold, creates a Salesforce task for the CSM and alerts the customer-success Slack channel."
  tags:
    - customer-success
    - crm
    - gainsight
    - salesforce
    - slack
capability:
  exposes:
    - type: mcp
      namespace: cs-ops
      port: 8080
      tools:
        - name: alert-low-health-score
          description: "Given a Gainsight company ID and health score threshold, check the score. If below threshold, create a Salesforce CSM task and notify Slack."
          inputParameters:
            - name: company_id
              in: body
              type: string
              description: "Gainsight company ID."
            - name: threshold
              in: body
              type: number
              description: "Health score threshold."
          steps:
            - name: get-health
              type: call
              call: gainsight.get-company-health
              with:
                company_id: "{{company_id}}"
            - name: create-sf-task
              type: call
              call: salesforce.create-task
              with:
                subject: "Low health score alert: {{company_id}} ({{get-health.score}})"
                priority: "High"
            - name: notify-cs
              type: call
              call: slack.post-message
              with:
                channel: "customer-success"
                text: "Health score alert: {{company_id}} dropped to {{get-health.score}} (threshold: {{threshold}})"
  consumes:
    - type: http
      namespace: gainsight
      baseUri: "https://adobe.gainsightcloud.com/v1"
      authentication:
        type: bearer
        token: "$secrets.gainsight_token"
      resources:
        - name: companies
          path: "/data/objects/Company/{{company_id}}"
          inputParameters:
            - name: company_id
              in: path
          operations:
            - name: get-company-health
              method: GET
    - type: http
      namespace: salesforce
      baseUri: "https://adobe.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
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Triggers a GitHub Actions workflow dispatch event and posts the run URL to a Slack channel for visibility.

naftiko: "0.5"
info:
  label: "GitHub Actions Workflow Trigger"
  description: "Triggers a GitHub Actions workflow dispatch event and posts the run URL to a Slack channel for visibility."
  tags:
    - engineering
    - cicd
    - github
    - github-actions
    - slack
capability:
  exposes:
    - type: mcp
      namespace: cicd-ops
      port: 8080
      tools:
        - name: trigger-workflow
          description: "Given a GitHub repo and workflow file name, trigger a workflow dispatch and post the run URL to Slack."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "GitHub repository in org/repo format."
            - name: workflow_id
              in: body
              type: string
              description: "Workflow file name (e.g., deploy.yml)."
            - name: ref
              in: body
              type: string
              description: "Git ref to run against."
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel for notification."
          steps:
            - name: dispatch-workflow
              type: call
              call: github.create-workflow-dispatch
              with:
                repo: "{{repo}}"
                workflow_id: "{{workflow_id}}"
                ref: "{{ref}}"
            - name: notify-slack
              type: call
              call: slack.post-message
              with:
                channel: "{{slack_channel}}"
                text: "GitHub Actions workflow {{workflow_id}} triggered on {{repo}} (ref: {{ref}})"
  consumes:
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: workflow-dispatches
          path: "/repos/{{repo}}/actions/workflows/{{workflow_id}}/dispatches"
          inputParameters:
            - name: repo
              in: path
            - name: workflow_id
              in: path
          operations:
            - name: create-workflow-dispatch
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a GitHub Actions workflow fails on a protected branch, creates a Jira bug, posts a Datadog deployment marker, and alerts the engineering Teams channel.

naftiko: "0.5"
info:
  label: "GitHub CI/CD Pipeline Failure Handler"
  description: "When a GitHub Actions workflow fails on a protected branch, creates a Jira bug, posts a Datadog deployment marker, and alerts the engineering Teams channel."
  tags:
    - devops
    - cicd
    - github
    - jira
    - datadog
capability:
  exposes:
    - type: mcp
      namespace: devops-ci
      port: 8080
      tools:
        - name: handle-pipeline-failure
          description: "Given a GitHub Actions failure event with repo, branch, commit, and workflow details, open a Jira bug, create a Datadog error event, and post an alert to the engineering Teams channel. Use when a protected-branch CI pipeline fails."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "GitHub repository full name, e.g. 'adobe/creative-cloud-api'."
            - name: branch
              in: body
              type: string
              description: "Branch where the failure occurred."
            - name: commit_sha
              in: body
              type: string
              description: "Failing commit SHA."
            - name: workflow_name
              in: body
              type: string
              description: "Name of the failed GitHub Actions workflow."
            - name: run_url
              in: body
              type: string
              description: "URL to the failed workflow run."
            - name: eng_channel_id
              in: body
              type: string
              description: "Engineering Teams channel ID."
          steps:
            - name: create-bug
              type: call
              call: jira.create-issue
              with:
                project_key: "ENG"
                issuetype: "Bug"
                summary: "[CI Failure] {{repo}} / {{branch}} — {{workflow_name}}"
                description: "Commit: {{commit_sha}}\nRun: {{run_url}}"
            - name: log-dd-event
              type: call
              call: datadog.create-event
              with:
                title: "CI Failure: {{repo}} — {{branch}}"
                text: "Commit {{commit_sha}} | Workflow {{workflow_name}}"
                alert_type: "error"
            - name: alert-eng
              type: call
              call: msteams-eng.post-channel-message
              with:
                channel_id: "{{eng_channel_id}}"
                text: "CI Failure: {{repo}} | Branch: {{branch}} | Jira: {{create-bug.key}} | Run: {{run_url}}"
  consumes:
    - type: http
      namespace: jira
      baseUri: "https://adobe.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: datadog
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: events
          path: "/events"
          operations:
            - name: create-event
              method: POST
    - type: http
      namespace: msteams-eng
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Fetches open Dependabot alerts for a GitHub repository and posts a severity-grouped summary to the security Slack channel.

naftiko: "0.5"
info:
  label: "GitHub Dependabot Alert Summary"
  description: "Fetches open Dependabot alerts for a GitHub repository and posts a severity-grouped summary to the security Slack channel."
  tags:
    - security
    - engineering
    - github
    - slack
capability:
  exposes:
    - type: mcp
      namespace: appsec
      port: 8080
      tools:
        - name: summarize-dependabot-alerts
          description: "Given a GitHub repository, fetch open Dependabot vulnerability alerts and post a severity-grouped count to the security Slack channel."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "GitHub repository in org/repo format."
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel for the summary."
          steps:
            - name: get-alerts
              type: call
              call: github.list-dependabot-alerts
              with:
                repo: "{{repo}}"
                state: "open"
            - name: post-summary
              type: call
              call: slack.post-message
              with:
                channel: "{{slack_channel}}"
                text: "Dependabot alerts for {{repo}}: Critical={{get-alerts.critical_count}}, High={{get-alerts.high_count}}, Medium={{get-alerts.medium_count}}"
  consumes:
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: dependabot-alerts
          path: "/repos/{{repo}}/dependabot/alerts"
          inputParameters:
            - name: repo
              in: path
          operations:
            - name: list-dependabot-alerts
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Checks a GitHub repository for branch protection, CODEOWNERS file, and required status checks, then posts a compliance summary to Slack.

naftiko: "0.5"
info:
  label: "GitHub Repo Compliance Check"
  description: "Checks a GitHub repository for branch protection, CODEOWNERS file, and required status checks, then posts a compliance summary to Slack."
  tags:
    - engineering
    - compliance
    - github
    - slack
capability:
  exposes:
    - type: mcp
      namespace: eng-compliance
      port: 8080
      tools:
        - name: check-repo-compliance
          description: "Given a GitHub repository name, verify branch protection rules, CODEOWNERS presence, and required status checks. Posts a compliance summary to the security Slack channel."
          inputParameters:
            - name: repo_name
              in: body
              type: string
              description: "GitHub repository name in org/repo format."
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel for compliance report."
          steps:
            - name: get-branch-protection
              type: call
              call: github.get-branch-protection
              with:
                repo: "{{repo_name}}"
                branch: "main"
            - name: get-codeowners
              type: call
              call: github.get-file
              with:
                repo: "{{repo_name}}"
                path: "CODEOWNERS"
            - name: post-summary
              type: call
              call: slack.post-message
              with:
                channel: "{{slack_channel}}"
                text: "Compliance check for {{repo_name}}: Branch protection={{get-branch-protection.enabled}}, CODEOWNERS={{get-codeowners.exists}}"
  consumes:
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: branch-protection
          path: "/repos/{{repo}}/branches/{{branch}}/protection"
          inputParameters:
            - name: repo
              in: path
            - name: branch
              in: path
          operations:
            - name: get-branch-protection
              method: GET
        - name: contents
          path: "/repos/{{repo}}/contents/{{path}}"
          inputParameters:
            - name: repo
              in: path
            - name: path
              in: path
          operations:
            - name: get-file
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When GitHub Advanced Security detects a critical CVE, creates a Jira security ticket, logs a Datadog event, and alerts the security engineering Teams channel.

naftiko: "0.5"
info:
  label: "GitHub Security Vulnerability Triage"
  description: "When GitHub Advanced Security detects a critical CVE, creates a Jira security ticket, logs a Datadog event, and alerts the security engineering Teams channel."
  tags:
    - security
    - github
    - devops
    - jira
    - vulnerability
capability:
  exposes:
    - type: mcp
      namespace: sec-vuln
      port: 8080
      tools:
        - name: triage-security-alert
          description: "Given a GitHub security alert with CVE, severity, and affected package, create a high-priority Jira security ticket, log a Datadog error event, and alert the security engineering Teams channel. Use when GitHub Advanced Security finds a critical CVE in an Adobe repo."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "GitHub repository full name."
            - name: cve_id
              in: body
              type: string
              description: "CVE identifier."
            - name: severity
              in: body
              type: string
              description: "Severity: critical, high, medium, or low."
            - name: package_name
              in: body
              type: string
              description: "Affected package name."
            - name: sec_channel_id
              in: body
              type: string
              description: "Security engineering Teams channel ID."
          steps:
            - name: create-sec-ticket
              type: call
              call: jira-sec.create-issue
              with:
                project_key: "SEC"
                issuetype: "Bug"
                summary: "[{{severity}}] {{cve_id}} in {{repo}} — {{package_name}}"
                description: "CVE: {{cve_id}} | Package: {{package_name}} | Severity: {{severity}}"
                priority: "Highest"
            - name: log-dd-event
              type: call
              call: datadog-sec.create-event
              with:
                title: "Security: {{cve_id}} in {{repo}}"
                text: "Package {{package_name}} | Severity: {{severity}} | Jira: {{create-sec-ticket.key}}"
                alert_type: "error"
            - name: alert-sec-team
              type: call
              call: msteams-sec.post-channel-message
              with:
                channel_id: "{{sec_channel_id}}"
                text: "SECURITY: {{severity}} CVE {{cve_id}} in {{repo}} / {{package_name}} | Jira: {{create-sec-ticket.key}} | Datadog: {{log-dd-event.url}}"
  consumes:
    - type: http
      namespace: jira-sec
      baseUri: "https://adobe.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: datadog-sec
      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: msteams-sec
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Retrieves performance metrics for a Google Ads campaign, returning impressions, clicks, conversions, and cost.

naftiko: "0.5"
info:
  label: "Google Ads Campaign Performance"
  description: "Retrieves performance metrics for a Google Ads campaign, returning impressions, clicks, conversions, and cost."
  tags:
    - marketing
    - advertising
    - google-ads
capability:
  exposes:
    - type: mcp
      namespace: paid-media
      port: 8080
      tools:
        - name: get-campaign-performance
          description: "Given a Google Ads customer ID and campaign ID, return impressions, clicks, conversions, and total cost for the last 7 days."
          inputParameters:
            - name: customer_id
              in: body
              type: string
              description: "Google Ads customer ID."
            - name: campaign_id
              in: body
              type: string
              description: "Google Ads campaign ID."
          call: google-ads.get-campaign-metrics
          with:
            customer_id: "{{customer_id}}"
            campaign_id: "{{campaign_id}}"
          outputParameters:
            - name: impressions
              type: integer
              mapping: "$.results[0].metrics.impressions"
            - name: clicks
              type: integer
              mapping: "$.results[0].metrics.clicks"
            - name: conversions
              type: number
              mapping: "$.results[0].metrics.conversions"
            - name: cost_micros
              type: number
              mapping: "$.results[0].metrics.costMicros"
  consumes:
    - type: http
      namespace: google-ads
      baseUri: "https://googleads.googleapis.com/v15"
      authentication:
        type: bearer
        token: "$secrets.google_ads_token"
      resources:
        - name: campaigns
          path: "/customers/{{customer_id}}/googleAds:searchStream"
          inputParameters:
            - name: customer_id
              in: path
          operations:
            - name: get-campaign-metrics
              method: POST

Fetches a Google Analytics weekly traffic summary and posts the key metrics to a marketing Slack channel.

naftiko: "0.5"
info:
  label: "Google Analytics Report to Slack"
  description: "Fetches a Google Analytics weekly traffic summary and posts the key metrics to a marketing Slack channel."
  tags:
    - marketing
    - analytics
    - google-analytics
    - slack
capability:
  exposes:
    - type: mcp
      namespace: marketing-analytics
      port: 8080
      tools:
        - name: post-weekly-traffic
          description: "Fetch weekly Google Analytics traffic metrics and post a summary to the marketing Slack channel."
          inputParameters:
            - name: property_id
              in: body
              type: string
              description: "Google Analytics property ID."
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel for the report."
          steps:
            - name: get-report
              type: call
              call: ga.run-report
              with:
                property_id: "{{property_id}}"
                date_range: "last7days"
            - name: post-slack
              type: call
              call: slack.post-message
              with:
                channel: "{{slack_channel}}"
                text: "Weekly traffic: {{get-report.sessions}} sessions, {{get-report.users}} users, {{get-report.bounce_rate}}% bounce rate"
  consumes:
    - type: http
      namespace: ga
      baseUri: "https://analyticsdata.googleapis.com/v1beta"
      authentication:
        type: bearer
        token: "$secrets.google_analytics_token"
      resources:
        - name: reports
          path: "/properties/{{property_id}}:runReport"
          inputParameters:
            - name: property_id
              in: path
          operations:
            - name: run-report
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves sharing permissions for a Google Drive file and returns a list of users with access level.

naftiko: "0.5"
info:
  label: "Google Drive File Permission Audit"
  description: "Retrieves sharing permissions for a Google Drive file and returns a list of users with access level."
  tags:
    - security
    - collaboration
    - google-drive
capability:
  exposes:
    - type: mcp
      namespace: data-governance
      port: 8080
      tools:
        - name: audit-file-permissions
          description: "Given a Google Drive file ID, return all permission entries with email, role, and type. Use for data access reviews."
          inputParameters:
            - name: file_id
              in: body
              type: string
              description: "Google Drive file ID."
          call: gdrive.list-permissions
          with:
            file_id: "{{file_id}}"
          outputParameters:
            - name: permissions
              type: array
              mapping: "$.permissions[*]"
  consumes:
    - type: http
      namespace: gdrive
      baseUri: "https://www.googleapis.com/drive/v3"
      authentication:
        type: bearer
        token: "$secrets.google_drive_token"
      resources:
        - name: permissions
          path: "/files/{{file_id}}/permissions"
          inputParameters:
            - name: file_id
              in: path
          operations:
            - name: list-permissions
              method: GET

Publishes a Google Tag Manager container version and notifies the marketing analytics Slack channel of the deployment.

naftiko: "0.5"
info:
  label: "Google Tag Manager Container Version Publish"
  description: "Publishes a Google Tag Manager container version and notifies the marketing analytics Slack channel of the deployment."
  tags:
    - marketing
    - analytics
    - google-tag-manager
    - slack
capability:
  exposes:
    - type: mcp
      namespace: martech-ops
      port: 8080
      tools:
        - name: publish-gtm-version
          description: "Given a GTM account, container, and version IDs, publish the container version and notify the analytics Slack channel."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "GTM account ID."
            - name: container_id
              in: body
              type: string
              description: "GTM container ID."
            - name: version_id
              in: body
              type: string
              description: "GTM container version ID."
          steps:
            - name: publish-version
              type: call
              call: gtm.publish-version
              with:
                account_id: "{{account_id}}"
                container_id: "{{container_id}}"
                version_id: "{{version_id}}"
            - name: notify-slack
              type: call
              call: slack.post-message
              with:
                channel: "marketing-analytics"
                text: "GTM container {{container_id}} version {{version_id}} published successfully."
  consumes:
    - type: http
      namespace: gtm
      baseUri: "https://www.googleapis.com/tagmanager/v2"
      authentication:
        type: bearer
        token: "$secrets.google_gtm_token"
      resources:
        - name: versions
          path: "/accounts/{{account_id}}/containers/{{container_id}}/versions/{{version_id}}:publish"
          inputParameters:
            - name: account_id
              in: path
            - name: container_id
              in: path
            - name: version_id
              in: path
          operations:
            - name: publish-version
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves the current state of a Grafana alert rule by UID, returning firing status and evaluation timestamp.

naftiko: "0.5"
info:
  label: "Grafana Alert Rule Status"
  description: "Retrieves the current state of a Grafana alert rule by UID, returning firing status and evaluation timestamp."
  tags:
    - monitoring
    - observability
    - grafana
capability:
  exposes:
    - type: mcp
      namespace: observability
      port: 8080
      tools:
        - name: get-alert-rule-status
          description: "Given a Grafana alert rule UID, return the current state, last evaluation time, and labels."
          inputParameters:
            - name: rule_uid
              in: body
              type: string
              description: "Grafana alert rule UID."
          call: grafana.get-alert-rule
          with:
            uid: "{{rule_uid}}"
          outputParameters:
            - name: state
              type: string
              mapping: "$.state"
            - name: last_eval
              type: string
              mapping: "$.lastEvaluation"
  consumes:
    - type: http
      namespace: grafana
      baseUri: "https://grafana.adobe.com/api"
      authentication:
        type: bearer
        token: "$secrets.grafana_token"
      resources:
        - name: alert-rules
          path: "/v1/provisioning/alert-rules/{{uid}}"
          inputParameters:
            - name: uid
              in: path
          operations:
            - name: get-alert-rule
              method: GET

Fetches a Salesforce contact record and syncs enriched fields (title, phone, company) into HubSpot for marketing campaigns.

naftiko: "0.5"
info:
  label: "HubSpot Contact Enrichment from Salesforce"
  description: "Fetches a Salesforce contact record and syncs enriched fields (title, phone, company) into HubSpot for marketing campaigns."
  tags:
    - marketing
    - crm
    - hubspot
    - salesforce
capability:
  exposes:
    - type: mcp
      namespace: marketing-sync
      port: 8080
      tools:
        - name: enrich-hubspot-contact
          description: "Given a Salesforce contact ID, fetch enriched fields and upsert them into the matching HubSpot contact record."
          inputParameters:
            - name: sf_contact_id
              in: body
              type: string
              description: "Salesforce contact ID."
          steps:
            - name: get-sf-contact
              type: call
              call: salesforce.get-contact
              with:
                contact_id: "{{sf_contact_id}}"
            - name: upsert-hubspot
              type: call
              call: hubspot.upsert-contact
              with:
                email: "{{get-sf-contact.Email}}"
                properties:
                  firstname: "{{get-sf-contact.FirstName}}"
                  lastname: "{{get-sf-contact.LastName}}"
                  jobtitle: "{{get-sf-contact.Title}}"
                  company: "{{get-sf-contact.Account.Name}}"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://adobe.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
    - type: http
      namespace: hubspot
      baseUri: "https://api.hubapi.com"
      authentication:
        type: bearer
        token: "$secrets.hubspot_token"
      resources:
        - name: contacts
          path: "/crm/v3/objects/contacts"
          operations:
            - name: upsert-contact
              method: POST

Creates a ServiceNow change request for planned maintenance and notifies the CAB Teams channel for approval.

naftiko: "0.5"
info:
  label: "IT Change Management Request Submission"
  description: "Creates a ServiceNow change request for planned maintenance and notifies the CAB Teams channel for approval."
  tags:
    - itsm
    - change-management
    - servicenow
    - approval
capability:
  exposes:
    - type: mcp
      namespace: change-management
      port: 8080
      tools:
        - name: submit-change-request
          description: "Given a change description and planned maintenance window, create a ServiceNow change request and notify the CAB Teams channel. Use when engineering teams need to schedule planned maintenance on Adobe production systems."
          inputParameters:
            - name: short_description
              in: body
              type: string
              description: "Brief description of the planned change."
            - name: description
              in: body
              type: string
              description: "Full change details including rollback plan and systems affected."
            - name: planned_start
              in: body
              type: string
              description: "Planned start time in ISO 8601 format."
            - name: planned_end
              in: body
              type: string
              description: "Planned end time in ISO 8601 format."
            - name: cab_channel_id
              in: body
              type: string
              description: "CAB Teams channel ID."
          steps:
            - name: create-change
              type: call
              call: servicenow-change.create-change-request
              with:
                short_description: "{{short_description}}"
                description: "{{description}}"
                start_date: "{{planned_start}}"
                end_date: "{{planned_end}}"
            - name: notify-cab
              type: call
              call: msteams-cab.post-channel-message
              with:
                channel_id: "{{cab_channel_id}}"
                text: "Change Request {{create-change.number}}: {{short_description}} | Window: {{planned_start}} to {{planned_end}} | Awaiting CAB approval"
  consumes:
    - type: http
      namespace: servicenow-change
      baseUri: "https://adobe.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: change-requests
          path: "/table/change_request"
          operations:
            - name: create-change-request
              method: POST
    - type: http
      namespace: msteams-cab
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

When Datadog fires a critical alert on a production service, opens a P1 ServiceNow incident, pages the on-call engineer via PagerDuty, and posts to the IT war-room Teams channel.

naftiko: "0.5"
info:
  label: "IT P1 Incident Triage"
  description: "When Datadog fires a critical alert on a production service, opens a P1 ServiceNow incident, pages the on-call engineer via PagerDuty, and posts to the IT war-room Teams channel."
  tags:
    - itsm
    - incident-response
    - datadog
    - pagerduty
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: it-ops
      port: 8080
      tools:
        - name: handle-critical-alert
          description: "Given a Datadog critical alert for a production Adobe service, create a P1 ServiceNow incident, trigger PagerDuty to page the on-call engineer, and post to the IT war-room Teams channel. Use when monitoring detects a critical service failure."
          inputParameters:
            - name: alert_id
              in: body
              type: string
              description: "Datadog monitor alert ID."
            - name: service_name
              in: body
              type: string
              description: "Affected Adobe service name."
            - name: alert_message
              in: body
              type: string
              description: "Human-readable alert description."
            - name: warroom_channel_id
              in: body
              type: string
              description: "IT war-room Teams channel ID."
          steps:
            - name: create-incident
              type: call
              call: servicenow.create-incident
              with:
                short_description: "P1 Alert — {{service_name}}"
                description: "Datadog alert {{alert_id}}: {{alert_message}}"
                priority: "1"
            - name: page-oncall
              type: call
              call: pagerduty.trigger-incident
              with:
                title: "P1 — {{service_name}}"
                severity: "critical"
                details: "INC: {{create-incident.number}} | Alert: {{alert_id}}"
            - name: post-warroom
              type: call
              call: msteams-it.post-channel-message
              with:
                channel_id: "{{warroom_channel_id}}"
                text: "P1 INCIDENT: {{service_name}} | INC: {{create-incident.number}} | PagerDuty: {{page-oncall.incident_key}} | {{alert_message}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://adobe.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
      baseUri: "https://events.pagerduty.com/v2"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.pagerduty_token"
        placement: header
      resources:
        - name: enqueue
          path: "/enqueue"
          operations:
            - name: trigger-incident
              method: POST
    - type: http
      namespace: msteams-it
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Searches Jira for overdue tickets, escalates their priority, and posts an escalation summary to the engineering Slack channel.

naftiko: "0.5"
info:
  label: "Jira Overdue Ticket Escalation"
  description: "Searches Jira for overdue tickets, escalates their priority, and posts an escalation summary to the engineering Slack channel."
  tags:
    - engineering
    - project-management
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: eng-ops
      port: 8080
      tools:
        - name: escalate-overdue-tickets
          description: "Search Jira for tickets past their due date in a given project, bump their priority, and post an escalation summary to Slack."
          inputParameters:
            - name: project_key
              in: body
              type: string
              description: "Jira project key."
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel for escalation notices."
          steps:
            - name: search-overdue
              type: call
              call: jira.search-issues
              with:
                jql: "project={{project_key}} AND duedate < now() AND status != Done"
            - name: post-escalation
              type: call
              call: slack.post-message
              with:
                channel: "{{slack_channel}}"
                text: "Overdue tickets in {{project_key}}: {{search-overdue.total}} issues need attention."
  consumes:
    - type: http
      namespace: jira
      baseUri: "https://adobe.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_token"
      resources:
        - name: search
          path: "/search"
          operations:
            - name: search-issues
              method: POST
    - type: http
      namespace: 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

Fetches all completed Jira issues for a version, formats release notes, and publishes them as a Confluence page.

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

At sprint close, fetches Jira velocity metrics, refreshes the Power BI agile dashboard, and posts a sprint summary to the engineering Teams channel.

naftiko: "0.5"
info:
  label: "Jira Sprint Velocity Report Publication"
  description: "At sprint close, fetches Jira velocity metrics, refreshes the Power BI agile dashboard, and posts a sprint summary to the engineering Teams channel."
  tags:
    - devops
    - jira
    - agile
    - power-bi
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: agile-reporting
      port: 8080
      tools:
        - name: publish-sprint-velocity
          description: "Given a Jira board ID and sprint ID, retrieve completed story points and velocity metrics, refresh the Power BI agile dashboard, and post a sprint summary to the engineering Teams channel. Use at each sprint close."
          inputParameters:
            - name: board_id
              in: body
              type: string
              description: "Jira software board ID."
            - name: sprint_id
              in: body
              type: string
              description: "Completed sprint ID."
            - name: pbi_dataset_id
              in: body
              type: string
              description: "Power BI dataset ID for the agile velocity dashboard."
            - name: eng_channel_id
              in: body
              type: string
              description: "Engineering Teams channel ID."
          steps:
            - name: get-sprint-metrics
              type: call
              call: jira-agile.get-sprint-report
              with:
                board_id: "{{board_id}}"
                sprint_id: "{{sprint_id}}"
            - name: refresh-pbi-agile
              type: call
              call: powerbi-agile.trigger-refresh
              with:
                dataset_id: "{{pbi_dataset_id}}"
            - name: post-summary
              type: call
              call: msteams-agile.post-channel-message
              with:
                channel_id: "{{eng_channel_id}}"
                text: "Sprint {{sprint_id}} closed. Velocity: {{get-sprint-metrics.completed_points}} pts | Completion: {{get-sprint-metrics.completion_rate}}% | Dashboard refreshed."
  consumes:
    - type: http
      namespace: jira-agile
      baseUri: "https://adobe.atlassian.net/rest/agile/1.0"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_token"
      resources:
        - name: sprint-issues
          path: "/board/{{board_id}}/sprint/{{sprint_id}}/issue"
          inputParameters:
            - name: board_id
              in: path
            - name: sprint_id
              in: path
          operations:
            - name: get-sprint-report
              method: GET
    - type: http
      namespace: powerbi-agile
      baseUri: "https://api.powerbi.com/v1.0/myorg"
      authentication:
        type: bearer
        token: "$secrets.powerbi_token"
      resources:
        - name: dataset-refreshes
          path: "/datasets/{{dataset_id}}/refreshes"
          inputParameters:
            - name: dataset_id
              in: path
          operations:
            - name: trigger-refresh
              method: POST
    - type: http
      namespace: msteams-agile
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

When a Kubernetes pod enters CrashLoopBackOff, captures logs via Datadog, creates a Jira ticket, and alerts the platform Slack channel.

naftiko: "0.5"
info:
  label: "Kubernetes Pod Restart Handler"
  description: "When a Kubernetes pod enters CrashLoopBackOff, captures logs via Datadog, creates a Jira ticket, and alerts the platform Slack channel."
  tags:
    - infrastructure
    - containers
    - kubernetes
    - datadog
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: platform-ops
      port: 8080
      tools:
        - name: handle-pod-crash
          description: "Given a Kubernetes namespace and pod name, fetch recent logs from Datadog, create a Jira investigation ticket, and alert the platform Slack channel."
          inputParameters:
            - name: namespace
              in: body
              type: string
              description: "Kubernetes namespace."
            - name: pod_name
              in: body
              type: string
              description: "Pod name in CrashLoopBackOff."
          steps:
            - name: fetch-logs
              type: call
              call: datadog.search-logs
              with:
                query: "kube_namespace:{{namespace}} pod_name:{{pod_name}}"
                limit: 50
            - name: create-ticket
              type: call
              call: jira.create-issue
              with:
                project_key: "PLATFORM"
                issuetype: "Bug"
                summary: "CrashLoopBackOff: {{pod_name}} in {{namespace}}"
                description: "Pod {{pod_name}} in namespace {{namespace}} is crash-looping. Recent logs attached."
            - name: alert-slack
              type: call
              call: slack.post-message
              with:
                channel: "platform-alerts"
                text: "CrashLoopBackOff: {{pod_name}} in {{namespace}} | Jira: {{create-ticket.key}}"
  consumes:
    - type: http
      namespace: datadog
      baseUri: "https://api.datadoghq.com/api/v2"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: logs
          path: "/logs/events/search"
          operations:
            - name: search-logs
              method: POST
    - type: http
      namespace: jira
      baseUri: "https://adobe.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a new job requisition is approved in Workday, creates the corresponding job posting on LinkedIn and updates the requisition with the LinkedIn post URL.

naftiko: "0.5"
info:
  label: "LinkedIn Job Posting Sync"
  description: "When a new job requisition is approved in Workday, creates the corresponding job posting on LinkedIn and updates the requisition with the LinkedIn post URL."
  tags:
    - hr
    - recruiting
    - workday
    - linkedin
capability:
  exposes:
    - type: mcp
      namespace: recruiting-ops
      port: 8080
      tools:
        - name: sync-job-to-linkedin
          description: "Given a Workday requisition ID, fetch the job details and create a LinkedIn job posting. Update Workday with the LinkedIn URL."
          inputParameters:
            - name: requisition_id
              in: body
              type: string
              description: "Workday job requisition ID."
          steps:
            - name: get-requisition
              type: call
              call: workday.get-requisition
              with:
                requisition_id: "{{requisition_id}}"
            - name: create-linkedin-post
              type: call
              call: linkedin.create-job
              with:
                title: "{{get-requisition.title}}"
                description: "{{get-requisition.description}}"
                location: "{{get-requisition.location}}"
            - name: update-workday
              type: call
              call: workday.update-requisition
              with:
                requisition_id: "{{requisition_id}}"
                linkedin_url: "{{create-linkedin-post.url}}"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd5-impl-services1.workday.com/ccx/service/adobe"
      authentication:
        type: basic
        username: "$secrets.workday_user"
        password: "$secrets.workday_password"
      resources:
        - name: requisitions
          path: "/Recruiting/v40.0"
          operations:
            - name: get-requisition
              method: GET
            - name: update-requisition
              method: PUT
    - type: http
      namespace: linkedin
      baseUri: "https://api.linkedin.com/v2"
      authentication:
        type: bearer
        token: "$secrets.linkedin_token"
      resources:
        - name: jobs
          path: "/simpleJobPostings"
          operations:
            - name: create-job
              method: POST

Retrieves Adobe's LinkedIn campaign performance metrics, enriches Marketo lead records with engagement signals, and posts a weekly digest to the social media Teams channel.

naftiko: "0.5"
info:
  label: "LinkedIn Social Campaign Performance"
  description: "Retrieves Adobe's LinkedIn campaign performance metrics, enriches Marketo lead records with engagement signals, and posts a weekly digest to the social media Teams channel."
  tags:
    - marketing
    - social
    - linkedin
    - marketo
    - analytics
capability:
  exposes:
    - type: mcp
      namespace: social-analytics
      port: 8080
      tools:
        - name: digest-linkedin-campaign
          description: "Given a LinkedIn campaign ID and Marketo program ID, retrieve campaign impressions, clicks, and conversion data from LinkedIn, enrich Marketo with engagement signals, and post a digest to the social media Teams channel. Use weekly to review LinkedIn campaign performance."
          inputParameters:
            - name: linkedin_campaign_id
              in: body
              type: string
              description: "LinkedIn campaign ID to retrieve metrics for."
            - name: marketo_program_id
              in: body
              type: string
              description: "Marketo program ID to update with engagement data."
            - name: social_channel_id
              in: body
              type: string
              description: "Social media Teams channel ID."
          steps:
            - name: get-linkedin-metrics
              type: call
              call: linkedin.get-campaign-analytics
              with:
                campaign_id: "{{linkedin_campaign_id}}"
            - name: update-marketo-program
              type: call
              call: marketo-social.update-program
              with:
                program_id: "{{marketo_program_id}}"
                impressions: "{{get-linkedin-metrics.impressions}}"
                clicks: "{{get-linkedin-metrics.clicks}}"
                conversions: "{{get-linkedin-metrics.conversions}}"
            - name: post-digest
              type: call
              call: msteams-social.post-channel-message
              with:
                channel_id: "{{social_channel_id}}"
                text: "LinkedIn Campaign {{linkedin_campaign_id}}: {{get-linkedin-metrics.impressions}} impressions | {{get-linkedin-metrics.clicks}} clicks | {{get-linkedin-metrics.conversions}} conversions | CTR: {{get-linkedin-metrics.ctr}}%"
  consumes:
    - type: http
      namespace: linkedin
      baseUri: "https://api.linkedin.com/v2"
      authentication:
        type: bearer
        token: "$secrets.linkedin_token"
      resources:
        - name: campaign-analytics
          path: "/adAnalytics"
          inputParameters:
            - name: campaign_id
              in: query
          operations:
            - name: get-campaign-analytics
              method: GET
    - type: http
      namespace: marketo-social
      baseUri: "https://adobe.mktorest.com/rest/v1"
      authentication:
        type: bearer
        token: "$secrets.marketo_token"
      resources:
        - name: programs
          path: "/programs/{{program_id}}.json"
          inputParameters:
            - name: program_id
              in: path
          operations:
            - name: update-program
              method: POST
    - type: http
      namespace: msteams-social
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Retrieves the send report for a Mailchimp campaign, returning open rate, click rate, and total recipients.

naftiko: "0.5"
info:
  label: "Mailchimp Campaign Send Report"
  description: "Retrieves the send report for a Mailchimp campaign, returning open rate, click rate, and total recipients."
  tags:
    - marketing
    - email
    - mailchimp
capability:
  exposes:
    - type: mcp
      namespace: email-ops
      port: 8080
      tools:
        - name: get-campaign-report
          description: "Given a Mailchimp campaign ID, return open rate, click rate, unsubscribe count, and total recipients."
          inputParameters:
            - name: campaign_id
              in: body
              type: string
              description: "Mailchimp campaign ID."
          call: mailchimp.get-report
          with:
            campaign_id: "{{campaign_id}}"
          outputParameters:
            - name: open_rate
              type: number
              mapping: "$.opens.open_rate"
            - name: click_rate
              type: number
              mapping: "$.clicks.click_rate"
            - name: total_recipients
              type: integer
              mapping: "$.emails_sent"
  consumes:
    - type: http
      namespace: mailchimp
      baseUri: "https://us1.api.mailchimp.com/3.0"
      authentication:
        type: basic
        username: "anystring"
        password: "$secrets.mailchimp_api_key"
      resources:
        - name: reports
          path: "/reports/{{campaign_id}}"
          inputParameters:
            - name: campaign_id
              in: path
          operations:
            - name: get-report
              method: GET

Aggregates Marketo campaign engagement metrics, publishes a refreshed Power BI marketing dashboard, and emails the weekly campaign digest to the marketing team.

naftiko: "0.5"
info:
  label: "Marketo Campaign Performance Digest"
  description: "Aggregates Marketo campaign engagement metrics, publishes a refreshed Power BI marketing dashboard, and emails the weekly campaign digest to the marketing team."
  tags:
    - marketing
    - marketo
    - power-bi
    - reporting
    - analytics
capability:
  exposes:
    - type: mcp
      namespace: mkt-reporting
      port: 8080
      tools:
        - name: digest-campaign-performance
          description: "Given a Marketo campaign ID and Power BI dataset ID, retrieve campaign performance metrics from Marketo, trigger a Power BI refresh, and email a digest to the marketing leadership. Use weekly for campaign performance reviews."
          inputParameters:
            - name: marketo_program_id
              in: body
              type: string
              description: "Marketo program ID to retrieve metrics for."
            - name: pbi_dataset_id
              in: body
              type: string
              description: "Power BI dataset ID for the marketing dashboard."
            - name: marketing_email
              in: body
              type: string
              description: "Marketing leadership email distribution list."
          steps:
            - name: get-campaign-metrics
              type: call
              call: marketo.get-program-metrics
              with:
                program_id: "{{marketo_program_id}}"
            - name: refresh-mkt-pbi
              type: call
              call: powerbi-mkt.trigger-refresh
              with:
                dataset_id: "{{pbi_dataset_id}}"
            - name: send-digest
              type: call
              call: msgraph-mkt.send-email
              with:
                to: "{{marketing_email}}"
                subject: "Campaign Performance Digest — Program {{marketo_program_id}}"
                body: "Emails sent: {{get-campaign-metrics.emails_sent}} | Open rate: {{get-campaign-metrics.open_rate}}% | Clicks: {{get-campaign-metrics.clicks}} | Dashboard refreshed."
  consumes:
    - type: http
      namespace: marketo
      baseUri: "https://adobe.mktorest.com/rest/v1"
      authentication:
        type: bearer
        token: "$secrets.marketo_token"
      resources:
        - name: program-metrics
          path: "/stats/programs/{{program_id}}/detail.json"
          inputParameters:
            - name: program_id
              in: path
          operations:
            - name: get-program-metrics
              method: GET
    - type: http
      namespace: powerbi-mkt
      baseUri: "https://api.powerbi.com/v1.0/myorg"
      authentication:
        type: bearer
        token: "$secrets.powerbi_token"
      resources:
        - name: dataset-refreshes
          path: "/datasets/{{dataset_id}}/refreshes"
          inputParameters:
            - name: dataset_id
              in: path
          operations:
            - name: trigger-refresh
              method: POST
    - type: http
      namespace: msgraph-mkt
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: send-mail
          path: "/users/{{sender}}/sendMail"
          operations:
            - name: send-email
              method: POST

Enrolls a qualified Salesforce lead in a Marketo product-specific nurture program based on their Creative Cloud trial activity.

naftiko: "0.5"
info:
  label: "Marketo Lead Nurture Enrollment from Salesforce"
  description: "Enrolls a qualified Salesforce lead in a Marketo product-specific nurture program based on their Creative Cloud trial activity."
  tags:
    - marketing
    - salesforce
    - marketo
    - lead-nurture
    - creative-cloud
capability:
  exposes:
    - type: mcp
      namespace: lead-nurture
      port: 8080
      tools:
        - name: enroll-lead-in-nurture
          description: "Given a Salesforce lead ID and Marketo program ID, retrieve the lead's details from Salesforce and enroll them in the specified Marketo nurture program. Use when a Creative Cloud trial lead qualifies for a nurture track."
          inputParameters:
            - name: salesforce_lead_id
              in: body
              type: string
              description: "Salesforce lead record ID."
            - name: marketo_program_id
              in: body
              type: string
              description: "Marketo program ID for the nurture campaign."
          steps:
            - name: get-lead
              type: call
              call: salesforce-leads.get-lead
              with:
                lead_id: "{{salesforce_lead_id}}"
            - name: enroll-in-program
              type: call
              call: marketo-programs.add-to-program
              with:
                email: "{{get-lead.Email}}"
                first_name: "{{get-lead.FirstName}}"
                last_name: "{{get-lead.LastName}}"
                program_id: "{{marketo_program_id}}"
  consumes:
    - type: http
      namespace: salesforce-leads
      baseUri: "https://adobe.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: leads
          path: "/sobjects/Lead/{{lead_id}}"
          inputParameters:
            - name: lead_id
              in: path
          operations:
            - name: get-lead
              method: GET
    - type: http
      namespace: marketo-programs
      baseUri: "https://adobe.mktorest.com/rest/v1"
      authentication:
        type: bearer
        token: "$secrets.marketo_token"
      resources:
        - name: program-members
          path: "/leads/programs/{{program_id}}.json"
          inputParameters:
            - name: program_id
              in: path
          operations:
            - name: add-to-program
              method: POST

Retrieves a lead record from Marketo and returns the current lead score, status, and last activity date.

naftiko: "0.5"
info:
  label: "Marketo Lead Scoring Update"
  description: "Retrieves a lead record from Marketo and returns the current lead score, status, and last activity date."
  tags:
    - marketing
    - crm
    - marketo
capability:
  exposes:
    - type: mcp
      namespace: marketing-ops
      port: 8080
      tools:
        - name: get-lead-score
          description: "Given a Marketo lead ID, return the current lead score, lifecycle status, and last activity timestamp. Use when sales needs to verify lead qualification before outreach."
          inputParameters:
            - name: lead_id
              in: body
              type: string
              description: "Marketo lead ID."
          call: marketo.get-lead
          with:
            lead_id: "{{lead_id}}"
          outputParameters:
            - name: lead_score
              type: number
              mapping: "$.result[0].leadScore"
            - name: status
              type: string
              mapping: "$.result[0].status"
            - name: last_activity
              type: string
              mapping: "$.result[0].lastActivityDate"
  consumes:
    - type: http
      namespace: marketo
      baseUri: "https://adobe-mkt.mktorest.com/rest/v1"
      authentication:
        type: bearer
        token: "$secrets.marketo_access_token"
      resources:
        - name: leads
          path: "/lead/{{lead_id}}.json"
          inputParameters:
            - name: lead_id
              in: path
          operations:
            - name: get-lead
              method: GET

Retrieves performance insights for a Meta (Facebook) advertising campaign, returning reach, impressions, spend, and conversions.

naftiko: "0.5"
info:
  label: "Meta Ads Campaign Report"
  description: "Retrieves performance insights for a Meta (Facebook) advertising campaign, returning reach, impressions, spend, and conversions."
  tags:
    - marketing
    - advertising
    - meta
    - facebook
capability:
  exposes:
    - type: mcp
      namespace: paid-media
      port: 8080
      tools:
        - name: get-meta-campaign-report
          description: "Given a Meta ad campaign ID, return reach, impressions, spend, and conversion count for the specified date range."
          inputParameters:
            - name: campaign_id
              in: body
              type: string
              description: "Meta Ads campaign ID."
            - name: date_preset
              in: body
              type: string
              description: "Date preset (e.g., last_7d, last_30d)."
          call: meta-ads.get-insights
          with:
            campaign_id: "{{campaign_id}}"
            date_preset: "{{date_preset}}"
          outputParameters:
            - name: reach
              type: integer
              mapping: "$.data[0].reach"
            - name: impressions
              type: integer
              mapping: "$.data[0].impressions"
            - name: spend
              type: string
              mapping: "$.data[0].spend"
  consumes:
    - type: http
      namespace: meta-ads
      baseUri: "https://graph.facebook.com/v18.0"
      authentication:
        type: bearer
        token: "$secrets.meta_ads_token"
      resources:
        - name: insights
          path: "/{{campaign_id}}/insights"
          inputParameters:
            - name: campaign_id
              in: path
          operations:
            - name: get-insights
              method: GET

Retrieves Microsoft 365 license usage data via Microsoft Graph, returning active users by product and available licenses.

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

Creates a new Microsoft Teams channel for a project and posts a welcome message with links to Jira board and Confluence space.

naftiko: "0.5"
info:
  label: "Microsoft Teams Channel Provisioning"
  description: "Creates a new Microsoft Teams channel for a project and posts a welcome message with links to Jira board and Confluence space."
  tags:
    - collaboration
    - project-management
    - microsoft-teams
    - jira
    - confluence
capability:
  exposes:
    - type: mcp
      namespace: collab-ops
      port: 8080
      tools:
        - name: provision-project-channel
          description: "Given a project name, create a Teams channel, and post a welcome message with links to the corresponding Jira board and Confluence space."
          inputParameters:
            - name: project_name
              in: body
              type: string
              description: "Project name for the new channel."
            - name: team_id
              in: body
              type: string
              description: "Microsoft Teams team ID."
            - name: jira_board_url
              in: body
              type: string
              description: "Jira board URL for the project."
            - name: confluence_space_url
              in: body
              type: string
              description: "Confluence space URL."
          steps:
            - name: create-channel
              type: call
              call: msteams.create-channel
              with:
                team_id: "{{team_id}}"
                display_name: "{{project_name}}"
                description: "Project channel for {{project_name}}"
            - name: post-welcome
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "{{create-channel.id}}"
                text: "Welcome to {{project_name}}! Jira: {{jira_board_url}} | Confluence: {{confluence_space_url}}"
  consumes:
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channels
          path: "/teams/{{team_id}}/channels"
          inputParameters:
            - name: team_id
              in: path
          operations:
            - name: create-channel
              method: POST
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Triggers SAP S/4HANA month-end financial close for Adobe's fiscal period, validates journal completeness, and notifies the finance team via Teams.

naftiko: "0.5"
info:
  label: "Monthly Financial Period Close"
  description: "Triggers SAP S/4HANA month-end financial close for Adobe's fiscal period, validates journal completeness, and notifies the finance team via Teams."
  tags:
    - finance
    - erp
    - period-close
    - sap
    - accounting
capability:
  exposes:
    - type: mcp
      namespace: finance-close
      port: 8080
      tools:
        - name: trigger-period-close
          description: "Given a fiscal period and company code, initiate the SAP period close sequence and validate journal postings. Post completion status to the finance Teams channel. Use at month end to automate the financial close workflow."
          inputParameters:
            - name: fiscal_period
              in: body
              type: string
              description: "Fiscal period in YYYYPP format, e.g. '202603'."
            - name: company_code
              in: body
              type: string
              description: "SAP company code, e.g. 'ADBE'."
            - name: finance_channel_id
              in: body
              type: string
              description: "Finance Teams channel ID."
          steps:
            - name: close-period
              type: call
              call: sap-fi.close-period
              with:
                fiscal_period: "{{fiscal_period}}"
                company_code: "{{company_code}}"
            - name: validate-journals
              type: call
              call: sap-journals.check-completeness
              with:
                fiscal_period: "{{fiscal_period}}"
                company_code: "{{company_code}}"
            - name: notify-finance
              type: call
              call: msteams-finance.post-channel-message
              with:
                channel_id: "{{finance_channel_id}}"
                text: "Period {{fiscal_period}} close complete for {{company_code}}. Journal status: {{validate-journals.status}} | Open items: {{validate-journals.open_count}}"
  consumes:
    - type: http
      namespace: sap-fi
      baseUri: "https://adobe-s4.sap.com/sap/opu/odata/sap/FAR_PERIOD_CLOSE_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: period-close
          path: "/PeriodClose"
          operations:
            - name: close-period
              method: POST
    - type: http
      namespace: sap-journals
      baseUri: "https://adobe-s4.sap.com/sap/opu/odata/sap/FAR_JOURNAL_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: journal-validation
          path: "/JournalEntryCompleteness"
          inputParameters:
            - name: fiscal_period
              in: query
            - name: company_code
              in: query
          operations:
            - name: check-completeness
              method: GET
    - type: http
      namespace: msteams-finance
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

When a new employee is created in Workday, opens a ServiceNow onboarding ticket, provisions their Okta account, and sends a Microsoft Teams welcome message.

naftiko: "0.5"
info:
  label: "New Employee Onboarding Orchestration"
  description: "When a new employee is created in Workday, opens a ServiceNow onboarding ticket, provisions their Okta account, and sends a Microsoft Teams welcome message."
  tags:
    - hr
    - onboarding
    - workday
    - servicenow
    - okta
capability:
  exposes:
    - type: mcp
      namespace: hr-onboarding
      port: 8080
      tools:
        - name: trigger-employee-onboarding
          description: "Given a Workday employee ID and start date, create a ServiceNow onboarding task, provision their Okta account, and send a Teams welcome message. Use when HR confirms a new hire in Workday."
          inputParameters:
            - name: workday_employee_id
              in: body
              type: string
              description: "Workday worker ID for the new hire."
            - name: start_date
              in: body
              type: string
              description: "Employee start date in YYYY-MM-DD format."
          steps:
            - name: get-employee
              type: call
              call: workday.get-worker
              with:
                worker_id: "{{workday_employee_id}}"
            - name: create-ticket
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Onboarding: {{get-employee.first_name}} {{get-employee.last_name}}"
                category: "hr_onboarding"
                assigned_group: "IT_Onboarding"
            - name: provision-okta
              type: call
              call: okta.create-user
              with:
                firstName: "{{get-employee.first_name}}"
                lastName: "{{get-employee.last_name}}"
                email: "{{get-employee.work_email}}"
                login: "{{get-employee.work_email}}"
            - name: send-welcome
              type: call
              call: msteams.send-message
              with:
                recipient_upn: "{{get-employee.work_email}}"
                text: "Welcome to Adobe, {{get-employee.first_name}}! Your onboarding ticket: {{create-ticket.number}}. Start date: {{start_date}}"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://adobe.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: okta
      baseUri: "https://adobe.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: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: messages
          path: "/users/{{recipient_upn}}/sendMail"
          inputParameters:
            - name: recipient_upn
              in: path
          operations:
            - name: send-message
              method: POST

When New Relic triggers a critical alert condition, creates a Jira incident ticket and notifies the on-call team via Slack.

naftiko: "0.5"
info:
  label: "New Relic Alert to Jira"
  description: "When New Relic triggers a critical alert condition, creates a Jira incident ticket and notifies the on-call team via Slack."
  tags:
    - monitoring
    - incident-management
    - new-relic
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: observability-ops
      port: 8080
      tools:
        - name: handle-newrelic-alert
          description: "Given a New Relic alert condition ID and violation details, create a Jira incident and alert the on-call Slack channel."
          inputParameters:
            - name: condition_id
              in: body
              type: string
              description: "New Relic alert condition ID."
            - name: violation_url
              in: body
              type: string
              description: "New Relic violation URL."
            - name: entity_name
              in: body
              type: string
              description: "Affected entity name."
          steps:
            - name: create-jira
              type: call
              call: jira.create-issue
              with:
                project_key: "OPS"
                issuetype: "Bug"
                summary: "New Relic alert: {{entity_name}}"
                description: "Condition {{condition_id}} violated. Details: {{violation_url}}"
            - name: notify-oncall
              type: call
              call: slack.post-message
              with:
                channel: "oncall-alerts"
                text: "New Relic critical alert on {{entity_name}} | Jira: {{create-jira.key}} | {{violation_url}}"
  consumes:
    - type: http
      namespace: jira
      baseUri: "https://adobe.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: 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

Assigns an Okta user to an application and logs the provisioning event to ServiceNow for audit.

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

Retrieves Okta privileged group membership, triggers a Power BI access review report refresh, and emails the security team for certification.

naftiko: "0.5"
info:
  label: "Okta Quarterly Privileged Access Review"
  description: "Retrieves Okta privileged group membership, triggers a Power BI access review report refresh, and emails the security team for certification."
  tags:
    - identity
    - security
    - okta
    - compliance
    - access-review
capability:
  exposes:
    - type: mcp
      namespace: access-review
      port: 8080
      tools:
        - name: run-privileged-access-review
          description: "Given an Okta group ID and Power BI dataset ID, pull current group membership, trigger a Power BI refresh, and email the certification report to the security team. Use quarterly for privileged access reviews."
          inputParameters:
            - name: okta_group_id
              in: body
              type: string
              description: "Okta group ID to certify."
            - name: pbi_dataset_id
              in: body
              type: string
              description: "Power BI dataset ID for access certification reports."
            - name: security_team_email
              in: body
              type: string
              description: "Security team email for the review."
          steps:
            - name: get-group-members
              type: call
              call: okta-review.get-group-users
              with:
                group_id: "{{okta_group_id}}"
            - name: refresh-pbi
              type: call
              call: powerbi-review.trigger-refresh
              with:
                dataset_id: "{{pbi_dataset_id}}"
            - name: send-cert-email
              type: call
              call: msgraph-review.send-email
              with:
                to: "{{security_team_email}}"
                subject: "Quarterly Access Review — Okta Group {{okta_group_id}}"
                body: "Group {{okta_group_id}} has {{get-group-members.total_count}} members. Review in Power BI and certify or revoke access."
  consumes:
    - type: http
      namespace: okta-review
      baseUri: "https://adobe.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_token"
        placement: header
      resources:
        - name: group-users
          path: "/groups/{{group_id}}/users"
          inputParameters:
            - name: group_id
              in: path
          operations:
            - name: get-group-users
              method: GET
    - type: http
      namespace: powerbi-review
      baseUri: "https://api.powerbi.com/v1.0/myorg"
      authentication:
        type: bearer
        token: "$secrets.powerbi_token"
      resources:
        - name: dataset-refreshes
          path: "/datasets/{{dataset_id}}/refreshes"
          inputParameters:
            - name: dataset_id
              in: path
          operations:
            - name: trigger-refresh
              method: POST
    - type: http
      namespace: msgraph-review
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: send-mail
          path: "/users/{{sender}}/sendMail"
          operations:
            - name: send-email
              method: POST

Retrieves all Okta group memberships for a given user, returning group names and IDs for access review.

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

Sends user-generated content to the OpenAI moderation endpoint and, if flagged, creates a Zendesk moderation ticket.

naftiko: "0.5"
info:
  label: "OpenAI Content Moderation"
  description: "Sends user-generated content to the OpenAI moderation endpoint and, if flagged, creates a Zendesk moderation ticket."
  tags:
    - content-safety
    - ai
    - openai
    - zendesk
capability:
  exposes:
    - type: mcp
      namespace: trust-safety
      port: 8080
      tools:
        - name: moderate-content
          description: "Given user-generated text, run it through OpenAI moderation. If flagged, create a Zendesk moderation review ticket."
          inputParameters:
            - name: content
              in: body
              type: string
              description: "User-generated content to moderate."
            - name: user_id
              in: body
              type: string
              description: "User ID who submitted the content."
          steps:
            - name: check-moderation
              type: call
              call: openai.create-moderation
              with:
                input: "{{content}}"
            - name: create-ticket
              type: call
              call: zendesk.create-ticket
              with:
                subject: "Content moderation flag — user {{user_id}}"
                description: "Flagged categories: {{check-moderation.results[0].categories}}"
                priority: "high"
  consumes:
    - type: http
      namespace: openai
      baseUri: "https://api.openai.com/v1"
      authentication:
        type: bearer
        token: "$secrets.openai_api_key"
      resources:
        - name: moderations
          path: "/moderations"
          operations:
            - name: create-moderation
              method: POST
    - type: http
      namespace: zendesk
      baseUri: "https://adobe.zendesk.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.zendesk_token"
      resources:
        - name: tickets
          path: "/tickets.json"
          operations:
            - name: create-ticket
              method: POST

Retrieves an invoice record from Oracle E-Business Suite by invoice number, returning status, amount, and payment date.

naftiko: "0.5"
info:
  label: "Oracle EBS Invoice Status Lookup"
  description: "Retrieves an invoice record from Oracle E-Business Suite by invoice number, returning status, amount, and payment date."
  tags:
    - finance
    - erp
    - oracle
capability:
  exposes:
    - type: mcp
      namespace: finance-ops
      port: 8080
      tools:
        - name: get-invoice-status
          description: "Given an Oracle EBS invoice number, return the invoice status, total amount, and scheduled payment date."
          inputParameters:
            - name: invoice_number
              in: body
              type: string
              description: "Oracle EBS invoice number."
          call: oracle-ebs.get-invoice
          with:
            invoice_num: "{{invoice_number}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.InvoiceStatus"
            - name: amount
              type: number
              mapping: "$.InvoiceAmount"
            - name: payment_date
              type: string
              mapping: "$.ScheduledPaymentDate"
  consumes:
    - type: http
      namespace: oracle-ebs
      baseUri: "https://adobe-ebs.oracle.com/webservices/rest/AP_INVOICES"
      authentication:
        type: basic
        username: "$secrets.oracle_user"
        password: "$secrets.oracle_password"
      resources:
        - name: invoices
          path: "/{{invoice_num}}"
          inputParameters:
            - name: invoice_num
              in: path
          operations:
            - name: get-invoice
              method: GET

Retrieves the current on-call engineer for a given PagerDuty schedule and returns their name, email, and shift end time.

naftiko: "0.5"
info:
  label: "PagerDuty On-Call Schedule Lookup"
  description: "Retrieves the current on-call engineer for a given PagerDuty schedule and returns their name, email, and shift end time."
  tags:
    - engineering
    - incident-management
    - pagerduty
capability:
  exposes:
    - type: mcp
      namespace: incident-ops
      port: 8080
      tools:
        - name: get-on-call
          description: "Given a PagerDuty schedule ID, return the current on-call engineer's name, email, and shift end time."
          inputParameters:
            - name: schedule_id
              in: body
              type: string
              description: "PagerDuty schedule ID."
          call: pagerduty.get-on-call
          with:
            schedule_id: "{{schedule_id}}"
          outputParameters:
            - name: name
              type: string
              mapping: "$.schedule.final_schedule.rendered_schedule_entries[0].user.summary"
            - name: email
              type: string
              mapping: "$.schedule.final_schedule.rendered_schedule_entries[0].user.email"
            - name: shift_end
              type: string
              mapping: "$.schedule.final_schedule.rendered_schedule_entries[0].end"
  consumes:
    - type: http
      namespace: pagerduty
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: bearer
        token: "$secrets.pagerduty_token"
      resources:
        - name: schedules
          path: "/schedules/{{schedule_id}}"
          inputParameters:
            - name: schedule_id
              in: path
          operations:
            - name: get-on-call
              method: GET

Retrieves the latest run results for a Postman API monitor, returning pass/fail count and average response time.

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

Triggers a Power BI dataset refresh by dataset ID and returns the refresh status.

naftiko: "0.5"
info:
  label: "Power BI Dataset Refresh"
  description: "Triggers a Power BI dataset refresh by dataset ID and returns the refresh status."
  tags:
    - analytics
    - reporting
    - power-bi
capability:
  exposes:
    - type: mcp
      namespace: bi-ops
      port: 8080
      tools:
        - name: refresh-dataset
          description: "Given a Power BI dataset ID, trigger a dataset refresh and return the request ID. Use when data pipelines complete and dashboards need updating."
          inputParameters:
            - name: dataset_id
              in: body
              type: string
              description: "Power BI dataset ID."
            - name: group_id
              in: body
              type: string
              description: "Power BI workspace (group) ID."
          call: powerbi.refresh-dataset
          with:
            group_id: "{{group_id}}"
            dataset_id: "{{dataset_id}}"
          outputParameters:
            - name: request_id
              type: string
              mapping: "$.requestId"
  consumes:
    - type: http
      namespace: powerbi
      baseUri: "https://api.powerbi.com/v1.0/myorg"
      authentication:
        type: bearer
        token: "$secrets.powerbi_token"
      resources:
        - name: datasets
          path: "/groups/{{group_id}}/datasets/{{dataset_id}}/refreshes"
          inputParameters:
            - name: group_id
              in: path
            - name: dataset_id
              in: path
          operations:
            - name: refresh-dataset
              method: POST

When a Salesforce support case is escalated to engineering, creates a Jira bug ticket and posts the link back into the Salesforce case notes.

naftiko: "0.5"
info:
  label: "Salesforce Case Escalation to Jira"
  description: "When a Salesforce support case is escalated to engineering, creates a Jira bug ticket and posts the link back into the Salesforce case notes."
  tags:
    - support
    - engineering
    - salesforce
    - jira
capability:
  exposes:
    - type: mcp
      namespace: support-eng
      port: 8080
      tools:
        - name: escalate-case-to-jira
          description: "Given a Salesforce case ID and severity, create a Jira engineering ticket and update the Salesforce case with the Jira link."
          inputParameters:
            - name: case_id
              in: body
              type: string
              description: "Salesforce case ID."
            - name: severity
              in: body
              type: string
              description: "Severity level (P1, P2, P3)."
            - name: summary
              in: body
              type: string
              description: "Brief summary of the engineering issue."
          steps:
            - name: create-jira-ticket
              type: call
              call: jira.create-issue
              with:
                project_key: "ENG"
                issuetype: "Bug"
                summary: "{{summary}}"
                priority: "{{severity}}"
                description: "Escalated from Salesforce case {{case_id}}."
            - name: update-sf-case
              type: call
              call: salesforce.update-case
              with:
                case_id: "{{case_id}}"
                jira_link: "{{create-jira-ticket.key}}"
  consumes:
    - type: http
      namespace: jira
      baseUri: "https://adobe.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: salesforce
      baseUri: "https://adobe.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: update-case
              method: PATCH

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

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

Retrieves the status of a Salesforce Marketing Cloud journey by journey ID, returning active contacts and completion rate.

naftiko: "0.5"
info:
  label: "Salesforce Marketing Cloud Journey Status"
  description: "Retrieves the status of a Salesforce Marketing Cloud journey by journey ID, returning active contacts and completion rate."
  tags:
    - marketing
    - customer-engagement
    - salesforce-marketing-cloud
capability:
  exposes:
    - type: mcp
      namespace: marketing-ops
      port: 8080
      tools:
        - name: get-journey-status
          description: "Given a Salesforce Marketing Cloud journey ID, return the journey status, active contact count, and completion rate."
          inputParameters:
            - name: journey_id
              in: body
              type: string
              description: "Marketing Cloud journey ID."
          call: sfmc.get-journey
          with:
            journey_id: "{{journey_id}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.status"
            - name: active_contacts
              type: integer
              mapping: "$.stats.activeContacts"
            - name: completion_rate
              type: number
              mapping: "$.stats.completionRate"
  consumes:
    - type: http
      namespace: sfmc
      baseUri: "https://adobe.rest.marketingcloudapis.com"
      authentication:
        type: bearer
        token: "$secrets.sfmc_token"
      resources:
        - name: journeys
          path: "/interaction/v1/interactions/{{journey_id}}"
          inputParameters:
            - name: journey_id
              in: path
          operations:
            - name: get-journey
              method: GET

Pulls Adobe's open sales opportunities from Salesforce, refreshes the Power BI pipeline dashboard, and emails a weekly summary to sales leadership.

naftiko: "0.5"
info:
  label: "Salesforce Opportunity Pipeline Digest"
  description: "Pulls Adobe's open sales opportunities from Salesforce, refreshes the Power BI pipeline dashboard, and emails a weekly summary to sales leadership."
  tags:
    - sales
    - crm
    - salesforce
    - power-bi
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: sales-digest
      port: 8080
      tools:
        - name: publish-pipeline-report
          description: "Given a Salesforce opportunity filter and Power BI dataset ID, retrieve the open sales pipeline from Salesforce, trigger a Power BI refresh, and email the pipeline summary to sales leadership. Use weekly for sales forecast reviews."
          inputParameters:
            - name: division
              in: body
              type: string
              description: "Sales division filter, e.g. 'Digital Experience' or 'Creative Cloud'."
            - name: pbi_dataset_id
              in: body
              type: string
              description: "Power BI dataset ID for the pipeline dashboard."
            - name: leadership_email
              in: body
              type: string
              description: "Sales leadership email distribution list."
          steps:
            - name: get-pipeline
              type: call
              call: salesforce.query-opportunities
              with:
                division: "{{division}}"
            - name: refresh-pbi
              type: call
              call: powerbi.trigger-refresh
              with:
                dataset_id: "{{pbi_dataset_id}}"
            - name: send-summary
              type: call
              call: msgraph.send-email
              with:
                to: "{{leadership_email}}"
                subject: "{{division}} Pipeline Report — {{get-pipeline.record_count}} opps | ${{get-pipeline.total_arr}}"
                body: "Open pipeline for {{division}}: {{get-pipeline.record_count}} opportunities totaling ${{get-pipeline.total_arr}} ARR. Power BI refreshed."
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://adobe.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: opportunities
          path: "/query"
          inputParameters:
            - name: division
              in: query
          operations:
            - name: query-opportunities
              method: GET
    - type: http
      namespace: powerbi
      baseUri: "https://api.powerbi.com/v1.0/myorg"
      authentication:
        type: bearer
        token: "$secrets.powerbi_token"
      resources:
        - name: dataset-refreshes
          path: "/datasets/{{dataset_id}}/refreshes"
          inputParameters:
            - name: dataset_id
              in: path
          operations:
            - name: trigger-refresh
              method: POST
    - type: http
      namespace: msgraph
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: send-mail
          path: "/users/{{sender}}/sendMail"
          operations:
            - name: send-email
              method: POST

When a Salesforce opportunity moves to Closed-Won, fetches deal details and posts a celebration message to the sales wins Slack channel.

naftiko: "0.5"
info:
  label: "Salesforce Opportunity Update to Slack"
  description: "When a Salesforce opportunity moves to Closed-Won, fetches deal details and posts a celebration message to the sales wins Slack channel."
  tags:
    - sales
    - crm
    - salesforce
    - slack
capability:
  exposes:
    - type: mcp
      namespace: sales-ops
      port: 8080
      tools:
        - name: announce-closed-won
          description: "Given a Salesforce opportunity ID, fetch deal details and post a win announcement to the Slack sales-wins channel."
          inputParameters:
            - name: opportunity_id
              in: body
              type: string
              description: "Salesforce opportunity ID."
          steps:
            - name: get-opportunity
              type: call
              call: salesforce.get-opportunity
              with:
                opportunity_id: "{{opportunity_id}}"
            - name: post-win
              type: call
              call: slack.post-message
              with:
                channel: "sales-wins"
                text: "Deal Won: {{get-opportunity.Name}} — ${{get-opportunity.Amount}} | Account: {{get-opportunity.Account.Name}}"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://adobe.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: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Queries Salesforce for the current quarter's pipeline by stage, formats the data, and posts the summary to a Microsoft Teams channel.

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

Scans SAP Ariba for supplier contracts expiring within 90 days, creates Jira renewal tasks, and emails contract owners.

naftiko: "0.5"
info:
  label: "SAP Ariba Contract Renewal Alert"
  description: "Scans SAP Ariba for supplier contracts expiring within 90 days, creates Jira renewal tasks, and emails contract owners."
  tags:
    - procurement
    - contract-management
    - sap-ariba
    - jira
capability:
  exposes:
    - type: mcp
      namespace: contract-ops
      port: 8080
      tools:
        - name: alert-expiring-contracts
          description: "Given a look-ahead window in days, fetch expiring supplier contracts from SAP Ariba and create a Jira renewal task for each. Use monthly to proactively manage contract renewals for Adobe's key technology and service vendors."
          inputParameters:
            - name: days_ahead
              in: body
              type: integer
              description: "Number of days ahead to scan for expiring contracts."
            - name: jira_project_key
              in: body
              type: string
              description: "Jira project key for procurement tasks."
          steps:
            - name: get-expiring
              type: call
              call: ariba-contracts.get-expiring-contracts
              with:
                days_ahead: "{{days_ahead}}"
            - name: create-renewal-task
              type: call
              call: jira-contracts.create-issue
              with:
                project_key: "{{jira_project_key}}"
                issuetype: "Task"
                summary: "Contract renewals due within {{days_ahead}} days"
                description: "Expiring contracts: {{get-expiring.contract_ids}}"
  consumes:
    - type: http
      namespace: ariba-contracts
      baseUri: "https://openapi.ariba.com/api/contract/v1"
      authentication:
        type: bearer
        token: "$secrets.ariba_token"
      resources:
        - name: contracts
          path: "/contracts"
          inputParameters:
            - name: days_ahead
              in: query
          operations:
            - name: get-expiring-contracts
              method: GET
    - type: http
      namespace: jira-contracts
      baseUri: "https://adobe.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST

Validates incoming SAP Ariba invoices against open purchase orders and routes exceptions to the accounts payable team via ServiceNow.

naftiko: "0.5"
info:
  label: "SAP Ariba Invoice Processing"
  description: "Validates incoming SAP Ariba invoices against open purchase orders and routes exceptions to the accounts payable team via ServiceNow."
  tags:
    - finance
    - procurement
    - sap-ariba
    - accounts-payable
    - erp
capability:
  exposes:
    - type: mcp
      namespace: ap-ops
      port: 8080
      tools:
        - name: process-ariba-invoice
          description: "Given an SAP Ariba invoice ID and PO number, retrieve and compare both documents, then create a ServiceNow approval task for AP review. Use when processing incoming supplier invoices requiring three-way match."
          inputParameters:
            - name: invoice_id
              in: body
              type: string
              description: "SAP Ariba invoice ID."
            - name: po_number
              in: body
              type: string
              description: "Related SAP purchase order number."
          steps:
            - name: get-invoice
              type: call
              call: ariba.get-invoice
              with:
                invoice_id: "{{invoice_id}}"
            - name: get-po
              type: call
              call: sap-erp.get-purchase-order
              with:
                po_number: "{{po_number}}"
            - name: create-approval
              type: call
              call: servicenow-ap.create-task
              with:
                short_description: "Invoice match: {{invoice_id}} vs PO {{po_number}}"
                description: "Invoice total: {{get-invoice.total_amount}} | PO total: {{get-po.total_amount}} | Vendor: {{get-invoice.vendor_name}}"
                assigned_group: "AP_Team"
  consumes:
    - type: http
      namespace: ariba
      baseUri: "https://openapi.ariba.com/api/invoice/v1"
      authentication:
        type: bearer
        token: "$secrets.ariba_token"
      resources:
        - name: invoices
          path: "/invoices/{{invoice_id}}"
          inputParameters:
            - name: invoice_id
              in: path
          operations:
            - name: get-invoice
              method: GET
    - type: http
      namespace: sap-erp
      baseUri: "https://adobe-s4.sap.com/sap/opu/odata/sap/MM_PUR_PO_MAINT_V2_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: purchase-orders
          path: "/A_PurchaseOrder('{{po_number}}')"
          inputParameters:
            - name: po_number
              in: path
          operations:
            - name: get-purchase-order
              method: GET
    - type: http
      namespace: servicenow-ap
      baseUri: "https://adobe.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST

Retrieves a supplier risk profile from SAP Ariba and, if the risk score exceeds the threshold, creates a ServiceNow task and alerts the procurement Slack channel.

naftiko: "0.5"
info:
  label: "SAP Ariba Supplier Risk Assessment"
  description: "Retrieves a supplier risk profile from SAP Ariba and, if the risk score exceeds the threshold, creates a ServiceNow task and alerts the procurement Slack channel."
  tags:
    - procurement
    - risk
    - sap-ariba
    - servicenow
    - slack
capability:
  exposes:
    - type: mcp
      namespace: procurement-risk
      port: 8080
      tools:
        - name: assess-supplier-risk
          description: "Given a SAP Ariba supplier ID and risk threshold, fetch the risk profile. If the score exceeds the threshold, create a ServiceNow remediation task and post to the procurement Slack channel."
          inputParameters:
            - name: supplier_id
              in: body
              type: string
              description: "SAP Ariba supplier ID."
            - name: risk_threshold
              in: body
              type: number
              description: "Risk score threshold (0-100)."
          steps:
            - name: get-risk-profile
              type: call
              call: ariba.get-supplier-risk
              with:
                supplier_id: "{{supplier_id}}"
            - name: create-task
              type: call
              call: servicenow.create-task
              with:
                short_description: "High-risk supplier: {{supplier_id}} (score: {{get-risk-profile.risk_score}})"
                category: "Procurement"
                priority: "2"
            - name: alert-procurement
              type: call
              call: slack.post-message
              with:
                channel: "procurement-alerts"
                text: "Supplier {{supplier_id}} risk score {{get-risk-profile.risk_score}} exceeds threshold {{risk_threshold}}. ServiceNow: {{create-task.number}}"
  consumes:
    - type: http
      namespace: ariba
      baseUri: "https://openapi.ariba.com/api/supplier-risk/v1"
      authentication:
        type: bearer
        token: "$secrets.ariba_token"
      resources:
        - name: suppliers
          path: "/suppliers/{{supplier_id}}/risk"
          inputParameters:
            - name: supplier_id
              in: path
          operations:
            - name: get-supplier-risk
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://adobe.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Queries SAP Concur for unsubmitted expense reports older than 14 days and sends reminder emails via Microsoft Graph.

naftiko: "0.5"
info:
  label: "SAP Concur Expense Submission Reminder"
  description: "Queries SAP Concur for unsubmitted expense reports older than 14 days and sends reminder emails via Microsoft Graph."
  tags:
    - finance
    - expense-management
    - sap-concur
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: finance-ops
      port: 8080
      tools:
        - name: send-expense-reminders
          description: "Fetch all unsubmitted SAP Concur expense reports older than a given threshold and send email reminders to report owners via Microsoft Graph."
          inputParameters:
            - name: days_threshold
              in: body
              type: integer
              description: "Number of days after which to flag unsubmitted reports."
          steps:
            - name: get-unsubmitted
              type: call
              call: concur.list-reports
              with:
                status: "UNSUBMITTED"
                older_than_days: "{{days_threshold}}"
            - name: send-reminders
              type: call
              call: msgraph.send-mail
              with:
                recipients: "{{get-unsubmitted.owner_emails}}"
                subject: "Action Required: Submit Your Expense Report"
                body: "You have an unsubmitted expense report older than {{days_threshold}} days. Please submit it in SAP Concur."
  consumes:
    - type: http
      namespace: concur
      baseUri: "https://us.api.concursolutions.com/api/v3.0"
      authentication:
        type: bearer
        token: "$secrets.concur_token"
      resources:
        - name: reports
          path: "/expense/reports"
          operations:
            - name: list-reports
              method: GET
    - type: http
      namespace: msgraph
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: mail
          path: "/me/sendMail"
          operations:
            - name: send-mail
              method: POST

Retrieves a goods receipt document from SAP S/4HANA by document number and returns quantity, posting date, and material details.

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

Checks the replication status of a SAP HANA system replication and posts the status to the DBA Microsoft Teams channel.

naftiko: "0.5"
info:
  label: "SAP HANA Data Replication Status"
  description: "Checks the replication status of a SAP HANA system replication and posts the status to the DBA Microsoft Teams channel."
  tags:
    - data
    - database
    - sap-hana
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: dba-ops
      port: 8080
      tools:
        - name: check-replication-status
          description: "Query SAP HANA system replication status and post the result to the DBA Teams channel."
          inputParameters:
            - name: hana_host
              in: body
              type: string
              description: "SAP HANA host identifier."
            - name: teams_channel_id
              in: body
              type: string
              description: "Microsoft Teams DBA channel ID."
          steps:
            - name: get-status
              type: call
              call: hana.get-replication-status
              with:
                host: "{{hana_host}}"
            - name: notify-dba
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "{{teams_channel_id}}"
                text: "HANA replication for {{hana_host}}: mode={{get-status.replication_mode}}, status={{get-status.replication_status}}"
  consumes:
    - type: http
      namespace: hana
      baseUri: "https://{{hana_host}}:8443/api/v1"
      authentication:
        type: basic
        username: "$secrets.hana_user"
        password: "$secrets.hana_password"
      resources:
        - name: replication
          path: "/system_replication"
          operations:
            - name: get-replication-status
              method: GET
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Checks material availability in SAP S/4HANA by material number and plant, returning available quantity and next replenishment date.

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

Looks up a SAP S/4HANA purchase order by number and returns header status, vendor, and total value.

naftiko: "0.5"
info:
  label: "SAP Purchase Order Status Lookup"
  description: "Looks up a SAP S/4HANA purchase order by number and returns header status, vendor, and total value."
  tags:
    - finance
    - procurement
    - erp
    - sap
capability:
  exposes:
    - type: mcp
      namespace: erp-ops
      port: 8080
      tools:
        - name: get-purchase-order
          description: "Given a SAP purchase order number, return the PO status, vendor name, total amount, and currency. Use when procurement or AP teams need to verify PO status before approving an invoice."
          inputParameters:
            - name: po_number
              in: body
              type: string
              description: "SAP purchase order number, e.g. '4500012345'."
          call: sap-po.get-po
          with:
            po_number: "{{po_number}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.d.OverallStatus"
            - name: vendor
              type: string
              mapping: "$.d.Supplier.CompanyName"
            - name: total_amount
              type: string
              mapping: "$.d.TotalAmount"
            - name: currency
              type: string
              mapping: "$.d.TransactionCurrency"
  consumes:
    - type: http
      namespace: sap-po
      baseUri: "https://adobe-s4.sap.com/sap/opu/odata/sap/MM_PUR_PO_MAINT_V2_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: purchase-orders
          path: "/A_PurchaseOrder('{{po_number}}')"
          inputParameters:
            - name: po_number
              in: path
          operations:
            - name: get-po
              method: GET

Retrieves vendor master data from SAP S/4HANA by vendor number, returning name, address, and payment terms.

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

Retrieves email delivery statistics from SendGrid for a given date range, returning delivered, bounced, and opened counts.

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

When a P1 ServiceNow incident is created, triggers a PagerDuty alert and updates the ServiceNow incident with the PagerDuty incident URL.

naftiko: "0.5"
info:
  label: "ServiceNow Incident to PagerDuty"
  description: "When a P1 ServiceNow incident is created, triggers a PagerDuty alert and updates the ServiceNow incident with the PagerDuty incident URL."
  tags:
    - it-operations
    - incident-management
    - servicenow
    - pagerduty
capability:
  exposes:
    - type: mcp
      namespace: incident-ops
      port: 8080
      tools:
        - name: escalate-to-pagerduty
          description: "Given a ServiceNow incident number, create a PagerDuty incident and update ServiceNow with the PagerDuty link."
          inputParameters:
            - name: incident_number
              in: body
              type: string
              description: "ServiceNow incident number."
            - name: service_id
              in: body
              type: string
              description: "PagerDuty service ID to alert."
          steps:
            - name: get-incident
              type: call
              call: servicenow.get-incident
              with:
                number: "{{incident_number}}"
            - name: create-pd-incident
              type: call
              call: pagerduty.create-incident
              with:
                service_id: "{{service_id}}"
                title: "{{get-incident.short_description}}"
                urgency: "high"
            - name: update-snow
              type: call
              call: servicenow.update-incident
              with:
                sys_id: "{{get-incident.sys_id}}"
                pagerduty_url: "{{create-pd-incident.html_url}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://adobe.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: get-incident
              method: GET
            - name: update-incident
              method: PATCH
    - type: http
      namespace: pagerduty
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: bearer
        token: "$secrets.pagerduty_token"
      resources:
        - name: incidents
          path: "/incidents"
          operations:
            - name: create-incident
              method: POST

Retrieves IT asset details from ServiceNow CMDB by asset tag, returning model, assigned user, and warranty status.

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

Creates a new ServiceNow knowledge base article from a resolved incident's details and notifies the author via Microsoft Teams.

naftiko: "0.5"
info:
  label: "ServiceNow Knowledge Article Creation"
  description: "Creates a new ServiceNow knowledge base article from a resolved incident's details and notifies the author via Microsoft Teams."
  tags:
    - it-operations
    - knowledge-management
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: km-ops
      port: 8080
      tools:
        - name: create-kb-from-incident
          description: "Given a ServiceNow incident number, extract resolution details, create a knowledge article, and notify the resolver via Teams."
          inputParameters:
            - name: incident_number
              in: body
              type: string
              description: "ServiceNow incident number."
          steps:
            - name: get-incident
              type: call
              call: servicenow.get-incident
              with:
                number: "{{incident_number}}"
            - name: create-article
              type: call
              call: servicenow.create-kb-article
              with:
                short_description: "KB: {{get-incident.short_description}}"
                text: "{{get-incident.close_notes}}"
                knowledge_base: "IT Knowledge Base"
            - name: notify-author
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "it-knowledge"
                text: "KB article created from {{incident_number}}: {{create-article.number}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://adobe.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: get-incident
              method: GET
        - name: kb-articles
          path: "/table/kb_knowledge"
          operations:
            - name: create-kb-article
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Moves documents older than a retention threshold from a SharePoint library to an archive site and logs the action.

naftiko: "0.5"
info:
  label: "SharePoint Document Archival"
  description: "Moves documents older than a retention threshold from a SharePoint library to an archive site and logs the action."
  tags:
    - governance
    - document-management
    - sharepoint
capability:
  exposes:
    - type: mcp
      namespace: doc-governance
      port: 8080
      tools:
        - name: archive-documents
          description: "Given a SharePoint site ID and library name, move documents past the retention period to the archive site."
          inputParameters:
            - name: site_id
              in: body
              type: string
              description: "SharePoint site ID."
            - name: library_name
              in: body
              type: string
              description: "Document library name."
            - name: retention_days
              in: body
              type: integer
              description: "Retention period in days."
          steps:
            - name: list-old-docs
              type: call
              call: sharepoint.list-items
              with:
                site_id: "{{site_id}}"
                library: "{{library_name}}"
                filter: "createdDateTime lt {{retention_days}}"
            - name: move-to-archive
              type: call
              call: sharepoint.move-items
              with:
                items: "{{list-old-docs.value}}"
                destination: "archive"
  consumes:
    - type: http
      namespace: sharepoint
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: drive-items
          path: "/sites/{{site_id}}/drive/items"
          inputParameters:
            - name: site_id
              in: path
          operations:
            - name: list-items
              method: GET
            - name: move-items
              method: PATCH

Lists Slack channels inactive for more than 90 days and posts a cleanup recommendation to the workspace admin channel.

naftiko: "0.5"
info:
  label: "Slack Channel Archive Audit"
  description: "Lists Slack channels inactive for more than 90 days and posts a cleanup recommendation to the workspace admin channel."
  tags:
    - collaboration
    - governance
    - slack
capability:
  exposes:
    - type: mcp
      namespace: workspace-ops
      port: 8080
      tools:
        - name: audit-inactive-channels
          description: "List Slack channels with no messages in the past N days and post a summary to the admin channel for archive consideration."
          inputParameters:
            - name: inactive_days
              in: body
              type: integer
              description: "Number of days of inactivity threshold."
            - name: admin_channel
              in: body
              type: string
              description: "Admin Slack channel for the report."
          steps:
            - name: list-channels
              type: call
              call: slack.list-channels
              with:
                types: "public_channel"
            - name: post-report
              type: call
              call: slack.post-message
              with:
                channel: "{{admin_channel}}"
                text: "Inactive channel audit: {{list-channels.inactive_count}} channels with no activity in {{inactive_days}} days. Review for archival."
  consumes:
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: channels
          path: "/conversations.list"
          operations:
            - name: list-channels
              method: GET
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Checks Snowflake task history for failed pipelines in the Experience Cloud data warehouse, logs anomalies to Datadog, and opens Jira tickets for the data engineering team.

naftiko: "0.5"
info:
  label: "Snowflake Data Pipeline Health Check"
  description: "Checks Snowflake task history for failed pipelines in the Experience Cloud data warehouse, logs anomalies to Datadog, and opens Jira tickets for the data engineering team."
  tags:
    - data
    - snowflake
    - datadog
    - monitoring
    - analytics
capability:
  exposes:
    - type: mcp
      namespace: data-ops
      port: 8080
      tools:
        - name: check-pipeline-health
          description: "Query Snowflake task execution history for failures, log each failure as a Datadog error event, and open a Jira ticket for the data engineering team if failures are detected. Use daily to verify Adobe's Experience Cloud data pipelines."
          inputParameters:
            - name: lookback_hours
              in: body
              type: integer
              description: "Hours of pipeline history to examine."
            - name: jira_project_key
              in: body
              type: string
              description: "Jira project key for data engineering tickets."
          steps:
            - name: get-failures
              type: call
              call: snowflake.get-task-failures
              with:
                lookback_hours: "{{lookback_hours}}"
            - name: log-dd-failures
              type: call
              call: datadog-data.create-event
              with:
                title: "Snowflake pipeline failures"
                text: "Failed tasks: {{get-failures.task_names}}"
                alert_type: "error"
            - name: create-jira
              type: call
              call: jira-data.create-issue
              with:
                project_key: "{{jira_project_key}}"
                issuetype: "Bug"
                summary: "Snowflake pipeline failures — {{get-failures.task_count}} tasks"
                description: "Tasks: {{get-failures.task_names}} | Datadog: {{log-dd-failures.url}}"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://adobe.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: task-history
          path: "/databases/EXPERIENCE_CLOUD/schemas/PUBLIC/tasks/history"
          inputParameters:
            - name: lookback_hours
              in: query
          operations:
            - name: get-task-failures
              method: GET
    - type: http
      namespace: datadog-data
      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: jira-data
      baseUri: "https://adobe.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST

Creates a Snowflake data share for a partner account, grants access to specified schemas, and logs the provisioning event to ServiceNow.

naftiko: "0.5"
info:
  label: "Snowflake Data Share Provisioning"
  description: "Creates a Snowflake data share for a partner account, grants access to specified schemas, and logs the provisioning event to ServiceNow."
  tags:
    - data
    - governance
    - snowflake
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: data-governance
      port: 8080
      tools:
        - name: provision-data-share
          description: "Given a Snowflake database, schema, and partner account, create a data share and log the action in ServiceNow."
          inputParameters:
            - name: database
              in: body
              type: string
              description: "Snowflake database name."
            - name: schema
              in: body
              type: string
              description: "Schema to share."
            - name: partner_account
              in: body
              type: string
              description: "Partner Snowflake account locator."
          steps:
            - name: create-share
              type: call
              call: snowflake.execute-statement
              with:
                statement: "CREATE SHARE IF NOT EXISTS share_{{partner_account}}; GRANT USAGE ON DATABASE {{database}} TO SHARE share_{{partner_account}}; GRANT USAGE ON SCHEMA {{database}}.{{schema}} TO SHARE share_{{partner_account}}"
            - name: log-provisioning
              type: call
              call: servicenow.create-record
              with:
                table: "u_data_share_audit"
                database: "{{database}}"
                schema: "{{schema}}"
                partner: "{{partner_account}}"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://adobe.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-statement
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://adobe.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: records
          path: "/table/{{table}}"
          inputParameters:
            - name: table
              in: path
          operations:
            - name: create-record
              method: POST

Executes a read-only SQL query against Snowflake and returns the result set for ad-hoc analytics requests.

naftiko: "0.5"
info:
  label: "Snowflake Query Execution"
  description: "Executes a read-only SQL query against Snowflake and returns the result set for ad-hoc analytics requests."
  tags:
    - data
    - analytics
    - snowflake
capability:
  exposes:
    - type: mcp
      namespace: data-ops
      port: 8080
      tools:
        - name: run-snowflake-query
          description: "Given a SQL query string, execute it against Snowflake and return the result rows. Use for ad-hoc data lookups by analysts and business users."
          inputParameters:
            - name: sql
              in: body
              type: string
              description: "Read-only SQL query to execute."
            - name: warehouse
              in: body
              type: string
              description: "Snowflake warehouse to use."
          call: snowflake.execute-statement
          with:
            statement: "{{sql}}"
            warehouse: "{{warehouse}}"
          outputParameters:
            - name: rows
              type: array
              mapping: "$.data"
            - name: row_count
              type: integer
              mapping: "$.resultSetMetaData.numRows"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://adobe.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-statement
              method: POST

Runs a Splunk saved search for high-severity security events and creates a ServiceNow security incident for each finding.

naftiko: "0.5"
info:
  label: "Splunk Security Event Triage"
  description: "Runs a Splunk saved search for high-severity security events and creates a ServiceNow security incident for each finding."
  tags:
    - security
    - siem
    - splunk
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: security-ops
      port: 8080
      tools:
        - name: triage-security-events
          description: "Run a Splunk saved search for critical security events and create ServiceNow incidents for findings."
          inputParameters:
            - name: saved_search_name
              in: body
              type: string
              description: "Splunk saved search name."
          steps:
            - name: run-search
              type: call
              call: splunk.dispatch-saved-search
              with:
                name: "{{saved_search_name}}"
            - name: create-incident
              type: call
              call: servicenow.create-incident
              with:
                short_description: "Splunk security finding: {{saved_search_name}}"
                category: "Security"
                impact: "1"
                urgency: "1"
                search_results: "{{run-search.results}}"
  consumes:
    - type: http
      namespace: splunk
      baseUri: "https://adobe-splunk.splunkcloud.com:8089/servicesNS/admin/search"
      authentication:
        type: bearer
        token: "$secrets.splunk_token"
      resources:
        - name: saved-searches
          path: "/saved/searches/{{name}}/dispatch"
          inputParameters:
            - name: name
              in: path
          operations:
            - name: dispatch-saved-search
              method: POST
    - type: http
      namespace: servicenow
      baseUri: "https://adobe.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

Triggers a Tableau Server extract refresh for a given workbook and posts the completion status to a Microsoft Teams channel.

naftiko: "0.5"
info:
  label: "Tableau Workbook Refresh Trigger"
  description: "Triggers a Tableau Server extract refresh for a given workbook and posts the completion status to a Microsoft Teams channel."
  tags:
    - analytics
    - reporting
    - tableau
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: bi-ops
      port: 8080
      tools:
        - name: refresh-tableau-workbook
          description: "Given a Tableau workbook ID, trigger an extract refresh and notify a Teams channel when complete."
          inputParameters:
            - name: workbook_id
              in: body
              type: string
              description: "Tableau workbook ID."
            - name: teams_channel_id
              in: body
              type: string
              description: "Microsoft Teams channel ID for notification."
          steps:
            - name: trigger-refresh
              type: call
              call: tableau.refresh-workbook
              with:
                workbook_id: "{{workbook_id}}"
            - name: notify-teams
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "{{teams_channel_id}}"
                text: "Tableau workbook {{workbook_id}} refresh triggered. Job ID: {{trigger-refresh.job.id}}"
  consumes:
    - type: http
      namespace: tableau
      baseUri: "https://tableau.adobe.com/api/3.21"
      authentication:
        type: bearer
        token: "$secrets.tableau_token"
      resources:
        - name: workbooks
          path: "/sites/{{site_id}}/workbooks/{{workbook_id}}/refresh"
          inputParameters:
            - name: workbook_id
              in: path
          operations:
            - name: refresh-workbook
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Triggers a Terraform Cloud run to provision a new cloud environment for a product team, and notifies the DevOps Teams channel upon completion.

naftiko: "0.5"
info:
  label: "Terraform Cloud Environment Provisioning"
  description: "Triggers a Terraform Cloud run to provision a new cloud environment for a product team, and notifies the DevOps Teams channel upon completion."
  tags:
    - devops
    - terraform
    - cloud
    - infrastructure
    - provisioning
capability:
  exposes:
    - type: mcp
      namespace: infra-provisioning
      port: 8080
      tools:
        - name: provision-cloud-environment
          description: "Given a Terraform Cloud workspace ID and environment label, trigger a plan-and-apply run to provision cloud infrastructure and notify the DevOps Teams channel. Use when product teams need new cloud environments for development or staging."
          inputParameters:
            - name: workspace_id
              in: body
              type: string
              description: "Terraform Cloud workspace ID."
            - name: environment_label
              in: body
              type: string
              description: "Human-readable environment label, e.g. 'photoshop-staging'."
            - name: devops_channel_id
              in: body
              type: string
              description: "DevOps Teams channel ID."
          steps:
            - name: trigger-run
              type: call
              call: terraform.create-run
              with:
                workspace_id: "{{workspace_id}}"
                message: "Provisioning {{environment_label}}"
                auto_apply: "true"
            - name: notify-devops
              type: call
              call: msteams-devops.post-channel-message
              with:
                channel_id: "{{devops_channel_id}}"
                text: "Terraform run triggered for {{environment_label}} (workspace {{workspace_id}}). Run ID: {{trigger-run.data.id}}"
  consumes:
    - type: http
      namespace: terraform
      baseUri: "https://app.terraform.io/api/v2"
      authentication:
        type: bearer
        token: "$secrets.terraform_token"
      resources:
        - name: runs
          path: "/runs"
          operations:
            - name: create-run
              method: POST
    - type: http
      namespace: msteams-devops
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Triggers a Terraform Cloud plan to detect infrastructure drift and, if drift is found, creates a Jira ticket and alerts the infra Slack channel.

naftiko: "0.5"
info:
  label: "Terraform Drift Detection Alert"
  description: "Triggers a Terraform Cloud plan to detect infrastructure drift and, if drift is found, creates a Jira ticket and alerts the infra Slack channel."
  tags:
    - infrastructure
    - iac
    - terraform
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: infra-ops
      port: 8080
      tools:
        - name: detect-terraform-drift
          description: "Given a Terraform Cloud workspace ID, trigger a speculative plan. If drift is detected, create a Jira ticket and alert the infra Slack channel."
          inputParameters:
            - name: workspace_id
              in: body
              type: string
              description: "Terraform Cloud workspace ID."
          steps:
            - name: trigger-plan
              type: call
              call: terraform.create-run
              with:
                workspace_id: "{{workspace_id}}"
                is_destroy: false
                message: "Automated drift detection"
            - name: create-ticket
              type: call
              call: jira.create-issue
              with:
                project_key: "INFRA"
                issuetype: "Task"
                summary: "Terraform drift detected in workspace {{workspace_id}}"
                description: "Plan run: {{trigger-plan.id}}"
            - name: alert-infra
              type: call
              call: slack.post-message
              with:
                channel: "infra-alerts"
                text: "Drift detected in Terraform workspace {{workspace_id}}. Jira: {{create-ticket.key}}"
  consumes:
    - type: http
      namespace: terraform
      baseUri: "https://app.terraform.io/api/v2"
      authentication:
        type: bearer
        token: "$secrets.terraform_token"
      resources:
        - name: runs
          path: "/runs"
          operations:
            - name: create-run
              method: POST
    - type: http
      namespace: jira
      baseUri: "https://adobe.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: 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

Sends a WhatsApp Business API template message to a customer and logs the delivery status to Salesforce.

naftiko: "0.5"
info:
  label: "WhatsApp Customer Notification"
  description: "Sends a WhatsApp Business API template message to a customer and logs the delivery status to Salesforce."
  tags:
    - communications
    - customer-engagement
    - whatsapp
    - salesforce
capability:
  exposes:
    - type: mcp
      namespace: comms-ops
      port: 8080
      tools:
        - name: send-whatsapp-notification
          description: "Given a customer phone number, template name, and Salesforce case ID, send a WhatsApp template message and log delivery to Salesforce."
          inputParameters:
            - name: phone_number
              in: body
              type: string
              description: "Customer phone number in E.164 format."
            - name: template_name
              in: body
              type: string
              description: "WhatsApp template name."
            - name: case_id
              in: body
              type: string
              description: "Salesforce case ID for logging."
          steps:
            - name: send-message
              type: call
              call: whatsapp.send-template
              with:
                to: "{{phone_number}}"
                template: "{{template_name}}"
            - name: log-to-sf
              type: call
              call: salesforce.create-activity
              with:
                case_id: "{{case_id}}"
                subject: "WhatsApp: {{template_name}}"
                status: "{{send-message.status}}"
  consumes:
    - type: http
      namespace: whatsapp
      baseUri: "https://graph.facebook.com/v18.0"
      authentication:
        type: bearer
        token: "$secrets.whatsapp_token"
      resources:
        - name: messages
          path: "/{{phone_number_id}}/messages"
          operations:
            - name: send-template
              method: POST
    - type: http
      namespace: salesforce
      baseUri: "https://adobe.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: activities
          path: "/sobjects/Task"
          operations:
            - name: create-activity
              method: POST

Retrieves an employee's current PTO and sick leave balances from Workday by employee ID.

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

Queries Workday for employees who have not completed benefits enrollment and sends reminder emails via Microsoft Graph.

naftiko: "0.5"
info:
  label: "Workday Benefits Enrollment Reminder"
  description: "Queries Workday for employees who have not completed benefits enrollment and sends reminder emails via Microsoft Graph."
  tags:
    - hr
    - benefits
    - workday
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: hr-ops
      port: 8080
      tools:
        - name: send-enrollment-reminders
          description: "Fetch employees with incomplete benefits enrollment from Workday and send email reminders via Microsoft Graph."
          inputParameters:
            - name: enrollment_period
              in: body
              type: string
              description: "Benefits enrollment period identifier."
          steps:
            - name: get-incomplete
              type: call
              call: workday.get-pending-enrollment
              with:
                period: "{{enrollment_period}}"
            - name: send-reminders
              type: call
              call: msgraph.send-mail
              with:
                recipients: "{{get-incomplete.employee_emails}}"
                subject: "Action Required: Complete Your Benefits Enrollment"
                body: "Please complete your benefits enrollment for period {{enrollment_period}} in Workday."
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd5-impl-services1.workday.com/ccx/service/adobe"
      authentication:
        type: basic
        username: "$secrets.workday_user"
        password: "$secrets.workday_password"
      resources:
        - name: benefits
          path: "/Benefits/v40.0"
          operations:
            - name: get-pending-enrollment
              method: GET
    - type: http
      namespace: msgraph
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: mail
          path: "/me/sendMail"
          operations:
            - name: send-mail
              method: POST

When a compensation change is approved in Workday, sends a confirmation email to the employee and notifies HR via Microsoft Teams.

naftiko: "0.5"
info:
  label: "Workday Compensation Change Notification"
  description: "When a compensation change is approved in Workday, sends a confirmation email to the employee and notifies HR via Microsoft Teams."
  tags:
    - hr
    - compensation
    - workday
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: hr-ops
      port: 8080
      tools:
        - name: notify-comp-change
          description: "Given a Workday employee ID and compensation event ID, fetch the change details, email the employee, and notify the HR Teams channel."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "Workday employee ID."
            - name: comp_event_id
              in: body
              type: string
              description: "Workday compensation event ID."
          steps:
            - name: get-comp-change
              type: call
              call: workday.get-comp-event
              with:
                employee_id: "{{employee_id}}"
                event_id: "{{comp_event_id}}"
            - name: email-employee
              type: call
              call: msgraph.send-mail
              with:
                to: "{{get-comp-change.employee_email}}"
                subject: "Compensation Change Confirmed"
                body: "Your compensation change effective {{get-comp-change.effective_date}} has been approved."
            - name: notify-hr
              type: call
              call: msteams.post-channel-message
              with:
                channel_id: "hr-notifications"
                text: "Comp change processed for {{employee_id}}: effective {{get-comp-change.effective_date}}"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd5-impl-services1.workday.com/ccx/service/adobe"
      authentication:
        type: basic
        username: "$secrets.workday_user"
        password: "$secrets.workday_password"
      resources:
        - name: compensation
          path: "/Compensation/v40.0"
          operations:
            - name: get-comp-event
              method: GET
    - type: http
      namespace: msgraph
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: mail
          path: "/me/sendMail"
          operations:
            - name: send-mail
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msteams_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Retrieves the direct reports and manager chain for a Workday employee, returning names and titles.

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

Retrieves headcount and payroll cost by cost center from Workday for use in monthly finance reporting and headcount planning.

naftiko: "0.5"
info:
  label: "Workday Payroll Headcount Snapshot"
  description: "Retrieves headcount and payroll cost by cost center from Workday for use in monthly finance reporting and headcount planning."
  tags:
    - hr
    - payroll
    - workday
    - headcount
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: hr-payroll
      port: 8080
      tools:
        - name: get-headcount-snapshot
          description: "Returns headcount and payroll cost grouped by cost center from Workday as of the specified date. Use for monthly finance reviews and headcount planning."
          inputParameters:
            - name: as_of_date
              in: body
              type: string
              description: "Snapshot date in YYYY-MM-DD format."
          call: workday-hcm.get-headcount
          with:
            effective_date: "{{as_of_date}}"
          outputParameters:
            - name: total_headcount
              type: string
              mapping: "$.Report_Entry[0].Total_Headcount"
            - name: total_cost
              type: string
              mapping: "$.Report_Entry[0].Total_Labor_Cost"
  consumes:
    - type: http
      namespace: workday-hcm
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: headcount
          path: "/reports/headcount_by_cost_center"
          inputParameters:
            - name: effective_date
              in: query
          operations:
            - name: get-headcount
              method: GET

Retrieves a Zendesk support ticket by ID and returns the subject, status, priority, and last comment.

naftiko: "0.5"
info:
  label: "Zendesk Ticket Summary Lookup"
  description: "Retrieves a Zendesk support ticket by ID and returns the subject, status, priority, and last comment."
  tags:
    - support
    - customer-service
    - zendesk
capability:
  exposes:
    - type: mcp
      namespace: support-ops
      port: 8080
      tools:
        - name: get-ticket-summary
          description: "Given a Zendesk ticket ID, return the subject, current status, priority, and most recent comment. Use for support queue triage."
          inputParameters:
            - name: ticket_id
              in: body
              type: string
              description: "Zendesk ticket ID."
          call: zendesk.get-ticket
          with:
            ticket_id: "{{ticket_id}}"
          outputParameters:
            - name: subject
              type: string
              mapping: "$.ticket.subject"
            - name: status
              type: string
              mapping: "$.ticket.status"
            - name: priority
              type: string
              mapping: "$.ticket.priority"
  consumes:
    - type: http
      namespace: zendesk
      baseUri: "https://adobe.zendesk.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.zendesk_token"
      resources:
        - name: tickets
          path: "/tickets/{{ticket_id}}.json"
          inputParameters:
            - name: ticket_id
              in: path
          operations:
            - name: get-ticket
              method: GET

Fetches a completed Zoom meeting recording and uploads it to Google Drive, then posts the share link to Slack.

naftiko: "0.5"
info:
  label: "Zoom Meeting Recording Upload"
  description: "Fetches a completed Zoom meeting recording and uploads it to Google Drive, then posts the share link to Slack."
  tags:
    - collaboration
    - meetings
    - zoom
    - google-drive
    - slack
capability:
  exposes:
    - type: mcp
      namespace: meeting-ops
      port: 8080
      tools:
        - name: upload-recording
          description: "Given a Zoom meeting ID, fetch the recording, upload to Google Drive, and share the link in Slack."
          inputParameters:
            - name: meeting_id
              in: body
              type: string
              description: "Zoom meeting ID."
            - name: drive_folder_id
              in: body
              type: string
              description: "Google Drive folder ID for upload."
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel for the share link."
          steps:
            - name: get-recording
              type: call
              call: zoom.get-recording
              with:
                meeting_id: "{{meeting_id}}"
            - name: upload-drive
              type: call
              call: gdrive.upload-file
              with:
                folder_id: "{{drive_folder_id}}"
                name: "recording-{{meeting_id}}.mp4"
                download_url: "{{get-recording.recording_files[0].download_url}}"
            - name: notify-slack
              type: call
              call: slack.post-message
              with:
                channel: "{{slack_channel}}"
                text: "Zoom recording uploaded: {{upload-drive.webViewLink}}"
  consumes:
    - type: http
      namespace: zoom
      baseUri: "https://api.zoom.us/v2"
      authentication:
        type: bearer
        token: "$secrets.zoom_token"
      resources:
        - name: recordings
          path: "/meetings/{{meeting_id}}/recordings"
          inputParameters:
            - name: meeting_id
              in: path
          operations:
            - name: get-recording
              method: GET
    - type: http
      namespace: gdrive
      baseUri: "https://www.googleapis.com/upload/drive/v3"
      authentication:
        type: bearer
        token: "$secrets.google_drive_token"
      resources:
        - name: files
          path: "/files"
          operations:
            - name: upload-file
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves company firmographic data from ZoomInfo by domain name, returning employee count, revenue, and industry.

naftiko: "0.5"
info:
  label: "ZoomInfo Company Enrichment"
  description: "Retrieves company firmographic data from ZoomInfo by domain name, returning employee count, revenue, and industry."
  tags:
    - sales
    - data-enrichment
    - zoominfo
capability:
  exposes:
    - type: mcp
      namespace: sales-intel
      port: 8080
      tools:
        - name: enrich-company
          description: "Given a company domain, return ZoomInfo firmographic data including employee count, annual revenue, and industry classification."
          inputParameters:
            - name: domain
              in: body
              type: string
              description: "Company domain name."
          call: zoominfo.get-company
          with:
            companyDomain: "{{domain}}"
          outputParameters:
            - name: company_name
              type: string
              mapping: "$.data[0].companyName"
            - name: employee_count
              type: integer
              mapping: "$.data[0].employeeCount"
            - name: revenue
              type: string
              mapping: "$.data[0].revenue"
            - name: industry
              type: string
              mapping: "$.data[0].industry"
  consumes:
    - type: http
      namespace: zoominfo
      baseUri: "https://api.zoominfo.com"
      authentication:
        type: bearer
        token: "$secrets.zoominfo_token"
      resources:
        - name: companies
          path: "/search/company"
          operations:
            - name: get-company
              method: POST