Bloomberg Capabilities

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

Sort
Expand

Given a batch of Bloomberg news articles, uses the Anthropic API to generate concise executive summaries and stores the results in Snowflake for downstream analytics.

naftiko: "0.5"
info:
  label: "AI-Assisted News Article Summarizer"
  description: "Given a batch of Bloomberg news articles, uses the Anthropic API to generate concise executive summaries and stores the results in Snowflake for downstream analytics."
  tags:
    - ai
    - automation
    - anthropic
    - snowflake
    - content
    - analytics
capability:
  exposes:
    - type: mcp
      namespace: ai-content
      port: 8080
      tools:
        - name: summarize-articles
          description: "Given a list of article IDs and a target Snowflake table, retrieve article content, generate executive summaries via Anthropic Claude, and store results in Snowflake. Use for automated editorial summarization pipelines."
          inputParameters:
            - name: article_ids
              in: body
              type: string
              description: "Comma-separated list of Bloomberg article IDs to summarize."
            - name: snowflake_table
              in: body
              type: string
              description: "The fully-qualified Snowflake table name for storing summaries, e.g. 'BLOOMBERG.CONTENT.ARTICLE_SUMMARIES'."
          steps:
            - name: generate-summary
              type: call
              call: "anthropic.create-message"
              with:
                model: "claude-opus-4-5"
                max_tokens: 1024
                system: "You are a financial news summarizer. Provide concise executive summaries."
                content: "Summarize the following Bloomberg articles: {{article_ids}}"
            - name: store-results
              type: call
              call: "snowflake.insert-rows"
              with:
                table: "{{snowflake_table}}"
                data: "{{generate-summary.content}}"
  consumes:
    - type: http
      namespace: anthropic
      baseUri: "https://api.anthropic.com/v1"
      authentication:
        type: apikey
        key: "x-api-key"
        value: "$secrets.anthropic_api_key"
        placement: header
      resources:
        - name: messages
          path: "/messages"
          operations:
            - name: create-message
              method: POST
    - type: http
      namespace: snowflake
      baseUri: "https://bloomberg.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: rows
          path: "/databases/bloomberg/schemas/content/tables/{{table}}/insertRows"
          inputParameters:
            - name: table
              in: path
          operations:
            - name: insert-rows
              method: POST

When an AWS budget threshold is breached, captures cost breakdown, creates a Jira cost investigation ticket, and alerts the cloud operations team on Slack.

naftiko: "0.5"
info:
  label: "AWS Cost Budget Breach Handler"
  description: "When an AWS budget threshold is breached, captures cost breakdown, creates a Jira cost investigation ticket, and alerts the cloud operations team on Slack."
  tags:
    - cloud
    - aws
    - jira
    - slack
    - cost-management
capability:
  exposes:
    - type: mcp
      namespace: cloud-cost-ops
      port: 8080
      tools:
        - name: handle-budget-breach
          description: "Given an AWS budget breach event, create a Jira investigation ticket and alert cloud ops on Slack."
          inputParameters:
            - name: budget_name
              in: body
              type: string
              description: "The AWS budget name that was breached."
            - name: actual_spend
              in: body
              type: string
              description: "The actual spend amount."
            - name: budget_limit
              in: body
              type: string
              description: "The budget limit."
          steps:
            - name: create-ticket
              type: call
              call: "jira-cloud.create-issue"
              with:
                project: "CLOUD"
                summary: "AWS budget breach: {{budget_name}} ({{actual_spend}}/{{budget_limit}})"
                description: "Budget {{budget_name}} exceeded. Actual: {{actual_spend}}, Limit: {{budget_limit}}."
                priority: "High"
            - name: alert-team
              type: call
              call: "slack-cloud.post-message"
              with:
                channel: "cloud-operations"
                text: "AWS BUDGET BREACH: {{budget_name}} at {{actual_spend}} (limit: {{budget_limit}}). Jira: {{create-ticket.key}}"
  consumes:
    - type: http
      namespace: jira-cloud
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-cloud
      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 storage size and object count metrics for an S3 bucket used by Bloomberg data pipelines.

naftiko: "0.5"
info:
  label: "AWS S3 Bucket Storage Metrics"
  description: "Retrieves storage size and object count metrics for an S3 bucket used by Bloomberg data pipelines."
  tags:
    - cloud
    - aws
    - storage
    - cost-management
capability:
  exposes:
    - type: mcp
      namespace: cloud-storage
      port: 8080
      tools:
        - name: get-bucket-metrics
          description: "Given an S3 bucket name, return its total storage size and object count. Use for cloud cost monitoring."
          inputParameters:
            - name: bucket_name
              in: body
              type: string
              description: "The AWS S3 bucket name."
          call: "aws-s3.get-bucket-size"
          with:
            bucket: "{{bucket_name}}"
          outputParameters:
            - name: size_gb
              type: number
              mapping: "$.Datapoints[0].Average"
            - name: object_count
              type: integer
              mapping: "$.ObjectCount"
  consumes:
    - type: http
      namespace: aws-s3
      baseUri: "https://monitoring.us-east-1.amazonaws.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.aws_cloudwatch_key"
        placement: header
      resources:
        - name: metrics
          path: "/"
          operations:
            - name: get-bucket-size
              method: POST

Checks Bloomberg AIM for unreconciled trades, creates ServiceNow tickets for discrepancies, and alerts the operations team on Slack.

naftiko: "0.5"
info:
  label: "Bloomberg AIM Trade Reconciliation Monitor"
  description: "Checks Bloomberg AIM for unreconciled trades, creates ServiceNow tickets for discrepancies, and alerts the operations team on Slack."
  tags:
    - trading
    - bloomberg-aim
    - servicenow
    - slack
    - reconciliation
capability:
  exposes:
    - type: mcp
      namespace: trade-recon
      port: 8080
      tools:
        - name: monitor-trade-reconciliation
          description: "Given a date, check Bloomberg AIM for unreconciled trades, create ServiceNow tickets, and alert operations."
          inputParameters:
            - name: trade_date
              in: body
              type: string
              description: "The trade date to reconcile in YYYY-MM-DD format."
          steps:
            - name: get-unreconciled
              type: call
              call: "bbg-aim.get-unreconciled-trades"
              with:
                date: "{{trade_date}}"
            - name: create-ticket
              type: call
              call: "snow-recon.create-incident"
              with:
                short_description: "Unreconciled trades: {{trade_date}} ({{get-unreconciled.count}} items)"
                description: "{{get-unreconciled.count}} trades unreconciled for {{trade_date}}. Details: {{get-unreconciled.summary}}"
                category: "trade_operations"
            - name: alert-ops
              type: call
              call: "slack-recon.post-message"
              with:
                channel: "trade-operations"
                text: "Trade Reconciliation Alert: {{get-unreconciled.count}} unreconciled trades for {{trade_date}}. SNOW: {{create-ticket.number}}"
  consumes:
    - type: http
      namespace: bbg-aim
      baseUri: "https://api.bloomberg.com/aim/v1"
      authentication:
        type: bearer
        token: "$secrets.bloomberg_aim_token"
      resources:
        - name: trades
          path: "/reconciliation/unmatched"
          operations:
            - name: get-unreconciled-trades
              method: GET
    - type: http
      namespace: snow-recon
      baseUri: "https://bloomberg.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: slack-recon
      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

Rotates Bloomberg API keys in HashiCorp Vault, updates the key in the Bloomberg API gateway, verifies connectivity, and notifies the platform team on Slack.

naftiko: "0.5"
info:
  label: "Bloomberg API Key Rotation Orchestrator"
  description: "Rotates Bloomberg API keys in HashiCorp Vault, updates the key in the Bloomberg API gateway, verifies connectivity, and notifies the platform team on Slack."
  tags:
    - security
    - hashicorp-vault
    - bloomberg-apis
    - slack
    - key-management
capability:
  exposes:
    - type: mcp
      namespace: key-rotation
      port: 8080
      tools:
        - name: rotate-api-key
          description: "Given a Bloomberg API key name, rotate it in Vault, update the gateway, and notify the platform team."
          inputParameters:
            - name: key_name
              in: body
              type: string
              description: "The Bloomberg API key identifier to rotate."
            - name: environment
              in: body
              type: string
              description: "Target environment: production, staging, or development."
          steps:
            - name: rotate-vault-secret
              type: call
              call: "vault-rotate.update-secret"
              with:
                path: "secret/bloomberg/api-keys/{{key_name}}"
                environment: "{{environment}}"
            - name: update-gateway
              type: call
              call: "bbg-gateway.update-key"
              with:
                key_name: "{{key_name}}"
                new_key: "{{rotate-vault-secret.new_key}}"
            - name: notify-platform
              type: call
              call: "slack-platform.post-message"
              with:
                channel: "platform-engineering"
                text: "API key rotated: {{key_name}} in {{environment}}. Vault updated. Gateway verified."
  consumes:
    - type: http
      namespace: vault-rotate
      baseUri: "https://vault.bloomberg.com/v1"
      authentication:
        type: bearer
        token: "$secrets.vault_token"
      resources:
        - name: secrets
          path: "/{{path}}"
          inputParameters:
            - name: path
              in: path
          operations:
            - name: update-secret
              method: PUT
    - type: http
      namespace: bbg-gateway
      baseUri: "https://api.bloomberg.com/gateway/v1"
      authentication:
        type: bearer
        token: "$secrets.bloomberg_gateway_token"
      resources:
        - name: keys
          path: "/keys/{{key_name}}"
          inputParameters:
            - name: key_name
              in: path
          operations:
            - name: update-key
              method: PUT
    - type: http
      namespace: slack-platform
      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

Executes a Bloomberg Query Language (BQL) query against Bloomberg Data and returns structured financial data results.

naftiko: "0.5"
info:
  label: "Bloomberg BQL Query Executor"
  description: "Executes a Bloomberg Query Language (BQL) query against Bloomberg Data and returns structured financial data results."
  tags:
    - financial-data
    - bloomberg-data
    - bql
    - analytics
capability:
  exposes:
    - type: mcp
      namespace: bql-ops
      port: 8080
      tools:
        - name: execute-bql-query
          description: "Given a BQL query string, execute it against Bloomberg Data and return results. Use for programmatic financial data retrieval."
          inputParameters:
            - name: bql_expression
              in: body
              type: string
              description: "The BQL query expression, e.g. 'get(px_last) for(['AAPL US Equity'])'."
          call: "bloomberg-bql.run-query"
          with:
            expression: "{{bql_expression}}"
          outputParameters:
            - name: data
              type: array
              mapping: "$.results"
            - name: field_count
              type: integer
              mapping: "$.fieldCount"
  consumes:
    - type: http
      namespace: bloomberg-bql
      baseUri: "https://api.bloomberg.com/eap/catalogs/bbg/data"
      authentication:
        type: bearer
        token: "$secrets.bloomberg_data_token"
      resources:
        - name: queries
          path: "/queries"
          operations:
            - name: run-query
              method: POST

Retrieves key financial data points for a company from Bloomberg Company Financials including revenue, EPS, and market cap.

naftiko: "0.5"
info:
  label: "Bloomberg Company Financials Lookup"
  description: "Retrieves key financial data points for a company from Bloomberg Company Financials including revenue, EPS, and market cap."
  tags:
    - financial-data
    - bloomberg-company-financials
    - research
capability:
  exposes:
    - type: mcp
      namespace: company-fin
      port: 8080
      tools:
        - name: get-company-financials
          description: "Given a company ticker, return key financial metrics from Bloomberg Company Financials. Use for equity research and due diligence."
          inputParameters:
            - name: ticker
              in: body
              type: string
              description: "The Bloomberg company ticker, e.g. 'AAPL US Equity'."
          call: "bbg-financials.get-financials"
          with:
            ticker: "{{ticker}}"
          outputParameters:
            - name: revenue
              type: number
              mapping: "$.revenue"
            - name: eps
              type: number
              mapping: "$.eps"
            - name: market_cap
              type: number
              mapping: "$.market_cap"
  consumes:
    - type: http
      namespace: bbg-financials
      baseUri: "https://api.bloomberg.com/eap/catalogs/bbg/data"
      authentication:
        type: bearer
        token: "$secrets.bloomberg_data_token"
      resources:
        - name: financials
          path: "/fields/{{ticker}}"
          inputParameters:
            - name: ticker
              in: path
          operations:
            - name: get-financials
              method: GET

When a data quality check fails in Snowflake for Bloomberg market data, creates a Jira ticket, notifies the data engineering team on Slack, and logs the incident in ServiceNow.

naftiko: "0.5"
info:
  label: "Bloomberg Data Quality Alert Handler"
  description: "When a data quality check fails in Snowflake for Bloomberg market data, creates a Jira ticket, notifies the data engineering team on Slack, and logs the incident in ServiceNow."
  tags:
    - data-quality
    - snowflake
    - jira
    - slack
    - bloomberg-data
capability:
  exposes:
    - type: mcp
      namespace: data-quality
      port: 8080
      tools:
        - name: handle-data-quality-alert
          description: "Given a failed data quality check name and affected dataset, create a Jira ticket for data engineering, post to Slack, and log a ServiceNow incident."
          inputParameters:
            - name: check_name
              in: body
              type: string
              description: "The name of the failed data quality check."
            - name: dataset
              in: body
              type: string
              description: "The affected Snowflake dataset, e.g. 'BLOOMBERG.MARKET_DATA.EQUITIES'."
            - name: error_details
              in: body
              type: string
              description: "Details about the data quality failure."
          steps:
            - name: create-jira-ticket
              type: call
              call: "jira-dq.create-issue"
              with:
                project: "DATAQUAL"
                summary: "Data quality failure: {{check_name}} on {{dataset}}"
                description: "{{error_details}}"
                issue_type: "Bug"
                priority: "High"
            - name: notify-slack
              type: call
              call: "slack-dq.post-message"
              with:
                channel: "data-quality-alerts"
                text: "Data quality alert: {{check_name}} failed on {{dataset}}. Jira: {{create-jira-ticket.key}}. Details: {{error_details}}"
            - name: log-incident
              type: call
              call: "snow-dq.create-incident"
              with:
                short_description: "Data quality failure: {{check_name}}"
                description: "Dataset: {{dataset}}. Jira: {{create-jira-ticket.key}}. {{error_details}}"
                category: "data_quality"
  consumes:
    - type: http
      namespace: jira-dq
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-dq
      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
    - type: http
      namespace: snow-dq
      baseUri: "https://bloomberg.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

Retrieves the latest Bloomberg Economics forecast data, generates an analyst brief via Anthropic Claude, and distributes via Slack and Confluence to the research team.

naftiko: "0.5"
info:
  label: "Bloomberg Economics Forecast Distributor"
  description: "Retrieves the latest Bloomberg Economics forecast data, generates an analyst brief via Anthropic Claude, and distributes via Slack and Confluence to the research team."
  tags:
    - economics
    - bloomberg-economics
    - anthropic
    - slack
    - confluence
capability:
  exposes:
    - type: mcp
      namespace: econ-ops
      port: 8080
      tools:
        - name: distribute-economics-forecast
          description: "Retrieve Bloomberg Economics forecasts, generate an analyst brief, and distribute to the research team."
          inputParameters:
            - name: indicator
              in: body
              type: string
              description: "The economic indicator, e.g. 'GDP', 'CPI', 'unemployment'."
            - name: region
              in: body
              type: string
              description: "The region, e.g. 'US', 'EU', 'Global'."
          steps:
            - name: get-forecast
              type: call
              call: "bbg-econ.get-forecast"
              with:
                indicator: "{{indicator}}"
                region: "{{region}}"
            - name: generate-brief
              type: call
              call: "anthropic-econ.create-message"
              with:
                model: "claude-opus-4-5"
                max_tokens: 2048
                system: "You are a macroeconomist. Write a concise analyst brief on the latest economic forecast data."
                content: "Generate an analyst brief for {{region}} {{indicator}} forecast: {{get-forecast.data}}"
            - name: distribute
              type: call
              call: "slack-econ.post-message"
              with:
                channel: "economics-research"
                text: "Economics Forecast Update: {{region}} {{indicator}}. {{generate-brief.content}}"
  consumes:
    - type: http
      namespace: bbg-econ
      baseUri: "https://api.bloomberg.com/eap/catalogs/bbg/data"
      authentication:
        type: bearer
        token: "$secrets.bloomberg_data_token"
      resources:
        - name: forecasts
          path: "/economics/forecasts"
          operations:
            - name: get-forecast
              method: GET
    - type: http
      namespace: anthropic-econ
      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: slack-econ
      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

Monitors Bloomberg EMSX for unusual order patterns, creates a ServiceNow investigation, alerts the trading desk on Slack, and logs the anomaly in Snowflake.

naftiko: "0.5"
info:
  label: "Bloomberg EMSX Order Anomaly Detector"
  description: "Monitors Bloomberg EMSX for unusual order patterns, creates a ServiceNow investigation, alerts the trading desk on Slack, and logs the anomaly in Snowflake."
  tags:
    - trading
    - bloomberg-emsx
    - servicenow
    - slack
    - snowflake
capability:
  exposes:
    - type: mcp
      namespace: emsx-ops
      port: 8080
      tools:
        - name: detect-order-anomaly
          description: "Given a Bloomberg EMSX order anomaly, create a ServiceNow investigation, alert the trading desk, and log to Snowflake."
          inputParameters:
            - name: order_id
              in: body
              type: string
              description: "The Bloomberg EMSX order ID."
            - name: anomaly_type
              in: body
              type: string
              description: "The type of order anomaly detected."
            - name: security
              in: body
              type: string
              description: "The affected security ticker."
          steps:
            - name: create-investigation
              type: call
              call: "snow-emsx.create-incident"
              with:
                short_description: "EMSX order anomaly: {{anomaly_type}} on {{security}}"
                description: "Order: {{order_id}}. Anomaly: {{anomaly_type}}. Security: {{security}}"
                category: "trading_surveillance"
                urgency: "1"
            - name: alert-desk
              type: call
              call: "slack-emsx.post-message"
              with:
                channel: "trading-desk"
                text: "ORDER ANOMALY: {{anomaly_type}} on {{security}} (Order: {{order_id}}). Investigation: {{create-investigation.number}}"
            - name: log-anomaly
              type: call
              call: "snowflake-emsx.insert-rows"
              with:
                table: "BLOOMBERG.SURVEILLANCE.ORDER_ANOMALIES"
                data: "{\"order_id\": \"{{order_id}}\", \"anomaly_type\": \"{{anomaly_type}}\", \"security\": \"{{security}}\"}"
  consumes:
    - type: http
      namespace: snow-emsx
      baseUri: "https://bloomberg.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: slack-emsx
      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
    - type: http
      namespace: snowflake-emsx
      baseUri: "https://bloomberg.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: rows
          path: "/databases/bloomberg/schemas/surveillance/tables/order_anomalies/insertRows"
          operations:
            - name: insert-rows
              method: POST

Provisions a new Bloomberg Enterprise Data feed by creating the Snowflake target tables, configuring the data pipeline in Databricks, and notifying stakeholders on Slack.

naftiko: "0.5"
info:
  label: "Bloomberg Enterprise Data Feed Onboarding"
  description: "Provisions a new Bloomberg Enterprise Data feed by creating the Snowflake target tables, configuring the data pipeline in Databricks, and notifying stakeholders on Slack."
  tags:
    - data-engineering
    - bloomberg-enterprise-data
    - snowflake
    - databricks
    - slack
capability:
  exposes:
    - type: mcp
      namespace: feed-onboard
      port: 8080
      tools:
        - name: onboard-data-feed
          description: "Given a new Bloomberg Enterprise Data feed name, create Snowflake tables, configure Databricks pipeline, and notify stakeholders."
          inputParameters:
            - name: feed_name
              in: body
              type: string
              description: "The Bloomberg Enterprise Data feed name."
            - name: target_schema
              in: body
              type: string
              description: "The target Snowflake schema."
          steps:
            - name: create-tables
              type: call
              call: "snowflake-onboard.execute-query"
              with:
                query: "CREATE TABLE IF NOT EXISTS {{target_schema}}.{{feed_name}} (data VARIANT, loaded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP())"
            - name: configure-pipeline
              type: call
              call: "dbx-onboard.create-job"
              with:
                name: "ingest-{{feed_name}}"
                target_table: "{{target_schema}}.{{feed_name}}"
            - name: notify-team
              type: call
              call: "slack-onboard.post-message"
              with:
                channel: "data-engineering"
                text: "New Bloomberg data feed onboarded: {{feed_name}}. Snowflake table: {{target_schema}}.{{feed_name}}. Databricks job: ingest-{{feed_name}}."
  consumes:
    - type: http
      namespace: snowflake-onboard
      baseUri: "https://bloomberg.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-query
              method: POST
    - type: http
      namespace: dbx-onboard
      baseUri: "https://bloomberg.cloud.databricks.com/api/2.1"
      authentication:
        type: bearer
        token: "$secrets.databricks_token"
      resources:
        - name: jobs
          path: "/jobs/create"
          operations:
            - name: create-job
              method: POST
    - type: http
      namespace: slack-onboard
      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

Monitors Bloomberg Government for regulatory updates, summarizes changes via Anthropic Claude, creates Jira compliance tasks, and notifies the legal team on Slack.

naftiko: "0.5"
info:
  label: "Bloomberg Government Regulatory Update Tracker"
  description: "Monitors Bloomberg Government for regulatory updates, summarizes changes via Anthropic Claude, creates Jira compliance tasks, and notifies the legal team on Slack."
  tags:
    - regulatory
    - bloomberg-government-bgov
    - anthropic
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: regulatory-ops
      port: 8080
      tools:
        - name: track-regulatory-update
          description: "Given a Bloomberg Government regulatory update, summarize via Anthropic, create Jira tasks, and notify the legal team."
          inputParameters:
            - name: regulation_id
              in: body
              type: string
              description: "The Bloomberg Government regulation identifier."
            - name: topic
              in: body
              type: string
              description: "The regulatory topic area."
          steps:
            - name: get-update
              type: call
              call: "bgov-reg.get-regulation"
              with:
                regulation_id: "{{regulation_id}}"
            - name: summarize
              type: call
              call: "anthropic-reg.create-message"
              with:
                model: "claude-opus-4-5"
                max_tokens: 2048
                system: "You are a regulatory analyst. Summarize the regulation and identify action items for compliance."
                content: "Summarize this regulatory update and list required actions: {{get-update.content}}"
            - name: create-task
              type: call
              call: "jira-reg.create-issue"
              with:
                project: "COMPLIANCE"
                summary: "Regulatory update: {{topic}} ({{regulation_id}})"
                description: "{{summarize.content}}"
                priority: "High"
            - name: notify-legal
              type: call
              call: "slack-reg.post-message"
              with:
                channel: "legal-regulatory"
                text: "Regulatory update: {{topic}}. Summary: {{summarize.content}}. Jira: {{create-task.key}}"
  consumes:
    - type: http
      namespace: bgov-reg
      baseUri: "https://api.bgov.com/v1"
      authentication:
        type: bearer
        token: "$secrets.bgov_token"
      resources:
        - name: regulations
          path: "/regulations/{{regulation_id}}"
          inputParameters:
            - name: regulation_id
              in: path
          operations:
            - name: get-regulation
              method: GET
    - type: http
      namespace: anthropic-reg
      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: jira-reg
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-reg
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves the current constituent list and weights for a Bloomberg index for portfolio analysis.

naftiko: "0.5"
info:
  label: "Bloomberg Index Composition Lookup"
  description: "Retrieves the current constituent list and weights for a Bloomberg index for portfolio analysis."
  tags:
    - financial-data
    - bloomberg-indices
    - portfolio
    - analytics
capability:
  exposes:
    - type: mcp
      namespace: index-ops
      port: 8080
      tools:
        - name: get-index-composition
          description: "Given a Bloomberg index ticker, return its constituent securities and weights. Use for portfolio rebalancing and benchmark analysis."
          inputParameters:
            - name: index_ticker
              in: body
              type: string
              description: "The Bloomberg index ticker, e.g. 'SPX Index'."
          call: "bloomberg-idx.get-constituents"
          with:
            ticker: "{{index_ticker}}"
          outputParameters:
            - name: constituents
              type: array
              mapping: "$.members"
            - name: count
              type: integer
              mapping: "$.totalMembers"
  consumes:
    - type: http
      namespace: bloomberg-idx
      baseUri: "https://api.bloomberg.com/eap/catalogs/bbg/data"
      authentication:
        type: bearer
        token: "$secrets.bloomberg_data_token"
      resources:
        - name: indices
          path: "/indices/{{ticker}}/constituents"
          inputParameters:
            - name: ticker
              in: path
          operations:
            - name: get-constituents
              method: GET

When a Bloomberg index rebalance is detected, retrieves updated constituents, generates an impact analysis via Anthropic, and distributes to portfolio managers via Slack.

naftiko: "0.5"
info:
  label: "Bloomberg Index Rebalance Notification"
  description: "When a Bloomberg index rebalance is detected, retrieves updated constituents, generates an impact analysis via Anthropic, and distributes to portfolio managers via Slack."
  tags:
    - financial-data
    - bloomberg-indices
    - anthropic
    - slack
    - portfolio
capability:
  exposes:
    - type: mcp
      namespace: index-rebalance
      port: 8080
      tools:
        - name: notify-index-rebalance
          description: "Given a Bloomberg index ticker with a pending rebalance, retrieve new constituents, analyze impact, and notify portfolio managers."
          inputParameters:
            - name: index_ticker
              in: body
              type: string
              description: "The Bloomberg index ticker."
            - name: rebalance_date
              in: body
              type: string
              description: "The effective rebalance date."
          steps:
            - name: get-changes
              type: call
              call: "bbg-idx-rebal.get-rebalance-changes"
              with:
                ticker: "{{index_ticker}}"
                date: "{{rebalance_date}}"
            - name: analyze-impact
              type: call
              call: "anthropic-idx.create-message"
              with:
                model: "claude-opus-4-5"
                max_tokens: 2048
                system: "You are a portfolio analyst. Summarize index rebalance changes and their impact on tracking portfolios."
                content: "Analyze these rebalance changes for {{index_ticker}} effective {{rebalance_date}}: {{get-changes.data}}"
            - name: notify-pm
              type: call
              call: "slack-pm.post-message"
              with:
                channel: "portfolio-management"
                text: "Index Rebalance: {{index_ticker}} effective {{rebalance_date}}. Impact: {{analyze-impact.content}}"
  consumes:
    - type: http
      namespace: bbg-idx-rebal
      baseUri: "https://api.bloomberg.com/eap/catalogs/bbg/data"
      authentication:
        type: bearer
        token: "$secrets.bloomberg_data_token"
      resources:
        - name: rebalance
          path: "/indices/{{ticker}}/rebalance"
          inputParameters:
            - name: ticker
              in: path
          operations:
            - name: get-rebalance-changes
              method: GET
    - type: http
      namespace: anthropic-idx
      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: slack-pm
      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

Monitors Bloomberg Instant Messaging for compliance keywords, flags messages for review, creates Jira compliance tickets, and alerts the compliance team on Slack.

naftiko: "0.5"
info:
  label: "Bloomberg Instant Messaging Compliance Monitor"
  description: "Monitors Bloomberg Instant Messaging for compliance keywords, flags messages for review, creates Jira compliance tickets, and alerts the compliance team on Slack."
  tags:
    - compliance
    - bloomberg-instant-messaging
    - jira
    - slack
    - surveillance
capability:
  exposes:
    - type: mcp
      namespace: msg-compliance
      port: 8080
      tools:
        - name: flag-compliance-message
          description: "Given a flagged Bloomberg IB message, create a Jira compliance ticket and alert the compliance team."
          inputParameters:
            - name: message_id
              in: body
              type: string
              description: "The Bloomberg IB message ID."
            - name: keyword_matched
              in: body
              type: string
              description: "The compliance keyword that was matched."
            - name: sender
              in: body
              type: string
              description: "The message sender identifier."
          steps:
            - name: create-compliance-ticket
              type: call
              call: "jira-comp.create-issue"
              with:
                project: "COMPLIANCE"
                summary: "IB message flagged: keyword '{{keyword_matched}}' from {{sender}}"
                description: "Message ID: {{message_id}}. Keyword: {{keyword_matched}}. Sender: {{sender}}"
                priority: "High"
            - name: alert-compliance
              type: call
              call: "slack-comp.post-message"
              with:
                channel: "compliance-surveillance"
                text: "Flagged IB message: {{sender}} triggered keyword '{{keyword_matched}}'. Jira: {{create-compliance-ticket.key}}"
  consumes:
    - type: http
      namespace: jira-comp
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-comp
      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 breaking Bloomberg News alert is detected, summarizes the impact via Anthropic Claude, posts to relevant Slack channels, and creates a Jira research task for analysts.

naftiko: "0.5"
info:
  label: "Bloomberg News Breaking Alert Distributor"
  description: "When a breaking Bloomberg News alert is detected, summarizes the impact via Anthropic Claude, posts to relevant Slack channels, and creates a Jira research task for analysts."
  tags:
    - news
    - bloomberg-news
    - anthropic
    - slack
    - jira
capability:
  exposes:
    - type: mcp
      namespace: breaking-news
      port: 8080
      tools:
        - name: distribute-breaking-alert
          description: "Given a Bloomberg News breaking alert, summarize impact, post to Slack, and create a Jira research task."
          inputParameters:
            - name: alert_id
              in: body
              type: string
              description: "The Bloomberg News alert identifier."
            - name: headline
              in: body
              type: string
              description: "The breaking news headline."
          steps:
            - name: get-alert-details
              type: call
              call: "bbg-breaking.get-alert"
              with:
                alert_id: "{{alert_id}}"
            - name: summarize-impact
              type: call
              call: "anthropic-break.create-message"
              with:
                model: "claude-opus-4-5"
                max_tokens: 1024
                system: "You are a financial news analyst. Provide a brief market impact assessment for this breaking news."
                content: "Assess market impact of: {{headline}}. Details: {{get-alert-details.body}}"
            - name: post-to-slack
              type: call
              call: "slack-break.post-message"
              with:
                channel: "breaking-news"
                text: "BREAKING: {{headline}}. Impact: {{summarize-impact.content}}"
            - name: create-research-task
              type: call
              call: "jira-break.create-issue"
              with:
                project: "RESEARCH"
                summary: "Research: {{headline}}"
                description: "Breaking alert: {{alert_id}}. {{summarize-impact.content}}"
                priority: "High"
  consumes:
    - type: http
      namespace: bbg-breaking
      baseUri: "https://api.bloomberg.com/content/v1"
      authentication:
        type: bearer
        token: "$secrets.bloomberg_content_token"
      resources:
        - name: alerts
          path: "/alerts/{{alert_id}}"
          inputParameters:
            - name: alert_id
              in: path
          operations:
            - name: get-alert
              method: GET
    - type: http
      namespace: anthropic-break
      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: slack-break
      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
    - type: http
      namespace: jira-break
      baseUri: "https://bloomberg.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

Fetches recent Bloomberg News articles for a given topic, runs sentiment analysis via Anthropic Claude, and stores results in Snowflake for downstream reporting.

naftiko: "0.5"
info:
  label: "Bloomberg News Sentiment Pipeline"
  description: "Fetches recent Bloomberg News articles for a given topic, runs sentiment analysis via Anthropic Claude, and stores results in Snowflake for downstream reporting."
  tags:
    - ai
    - nlp
    - bloomberg-news
    - anthropic
    - snowflake
capability:
  exposes:
    - type: mcp
      namespace: news-analytics
      port: 8080
      tools:
        - name: analyze-news-sentiment
          description: "Given a news topic and date range, retrieve Bloomberg News articles, analyze sentiment via Anthropic Claude, and store results in Snowflake."
          inputParameters:
            - name: topic
              in: body
              type: string
              description: "The news topic or company name to search for."
            - name: date_range
              in: body
              type: string
              description: "Date range for articles, e.g. '7d' for last 7 days."
          steps:
            - name: fetch-articles
              type: call
              call: "bbg-news.search-articles"
              with:
                query: "{{topic}}"
                range: "{{date_range}}"
            - name: analyze-sentiment
              type: call
              call: "anthropic-nlp.create-message"
              with:
                model: "claude-opus-4-5"
                max_tokens: 2048
                system: "You are a financial sentiment analyst. Classify each article as positive, negative, or neutral with a confidence score."
                content: "Analyze sentiment for these articles: {{fetch-articles.articles}}"
            - name: store-results
              type: call
              call: "snowflake-sent.insert-rows"
              with:
                table: "BLOOMBERG.ANALYTICS.NEWS_SENTIMENT"
                data: "{{analyze-sentiment.content}}"
  consumes:
    - type: http
      namespace: bbg-news
      baseUri: "https://api.bloomberg.com/content/v1"
      authentication:
        type: bearer
        token: "$secrets.bloomberg_content_token"
      resources:
        - name: articles
          path: "/search"
          operations:
            - name: search-articles
              method: GET
    - type: http
      namespace: anthropic-nlp
      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: snowflake-sent
      baseUri: "https://bloomberg.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: rows
          path: "/databases/bloomberg/schemas/analytics/tables/news_sentiment/insertRows"
          operations:
            - name: insert-rows
              method: POST

Monitors Bloomberg Tax for upcoming filing deadlines, creates Jira tasks for each deadline, and sends reminders to the tax team via Slack.

naftiko: "0.5"
info:
  label: "Bloomberg Tax Filing Deadline Tracker"
  description: "Monitors Bloomberg Tax for upcoming filing deadlines, creates Jira tasks for each deadline, and sends reminders to the tax team via Slack."
  tags:
    - compliance
    - bloomberg-tax-btax
    - jira
    - slack
    - tax
capability:
  exposes:
    - type: mcp
      namespace: tax-ops
      port: 8080
      tools:
        - name: track-tax-deadlines
          description: "Given a jurisdiction and date range, retrieve Bloomberg Tax filing deadlines, create Jira tasks, and notify the tax team."
          inputParameters:
            - name: jurisdiction
              in: body
              type: string
              description: "The tax jurisdiction, e.g. 'US-Federal'."
            - name: days_ahead
              in: body
              type: string
              description: "Number of days ahead to look for deadlines."
          steps:
            - name: get-deadlines
              type: call
              call: "btax-deadlines.get-upcoming"
              with:
                jurisdiction: "{{jurisdiction}}"
                days: "{{days_ahead}}"
            - name: create-tasks
              type: call
              call: "jira-tax.create-issue"
              with:
                project: "TAX"
                summary: "Tax filing deadline: {{jurisdiction}} - {{get-deadlines.next_deadline}}"
                description: "Deadline: {{get-deadlines.next_deadline}}. Filing: {{get-deadlines.filing_type}}"
                priority: "High"
            - name: notify-team
              type: call
              call: "slack-tax.post-message"
              with:
                channel: "tax-compliance"
                text: "Upcoming tax deadline: {{jurisdiction}} - {{get-deadlines.filing_type}} due {{get-deadlines.next_deadline}}. Jira: {{create-tasks.key}}"
  consumes:
    - type: http
      namespace: btax-deadlines
      baseUri: "https://api.tax.bloomberg.com/v1"
      authentication:
        type: bearer
        token: "$secrets.btax_token"
      resources:
        - name: deadlines
          path: "/deadlines"
          operations:
            - name: get-upcoming
              method: GET
    - type: http
      namespace: jira-tax
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-tax
      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

Analyzes Bloomberg Terminal usage from enterprise data, identifies underutilized licenses, generates a reallocation recommendation via Anthropic, and notifies stakeholders on Slack.

naftiko: "0.5"
info:
  label: "Bloomberg Terminal License Optimization"
  description: "Analyzes Bloomberg Terminal usage from enterprise data, identifies underutilized licenses, generates a reallocation recommendation via Anthropic, and notifies stakeholders on Slack."
  tags:
    - licensing
    - bloomberg-terminal
    - bloomberg-enterprise
    - anthropic
    - cost-management
capability:
  exposes:
    - type: mcp
      namespace: license-ops
      port: 8080
      tools:
        - name: optimize-terminal-licenses
          description: "Analyze Bloomberg Terminal usage, identify underutilized licenses, and recommend reallocations."
          inputParameters:
            - name: usage_period
              in: body
              type: string
              description: "Usage period to analyze, e.g. 'Q1-2026'."
          steps:
            - name: get-usage
              type: call
              call: "bbg-enterprise.get-terminal-usage"
              with:
                period: "{{usage_period}}"
            - name: analyze-usage
              type: call
              call: "anthropic-license.create-message"
              with:
                model: "claude-opus-4-5"
                max_tokens: 2048
                system: "You are a Bloomberg Terminal license optimization specialist. Identify underutilized licenses and recommend reallocations."
                content: "Analyze this Terminal usage data and recommend optimizations: {{get-usage.data}}"
            - name: notify-stakeholders
              type: call
              call: "slack-license.post-message"
              with:
                channel: "vendor-management"
                text: "Bloomberg Terminal license review for {{usage_period}} complete. Recommendations: {{analyze-usage.content}}"
  consumes:
    - type: http
      namespace: bbg-enterprise
      baseUri: "https://api.bloomberg.com/enterprise/v1"
      authentication:
        type: apikey
        key: "X-Bloomberg-Key"
        value: "$secrets.bloomberg_enterprise_key"
        placement: header
      resources:
        - name: usage
          path: "/terminal/usage"
          operations:
            - name: get-terminal-usage
              method: GET
    - type: http
      namespace: anthropic-license
      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: slack-license
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves the current active Terminal session count and license utilization from Bloomberg Enterprise for capacity reporting.

naftiko: "0.5"
info:
  label: "Bloomberg Terminal Session Lookup"
  description: "Retrieves the current active Terminal session count and license utilization from Bloomberg Enterprise for capacity reporting."
  tags:
    - bloomberg-terminal
    - licensing
    - bloomberg-enterprise
capability:
  exposes:
    - type: mcp
      namespace: terminal-ops
      port: 8080
      tools:
        - name: get-terminal-sessions
          description: "Given a date range, return active Bloomberg Terminal session counts and license usage. Use for capacity planning and compliance audits."
          inputParameters:
            - name: date_from
              in: body
              type: string
              description: "Start date in YYYY-MM-DD format."
            - name: date_to
              in: body
              type: string
              description: "End date in YYYY-MM-DD format."
          call: "bloomberg-terminal.get-sessions"
          with:
            date_from: "{{date_from}}"
            date_to: "{{date_to}}"
          outputParameters:
            - name: active_sessions
              type: integer
              mapping: "$.total_active"
            - name: license_utilization
              type: string
              mapping: "$.utilization_pct"
  consumes:
    - type: http
      namespace: bloomberg-terminal
      baseUri: "https://api.bloomberg.com/enterprise/v1"
      authentication:
        type: apikey
        key: "X-Bloomberg-Key"
        value: "$secrets.bloomberg_enterprise_key"
        placement: header
      resources:
        - name: sessions
          path: "/terminal/sessions"
          operations:
            - name: get-sessions
              method: GET

When Bloomberg Valuation Service detects a pricing discrepancy, creates a Jira investigation ticket, notifies the valuation team on Slack, and logs the event in Snowflake for audit.

naftiko: "0.5"
info:
  label: "Bloomberg Valuation Discrepancy Alert"
  description: "When Bloomberg Valuation Service detects a pricing discrepancy, creates a Jira investigation ticket, notifies the valuation team on Slack, and logs the event in Snowflake for audit."
  tags:
    - financial-data
    - bloomberg-valuation-service-bval
    - jira
    - slack
    - snowflake
capability:
  exposes:
    - type: mcp
      namespace: valuation-ops
      port: 8080
      tools:
        - name: handle-valuation-discrepancy
          description: "Given a BVAL pricing discrepancy, create a Jira ticket, alert the valuation team, and log to Snowflake."
          inputParameters:
            - name: security_id
              in: body
              type: string
              description: "The security identifier with the discrepancy."
            - name: expected_price
              in: body
              type: string
              description: "The expected price."
            - name: actual_price
              in: body
              type: string
              description: "The actual Bloomberg BVAL price."
          steps:
            - name: create-ticket
              type: call
              call: "jira-val.create-issue"
              with:
                project: "VAL"
                summary: "BVAL discrepancy: {{security_id}} (expected: {{expected_price}}, actual: {{actual_price}})"
                description: "Security: {{security_id}}. Expected: {{expected_price}}. BVAL: {{actual_price}}."
                priority: "High"
            - name: notify-team
              type: call
              call: "slack-val.post-message"
              with:
                channel: "valuation-team"
                text: "BVAL discrepancy: {{security_id}}. Expected: {{expected_price}}, Actual: {{actual_price}}. Jira: {{create-ticket.key}}"
            - name: log-audit
              type: call
              call: "snowflake-val.insert-rows"
              with:
                table: "BLOOMBERG.AUDIT.VALUATION_DISCREPANCIES"
                data: "{\"security\": \"{{security_id}}\", \"expected\": \"{{expected_price}}\", \"actual\": \"{{actual_price}}\", \"jira\": \"{{create-ticket.key}}\"}"
  consumes:
    - type: http
      namespace: jira-val
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-val
      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
    - type: http
      namespace: snowflake-val
      baseUri: "https://bloomberg.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: rows
          path: "/databases/bloomberg/schemas/audit/tables/valuation_discrepancies/insertRows"
          operations:
            - name: insert-rows
              method: POST

When a change request is submitted in ServiceNow for a production system, retrieves the risk assessment and routes to the appropriate Change Advisory Board approvers via Teams.

naftiko: "0.5"
info:
  label: "Change Management Approval Gate"
  description: "When a change request is submitted in ServiceNow for a production system, retrieves the risk assessment and routes to the appropriate Change Advisory Board approvers via Teams."
  tags:
    - itsm
    - change-management
    - servicenow
    - microsoft-teams
    - approval
capability:
  exposes:
    - type: mcp
      namespace: change-management
      port: 8080
      tools:
        - name: route-change-request
          description: "Given a ServiceNow change request number, retrieve the risk level and CAB group, notify the appropriate approvers via Teams, and update the change record with routing confirmation. Use when a change request needs CAB review."
          inputParameters:
            - name: change_number
              in: body
              type: string
              description: "The ServiceNow change request number, e.g. 'CHG0001234'."
          steps:
            - name: get-change
              type: call
              call: "servicenow.get-change"
              with:
                number: "{{change_number}}"
            - name: notify-cab
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.cab_teams_channel_id"
                text: "CAB Review Required: {{change_number}} — {{get-change.short_description}} | Risk: {{get-change.risk}} | Planned: {{get-change.start_date}}"
            - name: update-change
              type: call
              call: "servicenow-update.patch-change"
              with:
                sys_id: "{{get-change.sys_id}}"
                state: "2"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://bloomberg.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: changes
          path: "/table/change_request"
          operations:
            - name: get-change
              method: GET
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST
    - type: http
      namespace: servicenow-update
      baseUri: "https://bloomberg.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: change-patch
          path: "/table/change_request/{{sys_id}}"
          inputParameters:
            - name: sys_id
              in: path
          operations:
            - name: patch-change
              method: PATCH

When a GitHub Actions pipeline fails on a protected branch, creates a Jira bug, posts an alert to Slack, and logs a PagerDuty incident for on-call engineers.

naftiko: "0.5"
info:
  label: "CI/CD Pipeline Failure Handler"
  description: "When a GitHub Actions pipeline fails on a protected branch, creates a Jira bug, posts an alert to Slack, and logs a PagerDuty incident for on-call engineers."
  tags:
    - devops
    - cicd
    - github
    - jira
    - slack
    - pagerduty
    - incident-response
capability:
  exposes:
    - type: mcp
      namespace: devops-ops
      port: 8080
      tools:
        - name: handle-pipeline-failure
          description: "Given a GitHub Actions pipeline failure event on a protected branch, create a Jira bug, post a Slack alert to the engineering channel, and trigger a PagerDuty incident. Invoke immediately when a critical pipeline fails."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "The GitHub repository name, e.g. 'bloomberg/comdb2'."
            - name: branch
              in: body
              type: string
              description: "The Git branch where the failure occurred."
            - name: run_id
              in: body
              type: string
              description: "The GitHub Actions run ID of the failed workflow."
            - name: commit_sha
              in: body
              type: string
              description: "The full Git commit SHA that triggered the pipeline."
            - name: failed_job
              in: body
              type: string
              description: "The name of the failed job within the workflow."
          steps:
            - name: create-bug
              type: call
              call: "jira.create-issue"
              with:
                project_key: "ENG"
                issuetype: "Bug"
                summary: "[CI Failure] {{repo}} / {{branch}} — {{failed_job}}"
                description: "Run: {{run_id}}\nCommit: {{commit_sha}}\nBranch: {{branch}}"
            - name: post-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "engineering-alerts"
                text: "Pipeline failure in {{repo}} on {{branch}}. Job: {{failed_job}} | Jira: {{create-bug.key}} | Run: {{run_id}}"
            - name: trigger-pagerduty
              type: call
              call: "pagerduty.create-incident"
              with:
                title: "CI Failure: {{repo}} {{branch}} {{failed_job}}"
                service_id: "$secrets.pagerduty_engineering_service_id"
                body: "Jira: {{create-bug.key}} | Run: {{run_id}} | Commit: {{commit_sha}}"
  consumes:
    - type: http
      namespace: jira
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST
    - 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: create-incident
              method: POST

When a Bloomberg client requests data access, creates a ServiceNow request, triggers manager approval in Slack, and provisions Okta access upon approval.

naftiko: "0.5"
info:
  label: "Client Data Access Request Workflow"
  description: "When a Bloomberg client requests data access, creates a ServiceNow request, triggers manager approval in Slack, and provisions Okta access upon approval."
  tags:
    - access-management
    - servicenow
    - slack
    - okta
    - data-governance
capability:
  exposes:
    - type: mcp
      namespace: data-access
      port: 8080
      tools:
        - name: process-data-access-request
          description: "Given a client data access request, create a ServiceNow ticket, notify the data steward for approval, and provision Okta access."
          inputParameters:
            - name: requester_email
              in: body
              type: string
              description: "Email of the person requesting access."
            - name: dataset_name
              in: body
              type: string
              description: "The Bloomberg dataset being requested."
            - name: business_justification
              in: body
              type: string
              description: "Business justification for access."
          steps:
            - name: create-request
              type: call
              call: "snow-access.create-request"
              with:
                short_description: "Data access request: {{dataset_name}}"
                description: "Requester: {{requester_email}}. Dataset: {{dataset_name}}. Justification: {{business_justification}}"
                category: "data_access"
            - name: notify-steward
              type: call
              call: "slack-access.post-message"
              with:
                channel: "data-governance-approvals"
                text: "New data access request: {{requester_email}} requests access to {{dataset_name}}. SNOW: {{create-request.number}}. Justification: {{business_justification}}"
            - name: provision-access
              type: call
              call: "okta-access.add-user-to-group"
              with:
                email: "{{requester_email}}"
                group: "dataset-{{dataset_name}}-readers"
  consumes:
    - type: http
      namespace: snow-access
      baseUri: "https://bloomberg.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: requests
          path: "/table/sc_request"
          operations:
            - name: create-request
              method: POST
    - type: http
      namespace: slack-access
      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
    - type: http
      namespace: okta-access
      baseUri: "https://bloomberg.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_api_token"
        placement: header
      resources:
        - name: groups
          path: "/groups/{group_id}/users"
          operations:
            - name: add-user-to-group
              method: PUT

When Datadog detects an AWS cost anomaly exceeding threshold, fetches the cost breakdown, creates a Jira ticket for the owning team, and posts a Slack summary to the FinOps channel.

naftiko: "0.5"
info:
  label: "Cloud Cost Anomaly Responder"
  description: "When Datadog detects an AWS cost anomaly exceeding threshold, fetches the cost breakdown, creates a Jira ticket for the owning team, and posts a Slack summary to the FinOps channel."
  tags:
    - cloud
    - finops
    - datadog
    - aws
    - jira
    - slack
    - cost-management
capability:
  exposes:
    - type: mcp
      namespace: finops-ops
      port: 8080
      tools:
        - name: handle-cost-anomaly
          description: "Given a Datadog cost anomaly alert with service name and threshold exceeded amount, fetch the AWS cost breakdown, open a Jira ticket for the owning team, and alert Slack. Use when cloud spend exceeds expected variance."
          inputParameters:
            - name: service_name
              in: body
              type: string
              description: "The AWS service or resource tag name that triggered the anomaly."
            - name: anomaly_amount
              in: body
              type: number
              description: "The dollar amount exceeding the expected cost threshold."
            - name: team_tag
              in: body
              type: string
              description: "The team ownership tag to route the Jira ticket to the correct group."
          steps:
            - name: get-cost-detail
              type: call
              call: "datadog.get-cost-metrics"
              with:
                service: "{{service_name}}"
            - name: create-ticket
              type: call
              call: "jira.create-issue"
              with:
                project_key: "FINOPS"
                issuetype: "Task"
                summary: "Cost anomaly: {{service_name}} exceeded by ${{anomaly_amount}}"
                description: "Service: {{service_name}}\nOverage: ${{anomaly_amount}}\nTeam: {{team_tag}}\nMetrics: {{get-cost-detail.summary}}"
            - name: notify-finops
              type: call
              call: "slack.post-message"
              with:
                channel: "finops-alerts"
                text: "Cost anomaly detected for {{service_name}}: ${{anomaly_amount}} over threshold. Jira: {{create-ticket.key}}."
  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: metrics
          path: "/metrics/query"
          operations:
            - name: get-cost-metrics
              method: GET
    - type: http
      namespace: jira
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a new compliance training course is published in Workday Learning, enrolls all eligible employees and sends reminders via Slack and Microsoft Teams.

naftiko: "0.5"
info:
  label: "Compliance Training Enrollment Notifier"
  description: "When a new compliance training course is published in Workday Learning, enrolls all eligible employees and sends reminders via Slack and Microsoft Teams."
  tags:
    - compliance
    - workday
    - slack
    - microsoft-teams
    - training
capability:
  exposes:
    - type: mcp
      namespace: compliance-ops
      port: 8080
      tools:
        - name: notify-compliance-training
          description: "Given a Workday Learning course ID, enroll eligible employees and send notifications via Slack and Teams."
          inputParameters:
            - name: course_id
              in: body
              type: string
              description: "The Workday Learning course ID."
            - name: department
              in: body
              type: string
              description: "Target department for enrollment."
          steps:
            - name: get-eligible
              type: call
              call: "workday-learn.get-eligible-workers"
              with:
                course_id: "{{course_id}}"
                department: "{{department}}"
            - name: notify-slack
              type: call
              call: "slack-compliance.post-message"
              with:
                channel: "compliance-training"
                text: "New mandatory training: Course {{course_id}} assigned to {{department}}. {{get-eligible.count}} employees enrolled. Deadline: 30 days."
            - name: notify-teams
              type: call
              call: "teams-compliance.post-channel-message"
              with:
                channel_id: "compliance-announcements"
                text: "Compliance Training Alert: Course {{course_id}} is now available for {{department}}. Please complete within 30 days."
  consumes:
    - type: http
      namespace: workday-learn
      baseUri: "https://wd5-services1.myworkday.com/ccx/api/v1/bloomberg"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: courses
          path: "/learning/courses/{{course_id}}/eligible"
          inputParameters:
            - name: course_id
              in: path
          operations:
            - name: get-eligible-workers
              method: GET
    - type: http
      namespace: slack-compliance
      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
    - type: http
      namespace: teams-compliance
      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"
          operations:
            - name: post-channel-message
              method: POST

Creates a new Confluence knowledge base article from a structured template when a resolved ServiceNow incident has a post-mortem, ensuring institutional knowledge is captured.

naftiko: "0.5"
info:
  label: "Confluence Knowledge Base Article Publisher"
  description: "Creates a new Confluence knowledge base article from a structured template when a resolved ServiceNow incident has a post-mortem, ensuring institutional knowledge is captured."
  tags:
    - itsm
    - knowledge-management
    - confluence
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: kb-management
      port: 8080
      tools:
        - name: publish-incident-postmortem
          description: "Given a resolved ServiceNow incident number and Confluence space key, retrieve the incident details and create a post-mortem knowledge article in Confluence. Use after P1/P2 incidents are resolved to capture learnings."
          inputParameters:
            - name: incident_number
              in: body
              type: string
              description: "The resolved ServiceNow incident number, e.g. 'INC0012345'."
            - name: confluence_space_key
              in: body
              type: string
              description: "The Confluence space key where the article will be created, e.g. 'INFRA'."
          steps:
            - name: get-incident
              type: call
              call: "servicenow.get-incident"
              with:
                number: "{{incident_number}}"
            - name: create-article
              type: call
              call: "confluence.create-page"
              with:
                space_key: "{{confluence_space_key}}"
                title: "Post-mortem: {{incident_number}} — {{get-incident.short_description}}"
                body: "Incident: {{incident_number}}\nDescription: {{get-incident.short_description}}\nResolution: {{get-incident.close_notes}}\nDuration: {{get-incident.resolved_at}}"
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://bloomberg.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: confluence
      baseUri: "https://bloomberg.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: pages
          path: "/content"
          operations:
            - name: create-page
              method: POST

Fetches the body content of a Confluence page by ID for use in automated documentation reviews and knowledge base lookups.

naftiko: "0.5"
info:
  label: "Confluence Page Content Retrieval"
  description: "Fetches the body content of a Confluence page by ID for use in automated documentation reviews and knowledge base lookups."
  tags:
    - documentation
    - confluence
    - knowledge-base
capability:
  exposes:
    - type: mcp
      namespace: docs
      port: 8080
      tools:
        - name: get-page-content
          description: "Given a Confluence page ID, return the page title and body content. Use for documentation audits or knowledge extraction."
          inputParameters:
            - name: page_id
              in: body
              type: string
              description: "The Confluence page ID."
          call: "confluence-docs.get-page"
          with:
            page_id: "{{page_id}}"
          outputParameters:
            - name: title
              type: string
              mapping: "$.title"
            - name: body
              type: string
              mapping: "$.body.storage.value"
  consumes:
    - type: http
      namespace: confluence-docs
      baseUri: "https://bloomberg.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_api_token"
      resources:
        - name: pages
          path: "/content/{{page_id}}"
          inputParameters:
            - name: page_id
              in: path
          operations:
            - name: get-page
              method: GET

Aggregates customer feedback from Salesforce cases, analyzes themes and sentiment via Anthropic Claude, and publishes a weekly insights report to Confluence.

naftiko: "0.5"
info:
  label: "Customer Feedback Analysis Pipeline"
  description: "Aggregates customer feedback from Salesforce cases, analyzes themes and sentiment via Anthropic Claude, and publishes a weekly insights report to Confluence."
  tags:
    - customer-experience
    - salesforce
    - anthropic
    - confluence
    - analytics
capability:
  exposes:
    - type: mcp
      namespace: feedback-ops
      port: 8080
      tools:
        - name: analyze-customer-feedback
          description: "Aggregate Salesforce cases, analyze feedback sentiment and themes via Anthropic, and publish insights to Confluence."
          inputParameters:
            - name: date_range
              in: body
              type: string
              description: "The date range for feedback analysis, e.g. 'last_7_days'."
          steps:
            - name: get-cases
              type: call
              call: "sf-feedback.query-cases"
              with:
                query: "SELECT Subject, Description, CreatedDate FROM Case WHERE CreatedDate = LAST_N_DAYS:7"
            - name: analyze-themes
              type: call
              call: "anthropic-feedback.create-message"
              with:
                model: "claude-opus-4-5"
                max_tokens: 4096
                system: "You are a customer experience analyst. Identify themes, sentiment trends, and actionable insights from customer feedback."
                content: "Analyze these customer cases from the past week: {{get-cases.records}}"
            - name: publish-report
              type: call
              call: "confluence-feedback.create-page"
              with:
                space: "CX"
                title: "Weekly Customer Feedback Report - {{date_range}}"
                body: "{{analyze-themes.content}}"
  consumes:
    - type: http
      namespace: sf-feedback
      baseUri: "https://bloomberg.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: query
          path: "/query"
          operations:
            - name: query-cases
              method: GET
    - type: http
      namespace: anthropic-feedback
      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: confluence-feedback
      baseUri: "https://bloomberg.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_api_token"
      resources:
        - name: pages
          path: "/content"
          operations:
            - name: create-page
              method: POST

When a Databricks job fails, captures the error log, creates a Jira ticket for the data engineering team, and posts a failure summary to Slack.

naftiko: "0.5"
info:
  label: "Databricks Job Failure Response"
  description: "When a Databricks job fails, captures the error log, creates a Jira ticket for the data engineering team, and posts a failure summary to Slack."
  tags:
    - data-engineering
    - databricks
    - jira
    - slack
    - pipeline
capability:
  exposes:
    - type: mcp
      namespace: data-pipeline-ops
      port: 8080
      tools:
        - name: handle-databricks-failure
          description: "Given a failed Databricks run ID, retrieve the error, create a Jira ticket, and notify the data engineering team on Slack."
          inputParameters:
            - name: run_id
              in: body
              type: string
              description: "The Databricks job run ID that failed."
            - name: job_name
              in: body
              type: string
              description: "The name of the Databricks job."
          steps:
            - name: get-run-details
              type: call
              call: "dbx-runs.get-run"
              with:
                run_id: "{{run_id}}"
            - name: create-ticket
              type: call
              call: "jira-data.create-issue"
              with:
                project: "DATA"
                summary: "Databricks job failure: {{job_name}}"
                description: "Run ID: {{run_id}}. Error: {{get-run-details.state.state_message}}"
                priority: "High"
            - name: notify-team
              type: call
              call: "slack-data.post-message"
              with:
                channel: "data-engineering"
                text: "Databricks job failed: {{job_name}} (Run: {{run_id}}). Error: {{get-run-details.state.state_message}}. Jira: {{create-ticket.key}}"
  consumes:
    - type: http
      namespace: dbx-runs
      baseUri: "https://bloomberg.cloud.databricks.com/api/2.1"
      authentication:
        type: bearer
        token: "$secrets.databricks_token"
      resources:
        - name: runs
          path: "/jobs/runs/get"
          operations:
            - name: get-run
              method: GET
    - type: http
      namespace: jira-data
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-data
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves p99 and p50 latency metrics for Bloomberg API endpoints from Datadog for performance monitoring.

naftiko: "0.5"
info:
  label: "Datadog API Latency Check"
  description: "Retrieves p99 and p50 latency metrics for Bloomberg API endpoints from Datadog for performance monitoring."
  tags:
    - observability
    - datadog
    - api-performance
    - latency
capability:
  exposes:
    - type: mcp
      namespace: api-perf
      port: 8080
      tools:
        - name: get-api-latency
          description: "Given a Bloomberg API service name, return p50 and p99 latency metrics from Datadog. Use for SLA compliance checks."
          inputParameters:
            - name: service_name
              in: body
              type: string
              description: "The Bloomberg API service name in Datadog."
          call: "dd-latency.get-metrics"
          with:
            service: "{{service_name}}"
          outputParameters:
            - name: p50_ms
              type: number
              mapping: "$.series[0].pointlist[-1][1]"
            - name: p99_ms
              type: number
              mapping: "$.series[1].pointlist[-1][1]"
  consumes:
    - type: http
      namespace: dd-latency
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: metrics
          path: "/query"
          operations:
            - name: get-metrics
              method: GET

When a Datadog monitor enters ALERT state for a critical service, retrieves monitor details and creates a PagerDuty incident to wake the responsible on-call team.

naftiko: "0.5"
info:
  label: "Datadog Infrastructure Alert Escalation"
  description: "When a Datadog monitor enters ALERT state for a critical service, retrieves monitor details and creates a PagerDuty incident to wake the responsible on-call team."
  tags:
    - observability
    - datadog
    - pagerduty
    - incident-response
    - monitoring
capability:
  exposes:
    - type: mcp
      namespace: observability-ops
      port: 8080
      tools:
        - name: escalate-monitor-alert
          description: "Given a Datadog monitor ID in ALERT state, fetch the monitor details and create a PagerDuty incident routed to the correct service. Use for any monitor that crosses critical threshold and needs on-call response."
          inputParameters:
            - name: monitor_id
              in: body
              type: integer
              description: "The Datadog monitor ID that entered ALERT state."
            - name: pagerduty_service_id
              in: body
              type: string
              description: "The PagerDuty service ID to route the incident to based on monitor ownership."
          steps:
            - name: get-monitor
              type: call
              call: "datadog.get-monitor"
              with:
                monitor_id: "{{monitor_id}}"
            - name: create-incident
              type: call
              call: "pagerduty.create-incident"
              with:
                title: "{{get-monitor.name}} — ALERT"
                service_id: "{{pagerduty_service_id}}"
                body: "Monitor: {{get-monitor.name}}\nQuery: {{get-monitor.query}}\nMessage: {{get-monitor.message}}"
  consumes:
    - type: http
      namespace: datadog
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: monitors
          path: "/monitor/{{monitor_id}}"
          inputParameters:
            - name: monitor_id
              in: path
          operations:
            - name: get-monitor
              method: GET
    - 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: create-incident
              method: POST

When Datadog detects an elevated SLO burn rate, creates a PagerDuty incident, opens a Jira ticket with burn rate context, and posts to the SRE Slack channel.

naftiko: "0.5"
info:
  label: "Datadog SLO Burn Rate Alert Handler"
  description: "When Datadog detects an elevated SLO burn rate, creates a PagerDuty incident, opens a Jira ticket with burn rate context, and posts to the SRE Slack channel."
  tags:
    - reliability
    - datadog
    - pagerduty
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: slo-ops
      port: 8080
      tools:
        - name: handle-slo-burn-rate
          description: "Given a Datadog SLO burn rate alert, create a PagerDuty incident, Jira ticket, and Slack notification."
          inputParameters:
            - name: slo_name
              in: body
              type: string
              description: "The Datadog SLO name."
            - name: burn_rate
              in: body
              type: string
              description: "The current burn rate multiplier."
            - name: remaining_budget
              in: body
              type: string
              description: "The remaining error budget percentage."
          steps:
            - name: page-sre
              type: call
              call: "pd-slo.create-incident"
              with:
                title: "SLO burn rate alert: {{slo_name}} at {{burn_rate}}x"
                service_id: "$secrets.pagerduty_sre_service"
                urgency: "high"
            - name: create-ticket
              type: call
              call: "jira-slo.create-issue"
              with:
                project: "SRE"
                summary: "SLO burn rate: {{slo_name}} at {{burn_rate}}x ({{remaining_budget}}% budget remaining)"
                priority: "Critical"
            - name: alert-sre
              type: call
              call: "slack-slo.post-message"
              with:
                channel: "sre-alerts"
                text: "SLO BURN RATE: {{slo_name}} at {{burn_rate}}x. Budget remaining: {{remaining_budget}}%. PD: {{page-sre.incident_url}}. Jira: {{create-ticket.key}}"
  consumes:
    - type: http
      namespace: pd-slo
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.pagerduty_token"
        placement: header
      resources:
        - name: incidents
          path: "/incidents"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: jira-slo
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-slo
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Fetches current SLO compliance metrics from Datadog for all production services and publishes a compliance summary to the engineering Confluence space.

naftiko: "0.5"
info:
  label: "Datadog SLO Compliance Report"
  description: "Fetches current SLO compliance metrics from Datadog for all production services and publishes a compliance summary to the engineering Confluence space."
  tags:
    - observability
    - datadog
    - confluence
    - reporting
    - slo
capability:
  exposes:
    - type: mcp
      namespace: slo-reporting
      port: 8080
      tools:
        - name: publish-slo-report
          description: "Fetch all SLO compliance metrics from Datadog for production services and publish a structured compliance report to Confluence. Use weekly before reliability review meetings."
          inputParameters:
            - name: confluence_page_id
              in: body
              type: string
              description: "The Confluence page ID where the SLO report will be updated."
          steps:
            - name: get-slos
              type: call
              call: "datadog.list-slos"
              with:
                tags: "env:production"
            - name: update-report
              type: call
              call: "confluence.update-page"
              with:
                page_id: "{{confluence_page_id}}"
                content: "SLO Report: {{get-slos.count}} SLOs in scope."
  consumes:
    - type: http
      namespace: datadog
      baseUri: "https://api.datadoghq.com/api/v1"
      authentication:
        type: apikey
        key: "DD-API-KEY"
        value: "$secrets.datadog_api_key"
        placement: header
      resources:
        - name: slos
          path: "/slo"
          operations:
            - name: list-slos
              method: GET
    - type: http
      namespace: confluence
      baseUri: "https://bloomberg.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: pages
          path: "/content/{{page_id}}"
          inputParameters:
            - name: page_id
              in: path
          operations:
            - name: update-page
              method: PUT

When an employee termination is processed in Workday, revokes Okta access, closes all open ServiceNow tickets assigned to the employee, and notifies the IT team via Teams.

naftiko: "0.5"
info:
  label: "Employee Offboarding Workflow"
  description: "When an employee termination is processed in Workday, revokes Okta access, closes all open ServiceNow tickets assigned to the employee, and notifies the IT team via Teams."
  tags:
    - hr
    - offboarding
    - workday
    - okta
    - servicenow
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: hr-offboarding
      port: 8080
      tools:
        - name: trigger-offboarding
          description: "Given a Workday employee ID and termination date, orchestrate the full offboarding: deactivate Okta account, close open ServiceNow tickets, and notify the IT offboarding team in Teams. Use when an employee departure is confirmed."
          inputParameters:
            - name: workday_employee_id
              in: body
              type: string
              description: "The Workday worker ID for the departing employee."
            - name: termination_date
              in: body
              type: string
              description: "The employee's last working day in ISO 8601 format."
          steps:
            - name: get-employee
              type: call
              call: "workday-read.get-worker"
              with:
                worker_id: "{{workday_employee_id}}"
            - name: deactivate-okta
              type: call
              call: "okta.deactivate-user"
              with:
                user_login: "{{get-employee.work_email}}"
            - name: close-tickets
              type: call
              call: "servicenow-write.close-user-tickets"
              with:
                assigned_to: "{{get-employee.work_email}}"
            - name: notify-it
              type: call
              call: "msteams-notify.post-channel-message"
              with:
                channel_id: "$secrets.it_offboarding_channel_id"
                text: "Offboarding initiated for {{get-employee.full_name}} ({{get-employee.work_email}}). Okta deactivated. Termination date: {{termination_date}}."
  consumes:
    - type: http
      namespace: workday-read
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/bloomberg/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: okta
      baseUri: "https://bloomberg.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_api_token"
        placement: header
      resources:
        - name: users
          path: "/users/{{user_login}}/lifecycle/deactivate"
          inputParameters:
            - name: user_login
              in: path
          operations:
            - name: deactivate-user
              method: POST
    - type: http
      namespace: servicenow-write
      baseUri: "https://bloomberg.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: close-user-tickets
              method: PATCH
    - type: http
      namespace: msteams-notify
      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-channel-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: "Employee 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: retrieve employee details from Workday, open a ServiceNow onboarding ticket, create the Microsoft 365 account, and send a Teams welcome message. Invoke when a new hire is confirmed in HR."
          inputParameters:
            - name: workday_employee_id
              in: body
              type: string
              description: "The Workday worker ID for the new hire, e.g. 'WD-00123'."
            - name: start_date
              in: body
              type: string
              description: "The employee's start date in ISO 8601 format, e.g. '2026-04-01'."
          steps:
            - name: get-employee
              type: call
              call: "workday.get-worker"
              with:
                worker_id: "{{workday_employee_id}}"
            - name: open-ticket
              type: call
              call: "servicenow.create-incident"
              with:
                category: "hr_onboarding"
                short_description: "New hire onboarding: {{get-employee.full_name}}"
                assigned_group: "IT_Onboarding"
            - name: send-welcome
              type: call
              call: "msteams.send-message"
              with:
                recipient_upn: "{{get-employee.work_email}}"
                text: "Welcome to Bloomberg, {{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: "/bloomberg/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://bloomberg.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: messages
          path: "/users/{{recipient_upn}}/sendMail"
          inputParameters:
            - name: recipient_upn
              in: path
          operations:
            - name: send-message
              method: POST

When a role change is detected in Workday, updates Okta group memberships, adjusts GitHub team assignments, and notifies the employee and manager on Slack.

naftiko: "0.5"
info:
  label: "Employee Role Change Access Update"
  description: "When a role change is detected in Workday, updates Okta group memberships, adjusts GitHub team assignments, and notifies the employee and manager on Slack."
  tags:
    - hr
    - workday
    - okta
    - github
    - slack
capability:
  exposes:
    - type: mcp
      namespace: role-change-ops
      port: 8080
      tools:
        - name: update-access-on-role-change
          description: "Given a Workday role change event, update Okta groups, GitHub teams, and notify via Slack."
          inputParameters:
            - name: employee_email
              in: body
              type: string
              description: "The employee's email."
            - name: new_role
              in: body
              type: string
              description: "The new role title."
            - name: new_department
              in: body
              type: string
              description: "The new department."
          steps:
            - name: update-okta
              type: call
              call: "okta-role.update-user-groups"
              with:
                email: "{{employee_email}}"
                department: "{{new_department}}"
            - name: update-github
              type: call
              call: "gh-role.update-team-membership"
              with:
                username: "{{employee_email}}"
                team: "{{new_department}}"
            - name: notify-change
              type: call
              call: "slack-role.post-message"
              with:
                channel: "it-provisioning"
                text: "Role change processed: {{employee_email}} moved to {{new_role}} in {{new_department}}. Okta and GitHub access updated."
  consumes:
    - type: http
      namespace: okta-role
      baseUri: "https://bloomberg.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_api_token"
        placement: header
      resources:
        - name: groups
          path: "/users/{{email}}/groups"
          inputParameters:
            - name: email
              in: path
          operations:
            - name: update-user-groups
              method: PUT
    - type: http
      namespace: gh-role
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: teams
          path: "/orgs/bloomberg/teams/{{team}}/memberships/{{username}}"
          inputParameters:
            - name: team
              in: path
            - name: username
              in: path
          operations:
            - name: update-team-membership
              method: PUT
    - type: http
      namespace: slack-role
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a GitHub Actions workflow fails, captures the failure log, creates a Jira bug ticket, and notifies the responsible team on Slack.

naftiko: "0.5"
info:
  label: "GitHub Actions Workflow Failure Response"
  description: "When a GitHub Actions workflow fails, captures the failure log, creates a Jira bug ticket, and notifies the responsible team on Slack."
  tags:
    - cicd
    - github
    - jira
    - slack
    - automation
capability:
  exposes:
    - type: mcp
      namespace: gha-ops
      port: 8080
      tools:
        - name: handle-workflow-failure
          description: "Given a failed GitHub Actions run, capture error details, create a Jira ticket, and notify Slack."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "The GitHub repository name."
            - name: run_id
              in: body
              type: string
              description: "The GitHub Actions workflow run ID."
            - name: workflow_name
              in: body
              type: string
              description: "The workflow name."
          steps:
            - name: get-run
              type: call
              call: "gh-actions.get-workflow-run"
              with:
                repo: "{{repo}}"
                run_id: "{{run_id}}"
            - name: create-ticket
              type: call
              call: "jira-gha.create-issue"
              with:
                project: "CICD"
                summary: "GHA failure: {{workflow_name}} in {{repo}}"
                description: "Run: {{run_id}}. Status: {{get-run.conclusion}}. URL: {{get-run.html_url}}"
                priority: "High"
            - name: notify-team
              type: call
              call: "slack-gha.post-message"
              with:
                channel: "cicd-alerts"
                text: "GHA failure: {{workflow_name}} in {{repo}}. Run: {{get-run.html_url}}. Jira: {{create-ticket.key}}"
  consumes:
    - type: http
      namespace: gh-actions
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: runs
          path: "/repos/{{repo}}/actions/runs/{{run_id}}"
          inputParameters:
            - name: repo
              in: path
            - name: run_id
              in: path
          operations:
            - name: get-workflow-run
              method: GET
    - type: http
      namespace: jira-gha
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-gha
      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

Monitors open GitHub pull requests approaching review SLA, assigns additional reviewers, and sends SLA warnings to the Slack engineering channel.

naftiko: "0.5"
info:
  label: "GitHub Code Review SLA Monitor"
  description: "Monitors open GitHub pull requests approaching review SLA, assigns additional reviewers, and sends SLA warnings to the Slack engineering channel."
  tags:
    - engineering
    - github
    - slack
    - code-review
    - sla
capability:
  exposes:
    - type: mcp
      namespace: review-ops
      port: 8080
      tools:
        - name: monitor-review-sla
          description: "Given a GitHub repository, check PRs nearing review SLA breach, assign reviewers, and alert Slack."
          inputParameters:
            - name: repo_name
              in: body
              type: string
              description: "The GitHub repository name."
            - name: sla_hours
              in: body
              type: string
              description: "The SLA threshold in hours."
          steps:
            - name: get-open-prs
              type: call
              call: "gh-review.list-pull-requests"
              with:
                repo: "{{repo_name}}"
                state: "open"
            - name: alert-team
              type: call
              call: "slack-review.post-message"
              with:
                channel: "engineering-reviews"
                text: "Review SLA warning: {{repo_name}} has PRs approaching {{sla_hours}}h SLA. PRs: {{get-open-prs.count}} pending review."
  consumes:
    - type: http
      namespace: gh-review
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: pulls
          path: "/repos/{{repo}}/pulls"
          inputParameters:
            - name: repo
              in: path
          operations:
            - name: list-pull-requests
              method: GET
    - type: http
      namespace: slack-review
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

On a new pull request in GitHub, triggers a Veracode static analysis scan and posts results back as a PR comment; blocks merge if critical vulnerabilities are found.

naftiko: "0.5"
info:
  label: "GitHub Pull Request Security Scan Gate"
  description: "On a new pull request in GitHub, triggers a Veracode static analysis scan and posts results back as a PR comment; blocks merge if critical vulnerabilities are found."
  tags:
    - devops
    - security
    - github
    - veracode
    - code-quality
capability:
  exposes:
    - type: mcp
      namespace: security-scanning
      port: 8080
      tools:
        - name: scan-pull-request
          description: "Given a GitHub repository and pull request number, trigger a Veracode SAST scan and post the findings as a PR review comment. Use when a PR targets main or release branches."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "The GitHub repository full name, e.g. 'bloomberg/bde'."
            - name: pr_number
              in: body
              type: integer
              description: "The GitHub pull request number."
            - name: commit_sha
              in: body
              type: string
              description: "The HEAD commit SHA of the pull request."
          steps:
            - name: trigger-scan
              type: call
              call: "veracode.create-scan"
              with:
                repo: "{{repo}}"
                ref: "{{commit_sha}}"
            - name: post-pr-comment
              type: call
              call: "github.create-pr-review"
              with:
                repo: "{{repo}}"
                pull_number: "{{pr_number}}"
                commit_id: "{{commit_sha}}"
                body: "Veracode scan {{trigger-scan.scan_id}} complete. Findings: {{trigger-scan.finding_count}}. Status: {{trigger-scan.policy_compliance_status}}"
  consumes:
    - type: http
      namespace: veracode
      baseUri: "https://analysiscenter.veracode.com/api/5.0"
      authentication:
        type: basic
        username: "$secrets.veracode_api_id"
        password: "$secrets.veracode_api_key"
      resources:
        - name: scans
          path: "/createbuild.do"
          operations:
            - name: create-scan
              method: POST
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: pull-request-reviews
          path: "/repos/{{repo}}/pulls/{{pull_number}}/reviews"
          inputParameters:
            - name: repo
              in: path
            - name: pull_number
              in: path
          operations:
            - name: create-pr-review
              method: POST

When a new GitHub release is published, triggers a Harness deployment pipeline, updates the Jira release ticket, and posts deployment status to the engineering Slack channel.

naftiko: "0.5"
info:
  label: "GitHub Release Deployment Tracker"
  description: "When a new GitHub release is published, triggers a Harness deployment pipeline, updates the Jira release ticket, and posts deployment status to the engineering Slack channel."
  tags:
    - cicd
    - github
    - harness
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: deploy-ops
      port: 8080
      tools:
        - name: track-release-deployment
          description: "Given a GitHub release tag, trigger the Harness deployment, update Jira, and notify Slack."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "The GitHub repository name."
            - name: release_tag
              in: body
              type: string
              description: "The release tag, e.g. 'v2.5.0'."
            - name: jira_release_ticket
              in: body
              type: string
              description: "The Jira release ticket key."
          steps:
            - name: trigger-deploy
              type: call
              call: "harness-deploy.trigger-pipeline"
              with:
                pipeline: "{{repo}}-production"
                tag: "{{release_tag}}"
            - name: update-jira
              type: call
              call: "jira-release.update-issue"
              with:
                issue_key: "{{jira_release_ticket}}"
                status: "Deploying"
                comment: "Deployment triggered for {{release_tag}} via Harness."
            - name: notify-engineering
              type: call
              call: "slack-eng.post-message"
              with:
                channel: "engineering-releases"
                text: "Deployment started: {{repo}} {{release_tag}}. Harness pipeline: {{trigger-deploy.execution_url}}. Jira: {{jira_release_ticket}}"
  consumes:
    - type: http
      namespace: harness-deploy
      baseUri: "https://app.harness.io/gateway/api"
      authentication:
        type: apikey
        key: "x-api-key"
        value: "$secrets.harness_api_key"
        placement: header
      resources:
        - name: pipelines
          path: "/pipelines/execute"
          operations:
            - name: trigger-pipeline
              method: POST
    - type: http
      namespace: jira-release
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue/{{issue_key}}"
          inputParameters:
            - name: issue_key
              in: path
          operations:
            - name: update-issue
              method: PUT
    - type: http
      namespace: slack-eng
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a new GitHub release is tagged, generates structured release notes from merged PRs since the last release and publishes them to Confluence and the engineering Slack channel.

naftiko: "0.5"
info:
  label: "GitHub Release Notes Publisher"
  description: "When a new GitHub release is tagged, generates structured release notes from merged PRs since the last release and publishes them to Confluence and the engineering Slack channel."
  tags:
    - devops
    - github
    - confluence
    - slack
    - release-management
capability:
  exposes:
    - type: mcp
      namespace: release-management
      port: 8080
      tools:
        - name: publish-release-notes
          description: "Given a GitHub repository and release tag, fetch merged PRs since the previous tag, compile structured release notes, publish to Confluence, and announce in the engineering Slack channel. Use when a new production release is cut."
          inputParameters:
            - name: repo
              in: body
              type: string
              description: "The GitHub repository full name, e.g. 'bloomberg/bde'."
            - name: release_tag
              in: body
              type: string
              description: "The new release tag, e.g. 'v3.2.1'."
            - name: confluence_space_key
              in: body
              type: string
              description: "The Confluence space key where release notes will be published."
          steps:
            - name: get-prs
              type: call
              call: "github.list-merged-prs"
              with:
                repo: "{{repo}}"
                tag: "{{release_tag}}"
            - name: publish-notes
              type: call
              call: "confluence.create-page"
              with:
                space_key: "{{confluence_space_key}}"
                title: "Release Notes: {{repo}} {{release_tag}}"
                body: "Release {{release_tag}} — {{get-prs.count}} PRs merged."
            - name: announce
              type: call
              call: "slack.post-message"
              with:
                channel: "engineering-releases"
                text: "{{repo}} {{release_tag}} released. Release notes: {{publish-notes.url}}"
  consumes:
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: pulls
          path: "/repos/{{repo}}/pulls"
          inputParameters:
            - name: repo
              in: path
          operations:
            - name: list-merged-prs
              method: GET
    - type: http
      namespace: confluence
      baseUri: "https://bloomberg.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: pages
          path: "/content"
          operations:
            - name: create-page
              method: POST
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Checks whether branch protection rules are enabled on a given GitHub repository's main branch.

naftiko: "0.5"
info:
  label: "GitHub Repo Branch Protection Check"
  description: "Checks whether branch protection rules are enabled on a given GitHub repository's main branch."
  tags:
    - security
    - github
    - compliance
    - branch-protection
capability:
  exposes:
    - type: mcp
      namespace: github-security
      port: 8080
      tools:
        - name: check-branch-protection
          description: "Given a GitHub repository name, return the branch protection settings for the main branch. Use during security audits."
          inputParameters:
            - name: repo_name
              in: body
              type: string
              description: "The GitHub repository name, e.g. 'bloomberg/memray'."
          call: "gh-protection.get-branch-protection"
          with:
            repo: "{{repo_name}}"
          outputParameters:
            - name: enforce_admins
              type: boolean
              mapping: "$.enforce_admins.enabled"
            - name: required_reviews
              type: integer
              mapping: "$.required_pull_request_reviews.required_approving_review_count"
  consumes:
    - type: http
      namespace: gh-protection
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: branch-protection
          path: "/repos/{{repo}}/branches/main/protection"
          inputParameters:
            - name: repo
              in: path
          operations:
            - name: get-branch-protection
              method: GET

When a developer is onboarded to a project team, grants access to the relevant GitHub repositories and sends a Slack confirmation to the team lead.

naftiko: "0.5"
info:
  label: "GitHub Repository Access Provisioning"
  description: "When a developer is onboarded to a project team, grants access to the relevant GitHub repositories and sends a Slack confirmation to the team lead."
  tags:
    - devops
    - identity
    - github
    - slack
    - access-management
capability:
  exposes:
    - type: mcp
      namespace: dev-access
      port: 8080
      tools:
        - name: provision-repo-access
          description: "Given a GitHub username, repository list, and permission level, add the user as a collaborator to each specified repository and notify the team lead in Slack. Use when a developer joins a project team."
          inputParameters:
            - name: github_username
              in: body
              type: string
              description: "The GitHub username of the developer to provision access for."
            - name: repo_name
              in: body
              type: string
              description: "The full repository name including org, e.g. 'bloomberg/bde'."
            - name: permission
              in: body
              type: string
              description: "Permission level: 'read', 'triage', 'write', 'maintain', or 'admin'."
            - name: team_lead_slack_id
              in: body
              type: string
              description: "The Slack user ID of the team lead to notify."
          steps:
            - name: add-collaborator
              type: call
              call: "github.add-repo-collaborator"
              with:
                repo: "{{repo_name}}"
                username: "{{github_username}}"
                permission: "{{permission}}"
            - name: notify-lead
              type: call
              call: "slack.send-dm"
              with:
                user_id: "{{team_lead_slack_id}}"
                text: "{{github_username}} has been granted {{permission}} access to {{repo_name}}."
  consumes:
    - type: http
      namespace: github
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: collaborators
          path: "/repos/{{repo}}/collaborators/{{username}}"
          inputParameters:
            - name: repo
              in: path
            - name: username
              in: path
          operations:
            - name: add-repo-collaborator
              method: PUT
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: dm
          path: "/chat.postMessage"
          operations:
            - name: send-dm
              method: POST

When a Grafana alert fires, looks up the associated runbook in Confluence, posts the relevant remediation steps to Slack, and creates a ServiceNow incident.

naftiko: "0.5"
info:
  label: "Grafana Alert to Runbook Executor"
  description: "When a Grafana alert fires, looks up the associated runbook in Confluence, posts the relevant remediation steps to Slack, and creates a ServiceNow incident."
  tags:
    - observability
    - grafana
    - confluence
    - slack
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: runbook-ops
      port: 8080
      tools:
        - name: execute-runbook-for-alert
          description: "Given a Grafana alert, find the Confluence runbook, post remediation steps to Slack, and create a ServiceNow incident."
          inputParameters:
            - name: alert_name
              in: body
              type: string
              description: "The Grafana alert rule name."
            - name: runbook_page_id
              in: body
              type: string
              description: "The Confluence runbook page ID."
          steps:
            - name: get-runbook
              type: call
              call: "confluence-rb.get-page"
              with:
                page_id: "{{runbook_page_id}}"
            - name: post-remediation
              type: call
              call: "slack-rb.post-message"
              with:
                channel: "sre-incidents"
                text: "Alert: {{alert_name}}. Runbook: {{get-runbook.title}}. Steps: {{get-runbook.body}}"
            - name: create-incident
              type: call
              call: "snow-rb.create-incident"
              with:
                short_description: "Grafana alert: {{alert_name}}"
                description: "Runbook: {{get-runbook.title}}. Auto-posted to #sre-incidents."
  consumes:
    - type: http
      namespace: confluence-rb
      baseUri: "https://bloomberg.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_api_token"
      resources:
        - name: pages
          path: "/content/{{page_id}}"
          inputParameters:
            - name: page_id
              in: path
          operations:
            - name: get-page
              method: GET
    - type: http
      namespace: slack-rb
      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
    - type: http
      namespace: snow-rb
      baseUri: "https://bloomberg.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

Captures a snapshot URL of a Grafana dashboard for sharing in incident reports and executive reviews.

naftiko: "0.5"
info:
  label: "Grafana Dashboard Snapshot"
  description: "Captures a snapshot URL of a Grafana dashboard for sharing in incident reports and executive reviews."
  tags:
    - observability
    - grafana
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: monitoring
      port: 8080
      tools:
        - name: create-dashboard-snapshot
          description: "Given a Grafana dashboard UID, create a shareable snapshot URL. Use for attaching dashboard state to incident reports."
          inputParameters:
            - name: dashboard_uid
              in: body
              type: string
              description: "The Grafana dashboard UID."
          call: "grafana-snap.create-snapshot"
          with:
            dashboard_uid: "{{dashboard_uid}}"
          outputParameters:
            - name: snapshot_url
              type: string
              mapping: "$.url"
  consumes:
    - type: http
      namespace: grafana-snap
      baseUri: "https://grafana.bloomberg.com/api"
      authentication:
        type: bearer
        token: "$secrets.grafana_token"
      resources:
        - name: snapshots
          path: "/snapshots"
          operations:
            - name: create-snapshot
              method: POST

When a Greenhouse candidate advances to the interview stage, fetches available interviewer slots from Microsoft 365 and creates calendar invites for the interview panel.

naftiko: "0.5"
info:
  label: "Greenhouse Candidate Interview Scheduler"
  description: "When a Greenhouse candidate advances to the interview stage, fetches available interviewer slots from Microsoft 365 and creates calendar invites for the interview panel."
  tags:
    - hr
    - recruiting
    - greenhouse
    - microsoft-365
capability:
  exposes:
    - type: mcp
      namespace: recruiting-scheduling
      port: 8080
      tools:
        - name: schedule-interview
          description: "Given a Greenhouse application ID and list of interviewer email addresses, retrieve candidate details, find common availability via Microsoft 365, and create calendar invites for the interview panel. Use when a candidate is advanced to interview stage."
          inputParameters:
            - name: application_id
              in: body
              type: string
              description: "The Greenhouse application ID for the candidate."
            - name: interviewer_emails
              in: body
              type: string
              description: "Comma-separated list of interviewer email addresses."
            - name: interview_date
              in: body
              type: string
              description: "Preferred interview date in ISO 8601 format."
          steps:
            - name: get-candidate
              type: call
              call: "greenhouse.get-application"
              with:
                application_id: "{{application_id}}"
            - name: create-invite
              type: call
              call: "msgraph.create-event"
              with:
                subject: "Interview: {{get-candidate.candidate_name}} — {{get-candidate.job_title}}"
                attendees: "{{interviewer_emails}}"
                start: "{{interview_date}}"
  consumes:
    - type: http
      namespace: greenhouse
      baseUri: "https://harvest.greenhouse.io/v1"
      authentication:
        type: basic
        username: "$secrets.greenhouse_api_key"
        password: ""
      resources:
        - name: applications
          path: "/applications/{{application_id}}"
          inputParameters:
            - name: application_id
              in: path
          operations:
            - name: get-application
              method: GET
    - type: http
      namespace: msgraph
      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

When Terraform detects infrastructure drift, creates a Jira remediation ticket, posts the drift diff to Slack, and opens a ServiceNow change request for re-alignment.

naftiko: "0.5"
info:
  label: "Infrastructure Drift Detection Response"
  description: "When Terraform detects infrastructure drift, creates a Jira remediation ticket, posts the drift diff to Slack, and opens a ServiceNow change request for re-alignment."
  tags:
    - infrastructure
    - terraform
    - jira
    - slack
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: drift-ops
      port: 8080
      tools:
        - name: handle-drift-detection
          description: "Given a Terraform workspace with drift, create a Jira ticket, notify Slack, and open a ServiceNow change request."
          inputParameters:
            - name: workspace_name
              in: body
              type: string
              description: "The Terraform workspace with detected drift."
            - name: drift_summary
              in: body
              type: string
              description: "Summary of the infrastructure drift detected."
          steps:
            - name: create-ticket
              type: call
              call: "jira-infra.create-issue"
              with:
                project: "INFRA"
                summary: "Infrastructure drift: {{workspace_name}}"
                description: "{{drift_summary}}"
                priority: "High"
            - name: notify-team
              type: call
              call: "slack-infra.post-message"
              with:
                channel: "infrastructure-alerts"
                text: "Drift detected in {{workspace_name}}: {{drift_summary}}. Jira: {{create-ticket.key}}"
            - name: create-change
              type: call
              call: "snow-infra.create-change"
              with:
                short_description: "Remediate drift: {{workspace_name}}"
                description: "Drift: {{drift_summary}}. Jira: {{create-ticket.key}}"
                type: "standard"
  consumes:
    - type: http
      namespace: jira-infra
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-infra
      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
    - type: http
      namespace: snow-infra
      baseUri: "https://bloomberg.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: changes
          path: "/table/change_request"
          operations:
            - name: create-change
              method: POST

Gathers completion metrics for all stories in a Jira epic, generates a progress summary via Anthropic, and posts to the project's Slack channel.

naftiko: "0.5"
info:
  label: "Jira Epic Completion Status Reporter"
  description: "Gathers completion metrics for all stories in a Jira epic, generates a progress summary via Anthropic, and posts to the project's Slack channel."
  tags:
    - project-management
    - jira
    - anthropic
    - slack
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: project-reporting
      port: 8080
      tools:
        - name: report-epic-status
          description: "Given a Jira epic key, gather story completion data, generate a progress summary, and post to Slack."
          inputParameters:
            - name: epic_key
              in: body
              type: string
              description: "The Jira epic key, e.g. 'PROJ-100'."
            - name: slack_channel
              in: body
              type: string
              description: "The Slack channel to post the report."
          steps:
            - name: get-epic-stories
              type: call
              call: "jira-epic.search-issues"
              with:
                jql: "'Epic Link' = {{epic_key}}"
            - name: generate-report
              type: call
              call: "anthropic-epic.create-message"
              with:
                model: "claude-opus-4-5"
                max_tokens: 1024
                system: "You are a project manager. Summarize epic progress with completion percentages and blockers."
                content: "Summarize progress for epic {{epic_key}}: {{get-epic-stories.issues}}"
            - name: post-report
              type: call
              call: "slack-epic.post-message"
              with:
                channel: "{{slack_channel}}"
                text: "Epic Status: {{epic_key}} - {{generate-report.content}}"
  consumes:
    - type: http
      namespace: jira-epic
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: search
          path: "/search"
          operations:
            - name: search-issues
              method: GET
    - type: http
      namespace: anthropic-epic
      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: slack-epic
      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

Generates a sprint planning digest from Jira by fetching open issues for a project, grouping by assignee and priority, and posting the summary to the team Slack channel.

naftiko: "0.5"
info:
  label: "Jira Sprint Planning Board Digest"
  description: "Generates a sprint planning digest from Jira by fetching open issues for a project, grouping by assignee and priority, and posting the summary to the team Slack channel."
  tags:
    - devops
    - jira
    - slack
    - sprint-planning
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: sprint-reporting
      port: 8080
      tools:
        - name: digest-sprint-board
          description: "Given a Jira project key and sprint ID, fetch all open issues, group by assignee and priority, and post a structured sprint summary to the designated Slack channel. Use at the start of sprint planning sessions."
          inputParameters:
            - name: project_key
              in: body
              type: string
              description: "The Jira project key, e.g. 'BTECH'."
            - name: sprint_id
              in: body
              type: integer
              description: "The Jira sprint ID for the planning session."
            - name: slack_channel
              in: body
              type: string
              description: "The Slack channel name to post the sprint digest to."
          steps:
            - name: get-issues
              type: call
              call: "jira.search-issues"
              with:
                jql: "project={{project_key}} AND sprint={{sprint_id}} AND status != Done"
            - name: post-digest
              type: call
              call: "slack.post-message"
              with:
                channel: "{{slack_channel}}"
                text: "Sprint {{sprint_id}} digest for {{project_key}}: {{get-issues.total}} open issues."
  consumes:
    - type: http
      namespace: jira
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issue-search
          path: "/search"
          operations:
            - name: search-issues
              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 the current status, assignee, and priority of a Jira ticket for use in status reporting and triage workflows.

naftiko: "0.5"
info:
  label: "Jira Ticket Status Lookup"
  description: "Retrieves the current status, assignee, and priority of a Jira ticket for use in status reporting and triage workflows."
  tags:
    - project-management
    - jira
    - ticket-tracking
capability:
  exposes:
    - type: mcp
      namespace: jira-ops
      port: 8080
      tools:
        - name: get-ticket-status
          description: "Given a Jira issue key, return its status, assignee, and priority. Use for quick status checks during standups or incident reviews."
          inputParameters:
            - name: issue_key
              in: body
              type: string
              description: "The Jira issue key, e.g. 'BBERG-1234'."
          call: "jira-lookup.get-issue"
          with:
            issue_key: "{{issue_key}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.fields.status.name"
            - name: assignee
              type: string
              mapping: "$.fields.assignee.displayName"
            - name: priority
              type: string
              mapping: "$.fields.priority.name"
  consumes:
    - type: http
      namespace: jira-lookup
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue/{{issue_key}}"
          inputParameters:
            - name: issue_key
              in: path
          operations:
            - name: get-issue
              method: GET

Fetches follower growth and post engagement metrics from Bloomberg's LinkedIn company page and posts a weekly digest to the marketing Slack channel.

naftiko: "0.5"
info:
  label: "LinkedIn Company Page Performance Digest"
  description: "Fetches follower growth and post engagement metrics from Bloomberg's LinkedIn company page and posts a weekly digest to the marketing Slack channel."
  tags:
    - marketing
    - social
    - linkedin
    - slack
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: social-reporting
      port: 8080
      tools:
        - name: digest-linkedin-performance
          description: "Fetch weekly follower growth and top post engagement metrics from Bloomberg's LinkedIn company page and post a summary to the marketing Slack channel. Use for weekly social performance reviews."
          inputParameters:
            - name: start_date
              in: body
              type: string
              description: "The start date for the reporting period in ISO 8601 format, e.g. '2026-03-13'."
            - name: end_date
              in: body
              type: string
              description: "The end date for the reporting period in ISO 8601 format, e.g. '2026-03-20'."
          steps:
            - name: get-follower-stats
              type: call
              call: "linkedin.get-follower-stats"
              with:
                organization_id: "$secrets.bloomberg_linkedin_org_id"
            - name: get-share-stats
              type: call
              call: "linkedin-shares.get-share-stats"
              with:
                organization_id: "$secrets.bloomberg_linkedin_org_id"
                start: "{{start_date}}"
                end: "{{end_date}}"
            - name: post-digest
              type: call
              call: "slack.post-message"
              with:
                channel: "marketing-analytics"
                text: "LinkedIn weekly digest ({{start_date}} to {{end_date}}): followers {{get-follower-stats.follower_count}}, impressions {{get-share-stats.impression_count}}, engagement {{get-share-stats.engagement_count}}."
  consumes:
    - type: http
      namespace: linkedin
      baseUri: "https://api.linkedin.com/v2"
      authentication:
        type: bearer
        token: "$secrets.linkedin_token"
      resources:
        - name: follower-stats
          path: "/organizationalEntityFollowerStatistics"
          operations:
            - name: get-follower-stats
              method: GET
    - type: http
      namespace: linkedin-shares
      baseUri: "https://api.linkedin.com/v2"
      authentication:
        type: bearer
        token: "$secrets.linkedin_token"
      resources:
        - name: share-stats
          path: "/organizationalEntityShareStatistics"
          operations:
            - name: get-share-stats
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When Bloomberg market data feed latency exceeds threshold in Datadog, creates a P1 ServiceNow incident, alerts the data operations team on Slack, and triggers a PagerDuty page.

naftiko: "0.5"
info:
  label: "Market Data Feed Interruption Handler"
  description: "When Bloomberg market data feed latency exceeds threshold in Datadog, creates a P1 ServiceNow incident, alerts the data operations team on Slack, and triggers a PagerDuty page."
  tags:
    - market-data
    - incident-response
    - datadog
    - servicenow
    - slack
    - pagerduty
capability:
  exposes:
    - type: mcp
      namespace: feed-ops
      port: 8080
      tools:
        - name: handle-feed-interruption
          description: "Given a Datadog alert for market data feed latency, create a P1 incident in ServiceNow, alert the data ops team, and page on-call via PagerDuty."
          inputParameters:
            - name: feed_name
              in: body
              type: string
              description: "Name of the affected Bloomberg data feed."
            - name: latency_ms
              in: body
              type: string
              description: "The current latency in milliseconds."
            - name: alert_url
              in: body
              type: string
              description: "Direct URL to the Datadog alert."
          steps:
            - name: create-incident
              type: call
              call: "snow-feed.create-incident"
              with:
                short_description: "[P1] Bloomberg data feed interruption: {{feed_name}}"
                description: "Latency: {{latency_ms}}ms. Alert: {{alert_url}}"
                urgency: "1"
                category: "data_feed"
            - name: alert-data-ops
              type: call
              call: "slack-feed.post-message"
              with:
                channel: "data-operations"
                text: "FEED ALERT: {{feed_name}} latency at {{latency_ms}}ms. Incident: {{create-incident.number}}. Alert: {{alert_url}}"
            - name: page-oncall
              type: call
              call: "pd-feed.create-incident"
              with:
                title: "Bloomberg Feed Interruption: {{feed_name}}"
                service_id: "$secrets.pagerduty_data_ops_service"
                urgency: "high"
  consumes:
    - type: http
      namespace: snow-feed
      baseUri: "https://bloomberg.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: slack-feed
      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
    - type: http
      namespace: pd-feed
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.pagerduty_token"
        placement: header
      resources:
        - name: incidents
          path: "/incidents"
          operations:
            - name: create-incident
              method: POST

After a Microsoft Teams meeting, extracts action items using Anthropic Claude, creates Jira tickets for each, and posts a summary to the team's Slack channel.

naftiko: "0.5"
info:
  label: "Microsoft Teams Meeting Action Item Tracker"
  description: "After a Microsoft Teams meeting, extracts action items using Anthropic Claude, creates Jira tickets for each, and posts a summary to the team's Slack channel."
  tags:
    - productivity
    - microsoft-teams
    - anthropic
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: meeting-ops
      port: 8080
      tools:
        - name: extract-meeting-actions
          description: "Given a Teams meeting transcript, extract action items via Anthropic, create Jira tickets, and post summary to Slack."
          inputParameters:
            - name: meeting_id
              in: body
              type: string
              description: "The Microsoft Teams meeting ID."
            - name: project_key
              in: body
              type: string
              description: "The Jira project key for action items."
          steps:
            - name: get-transcript
              type: call
              call: "teams-meetings.get-transcript"
              with:
                meeting_id: "{{meeting_id}}"
            - name: extract-actions
              type: call
              call: "anthropic-actions.create-message"
              with:
                model: "claude-opus-4-5"
                max_tokens: 2048
                system: "Extract action items from the meeting transcript. Format each as: assignee, task description, due date."
                content: "{{get-transcript.content}}"
            - name: notify-team
              type: call
              call: "slack-meetings.post-message"
              with:
                channel: "team-actions"
                text: "Meeting action items from {{meeting_id}}: {{extract-actions.content}}"
  consumes:
    - type: http
      namespace: teams-meetings
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: transcripts
          path: "/me/onlineMeetings/{{meeting_id}}/transcripts"
          inputParameters:
            - name: meeting_id
              in: path
          operations:
            - name: get-transcript
              method: GET
    - type: http
      namespace: anthropic-actions
      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: slack-meetings
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a new hire starts, provisions their Okta account, creates GitHub org membership, assigns Jira project access, and notifies the hiring manager on Slack.

naftiko: "0.5"
info:
  label: "New Hire IT Provisioning Orchestrator"
  description: "When a new hire starts, provisions their Okta account, creates GitHub org membership, assigns Jira project access, and notifies the hiring manager on Slack."
  tags:
    - hr
    - onboarding
    - okta
    - github
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: it-provisioning
      port: 8080
      tools:
        - name: provision-new-hire
          description: "Given new hire details, create Okta account, add to GitHub org, assign Jira access, and notify hiring manager via Slack."
          inputParameters:
            - name: employee_name
              in: body
              type: string
              description: "The new hire's full name."
            - name: email
              in: body
              type: string
              description: "The new hire's corporate email."
            - name: department
              in: body
              type: string
              description: "The department the new hire is joining."
            - name: manager_slack_id
              in: body
              type: string
              description: "Slack user ID of the hiring manager."
          steps:
            - name: create-okta-user
              type: call
              call: "okta-prov.create-user"
              with:
                email: "{{email}}"
                firstName: "{{employee_name}}"
                department: "{{department}}"
            - name: add-github-member
              type: call
              call: "gh-prov.add-org-member"
              with:
                username: "{{email}}"
                role: "member"
            - name: add-jira-access
              type: call
              call: "jira-prov.add-user-to-group"
              with:
                email: "{{email}}"
                group: "{{department}}-developers"
            - name: notify-manager
              type: call
              call: "slack-prov.post-message"
              with:
                channel: "{{manager_slack_id}}"
                text: "IT provisioning complete for {{employee_name}} ({{email}}). Okta, GitHub, and Jira access have been configured."
  consumes:
    - type: http
      namespace: okta-prov
      baseUri: "https://bloomberg.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_api_token"
        placement: header
      resources:
        - name: users
          path: "/users"
          operations:
            - name: create-user
              method: POST
    - type: http
      namespace: gh-prov
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: members
          path: "/orgs/bloomberg/memberships/{{username}}"
          inputParameters:
            - name: username
              in: path
          operations:
            - name: add-org-member
              method: PUT
    - type: http
      namespace: jira-prov
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: groups
          path: "/group/user"
          operations:
            - name: add-user-to-group
              method: POST
    - type: http
      namespace: slack-prov
      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 vendor record in SAP, provisions access in Okta, creates an onboarding checklist in Jira, and notifies procurement on Slack.

naftiko: "0.5"
info:
  label: "New Vendor Onboarding Orchestrator"
  description: "Creates a vendor record in SAP, provisions access in Okta, creates an onboarding checklist in Jira, and notifies procurement on Slack."
  tags:
    - procurement
    - sap
    - okta
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: vendor-onboard
      port: 8080
      tools:
        - name: onboard-new-vendor
          description: "Given vendor details, create SAP record, provision Okta access, create Jira checklist, and notify procurement."
          inputParameters:
            - name: vendor_name
              in: body
              type: string
              description: "The vendor company name."
            - name: contact_email
              in: body
              type: string
              description: "The vendor primary contact email."
            - name: service_category
              in: body
              type: string
              description: "The vendor service category."
          steps:
            - name: create-sap-vendor
              type: call
              call: "sap-vendor.create-business-partner"
              with:
                name: "{{vendor_name}}"
                email: "{{contact_email}}"
                category: "{{service_category}}"
            - name: provision-access
              type: call
              call: "okta-vendor.create-user"
              with:
                email: "{{contact_email}}"
                group: "external-vendors"
            - name: create-checklist
              type: call
              call: "jira-vendor.create-issue"
              with:
                project: "PROC"
                summary: "Vendor onboarding: {{vendor_name}}"
                description: "Contact: {{contact_email}}. Category: {{service_category}}. SAP: {{create-sap-vendor.vendor_id}}"
                issue_type: "Task"
            - name: notify-procurement
              type: call
              call: "slack-vendor.post-message"
              with:
                channel: "procurement"
                text: "New vendor onboarded: {{vendor_name}} ({{service_category}}). SAP: {{create-sap-vendor.vendor_id}}. Jira: {{create-checklist.key}}"
  consumes:
    - type: http
      namespace: sap-vendor
      baseUri: "https://sap.bloomberg.com/sap/opu/odata/sap"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: partners
          path: "/API_BUSINESS_PARTNER/A_BusinessPartner"
          operations:
            - name: create-business-partner
              method: POST
    - type: http
      namespace: okta-vendor
      baseUri: "https://bloomberg.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_api_token"
        placement: header
      resources:
        - name: users
          path: "/users"
          operations:
            - name: create-user
              method: POST
    - type: http
      namespace: jira-vendor
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-vendor
      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

Launches a quarterly Okta access review campaign, generates a user access report, sends review requests to managers via Slack, and tracks completion in Jira.

naftiko: "0.5"
info:
  label: "Okta Access Certification Campaign"
  description: "Launches a quarterly Okta access review campaign, generates a user access report, sends review requests to managers via Slack, and tracks completion in Jira."
  tags:
    - identity
    - okta
    - slack
    - jira
    - access-management
capability:
  exposes:
    - type: mcp
      namespace: access-cert
      port: 8080
      tools:
        - name: launch-access-certification
          description: "Launch a quarterly access certification campaign across Okta, send review requests, and track in Jira."
          inputParameters:
            - name: quarter
              in: body
              type: string
              description: "The quarter for the review, e.g. 'Q1-2026'."
            - name: app_name
              in: body
              type: string
              description: "The Okta application to review."
          steps:
            - name: get-app-users
              type: call
              call: "okta-cert.get-app-users"
              with:
                app_name: "{{app_name}}"
            - name: create-tracking-epic
              type: call
              call: "jira-cert.create-issue"
              with:
                project: "SEC"
                summary: "Access certification: {{app_name}} {{quarter}}"
                description: "Quarterly access review for {{app_name}}. Users: {{get-app-users.count}}"
                issue_type: "Epic"
            - name: notify-managers
              type: call
              call: "slack-cert.post-message"
              with:
                channel: "access-reviews"
                text: "Quarterly access certification launched: {{app_name}} ({{quarter}}). {{get-app-users.count}} users to review. Epic: {{create-tracking-epic.key}}"
  consumes:
    - type: http
      namespace: okta-cert
      baseUri: "https://bloomberg.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_api_token"
        placement: header
      resources:
        - name: app-users
          path: "/apps/{{app_name}}/users"
          inputParameters:
            - name: app_name
              in: path
          operations:
            - name: get-app-users
              method: GET
    - type: http
      namespace: jira-cert
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-cert
      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

Identifies Okta users in a given group who have not enrolled in MFA, sends them a Teams reminder, and escalates to their manager in Workday if enrollment is not completed within 24 hours.

naftiko: "0.5"
info:
  label: "Okta MFA Enrollment Enforcement"
  description: "Identifies Okta users in a given group who have not enrolled in MFA, sends them a Teams reminder, and escalates to their manager in Workday if enrollment is not completed within 24 hours."
  tags:
    - identity
    - security
    - okta
    - workday
    - microsoft-teams
    - compliance
capability:
  exposes:
    - type: mcp
      namespace: security-compliance
      port: 8080
      tools:
        - name: enforce-mfa-enrollment
          description: "Given an Okta group ID, find users without MFA enrolled, send them a Teams message requesting enrollment, and identify their Workday managers for escalation. Use for security compliance enforcement cycles."
          inputParameters:
            - name: okta_group_id
              in: body
              type: string
              description: "The Okta group ID to audit for MFA enrollment."
          steps:
            - name: list-group-users
              type: call
              call: "okta.list-group-members"
              with:
                group_id: "{{okta_group_id}}"
            - name: notify-users
              type: call
              call: "msteams.send-message"
              with:
                recipient_upn: "{{list-group-users.email}}"
                text: "Action required: Please enroll in MFA within 24 hours to maintain Bloomberg system access."
  consumes:
    - type: http
      namespace: okta
      baseUri: "https://bloomberg.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: list-group-members
              method: GET
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: mail
          path: "/users/{{recipient_upn}}/sendMail"
          inputParameters:
            - name: recipient_upn
              in: path
          operations:
            - name: send-message
              method: POST

When Okta detects a suspicious login, blocks the session, creates a ServiceNow security incident, and alerts the security team on Slack.

naftiko: "0.5"
info:
  label: "Okta Suspicious Login Response"
  description: "When Okta detects a suspicious login, blocks the session, creates a ServiceNow security incident, and alerts the security team on Slack."
  tags:
    - security
    - okta
    - servicenow
    - slack
    - threat-detection
capability:
  exposes:
    - type: mcp
      namespace: security-response
      port: 8080
      tools:
        - name: handle-suspicious-login
          description: "Given an Okta suspicious login event, block the session, create a security incident, and notify the security team."
          inputParameters:
            - name: user_email
              in: body
              type: string
              description: "The email of the user with suspicious activity."
            - name: event_type
              in: body
              type: string
              description: "The type of suspicious event detected."
            - name: ip_address
              in: body
              type: string
              description: "The source IP address."
          steps:
            - name: block-session
              type: call
              call: "okta-sec.clear-user-sessions"
              with:
                email: "{{user_email}}"
            - name: create-incident
              type: call
              call: "snow-sec.create-incident"
              with:
                short_description: "Suspicious login: {{user_email}} from {{ip_address}}"
                description: "Event: {{event_type}}. User sessions cleared. IP: {{ip_address}}"
                category: "security"
                urgency: "1"
            - name: alert-security
              type: call
              call: "slack-sec.post-message"
              with:
                channel: "security-alerts"
                text: "SUSPICIOUS LOGIN: {{user_email}} from {{ip_address}}. Event: {{event_type}}. Sessions cleared. Incident: {{create-incident.number}}"
  consumes:
    - type: http
      namespace: okta-sec
      baseUri: "https://bloomberg.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_api_token"
        placement: header
      resources:
        - name: sessions
          path: "/users/{{email}}/sessions"
          inputParameters:
            - name: email
              in: path
          operations:
            - name: clear-user-sessions
              method: DELETE
    - type: http
      namespace: snow-sec
      baseUri: "https://bloomberg.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incidents
          path: "/table/incident"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: slack-sec
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Fetches all users assigned to a specific Okta application and generates a Confluence access review report for compliance auditing.

naftiko: "0.5"
info:
  label: "Okta User Access Review"
  description: "Fetches all users assigned to a specific Okta application and generates a Confluence access review report for compliance auditing."
  tags:
    - identity
    - security
    - okta
    - confluence
    - compliance
    - access-management
capability:
  exposes:
    - type: mcp
      namespace: identity-compliance
      port: 8080
      tools:
        - name: run-access-review
          description: "Given an Okta application ID and Confluence page ID, fetch all users assigned to the application and update the Confluence access review page with current membership. Use for quarterly access reviews and compliance audits."
          inputParameters:
            - name: okta_app_id
              in: body
              type: string
              description: "The Okta application ID to review, e.g. '0oa1b2c3d4e5f6g7h8i9'."
            - name: confluence_page_id
              in: body
              type: string
              description: "The Confluence page ID where the access review report will be published."
          steps:
            - name: list-app-users
              type: call
              call: "okta.list-app-users"
              with:
                app_id: "{{okta_app_id}}"
            - name: update-report
              type: call
              call: "confluence.update-page"
              with:
                page_id: "{{confluence_page_id}}"
                content: "Access review for app {{okta_app_id}}: {{list-app-users.count}} users as of today."
  consumes:
    - type: http
      namespace: okta
      baseUri: "https://bloomberg.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_api_token"
        placement: header
      resources:
        - name: app-users
          path: "/apps/{{app_id}}/users"
          inputParameters:
            - name: app_id
              in: path
          operations:
            - name: list-app-users
              method: GET
    - type: http
      namespace: confluence
      baseUri: "https://bloomberg.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: pages
          path: "/content/{{page_id}}"
          inputParameters:
            - name: page_id
              in: path
          operations:
            - name: update-page
              method: PUT

Retrieves the list of Okta groups a user belongs to for access review and compliance checks.

naftiko: "0.5"
info:
  label: "Okta User Group Membership Lookup"
  description: "Retrieves the list of Okta groups a user belongs to for access review and compliance checks."
  tags:
    - identity
    - okta
    - access-management
capability:
  exposes:
    - type: mcp
      namespace: identity-ops
      port: 8080
      tools:
        - name: get-user-groups
          description: "Given an Okta user email, return the list of groups they belong to. Use for quarterly access reviews."
          inputParameters:
            - name: user_email
              in: body
              type: string
              description: "The user's email address in Okta."
          call: "okta-groups.get-user-groups"
          with:
            email: "{{user_email}}"
          outputParameters:
            - name: groups
              type: array
              mapping: "$.groups[*].profile.name"
  consumes:
    - type: http
      namespace: okta-groups
      baseUri: "https://bloomberg.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_api_token"
        placement: header
      resources:
        - name: user-groups
          path: "/users/{{email}}/groups"
          inputParameters:
            - name: email
              in: path
          operations:
            - name: get-user-groups
              method: GET

When a hiring manager approves a new headcount request in Workday, creates a linked Greenhouse job requisition and posts it to LinkedIn.

naftiko: "0.5"
info:
  label: "Open Role Requisition Creator"
  description: "When a hiring manager approves a new headcount request in Workday, creates a linked Greenhouse job requisition and posts it to LinkedIn."
  tags:
    - hr
    - recruiting
    - workday
    - greenhouse
    - linkedin
capability:
  exposes:
    - type: mcp
      namespace: recruiting
      port: 8080
      tools:
        - name: create-requisition
          description: "Given a department, role title, level, and hiring manager Workday ID, create a Greenhouse job requisition and post the opening to LinkedIn. Invoke when a headcount request has been approved."
          inputParameters:
            - name: role_title
              in: body
              type: string
              description: "The job title for the open role, e.g. 'Senior Software Engineer'."
            - name: department
              in: body
              type: string
              description: "The Bloomberg department code, e.g. 'BTECH-CORE'."
            - name: hiring_manager_id
              in: body
              type: string
              description: "The Workday worker ID of the hiring manager."
          steps:
            - name: get-manager
              type: call
              call: "workday.get-worker"
              with:
                worker_id: "{{hiring_manager_id}}"
            - name: create-job
              type: call
              call: "greenhouse.create-job"
              with:
                title: "{{role_title}}"
                department: "{{department}}"
                hiring_manager_name: "{{get-manager.full_name}}"
            - name: post-to-linkedin
              type: call
              call: "linkedin.create-job-posting"
              with:
                job_id: "{{create-job.id}}"
                title: "{{role_title}}"
                company_id: "$secrets.bloomberg_linkedin_company_id"
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/bloomberg/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET
    - type: http
      namespace: greenhouse
      baseUri: "https://harvest.greenhouse.io/v1"
      authentication:
        type: basic
        username: "$secrets.greenhouse_api_key"
        password: ""
      resources:
        - name: jobs
          path: "/jobs"
          operations:
            - name: create-job
              method: POST
    - type: http
      namespace: linkedin
      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

After a PagerDuty incident is resolved, gathers timeline from PagerDuty, generates a post-mortem via Anthropic Claude, and publishes to Confluence.

naftiko: "0.5"
info:
  label: "PagerDuty Incident Post-Mortem Generator"
  description: "After a PagerDuty incident is resolved, gathers timeline from PagerDuty, generates a post-mortem via Anthropic Claude, and publishes to Confluence."
  tags:
    - incident-response
    - pagerduty
    - anthropic
    - confluence
    - post-mortem
capability:
  exposes:
    - type: mcp
      namespace: postmortem-ops
      port: 8080
      tools:
        - name: generate-post-mortem
          description: "Given a resolved PagerDuty incident ID, gather the timeline, generate a post-mortem, and publish to Confluence."
          inputParameters:
            - name: incident_id
              in: body
              type: string
              description: "The PagerDuty incident ID."
          steps:
            - name: get-incident
              type: call
              call: "pd-pm.get-incident"
              with:
                incident_id: "{{incident_id}}"
            - name: generate-report
              type: call
              call: "anthropic-pm.create-message"
              with:
                model: "claude-opus-4-5"
                max_tokens: 4096
                system: "You are an SRE writing a blameless post-mortem. Include timeline, root cause, impact, and action items."
                content: "Generate a post-mortem for this incident: {{get-incident.data}}"
            - name: publish-postmortem
              type: call
              call: "confluence-pm.create-page"
              with:
                space: "SRE"
                title: "Post-Mortem: {{get-incident.title}}"
                body: "{{generate-report.content}}"
  consumes:
    - type: http
      namespace: pd-pm
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.pagerduty_token"
        placement: header
      resources:
        - name: incidents
          path: "/incidents/{{incident_id}}"
          inputParameters:
            - name: incident_id
              in: path
          operations:
            - name: get-incident
              method: GET
    - type: http
      namespace: anthropic-pm
      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: confluence-pm
      baseUri: "https://bloomberg.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_api_token"
      resources:
        - name: pages
          path: "/content"
          operations:
            - name: create-page
              method: POST

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

naftiko: "0.5"
info:
  label: "PagerDuty On-Call Schedule Lookup"
  description: "Retrieves the current on-call engineer for a given PagerDuty schedule for incident routing."
  tags:
    - incident-response
    - pagerduty
    - on-call
capability:
  exposes:
    - type: mcp
      namespace: oncall-ops
      port: 8080
      tools:
        - name: get-current-oncall
          description: "Given a PagerDuty schedule ID, return the currently on-call engineer's name and contact info. Use for incident routing."
          inputParameters:
            - name: schedule_id
              in: body
              type: string
              description: "The PagerDuty schedule ID."
          call: "pd-oncall.get-oncall"
          with:
            schedule_id: "{{schedule_id}}"
          outputParameters:
            - name: user_name
              type: string
              mapping: "$.oncalls[0].user.summary"
            - name: user_email
              type: string
              mapping: "$.oncalls[0].user.email"
  consumes:
    - type: http
      namespace: pd-oncall
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.pagerduty_token"
        placement: header
      resources:
        - name: oncalls
          path: "/oncalls"
          operations:
            - name: get-oncall
              method: GET

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

naftiko: "0.5"
info:
  label: "Payroll Headcount Snapshot"
  description: "Returns current headcount by department and cost center from Workday, formatted for finance reporting and headcount planning."
  tags:
    - hr
    - finance
    - workday
    - reporting
    - headcount
capability:
  exposes:
    - type: mcp
      namespace: hr-reporting
      port: 8080
      tools:
        - name: get-headcount-snapshot
          description: "Returns a list of all active employees grouped by department and cost center from Workday. Use for headcount planning, finance reporting, and cost center analysis."
          call: "workday.list-workers"
          outputParameters:
            - name: employees
              type: array
              mapping: "$.data[*]"
  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: "/bloomberg/workers"
          operations:
            - name: list-workers
              method: GET

Checks the last refresh status of a Power BI dataset to verify dashboards are current.

naftiko: "0.5"
info:
  label: "Power BI Dataset Refresh Status"
  description: "Checks the last refresh status of a Power BI dataset to verify dashboards are current."
  tags:
    - analytics
    - power-bi
    - dashboards
capability:
  exposes:
    - type: mcp
      namespace: bi-ops
      port: 8080
      tools:
        - name: get-dataset-refresh-status
          description: "Given a Power BI dataset ID, return the last refresh timestamp and status. Use for dashboard freshness monitoring."
          inputParameters:
            - name: dataset_id
              in: body
              type: string
              description: "The Power BI dataset ID."
          call: "pbi-refresh.get-refresh-history"
          with:
            dataset_id: "{{dataset_id}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.value[0].status"
            - name: end_time
              type: string
              mapping: "$.value[0].endTime"
  consumes:
    - type: http
      namespace: pbi-refresh
      baseUri: "https://api.powerbi.com/v1.0/myorg"
      authentication:
        type: bearer
        token: "$secrets.powerbi_token"
      resources:
        - name: refreshes
          path: "/datasets/{{dataset_id}}/refreshes"
          inputParameters:
            - name: dataset_id
              in: path
          operations:
            - name: get-refresh-history
              method: GET

Gathers compliance evidence from Okta access logs, GitHub audit logs, and ServiceNow change records, assembles an evidence package, and publishes to Confluence.

naftiko: "0.5"
info:
  label: "Quarterly Compliance Evidence Collector"
  description: "Gathers compliance evidence from Okta access logs, GitHub audit logs, and ServiceNow change records, assembles an evidence package, and publishes to Confluence."
  tags:
    - compliance
    - okta
    - github
    - servicenow
    - confluence
capability:
  exposes:
    - type: mcp
      namespace: compliance-evidence
      port: 8080
      tools:
        - name: collect-compliance-evidence
          description: "Gather access logs from Okta, audit logs from GitHub, change records from ServiceNow, and publish evidence to Confluence."
          inputParameters:
            - name: quarter
              in: body
              type: string
              description: "The quarter for evidence collection, e.g. 'Q1-2026'."
            - name: control_id
              in: body
              type: string
              description: "The compliance control ID."
          steps:
            - name: get-access-logs
              type: call
              call: "okta-evidence.get-system-log"
              with:
                since: "{{quarter}}"
                filter: "eventType eq \"user.session.start\""
            - name: get-audit-logs
              type: call
              call: "gh-evidence.get-audit-log"
              with:
                org: "bloomberg"
                since: "{{quarter}}"
            - name: get-changes
              type: call
              call: "snow-evidence.get-changes"
              with:
                quarter: "{{quarter}}"
            - name: publish-evidence
              type: call
              call: "confluence-evidence.create-page"
              with:
                space: "COMPLIANCE"
                title: "Evidence Package: {{control_id}} - {{quarter}}"
                body: "Access logs: {{get-access-logs.count}} entries. Audit events: {{get-audit-logs.count}}. Changes: {{get-changes.count}}"
  consumes:
    - type: http
      namespace: okta-evidence
      baseUri: "https://bloomberg.okta.com/api/v1"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.okta_api_token"
        placement: header
      resources:
        - name: logs
          path: "/logs"
          operations:
            - name: get-system-log
              method: GET
    - type: http
      namespace: gh-evidence
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: audit
          path: "/orgs/{{org}}/audit-log"
          inputParameters:
            - name: org
              in: path
          operations:
            - name: get-audit-log
              method: GET
    - type: http
      namespace: snow-evidence
      baseUri: "https://bloomberg.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: changes
          path: "/table/change_request"
          operations:
            - name: get-changes
              method: GET
    - type: http
      namespace: confluence-evidence
      baseUri: "https://bloomberg.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_api_token"
      resources:
        - name: pages
          path: "/content"
          operations:
            - name: create-page
              method: POST

Pulls earnings data from Bloomberg Company Financials, generates an executive summary via Anthropic, and publishes it to a Confluence page for analyst review.

naftiko: "0.5"
info:
  label: "Quarterly Earnings Report Assembler"
  description: "Pulls earnings data from Bloomberg Company Financials, generates an executive summary via Anthropic, and publishes it to a Confluence page for analyst review."
  tags:
    - financial-data
    - bloomberg-company-financials
    - anthropic
    - confluence
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: earnings-ops
      port: 8080
      tools:
        - name: assemble-earnings-report
          description: "Given a company ticker and quarter, pull Bloomberg earnings data, generate an AI summary, and publish to Confluence."
          inputParameters:
            - name: ticker
              in: body
              type: string
              description: "The Bloomberg company ticker, e.g. 'MSFT US Equity'."
            - name: quarter
              in: body
              type: string
              description: "The fiscal quarter, e.g. 'Q1 2026'."
          steps:
            - name: pull-earnings
              type: call
              call: "bbg-earn.get-earnings"
              with:
                ticker: "{{ticker}}"
                period: "{{quarter}}"
            - name: generate-summary
              type: call
              call: "anthropic-earn.create-message"
              with:
                model: "claude-opus-4-5"
                max_tokens: 2048
                system: "You are a financial analyst. Write a concise earnings summary."
                content: "Summarize these earnings for {{ticker}} {{quarter}}: {{pull-earnings.data}}"
            - name: publish-page
              type: call
              call: "confluence-earn.create-page"
              with:
                space: "RESEARCH"
                title: "Earnings Summary: {{ticker}} {{quarter}}"
                body: "{{generate-summary.content}}"
  consumes:
    - type: http
      namespace: bbg-earn
      baseUri: "https://api.bloomberg.com/eap/catalogs/bbg/data"
      authentication:
        type: bearer
        token: "$secrets.bloomberg_data_token"
      resources:
        - name: earnings
          path: "/fields/{{ticker}}/earnings"
          inputParameters:
            - name: ticker
              in: path
          operations:
            - name: get-earnings
              method: GET
    - type: http
      namespace: anthropic-earn
      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: confluence-earn
      baseUri: "https://bloomberg.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_api_token"
      resources:
        - name: pages
          path: "/content"
          operations:
            - name: create-page
              method: POST

Fetches key account health metrics from Salesforce CRM for a given client, enriches with recent news from Bloomberg Terminal API, and delivers a briefing to the account manager via Slack.

naftiko: "0.5"
info:
  label: "Salesforce Account Health Digest"
  description: "Fetches key account health metrics from Salesforce CRM for a given client, enriches with recent news from Bloomberg Terminal API, and delivers a briefing to the account manager via Slack."
  tags:
    - crm
    - sales
    - salesforce
    - slack
    - reporting
    - account-management
capability:
  exposes:
    - type: mcp
      namespace: crm-reporting
      port: 8080
      tools:
        - name: digest-account-health
          description: "Given a Salesforce account ID, retrieve account health data including open opportunities and recent activity, then post an account briefing to the responsible account manager's Slack DM. Use before client meetings or for weekly account reviews."
          inputParameters:
            - name: salesforce_account_id
              in: body
              type: string
              description: "The Salesforce Account ID (18-character), e.g. '0010000000ABcDEFGH'."
            - name: account_manager_slack_id
              in: body
              type: string
              description: "The Slack user ID of the account manager to receive the briefing."
          steps:
            - name: get-account
              type: call
              call: "salesforce.get-account"
              with:
                account_id: "{{salesforce_account_id}}"
            - name: get-opportunities
              type: call
              call: "salesforce-opps.list-opportunities"
              with:
                account_id: "{{salesforce_account_id}}"
            - name: post-briefing
              type: call
              call: "slack.post-dm"
              with:
                user_id: "{{account_manager_slack_id}}"
                text: "Account brief for {{get-account.Name}}: {{get-opportunities.count}} open opportunities totaling ${{get-opportunities.total_amount}}. Last activity: {{get-account.LastActivityDate}}."
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://bloomberg.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://bloomberg.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: opportunities
          path: "/sobjects/Opportunity"
          operations:
            - name: list-opportunities
              method: GET
    - type: http
      namespace: slack
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: dm-messages
          path: "/chat.postMessage"
          operations:
            - name: post-dm
              method: POST

Retrieves Salesforce account details including industry, revenue tier, and account owner for sales enablement workflows.

naftiko: "0.5"
info:
  label: "Salesforce Account Lookup"
  description: "Retrieves Salesforce account details including industry, revenue tier, and account owner for sales enablement workflows."
  tags:
    - crm
    - salesforce
    - account-management
capability:
  exposes:
    - type: mcp
      namespace: crm-ops
      port: 8080
      tools:
        - name: get-account-details
          description: "Given a Salesforce account ID, return account details including owner, industry, and tier. Use for account health checks and sales planning."
          inputParameters:
            - name: account_id
              in: body
              type: string
              description: "The Salesforce account ID."
          call: "sf-account.get-account"
          with:
            account_id: "{{account_id}}"
          outputParameters:
            - name: name
              type: string
              mapping: "$.Name"
            - name: industry
              type: string
              mapping: "$.Industry"
            - name: owner
              type: string
              mapping: "$.Owner.Name"
  consumes:
    - type: http
      namespace: sf-account
      baseUri: "https://bloomberg.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

When a new Salesforce lead is created, enriches it with company data from Bloomberg Enterprise Data, scores the lead, and notifies the sales rep on Slack.

naftiko: "0.5"
info:
  label: "Salesforce Lead Qualification Enrichment"
  description: "When a new Salesforce lead is created, enriches it with company data from Bloomberg Enterprise Data, scores the lead, and notifies the sales rep on Slack."
  tags:
    - crm
    - salesforce
    - bloomberg-enterprise-data
    - slack
    - lead-management
capability:
  exposes:
    - type: mcp
      namespace: lead-ops
      port: 8080
      tools:
        - name: enrich-and-qualify-lead
          description: "Given a new Salesforce lead, enrich with Bloomberg data and notify the sales rep."
          inputParameters:
            - name: lead_id
              in: body
              type: string
              description: "The Salesforce lead ID."
            - name: company_name
              in: body
              type: string
              description: "The lead's company name."
          steps:
            - name: get-company-data
              type: call
              call: "bbg-data.get-company-profile"
              with:
                company: "{{company_name}}"
            - name: update-lead
              type: call
              call: "sf-lead.update-lead"
              with:
                lead_id: "{{lead_id}}"
                industry: "{{get-company-data.industry}}"
                revenue: "{{get-company-data.revenue}}"
            - name: notify-rep
              type: call
              call: "slack-sales.post-message"
              with:
                channel: "sales-leads"
                text: "New enriched lead: {{company_name}}. Industry: {{get-company-data.industry}}. Revenue: {{get-company-data.revenue}}."
  consumes:
    - type: http
      namespace: bbg-data
      baseUri: "https://api.bloomberg.com/enterprise/v1"
      authentication:
        type: apikey
        key: "X-Bloomberg-Key"
        value: "$secrets.bloomberg_enterprise_key"
        placement: header
      resources:
        - name: companies
          path: "/companies/{{company}}"
          inputParameters:
            - name: company
              in: path
          operations:
            - name: get-company-profile
              method: GET
    - type: http
      namespace: sf-lead
      baseUri: "https://bloomberg.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
    - type: http
      namespace: slack-sales
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

When a new Salesforce lead is created, enriches the record with firmographic data from ZoomInfo and updates the lead score, then routes to the correct sales development representative.

naftiko: "0.5"
info:
  label: "Salesforce New Lead Enrichment"
  description: "When a new Salesforce lead is created, enriches the record with firmographic data from ZoomInfo and updates the lead score, then routes to the correct sales development representative."
  tags:
    - crm
    - sales
    - salesforce
    - zoominfo
    - lead-management
capability:
  exposes:
    - type: mcp
      namespace: lead-enrichment
      port: 8080
      tools:
        - name: enrich-new-lead
          description: "Given a Salesforce lead ID, look up the company and contact in ZoomInfo to get firmographic data, update the Salesforce lead with enriched fields, and assign to the appropriate SDR. Use when a new inbound lead is created."
          inputParameters:
            - name: lead_id
              in: body
              type: string
              description: "The Salesforce Lead ID (18-character)."
          steps:
            - name: get-lead
              type: call
              call: "salesforce.get-lead"
              with:
                lead_id: "{{lead_id}}"
            - name: enrich-company
              type: call
              call: "zoominfo.search-company"
              with:
                name: "{{get-lead.Company}}"
                domain: "{{get-lead.Website}}"
            - name: update-lead
              type: call
              call: "salesforce-update.update-lead"
              with:
                lead_id: "{{lead_id}}"
                NumberOfEmployees: "{{enrich-company.employeeCount}}"
                AnnualRevenue: "{{enrich-company.revenue}}"
                Industry: "{{enrich-company.industry}}"
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://bloomberg.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-update
      baseUri: "https://bloomberg.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: lead-update
          path: "/sobjects/Lead/{{lead_id}}"
          inputParameters:
            - name: lead_id
              in: path
          operations:
            - name: update-lead
              method: PATCH

When a Salesforce opportunity is marked as Closed-Won, triggers a welcome email via HubSpot, creates an onboarding project in Jira, and notifies the account team on Slack.

naftiko: "0.5"
info:
  label: "Salesforce Opportunity Closure Workflow"
  description: "When a Salesforce opportunity is marked as Closed-Won, triggers a welcome email via HubSpot, creates an onboarding project in Jira, and notifies the account team on Slack."
  tags:
    - crm
    - salesforce
    - hubspot
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: deal-ops
      port: 8080
      tools:
        - name: process-opportunity-closure
          description: "Given a closed-won Salesforce opportunity, trigger client onboarding via HubSpot, Jira, and Slack."
          inputParameters:
            - name: opportunity_id
              in: body
              type: string
              description: "The Salesforce opportunity ID."
            - name: account_name
              in: body
              type: string
              description: "The account name for the closed deal."
            - name: deal_value
              in: body
              type: string
              description: "The deal value."
          steps:
            - name: send-welcome
              type: call
              call: "hubspot-onboard.send-email"
              with:
                template: "client-welcome"
                account: "{{account_name}}"
            - name: create-onboarding-project
              type: call
              call: "jira-onboard.create-issue"
              with:
                project: "ONBOARD"
                summary: "Client onboarding: {{account_name}}"
                description: "Opportunity: {{opportunity_id}}. Value: {{deal_value}}."
                issue_type: "Epic"
            - name: notify-team
              type: call
              call: "slack-deals.post-message"
              with:
                channel: "deal-wins"
                text: "Closed-Won: {{account_name}} ({{deal_value}}). Onboarding started. Jira: {{create-onboarding-project.key}}"
  consumes:
    - type: http
      namespace: hubspot-onboard
      baseUri: "https://api.hubapi.com"
      authentication:
        type: bearer
        token: "$secrets.hubspot_token"
      resources:
        - name: emails
          path: "/marketing/v3/transactional/single-email/send"
          operations:
            - name: send-email
              method: POST
    - type: http
      namespace: jira-onboard
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-deals
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Updates a Salesforce opportunity to the next stage when a deal milestone is confirmed, and notifies the sales team Slack channel.

naftiko: "0.5"
info:
  label: "Salesforce Opportunity Stage Update"
  description: "Updates a Salesforce opportunity to the next stage when a deal milestone is confirmed, and notifies the sales team Slack channel."
  tags:
    - crm
    - sales
    - salesforce
    - slack
capability:
  exposes:
    - type: mcp
      namespace: crm-ops
      port: 8080
      tools:
        - name: advance-opportunity-stage
          description: "Given a Salesforce opportunity ID and new stage name, update the opportunity stage and post a Slack notification to the sales team. Use when a deal milestone is confirmed by the account team."
          inputParameters:
            - name: opportunity_id
              in: body
              type: string
              description: "The Salesforce Opportunity ID (18-character)."
            - name: new_stage
              in: body
              type: string
              description: "The new stage name, e.g. 'Proposal/Price Quote', 'Negotiation/Review', 'Closed Won'."
          steps:
            - name: update-opp
              type: call
              call: "salesforce.update-opportunity"
              with:
                opportunity_id: "{{opportunity_id}}"
                StageName: "{{new_stage}}"
            - name: notify-sales
              type: call
              call: "slack.post-message"
              with:
                channel: "sales-wins"
                text: "Opportunity {{opportunity_id}} advanced to stage: {{new_stage}}."
  consumes:
    - type: http
      namespace: salesforce
      baseUri: "https://bloomberg.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: opportunities
          path: "/sobjects/Opportunity/{{opportunity_id}}"
          inputParameters:
            - name: opportunity_id
              in: path
          operations:
            - name: update-opportunity
              method: PATCH
    - type: http
      namespace: slack
      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 SAP detects a budget overrun for a cost center, creates a Jira ticket for finance review, notifies the cost center manager on Slack, and logs the event in ServiceNow.

naftiko: "0.5"
info:
  label: "SAP Budget Overrun Escalation"
  description: "When SAP detects a budget overrun for a cost center, creates a Jira ticket for finance review, notifies the cost center manager on Slack, and logs the event in ServiceNow."
  tags:
    - finance
    - sap
    - jira
    - slack
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: finance-ops
      port: 8080
      tools:
        - name: escalate-budget-overrun
          description: "Given a cost center and overrun amount, create a Jira finance ticket, notify the manager via Slack, and log in ServiceNow."
          inputParameters:
            - name: cost_center
              in: body
              type: string
              description: "The SAP cost center ID."
            - name: overrun_amount
              in: body
              type: string
              description: "The budget overrun amount."
            - name: manager_email
              in: body
              type: string
              description: "Email of the cost center manager."
          steps:
            - name: create-finance-ticket
              type: call
              call: "jira-fin.create-issue"
              with:
                project: "FIN"
                summary: "Budget overrun: Cost center {{cost_center}} exceeded by {{overrun_amount}}"
                description: "Manager: {{manager_email}}. Review and approve variance or identify reallocation."
                priority: "High"
            - name: notify-manager
              type: call
              call: "slack-fin.post-message"
              with:
                channel: "finance-alerts"
                text: "Budget overrun detected: Cost center {{cost_center}} exceeded by {{overrun_amount}}. Jira: {{create-finance-ticket.key}}. Please review."
            - name: log-event
              type: call
              call: "snow-fin.create-incident"
              with:
                short_description: "Budget overrun: {{cost_center}}"
                description: "Overrun: {{overrun_amount}}. Jira: {{create-finance-ticket.key}}"
                category: "finance"
  consumes:
    - type: http
      namespace: jira-fin
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-fin
      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
    - type: http
      namespace: snow-fin
      baseUri: "https://bloomberg.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

Queries SAP for budget and actuals data by cost center, computes variance, and publishes a formatted Power BI dataset and Slack summary for finance leadership.

naftiko: "0.5"
info:
  label: "SAP Budget vs Actuals Variance Report"
  description: "Queries SAP for budget and actuals data by cost center, computes variance, and publishes a formatted Power BI dataset and Slack summary for finance leadership."
  tags:
    - finance
    - erp
    - sap
    - reporting
    - budgeting
capability:
  exposes:
    - type: mcp
      namespace: finance-reporting
      port: 8080
      tools:
        - name: publish-budget-variance
          description: "Given a SAP controlling area and fiscal period, retrieve budget and actuals by cost center, calculate variance percentages, and post a summary to the finance Slack channel. Use monthly for budget review cycles."
          inputParameters:
            - name: controlling_area
              in: body
              type: string
              description: "The SAP controlling area code, e.g. '1000'."
            - name: fiscal_period
              in: body
              type: string
              description: "The fiscal period in YYYYMM format, e.g. '202603'."
          steps:
            - name: get-actuals
              type: call
              call: "sap.get-cost-center-actuals"
              with:
                controlling_area: "{{controlling_area}}"
                period: "{{fiscal_period}}"
            - name: post-finance-summary
              type: call
              call: "slack.post-message"
              with:
                channel: "finance-leadership"
                text: "Budget variance report for period {{fiscal_period}}: Total actuals {{get-actuals.total_actual}}, budget {{get-actuals.total_budget}}."
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://bloomberg-s4.sap.com/sap/opu/odata/sap/FCO_PI_CONTROLLING_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: cost-center-actuals
          path: "/CostCenterActualsSet"
          operations:
            - name: get-cost-center-actuals
              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 SAP Concur flags an expense report anomaly, creates a Jira audit ticket, notifies the employee's manager on Slack, and opens a ServiceNow compliance case.

naftiko: "0.5"
info:
  label: "SAP Concur Expense Anomaly Handler"
  description: "When SAP Concur flags an expense report anomaly, creates a Jira audit ticket, notifies the employee's manager on Slack, and opens a ServiceNow compliance case."
  tags:
    - finance
    - sap-concur
    - jira
    - slack
    - servicenow
capability:
  exposes:
    - type: mcp
      namespace: expense-ops
      port: 8080
      tools:
        - name: handle-expense-anomaly
          description: "Given an expense report anomaly from SAP Concur, create a Jira audit ticket, notify the manager, and log a compliance case."
          inputParameters:
            - name: report_id
              in: body
              type: string
              description: "The SAP Concur expense report ID."
            - name: employee_name
              in: body
              type: string
              description: "The employee who submitted the report."
            - name: anomaly_type
              in: body
              type: string
              description: "The type of anomaly detected."
          steps:
            - name: create-audit-ticket
              type: call
              call: "jira-audit.create-issue"
              with:
                project: "AUDIT"
                summary: "Expense anomaly: {{anomaly_type}} - {{employee_name}}"
                description: "Report: {{report_id}}. Employee: {{employee_name}}. Anomaly: {{anomaly_type}}"
                priority: "High"
            - name: notify-manager
              type: call
              call: "slack-audit.post-message"
              with:
                channel: "expense-compliance"
                text: "Expense anomaly detected: {{employee_name}} report {{report_id}}. Type: {{anomaly_type}}. Jira: {{create-audit-ticket.key}}"
            - name: log-compliance-case
              type: call
              call: "snow-audit.create-incident"
              with:
                short_description: "Expense anomaly: {{anomaly_type}} - {{employee_name}}"
                description: "Report: {{report_id}}. Jira: {{create-audit-ticket.key}}"
                category: "compliance"
  consumes:
    - type: http
      namespace: jira-audit
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-audit
      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
    - type: http
      namespace: snow-audit
      baseUri: "https://bloomberg.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

Checks the payment status of a vendor invoice in SAP to verify whether it has been processed or is pending.

naftiko: "0.5"
info:
  label: "SAP Vendor Payment Status"
  description: "Checks the payment status of a vendor invoice in SAP to verify whether it has been processed or is pending."
  tags:
    - erp
    - sap
    - accounts-payable
    - finance
capability:
  exposes:
    - type: mcp
      namespace: ap-ops
      port: 8080
      tools:
        - name: get-payment-status
          description: "Given a SAP vendor invoice number, return its payment status and date. Use for vendor payment inquiries."
          inputParameters:
            - name: invoice_number
              in: body
              type: string
              description: "The SAP vendor invoice number."
          call: "sap-ap.get-invoice-status"
          with:
            invoice: "{{invoice_number}}"
          outputParameters:
            - name: status
              type: string
              mapping: "$.payment_status"
            - name: payment_date
              type: string
              mapping: "$.clearing_date"
  consumes:
    - type: http
      namespace: sap-ap
      baseUri: "https://sap.bloomberg.com/sap/opu/odata/sap"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: invoices
          path: "/API_SUPPLIER_INVOICE_SRV/A_SupplierInvoice('{{invoice}}')"
          inputParameters:
            - name: invoice
              in: path
          operations:
            - name: get-invoice-status
              method: GET

When a critical GitHub Dependabot alert is opened, creates a Jira security ticket, assigns to the owning team, and posts to the security Slack channel with SLA deadlines.

naftiko: "0.5"
info:
  label: "Security Vulnerability Remediation Tracker"
  description: "When a critical GitHub Dependabot alert is opened, creates a Jira security ticket, assigns to the owning team, and posts to the security Slack channel with SLA deadlines."
  tags:
    - security
    - github
    - jira
    - slack
    - vulnerability-management
capability:
  exposes:
    - type: mcp
      namespace: vuln-ops
      port: 8080
      tools:
        - name: track-vulnerability-remediation
          description: "Given a GitHub Dependabot alert, create a Jira security ticket, assign to the owning team, and notify Slack with remediation SLA."
          inputParameters:
            - name: repo_name
              in: body
              type: string
              description: "The GitHub repository with the vulnerability."
            - name: alert_number
              in: body
              type: string
              description: "The Dependabot alert number."
            - name: severity
              in: body
              type: string
              description: "Vulnerability severity: critical, high, medium, low."
          steps:
            - name: get-alert
              type: call
              call: "gh-vuln.get-dependabot-alert"
              with:
                repo: "{{repo_name}}"
                alert_number: "{{alert_number}}"
            - name: create-ticket
              type: call
              call: "jira-vuln.create-issue"
              with:
                project: "SEC"
                summary: "[{{severity}}] Dependabot: {{get-alert.package}} in {{repo_name}}"
                description: "CVE: {{get-alert.cve_id}}. Package: {{get-alert.package}}@{{get-alert.vulnerable_version}}. Fix: {{get-alert.patched_version}}."
                priority: "Critical"
            - name: notify-security
              type: call
              call: "slack-vuln.post-message"
              with:
                channel: "security-vulnerabilities"
                text: "[{{severity}}] Dependabot alert in {{repo_name}}: {{get-alert.package}}. CVE: {{get-alert.cve_id}}. Jira: {{create-ticket.key}}. SLA: 48 hours for critical."
  consumes:
    - type: http
      namespace: gh-vuln
      baseUri: "https://api.github.com"
      authentication:
        type: bearer
        token: "$secrets.github_token"
      resources:
        - name: alerts
          path: "/repos/{{repo}}/dependabot/alerts/{{alert_number}}"
          inputParameters:
            - name: repo
              in: path
            - name: alert_number
              in: path
          operations:
            - name: get-dependabot-alert
              method: GET
    - type: http
      namespace: jira-vuln
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-vuln
      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 details of a ServiceNow change request including approval status and implementation window.

naftiko: "0.5"
info:
  label: "ServiceNow Change Request Lookup"
  description: "Retrieves details of a ServiceNow change request including approval status and implementation window."
  tags:
    - itsm
    - servicenow
    - change-management
capability:
  exposes:
    - type: mcp
      namespace: change-ops
      port: 8080
      tools:
        - name: get-change-request
          description: "Given a ServiceNow change request number, return its status, approval state, and scheduled window. Use for change review boards."
          inputParameters:
            - name: change_number
              in: body
              type: string
              description: "The ServiceNow change request number, e.g. 'CHG0012345'."
          call: "snow-change.get-change"
          with:
            number: "{{change_number}}"
          outputParameters:
            - name: state
              type: string
              mapping: "$.result.state"
            - name: approval
              type: string
              mapping: "$.result.approval"
            - name: start_date
              type: string
              mapping: "$.result.start_date"
  consumes:
    - type: http
      namespace: snow-change
      baseUri: "https://bloomberg.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: changes
          path: "/table/change_request"
          operations:
            - name: get-change
              method: GET

When a high-priority ServiceNow incident is raised, looks up the on-call engineer from PagerDuty and assigns the ticket, then posts a Slack alert with full incident context.

naftiko: "0.5"
info:
  label: "ServiceNow Incident Triage and Escalation"
  description: "When a high-priority ServiceNow incident is raised, looks up the on-call engineer from PagerDuty and assigns the ticket, then posts a Slack alert with full incident context."
  tags:
    - itsm
    - incident-response
    - servicenow
    - pagerduty
    - slack
capability:
  exposes:
    - type: mcp
      namespace: itsm-ops
      port: 8080
      tools:
        - name: triage-incident
          description: "Given a ServiceNow incident number, fetch incident details, look up the current on-call engineer via PagerDuty, assign the ticket to them, and post a Slack alert. Use for P1/P2 incidents requiring immediate triage."
          inputParameters:
            - name: incident_number
              in: body
              type: string
              description: "The ServiceNow incident number, e.g. 'INC0012345'."
            - name: priority
              in: body
              type: string
              description: "The incident priority level: 1 (Critical), 2 (High), 3 (Medium)."
          steps:
            - name: get-incident
              type: call
              call: "servicenow.get-incident"
              with:
                number: "{{incident_number}}"
            - name: get-oncall
              type: call
              call: "pagerduty.get-oncall-user"
              with:
                schedule_id: "$secrets.pagerduty_it_schedule_id"
            - name: assign-incident
              type: call
              call: "servicenow-assign.update-incident"
              with:
                sys_id: "{{get-incident.sys_id}}"
                assigned_to: "{{get-oncall.user_email}}"
            - name: alert-slack
              type: call
              call: "slack.post-message"
              with:
                channel: "it-incidents"
                text: "P{{priority}} Incident {{incident_number}}: {{get-incident.short_description}} assigned to {{get-oncall.user_name}}."
  consumes:
    - type: http
      namespace: servicenow
      baseUri: "https://bloomberg.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: pagerduty
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.pagerduty_token"
        placement: header
      resources:
        - name: oncalls
          path: "/oncalls"
          operations:
            - name: get-oncall-user
              method: GET
    - type: http
      namespace: servicenow-assign
      baseUri: "https://bloomberg.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: incident-update
          path: "/table/incident/{{sys_id}}"
          inputParameters:
            - name: sys_id
              in: path
          operations:
            - name: update-incident
              method: PATCH
    - 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 credit usage, identifies top-spending warehouses, generates a cost optimization report via Anthropic, and publishes to Confluence.

naftiko: "0.5"
info:
  label: "Snowflake Cost Optimization Report"
  description: "Queries Snowflake credit usage, identifies top-spending warehouses, generates a cost optimization report via Anthropic, and publishes to Confluence."
  tags:
    - cost-management
    - snowflake
    - anthropic
    - confluence
    - analytics
capability:
  exposes:
    - type: mcp
      namespace: cost-ops
      port: 8080
      tools:
        - name: generate-cost-report
          description: "Query Snowflake credit usage, generate optimization recommendations via Anthropic, and publish to Confluence."
          inputParameters:
            - name: time_period
              in: body
              type: string
              description: "The time period to analyze, e.g. 'last_30_days'."
          steps:
            - name: query-usage
              type: call
              call: "snowflake-cost.execute-query"
              with:
                query: "SELECT warehouse_name, SUM(credits_used) FROM snowflake.account_usage.warehouse_metering_history WHERE start_time > DATEADD(day, -30, CURRENT_TIMESTAMP()) GROUP BY 1 ORDER BY 2 DESC"
            - name: generate-recommendations
              type: call
              call: "anthropic-cost.create-message"
              with:
                model: "claude-opus-4-5"
                max_tokens: 2048
                system: "You are a cloud cost optimization expert. Analyze Snowflake usage and provide actionable recommendations."
                content: "Analyze this Snowflake credit usage and suggest optimizations: {{query-usage.data}}"
            - name: publish-report
              type: call
              call: "confluence-cost.create-page"
              with:
                space: "FINOPS"
                title: "Snowflake Cost Optimization Report - {{time_period}}"
                body: "{{generate-recommendations.content}}"
  consumes:
    - type: http
      namespace: snowflake-cost
      baseUri: "https://bloomberg.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-query
              method: POST
    - type: http
      namespace: anthropic-cost
      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: confluence-cost
      baseUri: "https://bloomberg.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_api_token"
      resources:
        - name: pages
          path: "/content"
          operations:
            - name: create-page
              method: POST

Queries Snowflake to detect stale or failed data pipeline runs, and opens a Jira task for the data engineering team when SLA breach is detected.

naftiko: "0.5"
info:
  label: "Snowflake Data Pipeline Health Check"
  description: "Queries Snowflake to detect stale or failed data pipeline runs, and opens a Jira task for the data engineering team when SLA breach is detected."
  tags:
    - data
    - analytics
    - snowflake
    - jira
    - monitoring
    - data-quality
capability:
  exposes:
    - type: mcp
      namespace: data-ops
      port: 8080
      tools:
        - name: check-pipeline-health
          description: "Given a Snowflake pipeline name and expected SLA in minutes, check if the most recent run completed within SLA. If breached, create a Jira task for the data engineering team. Use for scheduled data pipeline SLA monitoring."
          inputParameters:
            - name: pipeline_name
              in: body
              type: string
              description: "The Snowflake task or pipeline name to check."
            - name: sla_minutes
              in: body
              type: integer
              description: "The maximum allowed minutes since last successful run."
          steps:
            - name: check-run
              type: call
              call: "snowflake.query-task-history"
              with:
                task_name: "{{pipeline_name}}"
            - name: create-task
              type: call
              call: "jira.create-issue"
              with:
                project_key: "DATA"
                issuetype: "Task"
                summary: "Pipeline SLA breach: {{pipeline_name}} exceeded {{sla_minutes}} minutes"
                description: "Pipeline {{pipeline_name}} last successful run: {{check-run.last_success_time}}."
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://bloomberg.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: task-history
          path: "/databases/bloomberg/schemas/monitoring/tasks/{{task_name}}/history"
          inputParameters:
            - name: task_name
              in: path
          operations:
            - name: query-task-history
              method: GET
    - type: http
      namespace: jira
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST

When a Snowflake data pipeline misses its SLA, creates a PagerDuty incident, opens a Jira ticket, and posts an alert to the data engineering Slack channel.

naftiko: "0.5"
info:
  label: "Snowflake Data Pipeline SLA Breach Handler"
  description: "When a Snowflake data pipeline misses its SLA, creates a PagerDuty incident, opens a Jira ticket, and posts an alert to the data engineering Slack channel."
  tags:
    - data-engineering
    - snowflake
    - pagerduty
    - jira
    - slack
capability:
  exposes:
    - type: mcp
      namespace: pipeline-sla
      port: 8080
      tools:
        - name: handle-pipeline-sla-breach
          description: "Given a Snowflake pipeline SLA breach, create a PagerDuty incident, Jira ticket, and Slack alert."
          inputParameters:
            - name: pipeline_name
              in: body
              type: string
              description: "The name of the pipeline that missed SLA."
            - name: expected_completion
              in: body
              type: string
              description: "The expected completion time."
            - name: actual_status
              in: body
              type: string
              description: "The current pipeline status."
          steps:
            - name: page-oncall
              type: call
              call: "pd-pipeline.create-incident"
              with:
                title: "Pipeline SLA breach: {{pipeline_name}}"
                service_id: "$secrets.pagerduty_data_service"
                urgency: "high"
            - name: create-ticket
              type: call
              call: "jira-pipeline.create-issue"
              with:
                project: "DATA"
                summary: "SLA breach: {{pipeline_name}}"
                description: "Expected: {{expected_completion}}. Status: {{actual_status}}. PagerDuty: {{page-oncall.incident_url}}"
                priority: "Critical"
            - name: alert-team
              type: call
              call: "slack-pipeline.post-message"
              with:
                channel: "data-engineering-alerts"
                text: "PIPELINE SLA BREACH: {{pipeline_name}}. Expected by {{expected_completion}}, status: {{actual_status}}. Jira: {{create-ticket.key}}"
  consumes:
    - type: http
      namespace: pd-pipeline
      baseUri: "https://api.pagerduty.com"
      authentication:
        type: apikey
        key: "Authorization"
        value: "$secrets.pagerduty_token"
        placement: header
      resources:
        - name: incidents
          path: "/incidents"
          operations:
            - name: create-incident
              method: POST
    - type: http
      namespace: jira-pipeline
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-pipeline
      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

Executes a parameterized query against Bloomberg market data stored in Snowflake and returns the result set for analytics dashboards.

naftiko: "0.5"
info:
  label: "Snowflake Market Data Query"
  description: "Executes a parameterized query against Bloomberg market data stored in Snowflake and returns the result set for analytics dashboards."
  tags:
    - snowflake
    - market-data
    - analytics
    - financial-data
capability:
  exposes:
    - type: mcp
      namespace: market-data
      port: 8080
      tools:
        - name: query-market-data
          description: "Given a SQL query template and parameters, execute against the Bloomberg market data warehouse in Snowflake. Use for ad-hoc market data analysis."
          inputParameters:
            - name: query
              in: body
              type: string
              description: "Parameterized SQL query to execute."
            - name: warehouse
              in: body
              type: string
              description: "Snowflake warehouse name, e.g. 'BLOOMBERG_ANALYTICS'."
          call: "snowflake-mkt.execute-query"
          with:
            query: "{{query}}"
            warehouse: "{{warehouse}}"
          outputParameters:
            - name: rows
              type: array
              mapping: "$.data"
            - name: row_count
              type: integer
              mapping: "$.rowCount"
  consumes:
    - type: http
      namespace: snowflake-mkt
      baseUri: "https://bloomberg.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: queries
          path: "/statements"
          operations:
            - name: execute-query
              method: POST

Monitors Snowflake for long-running queries exceeding execution thresholds and alerts the data platform team in Slack with query details and user attribution.

naftiko: "0.5"
info:
  label: "Snowflake Query Performance Monitor"
  description: "Monitors Snowflake for long-running queries exceeding execution thresholds and alerts the data platform team in Slack with query details and user attribution."
  tags:
    - data
    - analytics
    - snowflake
    - slack
    - monitoring
    - performance
capability:
  exposes:
    - type: mcp
      namespace: data-monitoring
      port: 8080
      tools:
        - name: monitor-query-performance
          description: "Query Snowflake's QUERY_HISTORY view for executions exceeding a given duration threshold in the past hour, and post a Slack alert listing offending queries and users. Use for scheduled data platform health monitoring."
          inputParameters:
            - name: threshold_seconds
              in: body
              type: integer
              description: "The execution time threshold in seconds; queries exceeding this will be reported."
          steps:
            - name: get-slow-queries
              type: call
              call: "snowflake.query-history"
              with:
                threshold: "{{threshold_seconds}}"
            - name: post-alert
              type: call
              call: "slack.post-message"
              with:
                channel: "data-platform-ops"
                text: "Slow query alert: {{get-slow-queries.count}} queries exceeded {{threshold_seconds}}s in the last hour."
  consumes:
    - type: http
      namespace: snowflake
      baseUri: "https://bloomberg.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: query-history
          path: "/databases/snowflake/schemas/account_usage/tables/query_history/rows"
          operations:
            - name: query-history
              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

Runs a parameterized Splunk search for security events and returns matching results for threat investigation.

naftiko: "0.5"
info:
  label: "Splunk Security Event Search"
  description: "Runs a parameterized Splunk search for security events and returns matching results for threat investigation."
  tags:
    - security
    - splunk
    - threat-detection
capability:
  exposes:
    - type: mcp
      namespace: security-ops
      port: 8080
      tools:
        - name: search-security-events
          description: "Given a Splunk search query for security events, execute and return results. Use during security incident investigations."
          inputParameters:
            - name: search_query
              in: body
              type: string
              description: "The SPL search query string."
            - name: time_range
              in: body
              type: string
              description: "Time range for the search, e.g. '-24h'."
          call: "splunk-sec.run-search"
          with:
            query: "{{search_query}}"
            earliest_time: "{{time_range}}"
          outputParameters:
            - name: results
              type: array
              mapping: "$.results"
            - name: result_count
              type: integer
              mapping: "$.result_count"
  consumes:
    - type: http
      namespace: splunk-sec
      baseUri: "https://splunk.bloomberg.com:8089/services"
      authentication:
        type: bearer
        token: "$secrets.splunk_token"
      resources:
        - name: searches
          path: "/search/jobs/export"
          operations:
            - name: run-search
              method: POST

Triggers a Tableau workbook refresh and notifies the business stakeholder via Teams once the data source is updated and the dashboard is ready.

naftiko: "0.5"
info:
  label: "Tableau Dashboard Refresh Trigger"
  description: "Triggers a Tableau workbook refresh and notifies the business stakeholder via Teams once the data source is updated and the dashboard is ready."
  tags:
    - data
    - analytics
    - tableau
    - microsoft-teams
    - reporting
capability:
  exposes:
    - type: mcp
      namespace: analytics-reporting
      port: 8080
      tools:
        - name: refresh-dashboard
          description: "Given a Tableau workbook ID and datasource ID, trigger a full data refresh and send a Teams notification to the business owner when complete. Use when underlying data has been updated and stakeholders need fresh insights."
          inputParameters:
            - name: workbook_id
              in: body
              type: string
              description: "The Tableau workbook LUID to refresh."
            - name: datasource_id
              in: body
              type: string
              description: "The Tableau datasource LUID backing the workbook."
            - name: owner_email
              in: body
              type: string
              description: "The email of the business owner to notify on completion."
          steps:
            - name: refresh-datasource
              type: call
              call: "tableau.refresh-datasource"
              with:
                datasource_id: "{{datasource_id}}"
            - name: notify-owner
              type: call
              call: "msteams.send-message"
              with:
                recipient_upn: "{{owner_email}}"
                text: "Your Tableau dashboard (workbook {{workbook_id}}) has been refreshed with the latest data."
  consumes:
    - type: http
      namespace: tableau
      baseUri: "https://10ax.online.tableau.com/api/3.21"
      authentication:
        type: apikey
        key: "X-Tableau-Auth"
        value: "$secrets.tableau_token"
        placement: header
      resources:
        - name: datasource-refresh
          path: "/sites/{{site_id}}/datasources/{{datasource_id}}/refresh"
          inputParameters:
            - name: datasource_id
              in: path
            - name: site_id
              in: path
          operations:
            - name: refresh-datasource
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: mail
          path: "/users/{{recipient_upn}}/sendMail"
          inputParameters:
            - name: recipient_upn
              in: path
          operations:
            - name: send-message
              method: POST

Monitors Tableau dashboard last refresh times, and when data is stale beyond threshold, creates a Jira ticket and notifies the dashboard owner on Slack.

naftiko: "0.5"
info:
  label: "Tableau Dashboard Stale Data Alert"
  description: "Monitors Tableau dashboard last refresh times, and when data is stale beyond threshold, creates a Jira ticket and notifies the dashboard owner on Slack."
  tags:
    - analytics
    - tableau
    - jira
    - slack
    - data-freshness
capability:
  exposes:
    - type: mcp
      namespace: dashboard-ops
      port: 8080
      tools:
        - name: alert-stale-dashboard
          description: "Given a Tableau workbook ID with stale data, create a Jira ticket and notify the owner via Slack."
          inputParameters:
            - name: workbook_id
              in: body
              type: string
              description: "The Tableau workbook ID."
            - name: last_refresh
              in: body
              type: string
              description: "The last refresh timestamp."
            - name: owner_email
              in: body
              type: string
              description: "Email of the dashboard owner."
          steps:
            - name: create-ticket
              type: call
              call: "jira-dash.create-issue"
              with:
                project: "BI"
                summary: "Stale dashboard data: workbook {{workbook_id}}"
                description: "Last refresh: {{last_refresh}}. Owner: {{owner_email}}."
                priority: "Medium"
            - name: notify-owner
              type: call
              call: "slack-dash.post-message"
              with:
                channel: "bi-alerts"
                text: "Dashboard {{workbook_id}} has stale data (last refresh: {{last_refresh}}). Jira: {{create-ticket.key}}. Please investigate."
  consumes:
    - type: http
      namespace: jira-dash
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-dash
      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 all published Tableau workbooks in a specified project for dashboard inventory and governance reporting.

naftiko: "0.5"
info:
  label: "Tableau Workbook List"
  description: "Lists all published Tableau workbooks in a specified project for dashboard inventory and governance reporting."
  tags:
    - analytics
    - tableau
    - governance
capability:
  exposes:
    - type: mcp
      namespace: bi-governance
      port: 8080
      tools:
        - name: list-workbooks
          description: "Given a Tableau project name, return all published workbooks. Use for dashboard inventory audits."
          inputParameters:
            - name: project_name
              in: body
              type: string
              description: "The Tableau project name."
          call: "tableau-list.get-workbooks"
          with:
            project: "{{project_name}}"
          outputParameters:
            - name: workbooks
              type: array
              mapping: "$.workbooks.workbook"
            - name: count
              type: integer
              mapping: "$.pagination.totalAvailable"
  consumes:
    - type: http
      namespace: tableau-list
      baseUri: "https://tableau.bloomberg.com/api/3.19"
      authentication:
        type: bearer
        token: "$secrets.tableau_token"
      resources:
        - name: workbooks
          path: "/sites/{site_id}/workbooks"
          operations:
            - name: get-workbooks
              method: GET

Creates a new Terraform Cloud workspace for a given project, links the GitHub repository, and notifies the infrastructure team via Slack.

naftiko: "0.5"
info:
  label: "Terraform Cloud Workspace Provisioner"
  description: "Creates a new Terraform Cloud workspace for a given project, links the GitHub repository, and notifies the infrastructure team via Slack."
  tags:
    - cloud
    - infrastructure
    - terraform
    - github
    - slack
capability:
  exposes:
    - type: mcp
      namespace: infra-provisioning
      port: 8080
      tools:
        - name: provision-terraform-workspace
          description: "Given a workspace name, GitHub repository, and Terraform organization, create a new Terraform Cloud workspace linked to the repository and notify the infrastructure team in Slack. Use when a new project or service requires cloud infrastructure."
          inputParameters:
            - name: workspace_name
              in: body
              type: string
              description: "The desired Terraform Cloud workspace name, e.g. 'bloomberg-trading-api-prod'."
            - name: github_repo
              in: body
              type: string
              description: "The GitHub repository to link, e.g. 'bloomberg/trading-api'."
            - name: tf_org
              in: body
              type: string
              description: "The Terraform Cloud organization name."
          steps:
            - name: create-workspace
              type: call
              call: "terraform.create-workspace"
              with:
                name: "{{workspace_name}}"
                organization: "{{tf_org}}"
            - name: link-vcs
              type: call
              call: "terraform-vcs.link-vcs-repo"
              with:
                workspace_id: "{{create-workspace.id}}"
                repo: "{{github_repo}}"
            - name: notify-infra
              type: call
              call: "slack.post-message"
              with:
                channel: "infrastructure"
                text: "Terraform workspace {{workspace_name}} created 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: terraform-vcs
      baseUri: "https://app.terraform.io/api/v2"
      authentication:
        type: bearer
        token: "$secrets.terraform_token"
      resources:
        - name: workspace-vcs
          path: "/workspaces/{{workspace_id}}/relationships/vars"
          inputParameters:
            - name: workspace_id
              in: path
          operations:
            - name: link-vcs-repo
              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

Scans Terraform plans for security misconfigurations, creates Jira tickets for violations, and posts a scan summary to the infrastructure Slack channel.

naftiko: "0.5"
info:
  label: "Terraform Security Scan Gate"
  description: "Scans Terraform plans for security misconfigurations, creates Jira tickets for violations, and posts a scan summary to the infrastructure Slack channel."
  tags:
    - security
    - terraform
    - jira
    - slack
    - infrastructure
capability:
  exposes:
    - type: mcp
      namespace: tf-security
      port: 8080
      tools:
        - name: scan-terraform-plan
          description: "Given a Terraform Cloud run ID, scan for security violations, create Jira tickets, and notify Slack."
          inputParameters:
            - name: run_id
              in: body
              type: string
              description: "The Terraform Cloud run ID to scan."
            - name: workspace
              in: body
              type: string
              description: "The Terraform workspace name."
          steps:
            - name: get-plan
              type: call
              call: "tfc-scan.get-run-plan"
              with:
                run_id: "{{run_id}}"
            - name: create-ticket
              type: call
              call: "jira-tfsec.create-issue"
              with:
                project: "SEC"
                summary: "Terraform security scan: {{workspace}} (run {{run_id}})"
                description: "Plan changes: {{get-plan.resource_changes}}. Review for security compliance."
                priority: "High"
            - name: notify-team
              type: call
              call: "slack-tfsec.post-message"
              with:
                channel: "infrastructure-security"
                text: "Terraform scan: {{workspace}} run {{run_id}}. Changes: {{get-plan.resource_changes}}. Jira: {{create-ticket.key}}"
  consumes:
    - type: http
      namespace: tfc-scan
      baseUri: "https://app.terraform.io/api/v2"
      authentication:
        type: bearer
        token: "$secrets.terraform_cloud_token"
      resources:
        - name: runs
          path: "/runs/{{run_id}}/plan"
          inputParameters:
            - name: run_id
              in: path
          operations:
            - name: get-run-plan
              method: GET
    - type: http
      namespace: jira-tfsec
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-tfsec
      baseUri: "https://slack.com/api"
      authentication:
        type: bearer
        token: "$secrets.slack_bot_token"
      resources:
        - name: messages
          path: "/chat.postMessage"
          operations:
            - name: post-message
              method: POST

Retrieves the current state version and last apply status for a Terraform Cloud workspace.

naftiko: "0.5"
info:
  label: "Terraform Workspace State Check"
  description: "Retrieves the current state version and last apply status for a Terraform Cloud workspace."
  tags:
    - infrastructure
    - terraform
    - iac
capability:
  exposes:
    - type: mcp
      namespace: infra-ops
      port: 8080
      tools:
        - name: get-workspace-state
          description: "Given a Terraform Cloud workspace name, return the current state version and last run status. Use for infrastructure drift detection."
          inputParameters:
            - name: workspace_name
              in: body
              type: string
              description: "The Terraform Cloud workspace name."
          call: "tfc-state.get-workspace"
          with:
            workspace: "{{workspace_name}}"
          outputParameters:
            - name: state_version
              type: string
              mapping: "$.data.attributes.current-state-version-id"
            - name: last_run_status
              type: string
              mapping: "$.data.attributes.latest-run.status"
  consumes:
    - type: http
      namespace: tfc-state
      baseUri: "https://app.terraform.io/api/v2"
      authentication:
        type: bearer
        token: "$secrets.terraform_cloud_token"
      resources:
        - name: workspaces
          path: "/organizations/bloomberg/workspaces/{{workspace}}"
          inputParameters:
            - name: workspace
              in: path
          operations:
            - name: get-workspace
              method: GET

When a vendor contract approaches expiration in SAP, creates a Jira renewal task, notifies procurement on Slack, and updates the Salesforce vendor record.

naftiko: "0.5"
info:
  label: "Vendor Contract Renewal Workflow"
  description: "When a vendor contract approaches expiration in SAP, creates a Jira renewal task, notifies procurement on Slack, and updates the Salesforce vendor record."
  tags:
    - procurement
    - sap
    - jira
    - slack
    - salesforce
capability:
  exposes:
    - type: mcp
      namespace: procurement-ops
      port: 8080
      tools:
        - name: process-contract-renewal
          description: "Given an expiring vendor contract, create a Jira renewal task, notify procurement, and update Salesforce."
          inputParameters:
            - name: vendor_name
              in: body
              type: string
              description: "The vendor name."
            - name: contract_id
              in: body
              type: string
              description: "The SAP contract ID."
            - name: expiration_date
              in: body
              type: string
              description: "The contract expiration date."
          steps:
            - name: create-renewal-task
              type: call
              call: "jira-proc.create-issue"
              with:
                project: "PROC"
                summary: "Contract renewal: {{vendor_name}} expires {{expiration_date}}"
                description: "SAP Contract: {{contract_id}}. Begin renewal negotiations."
                priority: "High"
            - name: notify-procurement
              type: call
              call: "slack-proc.post-message"
              with:
                channel: "procurement"
                text: "Contract expiring: {{vendor_name}} ({{contract_id}}) on {{expiration_date}}. Jira: {{create-renewal-task.key}}"
            - name: update-salesforce
              type: call
              call: "sf-vendor.update-account"
              with:
                contract_id: "{{contract_id}}"
                status: "Renewal Pending"
  consumes:
    - type: http
      namespace: jira-proc
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: slack-proc
      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
    - type: http
      namespace: sf-vendor
      baseUri: "https://bloomberg.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: accounts
          path: "/sobjects/Contract/{{contract_id}}"
          inputParameters:
            - name: contract_id
              in: path
          operations:
            - name: update-account
              method: PATCH

Retrieves a vendor invoice from the AP system, validates it against the corresponding purchase order in SAP, and routes it for approval via ServiceNow.

naftiko: "0.5"
info:
  label: "Vendor Invoice Processing"
  description: "Retrieves a vendor invoice from the AP system, validates it against the corresponding purchase order in SAP, and routes it for approval via ServiceNow."
  tags:
    - finance
    - erp
    - sap
    - servicenow
    - accounts-payable
    - approval
capability:
  exposes:
    - type: mcp
      namespace: finance-ap
      port: 8080
      tools:
        - name: process-vendor-invoice
          description: "Given a vendor invoice number and SAP purchase order number, retrieve and validate the invoice against the PO, then create a ServiceNow approval workflow. Use for accounts payable invoice processing."
          inputParameters:
            - name: invoice_number
              in: body
              type: string
              description: "The vendor invoice number to process."
            - name: po_number
              in: body
              type: string
              description: "The SAP purchase order number to validate against."
          steps:
            - name: get-po
              type: call
              call: "sap.get-purchase-order"
              with:
                po_number: "{{po_number}}"
            - name: submit-approval
              type: call
              call: "servicenow.create-approval"
              with:
                category: "ap_invoice_approval"
                short_description: "Invoice {{invoice_number}} for PO {{po_number}} — Amount: {{get-po.total_amount}}"
  consumes:
    - type: http
      namespace: sap
      baseUri: "https://bloomberg-s4.sap.com/sap/opu/odata/sap/MM_PUR_PO_MAINT_V2_SRV"
      authentication:
        type: basic
        username: "$secrets.sap_user"
        password: "$secrets.sap_password"
      resources:
        - name: purchase-orders
          path: "/A_PurchaseOrder('{{po_number}}')"
          inputParameters:
            - name: po_number
              in: path
          operations:
            - name: get-purchase-order
              method: GET
    - type: http
      namespace: servicenow
      baseUri: "https://bloomberg.service-now.com/api/now"
      authentication:
        type: basic
        username: "$secrets.servicenow_user"
        password: "$secrets.servicenow_password"
      resources:
        - name: approval-requests
          path: "/table/sc_request"
          operations:
            - name: create-approval
              method: POST

Gathers KPI data from Snowflake, generates an executive summary via Anthropic Claude, and distributes the digest via Slack and Microsoft Teams to leadership.

naftiko: "0.5"
info:
  label: "Weekly Executive KPI Dashboard Digest"
  description: "Gathers KPI data from Snowflake, generates an executive summary via Anthropic Claude, and distributes the digest via Slack and Microsoft Teams to leadership."
  tags:
    - reporting
    - snowflake
    - anthropic
    - slack
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: exec-reporting
      port: 8080
      tools:
        - name: generate-kpi-digest
          description: "Query Snowflake for KPIs, generate an executive summary via Anthropic, and distribute via Slack and Teams."
          inputParameters:
            - name: week_ending
              in: body
              type: string
              description: "The week ending date in YYYY-MM-DD format."
          steps:
            - name: query-kpis
              type: call
              call: "snowflake-kpi.execute-query"
              with:
                query: "SELECT metric_name, current_value, target_value, pct_change FROM analytics.executive_kpis WHERE week_ending = '{{week_ending}}'"
            - name: generate-summary
              type: call
              call: "anthropic-kpi.create-message"
              with:
                model: "claude-opus-4-5"
                max_tokens: 2048
                system: "You are an executive briefing writer. Create a concise, action-oriented KPI summary for senior leadership."
                content: "Create an executive KPI digest for week ending {{week_ending}}: {{query-kpis.data}}"
            - name: post-to-slack
              type: call
              call: "slack-exec.post-message"
              with:
                channel: "executive-briefings"
                text: "Weekly KPI Digest ({{week_ending}}): {{generate-summary.content}}"
  consumes:
    - type: http
      namespace: snowflake-kpi
      baseUri: "https://bloomberg.snowflakecomputing.com/api/v2"
      authentication:
        type: bearer
        token: "$secrets.snowflake_token"
      resources:
        - name: statements
          path: "/statements"
          operations:
            - name: execute-query
              method: POST
    - type: http
      namespace: anthropic-kpi
      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: slack-exec
      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 employee's profile including title, department, and manager from Workday for HR automation workflows.

naftiko: "0.5"
info:
  label: "Workday Employee Profile Lookup"
  description: "Retrieves an employee's profile including title, department, and manager from Workday for HR automation workflows."
  tags:
    - hr
    - workday
    - employee-data
capability:
  exposes:
    - type: mcp
      namespace: hr-ops
      port: 8080
      tools:
        - name: get-employee-profile
          description: "Given a Workday employee ID, return their name, title, department, and manager. Use for onboarding, offboarding, and access review processes."
          inputParameters:
            - name: employee_id
              in: body
              type: string
              description: "The Workday employee ID."
          call: "workday-hr.get-worker"
          with:
            worker_id: "{{employee_id}}"
          outputParameters:
            - name: full_name
              type: string
              mapping: "$.worker.name"
            - name: title
              type: string
              mapping: "$.worker.title"
            - name: department
              type: string
              mapping: "$.worker.department"
            - name: manager
              type: string
              mapping: "$.worker.manager.name"
  consumes:
    - type: http
      namespace: workday-hr
      baseUri: "https://wd5-services1.myworkday.com/ccx/api/v1/bloomberg"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: workers
          path: "/workers/{{worker_id}}"
          inputParameters:
            - name: worker_id
              in: path
          operations:
            - name: get-worker
              method: GET

Collects performance review data from Workday, generates department-level insights via Anthropic Claude, and publishes the summary to Confluence for HR leadership.

naftiko: "0.5"
info:
  label: "Workday Performance Review Aggregator"
  description: "Collects performance review data from Workday, generates department-level insights via Anthropic Claude, and publishes the summary to Confluence for HR leadership."
  tags:
    - hr
    - workday
    - anthropic
    - confluence
    - performance-management
capability:
  exposes:
    - type: mcp
      namespace: perf-review
      port: 8080
      tools:
        - name: aggregate-performance-reviews
          description: "Collect Workday performance reviews for a department, generate insights, and publish to Confluence."
          inputParameters:
            - name: department
              in: body
              type: string
              description: "The department name."
            - name: review_cycle
              in: body
              type: string
              description: "The review cycle, e.g. 'H1-2026'."
          steps:
            - name: get-reviews
              type: call
              call: "workday-perf.get-reviews"
              with:
                department: "{{department}}"
                cycle: "{{review_cycle}}"
            - name: generate-insights
              type: call
              call: "anthropic-perf.create-message"
              with:
                model: "claude-opus-4-5"
                max_tokens: 2048
                system: "You are an HR analytics expert. Summarize performance trends, identify top performers, and flag areas needing attention."
                content: "Analyze performance review data for {{department}} ({{review_cycle}}): {{get-reviews.data}}"
            - name: publish-summary
              type: call
              call: "confluence-perf.create-page"
              with:
                space: "HR"
                title: "Performance Review Summary: {{department}} - {{review_cycle}}"
                body: "{{generate-insights.content}}"
  consumes:
    - type: http
      namespace: workday-perf
      baseUri: "https://wd5-services1.myworkday.com/ccx/api/v1/bloomberg"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: reviews
          path: "/performance/reviews"
          operations:
            - name: get-reviews
              method: GET
    - type: http
      namespace: anthropic-perf
      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: confluence-perf
      baseUri: "https://bloomberg.atlassian.net/wiki/rest/api"
      authentication:
        type: basic
        username: "$secrets.confluence_user"
        password: "$secrets.confluence_api_token"
      resources:
        - name: pages
          path: "/content"
          operations:
            - name: create-page
              method: POST

Initiates a performance review cycle in Workday for a given department, creates a tracking Jira epic, and notifies HR business partners via Teams.

naftiko: "0.5"
info:
  label: "Workday Performance Review Cycle Kickoff"
  description: "Initiates a performance review cycle in Workday for a given department, creates a tracking Jira epic, and notifies HR business partners via Teams."
  tags:
    - hr
    - performance-management
    - workday
    - jira
    - microsoft-teams
capability:
  exposes:
    - type: mcp
      namespace: hr-performance
      port: 8080
      tools:
        - name: kickoff-review-cycle
          description: "Given a department ID and review cycle period, initiate the performance review process in Workday, create a Jira tracking epic, and notify relevant HR business partners in Teams. Use at the start of each semi-annual review cycle."
          inputParameters:
            - name: department_id
              in: body
              type: string
              description: "The Workday department ID for which to initiate the review cycle."
            - name: review_period
              in: body
              type: string
              description: "The review period label, e.g. 'H1-2026'."
          steps:
            - name: initiate-review
              type: call
              call: "workday.create-review-process"
              with:
                department_id: "{{department_id}}"
                period: "{{review_period}}"
            - name: create-epic
              type: call
              call: "jira.create-issue"
              with:
                project_key: "HR"
                issuetype: "Epic"
                summary: "Performance Review {{review_period}} — Dept {{department_id}}"
            - name: notify-hrbp
              type: call
              call: "msteams.post-channel-message"
              with:
                channel_id: "$secrets.hrbp_teams_channel_id"
                text: "Performance review cycle {{review_period}} has been initiated for department {{department_id}}. Jira epic: {{create-epic.key}}."
  consumes:
    - type: http
      namespace: workday
      baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
      authentication:
        type: bearer
        token: "$secrets.workday_token"
      resources:
        - name: review-processes
          path: "/bloomberg/performanceManagement/reviewProcesses"
          operations:
            - name: create-review-process
              method: POST
    - type: http
      namespace: jira
      baseUri: "https://bloomberg.atlassian.net/rest/api/3"
      authentication:
        type: basic
        username: "$secrets.jira_user"
        password: "$secrets.jira_api_token"
      resources:
        - name: issues
          path: "/issue"
          operations:
            - name: create-issue
              method: POST
    - type: http
      namespace: msteams
      baseUri: "https://graph.microsoft.com/v1.0"
      authentication:
        type: bearer
        token: "$secrets.msgraph_token"
      resources:
        - name: channel-messages
          path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
          inputParameters:
            - name: channel_id
              in: path
          operations:
            - name: post-channel-message
              method: POST

When a new Bloomberg client webinar is created in Zoom, syncs registration data to Salesforce as campaign member records and posts a Slack notification to the events team.

naftiko: "0.5"
info:
  label: "Zoom Webinar Registration Sync"
  description: "When a new Bloomberg client webinar is created in Zoom, syncs registration data to Salesforce as campaign member records and posts a Slack notification to the events team."
  tags:
    - marketing
    - events
    - zoom
    - salesforce
    - slack
capability:
  exposes:
    - type: mcp
      namespace: events-ops
      port: 8080
      tools:
        - name: sync-webinar-registrants
          description: "Given a Zoom webinar ID and Salesforce campaign ID, fetch all webinar registrants from Zoom and create corresponding Salesforce campaign member records. Use after webinar registration closes or for real-time sync."
          inputParameters:
            - name: webinar_id
              in: body
              type: string
              description: "The Zoom webinar ID."
            - name: salesforce_campaign_id
              in: body
              type: string
              description: "The Salesforce campaign ID to sync registrants into."
          steps:
            - name: get-registrants
              type: call
              call: "zoom.list-webinar-registrants"
              with:
                webinar_id: "{{webinar_id}}"
            - name: create-campaign-members
              type: call
              call: "salesforce.create-campaign-members"
              with:
                campaign_id: "{{salesforce_campaign_id}}"
                registrant_data: "{{get-registrants.registrants}}"
            - name: notify-events
              type: call
              call: "slack.post-message"
              with:
                channel: "events-team"
                text: "Webinar {{webinar_id}} registrants synced to Salesforce campaign {{salesforce_campaign_id}}: {{get-registrants.total_records}} records."
  consumes:
    - type: http
      namespace: zoom
      baseUri: "https://api.zoom.us/v2"
      authentication:
        type: bearer
        token: "$secrets.zoom_token"
      resources:
        - name: webinar-registrants
          path: "/webinars/{{webinar_id}}/registrants"
          inputParameters:
            - name: webinar_id
              in: path
          operations:
            - name: list-webinar-registrants
              method: GET
    - type: http
      namespace: salesforce
      baseUri: "https://bloomberg.my.salesforce.com/services/data/v58.0"
      authentication:
        type: bearer
        token: "$secrets.salesforce_token"
      resources:
        - name: campaign-members
          path: "/sobjects/CampaignMember"
          operations:
            - name: create-campaign-members
              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