American Express Capabilities

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

Sort
Expand

Generates a conversion funnel report from Adobe Analytics, stores results in Snowflake, and distributes findings via Slack and email to the product team.

naftiko: "0.5"
info:
  label: "Adobe Analytics Conversion Funnel Report"
  description: "Generates a conversion funnel report from Adobe Analytics, stores results in Snowflake, and distributes findings via Slack and email to the product team."
  tags:
    - adobe-analytics
    - analytics
    - snowflake
    - slack
capability:
  exposes:
    - type: mcp
      namespace: funnel-report
      port: 8080
      tools:
        - name: generate-funnel-report
          description: "Generate a conversion funnel report and distribute to stakeholders. Use for periodic product analytics reviews."
          inputParameters:
            - name: report_suite_id
              in: body
              type: string
              description: "Adobe Analytics report suite ID."
          steps:
            - name: run-funnel
              type: call
              call: "adobe-analytics.run-report"
              with:
                rsid: "{{report_suite_id}}"
                dimension: "evar1"
                metrics: "visits,applications,approvals"
            - name: store-results
              type: call
              call: "snowflake.run-query"
              with:
                query: "INSERT INTO ANALYTICS_DB.PUBLIC.FUNNEL_REPORTS VALUES ('{{report_suite_id}}', {{run-funnel.visits}}, {{run-funnel.applications}}, {{run-funnel.approvals}}, CURRENT_TIMESTAMP())"
            - name: post-summary
              type: call
              call: "slack.post-message"
              with:
                channel: "product-analytics"
                text: "Funnel: Visits={{run-funnel.visits}} > Applications={{run-funnel.applications}} > Approvals={{run-funnel.approvals}}"
  consumes:
    - namespace: adobe-analytics
      type: http
      baseUri: "https://analytics.adobe.io/api/americanexpress/reports"
      authentication:
        type: bearer
        token: "$secrets.adobe_analytics_token"
      resources:
        - name: reports
          path: "/ranked"
          operations:
            - name: run-report
              method: POST
    - namespace: snowflake
      type: http
      baseUri: "https://americanexpress.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - namespace: slack
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Launches a targeted Amex Offers campaign by querying eligible cardholders in Snowflake, creating the offer in the offers platform, and triggering email notifications via Adobe Campaign.

naftiko: "0.5"
info:
  label: "Amex Offer Activation Campaign"
  description: "Launches a targeted Amex Offers campaign by querying eligible cardholders in Snowflake, creating the offer in the offers platform, and triggering email notifications via Adobe Campaign."
  tags:
    - offers
    - marketing
    - snowflake
    - adobe-campaign
capability:
  exposes:
    - type: mcp
      namespace: offer-campaigns
      port: 8080
      tools:
        - name: launch-offer-campaign
          description: "Find eligible cardholders, create an offer, and trigger the email campaign. Use when launching a new Amex Offers promotion."
          inputParameters:
            - name: offer_name
              in: body
              type: string
              description: "Name of the Amex Offer."
            - name: merchant_id
              in: body
              type: string
              description: "Participating merchant ID."
            - name: discount_percent
              in: body
              type: string
              description: "Discount percentage."
            - name: target_segment
              in: body
              type: string
              description: "Target cardholder segment."
            - name: campaign_template_id
              in: body
              type: string
              description: "Adobe Campaign template ID."
          steps:
            - name: find-eligible
              type: call
              call: "snowflake.run-query"
              with:
                query: "SELECT account_id FROM MARKETING_DB.PUBLIC.CARDHOLDER_SEGMENTS WHERE segment='{{target_segment}}' AND eligible=TRUE"
            - name: create-offer
              type: call
              call: "amex-offers.create-offer"
              with:
                name: "{{offer_name}}"
                merchant_id: "{{merchant_id}}"
                discount: "{{discount_percent}}"
                segment: "{{target_segment}}"
            - name: trigger-emails
              type: call
              call: "adobe-campaign.trigger-campaign"
              with:
                campaign_id: "{{campaign_template_id}}"
                offer_id: "{{create-offer.offer_id}}"
                audience_count: "{{find-eligible.row_count}}"
  consumes:
    - namespace: snowflake
      type: http
      baseUri: "https://americanexpress.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - namespace: amex-offers
      type: http
      baseUri: "https://api.americanexpress.com/v1/offers"
      authentication:
        type: bearer
        token: "$secrets.amex_offers_token"
      resources:
        - name: offers
          path: "/offers"
          operations:
            - name: create-offer
              method: POST
    - namespace: adobe-campaign
      type: http
      baseUri: "https://mc.adobe.io/americanexpress/campaign"
      authentication:
        type: bearer
        token: "$secrets.adobe_campaign_token"
      resources:
        - name: campaigns
          path: "/campaigns"
          operations:
            - name: trigger-campaign
              method: POST

Screens high-value transactions for anti-money laundering by running sanctions checks, creating a compliance review case, and filing a suspicious activity report if needed.

naftiko: "0.5"
info:
  label: "AML Transaction Screening Workflow"
  description: "Screens high-value transactions for anti-money laundering by running sanctions checks, creating a compliance review case, and filing a suspicious activity report if needed."
  tags:
    - compliance
    - aml
    - security
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: aml-screening
      port: 8080
      tools:
        - name: screen-transaction
          description: "Screen a transaction for AML, create a compliance case, and file a SAR if warranted. Use when a high-value transaction triggers AML rules."
          inputParameters:
            - name: transaction_id
              in: body
              type: string
              description: "Transaction ID to screen."
            - name: amount
              in: body
              type: string
              description: "Transaction amount."
            - name: parties
              in: body
              type: string
              description: "Comma-separated party names."
          steps:
            - name: screen
              type: call
              call: "amex-sanctions.screen-transaction"
              with:
                transaction_id: "{{transaction_id}}"
                amount: "{{amount}}"
                parties: "{{parties}}"
            - name: create-review
              type: call
              call: "servicenow.create-case"
              with:
                short_description: "AML screening — txn {{transaction_id}}"
                category: "aml"
                priority: "{{screen.risk_level}}"
                description: "Screening result: {{screen.result}}. Hit count: {{screen.hit_count}}."
            - name: file-report
              type: call
              call: "amex-sar.file-sar"
              with:
                transaction_id: "{{transaction_id}}"
                case_id: "{{create-review.sys_id}}"
                screening_result: "{{screen.result}}"
  consumes:
    - namespace: amex-sanctions
      type: http
      baseUri: "https://api.americanexpress.com/v1/sanctions"
      authentication:
        type: bearer
        token: "$secrets.amex_sanctions_token"
      resources:
        - name: screening
          path: "/screen"
          operations:
            - name: screen-transaction
              method: POST
    - namespace: servicenow
      type: http
      baseUri: "https://americanexpress.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: cases
          path: "/table/sn_compliance_case"
          operations:
            - name: create-case
              method: POST
    - namespace: amex-sar
      type: http
      baseUri: "https://api.americanexpress.com/v1/sar"
      authentication:
        type: bearer
        token: "$secrets.amex_sar_token"
      resources:
        - name: reports
          path: "/reports"
          operations:
            - name: file-sar
              method: POST

On a CI/CD pipeline failure in GitHub Actions, creates a Datadog event marker, opens a Jira bug, and posts an alert to the engineering Slack channel.

naftiko: "0.5"
info:
  label: "Application Pipeline Failure Response"
  description: "On a CI/CD pipeline failure in GitHub Actions, creates a Datadog event marker, opens a Jira bug, and posts an alert to the engineering Slack channel."
  tags:
    - devops
    - github-actions
    - datadog
    - jira
    - slack
    - incident-response
capability:
  exposes:
    - type: mcp
      namespace: devops-ops
      port: 8080
      tools:
        - name: handle-pipeline-failure
          description: "Given a GitHub Actions workflow failure, create a Datadog event, open a Jira bug, and alert Slack. Invoke when a protected-branch pipeline fails in any American Express engineering repository."
          inputParameters:
            - name: repo_name
              in: body
              type: string
              description: "The GitHub repository name where the failure occurred."
            - name: workflow_name
              in: body
              type: string
              description: "The name of the failed GitHub Actions workflow."
            - name: run_id
              in: body
              type: string
              description: "The GitHub Actions run ID for the failed workflow."
            - name: commit_sha
              in: body
              type: string
              description: "The commit SHA that triggered the failed run."
            - name: branch
              in: body
              type: string
              description: "The branch on which the failure occurred."
          steps:
            - name: create-datadog-event
              type: call
              call: "datadog.create-event"
              with:
                title: "Pipeline failure: {{repo_name}} / {{workflow_name}}"
                text: "Run {{run_id}} failed on branch {{branch}} at commit {{commit_sha}}"
                alert_type: "error"
                tags: "repo:{{repo_name}},env:ci"
            - name: open-jira-bug
              type: call
              call: "jira-eng.create-issue"
              with:
                project_key: "ENG"
                issuetype: "Bug"
                summary: "[CI Failure] {{repo_name}} — {{workflow_name}} on {{branch}}"
                description: "Workflow: {{workflow_name}}\nRun ID: {{run_id}}\nBranch: {{branch}}\nCommit: {{commit_sha}}\nDatadog event: {{create-datadog-event.id}}"
            - name: post-alert
              type: call
              call: "slack-eng.post-message"
              with:
                channel: "engineering-alerts"
                text: "Pipeline Failure | Repo: {{repo_name}} | Workflow: {{workflow_name}} | Branch: {{branch}} | Jira: {{open-jira-bug.key}}"
  consumes:
    - namespace: datadog
      type: http
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: event
          path: "/events"
          operations:
            - name: create-event
              method: POST
    - namespace: jira-eng
      type: http
      baseUri: "https://americanexpress.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issue
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - namespace: slack-eng
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Identifies underutilized Azure resources by querying cost data, creates a Jira ticket for the cloud team, and posts a summary to Slack.

naftiko: "0.5"
info:
  label: "Azure Resource Cost Optimization Alert"
  description: "Identifies underutilized Azure resources by querying cost data, creates a Jira ticket for the cloud team, and posts a summary to Slack."
  tags:
    - cloud
    - azure
    - finops
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: azure-finops
      port: 8080
      tools:
        - name: alert-cost-optimization
          description: "Query Azure costs, create a remediation ticket, and alert the FinOps team. Use when Azure cost thresholds are breached."
          inputParameters:
            - name: subscription_id
              in: body
              type: string
              description: "Azure subscription ID."
          steps:
            - name: query-costs
              type: call
              call: "azure.query-costs"
              with:
                subscription_id: "{{subscription_id}}"
                timeframe: "MonthToDate"
                type: "Usage"
            - name: create-ticket
              type: call
              call: "jira.create-issue"
              with:
                project_key: "CLOUD"
                issuetype: "Task"
                summary: "Azure cost optimization — ${{query-costs.total_cost}}"
                description: "Subscription: {{subscription_id}}. Total MTD: ${{query-costs.total_cost}}. Top resource: {{query-costs.top_resource}}."
            - name: post-summary
              type: call
              call: "slack.post-message"
              with:
                channel: "cloud-finops"
                text: "Azure cost alert: ${{query-costs.total_cost}} MTD for subscription {{subscription_id}}. Top resource: {{query-costs.top_resource}}. Jira: {{create-ticket.key}}"
  consumes:
    - namespace: azure
      type: http
      baseUri: "https://management.azure.com"
      authentication:
        type: bearer
        token: "$secrets.azure_token"
      resources:
        - name: cost
          path: "/subscriptions/{subscription_id}/providers/Microsoft.CostManagement/query"
          inputParameters:
            - name: subscription_id
              in: path
          operations:
            - name: query-costs
              method: POST
    - namespace: jira
      type: http
      baseUri: "https://americanexpress.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issue
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - namespace: slack
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Monitors Bloomberg market data feeds for significant movements, creates an alert in ServiceNow, and notifies the trading desk via Slack with context from Snowflake analytics.

naftiko: "0.5"
info:
  label: "Bloomberg Market Data Alert Workflow"
  description: "Monitors Bloomberg market data feeds for significant movements, creates an alert in ServiceNow, and notifies the trading desk via Slack with context from Snowflake analytics."
  tags:
    - bloomberg
    - market-data
    - servicenow
    - snowflake
    - slack
capability:
  exposes:
    - type: mcp
      namespace: market-alerts
      port: 8080
      tools:
        - name: process-market-alert
          description: "Process a market data movement by calculating exposure, creating an incident, and alerting the desk. Use when Bloomberg detects significant price movements."
          inputParameters:
            - name: dataset
              in: body
              type: string
              description: "Bloomberg dataset identifier."
            - name: securities
              in: body
              type: string
              description: "Comma-separated security identifiers."
          steps:
            - name: get-data
              type: call
              call: "bloomberg.get-market-data"
              with:
                dataset: "{{dataset}}"
                securities: "{{securities}}"
            - name: get-exposure
              type: call
              call: "snowflake.run-query"
              with:
                query: "SELECT SUM(notional) as exposure FROM TREASURY_DB.PUBLIC.POSITIONS WHERE security IN ('{{securities}}')"
            - name: create-alert
              type: call
              call: "servicenow.create-incident"
              with:
                short_description: "Market movement alert: {{securities}}"
                category: "market-risk"
                description: "Movement: {{get-data.change_pct}}%. Exposure: ${{get-exposure.exposure}}."
            - name: notify-desk
              type: call
              call: "slack.post-message"
              with:
                channel: "trading-desk"
                text: "Market alert: {{securities}} moved {{get-data.change_pct}}%. Our exposure: ${{get-exposure.exposure}}. SNOW: {{create-alert.number}}"
  consumes:
    - namespace: bloomberg
      type: http
      baseUri: "https://api.bloomberg.com/eap/v1"
      authentication:
        type: bearer
        token: "$secrets.bloomberg_token"
      resources:
        - name: data
          path: "/data/{dataset}"
          inputParameters:
            - name: dataset
              in: path
          operations:
            - name: get-market-data
              method: GET
    - namespace: snowflake
      type: http
      baseUri: "https://americanexpress.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - namespace: servicenow
      type: http
      baseUri: "https://americanexpress.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
    - namespace: slack
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Classifies documents uploaded to Box by extracting metadata, running classification, updating Box metadata, and logging results in ServiceNow.

naftiko: "0.5"
info:
  label: "Box Document Classification Workflow"
  description: "Classifies documents uploaded to Box by extracting metadata, running classification, updating Box metadata, and logging results in ServiceNow."
  tags:
    - box
    - document-management
    - classification
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: doc-classify
      port: 8080
      tools:
        - name: classify-document
          description: "Classify a Box document and update its metadata. Use when a new document is uploaded to a monitored Box folder."
          inputParameters:
            - name: file_id
              in: body
              type: string
              description: "Box file ID."
          steps:
            - name: get-file
              type: call
              call: "box.get-file"
              with:
                file_id: "{{file_id}}"
            - name: classify
              type: call
              call: "amex-classify.classify-document"
              with:
                file_name: "{{get-file.name}}"
                file_type: "{{get-file.extension}}"
            - name: update-meta
              type: call
              call: "box.update-metadata"
              with:
                file_id: "{{file_id}}"
                classification: "{{classify.classification}}"
            - name: log-result
              type: call
              call: "servicenow.create-record"
              with:
                file_id: "{{file_id}}"
                classification: "{{classify.classification}}"
  consumes:
    - namespace: box
      type: http
      baseUri: "https://api.box.com/2.0"
      authentication:
        type: bearer
        token: "$secrets.box_token"
      resources:
        - name: files
          path: "/files/{file_id}"
          inputParameters:
            - name: file_id
              in: path
          operations:
            - name: get-file
              method: GET
            - name: update-metadata
              method: POST
    - namespace: amex-classify
      type: http
      baseUri: "https://api.americanexpress.com/v1/ai"
      authentication:
        type: bearer
        token: "$secrets.amex_ai_token"
      resources:
        - name: classify
          path: "/classify"
          operations:
            - name: classify-document
              method: POST
    - namespace: servicenow
      type: http
      baseUri: "https://americanexpress.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: records
          path: "/table/u_document_classification"
          operations:
            - name: create-record
              method: POST

Processes a cardholder account closure by verifying zero balance, closing the account, archiving data to S3, and sending a confirmation letter via DocuSign.

naftiko: "0.5"
info:
  label: "Cardholder Account Closure Workflow"
  description: "Processes a cardholder account closure by verifying zero balance, closing the account, archiving data to S3, and sending a confirmation letter via DocuSign."
  tags:
    - cardholder
    - accounts
    - s3
    - docusign
capability:
  exposes:
    - type: mcp
      namespace: account-closure
      port: 8080
      tools:
        - name: close-account
          description: "Close a cardholder account, archive data, and send confirmation. Use when a cardholder requests account closure."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "Cardholder account ID."
            - name: closure_reason
              in: body
              type: string
              description: "Reason for closure."
            - name: cardholder_email
              in: body
              type: string
              description: "Cardholder email."
          steps:
            - name: verify-balance
              type: call
              call: "amex-accounts.get-account"
              with:
                account_id: "{{account_id}}"
            - name: close
              type: call
              call: "amex-accounts.close-account"
              with:
                account_id: "{{account_id}}"
                reason: "{{closure_reason}}"
            - name: archive
              type: call
              call: "s3.upload-archive"
              with:
                account_id: "{{account_id}}"
                data: "{{close.archive_payload}}"
            - name: send-letter
              type: call
              call: "docusign.send-envelope"
              with:
                ds_account_id: "$secrets.docusign_account_id"
                recipient_email: "{{cardholder_email}}"
                template_id: "$secrets.closure_template_id"
  consumes:
    - namespace: amex-accounts
      type: http
      baseUri: "https://api.americanexpress.com/v1/accounts"
      authentication:
        type: bearer
        token: "$secrets.amex_accounts_token"
      resources:
        - name: account
          path: "/accounts/{account_id}"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: get-account
              method: GET
            - name: close-account
              method: POST
    - namespace: s3
      type: http
      baseUri: "https://s3.amazonaws.com"
      authentication:
        type: bearer
        token: "$secrets.aws_token"
      resources:
        - name: objects
          path: "/amex-archive/{account_id}"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: upload-archive
              method: PUT
    - namespace: docusign
      type: http
      baseUri: "https://na4.docusign.net/restapi/v2.1"
      authentication:
        type: bearer
        token: "$secrets.docusign_token"
      resources:
        - name: envelopes
          path: "/accounts/{ds_account_id}/envelopes"
          inputParameters:
            - name: ds_account_id
              in: path
          operations:
            - name: send-envelope
              method: POST

Retrieves the current status, credit limit, and outstanding balance for a cardholder account from the American Express accounts platform.

naftiko: "0.5"
info:
  label: "Cardholder Account Status Lookup"
  description: "Retrieves the current status, credit limit, and outstanding balance for a cardholder account from the American Express accounts platform."
  tags:
    - payments
    - cardholder
    - lookup
    - account-management
capability:
  exposes:
    - type: mcp
      namespace: account-lookup
      port: 8080
      tools:
        - name: get-account-status
          description: "Given a cardholder account ID, return the account status, credit limit, current balance, and payment due date. Use when a customer service representative or agent needs to check account standing before processing a request."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The cardholder account ID to look up."
          call: "amex-accounts.get-account"
          with:
            account_id: "{{account_id}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.account_status"
            - name: credit_limit
              type: number
              mapping: "$.credit_limit"
            - name: current_balance
              type: number
              mapping: "$.current_balance"
            - name: payment_due_date
              type: string
              mapping: "$.payment_due_date"
  consumes:
    - namespace: amex-accounts
      type: http
      baseUri: "https://api.americanexpress.com/v1/accounts"
      authentication:
        type: bearer
        token: "$secrets.amex_accounts_token"
      resources:
        - name: account
          path: "/{account_id}"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: get-account
              method: GET

Retrieves the primary mailing address on file for a cardholder account.

naftiko: "0.5"
info:
  label: "Cardholder Address on File Lookup"
  description: "Retrieves the primary mailing address on file for a cardholder account."
  tags:
    - cardholder
    - accounts
    - data
capability:
  exposes:
    - type: mcp
      namespace: amex-accounts
      port: 8080
      tools:
        - name: get-address
          description: "Given a cardholder account ID, return the primary mailing address on file. Use when verifying cardholder address information."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The cardholder account ID."
          call: "amex-accounts.get-address"
          with:
            account_id: "{{account_id}}"
          outputParameters:
            - name: street
              type: string
              mapping: "$.street"
            - name: city
              type: string
              mapping: "$.city"
            - name: state
              type: string
              mapping: "$.state"
            - name: zip
              type: string
              mapping: "$.zip"
            - name: country
              type: string
              mapping: "$.country"
  consumes:
    - namespace: amex-accounts
      type: http
      baseUri: "https://api.americanexpress.com/v1/accounts"
      authentication:
        type: bearer
        token: "$secrets.amex_accounts_token"
      resources:
        - name: address
          path: "/accounts/{account_id}/address"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: get-address
              method: GET

Evaluates a cardholder's spend history to determine annual fee waiver eligibility, creates a decision record, and sends the outcome notification.

naftiko: "0.5"
info:
  label: "Cardholder Annual Fee Waiver Evaluation"
  description: "Evaluates a cardholder's spend history to determine annual fee waiver eligibility, creates a decision record, and sends the outcome notification."
  tags:
    - cardholder
    - billing
    - retention
    - salesforce
capability:
  exposes:
    - type: mcp
      namespace: fee-waiver
      port: 8080
      tools:
        - name: evaluate-fee-waiver
          description: "Evaluate fee waiver eligibility based on spend history, record the decision, and notify the cardholder. Use when a cardholder requests an annual fee waiver."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "Cardholder account ID."
            - name: cardholder_email
              in: body
              type: string
              description: "Cardholder email."
          steps:
            - name: get-spend
              type: call
              call: "amex-accounts.get-spend-summary"
              with:
                account_id: "{{account_id}}"
            - name: create-decision
              type: call
              call: "salesforce.create-case"
              with:
                Subject: "Fee waiver evaluation — {{account_id}}"
                Description: "Annual spend: ${{get-spend.annual_spend}}. Tenure: {{get-spend.tenure_years}} years."
                Type: "Fee Waiver"
            - name: send-outcome
              type: call
              call: "email.send-email"
              with:
                to: "{{cardholder_email}}"
                subject: "Annual Fee Review Complete"
                body: "Based on your ${{get-spend.annual_spend}} annual spend and {{get-spend.tenure_years}} year membership, your fee waiver decision has been recorded. Reference: {{create-decision.id}}"
  consumes:
    - namespace: amex-accounts
      type: http
      baseUri: "https://api.americanexpress.com/v1/accounts"
      authentication:
        type: bearer
        token: "$secrets.amex_accounts_token"
      resources:
        - name: spend-summary
          path: "/accounts/{account_id}/spend-summary"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: get-spend-summary
              method: GET
    - namespace: salesforce
      type: http
      baseUri: "https://americanexpress.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: cases
          path: "/sobjects/Case"
          operations:
            - name: create-case
              method: POST
    - namespace: email
      type: http
      baseUri: "https://api.americanexpress.com/v1/notifications"
      authentication:
        type: bearer
        token: "$secrets.amex_notifications_token"
      resources:
        - name: messages
          path: "/email/send"
          operations:
            - name: send-email
              method: POST

Checks the current AutoPay enrollment status and payment method for a cardholder account.

naftiko: "0.5"
info:
  label: "Cardholder AutoPay Status Lookup"
  description: "Checks the current AutoPay enrollment status and payment method for a cardholder account."
  tags:
    - payments
    - cardholder
    - autopay
capability:
  exposes:
    - type: mcp
      namespace: amex-payments
      port: 8080
      tools:
        - name: get-autopay-status
          description: "Given a cardholder account ID, return the AutoPay enrollment status, payment method, and amount type. Use when verifying automatic payment settings."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The cardholder account ID."
          call: "amex-payments.get-autopay-status"
          with:
            account_id: "{{account_id}}"
          outputParameters:
            - name: enrolled
              type: boolean
              mapping: "$.enrolled"
            - name: payment_method
              type: string
              mapping: "$.payment_method"
            - name: amount_type
              type: string
              mapping: "$.amount_type"
  consumes:
    - namespace: amex-payments
      type: http
      baseUri: "https://api.americanexpress.com/v1/payments"
      authentication:
        type: bearer
        token: "$secrets.amex_payments_token"
      resources:
        - name: autopay
          path: "/accounts/{account_id}/autopay"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: get-autopay-status
              method: GET

Synchronizes cardholder benefits enrollment by fetching card product details, enrolling the cardholder in benefits, and confirming via push notification.

naftiko: "0.5"
info:
  label: "Cardholder Benefits Enrollment Sync"
  description: "Synchronizes cardholder benefits enrollment by fetching card product details, enrolling the cardholder in benefits, and confirming via push notification."
  tags:
    - cardholder
    - benefits
    - enrollment
    - notifications
capability:
  exposes:
    - type: mcp
      namespace: benefits-sync
      port: 8080
      tools:
        - name: sync-benefits
          description: "Enroll a cardholder in their card product benefits and confirm activation. Use when a new card is activated or a product upgrade occurs."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "Cardholder account ID."
            - name: product_id
              in: body
              type: string
              description: "Card product ID."
          steps:
            - name: get-product
              type: call
              call: "amex-products.get-product"
              with:
                product_id: "{{product_id}}"
            - name: enroll-benefits
              type: call
              call: "amex-benefits.enroll"
              with:
                account_id: "{{account_id}}"
                benefits: "{{get-product.included_benefits}}"
            - name: confirm
              type: call
              call: "amex-push.send-push"
              with:
                account_id: "{{account_id}}"
                title: "Benefits activated"
                body: "Your {{get-product.name}} benefits are now active. {{enroll-benefits.benefit_count}} benefits enrolled."
  consumes:
    - namespace: amex-products
      type: http
      baseUri: "https://api.americanexpress.com/v1/products"
      authentication:
        type: bearer
        token: "$secrets.amex_products_token"
      resources:
        - name: products
          path: "/products/{product_id}"
          inputParameters:
            - name: product_id
              in: path
          operations:
            - name: get-product
              method: GET
    - namespace: amex-benefits
      type: http
      baseUri: "https://api.americanexpress.com/v1/benefits"
      authentication:
        type: bearer
        token: "$secrets.amex_benefits_token"
      resources:
        - name: enrollment
          path: "/enrollment"
          operations:
            - name: enroll
              method: POST
    - namespace: amex-push
      type: http
      baseUri: "https://api.americanexpress.com/v1/notifications"
      authentication:
        type: bearer
        token: "$secrets.amex_notifications_token"
      resources:
        - name: push
          path: "/push/send"
          operations:
            - name: send-push
              method: POST

Processes a chargeback by retrieving the original transaction, filing the chargeback with the merchant acquirer, updating the cardholder ledger, and sending status notification.

naftiko: "0.5"
info:
  label: "Cardholder Chargeback Processing"
  description: "Processes a chargeback by retrieving the original transaction, filing the chargeback with the merchant acquirer, updating the cardholder ledger, and sending status notification."
  tags:
    - chargebacks
    - payments
    - cardholder
    - settlements
capability:
  exposes:
    - type: mcp
      namespace: chargeback-ops
      port: 8080
      tools:
        - name: process-chargeback
          description: "File a chargeback, issue provisional credit, and notify the cardholder. Use when a cardholder disputes a transaction and a chargeback is warranted."
          inputParameters:
            - name: transaction_id
              in: body
              type: string
              description: "Original transaction ID."
            - name: reason_code
              in: body
              type: string
              description: "Chargeback reason code."
            - name: cardholder_email
              in: body
              type: string
              description: "Cardholder email address."
          steps:
            - name: get-txn
              type: call
              call: "amex-transactions.get-transaction"
              with:
                txn_id: "{{transaction_id}}"
            - name: file-cb
              type: call
              call: "amex-chargebacks.file-chargeback"
              with:
                transaction_id: "{{transaction_id}}"
                reason_code: "{{reason_code}}"
                amount: "{{get-txn.amount}}"
            - name: credit-ledger
              type: call
              call: "amex-ledger.create-entry"
              with:
                account_id: "{{get-txn.account_id}}"
                amount: "{{get-txn.amount}}"
                type: "provisional_credit"
                reference: "{{file-cb.chargeback_id}}"
            - name: notify
              type: call
              call: "email.send-email"
              with:
                to: "{{cardholder_email}}"
                subject: "Chargeback filed — provisional credit issued"
                body: "A provisional credit of ${{get-txn.amount}} has been applied. Chargeback ID: {{file-cb.chargeback_id}}"
  consumes:
    - namespace: amex-transactions
      type: http
      baseUri: "https://api.americanexpress.com/v1/transactions"
      authentication:
        type: bearer
        token: "$secrets.amex_transactions_token"
      resources:
        - name: transaction
          path: "/transactions/{txn_id}"
          inputParameters:
            - name: txn_id
              in: path
          operations:
            - name: get-transaction
              method: GET
    - namespace: amex-chargebacks
      type: http
      baseUri: "https://api.americanexpress.com/v1/chargebacks"
      authentication:
        type: bearer
        token: "$secrets.amex_chargebacks_token"
      resources:
        - name: chargeback
          path: "/chargebacks"
          operations:
            - name: file-chargeback
              method: POST
    - namespace: amex-ledger
      type: http
      baseUri: "https://api.americanexpress.com/v1/ledger"
      authentication:
        type: bearer
        token: "$secrets.amex_ledger_token"
      resources:
        - name: entries
          path: "/entries"
          operations:
            - name: create-entry
              method: POST
    - namespace: email
      type: http
      baseUri: "https://api.americanexpress.com/v1/notifications"
      authentication:
        type: bearer
        token: "$secrets.amex_notifications_token"
      resources:
        - name: messages
          path: "/email/send"
          operations:
            - name: send-email
              method: POST

Evaluates a cardholder's credit limit increase request by pulling account history, running a risk score, creating a Jira review task, and notifying the cardholder via SMS.

naftiko: "0.5"
info:
  label: "Cardholder Credit Limit Increase Review"
  description: "Evaluates a cardholder's credit limit increase request by pulling account history, running a risk score, creating a Jira review task, and notifying the cardholder via SMS."
  tags:
    - cardholder
    - credit
    - risk
    - jira
capability:
  exposes:
    - type: mcp
      namespace: cli-review
      port: 8080
      tools:
        - name: review-cli-request
          description: "Evaluate a credit limit increase request by checking account history, scoring risk, and creating a review task. Use when a cardholder requests a credit limit increase."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "Cardholder account ID."
            - name: requested_amount
              in: body
              type: string
              description: "Requested credit limit increase amount."
          steps:
            - name: get-account
              type: call
              call: "amex-accounts.get-account"
              with:
                account_id: "{{account_id}}"
            - name: risk-score
              type: call
              call: "amex-risk.get-risk-score"
              with:
                account_id: "{{account_id}}"
                requested_increase: "{{requested_amount}}"
            - name: create-review
              type: call
              call: "jira.create-issue"
              with:
                project_key: "CLR"
                issuetype: "Task"
                summary: "CLI review — {{account_id}} risk={{risk-score.score}}"
                description: "Requested: ${{requested_amount}}. Current limit: ${{get-account.credit_limit}}. Risk score: {{risk-score.score}}."
            - name: notify-cardholder
              type: call
              call: "amex-sms.send-sms"
              with:
                phone: "{{get-account.phone}}"
                message: "Your credit limit increase request is under review. Reference: {{create-review.key}}"
  consumes:
    - namespace: amex-accounts
      type: http
      baseUri: "https://api.americanexpress.com/v1/accounts"
      authentication:
        type: bearer
        token: "$secrets.amex_accounts_token"
      resources:
        - name: account
          path: "/accounts/{account_id}"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: get-account
              method: GET
    - namespace: amex-risk
      type: http
      baseUri: "https://api.americanexpress.com/v1/risk"
      authentication:
        type: bearer
        token: "$secrets.amex_risk_token"
      resources:
        - name: scoring
          path: "/score"
          operations:
            - name: get-risk-score
              method: POST
    - namespace: jira
      type: http
      baseUri: "https://americanexpress.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issue
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - namespace: amex-sms
      type: http
      baseUri: "https://api.americanexpress.com/v1/notifications"
      authentication:
        type: bearer
        token: "$secrets.amex_notifications_token"
      resources:
        - name: sms
          path: "/sms/send"
          operations:
            - name: send-sms
              method: POST

Retrieves the current credit limit and available credit for a cardholder account from the accounts platform.

naftiko: "0.5"
info:
  label: "Cardholder Credit Limit Lookup"
  description: "Retrieves the current credit limit and available credit for a cardholder account from the accounts platform."
  tags:
    - payments
    - cardholder
    - accounts
capability:
  exposes:
    - type: mcp
      namespace: amex-accounts
      port: 8080
      tools:
        - name: get-credit-limit
          description: "Given a cardholder account ID, return the current credit limit, available credit, and currency. Use when an agent needs to check a cardholder's credit availability."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The cardholder account ID."
          call: "amex-accounts.get-credit-limit"
          with:
            account_id: "{{account_id}}"
          outputParameters:
            - name: credit_limit
              type: number
              mapping: "$.credit_limit"
            - name: available_credit
              type: number
              mapping: "$.available_credit"
            - name: currency
              type: string
              mapping: "$.currency"
  consumes:
    - namespace: amex-accounts
      type: http
      baseUri: "https://api.americanexpress.com/v1/accounts"
      authentication:
        type: bearer
        token: "$secrets.amex_accounts_token"
      resources:
        - name: credit-limit
          path: "/accounts/{account_id}/credit-limit"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: get-credit-limit
              method: GET

Provisions a cardholder's card into a digital wallet by verifying identity, generating a token, registering with the wallet provider, and confirming via push notification.

naftiko: "0.5"
info:
  label: "Cardholder Digital Wallet Provisioning"
  description: "Provisions a cardholder's card into a digital wallet by verifying identity, generating a token, registering with the wallet provider, and confirming via push notification."
  tags:
    - cardholder
    - digital-wallets
    - payments
    - security
capability:
  exposes:
    - type: mcp
      namespace: wallet-provision
      port: 8080
      tools:
        - name: provision-wallet
          description: "Provision a card into a digital wallet with identity verification and token generation. Use when a cardholder adds their card to Apple Pay or Google Pay."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "Cardholder account ID."
            - name: card_id
              in: body
              type: string
              description: "Card ID to provision."
            - name: wallet_type
              in: body
              type: string
              description: "Wallet type (apple-pay, google-pay)."
            - name: device_id
              in: body
              type: string
              description: "Device identifier."
            - name: verification_method
              in: body
              type: string
              description: "Verification method (sms, email)."
          steps:
            - name: verify
              type: call
              call: "amex-identity.verify-identity"
              with:
                account_id: "{{account_id}}"
                verification_method: "{{verification_method}}"
            - name: tokenize
              type: call
              call: "amex-tokens.generate-token"
              with:
                card_id: "{{card_id}}"
                wallet_type: "{{wallet_type}}"
            - name: register
              type: call
              call: "amex-wallets.register-wallet"
              with:
                token_id: "{{tokenize.token_id}}"
                wallet_type: "{{wallet_type}}"
                device_id: "{{device_id}}"
            - name: confirm
              type: call
              call: "amex-push.send-push"
              with:
                account_id: "{{account_id}}"
                title: "Card added to {{wallet_type}}"
                body: "Your card ending in {{tokenize.last_four}} is now available in {{wallet_type}}."
  consumes:
    - namespace: amex-identity
      type: http
      baseUri: "https://api.americanexpress.com/v1/identity"
      authentication:
        type: bearer
        token: "$secrets.amex_identity_token"
      resources:
        - name: verify
          path: "/verify"
          operations:
            - name: verify-identity
              method: POST
    - namespace: amex-tokens
      type: http
      baseUri: "https://api.americanexpress.com/v1/tokens"
      authentication:
        type: bearer
        token: "$secrets.amex_tokens_token"
      resources:
        - name: tokens
          path: "/tokens"
          operations:
            - name: generate-token
              method: POST
    - namespace: amex-wallets
      type: http
      baseUri: "https://api.americanexpress.com/v1/wallets"
      authentication:
        type: bearer
        token: "$secrets.amex_wallets_token"
      resources:
        - name: registrations
          path: "/registrations"
          operations:
            - name: register-wallet
              method: POST
    - namespace: amex-push
      type: http
      baseUri: "https://api.americanexpress.com/v1/notifications"
      authentication:
        type: bearer
        token: "$secrets.amex_notifications_token"
      resources:
        - name: push
          path: "/push/send"
          operations:
            - name: send-push
              method: POST

Retrieves the current status of an open dispute for a cardholder from the disputes platform.

naftiko: "0.5"
info:
  label: "Cardholder Dispute Status Lookup"
  description: "Retrieves the current status of an open dispute for a cardholder from the disputes platform."
  tags:
    - disputes
    - cardholder
    - customer-support
capability:
  exposes:
    - type: mcp
      namespace: amex-disputes
      port: 8080
      tools:
        - name: get-dispute-status
          description: "Given a dispute ID, return the current status, resolution ETA, and last update timestamp. Use when a cardholder inquires about an ongoing dispute."
          inputParameters:
            - name: dispute_id
              in: body
              type: string
              description: "The dispute identifier."
          call: "amex-disputes.get-dispute-status"
          with:
            dispute_id: "{{dispute_id}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.status"
            - name: resolution_eta
              type: string
              mapping: "$.resolution_eta"
            - name: last_update
              type: string
              mapping: "$.last_update"
  consumes:
    - namespace: amex-disputes
      type: http
      baseUri: "https://api.americanexpress.com/v1/disputes"
      authentication:
        type: bearer
        token: "$secrets.amex_disputes_token"
      resources:
        - name: status
          path: "/disputes/{dispute_id}/status"
          inputParameters:
            - name: dispute_id
              in: path
          operations:
            - name: get-dispute-status
              method: GET

When a fraud signal is raised on a cardholder account, retrieves transaction details from the core payments platform, opens a ServiceNow incident, and sends a Twilio SMS alert to the cardholder.

naftiko: "0.5"
info:
  label: "Cardholder Fraud Alert Triage"
  description: "When a fraud signal is raised on a cardholder account, retrieves transaction details from the core payments platform, opens a ServiceNow incident, and sends a Twilio SMS alert to the cardholder."
  tags:
    - fraud
    - payments
    - servicenow
    - twilio
    - incident-response
capability:
  exposes:
    - type: mcp
      namespace: fraud-ops
      port: 8080
      tools:
        - name: handle-fraud-alert
          description: "Given a card account ID and transaction ID, fetch transaction details, open a ServiceNow fraud incident, and send an SMS alert to the cardholder. Invoke when a fraud signal is detected on a cardholder account."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The cardholder account identifier from the payments platform."
            - name: transaction_id
              in: body
              type: string
              description: "The transaction ID flagged as potentially fraudulent."
            - name: cardholder_phone
              in: body
              type: string
              description: "The cardholder's mobile phone number in E.164 format for SMS notification."
          steps:
            - name: get-transaction
              type: call
              call: "amex-payments.get-transaction"
              with:
                account_id: "{{account_id}}"
                transaction_id: "{{transaction_id}}"
            - name: open-incident
              type: call
              call: "servicenow.create-incident"
              with:
                category: "fraud"
                short_description: "Fraud alert on account {{account_id}} — txn {{transaction_id}}"
                urgency: "1"
                impact: "1"
            - name: send-sms
              type: call
              call: "twilio.send-sms"
              with:
                to: "{{cardholder_phone}}"
                body: "American Express Alert: Suspicious activity detected on your account ending {{get-transaction.last_four}}. If unrecognized, call 1-800-528-4800. Ref: {{open-incident.number}}"
  consumes:
    - namespace: amex-payments
      type: http
      baseUri: "https://api.americanexpress.com/v1/payments"
      authentication:
        type: bearer
        token: "$secrets.amex_payments_token"
      resources:
        - name: transaction
          path: "/accounts/{account_id}/transactions/{transaction_id}"
          inputParameters:
            - name: account_id
              in: path
            - name: transaction_id
              in: path
          operations:
            - name: get-transaction
              method: GET
    - namespace: servicenow
      type: http
      baseUri: "https://americanexpress.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incident
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - namespace: twilio
      type: http
      baseUri: "https://api.twilio.com/2010-04-01"
      authentication:
        type: basic
        username: "$secrets.twilio_account_sid"
        password: "$secrets.twilio_auth_token"
      resources:
        - name: messages
          path: "/Accounts/{account_sid}/Messages.json"
          inputParameters:
            - name: account_sid
              in: path
          operations:
            - name: send-sms
              method: POST

Generates and delivers international fee disclosures for cardholders traveling abroad by fetching fee schedules, generating the disclosure document, and emailing it to the cardholder.

naftiko: "0.5"
info:
  label: "Cardholder International Fee Disclosure"
  description: "Generates and delivers international fee disclosures for cardholders traveling abroad by fetching fee schedules, generating the disclosure document, and emailing it to the cardholder."
  tags:
    - cardholder
    - compliance
    - travel
    - notifications
capability:
  exposes:
    - type: mcp
      namespace: fee-disclosure
      port: 8080
      tools:
        - name: send-fee-disclosure
          description: "Generate and deliver an international fee disclosure. Use when a cardholder sets a travel notification for an international destination."
          inputParameters:
            - name: product_id
              in: body
              type: string
              description: "Card product ID."
            - name: destination
              in: body
              type: string
              description: "Destination country."
            - name: cardholder_email
              in: body
              type: string
              description: "Cardholder email."
          steps:
            - name: get-fees
              type: call
              call: "amex-fees.get-fee-schedule"
              with:
                product_id: "{{product_id}}"
                destination_country: "{{destination}}"
            - name: generate-doc
              type: call
              call: "amex-docs.generate-disclosure"
              with:
                template: "international-fee-disclosure"
                fee_schedule: "{{get-fees.schedule}}"
                destination: "{{destination}}"
            - name: deliver
              type: call
              call: "email.send-email"
              with:
                to: "{{cardholder_email}}"
                subject: "International Fee Disclosure for {{destination}}"
                body: "Attached is your fee disclosure for travel to {{destination}}. Foreign transaction fee: {{get-fees.fx_fee_pct}}%."
  consumes:
    - namespace: amex-fees
      type: http
      baseUri: "https://api.americanexpress.com/v1/fees"
      authentication:
        type: bearer
        token: "$secrets.amex_fees_token"
      resources:
        - name: schedules
          path: "/products/{product_id}/international-fees"
          inputParameters:
            - name: product_id
              in: path
          operations:
            - name: get-fee-schedule
              method: GET
    - namespace: amex-docs
      type: http
      baseUri: "https://api.americanexpress.com/v1/documents"
      authentication:
        type: bearer
        token: "$secrets.amex_docs_token"
      resources:
        - name: disclosures
          path: "/generate"
          operations:
            - name: generate-disclosure
              method: POST
    - namespace: email
      type: http
      baseUri: "https://api.americanexpress.com/v1/notifications"
      authentication:
        type: bearer
        token: "$secrets.amex_notifications_token"
      resources:
        - name: messages
          path: "/email/send"
          operations:
            - name: send-email
              method: POST

When a cardholder account triggers a KYC review flag, generates a document request via the customer communications platform and creates a Salesforce case for the KYC team to track.

naftiko: "0.5"
info:
  label: "Cardholder KYC Document Request"
  description: "When a cardholder account triggers a KYC review flag, generates a document request via the customer communications platform and creates a Salesforce case for the KYC team to track."
  tags:
    - kyc
    - compliance
    - payments
    - salesforce
    - customer-support
capability:
  exposes:
    - type: mcp
      namespace: kyc-ops
      port: 8080
      tools:
        - name: initiate-kyc-review
          description: "Given a cardholder account ID and KYC flag reason, create a Salesforce KYC case and send a document request notification to the cardholder. Use when account activity triggers a Know Your Customer review requirement."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The cardholder account ID that triggered the KYC flag."
            - name: flag_reason
              in: body
              type: string
              description: "The reason the KYC review was triggered (e.g., high_transaction_volume, new_market)."
            - name: cardholder_email
              in: body
              type: string
              description: "The cardholder's email address for document request communications."
          steps:
            - name: create-kyc-case
              type: call
              call: "salesforce-kyc.create-case"
              with:
                account_id: "{{account_id}}"
                subject: "KYC Review Required — Account {{account_id}}"
                description: "KYC flag reason: {{flag_reason}}"
                type: "KYC Review"
                priority: "High"
            - name: send-doc-request
              type: call
              call: "amex-comms.send-email"
              with:
                to: "{{cardholder_email}}"
                template_id: "kyc_document_request"
                account_id: "{{account_id}}"
                case_number: "{{create-kyc-case.case_number}}"
  consumes:
    - namespace: salesforce-kyc
      type: http
      baseUri: "https://americanexpress.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_access_token"
      resources:
        - name: case
          path: "/sobjects/Case"
          operations:
            - name: create-case
              method: POST
    - namespace: amex-comms
      type: http
      baseUri: "https://api.americanexpress.com/v1/communications"
      authentication:
        type: bearer
        token: "$secrets.amex_comms_token"
      resources:
        - name: email
          path: "/email/send"
          operations:
            - name: send-email
              method: POST

When a cardholder reports a lost card, cancels the existing card, orders a replacement, creates a ServiceNow case, and sends a confirmation via email.

naftiko: "0.5"
info:
  label: "Cardholder Lost Card Replacement Workflow"
  description: "When a cardholder reports a lost card, cancels the existing card, orders a replacement, creates a ServiceNow case, and sends a confirmation via email."
  tags:
    - cardholder
    - cards
    - servicenow
    - customer-support
capability:
  exposes:
    - type: mcp
      namespace: card-replace
      port: 8080
      tools:
        - name: replace-lost-card
          description: "Cancel a lost card, order a replacement, create a support case, and confirm with the cardholder. Use when a cardholder reports a lost or stolen card."
          inputParameters:
            - name: card_id
              in: body
              type: string
              description: "The card ID to replace."
            - name: cardholder_email
              in: body
              type: string
              description: "Cardholder email address for confirmation."
          steps:
            - name: cancel-card
              type: call
              call: "amex-cards.cancel-card"
              with:
                card_id: "{{card_id}}"
            - name: order-replacement
              type: call
              call: "amex-cards.order-replacement"
              with:
                card_id: "{{card_id}}"
                shipping: "expedited"
            - name: create-case
              type: call
              call: "servicenow.create-case"
              with:
                short_description: "Lost card replacement — {{card_id}}"
                category: "card-services"
                priority: "2"
            - name: send-confirmation
              type: call
              call: "email.send-email"
              with:
                to: "{{cardholder_email}}"
                subject: "Your replacement card is on its way"
                body: "Your card ending in {{cancel-card.last_four}} has been cancelled. A replacement will arrive within 2 business days. Case: {{create-case.number}}"
  consumes:
    - namespace: amex-cards
      type: http
      baseUri: "https://api.americanexpress.com/v1/cards"
      authentication:
        type: bearer
        token: "$secrets.amex_cards_token"
      resources:
        - name: card
          path: "/cards/{card_id}"
          inputParameters:
            - name: card_id
              in: path
          operations:
            - name: cancel-card
              method: POST
            - name: order-replacement
              method: POST
    - namespace: servicenow
      type: http
      baseUri: "https://americanexpress.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: cases
          path: "/table/sn_customerservice_case"
          operations:
            - name: create-case
              method: POST
    - namespace: email
      type: http
      baseUri: "https://api.americanexpress.com/v1/notifications"
      authentication:
        type: bearer
        token: "$secrets.amex_notifications_token"
      resources:
        - name: messages
          path: "/email/send"
          operations:
            - name: send-email
              method: POST

Checks whether a cardholder is eligible for a specific Amex Offer based on account profile and spending history.

naftiko: "0.5"
info:
  label: "Cardholder Offer Eligibility Check"
  description: "Checks whether a cardholder is eligible for a specific Amex Offer based on account profile and spending history."
  tags:
    - offers
    - cardholder
    - marketing
capability:
  exposes:
    - type: mcp
      namespace: amex-offers
      port: 8080
      tools:
        - name: check-eligibility
          description: "Given an offer ID and account ID, return eligibility status, reason, and offer name. Use when verifying if a cardholder qualifies for a specific Amex Offer."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The cardholder account ID."
            - name: offer_id
              in: body
              type: string
              description: "The Amex Offer identifier."
          call: "amex-offers.check-eligibility"
          with:
            account_id: "{{account_id}}"
            offer_id: "{{offer_id}}"
          outputParameters:
            - name: eligible
              type: boolean
              mapping: "$.eligible"
            - name: reason
              type: string
              mapping: "$.reason"
            - name: offer_name
              type: string
              mapping: "$.offer_name"
  consumes:
    - namespace: amex-offers
      type: http
      baseUri: "https://api.americanexpress.com/v1/offers"
      authentication:
        type: bearer
        token: "$secrets.amex_offers_token"
      resources:
        - name: eligibility
          path: "/offers/{offer_id}/eligibility/{account_id}"
          inputParameters:
            - name: account_id
              in: path
            - name: offer_id
              in: path
          operations:
            - name: check-eligibility
              method: GET

Retrieves the paperless statement enrollment status for a cardholder account.

naftiko: "0.5"
info:
  label: "Cardholder Paperless Preference Lookup"
  description: "Retrieves the paperless statement enrollment status for a cardholder account."
  tags:
    - cardholder
    - accounts
    - preferences
capability:
  exposes:
    - type: mcp
      namespace: amex-preferences
      port: 8080
      tools:
        - name: get-paperless-status
          description: "Given a cardholder account ID, return the paperless enrollment status and notification email. Use when verifying statement delivery preferences."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The cardholder account ID."
          call: "amex-preferences.get-paperless-status"
          with:
            account_id: "{{account_id}}"
          outputParameters:
            - name: enrolled
              type: boolean
              mapping: "$.enrolled"
            - name: email
              type: string
              mapping: "$.notification_email"
            - name: enrollment_date
              type: string
              mapping: "$.enrollment_date"
  consumes:
    - namespace: amex-preferences
      type: http
      baseUri: "https://api.americanexpress.com/v1/preferences"
      authentication:
        type: bearer
        token: "$secrets.amex_preferences_token"
      resources:
        - name: paperless
          path: "/accounts/{account_id}/paperless"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: get-paperless-status
              method: GET

Sets up a payment plan for a cardholder by evaluating eligibility, creating the plan, updating the billing system, and confirming via email.

naftiko: "0.5"
info:
  label: "Cardholder Payment Plan Setup"
  description: "Sets up a payment plan for a cardholder by evaluating eligibility, creating the plan, updating the billing system, and confirming via email."
  tags:
    - cardholder
    - billing
    - payments
    - customer-support
capability:
  exposes:
    - type: mcp
      namespace: payment-plans
      port: 8080
      tools:
        - name: setup-payment-plan
          description: "Create a payment plan for a cardholder and confirm enrollment. Use when a cardholder requests to pay a balance in installments."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "Cardholder account ID."
            - name: amount
              in: body
              type: string
              description: "Plan amount."
            - name: term_months
              in: body
              type: string
              description: "Number of months for the plan."
          steps:
            - name: get-account
              type: call
              call: "amex-accounts.get-account"
              with:
                account_id: "{{account_id}}"
            - name: create-plan
              type: call
              call: "amex-plans.create-plan"
              with:
                account_id: "{{account_id}}"
                amount: "{{amount}}"
                term_months: "{{term_months}}"
                interest_rate: "{{get-account.plan_rate}}"
            - name: confirm
              type: call
              call: "email.send-email"
              with:
                to: "{{get-account.email}}"
                subject: "Payment plan confirmed"
                body: "Your payment plan of ${{amount}} over {{term_months}} months has been set up. Monthly payment: ${{create-plan.monthly_payment}}. Plan ID: {{create-plan.plan_id}}"
  consumes:
    - namespace: amex-accounts
      type: http
      baseUri: "https://api.americanexpress.com/v1/accounts"
      authentication:
        type: bearer
        token: "$secrets.amex_accounts_token"
      resources:
        - name: account
          path: "/accounts/{account_id}"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: get-account
              method: GET
    - namespace: amex-plans
      type: http
      baseUri: "https://api.americanexpress.com/v1/payment-plans"
      authentication:
        type: bearer
        token: "$secrets.amex_plans_token"
      resources:
        - name: plans
          path: "/plans"
          operations:
            - name: create-plan
              method: POST
    - namespace: email
      type: http
      baseUri: "https://api.americanexpress.com/v1/notifications"
      authentication:
        type: bearer
        token: "$secrets.amex_notifications_token"
      resources:
        - name: messages
          path: "/email/send"
          operations:
            - name: send-email
              method: POST

Returns the most recent transactions for a cardholder account from the transaction history API.

naftiko: "0.5"
info:
  label: "Cardholder Recent Transactions Lookup"
  description: "Returns the most recent transactions for a cardholder account from the transaction history API."
  tags:
    - payments
    - cardholder
    - transactions
capability:
  exposes:
    - type: mcp
      namespace: amex-transactions
      port: 8080
      tools:
        - name: get-recent-transactions
          description: "Given a cardholder account ID, return the most recent transactions including merchant, amount, and date. Use when reviewing recent account activity."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The cardholder account ID."
          call: "amex-transactions.get-recent-transactions"
          with:
            account_id: "{{account_id}}"
          outputParameters:
            - name: transactions
              type: array
              mapping: "$.transactions"
            - name: count
              type: number
              mapping: "$.count"
  consumes:
    - namespace: amex-transactions
      type: http
      baseUri: "https://api.americanexpress.com/v1/transactions"
      authentication:
        type: bearer
        token: "$secrets.amex_transactions_token"
      resources:
        - name: transactions
          path: "/accounts/{account_id}/transactions"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: get-recent-transactions
              method: GET

Retrieves a cardholder's current Membership Rewards point balance and tier status from the rewards platform and returns a structured summary.

naftiko: "0.5"
info:
  label: "Cardholder Rewards Balance Lookup"
  description: "Retrieves a cardholder's current Membership Rewards point balance and tier status from the rewards platform and returns a structured summary."
  tags:
    - rewards
    - payments
    - cardholder
    - lookup
capability:
  exposes:
    - type: mcp
      namespace: rewards
      port: 8080
      tools:
        - name: get-rewards-balance
          description: "Given a cardholder account ID, return the current Membership Rewards point balance, tier, and expiry date. Use when an agent or representative needs to check a cardholder's rewards standing."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The cardholder account ID for which to retrieve rewards balance."
          call: "amex-rewards.get-balance"
          with:
            account_id: "{{account_id}}"
          outputParameters:
            - name: points_balance
              type: number
              mapping: "$.points_balance"
            - name: tier
              type: string
              mapping: "$.tier"
            - name: expiry_date
              type: string
              mapping: "$.expiry_date"
  consumes:
    - namespace: amex-rewards
      type: http
      baseUri: "https://api.americanexpress.com/v1/rewards"
      authentication:
        type: bearer
        token: "$secrets.amex_rewards_token"
      resources:
        - name: balance
          path: "/accounts/{account_id}/balance"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: get-balance
              method: GET

Generates personalized spending insights for a cardholder by analyzing spend categories in Snowflake, creating a visual in Tableau, and delivering via email.

naftiko: "0.5"
info:
  label: "Cardholder Spend Category Insights Digest"
  description: "Generates personalized spending insights for a cardholder by analyzing spend categories in Snowflake, creating a visual in Tableau, and delivering via email."
  tags:
    - cardholder
    - analytics
    - snowflake
    - tableau
    - personalization
capability:
  exposes:
    - type: mcp
      namespace: spend-insights
      port: 8080
      tools:
        - name: generate-spend-insights
          description: "Analyze spending patterns and deliver a personalized insights digest. Use for monthly cardholder engagement."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "Cardholder account ID."
            - name: month
              in: body
              type: string
              description: "Month for insights (e.g. 2026-03)."
            - name: cardholder_email
              in: body
              type: string
              description: "Cardholder email."
          steps:
            - name: analyze-spend
              type: call
              call: "snowflake.run-query"
              with:
                query: "SELECT category, SUM(amount) as total FROM CARDHOLDER_DB.PUBLIC.TRANSACTIONS WHERE account_id='{{account_id}}' AND month='{{month}}' GROUP BY category ORDER BY total DESC LIMIT 5"
            - name: generate-visual
              type: call
              call: "tableau.get-view-image"
              with:
                site_id: "$secrets.tableau_site_id"
                view_id: "$secrets.spend_insights_view_id"
            - name: deliver
              type: call
              call: "email.send-email"
              with:
                to: "{{cardholder_email}}"
                subject: "Your {{month}} Spending Insights"
                body: "Your top category was {{analyze-spend.results[0].category}} at ${{analyze-spend.results[0].total}}."
  consumes:
    - namespace: snowflake
      type: http
      baseUri: "https://americanexpress.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - namespace: tableau
      type: http
      baseUri: "https://americanexpress.online.tableau.com/api/3.19"
      authentication:
        type: bearer
        token: "$secrets.tableau_token"
      resources:
        - name: views
          path: "/sites/{site_id}/views/{view_id}/image"
          inputParameters:
            - name: site_id
              in: path
            - name: view_id
              in: path
          operations:
            - name: get-view-image
              method: GET
    - namespace: email
      type: http
      baseUri: "https://api.americanexpress.com/v1/notifications"
      authentication:
        type: bearer
        token: "$secrets.amex_notifications_token"
      resources:
        - name: messages
          path: "/email/send"
          operations:
            - name: send-email
              method: POST

Retrieves the latest statement balance and minimum payment due for a cardholder account.

naftiko: "0.5"
info:
  label: "Cardholder Statement Balance Lookup"
  description: "Retrieves the latest statement balance and minimum payment due for a cardholder account."
  tags:
    - payments
    - cardholder
    - billing
capability:
  exposes:
    - type: mcp
      namespace: amex-billing
      port: 8080
      tools:
        - name: get-statement-balance
          description: "Given a cardholder account ID, return the current statement balance, minimum payment due, and due date. Use when a representative needs billing information."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The cardholder account ID."
          call: "amex-billing.get-statement-balance"
          with:
            account_id: "{{account_id}}"
          outputParameters:
            - name: statement_balance
              type: number
              mapping: "$.statement_balance"
            - name: minimum_payment
              type: number
              mapping: "$.minimum_payment"
            - name: due_date
              type: string
              mapping: "$.due_date"
  consumes:
    - namespace: amex-billing
      type: http
      baseUri: "https://api.americanexpress.com/v1/billing"
      authentication:
        type: bearer
        token: "$secrets.amex_billing_token"
      resources:
        - name: statement
          path: "/accounts/{account_id}/statement"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: get-statement-balance
              method: GET

Checks whether a cardholder has active travel notifications on file and returns destination and date ranges.

naftiko: "0.5"
info:
  label: "Cardholder Travel Notification Status"
  description: "Checks whether a cardholder has active travel notifications on file and returns destination and date ranges."
  tags:
    - cardholder
    - travel
    - notifications
capability:
  exposes:
    - type: mcp
      namespace: amex-travel
      port: 8080
      tools:
        - name: get-travel-notifications
          description: "Given a cardholder account ID, return active travel notifications including destinations and dates. Use when verifying travel alerts before flagging foreign transactions."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The cardholder account ID."
          call: "amex-travel.get-travel-notifications"
          with:
            account_id: "{{account_id}}"
          outputParameters:
            - name: notifications
              type: array
              mapping: "$.notifications"
            - name: active_count
              type: number
              mapping: "$.active_count"
  consumes:
    - namespace: amex-travel
      type: http
      baseUri: "https://api.americanexpress.com/v1/travel"
      authentication:
        type: bearer
        token: "$secrets.amex_travel_token"
      resources:
        - name: notifications
          path: "/accounts/{account_id}/travel-notifications"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: get-travel-notifications
              method: GET

When AWS Cost Explorer detects a spend anomaly above threshold, retrieves the anomaly details, opens a ServiceNow change request, and notifies the cloud FinOps Slack channel.

naftiko: "0.5"
info:
  label: "Cloud Cost Anomaly Response"
  description: "When AWS Cost Explorer detects a spend anomaly above threshold, retrieves the anomaly details, opens a ServiceNow change request, and notifies the cloud FinOps Slack channel."
  tags:
    - cloud
    - finops
    - aws
    - servicenow
    - slack
    - cost-management
capability:
  exposes:
    - type: mcp
      namespace: cloud-finops
      port: 8080
      tools:
        - name: handle-cost-anomaly
          description: "Given an AWS cost anomaly ID and the affected service/account, retrieve anomaly details from AWS Cost Explorer, open a ServiceNow change request for cost investigation, and alert the FinOps Slack channel. Invoke when a cost spike exceeds defined thresholds."
          inputParameters:
            - name: anomaly_id
              in: body
              type: string
              description: "The AWS Cost Explorer anomaly ID."
            - name: aws_account_id
              in: body
              type: string
              description: "The AWS account ID where the anomaly was detected."
            - name: estimated_overage_usd
              in: body
              type: number
              description: "Estimated cost overage in USD."
          steps:
            - name: get-anomaly
              type: call
              call: "aws-cost.get-anomaly"
              with:
                anomaly_id: "{{anomaly_id}}"
            - name: open-change-request
              type: call
              call: "servicenow-cloud.create-change"
              with:
                category: "cloud_cost"
                short_description: "Cost anomaly on AWS account {{aws_account_id}} — est. overage ${{estimated_overage_usd}}"
                description: "Anomaly ID: {{anomaly_id}}\nService: {{get-anomaly.service}}\nRoot cause hypothesis: {{get-anomaly.root_cause}}\nImpact period: {{get-anomaly.start_date}} to {{get-anomaly.end_date}}"
            - name: post-alert
              type: call
              call: "slack-finops.post-message"
              with:
                channel: "cloud-finops"
                text: "AWS Cost Anomaly | Account: {{aws_account_id}} | Service: {{get-anomaly.service}} | Overage: ${{estimated_overage_usd}} | ServiceNow: {{open-change-request.number}}"
  consumes:
    - namespace: aws-cost
      type: http
      baseUri: "https://ce.us-east-1.amazonaws.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.aws_sigv4_auth"
        placement: header
      resources:
        - name: anomaly
          path: "/GetAnomalies"
          operations:
            - name: get-anomaly
              method: POST
    - namespace: servicenow-cloud
      type: http
      baseUri: "https://americanexpress.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: change
          path: "/table/change_request"
          operations:
            - name: create-change
              method: POST
    - namespace: slack-finops
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Responds to DDoS attacks by activating Cloudflare under-attack mode, creating a security incident in ServiceNow, alerting via PagerDuty, and posting status to Slack.

naftiko: "0.5"
info:
  label: "Cloudflare DDoS Mitigation Response"
  description: "Responds to DDoS attacks by activating Cloudflare under-attack mode, creating a security incident in ServiceNow, alerting via PagerDuty, and posting status to Slack."
  tags:
    - cloudflare
    - security
    - servicenow
    - pagerduty
    - slack
capability:
  exposes:
    - type: mcp
      namespace: ddos-response
      port: 8080
      tools:
        - name: mitigate-ddos
          description: "Activate DDoS mitigation and alert security teams. Use when a DDoS attack is detected."
          inputParameters:
            - name: zone_id
              in: body
              type: string
              description: "Cloudflare zone ID."
          steps:
            - name: activate-uam
              type: call
              call: "cloudflare.set-security-level"
              with:
                zone_id: "{{zone_id}}"
                value: "under_attack"
            - name: create-incident
              type: call
              call: "servicenow.create-incident"
              with:
                short_description: "DDoS attack — {{zone_id}}"
                category: "security"
                priority: "1"
            - name: page-security
              type: call
              call: "pagerduty.create-incident"
              with:
                title: "DDoS attack: zone {{zone_id}}"
                service_id: "$secrets.pd_security_service_id"
                urgency: "high"
            - name: post-status
              type: call
              call: "slack.post-message"
              with:
                channel: "security-ops"
                text: "DDoS mitigation active: {{zone_id}} | SNOW: {{create-incident.number}} | PD: {{page-security.incident_number}}"
  consumes:
    - namespace: cloudflare
      type: http
      baseUri: "https://api.cloudflare.com/client/v4"
      authentication:
        type: bearer
        token: "$secrets.cloudflare_token"
      resources:
        - name: zones
          path: "/zones/{zone_id}/settings/security_level"
          inputParameters:
            - name: zone_id
              in: path
          operations:
            - name: set-security-level
              method: PATCH
    - namespace: servicenow
      type: http
      baseUri: "https://americanexpress.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
    - namespace: pagerduty
      type: http
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: bearer
        token: "$secrets.pagerduty_token"
      resources:
        - name: incidents
          path: "/incidents"
          operations:
            - name: create-incident
              method: POST
    - namespace: slack
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Responds to CloudWatch alarms for Lambda error spikes by fetching error logs, creating a PagerDuty incident, and posting diagnostics to Slack.

naftiko: "0.5"
info:
  label: "CloudWatch Lambda Error Spike Response"
  description: "Responds to CloudWatch alarms for Lambda error spikes by fetching error logs, creating a PagerDuty incident, and posting diagnostics to Slack."
  tags:
    - aws
    - cloudwatch
    - lambda
    - pagerduty
    - slack
capability:
  exposes:
    - type: mcp
      namespace: lambda-errors
      port: 8080
      tools:
        - name: respond-lambda-errors
          description: "Fetch Lambda error logs, page on-call, and post diagnostics. Use when CloudWatch detects an error spike in a Lambda function."
          inputParameters:
            - name: function_name
              in: body
              type: string
              description: "AWS Lambda function name."
          steps:
            - name: get-errors
              type: call
              call: "cloudwatch.get-log-events"
              with:
                logGroupName: "/aws/lambda/{{function_name}}"
                filterPattern: "ERROR"
                limit: "25"
            - name: page-team
              type: call
              call: "pagerduty.create-incident"
              with:
                title: "Lambda error spike: {{function_name}}"
                service_id: "$secrets.pd_lambda_service_id"
                urgency: "high"
            - name: post-diagnostics
              type: call
              call: "slack.post-message"
              with:
                channel: "serverless-ops"
                text: "Lambda error spike: {{function_name}} | Errors: {{get-errors.event_count}} | PD: {{page-team.incident_number}} | Latest: {{get-errors.events[0].message}}"
  consumes:
    - namespace: cloudwatch
      type: http
      baseUri: "https://logs.us-east-1.amazonaws.com"
      authentication:
        type: bearer
        token: "$secrets.aws_token"
      resources:
        - name: logs
          path: "/"
          operations:
            - name: get-log-events
              method: POST
    - namespace: pagerduty
      type: http
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: bearer
        token: "$secrets.pagerduty_token"
      resources:
        - name: incidents
          path: "/incidents"
          operations:
            - name: create-incident
              method: POST
    - namespace: slack
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Provisions corporate cards in bulk by reading employee data from Workday, creating card accounts, and sending activation instructions via email.

naftiko: "0.5"
info:
  label: "Corporate Card Bulk Provisioning"
  description: "Provisions corporate cards in bulk by reading employee data from Workday, creating card accounts, and sending activation instructions via email."
  tags:
    - corporate
    - cards
    - workday
    - onboarding
capability:
  exposes:
    - type: mcp
      namespace: bulk-provision
      port: 8080
      tools:
        - name: bulk-provision-cards
          description: "Provision corporate cards for a department by pulling employees from Workday and creating card accounts. Use during new department onboarding."
          inputParameters:
            - name: department
              in: body
              type: string
              description: "Department name."
            - name: card_program
              in: body
              type: string
              description: "Corporate card program ID."
            - name: spending_limit
              in: body
              type: string
              description: "Default spending limit."
            - name: distribution_list
              in: body
              type: string
              description: "Distribution list email."
          steps:
            - name: get-employees
              type: call
              call: "workday.get-workers"
              with:
                department: "{{department}}"
                status: "active"
            - name: provision-cards
              type: call
              call: "amex-corporate.bulk-provision"
              with:
                employees: "{{get-employees.workers}}"
                card_program: "{{card_program}}"
                spending_limit: "{{spending_limit}}"
            - name: send-instructions
              type: call
              call: "email.send-email"
              with:
                to: "{{distribution_list}}"
                subject: "Corporate Amex cards provisioned"
                body: "{{provision-cards.provisioned_count}} cards provisioned for {{department}}. Employees will receive activation instructions individually."
  consumes:
    - namespace: workday
      type: http
      baseUri: "https://wd3-impl-services1.workday.com/ccx/service/amex"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/workers"
          operations:
            - name: get-workers
              method: GET
    - namespace: amex-corporate
      type: http
      baseUri: "https://api.americanexpress.com/v1/corporate"
      authentication:
        type: bearer
        token: "$secrets.amex_corporate_token"
      resources:
        - name: cards
          path: "/cards/bulk-provision"
          operations:
            - name: bulk-provision
              method: POST
    - namespace: email
      type: http
      baseUri: "https://api.americanexpress.com/v1/notifications"
      authentication:
        type: bearer
        token: "$secrets.amex_notifications_token"
      resources:
        - name: messages
          path: "/email/send"
          operations:
            - name: send-email
              method: POST

Pulls approved corporate card transactions from SAP Concur and posts summarized expense entries to SAP S/4HANA for financial reconciliation.

naftiko: "0.5"
info:
  label: "Corporate Card Expense Report Sync"
  description: "Pulls approved corporate card transactions from SAP Concur and posts summarized expense entries to SAP S/4HANA for financial reconciliation."
  tags:
    - finance
    - expense-management
    - sap-concur
    - sap-s4hana
    - reconciliation
capability:
  exposes:
    - type: mcp
      namespace: expense-finance
      port: 8080
      tools:
        - name: sync-expense-report
          description: "Given a Concur expense report ID, fetch the approved report and post each line item as a journal entry in SAP S/4HANA. Use when corporate card expenses need to be reconciled in the general ledger."
          inputParameters:
            - name: report_id
              in: body
              type: string
              description: "The SAP Concur expense report ID to sync."
            - name: company_code
              in: body
              type: string
              description: "The SAP S/4HANA company code for posting journal entries (e.g., 1000)."
          steps:
            - name: get-report
              type: call
              call: "concur.get-expense-report"
              with:
                report_id: "{{report_id}}"
            - name: post-journal
              type: call
              call: "s4hana.post-journal-entry"
              with:
                company_code: "{{company_code}}"
                amount: "{{get-report.total_amount}}"
                currency: "{{get-report.currency_code}}"
                cost_center: "{{get-report.cost_center}}"
                reference: "{{report_id}}"
  consumes:
    - namespace: concur
      type: http
      baseUri: "https://www.concursolutions.com/api/v3.0"
      authentication:
        type: bearer
        token: "$secrets.concur_access_token"
      resources:
        - name: expense-report
          path: "/expense/reports/{report_id}"
          inputParameters:
            - name: report_id
              in: path
          operations:
            - name: get-expense-report
              method: GET
    - namespace: s4hana
      type: http
      baseUri: "https://americanexpress-s4.sap.com/sap/opu/odata/sap/API_JOURNALENTRYITEMBASIC_SRV"
      authentication:
        type: basic
        username: "$secrets.s4hana_user"
        password: "$secrets.s4hana_password"
      resources:
        - name: journal-entry
          path: "/JournalEntryItemBasic"
          operations:
            - name: post-journal-entry
              method: POST

Retrieves the spending limits and current utilization for a corporate card account.

naftiko: "0.5"
info:
  label: "Corporate Card Spending Limit Lookup"
  description: "Retrieves the spending limits and current utilization for a corporate card account."
  tags:
    - corporate
    - payments
    - accounts
capability:
  exposes:
    - type: mcp
      namespace: amex-corporate
      port: 8080
      tools:
        - name: get-spending-limit
          description: "Given a corporate card ID, return the monthly spending limit, current utilization, and remaining balance. Use when checking corporate card spending capacity."
          inputParameters:
            - name: card_id
              in: body
              type: string
              description: "The corporate card ID."
          call: "amex-corporate.get-spending-limit"
          with:
            card_id: "{{card_id}}"
          outputParameters:
            - name: monthly_limit
              type: number
              mapping: "$.monthly_limit"
            - name: utilized
              type: number
              mapping: "$.utilized"
            - name: remaining
              type: number
              mapping: "$.remaining"
  consumes:
    - namespace: amex-corporate
      type: http
      baseUri: "https://api.americanexpress.com/v1/corporate"
      authentication:
        type: bearer
        token: "$secrets.amex_corporate_token"
      resources:
        - name: spending-limits
          path: "/cards/{card_id}/spending-limits"
          inputParameters:
            - name: card_id
              in: path
          operations:
            - name: get-spending-limit
              method: GET

Detects corporate card expense policy violations, creates a compliance case in Jira, notifies the employee's manager via email, and flags the expense in the expense management system.

naftiko: "0.5"
info:
  label: "Corporate Expense Policy Violation Handler"
  description: "Detects corporate card expense policy violations, creates a compliance case in Jira, notifies the employee's manager via email, and flags the expense in the expense management system."
  tags:
    - corporate
    - compliance
    - jira
    - expense-management
capability:
  exposes:
    - type: mcp
      namespace: expense-compliance
      port: 8080
      tools:
        - name: handle-policy-violation
          description: "Flag a policy-violating expense, create a compliance case, and notify the manager. Use when an expense policy violation is detected."
          inputParameters:
            - name: expense_id
              in: body
              type: string
              description: "Expense record ID."
            - name: violation_reason
              in: body
              type: string
              description: "Reason for the policy violation."
          steps:
            - name: get-expense
              type: call
              call: "amex-expenses.get-expense"
              with:
                expense_id: "{{expense_id}}"
            - name: flag-violation
              type: call
              call: "amex-expenses.flag-expense"
              with:
                expense_id: "{{expense_id}}"
                flag: "policy-violation"
                reason: "{{violation_reason}}"
            - name: create-case
              type: call
              call: "jira.create-issue"
              with:
                project_key: "COMP"
                issuetype: "Task"
                summary: "Expense policy violation — {{get-expense.employee_name}}"
                description: "Expense: ${{get-expense.amount}} at {{get-expense.merchant}}. Violation: {{violation_reason}}."
            - name: notify-manager
              type: call
              call: "email.send-email"
              with:
                to: "{{get-expense.manager_email}}"
                subject: "Expense policy violation flagged"
                body: "An expense by {{get-expense.employee_name}} for ${{get-expense.amount}} has been flagged. Jira: {{create-case.key}}"
  consumes:
    - namespace: amex-expenses
      type: http
      baseUri: "https://api.americanexpress.com/v1/expenses"
      authentication:
        type: bearer
        token: "$secrets.amex_expenses_token"
      resources:
        - name: expense
          path: "/expenses/{expense_id}"
          inputParameters:
            - name: expense_id
              in: path
          operations:
            - name: get-expense
              method: GET
            - name: flag-expense
              method: PUT
    - namespace: jira
      type: http
      baseUri: "https://americanexpress.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issue
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - namespace: email
      type: http
      baseUri: "https://api.americanexpress.com/v1/notifications"
      authentication:
        type: bearer
        token: "$secrets.amex_notifications_token"
      resources:
        - name: messages
          path: "/email/send"
          operations:
            - name: send-email
              method: POST

When a SAP Concur travel booking is submitted, validates it against the American Express travel policy and flags non-compliant bookings by creating a ServiceNow task for manager review.

naftiko: "0.5"
info:
  label: "Corporate Travel Booking Policy Compliance Check"
  description: "When a SAP Concur travel booking is submitted, validates it against the American Express travel policy and flags non-compliant bookings by creating a ServiceNow task for manager review."
  tags:
    - travel
    - expense-management
    - sap-concur
    - servicenow
    - compliance
capability:
  exposes:
    - type: mcp
      namespace: travel-compliance
      port: 8080
      tools:
        - name: check-travel-booking-compliance
          description: "Given a Concur travel booking ID, retrieve booking details and validate against policy rules. If non-compliant, create a ServiceNow approval task for the employee's manager. Use when travel bookings are submitted for pre-trip approval."
          inputParameters:
            - name: booking_id
              in: body
              type: string
              description: "The SAP Concur travel booking ID to validate."
            - name: employee_id
              in: body
              type: string
              description: "The employee ID of the traveler."
          steps:
            - name: get-booking
              type: call
              call: "concur-travel.get-booking"
              with:
                booking_id: "{{booking_id}}"
            - name: create-approval-task
              type: call
              call: "servicenow-travel.create-task"
              with:
                category: "travel_compliance"
                short_description: "Travel booking policy review required: {{booking_id}}"
                description: "Employee: {{employee_id}}\nDestination: {{get-booking.destination}}\nCost: ${{get-booking.total_cost}}\nDates: {{get-booking.travel_dates}}\nBooking: {{booking_id}}"
  consumes:
    - namespace: concur-travel
      type: http
      baseUri: "https://www.concursolutions.com/api/v3.0"
      authentication:
        type: bearer
        token: "$secrets.concur_access_token"
      resources:
        - name: booking
          path: "/travel/trips/{booking_id}"
          inputParameters:
            - name: booking_id
              in: path
          operations:
            - name: get-booking
              method: GET
    - namespace: servicenow-travel
      type: http
      baseUri: "https://americanexpress.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: task
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST

Fetches real-time currency exchange rates from the Amex FX service for a given currency pair.

naftiko: "0.5"
info:
  label: "Currency Exchange Rate Lookup"
  description: "Fetches real-time currency exchange rates from the Amex FX service for a given currency pair."
  tags:
    - payments
    - forex
    - data
capability:
  exposes:
    - type: mcp
      namespace: amex-fx
      port: 8080
      tools:
        - name: get-exchange-rate
          description: "Given base and target currencies, return the current exchange rate, spread, and timestamp. Use when processing international transactions or quoting FX rates."
          inputParameters:
            - name: base_currency
              in: body
              type: string
              description: "The base currency code (e.g. USD)."
            - name: target_currency
              in: body
              type: string
              description: "The target currency code (e.g. EUR)."
          call: "amex-fx.get-exchange-rate"
          with:
            base_currency: "{{base_currency}}"
            target_currency: "{{target_currency}}"
          outputParameters:
            - name: rate
              type: number
              mapping: "$.rate"
            - name: spread
              type: number
              mapping: "$.spread"
            - name: timestamp
              type: string
              mapping: "$.timestamp"
  consumes:
    - namespace: amex-fx
      type: http
      baseUri: "https://api.americanexpress.com/v1/fx"
      authentication:
        type: bearer
        token: "$secrets.amex_fx_token"
      resources:
        - name: rates
          path: "/rates/{base_currency}/{target_currency}"
          inputParameters:
            - name: base_currency
              in: path
            - name: target_currency
              in: path
          operations:
            - name: get-exchange-rate
              method: GET

Retrieves recent resolved Salesforce Service Cloud cases, submits case notes to OpenAI for sentiment and theme extraction, and posts a digest to a Slack channel for the customer experience team.

naftiko: "0.5"
info:
  label: "Customer Sentiment Analysis from Support Cases"
  description: "Retrieves recent resolved Salesforce Service Cloud cases, submits case notes to OpenAI for sentiment and theme extraction, and posts a digest to a Slack channel for the customer experience team."
  tags:
    - customer-support
    - salesforce
    - openai
    - slack
    - ai
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: cx-intelligence
      port: 8080
      tools:
        - name: digest-support-sentiment
          description: "Given a Salesforce queue name and date range, retrieve closed cases, send transcripts to OpenAI for sentiment analysis, and post a summary digest to Slack. Use when the CX team needs a weekly support sentiment report."
          inputParameters:
            - name: queue_name
              in: body
              type: string
              description: "The Salesforce Service Cloud queue name to analyze (e.g., AmexCardholderSupport)."
            - name: from_date
              in: body
              type: string
              description: "Start date for case retrieval in YYYY-MM-DD format."
            - name: to_date
              in: body
              type: string
              description: "End date for case retrieval in YYYY-MM-DD format."
          steps:
            - name: get-cases
              type: call
              call: "salesforce.query-cases"
              with:
                queue: "{{queue_name}}"
                closed_from: "{{from_date}}"
                closed_to: "{{to_date}}"
            - name: analyze-sentiment
              type: call
              call: "openai.create-completion"
              with:
                model: "gpt-4o"
                prompt: "Analyze the following support case summaries and return a JSON object with: overall_sentiment (positive/neutral/negative), top_themes (array of strings), and recommended_actions (array of strings). Cases: {{get-cases.summaries}}"
            - name: post-digest
              type: call
              call: "slack-cx.post-message"
              with:
                channel: "cx-insights"
                text: "CX Sentiment Digest ({{from_date}} to {{to_date}}) | Queue: {{queue_name}} | Sentiment: {{analyze-sentiment.overall_sentiment}} | Top themes: {{analyze-sentiment.top_themes}}"
  consumes:
    - namespace: salesforce
      type: http
      baseUri: "https://americanexpress.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_access_token"
      resources:
        - name: cases
          path: "/query"
          inputParameters:
            - name: q
              in: query
          operations:
            - name: query-cases
              method: GET
    - namespace: openai
      type: http
      baseUri: "https://api.openai.com/v1"
      authentication:
        type: bearer
        token: "$secrets.openai_api_key"
      resources:
        - name: completion
          path: "/chat/completions"
          operations:
            - name: create-completion
              method: POST
    - namespace: slack-cx
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Queries Datadog for the current health status and error rate of a specified American Express microservice.

naftiko: "0.5"
info:
  label: "Datadog Service Health Check"
  description: "Queries Datadog for the current health status and error rate of a specified American Express microservice."
  tags:
    - datadog
    - monitoring
    - infrastructure
capability:
  exposes:
    - type: mcp
      namespace: datadog
      port: 8080
      tools:
        - name: get-service-health
          description: "Given a service name, return the current monitor status and error rate from Datadog. Use when checking the health of a production service."
          inputParameters:
            - name: service_name
              in: body
              type: string
              description: "The microservice name to check."
          call: "datadog.get-service-health"
          with:
            service_name: "{{service_name}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.monitors[0].overall_state"
            - name: error_rate
              type: number
              mapping: "$.monitors[0].error_rate"
            - name: name
              type: string
              mapping: "$.monitors[0].name"
  consumes:
    - namespace: datadog
      type: http
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.datadog_api_key"
      resources:
        - name: monitors
          path: "/monitor/search"
          operations:
            - name: get-service-health
              method: GET

Retrieves the weekly SLO compliance summary from Datadog across all payment processing services and posts a structured digest to the engineering Slack channel.

naftiko: "0.5"
info:
  label: "Datadog SLO Breach Weekly Digest"
  description: "Retrieves the weekly SLO compliance summary from Datadog across all payment processing services and posts a structured digest to the engineering Slack channel."
  tags:
    - observability
    - datadog
    - slo
    - slack
    - payments
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: slo-reporting
      port: 8080
      tools:
        - name: digest-slo-compliance
          description: "Given a list of Datadog SLO IDs and a reporting week, retrieve SLO compliance data for all payment services and post a digest to Slack. Use every Monday to review the prior week's SLO performance."
          inputParameters:
            - name: slo_ids
              in: body
              type: string
              description: "Comma-separated list of Datadog SLO IDs to include in the digest."
            - name: week_start
              in: body
              type: string
              description: "Start date of the reporting week in YYYY-MM-DD format."
          steps:
            - name: get-slo-history
              type: call
              call: "datadog-slo.get-slo-history"
              with:
                slo_ids: "{{slo_ids}}"
                from_ts: "{{week_start}}"
            - name: post-digest
              type: call
              call: "slack-slo.post-message"
              with:
                channel: "engineering-slo"
                text: "SLO Compliance Digest | Week of {{week_start}} | Overall: {{get-slo-history.overall_compliance}}% | Breaches: {{get-slo-history.breach_count}} | Details in Datadog."
  consumes:
    - namespace: datadog-slo
      type: http
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: slo-history
          path: "/slo/history"
          operations:
            - name: get-slo-history
              method: GET
    - namespace: slack-slo
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Responds to Dynatrace application slowdown alerts by fetching problem details, creating a PagerDuty incident, and opening a Jira issue for the responsible team.

naftiko: "0.5"
info:
  label: "Dynatrace Application Slowdown Response"
  description: "Responds to Dynatrace application slowdown alerts by fetching problem details, creating a PagerDuty incident, and opening a Jira issue for the responsible team."
  tags:
    - dynatrace
    - monitoring
    - pagerduty
    - jira
capability:
  exposes:
    - type: mcp
      namespace: dt-response
      port: 8080
      tools:
        - name: handle-slowdown
          description: "Respond to a Dynatrace slowdown by paging on-call and creating a tracking issue. Use when Dynatrace detects application performance degradation."
          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: page-team
              type: call
              call: "pagerduty.create-incident"
              with:
                title: "App slowdown: {{get-problem.title}}"
                service_id: "$secrets.pd_app_service_id"
                urgency: "high"
                body: "Impact: {{get-problem.impactLevel}}. Root cause: {{get-problem.rootCauseEntity}}."
            - name: create-issue
              type: call
              call: "jira.create-issue"
              with:
                project_key: "OPS"
                issuetype: "Bug"
                summary: "Dynatrace: {{get-problem.title}}"
                description: "Problem ID: {{problem_id}}. Impact: {{get-problem.impactLevel}}. PagerDuty: {{page-team.incident_number}}."
  consumes:
    - namespace: dynatrace
      type: http
      baseUri: "https://americanexpress.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
    - namespace: pagerduty
      type: http
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: bearer
        token: "$secrets.pagerduty_token"
      resources:
        - name: incidents
          path: "/incidents"
          operations:
            - name: create-incident
              method: POST
    - namespace: jira
      type: http
      baseUri: "https://americanexpress.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issue
          path: "/issue"
          operations:
            - name: create-issue
              method: POST

When an employee termination is recorded in Workday, cancels the employee's corporate card account and opens a ServiceNow offboarding task.

naftiko: "0.5"
info:
  label: "Employee Offboarding Card Cancellation"
  description: "When an employee termination is recorded in Workday, cancels the employee's corporate card account and opens a ServiceNow offboarding task."
  tags:
    - hr
    - offboarding
    - workday
    - payments
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: hr-offboarding
      port: 8080
      tools:
        - name: cancel-employee-card
          description: "Given a Workday employee ID and termination date, retrieve the employee's corporate card account ID, cancel the card, and open a ServiceNow offboarding task. Invoke on confirmed employee termination."
          inputParameters:
            - name: workday_employee_id
              in: body
              type: string
              description: "The Workday worker ID of the departing employee."
            - name: termination_date
              in: body
              type: string
              description: "The effective termination date in YYYY-MM-DD format."
            - name: card_account_id
              in: body
              type: string
              description: "The corporate card account ID to cancel."
          steps:
            - name: get-employee
              type: call
              call: "workday-offboard.get-worker"
              with:
                worker_id: "{{workday_employee_id}}"
            - name: cancel-card
              type: call
              call: "amex-corp-offboard.cancel-account"
              with:
                account_id: "{{card_account_id}}"
                reason: "employee_termination"
                effective_date: "{{termination_date}}"
            - name: open-offboarding-task
              type: call
              call: "servicenow-offboard.create-task"
              with:
                category: "hr_offboarding"
                short_description: "Corporate card cancelled for {{get-employee.full_name}} ({{workday_employee_id}})"
                description: "Card account {{card_account_id}} cancelled effective {{termination_date}}. Cancel ref: {{cancel-card.confirmation_id}}"
  consumes:
    - namespace: workday-offboard
      type: http
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_access_token"
      resources:
        - name: worker
          path: "/workers/{worker_id}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - namespace: amex-corp-offboard
      type: http
      baseUri: "https://api.americanexpress.com/v1/corporate"
      authentication:
        type: bearer
        token: "$secrets.amex_corp_token"
      resources:
        - name: account
          path: "/accounts/{account_id}/cancel"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: cancel-account
              method: POST
    - namespace: servicenow-offboard
      type: http
      baseUri: "https://americanexpress.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: task
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST

Triggers the annual performance review cycle in Workday for a specified business unit and sends a Microsoft Teams notification to all managers in that unit.

naftiko: "0.5"
info:
  label: "Employee Performance Review Cycle Initiation"
  description: "Triggers the annual performance review cycle in Workday for a specified business unit and sends a Microsoft Teams notification to all managers in that unit."
  tags:
    - hr
    - performance-management
    - workday
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: performance-hr
      port: 8080
      tools:
        - name: initiate-performance-review
          description: "Given a Workday business unit ID and review period, trigger the performance review process in Workday and send a Teams notification to all managers in the unit with instructions. Use at the start of annual or mid-year review cycles."
          inputParameters:
            - name: business_unit_id
              in: body
              type: string
              description: "The Workday business unit ID for which to initiate the review cycle."
            - name: review_period
              in: body
              type: string
              description: "The review period label (e.g., 2026-Annual, 2026-MidYear)."
            - name: due_date
              in: body
              type: string
              description: "The deadline for review completion in YYYY-MM-DD format."
          steps:
            - name: start-review-process
              type: call
              call: "workday-perf.initiate-review"
              with:
                business_unit_id: "{{business_unit_id}}"
                review_period: "{{review_period}}"
                due_date: "{{due_date}}"
            - name: notify-managers
              type: call
              call: "msteams-hr.post-channel-message"
              with:
                channel_id: "$secrets.teams_managers_channel_id"
                content: "The {{review_period}} performance review cycle has been initiated. Please complete reviews for your direct reports by {{due_date}}. Process ID: {{start-review-process.process_id}}"
  consumes:
    - namespace: workday-perf
      type: http
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_access_token"
      resources:
        - name: review
          path: "/performanceReviews"
          operations:
            - name: initiate-review
              method: POST
    - namespace: msteams-hr
      type: http
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-message
          path: "/teams/{team_id}/channels/{channel_id}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

When a fraud alert triggers, retrieves transaction details, creates a case in the fraud investigation system, suspends the card, and notifies the cardholder via push notification.

naftiko: "0.5"
info:
  label: "Fraud Alert Investigation Workflow"
  description: "When a fraud alert triggers, retrieves transaction details, creates a case in the fraud investigation system, suspends the card, and notifies the cardholder via push notification."
  tags:
    - fraud
    - security
    - cardholder
    - investigations
capability:
  exposes:
    - type: mcp
      namespace: fraud-ops
      port: 8080
      tools:
        - name: investigate-fraud-alert
          description: "Investigate a fraud alert by fetching details, creating a case, suspending the card, and notifying the cardholder. Use when a fraud detection alert fires."
          inputParameters:
            - name: alert_id
              in: body
              type: string
              description: "The fraud alert identifier."
          steps:
            - name: get-alert
              type: call
              call: "amex-fraud.get-alert"
              with:
                alert_id: "{{alert_id}}"
            - name: create-case
              type: call
              call: "amex-fraud.create-case"
              with:
                alert_id: "{{alert_id}}"
                amount: "{{get-alert.amount}}"
                merchant: "{{get-alert.merchant_name}}"
                card_id: "{{get-alert.card_id}}"
            - name: suspend-card
              type: call
              call: "amex-cards.suspend-card"
              with:
                card_id: "{{get-alert.card_id}}"
            - name: notify-cardholder
              type: call
              call: "amex-push.send-push"
              with:
                account_id: "{{get-alert.account_id}}"
                title: "Suspicious activity detected"
                body: "A ${{get-alert.amount}} charge at {{get-alert.merchant_name}} was flagged. Your card has been temporarily suspended. Case: {{create-case.case_id}}"
  consumes:
    - namespace: amex-fraud
      type: http
      baseUri: "https://api.americanexpress.com/v1/fraud"
      authentication:
        type: bearer
        token: "$secrets.amex_fraud_token"
      resources:
        - name: alerts
          path: "/alerts/{alert_id}"
          inputParameters:
            - name: alert_id
              in: path
          operations:
            - name: get-alert
              method: GET
        - name: cases
          path: "/cases"
          operations:
            - name: create-case
              method: POST
    - namespace: amex-cards
      type: http
      baseUri: "https://api.americanexpress.com/v1/cards"
      authentication:
        type: bearer
        token: "$secrets.amex_cards_token"
      resources:
        - name: card
          path: "/cards/{card_id}/suspend"
          inputParameters:
            - name: card_id
              in: path
          operations:
            - name: suspend-card
              method: POST
    - namespace: amex-push
      type: http
      baseUri: "https://api.americanexpress.com/v1/notifications"
      authentication:
        type: bearer
        token: "$secrets.amex_notifications_token"
      resources:
        - name: push
          path: "/push/send"
          operations:
            - name: send-push
              method: POST

Scans GitHub pull requests for security vulnerabilities using SonarQube, posts findings as PR comments, and creates a Jira security issue if critical vulnerabilities are found.

naftiko: "0.5"
info:
  label: "GitHub Pull Request Security Scan"
  description: "Scans GitHub pull requests for security vulnerabilities using SonarQube, posts findings as PR comments, and creates a Jira security issue if critical vulnerabilities are found."
  tags:
    - github
    - security
    - sonarqube
    - jira
capability:
  exposes:
    - type: mcp
      namespace: pr-security
      port: 8080
      tools:
        - name: scan-pr-security
          description: "Scan a pull request for vulnerabilities and report findings. Use when a PR is opened against a protected branch."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "GitHub repository name."
            - name: pr_number
              in: body
              type: string
              description: "Pull request number."
          steps:
            - name: get-pr
              type: call
              call: "github.get-pr"
              with:
                repo: "{{repo}}"
                pr_number: "{{pr_number}}"
            - name: scan
              type: call
              call: "sonarqube.get-analysis"
              with:
                projectKey: "{{repo}}-pr-{{pr_number}}"
            - name: comment
              type: call
              call: "github.post-comment"
              with:
                repo: "{{repo}}"
                pr_number: "{{pr_number}}"
                body: "Security scan: {{scan.projectStatus.status}}. Vulnerabilities: {{scan.projectStatus.conditions}}"
            - name: create-sec-issue
              type: call
              call: "jira.create-issue"
              with:
                project_key: "SEC"
                issuetype: "Bug"
                summary: "Security scan findings: {{repo}} PR#{{pr_number}}"
                description: "Status: {{scan.projectStatus.status}}. PR: {{get-pr.html_url}}"
  consumes:
    - namespace: github
      type: http
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: pulls
          path: "/repos/americanexpress/{repo}/pulls/{pr_number}"
          inputParameters:
            - name: repo
              in: path
            - name: pr_number
              in: path
          operations:
            - name: get-pr
              method: GET
            - name: post-comment
              method: POST
    - namespace: sonarqube
      type: http
      baseUri: "https://sonarqube.americanexpress.com/api"
      authentication:
        type: bearer
        token: "$secrets.sonarqube_token"
      resources:
        - name: analysis
          path: "/qualitygates/project_status"
          operations:
            - name: get-analysis
              method: GET
    - namespace: jira
      type: http
      baseUri: "https://americanexpress.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issue
          path: "/issue"
          operations:
            - name: create-issue
              method: POST

Retrieves the latest commit status and open issue count for a given GitHub repository.

naftiko: "0.5"
info:
  label: "GitHub Repository Status Check"
  description: "Retrieves the latest commit status and open issue count for a given GitHub repository."
  tags:
    - github
    - engineering
    - development
capability:
  exposes:
    - type: mcp
      namespace: github
      port: 8080
      tools:
        - name: get-repo-status
          description: "Given a repository name, return the default branch, open issues count, and last updated timestamp. Use when checking repository health."
          inputParameters:
            - name: repo_name
              in: body
              type: string
              description: "The GitHub repository name."
          call: "github.get-repo-status"
          with:
            repo_name: "{{repo_name}}"
          outputParameters:
            - name: default_branch
              type: string
              mapping: "$.default_branch"
            - name: open_issues_count
              type: number
              mapping: "$.open_issues_count"
            - name: updated_at
              type: string
              mapping: "$.updated_at"
  consumes:
    - namespace: github
      type: http
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: repo
          path: "/repos/americanexpress/{repo_name}"
          inputParameters:
            - name: repo_name
              in: path
          operations:
            - name: get-repo-status
              method: GET

When GitHub Dependabot raises a critical vulnerability alert on an American Express repository, opens a Jira security issue and sends a Slack notification to the AppSec team.

naftiko: "0.5"
info:
  label: "GitHub Security Vulnerability Triage"
  description: "When GitHub Dependabot raises a critical vulnerability alert on an American Express repository, opens a Jira security issue and sends a Slack notification to the AppSec team."
  tags:
    - security
    - devops
    - github
    - jira
    - slack
    - vulnerability-management
capability:
  exposes:
    - type: mcp
      namespace: appsec-triage
      port: 8080
      tools:
        - name: triage-vulnerability-alert
          description: "Given a GitHub repository and Dependabot alert number, retrieve alert details, open a Jira security issue, and notify the AppSec Slack channel. Use when a critical or high severity Dependabot alert is raised."
          inputParameters:
            - name: repo_owner
              in: body
              type: string
              description: "The GitHub organization or owner of the repository (e.g., americanexpress)."
            - name: repo_name
              in: body
              type: string
              description: "The name of the GitHub repository with the vulnerability."
            - name: alert_number
              in: body
              type: integer
              description: "The Dependabot alert number from GitHub."
          steps:
            - name: get-alert
              type: call
              call: "github.get-dependabot-alert"
              with:
                owner: "{{repo_owner}}"
                repo: "{{repo_name}}"
                alert_number: "{{alert_number}}"
            - name: create-security-issue
              type: call
              call: "jira-security.create-issue"
              with:
                project_key: "SEC"
                issuetype: "Security Vulnerability"
                summary: "[Dependabot] {{get-alert.dependency_name}} {{get-alert.severity}} in {{repo_name}}"
                description: "CVE: {{get-alert.cve_id}}\nPackage: {{get-alert.dependency_name}}\nSeverity: {{get-alert.severity}}\nRepo: {{repo_owner}}/{{repo_name}}\nAlert: {{alert_number}}\nFixed version: {{get-alert.fixed_version}}"
            - name: notify-appsec
              type: call
              call: "slack-appsec.post-message"
              with:
                channel: "appsec-alerts"
                text: "Vulnerability Alert | Repo: {{repo_owner}}/{{repo_name}} | Package: {{get-alert.dependency_name}} | Severity: {{get-alert.severity}} | CVE: {{get-alert.cve_id}} | Jira: {{create-security-issue.key}}"
  consumes:
    - namespace: github
      type: http
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: dependabot-alert
          path: "/repos/{owner}/{repo}/dependabot/alerts/{alert_number}"
          inputParameters:
            - name: owner
              in: path
            - name: repo
              in: path
            - name: alert_number
              in: path
          operations:
            - name: get-dependabot-alert
              method: GET
    - namespace: jira-security
      type: http
      baseUri: "https://americanexpress.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issue
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - namespace: slack-appsec
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Verifies a cardholder's lounge access entitlement based on card product and returns nearby eligible lounges for a given airport.

naftiko: "0.5"
info:
  label: "Global Lounge Access Lookup"
  description: "Verifies a cardholder's lounge access entitlement based on card product and returns nearby eligible lounges for a given airport."
  tags:
    - travel
    - cardholder
    - lounges
capability:
  exposes:
    - type: mcp
      namespace: amex-lounges
      port: 8080
      tools:
        - name: get-lounge-access
          description: "Given a card product and airport code, return lounge eligibility and available lounges. Use when a cardholder asks about airport lounge access."
          inputParameters:
            - name: airport_code
              in: body
              type: string
              description: "The IATA airport code."
            - name: card_product
              in: body
              type: string
              description: "The card product identifier."
          call: "amex-lounges.get-lounge-access"
          with:
            airport_code: "{{airport_code}}"
            card_product: "{{card_product}}"
          outputParameters:
            - name: eligible
              type: boolean
              mapping: "$.eligible"
            - name: lounges
              type: array
              mapping: "$.lounges"
            - name: pass_type
              type: string
              mapping: "$.pass_type"
  consumes:
    - namespace: amex-lounges
      type: http
      baseUri: "https://api.americanexpress.com/v1/lounges"
      authentication:
        type: bearer
        token: "$secrets.amex_lounges_token"
      resources:
        - name: access
          path: "/cards/{card_product}/airports/{airport_code}/lounges"
          inputParameters:
            - name: airport_code
              in: path
            - name: card_product
              in: path
          operations:
            - name: get-lounge-access
              method: GET

Generates a campaign ROI report by pulling performance data from Google Analytics, enriching with spend data from Snowflake, and distributing via email.

naftiko: "0.5"
info:
  label: "Google Analytics Campaign ROI Report"
  description: "Generates a campaign ROI report by pulling performance data from Google Analytics, enriching with spend data from Snowflake, and distributing via email."
  tags:
    - google-analytics
    - marketing
    - snowflake
    - analytics
capability:
  exposes:
    - type: mcp
      namespace: campaign-roi
      port: 8080
      tools:
        - name: generate-roi-report
          description: "Pull campaign performance, enrich with spend data, and distribute. Use for periodic campaign reporting."
          inputParameters:
            - name: ga_property_id
              in: body
              type: string
              description: "Google Analytics property ID."
            - name: date_range
              in: body
              type: string
              description: "Date range for the report."
          steps:
            - name: get-performance
              type: call
              call: "google-analytics.run-report"
              with:
                property_id: "{{ga_property_id}}"
                dateRange: "{{date_range}}"
            - name: get-spend
              type: call
              call: "snowflake.run-query"
              with:
                query: "SELECT SUM(spend) as total_spend FROM MARKETING_DB.PUBLIC.CAMPAIGN_SPEND WHERE date_range='{{date_range}}'"
            - name: distribute
              type: call
              call: "email.send-email"
              with:
                to: "marketing-leadership@americanexpress.com"
                subject: "Campaign ROI Report — {{date_range}}"
                body: "Sessions: {{get-performance.totals.sessions}}. Conversions: {{get-performance.totals.conversions}}. Revenue: ${{get-performance.totals.revenue}}. Spend: ${{get-spend.total_spend}}."
  consumes:
    - namespace: google-analytics
      type: http
      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
    - namespace: snowflake
      type: http
      baseUri: "https://americanexpress.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - namespace: email
      type: http
      baseUri: "https://api.americanexpress.com/v1/notifications"
      authentication:
        type: bearer
        token: "$secrets.amex_notifications_token"
      resources:
        - name: messages
          path: "/email/send"
          operations:
            - name: send-email
              method: POST

Pulls a headcount snapshot from Workday by department and pushes the data to Snowflake for aggregation in workforce analytics dashboards.

naftiko: "0.5"
info:
  label: "Headcount Reporting Snapshot"
  description: "Pulls a headcount snapshot from Workday by department and pushes the data to Snowflake for aggregation in workforce analytics dashboards."
  tags:
    - hr
    - workforce-analytics
    - workday
    - snowflake
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: hr-reporting
      port: 8080
      tools:
        - name: publish-headcount-snapshot
          description: "Given a department ID and reporting period, retrieve headcount data from Workday and insert a snapshot record into the Snowflake workforce analytics table. Use for monthly headcount reporting and workforce planning."
          inputParameters:
            - name: department_id
              in: body
              type: string
              description: "The Workday department ID to pull headcount data for."
            - name: reporting_period
              in: body
              type: string
              description: "The reporting period in YYYY-MM format (e.g., 2026-03)."
          steps:
            - name: get-headcount
              type: call
              call: "workday-hr.get-headcount"
              with:
                department_id: "{{department_id}}"
                as_of_date: "{{reporting_period}}"
            - name: insert-snapshot
              type: call
              call: "snowflake-hr.insert-headcount"
              with:
                department_id: "{{department_id}}"
                period: "{{reporting_period}}"
                headcount: "{{get-headcount.total_headcount}}"
                fte_count: "{{get-headcount.fte_count}}"
                contractor_count: "{{get-headcount.contractor_count}}"
  consumes:
    - namespace: workday-hr
      type: http
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_access_token"
      resources:
        - name: headcount
          path: "/organizations/{department_id}/headcount"
          inputParameters:
            - name: department_id
              in: path
          operations:
            - name: get-headcount
              method: GET
    - namespace: snowflake-hr
      type: http
      baseUri: "https://americanexpress.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: headcount
          path: "/statements"
          operations:
            - name: insert-headcount
              method: POST

Synchronizes new contacts from HubSpot to Salesforce by fetching contact details, creating the Salesforce record, and logging the sync in Snowflake.

naftiko: "0.5"
info:
  label: "HubSpot to Salesforce Contact Sync"
  description: "Synchronizes new contacts from HubSpot to Salesforce by fetching contact details, creating the Salesforce record, and logging the sync in Snowflake."
  tags:
    - hubspot
    - salesforce
    - data-sync
    - snowflake
capability:
  exposes:
    - type: mcp
      namespace: contact-sync
      port: 8080
      tools:
        - name: sync-contact
          description: "Sync a HubSpot contact to Salesforce and log the operation. Use when a new contact is created in HubSpot."
          inputParameters:
            - name: contact_id
              in: body
              type: string
              description: "HubSpot contact ID."
          steps:
            - name: get-hs-contact
              type: call
              call: "hubspot.get-contact"
              with:
                contact_id: "{{contact_id}}"
            - name: create-sf-contact
              type: call
              call: "salesforce.create-contact"
              with:
                FirstName: "{{get-hs-contact.properties.firstname}}"
                LastName: "{{get-hs-contact.properties.lastname}}"
                Email: "{{get-hs-contact.properties.email}}"
                Company: "{{get-hs-contact.properties.company}}"
            - name: log-sync
              type: call
              call: "snowflake.run-query"
              with:
                query: "INSERT INTO SYNC_DB.PUBLIC.CONTACT_SYNC_LOG VALUES ('{{contact_id}}', '{{create-sf-contact.id}}', CURRENT_TIMESTAMP())"
  consumes:
    - namespace: hubspot
      type: http
      baseUri: "https://api.hubapi.com"
      authentication:
        type: bearer
        token: "$secrets.hubspot_token"
      resources:
        - name: contacts
          path: "/crm/v3/objects/contacts/{contact_id}"
          inputParameters:
            - name: contact_id
              in: path
          operations:
            - name: get-contact
              method: GET
    - namespace: salesforce
      type: http
      baseUri: "https://americanexpress.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: contacts
          path: "/sobjects/Contact"
          operations:
            - name: create-contact
              method: POST
    - namespace: snowflake
      type: http
      baseUri: "https://americanexpress.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST

Generates a sprint retrospective digest by pulling completed stories from Jira, calculating velocity metrics, and posting the summary to Confluence and Slack.

naftiko: "0.5"
info:
  label: "Jira Sprint Retrospective Digest"
  description: "Generates a sprint retrospective digest by pulling completed stories from Jira, calculating velocity metrics, and posting the summary to Confluence and Slack."
  tags:
    - jira
    - engineering
    - confluence
    - slack
capability:
  exposes:
    - type: mcp
      namespace: sprint-retro
      port: 8080
      tools:
        - name: generate-retro-digest
          description: "Generate a sprint retrospective by summarizing completed work and posting to Confluence and Slack. Use at the end of each sprint."
          inputParameters:
            - name: project_key
              in: body
              type: string
              description: "Jira project key."
            - name: sprint_id
              in: body
              type: string
              description: "Sprint ID."
            - name: confluence_space
              in: body
              type: string
              description: "Confluence space key."
            - name: team_channel
              in: body
              type: string
              description: "Team Slack channel."
          steps:
            - name: get-completed
              type: call
              call: "jira.search-issues"
              with:
                jql: "project={{project_key}} AND sprint={{sprint_id}} AND status=Done"
            - name: create-retro
              type: call
              call: "confluence.create-page"
              with:
                spaceKey: "{{confluence_space}}"
                title: "Sprint {{sprint_id}} Retrospective"
                body: "Completed: {{get-completed.total}} stories. Story points: {{get-completed.total_points}}."
            - name: post-digest
              type: call
              call: "slack.post-message"
              with:
                channel: "{{team_channel}}"
                text: "Sprint {{sprint_id}} complete: {{get-completed.total}} stories ({{get-completed.total_points}} pts). Retro: {{create-retro.url}}"
  consumes:
    - namespace: jira
      type: http
      baseUri: "https://americanexpress.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: search
          path: "/search"
          operations:
            - name: search-issues
              method: GET
    - namespace: confluence
      type: http
      baseUri: "https://americanexpress.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: pages
          path: "/content"
          operations:
            - name: create-page
              method: POST
    - namespace: slack
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Synchronizes employer brand campaign data from LinkedIn to Snowflake analytics, refreshes the Tableau dashboard, and sends a performance summary to the recruitment marketing team via Slack.

naftiko: "0.5"
info:
  label: "LinkedIn Employer Brand Campaign Sync"
  description: "Synchronizes employer brand campaign data from LinkedIn to Snowflake analytics, refreshes the Tableau dashboard, and sends a performance summary to the recruitment marketing team via Slack."
  tags:
    - linkedin
    - marketing
    - snowflake
    - tableau
    - slack
capability:
  exposes:
    - type: mcp
      namespace: linkedin-sync
      port: 8080
      tools:
        - name: sync-linkedin-campaign
          description: "Sync LinkedIn campaign data to analytics and notify the team. Use after a campaign period ends."
          inputParameters:
            - name: campaign_id
              in: body
              type: string
              description: "LinkedIn campaign ID."
          steps:
            - name: get-campaign
              type: call
              call: "linkedin.get-campaign"
              with:
                campaign_id: "{{campaign_id}}"
            - name: sync-data
              type: call
              call: "snowflake.run-query"
              with:
                query: "INSERT INTO MARKETING_DB.PUBLIC.LINKEDIN_CAMPAIGNS VALUES ('{{campaign_id}}', '{{get-campaign.name}}', {{get-campaign.impressions}}, {{get-campaign.clicks}}, {{get-campaign.spend}})"
            - name: refresh-dash
              type: call
              call: "tableau.refresh-extract"
              with:
                site_id: "$secrets.tableau_site_id"
                datasource_id: "$secrets.linkedin_datasource_id"
            - name: notify-team
              type: call
              call: "slack.post-message"
              with:
                channel: "recruitment-marketing"
                text: "LinkedIn campaign synced: {{get-campaign.name}} | Impressions: {{get-campaign.impressions}} | Clicks: {{get-campaign.clicks}} | Spend: ${{get-campaign.spend}}"
  consumes:
    - namespace: linkedin
      type: http
      baseUri: "https://api.linkedin.com/v2"
      authentication:
        type: bearer
        token: "$secrets.linkedin_token"
      resources:
        - name: campaigns
          path: "/adCampaignsV2/{campaign_id}"
          inputParameters:
            - name: campaign_id
              in: path
          operations:
            - name: get-campaign
              method: GET
    - namespace: snowflake
      type: http
      baseUri: "https://americanexpress.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - namespace: tableau
      type: http
      baseUri: "https://americanexpress.online.tableau.com/api/3.19"
      authentication:
        type: bearer
        token: "$secrets.tableau_token"
      resources:
        - name: extracts
          path: "/sites/{site_id}/datasources/{datasource_id}/refresh"
          inputParameters:
            - name: site_id
              in: path
            - name: datasource_id
              in: path
          operations:
            - name: refresh-extract
              method: POST
    - namespace: slack
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Launches a customer retention campaign by identifying at-risk cardholders in Snowflake, creating a Mailchimp campaign, and logging results in Salesforce.

naftiko: "0.5"
info:
  label: "Mailchimp Customer Retention Campaign"
  description: "Launches a customer retention campaign by identifying at-risk cardholders in Snowflake, creating a Mailchimp campaign, and logging results in Salesforce."
  tags:
    - marketing
    - mailchimp
    - snowflake
    - salesforce
    - retention
capability:
  exposes:
    - type: mcp
      namespace: retention-campaign
      port: 8080
      tools:
        - name: launch-retention-campaign
          description: "Identify at-risk cardholders and launch a retention email campaign. Use for periodic retention outreach."
          inputParameters: []
          steps:
            - name: find-at-risk
              type: call
              call: "snowflake.run-query"
              with:
                query: "SELECT account_id, email FROM RETENTION_DB.PUBLIC.AT_RISK_CARDHOLDERS WHERE churn_score > 0.7"
            - name: create-campaign
              type: call
              call: "mailchimp.create-campaign"
              with:
                type: "regular"
                subject_line: "We miss you — exclusive offer inside"
                from_name: "American Express"
            - name: send
              type: call
              call: "mailchimp.send-campaign"
              with:
                campaign_id: "{{create-campaign.id}}"
            - name: log-campaign
              type: call
              call: "salesforce.create-campaign"
              with:
                Name: "Retention — {{create-campaign.id}}"
                Type: "Email"
                Status: "Sent"
  consumes:
    - namespace: snowflake
      type: http
      baseUri: "https://americanexpress.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - namespace: mailchimp
      type: http
      baseUri: "https://us1.api.mailchimp.com/3.0"
      authentication:
        type: basic
        username: "apikey"
        password: "$secrets.mailchimp_api_key"
      resources:
        - name: campaigns
          path: "/campaigns"
          operations:
            - name: create-campaign
              method: POST
            - name: send-campaign
              method: POST
    - namespace: salesforce
      type: http
      baseUri: "https://americanexpress.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: campaigns
          path: "/sobjects/Campaign"
          operations:
            - name: create-campaign
              method: POST

Retrieves weekly campaign performance metrics from Adobe Analytics and posts a formatted digest to the marketing Slack channel and Microsoft Teams marketing hub.

naftiko: "0.5"
info:
  label: "Marketing Campaign Performance Digest"
  description: "Retrieves weekly campaign performance metrics from Adobe Analytics and posts a formatted digest to the marketing Slack channel and Microsoft Teams marketing hub."
  tags:
    - marketing
    - adobe-analytics
    - slack
    - microsoft-teams
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: marketing-reporting
      port: 8080
      tools:
        - name: digest-campaign-performance
          description: "Given an Adobe Analytics report suite ID and date range, retrieve campaign performance metrics (impressions, clicks, conversions) and post a summary digest to the marketing Slack channel and Teams. Use for weekly or monthly campaign performance reviews."
          inputParameters:
            - name: report_suite_id
              in: body
              type: string
              description: "The Adobe Analytics report suite ID to query."
            - name: from_date
              in: body
              type: string
              description: "Start date for the performance period in YYYY-MM-DD format."
            - name: to_date
              in: body
              type: string
              description: "End date for the performance period in YYYY-MM-DD format."
          steps:
            - name: get-metrics
              type: call
              call: "adobe-analytics.get-report"
              with:
                report_suite_id: "{{report_suite_id}}"
                date_from: "{{from_date}}"
                date_to: "{{to_date}}"
                metrics: "pageviews,visits,orders,revenue"
            - name: post-slack-digest
              type: call
              call: "slack-marketing.post-message"
              with:
                channel: "marketing-performance"
                text: "Campaign Performance {{from_date}} to {{to_date}} | Visits: {{get-metrics.visits}} | Conversions: {{get-metrics.orders}} | Revenue: ${{get-metrics.revenue}}"
            - name: post-teams-digest
              type: call
              call: "msteams-marketing.post-channel-message"
              with:
                channel_id: "$secrets.teams_marketing_channel_id"
                content: "Weekly Campaign Summary ({{from_date}} — {{to_date}})\nVisits: {{get-metrics.visits}}\nOrders: {{get-metrics.orders}}\nRevenue: ${{get-metrics.revenue}}"
  consumes:
    - namespace: adobe-analytics
      type: http
      baseUri: "https://analytics.adobe.io/api"
      authentication:
        type: bearer
        token: "$secrets.adobe_analytics_token"
      resources:
        - name: report
          path: "/{global_company_id}/reports"
          inputParameters:
            - name: global_company_id
              in: path
          operations:
            - name: get-report
              method: POST
    - namespace: slack-marketing
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST
    - namespace: msteams-marketing
      type: http
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-message
          path: "/teams/{team_id}/channels/{channel_id}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Verifies whether a specific merchant is enrolled in the American Express acceptance network.

naftiko: "0.5"
info:
  label: "Merchant Acceptance Verification"
  description: "Verifies whether a specific merchant is enrolled in the American Express acceptance network."
  tags:
    - merchants
    - payments
    - network
capability:
  exposes:
    - type: mcp
      namespace: amex-network
      port: 8080
      tools:
        - name: verify-acceptance
          description: "Given a merchant ID, verify their enrollment in the Amex acceptance network and return network status and enrollment date. Use when confirming merchant acceptance."
          inputParameters:
            - name: merchant_id
              in: body
              type: string
              description: "The merchant identifier."
          call: "amex-network.verify-acceptance"
          with:
            merchant_id: "{{merchant_id}}"
          outputParameters:
            - name: accepted
              type: boolean
              mapping: "$.accepted"
            - name: network_status
              type: string
              mapping: "$.network_status"
            - name: enrollment_date
              type: string
              mapping: "$.enrollment_date"
  consumes:
    - namespace: amex-network
      type: http
      baseUri: "https://api.americanexpress.com/v1/network"
      authentication:
        type: bearer
        token: "$secrets.amex_network_token"
      resources:
        - name: acceptance
          path: "/merchants/{merchant_id}/acceptance"
          inputParameters:
            - name: merchant_id
              in: path
          operations:
            - name: verify-acceptance
              method: GET

Looks up a merchant category code and returns its description and risk classification from the merchant data service.

naftiko: "0.5"
info:
  label: "Merchant Category Code Lookup"
  description: "Looks up a merchant category code and returns its description and risk classification from the merchant data service."
  tags:
    - merchants
    - payments
    - data
capability:
  exposes:
    - type: mcp
      namespace: amex-merchant-data
      port: 8080
      tools:
        - name: get-mcc
          description: "Given a merchant category code, return its description, risk level, and category. Use when classifying merchant transactions."
          inputParameters:
            - name: mcc_code
              in: body
              type: string
              description: "The merchant category code to look up."
          call: "amex-merchant-data.get-mcc"
          with:
            mcc_code: "{{mcc_code}}"
          outputParameters:
            - name: description
              type: string
              mapping: "$.description"
            - name: risk_level
              type: string
              mapping: "$.risk_level"
            - name: category
              type: string
              mapping: "$.category"
  consumes:
    - namespace: amex-merchant-data
      type: http
      baseUri: "https://api.americanexpress.com/v1/merchants"
      authentication:
        type: bearer
        token: "$secrets.amex_merchant_token"
      resources:
        - name: mcc
          path: "/mcc/{mcc_code}"
          inputParameters:
            - name: mcc_code
              in: path
          operations:
            - name: get-mcc
              method: GET

When a cardholder dispute is filed, retrieves dispute details from the disputes platform, creates a Jira case for the disputes team, and posts a Slack notification to the resolution channel.

naftiko: "0.5"
info:
  label: "Merchant Dispute Resolution Workflow"
  description: "When a cardholder dispute is filed, retrieves dispute details from the disputes platform, creates a Jira case for the disputes team, and posts a Slack notification to the resolution channel."
  tags:
    - disputes
    - payments
    - jira
    - slack
    - customer-support
capability:
  exposes:
    - type: mcp
      namespace: disputes-ops
      port: 8080
      tools:
        - name: open-dispute-case
          description: "Given a dispute ID, fetch dispute details and open a Jira issue for the disputes resolution team. Post a Slack alert to the disputes channel with key context. Use when a new cardholder dispute requires case management."
          inputParameters:
            - name: dispute_id
              in: body
              type: string
              description: "The unique dispute identifier from the disputes platform."
            - name: jira_project_key
              in: body
              type: string
              description: "The Jira project key for dispute cases (e.g., DISP)."
          steps:
            - name: get-dispute
              type: call
              call: "amex-disputes.get-dispute"
              with:
                dispute_id: "{{dispute_id}}"
            - name: create-jira-issue
              type: call
              call: "jira.create-issue"
              with:
                project_key: "{{jira_project_key}}"
                issuetype: "Task"
                summary: "Dispute {{dispute_id}} — {{get-dispute.merchant_name}} ${{get-dispute.amount}}"
                description: "Cardholder: {{get-dispute.cardholder_name}}\nMerchant: {{get-dispute.merchant_name}}\nAmount: {{get-dispute.amount}} {{get-dispute.currency}}\nDate: {{get-dispute.transaction_date}}"
            - name: post-slack-alert
              type: call
              call: "slack.post-message"
              with:
                channel: "disputes-team"
                text: "New dispute opened: {{dispute_id}} | Merchant: {{get-dispute.merchant_name}} | Amount: ${{get-dispute.amount}} | Jira: {{create-jira-issue.key}}"
  consumes:
    - namespace: amex-disputes
      type: http
      baseUri: "https://api.americanexpress.com/v1/disputes"
      authentication:
        type: bearer
        token: "$secrets.amex_disputes_token"
      resources:
        - name: dispute
          path: "/disputes/{dispute_id}"
          inputParameters:
            - name: dispute_id
              in: path
          operations:
            - name: get-dispute
              method: GET
    - namespace: jira
      type: http
      baseUri: "https://americanexpress.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issue
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - namespace: slack
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves the current discount rate and fee structure for a merchant enrolled in the Amex network.

naftiko: "0.5"
info:
  label: "Merchant Fee Rate Lookup"
  description: "Retrieves the current discount rate and fee structure for a merchant enrolled in the Amex network."
  tags:
    - merchants
    - payments
    - fees
capability:
  exposes:
    - type: mcp
      namespace: amex-merchant-data
      port: 8080
      tools:
        - name: get-fee-rate
          description: "Given a merchant ID, return the discount rate, transaction fee, and effective date. Use when reviewing merchant fee arrangements."
          inputParameters:
            - name: merchant_id
              in: body
              type: string
              description: "The merchant identifier."
          call: "amex-merchant-data.get-fee-rate"
          with:
            merchant_id: "{{merchant_id}}"
          outputParameters:
            - name: discount_rate
              type: number
              mapping: "$.discount_rate"
            - name: transaction_fee
              type: number
              mapping: "$.transaction_fee"
            - name: effective_date
              type: string
              mapping: "$.effective_date"
  consumes:
    - namespace: amex-merchant-data
      type: http
      baseUri: "https://api.americanexpress.com/v1/merchants"
      authentication:
        type: bearer
        token: "$secrets.amex_merchant_token"
      resources:
        - name: fees
          path: "/merchants/{merchant_id}/fees"
          inputParameters:
            - name: merchant_id
              in: path
          operations:
            - name: get-fee-rate
              method: GET

Retrieves the current status of a merchant onboarding application from the merchant services platform and returns structured status details.

naftiko: "0.5"
info:
  label: "Merchant Onboarding Application Status Check"
  description: "Retrieves the current status of a merchant onboarding application from the merchant services platform and returns structured status details."
  tags:
    - merchant-services
    - onboarding
    - payments
    - lookup
capability:
  exposes:
    - type: mcp
      namespace: merchant-onboarding
      port: 8080
      tools:
        - name: get-merchant-application-status
          description: "Given a merchant application ID, return the current onboarding status, review stage, and any pending requirements. Use when a merchant services agent needs to check where an application stands."
          inputParameters:
            - name: application_id
              in: body
              type: string
              description: "The merchant onboarding application ID issued at submission."
          call: "amex-merchant.get-application"
          with:
            application_id: "{{application_id}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.status"
            - name: review_stage
              type: string
              mapping: "$.review_stage"
            - name: pending_items
              type: array
              mapping: "$.pending_items"
  consumes:
    - namespace: amex-merchant
      type: http
      baseUri: "https://api.americanexpress.com/v1/merchant-services"
      authentication:
        type: bearer
        token: "$secrets.amex_merchant_token"
      resources:
        - name: application
          path: "/applications/{application_id}"
          inputParameters:
            - name: application_id
              in: path
          operations:
            - name: get-application
              method: GET

Performs merchant risk assessment by aggregating transaction data from Snowflake, running a risk model, updating the merchant profile in Salesforce, and filing findings in ServiceNow.

naftiko: "0.5"
info:
  label: "Merchant Risk Assessment Workflow"
  description: "Performs merchant risk assessment by aggregating transaction data from Snowflake, running a risk model, updating the merchant profile in Salesforce, and filing findings in ServiceNow."
  tags:
    - merchants
    - risk
    - snowflake
    - salesforce
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: merchant-risk
      port: 8080
      tools:
        - name: assess-merchant-risk
          description: "Assess merchant risk by analyzing transaction patterns and scoring. Use during periodic merchant risk reviews."
          inputParameters:
            - name: merchant_id
              in: body
              type: string
              description: "Merchant ID."
            - name: sf_account_id
              in: body
              type: string
              description: "Salesforce account ID."
          steps:
            - name: get-txn-data
              type: call
              call: "snowflake.run-query"
              with:
                query: "SELECT AVG(amount) as avg_txn, COUNT(*) as txn_count, SUM(chargeback_amount) as cb_total FROM MERCHANT_DB.PUBLIC.TRANSACTIONS WHERE merchant_id='{{merchant_id}}' AND date >= DATEADD(month, -6, CURRENT_DATE())"
            - name: score
              type: call
              call: "amex-risk.score-merchant"
              with:
                merchant_id: "{{merchant_id}}"
                avg_transaction: "{{get-txn-data.avg_txn}}"
                chargeback_total: "{{get-txn-data.cb_total}}"
            - name: update-sf
              type: call
              call: "salesforce.update-account"
              with:
                account_id: "{{sf_account_id}}"
                Risk_Score__c: "{{score.risk_score}}"
                Last_Assessment__c: "{{score.assessment_date}}"
            - name: file-findings
              type: call
              call: "servicenow.create-case"
              with:
                short_description: "Merchant risk assessment — {{merchant_id}}"
                description: "Risk score: {{score.risk_score}}. Avg txn: ${{get-txn-data.avg_txn}}. Chargeback total: ${{get-txn-data.cb_total}}."
  consumes:
    - namespace: snowflake
      type: http
      baseUri: "https://americanexpress.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - namespace: amex-risk
      type: http
      baseUri: "https://api.americanexpress.com/v1/risk"
      authentication:
        type: bearer
        token: "$secrets.amex_risk_token"
      resources:
        - name: merchant-risk
          path: "/merchants/score"
          operations:
            - name: score-merchant
              method: POST
    - namespace: salesforce
      type: http
      baseUri: "https://americanexpress.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
    - namespace: servicenow
      type: http
      baseUri: "https://americanexpress.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: cases
          path: "/table/sn_risk_case"
          operations:
            - name: create-case
              method: POST

Retrieves the latest settlement status and payout details for a merchant from the settlements service.

naftiko: "0.5"
info:
  label: "Merchant Settlement Status Lookup"
  description: "Retrieves the latest settlement status and payout details for a merchant from the settlements service."
  tags:
    - merchants
    - payments
    - settlements
capability:
  exposes:
    - type: mcp
      namespace: amex-settlements
      port: 8080
      tools:
        - name: get-settlement-status
          description: "Given a merchant ID, return the latest settlement amount, status, and payout date. Use when a merchant inquires about payment settlement."
          inputParameters:
            - name: merchant_id
              in: body
              type: string
              description: "The merchant identifier."
          call: "amex-settlements.get-settlement-status"
          with:
            merchant_id: "{{merchant_id}}"
          outputParameters:
            - name: settlement_amount
              type: number
              mapping: "$.amount"
            - name: status
              type: string
              mapping: "$.status"
            - name: payout_date
              type: string
              mapping: "$.payout_date"
  consumes:
    - namespace: amex-settlements
      type: http
      baseUri: "https://api.americanexpress.com/v1/settlements"
      authentication:
        type: bearer
        token: "$secrets.amex_settlements_token"
      resources:
        - name: settlement
          path: "/merchants/{merchant_id}/settlements/latest"
          inputParameters:
            - name: merchant_id
              in: path
          operations:
            - name: get-settlement-status
              method: GET

When a new employee is created in Workday, provisions a corporate card account and sends onboarding instructions via Microsoft Teams.

naftiko: "0.5"
info:
  label: "New Employee Card Provisioning"
  description: "When a new employee is created in Workday, provisions a corporate card account and sends onboarding instructions via Microsoft Teams."
  tags:
    - hr
    - onboarding
    - workday
    - payments
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: hr-provisioning
      port: 8080
      tools:
        - name: provision-employee-card
          description: "Given a Workday employee ID, retrieve employee details, create a corporate card account, and send the cardholder a Teams message with activation instructions. Invoke during new hire onboarding."
          inputParameters:
            - name: workday_employee_id
              in: body
              type: string
              description: "The Workday worker ID for the new hire."
            - name: cost_center
              in: body
              type: string
              description: "The cost center code to associate with the new corporate card."
          steps:
            - name: get-employee
              type: call
              call: "workday.get-worker"
              with:
                worker_id: "{{workday_employee_id}}"
            - name: create-card-account
              type: call
              call: "amex-corp.create-card-account"
              with:
                first_name: "{{get-employee.first_name}}"
                last_name: "{{get-employee.last_name}}"
                email: "{{get-employee.work_email}}"
                cost_center: "{{cost_center}}"
            - name: send-instructions
              type: call
              call: "msteams.send-message"
              with:
                recipient_upn: "{{get-employee.work_email}}"
                text: "Welcome! Your American Express corporate card has been provisioned. Account reference: {{create-card-account.account_id}}. Activate at amex.com/activate."
  consumes:
    - namespace: workday
      type: http
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_access_token"
      resources:
        - name: worker
          path: "/workers/{worker_id}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - namespace: amex-corp
      type: http
      baseUri: "https://api.americanexpress.com/v1/corporate"
      authentication:
        type: bearer
        token: "$secrets.amex_corp_token"
      resources:
        - name: card-account
          path: "/accounts"
          operations:
            - name: create-card-account
              method: POST
    - namespace: msteams
      type: http
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: chat-message
          path: "/users/{recipient_upn}/sendMail"
          inputParameters:
            - name: recipient_upn
              in: path
          operations:
            - name: send-message
              method: POST

Orchestrates new merchant onboarding by creating the merchant record, provisioning payment gateway credentials, assigning a relationship manager in Salesforce, and sending a welcome kit email.

naftiko: "0.5"
info:
  label: "New Merchant Onboarding Orchestration"
  description: "Orchestrates new merchant onboarding by creating the merchant record, provisioning payment gateway credentials, assigning a relationship manager in Salesforce, and sending a welcome kit email."
  tags:
    - merchants
    - onboarding
    - salesforce
    - payments
capability:
  exposes:
    - type: mcp
      namespace: merchant-onboard
      port: 8080
      tools:
        - name: onboard-merchant
          description: "Onboard a new merchant by creating their record, provisioning gateway credentials, creating a Salesforce account, and sending a welcome email. Use when a new merchant is approved for the network."
          inputParameters:
            - name: merchant_name
              in: body
              type: string
              description: "Legal name of the merchant."
            - name: mcc_code
              in: body
              type: string
              description: "Merchant category code."
            - name: contact_email
              in: body
              type: string
              description: "Primary contact email."
          steps:
            - name: create-merchant
              type: call
              call: "amex-merchants.create-merchant"
              with:
                name: "{{merchant_name}}"
                mcc: "{{mcc_code}}"
                contact_email: "{{contact_email}}"
            - name: provision-gateway
              type: call
              call: "amex-gateway.provision-credentials"
              with:
                merchant_id: "{{create-merchant.merchant_id}}"
            - name: create-sf-account
              type: call
              call: "salesforce.create-account"
              with:
                Name: "{{merchant_name}}"
                Type: "Merchant"
                AmexMerchantId__c: "{{create-merchant.merchant_id}}"
            - name: send-welcome
              type: call
              call: "email.send-email"
              with:
                to: "{{contact_email}}"
                subject: "Welcome to the American Express Network"
                body: "Your merchant ID is {{create-merchant.merchant_id}}. Gateway credentials have been provisioned. Your account manager will reach out shortly."
  consumes:
    - namespace: amex-merchants
      type: http
      baseUri: "https://api.americanexpress.com/v1/merchants"
      authentication:
        type: bearer
        token: "$secrets.amex_merchant_token"
      resources:
        - name: merchant
          path: "/merchants"
          operations:
            - name: create-merchant
              method: POST
    - namespace: amex-gateway
      type: http
      baseUri: "https://api.americanexpress.com/v1/gateway"
      authentication:
        type: bearer
        token: "$secrets.amex_gateway_token"
      resources:
        - name: credentials
          path: "/merchants/{merchant_id}/credentials"
          inputParameters:
            - name: merchant_id
              in: path
          operations:
            - name: provision-credentials
              method: POST
    - namespace: salesforce
      type: http
      baseUri: "https://americanexpress.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: accounts
          path: "/sobjects/Account"
          operations:
            - name: create-account
              method: POST
    - namespace: email
      type: http
      baseUri: "https://api.americanexpress.com/v1/notifications"
      authentication:
        type: bearer
        token: "$secrets.amex_notifications_token"
      resources:
        - name: messages
          path: "/email/send"
          operations:
            - name: send-email
              method: POST

Responds to New Relic performance alerts by fetching violation details, creating a PagerDuty incident, opening a Jira bug, and posting to the engineering Slack channel.

naftiko: "0.5"
info:
  label: "New Relic Performance Degradation Handler"
  description: "Responds to New Relic performance alerts by fetching violation details, creating a PagerDuty incident, opening a Jira bug, and posting to the engineering Slack channel."
  tags:
    - new-relic
    - monitoring
    - pagerduty
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: perf-handler
      port: 8080
      tools:
        - name: handle-perf-degradation
          description: "Respond to a performance degradation alert by paging on-call, creating a bug, and notifying engineering. Use when New Relic detects performance issues."
          inputParameters:
            - name: policy_id
              in: body
              type: string
              description: "New Relic alert policy ID."
          steps:
            - name: get-violations
              type: call
              call: "newrelic.get-violations"
              with:
                policy_id: "{{policy_id}}"
            - name: page-oncall
              type: call
              call: "pagerduty.create-incident"
              with:
                title: "Perf degradation: {{get-violations.condition_name}}"
                service_id: "$secrets.pd_service_id"
                urgency: "high"
            - name: create-bug
              type: call
              call: "jira.create-issue"
              with:
                project_key: "ENG"
                issuetype: "Bug"
                summary: "Perf degradation: {{get-violations.condition_name}}"
                description: "Violation: {{get-violations.condition_name}}. Threshold: {{get-violations.threshold}}. Value: {{get-violations.value}}."
            - name: alert-eng
              type: call
              call: "slack.post-message"
              with:
                channel: "engineering-alerts"
                text: "Performance degradation: {{get-violations.condition_name}} | PD: {{page-oncall.incident_number}} | Jira: {{create-bug.key}}"
  consumes:
    - namespace: newrelic
      type: http
      baseUri: "https://api.newrelic.com/v2"
      authentication:
        type: bearer
        token: "$secrets.newrelic_token"
      resources:
        - name: alerts
          path: "/alerts_violations.json"
          operations:
            - name: get-violations
              method: GET
    - namespace: pagerduty
      type: http
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: bearer
        token: "$secrets.pagerduty_token"
      resources:
        - name: incidents
          path: "/incidents"
          operations:
            - name: create-incident
              method: POST
    - namespace: jira
      type: http
      baseUri: "https://americanexpress.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issue
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - namespace: slack
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a role change is recorded in Workday, updates the employee's Okta group memberships and notifies the employee via Microsoft Teams of their new access.

naftiko: "0.5"
info:
  label: "Okta Access Provisioning for New Role"
  description: "When a role change is recorded in Workday, updates the employee's Okta group memberships and notifies the employee via Microsoft Teams of their new access."
  tags:
    - identity
    - security
    - okta
    - workday
    - microsoft-teams
    - access-management
capability:
  exposes:
    - type: mcp
      namespace: identity-provisioning
      port: 8080
      tools:
        - name: provision-role-access
          description: "Given a Workday employee ID and new role, retrieve the employee's Okta user ID, update their group memberships to reflect the new role, and notify them via Teams. Use when an employee changes roles and needs updated system access."
          inputParameters:
            - name: workday_employee_id
              in: body
              type: string
              description: "The Workday worker ID of the employee whose role is changing."
            - name: new_role
              in: body
              type: string
              description: "The new role or job title as defined in Workday."
            - name: okta_group_id
              in: body
              type: string
              description: "The Okta group ID corresponding to the new role's access profile."
          steps:
            - name: get-employee
              type: call
              call: "workday-iam.get-worker"
              with:
                worker_id: "{{workday_employee_id}}"
            - name: get-okta-user
              type: call
              call: "okta.get-user-by-login"
              with:
                login: "{{get-employee.work_email}}"
            - name: add-to-group
              type: call
              call: "okta-groups.add-user-to-group"
              with:
                group_id: "{{okta_group_id}}"
                user_id: "{{get-okta-user.id}}"
            - name: notify-employee
              type: call
              call: "msteams-iam.send-message"
              with:
                recipient_upn: "{{get-employee.work_email}}"
                text: "Your access has been updated for your new role: {{new_role}}. If you have questions, contact the IT help desk."
  consumes:
    - namespace: workday-iam
      type: http
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_access_token"
      resources:
        - name: worker
          path: "/workers/{worker_id}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - namespace: okta
      type: http
      baseUri: "https://americanexpress.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_api_token"
        placement: header
      resources:
        - name: user
          path: "/users/{login}"
          inputParameters:
            - name: login
              in: path
          operations:
            - name: get-user-by-login
              method: GET
    - namespace: okta-groups
      type: http
      baseUri: "https://americanexpress.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_api_token"
        placement: header
      resources:
        - name: group-membership
          path: "/groups/{group_id}/users/{user_id}"
          inputParameters:
            - name: group_id
              in: path
            - name: user_id
              in: path
          operations:
            - name: add-user-to-group
              method: PUT
    - namespace: msteams-iam
      type: http
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: mail
          path: "/users/{recipient_upn}/sendMail"
          inputParameters:
            - name: recipient_upn
              in: path
          operations:
            - name: send-message
              method: POST

Deprovisions a terminated employee by deactivating their Okta account, revoking all app assignments, creating a ServiceNow closure ticket, and notifying security via Slack.

naftiko: "0.5"
info:
  label: "Okta User Deprovisioning Workflow"
  description: "Deprovisions a terminated employee by deactivating their Okta account, revoking all app assignments, creating a ServiceNow closure ticket, and notifying security via Slack."
  tags:
    - identity
    - okta
    - servicenow
    - security
    - offboarding
capability:
  exposes:
    - type: mcp
      namespace: okta-deprovision
      port: 8080
      tools:
        - name: deprovision-user
          description: "Deactivate an Okta user, revoke app assignments, create a closure ticket, and notify security. Use when an employee is terminated."
          inputParameters:
            - name: user_id
              in: body
              type: string
              description: "Okta user ID of the terminated employee."
          steps:
            - name: deactivate
              type: call
              call: "okta.deactivate-user"
              with:
                user_id: "{{user_id}}"
            - name: revoke-apps
              type: call
              call: "okta.list-apps"
              with:
                user_id: "{{user_id}}"
            - name: create-ticket
              type: call
              call: "servicenow.create-request"
              with:
                short_description: "User deprovisioned — {{user_id}}"
                description: "Okta account deactivated. App assignments revoked: {{revoke-apps.app_count}}."
            - name: notify-security
              type: call
              call: "slack.post-message"
              with:
                channel: "security-ops"
                text: "User deprovisioned: {{user_id}}. {{revoke-apps.app_count}} app assignments revoked. SNOW: {{create-ticket.number}}"
  consumes:
    - namespace: okta
      type: http
      baseUri: "https://americanexpress.okta.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.okta_token"
      resources:
        - name: users
          path: "/users/{user_id}"
          inputParameters:
            - name: user_id
              in: path
          operations:
            - name: deactivate-user
              method: POST
            - name: list-apps
              method: GET
    - namespace: servicenow
      type: http
      baseUri: "https://americanexpress.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: create-request
              method: POST
    - namespace: slack
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Monitors Oracle database health by querying performance metrics, creating a ServiceNow incident if thresholds are breached, and notifying the DBA team via Slack.

naftiko: "0.5"
info:
  label: "Oracle Database Health Monitoring"
  description: "Monitors Oracle database health by querying performance metrics, creating a ServiceNow incident if thresholds are breached, and notifying the DBA team via Slack."
  tags:
    - oracle
    - database
    - servicenow
    - slack
    - monitoring
capability:
  exposes:
    - type: mcp
      namespace: oracle-health
      port: 8080
      tools:
        - name: monitor-oracle-health
          description: "Check Oracle database health, create an incident if degraded, and notify DBAs. Use when scheduled health checks run or alerts trigger."
          inputParameters:
            - name: database_name
              in: body
              type: string
              description: "Oracle database name."
          steps:
            - name: check-health
              type: call
              call: "oracle-cloud.get-health"
              with: {}
            - name: create-incident
              type: call
              call: "servicenow.create-incident"
              with:
                short_description: "Oracle DB health alert — {{database_name}}"
                category: "database"
                priority: "2"
                description: "CPU: {{check-health.cpu_pct}}%. Sessions: {{check-health.active_sessions}}. Tablespace: {{check-health.tablespace_pct}}%."
            - name: notify-dba
              type: call
              call: "slack.post-message"
              with:
                channel: "dba-ops"
                text: "Oracle DB alert: {{database_name}} | CPU: {{check-health.cpu_pct}}% | Sessions: {{check-health.active_sessions}} | SNOW: {{create-incident.number}}"
  consumes:
    - namespace: oracle-cloud
      type: http
      baseUri: "https://database.americanexpress.oraclecloud.com/ords"
      authentication:
        type: bearer
        token: "$secrets.oracle_token"
      resources:
        - name: metrics
          path: "/admin/health"
          operations:
            - name: get-health
              method: GET
    - namespace: servicenow
      type: http
      baseUri: "https://americanexpress.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
    - namespace: slack
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Generates a postmortem for a PagerDuty incident by fetching incident timeline, creating a Confluence postmortem page, and notifying stakeholders via Slack.

naftiko: "0.5"
info:
  label: "PagerDuty Incident Postmortem Generator"
  description: "Generates a postmortem for a PagerDuty incident by fetching incident timeline, creating a Confluence postmortem page, and notifying stakeholders via Slack."
  tags:
    - pagerduty
    - incident-management
    - confluence
    - slack
capability:
  exposes:
    - type: mcp
      namespace: postmortem-gen
      port: 8080
      tools:
        - name: generate-postmortem
          description: "Generate a postmortem document from a PagerDuty incident and share it. Use after an incident is resolved."
          inputParameters:
            - name: incident_id
              in: body
              type: string
              description: "PagerDuty incident ID."
          steps:
            - name: get-incident
              type: call
              call: "pagerduty.get-incident"
              with:
                incident_id: "{{incident_id}}"
            - name: get-timeline
              type: call
              call: "pagerduty.get-timeline"
              with:
                incident_id: "{{incident_id}}"
            - name: create-postmortem
              type: call
              call: "confluence.create-page"
              with:
                spaceKey: "ENG"
                title: "Postmortem: {{get-incident.title}}"
                body: "Severity: {{get-incident.urgency}}. Duration: {{get-incident.duration}}. Timeline entries: {{get-timeline.total}}."
            - name: notify
              type: call
              call: "slack.post-message"
              with:
                channel: "engineering"
                text: "Postmortem ready: {{get-incident.title}} | Severity: {{get-incident.urgency}} | Doc: {{create-postmortem.url}}"
  consumes:
    - namespace: pagerduty
      type: http
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: bearer
        token: "$secrets.pagerduty_token"
      resources:
        - name: incidents
          path: "/incidents/{incident_id}"
          inputParameters:
            - name: incident_id
              in: path
          operations:
            - name: get-incident
              method: GET
        - name: logs
          path: "/incidents/{incident_id}/log_entries"
          inputParameters:
            - name: incident_id
              in: path
          operations:
            - name: get-timeline
              method: GET
    - namespace: confluence
      type: http
      baseUri: "https://americanexpress.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: pages
          path: "/content"
          operations:
            - name: create-page
              method: POST
    - namespace: slack
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When Palo Alto Networks detects a blocked threat on the corporate network, retrieves the threat log entry and creates a ServiceNow security incident for the SOC team to review.

naftiko: "0.5"
info:
  label: "Palo Alto Networks Threat Block and Incident Log"
  description: "When Palo Alto Networks detects a blocked threat on the corporate network, retrieves the threat log entry and creates a ServiceNow security incident for the SOC team to review."
  tags:
    - security
    - palo-alto-networks
    - servicenow
    - threat-response
    - network-security
capability:
  exposes:
    - type: mcp
      namespace: network-security
      port: 8080
      tools:
        - name: log-network-threat
          description: "Given a Palo Alto Networks threat log entry ID, retrieve the threat details and create a ServiceNow security incident for SOC review. Use when automated threat blocking events require case tracking and analyst review."
          inputParameters:
            - name: threat_log_id
              in: body
              type: string
              description: "The Palo Alto Networks threat log entry ID."
            - name: firewall_hostname
              in: body
              type: string
              description: "The hostname of the Palo Alto firewall that generated the log."
          steps:
            - name: get-threat-log
              type: call
              call: "paloalto.get-threat-log"
              with:
                log_id: "{{threat_log_id}}"
            - name: create-soc-incident
              type: call
              call: "servicenow-netsec.create-incident"
              with:
                category: "security"
                subcategory: "network_threat"
                short_description: "Network threat blocked by {{firewall_hostname}}: {{get-threat-log.threat_name}}"
                description: "Firewall: {{firewall_hostname}}\nThreat: {{get-threat-log.threat_name}}\nSeverity: {{get-threat-log.severity}}\nSource IP: {{get-threat-log.source_ip}}\nDestination: {{get-threat-log.destination_ip}}\nAction: {{get-threat-log.action}}"
                urgency: "2"
  consumes:
    - namespace: paloalto
      type: http
      baseUri: "https://panorama.americanexpress.com/restapi/v10.1"
      authentication:
        type: apikey
        key: "X-PAN-KEY"
        value: "$secrets.paloalto_api_key"
        placement: header
      resources:
        - name: threat-log
          path: "/Objects/Threats/{log_id}"
          inputParameters:
            - name: log_id
              in: path
          operations:
            - name: get-threat-log
              method: GET
    - namespace: servicenow-netsec
      type: http
      baseUri: "https://americanexpress.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incident
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST

Rotates TLS certificates for payment gateway endpoints by generating a new certificate, deploying it via Terraform, validating connectivity, and notifying the infrastructure team via Slack.

naftiko: "0.5"
info:
  label: "Payment Gateway Certificate Rotation"
  description: "Rotates TLS certificates for payment gateway endpoints by generating a new certificate, deploying it via Terraform, validating connectivity, and notifying the infrastructure team via Slack."
  tags:
    - security
    - infrastructure
    - terraform
    - slack
capability:
  exposes:
    - type: mcp
      namespace: cert-rotation
      port: 8080
      tools:
        - name: rotate-gateway-cert
          description: "Generate a new TLS certificate, deploy via Terraform, validate, and notify the team. Use during scheduled certificate rotation windows."
          inputParameters: []
          steps:
            - name: generate-cert
              type: call
              call: "amex-pki.generate-cert"
              with:
                domain: "gateway.americanexpress.com"
                validity_days: "365"
            - name: deploy-cert
              type: call
              call: "terraform-cloud.trigger-apply"
              with:
                workspace_id: "$secrets.tf_gateway_workspace"
                message: "Cert rotation — {{generate-cert.serial_number}}"
            - name: validate
              type: call
              call: "amex-gateway.check-health"
              with: {}
            - name: notify
              type: call
              call: "slack.post-message"
              with:
                channel: "infra-ops"
                text: "TLS cert rotated for gateway.americanexpress.com. Serial: {{generate-cert.serial_number}}. Health: {{validate.status}}"
  consumes:
    - namespace: amex-pki
      type: http
      baseUri: "https://api.americanexpress.com/v1/pki"
      authentication:
        type: bearer
        token: "$secrets.amex_pki_token"
      resources:
        - name: certificates
          path: "/certificates"
          operations:
            - name: generate-cert
              method: POST
    - namespace: terraform-cloud
      type: http
      baseUri: "https://app.terraform.io/api/v2"
      authentication:
        type: bearer
        token: "$secrets.terraform_token"
      resources:
        - name: runs
          path: "/runs"
          operations:
            - name: trigger-apply
              method: POST
    - namespace: amex-gateway
      type: http
      baseUri: "https://api.americanexpress.com/v1/gateway"
      authentication:
        type: bearer
        token: "$secrets.amex_gateway_token"
      resources:
        - name: health
          path: "/health"
          operations:
            - name: check-health
              method: GET
    - namespace: slack
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a Datadog monitor detects payment network latency breaching SLA thresholds, creates a PagerDuty critical incident, updates a ServiceNow major incident, and posts a status update to the executive Slack channel.

naftiko: "0.5"
info:
  label: "Payment Network Incident Escalation"
  description: "When a Datadog monitor detects payment network latency breaching SLA thresholds, creates a PagerDuty critical incident, updates a ServiceNow major incident, and posts a status update to the executive Slack channel."
  tags:
    - payments
    - sla
    - datadog
    - pagerduty
    - servicenow
    - incident-response
capability:
  exposes:
    - type: mcp
      namespace: network-incident
      port: 8080
      tools:
        - name: escalate-network-incident
          description: "Given a Datadog monitor ID and affected payment network segment, retrieve monitor state, create a critical PagerDuty incident, open a ServiceNow major incident, and post an executive Slack alert. Use when payment network SLAs are breached."
          inputParameters:
            - name: monitor_id
              in: body
              type: string
              description: "The Datadog monitor ID for the payment network SLA check."
            - name: network_segment
              in: body
              type: string
              description: "The affected payment network segment (e.g., card-auth, settlement)."
            - name: latency_p99_ms
              in: body
              type: number
              description: "The measured P99 latency in milliseconds that breached SLA."
          steps:
            - name: get-monitor-state
              type: call
              call: "datadog-network.get-monitor"
              with:
                monitor_id: "{{monitor_id}}"
            - name: create-pd-critical
              type: call
              call: "pagerduty-network.create-incident"
              with:
                title: "CRITICAL: Payment network SLA breach — {{network_segment}}"
                service_id: "$secrets.pagerduty_network_service_id"
                urgency: "high"
                body: "Segment: {{network_segment}} | P99: {{latency_p99_ms}}ms | Monitor: {{monitor_id}}"
            - name: open-major-incident
              type: call
              call: "servicenow-network.create-incident"
              with:
                category: "network"
                subcategory: "payment_processing"
                short_description: "Payment network SLA breach: {{network_segment}} P99={{latency_p99_ms}}ms"
                urgency: "1"
                impact: "1"
                severity: "1"
            - name: post-executive-alert
              type: call
              call: "slack-executive.post-message"
              with:
                channel: "exec-alerts"
                text: "CRITICAL | Payment Network | Segment: {{network_segment}} | P99 Latency: {{latency_p99_ms}}ms | PagerDuty: {{create-pd-critical.incident_number}} | SNOW: {{open-major-incident.number}}"
  consumes:
    - namespace: datadog-network
      type: http
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: monitor
          path: "/monitor/{monitor_id}"
          inputParameters:
            - name: monitor_id
              in: path
          operations:
            - name: get-monitor
              method: GET
    - namespace: pagerduty-network
      type: http
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.pagerduty_api_key"
        placement: header
      resources:
        - name: incident
          path: "/incidents"
          operations:
            - name: create-incident
              method: POST
    - namespace: servicenow-network
      type: http
      baseUri: "https://americanexpress.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incident
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - namespace: slack-executive
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Checks the PCI-DSS compliance status of a merchant from the compliance registry.

naftiko: "0.5"
info:
  label: "PCI Compliance Status Lookup"
  description: "Checks the PCI-DSS compliance status of a merchant from the compliance registry."
  tags:
    - compliance
    - merchants
    - security
capability:
  exposes:
    - type: mcp
      namespace: amex-compliance
      port: 8080
      tools:
        - name: get-pci-status
          description: "Given a merchant ID, return the PCI-DSS compliance status, last assessment date, and compliance level. Use when verifying merchant security compliance."
          inputParameters:
            - name: merchant_id
              in: body
              type: string
              description: "The merchant identifier."
          call: "amex-compliance.get-pci-status"
          with:
            merchant_id: "{{merchant_id}}"
          outputParameters:
            - name: compliant
              type: boolean
              mapping: "$.compliant"
            - name: last_assessment
              type: string
              mapping: "$.last_assessment"
            - name: level
              type: string
              mapping: "$.level"
  consumes:
    - namespace: amex-compliance
      type: http
      baseUri: "https://api.americanexpress.com/v1/compliance"
      authentication:
        type: bearer
        token: "$secrets.amex_compliance_token"
      resources:
        - name: pci-status
          path: "/merchants/{merchant_id}/pci-status"
          inputParameters:
            - name: merchant_id
              in: path
          operations:
            - name: get-pci-status
              method: GET

When a purchase order is submitted in SAP Ariba, retrieves PO details and creates a ServiceNow approval task for the appropriate budget owner.

naftiko: "0.5"
info:
  label: "Purchase Order Approval Workflow"
  description: "When a purchase order is submitted in SAP Ariba, retrieves PO details and creates a ServiceNow approval task for the appropriate budget owner."
  tags:
    - procurement
    - finance
    - sap-ariba
    - servicenow
    - approval
capability:
  exposes:
    - type: mcp
      namespace: procurement-approval
      port: 8080
      tools:
        - name: route-po-for-approval
          description: "Given an SAP Ariba purchase order ID, retrieve PO details including amount and vendor, and create a ServiceNow approval task for the budget owner. Use when purchase orders above threshold require additional approval routing."
          inputParameters:
            - name: po_id
              in: body
              type: string
              description: "The SAP Ariba purchase order ID to route for approval."
            - name: approver_email
              in: body
              type: string
              description: "The email address of the designated budget approver."
          steps:
            - name: get-po
              type: call
              call: "ariba.get-purchase-order"
              with:
                po_id: "{{po_id}}"
            - name: create-approval
              type: call
              call: "servicenow-procurement.create-task"
              with:
                category: "procurement_approval"
                short_description: "PO approval required: {{po_id}} — ${{get-po.total_amount}} {{get-po.currency}}"
                description: "PO: {{po_id}}\nVendor: {{get-po.vendor_name}}\nAmount: ${{get-po.total_amount}} {{get-po.currency}}\nLine items: {{get-po.line_item_count}}\nRequested by: {{get-po.requester_name}}"
                assigned_to: "{{approver_email}}"
  consumes:
    - namespace: ariba
      type: http
      baseUri: "https://openapi.ariba.com/api/purchase-orders/v1"
      authentication:
        type: bearer
        token: "$secrets.ariba_access_token"
      resources:
        - name: purchase-order
          path: "/purchaseOrders/{po_id}"
          inputParameters:
            - name: po_id
              in: path
          operations:
            - name: get-purchase-order
              method: GET
    - namespace: servicenow-procurement
      type: http
      baseUri: "https://americanexpress.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: task
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST

Prepares quarterly compliance audit materials by extracting control evidence from ServiceNow, generating a summary from Snowflake, and distributing the report via SharePoint and email.

naftiko: "0.5"
info:
  label: "Quarterly Compliance Audit Preparation"
  description: "Prepares quarterly compliance audit materials by extracting control evidence from ServiceNow, generating a summary from Snowflake, and distributing the report via SharePoint and email."
  tags:
    - compliance
    - audit
    - servicenow
    - snowflake
    - sharepoint
capability:
  exposes:
    - type: mcp
      namespace: audit-prep
      port: 8080
      tools:
        - name: prepare-audit
          description: "Gather compliance evidence, generate a summary, upload to SharePoint, and distribute. Use at quarter end for audit preparation."
          inputParameters:
            - name: quarter
              in: body
              type: string
              description: "Quarter identifier (e.g. Q1-2026)."
          steps:
            - name: get-controls
              type: call
              call: "servicenow.list-controls"
              with:
                state: "active"
                quarter: "{{quarter}}"
            - name: generate-summary
              type: call
              call: "snowflake.run-query"
              with:
                query: "SELECT control_id, status, evidence_count FROM COMPLIANCE_DB.PUBLIC.AUDIT_EVIDENCE WHERE quarter='{{quarter}}'"
            - name: upload-report
              type: call
              call: "sharepoint.upload-file"
              with:
                drive_id: "$secrets.compliance_drive_id"
                name: "Q{{quarter}}_audit_report.pdf"
                content: "{{generate-summary.results}}"
            - name: distribute
              type: call
              call: "email.send-email"
              with:
                to: "compliance-team@americanexpress.com"
                subject: "Q{{quarter}} Compliance Audit Materials Ready"
                body: "Audit materials uploaded to SharePoint. Controls reviewed: {{get-controls.count}}. Evidence items: {{generate-summary.row_count}}."
  consumes:
    - namespace: servicenow
      type: http
      baseUri: "https://americanexpress.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: controls
          path: "/table/sn_compliance_control"
          operations:
            - name: list-controls
              method: GET
    - namespace: snowflake
      type: http
      baseUri: "https://americanexpress.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - namespace: sharepoint
      type: http
      baseUri: "https://americanexpress.sharepoint.com/_api/v2.0"
      authentication:
        type: bearer
        token: "$secrets.sharepoint_token"
      resources:
        - name: files
          path: "/drives/{drive_id}/items"
          inputParameters:
            - name: drive_id
              in: path
          operations:
            - name: upload-file
              method: POST
    - namespace: email
      type: http
      baseUri: "https://api.americanexpress.com/v1/notifications"
      authentication:
        type: bearer
        token: "$secrets.amex_notifications_token"
      resources:
        - name: messages
          path: "/email/send"
          operations:
            - name: send-email
              method: POST

Generates a quarterly revenue report for a merchant by querying Snowflake analytics, creating a Tableau extract refresh, and distributing the report via email.

naftiko: "0.5"
info:
  label: "Quarterly Merchant Revenue Report"
  description: "Generates a quarterly revenue report for a merchant by querying Snowflake analytics, creating a Tableau extract refresh, and distributing the report via email."
  tags:
    - merchants
    - analytics
    - snowflake
    - tableau
capability:
  exposes:
    - type: mcp
      namespace: merchant-reports
      port: 8080
      tools:
        - name: generate-revenue-report
          description: "Generate a quarterly revenue report for a merchant using Snowflake data and Tableau visualization. Use at quarter end for merchant reporting."
          inputParameters:
            - name: merchant_id
              in: body
              type: string
              description: "Merchant ID for the report."
            - name: quarter
              in: body
              type: string
              description: "Quarter identifier (e.g. Q1-2026)."
            - name: merchant_email
              in: body
              type: string
              description: "Merchant contact email."
            - name: datasource_id
              in: body
              type: string
              description: "Tableau datasource ID."
          steps:
            - name: run-revenue-query
              type: call
              call: "snowflake.run-query"
              with:
                query: "SELECT SUM(amount) as total_revenue, COUNT(*) as txn_count FROM MERCHANT_DB.PUBLIC.TRANSACTIONS WHERE merchant_id='{{merchant_id}}' AND quarter='{{quarter}}'"
            - name: refresh-tableau
              type: call
              call: "tableau.refresh-extract"
              with:
                site_id: "$secrets.tableau_site_id"
                datasource_id: "{{datasource_id}}"
            - name: send-report
              type: call
              call: "email.send-email"
              with:
                to: "{{merchant_email}}"
                subject: "Q{{quarter}} Revenue Report"
                body: "Total revenue: ${{run-revenue-query.total_revenue}}. Transaction count: {{run-revenue-query.txn_count}}. Your Tableau dashboard has been refreshed."
  consumes:
    - namespace: snowflake
      type: http
      baseUri: "https://americanexpress.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - namespace: tableau
      type: http
      baseUri: "https://americanexpress.online.tableau.com/api/3.19"
      authentication:
        type: bearer
        token: "$secrets.tableau_token"
      resources:
        - name: extracts
          path: "/sites/{site_id}/datasources/{datasource_id}/refresh"
          inputParameters:
            - name: site_id
              in: path
            - name: datasource_id
              in: path
          operations:
            - name: refresh-extract
              method: POST
    - namespace: email
      type: http
      baseUri: "https://api.americanexpress.com/v1/notifications"
      authentication:
        type: bearer
        token: "$secrets.amex_notifications_token"
      resources:
        - name: messages
          path: "/email/send"
          operations:
            - name: send-email
              method: POST

Retrieves a compliance document from SharePoint, submits it to Anthropic Claude for key obligation extraction, and posts the summary to the Legal & Compliance Teams channel.

naftiko: "0.5"
info:
  label: "Regulatory Compliance Document Summarization"
  description: "Retrieves a compliance document from SharePoint, submits it to Anthropic Claude for key obligation extraction, and posts the summary to the Legal & Compliance Teams channel."
  tags:
    - compliance
    - legal
    - sharepoint
    - anthropic
    - ai
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: compliance-ai
      port: 8080
      tools:
        - name: summarize-compliance-doc
          description: "Given a SharePoint document site ID and file path, retrieve the document, send it to Anthropic Claude to extract key regulatory obligations and risk items, and post the summary to a Teams channel. Use when legal or compliance teams need rapid document triage."
          inputParameters:
            - name: site_id
              in: body
              type: string
              description: "The SharePoint site ID where the compliance document is stored."
            - name: file_path
              in: body
              type: string
              description: "The relative file path of the document within the SharePoint site."
            - name: teams_channel_id
              in: body
              type: string
              description: "The Microsoft Teams channel ID to post the summary to."
          steps:
            - name: get-document
              type: call
              call: "sharepoint.get-file-content"
              with:
                site_id: "{{site_id}}"
                file_path: "{{file_path}}"
            - name: extract-obligations
              type: call
              call: "anthropic.create-message"
              with:
                model: "claude-opus-4-5"
                prompt: "You are a regulatory compliance analyst. Extract and list: (1) key obligations, (2) compliance deadlines, (3) risk areas from this document. Be concise. Document: {{get-document.content}}"
            - name: post-to-teams
              type: call
              call: "msteams-compliance.post-channel-message"
              with:
                channel_id: "{{teams_channel_id}}"
                content: "Compliance Summary for {{file_path}}:\n\n{{extract-obligations.content}}"
  consumes:
    - namespace: sharepoint
      type: http
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: file-content
          path: "/sites/{site_id}/drive/root:/{file_path}:/content"
          inputParameters:
            - name: site_id
              in: path
            - name: file_path
              in: path
          operations:
            - name: get-file-content
              method: GET
    - namespace: anthropic
      type: http
      baseUri: "https://api.anthropic.com/v1"
      authentication:
        type: apikey
        key: "x-api-key"
        value: "$secrets.anthropic_api_key"
        placement: header
      resources:
        - name: message
          path: "/messages"
          operations:
            - name: create-message
              method: POST
    - namespace: msteams-compliance
      type: http
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-message
          path: "/teams/{team_id}/channels/{channel_id}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Enriches Salesforce leads with ZoomInfo company data, calculates a lead score, updates the lead record, and notifies the assigned sales rep via Slack.

naftiko: "0.5"
info:
  label: "Salesforce Lead Scoring Enrichment"
  description: "Enriches Salesforce leads with ZoomInfo company data, calculates a lead score, updates the lead record, and notifies the assigned sales rep via Slack."
  tags:
    - salesforce
    - zoominfo
    - sales
    - slack
capability:
  exposes:
    - type: mcp
      namespace: lead-enrichment
      port: 8080
      tools:
        - name: enrich-lead
          description: "Enrich a Salesforce lead with ZoomInfo data and notify the sales rep. Use when a new high-potential lead enters the pipeline."
          inputParameters:
            - name: lead_id
              in: body
              type: string
              description: "Salesforce lead ID."
            - name: company_name
              in: body
              type: string
              description: "Company name to enrich."
            - name: sales_rep_channel
              in: body
              type: string
              description: "Sales rep Slack channel."
          steps:
            - name: enrich
              type: call
              call: "zoominfo.search-company"
              with:
                company_name: "{{company_name}}"
            - name: update-lead
              type: call
              call: "salesforce.update-lead"
              with:
                lead_id: "{{lead_id}}"
                Company_Size__c: "{{enrich.employee_count}}"
                Revenue__c: "{{enrich.revenue}}"
                Lead_Score__c: "{{enrich.score}}"
            - name: notify-rep
              type: call
              call: "slack.post-message"
              with:
                channel: "{{sales_rep_channel}}"
                text: "Lead enriched: {{company_name}} | Revenue: ${{enrich.revenue}} | Score: {{enrich.score}} | Employees: {{enrich.employee_count}}"
  consumes:
    - namespace: zoominfo
      type: http
      baseUri: "https://api.zoominfo.com"
      authentication:
        type: bearer
        token: "$secrets.zoominfo_token"
      resources:
        - name: companies
          path: "/search/company"
          operations:
            - name: search-company
              method: POST
    - namespace: salesforce
      type: http
      baseUri: "https://americanexpress.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: update-lead
              method: PATCH
    - namespace: slack
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a new lead is created in Salesforce for a card product, enriches the lead with firmographic data from ZoomInfo and updates the Salesforce record with company and contact details.

naftiko: "0.5"
info:
  label: "Salesforce Lead to Card Applicant Enrichment"
  description: "When a new lead is created in Salesforce for a card product, enriches the lead with firmographic data from ZoomInfo and updates the Salesforce record with company and contact details."
  tags:
    - sales
    - crm
    - salesforce
    - zoominfo
    - lead-enrichment
capability:
  exposes:
    - type: mcp
      namespace: lead-enrichment
      port: 8080
      tools:
        - name: enrich-card-lead
          description: "Given a Salesforce lead ID, retrieve lead details, search ZoomInfo for matching company and contact data, and update the Salesforce lead record with enriched firmographic information. Use when new B2B card product leads are created."
          inputParameters:
            - name: lead_id
              in: body
              type: string
              description: "The Salesforce lead ID to enrich."
          steps:
            - name: get-lead
              type: call
              call: "salesforce-leads.get-lead"
              with:
                lead_id: "{{lead_id}}"
            - name: search-zoominfo
              type: call
              call: "zoominfo.search-contact"
              with:
                first_name: "{{get-lead.first_name}}"
                last_name: "{{get-lead.last_name}}"
                company_name: "{{get-lead.company}}"
            - name: update-lead
              type: call
              call: "salesforce-leads-update.update-lead"
              with:
                lead_id: "{{lead_id}}"
                company_revenue: "{{search-zoominfo.company_revenue}}"
                employee_count: "{{search-zoominfo.employee_count}}"
                industry: "{{search-zoominfo.industry}}"
                linkedin_url: "{{search-zoominfo.linkedin_url}}"
  consumes:
    - namespace: salesforce-leads
      type: http
      baseUri: "https://americanexpress.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_access_token"
      resources:
        - name: lead
          path: "/sobjects/Lead/{lead_id}"
          inputParameters:
            - name: lead_id
              in: path
          operations:
            - name: get-lead
              method: GET
    - namespace: zoominfo
      type: http
      baseUri: "https://api.zoominfo.com/search"
      authentication:
        type: bearer
        token: "$secrets.zoominfo_token"
      resources:
        - name: contact
          path: "/contact"
          operations:
            - name: search-contact
              method: POST
    - namespace: salesforce-leads-update
      type: http
      baseUri: "https://americanexpress.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_access_token"
      resources:
        - name: lead
          path: "/sobjects/Lead/{lead_id}"
          inputParameters:
            - name: lead_id
              in: path
          operations:
            - name: update-lead
              method: PATCH

When a Salesforce opportunity for a new corporate card program is marked Closed-Won, creates the program account in the corporate card platform and sends confirmation to the sales rep via email.

naftiko: "0.5"
info:
  label: "Salesforce Opportunity to Card Program Sync"
  description: "When a Salesforce opportunity for a new corporate card program is marked Closed-Won, creates the program account in the corporate card platform and sends confirmation to the sales rep via email."
  tags:
    - sales
    - crm
    - salesforce
    - payments
    - corporate-cards
capability:
  exposes:
    - type: mcp
      namespace: sales-card-sync
      port: 8080
      tools:
        - name: activate-card-program
          description: "Given a Salesforce opportunity ID for a closed-won corporate card program deal, retrieve opportunity details, create the card program account, and notify the responsible sales representative. Use when a B2B card program deal is won and needs activation."
          inputParameters:
            - name: opportunity_id
              in: body
              type: string
              description: "The Salesforce opportunity ID for the closed-won card program."
          steps:
            - name: get-opportunity
              type: call
              call: "salesforce-crm.get-opportunity"
              with:
                opportunity_id: "{{opportunity_id}}"
            - name: create-program
              type: call
              call: "amex-programs.create-program"
              with:
                company_name: "{{get-opportunity.account_name}}"
                credit_limit: "{{get-opportunity.amount}}"
                billing_contact_email: "{{get-opportunity.billing_email}}"
                program_type: "corporate_card"
            - name: notify-rep
              type: call
              call: "salesforce-email.send-email"
              with:
                to: "{{get-opportunity.owner_email}}"
                subject: "Card program activated for {{get-opportunity.account_name}}"
                body: "The corporate card program for {{get-opportunity.account_name}} has been activated. Program ID: {{create-program.program_id}}."
  consumes:
    - namespace: salesforce-crm
      type: http
      baseUri: "https://americanexpress.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_access_token"
      resources:
        - name: opportunity
          path: "/sobjects/Opportunity/{opportunity_id}"
          inputParameters:
            - name: opportunity_id
              in: path
          operations:
            - name: get-opportunity
              method: GET
    - namespace: amex-programs
      type: http
      baseUri: "https://api.americanexpress.com/v1/corporate"
      authentication:
        type: bearer
        token: "$secrets.amex_corp_token"
      resources:
        - name: program
          path: "/programs"
          operations:
            - name: create-program
              method: POST
    - namespace: salesforce-email
      type: http
      baseUri: "https://americanexpress.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_access_token"
      resources:
        - name: email
          path: "/actions/standard/emailSimple"
          operations:
            - name: send-email
              method: POST

Generates a merchant renewal pipeline digest by querying Salesforce opportunities, summarizing in Snowflake, and distributing via Slack.

naftiko: "0.5"
info:
  label: "Salesforce Renewal Pipeline Digest"
  description: "Generates a merchant renewal pipeline digest by querying Salesforce opportunities, summarizing in Snowflake, and distributing via Slack."
  tags:
    - salesforce
    - renewals
    - snowflake
    - slack
capability:
  exposes:
    - type: mcp
      namespace: renewal-digest
      port: 8080
      tools:
        - name: generate-renewal-digest
          description: "Summarize the renewal pipeline and share with the team. Use for weekly pipeline reviews."
          inputParameters: []
          steps:
            - name: get-renewals
              type: call
              call: "salesforce.run-soql"
              with:
                q: "SELECT Name, Amount, CloseDate FROM Opportunity WHERE StageName='Renewal' AND CloseDate=THIS_QUARTER"
            - name: summarize
              type: call
              call: "snowflake.run-query"
              with:
                query: "SELECT COUNT(*) as total, SUM(amount) as pipeline_value FROM SALES_DB.PUBLIC.RENEWAL_PIPELINE WHERE quarter=CURRENT_QUARTER()"
            - name: post-digest
              type: call
              call: "slack.post-message"
              with:
                channel: "merchant-renewals"
                text: "Renewal pipeline: {{summarize.total}} renewals | ${{summarize.pipeline_value}} | Details in Salesforce"
  consumes:
    - namespace: salesforce
      type: http
      baseUri: "https://americanexpress.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: query
          path: "/query"
          operations:
            - name: run-soql
              method: GET
    - namespace: snowflake
      type: http
      baseUri: "https://americanexpress.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - namespace: slack
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a ServiceNow change request reaches the Approval state, retrieves the change details and notifies all relevant stakeholders via Microsoft Teams.

naftiko: "0.5"
info:
  label: "ServiceNow Change Management Notification"
  description: "When a ServiceNow change request reaches the Approval state, retrieves the change details and notifies all relevant stakeholders via Microsoft Teams."
  tags:
    - itsm
    - servicenow
    - microsoft-teams
    - change-management
capability:
  exposes:
    - type: mcp
      namespace: change-management
      port: 8080
      tools:
        - name: notify-change-approvers
          description: "Given a ServiceNow change request number, retrieve change details and send a Teams notification to all listed approvers with context and an approval link. Use when change requests require stakeholder awareness and sign-off."
          inputParameters:
            - name: change_number
              in: body
              type: string
              description: "The ServiceNow change request number (e.g., CHG0012345)."
            - name: approver_upns
              in: body
              type: string
              description: "Comma-separated list of approver UPNs (email addresses) to notify."
          steps:
            - name: get-change
              type: call
              call: "servicenow-chg.get-change"
              with:
                number: "{{change_number}}"
            - name: notify-team
              type: call
              call: "msteams-change.post-channel-message"
              with:
                channel_id: "$secrets.teams_change_mgmt_channel_id"
                content: "Change Request Pending Approval\nCHG: {{change_number}}\nSummary: {{get-change.short_description}}\nScheduled: {{get-change.start_date}}\nRisk: {{get-change.risk}}\nApprovers: {{approver_upns}}"
  consumes:
    - namespace: servicenow-chg
      type: http
      baseUri: "https://americanexpress.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: change
          path: "/table/change_request"
          inputParameters:
            - name: number
              in: query
          operations:
            - name: get-change
              method: GET
    - namespace: msteams-change
      type: http
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-message
          path: "/teams/{team_id}/channels/{channel_id}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

Automatically remediates common ServiceNow incidents by identifying the issue type, executing a remediation runbook, updating the incident, and notifying the on-call engineer via PagerDuty.

naftiko: "0.5"
info:
  label: "ServiceNow Incident Auto-Remediation"
  description: "Automatically remediates common ServiceNow incidents by identifying the issue type, executing a remediation runbook, updating the incident, and notifying the on-call engineer via PagerDuty."
  tags:
    - servicenow
    - automation
    - pagerduty
    - incident-management
capability:
  exposes:
    - type: mcp
      namespace: auto-remediation
      port: 8080
      tools:
        - name: auto-remediate-incident
          description: "Auto-remediate a ServiceNow incident by executing a runbook and notifying on-call. Use when an incident matches an auto-remediation pattern."
          inputParameters:
            - name: incident_id
              in: body
              type: string
              description: "ServiceNow incident ID."
          steps:
            - name: get-incident
              type: call
              call: "servicenow.get-incident"
              with:
                incident_id: "{{incident_id}}"
            - name: run-remediation
              type: call
              call: "amex-runbooks.execute-runbook"
              with:
                runbook_id: "{{get-incident.category}}-auto-fix"
                incident_id: "{{incident_id}}"
                ci: "{{get-incident.cmdb_ci}}"
            - name: update-incident
              type: call
              call: "servicenow.update-incident"
              with:
                incident_id: "{{incident_id}}"
                state: "resolved"
                work_notes: "Auto-remediated via runbook. Result: {{run-remediation.status}}"
            - name: notify-oncall
              type: call
              call: "pagerduty.create-incident"
              with:
                title: "Auto-remediation completed: {{incident_id}}"
                body: "Incident {{incident_id}} was auto-remediated. Status: {{run-remediation.status}}"
  consumes:
    - namespace: servicenow
      type: http
      baseUri: "https://americanexpress.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident/{incident_id}"
          inputParameters:
            - name: incident_id
              in: path
          operations:
            - name: get-incident
              method: GET
            - name: update-incident
              method: PATCH
    - namespace: amex-runbooks
      type: http
      baseUri: "https://api.americanexpress.com/v1/automation"
      authentication:
        type: bearer
        token: "$secrets.amex_automation_token"
      resources:
        - name: runbooks
          path: "/runbooks/{runbook_id}/execute"
          inputParameters:
            - name: runbook_id
              in: path
          operations:
            - name: execute-runbook
              method: POST
    - namespace: pagerduty
      type: http
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: bearer
        token: "$secrets.pagerduty_token"
      resources:
        - name: incidents
          path: "/incidents"
          operations:
            - name: create-incident
              method: POST

Recovers from a Snowflake data pipeline failure by checking pipeline status, retrying the failed task, creating a ServiceNow incident, and notifying the data engineering team via Slack.

naftiko: "0.5"
info:
  label: "Snowflake Data Pipeline Failure Recovery"
  description: "Recovers from a Snowflake data pipeline failure by checking pipeline status, retrying the failed task, creating a ServiceNow incident, and notifying the data engineering team via Slack."
  tags:
    - snowflake
    - data-engineering
    - servicenow
    - slack
capability:
  exposes:
    - type: mcp
      namespace: pipeline-recovery
      port: 8080
      tools:
        - name: recover-pipeline
          description: "Check a failed Snowflake pipeline, retry execution, create an incident, and notify the team. Use when a data pipeline task fails."
          inputParameters:
            - name: task_name
              in: body
              type: string
              description: "Snowflake task name."
          steps:
            - name: check-status
              type: call
              call: "snowflake.run-query"
              with:
                query: "SELECT * FROM TABLE(INFORMATION_SCHEMA.TASK_HISTORY()) WHERE NAME='{{task_name}}' AND STATE='FAILED' ORDER BY SCHEDULED_TIME DESC LIMIT 1"
            - name: retry-task
              type: call
              call: "snowflake.run-query"
              with:
                query: "EXECUTE TASK {{task_name}}"
            - name: create-incident
              type: call
              call: "servicenow.create-incident"
              with:
                short_description: "Snowflake pipeline failure: {{task_name}}"
                category: "data-engineering"
                priority: "2"
                description: "Task {{task_name}} failed. Error: {{check-status.error_message}}. Retry initiated."
            - name: notify-team
              type: call
              call: "slack.post-message"
              with:
                channel: "data-engineering"
                text: "Pipeline failure: {{task_name}}. Error: {{check-status.error_message}}. Retry initiated. SNOW: {{create-incident.number}}"
  consumes:
    - namespace: snowflake
      type: http
      baseUri: "https://americanexpress.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: run-query
              method: POST
    - namespace: servicenow
      type: http
      baseUri: "https://americanexpress.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
    - namespace: slack
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a Snowflake data quality check fails for a critical financial dataset, logs the failure details and creates a Jira data engineering issue for remediation.

naftiko: "0.5"
info:
  label: "Snowflake Data Quality Monitoring Alert"
  description: "When a Snowflake data quality check fails for a critical financial dataset, logs the failure details and creates a Jira data engineering issue for remediation."
  tags:
    - data
    - analytics
    - snowflake
    - jira
    - data-quality
    - monitoring
capability:
  exposes:
    - type: mcp
      namespace: data-quality
      port: 8080
      tools:
        - name: handle-data-quality-failure
          description: "Given a Snowflake table name, failed check name, and failure details, create a Jira issue for the data engineering team and post a Slack notification to the data ops channel. Use when automated data quality checks fail on financial or compliance datasets."
          inputParameters:
            - name: table_name
              in: body
              type: string
              description: "The fully-qualified Snowflake table name (database.schema.table) where the quality check failed."
            - name: check_name
              in: body
              type: string
              description: "The name of the data quality check that failed (e.g., null_count_check, row_count_threshold)."
            - name: failure_details
              in: body
              type: string
              description: "A description of why the check failed and what values were observed."
          steps:
            - name: create-dq-issue
              type: call
              call: "jira-data.create-issue"
              with:
                project_key: "DATA"
                issuetype: "Bug"
                summary: "Data quality failure: {{check_name}} on {{table_name}}"
                description: "Table: {{table_name}}\nCheck: {{check_name}}\nDetails: {{failure_details}}"
                priority: "High"
            - name: post-data-alert
              type: call
              call: "slack-data.post-message"
              with:
                channel: "data-ops"
                text: "Data Quality Failure | Table: {{table_name}} | Check: {{check_name}} | Jira: {{create-dq-issue.key}}"
  consumes:
    - namespace: jira-data
      type: http
      baseUri: "https://americanexpress.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issue
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - namespace: slack-data
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves the list of supplementary cards associated with a primary cardholder account.

naftiko: "0.5"
info:
  label: "Supplementary Card List Lookup"
  description: "Retrieves the list of supplementary cards associated with a primary cardholder account."
  tags:
    - cardholder
    - accounts
    - cards
capability:
  exposes:
    - type: mcp
      namespace: amex-accounts
      port: 8080
      tools:
        - name: get-supplementary-cards
          description: "Given a primary cardholder account ID, return all supplementary cards with their status and holder names. Use when managing additional cards on an account."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The primary cardholder account ID."
          call: "amex-accounts.get-supplementary-cards"
          with:
            account_id: "{{account_id}}"
          outputParameters:
            - name: cards
              type: array
              mapping: "$.cards"
            - name: total_count
              type: number
              mapping: "$.total_count"
  consumes:
    - namespace: amex-accounts
      type: http
      baseUri: "https://api.americanexpress.com/v1/accounts"
      authentication:
        type: bearer
        token: "$secrets.amex_accounts_token"
      resources:
        - name: supplementary-cards
          path: "/accounts/{account_id}/supplementary-cards"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: get-supplementary-cards
              method: GET

When CrowdStrike detects a suspicious login event for a privileged account, suspends the Okta user session, opens a ServiceNow security incident, and alerts the SOC Slack channel.

naftiko: "0.5"
info:
  label: "Suspicious Login Threat Response"
  description: "When CrowdStrike detects a suspicious login event for a privileged account, suspends the Okta user session, opens a ServiceNow security incident, and alerts the SOC Slack channel."
  tags:
    - security
    - crowdstrike
    - okta
    - servicenow
    - slack
    - identity
    - threat-response
capability:
  exposes:
    - type: mcp
      namespace: soc-response
      port: 8080
      tools:
        - name: respond-to-suspicious-login
          description: "Given a CrowdStrike detection ID and the affected user's email, retrieve detection details, suspend the user's Okta sessions, open a ServiceNow security incident, and alert the SOC Slack channel. Use for privileged account compromise response."
          inputParameters:
            - name: detection_id
              in: body
              type: string
              description: "The CrowdStrike Falcon detection ID for the suspicious login event."
            - name: user_email
              in: body
              type: string
              description: "The email address of the account flagged in the detection."
          steps:
            - name: get-detection
              type: call
              call: "crowdstrike.get-detection"
              with:
                detection_id: "{{detection_id}}"
            - name: get-okta-user
              type: call
              call: "okta-soc.get-user-by-login"
              with:
                login: "{{user_email}}"
            - name: clear-sessions
              type: call
              call: "okta-sessions.clear-user-sessions"
              with:
                user_id: "{{get-okta-user.id}}"
            - name: create-sec-incident
              type: call
              call: "servicenow-soc.create-incident"
              with:
                category: "security"
                subcategory: "suspicious_login"
                short_description: "Suspicious login detected for {{user_email}}"
                description: "CrowdStrike Detection: {{detection_id}}\nUser: {{user_email}}\nOkta sessions cleared: true\nDetection details: {{get-detection.description}}"
                urgency: "1"
                impact: "2"
            - name: alert-soc
              type: call
              call: "slack-soc.post-message"
              with:
                channel: "soc-alerts"
                text: "Suspicious Login Response | User: {{user_email}} | Detection: {{detection_id}} | Okta sessions cleared | SNOW: {{create-sec-incident.number}}"
  consumes:
    - namespace: crowdstrike
      type: http
      baseUri: "https://api.crowdstrike.com"
      authentication:
        type: bearer
        token: "$secrets.crowdstrike_access_token"
      resources:
        - name: detection
          path: "/detects/entities/detect/v2"
          operations:
            - name: get-detection
              method: GET
    - namespace: okta-soc
      type: http
      baseUri: "https://americanexpress.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_api_token"
        placement: header
      resources:
        - name: user
          path: "/users/{login}"
          inputParameters:
            - name: login
              in: path
          operations:
            - name: get-user-by-login
              method: GET
    - namespace: okta-sessions
      type: http
      baseUri: "https://americanexpress.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_api_token"
        placement: header
      resources:
        - name: user-sessions
          path: "/users/{user_id}/sessions"
          inputParameters:
            - name: user_id
              in: path
          operations:
            - name: clear-user-sessions
              method: DELETE
    - namespace: servicenow-soc
      type: http
      baseUri: "https://americanexpress.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incident
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - namespace: slack-soc
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Provisions Tableau dashboard access for a user by verifying their role in Okta, adding them to the Tableau site, and confirming via email.

naftiko: "0.5"
info:
  label: "Tableau Dashboard Access Provisioning"
  description: "Provisions Tableau dashboard access for a user by verifying their role in Okta, adding them to the Tableau site, and confirming via email."
  tags:
    - tableau
    - okta
    - access-management
    - email
capability:
  exposes:
    - type: mcp
      namespace: tableau-access
      port: 8080
      tools:
        - name: provision-tableau-access
          description: "Verify a user's role and provision Tableau access. Use when a user requests dashboard access."
          inputParameters:
            - name: user_id
              in: body
              type: string
              description: "Okta user ID."
            - name: tableau_role
              in: body
              type: string
              description: "Tableau site role (Viewer, Explorer, Creator)."
          steps:
            - name: verify-role
              type: call
              call: "okta.get-user"
              with:
                user_id: "{{user_id}}"
            - name: add-to-tableau
              type: call
              call: "tableau.add-user"
              with:
                site_id: "$secrets.tableau_site_id"
                email: "{{verify-role.profile.email}}"
                role: "{{tableau_role}}"
            - name: confirm
              type: call
              call: "email.send-email"
              with:
                to: "{{verify-role.profile.email}}"
                subject: "Tableau access granted"
                body: "You now have {{tableau_role}} access to the Tableau site. Login at https://americanexpress.online.tableau.com"
  consumes:
    - namespace: okta
      type: http
      baseUri: "https://americanexpress.okta.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.okta_token"
      resources:
        - name: users
          path: "/users/{user_id}"
          inputParameters:
            - name: user_id
              in: path
          operations:
            - name: get-user
              method: GET
    - namespace: tableau
      type: http
      baseUri: "https://americanexpress.online.tableau.com/api/3.19"
      authentication:
        type: bearer
        token: "$secrets.tableau_token"
      resources:
        - name: users
          path: "/sites/{site_id}/users"
          inputParameters:
            - name: site_id
              in: path
          operations:
            - name: add-user
              method: POST
    - namespace: email
      type: http
      baseUri: "https://api.americanexpress.com/v1/notifications"
      authentication:
        type: bearer
        token: "$secrets.amex_notifications_token"
      resources:
        - name: messages
          path: "/email/send"
          operations:
            - name: send-email
              method: POST

Triggers a Tableau workbook refresh for monthly financial reporting dashboards and posts the refresh status to the Finance Slack channel.

naftiko: "0.5"
info:
  label: "Tableau Financial Dashboard Refresh"
  description: "Triggers a Tableau workbook refresh for monthly financial reporting dashboards and posts the refresh status to the Finance Slack channel."
  tags:
    - data
    - analytics
    - tableau
    - slack
    - finance
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: finance-reporting
      port: 8080
      tools:
        - name: refresh-financial-dashboard
          description: "Given a Tableau workbook ID, trigger a datasource refresh and post the job status to the finance Slack channel once complete. Use at month-end or quarter-end to refresh executive financial dashboards."
          inputParameters:
            - name: workbook_id
              in: body
              type: string
              description: "The Tableau workbook ID to refresh."
            - name: site_id
              in: body
              type: string
              description: "The Tableau site ID where the workbook is hosted."
          steps:
            - name: trigger-refresh
              type: call
              call: "tableau.refresh-workbook"
              with:
                site_id: "{{site_id}}"
                workbook_id: "{{workbook_id}}"
            - name: post-status
              type: call
              call: "slack-finance.post-message"
              with:
                channel: "finance-reporting"
                text: "Tableau dashboard refresh triggered | Workbook: {{workbook_id}} | Job ID: {{trigger-refresh.job_id}} | Status: {{trigger-refresh.status}}"
  consumes:
    - namespace: tableau
      type: http
      baseUri: "https://americanexpress.tableau.com/api/2.8"
      authentication:
        type: apikey
        key: "X-Tableau-Auth"
        value: "$secrets.tableau_auth_token"
        placement: header
      resources:
        - name: workbook-refresh
          path: "/sites/{site_id}/workbooks/{workbook_id}/refresh"
          inputParameters:
            - name: site_id
              in: path
            - name: workbook_id
              in: path
          operations:
            - name: refresh-workbook
              method: POST
    - namespace: slack-finance
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Detects Terraform infrastructure drift by triggering a plan, comparing state, creating a Jira remediation ticket, and alerting the platform team via Slack.

naftiko: "0.5"
info:
  label: "Terraform Infrastructure Drift Detection"
  description: "Detects Terraform infrastructure drift by triggering a plan, comparing state, creating a Jira remediation ticket, and alerting the platform team via Slack."
  tags:
    - terraform
    - infrastructure
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: drift-detection
      port: 8080
      tools:
        - name: detect-drift
          description: "Trigger a Terraform plan to detect drift and report findings. Use during scheduled drift detection runs."
          inputParameters:
            - name: workspace_id
              in: body
              type: string
              description: "Terraform Cloud workspace ID."
          steps:
            - name: trigger-plan
              type: call
              call: "terraform-cloud.create-run"
              with:
                workspace_id: "{{workspace_id}}"
                is_destroy: "false"
                message: "Drift detection run"
            - name: check-plan
              type: call
              call: "terraform-cloud.get-run"
              with:
                run_id: "{{trigger-plan.id}}"
            - name: create-ticket
              type: call
              call: "jira.create-issue"
              with:
                project_key: "PLAT"
                issuetype: "Task"
                summary: "Terraform drift detected: {{workspace_id}}"
                description: "Resources to add: {{check-plan.resource_additions}}. To change: {{check-plan.resource_changes}}. To destroy: {{check-plan.resource_destructions}}."
            - name: alert-team
              type: call
              call: "slack.post-message"
              with:
                channel: "platform-engineering"
                text: "Drift detected in {{workspace_id}} | +{{check-plan.resource_additions}} ~{{check-plan.resource_changes}} -{{check-plan.resource_destructions}} | Jira: {{create-ticket.key}}"
  consumes:
    - namespace: terraform-cloud
      type: http
      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
        - name: run-detail
          path: "/runs/{run_id}"
          inputParameters:
            - name: run_id
              in: path
          operations:
            - name: get-run
              method: GET
    - namespace: jira
      type: http
      baseUri: "https://americanexpress.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issue
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - namespace: slack
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a Terraform Cloud plan is created for a production workspace, retrieves plan details, posts a summary to the engineering Slack channel, and creates a ServiceNow change request for approval.

naftiko: "0.5"
info:
  label: "Terraform Infrastructure Provisioning Approval"
  description: "When a Terraform Cloud plan is created for a production workspace, retrieves plan details, posts a summary to the engineering Slack channel, and creates a ServiceNow change request for approval."
  tags:
    - cloud
    - infrastructure
    - terraform
    - servicenow
    - slack
    - devops
capability:
  exposes:
    - type: mcp
      namespace: infra-provisioning
      port: 8080
      tools:
        - name: request-infra-change-approval
          description: "Given a Terraform Cloud workspace ID and run ID, fetch the plan summary, open a ServiceNow change request for the infrastructure change, and post a Slack notification to the engineering channel with plan details. Use when production Terraform plans need change management approval."
          inputParameters:
            - name: workspace_id
              in: body
              type: string
              description: "The Terraform Cloud workspace ID where the plan was created."
            - name: run_id
              in: body
              type: string
              description: "The Terraform Cloud run ID for the plan."
          steps:
            - name: get-plan
              type: call
              call: "terraform.get-run"
              with:
                run_id: "{{run_id}}"
            - name: create-change
              type: call
              call: "servicenow-infra.create-change"
              with:
                category: "infrastructure"
                short_description: "Terraform plan requires approval: workspace {{workspace_id}}"
                description: "Run ID: {{run_id}}\nWorkspace: {{workspace_id}}\nAdd: {{get-plan.resource_additions}}\nChange: {{get-plan.resource_changes}}\nDestroy: {{get-plan.resource_destructions}}"
                risk: "moderate"
            - name: post-notification
              type: call
              call: "slack-infra.post-message"
              with:
                channel: "infra-changes"
                text: "Terraform Plan Pending Approval | Workspace: {{workspace_id}} | Run: {{run_id}} | +{{get-plan.resource_additions}} ~{{get-plan.resource_changes}} -{{get-plan.resource_destructions}} | SNOW: {{create-change.number}}"
  consumes:
    - namespace: terraform
      type: http
      baseUri: "https://app.terraform.io/api/v2"
      authentication:
        type: bearer
        token: "$secrets.terraform_token"
      resources:
        - name: run
          path: "/runs/{run_id}"
          inputParameters:
            - name: run_id
              in: path
          operations:
            - name: get-run
              method: GET
    - namespace: servicenow-infra
      type: http
      baseUri: "https://americanexpress.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: change
          path: "/table/change_request"
          operations:
            - name: create-change
              method: POST
    - namespace: slack-infra
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Monitors Datadog for transaction volume anomaly alerts and, when triggered, creates a PagerDuty incident and posts to the payments operations Slack channel.

naftiko: "0.5"
info:
  label: "Transaction Anomaly Monitoring Alert"
  description: "Monitors Datadog for transaction volume anomaly alerts and, when triggered, creates a PagerDuty incident and posts to the payments operations Slack channel."
  tags:
    - observability
    - datadog
    - pagerduty
    - slack
    - payments
    - monitoring
capability:
  exposes:
    - type: mcp
      namespace: payments-observability
      port: 8080
      tools:
        - name: handle-transaction-anomaly
          description: "Given a Datadog anomaly alert ID and severity, retrieve alert details, create a PagerDuty incident for the on-call payments team, and post a Slack notification. Use when transaction processing anomalies are detected."
          inputParameters:
            - name: alert_id
              in: body
              type: string
              description: "The Datadog monitor alert ID for the transaction anomaly."
            - name: severity
              in: body
              type: string
              description: "Alert severity level: critical, high, medium, or low."
            - name: affected_service
              in: body
              type: string
              description: "The name of the affected payments service or pipeline."
          steps:
            - name: get-alert
              type: call
              call: "datadog-monitor.get-monitor"
              with:
                monitor_id: "{{alert_id}}"
            - name: create-pd-incident
              type: call
              call: "pagerduty.create-incident"
              with:
                title: "Transaction anomaly on {{affected_service}} — severity {{severity}}"
                service_id: "$secrets.pagerduty_payments_service_id"
                urgency: "{{severity}}"
                body: "Datadog alert {{alert_id}}: {{get-alert.message}}"
            - name: post-slack
              type: call
              call: "slack-payments.post-message"
              with:
                channel: "payments-ops"
                text: "Transaction Anomaly Detected | Service: {{affected_service}} | Severity: {{severity}} | PagerDuty: {{create-pd-incident.incident_number}} | Alert: {{alert_id}}"
  consumes:
    - namespace: datadog-monitor
      type: http
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: monitor
          path: "/monitor/{monitor_id}"
          inputParameters:
            - name: monitor_id
              in: path
          operations:
            - name: get-monitor
              method: GET
    - namespace: pagerduty
      type: http
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.pagerduty_api_key"
        placement: header
      resources:
        - name: incident
          path: "/incidents"
          operations:
            - name: create-incident
              method: POST
    - namespace: slack-payments
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Manages vendor contract renewals by fetching contract details from DocuSign, creating a review task in Jira, and notifying procurement via Slack and email.

naftiko: "0.5"
info:
  label: "Vendor Contract Renewal Workflow"
  description: "Manages vendor contract renewals by fetching contract details from DocuSign, creating a review task in Jira, and notifying procurement via Slack and email."
  tags:
    - procurement
    - docusign
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: contract-renewal
      port: 8080
      tools:
        - name: process-renewal
          description: "Fetch contract details, create a review task, and notify stakeholders. Use when a vendor contract approaches its renewal date."
          inputParameters:
            - name: envelope_id
              in: body
              type: string
              description: "DocuSign envelope ID."
            - name: vendor_name
              in: body
              type: string
              description: "Vendor name."
            - name: contract_value
              in: body
              type: string
              description: "Contract value."
            - name: vendor_email
              in: body
              type: string
              description: "Vendor contact email."
          steps:
            - name: get-contract
              type: call
              call: "docusign.get-envelope"
              with:
                ds_account_id: "$secrets.docusign_account_id"
                envelope_id: "{{envelope_id}}"
            - name: create-review
              type: call
              call: "jira.create-issue"
              with:
                project_key: "PROC"
                issuetype: "Task"
                summary: "Contract renewal: {{get-contract.emailSubject}}"
                description: "Vendor: {{vendor_name}}. Expiry: {{get-contract.expireAfter}}. Value: ${{contract_value}}."
            - name: notify-procurement
              type: call
              call: "slack.post-message"
              with:
                channel: "procurement"
                text: "Contract renewal due: {{vendor_name}} | Expiry: {{get-contract.expireAfter}} | Value: ${{contract_value}} | Jira: {{create-review.key}}"
            - name: notify-vendor
              type: call
              call: "email.send-email"
              with:
                to: "{{vendor_email}}"
                subject: "Contract renewal notice"
                body: "Your contract with American Express is approaching renewal. Our procurement team will be in touch."
  consumes:
    - namespace: docusign
      type: http
      baseUri: "https://na4.docusign.net/restapi/v2.1"
      authentication:
        type: bearer
        token: "$secrets.docusign_token"
      resources:
        - name: envelopes
          path: "/accounts/{ds_account_id}/envelopes/{envelope_id}"
          inputParameters:
            - name: ds_account_id
              in: path
            - name: envelope_id
              in: path
          operations:
            - name: get-envelope
              method: GET
    - namespace: jira
      type: http
      baseUri: "https://americanexpress.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issue
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - namespace: slack
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST
    - namespace: email
      type: http
      baseUri: "https://api.americanexpress.com/v1/notifications"
      authentication:
        type: bearer
        token: "$secrets.amex_notifications_token"
      resources:
        - name: messages
          path: "/email/send"
          operations:
            - name: send-email
              method: POST

Routes a vendor invoice through approval by validating the PO in SAP, creating an approval task in ServiceNow, and notifying the approver via Slack.

naftiko: "0.5"
info:
  label: "Vendor Invoice Approval Workflow"
  description: "Routes a vendor invoice through approval by validating the PO in SAP, creating an approval task in ServiceNow, and notifying the approver via Slack."
  tags:
    - finance
    - procurement
    - servicenow
    - slack
capability:
  exposes:
    - type: mcp
      namespace: invoice-approval
      port: 8080
      tools:
        - name: route-invoice-approval
          description: "Validate a purchase order, create an approval task, and notify the approver. Use when a vendor invoice requires approval routing."
          inputParameters:
            - name: po_number
              in: body
              type: string
              description: "Purchase order number."
            - name: vendor_name
              in: body
              type: string
              description: "Vendor name."
            - name: invoice_amount
              in: body
              type: string
              description: "Invoice amount."
          steps:
            - name: validate-po
              type: call
              call: "sap.get-po"
              with:
                po_number: "{{po_number}}"
            - name: create-approval
              type: call
              call: "servicenow.create-approval"
              with:
                source_table: "ap_invoice"
                approver: "{{validate-po.budget_owner}}"
                state: "requested"
            - name: notify-approver
              type: call
              call: "slack.post-message"
              with:
                channel: "{{validate-po.budget_owner_slack}}"
                text: "Invoice approval needed: PO {{po_number}} | Vendor: {{vendor_name}} | Amount: ${{invoice_amount}} | Approval: {{create-approval.sys_id}}"
  consumes:
    - namespace: sap
      type: http
      baseUri: "https://api.americanexpress.com/v1/sap"
      authentication:
        type: bearer
        token: "$secrets.sap_token"
      resources:
        - name: purchase-orders
          path: "/purchase-orders/{po_number}"
          inputParameters:
            - name: po_number
              in: path
          operations:
            - name: get-po
              method: GET
    - namespace: servicenow
      type: http
      baseUri: "https://americanexpress.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: approvals
          path: "/table/sysapproval_approver"
          operations:
            - name: create-approval
              method: POST
    - namespace: slack
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Routes compensation change requests through approval by fetching the proposal from Workday, creating a Jira approval task, and notifying HR leadership via Slack.

naftiko: "0.5"
info:
  label: "Workday Compensation Change Approval"
  description: "Routes compensation change requests through approval by fetching the proposal from Workday, creating a Jira approval task, and notifying HR leadership via Slack."
  tags:
    - hr
    - workday
    - jira
    - slack
    - compensation
capability:
  exposes:
    - type: mcp
      namespace: comp-approval
      port: 8080
      tools:
        - name: route-comp-approval
          description: "Route a compensation change through the approval workflow. Use when a manager submits a salary adjustment proposal."
          inputParameters:
            - name: proposal_id
              in: body
              type: string
              description: "Workday compensation proposal ID."
          steps:
            - name: get-proposal
              type: call
              call: "workday.get-proposal"
              with:
                proposal_id: "{{proposal_id}}"
            - name: create-approval
              type: call
              call: "jira.create-issue"
              with:
                project_key: "HRA"
                issuetype: "Task"
                summary: "Comp change approval — {{get-proposal.employee_name}}"
                description: "Current: ${{get-proposal.current_salary}}. Proposed: ${{get-proposal.proposed_salary}}. Reason: {{get-proposal.reason}}."
            - name: notify-hr
              type: call
              call: "slack.post-message"
              with:
                channel: "hr-leadership"
                text: "Comp change pending: {{get-proposal.employee_name}} | ${{get-proposal.current_salary}} → ${{get-proposal.proposed_salary}} | Jira: {{create-approval.key}}"
  consumes:
    - namespace: workday
      type: http
      baseUri: "https://wd3-impl-services1.workday.com/ccx/service/amex"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: compensation
          path: "/compensation/proposals/{proposal_id}"
          inputParameters:
            - name: proposal_id
              in: path
          operations:
            - name: get-proposal
              method: GET
    - namespace: jira
      type: http
      baseUri: "https://americanexpress.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issue
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - namespace: slack
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Orchestrates employee termination by updating Workday, deactivating Okta, revoking corporate card, and creating a ServiceNow offboarding ticket.

naftiko: "0.5"
info:
  label: "Workday Employee Termination Orchestration"
  description: "Orchestrates employee termination by updating Workday, deactivating Okta, revoking corporate card, and creating a ServiceNow offboarding ticket."
  tags:
    - hr
    - workday
    - okta
    - offboarding
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: termination-ops
      port: 8080
      tools:
        - name: orchestrate-termination
          description: "Process an employee termination across all systems. Use when HR initiates an employee separation."
          inputParameters:
            - name: worker_id
              in: body
              type: string
              description: "Workday worker ID."
            - name: okta_user_id
              in: body
              type: string
              description: "Okta user ID."
            - name: card_id
              in: body
              type: string
              description: "Corporate card ID."
            - name: termination_date
              in: body
              type: string
              description: "Last day of employment."
            - name: reason
              in: body
              type: string
              description: "Termination reason."
          steps:
            - name: terminate-wd
              type: call
              call: "workday.terminate-worker"
              with:
                worker_id: "{{worker_id}}"
                termination_date: "{{termination_date}}"
                reason: "{{reason}}"
            - name: deactivate-okta
              type: call
              call: "okta.deactivate-user"
              with:
                user_id: "{{okta_user_id}}"
            - name: cancel-card
              type: call
              call: "amex-corporate.cancel-card"
              with:
                card_id: "{{card_id}}"
            - name: create-ticket
              type: call
              call: "servicenow.create-request"
              with:
                short_description: "Offboarding — {{worker_id}}"
                description: "Workday terminated. Okta deactivated. Corporate card cancelled. Termination date: {{termination_date}}."
  consumes:
    - namespace: workday
      type: http
      baseUri: "https://wd3-impl-services1.workday.com/ccx/service/amex"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/workers/{worker_id}/terminate"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: terminate-worker
              method: POST
    - namespace: okta
      type: http
      baseUri: "https://americanexpress.okta.com/api/v1"
      authentication:
        type: bearer
        token: "$secrets.okta_token"
      resources:
        - name: users
          path: "/users/{user_id}/lifecycle/deactivate"
          inputParameters:
            - name: user_id
              in: path
          operations:
            - name: deactivate-user
              method: POST
    - namespace: amex-corporate
      type: http
      baseUri: "https://api.americanexpress.com/v1/corporate"
      authentication:
        type: bearer
        token: "$secrets.amex_corporate_token"
      resources:
        - name: cards
          path: "/cards/{card_id}/cancel"
          inputParameters:
            - name: card_id
              in: path
          operations:
            - name: cancel-card
              method: POST
    - namespace: servicenow
      type: http
      baseUri: "https://americanexpress.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: create-request
              method: POST

Retrieves the current list of open job requisitions from Workday for a specified organization and returns structured data for workforce planning analysis.

naftiko: "0.5"
info:
  label: "Workday Open Requisition Report"
  description: "Retrieves the current list of open job requisitions from Workday for a specified organization and returns structured data for workforce planning analysis."
  tags:
    - hr
    - recruiting
    - workday
    - workforce-planning
    - lookup
capability:
  exposes:
    - type: mcp
      namespace: recruiting
      port: 8080
      tools:
        - name: get-open-requisitions
          description: "Given a Workday organization ID, return all open job requisitions including job title, department, level, and days open. Use when HR business partners or talent acquisition teams need visibility into open headcount."
          inputParameters:
            - name: organization_id
              in: body
              type: string
              description: "The Workday organization ID to retrieve open requisitions for."
          call: "workday-recruiting.get-requisitions"
          with:
            organization_id: "{{organization_id}}"
          outputParameters:
            - name: requisitions
              type: array
              mapping: "$.data"
            - name: total_open
              type: number
              mapping: "$.total"
  consumes:
    - namespace: workday-recruiting
      type: http
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_access_token"
      resources:
        - name: requisitions
          path: "/jobRequisitions"
          inputParameters:
            - name: organization_id
              in: query
          operations:
            - name: get-requisitions
              method: GET

Escalates high-priority Zendesk support tickets by fetching ticket details, creating a Jira issue for the product team, and alerting the support lead via Slack.

naftiko: "0.5"
info:
  label: "Zendesk Ticket Escalation Workflow"
  description: "Escalates high-priority Zendesk support tickets by fetching ticket details, creating a Jira issue for the product team, and alerting the support lead via Slack."
  tags:
    - zendesk
    - customer-support
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: ticket-escalation
      port: 8080
      tools:
        - name: escalate-ticket
          description: "Escalate a Zendesk ticket to the product team via Jira and notify the support lead. Use when a support ticket requires product team intervention."
          inputParameters:
            - name: ticket_id
              in: body
              type: string
              description: "Zendesk ticket ID."
          steps:
            - name: get-ticket
              type: call
              call: "zendesk.get-ticket"
              with:
                ticket_id: "{{ticket_id}}"
            - name: create-jira
              type: call
              call: "jira.create-issue"
              with:
                project_key: "SUP"
                issuetype: "Bug"
                summary: "Escalation: {{get-ticket.subject}}"
                description: "Zendesk #{{ticket_id}}: {{get-ticket.description}}. Priority: {{get-ticket.priority}}."
            - name: alert-lead
              type: call
              call: "slack.post-message"
              with:
                channel: "support-escalations"
                text: "Ticket escalated: #{{ticket_id}} — {{get-ticket.subject}} | Priority: {{get-ticket.priority}} | Jira: {{create-jira.key}}"
  consumes:
    - namespace: zendesk
      type: http
      baseUri: "https://americanexpress.zendesk.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.zendesk_token"
      resources:
        - name: tickets
          path: "/tickets/{ticket_id}"
          inputParameters:
            - name: ticket_id
              in: path
          operations:
            - name: get-ticket
              method: GET
    - namespace: jira
      type: http
      baseUri: "https://americanexpress.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issue
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - namespace: slack
      type: http
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: message
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST