IBM Capabilities
Naftiko 0.5 capability definitions for IBM - 103 capabilities showing integration workflows and service orchestrations.
Fetches IBM campaign performance metrics from Adobe Analytics and posts a weekly summary report to Salesforce as an activity log on the relevant campaign record.
naftiko: "0.5"
info:
label: "Adobe Analytics Campaign Performance Digest"
description: "Fetches IBM campaign performance metrics from Adobe Analytics and posts a weekly summary report to Salesforce as an activity log on the relevant campaign record."
tags:
- marketing
- analytics
- adobe-analytics
- salesforce
- reporting
capability:
exposes:
- type: mcp
namespace: marketing-reporting
port: 8080
tools:
- name: digest-campaign-performance
description: "Given an Adobe Analytics report suite ID and a Salesforce campaign ID, retrieve key campaign metrics and log a performance summary on the Salesforce campaign record."
inputParameters:
- name: report_suite_id
in: body
type: string
description: "Adobe Analytics report suite ID."
- name: campaign_id
in: body
type: string
description: "Salesforce campaign record ID."
- name: date_range
in: body
type: string
description: "Date range string for the report, e.g. 2025-01-01/2025-01-31."
steps:
- name: get-analytics
type: call
call: "adobe-analytics.get-report"
with:
rsid: "{{report_suite_id}}"
dateRange: "{{date_range}}"
- name: log-activity
type: call
call: "salesforce-campaign.create-activity"
with:
WhatId: "{{campaign_id}}"
Subject: "Campaign Performance Digest — {{date_range}}"
Description: "Visits: {{get-analytics.visits}} | Conversions: {{get-analytics.conversions}} | Revenue: {{get-analytics.revenue}}"
consumes:
- type: http
namespace: adobe-analytics
baseUri: "https://analytics.adobe.io/api/{{company_id}}/reports"
authentication:
type: bearer
token: "$secrets.adobe_analytics_token"
resources:
- name: reports
path: "/ranked"
operations:
- name: get-report
method: POST
- type: http
namespace: salesforce-campaign
baseUri: "https://ibm.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: activities
path: "/sobjects/Task"
operations:
- name: create-activity
method: POST
Compares ADP payroll totals against Workday compensation records and creates a ServiceNow task for any discrepancies found.
naftiko: "0.5"
info:
label: "ADP Payroll Discrepancy to Workday Review"
description: "Compares ADP payroll totals against Workday compensation records and creates a ServiceNow task for any discrepancies found."
tags:
- hr
- finance
- adp
- workday
- servicenow
capability:
exposes:
- type: mcp
namespace: payroll-audit
port: 8080
tools:
- name: audit-payroll
description: "Given a payroll period, compare ADP run totals to Workday compensation and flag discrepancies."
inputParameters:
- name: payroll_period
in: body
type: string
description: "Payroll period code, e.g. 2026-03."
steps:
- name: get-adp-totals
type: call
call: "adp.get-payroll-summary"
with:
period: "{{payroll_period}}"
- name: get-workday-totals
type: call
call: "workday.get-comp-totals"
with:
period: "{{payroll_period}}"
- name: create-review-task
type: call
call: "servicenow-payroll.create-task"
with:
short_description: "Payroll audit: ADP={{get-adp-totals.total}} vs Workday={{get-workday-totals.total}} for {{payroll_period}}"
assignment_group: "HR_Payroll"
consumes:
- type: http
namespace: adp
baseUri: "https://api.adp.com"
authentication:
type: bearer
token: "$secrets.adp_token"
resources:
- name: payroll
path: "/payroll/v1/payroll-output"
inputParameters:
- name: period
in: query
operations:
- name: get-payroll-summary
method: GET
- type: http
namespace: workday
baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: compensation
path: "/ibm/compensation/totals"
inputParameters:
- name: period
in: query
operations:
- name: get-comp-totals
method: GET
- type: http
namespace: servicenow-payroll
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: tasks
path: "/table/sc_task"
operations:
- name: create-task
method: POST
Lists IAM-granted access to IBM S3 buckets and flags any public or cross-account permissions. Creates a ServiceNow security task for each non-compliant bucket found.
naftiko: "0.5"
info:
label: "Amazon S3 Data Lake Access Review"
description: "Lists IAM-granted access to IBM S3 buckets and flags any public or cross-account permissions. Creates a ServiceNow security task for each non-compliant bucket found."
tags:
- cloud
- security
- aws
- servicenow
- access-review
capability:
exposes:
- type: mcp
namespace: s3-access-review
port: 8080
tools:
- name: review-s3-access
description: "Given an AWS account ID, enumerate S3 bucket policies and ACLs for public or cross-account access. Create a ServiceNow security task for each non-compliant bucket."
inputParameters:
- name: aws_account_id
in: body
type: string
description: "AWS account ID to review."
steps:
- name: list-buckets
type: call
call: "aws-s3.list-buckets"
with:
account_id: "{{aws_account_id}}"
- name: create-security-task
type: call
call: "servicenow-s3.create-task"
with:
short_description: "S3 access review: {{aws_account_id}} — non-compliant buckets found"
description: "Non-compliant buckets: {{list-buckets.non_compliant_count}}"
assignment_group: "Cloud_Security"
consumes:
- type: http
namespace: aws-s3
baseUri: "https://s3.amazonaws.com"
authentication:
type: bearer
token: "$secrets.aws_s3_token"
resources:
- name: buckets
path: "/"
operations:
- name: list-buckets
method: GET
- type: http
namespace: servicenow-s3
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: tasks
path: "/table/sc_task"
operations:
- name: create-task
method: POST
When an AWS CloudWatch alarm enters ALARM state, creates a ServiceNow incident and notifies the infrastructure team via Slack.
naftiko: "0.5"
info:
label: "AWS CloudWatch Alarm to ServiceNow Incident"
description: "When an AWS CloudWatch alarm enters ALARM state, creates a ServiceNow incident and notifies the infrastructure team via Slack."
tags:
- cloud
- itsm
- aws
- servicenow
- slack
capability:
exposes:
- type: mcp
namespace: cloud-ops
port: 8080
tools:
- name: handle-cloudwatch-alarm
description: "Given a CloudWatch alarm name, retrieve alarm details and create a ServiceNow incident with Slack notification."
inputParameters:
- name: alarm_name
in: body
type: string
description: "CloudWatch alarm name."
steps:
- name: get-alarm
type: call
call: "cloudwatch.describe-alarm"
with:
alarm_name: "{{alarm_name}}"
- name: create-incident
type: call
call: "servicenow-ops.create-incident"
with:
short_description: "CloudWatch alarm: {{alarm_name}} — {{get-alarm.StateReason}}"
urgency: "2"
impact: "2"
assignment_group: "Cloud_Infrastructure"
- name: notify-infra
type: call
call: "slack.post-message"
with:
channel: "#infra-alerts"
text: "ServiceNow {{create-incident.number}} created for CloudWatch alarm {{alarm_name}}"
consumes:
- type: http
namespace: cloudwatch
baseUri: "https://monitoring.us-east-1.amazonaws.com"
authentication:
type: apikey
key: "Authorization"
value: "$secrets.aws_sigv4_token"
placement: header
resources:
- name: alarms
path: "/?Action=DescribeAlarms&AlarmNames.member.1={{alarm_name}}"
inputParameters:
- name: alarm_name
in: query
operations:
- name: describe-alarm
method: GET
- type: http
namespace: servicenow-ops
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: incidents
path: "/table/incident"
operations:
- name: create-incident
method: POST
- type: http
namespace: slack
baseUri: "https://slack.com/api"
authentication:
type: bearer
token: "$secrets.slack_bot_token"
resources:
- name: messages
path: "/chat.postMessage"
operations:
- name: post-message
method: POST
Retrieves the running state, instance type, and availability zone of an AWS EC2 instance by instance ID.
naftiko: "0.5"
info:
label: "AWS EC2 Instance Status Lookup"
description: "Retrieves the running state, instance type, and availability zone of an AWS EC2 instance by instance ID."
tags:
- cloud
- infrastructure
- aws
capability:
exposes:
- type: mcp
namespace: cloud-infra
port: 8080
tools:
- name: get-ec2-status
description: "Given an EC2 instance ID, return the instance state, type, availability zone, and launch time."
inputParameters:
- name: instance_id
in: body
type: string
description: "AWS EC2 instance ID."
call: aws.describe-instance
with:
instance_id: "{{instance_id}}"
consumes:
- type: http
namespace: aws
baseUri: "https://ec2.us-east-1.amazonaws.com"
authentication:
type: apikey
key: "Authorization"
value: "$secrets.aws_sigv4_token"
placement: header
resources:
- name: instances
path: "/?Action=DescribeInstances&InstanceId.1={{instance_id}}"
inputParameters:
- name: instance_id
in: query
operations:
- name: describe-instance
method: GET
Scans AWS S3 buckets for public access configuration and creates ServiceNow compliance tasks for any misconfigured buckets.
naftiko: "0.5"
info:
label: "AWS S3 Compliance Scan to ServiceNow"
description: "Scans AWS S3 buckets for public access configuration and creates ServiceNow compliance tasks for any misconfigured buckets."
tags:
- security
- compliance
- aws
- servicenow
- slack
capability:
exposes:
- type: mcp
namespace: cloud-compliance
port: 8080
tools:
- name: scan-s3-compliance
description: "Given an AWS account, check S3 buckets for public access and create compliance tasks for violations."
inputParameters:
- name: account_id
in: body
type: string
description: "AWS account ID."
steps:
- name: list-buckets
type: call
call: "aws-s3.list-buckets"
with:
account_id: "{{account_id}}"
- name: create-compliance-task
type: call
call: "servicenow-comp.create-task"
with:
short_description: "S3 compliance: {{list-buckets.public_bucket_count}} public buckets in account {{account_id}}"
assignment_group: "Cloud_Security"
priority: "1"
- name: notify-security
type: call
call: "slack.post-message"
with:
channel: "#cloud-security"
text: "S3 compliance scan: {{list-buckets.public_bucket_count}} public buckets found in account {{account_id}} — ServiceNow: {{create-compliance-task.number}}"
consumes:
- type: http
namespace: aws-s3
baseUri: "https://s3.amazonaws.com"
authentication:
type: apikey
key: "Authorization"
value: "$secrets.aws_sigv4_token"
placement: header
resources:
- name: buckets
path: "/"
operations:
- name: list-buckets
method: GET
- type: http
namespace: servicenow-comp
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: tasks
path: "/table/sc_task"
operations:
- name: create-task
method: POST
- type: http
namespace: slack
baseUri: "https://slack.com/api"
authentication:
type: bearer
token: "$secrets.slack_bot_token"
resources:
- name: messages
path: "/chat.postMessage"
operations:
- name: post-message
method: POST
When Azure AD Identity Protection flags a high-risk sign-in, suspends the user in Okta and creates a ServiceNow security incident.
naftiko: "0.5"
info:
label: "Azure AD Risky Sign-In to Okta Suspension"
description: "When Azure AD Identity Protection flags a high-risk sign-in, suspends the user in Okta and creates a ServiceNow security incident."
tags:
- security
- identity
- azure
- okta
- servicenow
capability:
exposes:
- type: mcp
namespace: identity-threat
port: 8080
tools:
- name: handle-risky-signin
description: "Given an Azure AD risk event ID, retrieve the details, suspend the user in Okta, and create a security incident."
inputParameters:
- name: risk_event_id
in: body
type: string
description: "Azure AD risk event ID."
steps:
- name: get-risk-event
type: call
call: "azure-ad.get-risk-detection"
with:
event_id: "{{risk_event_id}}"
- name: suspend-okta-user
type: call
call: "okta.suspend-user"
with:
user_id: "{{get-risk-event.userPrincipalName}}"
- name: create-sec-incident
type: call
call: "servicenow-sec.create-incident"
with:
short_description: "High-risk sign-in: {{get-risk-event.userPrincipalName}} from {{get-risk-event.ipAddress}}"
severity: "1"
category: "security"
assignment_group: "SOC_Team"
consumes:
- type: http
namespace: azure-ad
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.azure_graph_token"
resources:
- name: risk-detections
path: "/identityProtection/riskDetections/{{event_id}}"
inputParameters:
- name: event_id
in: path
operations:
- name: get-risk-detection
method: GET
- type: http
namespace: okta
baseUri: "https://ibm.okta.com/api/v1"
authentication:
type: apikey
key: "Authorization"
value: "SSWS $secrets.okta_api_token"
placement: header
resources:
- name: users
path: "/users/{{user_id}}/lifecycle/suspend"
inputParameters:
- name: user_id
in: path
operations:
- name: suspend-user
method: POST
- type: http
namespace: servicenow-sec
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: incidents
path: "/table/sn_si_incident"
operations:
- name: create-incident
method: POST
When Azure Cost Management detects a spend anomaly, creates a Jira FinOps ticket and notifies the cloud governance team.
naftiko: "0.5"
info:
label: "Azure Cost Anomaly to FinOps Jira"
description: "When Azure Cost Management detects a spend anomaly, creates a Jira FinOps ticket and notifies the cloud governance team."
tags:
- cloud
- finops
- azure
- jira
- slack
capability:
exposes:
- type: mcp
namespace: cloud-finops
port: 8080
tools:
- name: handle-cost-anomaly
description: "Given an Azure subscription and anomaly details, create a FinOps Jira ticket and notify the team."
inputParameters:
- name: subscription_id
in: body
type: string
description: "Azure subscription ID."
- name: anomaly_description
in: body
type: string
description: "Description of the cost anomaly."
steps:
- name: get-cost-details
type: call
call: "azure-cost.get-cost-summary"
with:
subscription_id: "{{subscription_id}}"
- name: create-finops-ticket
type: call
call: "jira.create-issue"
with:
project: "FINOPS"
issuetype: "Task"
summary: "Azure cost anomaly: {{anomaly_description}}"
description: "Subscription: {{subscription_id}} | Current spend: {{get-cost-details.total_cost}}"
- name: notify-governance
type: call
call: "slack.post-message"
with:
channel: "#cloud-governance"
text: "Azure cost anomaly detected in subscription {{subscription_id}} — Jira: {{create-finops-ticket.key}}"
consumes:
- type: http
namespace: azure-cost
baseUri: "https://management.azure.com"
authentication:
type: bearer
token: "$secrets.azure_token"
resources:
- name: cost-summary
path: "/subscriptions/{{subscription_id}}/providers/Microsoft.CostManagement/query"
inputParameters:
- name: subscription_id
in: path
operations:
- name: get-cost-summary
method: POST
- type: http
namespace: jira
baseUri: "https://ibm-jira.atlassian.net/rest/api/3"
authentication:
type: basic
username: "$secrets.jira_user"
password: "$secrets.jira_api_token"
resources:
- name: issues
path: "/issue"
operations:
- name: create-issue
method: POST
- type: http
namespace: slack
baseUri: "https://slack.com/api"
authentication:
type: bearer
token: "$secrets.slack_bot_token"
resources:
- name: messages
path: "/chat.postMessage"
operations:
- name: post-message
method: POST
When an Azure Databricks job fails, retrieves the error output and creates a Jira ticket for the data engineering team.
naftiko: "0.5"
info:
label: "Azure Databricks Job Failure to Jira"
description: "When an Azure Databricks job fails, retrieves the error output and creates a Jira ticket for the data engineering team."
tags:
- data
- devops
- azure-databricks
- jira
- slack
capability:
exposes:
- type: mcp
namespace: data-ops
port: 8080
tools:
- name: handle-databricks-failure
description: "Given a Databricks run ID, get the failure details and create a Jira ticket."
inputParameters:
- name: run_id
in: body
type: string
description: "Databricks job run ID."
steps:
- name: get-run
type: call
call: "databricks.get-run"
with:
run_id: "{{run_id}}"
- name: create-ticket
type: call
call: "jira.create-issue"
with:
project: "DATA"
issuetype: "Bug"
summary: "Databricks job failure: {{get-run.run_name}}"
description: "Error: {{get-run.state.state_message}} | Cluster: {{get-run.cluster_instance.cluster_id}}"
- name: notify-team
type: call
call: "slack.post-message"
with:
channel: "#data-engineering"
text: "Databricks job {{get-run.run_name}} failed — Jira: {{create-ticket.key}}"
consumes:
- type: http
namespace: databricks
baseUri: "https://adb-ibm.azuredatabricks.net/api/2.1"
authentication:
type: bearer
token: "$secrets.databricks_token"
resources:
- name: runs
path: "/jobs/runs/get?run_id={{run_id}}"
inputParameters:
- name: run_id
in: query
operations:
- name: get-run
method: GET
- type: http
namespace: jira
baseUri: "https://ibm-jira.atlassian.net/rest/api/3"
authentication:
type: basic
username: "$secrets.jira_user"
password: "$secrets.jira_api_token"
resources:
- name: issues
path: "/issue"
operations:
- name: create-issue
method: POST
- type: http
namespace: slack
baseUri: "https://slack.com/api"
authentication:
type: bearer
token: "$secrets.slack_bot_token"
resources:
- name: messages
path: "/chat.postMessage"
operations:
- name: post-message
method: POST
When an Azure DevOps pipeline fails, retrieves the failure details and creates a Jira bug ticket with the error logs.
naftiko: "0.5"
info:
label: "Azure DevOps Pipeline Failure to Jira"
description: "When an Azure DevOps pipeline fails, retrieves the failure details and creates a Jira bug ticket with the error logs."
tags:
- devops
- ci-cd
- azure-devops
- jira
capability:
exposes:
- type: mcp
namespace: ci-ops
port: 8080
tools:
- name: handle-pipeline-failure
description: "Given an Azure DevOps build ID and project, get the failure details and create a Jira bug."
inputParameters:
- name: project
in: body
type: string
description: "Azure DevOps project name."
- name: build_id
in: body
type: string
description: "Failed build ID."
steps:
- name: get-build
type: call
call: "azdo.get-build"
with:
project: "{{project}}"
build_id: "{{build_id}}"
- name: create-bug
type: call
call: "jira.create-issue"
with:
project: "ENG"
issuetype: "Bug"
summary: "Pipeline failure: {{get-build.definition.name}} build #{{build_id}}"
description: "Build status: {{get-build.result}} | Reason: {{get-build.failureReason}}"
consumes:
- type: http
namespace: azdo
baseUri: "https://dev.azure.com/ibm"
authentication:
type: basic
username: "$secrets.azdo_user"
password: "$secrets.azdo_pat"
resources:
- name: builds
path: "/{{project}}/_apis/build/builds/{{build_id}}"
inputParameters:
- name: project
in: path
- name: build_id
in: path
operations:
- name: get-build
method: GET
- type: http
namespace: jira
baseUri: "https://ibm-jira.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
Queries Azure Log Analytics for error spikes on a given service and forwards alert payloads to New Relic as custom events. Used by SRE agents for cross-platform observability correlation.
naftiko: "0.5"
info:
label: "Azure Log Analytics Alert to New Relic"
description: "Queries Azure Log Analytics for error spikes on a given service and forwards alert payloads to New Relic as custom events. Used by SRE agents for cross-platform observability correlation."
tags:
- observability
- cloud
- azure-log-analytics
- new-relic
- monitoring
capability:
exposes:
- type: mcp
namespace: cloud-obs
port: 8080
tools:
- name: forward-log-alert
description: "Given an Azure Log Analytics workspace ID and KQL query, run the query and forward matching log records as custom events to New Relic for unified alerting."
inputParameters:
- name: workspace_id
in: body
type: string
description: "Azure Log Analytics workspace GUID."
- name: kql_query
in: body
type: string
description: "KQL query to run against the workspace, e.g. AzureDiagnostics | where Level == 'Error'."
steps:
- name: run-query
type: call
call: "azure-logs.run-query"
with:
workspaceId: "{{workspace_id}}"
query: "{{kql_query}}"
- name: post-events
type: call
call: "newrelic-events.post-events"
with:
eventType: "AzureLogAlert"
attributes: "{{run-query.rows}}"
consumes:
- type: http
namespace: azure-logs
baseUri: "https://api.loganalytics.io/v1"
authentication:
type: bearer
token: "$secrets.azure_log_analytics_token"
resources:
- name: query
path: "/workspaces/{{workspaceId}}/query"
inputParameters:
- name: workspaceId
in: path
operations:
- name: run-query
method: POST
- type: http
namespace: newrelic-events
baseUri: "https://insights-collector.newrelic.com/v1"
authentication:
type: apikey
key: "X-Insert-Key"
value: "$secrets.newrelic_insert_key"
placement: header
resources:
- name: events
path: "/accounts/{{account_id}}/events"
inputParameters:
- name: account_id
in: path
operations:
- name: post-events
method: POST
Checks the deployment health of a registered Azure Machine Learning model endpoint and creates a ServiceNow incident if the endpoint is unhealthy or scoring latency is degraded.
naftiko: "0.5"
info:
label: "Azure Machine Learning Model Deployment Monitor"
description: "Checks the deployment health of a registered Azure Machine Learning model endpoint and creates a ServiceNow incident if the endpoint is unhealthy or scoring latency is degraded."
tags:
- ai
- cloud
- azure-machine-learning
- servicenow
- monitoring
capability:
exposes:
- type: mcp
namespace: ml-ops
port: 8080
tools:
- name: monitor-ml-endpoint
description: "Given an Azure ML workspace name and endpoint name, check real-time endpoint health and latency metrics and open a ServiceNow incident if degraded."
inputParameters:
- name: workspace_name
in: body
type: string
description: "Azure ML workspace name."
- name: endpoint_name
in: body
type: string
description: "Online endpoint name within the workspace."
- name: latency_threshold_ms
in: body
type: integer
description: "P99 latency threshold in milliseconds above which to alert."
steps:
- name: get-endpoint-status
type: call
call: "azure-ml.get-endpoint"
with:
workspaceName: "{{workspace_name}}"
endpointName: "{{endpoint_name}}"
- name: create-ml-incident
type: call
call: "servicenow-ml.create-incident"
with:
short_description: "ML endpoint degraded: {{endpoint_name}} in {{workspace_name}}"
category: "AI_Operations"
urgency: "2"
description: "Endpoint state: {{get-endpoint-status.provisioningState}} | Traffic: {{get-endpoint-status.trafficRules}}"
consumes:
- type: http
namespace: azure-ml
baseUri: "https://management.azure.com/subscriptions/{{subscriptionId}}/resourceGroups/{{resourceGroup}}/providers/Microsoft.MachineLearningServices"
authentication:
type: bearer
token: "$secrets.azure_ml_token"
resources:
- name: endpoints
path: "/workspaces/{{workspaceName}}/onlineEndpoints/{{endpointName}}"
inputParameters:
- name: workspaceName
in: path
- name: endpointName
in: path
operations:
- name: get-endpoint
method: GET
- type: http
namespace: servicenow-ml
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: incidents
path: "/table/incident"
operations:
- name: create-incident
method: POST
Queries Azure Cost Management for the current month spend of a resource group, returning cost breakdown by service category.
naftiko: "0.5"
info:
label: "Azure Resource Group Cost Lookup"
description: "Queries Azure Cost Management for the current month spend of a resource group, returning cost breakdown by service category."
tags:
- cloud
- finops
- azure
capability:
exposes:
- type: mcp
namespace: finops
port: 8080
tools:
- name: get-resource-group-cost
description: "Given an Azure subscription ID and resource group name, return the current month cost breakdown."
inputParameters:
- name: subscription_id
in: body
type: string
description: "Azure subscription ID."
- name: resource_group
in: body
type: string
description: "Azure resource group name."
call: azure-cost.get-cost-summary
with:
subscription_id: "{{subscription_id}}"
resource_group: "{{resource_group}}"
consumes:
- type: http
namespace: azure-cost
baseUri: "https://management.azure.com"
authentication:
type: bearer
token: "$secrets.azure_token"
resources:
- name: cost-summary
path: "/subscriptions/{{subscription_id}}/resourceGroups/{{resource_group}}/providers/Microsoft.CostManagement/query"
inputParameters:
- name: subscription_id
in: path
- name: resource_group
in: path
operations:
- name: get-cost-summary
method: POST
When a Bitbucket pull request is merged to main, creates a ServiceNow change request for deployment tracking and attaches the PR diff summary.
naftiko: "0.5"
info:
label: "Bitbucket PR Code Review to ServiceNow Change"
description: "When a Bitbucket pull request is merged to main, creates a ServiceNow change request for deployment tracking and attaches the PR diff summary."
tags:
- devops
- cicd
- bitbucket
- servicenow
- change-management
capability:
exposes:
- type: mcp
namespace: change-mgmt
port: 8080
tools:
- name: create-deployment-change
description: "Given a Bitbucket workspace, repository slug, and pull request ID, fetch the PR details and create a ServiceNow standard change request for the merged code."
inputParameters:
- name: workspace
in: body
type: string
description: "Bitbucket workspace slug."
- name: repo_slug
in: body
type: string
description: "Bitbucket repository slug."
- name: pr_id
in: body
type: integer
description: "Bitbucket pull request ID."
steps:
- name: get-pr
type: call
call: "bitbucket.get-pr"
with:
workspace: "{{workspace}}"
repo_slug: "{{repo_slug}}"
pull_request_id: "{{pr_id}}"
- name: create-change
type: call
call: "servicenow-std.create-change"
with:
short_description: "Deploy: {{get-pr.title}} ({{repo_slug}} PR#{{pr_id}})"
type: "standard"
description: "Author: {{get-pr.author.display_name}} | Merged: {{get-pr.updated_on}}"
consumes:
- type: http
namespace: bitbucket
baseUri: "https://api.bitbucket.org/2.0"
authentication:
type: bearer
token: "$secrets.bitbucket_token"
resources:
- name: pull-requests
path: "/repositories/{{workspace}}/{{repo_slug}}/pullrequests/{{pull_request_id}}"
inputParameters:
- name: workspace
in: path
- name: repo_slug
in: path
- name: pull_request_id
in: path
operations:
- name: get-pr
method: GET
- type: http
namespace: servicenow-std
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: changes
path: "/table/change_request"
operations:
- name: create-change
method: POST
Lists DNS records for a Cloudflare zone, returning record types, values, and TTL settings for network management queries.
naftiko: "0.5"
info:
label: "Cloudflare DNS Record Lookup"
description: "Lists DNS records for a Cloudflare zone, returning record types, values, and TTL settings for network management queries."
tags:
- networking
- dns
- cloudflare
capability:
exposes:
- type: mcp
namespace: dns
port: 8080
tools:
- name: list-dns-records
description: "Given a Cloudflare zone ID, return all DNS records with type, name, content, and TTL."
inputParameters:
- name: zone_id
in: body
type: string
description: "Cloudflare zone identifier."
call: cloudflare.list-records
with:
zone_id: "{{zone_id}}"
consumes:
- type: http
namespace: cloudflare
baseUri: "https://api.cloudflare.com/client/v4"
authentication:
type: bearer
token: "$secrets.cloudflare_token"
resources:
- name: dns-records
path: "/zones/{{zone_id}}/dns_records"
inputParameters:
- name: zone_id
in: path
operations:
- name: list-records
method: GET
When Cloudflare rate limiting triggers for a zone, creates a PagerDuty incident and updates the Cloudflare WAF rule to block the source IP.
naftiko: "0.5"
info:
label: "Cloudflare Rate Limit Breach to PagerDuty"
description: "When Cloudflare rate limiting triggers for a zone, creates a PagerDuty incident and updates the Cloudflare WAF rule to block the source IP."
tags:
- security
- networking
- cloudflare
- pagerduty
capability:
exposes:
- type: mcp
namespace: waf-ops
port: 8080
tools:
- name: handle-rate-limit-breach
description: "Given a Cloudflare zone and source IP, block the IP and create a PagerDuty incident."
inputParameters:
- name: zone_id
in: body
type: string
description: "Cloudflare zone ID."
- name: source_ip
in: body
type: string
description: "Offending source IP address."
steps:
- name: block-ip
type: call
call: "cloudflare.create-firewall-rule"
with:
zone_id: "{{zone_id}}"
mode: "block"
ip: "{{source_ip}}"
- name: create-incident
type: call
call: "pagerduty.create-incident"
with:
service_id: "$secrets.pd_security_service_id"
title: "Rate limit breach: {{source_ip}} blocked on zone {{zone_id}}"
urgency: "high"
consumes:
- type: http
namespace: cloudflare
baseUri: "https://api.cloudflare.com/client/v4"
authentication:
type: bearer
token: "$secrets.cloudflare_token"
resources:
- name: firewall-rules
path: "/zones/{{zone_id}}/firewall/access_rules/rules"
inputParameters:
- name: zone_id
in: path
operations:
- name: create-firewall-rule
method: POST
- type: http
namespace: pagerduty
baseUri: "https://api.pagerduty.com"
authentication:
type: apikey
key: "Authorization"
value: "Token token=$secrets.pagerduty_token"
placement: header
resources:
- name: incidents
path: "/incidents"
operations:
- name: create-incident
method: POST
Retrieves active threat indicators from Palo Alto Networks and creates or updates Cloudflare WAF custom rules to block matching IP ranges.
naftiko: "0.5"
info:
label: "Cloudflare WAF Rule Update from Threat Intelligence"
description: "Retrieves active threat indicators from Palo Alto Networks and creates or updates Cloudflare WAF custom rules to block matching IP ranges."
tags:
- security
- cloudflare
- palo-alto-networks
- threat-intelligence
- waf
capability:
exposes:
- type: mcp
namespace: security-waf
port: 8080
tools:
- name: update-waf-blocklist
description: "Given a Palo Alto Networks threat feed type, fetch current malicious IP indicators and push blocking WAF rules to the specified Cloudflare zone."
inputParameters:
- name: threat_feed_type
in: body
type: string
description: "Palo Alto threat feed category, e.g. command-and-control."
- name: cloudflare_zone_id
in: body
type: string
description: "Cloudflare zone ID to apply WAF rules to."
steps:
- name: get-indicators
type: call
call: "palo-alto-ti.get-threat-indicators"
with:
feed_type: "{{threat_feed_type}}"
- name: update-waf-rule
type: call
call: "cloudflare.update-waf-rule"
with:
zone_id: "{{cloudflare_zone_id}}"
ip_list: "{{get-indicators.ip_addresses}}"
action: "block"
consumes:
- type: http
namespace: palo-alto-ti
baseUri: "https://autofocus.paloaltonetworks.com/api/v1.0"
authentication:
type: apikey
key: "apiKey"
value: "$secrets.paloalto_autofocus_key"
placement: query
resources:
- name: threat-indicators
path: "/samples/search"
operations:
- name: get-threat-indicators
method: POST
- type: http
namespace: cloudflare
baseUri: "https://api.cloudflare.com/client/v4"
authentication:
type: bearer
token: "$secrets.cloudflare_token"
resources:
- name: waf-rules
path: "/zones/{{zone_id}}/firewall/rules"
inputParameters:
- name: zone_id
in: path
operations:
- name: update-waf-rule
method: PUT
Retrieves a Confluence page by title and space key, returning the page content body, last modified date, and author.
naftiko: "0.5"
info:
label: "Confluence Page Lookup"
description: "Retrieves a Confluence page by title and space key, returning the page content body, last modified date, and author."
tags:
- knowledge
- confluence
- documentation
capability:
exposes:
- type: mcp
namespace: knowledge
port: 8080
tools:
- name: get-confluence-page
description: "Given a space key and page title, return the Confluence page content, author, and last update timestamp."
inputParameters:
- name: space_key
in: body
type: string
description: "Confluence space key."
- name: page_title
in: body
type: string
description: "Page title to search for."
call: confluence.get-page
with:
spaceKey: "{{space_key}}"
title: "{{page_title}}"
consumes:
- type: http
namespace: confluence
baseUri: "https://ibm-wiki.atlassian.net/wiki/rest/api"
authentication:
type: basic
username: "$secrets.confluence_user"
password: "$secrets.confluence_api_token"
resources:
- name: content
path: "/content"
inputParameters:
- name: spaceKey
in: query
- name: title
in: query
operations:
- name: get-page
method: GET
When a PagerDuty incident fires, retrieves the corresponding Confluence runbook and posts the remediation steps to the incident Slack channel.
naftiko: "0.5"
info:
label: "Confluence Runbook Trigger from PagerDuty"
description: "When a PagerDuty incident fires, retrieves the corresponding Confluence runbook and posts the remediation steps to the incident Slack channel."
tags:
- operations
- documentation
- pagerduty
- confluence
- slack
capability:
exposes:
- type: mcp
namespace: runbook-ops
port: 8080
tools:
- name: fetch-runbook
description: "Given a PagerDuty incident ID, look up the service, find the Confluence runbook, and post steps to Slack."
inputParameters:
- name: incident_id
in: body
type: string
description: "PagerDuty incident ID."
- name: runbook_space
in: body
type: string
description: "Confluence space key for runbooks."
steps:
- name: get-incident
type: call
call: "pagerduty.get-incident"
with:
incident_id: "{{incident_id}}"
- name: get-runbook
type: call
call: "confluence.get-page"
with:
spaceKey: "{{runbook_space}}"
title: "Runbook: {{get-incident.service.summary}}"
- name: post-runbook
type: call
call: "slack.post-message"
with:
channel: "#incident-{{incident_id}}"
text: "Runbook for {{get-incident.service.summary}}:\n{{get-runbook.body.storage.value}}"
consumes:
- type: http
namespace: pagerduty
baseUri: "https://api.pagerduty.com"
authentication:
type: apikey
key: "Authorization"
value: "Token token=$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: confluence
baseUri: "https://ibm-wiki.atlassian.net/wiki/rest/api"
authentication:
type: basic
username: "$secrets.confluence_user"
password: "$secrets.confluence_api_token"
resources:
- name: content
path: "/content"
operations:
- name: get-page
method: GET
- type: http
namespace: slack
baseUri: "https://slack.com/api"
authentication:
type: bearer
token: "$secrets.slack_bot_token"
resources:
- name: messages
path: "/chat.postMessage"
operations:
- name: post-message
method: POST
When a Datadog monitor triggers a critical alert, creates a PagerDuty incident and posts a summary to the Slack on-call channel.
naftiko: "0.5"
info:
label: "Datadog Alert to PagerDuty Incident"
description: "When a Datadog monitor triggers a critical alert, creates a PagerDuty incident and posts a summary to the Slack on-call channel."
tags:
- observability
- incident-response
- datadog
- pagerduty
- slack
capability:
exposes:
- type: mcp
namespace: incident-ops
port: 8080
tools:
- name: escalate-datadog-alert
description: "Given a Datadog monitor ID, check the monitor status and if critical, create a PagerDuty incident and notify Slack."
inputParameters:
- name: monitor_id
in: body
type: string
description: "Datadog monitor ID."
- name: service_id
in: body
type: string
description: "PagerDuty service ID for routing."
steps:
- name: get-monitor
type: call
call: "datadog.get-monitor"
with:
monitor_id: "{{monitor_id}}"
- name: create-pd-incident
type: call
call: "pagerduty.create-incident"
with:
service_id: "{{service_id}}"
title: "Datadog Critical: {{get-monitor.name}}"
urgency: "high"
- name: notify-slack
type: call
call: "slack.post-message"
with:
channel: "#oncall-alerts"
text: "PagerDuty incident {{create-pd-incident.incident.id}} created for Datadog monitor {{get-monitor.name}}"
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: "Token token=$secrets.pagerduty_token"
placement: header
resources:
- name: incidents
path: "/incidents"
operations:
- name: create-incident
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 Datadog APM detects a latency spike above threshold, creates a Jira performance ticket and sends a Slack alert to the platform team.
naftiko: "0.5"
info:
label: "Datadog APM Latency Spike to Jira"
description: "When Datadog APM detects a latency spike above threshold, creates a Jira performance ticket and sends a Slack alert to the platform team."
tags:
- observability
- devops
- datadog
- jira
- slack
capability:
exposes:
- type: mcp
namespace: perf-ops
port: 8080
tools:
- name: handle-latency-spike
description: "Given a Datadog service name and latency threshold, check current p99 latency and create a Jira ticket if exceeded."
inputParameters:
- name: service_name
in: body
type: string
description: "Datadog service name."
- name: latency_threshold_ms
in: body
type: number
description: "P99 latency threshold in milliseconds."
steps:
- name: get-metrics
type: call
call: "datadog.get-service-metrics"
with:
service: "{{service_name}}"
- name: create-perf-ticket
type: call
call: "jira.create-issue"
with:
project: "PERF"
issuetype: "Task"
summary: "Latency spike: {{service_name}} p99 at {{get-metrics.p99_latency}}ms"
priority: "High"
- name: alert-platform
type: call
call: "slack.post-message"
with:
channel: "#platform-eng"
text: "Latency spike: {{service_name}} p99={{get-metrics.p99_latency}}ms (threshold: {{latency_threshold_ms}}ms) — Jira: {{create-perf-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: service-metrics
path: "/metrics/query"
operations:
- name: get-service-metrics
method: GET
- type: http
namespace: jira
baseUri: "https://ibm-jira.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
Retrieves the service dependency map from Datadog APM for a given service, showing upstream and downstream dependencies.
naftiko: "0.5"
info:
label: "Datadog Service Map Lookup"
description: "Retrieves the service dependency map from Datadog APM for a given service, showing upstream and downstream dependencies."
tags:
- observability
- datadog
- apm
capability:
exposes:
- type: mcp
namespace: observability
port: 8080
tools:
- name: get-service-dependencies
description: "Given a Datadog service name, return the upstream and downstream service dependencies from the APM service map."
inputParameters:
- name: service_name
in: body
type: string
description: "Datadog APM service name."
call: datadog.get-service-dependencies
with:
service: "{{service_name}}"
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: service-dependencies
path: "/service_dependencies"
inputParameters:
- name: service
in: query
operations:
- name: get-service-dependencies
method: GET
Monitors Datadog SLO burn rate and, when a threshold is breached, automatically opens a P1 ServiceNow incident and notifies New Relic with a deployment marker.
naftiko: "0.5"
info:
label: "Datadog SLO Breach to ServiceNow Incident"
description: "Monitors Datadog SLO burn rate and, when a threshold is breached, automatically opens a P1 ServiceNow incident and notifies New Relic with a deployment marker."
tags:
- observability
- itsm
- datadog
- new-relic
- servicenow
- incident-response
capability:
exposes:
- type: mcp
namespace: slo-ops
port: 8080
tools:
- name: handle-slo-breach
description: "Given a Datadog SLO ID and service name, check the current error budget burn rate and open a P1 ServiceNow incident if the burn rate exceeds the threshold."
inputParameters:
- name: slo_id
in: body
type: string
description: "Datadog SLO identifier."
- name: service_name
in: body
type: string
description: "Name of the service associated with the SLO."
- name: burn_rate_threshold
in: body
type: number
description: "Burn rate value above which to open an incident."
steps:
- name: get-slo
type: call
call: "datadog-slo.get-slo-history"
with:
slo_id: "{{slo_id}}"
- name: open-incident
type: call
call: "servicenow-p1.create-incident"
with:
short_description: "SLO breach: {{service_name}} burn rate exceeded {{burn_rate_threshold}}"
urgency: "1"
impact: "1"
assignment_group: "Platform_SRE"
- name: mark-deployment
type: call
call: "newrelic.create-deployment"
with:
entity_name: "{{service_name}}"
description: "SLO breach event — incident {{open-incident.number}}"
consumes:
- type: http
namespace: datadog-slo
baseUri: "https://api.datadoghq.com/api/v1"
authentication:
type: apikey
key: "DD-API-KEY"
value: "$secrets.datadog_api_key"
placement: header
resources:
- name: slo-history
path: "/slo/{{slo_id}}/history"
inputParameters:
- name: slo_id
in: path
operations:
- name: get-slo-history
method: GET
- type: http
namespace: servicenow-p1
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: incidents
path: "/table/incident"
operations:
- name: create-incident
method: POST
- type: http
namespace: newrelic
baseUri: "https://api.newrelic.com/v2"
authentication:
type: apikey
key: "X-Api-Key"
value: "$secrets.newrelic_api_key"
placement: header
resources:
- name: deployments
path: "/applications/deployments.json"
operations:
- name: create-deployment
method: POST
When Dynatrace detects an application problem, creates a ServiceNow incident with root cause details and notifies the on-call team.
naftiko: "0.5"
info:
label: "Dynatrace Problem to ServiceNow Incident"
description: "When Dynatrace detects an application problem, creates a ServiceNow incident with root cause details and notifies the on-call team."
tags:
- observability
- itsm
- dynatrace
- servicenow
- slack
capability:
exposes:
- type: mcp
namespace: apm-ops
port: 8080
tools:
- name: handle-dynatrace-problem
description: "Given a Dynatrace problem ID, retrieve the root cause analysis and create a ServiceNow incident."
inputParameters:
- name: problem_id
in: body
type: string
description: "Dynatrace problem ID."
steps:
- name: get-problem
type: call
call: "dynatrace.get-problem"
with:
problem_id: "{{problem_id}}"
- name: create-incident
type: call
call: "servicenow-ops.create-incident"
with:
short_description: "Dynatrace: {{get-problem.title}}"
description: "Root cause: {{get-problem.rootCauseEntity.name}} | Impact: {{get-problem.impactLevel}}"
urgency: "1"
assignment_group: "Application_Support"
- name: notify-oncall
type: call
call: "slack.post-message"
with:
channel: "#oncall-alerts"
text: "Dynatrace problem {{problem_id}} — ServiceNow {{create-incident.number}} created"
consumes:
- type: http
namespace: dynatrace
baseUri: "https://ibm.live.dynatrace.com/api/v2"
authentication:
type: apikey
key: "Authorization"
value: "Api-Token $secrets.dynatrace_token"
placement: header
resources:
- name: problems
path: "/problems/{{problem_id}}"
inputParameters:
- name: problem_id
in: path
operations:
- name: get-problem
method: GET
- type: http
namespace: servicenow-ops
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: incidents
path: "/table/incident"
operations:
- name: create-incident
method: POST
- type: http
namespace: slack
baseUri: "https://slack.com/api"
authentication:
type: bearer
token: "$secrets.slack_bot_token"
resources:
- name: messages
path: "/chat.postMessage"
operations:
- name: post-message
method: POST
When a GitHub Actions workflow fails on a release branch, creates a ServiceNow change request and alerts via SolarWinds event. Used by DevOps agents for automated release governance.
naftiko: "0.5"
info:
label: "GitHub Actions CI Failure to ServiceNow Change"
description: "When a GitHub Actions workflow fails on a release branch, creates a ServiceNow change request and alerts via SolarWinds event. Used by DevOps agents for automated release governance."
tags:
- devops
- cicd
- github
- servicenow
- solarwinds
capability:
exposes:
- type: mcp
namespace: devops
port: 8080
tools:
- name: handle-pipeline-failure
description: "Given a GitHub workflow run failure event, open a ServiceNow change request and send a SolarWinds alert event with failure context."
inputParameters:
- name: repo
in: body
type: string
description: "GitHub repository full name, e.g. ibm/my-service."
- name: run_id
in: body
type: string
description: "GitHub Actions workflow run ID."
- name: branch
in: body
type: string
description: "Branch name where the failure occurred."
- name: commit_sha
in: body
type: string
description: "Full SHA of the failing commit."
steps:
- name: get-run
type: call
call: "github.get-workflow-run"
with:
owner: "ibm"
repo: "{{repo}}"
run_id: "{{run_id}}"
- name: open-change
type: call
call: "servicenow-cr.create-change"
with:
short_description: "CI failure on {{branch}} — {{repo}} ({{commit_sha}})"
type: "emergency"
description: "Workflow run {{run_id}} failed. Conclusion: {{get-run.conclusion}}"
- name: send-event
type: call
call: "solarwinds.create-event"
with:
message: "CI failure: {{repo}} / {{branch}} — Change: {{open-change.number}}"
severity: "critical"
consumes:
- type: http
namespace: github
baseUri: "https://api.github.com"
authentication:
type: bearer
token: "$secrets.github_token"
resources:
- name: workflow-runs
path: "/repos/{{owner}}/{{repo}}/actions/runs/{{run_id}}"
inputParameters:
- name: owner
in: path
- name: repo
in: path
- name: run_id
in: path
operations:
- name: get-workflow-run
method: GET
- type: http
namespace: servicenow-cr
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: change-requests
path: "/table/change_request"
operations:
- name: create-change
method: POST
- type: http
namespace: solarwinds
baseUri: "https://api.solarwinds.com/v1"
authentication:
type: bearer
token: "$secrets.solarwinds_token"
resources:
- name: events
path: "/events"
operations:
- name: create-event
method: POST
When a GitHub Actions workflow run fails tests, retrieves the failure logs and posts a summary to the engineering Slack channel.
naftiko: "0.5"
info:
label: "GitHub Actions Test Failure to Slack"
description: "When a GitHub Actions workflow run fails tests, retrieves the failure logs and posts a summary to the engineering Slack channel."
tags:
- devops
- ci-cd
- github
- slack
capability:
exposes:
- type: mcp
namespace: ci-notify
port: 8080
tools:
- name: notify-test-failure
description: "Given a GitHub repository and workflow run ID, retrieve the failure details and notify Slack."
inputParameters:
- name: repo
in: body
type: string
description: "GitHub repository in owner/repo format."
- name: run_id
in: body
type: string
description: "GitHub Actions workflow run ID."
steps:
- name: get-run
type: call
call: "github.get-workflow-run"
with:
repo: "{{repo}}"
run_id: "{{run_id}}"
- name: notify-channel
type: call
call: "slack.post-message"
with:
channel: "#ci-cd"
text: "Test failure in {{repo}}: {{get-run.name}} — Branch: {{get-run.head_branch}} | Commit: {{get-run.head_sha}} | Author: {{get-run.actor.login}}"
consumes:
- type: http
namespace: github
baseUri: "https://api.github.com"
authentication:
type: bearer
token: "$secrets.github_token"
resources:
- name: workflow-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: slack
baseUri: "https://slack.com/api"
authentication:
type: bearer
token: "$secrets.slack_bot_token"
resources:
- name: messages
path: "/chat.postMessage"
operations:
- name: post-message
method: POST
When GitHub Dependabot finds a critical vulnerability, creates a Jira security task and notifies the AppSec team via Slack.
naftiko: "0.5"
info:
label: "GitHub Dependabot Alert to Jira Security Task"
description: "When GitHub Dependabot finds a critical vulnerability, creates a Jira security task and notifies the AppSec team via Slack."
tags:
- security
- devops
- github
- jira
- slack
capability:
exposes:
- type: mcp
namespace: appsec
port: 8080
tools:
- name: handle-dependabot-alert
description: "Given a GitHub repository and alert number, retrieve vulnerability details, create a Jira security task, and notify AppSec."
inputParameters:
- name: repo
in: body
type: string
description: "GitHub repository in owner/repo format."
- name: alert_number
in: body
type: string
description: "Dependabot alert number."
steps:
- name: get-alert
type: call
call: "github.get-dependabot-alert"
with:
repo: "{{repo}}"
alert_number: "{{alert_number}}"
- name: create-sec-task
type: call
call: "jira.create-issue"
with:
project: "SEC"
issuetype: "Task"
summary: "Dependabot: {{get-alert.security_advisory.summary}} in {{repo}}"
priority: "Critical"
description: "CVE: {{get-alert.security_advisory.cve_id}} | Severity: {{get-alert.security_advisory.severity}} | Package: {{get-alert.dependency.package.name}}"
- name: notify-appsec
type: call
call: "slack.post-message"
with:
channel: "#appsec"
text: "Critical vulnerability in {{repo}}: {{get-alert.security_advisory.summary}} — Jira: {{create-sec-task.key}}"
consumes:
- type: http
namespace: github
baseUri: "https://api.github.com"
authentication:
type: bearer
token: "$secrets.github_token"
resources:
- name: dependabot-alerts
path: "/repos/{{repo}}/dependabot/alerts/{{alert_number}}"
inputParameters:
- name: repo
in: path
- name: alert_number
in: path
operations:
- name: get-dependabot-alert
method: GET
- type: http
namespace: jira
baseUri: "https://ibm-jira.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 GitHub pull request is merged to main, creates a Datadog deployment event and updates the ServiceNow change request.
naftiko: "0.5"
info:
label: "GitHub PR Merge to Datadog Deployment Marker"
description: "When a GitHub pull request is merged to main, creates a Datadog deployment event and updates the ServiceNow change request."
tags:
- devops
- observability
- github
- datadog
- servicenow
capability:
exposes:
- type: mcp
namespace: deploy-tracking
port: 8080
tools:
- name: track-pr-merge
description: "Given a merged PR number and repo, create a Datadog deployment marker and close the associated ServiceNow change request."
inputParameters:
- name: repo
in: body
type: string
description: "GitHub repository in owner/repo format."
- name: pr_number
in: body
type: string
description: "Pull request number."
- name: change_number
in: body
type: string
description: "ServiceNow change request number."
steps:
- name: get-pr
type: call
call: "github.get-pull-request"
with:
repo: "{{repo}}"
pr_number: "{{pr_number}}"
- name: create-dd-event
type: call
call: "datadog.create-event"
with:
title: "Deployment: {{get-pr.title}}"
text: "PR #{{pr_number}} merged by {{get-pr.merged_by.login}}"
tags: "repo:{{repo}}"
- name: close-change
type: call
call: "servicenow-chg.update-change"
with:
number: "{{change_number}}"
state: "closed"
close_notes: "Deployed via PR #{{pr_number}}"
consumes:
- type: http
namespace: github
baseUri: "https://api.github.com"
authentication:
type: bearer
token: "$secrets.github_token"
resources:
- name: pull-requests
path: "/repos/{{repo}}/pulls/{{pr_number}}"
inputParameters:
- name: repo
in: path
- name: pr_number
in: path
operations:
- name: get-pull-request
method: GET
- type: http
namespace: datadog
baseUri: "https://api.datadoghq.com/api/v1"
authentication:
type: apikey
key: "DD-API-KEY"
value: "$secrets.datadog_api_key"
placement: header
resources:
- name: events
path: "/events"
operations:
- name: create-event
method: POST
- type: http
namespace: servicenow-chg
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: changes
path: "/table/change_request"
operations:
- name: update-change
method: PATCH
Retrieves branch protection rules for a GitHub repository, returning required reviews, status checks, and enforcement settings.
naftiko: "0.5"
info:
label: "GitHub Repository Branch Protection Lookup"
description: "Retrieves branch protection rules for a GitHub repository, returning required reviews, status checks, and enforcement settings."
tags:
- devops
- security
- github
capability:
exposes:
- type: mcp
namespace: code-governance
port: 8080
tools:
- name: get-branch-protection
description: "Given a GitHub repository and branch name, return the branch protection settings including required reviewers and status checks."
inputParameters:
- name: repo
in: body
type: string
description: "Repository in owner/repo format."
- name: branch
in: body
type: string
description: "Branch name, e.g. main."
call: github.get-branch-protection
with:
repo: "{{repo}}"
branch: "{{branch}}"
consumes:
- type: http
namespace: github
baseUri: "https://api.github.com"
authentication:
type: bearer
token: "$secrets.github_token"
resources:
- name: branch-protection
path: "/repos/{{repo}}/branches/{{branch}}/protection"
inputParameters:
- name: repo
in: path
- name: branch
in: path
operations:
- name: get-branch-protection
method: GET
Runs SonarQube quality gate checks against a GitHub repository and posts the scan summary as a ServiceNow change advisory board note.
naftiko: "0.5"
info:
label: "GitHub Repository Security Scan Digest"
description: "Runs SonarQube quality gate checks against a GitHub repository and posts the scan summary as a ServiceNow change advisory board note."
tags:
- devops
- security
- github
- sonarqube
- servicenow
- code-quality
capability:
exposes:
- type: mcp
namespace: devops-quality
port: 8080
tools:
- name: digest-security-scan
description: "Given a GitHub repository name and SonarQube project key, retrieve the latest quality gate result and post a scan digest as a ServiceNow advisory note."
inputParameters:
- name: repo
in: body
type: string
description: "GitHub repository name within the ibm org."
- name: sonar_project_key
in: body
type: string
description: "SonarQube project key, e.g. ibm_my-service."
steps:
- name: get-quality-gate
type: call
call: "sonarqube.get-quality-gate"
with:
projectKey: "{{sonar_project_key}}"
- name: get-repo-info
type: call
call: "github-scan.get-repo"
with:
owner: "ibm"
repo: "{{repo}}"
- name: post-advisory
type: call
call: "servicenow-cab.create-advisory"
with:
short_description: "Code scan: {{repo}} — Gate: {{get-quality-gate.status}}"
description: "Bugs: {{get-quality-gate.bugs}} | Vulnerabilities: {{get-quality-gate.vulnerabilities}} | Coverage: {{get-quality-gate.coverage}}"
consumes:
- type: http
namespace: sonarqube
baseUri: "https://sonarqube.ibm.internal/api"
authentication:
type: basic
username: "$secrets.sonar_token"
password: ""
resources:
- name: quality-gate
path: "/qualitygates/project_status"
inputParameters:
- name: projectKey
in: query
operations:
- name: get-quality-gate
method: GET
- type: http
namespace: github-scan
baseUri: "https://api.github.com"
authentication:
type: bearer
token: "$secrets.github_token"
resources:
- name: repos
path: "/repos/{{owner}}/{{repo}}"
inputParameters:
- name: owner
in: path
- name: repo
in: path
operations:
- name: get-repo
method: GET
- type: http
namespace: servicenow-cab
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: advisories
path: "/table/change_request"
operations:
- name: create-advisory
method: POST
On a GitLab merge request to a protected branch, runs a SonarQube quality gate check and blocks the MR with a comment if vulnerabilities exceed the allowed threshold.
naftiko: "0.5"
info:
label: "GitLab Merge Request Security Gate"
description: "On a GitLab merge request to a protected branch, runs a SonarQube quality gate check and blocks the MR with a comment if vulnerabilities exceed the allowed threshold."
tags:
- devops
- security
- gitlab
- sonarqube
- code-quality
capability:
exposes:
- type: mcp
namespace: mr-security-gate
port: 8080
tools:
- name: gate-merge-request
description: "Given a GitLab project ID, MR IID, and SonarQube project key, run a quality gate check and post a blocking comment on the MR if critical vulnerabilities are found."
inputParameters:
- name: gitlab_project_id
in: body
type: string
description: "GitLab project ID (numeric)."
- name: mr_iid
in: body
type: string
description: "GitLab merge request internal ID."
- name: sonar_project_key
in: body
type: string
description: "SonarQube project key to check."
steps:
- name: get-quality-gate
type: call
call: "sonarqube-gate.get-quality-gate"
with:
projectKey: "{{sonar_project_key}}"
- name: post-mr-comment
type: call
call: "gitlab.create-mr-note"
with:
project_id: "{{gitlab_project_id}}"
merge_request_iid: "{{mr_iid}}"
body: "Security Gate: {{get-quality-gate.status}} | Vulnerabilities: {{get-quality-gate.vulnerabilities}} | Blockers: {{get-quality-gate.blocker_violations}}"
consumes:
- type: http
namespace: sonarqube-gate
baseUri: "https://sonarqube.ibm.internal/api"
authentication:
type: basic
username: "$secrets.sonar_token"
password: ""
resources:
- name: quality-gate
path: "/qualitygates/project_status"
inputParameters:
- name: projectKey
in: query
operations:
- name: get-quality-gate
method: GET
- type: http
namespace: gitlab
baseUri: "https://gitlab.ibm.com/api/v4"
authentication:
type: bearer
token: "$secrets.gitlab_token"
resources:
- name: mr-notes
path: "/projects/{{project_id}}/merge_requests/{{merge_request_iid}}/notes"
inputParameters:
- name: project_id
in: path
- name: merge_request_iid
in: path
operations:
- name: create-mr-note
method: POST
Lists recently provisioned GCP resources in a project and creates a ServiceNow change record for each untracked resource detected during daily audit.
naftiko: "0.5"
info:
label: "Google Cloud Platform Resource Provisioning Audit"
description: "Lists recently provisioned GCP resources in a project and creates a ServiceNow change record for each untracked resource detected during daily audit."
tags:
- cloud
- gcp
- servicenow
- governance
- audit
capability:
exposes:
- type: mcp
namespace: cloud-audit
port: 8080
tools:
- name: audit-gcp-resources
description: "Given a GCP project ID, list all compute and storage resources created in the last 24 hours and open ServiceNow change records for any resources not already tracked."
inputParameters:
- name: gcp_project_id
in: body
type: string
description: "Google Cloud Platform project ID."
steps:
- name: list-resources
type: call
call: "gcp.list-assets"
with:
projectId: "{{gcp_project_id}}"
assetTypes: "compute.googleapis.com/Instance,storage.googleapis.com/Bucket"
- name: create-change-record
type: call
call: "servicenow-audit.create-change"
with:
short_description: "GCP resource audit: {{gcp_project_id}}"
description: "New resources detected: {{list-resources.asset_count}}"
consumes:
- type: http
namespace: gcp
baseUri: "https://cloudasset.googleapis.com/v1"
authentication:
type: bearer
token: "$secrets.gcp_token"
resources:
- name: assets
path: "/projects/{{projectId}}/assets"
inputParameters:
- name: projectId
in: path
- name: assetTypes
in: query
operations:
- name: list-assets
method: GET
- type: http
namespace: servicenow-audit
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: changes
path: "/table/change_request"
operations:
- name: create-change
method: POST
When a Grafana alert fires, creates a ServiceNow incident and attaches the relevant Confluence runbook link for remediation.
naftiko: "0.5"
info:
label: "Grafana Alert to ServiceNow with Runbook"
description: "When a Grafana alert fires, creates a ServiceNow incident and attaches the relevant Confluence runbook link for remediation."
tags:
- observability
- itsm
- grafana
- servicenow
- confluence
capability:
exposes:
- type: mcp
namespace: alert-mgmt
port: 8080
tools:
- name: handle-grafana-alert
description: "Given a Grafana alert rule name and service, create a ServiceNow incident and attach the Confluence runbook."
inputParameters:
- name: alert_name
in: body
type: string
description: "Grafana alert rule name."
- name: service_name
in: body
type: string
description: "Affected service name."
steps:
- name: get-runbook
type: call
call: "confluence.get-page"
with:
spaceKey: "RUNBOOKS"
title: "Runbook: {{service_name}}"
- name: create-incident
type: call
call: "servicenow-ops.create-incident"
with:
short_description: "Grafana alert: {{alert_name}} on {{service_name}}"
description: "Runbook: {{get-runbook.url}}"
urgency: "2"
assignment_group: "Platform_SRE"
consumes:
- type: http
namespace: confluence
baseUri: "https://ibm-wiki.atlassian.net/wiki/rest/api"
authentication:
type: basic
username: "$secrets.confluence_user"
password: "$secrets.confluence_api_token"
resources:
- name: content
path: "/content"
operations:
- name: get-page
method: GET
- type: http
namespace: servicenow-ops
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: incidents
path: "/table/incident"
operations:
- name: create-incident
method: POST
Searches HubSpot CRM for a contact by email address, returning company, lifecycle stage, and last activity date.
naftiko: "0.5"
info:
label: "HubSpot Contact Lookup"
description: "Searches HubSpot CRM for a contact by email address, returning company, lifecycle stage, and last activity date."
tags:
- crm
- marketing
- hubspot
capability:
exposes:
- type: mcp
namespace: crm
port: 8080
tools:
- name: lookup-contact
description: "Given an email address, search HubSpot CRM for the matching contact and return company, lifecycle stage, and last activity."
inputParameters:
- name: email
in: body
type: string
description: "Contact email address."
call: hubspot.search-contacts
with:
email: "{{email}}"
outputParameters:
- name: company
type: string
mapping: "$.results[0].properties.company"
- name: lifecycle_stage
type: string
mapping: "$.results[0].properties.lifecyclestage"
consumes:
- type: http
namespace: hubspot
baseUri: "https://api.hubapi.com"
authentication:
type: bearer
token: "$secrets.hubspot_token"
resources:
- name: contacts
path: "/crm/v3/objects/contacts/search"
operations:
- name: search-contacts
method: POST
Retrieves high-scoring leads from HubSpot and creates corresponding Salesforce lead records with owner assignment and Slack notification.
naftiko: "0.5"
info:
label: "HubSpot Lead Scoring to Salesforce Assignment"
description: "Retrieves high-scoring leads from HubSpot and creates corresponding Salesforce lead records with owner assignment and Slack notification."
tags:
- crm
- marketing
- hubspot
- salesforce
- slack
capability:
exposes:
- type: mcp
namespace: lead-ops
port: 8080
tools:
- name: route-high-score-leads
description: "Given a HubSpot lead score threshold, retrieve qualifying leads and create Salesforce records with routing."
inputParameters:
- name: score_threshold
in: body
type: number
description: "Minimum lead score to qualify."
steps:
- name: get-leads
type: call
call: "hubspot.search-contacts"
with:
min_score: "{{score_threshold}}"
- name: create-sf-lead
type: call
call: "salesforce.create-lead"
with:
FirstName: "{{get-leads.results[0].properties.firstname}}"
LastName: "{{get-leads.results[0].properties.lastname}}"
Company: "{{get-leads.results[0].properties.company}}"
Email: "{{get-leads.results[0].properties.email}}"
- name: notify-sales
type: call
call: "slack.post-message"
with:
channel: "#sales-leads"
text: "High-score lead routed to Salesforce: {{get-leads.results[0].properties.firstname}} {{get-leads.results[0].properties.lastname}} (Score: {{get-leads.results[0].properties.hubspotscore}})"
consumes:
- type: http
namespace: hubspot
baseUri: "https://api.hubapi.com"
authentication:
type: bearer
token: "$secrets.hubspot_token"
resources:
- name: contacts
path: "/crm/v3/objects/contacts/search"
operations:
- name: search-contacts
method: POST
- type: http
namespace: salesforce
baseUri: "https://ibm.my.salesforce.com/services/data/v59.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: leads
path: "/sobjects/Lead"
operations:
- name: create-lead
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 Jira bug is marked as a recurring defect, creates a ServiceNow problem record and links the Jira issue to the problem for root cause analysis.
naftiko: "0.5"
info:
label: "Jira Bug to ServiceNow Problem"
description: "When a Jira bug is marked as a recurring defect, creates a ServiceNow problem record and links the Jira issue to the problem for root cause analysis."
tags:
- devops
- itsm
- jira
- servicenow
- problem-management
capability:
exposes:
- type: mcp
namespace: problem-mgmt
port: 8080
tools:
- name: escalate-bug-to-problem
description: "Given a Jira issue key for a recurring bug, create a ServiceNow problem record and update the Jira issue with the problem number."
inputParameters:
- name: issue_key
in: body
type: string
description: "Jira issue key for the recurring bug."
steps:
- name: get-jira-bug
type: call
call: "jira.get-issue"
with:
issue_key: "{{issue_key}}"
- name: create-problem
type: call
call: "servicenow-prob.create-problem"
with:
short_description: "Recurring defect: {{get-jira-bug.fields.summary}}"
description: "Jira ref: {{issue_key}} | Priority: {{get-jira-bug.fields.priority.name}}"
category: "software"
- name: update-jira
type: call
call: "jira.add-comment"
with:
issue_key: "{{issue_key}}"
body: "ServiceNow problem {{create-problem.number}} created for root cause analysis."
consumes:
- type: http
namespace: jira
baseUri: "https://ibm-jira.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
- name: comments
path: "/issue/{{issue_key}}/comment"
inputParameters:
- name: issue_key
in: path
operations:
- name: add-comment
method: POST
- type: http
namespace: servicenow-prob
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: problems
path: "/table/problem"
operations:
- name: create-problem
method: POST
When a Jira epic is completed, updates the corresponding Salesforce opportunity stage and notifies the account team.
naftiko: "0.5"
info:
label: "Jira Epic Completion to Salesforce Update"
description: "When a Jira epic is completed, updates the corresponding Salesforce opportunity stage and notifies the account team."
tags:
- devops
- crm
- jira
- salesforce
- slack
capability:
exposes:
- type: mcp
namespace: delivery-crm
port: 8080
tools:
- name: sync-epic-completion
description: "Given a Jira epic key and Salesforce opportunity ID, update the opportunity delivery status and notify the team."
inputParameters:
- name: epic_key
in: body
type: string
description: "Jira epic key."
- name: opportunity_id
in: body
type: string
description: "Salesforce opportunity ID."
steps:
- name: get-epic
type: call
call: "jira.get-issue"
with:
issue_key: "{{epic_key}}"
- name: update-opportunity
type: call
call: "salesforce.update-opportunity"
with:
opportunity_id: "{{opportunity_id}}"
StageName: "Delivered"
Description: "Epic {{epic_key}} completed: {{get-epic.fields.summary}}"
- name: notify-account
type: call
call: "slack.post-message"
with:
channel: "#account-team"
text: "Epic {{epic_key}} delivered — Salesforce opportunity {{opportunity_id}} updated to Delivered"
consumes:
- type: http
namespace: jira
baseUri: "https://ibm-jira.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
- type: http
namespace: salesforce
baseUri: "https://ibm.my.salesforce.com/services/data/v59.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
Retrieves the current status, assignee, and priority of a Jira issue by key for project management and engineering queries.
naftiko: "0.5"
info:
label: "Jira Issue Status Lookup"
description: "Retrieves the current status, assignee, and priority of a Jira issue by key for project management and engineering queries."
tags:
- devops
- jira
- project-management
capability:
exposes:
- type: mcp
namespace: project-mgmt
port: 8080
tools:
- name: get-jira-issue
description: "Given a Jira issue key, retrieve current status, assignee, priority, and summary."
inputParameters:
- name: issue_key
in: body
type: string
description: "Jira issue key, e.g. PROJ-1234."
call: jira.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
baseUri: "https://ibm-jira.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
Compiles completed Jira issues for a release version, generates a Confluence release notes page, and notifies stakeholders via Slack.
naftiko: "0.5"
info:
label: "Jira Release Notes to Confluence"
description: "Compiles completed Jira issues for a release version, generates a Confluence release notes page, and notifies stakeholders via Slack."
tags:
- devops
- documentation
- jira
- confluence
- slack
capability:
exposes:
- type: mcp
namespace: release-mgmt
port: 8080
tools:
- name: generate-release-notes
description: "Given a Jira project and fix version, compile issues and create a Confluence release notes page."
inputParameters:
- name: project
in: body
type: string
description: "Jira project key."
- name: fix_version
in: body
type: string
description: "Jira fix version name."
steps:
- name: get-issues
type: call
call: "jira.search-issues"
with:
jql: "project={{project}} AND fixVersion='{{fix_version}}' AND status=Done"
- name: create-release-page
type: call
call: "confluence.create-page"
with:
space_key: "RELEASES"
title: "Release Notes: {{project}} {{fix_version}}"
body: "## Release {{fix_version}}\n\n### Issues Completed\n{{get-issues.summary_list}}"
- name: notify-stakeholders
type: call
call: "slack.post-message"
with:
channel: "#releases"
text: "Release notes published for {{project}} {{fix_version}}: {{create-release-page.url}}"
consumes:
- type: http
namespace: jira
baseUri: "https://ibm-jira.atlassian.net/rest/api/3"
authentication:
type: basic
username: "$secrets.jira_user"
password: "$secrets.jira_api_token"
resources:
- name: search
path: "/search"
operations:
- name: search-issues
method: POST
- type: http
namespace: confluence
baseUri: "https://ibm-wiki.atlassian.net/wiki/rest/api"
authentication:
type: basic
username: "$secrets.confluence_user"
password: "$secrets.confluence_api_token"
resources:
- name: content
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
Lists all active routes and services registered in the Kong API Gateway and reconciles them against a ServiceNow CMDB API record baseline.
naftiko: "0.5"
info:
label: "Kong API Gateway Route Audit"
description: "Lists all active routes and services registered in the Kong API Gateway and reconciles them against a ServiceNow CMDB API record baseline."
tags:
- api
- integration
- kong
- servicenow
- governance
capability:
exposes:
- type: mcp
namespace: api-governance
port: 8080
tools:
- name: audit-kong-routes
description: "List all Kong services and routes and compare against the ServiceNow CMDB. Create a CMDB update task for any unregistered API route detected."
inputParameters:
- name: kong_admin_url
in: body
type: string
description: "Kong Admin API base URL."
steps:
- name: list-services
type: call
call: "kong.list-services"
with:
admin_url: "{{kong_admin_url}}"
- name: create-cmdb-task
type: call
call: "servicenow-cmdb.create-task"
with:
short_description: "Kong API audit — unregistered routes detected"
description: "Total services: {{list-services.total}} | Unregistered: {{list-services.unregistered_count}}"
assignment_group: "API_Platform"
consumes:
- type: http
namespace: kong
baseUri: "https://kong-admin.ibm.internal:8001"
authentication:
type: apikey
key: "Kong-Admin-Token"
value: "$secrets.kong_admin_token"
placement: header
resources:
- name: services
path: "/services"
operations:
- name: list-services
method: GET
- type: http
namespace: servicenow-cmdb
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: tasks
path: "/table/sc_task"
operations:
- name: create-task
method: POST
Pulls new LinkedIn recruiter candidates for a given job requisition and creates candidate records in PeopleSoft HCM for recruiter review.
naftiko: "0.5"
info:
label: "LinkedIn Talent Pipeline to PeopleSoft Candidate Record"
description: "Pulls new LinkedIn recruiter candidates for a given job requisition and creates candidate records in PeopleSoft HCM for recruiter review."
tags:
- hr
- recruiting
- linkedin
- peoplesoft
- talent-acquisition
capability:
exposes:
- type: mcp
namespace: talent-acquisition
port: 8080
tools:
- name: sync-linkedin-candidates
description: "Given a LinkedIn job posting ID and a PeopleSoft business unit, fetch newly applied candidates from LinkedIn Recruiter and create candidate profiles in PeopleSoft HCM."
inputParameters:
- name: linkedin_job_id
in: body
type: string
description: "LinkedIn job posting ID."
- name: business_unit
in: body
type: string
description: "PeopleSoft HCM business unit code."
steps:
- name: get-candidates
type: call
call: "linkedin.get-applicants"
with:
jobId: "{{linkedin_job_id}}"
- name: create-ps-candidates
type: call
call: "peoplesoft.create-candidate"
with:
business_unit: "{{business_unit}}"
applicants: "{{get-candidates.applicants}}"
consumes:
- type: http
namespace: linkedin
baseUri: "https://api.linkedin.com/v2"
authentication:
type: bearer
token: "$secrets.linkedin_token"
resources:
- name: applicants
path: "/jobApplications"
inputParameters:
- name: jobId
in: query
operations:
- name: get-applicants
method: GET
- type: http
namespace: peoplesoft
baseUri: "https://ibm-ps.internal/hcm/api/v1"
authentication:
type: basic
username: "$secrets.peoplesoft_user"
password: "$secrets.peoplesoft_password"
resources:
- name: candidates
path: "/candidates"
operations:
- name: create-candidate
method: POST
Retrieves a Microsoft Teams meeting transcript summary and publishes it as a Confluence page for team knowledge base.
naftiko: "0.5"
info:
label: "Microsoft Teams Meeting Summary to Confluence"
description: "Retrieves a Microsoft Teams meeting transcript summary and publishes it as a Confluence page for team knowledge base."
tags:
- communication
- documentation
- microsoft-teams
- confluence
capability:
exposes:
- type: mcp
namespace: meeting-notes
port: 8080
tools:
- name: publish-meeting-notes
description: "Given a Teams meeting ID and Confluence space, retrieve the transcript and create a Confluence page."
inputParameters:
- name: meeting_id
in: body
type: string
description: "Microsoft Teams meeting ID."
- name: space_key
in: body
type: string
description: "Confluence space key."
steps:
- name: get-transcript
type: call
call: "teams.get-meeting-transcript"
with:
meeting_id: "{{meeting_id}}"
- name: create-page
type: call
call: "confluence.create-page"
with:
space_key: "{{space_key}}"
title: "Meeting Notes: {{get-transcript.subject}} — {{get-transcript.date}}"
body: "## Attendees\n{{get-transcript.attendees}}\n\n## Summary\n{{get-transcript.summary}}"
consumes:
- type: http
namespace: teams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.azure_graph_token"
resources:
- name: meetings
path: "/me/onlineMeetings/{{meeting_id}}/transcripts"
inputParameters:
- name: meeting_id
in: path
operations:
- name: get-meeting-transcript
method: GET
- type: http
namespace: confluence
baseUri: "https://ibm-wiki.atlassian.net/wiki/rest/api"
authentication:
type: basic
username: "$secrets.confluence_user"
password: "$secrets.confluence_api_token"
resources:
- name: content
path: "/content"
operations:
- name: create-page
method: POST
Retrieves the health status, response time, and error rate of an application monitored by New Relic APM.
naftiko: "0.5"
info:
label: "New Relic Application Health Lookup"
description: "Retrieves the health status, response time, and error rate of an application monitored by New Relic APM."
tags:
- observability
- new-relic
- apm
capability:
exposes:
- type: mcp
namespace: app-health
port: 8080
tools:
- name: get-app-health
description: "Given a New Relic application name, return its health status, average response time, and error rate."
inputParameters:
- name: app_name
in: body
type: string
description: "New Relic application name."
call: newrelic.get-application
with:
name: "{{app_name}}"
outputParameters:
- name: health_status
type: string
mapping: "$.applications[0].health_status"
- name: response_time
type: number
mapping: "$.applications[0].application_summary.response_time"
consumes:
- type: http
namespace: newrelic
baseUri: "https://api.newrelic.com/v2"
authentication:
type: apikey
key: "X-Api-Key"
value: "$secrets.newrelic_api_key"
placement: header
resources:
- name: applications
path: "/applications.json"
inputParameters:
- name: name
in: query
operations:
- name: get-application
method: GET
When New Relic detects an application error rate spike, creates a Jira bug ticket and notifies the engineering team via Slack.
naftiko: "0.5"
info:
label: "New Relic Error Spike to Jira Bug"
description: "When New Relic detects an application error rate spike, creates a Jira bug ticket and notifies the engineering team via Slack."
tags:
- observability
- devops
- new-relic
- jira
- slack
capability:
exposes:
- type: mcp
namespace: error-tracking
port: 8080
tools:
- name: handle-error-spike
description: "Given a New Relic application ID and error threshold, check the error rate, create a Jira bug if exceeded, and notify Slack."
inputParameters:
- name: app_id
in: body
type: string
description: "New Relic application ID."
- name: error_threshold
in: body
type: number
description: "Error rate percentage threshold."
steps:
- name: get-app-metrics
type: call
call: "newrelic.get-app-metrics"
with:
app_id: "{{app_id}}"
- name: create-bug
type: call
call: "jira.create-issue"
with:
project: "ENG"
issuetype: "Bug"
summary: "Error spike: {{get-app-metrics.app_name}} at {{get-app-metrics.error_rate}}%"
priority: "High"
- name: notify-team
type: call
call: "slack.post-message"
with:
channel: "#engineering"
text: "Error spike detected for {{get-app-metrics.app_name}} — Jira: {{create-bug.key}}"
consumes:
- type: http
namespace: newrelic
baseUri: "https://api.newrelic.com/v2"
authentication:
type: apikey
key: "X-Api-Key"
value: "$secrets.newrelic_api_key"
placement: header
resources:
- name: applications
path: "/applications/{{app_id}}.json"
inputParameters:
- name: app_id
in: path
operations:
- name: get-app-metrics
method: GET
- type: http
namespace: jira
baseUri: "https://ibm-jira.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
Resets a user MFA factors in Okta based on an approved ServiceNow request, then updates the ticket with completion status.
naftiko: "0.5"
info:
label: "Okta MFA Reset with ServiceNow Ticket"
description: "Resets a user MFA factors in Okta based on an approved ServiceNow request, then updates the ticket with completion status."
tags:
- security
- identity
- okta
- servicenow
capability:
exposes:
- type: mcp
namespace: identity-ops
port: 8080
tools:
- name: reset-mfa
description: "Given a ServiceNow request number and user email, reset the user MFA in Okta and update the ServiceNow ticket."
inputParameters:
- name: request_number
in: body
type: string
description: "ServiceNow request number."
- name: user_email
in: body
type: string
description: "User email for MFA reset."
steps:
- name: reset-okta-mfa
type: call
call: "okta.reset-factors"
with:
user_id: "{{user_email}}"
- name: update-ticket
type: call
call: "servicenow-req.update-request"
with:
number: "{{request_number}}"
state: "closed_complete"
close_notes: "MFA factors reset for {{user_email}}"
consumes:
- type: http
namespace: okta
baseUri: "https://ibm.okta.com/api/v1"
authentication:
type: apikey
key: "Authorization"
value: "SSWS $secrets.okta_api_token"
placement: header
resources:
- name: factors
path: "/users/{{user_id}}/lifecycle/reset_factors"
inputParameters:
- name: user_id
in: path
operations:
- name: reset-factors
method: POST
- type: http
namespace: servicenow-req
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: requests
path: "/table/sc_request"
operations:
- name: update-request
method: PATCH
Generates a quarterly access review by pulling all Okta application assignments, loading to Snowflake, and creating a ServiceNow access review task.
naftiko: "0.5"
info:
label: "Okta Quarterly Access Review Report"
description: "Generates a quarterly access review by pulling all Okta application assignments, loading to Snowflake, and creating a ServiceNow access review task."
tags:
- security
- compliance
- okta
- snowflake
- servicenow
capability:
exposes:
- type: mcp
namespace: access-review
port: 8080
tools:
- name: run-access-review
description: "Pull all Okta app assignments, load into Snowflake for analysis, and create a ServiceNow review task."
inputParameters:
- name: review_quarter
in: body
type: string
description: "Quarter label, e.g. Q1-2026."
steps:
- name: get-app-assignments
type: call
call: "okta.list-app-users"
with:
limit: "200"
- name: load-to-snowflake
type: call
call: "snowflake.execute-query"
with:
statement: "INSERT INTO SECURITY.ACCESS_REVIEWS (quarter, app_count) VALUES ('{{review_quarter}}', {{get-app-assignments.total}})"
- name: create-review-task
type: call
call: "servicenow-sec.create-task"
with:
short_description: "Quarterly access review: {{review_quarter}} — {{get-app-assignments.total}} assignments"
assignment_group: "IAM_Team"
consumes:
- type: http
namespace: okta
baseUri: "https://ibm.okta.com/api/v1"
authentication:
type: apikey
key: "Authorization"
value: "SSWS $secrets.okta_api_token"
placement: header
resources:
- name: app-users
path: "/apps"
operations:
- name: list-app-users
method: GET
- type: http
namespace: snowflake
baseUri: "https://ibm.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: servicenow-sec
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: tasks
path: "/table/sc_task"
operations:
- name: create-task
method: POST
When Okta flags a suspicious login event, triggers a Splunk investigation query and creates a ServiceNow security incident with findings.
naftiko: "0.5"
info:
label: "Okta Suspicious Login to Splunk Investigation"
description: "When Okta flags a suspicious login event, triggers a Splunk investigation query and creates a ServiceNow security incident with findings."
tags:
- security
- identity
- okta
- splunk
- servicenow
capability:
exposes:
- type: mcp
namespace: threat-response
port: 8080
tools:
- name: investigate-suspicious-login
description: "Given an Okta event ID, retrieve the event details, run a Splunk correlation query, and create a security incident."
inputParameters:
- name: event_id
in: body
type: string
description: "Okta system log event ID."
steps:
- name: get-okta-event
type: call
call: "okta.get-event"
with:
event_id: "{{event_id}}"
- name: run-splunk-query
type: call
call: "splunk.create-search"
with:
search: "index=network src_ip={{get-okta-event.client.ipAddress}} earliest=-24h"
- name: create-sec-incident
type: call
call: "servicenow-sec.create-incident"
with:
short_description: "Suspicious login: {{get-okta-event.actor.displayName}} from {{get-okta-event.client.ipAddress}}"
category: "security"
severity: "2"
assignment_group: "SOC_Team"
consumes:
- type: http
namespace: okta
baseUri: "https://ibm.okta.com/api/v1"
authentication:
type: apikey
key: "Authorization"
value: "SSWS $secrets.okta_api_token"
placement: header
resources:
- name: events
path: "/logs/{{event_id}}"
inputParameters:
- name: event_id
in: path
operations:
- name: get-event
method: GET
- type: http
namespace: splunk
baseUri: "https://splunk.ibm.com:8089/services"
authentication:
type: bearer
token: "$secrets.splunk_token"
resources:
- name: search-jobs
path: "/search/jobs"
operations:
- name: create-search
method: POST
- type: http
namespace: servicenow-sec
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: incidents
path: "/table/sn_si_incident"
operations:
- name: create-incident
method: POST
Lists all Okta groups a user belongs to by email address for identity governance and access review queries.
naftiko: "0.5"
info:
label: "Okta User Group Membership Lookup"
description: "Lists all Okta groups a user belongs to by email address for identity governance and access review queries."
tags:
- security
- identity
- okta
capability:
exposes:
- type: mcp
namespace: identity
port: 8080
tools:
- name: get-user-groups
description: "Given a user email, retrieve all Okta group memberships for the user."
inputParameters:
- name: user_email
in: body
type: string
description: "User email address registered in Okta."
call: okta.get-user-groups
with:
user_id: "{{user_email}}"
consumes:
- type: http
namespace: okta
baseUri: "https://ibm.okta.com/api/v1"
authentication:
type: apikey
key: "Authorization"
value: "SSWS $secrets.okta_api_token"
placement: header
resources:
- name: user-groups
path: "/users/{{user_id}}/groups"
inputParameters:
- name: user_id
in: path
operations:
- name: get-user-groups
method: GET
Queries Oracle Cloud cost management for daily spend anomalies above a configured threshold and creates a ServiceNow task for FinOps review.
naftiko: "0.5"
info:
label: "Oracle Cloud Cost Anomaly Detection"
description: "Queries Oracle Cloud cost management for daily spend anomalies above a configured threshold and creates a ServiceNow task for FinOps review."
tags:
- cloud
- finops
- oracle-cloud
- servicenow
- cost-management
capability:
exposes:
- type: mcp
namespace: cloud-finops
port: 8080
tools:
- name: detect-cost-anomaly
description: "Given an Oracle Cloud compartment OCID and a daily spend threshold in USD, check the current day's cost and open a ServiceNow FinOps review task if the threshold is exceeded."
inputParameters:
- name: compartment_id
in: body
type: string
description: "Oracle Cloud compartment OCID to analyze."
- name: threshold_usd
in: body
type: number
description: "Daily spend threshold in USD above which to trigger an alert."
steps:
- name: get-daily-cost
type: call
call: "oracle-cloud.get-usage-summary"
with:
compartmentId: "{{compartment_id}}"
- name: create-review-task
type: call
call: "servicenow-finops.create-task"
with:
short_description: "Cost anomaly: {{compartment_id}} exceeded ${{threshold_usd}}"
category: "finops"
assignment_group: "Cloud_FinOps"
description: "Daily cost: ${{get-daily-cost.total_amount_usd}}"
consumes:
- type: http
namespace: oracle-cloud
baseUri: "https://usageapi.us-ashburn-1.oraclecloud.com/20200107"
authentication:
type: bearer
token: "$secrets.oracle_cloud_token"
resources:
- name: usage-summary
path: "/usageSummary"
inputParameters:
- name: compartmentId
in: query
operations:
- name: get-usage-summary
method: POST
- type: http
namespace: servicenow-finops
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: tasks
path: "/table/sc_task"
operations:
- name: create-task
method: POST
Retrieves general ledger journal entry details from Oracle E-Business Suite for a given period and ledger. Used by finance agents during period-close reconciliation.
naftiko: "0.5"
info:
label: "Oracle E-Business Suite GL Journal Lookup"
description: "Retrieves general ledger journal entry details from Oracle E-Business Suite for a given period and ledger. Used by finance agents during period-close reconciliation."
tags:
- finance
- erp
- oracle-ebs
- general-ledger
- reporting
capability:
exposes:
- type: mcp
namespace: gl-finance
port: 8080
tools:
- name: get-gl-journal
description: "Given a ledger ID and accounting period name, retrieve unposted journal entries from Oracle EBS for review and approval."
inputParameters:
- name: ledger_id
in: body
type: string
description: "Oracle EBS ledger ID."
- name: period_name
in: body
type: string
description: "Accounting period name, e.g. JAN-2025."
call: "oracle-ebs.get-journals"
with:
ledger_id: "{{ledger_id}}"
period_name: "{{period_name}}"
outputParameters:
- name: journal_count
type: string
mapping: "$.count"
- name: total_debit
type: string
mapping: "$.totalDebit"
- name: total_credit
type: string
mapping: "$.totalCredit"
consumes:
- type: http
namespace: oracle-ebs
baseUri: "https://ibm-ebs.oracle.com/webservices/portal"
authentication:
type: basic
username: "$secrets.oracle_ebs_user"
password: "$secrets.oracle_ebs_password"
resources:
- name: journals
path: "/GlJournalLookupService/getJournals"
inputParameters:
- name: ledger_id
in: query
- name: period_name
in: query
operations:
- name: get-journals
method: GET
Extracts accounts payable invoice data from Oracle E-Business Suite and loads it into Snowflake for finance analytics.
naftiko: "0.5"
info:
label: "Oracle EBS AP Invoice to Snowflake Sync"
description: "Extracts accounts payable invoice data from Oracle E-Business Suite and loads it into Snowflake for finance analytics."
tags:
- finance
- data
- oracle
- snowflake
capability:
exposes:
- type: mcp
namespace: finance-etl
port: 8080
tools:
- name: sync-ap-invoices
description: "Given a date range, extract AP invoices from Oracle EBS and load them into the Snowflake finance schema."
inputParameters:
- name: start_date
in: body
type: string
description: "Start date for invoice extraction."
- name: end_date
in: body
type: string
description: "End date for invoice extraction."
steps:
- name: get-invoices
type: call
call: "oracle-ebs.get-ap-invoices"
with:
start_date: "{{start_date}}"
end_date: "{{end_date}}"
- name: load-to-snowflake
type: call
call: "snowflake.execute-query"
with:
statement: "INSERT INTO FINANCE.AP_INVOICES SELECT * FROM TABLE(RESULT_SCAN('{{get-invoices.query_id}}'))"
consumes:
- type: http
namespace: oracle-ebs
baseUri: "https://oracle-ebs.ibm.com/webservices/rest"
authentication:
type: basic
username: "$secrets.oracle_ebs_user"
password: "$secrets.oracle_ebs_password"
resources:
- name: ap-invoices
path: "/ap/invoices"
inputParameters:
- name: start_date
in: query
- name: end_date
in: query
operations:
- name: get-ap-invoices
method: GET
- type: http
namespace: snowflake
baseUri: "https://ibm.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: execute-query
method: POST
Monitors Oracle GoldenGate replication lag and, when threshold is exceeded, creates a ServiceNow incident and notifies the DBA team.
naftiko: "0.5"
info:
label: "Oracle GoldenGate Replication Lag Alert"
description: "Monitors Oracle GoldenGate replication lag and, when threshold is exceeded, creates a ServiceNow incident and notifies the DBA team."
tags:
- data
- database
- oracle
- servicenow
- slack
capability:
exposes:
- type: mcp
namespace: db-replication
port: 8080
tools:
- name: check-replication-lag
description: "Given a GoldenGate process name and lag threshold, check the lag and alert if exceeded."
inputParameters:
- name: process_name
in: body
type: string
description: "GoldenGate extract/replicat process name."
- name: lag_threshold_seconds
in: body
type: number
description: "Maximum acceptable lag in seconds."
steps:
- name: get-lag
type: call
call: "goldengate.get-process-status"
with:
process_name: "{{process_name}}"
- name: create-incident
type: call
call: "servicenow-db.create-incident"
with:
short_description: "GoldenGate lag alert: {{process_name}} at {{get-lag.lag_seconds}}s"
urgency: "2"
assignment_group: "DBA_Team"
- name: notify-dba
type: call
call: "slack.post-message"
with:
channel: "#dba-alerts"
text: "GoldenGate replication lag: {{process_name}} = {{get-lag.lag_seconds}}s (threshold: {{lag_threshold_seconds}}s)"
consumes:
- type: http
namespace: goldengate
baseUri: "https://goldengate.ibm.com/api/v2"
authentication:
type: basic
username: "$secrets.gg_user"
password: "$secrets.gg_password"
resources:
- name: processes
path: "/processes/{{process_name}}/status"
inputParameters:
- name: process_name
in: path
operations:
- name: get-process-status
method: GET
- type: http
namespace: servicenow-db
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: incidents
path: "/table/incident"
operations:
- name: create-incident
method: POST
- type: http
namespace: slack
baseUri: "https://slack.com/api"
authentication:
type: bearer
token: "$secrets.slack_bot_token"
resources:
- name: messages
path: "/chat.postMessage"
operations:
- name: post-message
method: POST
Queries Oracle Integration Cloud for failed integration instances over the last hour and creates a Datadog event for each failure to enable unified alerting.
naftiko: "0.5"
info:
label: "Oracle Integration Cloud Process Monitoring"
description: "Queries Oracle Integration Cloud for failed integration instances over the last hour and creates a Datadog event for each failure to enable unified alerting."
tags:
- integration
- observability
- oracle-integration
- datadog
- monitoring
capability:
exposes:
- type: mcp
namespace: integration-monitoring
port: 8080
tools:
- name: monitor-oic-failures
description: "Given an Oracle Integration Cloud base URL and lookback window in minutes, retrieve failed integration instances and post each as a Datadog event for monitoring."
inputParameters:
- name: oic_base_url
in: body
type: string
description: "Oracle Integration Cloud instance base URL."
- name: lookback_minutes
in: body
type: integer
description: "Number of minutes to look back for failed instances."
steps:
- name: get-failures
type: call
call: "oracle-oic.get-failed-instances"
with:
baseUrl: "{{oic_base_url}}"
lookbackMinutes: "{{lookback_minutes}}"
- name: post-dd-events
type: call
call: "datadog-event.post-event"
with:
title: "OIC Integration Failure"
text: "Failed instances: {{get-failures.failed_count}}"
tags: "source:oracle_integration,env:prod"
consumes:
- type: http
namespace: oracle-oic
baseUri: "https://ibm-oic.integration.ocp.oraclecloud.com/ic/api/integration/v1"
authentication:
type: basic
username: "$secrets.oic_user"
password: "$secrets.oic_password"
resources:
- name: instances
path: "/instances"
inputParameters:
- name: status
in: query
operations:
- name: get-failed-instances
method: GET
- type: http
namespace: datadog-event
baseUri: "https://api.datadoghq.com/api/v1"
authentication:
type: apikey
key: "DD-API-KEY"
value: "$secrets.datadog_api_key"
placement: header
resources:
- name: events
path: "/events"
operations:
- name: post-event
method: POST
When a PagerDuty incident is resolved, generates a postmortem page in Confluence with incident timeline and notifies the SRE team.
naftiko: "0.5"
info:
label: "PagerDuty Incident to Confluence Postmortem"
description: "When a PagerDuty incident is resolved, generates a postmortem page in Confluence with incident timeline and notifies the SRE team."
tags:
- operations
- documentation
- pagerduty
- confluence
- slack
capability:
exposes:
- type: mcp
namespace: postmortem
port: 8080
tools:
- name: create-postmortem
description: "Given a PagerDuty incident ID, retrieve the timeline, create a Confluence postmortem page, and notify the team."
inputParameters:
- name: incident_id
in: body
type: string
description: "PagerDuty incident ID."
steps:
- name: get-incident
type: call
call: "pagerduty.get-incident"
with:
incident_id: "{{incident_id}}"
- name: create-page
type: call
call: "confluence.create-page"
with:
space_key: "SRE"
title: "Postmortem: {{get-incident.title}} — {{get-incident.created_at}}"
body: "## Incident Summary\n- **Title:** {{get-incident.title}}\n- **Severity:** {{get-incident.urgency}}\n- **Duration:** {{get-incident.duration}}\n\n## Timeline\n{{get-incident.log_entries}}"
- name: notify-sre
type: call
call: "slack.post-message"
with:
channel: "#sre-team"
text: "Postmortem created for incident {{incident_id}}: {{create-page.url}}"
consumes:
- type: http
namespace: pagerduty
baseUri: "https://api.pagerduty.com"
authentication:
type: apikey
key: "Authorization"
value: "Token token=$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: confluence
baseUri: "https://ibm-wiki.atlassian.net/wiki/rest/api"
authentication:
type: basic
username: "$secrets.confluence_user"
password: "$secrets.confluence_api_token"
resources:
- name: content
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
Retrieves the current on-call engineer for a given PagerDuty schedule, returning name, contact, and escalation level.
naftiko: "0.5"
info:
label: "PagerDuty On-Call Schedule Lookup"
description: "Retrieves the current on-call engineer for a given PagerDuty schedule, returning name, contact, and escalation level."
tags:
- operations
- pagerduty
- incident-response
capability:
exposes:
- type: mcp
namespace: ops
port: 8080
tools:
- name: get-on-call
description: "Given a PagerDuty schedule ID, return the current on-call engineer name and contact information."
inputParameters:
- name: schedule_id
in: body
type: string
description: "PagerDuty schedule ID."
call: pagerduty.get-on-call
with:
schedule_id: "{{schedule_id}}"
outputParameters:
- name: engineer_name
type: string
mapping: "$.schedule.final_schedule.rendered_schedule_entries[0].user.name"
- name: engineer_email
type: string
mapping: "$.schedule.final_schedule.rendered_schedule_entries[0].user.email"
consumes:
- type: http
namespace: pagerduty
baseUri: "https://api.pagerduty.com"
authentication:
type: apikey
key: "Authorization"
value: "Token token=$secrets.pagerduty_token"
placement: header
resources:
- name: schedules
path: "/schedules/{{schedule_id}}"
inputParameters:
- name: schedule_id
in: path
operations:
- name: get-on-call
method: GET
When a Palo Alto Networks firewall generates a critical threat alert, creates a ServiceNow security incident and enriches it with threat intelligence from the alert payload.
naftiko: "0.5"
info:
label: "Palo Alto Networks Security Alert to ServiceNow Incident"
description: "When a Palo Alto Networks firewall generates a critical threat alert, creates a ServiceNow security incident and enriches it with threat intelligence from the alert payload."
tags:
- security
- itsm
- palo-alto-networks
- servicenow
- incident-response
capability:
exposes:
- type: mcp
namespace: security-ops
port: 8080
tools:
- name: handle-firewall-alert
description: "Given a Palo Alto Networks device hostname and threat log ID, retrieve the threat details and open a P2 ServiceNow security incident with full alert context."
inputParameters:
- name: device_hostname
in: body
type: string
description: "Hostname or IP of the Palo Alto Networks firewall."
- name: log_id
in: body
type: string
description: "Threat log entry ID from Palo Alto Networks."
steps:
- name: get-threat-log
type: call
call: "palo-alto.get-threat-log"
with:
hostname: "{{device_hostname}}"
log_id: "{{log_id}}"
- name: create-sec-incident
type: call
call: "servicenow-sec.create-incident"
with:
short_description: "Firewall threat: {{get-threat-log.threat_name}} from {{get-threat-log.src_ip}}"
category: "security"
urgency: "2"
impact: "2"
work_notes: "Severity: {{get-threat-log.severity}} | Destination: {{get-threat-log.dst_ip}}"
consumes:
- type: http
namespace: palo-alto
baseUri: "https://{{device_hostname}}/restapi/v10.1"
authentication:
type: apikey
key: "X-PAN-KEY"
value: "$secrets.paloalto_api_key"
placement: header
resources:
- name: threat-logs
path: "/log/threat"
inputParameters:
- name: log_id
in: query
operations:
- name: get-threat-log
method: GET
- type: http
namespace: servicenow-sec
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: incidents
path: "/table/incident"
operations:
- name: create-incident
method: POST
When an employee termination is recorded in PeopleSoft, opens a ServiceNow offboarding task, revokes Salesforce access, and creates a GitHub access removal issue.
naftiko: "0.5"
info:
label: "PeopleSoft Employee Termination and ServiceNow Offboarding"
description: "When an employee termination is recorded in PeopleSoft, opens a ServiceNow offboarding task, revokes Salesforce access, and creates a GitHub access removal issue."
tags:
- hr
- offboarding
- peoplesoft
- servicenow
- salesforce
- github
capability:
exposes:
- type: mcp
namespace: hr-offboarding
port: 8080
tools:
- name: trigger-offboarding
description: "Given a PeopleSoft employee ID and termination date, open a ServiceNow offboarding task, remove the employee from Salesforce user list, and file a GitHub issue to revoke repo access."
inputParameters:
- name: employee_id
in: body
type: string
description: "PeopleSoft employee ID."
- name: termination_date
in: body
type: string
description: "Effective termination date in YYYY-MM-DD format."
- name: employee_email
in: body
type: string
description: "Corporate email address of the departing employee."
steps:
- name: open-offboard-task
type: call
call: "servicenow-task.create-task"
with:
short_description: "Offboarding: {{employee_id}} effective {{termination_date}}"
category: "hr_offboarding"
assignment_group: "IT_Security"
- name: deactivate-sf-user
type: call
call: "salesforce-user.deactivate-user"
with:
email: "{{employee_email}}"
- name: file-github-issue
type: call
call: "github-offboard.create-issue"
with:
owner: "ibm"
repo: "access-management"
title: "Revoke access: {{employee_email}} (terminated {{termination_date}})"
body: "Employee {{employee_id}} has been terminated. Please revoke all repository access."
consumes:
- type: http
namespace: servicenow-task
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: tasks
path: "/table/sc_task"
operations:
- name: create-task
method: POST
- type: http
namespace: salesforce-user
baseUri: "https://ibm.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: users
path: "/sobjects/User"
operations:
- name: deactivate-user
method: PATCH
- type: http
namespace: github-offboard
baseUri: "https://api.github.com"
authentication:
type: bearer
token: "$secrets.github_token"
resources:
- name: issues
path: "/repos/{{owner}}/{{repo}}/issues"
inputParameters:
- name: owner
in: path
- name: repo
in: path
operations:
- name: create-issue
method: POST
Syncs completed Pluralsight course data for an employee to their PeopleSoft HCM training record. Used by L&D agents for compliance tracking.
naftiko: "0.5"
info:
label: "Pluralsight Learning Completion to PeopleSoft Training Record"
description: "Syncs completed Pluralsight course data for an employee to their PeopleSoft HCM training record. Used by L&D agents for compliance tracking."
tags:
- hr
- learning
- pluralsight
- peoplesoft
- compliance
capability:
exposes:
- type: mcp
namespace: learning-sync
port: 8080
tools:
- name: sync-learning-completion
description: "Given a Pluralsight user handle and a PeopleSoft employee ID, retrieve all completed courses from Pluralsight and upsert corresponding training records in PeopleSoft HCM."
inputParameters:
- name: pluralsight_handle
in: body
type: string
description: "Pluralsight user handle or email."
- name: employee_id
in: body
type: string
description: "PeopleSoft employee ID."
steps:
- name: get-completions
type: call
call: "pluralsight.get-completions"
with:
handle: "{{pluralsight_handle}}"
- name: upsert-training
type: call
call: "peoplesoft-training.upsert-training"
with:
employee_id: "{{employee_id}}"
courses: "{{get-completions.courses}}"
consumes:
- type: http
namespace: pluralsight
baseUri: "https://api.pluralsight.com/v2"
authentication:
type: bearer
token: "$secrets.pluralsight_token"
resources:
- name: completions
path: "/users/{{handle}}/courses/completions"
inputParameters:
- name: handle
in: path
operations:
- name: get-completions
method: GET
- type: http
namespace: peoplesoft-training
baseUri: "https://ibm-ps.internal/hcm/api/v1"
authentication:
type: basic
username: "$secrets.peoplesoft_user"
password: "$secrets.peoplesoft_password"
resources:
- name: training-records
path: "/employees/{{employee_id}}/training"
inputParameters:
- name: employee_id
in: path
operations:
- name: upsert-training
method: PUT
Checks the last refresh status of a Power BI dataset, returning completion time and status for reporting readiness queries.
naftiko: "0.5"
info:
label: "Power BI Dataset Refresh Status"
description: "Checks the last refresh status of a Power BI dataset, returning completion time and status for reporting readiness queries."
tags:
- analytics
- reporting
- power-bi
capability:
exposes:
- type: mcp
namespace: reporting
port: 8080
tools:
- name: get-dataset-refresh-status
description: "Given a Power BI group ID and dataset ID, return the last refresh status and end time."
inputParameters:
- name: group_id
in: body
type: string
description: "Power BI workspace group ID."
- name: dataset_id
in: body
type: string
description: "Power BI dataset ID."
call: powerbi.get-refresh-history
with:
group_id: "{{group_id}}"
dataset_id: "{{dataset_id}}"
consumes:
- type: http
namespace: powerbi
baseUri: "https://api.powerbi.com/v1.0/myorg"
authentication:
type: bearer
token: "$secrets.powerbi_token"
resources:
- name: refreshes
path: "/groups/{{group_id}}/datasets/{{dataset_id}}/refreshes"
inputParameters:
- name: group_id
in: path
- name: dataset_id
in: path
operations:
- name: get-refresh-history
method: GET
Triggers a Power BI dataset refresh, waits for completion, and posts the report link to designated Slack channels for stakeholder distribution.
naftiko: "0.5"
info:
label: "Power BI Report Distribution via Slack"
description: "Triggers a Power BI dataset refresh, waits for completion, and posts the report link to designated Slack channels for stakeholder distribution."
tags:
- analytics
- reporting
- power-bi
- slack
capability:
exposes:
- type: mcp
namespace: report-dist
port: 8080
tools:
- name: distribute-report
description: "Given a Power BI dataset ID and report URL, trigger a refresh and distribute to Slack."
inputParameters:
- name: dataset_id
in: body
type: string
description: "Power BI dataset ID."
- name: report_url
in: body
type: string
description: "Power BI report URL."
- name: slack_channel
in: body
type: string
description: "Slack channel for distribution."
steps:
- name: trigger-refresh
type: call
call: "powerbi.trigger-refresh"
with:
dataset_id: "{{dataset_id}}"
- name: post-report
type: call
call: "slack.post-message"
with:
channel: "{{slack_channel}}"
text: "Weekly report refreshed and ready: {{report_url}}"
consumes:
- type: http
namespace: powerbi
baseUri: "https://api.powerbi.com/v1.0/myorg"
authentication:
type: bearer
token: "$secrets.powerbi_token"
resources:
- name: datasets
path: "/datasets/{{dataset_id}}/refreshes"
inputParameters:
- name: dataset_id
in: path
operations:
- name: trigger-refresh
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 the health status of Red Hat OpenShift cluster nodes and pushes custom metrics to Datadog for unified monitoring dashboards.
naftiko: "0.5"
info:
label: "Red Hat OpenShift Cluster Health to Datadog"
description: "Checks the health status of Red Hat OpenShift cluster nodes and pushes custom metrics to Datadog for unified monitoring dashboards."
tags:
- infrastructure
- observability
- red-hat
- datadog
- slack
capability:
exposes:
- type: mcp
namespace: k8s-health
port: 8080
tools:
- name: check-cluster-health
description: "Given an OpenShift cluster URL, check node readiness and push health metrics to Datadog."
inputParameters:
- name: cluster_url
in: body
type: string
description: "OpenShift API server URL."
steps:
- name: get-nodes
type: call
call: "openshift.get-nodes"
with:
cluster_url: "{{cluster_url}}"
- name: push-metrics
type: call
call: "datadog.submit-metrics"
with:
series_name: "openshift.node.ready_count"
value: "{{get-nodes.ready_count}}"
tags: "cluster:{{cluster_url}}"
- name: notify-ops
type: call
call: "slack.post-message"
with:
channel: "#k8s-ops"
text: "OpenShift cluster health: {{get-nodes.ready_count}}/{{get-nodes.total_count}} nodes ready"
consumes:
- type: http
namespace: openshift
baseUri: "{{cluster_url}}"
authentication:
type: bearer
token: "$secrets.openshift_token"
resources:
- name: nodes
path: "/api/v1/nodes"
operations:
- name: get-nodes
method: GET
- type: http
namespace: datadog
baseUri: "https://api.datadoghq.com/api/v2"
authentication:
type: apikey
key: "DD-API-KEY"
value: "$secrets.datadog_api_key"
placement: header
resources:
- name: metrics
path: "/series"
operations:
- name: submit-metrics
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
Lists all active Salesforce Flow and Process Builder automations and logs a governance snapshot to a Crystal Reports dataset for quarterly review.
naftiko: "0.5"
info:
label: "Salesforce Automation Workflow Audit"
description: "Lists all active Salesforce Flow and Process Builder automations and logs a governance snapshot to a Crystal Reports dataset for quarterly review."
tags:
- sales
- governance
- salesforce
- crystal-reports
- audit
capability:
exposes:
- type: mcp
namespace: sf-governance
port: 8080
tools:
- name: audit-sf-automations
description: "List all active Salesforce Flows and Process Builder records and push the governance snapshot to a Crystal Reports data store for quarterly compliance review."
inputParameters:
- name: report_quarter
in: body
type: string
description: "Report quarter label, e.g. Q1-2025."
steps:
- name: list-flows
type: call
call: "salesforce-flows.list-flows"
with:
status: "Active"
- name: push-to-report
type: call
call: "crystal-gov.refresh-report"
with:
report_name: "SalesforceAutomationAudit"
quarter: "{{report_quarter}}"
data: "{{list-flows.records}}"
consumes:
- type: http
namespace: salesforce-flows
baseUri: "https://ibm.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: flows
path: "/query"
inputParameters:
- name: q
in: query
operations:
- name: list-flows
method: GET
- type: http
namespace: crystal-gov
baseUri: "https://ibm-bobj.internal/biprws/v1"
authentication:
type: bearer
token: "$secrets.crystal_reports_token"
resources:
- name: reports
path: "/reports/refresh"
operations:
- name: refresh-report
method: POST
Retrieves the current status, owner, and priority of a Salesforce support case by case number.
naftiko: "0.5"
info:
label: "Salesforce Case Status Lookup"
description: "Retrieves the current status, owner, and priority of a Salesforce support case by case number."
tags:
- crm
- support
- salesforce
capability:
exposes:
- type: mcp
namespace: support
port: 8080
tools:
- name: get-case-status
description: "Given a Salesforce case number, return the case status, owner, priority, and subject."
inputParameters:
- name: case_number
in: body
type: string
description: "Salesforce case number."
call: salesforce.get-case
with:
case_number: "{{case_number}}"
consumes:
- type: http
namespace: salesforce
baseUri: "https://ibm.my.salesforce.com/services/data/v59.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: cases
path: "/query?q=SELECT+Id,Status,Priority,Owner.Name,Subject+FROM+Case+WHERE+CaseNumber='{{case_number}}'"
inputParameters:
- name: case_number
in: query
operations:
- name: get-case
method: GET
When a Salesforce opportunity moves to Closed-Won, creates a Jira project for delivery and posts the kickoff notification to Slack.
naftiko: "0.5"
info:
label: "Salesforce Closed-Won to Jira Project"
description: "When a Salesforce opportunity moves to Closed-Won, creates a Jira project for delivery and posts the kickoff notification to Slack."
tags:
- crm
- devops
- salesforce
- jira
- slack
capability:
exposes:
- type: mcp
namespace: deal-handoff
port: 8080
tools:
- name: handle-closed-won
description: "Given a Salesforce opportunity ID, retrieve deal details, create a Jira project, and notify the delivery team via Slack."
inputParameters:
- name: opportunity_id
in: body
type: string
description: "Salesforce opportunity ID."
steps:
- name: get-opportunity
type: call
call: "salesforce.get-opportunity"
with:
opportunity_id: "{{opportunity_id}}"
- name: create-jira-project
type: call
call: "jira.create-project"
with:
name: "{{get-opportunity.Name}}"
key: "{{get-opportunity.ProjectKey}}"
projectTypeKey: "software"
- name: notify-delivery
type: call
call: "slack.post-message"
with:
channel: "#delivery-team"
text: "New project created: {{get-opportunity.Name}} | Jira: {{create-jira-project.key}} | Value: {{get-opportunity.Amount}}"
consumes:
- type: http
namespace: salesforce
baseUri: "https://ibm.my.salesforce.com/services/data/v59.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: opportunities
path: "/sobjects/Opportunity/{{opportunity_id}}"
inputParameters:
- name: opportunity_id
in: path
operations:
- name: get-opportunity
method: GET
- type: http
namespace: jira
baseUri: "https://ibm-jira.atlassian.net/rest/api/3"
authentication:
type: basic
username: "$secrets.jira_user"
password: "$secrets.jira_api_token"
resources:
- name: projects
path: "/project"
operations:
- name: create-project
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
Identifies Salesforce contracts expiring within 90 days and enrolls the contacts in a HubSpot renewal nurture workflow.
naftiko: "0.5"
info:
label: "Salesforce Contract Expiry to HubSpot Nurture"
description: "Identifies Salesforce contracts expiring within 90 days and enrolls the contacts in a HubSpot renewal nurture workflow."
tags:
- crm
- marketing
- salesforce
- hubspot
- slack
capability:
exposes:
- type: mcp
namespace: renewal-nurture
port: 8080
tools:
- name: trigger-renewal-nurture
description: "Given a Salesforce contract ID expiring soon, enroll the account contact in a HubSpot nurture workflow and notify the CSM."
inputParameters:
- name: contract_id
in: body
type: string
description: "Salesforce contract ID."
steps:
- name: get-contract
type: call
call: "salesforce.get-contract"
with:
contract_id: "{{contract_id}}"
- name: enroll-nurture
type: call
call: "hubspot.enroll-workflow"
with:
email: "{{get-contract.Contact.Email}}"
workflow_id: "$secrets.hubspot_renewal_workflow_id"
- name: notify-csm
type: call
call: "slack.post-message"
with:
channel: "#customer-success"
text: "Contract {{contract_id}} for {{get-contract.Account.Name}} expires {{get-contract.EndDate}} — HubSpot nurture enrolled"
consumes:
- type: http
namespace: salesforce
baseUri: "https://ibm.my.salesforce.com/services/data/v59.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: contracts
path: "/sobjects/Contract/{{contract_id}}"
inputParameters:
- name: contract_id
in: path
operations:
- name: get-contract
method: GET
- type: http
namespace: hubspot
baseUri: "https://api.hubapi.com"
authentication:
type: bearer
token: "$secrets.hubspot_token"
resources:
- name: workflows
path: "/automation/v4/actions/workflows/{{workflow_id}}/enrollments"
inputParameters:
- name: workflow_id
in: path
operations:
- name: enroll-workflow
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 Salesforce lead is converted, creates or updates the corresponding HubSpot contact with matched fields. Used by marketing operations agents to maintain CRM-MAP alignment.
naftiko: "0.5"
info:
label: "Salesforce Lead to HubSpot Contact Sync"
description: "When a Salesforce lead is converted, creates or updates the corresponding HubSpot contact with matched fields. Used by marketing operations agents to maintain CRM-MAP alignment."
tags:
- sales
- marketing
- salesforce
- hubspot
- crm
capability:
exposes:
- type: mcp
namespace: crm-sync
port: 8080
tools:
- name: sync-lead-to-hubspot
description: "Given a Salesforce lead ID, fetch lead details and upsert the contact record in HubSpot CRM, aligning email, company, and lifecycle stage."
inputParameters:
- name: lead_id
in: body
type: string
description: "Salesforce Lead ID (18-char)."
steps:
- name: get-lead
type: call
call: "salesforce-lead.get-lead"
with:
lead_id: "{{lead_id}}"
- name: upsert-contact
type: call
call: "hubspot.upsert-contact"
with:
email: "{{get-lead.Email}}"
firstname: "{{get-lead.FirstName}}"
lastname: "{{get-lead.LastName}}"
company: "{{get-lead.Company}}"
lifecyclestage: "lead"
consumes:
- type: http
namespace: salesforce-lead
baseUri: "https://ibm.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: hubspot
baseUri: "https://api.hubapi.com/crm/v3"
authentication:
type: bearer
token: "$secrets.hubspot_token"
resources:
- name: contacts
path: "/objects/contacts/batch/upsert"
operations:
- name: upsert-contact
method: POST
Pulls open opportunities from Salesforce, filters by stage and close date, and posts a pipeline summary to ServiceNow as a knowledge article. Used weekly by sales operations agents.
naftiko: "0.5"
info:
label: "Salesforce Opportunity Pipeline Digest"
description: "Pulls open opportunities from Salesforce, filters by stage and close date, and posts a pipeline summary to ServiceNow as a knowledge article. Used weekly by sales operations agents."
tags:
- sales
- crm
- salesforce
- servicenow
- reporting
capability:
exposes:
- type: mcp
namespace: sales-reporting
port: 8080
tools:
- name: digest-open-pipeline
description: "Given a Salesforce stage filter and a close-date window (days), query open opportunities and post a pipeline digest to ServiceNow as a knowledge article draft."
inputParameters:
- name: stage_filter
in: body
type: string
description: "Salesforce opportunity stage name to filter, e.g. Proposal/Price Quote."
- name: close_days
in: body
type: integer
description: "Number of days from today to use as the close-date upper bound."
steps:
- name: get-opportunities
type: call
call: "salesforce.query-opportunities"
with:
stage: "{{stage_filter}}"
close_days: "{{close_days}}"
- name: post-knowledge
type: call
call: "servicenow.create-kb-article"
with:
title: "Pipeline Digest — {{stage_filter}}"
text: "{{get-opportunities.records}}"
category: "sales_ops"
consumes:
- type: http
namespace: salesforce
baseUri: "https://ibm.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: opportunities
path: "/query"
inputParameters:
- name: q
in: query
operations:
- name: query-opportunities
method: GET
- type: http
namespace: servicenow
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: kb-articles
path: "/table/kb_knowledge"
operations:
- name: create-kb-article
method: POST
Identifies at-risk Salesforce renewal opportunities and enrolls the account contacts into a HubSpot retention campaign.
naftiko: "0.5"
info:
label: "Salesforce Renewal Risk to HubSpot Campaign"
description: "Identifies at-risk Salesforce renewal opportunities and enrolls the account contacts into a HubSpot retention campaign."
tags:
- crm
- marketing
- salesforce
- hubspot
capability:
exposes:
- type: mcp
namespace: retention
port: 8080
tools:
- name: handle-renewal-risk
description: "Given a Salesforce opportunity ID flagged as at-risk, retrieve account contacts and enroll them in a HubSpot retention campaign."
inputParameters:
- name: opportunity_id
in: body
type: string
description: "Salesforce opportunity ID."
- name: campaign_id
in: body
type: string
description: "HubSpot campaign ID for retention."
steps:
- name: get-opportunity
type: call
call: "salesforce.get-opportunity"
with:
opportunity_id: "{{opportunity_id}}"
- name: enroll-contact
type: call
call: "hubspot.add-to-campaign"
with:
email: "{{get-opportunity.Contact.Email}}"
campaign_id: "{{campaign_id}}"
consumes:
- type: http
namespace: salesforce
baseUri: "https://ibm.my.salesforce.com/services/data/v59.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: opportunities
path: "/sobjects/Opportunity/{{opportunity_id}}"
inputParameters:
- name: opportunity_id
in: path
operations:
- name: get-opportunity
method: GET
- type: http
namespace: hubspot
baseUri: "https://api.hubapi.com"
authentication:
type: bearer
token: "$secrets.hubspot_token"
resources:
- name: campaigns
path: "/email/public/v1/campaigns/{{campaign_id}}/contacts"
inputParameters:
- name: campaign_id
in: path
operations:
- name: add-to-campaign
method: POST
Retrieves SAP BRIM billing document totals for a given billing period and compares them against Salesforce contract ARR values to detect discrepancies.
naftiko: "0.5"
info:
label: "SAP BRIM Subscription Billing Reconciliation"
description: "Retrieves SAP BRIM billing document totals for a given billing period and compares them against Salesforce contract ARR values to detect discrepancies."
tags:
- finance
- erp
- sap-s4hana
- salesforce
- billing
- reconciliation
capability:
exposes:
- type: mcp
namespace: billing-finance
port: 8080
tools:
- name: reconcile-brim-billing
description: "Given a SAP BRIM billing period and a Salesforce contract ID, fetch billed amounts from SAP and compare against the contracted ARR in Salesforce, flagging discrepancies."
inputParameters:
- name: billing_period
in: body
type: string
description: "SAP BRIM billing period in YYYYMM format."
- name: contract_id
in: body
type: string
description: "Salesforce contract record ID."
steps:
- name: get-brim-docs
type: call
call: "sap-brim.get-billing-docs"
with:
billing_period: "{{billing_period}}"
- name: get-sf-contract
type: call
call: "salesforce-contract.get-contract"
with:
contract_id: "{{contract_id}}"
- name: log-reconciliation
type: call
call: "salesforce-note.create-note"
with:
ParentId: "{{contract_id}}"
Title: "BRIM Reconciliation {{billing_period}}"
Body: "BRIM total: {{get-brim-docs.total_amount}} | SF ARR: {{get-sf-contract.annual_arr}}"
consumes:
- type: http
namespace: sap-brim
baseUri: "https://ibm-s4.sap.com/sap/opu/odata/sap/BRIM_BILLING_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: billing-docs
path: "/BillingDocuments"
inputParameters:
- name: billing_period
in: query
operations:
- name: get-billing-docs
method: GET
- type: http
namespace: salesforce-contract
baseUri: "https://ibm.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: contracts
path: "/sobjects/Contract/{{contract_id}}"
inputParameters:
- name: contract_id
in: path
operations:
- name: get-contract
method: GET
- type: http
namespace: salesforce-note
baseUri: "https://ibm.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: notes
path: "/sobjects/Note"
operations:
- name: create-note
method: POST
Triggers a SAP BW query refresh for a given InfoProvider and distributes the result set to a configured Crystal Reports dashboard.
naftiko: "0.5"
info:
label: "SAP BW Report Refresh and Distribution"
description: "Triggers a SAP BW query refresh for a given InfoProvider and distributes the result set to a configured Crystal Reports dashboard."
tags:
- data
- analytics
- sap-bw
- crystal-reports
- reporting
capability:
exposes:
- type: mcp
namespace: bw-reporting
port: 8080
tools:
- name: refresh-bw-report
description: "Given a SAP BW InfoProvider name and a Crystal Reports report name, trigger the BW query refresh and push the updated dataset to the Crystal Reports server."
inputParameters:
- name: info_provider
in: body
type: string
description: "SAP BW InfoProvider technical name."
- name: report_name
in: body
type: string
description: "Crystal Reports report name to refresh."
steps:
- name: trigger-bw-refresh
type: call
call: "sap-bw.refresh-query"
with:
infoProvider: "{{info_provider}}"
- name: push-to-crystal
type: call
call: "crystal-bw.refresh-report"
with:
report_name: "{{report_name}}"
data: "{{trigger-bw-refresh.result_set}}"
consumes:
- type: http
namespace: sap-bw
baseUri: "https://ibm-bw.sap.com/sap/bw/ina/GetServerInfo"
authentication:
type: basic
username: "$secrets.sap_bw_user"
password: "$secrets.sap_bw_password"
resources:
- name: queries
path: "/query/refresh"
operations:
- name: refresh-query
method: POST
- type: http
namespace: crystal-bw
baseUri: "https://ibm-bobj.internal/biprws/v1"
authentication:
type: bearer
token: "$secrets.crystal_reports_token"
resources:
- name: reports
path: "/reports/refresh"
operations:
- name: refresh-report
method: POST
When SAP Concur flags an expense policy violation, creates a ServiceNow compliance task and notifies the finance team via Slack.
naftiko: "0.5"
info:
label: "SAP Concur Expense Violation to ServiceNow"
description: "When SAP Concur flags an expense policy violation, creates a ServiceNow compliance task and notifies the finance team via Slack."
tags:
- finance
- compliance
- sap-concur
- servicenow
- slack
capability:
exposes:
- type: mcp
namespace: expense-compliance
port: 8080
tools:
- name: handle-expense-violation
description: "Given a Concur expense report ID with violations, create a ServiceNow compliance task and notify finance."
inputParameters:
- name: report_id
in: body
type: string
description: "SAP Concur expense report ID."
steps:
- name: get-report
type: call
call: "concur.get-expense-report"
with:
report_id: "{{report_id}}"
- name: create-compliance-task
type: call
call: "servicenow-comp.create-task"
with:
short_description: "Expense violation: Report {{report_id}} — {{get-report.OwnerName}}"
description: "Total: {{get-report.Total}} | Violations: {{get-report.PolicyViolations}}"
assignment_group: "Finance_Compliance"
- name: notify-finance
type: call
call: "slack.post-message"
with:
channel: "#finance-compliance"
text: "Expense policy violation flagged for {{get-report.OwnerName}} — ServiceNow: {{create-compliance-task.number}}"
consumes:
- type: http
namespace: concur
baseUri: "https://us.api.concursolutions.com/api/v3.0"
authentication:
type: bearer
token: "$secrets.concur_token"
resources:
- name: expense-reports
path: "/expense/reports/{{report_id}}"
inputParameters:
- name: report_id
in: path
operations:
- name: get-expense-report
method: GET
- type: http
namespace: servicenow-comp
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: tasks
path: "/table/sc_task"
operations:
- name: create-task
method: POST
- type: http
namespace: slack
baseUri: "https://slack.com/api"
authentication:
type: bearer
token: "$secrets.slack_bot_token"
resources:
- name: messages
path: "/chat.postMessage"
operations:
- name: post-message
method: POST
Queries SAP HANA system views for memory and CPU health metrics and creates a ServiceNow monitoring record when thresholds are breached.
naftiko: "0.5"
info:
label: "SAP HANA Database Health Check"
description: "Queries SAP HANA system views for memory and CPU health metrics and creates a ServiceNow monitoring record when thresholds are breached."
tags:
- data
- database
- sap-hana
- servicenow
- monitoring
capability:
exposes:
- type: mcp
namespace: db-health
port: 8080
tools:
- name: check-hana-health
description: "Given a SAP HANA system host, retrieve memory usage and CPU load from system views. If usage exceeds thresholds, create a ServiceNow monitoring event."
inputParameters:
- name: hana_host
in: body
type: string
description: "Hostname of the SAP HANA system."
- name: memory_threshold_pct
in: body
type: number
description: "Memory usage percentage above which to fire an alert."
steps:
- name: get-hana-metrics
type: call
call: "sap-hana.get-system-metrics"
with:
host: "{{hana_host}}"
- name: create-monitoring-event
type: call
call: "servicenow-mon.create-event"
with:
source: "SAP HANA"
node: "{{hana_host}}"
type: "Memory"
severity: "3"
description: "HANA memory at {{get-hana-metrics.memory_pct}}% on {{hana_host}}"
consumes:
- type: http
namespace: sap-hana
baseUri: "https://{{hana_host}}:4300/sap/hana/xs/api/v1"
authentication:
type: basic
username: "$secrets.hana_user"
password: "$secrets.hana_password"
resources:
- name: system-metrics
path: "/system/monitoring/host_information"
operations:
- name: get-system-metrics
method: GET
- type: http
namespace: servicenow-mon
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: events
path: "/table/em_event"
operations:
- name: create-event
method: POST
Queries SAP S/4HANA for material stock availability and posts a summary to the Slack procurement channel when levels are below threshold.
naftiko: "0.5"
info:
label: "SAP Material Availability Check to Slack"
description: "Queries SAP S/4HANA for material stock availability and posts a summary to the Slack procurement channel when levels are below threshold."
tags:
- erp
- supply-chain
- sap
- slack
capability:
exposes:
- type: mcp
namespace: procurement
port: 8080
tools:
- name: check-material-stock
description: "Given a SAP material number and plant, check stock availability and notify Slack if below threshold."
inputParameters:
- name: material_number
in: body
type: string
description: "SAP material number."
- name: plant
in: body
type: string
description: "SAP plant code."
steps:
- name: get-stock
type: call
call: "sap.get-material-stock"
with:
material: "{{material_number}}"
plant: "{{plant}}"
- name: notify-procurement
type: call
call: "slack.post-message"
with:
channel: "#procurement"
text: "Material {{material_number}} at plant {{plant}}: Available stock = {{get-stock.available_quantity}} {{get-stock.unit}}"
consumes:
- type: http
namespace: sap
baseUri: "https://ibm-s4.sap.com/sap/opu/odata/sap/API_MATERIAL_STOCK_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: material-stock
path: "/A_MatlStkInAcctMod(Material='{{material}}',Plant='{{plant}}')"
inputParameters:
- name: material
in: path
- name: plant
in: path
operations:
- name: get-material-stock
method: GET
- 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
Pulls delivery status from SAP S/4HANA and updates the corresponding Salesforce opportunity with fulfillment progress.
naftiko: "0.5"
info:
label: "SAP S/4HANA Delivery Status to Salesforce"
description: "Pulls delivery status from SAP S/4HANA and updates the corresponding Salesforce opportunity with fulfillment progress."
tags:
- erp
- crm
- sap
- salesforce
capability:
exposes:
- type: mcp
namespace: fulfillment
port: 8080
tools:
- name: sync-delivery-status
description: "Given a SAP delivery number and Salesforce opportunity ID, update the opportunity with delivery progress."
inputParameters:
- name: delivery_number
in: body
type: string
description: "SAP delivery document number."
- name: opportunity_id
in: body
type: string
description: "Salesforce opportunity ID."
steps:
- name: get-delivery
type: call
call: "sap.get-delivery"
with:
delivery: "{{delivery_number}}"
- name: update-sf-opportunity
type: call
call: "salesforce.update-opportunity"
with:
opportunity_id: "{{opportunity_id}}"
Description: "Delivery {{delivery_number}}: Status={{get-delivery.OverallStatus}}, Shipped={{get-delivery.ActualGoodsMovementDate}}"
consumes:
- type: http
namespace: sap
baseUri: "https://ibm-s4.sap.com/sap/opu/odata/sap/API_OUTBOUND_DELIVERY_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: deliveries
path: "/A_OutbDeliveryHeader('{{delivery}}')"
inputParameters:
- name: delivery
in: path
operations:
- name: get-delivery
method: GET
- type: http
namespace: salesforce
baseUri: "https://ibm.my.salesforce.com/services/data/v59.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: opportunities
path: "/sobjects/Opportunity/{{opportunity_id}}"
inputParameters:
- name: opportunity_id
in: path
operations:
- name: update-opportunity
method: PATCH
Retrieves the processing status of a vendor invoice from SAP S/4HANA. Used by finance teams and agents to check whether an invoice is pending, parked, or cleared.
naftiko: "0.5"
info:
label: "SAP S/4HANA Invoice Processing Status"
description: "Retrieves the processing status of a vendor invoice from SAP S/4HANA. Used by finance teams and agents to check whether an invoice is pending, parked, or cleared."
tags:
- finance
- erp
- sap-s4hana
- accounts-payable
capability:
exposes:
- type: mcp
namespace: erp-ap
port: 8080
tools:
- name: get-invoice-status
description: "Given a supplier invoice document number and fiscal year, return the posting status and clearing date from SAP S/4HANA."
inputParameters:
- name: invoice_doc
in: body
type: string
description: "SAP supplier invoice document number."
- name: fiscal_year
in: body
type: string
description: "Four-digit fiscal year, e.g. 2025."
call: "sap-fi.get-invoice"
with:
SupplierInvoice: "{{invoice_doc}}"
FiscalYear: "{{fiscal_year}}"
outputParameters:
- name: posting_status
type: string
mapping: "$.d.PostingStatus"
- name: clearing_date
type: string
mapping: "$.d.ClearingDate"
- name: net_amount
type: string
mapping: "$.d.InvoiceGrossAmount"
consumes:
- type: http
namespace: sap-fi
baseUri: "https://ibm-s4.sap.com/sap/opu/odata/sap/API_SUPPLIERINVOICE_PROCESS_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: supplier-invoices
path: "/A_SupplierInvoice(SupplierInvoice='{{SupplierInvoice}}',FiscalYear='{{FiscalYear}}')"
inputParameters:
- name: SupplierInvoice
in: path
- name: FiscalYear
in: path
operations:
- name: get-invoice
method: GET
Looks up a SAP S/4HANA purchase order by number and returns header status, vendor, and total value. Used by procurement agents to verify PO state before approvals or payments.
naftiko: "0.5"
info:
label: "SAP S/4HANA Purchase Order Lookup"
description: "Looks up a SAP S/4HANA purchase order by number and returns header status, vendor, and total value. Used by procurement agents to verify PO state before approvals or payments."
tags:
- finance
- erp
- sap-s4hana
- procurement
capability:
exposes:
- type: mcp
namespace: erp
port: 8080
tools:
- name: get-purchase-order
description: "Given a PO number, retrieve the purchase order header from SAP S/4HANA including status, vendor name, total amount, and currency."
inputParameters:
- name: po_number
in: body
type: string
description: "SAP purchase order number, e.g. 4500001234."
call: "sap-s4.get-po"
with:
po_number: "{{po_number}}"
outputParameters:
- name: status
type: string
mapping: "$.d.OverallStatus"
- name: vendor
type: string
mapping: "$.d.Supplier.CompanyName"
- name: total_amount
type: string
mapping: "$.d.TotalAmount"
- name: currency
type: string
mapping: "$.d.TransactionCurrency"
consumes:
- type: http
namespace: sap-s4
baseUri: "https://ibm-s4.sap.com/sap/opu/odata/sap/MM_PUR_PO_MAINT_V2_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: purchase-orders
path: "/A_PurchaseOrder('{{po_number}}')"
inputParameters:
- name: po_number
in: path
operations:
- name: get-po
method: GET
Retrieves the fulfillment status of a SAP SD sales order by order number and updates the corresponding Salesforce opportunity with the latest delivery status.
naftiko: "0.5"
info:
label: "SAP Sales and Distribution Order Status Check"
description: "Retrieves the fulfillment status of a SAP SD sales order by order number and updates the corresponding Salesforce opportunity with the latest delivery status."
tags:
- sales
- erp
- sap-s4hana
- salesforce
- order-management
capability:
exposes:
- type: mcp
namespace: order-mgmt
port: 8080
tools:
- name: sync-sd-order-status
description: "Given a SAP SD order number and a Salesforce opportunity ID, retrieve the delivery status from SAP S/4HANA SD and update the opportunity with fulfilment details."
inputParameters:
- name: sd_order_number
in: body
type: string
description: "SAP SD sales order number."
- name: opportunity_id
in: body
type: string
description: "Salesforce opportunity ID to update."
steps:
- name: get-sd-order
type: call
call: "sap-sd.get-order"
with:
order_number: "{{sd_order_number}}"
- name: update-opportunity
type: call
call: "salesforce-opp.update-opportunity"
with:
opportunity_id: "{{opportunity_id}}"
delivery_status: "{{get-sd-order.OverallSDProcessStatus}}"
requested_delivery: "{{get-sd-order.RequestedDeliveryDate}}"
consumes:
- type: http
namespace: sap-sd
baseUri: "https://ibm-s4.sap.com/sap/opu/odata/sap/API_SALES_ORDER_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: orders
path: "/A_SalesOrder('{{order_number}}')"
inputParameters:
- name: order_number
in: path
operations:
- name: get-order
method: GET
- type: http
namespace: salesforce-opp
baseUri: "https://ibm.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
When a ServiceNow change request is approved, triggers the Terraform Cloud run to apply and updates the change ticket with results.
naftiko: "0.5"
info:
label: "ServiceNow Change Approval to Terraform Apply"
description: "When a ServiceNow change request is approved, triggers the Terraform Cloud run to apply and updates the change ticket with results."
tags:
- itsm
- infrastructure
- servicenow
- terraform
capability:
exposes:
- type: mcp
namespace: change-deploy
port: 8080
tools:
- name: apply-approved-change
description: "Given a ServiceNow change number and Terraform run ID, confirm the run and update the change record."
inputParameters:
- name: change_number
in: body
type: string
description: "ServiceNow change request number."
- name: run_id
in: body
type: string
description: "Terraform Cloud run ID to apply."
steps:
- name: apply-run
type: call
call: "terraform.apply-run"
with:
run_id: "{{run_id}}"
- name: update-change
type: call
call: "servicenow-chg.update-change"
with:
number: "{{change_number}}"
work_notes: "Terraform run {{run_id}} applied successfully"
state: "implement"
consumes:
- type: http
namespace: terraform
baseUri: "https://app.terraform.io/api/v2"
authentication:
type: bearer
token: "$secrets.terraform_token"
resources:
- name: runs
path: "/runs/{{run_id}}/actions/apply"
inputParameters:
- name: run_id
in: path
operations:
- name: apply-run
method: POST
- type: http
namespace: servicenow-chg
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: changes
path: "/table/change_request"
operations:
- name: update-change
method: PATCH
Compares Terraform Cloud state against ServiceNow CMDB records and creates reconciliation tasks for any configuration drift detected.
naftiko: "0.5"
info:
label: "ServiceNow CMDB Drift Detection"
description: "Compares Terraform Cloud state against ServiceNow CMDB records and creates reconciliation tasks for any configuration drift detected."
tags:
- itsm
- infrastructure
- servicenow
- terraform
- governance
capability:
exposes:
- type: mcp
namespace: cmdb-audit
port: 8080
tools:
- name: detect-cmdb-drift
description: "Given a Terraform workspace and ServiceNow CMDB class, compare resource counts and create tasks for discrepancies."
inputParameters:
- name: workspace_name
in: body
type: string
description: "Terraform Cloud workspace name."
- name: cmdb_class
in: body
type: string
description: "ServiceNow CMDB class name."
steps:
- name: get-tf-resources
type: call
call: "terraform.get-workspace-resources"
with:
workspace: "{{workspace_name}}"
- name: get-cmdb-records
type: call
call: "servicenow-cmdb.get-records"
with:
class_name: "{{cmdb_class}}"
- name: create-recon-task
type: call
call: "servicenow-cmdb.create-task"
with:
short_description: "CMDB drift: Terraform has {{get-tf-resources.count}} resources vs CMDB {{get-cmdb-records.count}} records"
assignment_group: "Configuration_Management"
consumes:
- type: http
namespace: terraform
baseUri: "https://app.terraform.io/api/v2"
authentication:
type: bearer
token: "$secrets.terraform_token"
resources:
- name: workspace-resources
path: "/organizations/ibm/workspaces/{{workspace}}/resources"
inputParameters:
- name: workspace
in: path
operations:
- name: get-workspace-resources
method: GET
- type: http
namespace: servicenow-cmdb
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: cmdb
path: "/table/{{class_name}}"
inputParameters:
- name: class_name
in: path
operations:
- name: get-records
method: GET
- name: tasks
path: "/table/sc_task"
operations:
- name: create-task
method: POST
Retrieves the current state, priority, and assignment group of a ServiceNow incident by number.
naftiko: "0.5"
info:
label: "ServiceNow Incident Status Lookup"
description: "Retrieves the current state, priority, and assignment group of a ServiceNow incident by number."
tags:
- itsm
- servicenow
- incident-management
capability:
exposes:
- type: mcp
namespace: itsm
port: 8080
tools:
- name: get-incident-status
description: "Given a ServiceNow incident number, return the current state, priority, assigned group, and short description."
inputParameters:
- name: incident_number
in: body
type: string
description: "ServiceNow incident number, e.g. INC0012345."
call: servicenow.get-incident
with:
number: "{{incident_number}}"
outputParameters:
- name: state
type: string
mapping: "$.result[0].state"
- name: priority
type: string
mapping: "$.result[0].priority"
- name: assignment_group
type: string
mapping: "$.result[0].assignment_group.display_value"
consumes:
- type: http
namespace: servicenow
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: incidents
path: "/table/incident"
inputParameters:
- name: number
in: query
operations:
- name: get-incident
method: GET
When a ServiceNow incident is opened, retrieves correlated Datadog alerts for the affected service and updates the incident with alert IDs and metric snapshots.
naftiko: "0.5"
info:
label: "ServiceNow Incident Triage and Datadog Correlation"
description: "When a ServiceNow incident is opened, retrieves correlated Datadog alerts for the affected service and updates the incident with alert IDs and metric snapshots."
tags:
- itsm
- observability
- servicenow
- datadog
- incident-response
capability:
exposes:
- type: mcp
namespace: itsm-ops
port: 8080
tools:
- name: handle-incident-triage
description: "Given a ServiceNow incident number and affected service name, fetch correlated Datadog alerts and enrich the incident record with alert context."
inputParameters:
- name: incident_number
in: body
type: string
description: "ServiceNow incident number, e.g. INC0012345."
- name: service_name
in: body
type: string
description: "Name of the affected service as tagged in Datadog."
steps:
- name: get-incident
type: call
call: "servicenow-read.get-incident"
with:
number: "{{incident_number}}"
- name: get-alerts
type: call
call: "datadog.list-alerts"
with:
service: "{{service_name}}"
- name: update-incident
type: call
call: "servicenow-write.update-incident"
with:
sys_id: "{{get-incident.sys_id}}"
work_notes: "Correlated Datadog alerts: {{get-alerts.alert_ids}}"
consumes:
- type: http
namespace: servicenow-read
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: incidents
path: "/table/incident"
inputParameters:
- name: number
in: query
operations:
- name: get-incident
method: GET
- 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"
inputParameters:
- name: tags
in: query
operations:
- name: list-alerts
method: GET
- type: http
namespace: servicenow-write
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: incident-update
path: "/table/incident/{{sys_id}}"
inputParameters:
- name: sys_id
in: path
operations:
- name: update-incident
method: PATCH
When a ServiceNow P1 incident is created, automatically sets up a Slack channel, pages the on-call via PagerDuty, and posts the bridge details.
naftiko: "0.5"
info:
label: "ServiceNow Major Incident Bridge Setup"
description: "When a ServiceNow P1 incident is created, automatically sets up a Slack channel, pages the on-call via PagerDuty, and posts the bridge details."
tags:
- itsm
- incident-response
- servicenow
- pagerduty
- slack
capability:
exposes:
- type: mcp
namespace: major-incident
port: 8080
tools:
- name: setup-incident-bridge
description: "Given a ServiceNow incident number, create a Slack channel, page the on-call, and post bridge details."
inputParameters:
- name: incident_number
in: body
type: string
description: "ServiceNow P1 incident number."
steps:
- name: get-incident
type: call
call: "servicenow.get-incident"
with:
number: "{{incident_number}}"
- name: create-channel
type: call
call: "slack.create-channel"
with:
name: "inc-{{incident_number}}"
- name: page-oncall
type: call
call: "pagerduty.create-incident"
with:
service_id: "$secrets.pd_p1_service_id"
title: "P1 Major Incident: {{get-incident.short_description}}"
urgency: "high"
- name: post-bridge-info
type: call
call: "slack.post-message"
with:
channel: "inc-{{incident_number}}"
text: "Major Incident Bridge\n- ServiceNow: {{incident_number}}\n- Summary: {{get-incident.short_description}}\n- PagerDuty: {{page-oncall.incident.id}}"
consumes:
- type: http
namespace: servicenow
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: incidents
path: "/table/incident"
operations:
- name: get-incident
method: GET
- type: http
namespace: slack
baseUri: "https://slack.com/api"
authentication:
type: bearer
token: "$secrets.slack_bot_token"
resources:
- name: channels
path: "/conversations.create"
operations:
- name: create-channel
method: POST
- name: messages
path: "/chat.postMessage"
operations:
- name: post-message
method: POST
- type: http
namespace: pagerduty
baseUri: "https://api.pagerduty.com"
authentication:
type: apikey
key: "Authorization"
value: "Token token=$secrets.pagerduty_token"
placement: header
resources:
- name: incidents
path: "/incidents"
operations:
- name: create-incident
method: POST
Posts a formatted message to a Slack channel for notifications, alerts, and team communication workflows.
naftiko: "0.5"
info:
label: "Slack Channel Message Poster"
description: "Posts a formatted message to a Slack channel for notifications, alerts, and team communication workflows."
tags:
- communication
- slack
- notifications
capability:
exposes:
- type: mcp
namespace: messaging
port: 8080
tools:
- name: post-slack-message
description: "Given a Slack channel name and message text, post the message to the channel."
inputParameters:
- name: channel
in: body
type: string
description: "Slack channel name or ID."
- name: message
in: body
type: string
description: "Message text to post."
call: slack.post-message
with:
channel: "{{channel}}"
text: "{{message}}"
consumes:
- type: http
namespace: slack
baseUri: "https://slack.com/api"
authentication:
type: bearer
token: "$secrets.slack_bot_token"
resources:
- name: messages
path: "/chat.postMessage"
operations:
- name: post-message
method: POST
Queries Snowflake warehouse credit consumption and, when budget threshold is exceeded, creates a ServiceNow task and notifies the FinOps team.
naftiko: "0.5"
info:
label: "Snowflake Cost Alert to FinOps Slack"
description: "Queries Snowflake warehouse credit consumption and, when budget threshold is exceeded, creates a ServiceNow task and notifies the FinOps team."
tags:
- data
- finops
- snowflake
- servicenow
- slack
capability:
exposes:
- type: mcp
namespace: data-finops
port: 8080
tools:
- name: check-snowflake-cost
description: "Given a Snowflake warehouse name and budget threshold, check credit usage and alert if exceeded."
inputParameters:
- name: warehouse_name
in: body
type: string
description: "Snowflake warehouse name."
- name: budget_credits
in: body
type: number
description: "Monthly credit budget threshold."
steps:
- name: get-usage
type: call
call: "snowflake.execute-query"
with:
statement: "SELECT SUM(CREDITS_USED) as total_credits FROM SNOWFLAKE.ACCOUNT_USAGE.WAREHOUSE_METERING_HISTORY WHERE WAREHOUSE_NAME='{{warehouse_name}}' AND START_TIME >= DATE_TRUNC('MONTH', CURRENT_DATE())"
- name: create-task
type: call
call: "servicenow-fin.create-task"
with:
short_description: "Snowflake cost alert: {{warehouse_name}} at {{get-usage.total_credits}} credits"
assignment_group: "FinOps"
- name: notify-finops
type: call
call: "slack.post-message"
with:
channel: "#finops"
text: "Snowflake warehouse {{warehouse_name}} has consumed {{get-usage.total_credits}} credits (budget: {{budget_credits}})"
consumes:
- type: http
namespace: snowflake
baseUri: "https://ibm.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: servicenow-fin
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: tasks
path: "/table/sc_task"
operations:
- name: create-task
method: POST
- type: http
namespace: slack
baseUri: "https://slack.com/api"
authentication:
type: bearer
token: "$secrets.slack_bot_token"
resources:
- name: messages
path: "/chat.postMessage"
operations:
- name: post-message
method: POST
Runs a Snowflake data quality check query and, if anomalies are detected, creates a Jira task for the data engineering team and notifies Slack.
naftiko: "0.5"
info:
label: "Snowflake Data Quality to Jira Task"
description: "Runs a Snowflake data quality check query and, if anomalies are detected, creates a Jira task for the data engineering team and notifies Slack."
tags:
- data
- quality
- snowflake
- jira
- slack
capability:
exposes:
- type: mcp
namespace: data-quality
port: 8080
tools:
- name: check-data-quality
description: "Given a Snowflake quality check query, execute it and create a Jira task if anomalies exceed the threshold."
inputParameters:
- name: quality_query
in: body
type: string
description: "SQL query that returns anomaly count."
- name: threshold
in: body
type: number
description: "Anomaly count threshold to trigger a task."
steps:
- name: run-check
type: call
call: "snowflake.execute-query"
with:
statement: "{{quality_query}}"
- name: create-jira-task
type: call
call: "jira.create-issue"
with:
project: "DATA"
issuetype: "Task"
summary: "Data quality anomaly detected — {{run-check.anomaly_count}} records"
priority: "High"
- name: notify-slack
type: call
call: "slack.post-message"
with:
channel: "#data-engineering"
text: "Data quality alert: {{run-check.anomaly_count}} anomalies found. Jira: {{create-jira-task.key}}"
consumes:
- type: http
namespace: snowflake
baseUri: "https://ibm.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: jira
baseUri: "https://ibm-jira.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
Executes a read-only SQL query against a Snowflake warehouse and returns the result set for analytics and reporting queries.
naftiko: "0.5"
info:
label: "Snowflake Query Execution"
description: "Executes a read-only SQL query against a Snowflake warehouse and returns the result set for analytics and reporting queries."
tags:
- data
- analytics
- snowflake
capability:
exposes:
- type: mcp
namespace: analytics
port: 8080
tools:
- name: run-snowflake-query
description: "Given a SQL statement, execute it against the Snowflake warehouse and return the result set."
inputParameters:
- name: sql_statement
in: body
type: string
description: "Read-only SQL query to execute."
- name: warehouse
in: body
type: string
description: "Snowflake warehouse name."
call: snowflake.execute-query
with:
statement: "{{sql_statement}}"
warehouse: "{{warehouse}}"
consumes:
- type: http
namespace: snowflake
baseUri: "https://ibm.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: execute-query
method: POST
When SolarWinds detects a network node as down, automatically opens a P1 ServiceNow network incident and creates a Datadog event for cross-platform correlation.
naftiko: "0.5"
info:
label: "SolarWinds Network Node Down Alert to ServiceNow"
description: "When SolarWinds detects a network node as down, automatically opens a P1 ServiceNow network incident and creates a Datadog event for cross-platform correlation."
tags:
- itsm
- observability
- solarwinds
- servicenow
- datadog
- network
capability:
exposes:
- type: mcp
namespace: network-ops
port: 8080
tools:
- name: handle-node-down
description: "Given a SolarWinds node ID and node name, verify the node status, open a P1 ServiceNow network incident, and post a Datadog alert event for unified NOC visibility."
inputParameters:
- name: node_id
in: body
type: string
description: "SolarWinds node ID."
- name: node_name
in: body
type: string
description: "Display name of the affected network node."
steps:
- name: get-node-status
type: call
call: "solarwinds-query.get-node"
with:
node_id: "{{node_id}}"
- name: open-network-incident
type: call
call: "servicenow-net.create-incident"
with:
short_description: "Network node down: {{node_name}}"
category: "network"
urgency: "1"
impact: "1"
description: "Node: {{node_name}} | Status: {{get-node-status.status}} | IP: {{get-node-status.ip_address}}"
- name: post-dd-alert
type: call
call: "datadog-net.post-event"
with:
title: "Node Down: {{node_name}}"
text: "SolarWinds node {{node_id}} is DOWN — Incident: {{open-network-incident.number}}"
alert_type: "error"
consumes:
- type: http
namespace: solarwinds-query
baseUri: "https://ibm-solarwinds.internal:17778/SolarWinds/InformationService/v3/Json"
authentication:
type: basic
username: "$secrets.solarwinds_user"
password: "$secrets.solarwinds_password"
resources:
- name: nodes
path: "/Query"
operations:
- name: get-node
method: POST
- type: http
namespace: servicenow-net
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: incidents
path: "/table/incident"
operations:
- name: create-incident
method: POST
- type: http
namespace: datadog-net
baseUri: "https://api.datadoghq.com/api/v1"
authentication:
type: apikey
key: "DD-API-KEY"
value: "$secrets.datadog_api_key"
placement: header
resources:
- name: events
path: "/events"
operations:
- name: post-event
method: POST
When SolarWinds detects a node down event, creates a PagerDuty incident and updates the ServiceNow CMDB with the outage status.
naftiko: "0.5"
info:
label: "SolarWinds Node Down to PagerDuty"
description: "When SolarWinds detects a node down event, creates a PagerDuty incident and updates the ServiceNow CMDB with the outage status."
tags:
- networking
- incident-response
- solarwinds
- pagerduty
- servicenow
capability:
exposes:
- type: mcp
namespace: network-ops
port: 8080
tools:
- name: handle-node-down
description: "Given a SolarWinds node ID, retrieve the node details, create a PagerDuty incident, and update the CMDB."
inputParameters:
- name: node_id
in: body
type: string
description: "SolarWinds node ID."
steps:
- name: get-node
type: call
call: "solarwinds.get-node"
with:
node_id: "{{node_id}}"
- name: create-pd-incident
type: call
call: "pagerduty.create-incident"
with:
service_id: "$secrets.pd_network_service_id"
title: "Node down: {{get-node.Caption}} ({{get-node.IPAddress}})"
urgency: "high"
- name: update-cmdb
type: call
call: "servicenow-cmdb.update-ci"
with:
name: "{{get-node.Caption}}"
operational_status: "non-operational"
consumes:
- type: http
namespace: solarwinds
baseUri: "https://solarwinds.ibm.com:17778/SolarWinds/InformationService/v3/Json"
authentication:
type: basic
username: "$secrets.solarwinds_user"
password: "$secrets.solarwinds_password"
resources:
- name: nodes
path: "/Query?query=SELECT+Caption,IPAddress,Status+FROM+Orion.Nodes+WHERE+NodeID={{node_id}}"
inputParameters:
- name: node_id
in: query
operations:
- name: get-node
method: GET
- type: http
namespace: pagerduty
baseUri: "https://api.pagerduty.com"
authentication:
type: apikey
key: "Authorization"
value: "Token token=$secrets.pagerduty_token"
placement: header
resources:
- name: incidents
path: "/incidents"
operations:
- name: create-incident
method: POST
- type: http
namespace: servicenow-cmdb
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: cmdb
path: "/table/cmdb_ci"
operations:
- name: update-ci
method: PATCH
When Splunk detects a security anomaly, creates a ServiceNow security incident and notifies the SOC team via Slack.
naftiko: "0.5"
info:
label: "Splunk Alert to ServiceNow Security Incident"
description: "When Splunk detects a security anomaly, creates a ServiceNow security incident and notifies the SOC team via Slack."
tags:
- security
- siem
- splunk
- servicenow
- slack
capability:
exposes:
- type: mcp
namespace: soc-ops
port: 8080
tools:
- name: handle-splunk-alert
description: "Given a Splunk alert ID and severity, create a ServiceNow security incident and send a Slack notification to the SOC channel."
inputParameters:
- name: alert_id
in: body
type: string
description: "Splunk alert ID."
- name: severity
in: body
type: string
description: "Alert severity level."
- name: alert_description
in: body
type: string
description: "Description of the security event."
steps:
- name: create-sec-incident
type: call
call: "servicenow-sec.create-incident"
with:
short_description: "Splunk security alert: {{alert_description}}"
severity: "{{severity}}"
category: "security"
assignment_group: "SOC_Team"
- name: notify-soc
type: call
call: "slack.post-message"
with:
channel: "#soc-alerts"
text: "Security incident {{create-sec-incident.number}} created from Splunk alert {{alert_id}} — Severity: {{severity}}"
consumes:
- type: http
namespace: servicenow-sec
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: incidents
path: "/table/sn_si_incident"
operations:
- name: create-incident
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
Executes a Splunk search query over a specified time range and returns matching log events for incident investigation.
naftiko: "0.5"
info:
label: "Splunk Log Search"
description: "Executes a Splunk search query over a specified time range and returns matching log events for incident investigation."
tags:
- security
- observability
- splunk
capability:
exposes:
- type: mcp
namespace: log-analysis
port: 8080
tools:
- name: search-splunk-logs
description: "Given a Splunk search query and time range, execute the search and return matching events."
inputParameters:
- name: search_query
in: body
type: string
description: "Splunk SPL search query."
- name: earliest_time
in: body
type: string
description: "Search start time, e.g. -24h."
call: splunk.create-search
with:
search: "{{search_query}}"
earliest_time: "{{earliest_time}}"
consumes:
- type: http
namespace: splunk
baseUri: "https://splunk.ibm.com:8089/services"
authentication:
type: bearer
token: "$secrets.splunk_token"
resources:
- name: search-jobs
path: "/search/jobs"
operations:
- name: create-search
method: POST
When a Tableau extract refresh fails, creates a ServiceNow incident and notifies the BI team via Slack with the error details.
naftiko: "0.5"
info:
label: "Tableau Dashboard Failure to ServiceNow"
description: "When a Tableau extract refresh fails, creates a ServiceNow incident and notifies the BI team via Slack with the error details."
tags:
- analytics
- itsm
- tableau
- servicenow
- slack
capability:
exposes:
- type: mcp
namespace: bi-ops
port: 8080
tools:
- name: handle-tableau-failure
description: "Given a Tableau datasource ID, check the last extract status and create an incident if failed."
inputParameters:
- name: datasource_id
in: body
type: string
description: "Tableau datasource ID."
steps:
- name: get-extract-status
type: call
call: "tableau.get-datasource"
with:
datasource_id: "{{datasource_id}}"
- name: create-incident
type: call
call: "servicenow-bi.create-incident"
with:
short_description: "Tableau extract failure: {{get-extract-status.name}}"
urgency: "3"
assignment_group: "BI_Team"
- name: notify-bi
type: call
call: "slack.post-message"
with:
channel: "#bi-team"
text: "Tableau extract failed for {{get-extract-status.name}} — ServiceNow: {{create-incident.number}}"
consumes:
- type: http
namespace: tableau
baseUri: "https://tableau.ibm.com/api/3.19"
authentication:
type: bearer
token: "$secrets.tableau_token"
resources:
- name: datasources
path: "/sites/ibm/datasources/{{datasource_id}}"
inputParameters:
- name: datasource_id
in: path
operations:
- name: get-datasource
method: GET
- type: http
namespace: servicenow-bi
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: incidents
path: "/table/incident"
operations:
- name: create-incident
method: POST
- type: http
namespace: slack
baseUri: "https://slack.com/api"
authentication:
type: bearer
token: "$secrets.slack_bot_token"
resources:
- name: messages
path: "/chat.postMessage"
operations:
- name: post-message
method: POST
Runs a Teradata SQL query to extract slow-query statistics and publishes the results as a Crystal Reports data refresh. Used by data engineering agents for weekly reporting.
naftiko: "0.5"
info:
label: "Teradata Query Performance Report to Crystal Reports"
description: "Runs a Teradata SQL query to extract slow-query statistics and publishes the results as a Crystal Reports data refresh. Used by data engineering agents for weekly reporting."
tags:
- data
- analytics
- teradata
- crystal-reports
- reporting
capability:
exposes:
- type: mcp
namespace: data-reporting
port: 8080
tools:
- name: publish-query-perf-report
description: "Given a Teradata database name and a lookback period in hours, query slow-query logs and trigger a Crystal Reports refresh with the extracted performance data."
inputParameters:
- name: database_name
in: body
type: string
description: "Teradata database name to analyze."
- name: lookback_hours
in: body
type: integer
description: "Number of hours to look back for slow queries."
steps:
- name: query-slow-queries
type: call
call: "teradata.run-query"
with:
database: "{{database_name}}"
hours: "{{lookback_hours}}"
- name: refresh-report
type: call
call: "crystal-reports.refresh-report"
with:
report_name: "QueryPerformanceWeekly"
dataset: "{{query-slow-queries.rows}}"
consumes:
- type: http
namespace: teradata
baseUri: "https://ibm-teradata.internal/api/v1"
authentication:
type: basic
username: "$secrets.teradata_user"
password: "$secrets.teradata_password"
resources:
- name: queries
path: "/query"
operations:
- name: run-query
method: POST
- type: http
namespace: crystal-reports
baseUri: "https://ibm-bobj.internal/biprws/v1"
authentication:
type: bearer
token: "$secrets.crystal_reports_token"
resources:
- name: reports
path: "/reports/refresh"
operations:
- name: refresh-report
method: POST
Checks all Terraform Cloud workspaces in an organization for configuration drift and creates ServiceNow change tasks for any workspaces with unapplied plan changes.
naftiko: "0.5"
info:
label: "Terraform Cloud Workspace Drift Detection"
description: "Checks all Terraform Cloud workspaces in an organization for configuration drift and creates ServiceNow change tasks for any workspaces with unapplied plan changes."
tags:
- cloud
- infrastructure
- terraform
- servicenow
- drift-detection
capability:
exposes:
- type: mcp
namespace: infra-ops
port: 8080
tools:
- name: detect-terraform-drift
description: "Given a Terraform Cloud organization name, list all workspaces with pending or errored runs and create a ServiceNow change task for each drifted workspace."
inputParameters:
- name: org_name
in: body
type: string
description: "Terraform Cloud organization name."
steps:
- name: list-workspaces
type: call
call: "terraform.list-workspaces"
with:
organization: "{{org_name}}"
- name: create-drift-task
type: call
call: "servicenow-drift.create-task"
with:
short_description: "Terraform drift detected in org: {{org_name}}"
description: "Workspaces with drift: {{list-workspaces.drifted_count}}"
assignment_group: "Cloud_Platform"
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: list-workspaces
method: GET
- type: http
namespace: servicenow-drift
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: tasks
path: "/table/sc_task"
operations:
- name: create-task
method: POST
When a Terraform Cloud run produces a plan with resource changes, creates a ServiceNow change request for approval before applying.
naftiko: "0.5"
info:
label: "Terraform Plan Approval to ServiceNow Change"
description: "When a Terraform Cloud run produces a plan with resource changes, creates a ServiceNow change request for approval before applying."
tags:
- infrastructure
- itsm
- terraform
- servicenow
- governance
capability:
exposes:
- type: mcp
namespace: infra-governance
port: 8080
tools:
- name: create-change-for-plan
description: "Given a Terraform run ID, retrieve the plan summary and create a ServiceNow change request for CAB approval."
inputParameters:
- name: run_id
in: body
type: string
description: "Terraform Cloud run ID."
steps:
- name: get-run
type: call
call: "terraform.get-run"
with:
run_id: "{{run_id}}"
- name: create-change
type: call
call: "servicenow-chg.create-change"
with:
short_description: "Terraform plan: {{get-run.plan_summary.resource_additions}} add, {{get-run.plan_summary.resource_changes}} change, {{get-run.plan_summary.resource_destructions}} destroy"
type: "standard"
category: "infrastructure"
assignment_group: "Cloud_Platform"
- name: notify-slack
type: call
call: "slack.post-message"
with:
channel: "#infra-changes"
text: "Change {{create-change.number}} created for Terraform run {{run_id}}"
consumes:
- type: http
namespace: terraform
baseUri: "https://app.terraform.io/api/v2"
authentication:
type: bearer
token: "$secrets.terraform_token"
resources:
- name: runs
path: "/runs/{{run_id}}"
inputParameters:
- name: run_id
in: path
operations:
- name: get-run
method: GET
- type: http
namespace: servicenow-chg
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: changes
path: "/table/change_request"
operations:
- name: create-change
method: POST
- type: http
namespace: slack
baseUri: "https://slack.com/api"
authentication:
type: bearer
token: "$secrets.slack_bot_token"
resources:
- name: messages
path: "/chat.postMessage"
operations:
- name: post-message
method: POST
Retrieves the current state and last run status of a Terraform Cloud workspace for infrastructure management queries.
naftiko: "0.5"
info:
label: "Terraform Workspace Status Lookup"
description: "Retrieves the current state and last run status of a Terraform Cloud workspace for infrastructure management queries."
tags:
- infrastructure
- terraform
- cloud
capability:
exposes:
- type: mcp
namespace: infra
port: 8080
tools:
- name: get-workspace-status
description: "Given a Terraform Cloud organization and workspace name, return the workspace status, last run state, and resource count."
inputParameters:
- name: organization
in: body
type: string
description: "Terraform Cloud organization name."
- name: workspace_name
in: body
type: string
description: "Workspace name."
call: terraform.get-workspace
with:
org: "{{organization}}"
workspace: "{{workspace_name}}"
consumes:
- type: http
namespace: terraform
baseUri: "https://app.terraform.io/api/v2"
authentication:
type: bearer
token: "$secrets.terraform_token"
resources:
- name: workspaces
path: "/organizations/{{org}}/workspaces/{{workspace}}"
inputParameters:
- name: org
in: path
- name: workspace
in: path
operations:
- name: get-workspace
method: GET
Queries Veritas NetBackup for backup job status on a given policy and creates a ServiceNow incident if any jobs have failed in the last 24 hours.
naftiko: "0.5"
info:
label: "Veritas NetBackup Job Status Check"
description: "Queries Veritas NetBackup for backup job status on a given policy and creates a ServiceNow incident if any jobs have failed in the last 24 hours."
tags:
- itsm
- backup
- veritas
- servicenow
- monitoring
capability:
exposes:
- type: mcp
namespace: backup-ops
port: 8080
tools:
- name: check-backup-status
description: "Given a Veritas NetBackup policy name, retrieve recent job results and open a ServiceNow incident for any failed backup jobs."
inputParameters:
- name: policy_name
in: body
type: string
description: "Veritas NetBackup policy name to check."
steps:
- name: get-jobs
type: call
call: "netbackup.get-jobs"
with:
policy: "{{policy_name}}"
- name: create-backup-incident
type: call
call: "servicenow-backup.create-incident"
with:
short_description: "Backup failure: policy {{policy_name}}"
category: "backup"
urgency: "2"
description: "Failed jobs: {{get-jobs.failed_count}} | Policy: {{policy_name}}"
consumes:
- type: http
namespace: netbackup
baseUri: "https://ibm-nbmaster.internal/netbackup/jobs"
authentication:
type: bearer
token: "$secrets.netbackup_token"
resources:
- name: jobs
path: "/jobs"
inputParameters:
- name: policy
in: query
operations:
- name: get-jobs
method: GET
- type: http
namespace: servicenow-backup
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: incidents
path: "/table/incident"
operations:
- name: create-incident
method: POST
Queries Workday for employees who have not completed benefits enrollment and sends reminder notifications via Slack and creates ServiceNow follow-up tasks.
naftiko: "0.5"
info:
label: "Workday Benefits Enrollment Reminder"
description: "Queries Workday for employees who have not completed benefits enrollment and sends reminder notifications via Slack and creates ServiceNow follow-up tasks."
tags:
- hr
- workday
- servicenow
- slack
- benefits
capability:
exposes:
- type: mcp
namespace: benefits-ops
port: 8080
tools:
- name: send-enrollment-reminders
description: "Given an enrollment deadline date, find unenrolled employees, notify them, and create HR follow-up tasks."
inputParameters:
- name: enrollment_deadline
in: body
type: string
description: "Benefits enrollment deadline date."
steps:
- name: get-unenrolled
type: call
call: "workday.get-unenrolled-workers"
with:
deadline: "{{enrollment_deadline}}"
- name: create-hr-task
type: call
call: "servicenow-hr.create-task"
with:
short_description: "Benefits enrollment follow-up: {{get-unenrolled.count}} employees pending"
assignment_group: "HR_Benefits"
- name: notify-hr
type: call
call: "slack.post-message"
with:
channel: "#hr-benefits"
text: "Benefits enrollment reminder: {{get-unenrolled.count}} employees have not yet enrolled. Deadline: {{enrollment_deadline}}"
consumes:
- type: http
namespace: workday
baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: unenrolled
path: "/ibm/workers?unenrolled=true&deadline={{deadline}}"
inputParameters:
- name: deadline
in: query
operations:
- name: get-unenrolled-workers
method: GET
- type: http
namespace: servicenow-hr
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: tasks
path: "/table/sc_task"
operations:
- name: create-task
method: POST
- type: http
namespace: slack
baseUri: "https://slack.com/api"
authentication:
type: bearer
token: "$secrets.slack_bot_token"
resources:
- name: messages
path: "/chat.postMessage"
operations:
- name: post-message
method: POST
Extracts compensation band data from Workday and triggers a Power BI dataset refresh, then notifies HR leadership via Slack.
naftiko: "0.5"
info:
label: "Workday Compensation Review to Power BI"
description: "Extracts compensation band data from Workday and triggers a Power BI dataset refresh, then notifies HR leadership via Slack."
tags:
- hr
- analytics
- workday
- power-bi
- slack
capability:
exposes:
- type: mcp
namespace: comp-analytics
port: 8080
tools:
- name: refresh-comp-report
description: "Given a Workday report URL, extract compensation data, trigger a Power BI refresh, and notify HR."
inputParameters:
- name: report_url
in: body
type: string
description: "Workday custom report URL."
- name: dataset_id
in: body
type: string
description: "Power BI dataset ID."
steps:
- name: get-comp-data
type: call
call: "workday.get-report"
with:
report_url: "{{report_url}}"
- name: refresh-dataset
type: call
call: "powerbi.trigger-refresh"
with:
dataset_id: "{{dataset_id}}"
- name: notify-hr
type: call
call: "slack.post-message"
with:
channel: "#hr-leadership"
text: "Compensation review dashboard refreshed — {{get-comp-data.record_count}} records processed"
consumes:
- type: http
namespace: workday
baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: reports
path: "/ibm/reports/{{report_url}}"
inputParameters:
- name: report_url
in: path
operations:
- name: get-report
method: GET
- type: http
namespace: powerbi
baseUri: "https://api.powerbi.com/v1.0/myorg"
authentication:
type: bearer
token: "$secrets.powerbi_token"
resources:
- name: datasets
path: "/datasets/{{dataset_id}}/refreshes"
inputParameters:
- name: dataset_id
in: path
operations:
- name: trigger-refresh
method: POST
- type: http
namespace: slack
baseUri: "https://slack.com/api"
authentication:
type: bearer
token: "$secrets.slack_bot_token"
resources:
- name: messages
path: "/chat.postMessage"
operations:
- name: post-message
method: POST
Retrieves employee profile details from Workday HCM by employee ID, returning name, department, title, and manager for HR and IT queries.
naftiko: "0.5"
info:
label: "Workday Employee Directory Lookup"
description: "Retrieves employee profile details from Workday HCM by employee ID, returning name, department, title, and manager for HR and IT queries."
tags:
- hr
- workday
- employee-data
capability:
exposes:
- type: mcp
namespace: hr
port: 8080
tools:
- name: get-employee-profile
description: "Given a Workday employee ID, retrieve full name, department, job title, and direct manager from Workday HCM."
inputParameters:
- name: employee_id
in: body
type: string
description: "Workday employee ID."
call: workday.get-worker
with:
worker_id: "{{employee_id}}"
outputParameters:
- name: full_name
type: string
mapping: "$.worker.fullName"
- name: department
type: string
mapping: "$.worker.department"
- name: title
type: string
mapping: "$.worker.jobTitle"
- name: manager
type: string
mapping: "$.worker.manager.fullName"
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: "/ibm/workers/{{worker_id}}"
inputParameters:
- name: worker_id
in: path
operations:
- name: get-worker
method: GET
Extracts the monthly headcount snapshot from Workday and loads it into Snowflake for HR analytics and workforce planning dashboards.
naftiko: "0.5"
info:
label: "Workday Headcount Report to Snowflake"
description: "Extracts the monthly headcount snapshot from Workday and loads it into Snowflake for HR analytics and workforce planning dashboards."
tags:
- hr
- data
- workday
- snowflake
capability:
exposes:
- type: mcp
namespace: hr-analytics
port: 8080
tools:
- name: sync-headcount
description: "Given an as-of date, extract the Workday headcount snapshot and load into Snowflake."
inputParameters:
- name: as_of_date
in: body
type: string
description: "Date for the headcount snapshot."
steps:
- name: get-headcount
type: call
call: "workday.get-headcount-report"
with:
effective_date: "{{as_of_date}}"
- name: load-to-snowflake
type: call
call: "snowflake.execute-query"
with:
statement: "INSERT INTO HR.HEADCOUNT_SNAPSHOTS (snapshot_date, department, count) VALUES ('{{as_of_date}}', '{{get-headcount.department}}', {{get-headcount.count}})"
consumes:
- type: http
namespace: workday
baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: headcount
path: "/ibm/reports/headcount?effectiveDate={{effective_date}}"
inputParameters:
- name: effective_date
in: query
operations:
- name: get-headcount-report
method: GET
- type: http
namespace: snowflake
baseUri: "https://ibm.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: execute-query
method: POST
When a new developer hire is detected in Workday, invites them to the GitHub organization and creates an Okta application assignment.
naftiko: "0.5"
info:
label: "Workday New Hire to GitHub Org Invite"
description: "When a new developer hire is detected in Workday, invites them to the GitHub organization and creates an Okta application assignment."
tags:
- hr
- devops
- workday
- github
- okta
- onboarding
capability:
exposes:
- type: mcp
namespace: dev-onboarding
port: 8080
tools:
- name: onboard-developer
description: "Given a Workday worker ID, retrieve the new hire details, invite them to the GitHub org, and assign Okta developer apps."
inputParameters:
- name: worker_id
in: body
type: string
description: "Workday worker ID of the new hire."
steps:
- name: get-new-hire
type: call
call: "workday.get-worker"
with:
worker_id: "{{worker_id}}"
- name: invite-to-github
type: call
call: "github.create-org-invitation"
with:
email: "{{get-new-hire.email}}"
role: "member"
- name: assign-okta-apps
type: call
call: "okta.assign-app"
with:
user_id: "{{get-new-hire.email}}"
app_id: "$secrets.okta_github_app_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: "/ibm/workers/{{worker_id}}"
inputParameters:
- name: worker_id
in: path
operations:
- name: get-worker
method: GET
- type: http
namespace: github
baseUri: "https://api.github.com"
authentication:
type: bearer
token: "$secrets.github_token"
resources:
- name: org-invitations
path: "/orgs/ibm/invitations"
operations:
- name: create-org-invitation
method: POST
- type: http
namespace: okta
baseUri: "https://ibm.okta.com/api/v1"
authentication:
type: apikey
key: "Authorization"
value: "SSWS $secrets.okta_api_token"
placement: header
resources:
- name: app-users
path: "/apps/{{app_id}}/users"
inputParameters:
- name: app_id
in: path
operations:
- name: assign-app
method: POST
When a Workday employee changes roles, updates their Okta group memberships to match the new department and creates a ServiceNow audit record.
naftiko: "0.5"
info:
label: "Workday Role Change to Okta Group Sync"
description: "When a Workday employee changes roles, updates their Okta group memberships to match the new department and creates a ServiceNow audit record."
tags:
- hr
- security
- workday
- okta
- servicenow
capability:
exposes:
- type: mcp
namespace: role-sync
port: 8080
tools:
- name: sync-role-groups
description: "Given a worker ID and new department, update Okta group memberships and log the change in ServiceNow."
inputParameters:
- name: worker_id
in: body
type: string
description: "Workday worker ID."
- name: new_department
in: body
type: string
description: "New department name."
steps:
- name: get-worker
type: call
call: "workday.get-worker"
with:
worker_id: "{{worker_id}}"
- name: update-groups
type: call
call: "okta.update-groups"
with:
user_id: "{{get-worker.email}}"
group_name: "{{new_department}}"
- name: create-audit
type: call
call: "servicenow-audit.create-record"
with:
short_description: "Role change: {{get-worker.full_name}} moved to {{new_department}}"
category: "access_management"
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: "/ibm/workers/{{worker_id}}"
inputParameters:
- name: worker_id
in: path
operations:
- name: get-worker
method: GET
- type: http
namespace: okta
baseUri: "https://ibm.okta.com/api/v1"
authentication:
type: apikey
key: "Authorization"
value: "SSWS $secrets.okta_api_token"
placement: header
resources:
- name: groups
path: "/groups"
operations:
- name: update-groups
method: PUT
- type: http
namespace: servicenow-audit
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: records
path: "/table/sys_audit"
operations:
- name: create-record
method: POST
When a Workday employee termination event fires, deactivates the user in Okta and creates a ServiceNow HR task to confirm offboarding completion.
naftiko: "0.5"
info:
label: "Workday Termination to Okta Deprovisioning"
description: "When a Workday employee termination event fires, deactivates the user in Okta and creates a ServiceNow HR task to confirm offboarding completion."
tags:
- hr
- security
- workday
- okta
- servicenow
- offboarding
capability:
exposes:
- type: mcp
namespace: offboarding
port: 8080
tools:
- name: handle-termination
description: "Given a Workday worker ID, deactivate the corresponding Okta user and create a ServiceNow offboarding task."
inputParameters:
- name: worker_id
in: body
type: string
description: "Workday worker ID of the terminated employee."
steps:
- name: get-worker
type: call
call: "workday.get-worker"
with:
worker_id: "{{worker_id}}"
- name: deactivate-okta-user
type: call
call: "okta.deactivate-user"
with:
user_id: "{{get-worker.email}}"
- name: create-offboarding-task
type: call
call: "servicenow-hr.create-task"
with:
short_description: "Offboarding: {{get-worker.full_name}} deprovisioned from Okta"
assignment_group: "HR_Operations"
category: "offboarding"
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: "/ibm/workers/{{worker_id}}"
inputParameters:
- name: worker_id
in: path
operations:
- name: get-worker
method: GET
- type: http
namespace: okta
baseUri: "https://ibm.okta.com/api/v1"
authentication:
type: apikey
key: "Authorization"
value: "SSWS $secrets.okta_api_token"
placement: header
resources:
- name: users
path: "/users/{{user_id}}/lifecycle/deactivate"
inputParameters:
- name: user_id
in: path
operations:
- name: deactivate-user
method: POST
- type: http
namespace: servicenow-hr
baseUri: "https://ibm.service-now.com/api/now"
authentication:
type: bearer
token: "$secrets.servicenow_token"
resources:
- name: tasks
path: "/table/sc_task"
operations:
- name: create-task
method: POST