NBC Capabilities

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

Sort
Expand

Pulls weekly advertising campaign metrics from Salesforce Marketing Cloud and publishes a performance digest to a Microsoft Teams channel for the ad sales team.

naftiko: "0.5"
info:
  label: "Advertising Campaign Performance Digest"
  description: "Pulls weekly advertising campaign metrics from Salesforce Marketing Cloud and publishes a performance digest to a Microsoft Teams channel for the ad sales team."
  tags:
    - marketing
    - advertising
    - reporting
    - salesforce
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: marketing-reporting
      port: 8080
      tools:
        - name: digest-campaign-performance
          description: "Given a campaign ID and date range, fetch performance metrics from Salesforce Marketing Cloud and post a summary digest to the ad sales Teams channel. Use for weekly campaign reviews."
          inputParameters:
            - name: campaign_id
              in: body
              type: string
              description: "The Salesforce Marketing Cloud campaign ID."
            - name: date_from
              in: body
              type: string
              description: "Report start date in YYYY-MM-DD format."
            - name: date_to
              in: body
              type: string
              description: "Report end date in YYYY-MM-DD format."
          steps:
            - name: get-metrics
              type: call
              call: "sfmc.get-campaign-metrics"
              with:
                campaign_id: "{{campaign_id}}"
                date_from: "{{date_from}}"
                date_to: "{{date_to}}"
            - name: post-digest
              type: call
              call: "msteams-mkt.post-message"
              with:
                channel_id: "$secrets.ad_sales_channel_id"
                text: "Campaign {{campaign_id}} digest ({{date_from}} to {{date_to}}): Impressions={{get-metrics.impressions}}, Clicks={{get-metrics.clicks}}, CTR={{get-metrics.ctr}}"
  consumes:
    - type: http
      namespace: sfmc
      baseUri: "https://api.salesforce.com/marketing/v1"
      authentication:
        type: bearer
        token: "$secrets.sfmc_token"
      resources:
        - name: campaign-metrics
          path: "/campaigns/{{campaign_id}}/metrics"
          inputParameters:
            - name: campaign_id
              in: path
            - name: date_from
              in: query
            - name: date_to
              in: query
          operations:
            - name: get-campaign-metrics
              method: GET
    - type: http
      namespace: msteams-mkt
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

Retrieves the production schedule from Airtable for a given show.

naftiko: "0.5"
info:
  label: "Airtable Production Schedule Lookup"
  description: "Retrieves the production schedule from Airtable for a given show."
  tags:
    - content-production
    - scheduling
    - airtable
capability:
  exposes:
    - type: mcp
      namespace: production-ops
      port: 8080
      tools:
        - name: get-production-schedule
          description: "Given a show name, return the production schedule from Airtable."
          inputParameters:
            - name: show_name
              in: body
              type: string
              description: "Show name."
          call: airtable.list-records
          with:
            base_id: "$secrets.airtable_base_id"
            table: "Production Schedule"
            filter: "Show = '{{show_name}}'"
          outputParameters:
            - name: records
              type: array
              mapping: "$.records"
  consumes:
    - type: http
      namespace: airtable
      baseUri: "https://api.airtable.com/v0"
      authentication:
        type: bearer
        token: "$secrets.airtable_token"
      resources:
        - name: records
          path: "/{{base_id}}/Production%20Schedule"
          inputParameters:
            - name: base_id
              in: path
          operations:
            - name: list-records
              method: GET

Executes a SQL query against Amazon Redshift for viewership analytics.

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

Submits a batch of news scripts or documents to Anthropic Claude for summarization and writes the output back to a SharePoint document library for editorial review.

naftiko: "0.5"
info:
  label: "Anthropic Content Summarization"
  description: "Submits a batch of news scripts or documents to Anthropic Claude for summarization and writes the output back to a SharePoint document library for editorial review."
  tags:
    - ai
    - content
    - anthropic
    - sharepoint
    - editorial
capability:
  exposes:
    - type: mcp
      namespace: ai-content
      port: 8080
      tools:
        - name: summarize-content
          description: "Given a document URL and content type, send the text to Anthropic Claude for summarization and save the summary to a SharePoint library. Use for news script review, briefing prep, or editorial content processing."
          inputParameters:
            - name: content_text
              in: body
              type: string
              description: "The raw text content to be summarized."
            - name: content_type
              in: body
              type: string
              description: "Content type hint: news_script, briefing, or report."
            - name: sharepoint_site_id
              in: body
              type: string
              description: "SharePoint site ID where the summary will be saved."
          steps:
            - name: generate-summary
              type: call
              call: "anthropic.create-message"
              with:
                model: "claude-3-5-sonnet-20241022"
                content: "Summarize the following {{content_type}} in 3-5 sentences: {{content_text}}"
            - name: save-summary
              type: call
              call: "sharepoint-ai.create-file"
              with:
                site_id: "{{sharepoint_site_id}}"
                content: "{{generate-summary.text}}"
  consumes:
    - type: http
      namespace: anthropic
      baseUri: "https://api.anthropic.com/v1"
      authentication:
        type: apikey
        key: "x-api-key"
        value: "$secrets.anthropic_api_key"
        placement: header
      resources:
        - name: messages
          path: "/messages"
          operations:
            - name: create-message
              method: POST
    - type: http
      namespace: sharepoint-ai
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: drive-items
          path: "/sites/{{site_id}}/drive/root/children"
          inputParameters:
            - name: site_id
              in: path
          operations:
            - name: create-file
              method: POST

Invalidates CloudFront CDN cache for content URLs and notifies the platform Slack channel.

naftiko: "0.5"
info:
  label: "AWS CloudFront Cache Invalidation"
  description: "Invalidates CloudFront CDN cache for content URLs and notifies the platform Slack channel."
  tags:
    - infrastructure
    - cdn
    - aws
    - slack
capability:
  exposes:
    - type: mcp
      namespace: platform-ops
      port: 8080
      tools:
        - name: invalidate-cdn-cache
          description: "Invalidate CloudFront paths and notify Slack."
          inputParameters:
            - name: distribution_id
              in: body
              type: string
              description: "CloudFront distribution ID."
            - name: paths
              in: body
              type: string
              description: "Paths to invalidate."
          steps:
            - name: create-invalidation
              type: call
              call: cloudfront.create-invalidation
              with:
                distribution_id: "{{distribution_id}}"
                paths: "{{paths}}"
            - name: notify
              type: call
              call: slack.post-message
              with:
                channel: "platform-ops"
                text: "CDN invalidation created for {{distribution_id}}: {{paths}}"
  consumes:
    - type: http
      namespace: cloudfront
      baseUri: "https://cloudfront.amazonaws.com/2020-05-31"
      authentication:
        type: aws-sigv4
        accessKeyId: "$secrets.aws_access_key"
        secretAccessKey: "$secrets.aws_secret_key"
      resources:
        - name: invalidations
          path: "/distribution/{{distribution_id}}/invalidation"
          inputParameters:
            - name: distribution_id
              in: path
          operations:
            - name: create-invalidation
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves CloudWatch alarm state for streaming infrastructure.

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

When AWS Cost Anomaly Detection fires, creates a Jira FinOps ticket and posts to Slack.

naftiko: "0.5"
info:
  label: "AWS Cost Anomaly Alert"
  description: "When AWS Cost Anomaly Detection fires, creates a Jira FinOps ticket and posts to Slack."
  tags:
    - finops
    - cloud
    - aws
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: finops
      port: 8080
      tools:
        - name: handle-cost-anomaly
          description: "Create a Jira ticket and alert Slack for a cost anomaly."
          inputParameters:
            - name: anomaly_id
              in: body
              type: string
              description: "Anomaly ID."
            - name: service_name
              in: body
              type: string
              description: "AWS service."
            - name: overage_usd
              in: body
              type: number
              description: "Estimated overage."
          steps:
            - name: create-jira
              type: call
              call: jira.create-issue
              with:
                project_key: "FINOPS"
                issuetype: "Task"
                summary: "Cost anomaly: {{service_name}} +${{overage_usd}}"
            - name: alert
              type: call
              call: slack.post-message
              with:
                channel: "cloud-finops"
                text: "Cost anomaly on {{service_name}}: +${{overage_usd}} | Jira: {{create-jira.key}}"
  consumes:
    - type: http
      namespace: jira
      baseUri: "https://nbc.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When AWS Cost Explorer detects a spending anomaly, queries the anomaly details, creates a Jira cost-review ticket, and posts an alert to the FinOps Teams channel.

naftiko: "0.5"
info:
  label: "AWS Cost Anomaly Responder"
  description: "When AWS Cost Explorer detects a spending anomaly, queries the anomaly details, creates a Jira cost-review ticket, and posts an alert to the FinOps Teams channel."
  tags:
    - cloud
    - finops
    - aws
    - jira
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: cloud-finops
      port: 8080
      tools:
        - name: handle-cost-anomaly
          description: "Given an AWS Cost Explorer anomaly ID, fetch anomaly details, open a Jira cost-review ticket, and alert the FinOps team in Teams. Invoke when AWS detects unexpected spend spikes."
          inputParameters:
            - name: anomaly_id
              in: body
              type: string
              description: "The AWS Cost Explorer anomaly ID."
            - name: service_name
              in: body
              type: string
              description: "The AWS service name associated with the anomaly."
            - name: estimated_cost
              in: body
              type: string
              description: "The estimated excess cost in USD."
          steps:
            - name: create-review-ticket
              type: call
              call: "jira-finops.create-issue"
              with:
                project_key: "FINOPS"
                issuetype: "Task"
                summary: "AWS cost anomaly: {{service_name}} - ${{estimated_cost}} excess"
                description: "Anomaly ID: {{anomaly_id}}\nService: {{service_name}}\nEstimated excess: ${{estimated_cost}}"
            - name: alert-finops
              type: call
              call: "msteams-finops.post-message"
              with:
                channel_id: "$secrets.finops_channel_id"
                text: "Cost Anomaly Detected: {{service_name}} — ${{estimated_cost}} excess. Jira: {{create-review-ticket.key}}"
  consumes:
    - type: http
      namespace: jira-finops
      baseUri: "https://nbc.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: msteams-finops
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

Retrieves the running state of an EC2 instance.

naftiko: "0.5"
info:
  label: "AWS EC2 Instance Status"
  description: "Retrieves the running state of an EC2 instance."
  tags:
    - cloud
    - infrastructure
    - aws
    - ec2
capability:
  exposes:
    - type: mcp
      namespace: cloud-ops
      port: 8080
      tools:
        - name: get-ec2-status
          description: "Given an instance ID, return state and type."
          inputParameters:
            - name: instance_id
              in: body
              type: string
              description: "EC2 instance ID."
          call: ec2.describe-instance
          with:
            instance_id: "{{instance_id}}"
          outputParameters:
            - name: state
              type: string
              mapping: "$.Reservations[0].Instances[0].State.Name"
  consumes:
    - type: http
      namespace: ec2
      baseUri: "https://ec2.us-east-1.amazonaws.com"
      authentication:
        type: aws-sigv4
        accessKeyId: "$secrets.aws_access_key"
        secretAccessKey: "$secrets.aws_secret_key"
      resources:
        - name: instances
          path: "/"
          operations:
            - name: describe-instance
              method: GET

Invokes a Lambda function for content processing tasks.

naftiko: "0.5"
info:
  label: "AWS Lambda Content Processor"
  description: "Invokes a Lambda function for content processing tasks."
  tags:
    - engineering
    - serverless
    - aws
    - aws-lambda
capability:
  exposes:
    - type: mcp
      namespace: content-ops
      port: 8080
      tools:
        - name: invoke-content-processor
          description: "Invoke a content processing Lambda with a JSON payload."
          inputParameters:
            - name: function_name
              in: body
              type: string
              description: "Lambda function name."
            - name: payload
              in: body
              type: string
              description: "JSON payload."
          call: lambda.invoke-function
          with:
            function_name: "{{function_name}}"
            payload: "{{payload}}"
          outputParameters:
            - name: status_code
              type: integer
              mapping: "$.StatusCode"
            - name: result
              type: string
              mapping: "$.Payload"
  consumes:
    - type: http
      namespace: lambda
      baseUri: "https://lambda.us-east-1.amazonaws.com/2015-03-31"
      authentication:
        type: aws-sigv4
        accessKeyId: "$secrets.aws_access_key"
        secretAccessKey: "$secrets.aws_secret_key"
      resources:
        - name: functions
          path: "/functions/{{function_name}}/invocations"
          inputParameters:
            - name: function_name
              in: path
          operations:
            - name: invoke-function
              method: POST

Retrieves the status of an AWS Elemental MediaConvert transcoding job.

naftiko: "0.5"
info:
  label: "AWS MediaConvert Job Status"
  description: "Retrieves the status of an AWS Elemental MediaConvert transcoding job."
  tags:
    - media
    - cloud
    - aws
capability:
  exposes:
    - type: mcp
      namespace: media-ops
      port: 8080
      tools:
        - name: get-transcode-status
          description: "Given a MediaConvert job ID, return the transcoding status and output URL."
          inputParameters:
            - name: job_id
              in: body
              type: string
              description: "MediaConvert job ID."
          call: mediaconvert.get-job
          with:
            job_id: "{{job_id}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.Job.Status"
            - name: output_uri
              type: string
              mapping: "$.Job.Settings.OutputGroups[0].OutputGroupSettings.HlsGroupSettings.Destination"
  consumes:
    - type: http
      namespace: mediaconvert
      baseUri: "https://mediaconvert.us-east-1.amazonaws.com/2017-08-29"
      authentication:
        type: aws-sigv4
        accessKeyId: "$secrets.aws_access_key"
        secretAccessKey: "$secrets.aws_secret_key"
      resources:
        - name: jobs
          path: "/jobs/{{job_id}}"
          inputParameters:
            - name: job_id
              in: path
          operations:
            - name: get-job
              method: GET

Retrieves the status of an AWS Elemental MediaPackage live channel.

naftiko: "0.5"
info:
  label: "AWS MediaPackage Channel Status"
  description: "Retrieves the status of an AWS Elemental MediaPackage live channel."
  tags:
    - streaming
    - media
    - aws
capability:
  exposes:
    - type: mcp
      namespace: streaming-ops
      port: 8080
      tools:
        - name: get-channel-status
          description: "Given a MediaPackage channel ID, return status and endpoints."
          inputParameters:
            - name: channel_id
              in: body
              type: string
              description: "MediaPackage channel ID."
          call: mediapackage.describe-channel
          with:
            id: "{{channel_id}}"
          outputParameters:
            - name: arn
              type: string
              mapping: "$.Arn"
            - name: hls_ingest
              type: string
              mapping: "$.HlsIngest.IngestEndpoints[0].Url"
  consumes:
    - type: http
      namespace: mediapackage
      baseUri: "https://mediapackage.us-east-1.amazonaws.com"
      authentication:
        type: aws-sigv4
        accessKeyId: "$secrets.aws_access_key"
        secretAccessKey: "$secrets.aws_secret_key"
      resources:
        - name: channels
          path: "/channels/{{id}}"
          inputParameters:
            - name: id
              in: path
          operations:
            - name: describe-channel
              method: GET

Submits a media frame to AWS Rekognition for content moderation analysis.

naftiko: "0.5"
info:
  label: "AWS Rekognition Content Moderation"
  description: "Submits a media frame to AWS Rekognition for content moderation analysis."
  tags:
    - content-safety
    - ai
    - aws
capability:
  exposes:
    - type: mcp
      namespace: trust-safety
      port: 8080
      tools:
        - name: moderate-media-frame
          description: "Given an S3 bucket and key for a media frame, run content moderation."
          inputParameters:
            - name: bucket
              in: body
              type: string
              description: "S3 bucket."
            - name: key
              in: body
              type: string
              description: "S3 object key."
          call: rekognition.detect-moderation-labels
          with:
            bucket: "{{bucket}}"
            key: "{{key}}"
          outputParameters:
            - name: labels
              type: array
              mapping: "$.ModerationLabels"
  consumes:
    - type: http
      namespace: rekognition
      baseUri: "https://rekognition.us-east-1.amazonaws.com"
      authentication:
        type: aws-sigv4
        accessKeyId: "$secrets.aws_access_key"
        secretAccessKey: "$secrets.aws_secret_key"
      resources:
        - name: moderation
          path: "/"
          operations:
            - name: detect-moderation-labels
              method: POST

Uploads a content asset to S3 for CDN delivery and notifies the content ops Slack channel.

naftiko: "0.5"
info:
  label: "AWS S3 Content Delivery Upload"
  description: "Uploads a content asset to S3 for CDN delivery and notifies the content ops Slack channel."
  tags:
    - media
    - content-delivery
    - amazon-s3
    - slack
capability:
  exposes:
    - type: mcp
      namespace: content-delivery
      port: 8080
      tools:
        - name: upload-content-asset
          description: "Upload a content asset to S3 and notify Slack."
          inputParameters:
            - name: bucket
              in: body
              type: string
              description: "S3 bucket."
            - name: key
              in: body
              type: string
              description: "S3 key."
            - name: source_url
              in: body
              type: string
              description: "Source URL."
          steps:
            - name: upload
              type: call
              call: s3.put-object
              with:
                bucket: "{{bucket}}"
                key: "{{key}}"
                source: "{{source_url}}"
            - name: notify
              type: call
              call: slack.post-message
              with:
                channel: "content-ops"
                text: "Content uploaded: s3://{{bucket}}/{{key}}"
  consumes:
    - type: http
      namespace: s3
      baseUri: "https://s3.us-east-1.amazonaws.com"
      authentication:
        type: aws-sigv4
        accessKeyId: "$secrets.aws_access_key"
        secretAccessKey: "$secrets.aws_secret_key"
      resources:
        - name: objects
          path: "/{{bucket}}/{{key}}"
          inputParameters:
            - name: bucket
              in: path
            - name: key
              in: path
          operations:
            - name: put-object
              method: PUT
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Lists media assets in an S3 bucket by prefix for content management.

naftiko: "0.5"
info:
  label: "AWS S3 Media Asset Lookup"
  description: "Lists media assets in an S3 bucket by prefix for content management."
  tags:
    - media
    - storage
    - amazon-s3
capability:
  exposes:
    - type: mcp
      namespace: media-ops
      port: 8080
      tools:
        - name: list-media-assets
          description: "Given an S3 bucket and prefix, list available media assets."
          inputParameters:
            - name: bucket
              in: body
              type: string
              description: "S3 bucket."
            - name: prefix
              in: body
              type: string
              description: "S3 key prefix."
          call: s3.list-objects
          with:
            bucket: "{{bucket}}"
            prefix: "{{prefix}}"
          outputParameters:
            - name: objects
              type: array
              mapping: "$.Contents[*].Key"
  consumes:
    - type: http
      namespace: s3
      baseUri: "https://s3.us-east-1.amazonaws.com"
      authentication:
        type: aws-sigv4
        accessKeyId: "$secrets.aws_access_key"
        secretAccessKey: "$secrets.aws_secret_key"
      resources:
        - name: objects
          path: "/{{bucket}}"
          inputParameters:
            - name: bucket
              in: path
          operations:
            - name: list-objects
              method: GET

Checks SQS queue depth and returns message counts.

naftiko: "0.5"
info:
  label: "AWS SQS Queue Depth Monitor"
  description: "Checks SQS queue depth and returns message counts."
  tags:
    - engineering
    - messaging
    - amazon-sqs
capability:
  exposes:
    - type: mcp
      namespace: platform-ops
      port: 8080
      tools:
        - name: get-queue-depth
          description: "Given an SQS queue URL, return message count."
          inputParameters:
            - name: queue_url
              in: body
              type: string
              description: "SQS queue URL."
          call: sqs.get-queue-attributes
          with:
            queue_url: "{{queue_url}}"
          outputParameters:
            - name: messages
              type: integer
              mapping: "$.Attributes.ApproximateNumberOfMessages"
  consumes:
    - type: http
      namespace: sqs
      baseUri: "https://sqs.us-east-1.amazonaws.com"
      authentication:
        type: aws-sigv4
        accessKeyId: "$secrets.aws_access_key"
        secretAccessKey: "$secrets.aws_secret_key"
      resources:
        - name: queues
          path: "/"
          operations:
            - name: get-queue-attributes
              method: POST

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

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

When an employee submits an expense report in SAP Concur that exceeds the policy threshold, creates a ServiceNow approval task for the finance manager and notifies them in Teams.

naftiko: "0.5"
info:
  label: "Concur Expense Report Approval"
  description: "When an employee submits an expense report in SAP Concur that exceeds the policy threshold, creates a ServiceNow approval task for the finance manager and notifies them in Teams."
  tags:
    - finance
    - expense-management
    - sap-concur
    - servicenow
    - microsoft-teams
    - approval
capability:
  exposes:
    - type: mcp
      namespace: finance-expenses
      port: 8080
      tools:
        - name: route-expense-approval
          description: "Given a Concur expense report ID and total amount, check if amount exceeds policy threshold and route to the finance manager via ServiceNow task and Teams notification. Use for automated expense approval routing."
          inputParameters:
            - name: report_id
              in: body
              type: string
              description: "The SAP Concur expense report ID."
            - name: total_amount
              in: body
              type: number
              description: "The total expense amount in USD."
            - name: policy_threshold
              in: body
              type: number
              description: "The approval threshold in USD. Reports above this require manager approval."
          steps:
            - name: get-report
              type: call
              call: "concur.get-expense-report"
              with:
                report_id: "{{report_id}}"
            - name: create-approval
              type: call
              call: "servicenow-exp.create-task"
              with:
                short_description: "Expense approval required: Report {{report_id}} - ${{total_amount}}"
                category: "finance_expense"
            - name: notify-manager
              type: call
              call: "msteams-exp.send-message"
              with:
                recipient_upn: "{{get-report.manager_email}}"
                text: "Expense report {{report_id}} for ${{total_amount}} requires your approval. ServiceNow task: {{create-approval.number}}"
  consumes:
    - type: http
      namespace: concur
      baseUri: "https://www.concursolutions.com/api/v3.0"
      authentication:
        type: bearer
        token: "$secrets.concur_token"
      resources:
        - name: expense-reports
          path: "/expense/reports/{{report_id}}"
          inputParameters:
            - name: report_id
              in: path
          operations:
            - name: get-expense-report
              method: GET
    - type: http
      namespace: servicenow-exp
      baseUri: "https://nbc.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST
    - type: http
      namespace: msteams-exp
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: chats
          path: "/chats"
          operations:
            - name: send-message
              method: POST

Searches Confluence for runbooks by keyword.

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

Retrieves the status of a Databricks content analytics job run.

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

When Datadog fires a host or service alert, queries the alert details, creates a ServiceNow incident, and notifies the on-call team via PagerDuty.

naftiko: "0.5"
info:
  label: "Datadog Infrastructure Alert Triage"
  description: "When Datadog fires a host or service alert, queries the alert details, creates a ServiceNow incident, and notifies the on-call team via PagerDuty."
  tags:
    - observability
    - monitoring
    - datadog
    - servicenow
    - pagerduty
capability:
  exposes:
    - type: mcp
      namespace: observability-ops
      port: 8080
      tools:
        - name: handle-datadog-alert
          description: "Given a Datadog alert ID, fetch alert details, create a ServiceNow incident, and page the on-call engineer via PagerDuty. Use for any infrastructure or application alert requiring human escalation."
          inputParameters:
            - name: alert_id
              in: body
              type: string
              description: "The Datadog monitor alert ID."
            - name: monitor_name
              in: body
              type: string
              description: "The name of the triggering Datadog monitor."
          steps:
            - name: get-alert
              type: call
              call: "datadog-alert.get-monitor"
              with:
                monitor_id: "{{alert_id}}"
            - name: create-incident
              type: call
              call: "servicenow-alert.create-incident"
              with:
                short_description: "Datadog alert: {{monitor_name}}"
                urgency: "1"
                category: "infrastructure"
            - name: page-oncall
              type: call
              call: "pagerduty-alert.trigger-incident"
              with:
                title: "Datadog: {{monitor_name}}"
                severity: "critical"
                incident_key: "dd-{{alert_id}}"
  consumes:
    - type: http
      namespace: datadog-alert
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: monitors
          path: "/monitor/{{monitor_id}}"
          inputParameters:
            - name: monitor_id
              in: path
          operations:
            - name: get-monitor
              method: GET
    - type: http
      namespace: servicenow-alert
      baseUri: "https://nbc.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: pagerduty-alert
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.pagerduty_token"
        placement: header
      resources:
        - name: incidents
          path: "/incidents"
          operations:
            - name: trigger-incident
              method: POST

Searches Datadog logs by query string for debugging.

naftiko: "0.5"
info:
  label: "Datadog Log Search"
  description: "Searches Datadog logs by query string for debugging."
  tags:
    - engineering
    - observability
    - datadog
capability:
  exposes:
    - type: mcp
      namespace: observability
      port: 8080
      tools:
        - name: search-logs
          description: "Given a log query, return matching entries."
          inputParameters:
            - name: query
              in: body
              type: string
              description: "Log search query."
          call: datadog.search-logs
          with:
            query: "{{query}}"
          outputParameters:
            - name: logs
              type: array
              mapping: "$.data"
  consumes:
    - type: http
      namespace: datadog
      baseUri: "https://api.datadoghq.com/api/v2"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: logs
          path: "/logs/events/search"
          operations:
            - name: search-logs
              method: POST

Fetches current SLO compliance metrics from Datadog for all production services and posts a weekly compliance summary to the engineering leadership Teams channel.

naftiko: "0.5"
info:
  label: "Datadog SLO Compliance Report"
  description: "Fetches current SLO compliance metrics from Datadog for all production services and posts a weekly compliance summary to the engineering leadership Teams channel."
  tags:
    - observability
    - slo
    - datadog
    - reporting
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: slo-reporting
      port: 8080
      tools:
        - name: publish-slo-report
          description: "Fetch all Datadog SLO statuses for the current week and post a compliance report to the engineering leadership Teams channel. Use for weekly engineering reviews and executive briefings."
          steps:
            - name: get-slos
              type: call
              call: "datadog-slo.list-slos"
            - name: post-report
              type: call
              call: "msteams-slo.post-message"
              with:
                channel_id: "$secrets.eng_leadership_channel_id"
                text: "Weekly SLO Report: {{get-slos.count}} SLOs monitored. See Datadog for full compliance details."
  consumes:
    - type: http
      namespace: datadog-slo
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: slos
          path: "/slo"
          operations:
            - name: list-slos
              method: GET
    - type: http
      namespace: msteams-slo
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

Queries Datadog for streaming platform health metrics and posts to the platform Slack channel.

naftiko: "0.5"
info:
  label: "Datadog Streaming Platform Health"
  description: "Queries Datadog for streaming platform health metrics and posts to the platform Slack channel."
  tags:
    - monitoring
    - streaming
    - datadog
    - slack
capability:
  exposes:
    - type: mcp
      namespace: platform-ops
      port: 8080
      tools:
        - name: check-streaming-health
          description: "Query Datadog for streaming latency and error rates and post to Slack."
          inputParameters:
            - name: service
              in: body
              type: string
              description: "Streaming service name."
          steps:
            - name: query-health
              type: call
              call: datadog.query-timeseries
              with:
                query: "avg:trace.http.request.duration{service:{{service}}}"
            - name: post-status
              type: call
              call: slack.post-message
              with:
                channel: "platform-ops"
                text: "Streaming health for {{service}}: {{query-health.series[0].pointlist[-1][1]}}ms avg latency"
  consumes:
    - type: http
      namespace: datadog
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: query
          path: "/query"
          operations:
            - name: query-timeseries
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Posts a show or event announcement to the NBC Discord community server.

naftiko: "0.5"
info:
  label: "Discord Community Announcement"
  description: "Posts a show or event announcement to the NBC Discord community server."
  tags:
    - marketing
    - community
    - discord
capability:
  exposes:
    - type: mcp
      namespace: community-ops
      port: 8080
      tools:
        - name: post-discord-announcement
          description: "Post an announcement to a Discord channel."
          inputParameters:
            - name: channel_id
              in: body
              type: string
              description: "Discord channel ID."
            - name: content
              in: body
              type: string
              description: "Announcement content."
          call: discord.create-message
          with:
            channel_id: "{{channel_id}}"
            content: "{{content}}"
          outputParameters:
            - name: message_id
              type: string
              mapping: "$.id"
  consumes:
    - type: http
      namespace: discord
      baseUri: "https://discord.com/api/v10"
      authentication:
        type: bearer
        token: "$secrets.discord_bot_token"
      resources:
        - name: messages
          path: "/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: create-message
              method: POST

Retrieves the signing status of a DocuSign talent contract envelope.

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

Searches the content index in Elasticsearch for shows, episodes, and clips.

naftiko: "0.5"
info:
  label: "Elasticsearch Content Search"
  description: "Searches the content index in Elasticsearch for shows, episodes, and clips."
  tags:
    - media
    - search
    - elasticsearch
capability:
  exposes:
    - type: mcp
      namespace: content-ops
      port: 8080
      tools:
        - name: search-content
          description: "Given a search query, return matching content from the index."
          inputParameters:
            - name: query
              in: body
              type: string
              description: "Search query."
          call: elasticsearch.search
          with:
            index: "content"
            q: "{{query}}"
          outputParameters:
            - name: hits
              type: array
              mapping: "$.hits.hits[*]._source"
            - name: total
              type: integer
              mapping: "$.hits.total.value"
  consumes:
    - type: http
      namespace: elasticsearch
      baseUri: "https://nbc-es.us-east-1.es.amazonaws.com"
      authentication:
        type: aws-sigv4
        accessKeyId: "$secrets.aws_access_key"
        secretAccessKey: "$secrets.aws_secret_key"
      resources:
        - name: search
          path: "/content/_search"
          operations:
            - name: search
              method: POST

Posts a show graphics review request to the creative Slack channel.

naftiko: "0.5"
info:
  label: "Figma Show Graphics Review"
  description: "Posts a show graphics review request to the creative Slack channel."
  tags:
    - design
    - content-production
    - figma
    - slack
capability:
  exposes:
    - type: mcp
      namespace: creative-ops
      port: 8080
      tools:
        - name: request-graphics-review
          description: "Fetch Figma file info and post review request to Slack."
          inputParameters:
            - name: file_key
              in: body
              type: string
              description: "Figma file key."
          steps:
            - name: get-file
              type: call
              call: figma.get-file
              with:
                file_key: "{{file_key}}"
            - name: post-review
              type: call
              call: slack.post-message
              with:
                channel: "creative"
                text: "Graphics review: {{get-file.name}} — https://www.figma.com/file/{{file_key}}"
  consumes:
    - type: http
      namespace: figma
      baseUri: "https://api.figma.com/v1"
      authentication:
        type: bearer
        token: "$secrets.figma_token"
      resources:
        - name: files
          path: "/files/{{file_key}}"
          inputParameters:
            - name: file_key
              in: path
          operations:
            - name: get-file
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Triggers a GitHub Actions workflow and notifies the engineering Slack channel.

naftiko: "0.5"
info:
  label: "GitHub CI/CD Pipeline Trigger"
  description: "Triggers a GitHub Actions workflow and notifies the engineering Slack channel."
  tags:
    - engineering
    - cicd
    - github-actions
    - slack
capability:
  exposes:
    - type: mcp
      namespace: cicd-ops
      port: 8080
      tools:
        - name: trigger-workflow
          description: "Trigger a GitHub Actions workflow dispatch and notify Slack."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "GitHub repo."
            - name: workflow_id
              in: body
              type: string
              description: "Workflow file."
            - name: ref
              in: body
              type: string
              description: "Git ref."
          steps:
            - name: dispatch
              type: call
              call: github.create-workflow-dispatch
              with:
                repo: "{{repo}}"
                workflow_id: "{{workflow_id}}"
                ref: "{{ref}}"
            - name: notify
              type: call
              call: slack.post-message
              with:
                channel: "engineering"
                text: "Workflow {{workflow_id}} triggered on {{repo}} ({{ref}})"
  consumes:
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: dispatches
          path: "/repos/{{repo}}/actions/workflows/{{workflow_id}}/dispatches"
          inputParameters:
            - name: repo
              in: path
            - name: workflow_id
              in: path
          operations:
            - name: create-workflow-dispatch
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Fetches Dependabot alerts and posts summary to security Slack.

naftiko: "0.5"
info:
  label: "GitHub Dependabot Alert Summary"
  description: "Fetches Dependabot alerts and posts summary to security Slack."
  tags:
    - security
    - engineering
    - github
    - slack
capability:
  exposes:
    - type: mcp
      namespace: appsec
      port: 8080
      tools:
        - name: summarize-alerts
          description: "Fetch open Dependabot alerts and post summary to Slack."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "GitHub repo."
          steps:
            - name: get-alerts
              type: call
              call: github.list-alerts
              with:
                repo: "{{repo}}"
                state: "open"
            - name: post
              type: call
              call: slack.post-message
              with:
                channel: "security-alerts"
                text: "Dependabot for {{repo}}: {{get-alerts.total}} open"
  consumes:
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: alerts
          path: "/repos/{{repo}}/dependabot/alerts"
          inputParameters:
            - name: repo
              in: path
          operations:
            - name: list-alerts
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

On a successful GitHub Actions deployment to production, records a deployment marker in Datadog and updates the associated Jira ticket to Done.

naftiko: "0.5"
info:
  label: "GitHub Deployment Status Tracker"
  description: "On a successful GitHub Actions deployment to production, records a deployment marker in Datadog and updates the associated Jira ticket to Done."
  tags:
    - devops
    - deployment
    - github
    - datadog
    - jira
capability:
  exposes:
    - type: mcp
      namespace: devops-deploy
      port: 8080
      tools:
        - name: record-deployment
          description: "Given a GitHub deployment event with repository, environment, and commit SHA, create a Datadog deployment marker and transition the linked Jira issue to Done. Use after any successful production deployment."
          inputParameters:
            - name: repository
              in: body
              type: string
              description: "The GitHub repository in owner/repo format."
            - name: environment
              in: body
              type: string
              description: "The target deployment environment (e.g., production, staging)."
            - name: commit_sha
              in: body
              type: string
              description: "The commit SHA that was deployed."
            - name: jira_issue_key
              in: body
              type: string
              description: "The Jira issue key to transition to Done (e.g., ENG-1234)."
          steps:
            - name: create-marker
              type: call
              call: "datadog-deploy.create-deployment"
              with:
                service: "{{repository}}"
                version: "{{commit_sha}}"
                env: "{{environment}}"
            - name: close-jira
              type: call
              call: "jira-deploy.transition-issue"
              with:
                issue_key: "{{jira_issue_key}}"
                transition_id: "31"
  consumes:
    - type: http
      namespace: datadog-deploy
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: deployments
          path: "/deployments"
          operations:
            - name: create-deployment
              method: POST
    - type: http
      namespace: jira-deploy
      baseUri: "https://nbc.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issue-transitions
          path: "/issue/{{issue_key}}/transitions"
          inputParameters:
            - name: issue_key
              in: path
          operations:
            - name: transition-issue
              method: POST

When a GitHub Actions workflow fails on a protected branch, opens a Jira bug, creates a Datadog event, and alerts the engineering team in Microsoft Teams.

naftiko: "0.5"
info:
  label: "GitHub Pipeline Failure Handler"
  description: "When a GitHub Actions workflow fails on a protected branch, opens a Jira bug, creates a Datadog event, and alerts the engineering team in Microsoft Teams."
  tags:
    - devops
    - ci-cd
    - github
    - jira
    - datadog
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: devops-ci
      port: 8080
      tools:
        - name: handle-pipeline-failure
          description: "Given a GitHub Actions run ID, repository, branch, and failing job name, open a Jira bug, create a Datadog deployment event, and alert the engineering Teams channel. Invoke on any protected-branch workflow failure."
          inputParameters:
            - name: run_id
              in: body
              type: string
              description: "The GitHub Actions workflow run ID."
            - name: repository
              in: body
              type: string
              description: "The GitHub repository in owner/repo format."
            - name: branch
              in: body
              type: string
              description: "The branch on which the workflow failed."
            - name: job_name
              in: body
              type: string
              description: "The name of the failed job."
            - name: commit_sha
              in: body
              type: string
              description: "The commit SHA that triggered the run."
          steps:
            - name: create-bug
              type: call
              call: "jira.create-issue"
              with:
                project_key: "ENG"
                issuetype: "Bug"
                summary: "[CI Failure] {{repository}} / {{branch}} - {{job_name}}"
                description: "Run ID: {{run_id}}\nCommit: {{commit_sha}}"
            - name: create-dd-event
              type: call
              call: "datadog-ci.create-event"
              with:
                title: "CI failure: {{repository}} {{branch}}"
                alert_type: "error"
                tags: "repo:{{repository}},branch:{{branch}}"
            - name: alert-engineering
              type: call
              call: "msteams-ci.post-message"
              with:
                channel_id: "$secrets.engineering_channel_id"
                text: "Build Failure: {{repository}} | Branch: {{branch}} | Job: {{job_name}} | Jira: {{create-bug.key}}"
  consumes:
    - type: http
      namespace: jira
      baseUri: "https://nbc.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: datadog-ci
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: events
          path: "/events"
          operations:
            - name: create-event
              method: POST
    - type: http
      namespace: msteams-ci
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

Retrieves Google Ads campaign performance metrics for media promotion campaigns.

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

Retrieves Peacock app usage metrics from Google Analytics and posts to Slack.

naftiko: "0.5"
info:
  label: "Google Analytics App Usage"
  description: "Retrieves Peacock app usage metrics from Google Analytics and posts to Slack."
  tags:
    - analytics
    - streaming
    - google-analytics
    - slack
capability:
  exposes:
    - type: mcp
      namespace: app-analytics
      port: 8080
      tools:
        - name: post-app-usage
          description: "Fetch app usage metrics and post to Slack."
          inputParameters:
            - name: property_id
              in: body
              type: string
              description: "GA property ID."
          steps:
            - name: get-report
              type: call
              call: ga.run-report
              with:
                property_id: "{{property_id}}"
                date_range: "last7days"
            - name: post
              type: call
              call: slack.post-message
              with:
                channel: "app-analytics"
                text: "App usage: {{get-report.sessions}} sessions, {{get-report.users}} users"
  consumes:
    - type: http
      namespace: ga
      baseUri: "https://analyticsdata.googleapis.com/v1beta"
      authentication:
        type: bearer
        token: "$secrets.google_analytics_token"
      resources:
        - name: reports
          path: "/properties/{{property_id}}:runReport"
          inputParameters:
            - name: property_id
              in: path
          operations:
            - name: run-report
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves ad serving metrics from Google Campaign Manager 360.

naftiko: "0.5"
info:
  label: "Google Campaign Manager Report"
  description: "Retrieves ad serving metrics from Google Campaign Manager 360."
  tags:
    - advertising
    - analytics
    - google-campaign-manager
capability:
  exposes:
    - type: mcp
      namespace: ad-ops
      port: 8080
      tools:
        - name: get-campaign-report
          description: "Given a Campaign Manager profile and report ID, return serving metrics."
          inputParameters:
            - name: profile_id
              in: body
              type: string
              description: "CM360 profile ID."
            - name: report_id
              in: body
              type: string
              description: "Report ID."
          call: cm360.get-report
          with:
            profile_id: "{{profile_id}}"
            report_id: "{{report_id}}"
          outputParameters:
            - name: data
              type: object
              mapping: "$.rows"
  consumes:
    - type: http
      namespace: cm360
      baseUri: "https://dfareporting.googleapis.com/dfareporting/v4"
      authentication:
        type: bearer
        token: "$secrets.google_cm360_token"
      resources:
        - name: reports
          path: "/userprofiles/{{profile_id}}/reports/{{report_id}}/files"
          inputParameters:
            - name: profile_id
              in: path
            - name: report_id
              in: path
          operations:
            - name: get-report
              method: GET

Retrieves the state of a Grafana alert monitoring streaming infrastructure.

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

Fetches unestimated or stale Jira issues from a project backlog and posts a grooming summary to the product team's Teams channel ahead of the sprint planning session.

naftiko: "0.5"
info:
  label: "Jira Backlog Grooming Digest"
  description: "Fetches unestimated or stale Jira issues from a project backlog and posts a grooming summary to the product team's Teams channel ahead of the sprint planning session."
  tags:
    - devops
    - project-management
    - jira
    - reporting
    - agile
capability:
  exposes:
    - type: mcp
      namespace: agile-reporting
      port: 8080
      tools:
        - name: digest-backlog
          description: "Given a Jira project key and staleness threshold in days, fetch unestimated and stale backlog issues and post a grooming summary to Teams. Use before sprint planning to ensure backlog hygiene."
          inputParameters:
            - name: project_key
              in: body
              type: string
              description: "The Jira project key to inspect (e.g., ENG)."
            - name: stale_days
              in: body
              type: integer
              description: "Number of days without update before an issue is considered stale."
          steps:
            - name: get-stale-issues
              type: call
              call: "jira-backlog.search-stale"
              with:
                project_key: "{{project_key}}"
                stale_days: "{{stale_days}}"
            - name: post-digest
              type: call
              call: "msteams-agile.post-message"
              with:
                channel_id: "$secrets.product_channel_id"
                text: "Backlog Grooming Digest ({{project_key}}): {{get-stale-issues.count}} stale/unestimated issues need attention before sprint planning."
  consumes:
    - type: http
      namespace: jira-backlog
      baseUri: "https://nbc.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/search"
          operations:
            - name: search-stale
              method: POST
    - type: http
      namespace: msteams-agile
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

Reports overdue Jira tickets to the engineering Slack channel.

naftiko: "0.5"
info:
  label: "Jira Overdue Ticket Report"
  description: "Reports overdue Jira tickets to the engineering Slack channel."
  tags:
    - engineering
    - project-management
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: eng-ops
      port: 8080
      tools:
        - name: report-overdue
          description: "Search Jira for overdue tickets and post count to Slack."
          inputParameters:
            - name: project_key
              in: body
              type: string
              description: "Jira project key."
          steps:
            - name: search
              type: call
              call: jira.search-issues
              with:
                jql: "project={{project_key}} AND duedate < now() AND status != Done"
            - name: post
              type: call
              call: slack.post-message
              with:
                channel: "engineering"
                text: "Overdue in {{project_key}}: {{search.total}} tickets"
  consumes:
    - type: http
      namespace: jira
      baseUri: "https://nbc.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_token"
      resources:
        - name: search
          path: "/search"
          operations:
            - name: search-issues
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Creates a Jira ticket for content production issues and notifies the production team via Slack.

naftiko: "0.5"
info:
  label: "Jira Production Ticket Creation"
  description: "Creates a Jira ticket for content production issues and notifies the production team via Slack."
  tags:
    - content-production
    - project-management
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: production-ops
      port: 8080
      tools:
        - name: create-production-ticket
          description: "Create a Jira production ticket and notify Slack."
          inputParameters:
            - name: show_name
              in: body
              type: string
              description: "Show or program name."
            - name: issue_type
              in: body
              type: string
              description: "Issue type (Task, Bug, Story)."
            - name: summary
              in: body
              type: string
              description: "Ticket summary."
          steps:
            - name: create-ticket
              type: call
              call: jira.create-issue
              with:
                project_key: "PROD"
                issuetype: "{{issue_type}}"
                summary: "{{summary}}"
                description: "Show: {{show_name}}"
            - name: notify-prod
              type: call
              call: slack.post-message
              with:
                channel: "production"
                text: "Production ticket: {{create-ticket.key}} — {{summary}} ({{show_name}})"
  consumes:
    - type: http
      namespace: jira
      baseUri: "https://nbc.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

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

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

Fetches the current sprint status from Jira for a given project, summarizes open, in-progress, and done issues, and posts the report to the engineering team's Teams channel.

naftiko: "0.5"
info:
  label: "Jira Sprint Status Report"
  description: "Fetches the current sprint status from Jira for a given project, summarizes open, in-progress, and done issues, and posts the report to the engineering team's Teams channel."
  tags:
    - devops
    - project-management
    - jira
    - reporting
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: sprint-reporting
      port: 8080
      tools:
        - name: get-sprint-status
          description: "Given a Jira project key, fetch the active sprint and summarize issues by status, then post the report to Teams. Use for daily standups or weekly sprint reviews."
          inputParameters:
            - name: project_key
              in: body
              type: string
              description: "The Jira project key (e.g., ENG, TECH)."
          steps:
            - name: get-sprint
              type: call
              call: "jira-sprint.get-active-sprint"
              with:
                project_key: "{{project_key}}"
            - name: get-issues
              type: call
              call: "jira-sprint.search-issues"
              with:
                sprint_id: "{{get-sprint.sprint_id}}"
                project_key: "{{project_key}}"
            - name: post-report
              type: call
              call: "msteams-sprint.post-message"
              with:
                channel_id: "$secrets.engineering_channel_id"
                text: "Sprint {{get-sprint.sprint_name}} status: {{get-issues.todo_count}} To Do, {{get-issues.inprogress_count}} In Progress, {{get-issues.done_count}} Done."
  consumes:
    - type: http
      namespace: jira-sprint
      baseUri: "https://nbc.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: sprints
          path: "/project/{{project_key}}/sprints"
          inputParameters:
            - name: project_key
              in: path
          operations:
            - name: get-active-sprint
              method: GET
        - name: issues
          path: "/search"
          operations:
            - name: search-issues
              method: POST
    - type: http
      namespace: msteams-sprint
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

Fetches LinkedIn campaign analytics for show promotions and posts to Slack.

naftiko: "0.5"
info:
  label: "LinkedIn Show Promotion Analytics"
  description: "Fetches LinkedIn campaign analytics for show promotions and posts to Slack."
  tags:
    - marketing
    - social-media
    - linkedin
    - slack
capability:
  exposes:
    - type: mcp
      namespace: social-ops
      port: 8080
      tools:
        - name: post-promotion-analytics
          description: "Fetch LinkedIn analytics and post to Slack."
          inputParameters:
            - name: campaign_id
              in: body
              type: string
              description: "LinkedIn campaign ID."
          steps:
            - name: get-analytics
              type: call
              call: linkedin.get-analytics
              with:
                campaign_id: "{{campaign_id}}"
            - name: post
              type: call
              call: slack.post-message
              with:
                channel: "marketing-social"
                text: "LinkedIn show promo: {{get-analytics.impressions}} impressions, {{get-analytics.clicks}} clicks"
  consumes:
    - type: http
      namespace: linkedin
      baseUri: "https://api.linkedin.com/v2"
      authentication:
        type: bearer
        token: "$secrets.linkedin_token"
      resources:
        - name: analytics
          path: "/adAnalyticsV2"
          operations:
            - name: get-analytics
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Fetches weekly post engagement metrics from the NBC LinkedIn organization page and posts a performance summary to the social media team's Teams channel.

naftiko: "0.5"
info:
  label: "LinkedIn Social Content Performance"
  description: "Fetches weekly post engagement metrics from the NBC LinkedIn organization page and posts a performance summary to the social media team's Teams channel."
  tags:
    - social
    - content
    - linkedin
    - marketing
    - reporting
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: social-reporting
      port: 8080
      tools:
        - name: digest-linkedin-performance
          description: "Given an NBC LinkedIn organization URN and date range, fetch post engagement stats and post a weekly performance digest to the social team Teams channel. Use for weekly social media reviews."
          inputParameters:
            - name: org_urn
              in: body
              type: string
              description: "The LinkedIn organization URN (e.g., urn:li:organization:12345)."
            - name: date_from
              in: body
              type: string
              description: "Start date for the report in YYYY-MM-DD format."
            - name: date_to
              in: body
              type: string
              description: "End date for the report in YYYY-MM-DD format."
          steps:
            - name: get-post-stats
              type: call
              call: "linkedin.get-share-statistics"
              with:
                org_urn: "{{org_urn}}"
                date_from: "{{date_from}}"
                date_to: "{{date_to}}"
            - name: post-digest
              type: call
              call: "msteams-social.post-message"
              with:
                channel_id: "$secrets.social_team_channel_id"
                text: "LinkedIn Weekly Digest ({{date_from}}–{{date_to}}): Impressions={{get-post-stats.impressions}}, Engagement={{get-post-stats.engagement_rate}}"
  consumes:
    - type: http
      namespace: linkedin
      baseUri: "https://api.linkedin.com/v2"
      authentication:
        type: bearer
        token: "$secrets.linkedin_token"
      resources:
        - name: share-statistics
          path: "/organizationalEntityShareStatistics"
          inputParameters:
            - name: org_urn
              in: query
            - name: date_from
              in: query
            - name: date_to
              in: query
          operations:
            - name: get-share-statistics
              method: GET
    - type: http
      namespace: msteams-social
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

Retrieves Meta Ads campaign insights for show promotion campaigns.

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

Retrieves Microsoft 365 license usage data via Microsoft Graph.

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

Creates a Notion page for a new show bible and shares the link via Slack.

naftiko: "0.5"
info:
  label: "Notion Show Bible Creation"
  description: "Creates a Notion page for a new show bible and shares the link via Slack."
  tags:
    - content-production
    - documentation
    - notion
    - slack
capability:
  exposes:
    - type: mcp
      namespace: content-ops
      port: 8080
      tools:
        - name: create-show-bible
          description: "Create a Notion show bible page and share on Slack."
          inputParameters:
            - name: show_name
              in: body
              type: string
              description: "Show name."
            - name: database_id
              in: body
              type: string
              description: "Notion database ID."
          steps:
            - name: create-page
              type: call
              call: notion.create-page
              with:
                parent_database_id: "{{database_id}}"
                title: "{{show_name}} — Show Bible"
            - name: share
              type: call
              call: slack.post-message
              with:
                channel: "production"
                text: "Show bible created: {{show_name}} — {{create-page.url}}"
  consumes:
    - type: http
      namespace: notion
      baseUri: "https://api.notion.com/v1"
      authentication:
        type: bearer
        token: "$secrets.notion_token"
      resources:
        - name: pages
          path: "/pages"
          operations:
            - name: create-page
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

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

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

Queries Okta for users without MFA enrolled in a specified group and creates a ServiceNow compliance task to remediate non-compliant accounts.

naftiko: "0.5"
info:
  label: "Okta MFA Enforcement Check"
  description: "Queries Okta for users without MFA enrolled in a specified group and creates a ServiceNow compliance task to remediate non-compliant accounts."
  tags:
    - identity
    - security
    - compliance
    - okta
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: security-compliance
      port: 8080
      tools:
        - name: check-mfa-compliance
          description: "Given an Okta group ID, identify users without MFA enrolled and create a ServiceNow compliance remediation task. Use for monthly security audits or compliance reporting."
          inputParameters:
            - name: group_id
              in: body
              type: string
              description: "The Okta group ID to audit for MFA compliance."
          steps:
            - name: get-users-without-mfa
              type: call
              call: "okta-mfa.list-users-without-factor"
              with:
                group_id: "{{group_id}}"
            - name: create-compliance-task
              type: call
              call: "servicenow-mfa.create-task"
              with:
                short_description: "MFA compliance remediation for group {{group_id}}"
                category: "security_compliance"
                description: "Users without MFA: {{get-users-without-mfa.count}}"
  consumes:
    - type: http
      namespace: okta-mfa
      baseUri: "https://nbc.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_api_token"
        placement: header
      resources:
        - name: group-users
          path: "/groups/{{group_id}}/users"
          inputParameters:
            - name: group_id
              in: path
          operations:
            - name: list-users-without-factor
              method: GET
    - type: http
      namespace: servicenow-mfa
      baseUri: "https://nbc.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST

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

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

Pulls all active Okta users assigned to a specified application group and cross-references with Workday to flag employees who are no longer active.

naftiko: "0.5"
info:
  label: "Okta User Access Review"
  description: "Pulls all active Okta users assigned to a specified application group and cross-references with Workday to flag employees who are no longer active."
  tags:
    - identity
    - security
    - okta
    - workday
    - access-review
capability:
  exposes:
    - type: mcp
      namespace: identity-review
      port: 8080
      tools:
        - name: run-access-review
          description: "Given an Okta group ID and application name, list all group members and cross-check against active Workday workers to identify stale or orphaned accounts. Use for quarterly access reviews."
          inputParameters:
            - name: group_id
              in: body
              type: string
              description: "The Okta group ID to review."
            - name: app_name
              in: body
              type: string
              description: "The application name for audit context."
          steps:
            - name: get-group-members
              type: call
              call: "okta-review.get-group-members"
              with:
                group_id: "{{group_id}}"
            - name: get-active-workers
              type: call
              call: "workday-review.get-active-workers"
  consumes:
    - type: http
      namespace: okta-review
      baseUri: "https://nbc.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_api_token"
        placement: header
      resources:
        - name: group-members
          path: "/groups/{{group_id}}/users"
          inputParameters:
            - name: group_id
              in: path
          operations:
            - name: get-group-members
              method: GET
    - type: http
      namespace: workday-review
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: active-workers
          path: "/nbc/workers"
          operations:
            - name: get-active-workers
              method: GET

During open enrollment, pulls active employees from Workday and syncs their benefit elections to the ADP benefits module, then confirms enrollment status via Teams notification.

naftiko: "0.5"
info:
  label: "Open Enrollment Benefits Sync"
  description: "During open enrollment, pulls active employees from Workday and syncs their benefit elections to the ADP benefits module, then confirms enrollment status via Teams notification."
  tags:
    - hr
    - benefits
    - open-enrollment
    - workday
    - adp
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: hr-benefits
      port: 8080
      tools:
        - name: sync-benefit-elections
          description: "Given an employee ID and a set of benefit election choices, sync the elections from Workday to ADP and send a Teams confirmation. Use during open enrollment or qualifying life events."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "The Workday worker ID of the enrolling employee."
            - name: benefit_plan_id
              in: body
              type: string
              description: "The ADP benefit plan identifier selected by the employee."
          steps:
            - name: get-employee
              type: call
              call: "workday-ben.get-worker"
              with:
                worker_id: "{{employee_id}}"
            - name: submit-election
              type: call
              call: "adp.update-benefit-election"
              with:
                associate_oid: "{{get-employee.adp_oid}}"
                plan_id: "{{benefit_plan_id}}"
            - name: confirm-enrollment
              type: call
              call: "msteams-ben.send-message"
              with:
                recipient_upn: "{{get-employee.work_email}}"
                text: "Your benefit election for plan {{benefit_plan_id}} has been submitted successfully."
  consumes:
    - type: http
      namespace: workday-ben
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/nbc/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: adp
      baseUri: "https://api.adp.com"
      authentication:
        type: bearer
        token: "$secrets.adp_token"
      resources:
        - name: benefit-elections
          path: "/benefits/v2/workers/{{associate_oid}}/benefit-elections"
          inputParameters:
            - name: associate_oid
              in: path
          operations:
            - name: update-benefit-election
              method: POST
    - type: http
      namespace: msteams-ben
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: chats
          path: "/chats"
          operations:
            - name: send-message
              method: POST

Uses OpenAI to generate searchable metadata tags for a media asset and stores them in Snowflake.

naftiko: "0.5"
info:
  label: "OpenAI Content Metadata Generation"
  description: "Uses OpenAI to generate searchable metadata tags for a media asset and stores them in Snowflake."
  tags:
    - ai
    - content-management
    - openai
    - snowflake
capability:
  exposes:
    - type: mcp
      namespace: content-ai
      port: 8080
      tools:
        - name: generate-metadata
          description: "Given a media asset description, generate metadata tags via OpenAI and store in Snowflake."
          inputParameters:
            - name: asset_id
              in: body
              type: string
              description: "Media asset ID."
            - name: description
              in: body
              type: string
              description: "Asset description."
          steps:
            - name: generate-tags
              type: call
              call: openai.create-completion
              with:
                model: "gpt-4"
                prompt: "Generate 10 searchable metadata tags for this media asset: {{description}}"
            - name: store-tags
              type: call
              call: snowflake.insert-row
              with:
                table: "MEDIA_ASSET_TAGS"
                values:
                  asset_id: "{{asset_id}}"
                  tags: "{{generate-tags.text}}"
  consumes:
    - type: http
      namespace: openai
      baseUri: "https://api.openai.com/v1"
      authentication:
        type: bearer
        token: "$secrets.openai_api_key"
      resources:
        - name: completions
          path: "/chat/completions"
          operations:
            - name: create-completion
              method: POST
    - type: http
      namespace: snowflake
      baseUri: "https://nbc.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: insert-row
              method: POST

Uses OpenAI to generate a marketing synopsis for a show episode and stores it in Salesforce.

naftiko: "0.5"
info:
  label: "OpenAI Show Synopsis Generation"
  description: "Uses OpenAI to generate a marketing synopsis for a show episode and stores it in Salesforce."
  tags:
    - ai
    - content-production
    - openai
    - salesforce
capability:
  exposes:
    - type: mcp
      namespace: content-ai
      port: 8080
      tools:
        - name: generate-synopsis
          description: "Given episode details, generate a synopsis and store in Salesforce."
          inputParameters:
            - name: show_name
              in: body
              type: string
              description: "Show name."
            - name: episode_title
              in: body
              type: string
              description: "Episode title."
            - name: plot_summary
              in: body
              type: string
              description: "Raw plot summary."
          steps:
            - name: generate
              type: call
              call: openai.create-completion
              with:
                model: "gpt-4"
                prompt: "Write a compelling 100-word marketing synopsis for {{show_name}} episode '{{episode_title}}': {{plot_summary}}"
            - name: store
              type: call
              call: salesforce.create-record
              with:
                object: "Episode__c"
                show: "{{show_name}}"
                episode: "{{episode_title}}"
                synopsis: "{{generate.text}}"
  consumes:
    - type: http
      namespace: openai
      baseUri: "https://api.openai.com/v1"
      authentication:
        type: bearer
        token: "$secrets.openai_api_key"
      resources:
        - name: completions
          path: "/chat/completions"
          operations:
            - name: create-completion
              method: POST
    - type: http
      namespace: salesforce
      baseUri: "https://nbc.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: records
          path: "/sobjects/Episode__c"
          operations:
            - name: create-record
              method: POST

Retrieves the current on-call engineer for a PagerDuty schedule.

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

Queries Snowflake for Peacock streaming engagement metrics and posts a daily digest to Slack.

naftiko: "0.5"
info:
  label: "Peacock Streaming Metrics Report"
  description: "Queries Snowflake for Peacock streaming engagement metrics and posts a daily digest to Slack."
  tags:
    - streaming
    - analytics
    - snowflake
    - slack
capability:
  exposes:
    - type: mcp
      namespace: streaming-ops
      port: 8080
      tools:
        - name: post-streaming-digest
          description: "Fetch daily streaming metrics and post to the streaming analytics Slack channel."
          inputParameters:
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel."
          steps:
            - name: fetch-metrics
              type: call
              call: snowflake.execute-statement
              with:
                statement: "SELECT total_streams, unique_viewers, avg_watch_time_min FROM daily_streaming_metrics WHERE date = CURRENT_DATE - 1"
            - name: post-digest
              type: call
              call: slack.post-message
              with:
                channel: "{{slack_channel}}"
                text: "Peacock daily metrics: {{fetch-metrics.data}}"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://nbc.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-statement
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

At the end of each financial period, queries SAP S/4HANA for open journal entries and unposted items, then creates a ServiceNow checklist task for the accounting team.

naftiko: "0.5"
info:
  label: "Period-End Close Checklist"
  description: "At the end of each financial period, queries SAP S/4HANA for open journal entries and unposted items, then creates a ServiceNow checklist task for the accounting team."
  tags:
    - finance
    - period-close
    - sap
    - servicenow
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: finance-close
      port: 8080
      tools:
        - name: run-period-close-checklist
          description: "Given a fiscal period and year, query SAP for open items and unposted journals, then generate a ServiceNow period-close checklist task. Use at month-end or quarter-end to support the accounting team."
          inputParameters:
            - name: fiscal_period
              in: body
              type: string
              description: "The fiscal period number (e.g., '006' for June)."
            - name: fiscal_year
              in: body
              type: string
              description: "The fiscal year (e.g., '2026')."
          steps:
            - name: get-open-items
              type: call
              call: "sap-close.get-open-items"
              with:
                period: "{{fiscal_period}}"
                year: "{{fiscal_year}}"
            - name: create-checklist
              type: call
              call: "servicenow-close.create-task"
              with:
                short_description: "Period close checklist FY{{fiscal_year}}/P{{fiscal_period}}"
                description: "Open items count: {{get-open-items.count}}. Review and clear all items before period close."
                category: "finance_close"
  consumes:
    - type: http
      namespace: sap-close
      baseUri: "https://nbc-s4.sap.com/sap/opu/odata/sap/API_JOURNALENTRYITEMBASIC_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: journal-entries
          path: "/A_JournalEntryItem"
          inputParameters:
            - name: period
              in: query
            - name: year
              in: query
          operations:
            - name: get-open-items
              method: GET
    - type: http
      namespace: servicenow-close
      baseUri: "https://nbc.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST

Retrieves latest Postman API monitor run results.

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

Triggers a dataset refresh in Power BI after a Snowflake data load completes and notifies the business intelligence team in Teams upon completion or failure.

naftiko: "0.5"
info:
  label: "Power BI Report Refresh Trigger"
  description: "Triggers a dataset refresh in Power BI after a Snowflake data load completes and notifies the business intelligence team in Teams upon completion or failure."
  tags:
    - data
    - analytics
    - power-bi
    - snowflake
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: bi-reporting
      port: 8080
      tools:
        - name: trigger-report-refresh
          description: "Given a Power BI dataset ID and workspace ID, trigger a dataset refresh and post completion status to the BI team Teams channel. Use after Snowflake data loads complete."
          inputParameters:
            - name: dataset_id
              in: body
              type: string
              description: "The Power BI dataset ID to refresh."
            - name: workspace_id
              in: body
              type: string
              description: "The Power BI workspace (group) ID containing the dataset."
          steps:
            - name: refresh-dataset
              type: call
              call: "powerbi.trigger-refresh"
              with:
                workspace_id: "{{workspace_id}}"
                dataset_id: "{{dataset_id}}"
            - name: notify-bi-team
              type: call
              call: "msteams-bi.post-message"
              with:
                channel_id: "$secrets.bi_team_channel_id"
                text: "Power BI dataset {{dataset_id}} refresh triggered in workspace {{workspace_id}}."
  consumes:
    - type: http
      namespace: powerbi
      baseUri: "https://api.powerbi.com/v1.0/myorg"
      authentication:
        type: bearer
        token: "$secrets.powerbi_token"
      resources:
        - name: dataset-refreshes
          path: "/groups/{{workspace_id}}/datasets/{{dataset_id}}/refreshes"
          inputParameters:
            - name: workspace_id
              in: path
            - name: dataset_id
              in: path
          operations:
            - name: trigger-refresh
              method: POST
    - type: http
      namespace: msteams-bi
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

Pulls account activity, open opportunities, and support case counts from Salesforce to generate an account health scorecard posted to the account team in Teams.

naftiko: "0.5"
info:
  label: "Salesforce Account Health Scorecard"
  description: "Pulls account activity, open opportunities, and support case counts from Salesforce to generate an account health scorecard posted to the account team in Teams."
  tags:
    - sales
    - crm
    - account-management
    - salesforce
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: crm-reporting
      port: 8080
      tools:
        - name: get-account-health
          description: "Given a Salesforce account ID, aggregate open opportunities, recent activity, and open cases into a health scorecard and post to the account team in Teams. Use for quarterly business reviews."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The Salesforce account ID (18-character)."
          steps:
            - name: get-account
              type: call
              call: "salesforce-acct.get-account"
              with:
                account_id: "{{account_id}}"
            - name: get-opportunities
              type: call
              call: "salesforce-opps.search-opportunities"
              with:
                account_id: "{{account_id}}"
            - name: post-scorecard
              type: call
              call: "msteams-crm.post-message"
              with:
                channel_id: "$secrets.sales_channel_id"
                text: "Account Health: {{get-account.name}} | Open Opps: {{get-opportunities.count}} | ACV: {{get-opportunities.total_acv}}"
  consumes:
    - type: http
      namespace: salesforce-acct
      baseUri: "https://nbc.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: accounts
          path: "/sobjects/Account/{{account_id}}"
          inputParameters:
            - name: account_id
              in: path
          operations:
            - name: get-account
              method: GET
    - type: http
      namespace: salesforce-opps
      baseUri: "https://nbc.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: opportunities
          path: "/query"
          operations:
            - name: search-opportunities
              method: GET
    - type: http
      namespace: msteams-crm
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

Queries Salesforce for ad sales pipeline and posts quarterly forecast to Slack.

naftiko: "0.5"
info:
  label: "Salesforce Ad Revenue Forecast"
  description: "Queries Salesforce for ad sales pipeline and posts quarterly forecast to Slack."
  tags:
    - advertising
    - sales
    - salesforce
    - slack
capability:
  exposes:
    - type: mcp
      namespace: ad-sales
      port: 8080
      tools:
        - name: post-revenue-forecast
          description: "Query Salesforce ad pipeline and post forecast to Slack."
          inputParameters:
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel."
          steps:
            - name: query-pipeline
              type: call
              call: salesforce.query
              with:
                q: "SELECT StageName, SUM(Amount) total FROM Opportunity WHERE RecordType.Name = 'Ad Sales' AND CloseDate = THIS_QUARTER GROUP BY StageName"
            - name: post-forecast
              type: call
              call: slack.post-message
              with:
                channel: "{{slack_channel}}"
                text: "Ad revenue forecast: {{query-pipeline.records}}"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://nbc.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: query
          path: "/query"
          operations:
            - name: query
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves an advertising campaign from Salesforce by campaign ID, returning advertiser, budget, and flight dates.

naftiko: "0.5"
info:
  label: "Salesforce Advertiser Campaign Lookup"
  description: "Retrieves an advertising campaign from Salesforce by campaign ID, returning advertiser, budget, and flight dates."
  tags:
    - advertising
    - sales
    - salesforce
capability:
  exposes:
    - type: mcp
      namespace: ad-sales
      port: 8080
      tools:
        - name: get-campaign
          description: "Given a Salesforce campaign ID, return advertiser, budget, and start/end dates."
          inputParameters:
            - name: campaign_id
              in: body
              type: string
              description: "Salesforce campaign ID."
          call: salesforce.get-campaign
          with:
            campaign_id: "{{campaign_id}}"
          outputParameters:
            - name: advertiser
              type: string
              mapping: "$.Account.Name"
            - name: budget
              type: number
              mapping: "$.BudgetedCost"
            - name: start_date
              type: string
              mapping: "$.StartDate"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://nbc.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: campaigns
          path: "/sobjects/Campaign/{{campaign_id}}"
          inputParameters:
            - name: campaign_id
              in: path
          operations:
            - name: get-campaign
              method: GET

Retrieves a Salesforce contact by email for advertiser relationship management.

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

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

naftiko: "0.5"
info:
  label: "Salesforce Lead Enrichment"
  description: "When a new lead is created in Salesforce, enriches it with company and contact data from ZoomInfo and updates the lead record with firmographic details."
  tags:
    - sales
    - crm
    - lead-management
    - salesforce
    - zoominfo
capability:
  exposes:
    - type: mcp
      namespace: crm-enrichment
      port: 8080
      tools:
        - name: enrich-salesforce-lead
          description: "Given a Salesforce lead ID, fetch firmographic enrichment from ZoomInfo and update the lead record with company size, industry, and revenue data. Use when a new lead is created or when lead data is incomplete."
          inputParameters:
            - name: lead_id
              in: body
              type: string
              description: "The Salesforce lead ID to enrich."
          steps:
            - name: get-lead
              type: call
              call: "salesforce-lead.get-lead"
              with:
                lead_id: "{{lead_id}}"
            - name: enrich-data
              type: call
              call: "zoominfo.search-company"
              with:
                company_name: "{{get-lead.company}}"
                email: "{{get-lead.email}}"
            - name: update-lead
              type: call
              call: "salesforce-lead-update.update-lead"
              with:
                lead_id: "{{lead_id}}"
                employees: "{{enrich-data.employee_count}}"
                annual_revenue: "{{enrich-data.revenue}}"
                industry: "{{enrich-data.industry}}"
  consumes:
    - type: http
      namespace: salesforce-lead
      baseUri: "https://nbc.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: leads
          path: "/sobjects/Lead/{{lead_id}}"
          inputParameters:
            - name: lead_id
              in: path
          operations:
            - name: get-lead
              method: GET
    - type: http
      namespace: zoominfo
      baseUri: "https://api.zoominfo.com/search"
      authentication:
        type: bearer
        token: "$secrets.zoominfo_token"
      resources:
        - name: company-search
          path: "/company"
          operations:
            - name: search-company
              method: POST
    - type: http
      namespace: salesforce-lead-update
      baseUri: "https://nbc.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

Queries Salesforce for current quarter ad sales pipeline and posts to Slack.

naftiko: "0.5"
info:
  label: "Salesforce Opportunity Pipeline"
  description: "Queries Salesforce for current quarter ad sales pipeline and posts to Slack."
  tags:
    - sales
    - advertising
    - salesforce
    - slack
capability:
  exposes:
    - type: mcp
      namespace: ad-sales
      port: 8080
      tools:
        - name: post-pipeline
          description: "Query Salesforce pipeline and post to Slack."
          inputParameters:
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel."
          steps:
            - name: query
              type: call
              call: salesforce.query
              with:
                q: "SELECT StageName, SUM(Amount) total FROM Opportunity WHERE CloseDate = THIS_QUARTER GROUP BY StageName"
            - name: post
              type: call
              call: slack.post-message
              with:
                channel: "{{slack_channel}}"
                text: "Pipeline: {{query.records}}"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://nbc.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: query
          path: "/query"
          operations:
            - name: query
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a Salesforce opportunity is marked Closed-Won, creates a corresponding sales order in SAP S/4HANA and updates the opportunity with the SAP order number.

naftiko: "0.5"
info:
  label: "Salesforce Opportunity Sync to SAP"
  description: "When a Salesforce opportunity is marked Closed-Won, creates a corresponding sales order in SAP S/4HANA and updates the opportunity with the SAP order number."
  tags:
    - sales
    - crm
    - erp
    - salesforce
    - sap
capability:
  exposes:
    - type: mcp
      namespace: sales-erp
      port: 8080
      tools:
        - name: sync-opportunity-to-sap
          description: "Given a Salesforce opportunity ID, create a SAP sales order and write the SAP order number back to Salesforce. Invoke when an opportunity moves to Closed-Won status."
          inputParameters:
            - name: opportunity_id
              in: body
              type: string
              description: "The Salesforce opportunity ID (18-character Salesforce ID)."
          steps:
            - name: get-opportunity
              type: call
              call: "salesforce.get-opportunity"
              with:
                opportunity_id: "{{opportunity_id}}"
            - name: create-sales-order
              type: call
              call: "sap-sales.create-sales-order"
              with:
                customer_id: "{{get-opportunity.account_sap_id}}"
                amount: "{{get-opportunity.amount}}"
                currency: "{{get-opportunity.currency_code}}"
            - name: update-opportunity
              type: call
              call: "salesforce-update.update-opportunity"
              with:
                opportunity_id: "{{opportunity_id}}"
                sap_order_number: "{{create-sales-order.order_id}}"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://nbc.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: opportunities
          path: "/sobjects/Opportunity/{{opportunity_id}}"
          inputParameters:
            - name: opportunity_id
              in: path
          operations:
            - name: get-opportunity
              method: GET
    - type: http
      namespace: sap-sales
      baseUri: "https://nbc-s4.sap.com/sap/opu/odata/sap/API_SALES_ORDER_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: sales-orders
          path: "/A_SalesOrder"
          operations:
            - name: create-sales-order
              method: POST
    - type: http
      namespace: salesforce-update
      baseUri: "https://nbc.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: opportunities
          path: "/sobjects/Opportunity/{{opportunity_id}}"
          inputParameters:
            - name: opportunity_id
              in: path
          operations:
            - name: update-opportunity
              method: PATCH

Retrieves a talent or vendor contract from SAP Ariba by contract ID.

naftiko: "0.5"
info:
  label: "SAP Ariba Contract Lookup"
  description: "Retrieves a talent or vendor contract from SAP Ariba by contract ID."
  tags:
    - procurement
    - contracts
    - sap-ariba
capability:
  exposes:
    - type: mcp
      namespace: procurement-ops
      port: 8080
      tools:
        - name: get-contract
          description: "Given an Ariba contract ID, return status and expiry."
          inputParameters:
            - name: contract_id
              in: body
              type: string
              description: "SAP Ariba contract ID."
          call: ariba.get-contract
          with:
            contract_id: "{{contract_id}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.status"
            - name: expiry
              type: string
              mapping: "$.expirationDate"
  consumes:
    - type: http
      namespace: ariba
      baseUri: "https://openapi.ariba.com/api/contract-compliance/v1"
      authentication:
        type: bearer
        token: "$secrets.ariba_token"
      resources:
        - name: contracts
          path: "/contracts/{{contract_id}}"
          inputParameters:
            - name: contract_id
              in: path
          operations:
            - name: get-contract
              method: GET

When a vendor invoice is received in SAP Ariba, checks the matching purchase order status in SAP S/4HANA and routes the invoice for approval or exception handling via ServiceNow.

naftiko: "0.5"
info:
  label: "SAP Invoice Approval Workflow"
  description: "When a vendor invoice is received in SAP Ariba, checks the matching purchase order status in SAP S/4HANA and routes the invoice for approval or exception handling via ServiceNow."
  tags:
    - finance
    - accounts-payable
    - sap
    - sap-ariba
    - servicenow
    - approval
capability:
  exposes:
    - type: mcp
      namespace: finance-ap
      port: 8080
      tools:
        - name: route-invoice-approval
          description: "Given an Ariba invoice ID and PO number, verify PO status in SAP S/4HANA and create a ServiceNow approval task or exception ticket. Use for automated invoice matching and escalation."
          inputParameters:
            - name: invoice_id
              in: body
              type: string
              description: "The SAP Ariba invoice document ID."
            - name: po_number
              in: body
              type: string
              description: "The associated SAP purchase order number."
          steps:
            - name: get-invoice
              type: call
              call: "ariba.get-invoice"
              with:
                invoice_id: "{{invoice_id}}"
            - name: check-po
              type: call
              call: "sap-erp.get-po"
              with:
                po_number: "{{po_number}}"
            - name: create-approval-task
              type: call
              call: "servicenow-ap.create-task"
              with:
                short_description: "Invoice approval: {{invoice_id}} vs PO {{po_number}}"
                category: "accounts_payable"
                po_status: "{{check-po.status}}"
  consumes:
    - type: http
      namespace: ariba
      baseUri: "https://openapi.ariba.com/api/invoice/v1"
      authentication:
        type: bearer
        token: "$secrets.ariba_token"
      resources:
        - name: invoices
          path: "/invoices/{{invoice_id}}"
          inputParameters:
            - name: invoice_id
              in: path
          operations:
            - name: get-invoice
              method: GET
    - type: http
      namespace: sap-erp
      baseUri: "https://nbc-s4.sap.com/sap/opu/odata/sap/MM_PUR_PO_MAINT_V2_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: purchase-orders
          path: "/A_PurchaseOrder('{{po_number}}')"
          inputParameters:
            - name: po_number
              in: path
          operations:
            - name: get-po
              method: GET
    - type: http
      namespace: servicenow-ap
      baseUri: "https://nbc.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST

Retrieves an invoice from SAP by invoice number, returning status, amount, and payment date.

naftiko: "0.5"
info:
  label: "SAP Invoice Status Lookup"
  description: "Retrieves an invoice from SAP by invoice number, returning status, amount, and payment date."
  tags:
    - finance
    - erp
    - sap
capability:
  exposes:
    - type: mcp
      namespace: finance-ops
      port: 8080
      tools:
        - name: get-invoice-status
          description: "Given an invoice number, return status, amount, and payment date."
          inputParameters:
            - name: invoice_number
              in: body
              type: string
              description: "SAP invoice number."
          call: sap.get-invoice
          with:
            invoice: "{{invoice_number}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.d.InvoiceStatus"
            - name: amount
              type: number
              mapping: "$.d.InvoiceAmount"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://nbc-s4.sap.com/sap/opu/odata/sap/API_SUPPLIERINVOICE_PROCESS_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: invoices
          path: "/A_SupplierInvoice('{{invoice}}')"
          inputParameters:
            - name: invoice
              in: path
          operations:
            - name: get-invoice
              method: GET

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

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

Retrieves vendor payment status from SAP.

naftiko: "0.5"
info:
  label: "SAP Vendor Payment Lookup"
  description: "Retrieves vendor payment status from SAP."
  tags:
    - finance
    - erp
    - sap
capability:
  exposes:
    - type: mcp
      namespace: finance-ops
      port: 8080
      tools:
        - name: get-payment-status
          description: "Given a vendor and invoice number, return payment status."
          inputParameters:
            - name: vendor
              in: body
              type: string
              description: "SAP vendor number."
            - name: invoice
              in: body
              type: string
              description: "Invoice number."
          call: sap.get-payment
          with:
            vendor: "{{vendor}}"
            invoice: "{{invoice}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.d.PaymentStatus"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://nbc-s4.sap.com/sap/opu/odata/sap/API_SUPPLIERINVOICE_PROCESS_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: payments
          path: "/A_SupplierInvoice"
          operations:
            - name: get-payment
              method: GET

Retrieves email delivery stats from SendGrid for subscriber newsletters.

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

When a change request is submitted in ServiceNow, notifies approvers via Microsoft Teams and awaits approval or rejection before proceeding with the deployment window.

naftiko: "0.5"
info:
  label: "ServiceNow Change Request Approval"
  description: "When a change request is submitted in ServiceNow, notifies approvers via Microsoft Teams and awaits approval or rejection before proceeding with the deployment window."
  tags:
    - itsm
    - change-management
    - servicenow
    - microsoft-teams
    - approval
capability:
  exposes:
    - type: mcp
      namespace: itsm-change
      port: 8080
      tools:
        - name: submit-change-request
          description: "Given a change description, risk level, and planned start time, create a ServiceNow change request and notify the CAB approvers via Teams. Use before any production deployment or infrastructure change."
          inputParameters:
            - name: change_description
              in: body
              type: string
              description: "Human-readable description of the change."
            - name: risk
              in: body
              type: string
              description: "Change risk level: low, medium, or high."
            - name: planned_start
              in: body
              type: string
              description: "Planned start datetime in ISO 8601 format."
          steps:
            - name: create-change
              type: call
              call: "servicenow-chg.create-change"
              with:
                short_description: "{{change_description}}"
                risk: "{{risk}}"
                start_date: "{{planned_start}}"
            - name: notify-approvers
              type: call
              call: "msteams-chg.post-message"
              with:
                channel_id: "$secrets.cab_channel_id"
                text: "Change Request {{create-change.number}} submitted for approval. Risk: {{risk}}. Planned: {{planned_start}}. Description: {{change_description}}"
  consumes:
    - type: http
      namespace: servicenow-chg
      baseUri: "https://nbc.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: change-requests
          path: "/table/change_request"
          operations:
            - name: create-change
              method: POST
    - type: http
      namespace: msteams-chg
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

Creates a Jira ticket from a P1 ServiceNow incident and notifies Slack.

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

Retrieves a ServiceNow incident by number, returning description, status, and assigned group.

naftiko: "0.5"
info:
  label: "ServiceNow IT Incident Lookup"
  description: "Retrieves a ServiceNow incident by number, returning description, status, and assigned group."
  tags:
    - it-operations
    - support
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: it-ops
      port: 8080
      tools:
        - name: get-incident
          description: "Given an incident number, return description, status, and assignment."
          inputParameters:
            - name: incident_number
              in: body
              type: string
              description: "ServiceNow incident number."
          call: servicenow.get-incident
          with:
            number: "{{incident_number}}"
          outputParameters:
            - name: description
              type: string
              mapping: "$.result.short_description"
            - name: state
              type: string
              mapping: "$.result.state"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://nbc.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: get-incident
              method: GET

When a P1 incident is created in ServiceNow, creates a Datadog event marker, assigns on-call engineers via PagerDuty, and posts an incident bridge link to the IT ops Teams channel.

naftiko: "0.5"
info:
  label: "ServiceNow IT Incident Response"
  description: "When a P1 incident is created in ServiceNow, creates a Datadog event marker, assigns on-call engineers via PagerDuty, and posts an incident bridge link to the IT ops Teams channel."
  tags:
    - itsm
    - incident-response
    - servicenow
    - datadog
    - pagerduty
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: itsm-ops
      port: 8080
      tools:
        - name: handle-p1-incident
          description: "Given a ServiceNow incident number and severity, trigger PagerDuty on-call escalation, create a Datadog event, and notify the IT ops Teams channel. Invoke for all P1 and P2 incidents."
          inputParameters:
            - name: incident_number
              in: body
              type: string
              description: "The ServiceNow incident number (e.g., INC0012345)."
            - name: severity
              in: body
              type: string
              description: "Incident severity: P1 or P2."
            - name: short_description
              in: body
              type: string
              description: "Brief description of the incident."
          steps:
            - name: escalate-oncall
              type: call
              call: "pagerduty.trigger-incident"
              with:
                title: "{{short_description}}"
                severity: "{{severity}}"
                incident_key: "{{incident_number}}"
            - name: create-dd-event
              type: call
              call: "datadog.create-event"
              with:
                title: "Incident {{incident_number}}: {{short_description}}"
                alert_type: "error"
                tags: "severity:{{severity}},source:servicenow"
            - name: notify-it-ops
              type: call
              call: "msteams-it.post-message"
              with:
                channel_id: "$secrets.it_ops_channel_id"
                text: "P1 Incident {{incident_number}}: {{short_description}} | PagerDuty: {{escalate-oncall.incident_url}} | Datadog: {{create-dd-event.event_url}}"
  consumes:
    - type: http
      namespace: pagerduty
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.pagerduty_token"
        placement: header
      resources:
        - name: incidents
          path: "/incidents"
          operations:
            - name: trigger-incident
              method: POST
    - type: http
      namespace: datadog
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: events
          path: "/events"
          operations:
            - name: create-event
              method: POST
    - type: http
      namespace: msteams-it
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

Moves documents older than a specified age from active SharePoint document libraries to an archive site and creates a Jira record of the archival action.

naftiko: "0.5"
info:
  label: "SharePoint Content Archive"
  description: "Moves documents older than a specified age from active SharePoint document libraries to an archive site and creates a Jira record of the archival action."
  tags:
    - content-management
    - sharepoint
    - jira
    - archival
capability:
  exposes:
    - type: mcp
      namespace: content-mgmt
      port: 8080
      tools:
        - name: archive-sharepoint-documents
          description: "Given a SharePoint site ID, library name, and age threshold, move qualifying documents to the archive library and log the action in Jira. Use for automated content lifecycle management."
          inputParameters:
            - name: site_id
              in: body
              type: string
              description: "The SharePoint site ID containing the source library."
            - name: library_name
              in: body
              type: string
              description: "The name of the document library to archive from."
            - name: age_days
              in: body
              type: integer
              description: "Documents older than this number of days will be archived."
          steps:
            - name: move-documents
              type: call
              call: "sharepoint.copy-item"
              with:
                site_id: "{{site_id}}"
                library: "{{library_name}}"
                age_days: "{{age_days}}"
            - name: log-archival
              type: call
              call: "jira-content.create-issue"
              with:
                project_key: "OPS"
                issuetype: "Task"
                summary: "Content archive: {{library_name}} documents >{{age_days}} days"
  consumes:
    - type: http
      namespace: sharepoint
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: drive-items
          path: "/sites/{{site_id}}/drives"
          inputParameters:
            - name: site_id
              in: path
          operations:
            - name: copy-item
              method: POST
    - type: http
      namespace: jira-content
      baseUri: "https://nbc.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST

Searches SharePoint media library for production assets by keyword.

naftiko: "0.5"
info:
  label: "SharePoint Media Library Search"
  description: "Searches SharePoint media library for production assets by keyword."
  tags:
    - media
    - document-management
    - sharepoint
capability:
  exposes:
    - type: mcp
      namespace: media-ops
      port: 8080
      tools:
        - name: search-media-library
          description: "Search SharePoint for media production assets."
          inputParameters:
            - name: keyword
              in: body
              type: string
              description: "Search keyword."
          call: sharepoint.search
          with:
            query: "{{keyword}}"
          outputParameters:
            - name: files
              type: array
              mapping: "$.value"
  consumes:
    - type: http
      namespace: sharepoint
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: search
          path: "/sites/nbc.sharepoint.com/drive/root/search(q='{{query}}')"
          inputParameters:
            - name: query
              in: path
          operations:
            - name: search
              method: GET

Creates a Slack incident channel and posts the incident summary.

naftiko: "0.5"
info:
  label: "Slack Incident Channel Creation"
  description: "Creates a Slack incident channel and posts the incident summary."
  tags:
    - incident-management
    - collaboration
    - slack
    - pagerduty
capability:
  exposes:
    - type: mcp
      namespace: incident-ops
      port: 8080
      tools:
        - name: create-incident-channel
          description: "Create a Slack incident channel with PagerDuty context."
          inputParameters:
            - name: incident_title
              in: body
              type: string
              description: "Incident title."
            - name: pd_incident_id
              in: body
              type: string
              description: "PagerDuty incident ID."
          steps:
            - name: get-pd
              type: call
              call: pagerduty.get-incident
              with:
                incident_id: "{{pd_incident_id}}"
            - name: create-channel
              type: call
              call: slack.create-channel
              with:
                name: "inc-{{incident_title}}"
            - name: post-brief
              type: call
              call: slack.post-message
              with:
                channel: "{{create-channel.id}}"
                text: "Incident: {{get-pd.title}} | PD: {{pd_incident_id}}"
  consumes:
    - type: http
      namespace: pagerduty
      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
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: channels
          path: "/conversations.create"
          operations:
            - name: create-channel
              method: POST
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Posts a show premiere announcement to the marketing Slack channel with viewership goals.

naftiko: "0.5"
info:
  label: "Slack Show Premiere Announcement"
  description: "Posts a show premiere announcement to the marketing Slack channel with viewership goals."
  tags:
    - marketing
    - content-production
    - slack
capability:
  exposes:
    - type: mcp
      namespace: content-ops
      port: 8080
      tools:
        - name: announce-premiere
          description: "Post a premiere announcement to Slack with details."
          inputParameters:
            - name: show_name
              in: body
              type: string
              description: "Show name."
            - name: premiere_date
              in: body
              type: string
              description: "Premiere date."
            - name: viewership_goal
              in: body
              type: string
              description: "Target viewership."
          call: slack.post-message
          with:
            channel: "marketing-content"
            text: "Premiere alert: {{show_name}} — {{premiere_date}} | Viewership goal: {{viewership_goal}}"
          outputParameters:
            - name: message_ts
              type: string
              mapping: "$.ts"
  consumes:
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Queries Snowflake for failed or stalled data pipeline runs and creates a Jira incident ticket, then posts a summary to the data engineering Teams channel.

naftiko: "0.5"
info:
  label: "Snowflake Data Pipeline Health Check"
  description: "Queries Snowflake for failed or stalled data pipeline runs and creates a Jira incident ticket, then posts a summary to the data engineering Teams channel."
  tags:
    - data
    - analytics
    - snowflake
    - jira
    - microsoft-teams
    - monitoring
capability:
  exposes:
    - type: mcp
      namespace: data-ops
      port: 8080
      tools:
        - name: check-pipeline-health
          description: "Query Snowflake task history for failed or stalled tasks within a time window and create a Jira incident if failures are found. Use for automated data pipeline monitoring."
          inputParameters:
            - name: lookback_hours
              in: body
              type: integer
              description: "Number of hours to look back for failed pipeline tasks."
          steps:
            - name: query-failures
              type: call
              call: "snowflake.query-task-history"
              with:
                lookback_hours: "{{lookback_hours}}"
            - name: create-incident
              type: call
              call: "jira-data.create-issue"
              with:
                project_key: "DATA"
                issuetype: "Bug"
                summary: "Snowflake pipeline failures detected in last {{lookback_hours}}h"
            - name: notify-data-team
              type: call
              call: "msteams-data.post-message"
              with:
                channel_id: "$secrets.data_eng_channel_id"
                text: "Pipeline health check: failures detected. Jira: {{create-incident.key}}"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://nbc.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: task-history
          path: "/statements"
          operations:
            - name: query-task-history
              method: POST
    - type: http
      namespace: jira-data
      baseUri: "https://nbc.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: msteams-data
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

Executes a SQL query against the Snowflake viewership analytics warehouse.

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

Queries Snowflake for weekly business KPIs and posts to Slack.

naftiko: "0.5"
info:
  label: "Snowflake Weekly KPI Report"
  description: "Queries Snowflake for weekly business KPIs and posts to Slack."
  tags:
    - analytics
    - reporting
    - snowflake
    - slack
capability:
  exposes:
    - type: mcp
      namespace: analytics-ops
      port: 8080
      tools:
        - name: post-weekly-kpis
          description: "Fetch weekly KPIs and post to Slack."
          inputParameters:
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel."
          steps:
            - name: fetch
              type: call
              call: snowflake.execute-statement
              with:
                statement: "SELECT metric, value FROM weekly_kpis WHERE report_date = CURRENT_DATE"
            - name: post
              type: call
              call: slack.post-message
              with:
                channel: "{{slack_channel}}"
                text: "Weekly KPIs: {{fetch.data}}"
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://nbc.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-statement
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Runs a Splunk saved search for security events and creates a ServiceNow incident.

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

Triggers a Tableau extract refresh for the viewership analytics dashboard and notifies Slack.

naftiko: "0.5"
info:
  label: "Tableau Viewership Dashboard Refresh"
  description: "Triggers a Tableau extract refresh for the viewership analytics dashboard and notifies Slack."
  tags:
    - analytics
    - streaming
    - tableau
    - slack
capability:
  exposes:
    - type: mcp
      namespace: bi-ops
      port: 8080
      tools:
        - name: refresh-viewership-dashboard
          description: "Trigger a Tableau refresh and notify Slack."
          inputParameters:
            - name: workbook_id
              in: body
              type: string
              description: "Tableau workbook ID."
          steps:
            - name: refresh
              type: call
              call: tableau.refresh-workbook
              with:
                workbook_id: "{{workbook_id}}"
            - name: notify
              type: call
              call: slack.post-message
              with:
                channel: "analytics"
                text: "Viewership dashboard refresh triggered. Job: {{refresh.job.id}}"
  consumes:
    - type: http
      namespace: tableau
      baseUri: "https://tableau.nbc.com/api/3.21"
      authentication:
        type: bearer
        token: "$secrets.tableau_token"
      resources:
        - name: workbooks
          path: "/sites/{{site_id}}/workbooks/{{workbook_id}}/refresh"
          inputParameters:
            - name: workbook_id
              in: path
          operations:
            - name: refresh-workbook
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Creates a new Terraform Cloud workspace for a project team, links it to the GitHub repository, and notifies the requesting team in Microsoft Teams.

naftiko: "0.5"
info:
  label: "Terraform Cloud Workspace Provisioner"
  description: "Creates a new Terraform Cloud workspace for a project team, links it to the GitHub repository, and notifies the requesting team in Microsoft Teams."
  tags:
    - cloud
    - infrastructure
    - terraform
    - github
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: infra-provisioning
      port: 8080
      tools:
        - name: provision-terraform-workspace
          description: "Given a project name, GitHub repository, and Terraform organization, create a new Terraform Cloud workspace linked to the repo and notify the requesting team in Teams. Use for new project infrastructure onboarding."
          inputParameters:
            - name: workspace_name
              in: body
              type: string
              description: "Name of the new Terraform Cloud workspace."
            - name: github_repo
              in: body
              type: string
              description: "GitHub repository in owner/repo format to link to the workspace."
            - name: tf_organization
              in: body
              type: string
              description: "Terraform Cloud organization name."
            - name: requester_upn
              in: body
              type: string
              description: "UPN of the engineer requesting the workspace."
          steps:
            - name: create-workspace
              type: call
              call: "terraform.create-workspace"
              with:
                name: "{{workspace_name}}"
                organization: "{{tf_organization}}"
                github_repo: "{{github_repo}}"
            - name: notify-requester
              type: call
              call: "msteams-tf.send-message"
              with:
                recipient_upn: "{{requester_upn}}"
                text: "Terraform workspace '{{workspace_name}}' has been provisioned and linked to {{github_repo}}."
  consumes:
    - type: http
      namespace: terraform
      baseUri: "https://app.terraform.io/api/v2"
      authentication:
        type: bearer
        token: "$secrets.terraform_token"
      resources:
        - name: workspaces
          path: "/organizations/{{organization}}/workspaces"
          inputParameters:
            - name: organization
              in: path
          operations:
            - name: create-workspace
              method: POST
    - type: http
      namespace: msteams-tf
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: chats
          path: "/chats"
          operations:
            - name: send-message
              method: POST

Sends a WhatsApp template message to viewers for show alerts.

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

Retrieves PTO and sick leave balances from Workday.

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

Queries Workday for employees with incomplete enrollment and sends reminders via Slack.

naftiko: "0.5"
info:
  label: "Workday Benefits Enrollment Reminder"
  description: "Queries Workday for employees with incomplete enrollment and sends reminders via Slack."
  tags:
    - hr
    - benefits
    - workday
    - slack
capability:
  exposes:
    - type: mcp
      namespace: hr-ops
      port: 8080
      tools:
        - name: send-enrollment-reminders
          description: "Fetch pending enrollment and notify via Slack."
          inputParameters:
            - name: enrollment_period
              in: body
              type: string
              description: "Enrollment period."
          steps:
            - name: get-pending
              type: call
              call: workday.get-pending-enrollment
              with:
                period: "{{enrollment_period}}"
            - name: notify
              type: call
              call: slack.post-message
              with:
                channel: "hr-benefits"
                text: "{{get-pending.count}} employees pending enrollment for {{enrollment_period}}"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd5-impl-services1.workday.com/ccx/service/nbc"
      authentication:
        type: basic
        username: "$secrets.workday_user"
        password: "$secrets.workday_password"
      resources:
        - name: benefits
          path: "/Benefits/v40.0"
          operations:
            - name: get-pending-enrollment
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a compensation change is approved, notifies HR via Slack.

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

When an employee termination is recorded in Workday, disables their Microsoft 365 account, revokes Okta access, closes open ServiceNow tickets, and notifies their manager via Teams.

naftiko: "0.5"
info:
  label: "Workday Employee Offboarding"
  description: "When an employee termination is recorded in Workday, disables their Microsoft 365 account, revokes Okta access, closes open ServiceNow tickets, and notifies their manager via Teams."
  tags:
    - hr
    - offboarding
    - workday
    - okta
    - microsoft-365
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: hr-offboarding
      port: 8080
      tools:
        - name: trigger-offboarding
          description: "Given a Workday employee ID and termination date, disable the Microsoft 365 account, deprovision Okta, close ServiceNow tickets, and alert the manager in Teams. Invoke when HR confirms a termination in Workday."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "The Workday worker ID of the departing employee."
            - name: termination_date
              in: body
              type: string
              description: "The employee's last day in YYYY-MM-DD format."
          steps:
            - name: get-employee
              type: call
              call: "workday-lookup.get-worker"
              with:
                worker_id: "{{employee_id}}"
            - name: disable-m365
              type: call
              call: "msgraph-offboard.disable-user"
              with:
                user_upn: "{{get-employee.work_email}}"
            - name: deprovision-okta
              type: call
              call: "okta.deactivate-user"
              with:
                login: "{{get-employee.work_email}}"
            - name: notify-manager
              type: call
              call: "msteams-notify.send-message"
              with:
                recipient_upn: "{{get-employee.manager_email}}"
                text: "Offboarding initiated for {{get-employee.full_name}} (last day: {{termination_date}}). IT access has been revoked."
  consumes:
    - type: http
      namespace: workday-lookup
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/nbc/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: msgraph-offboard
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: users
          path: "/users/{{user_upn}}"
          inputParameters:
            - name: user_upn
              in: path
          operations:
            - name: disable-user
              method: PATCH
    - type: http
      namespace: okta
      baseUri: "https://nbc.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_api_token"
        placement: header
      resources:
        - name: users
          path: "/users/{{login}}/lifecycle/deactivate"
          inputParameters:
            - name: login
              in: path
          operations:
            - name: deactivate-user
              method: POST
    - type: http
      namespace: msteams-notify
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: chats
          path: "/chats"
          operations:
            - name: send-message
              method: POST

Returns current NBC headcount by department and cost center from Workday, used for workforce planning and finance reporting.

naftiko: "0.5"
info:
  label: "Workday Headcount Snapshot"
  description: "Returns current NBC headcount by department and cost center from Workday, used for workforce planning and finance reporting."
  tags:
    - hr
    - workforce-planning
    - reporting
    - workday
capability:
  exposes:
    - type: mcp
      namespace: hr-reporting
      port: 8080
      tools:
        - name: get-headcount-by-department
          description: "Returns headcount grouped by department and cost center from Workday. Use for workforce planning, budget alignment, and executive reporting."
          call: "workday-hc.get-headcount"
          outputParameters:
            - name: employees
              type: array
              mapping: "$.data[*]"
  consumes:
    - type: http
      namespace: workday-hc
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: headcount
          path: "/nbc/workers"
          operations:
            - name: get-headcount
              method: GET

When a new job requisition is approved in Workday, creates a corresponding LinkedIn job posting and notifies the talent acquisition team in Teams.

naftiko: "0.5"
info:
  label: "Workday Job Requisition Publisher"
  description: "When a new job requisition is approved in Workday, creates a corresponding LinkedIn job posting and notifies the talent acquisition team in Teams."
  tags:
    - hr
    - recruiting
    - workday
    - linkedin
    - talent-acquisition
capability:
  exposes:
    - type: mcp
      namespace: talent-acquisition
      port: 8080
      tools:
        - name: publish-job-requisition
          description: "Given a Workday job requisition ID, fetch job details and publish the posting to LinkedIn, then notify the talent acquisition Teams channel. Use when a new requisition is approved in Workday."
          inputParameters:
            - name: requisition_id
              in: body
              type: string
              description: "The Workday job requisition ID."
          steps:
            - name: get-requisition
              type: call
              call: "workday-rec.get-job-requisition"
              with:
                req_id: "{{requisition_id}}"
            - name: post-to-linkedin
              type: call
              call: "linkedin-jobs.create-job-posting"
              with:
                title: "{{get-requisition.job_title}}"
                description: "{{get-requisition.description}}"
                location: "{{get-requisition.location}}"
                company_urn: "$secrets.nbc_linkedin_org_urn"
            - name: notify-ta-team
              type: call
              call: "msteams-ta.post-message"
              with:
                channel_id: "$secrets.ta_channel_id"
                text: "New job posted: {{get-requisition.job_title}} | LinkedIn posting: {{post-to-linkedin.job_url}}"
  consumes:
    - type: http
      namespace: workday-rec
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: job-requisitions
          path: "/nbc/jobRequisitions/{{req_id}}"
          inputParameters:
            - name: req_id
              in: path
          operations:
            - name: get-job-requisition
              method: GET
    - type: http
      namespace: linkedin-jobs
      baseUri: "https://api.linkedin.com/v2"
      authentication:
        type: bearer
        token: "$secrets.linkedin_token"
      resources:
        - name: job-postings
          path: "/jobPostings"
          operations:
            - name: create-job-posting
              method: POST
    - type: http
      namespace: msteams-ta
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-message
              method: POST

When a new hire is created in Workday, opens a ServiceNow onboarding ticket, provisions a Microsoft 365 account, and sends a Teams welcome message to the new employee and their manager.

naftiko: "0.5"
info:
  label: "Workday New Hire Onboarding Orchestrator"
  description: "When a new hire is created in Workday, opens a ServiceNow onboarding ticket, provisions a Microsoft 365 account, and sends a Teams welcome message to the new employee and their manager."
  tags:
    - hr
    - onboarding
    - workday
    - servicenow
    - microsoft-teams
    - microsoft-365
capability:
  exposes:
    - type: mcp
      namespace: hr-onboarding
      port: 8080
      tools:
        - name: trigger-onboarding
          description: "Given a Workday employee ID and start date, orchestrate the full onboarding sequence across ServiceNow, Microsoft 365, and Microsoft Teams. Invoke when a new hire record is created or when onboarding needs to be re-triggered."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "The Workday worker ID for the new hire."
            - name: start_date
              in: body
              type: string
              description: "The employee's start date in YYYY-MM-DD format."
          steps:
            - name: get-employee
              type: call
              call: "workday.get-worker"
              with:
                worker_id: "{{employee_id}}"
            - name: open-ticket
              type: call
              call: "servicenow.create-incident"
              with:
                short_description: "New hire onboarding: {{get-employee.full_name}}"
                category: "hr_onboarding"
                assigned_to: "IT_Onboarding_Team"
            - name: provision-account
              type: call
              call: "msgraph.create-user"
              with:
                display_name: "{{get-employee.full_name}}"
                mail_nickname: "{{get-employee.user_principal_name}}"
                department: "{{get-employee.department}}"
            - name: send-welcome
              type: call
              call: "msteams.send-message"
              with:
                recipient_upn: "{{get-employee.work_email}}"
                text: "Welcome to NBC, {{get-employee.first_name}}! Your onboarding ticket is {{open-ticket.number}}."
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/nbc/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://nbc.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msgraph
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: users
          path: "/users"
          operations:
            - name: create-user
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: chats
          path: "/chats"
          operations:
            - name: send-message
              method: POST

Creates a position requisition in Workday and notifies recruiting via Slack.

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

Retrieves manager and direct reports for a Workday employee.

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

At the start of performance review season, queries Workday for eligible employees and creates review tasks in ServiceNow for each manager to complete.

naftiko: "0.5"
info:
  label: "Workday Performance Review Initiator"
  description: "At the start of performance review season, queries Workday for eligible employees and creates review tasks in ServiceNow for each manager to complete."
  tags:
    - hr
    - performance-management
    - workday
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: hr-performance
      port: 8080
      tools:
        - name: initiate-performance-reviews
          description: "Given a review cycle name and department, fetch eligible employees from Workday and create individual performance review tasks in ServiceNow for their managers. Use at the start of each review cycle."
          inputParameters:
            - name: review_cycle
              in: body
              type: string
              description: "Name of the performance review cycle (e.g., 2026-H1)."
            - name: department
              in: body
              type: string
              description: "Department name to scope the review initiation."
          steps:
            - name: get-eligible-employees
              type: call
              call: "workday-perf.get-workers-by-department"
              with:
                department: "{{department}}"
            - name: create-review-tasks
              type: call
              call: "servicenow-perf.create-task"
              with:
                short_description: "Performance review {{review_cycle}} for {{department}}"
                category: "hr_performance"
  consumes:
    - type: http
      namespace: workday-perf
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers-by-department
          path: "/nbc/workers"
          inputParameters:
            - name: department
              in: query
          operations:
            - name: get-workers-by-department
              method: GET
    - type: http
      namespace: servicenow-perf
      baseUri: "https://nbc.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: tasks
          path: "/table/sc_task"
          operations:
            - name: create-task
              method: POST

When an employee's role changes in Workday, updates their Okta group memberships to match the new role's access profile and creates a ServiceNow change record.

naftiko: "0.5"
info:
  label: "Workday Role Change Access Sync"
  description: "When an employee's role changes in Workday, updates their Okta group memberships to match the new role's access profile and creates a ServiceNow change record."
  tags:
    - hr
    - identity
    - role-change
    - workday
    - okta
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: hr-identity
      port: 8080
      tools:
        - name: sync-role-change-access
          description: "Given a Workday employee ID and new role, update Okta group memberships to align with the new role's access profile and log the change in ServiceNow. Invoke when an employee's position or department changes in Workday."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "The Workday worker ID of the employee whose role changed."
            - name: new_role
              in: body
              type: string
              description: "The new job title or role name."
            - name: new_department
              in: body
              type: string
              description: "The new department the employee is moving to."
          steps:
            - name: get-employee
              type: call
              call: "workday-role.get-worker"
              with:
                worker_id: "{{employee_id}}"
            - name: update-okta-groups
              type: call
              call: "okta-role.update-user-groups"
              with:
                login: "{{get-employee.work_email}}"
                department: "{{new_department}}"
                role: "{{new_role}}"
            - name: log-change
              type: call
              call: "servicenow-role.create-change"
              with:
                short_description: "Role change: {{get-employee.full_name}} → {{new_role}} in {{new_department}}"
                category: "hr_role_change"
  consumes:
    - type: http
      namespace: workday-role
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/nbc/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: okta-role
      baseUri: "https://nbc.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_api_token"
        placement: header
      resources:
        - name: user-groups
          path: "/users/{{login}}/groups"
          inputParameters:
            - name: login
              in: path
          operations:
            - name: update-user-groups
              method: PUT
    - type: http
      namespace: servicenow-role
      baseUri: "https://nbc.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: change-requests
          path: "/table/change_request"
          operations:
            - name: create-change
              method: POST

Retrieves a Zendesk viewer support ticket by ID.

naftiko: "0.5"
info:
  label: "Zendesk Viewer Support Lookup"
  description: "Retrieves a Zendesk viewer support ticket by ID."
  tags:
    - support
    - customer-service
    - zendesk
capability:
  exposes:
    - type: mcp
      namespace: support-ops
      port: 8080
      tools:
        - name: get-viewer-ticket
          description: "Given a ticket ID, return subject, status, and priority."
          inputParameters:
            - name: ticket_id
              in: body
              type: string
              description: "Zendesk ticket ID."
          call: zendesk.get-ticket
          with:
            ticket_id: "{{ticket_id}}"
          outputParameters:
            - name: subject
              type: string
              mapping: "$.ticket.subject"
            - name: status
              type: string
              mapping: "$.ticket.status"
  consumes:
    - type: http
      namespace: zendesk
      baseUri: "https://nbc.zendesk.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.zendesk_token"
      resources:
        - name: tickets
          path: "/tickets/{{ticket_id}}.json"
          inputParameters:
            - name: ticket_id
              in: path
          operations:
            - name: get-ticket
              method: GET

Schedules a Zoom meeting for an NBC production crew, creates a SharePoint folder for the production, and sends invites via Microsoft 365 calendar.

naftiko: "0.5"
info:
  label: "Zoom Meeting Scheduler for Production Crews"
  description: "Schedules a Zoom meeting for an NBC production crew, creates a SharePoint folder for the production, and sends invites via Microsoft 365 calendar."
  tags:
    - communication
    - production
    - zoom
    - sharepoint
    - microsoft-365
capability:
  exposes:
    - type: mcp
      namespace: production-ops
      port: 8080
      tools:
        - name: schedule-production-meeting
          description: "Given a production name, attendee list, and meeting datetime, schedule a Zoom meeting, create a SharePoint production folder, and send calendar invites. Use for coordinating production crews and pre-production planning."
          inputParameters:
            - name: production_name
              in: body
              type: string
              description: "Name of the production or show."
            - name: meeting_start
              in: body
              type: string
              description: "Meeting start time in ISO 8601 format."
            - name: duration_minutes
              in: body
              type: integer
              description: "Duration of the meeting in minutes."
            - name: attendee_emails
              in: body
              type: string
              description: "Comma-separated list of attendee email addresses."
          steps:
            - name: create-zoom-meeting
              type: call
              call: "zoom.create-meeting"
              with:
                topic: "Production Kick-off: {{production_name}}"
                start_time: "{{meeting_start}}"
                duration: "{{duration_minutes}}"
            - name: create-sp-folder
              type: call
              call: "sharepoint-prod.create-folder"
              with:
                site_id: "$secrets.productions_site_id"
                folder_name: "{{production_name}}"
            - name: send-invite
              type: call
              call: "msgraph-cal.create-event"
              with:
                subject: "Production: {{production_name}}"
                start: "{{meeting_start}}"
                join_url: "{{create-zoom-meeting.join_url}}"
  consumes:
    - type: http
      namespace: zoom
      baseUri: "https://api.zoom.us/v2"
      authentication:
        type: bearer
        token: "$secrets.zoom_token"
      resources:
        - name: meetings
          path: "/users/me/meetings"
          operations:
            - name: create-meeting
              method: POST
    - type: http
      namespace: sharepoint-prod
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: folders
          path: "/sites/{{site_id}}/drive/root/children"
          inputParameters:
            - name: site_id
              in: path
          operations:
            - name: create-folder
              method: POST
    - type: http
      namespace: msgraph-cal
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: events
          path: "/me/events"
          operations:
            - name: create-event
              method: POST

Creates a Zoom meeting for production crews and shares the link via Slack.

naftiko: "0.5"
info:
  label: "Zoom Production Meeting Scheduler"
  description: "Creates a Zoom meeting for production crews and shares the link via Slack."
  tags:
    - collaboration
    - content-production
    - zoom
    - slack
capability:
  exposes:
    - type: mcp
      namespace: production-ops
      port: 8080
      tools:
        - name: schedule-production-meeting
          description: "Create a Zoom meeting and share on Slack."
          inputParameters:
            - name: topic
              in: body
              type: string
              description: "Meeting topic."
            - name: duration
              in: body
              type: integer
              description: "Duration in minutes."
            - name: slack_channel
              in: body
              type: string
              description: "Slack channel."
          steps:
            - name: create-meeting
              type: call
              call: zoom.create-meeting
              with:
                topic: "{{topic}}"
                duration: "{{duration}}"
            - name: share-link
              type: call
              call: slack.post-message
              with:
                channel: "{{slack_channel}}"
                text: "Production meeting: {{topic}} — {{create-meeting.join_url}}"
  consumes:
    - type: http
      namespace: zoom
      baseUri: "https://api.zoom.us/v2"
      authentication:
        type: bearer
        token: "$secrets.zoom_token"
      resources:
        - name: meetings
          path: "/users/me/meetings"
          operations:
            - name: create-meeting
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST