L'Oréal Capabilities
Naftiko 0.5 capability definitions for L'Oréal - 107 capabilities showing integration workflows and service orchestrations.
Fetches marketing campaign attribution data from Adobe Analytics for a given campaign and date range.
naftiko: "0.5"
info:
label: "Adobe Analytics Campaign Attribution"
description: "Fetches marketing campaign attribution data from Adobe Analytics for a given campaign and date range."
tags:
- marketing
- analytics
- adobe-analytics
- reporting
capability:
exposes:
- type: mcp
namespace: digital-analytics
port: 8080
tools:
- name: get-campaign-attribution
description: "Pull campaign attribution metrics from Adobe Analytics including visits, conversions, and revenue attributed to a campaign."
inputParameters:
- name: campaign_id
type: string
description: "Adobe Analytics campaign tracking code."
- name: date_from
type: string
description: "Start date in YYYY-MM-DD format."
- name: date_to
type: string
description: "End date in YYYY-MM-DD format."
call: adobe.get-report
with:
rsid: "lorealproduction"
campaign_id: "{{campaign_id}}"
dateFrom: "{{date_from}}"
dateTo: "{{date_to}}"
outputParameters:
- name: visits
type: string
mapping: "$.report.data.visits"
- name: conversions
type: string
mapping: "$.report.data.conversions"
- name: revenue
type: string
mapping: "$.report.data.revenue"
consumes:
- type: http
namespace: adobe
baseUri: "https://analytics.adobe.io/api/loreal"
authentication:
type: bearer
token: "$secrets.adobe_analytics_token"
resources:
- name: reports
path: "/reports"
operations:
- name: get-report
method: POST
Uses Anthropic Claude to classify and summarize incoming customer complaints from Salesforce Service Cloud, then routes them to the appropriate ServiceNow queue.
naftiko: "0.5"
info:
label: "AI-Assisted Customer Complaint Triage"
description: "Uses Anthropic Claude to classify and summarize incoming customer complaints from Salesforce Service Cloud, then routes them to the appropriate ServiceNow queue."
tags:
- customer-support
- ai
- salesforce
- servicenow
- anthropic
capability:
exposes:
- type: mcp
namespace: cx-ops
port: 8080
tools:
- name: triage-customer-complaint
description: "Given a Salesforce Service Cloud case ID, retrieve case details, use Anthropic Claude to classify severity and summarize the complaint, then create a routed ServiceNow incident with the summary."
inputParameters:
- name: case_id
type: string
description: "Salesforce Service Cloud case record ID."
steps:
- name: get-case
type: call
call: salesforce.get-case
with:
case_id: "{{case_id}}"
- name: classify-complaint
type: call
call: anthropic.create-message
with:
model: "claude-3-5-sonnet-20241022"
prompt: "Classify and summarize this customer complaint for routing: {{get-case.Description}}"
- name: create-incident
type: call
call: servicenow.create-incident
with:
short_description: "Customer complaint: {{get-case.Subject}}"
description: "AI summary: {{classify-complaint.content}}"
category: "customer_complaint"
consumes:
- type: http
namespace: salesforce
baseUri: "https://loreal.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: cases
path: "/sobjects/Case/{{case_id}}"
inputParameters:
- name: case_id
in: path
operations:
- name: get-case
method: GET
- type: http
namespace: anthropic
baseUri: "https://api.anthropic.com/v1"
authentication:
type: apikey
key: "x-api-key"
value: "$secrets.anthropic_api_key"
placement: header
resources:
- name: messages
path: "/messages"
operations:
- name: create-message
method: POST
- type: http
namespace: servicenow
baseUri: "https://loreal.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: incidents
path: "/table/incident"
operations:
- name: create-incident
method: POST
Checks Azure Active Directory group memberships for a user to validate access rights and role assignments.
naftiko: "0.5"
info:
label: "Azure AD User Group Membership Check"
description: "Checks Azure Active Directory group memberships for a user to validate access rights and role assignments."
tags:
- security
- identity
- azure-active-directory
- access
capability:
exposes:
- type: mcp
namespace: identity
port: 8080
tools:
- name: check-group-membership
description: "List Azure AD group memberships for a user. Returns group names and IDs for access validation."
inputParameters:
- name: user_upn
type: string
description: "User principal name (email) in Azure AD."
call: azuread.get-member-of
with:
upn: "{{user_upn}}"
outputParameters:
- name: groups
type: string
mapping: "$.value"
consumes:
- type: http
namespace: azuread
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: member-of
path: "/users/{{upn}}/memberOf"
inputParameters:
- name: upn
in: path
operations:
- name: get-member-of
method: GET
Handles release approvals by checking Azure DevOps pipeline status, validating change requests in ServiceNow, and notifying the release team via Teams.
naftiko: "0.5"
info:
label: "Azure DevOps Release Approval Handler"
description: "Handles release approvals by checking Azure DevOps pipeline status, validating change requests in ServiceNow, and notifying the release team via Teams."
tags:
- operations
- devops
- azure-devops
- servicenow
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: release-management
port: 8080
tools:
- name: handle-release-approval
description: "Handle a release approval by validating pipeline status, checking change management records, and notifying the team."
inputParameters:
- name: pipeline_id
type: string
description: "Azure DevOps pipeline ID."
- name: change_request
type: string
description: "ServiceNow change request number."
steps:
- name: get-pipeline
type: call
call: azuredevops.get-pipeline-run
with:
pipeline_id: "{{pipeline_id}}"
- name: validate-change
type: call
call: servicenow.get-change-request
with:
number: "{{change_request}}"
- name: notify-team
type: call
call: msteams.send-message
with:
channel_id: "release-management"
text: "Release ready: Pipeline {{pipeline_id}} ({{get-pipeline.status}}). Change {{change_request}}: {{validate-change.approval_status}}."
consumes:
- type: http
namespace: azuredevops
baseUri: "https://dev.azure.com/loreal"
authentication:
type: bearer
token: "$secrets.azure_devops_token"
resources:
- name: pipelines
path: "/_apis/pipelines/{{pipeline_id}}/runs"
inputParameters:
- name: pipeline_id
in: path
operations:
- name: get-pipeline-run
method: GET
- type: http
namespace: servicenow
baseUri: "https://loreal.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: changes
path: "/table/change_request/{{number}}"
inputParameters:
- name: number
in: path
operations:
- name: get-change-request
method: GET
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST
Generates beauty advisor performance metrics by pulling sales data from Salesforce, attendance from Workday, and refreshing the Power BI performance dashboard.
naftiko: "0.5"
info:
label: "Beauty Advisor Performance Dashboard"
description: "Generates beauty advisor performance metrics by pulling sales data from Salesforce, attendance from Workday, and refreshing the Power BI performance dashboard."
tags:
- sales
- hr
- salesforce
- workday
- power-bi
capability:
exposes:
- type: mcp
namespace: retail-performance
port: 8080
tools:
- name: generate-advisor-dashboard
description: "Generate beauty advisor performance metrics combining sales achievements with workforce data."
inputParameters:
- name: region
type: string
description: "Sales region code."
- name: period
type: string
description: "Reporting period in YYYY-MM format."
steps:
- name: get-sales
type: call
call: salesforce.get-advisor-sales
with:
region: "{{region}}"
period: "{{period}}"
- name: get-attendance
type: call
call: workday.get-attendance
with:
region: "{{region}}"
period: "{{period}}"
- name: refresh-dashboard
type: call
call: powerbi.refresh-dataset
with:
datasetId: "beauty-advisor-performance"
consumes:
- type: http
namespace: salesforce
baseUri: "https://loreal.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: reports
path: "/analytics/reports"
operations:
- name: get-advisor-sales
method: POST
- type: http
namespace: workday
baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: attendance
path: "/loreal/attendance"
operations:
- name: get-attendance
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/{{datasetId}}/refreshes"
inputParameters:
- name: datasetId
in: path
operations:
- name: refresh-dataset
method: POST
Coordinates brand ambassador events by creating a Salesforce campaign, setting up attendee registration in Google Forms, and notifying event coordinators via Teams.
naftiko: "0.5"
info:
label: "Brand Ambassador Event Coordinator"
description: "Coordinates brand ambassador events by creating a Salesforce campaign, setting up attendee registration in Google Forms, and notifying event coordinators via Teams."
tags:
- marketing
- events
- salesforce
- google-forms
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: event-management
port: 8080
tools:
- name: coordinate-ambassador-event
description: "Coordinate a brand ambassador event by setting up campaign tracking, registration, and team notification."
inputParameters:
- name: event_name
type: string
description: "Name of the event."
- name: brand
type: string
description: "Brand name."
- name: event_date
type: string
description: "Event date."
- name: location
type: string
description: "Event location."
steps:
- name: create-campaign
type: call
call: salesforce.create-campaign
with:
Name: "{{event_name}}"
Type: "Ambassador Event"
Brand__c: "{{brand}}"
StartDate: "{{event_date}}"
- name: notify-coordinators
type: call
call: msteams.send-message
with:
channel_id: "brand-events"
text: "Event created: {{event_name}} for {{brand}} on {{event_date}} at {{location}}. Campaign ID: {{create-campaign.id}}."
consumes:
- type: http
namespace: salesforce
baseUri: "https://loreal.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: campaigns
path: "/sobjects/Campaign"
operations:
- name: create-campaign
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST
Monitors brand sentiment via Snowflake social listening data, creates a Salesforce case for negative trends, and posts an alert to the brand management Teams channel.
naftiko: "0.5"
info:
label: "Brand Sentiment Monitoring Responder"
description: "Monitors brand sentiment via Snowflake social listening data, creates a Salesforce case for negative trends, and posts an alert to the brand management Teams channel."
tags:
- marketing
- social
- snowflake
- salesforce
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: brand-monitoring
port: 8080
tools:
- name: respond-to-sentiment
description: "Monitor brand sentiment and respond to negative trends by creating a case and alerting the team."
inputParameters:
- name: brand_name
type: string
description: "Brand name to monitor."
- name: threshold
type: number
description: "Negative sentiment threshold percentage."
steps:
- name: get-sentiment
type: call
call: snowflake.execute-query
with:
warehouse: "SOCIAL_ANALYTICS_WH"
query: "SELECT sentiment_score, negative_pct, volume FROM brand_sentiment WHERE brand='{{brand_name}}' AND date=CURRENT_DATE()"
- name: create-case
type: call
call: salesforce.create-case
with:
Subject: "Negative sentiment alert: {{brand_name}}"
Description: "Negative sentiment at {{get-sentiment.negative_pct}}% (threshold: {{threshold}}%). Volume: {{get-sentiment.volume}} mentions."
Priority: "High"
- name: alert-team
type: call
call: msteams.send-message
with:
channel_id: "brand-management"
text: "SENTIMENT ALERT: {{brand_name}} negative sentiment at {{get-sentiment.negative_pct}}%. Case: {{create-case.CaseNumber}}."
consumes:
- type: http
namespace: snowflake
baseUri: "https://loreal.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: salesforce
baseUri: "https://loreal.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: cases
path: "/sobjects/Case"
operations:
- name: create-case
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST
On a GitHub Actions pipeline failure on a protected branch, creates a Jira bug, posts a Datadog event marker, and alerts the engineering Teams channel.
naftiko: "0.5"
info:
label: "CI/CD Pipeline Failure Response"
description: "On a GitHub Actions pipeline failure on a protected branch, creates a Jira bug, posts a Datadog event marker, and alerts the engineering Teams channel."
tags:
- devops
- cicd
- github
- jira
- datadog
capability:
exposes:
- type: mcp
namespace: devops
port: 8080
tools:
- name: handle-pipeline-failure
description: "Given a GitHub Actions pipeline failure event, create a Jira bug in the engineering project, post a Datadog deployment event, and alert the engineering Teams channel with full context."
inputParameters:
- name: repo
type: string
description: "GitHub repository full name (org/repo)."
- name: branch
type: string
description: "Branch name where the failure occurred."
- name: workflow_run_id
type: string
description: "GitHub Actions workflow run ID."
- name: commit_sha
type: string
description: "Git commit SHA that triggered the pipeline."
steps:
- name: create-bug
type: call
call: jira.create-issue
with:
project_key: "ENG"
issuetype: "Bug"
summary: "[CI Failure] {{repo}} / {{branch}}"
description: "Workflow run {{workflow_run_id}} failed on commit {{commit_sha}}"
- name: post-event
type: call
call: datadog.create-event
with:
title: "CI failure: {{repo}}"
text: "Branch {{branch}} pipeline failed. Jira: {{create-bug.key}}"
alert_type: "error"
- name: alert-team
type: call
call: msteams.post-channel-message
with:
channel_id: "engineering-alerts"
text: "Pipeline failure: {{repo}} | Branch: {{branch}} | Jira: {{create-bug.key}} | Run: {{workflow_run_id}}"
consumes:
- type: http
namespace: jira
baseUri: "https://loreal.atlassian.net/rest/api/3"
authentication:
type: basic
username: "$secrets.jira_user"
password: "$secrets.jira_api_token"
resources:
- name: issues
path: "/issue"
operations:
- name: create-issue
method: POST
- type: http
namespace: datadog
baseUri: "https://api.datadoghq.com/api/v1"
authentication:
type: apikey
key: "DD-API-KEY"
value: "$secrets.datadog_api_key"
placement: header
resources:
- name: events
path: "/events"
operations:
- name: create-event
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/engineering/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Orchestrates clinical trial data collection by pulling trial metadata from Jira, collecting results from Snowflake, and storing the summary report in SharePoint.
naftiko: "0.5"
info:
label: "Clinical Trial Data Collection Orchestrator"
description: "Orchestrates clinical trial data collection by pulling trial metadata from Jira, collecting results from Snowflake, and storing the summary report in SharePoint."
tags:
- r-and-d
- quality
- jira
- snowflake
- sharepoint
capability:
exposes:
- type: mcp
namespace: clinical-trials
port: 8080
tools:
- name: collect-trial-data
description: "Collect and organize clinical trial data from multiple sources into a structured report."
inputParameters:
- name: trial_id
type: string
description: "Clinical trial identifier."
- name: phase
type: string
description: "Trial phase (e.g., Phase I, Phase II)."
steps:
- name: get-trial-metadata
type: call
call: jira.get-issue
with:
issue_key: "{{trial_id}}"
- name: get-trial-results
type: call
call: snowflake.execute-query
with:
warehouse: "RD_ANALYTICS_WH"
query: "SELECT subject_count, adverse_events, efficacy_score FROM clinical_results WHERE trial_id='{{trial_id}}' AND phase='{{phase}}'"
- name: store-report
type: call
call: sharepoint.upload-file
with:
site: "rd-clinical-trials"
folder: "{{trial_id}}"
filename: "{{trial_id}}-{{phase}}-results.json"
content: "{{get-trial-results.data}}"
consumes:
- type: http
namespace: jira
baseUri: "https://loreal.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: snowflake
baseUri: "https://loreal.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: sharepoint
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: files
path: "/sites/{{site}}/drive/root:/{{folder}}/{{filename}}:/content"
inputParameters:
- name: site
in: path
- name: folder
in: path
- name: filename
in: path
operations:
- name: upload-file
method: PUT
Queries AWS Cost Explorer for spend anomalies exceeding a threshold and creates a Jira task and a Datadog event to track remediation.
naftiko: "0.5"
info:
label: "Cloud Cost Anomaly Detection"
description: "Queries AWS Cost Explorer for spend anomalies exceeding a threshold and creates a Jira task and a Datadog event to track remediation."
tags:
- cloud
- finops
- aws
- datadog
- jira
capability:
exposes:
- type: mcp
namespace: cloud-finops
port: 8080
tools:
- name: handle-cost-anomaly
description: "Given an AWS account ID and spend threshold, query Cost Explorer for anomalies, create a Jira tracking ticket, and post a Datadog event. Use when automated cost alerts fire."
inputParameters:
- name: account_id
type: string
description: "AWS account ID to check for spend anomalies."
- name: threshold_usd
type: number
description: "Anomaly threshold in USD. Anomalies above this value are reported."
- name: date_from
type: string
description: "Start date for the cost lookback period in YYYY-MM-DD format."
steps:
- name: get-anomalies
type: call
call: aws-cost.get-anomalies
with:
accountId: "{{account_id}}"
threshold: "{{threshold_usd}}"
startDate: "{{date_from}}"
- name: create-task
type: call
call: jira.create-issue
with:
project_key: "CLOUD"
issuetype: "Task"
summary: "Cost anomaly detected on AWS account {{account_id}}"
description: "Anomaly details: {{get-anomalies.summary}}"
- name: post-event
type: call
call: datadog.create-event
with:
title: "AWS cost anomaly: {{account_id}}"
text: "Threshold {{threshold_usd}} USD exceeded. Jira: {{create-task.key}}"
alert_type: "warning"
consumes:
- type: http
namespace: aws-cost
baseUri: "https://ce.us-east-1.amazonaws.com"
authentication:
type: bearer
token: "$secrets.aws_cost_explorer_token"
resources:
- name: anomalies
path: "/GetAnomalies"
operations:
- name: get-anomalies
method: POST
- type: http
namespace: jira
baseUri: "https://loreal.atlassian.net/rest/api/3"
authentication:
type: basic
username: "$secrets.jira_user"
password: "$secrets.jira_api_token"
resources:
- name: issues
path: "/issue"
operations:
- name: create-issue
method: POST
- type: http
namespace: datadog
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
Compiles competitive intelligence by querying Circana market data from Snowflake, pulling brand share trends, and distributing a digest via Teams and Salesforce.
naftiko: "0.5"
info:
label: "Competitive Market Intelligence Digest"
description: "Compiles competitive intelligence by querying Circana market data from Snowflake, pulling brand share trends, and distributing a digest via Teams and Salesforce."
tags:
- marketing
- analytics
- snowflake
- microsoft-teams
- salesforce
capability:
exposes:
- type: mcp
namespace: market-intelligence
port: 8080
tools:
- name: generate-competitive-digest
description: "Generate a competitive market intelligence digest by combining market share data with brand performance and distributing to stakeholders."
inputParameters:
- name: category
type: string
description: "Product category (e.g., skincare, haircare)."
- name: period
type: string
description: "Reporting period in YYYY-MM format."
steps:
- name: get-market-data
type: call
call: snowflake.execute-query
with:
warehouse: "MARKET_ANALYTICS_WH"
query: "SELECT brand, market_share_pct, share_change_pct FROM circana_market_data WHERE category='{{category}}' AND period='{{period}}' ORDER BY market_share_pct DESC"
- name: update-sf-report
type: call
call: salesforce.update-market-report
with:
category: "{{category}}"
period: "{{period}}"
data: "{{get-market-data.data}}"
- name: post-digest
type: call
call: msteams.send-message
with:
channel_id: "market-intelligence"
text: "Market Intelligence Digest - {{category}} ({{period}}): Top brand share {{get-market-data.top_brand}} at {{get-market-data.top_share}}%."
consumes:
- type: http
namespace: snowflake
baseUri: "https://loreal.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: salesforce
baseUri: "https://loreal.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: reports
path: "/sobjects/Market_Report__c"
operations:
- name: update-market-report
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST
Aggregates consumer product reviews from Snowflake, identifies trending complaints, and creates Jira tasks for product teams while posting a summary to Teams.
naftiko: "0.5"
info:
label: "Consumer Review Analysis Pipeline"
description: "Aggregates consumer product reviews from Snowflake, identifies trending complaints, and creates Jira tasks for product teams while posting a summary to Teams."
tags:
- marketing
- quality
- snowflake
- jira
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: consumer-insights
port: 8080
tools:
- name: analyze-consumer-reviews
description: "Analyze consumer reviews to identify trending complaints and route actionable items to product teams."
inputParameters:
- name: product_line
type: string
description: "Product line to analyze."
- name: period_days
type: number
description: "Number of days to look back."
steps:
- name: get-reviews
type: call
call: snowflake.execute-query
with:
warehouse: "CONSUMER_ANALYTICS_WH"
query: "SELECT complaint_topic, count, avg_rating FROM review_analysis WHERE product_line='{{product_line}}' AND review_date >= DATEADD(day, -{{period_days}}, CURRENT_DATE()) ORDER BY count DESC LIMIT 10"
- name: create-product-tasks
type: call
call: jira.create-issue
with:
project_key: "PROD"
issuetype: "Task"
summary: "Consumer review trends: {{product_line}} (last {{period_days}} days)"
description: "Top complaint topics: {{get-reviews.data}}. Average rating: {{get-reviews.avg_rating}}."
- name: post-summary
type: call
call: msteams.send-message
with:
channel_id: "product-insights"
text: "Review analysis for {{product_line}}: Top issues identified. Jira: {{create-product-tasks.key}}."
consumes:
- type: http
namespace: snowflake
baseUri: "https://loreal.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://loreal.atlassian.net/rest/api/3"
authentication:
type: basic
username: "$secrets.jira_user"
password: "$secrets.jira_api_token"
resources:
- name: issues
path: "/issue"
operations:
- name: create-issue
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST
Initiates a quality audit for a contract manufacturer by pulling supplier data from SAP Ariba, creating a Jira audit task, and sharing the audit checklist via SharePoint.
naftiko: "0.5"
info:
label: "Contract Manufacturer Quality Audit Workflow"
description: "Initiates a quality audit for a contract manufacturer by pulling supplier data from SAP Ariba, creating a Jira audit task, and sharing the audit checklist via SharePoint."
tags:
- quality
- procurement
- sap
- jira
- sharepoint
capability:
exposes:
- type: mcp
namespace: quality-audit
port: 8080
tools:
- name: initiate-cm-audit
description: "Start a contract manufacturer quality audit by gathering supplier data, creating an audit task, and sharing the checklist."
inputParameters:
- name: supplier_id
type: string
description: "SAP Ariba supplier ID."
- name: audit_type
type: string
description: "Type of audit: routine, for-cause, pre-approval."
steps:
- name: get-supplier
type: call
call: ariba.get-supplier
with:
supplier_id: "{{supplier_id}}"
- name: create-audit-task
type: call
call: jira.create-issue
with:
project_key: "QAUDIT"
issuetype: "Task"
summary: "CM Quality Audit: {{get-supplier.name}} ({{audit_type}})"
description: "Audit type: {{audit_type}}. Supplier: {{get-supplier.name}}. Location: {{get-supplier.address}}."
- name: share-checklist
type: call
call: sharepoint.copy-template
with:
template: "quality-audit-checklist-{{audit_type}}"
destination: "audits/{{supplier_id}}"
name: "audit-{{supplier_id}}-checklist"
consumes:
- type: http
namespace: ariba
baseUri: "https://openapi.ariba.com/api/supplier-management/v1"
authentication:
type: bearer
token: "$secrets.ariba_token"
resources:
- name: suppliers
path: "/suppliers/{{supplier_id}}"
inputParameters:
- name: supplier_id
in: path
operations:
- name: get-supplier
method: GET
- type: http
namespace: jira
baseUri: "https://loreal.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: sharepoint
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: files
path: "/sites/quality/drive/items"
operations:
- name: copy-template
method: POST
Tracks regulatory submission status by querying Jira for submission tasks, checking document completeness in SharePoint, and updating the compliance dashboard in Power BI.
naftiko: "0.5"
info:
label: "Cosmetics Regulatory Submission Tracker"
description: "Tracks regulatory submission status by querying Jira for submission tasks, checking document completeness in SharePoint, and updating the compliance dashboard in Power BI."
tags:
- regulatory
- quality
- jira
- sharepoint
- power-bi
capability:
exposes:
- type: mcp
namespace: regulatory-ops
port: 8080
tools:
- name: track-regulatory-submission
description: "Track the status of a cosmetics regulatory submission across project management, document storage, and reporting systems."
inputParameters:
- name: submission_id
type: string
description: "Jira issue key for the regulatory submission."
steps:
- name: get-submission-status
type: call
call: jira.get-issue
with:
issue_key: "{{submission_id}}"
- name: check-documents
type: call
call: sharepoint.list-folder
with:
site: "regulatory-submissions"
folder: "{{submission_id}}"
- name: refresh-dashboard
type: call
call: powerbi.refresh-dataset
with:
datasetId: "regulatory-compliance-tracker"
consumes:
- type: http
namespace: jira
baseUri: "https://loreal.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: sharepoint
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: folders
path: "/sites/{{site}}/drive/root:/{{folder}}:/children"
inputParameters:
- name: site
in: path
- name: folder
in: path
operations:
- name: list-folder
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/{{datasetId}}/refreshes"
inputParameters:
- name: datasetId
in: path
operations:
- name: refresh-dataset
method: POST
Routes a customer complaint from Zendesk to a quality investigation by looking up the product batch in SAP, creating a Jira investigation ticket, and updating the Zendesk ticket.
naftiko: "0.5"
info:
label: "Customer Complaint to Quality Investigation"
description: "Routes a customer complaint from Zendesk to a quality investigation by looking up the product batch in SAP, creating a Jira investigation ticket, and updating the Zendesk ticket."
tags:
- quality
- customer-service
- zendesk
- sap
- jira
capability:
exposes:
- type: mcp
namespace: complaint-quality
port: 8080
tools:
- name: route-complaint-to-quality
description: "Route a customer complaint to the quality team by tracing the product batch and creating an investigation ticket."
inputParameters:
- name: ticket_id
type: string
description: "Zendesk complaint ticket ID."
- name: batch_number
type: string
description: "Product batch number from the complaint."
- name: material_number
type: string
description: "Product material number."
steps:
- name: get-ticket
type: call
call: zendesk.get-ticket
with:
ticket_id: "{{ticket_id}}"
- name: trace-batch
type: call
call: sap.get-batch
with:
batch: "{{batch_number}}"
material: "{{material_number}}"
- name: create-investigation
type: call
call: jira.create-issue
with:
project_key: "QUAL"
issuetype: "Bug"
summary: "Customer complaint investigation: batch {{batch_number}}"
description: "Complaint: {{get-ticket.subject}}. Batch produced at {{trace-batch.plant}} on {{trace-batch.production_date}}."
- name: update-ticket
type: call
call: zendesk.update-ticket
with:
ticket_id: "{{ticket_id}}"
comment: "Quality investigation opened: {{create-investigation.key}}. Our quality team is reviewing batch {{batch_number}}."
consumes:
- type: http
namespace: zendesk
baseUri: "https://loreal.zendesk.com/api/v2"
authentication:
type: bearer
token: "$secrets.zendesk_token"
resources:
- name: tickets
path: "/tickets/{{ticket_id}}"
inputParameters:
- name: ticket_id
in: path
operations:
- name: get-ticket
method: GET
- name: update-ticket
method: PUT
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_BATCH_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: batches
path: "/A_Batch"
operations:
- name: get-batch
method: GET
- type: http
namespace: jira
baseUri: "https://loreal.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 Datadog APM for application latency percentiles over a time window for a specified service.
naftiko: "0.5"
info:
label: "Datadog Application Latency Report"
description: "Queries Datadog APM for application latency percentiles over a time window for a specified service."
tags:
- operations
- monitoring
- datadog
- performance
capability:
exposes:
- type: mcp
namespace: observability
port: 8080
tools:
- name: get-latency-report
description: "Fetch p50, p95, and p99 latency metrics from Datadog APM for a given service over a specified time range."
inputParameters:
- name: service_name
type: string
description: "Datadog APM service name."
- name: time_from
type: string
description: "Start timestamp in epoch seconds."
- name: time_to
type: string
description: "End timestamp in epoch seconds."
call: datadog.query-timeseries
with:
query: "avg:trace.servlet.request.duration{service:{{service_name}}}"
from: "{{time_from}}"
to: "{{time_to}}"
outputParameters:
- name: p50_ms
type: string
mapping: "$.series[0].pointlist[0][1]"
- name: p95_ms
type: string
mapping: "$.series[1].pointlist[0][1]"
- name: p99_ms
type: string
mapping: "$.series[2].pointlist[0][1]"
consumes:
- type: http
namespace: datadog
baseUri: "https://api.datadoghq.com/api/v1"
authentication:
type: apikey
key: "DD-API-KEY"
value: "$secrets.datadog_api_key"
placement: header
resources:
- name: query
path: "/query"
operations:
- name: query-timeseries
method: GET
When a Datadog monitor fires a critical alert, creates a ServiceNow incident, assigns an on-call engineer via PagerDuty, and notifies the ops Teams channel.
naftiko: "0.5"
info:
label: "Datadog Infrastructure Alert Response"
description: "When a Datadog monitor fires a critical alert, creates a ServiceNow incident, assigns an on-call engineer via PagerDuty, and notifies the ops Teams channel."
tags:
- itsm
- observability
- datadog
- servicenow
- pagerduty
capability:
exposes:
- type: mcp
namespace: infra-ops
port: 8080
tools:
- name: handle-infrastructure-alert
description: "Given a Datadog monitor alert ID and severity, create a ServiceNow incident, trigger a PagerDuty incident to page on-call, and post context to the ops Teams channel."
inputParameters:
- name: monitor_id
type: string
description: "Datadog monitor ID that triggered the alert."
- name: severity
type: string
description: "Alert severity: critical, warning, or info."
- name: affected_service
type: string
description: "Name of the affected service or host."
steps:
- name: get-monitor
type: call
call: datadog.get-monitor
with:
monitor_id: "{{monitor_id}}"
- name: create-incident
type: call
call: servicenow.create-incident
with:
short_description: "Infrastructure alert: {{affected_service}} — {{severity}}"
urgency: "1"
impact: "1"
description: "Datadog monitor {{monitor_id}}: {{get-monitor.message}}"
- name: page-oncall
type: call
call: pagerduty.create-incident
with:
title: "Infrastructure alert: {{affected_service}}"
service_id: "$secrets.pagerduty_infra_service_id"
body: "ServiceNow: {{create-incident.number}} | Monitor: {{monitor_id}}"
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: servicenow
baseUri: "https://loreal.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: incidents
path: "/table/incident"
operations:
- name: create-incident
method: POST
- type: http
namespace: pagerduty
baseUri: "https://api.pagerduty.com"
authentication:
type: apikey
key: "Authorization"
value: "$secrets.pagerduty_token"
placement: header
resources:
- name: incidents
path: "/incidents"
operations:
- name: create-incident
method: POST
Fetches SLO compliance data from Datadog for all production services and publishes a weekly compliance report to SharePoint and the engineering Teams channel.
naftiko: "0.5"
info:
label: "Datadog SLO Compliance Report"
description: "Fetches SLO compliance data from Datadog for all production services and publishes a weekly compliance report to SharePoint and the engineering Teams channel."
tags:
- observability
- slo
- datadog
- reporting
- sharepoint
capability:
exposes:
- type: mcp
namespace: slo-reporting
port: 8080
tools:
- name: publish-slo-report
description: "Fetch weekly SLO compliance metrics for all production services from Datadog and upload the formatted report to SharePoint, then post a summary to the engineering Teams channel."
inputParameters:
- name: teams_channel_id
type: string
description: "Teams channel ID for the engineering team."
- name: sharepoint_site_id
type: string
description: "SharePoint site ID to upload the report to."
steps:
- name: get-slos
type: call
call: datadog.list-slos
with:
tags: "env:production"
- name: upload-report
type: call
call: sharepoint.upload-file
with:
site_id: "{{sharepoint_site_id}}"
folder_path: "SLOReports/weekly"
content: "{{get-slos.data}}"
- name: post-summary
type: call
call: msteams.post-channel-message
with:
channel_id: "{{teams_channel_id}}"
text: "Weekly SLO report published: {{get-slos.complianceCount}} services meeting targets. Report: {{upload-report.sharepoint_url}}"
consumes:
- type: http
namespace: datadog
baseUri: "https://api.datadoghq.com/api/v1"
authentication:
type: apikey
key: "DD-API-KEY"
value: "$secrets.datadog_api_key"
placement: header
resources:
- name: slos
path: "/slo"
inputParameters:
- name: tags
in: query
operations:
- name: list-slos
method: GET
- type: http
namespace: sharepoint
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: files
path: "/sites/{{site_id}}/drive/items/root:/{{folder_path}}:/children"
inputParameters:
- name: site_id
in: path
- name: folder_path
in: path
operations:
- name: upload-file
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/engineering/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Pulls demand forecast data from Snowflake, checks current inventory in SAP, and creates or adjusts planned production orders to meet projected demand.
naftiko: "0.5"
info:
label: "Demand Forecast to Production Planning Sync"
description: "Pulls demand forecast data from Snowflake, checks current inventory in SAP, and creates or adjusts planned production orders to meet projected demand."
tags:
- supply-chain
- manufacturing
- snowflake
- sap
- planning
capability:
exposes:
- type: mcp
namespace: demand-planning
port: 8080
tools:
- name: sync-demand-to-production
description: "Synchronize demand forecasts with production planning by querying forecast data, checking inventory, and creating planned orders in SAP."
inputParameters:
- name: product_category
type: string
description: "Product category for demand forecast."
- name: planning_horizon_weeks
type: number
description: "Number of weeks for the planning horizon."
- name: plant_code
type: string
description: "SAP plant code."
steps:
- name: get-forecast
type: call
call: snowflake.execute-query
with:
warehouse: "DEMAND_PLANNING_WH"
query: "SELECT sku, forecasted_units FROM demand_forecast WHERE category='{{product_category}}' AND weeks_ahead<={{planning_horizon_weeks}}"
- name: check-inventory
type: call
call: sap.get-plant-stock
with:
plant: "{{plant_code}}"
category: "{{product_category}}"
- name: create-planned-orders
type: call
call: sap.create-planned-order
with:
plant: "{{plant_code}}"
forecast_data: "{{get-forecast.data}}"
current_stock: "{{check-inventory.stock_levels}}"
consumes:
- type: http
namespace: snowflake
baseUri: "https://loreal.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: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_MATERIAL_STOCK_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: stock
path: "/A_MatlStkInAcctMod"
operations:
- name: get-plant-stock
method: GET
- name: planned-orders
path: "/A_PlannedOrder"
operations:
- name: create-planned-order
method: POST
Monitors product pricing across e-commerce channels by querying Snowflake pricing data, comparing against MAP policy, and creating Salesforce cases for violations.
naftiko: "0.5"
info:
label: "Digital Shelf Price Monitor"
description: "Monitors product pricing across e-commerce channels by querying Snowflake pricing data, comparing against MAP policy, and creating Salesforce cases for violations."
tags:
- ecommerce
- sales
- snowflake
- salesforce
- pricing
capability:
exposes:
- type: mcp
namespace: pricing-ops
port: 8080
tools:
- name: monitor-digital-pricing
description: "Monitor digital shelf pricing for MAP violations by comparing current prices against policy and flagging violations."
inputParameters:
- name: brand
type: string
description: "Brand name to monitor."
- name: marketplace
type: string
description: "E-commerce marketplace (e.g., amazon, walmart)."
steps:
- name: get-prices
type: call
call: snowflake.execute-query
with:
warehouse: "ECOM_ANALYTICS_WH"
query: "SELECT sku, current_price, map_price, retailer FROM digital_shelf_prices WHERE brand='{{brand}}' AND marketplace='{{marketplace}}' AND current_price < map_price"
- name: create-violation-cases
type: call
call: salesforce.create-case
with:
Subject: "MAP violation: {{brand}} on {{marketplace}}"
Description: "{{get-prices.violation_count}} SKUs priced below MAP on {{marketplace}}."
Priority: "High"
Type: "MAP Violation"
- name: notify-team
type: call
call: msteams.send-message
with:
channel_id: "pricing-compliance"
text: "MAP Alert: {{get-prices.violation_count}} violations for {{brand}} on {{marketplace}}. Case: {{create-violation-cases.CaseNumber}}."
consumes:
- type: http
namespace: snowflake
baseUri: "https://loreal.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: salesforce
baseUri: "https://loreal.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: cases
path: "/sobjects/Case"
operations:
- name: create-case
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST
Processes DTC product returns by updating the Salesforce case, creating a return goods receipt in SAP, and issuing a refund notification via email.
naftiko: "0.5"
info:
label: "Direct-to-Consumer Returns Processing"
description: "Processes DTC product returns by updating the Salesforce case, creating a return goods receipt in SAP, and issuing a refund notification via email."
tags:
- ecommerce
- supply-chain
- salesforce
- sap
- customer-service
capability:
exposes:
- type: mcp
namespace: dtc-returns
port: 8080
tools:
- name: process-dtc-return
description: "Process a direct-to-consumer product return across CRM, ERP, and customer notification systems."
inputParameters:
- name: case_id
type: string
description: "Salesforce case ID for the return."
- name: order_number
type: string
description: "Original SAP sales order number."
- name: reason
type: string
description: "Return reason code."
steps:
- name: update-case
type: call
call: salesforce.update-case
with:
case_id: "{{case_id}}"
Status: "In Progress"
Return_Reason__c: "{{reason}}"
- name: create-return-order
type: call
call: sap.create-return-order
with:
reference_order: "{{order_number}}"
reason: "{{reason}}"
- name: send-notification
type: call
call: msgraph.send-mail
with:
to: "{{update-case.contact_email}}"
subject: "Return processed: {{order_number}}"
body: "Your return has been processed. Return reference: {{create-return-order.return_number}}. Refund will be issued within 5-7 business days."
consumes:
- type: http
namespace: salesforce
baseUri: "https://loreal.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: cases
path: "/sobjects/Case/{{case_id}}"
inputParameters:
- name: case_id
in: path
operations:
- name: update-case
method: PATCH
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_RETURNS_DELIVERY_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: returns
path: "/A_ReturnsDeliveryHeader"
operations:
- name: create-return-order
method: POST
- type: http
namespace: msgraph
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: mail
path: "/me/sendMail"
operations:
- name: send-mail
method: POST
Tracks e-commerce order fulfillment by querying Salesforce for order status, checking SAP warehouse picking status, and updating the customer via Zendesk.
naftiko: "0.5"
info:
label: "E-commerce Order Fulfillment Tracker"
description: "Tracks e-commerce order fulfillment by querying Salesforce for order status, checking SAP warehouse picking status, and updating the customer via Zendesk."
tags:
- ecommerce
- supply-chain
- salesforce
- sap
- zendesk
capability:
exposes:
- type: mcp
namespace: ecom-fulfillment
port: 8080
tools:
- name: track-fulfillment
description: "Track an e-commerce order through fulfillment by checking CRM status, warehouse picking, and updating the customer ticket."
inputParameters:
- name: order_id
type: string
description: "Salesforce order ID."
- name: ticket_id
type: string
description: "Zendesk ticket ID for customer inquiry."
steps:
- name: get-order
type: call
call: salesforce.get-order
with:
order_id: "{{order_id}}"
- name: check-picking
type: call
call: sap.get-delivery-status
with:
sales_order: "{{get-order.sap_order_number}}"
- name: update-ticket
type: call
call: zendesk.update-ticket
with:
ticket_id: "{{ticket_id}}"
comment: "Order {{order_id}} status: {{get-order.status}}. Warehouse picking: {{check-picking.picking_status}}. Estimated ship: {{check-picking.ship_date}}."
consumes:
- type: http
namespace: salesforce
baseUri: "https://loreal.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: orders
path: "/sobjects/Order/{{order_id}}"
inputParameters:
- name: order_id
in: path
operations:
- name: get-order
method: GET
- type: http
namespace: sap
baseUri: "https://loreal-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"
operations:
- name: get-delivery-status
method: GET
- type: http
namespace: zendesk
baseUri: "https://loreal.zendesk.com/api/v2"
authentication:
type: bearer
token: "$secrets.zendesk_token"
resources:
- name: tickets
path: "/tickets/{{ticket_id}}"
inputParameters:
- name: ticket_id
in: path
operations:
- name: update-ticket
method: PUT
Generates a personalized learning path by pulling employee skills from Workday, matching with available courses in Pluralsight, and creating a development plan in Jira.
naftiko: "0.5"
info:
label: "Employee Learning Path Generator"
description: "Generates a personalized learning path by pulling employee skills from Workday, matching with available courses in Pluralsight, and creating a development plan in Jira."
tags:
- hr
- training
- workday
- pluralsight
- jira
capability:
exposes:
- type: mcp
namespace: hr-learning
port: 8080
tools:
- name: generate-learning-path
description: "Create a personalized learning path by assessing current skills and matching with available training courses."
inputParameters:
- name: employee_id
type: string
description: "Workday employee ID."
- name: target_role
type: string
description: "Target role for development."
steps:
- name: get-skills
type: call
call: workday.get-worker-skills
with:
worker_id: "{{employee_id}}"
- name: find-courses
type: call
call: pluralsight.search-courses
with:
role: "{{target_role}}"
exclude_skills: "{{get-skills.current_skills}}"
- name: create-plan
type: call
call: jira.create-issue
with:
project_key: "LEARN"
issuetype: "Task"
summary: "Learning path: {{target_role}} for employee {{employee_id}}"
description: "Recommended courses: {{find-courses.course_list}}. Skill gaps: {{find-courses.gap_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: skills
path: "/loreal/workers/{{worker_id}}/skills"
inputParameters:
- name: worker_id
in: path
operations:
- name: get-worker-skills
method: GET
- type: http
namespace: pluralsight
baseUri: "https://api.pluralsight.com/api/v1"
authentication:
type: bearer
token: "$secrets.pluralsight_token"
resources:
- name: courses
path: "/courses/search"
operations:
- name: search-courses
method: GET
- type: http
namespace: jira
baseUri: "https://loreal.atlassian.net/rest/api/3"
authentication:
type: basic
username: "$secrets.jira_user"
password: "$secrets.jira_api_token"
resources:
- name: issues
path: "/issue"
operations:
- name: create-issue
method: POST
When an employee separation is recorded in Workday, revokes Okta access, closes open ServiceNow tickets, and notifies the manager via Teams.
naftiko: "0.5"
info:
label: "Employee Offboarding Workflow"
description: "When an employee separation is recorded in Workday, revokes Okta access, closes open ServiceNow tickets, and notifies the manager via Teams."
tags:
- hr
- offboarding
- workday
- okta
- servicenow
capability:
exposes:
- type: mcp
namespace: hr-offboarding
port: 8080
tools:
- name: trigger-offboarding
description: "Given a Workday employee ID, revoke Okta SSO access, deactivate Microsoft 365 account, close open ServiceNow tickets, and notify the manager via Teams."
inputParameters:
- name: employee_id
type: string
description: "Workday worker ID of the departing employee."
- name: last_day
type: string
description: "Last working day in YYYY-MM-DD format."
steps:
- name: get-worker
type: call
call: workday.get-worker
with:
worker_id: "{{employee_id}}"
- name: deactivate-okta
type: call
call: okta.deactivate-user
with:
user_id: "{{get-worker.work_email}}"
- name: disable-m365
type: call
call: msgraph.update-user
with:
user_id: "{{get-worker.work_email}}"
accountEnabled: "false"
- name: notify-manager
type: call
call: msteams.send-message
with:
recipient_upn: "{{get-worker.manager_email}}"
text: "Offboarding complete for {{get-worker.full_name}} (last day: {{last_day}}). All system access has been revoked."
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: "/loreal/workers/{{worker_id}}"
inputParameters:
- name: worker_id
in: path
operations:
- name: get-worker
method: GET
- type: http
namespace: okta
baseUri: "https://loreal.okta.com/api/v1"
authentication:
type: apikey
key: "Authorization"
value: "$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: msgraph
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: users
path: "/users/{{user_id}}"
inputParameters:
- name: user_id
in: path
operations:
- name: update-user
method: PATCH
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: chats
path: "/chats"
operations:
- name: send-message
method: POST
Syncs Facebook lead gen ad form submissions to Salesforce leads, enriches with ZoomInfo data, and notifies the sales team via Teams.
naftiko: "0.5"
info:
label: "Facebook Ad to Salesforce Lead Sync"
description: "Syncs Facebook lead gen ad form submissions to Salesforce leads, enriches with ZoomInfo data, and notifies the sales team via Teams."
tags:
- marketing
- sales
- facebook
- salesforce
- zoominfo
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: lead-management
port: 8080
tools:
- name: sync-fb-leads
description: "Sync Facebook lead ad submissions to Salesforce with enrichment and team notification."
inputParameters:
- name: form_id
type: string
description: "Facebook lead form ID."
- name: campaign_id
type: string
description: "Salesforce campaign ID for attribution."
steps:
- name: get-leads
type: call
call: facebook.get-lead-forms
with:
form_id: "{{form_id}}"
- name: enrich-leads
type: call
call: zoominfo.enrich-contact
with:
email: "{{get-leads.email}}"
- name: create-sf-lead
type: call
call: salesforce.create-lead
with:
Email: "{{get-leads.email}}"
FirstName: "{{get-leads.first_name}}"
LastName: "{{get-leads.last_name}}"
Company: "{{enrich-leads.company}}"
Title: "{{enrich-leads.title}}"
CampaignId: "{{campaign_id}}"
- name: notify-sales
type: call
call: msteams.send-message
with:
channel_id: "sales-leads"
text: "New lead from Facebook: {{get-leads.first_name}} {{get-leads.last_name}} at {{enrich-leads.company}}. SF Lead: {{create-sf-lead.id}}."
consumes:
- type: http
namespace: facebook
baseUri: "https://graph.facebook.com/v18.0"
authentication:
type: bearer
token: "$secrets.meta_token"
resources:
- name: leads
path: "/{{form_id}}/leads"
inputParameters:
- name: form_id
in: path
operations:
- name: get-lead-forms
method: GET
- type: http
namespace: zoominfo
baseUri: "https://api.zoominfo.com/enrich"
authentication:
type: bearer
token: "$secrets.zoominfo_token"
resources:
- name: contacts
path: "/contact"
operations:
- name: enrich-contact
method: POST
- type: http
namespace: salesforce
baseUri: "https://loreal.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: leads
path: "/sobjects/Lead"
operations:
- name: create-lead
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST
Tracks fragrance stability testing by pulling test schedules from Jira, querying lab results from Snowflake, and storing completed reports in SharePoint.
naftiko: "0.5"
info:
label: "Fragrance Stability Test Tracker"
description: "Tracks fragrance stability testing by pulling test schedules from Jira, querying lab results from Snowflake, and storing completed reports in SharePoint."
tags:
- r-and-d
- quality
- jira
- snowflake
- sharepoint
capability:
exposes:
- type: mcp
namespace: rd-stability
port: 8080
tools:
- name: track-stability-test
description: "Track fragrance stability tests by correlating schedules with lab results and archiving reports."
inputParameters:
- name: test_id
type: string
description: "Jira stability test ticket key."
steps:
- name: get-schedule
type: call
call: jira.get-issue
with:
issue_key: "{{test_id}}"
- name: get-results
type: call
call: snowflake.execute-query
with:
warehouse: "RD_ANALYTICS_WH"
query: "SELECT test_point, color_delta, odor_score, viscosity FROM stability_results WHERE test_id='{{test_id}}' ORDER BY test_point"
- name: archive-report
type: call
call: sharepoint.upload-file
with:
site: "rd-stability"
folder: "completed-tests"
filename: "{{test_id}}-stability-report.json"
consumes:
- type: http
namespace: jira
baseUri: "https://loreal.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: snowflake
baseUri: "https://loreal.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: sharepoint
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: files
path: "/sites/rd-stability/drive/root:/{{folder}}/{{filename}}:/content"
operations:
- name: upload-file
method: PUT
When a GitHub release is published, generates AI-assisted release notes using Anthropic Claude and posts them to the engineering Teams channel and Confluence.
naftiko: "0.5"
info:
label: "GitHub Deployment Release Notes"
description: "When a GitHub release is published, generates AI-assisted release notes using Anthropic Claude and posts them to the engineering Teams channel and Confluence."
tags:
- devops
- github
- anthropic
- confluence
- release-management
capability:
exposes:
- type: mcp
namespace: release-ops
port: 8080
tools:
- name: publish-release-notes
description: "Given a GitHub release tag and repository, fetch the commit log, generate polished release notes using Anthropic Claude, and publish to Confluence and the engineering Teams channel."
inputParameters:
- name: repo_owner
type: string
description: "GitHub organization or owner name."
- name: repo_name
type: string
description: "GitHub repository name."
- name: tag
type: string
description: "Release tag name (e.g., v1.4.0)."
- name: teams_channel_id
type: string
description: "Teams channel ID for engineering announcements."
steps:
- name: get-release
type: call
call: github.get-release
with:
owner: "{{repo_owner}}"
repo: "{{repo_name}}"
tag: "{{tag}}"
- name: generate-notes
type: call
call: anthropic.create-message
with:
model: "claude-3-5-sonnet-20241022"
prompt: "Generate professional release notes from these commits: {{get-release.body}}"
- name: publish-to-confluence
type: call
call: confluence.create-page
with:
space_key: "ENG"
title: "Release Notes {{tag}} — {{repo_name}}"
content: "{{generate-notes.content}}"
- name: notify-team
type: call
call: msteams.post-channel-message
with:
channel_id: "{{teams_channel_id}}"
text: "Release {{tag}} published for {{repo_name}}. Confluence: {{publish-to-confluence.url}}"
consumes:
- type: http
namespace: github
baseUri: "https://api.github.com"
authentication:
type: bearer
token: "$secrets.github_token"
resources:
- name: releases
path: "/repos/{{owner}}/{{repo}}/releases/tags/{{tag}}"
inputParameters:
- name: owner
in: path
- name: repo
in: path
- name: tag
in: path
operations:
- name: get-release
method: GET
- type: http
namespace: anthropic
baseUri: "https://api.anthropic.com/v1"
authentication:
type: apikey
key: "x-api-key"
value: "$secrets.anthropic_api_key"
placement: header
resources:
- name: messages
path: "/messages"
operations:
- name: create-message
method: POST
- type: http
namespace: confluence
baseUri: "https://loreal.atlassian.net/wiki/rest/api"
authentication:
type: basic
username: "$secrets.jira_user"
password: "$secrets.jira_api_token"
resources:
- name: pages
path: "/content"
operations:
- name: create-page
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/engineering/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Triggers a GitHub Advanced Security scan on a repository, checks Dependabot alerts, and creates Jira issues for critical vulnerabilities.
naftiko: "0.5"
info:
label: "GitHub Repository Security Scan"
description: "Triggers a GitHub Advanced Security scan on a repository, checks Dependabot alerts, and creates Jira issues for critical vulnerabilities."
tags:
- security
- devops
- github
- jira
- vulnerability-management
capability:
exposes:
- type: mcp
namespace: security-ops
port: 8080
tools:
- name: scan-repo-vulnerabilities
description: "Given a GitHub repository, retrieve critical Dependabot and code scanning alerts, then create Jira security issues for each critical finding. Use during security review cycles or on-demand."
inputParameters:
- name: repo_owner
type: string
description: "GitHub organization or owner name."
- name: repo_name
type: string
description: "GitHub repository name."
steps:
- name: get-dependabot-alerts
type: call
call: github.list-dependabot-alerts
with:
owner: "{{repo_owner}}"
repo: "{{repo_name}}"
severity: "critical"
- name: create-security-issue
type: call
call: jira.create-issue
with:
project_key: "SEC"
issuetype: "Bug"
summary: "Critical vulnerability in {{repo_owner}}/{{repo_name}}"
description: "Dependabot alerts: {{get-dependabot-alerts.count}} critical findings. Repo: {{repo_owner}}/{{repo_name}}"
consumes:
- type: http
namespace: github
baseUri: "https://api.github.com"
authentication:
type: bearer
token: "$secrets.github_token"
resources:
- name: dependabot-alerts
path: "/repos/{{owner}}/{{repo}}/dependabot/alerts"
inputParameters:
- name: owner
in: path
- name: repo
in: path
- name: severity
in: query
operations:
- name: list-dependabot-alerts
method: GET
- type: http
namespace: jira
baseUri: "https://loreal.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
Retrieves e-commerce conversion funnel metrics from Google Analytics for a specific brand property.
naftiko: "0.5"
info:
label: "Google Analytics E-commerce Funnel Report"
description: "Retrieves e-commerce conversion funnel metrics from Google Analytics for a specific brand property."
tags:
- marketing
- analytics
- google-analytics
- ecommerce
capability:
exposes:
- type: mcp
namespace: web-analytics
port: 8080
tools:
- name: get-ecommerce-funnel
description: "Fetch e-commerce funnel data from Google Analytics including sessions, add-to-cart rate, checkout rate, and purchase conversion rate."
inputParameters:
- name: property_id
type: string
description: "Google Analytics 4 property ID."
- name: date_from
type: string
description: "Start date in YYYY-MM-DD format."
- name: date_to
type: string
description: "End date in YYYY-MM-DD format."
call: ga.run-report
with:
property: "{{property_id}}"
dateRanges_startDate: "{{date_from}}"
dateRanges_endDate: "{{date_to}}"
outputParameters:
- name: sessions
type: string
mapping: "$.rows[0].metricValues[0].value"
- name: add_to_cart_rate
type: string
mapping: "$.rows[0].metricValues[1].value"
- name: purchase_rate
type: string
mapping: "$.rows[0].metricValues[2].value"
consumes:
- type: http
namespace: ga
baseUri: "https://analyticsdata.googleapis.com/v1beta"
authentication:
type: bearer
token: "$secrets.google_analytics_token"
resources:
- name: reports
path: "/properties/{{property}}/runReport"
inputParameters:
- name: property
in: path
operations:
- name: run-report
method: POST
Retrieves the current live container version from Google Tag Manager for a brand website property.
naftiko: "0.5"
info:
label: "Google Tag Manager Container Version Lookup"
description: "Retrieves the current live container version from Google Tag Manager for a brand website property."
tags:
- marketing
- analytics
- google-tag-manager
- web
capability:
exposes:
- type: mcp
namespace: tag-management
port: 8080
tools:
- name: get-container-version
description: "Fetch the current live GTM container version including tag count, trigger count, and publish date."
inputParameters:
- name: account_id
type: string
description: "GTM account ID."
- name: container_id
type: string
description: "GTM container ID."
call: gtm.get-live-version
with:
accountId: "{{account_id}}"
containerId: "{{container_id}}"
outputParameters:
- name: version_id
type: string
mapping: "$.containerVersionId"
- name: tag_count
type: string
mapping: "$.tag.length"
- name: publish_date
type: string
mapping: "$.fingerprint"
consumes:
- type: http
namespace: gtm
baseUri: "https://www.googleapis.com/tagmanager/v2"
authentication:
type: bearer
token: "$secrets.google_gtm_token"
resources:
- name: versions
path: "/accounts/{{accountId}}/containers/{{containerId}}/versions/live"
inputParameters:
- name: accountId
in: path
- name: containerId
in: path
operations:
- name: get-live-version
method: GET
Pulls influencer campaign spend from Salesforce, engagement data from Instagram, and sales lift from Snowflake to calculate ROI and post results to Teams.
naftiko: "0.5"
info:
label: "Influencer Campaign ROI Analyzer"
description: "Pulls influencer campaign spend from Salesforce, engagement data from Instagram, and sales lift from Snowflake to calculate ROI and post results to Teams."
tags:
- marketing
- social
- salesforce
- instagram
- snowflake
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: influencer-analytics
port: 8080
tools:
- name: analyze-influencer-roi
description: "Calculate influencer campaign ROI by combining spend data, engagement metrics, and sales lift, then post the summary to Teams."
inputParameters:
- name: campaign_id
type: string
description: "Salesforce campaign ID for the influencer program."
- name: ig_account_id
type: string
description: "Instagram business account ID."
- name: date_from
type: string
description: "Start date in YYYY-MM-DD format."
- name: date_to
type: string
description: "End date in YYYY-MM-DD format."
steps:
- name: get-spend
type: call
call: salesforce.get-campaign
with:
campaign_id: "{{campaign_id}}"
- name: get-engagement
type: call
call: instagram.get-insights
with:
ig_user_id: "{{ig_account_id}}"
since: "{{date_from}}"
until: "{{date_to}}"
- name: get-sales-lift
type: call
call: snowflake.execute-query
with:
warehouse: "MARKETING_ANALYTICS_WH"
query: "SELECT sales_lift_pct FROM influencer_attribution WHERE campaign_id='{{campaign_id}}'"
- name: post-results
type: call
call: msteams.send-message
with:
channel_id: "influencer-marketing"
text: "Influencer ROI for {{campaign_id}}: Spend ${{get-spend.actual_cost}}, Engagement {{get-engagement.total_interactions}}, Sales lift {{get-sales-lift.sales_lift_pct}}%."
consumes:
- type: http
namespace: salesforce
baseUri: "https://loreal.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: campaigns
path: "/sobjects/Campaign/{{campaign_id}}"
inputParameters:
- name: campaign_id
in: path
operations:
- name: get-campaign
method: GET
- type: http
namespace: instagram
baseUri: "https://graph.facebook.com/v18.0"
authentication:
type: bearer
token: "$secrets.meta_token"
resources:
- name: insights
path: "/{{ig_user_id}}/insights"
inputParameters:
- name: ig_user_id
in: path
operations:
- name: get-insights
method: GET
- type: http
namespace: snowflake
baseUri: "https://loreal.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: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST
Assesses ingredient safety by pulling INCI data from SharePoint, checking regulatory status in Snowflake, and creating a Jira review ticket for the toxicology team.
naftiko: "0.5"
info:
label: "Ingredient Safety Assessment Workflow"
description: "Assesses ingredient safety by pulling INCI data from SharePoint, checking regulatory status in Snowflake, and creating a Jira review ticket for the toxicology team."
tags:
- r-and-d
- quality
- regulatory
- sharepoint
- snowflake
- jira
capability:
exposes:
- type: mcp
namespace: ingredient-safety
port: 8080
tools:
- name: assess-ingredient-safety
description: "Conduct an ingredient safety assessment by gathering INCI data, checking regulatory status, and routing for toxicology review."
inputParameters:
- name: ingredient_name
type: string
description: "INCI ingredient name."
- name: concentration_pct
type: number
description: "Proposed concentration percentage."
steps:
- name: get-inci-docs
type: call
call: sharepoint.search-docs
with:
query: "{{ingredient_name}} safety INCI"
site: "rd-safety"
- name: check-regulatory
type: call
call: snowflake.execute-query
with:
warehouse: "REGULATORY_WH"
query: "SELECT status, max_concentration, restricted_markets FROM ingredient_regulatory WHERE inci_name='{{ingredient_name}}'"
- name: create-review
type: call
call: jira.create-issue
with:
project_key: "SAFETY"
issuetype: "Task"
summary: "Ingredient safety review: {{ingredient_name}} at {{concentration_pct}}%"
description: "Regulatory status: {{check-regulatory.status}}. Max allowed: {{check-regulatory.max_concentration}}%. Documents found: {{get-inci-docs.count}}."
consumes:
- type: http
namespace: sharepoint
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: search
path: "/sites/rd-safety/drive/root/search"
operations:
- name: search-docs
method: GET
- type: http
namespace: snowflake
baseUri: "https://loreal.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://loreal.atlassian.net/rest/api/3"
authentication:
type: basic
username: "$secrets.jira_user"
password: "$secrets.jira_api_token"
resources:
- name: issues
path: "/issue"
operations:
- name: create-issue
method: POST
Fetches engagement metrics for a brand Instagram account over a date range including likes, comments, and follower growth.
naftiko: "0.5"
info:
label: "Instagram Brand Engagement Lookup"
description: "Fetches engagement metrics for a brand Instagram account over a date range including likes, comments, and follower growth."
tags:
- marketing
- social
- instagram
- reporting
capability:
exposes:
- type: mcp
namespace: social-analytics
port: 8080
tools:
- name: get-instagram-engagement
description: "Retrieve Instagram engagement metrics for a brand account including total likes, comments, shares, and follower delta."
inputParameters:
- name: account_id
type: string
description: "Instagram business account ID."
- name: date_from
type: string
description: "Start date in YYYY-MM-DD format."
- name: date_to
type: string
description: "End date in YYYY-MM-DD format."
call: instagram.get-insights
with:
ig_user_id: "{{account_id}}"
since: "{{date_from}}"
until: "{{date_to}}"
outputParameters:
- name: total_likes
type: string
mapping: "$.data[0].values[0].value"
- name: total_comments
type: string
mapping: "$.data[1].values[0].value"
- name: follower_count
type: string
mapping: "$.data[2].values[0].value"
consumes:
- type: http
namespace: instagram
baseUri: "https://graph.facebook.com/v18.0"
authentication:
type: bearer
token: "$secrets.meta_token"
resources:
- name: insights
path: "/{{ig_user_id}}/insights"
inputParameters:
- name: ig_user_id
in: path
- name: since
in: query
- name: until
in: query
operations:
- name: get-insights
method: GET
Submits a vendor invoice to SAP Ariba for three-way match validation, creates an approval task in ServiceNow, and notifies the approver via Teams.
naftiko: "0.5"
info:
label: "Invoice Processing and Approval"
description: "Submits a vendor invoice to SAP Ariba for three-way match validation, creates an approval task in ServiceNow, and notifies the approver via Teams."
tags:
- finance
- procurement
- sap-ariba
- servicenow
- approval
capability:
exposes:
- type: mcp
namespace: finance-ops
port: 8080
tools:
- name: process-invoice
description: "Given a vendor invoice number and amount, submit it to SAP Ariba for three-way match, create a ServiceNow approval task, and notify the finance approver via Teams."
inputParameters:
- name: invoice_number
type: string
description: "Vendor invoice number."
- name: vendor_id
type: string
description: "SAP vendor ID."
- name: amount
type: number
description: "Invoice total amount."
- name: approver_upn
type: string
description: "UPN (email) of the finance approver in Microsoft 365."
steps:
- name: submit-invoice
type: call
call: sap-ariba.create-invoice
with:
invoiceNumber: "{{invoice_number}}"
vendorId: "{{vendor_id}}"
totalAmount: "{{amount}}"
- name: create-approval-task
type: call
call: servicenow.create-task
with:
short_description: "Invoice approval required: {{invoice_number}}"
assigned_to: "{{approver_upn}}"
description: "Ariba invoice ID: {{submit-invoice.invoiceId}}"
- name: notify-approver
type: call
call: msteams.send-message
with:
recipient_upn: "{{approver_upn}}"
text: "Invoice {{invoice_number}} for {{amount}} requires your approval. ServiceNow task: {{create-approval-task.number}}"
consumes:
- type: http
namespace: sap-ariba
baseUri: "https://openapi.ariba.com/api/invoice/v1"
authentication:
type: bearer
token: "$secrets.ariba_token"
resources:
- name: invoices
path: "/invoices"
operations:
- name: create-invoice
method: POST
- type: http
namespace: servicenow
baseUri: "https://loreal.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: tasks
path: "/table/sc_task"
operations:
- name: create-task
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: chats
path: "/chats"
operations:
- name: send-message
method: POST
Searches Jira for open quality defect issues in a project and returns defect counts by priority.
naftiko: "0.5"
info:
label: "Jira Quality Defect Lookup"
description: "Searches Jira for open quality defect issues in a project and returns defect counts by priority."
tags:
- quality
- project-management
- jira
- defects
capability:
exposes:
- type: mcp
namespace: quality-tracking
port: 8080
tools:
- name: get-quality-defects
description: "Search Jira for open quality defects in a project. Returns issue count grouped by priority."
inputParameters:
- name: project_key
type: string
description: "Jira project key for the quality project."
call: jira.search-issues
with:
jql: "project={{project_key}} AND type=Bug AND status!=Done"
outputParameters:
- name: total
type: string
mapping: "$.total"
- name: issues
type: string
mapping: "$.issues"
consumes:
- type: http
namespace: jira
baseUri: "https://loreal.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
Aggregates completed story points from the last Jira sprint and posts a velocity digest to the engineering Teams channel.
naftiko: "0.5"
info:
label: "Jira Sprint Velocity Digest"
description: "Aggregates completed story points from the last Jira sprint and posts a velocity digest to the engineering Teams channel."
tags:
- devops
- project-management
- jira
- microsoft-teams
- reporting
capability:
exposes:
- type: mcp
namespace: agile-reporting
port: 8080
tools:
- name: digest-sprint-velocity
description: "Given a Jira board ID and sprint ID, fetch completed issues and story points, then post a velocity summary to the engineering Teams channel."
inputParameters:
- name: board_id
type: string
description: "Jira board ID."
- name: sprint_id
type: string
description: "Jira sprint ID to summarize."
- name: teams_channel_id
type: string
description: "Teams channel ID for the engineering team."
steps:
- name: get-sprint-issues
type: call
call: jira.get-sprint-issues
with:
boardId: "{{board_id}}"
sprintId: "{{sprint_id}}"
- name: post-digest
type: call
call: msteams.post-channel-message
with:
channel_id: "{{teams_channel_id}}"
text: "Sprint {{sprint_id}} complete — {{get-sprint-issues.totalPoints}} story points delivered across {{get-sprint-issues.issueCount}} issues."
consumes:
- type: http
namespace: jira
baseUri: "https://loreal.atlassian.net/rest/api/3"
authentication:
type: basic
username: "$secrets.jira_user"
password: "$secrets.jira_api_token"
resources:
- name: sprint-issues
path: "/board/{{boardId}}/sprint/{{sprintId}}/issue"
inputParameters:
- name: boardId
in: path
- name: sprintId
in: path
operations:
- name: get-sprint-issues
method: GET
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/engineering/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Publishes a sponsored content post to a L'Oréal LinkedIn brand page and records the post ID in Salesforce for attribution tracking.
naftiko: "0.5"
info:
label: "LinkedIn Brand Campaign Publisher"
description: "Publishes a sponsored content post to a L'Oréal LinkedIn brand page and records the post ID in Salesforce for attribution tracking."
tags:
- marketing
- social
- linkedin
- salesforce
- content
capability:
exposes:
- type: mcp
namespace: social-publishing
port: 8080
tools:
- name: publish-linkedin-post
description: "Given post copy, image URL, and a Salesforce campaign ID, publish a LinkedIn sponsored content post on the brand page and log the post ID back to the Salesforce campaign record."
inputParameters:
- name: org_urn
type: string
description: "LinkedIn organization URN for the brand page."
- name: post_text
type: string
description: "Post copy text to publish."
- name: image_url
type: string
description: "URL of the image asset to attach."
- name: campaign_id
type: string
description: "Salesforce campaign record ID for attribution."
steps:
- name: publish-post
type: call
call: linkedin.create-post
with:
author: "{{org_urn}}"
commentary: "{{post_text}}"
content_url: "{{image_url}}"
- name: update-campaign
type: call
call: salesforce.update-campaign
with:
campaign_id: "{{campaign_id}}"
LinkedIn_Post_ID__c: "{{publish-post.id}}"
consumes:
- type: http
namespace: linkedin
baseUri: "https://api.linkedin.com/v2"
authentication:
type: bearer
token: "$secrets.linkedin_token"
resources:
- name: posts
path: "/posts"
operations:
- name: create-post
method: POST
- type: http
namespace: salesforce
baseUri: "https://loreal.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: campaigns
path: "/sobjects/Campaign/{{campaign_id}}"
inputParameters:
- name: campaign_id
in: path
operations:
- name: update-campaign
method: PATCH
Enriches the talent pipeline by pulling open requisitions from Workday, matching with LinkedIn talent pool data, and creating sourcing tasks in Jira.
naftiko: "0.5"
info:
label: "LinkedIn Talent Pipeline Enrichment"
description: "Enriches the talent pipeline by pulling open requisitions from Workday, matching with LinkedIn talent pool data, and creating sourcing tasks in Jira."
tags:
- hr
- recruiting
- workday
- linkedin
- jira
capability:
exposes:
- type: mcp
namespace: talent-acquisition
port: 8080
tools:
- name: enrich-talent-pipeline
description: "Enrich the talent pipeline by matching open positions with LinkedIn talent data and creating sourcing tasks."
inputParameters:
- name: department
type: string
description: "Department for open requisitions."
steps:
- name: get-requisitions
type: call
call: workday.get-open-positions
with:
department: "{{department}}"
- name: search-talent
type: call
call: linkedin.search-candidates
with:
skills: "{{get-requisitions.required_skills}}"
location: "{{get-requisitions.location}}"
- name: create-sourcing-tasks
type: call
call: jira.create-issue
with:
project_key: "RECRUIT"
issuetype: "Task"
summary: "Talent sourcing: {{department}} ({{get-requisitions.count}} open roles)"
description: "LinkedIn talent pool: {{search-talent.candidate_count}} matches. Top skills in demand: {{get-requisitions.top_skills}}."
consumes:
- type: http
namespace: workday
baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: positions
path: "/loreal/jobRequisitions"
operations:
- name: get-open-positions
method: GET
- type: http
namespace: linkedin
baseUri: "https://api.linkedin.com/v2"
authentication:
type: bearer
token: "$secrets.linkedin_token"
resources:
- name: talent
path: "/talentPool"
operations:
- name: search-candidates
method: POST
- type: http
namespace: jira
baseUri: "https://loreal.atlassian.net/rest/api/3"
authentication:
type: basic
username: "$secrets.jira_user"
password: "$secrets.jira_api_token"
resources:
- name: issues
path: "/issue"
operations:
- name: create-issue
method: POST
When a manufacturing line goes down, creates a ServiceNow incident, updates the production order status in SAP, and alerts the plant operations team via Teams.
naftiko: "0.5"
info:
label: "Manufacturing Downtime Incident Handler"
description: "When a manufacturing line goes down, creates a ServiceNow incident, updates the production order status in SAP, and alerts the plant operations team via Teams."
tags:
- manufacturing
- operations
- servicenow
- sap
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: mfg-ops
port: 8080
tools:
- name: handle-downtime
description: "Orchestrate the response to a manufacturing line downtime event by creating an incident, updating SAP, and notifying operations."
inputParameters:
- name: production_line
type: string
description: "Manufacturing production line identifier."
- name: plant_code
type: string
description: "SAP plant code."
- name: reason
type: string
description: "Reason for downtime."
steps:
- name: create-incident
type: call
call: servicenow.create-incident
with:
short_description: "Line down: {{production_line}} at plant {{plant_code}}"
category: "manufacturing"
urgency: "1"
description: "Production line {{production_line}} is down. Reason: {{reason}}."
- name: update-sap-order
type: call
call: sap.update-production-status
with:
plant: "{{plant_code}}"
line: "{{production_line}}"
status: "INTERRUPTED"
- name: alert-ops
type: call
call: msteams.send-message
with:
channel_id: "plant-operations"
text: "LINE DOWN: {{production_line}} at {{plant_code}}. Reason: {{reason}}. Incident: {{create-incident.number}}."
consumes:
- type: http
namespace: servicenow
baseUri: "https://loreal.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: incidents
path: "/table/incident"
operations:
- name: create-incident
method: POST
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_PRODUCTION_ORDER_2_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: production-orders
path: "/A_ProductionOrder"
operations:
- name: update-production-status
method: PATCH
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST
Coordinates a marketing campaign launch by creating a Salesforce campaign, scheduling Meta Ads, and notifying the marketing team via Teams.
naftiko: "0.5"
info:
label: "Marketing Campaign Launch Coordinator"
description: "Coordinates a marketing campaign launch by creating a Salesforce campaign, scheduling Meta Ads, and notifying the marketing team via Teams."
tags:
- marketing
- campaigns
- salesforce
- meta
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: campaign-ops
port: 8080
tools:
- name: launch-campaign
description: "Orchestrate a marketing campaign launch by creating the Salesforce campaign record, activating Meta ad sets, and sending a Teams notification."
inputParameters:
- name: campaign_name
type: string
description: "Name of the marketing campaign."
- name: brand
type: string
description: "Brand name (e.g., Lancôme, Maybelline)."
- name: start_date
type: string
description: "Campaign start date in YYYY-MM-DD format."
- name: budget_usd
type: number
description: "Total campaign budget in USD."
steps:
- name: create-sf-campaign
type: call
call: salesforce.create-campaign
with:
Name: "{{campaign_name}}"
Brand__c: "{{brand}}"
StartDate: "{{start_date}}"
BudgetedCost: "{{budget_usd}}"
Status: "Planned"
- name: activate-meta-ads
type: call
call: meta.update-campaign-status
with:
campaign_name: "{{campaign_name}}"
status: "ACTIVE"
- name: notify-team
type: call
call: msteams.send-message
with:
channel_id: "marketing-launches"
text: "Campaign '{{campaign_name}}' for {{brand}} launched. SF ID: {{create-sf-campaign.id}}. Budget: ${{budget_usd}}. Start: {{start_date}}."
consumes:
- type: http
namespace: salesforce
baseUri: "https://loreal.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: campaigns
path: "/sobjects/Campaign"
operations:
- name: create-campaign
method: POST
- type: http
namespace: meta
baseUri: "https://graph.facebook.com/v18.0"
authentication:
type: bearer
token: "$secrets.meta_token"
resources:
- name: campaigns
path: "/campaigns"
operations:
- name: update-campaign-status
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST
Aggregates campaign performance metrics from Salesforce Marketing Cloud and publishes a daily digest to a Microsoft Teams channel.
naftiko: "0.5"
info:
label: "Marketing Campaign Performance Digest"
description: "Aggregates campaign performance metrics from Salesforce Marketing Cloud and publishes a daily digest to a Microsoft Teams channel."
tags:
- marketing
- reporting
- salesforce
- microsoft-teams
- digest
capability:
exposes:
- type: mcp
namespace: marketing-reporting
port: 8080
tools:
- name: digest-campaign-performance
description: "Fetch top campaign performance metrics from Salesforce Marketing Cloud for a given date range and post a formatted summary to the marketing Teams channel."
inputParameters:
- name: date_from
type: string
description: "Start date for the reporting period in YYYY-MM-DD format."
- name: date_to
type: string
description: "End date for the reporting period in YYYY-MM-DD format."
- name: teams_channel_id
type: string
description: "Microsoft Teams channel ID to post the digest to."
steps:
- name: get-campaigns
type: call
call: sfmc.list-campaigns
with:
dateFrom: "{{date_from}}"
dateTo: "{{date_to}}"
- name: post-digest
type: call
call: msteams.post-channel-message
with:
channel_id: "{{teams_channel_id}}"
text: "Marketing Campaign Digest ({{date_from}} to {{date_to}}): {{get-campaigns.summary}}"
consumes:
- type: http
namespace: sfmc
baseUri: "https://api.salesforce.com/marketing/v1"
authentication:
type: bearer
token: "$secrets.sfmc_token"
resources:
- name: campaigns
path: "/campaigns"
inputParameters:
- name: dateFrom
in: query
- name: dateTo
in: query
operations:
- name: list-campaigns
method: GET
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Generates a media mix optimization report by pulling spend data from Meta and Google Ads via Snowflake, correlating with sales, and refreshing the Power BI dashboard.
naftiko: "0.5"
info:
label: "Media Mix Optimization Report Generator"
description: "Generates a media mix optimization report by pulling spend data from Meta and Google Ads via Snowflake, correlating with sales, and refreshing the Power BI dashboard."
tags:
- marketing
- analytics
- snowflake
- power-bi
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: media-planning
port: 8080
tools:
- name: generate-media-mix-report
description: "Generate a media mix optimization report combining multi-channel spend with sales outcomes."
inputParameters:
- name: brand
type: string
description: "Brand name."
- name: date_from
type: string
description: "Start date."
- name: date_to
type: string
description: "End date."
steps:
- name: get-media-data
type: call
call: snowflake.execute-query
with:
warehouse: "MARKETING_ANALYTICS_WH"
query: "SELECT channel, spend, impressions, conversions, roas FROM media_mix WHERE brand='{{brand}}' AND date BETWEEN '{{date_from}}' AND '{{date_to}}' GROUP BY channel"
- name: refresh-dashboard
type: call
call: powerbi.refresh-dataset
with:
datasetId: "media-mix-optimization"
- name: post-summary
type: call
call: msteams.send-message
with:
channel_id: "media-planning"
text: "Media mix report ready for {{brand}} ({{date_from}} to {{date_to}}). Best ROAS channel: {{get-media-data.top_channel}}."
consumes:
- type: http
namespace: snowflake
baseUri: "https://loreal.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: powerbi
baseUri: "https://api.powerbi.com/v1.0/myorg"
authentication:
type: bearer
token: "$secrets.powerbi_token"
resources:
- name: datasets
path: "/datasets/{{datasetId}}/refreshes"
inputParameters:
- name: datasetId
in: path
operations:
- name: refresh-dataset
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST
Retrieves ad campaign performance metrics from Meta Ads Manager for a given campaign and date range.
naftiko: "0.5"
info:
label: "Meta Ad Campaign Performance Lookup"
description: "Retrieves ad campaign performance metrics from Meta Ads Manager for a given campaign and date range."
tags:
- marketing
- social
- meta
- reporting
capability:
exposes:
- type: mcp
namespace: meta-ads
port: 8080
tools:
- name: get-campaign-insights
description: "Fetch Meta Ads campaign insights including impressions, reach, clicks, and spend for a given campaign ID and date range. Use for paid social performance reviews."
inputParameters:
- name: campaign_id
type: string
description: "Meta Ads campaign ID."
- name: date_from
type: string
description: "Start date in YYYY-MM-DD format."
- name: date_to
type: string
description: "End date in YYYY-MM-DD format."
call: meta.get-campaign-insights
with:
campaign_id: "{{campaign_id}}"
date_preset: "custom"
time_range_since: "{{date_from}}"
time_range_until: "{{date_to}}"
outputParameters:
- name: impressions
type: string
mapping: "$.data[0].impressions"
- name: reach
type: string
mapping: "$.data[0].reach"
- name: clicks
type: string
mapping: "$.data[0].clicks"
- name: spend
type: string
mapping: "$.data[0].spend"
consumes:
- type: http
namespace: meta
baseUri: "https://graph.facebook.com/v18.0"
authentication:
type: bearer
token: "$secrets.meta_token"
resources:
- name: campaign-insights
path: "/{{campaign_id}}/insights"
inputParameters:
- name: campaign_id
in: path
- name: date_preset
in: query
- name: time_range_since
in: query
- name: time_range_until
in: query
operations:
- name: get-campaign-insights
method: GET
When a new hire is created in Workday, opens a ServiceNow onboarding ticket, provisions a Microsoft 365 account, and sends a Teams welcome message.
naftiko: "0.5"
info:
label: "New Hire Onboarding Orchestrator"
description: "When a new hire is created in Workday, opens a ServiceNow onboarding ticket, provisions a Microsoft 365 account, and sends a Teams welcome message."
tags:
- hr
- onboarding
- workday
- servicenow
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: hr-onboarding
port: 8080
tools:
- name: trigger-onboarding
description: "Given a Workday employee ID and start date, orchestrate the full onboarding sequence across ServiceNow ticketing, Microsoft Graph account provisioning, and Teams welcome notification."
inputParameters:
- name: employee_id
type: string
description: "Workday worker ID for the new hire."
- name: start_date
type: string
description: "Employee start date in YYYY-MM-DD format."
- name: department
type: string
description: "Department name for the new hire, used to assign the correct onboarding group."
steps:
- name: get-worker
type: call
call: workday.get-worker
with:
worker_id: "{{employee_id}}"
- name: create-ticket
type: call
call: servicenow.create-incident
with:
short_description: "New hire onboarding: {{get-worker.full_name}}"
category: "hr_onboarding"
assignment_group: "IT_Onboarding"
- name: provision-account
type: call
call: msgraph.create-user
with:
displayName: "{{get-worker.full_name}}"
mail: "{{get-worker.work_email}}"
department: "{{department}}"
- name: send-welcome
type: call
call: msteams.send-message
with:
recipient_upn: "{{get-worker.work_email}}"
text: "Welcome to L'Oréal, {{get-worker.first_name}}! Your onboarding ticket is {{create-ticket.number}}."
consumes:
- type: http
namespace: workday
baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: workers
path: "/loreal/workers/{{worker_id}}"
inputParameters:
- name: worker_id
in: path
operations:
- name: get-worker
method: GET
- type: http
namespace: servicenow
baseUri: "https://loreal.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: incidents
path: "/table/incident"
operations:
- name: create-incident
method: POST
- type: http
namespace: msgraph
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: users
path: "/users"
operations:
- name: create-user
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: chats
path: "/chats"
operations:
- name: send-message
method: POST
Coordinates a new market launch by creating Jira epic with subtasks, setting up Salesforce territory records, and notifying the regional team via Teams.
naftiko: "0.5"
info:
label: "New Market Launch Checklist Coordinator"
description: "Coordinates a new market launch by creating Jira epic with subtasks, setting up Salesforce territory records, and notifying the regional team via Teams."
tags:
- sales
- marketing
- jira
- salesforce
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: market-launch
port: 8080
tools:
- name: coordinate-market-launch
description: "Coordinate the launch of products in a new market by creating project tasks, setting up CRM territories, and notifying regional teams."
inputParameters:
- name: market_name
type: string
description: "Name of the new market (e.g., Vietnam, Colombia)."
- name: brand
type: string
description: "Brand being launched."
- name: launch_date
type: string
description: "Target launch date."
steps:
- name: create-epic
type: call
call: jira.create-issue
with:
project_key: "LAUNCH"
issuetype: "Epic"
summary: "New market launch: {{brand}} in {{market_name}}"
description: "Target launch: {{launch_date}}. Brand: {{brand}}."
- name: setup-territory
type: call
call: salesforce.create-territory
with:
Name: "{{market_name}} - {{brand}}"
Territory_Type__c: "New Market"
Launch_Date__c: "{{launch_date}}"
- name: notify-regional
type: call
call: msteams.send-message
with:
channel_id: "international-launches"
text: "New market launch initiated: {{brand}} in {{market_name}}. Target: {{launch_date}}. Epic: {{create-epic.key}}."
consumes:
- type: http
namespace: jira
baseUri: "https://loreal.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: salesforce
baseUri: "https://loreal.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: territories
path: "/sobjects/Territory__c"
operations:
- name: create-territory
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST
When an R&D formulation is submitted, retrieves the bill of materials from SAP, checks regulatory compliance documents in SharePoint, and creates a review task in Jira.
naftiko: "0.5"
info:
label: "New Product Formulation Review Workflow"
description: "When an R&D formulation is submitted, retrieves the bill of materials from SAP, checks regulatory compliance documents in SharePoint, and creates a review task in Jira."
tags:
- r-and-d
- quality
- sap
- sharepoint
- jira
capability:
exposes:
- type: mcp
namespace: rd-formulation
port: 8080
tools:
- name: initiate-formulation-review
description: "Orchestrate a new product formulation review by pulling the BOM, checking regulatory docs, and creating a review task."
inputParameters:
- name: material_number
type: string
description: "SAP material number for the new formulation."
- name: plant_code
type: string
description: "SAP plant code."
- name: formulation_name
type: string
description: "Name of the new formulation."
steps:
- name: get-bom
type: call
call: sap.get-bom
with:
material: "{{material_number}}"
plant: "{{plant_code}}"
- name: check-regulatory
type: call
call: sharepoint.search-docs
with:
query: "{{formulation_name}} regulatory INCI"
site: "regulatory-affairs"
- name: create-review-task
type: call
call: jira.create-issue
with:
project_key: "RND"
issuetype: "Task"
summary: "Formulation review: {{formulation_name}}"
description: "BOM contains {{get-bom.component_count}} components. Regulatory docs found: {{check-regulatory.result_count}}."
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_BILL_OF_MATERIAL_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: bom
path: "/MaterialBOM"
operations:
- name: get-bom
method: GET
- type: http
namespace: sharepoint
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: search
path: "/sites/regulatory-affairs/drive/root/search"
operations:
- name: search-docs
method: GET
- type: http
namespace: jira
baseUri: "https://loreal.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
Onboards a new SKU by creating the material master in SAP, setting up the Salesforce product record, and notifying the supply chain team via Teams.
naftiko: "0.5"
info:
label: "New SKU Listing Onboarding Workflow"
description: "Onboards a new SKU by creating the material master in SAP, setting up the Salesforce product record, and notifying the supply chain team via Teams."
tags:
- supply-chain
- sales
- sap
- salesforce
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: sku-management
port: 8080
tools:
- name: onboard-new-sku
description: "Orchestrate the onboarding of a new SKU across ERP, CRM, and notification systems."
inputParameters:
- name: sku_name
type: string
description: "Product name for the new SKU."
- name: brand
type: string
description: "Brand name."
- name: category
type: string
description: "Product category."
- name: unit_cost
type: number
description: "Unit cost in USD."
steps:
- name: create-material
type: call
call: sap.create-material
with:
description: "{{sku_name}}"
material_group: "{{category}}"
brand: "{{brand}}"
standard_price: "{{unit_cost}}"
- name: create-sf-product
type: call
call: salesforce.create-product
with:
Name: "{{sku_name}}"
ProductCode: "{{create-material.material_number}}"
Family: "{{category}}"
IsActive: true
- name: notify-supply-chain
type: call
call: msteams.send-message
with:
channel_id: "supply-chain-ops"
text: "New SKU onboarded: {{sku_name}} ({{create-material.material_number}}). Brand: {{brand}}. Category: {{category}}."
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_PRODUCT_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: materials
path: "/A_Product"
operations:
- name: create-material
method: POST
- type: http
namespace: salesforce
baseUri: "https://loreal.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: products
path: "/sobjects/Product2"
operations:
- name: create-product
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST
When an access request is approved in ServiceNow, provisions the requested Okta group membership and confirms via Teams.
naftiko: "0.5"
info:
label: "Okta Access Request Provisioning"
description: "When an access request is approved in ServiceNow, provisions the requested Okta group membership and confirms via Teams."
tags:
- identity
- security
- okta
- servicenow
- access-management
capability:
exposes:
- type: mcp
namespace: identity-ops
port: 8080
tools:
- name: provision-access
description: "Given an approved ServiceNow access request ticket, assign the user to the corresponding Okta group and update the ticket status to resolved. Use for access provisioning automation."
inputParameters:
- name: snow_ticket_id
type: string
description: "ServiceNow request ticket sys_id."
- name: user_email
type: string
description: "User email address to provision access for."
- name: okta_group_id
type: string
description: "Okta group ID to assign the user to."
steps:
- name: add-to-group
type: call
call: okta.add-user-to-group
with:
groupId: "{{okta_group_id}}"
userId: "{{user_email}}"
- name: resolve-ticket
type: call
call: servicenow.update-request
with:
sys_id: "{{snow_ticket_id}}"
state: "3"
close_notes: "Access provisioned to Okta group {{okta_group_id}}"
- name: notify-user
type: call
call: msteams.send-message
with:
recipient_upn: "{{user_email}}"
text: "Your access request has been fulfilled. You now have access to the requested resources (Okta group: {{okta_group_id}})."
consumes:
- type: http
namespace: okta
baseUri: "https://loreal.okta.com/api/v1"
authentication:
type: apikey
key: "Authorization"
value: "$secrets.okta_api_token"
placement: header
resources:
- name: group-members
path: "/groups/{{groupId}}/users/{{userId}}"
inputParameters:
- name: groupId
in: path
- name: userId
in: path
operations:
- name: add-user-to-group
method: PUT
- type: http
namespace: servicenow
baseUri: "https://loreal.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: requests
path: "/table/sc_request/{{sys_id}}"
inputParameters:
- name: sys_id
in: path
operations:
- name: update-request
method: PATCH
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: chats
path: "/chats"
operations:
- name: send-message
method: POST
Handles contractor access expiry by checking Okta account status, verifying contract end dates in Workday, and creating deprovisioning tasks in ServiceNow.
naftiko: "0.5"
info:
label: "Okta Contractor Access Expiry Handler"
description: "Handles contractor access expiry by checking Okta account status, verifying contract end dates in Workday, and creating deprovisioning tasks in ServiceNow."
tags:
- security
- identity
- okta
- workday
- servicenow
capability:
exposes:
- type: mcp
namespace: access-lifecycle
port: 8080
tools:
- name: handle-contractor-expiry
description: "Handle contractor access expiry by verifying employment status and creating deprovisioning tasks."
inputParameters:
- name: contractor_email
type: string
description: "Contractor email address."
steps:
- name: get-okta-status
type: call
call: okta.get-user
with:
email: "{{contractor_email}}"
- name: check-workday
type: call
call: workday.get-worker-by-email
with:
email: "{{contractor_email}}"
- name: create-deprovision-task
type: call
call: servicenow.create-task
with:
short_description: "Contractor access expiry: {{contractor_email}}"
description: "Okta status: {{get-okta-status.status}}. Workday end date: {{check-workday.contract_end_date}}. Deprovisioning required."
category: "identity_management"
consumes:
- type: http
namespace: okta
baseUri: "https://loreal.okta.com/api/v1"
authentication:
type: bearer
token: "$secrets.okta_api_token"
resources:
- name: users
path: "/users/{{email}}"
inputParameters:
- name: email
in: path
operations:
- name: get-user
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: workers
path: "/loreal/workers"
operations:
- name: get-worker-by-email
method: GET
- type: http
namespace: servicenow
baseUri: "https://loreal.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: tasks
path: "/table/sc_task"
operations:
- name: create-task
method: POST
Audits privileged access by pulling Okta admin role assignments, cross-referencing with Workday employment status, and creating a ServiceNow review task for stale accounts.
naftiko: "0.5"
info:
label: "Okta Privileged Access Audit Workflow"
description: "Audits privileged access by pulling Okta admin role assignments, cross-referencing with Workday employment status, and creating a ServiceNow review task for stale accounts."
tags:
- security
- identity
- okta
- workday
- servicenow
capability:
exposes:
- type: mcp
namespace: security-audit
port: 8080
tools:
- name: audit-privileged-access
description: "Audit privileged Okta accounts by verifying employment status and flagging stale or orphaned admin accounts."
inputParameters:
- name: role_type
type: string
description: "Okta admin role type to audit (e.g., SUPER_ADMIN, ORG_ADMIN)."
steps:
- name: get-admin-users
type: call
call: okta.list-role-assignments
with:
role_type: "{{role_type}}"
- name: check-employment
type: call
call: workday.get-active-workers
with:
email_list: "{{get-admin-users.emails}}"
- name: create-review
type: call
call: servicenow.create-task
with:
short_description: "Privileged access audit: {{role_type}} role"
description: "Total admins: {{get-admin-users.count}}. Inactive employees with admin access: {{check-employment.stale_count}}."
category: "security"
consumes:
- type: http
namespace: okta
baseUri: "https://loreal.okta.com/api/v1"
authentication:
type: bearer
token: "$secrets.okta_api_token"
resources:
- name: roles
path: "/users"
operations:
- name: list-role-assignments
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: workers
path: "/loreal/workers"
operations:
- name: get-active-workers
method: GET
- type: http
namespace: servicenow
baseUri: "https://loreal.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: tasks
path: "/table/sc_task"
operations:
- name: create-task
method: POST
Checks packaging materials against sustainability requirements by querying SAP BOM data, verifying compliance in Snowflake, and creating a Jira task for non-compliant items.
naftiko: "0.5"
info:
label: "Packaging Sustainability Compliance Checker"
description: "Checks packaging materials against sustainability requirements by querying SAP BOM data, verifying compliance in Snowflake, and creating a Jira task for non-compliant items."
tags:
- sustainability
- quality
- sap
- snowflake
- jira
capability:
exposes:
- type: mcp
namespace: sustainability
port: 8080
tools:
- name: check-packaging-compliance
description: "Verify packaging sustainability compliance by cross-referencing BOM materials with sustainability standards and flagging non-compliant components."
inputParameters:
- name: material_number
type: string
description: "SAP material number for the packaged product."
- name: plant_code
type: string
description: "SAP plant code."
steps:
- name: get-packaging-bom
type: call
call: sap.get-bom
with:
material: "{{material_number}}"
plant: "{{plant_code}}"
- name: check-compliance
type: call
call: snowflake.execute-query
with:
warehouse: "SUSTAINABILITY_WH"
query: "SELECT material_id, recyclable_pct, compliant FROM packaging_sustainability WHERE material_id IN ({{get-packaging-bom.component_ids}})"
- name: create-task
type: call
call: jira.create-issue
with:
project_key: "SUSTAIN"
issuetype: "Task"
summary: "Packaging compliance review: {{material_number}}"
description: "Non-compliant components found: {{check-compliance.non_compliant_count}}. Review required."
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_BILL_OF_MATERIAL_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: bom
path: "/MaterialBOM"
operations:
- name: get-bom
method: GET
- type: http
namespace: snowflake
baseUri: "https://loreal.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://loreal.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
Retrieves current headcount by department and cost center from Workday for payroll planning and cost allocation reporting.
naftiko: "0.5"
info:
label: "Payroll Headcount Snapshot"
description: "Retrieves current headcount by department and cost center from Workday for payroll planning and cost allocation reporting."
tags:
- hr
- finance
- payroll
- workday
- reporting
capability:
exposes:
- type: mcp
namespace: hr-finance
port: 8080
tools:
- name: get-headcount-by-department
description: "Returns a list of active employees grouped by department and cost center with employment type. Use for headcount planning, budgeting, and HR cost reporting."
call: workday.headcount-export
outputParameters:
- name: employees
type: array
mapping: "$.data"
items:
- name: employee_id
type: string
mapping: "$.id"
- name: full_name
type: string
mapping: "$.fullName"
- name: department
type: string
mapping: "$.department"
- name: cost_center
type: string
mapping: "$.costCenter"
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-export
path: "/loreal/workers"
operations:
- name: headcount-export
method: GET
Monitors manufacturing plant energy consumption by querying Snowflake IoT data, comparing against targets, and creating a ServiceNow task for anomalies.
naftiko: "0.5"
info:
label: "Plant Energy Consumption Monitor"
description: "Monitors manufacturing plant energy consumption by querying Snowflake IoT data, comparing against targets, and creating a ServiceNow task for anomalies."
tags:
- manufacturing
- sustainability
- snowflake
- servicenow
- iot
capability:
exposes:
- type: mcp
namespace: energy-monitoring
port: 8080
tools:
- name: monitor-energy-consumption
description: "Monitor plant energy consumption against targets and flag anomalies for investigation."
inputParameters:
- name: plant_code
type: string
description: "SAP plant code."
- name: date
type: string
description: "Date to check in YYYY-MM-DD format."
steps:
- name: get-consumption
type: call
call: snowflake.execute-query
with:
warehouse: "IOT_ANALYTICS_WH"
query: "SELECT kwh_actual, kwh_target, variance_pct FROM plant_energy WHERE plant='{{plant_code}}' AND date='{{date}}'"
- name: create-anomaly-task
type: call
call: servicenow.create-task
with:
short_description: "Energy anomaly: plant {{plant_code}} on {{date}}"
description: "Actual: {{get-consumption.kwh_actual}} kWh. Target: {{get-consumption.kwh_target}} kWh. Variance: {{get-consumption.variance_pct}}%."
category: "facilities"
- name: notify-team
type: call
call: msteams.send-message
with:
channel_id: "plant-sustainability"
text: "Energy alert for {{plant_code}}: {{get-consumption.variance_pct}}% over target on {{date}}."
consumes:
- type: http
namespace: snowflake
baseUri: "https://loreal.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
baseUri: "https://loreal.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: tasks
path: "/table/sc_task"
operations:
- name: create-task
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST
Triggers a refresh of a Power BI brand sales dashboard dataset and returns the refresh status.
naftiko: "0.5"
info:
label: "Power BI Brand Sales Dashboard Refresh"
description: "Triggers a refresh of a Power BI brand sales dashboard dataset and returns the refresh status."
tags:
- analytics
- reporting
- power-bi
- sales
capability:
exposes:
- type: mcp
namespace: bi-reporting
port: 8080
tools:
- name: refresh-brand-dashboard
description: "Trigger a dataset refresh for a Power BI brand sales dashboard and return the resulting refresh status."
inputParameters:
- name: dataset_id
type: string
description: "Power BI dataset ID for the brand sales dashboard."
call: powerbi.refresh-dataset
with:
datasetId: "{{dataset_id}}"
outputParameters:
- name: refresh_id
type: string
mapping: "$.id"
- name: status
type: string
mapping: "$.status"
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/{{datasetId}}/refreshes"
inputParameters:
- name: datasetId
in: path
operations:
- name: refresh-dataset
method: POST
Triggers a Power BI dataset refresh on schedule and posts completion status to the analytics Teams channel.
naftiko: "0.5"
info:
label: "Power BI Report Refresh Trigger"
description: "Triggers a Power BI dataset refresh on schedule and posts completion status to the analytics Teams channel."
tags:
- data
- analytics
- power-bi
- microsoft-teams
- reporting
capability:
exposes:
- type: mcp
namespace: bi-reporting
port: 8080
tools:
- name: trigger-dataset-refresh
description: "Trigger a Power BI dataset refresh for a given workspace and dataset, then post completion status to the analytics Teams channel. Use for scheduled BI refresh orchestration."
inputParameters:
- name: workspace_id
type: string
description: "Power BI workspace (group) ID."
- name: dataset_id
type: string
description: "Power BI dataset ID to refresh."
- name: teams_channel_id
type: string
description: "Teams channel ID to notify on completion."
steps:
- name: refresh-dataset
type: call
call: powerbi.trigger-refresh
with:
workspaceId: "{{workspace_id}}"
datasetId: "{{dataset_id}}"
- name: notify-team
type: call
call: msteams.post-message
with:
channel_id: "{{teams_channel_id}}"
text: "Power BI dataset {{dataset_id}} refresh triggered successfully in workspace {{workspace_id}}."
consumes:
- type: http
namespace: powerbi
baseUri: "https://api.powerbi.com/v1.0/myorg"
authentication:
type: bearer
token: "$secrets.powerbi_token"
resources:
- name: dataset-refreshes
path: "/groups/{{workspaceId}}/datasets/{{datasetId}}/refreshes"
inputParameters:
- name: workspaceId
in: path
- name: datasetId
in: path
operations:
- name: trigger-refresh
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/analytics/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: post-message
method: POST
Analyzes product costing variances by comparing SAP standard costs with actual production costs from Snowflake and creating a finance review task in Jira.
naftiko: "0.5"
info:
label: "Product Costing Variance Analyzer"
description: "Analyzes product costing variances by comparing SAP standard costs with actual production costs from Snowflake and creating a finance review task in Jira."
tags:
- finance
- manufacturing
- sap
- snowflake
- jira
capability:
exposes:
- type: mcp
namespace: cost-analytics
port: 8080
tools:
- name: analyze-costing-variance
description: "Analyze product costing variances between standard and actual costs and route significant variances for review."
inputParameters:
- name: material_number
type: string
description: "SAP material number."
- name: period
type: string
description: "Costing period in YYYY-MM format."
steps:
- name: get-standard-cost
type: call
call: sap.get-material-cost
with:
material: "{{material_number}}"
- name: get-actual-cost
type: call
call: snowflake.execute-query
with:
warehouse: "FINANCE_WH"
query: "SELECT actual_cost_per_unit, total_production_cost FROM production_costs WHERE material='{{material_number}}' AND period='{{period}}'"
- name: create-review
type: call
call: jira.create-issue
with:
project_key: "FIN"
issuetype: "Task"
summary: "Costing variance review: {{material_number}} ({{period}})"
description: "Standard cost: {{get-standard-cost.standard_price}}. Actual: {{get-actual-cost.actual_cost_per_unit}}. Variance: needs review."
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_PRODUCT_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: materials
path: "/A_Product('{{material}}')"
inputParameters:
- name: material
in: path
operations:
- name: get-material-cost
method: GET
- type: http
namespace: snowflake
baseUri: "https://loreal.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://loreal.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
Assembles a product launch briefing by pulling campaign assets from Adobe Creative Cloud and distributing the package to brand teams via SharePoint and Teams.
naftiko: "0.5"
info:
label: "Product Launch Content Briefing"
description: "Assembles a product launch briefing by pulling campaign assets from Adobe Creative Cloud and distributing the package to brand teams via SharePoint and Teams."
tags:
- marketing
- content
- adobe
- sharepoint
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: content-ops
port: 8080
tools:
- name: assemble-launch-briefing
description: "Given a product launch ID, retrieve approved creative assets from Adobe Experience Manager, upload them to a SharePoint brand folder, and notify the brand team via Teams."
inputParameters:
- name: launch_id
type: string
description: "Internal product launch ID."
- name: brand_name
type: string
description: "Brand name (e.g., Lancôme, Maybelline) for folder routing."
- name: teams_channel_id
type: string
description: "Teams channel ID for the brand team notification."
steps:
- name: get-assets
type: call
call: aem.list-assets
with:
launchId: "{{launch_id}}"
brand: "{{brand_name}}"
- name: upload-to-sharepoint
type: call
call: sharepoint.upload-file
with:
site_id: "brand_launches"
folder_path: "Launches/{{brand_name}}/{{launch_id}}"
content: "{{get-assets.packageUrl}}"
- name: notify-team
type: call
call: msteams.post-channel-message
with:
channel_id: "{{teams_channel_id}}"
text: "Launch briefing ready for {{brand_name}} ({{launch_id}}). Assets: {{upload-to-sharepoint.sharepoint_url}}"
consumes:
- type: http
namespace: aem
baseUri: "https://author.loreal.adobecqms.net/api/assets"
authentication:
type: basic
username: "$secrets.aem_user"
password: "$secrets.aem_password"
resources:
- name: assets
path: "/loreal/launches/{{launchId}}"
inputParameters:
- name: launchId
in: path
operations:
- name: list-assets
method: GET
- type: http
namespace: sharepoint
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: files
path: "/sites/{{site_id}}/drive/items/root:/{{folder_path}}:/children"
inputParameters:
- name: site_id
in: path
- name: folder_path
in: path
operations:
- name: upload-file
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/brand/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
When a quality issue is detected, traces the affected batch in SAP, creates a ServiceNow incident, notifies the quality team via Teams, and opens a Jira investigation ticket.
naftiko: "0.5"
info:
label: "Product Recall Investigation Orchestrator"
description: "When a quality issue is detected, traces the affected batch in SAP, creates a ServiceNow incident, notifies the quality team via Teams, and opens a Jira investigation ticket."
tags:
- quality
- supply-chain
- sap
- servicenow
- microsoft-teams
- jira
capability:
exposes:
- type: mcp
namespace: quality-ops
port: 8080
tools:
- name: investigate-recall
description: "Orchestrate a product recall investigation by tracing the batch, creating an incident, notifying the quality team, and opening a tracking ticket."
inputParameters:
- name: batch_number
type: string
description: "Affected product batch number."
- name: material_number
type: string
description: "SAP material number of the affected product."
- name: severity
type: string
description: "Severity level: critical, high, medium, low."
steps:
- name: trace-batch
type: call
call: sap.get-batch-details
with:
batch: "{{batch_number}}"
material: "{{material_number}}"
- name: create-incident
type: call
call: servicenow.create-incident
with:
short_description: "Product recall investigation: batch {{batch_number}}"
category: "quality"
urgency: "{{severity}}"
description: "Batch {{batch_number}} produced at {{trace-batch.plant}}. Investigation required."
- name: notify-team
type: call
call: msteams.send-message
with:
channel_id: "quality-alerts"
text: "RECALL ALERT: Batch {{batch_number}} under investigation. Incident: {{create-incident.number}}. Severity: {{severity}}."
- name: create-jira-ticket
type: call
call: jira.create-issue
with:
project_key: "QUAL"
issuetype: "Task"
summary: "Recall investigation: {{material_number}} batch {{batch_number}}"
description: "ServiceNow incident: {{create-incident.number}}. Plant: {{trace-batch.plant}}."
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_BATCH_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: batches
path: "/A_Batch"
operations:
- name: get-batch-details
method: GET
- type: http
namespace: servicenow
baseUri: "https://loreal.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: incidents
path: "/table/incident"
operations:
- name: create-incident
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST
- type: http
namespace: jira
baseUri: "https://loreal.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
Orchestrates the release of a production batch by verifying quality inspection results in SAP QM, updating the batch status, and notifying the logistics team via Teams.
naftiko: "0.5"
info:
label: "Production Batch Release Workflow"
description: "Orchestrates the release of a production batch by verifying quality inspection results in SAP QM, updating the batch status, and notifying the logistics team via Teams."
tags:
- manufacturing
- quality
- sap
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: batch-release
port: 8080
tools:
- name: release-production-batch
description: "Release a production batch after quality verification by checking inspection results, updating batch status, and notifying logistics."
inputParameters:
- name: batch_number
type: string
description: "Production batch number."
- name: material_number
type: string
description: "SAP material number."
steps:
- name: check-inspection
type: call
call: sap.get-inspection-result
with:
batch: "{{batch_number}}"
material: "{{material_number}}"
- name: release-batch
type: call
call: sap.update-batch-status
with:
batch: "{{batch_number}}"
material: "{{material_number}}"
status: "RELEASED"
- name: notify-logistics
type: call
call: msteams.send-message
with:
channel_id: "logistics-ops"
text: "Batch {{batch_number}} ({{material_number}}) released for distribution. Inspection: {{check-inspection.usage_decision}}."
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_INSPECTIONLOT_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: inspections
path: "/A_InspectionLot"
operations:
- name: get-inspection-result
method: GET
- name: update-batch-status
method: PATCH
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST
Reviews the R&D patent portfolio by querying SharePoint for patent documents, pulling innovation metrics from Snowflake, and creating a review summary in Jira.
naftiko: "0.5"
info:
label: "R&D Patent Portfolio Review"
description: "Reviews the R&D patent portfolio by querying SharePoint for patent documents, pulling innovation metrics from Snowflake, and creating a review summary in Jira."
tags:
- r-and-d
- innovation
- sharepoint
- snowflake
- jira
capability:
exposes:
- type: mcp
namespace: rd-innovation
port: 8080
tools:
- name: review-patent-portfolio
description: "Review the patent portfolio by pulling documents, analyzing metrics, and creating a summary task."
inputParameters:
- name: technology_area
type: string
description: "Technology area for patent review."
- name: review_year
type: string
description: "Year for the review."
steps:
- name: get-patents
type: call
call: sharepoint.search-docs
with:
query: "patent {{technology_area}} {{review_year}}"
site: "rd-innovation"
- name: get-metrics
type: call
call: snowflake.execute-query
with:
warehouse: "RD_ANALYTICS_WH"
query: "SELECT patent_count, pending_count, granted_count FROM patent_metrics WHERE tech_area='{{technology_area}}' AND year='{{review_year}}'"
- name: create-review
type: call
call: jira.create-issue
with:
project_key: "RND"
issuetype: "Task"
summary: "Patent portfolio review: {{technology_area}} ({{review_year}})"
description: "Total patents: {{get-metrics.patent_count}}. Pending: {{get-metrics.pending_count}}. Granted: {{get-metrics.granted_count}}. Documents found: {{get-patents.count}}."
consumes:
- type: http
namespace: sharepoint
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: search
path: "/sites/rd-innovation/drive/root/search"
operations:
- name: search-docs
method: GET
- type: http
namespace: snowflake
baseUri: "https://loreal.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://loreal.atlassian.net/rest/api/3"
authentication:
type: basic
username: "$secrets.jira_user"
password: "$secrets.jira_api_token"
resources:
- name: issues
path: "/issue"
operations:
- name: create-issue
method: POST
When inventory drops below threshold, checks SAP stock levels, identifies affected production orders, and creates a procurement request in SAP Ariba.
naftiko: "0.5"
info:
label: "Raw Material Shortage Alert Handler"
description: "When inventory drops below threshold, checks SAP stock levels, identifies affected production orders, and creates a procurement request in SAP Ariba."
tags:
- supply-chain
- procurement
- sap
- manufacturing
capability:
exposes:
- type: mcp
namespace: supply-ops
port: 8080
tools:
- name: handle-material-shortage
description: "Respond to a raw material shortage by checking stock, identifying impacted orders, and triggering a procurement request."
inputParameters:
- name: material_number
type: string
description: "SAP material number for the raw material."
- name: plant_code
type: string
description: "SAP plant code."
- name: reorder_quantity
type: number
description: "Quantity to reorder."
steps:
- name: check-stock
type: call
call: sap.get-stock
with:
material: "{{material_number}}"
plant: "{{plant_code}}"
- name: get-affected-orders
type: call
call: sap.get-dependent-orders
with:
material: "{{material_number}}"
plant: "{{plant_code}}"
- name: create-requisition
type: call
call: ariba.create-requisition
with:
material: "{{material_number}}"
quantity: "{{reorder_quantity}}"
plant: "{{plant_code}}"
justification: "Stock below threshold. Current: {{check-stock.unrestricted_qty}}. Affected orders: {{get-affected-orders.count}}."
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_MATERIAL_STOCK_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: stock
path: "/A_MatlStkInAcctMod"
operations:
- name: get-stock
method: GET
- name: orders
path: "/A_ProductionOrder"
operations:
- name: get-dependent-orders
method: GET
- type: http
namespace: ariba
baseUri: "https://openapi.ariba.com/api/procurement/v1"
authentication:
type: bearer
token: "$secrets.ariba_token"
resources:
- name: requisitions
path: "/requisitions"
operations:
- name: create-requisition
method: POST
Audits retail planogram compliance by pulling store visit data from Salesforce, checking compliance metrics in Snowflake, and creating follow-up tasks in Jira.
naftiko: "0.5"
info:
label: "Retail Planogram Compliance Audit"
description: "Audits retail planogram compliance by pulling store visit data from Salesforce, checking compliance metrics in Snowflake, and creating follow-up tasks in Jira."
tags:
- sales
- retail
- salesforce
- snowflake
- jira
capability:
exposes:
- type: mcp
namespace: retail-compliance
port: 8080
tools:
- name: audit-planogram-compliance
description: "Audit retail planogram compliance by combining store visit data with compliance metrics."
inputParameters:
- name: region
type: string
description: "Sales region."
- name: audit_week
type: string
description: "Audit week in YYYY-WW format."
steps:
- name: get-visits
type: call
call: salesforce.get-store-visits
with:
region: "{{region}}"
week: "{{audit_week}}"
- name: get-compliance
type: call
call: snowflake.execute-query
with:
warehouse: "RETAIL_ANALYTICS_WH"
query: "SELECT store_id, planogram_score, oos_count FROM planogram_compliance WHERE region='{{region}}' AND week='{{audit_week}}'"
- name: create-followups
type: call
call: jira.create-issue
with:
project_key: "RETAIL"
issuetype: "Task"
summary: "Planogram compliance follow-up: {{region}} week {{audit_week}}"
description: "Stores audited: {{get-visits.store_count}}. Average compliance: {{get-compliance.avg_score}}%. Below threshold: {{get-compliance.below_threshold_count}}."
consumes:
- type: http
namespace: salesforce
baseUri: "https://loreal.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: visits
path: "/sobjects/Store_Visit__c"
operations:
- name: get-store-visits
method: GET
- type: http
namespace: snowflake
baseUri: "https://loreal.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://loreal.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
Retrieves retail account data from Salesforce, pulls shelf compliance scores from Snowflake, and creates a follow-up task in Jira for the field sales team.
naftiko: "0.5"
info:
label: "Retail Shelf Audit Orchestrator"
description: "Retrieves retail account data from Salesforce, pulls shelf compliance scores from Snowflake, and creates a follow-up task in Jira for the field sales team."
tags:
- sales
- retail
- salesforce
- snowflake
- jira
capability:
exposes:
- type: mcp
namespace: retail-ops
port: 8080
tools:
- name: run-shelf-audit
description: "Orchestrate a retail shelf audit by pulling account data, checking compliance scores, and creating follow-up tasks."
inputParameters:
- name: account_id
type: string
description: "Salesforce retail account ID."
- name: audit_period
type: string
description: "Audit period in YYYY-MM format."
steps:
- name: get-account
type: call
call: salesforce.get-account
with:
account_id: "{{account_id}}"
- name: get-compliance
type: call
call: snowflake.execute-query
with:
warehouse: "RETAIL_ANALYTICS_WH"
query: "SELECT compliance_score, oos_rate FROM shelf_audit WHERE account_id='{{account_id}}' AND period='{{audit_period}}'"
- name: create-followup
type: call
call: jira.create-issue
with:
project_key: "RETAIL"
issuetype: "Task"
summary: "Shelf audit follow-up: {{get-account.name}} - {{audit_period}}"
description: "Compliance score: {{get-compliance.compliance_score}}%. OOS rate: {{get-compliance.oos_rate}}%."
consumes:
- type: http
namespace: salesforce
baseUri: "https://loreal.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: accounts
path: "/sobjects/Account/{{account_id}}"
inputParameters:
- name: account_id
in: path
operations:
- name: get-account
method: GET
- type: http
namespace: snowflake
baseUri: "https://loreal.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://loreal.atlassian.net/rest/api/3"
authentication:
type: basic
username: "$secrets.jira_user"
password: "$secrets.jira_api_token"
resources:
- name: issues
path: "/issue"
operations:
- name: create-issue
method: POST
When a new lead is created in Salesforce, enriches the record with company data from ZoomInfo and updates the lead score.
naftiko: "0.5"
info:
label: "Salesforce Lead Enrichment"
description: "When a new lead is created in Salesforce, enriches the record with company data from ZoomInfo and updates the lead score."
tags:
- crm
- sales
- salesforce
- zoominfo
- lead-enrichment
capability:
exposes:
- type: mcp
namespace: crm
port: 8080
tools:
- name: enrich-lead
description: "Given a Salesforce lead ID, fetch company firmographic data from ZoomInfo and write enriched fields back to the Salesforce lead record. Use when a new lead lacks company details."
inputParameters:
- name: lead_id
type: string
description: "Salesforce lead record ID (18-character Salesforce ID)."
steps:
- name: get-lead
type: call
call: salesforce.get-lead
with:
lead_id: "{{lead_id}}"
- name: enrich-company
type: call
call: zoominfo.search-company
with:
company_name: "{{get-lead.Company}}"
domain: "{{get-lead.Website}}"
- name: update-lead
type: call
call: salesforce-update.update-lead
with:
lead_id: "{{lead_id}}"
NumberOfEmployees: "{{enrich-company.employeeCount}}"
AnnualRevenue: "{{enrich-company.revenue}}"
Industry: "{{enrich-company.industry}}"
consumes:
- type: http
namespace: salesforce
baseUri: "https://loreal.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: leads
path: "/sobjects/Lead/{{lead_id}}"
inputParameters:
- name: lead_id
in: path
operations:
- name: get-lead
method: GET
- type: http
namespace: zoominfo
baseUri: "https://api.zoominfo.com/search"
authentication:
type: bearer
token: "$secrets.zoominfo_token"
resources:
- name: companies
path: "/company"
operations:
- name: search-company
method: POST
- type: http
namespace: salesforce-update
baseUri: "https://loreal.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: leads
path: "/sobjects/Lead/{{lead_id}}"
inputParameters:
- name: lead_id
in: path
operations:
- name: update-lead
method: PATCH
When a Salesforce opportunity advances to Closed Won, triggers a Workday cost center allocation update and notifies sales leadership via Teams.
naftiko: "0.5"
info:
label: "Salesforce Opportunity Stage Sync"
description: "When a Salesforce opportunity advances to Closed Won, triggers a Workday cost center allocation update and notifies sales leadership via Teams."
tags:
- crm
- sales
- salesforce
- workday
- finance
capability:
exposes:
- type: mcp
namespace: sales-ops
port: 8080
tools:
- name: sync-opportunity-close
description: "Given a Salesforce opportunity ID in Closed Won status, fetch opportunity details, update the associated Workday cost center budget, and post a win notification to the sales leadership Teams channel."
inputParameters:
- name: opportunity_id
type: string
description: "Salesforce opportunity record ID."
- name: teams_channel_id
type: string
description: "Teams channel ID for sales leadership notifications."
steps:
- name: get-opportunity
type: call
call: salesforce.get-opportunity
with:
opportunity_id: "{{opportunity_id}}"
- name: update-budget
type: call
call: workday.update-cost-center
with:
cost_center: "{{get-opportunity.CostCenter__c}}"
amount: "{{get-opportunity.Amount}}"
- name: post-win
type: call
call: msteams.post-channel-message
with:
channel_id: "{{teams_channel_id}}"
text: "New win: {{get-opportunity.Name}} — {{get-opportunity.Amount}} {{get-opportunity.CurrencyIsoCode}}"
consumes:
- type: http
namespace: salesforce
baseUri: "https://loreal.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: opportunities
path: "/sobjects/Opportunity/{{opportunity_id}}"
inputParameters:
- name: opportunity_id
in: path
operations:
- name: get-opportunity
method: GET
- type: http
namespace: workday
baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: cost-centers
path: "/loreal/costCenters/{{cost_center}}"
inputParameters:
- name: cost_center
in: path
operations:
- name: update-cost-center
method: PATCH
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/sales/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Retrieves retail account details from Salesforce including account health score, open opportunities, and last order date.
naftiko: "0.5"
info:
label: "Salesforce Retail Account Lookup"
description: "Retrieves retail account details from Salesforce including account health score, open opportunities, and last order date."
tags:
- sales
- retail
- salesforce
- crm
capability:
exposes:
- type: mcp
namespace: crm-retail
port: 8080
tools:
- name: get-retail-account
description: "Look up a retail account in Salesforce by account ID. Returns health score, open opportunity count, and last order date."
inputParameters:
- name: account_id
type: string
description: "Salesforce account ID."
call: salesforce.get-account
with:
account_id: "{{account_id}}"
outputParameters:
- name: account_name
type: string
mapping: "$.Name"
- name: health_score
type: string
mapping: "$.Health_Score__c"
- name: open_opportunities
type: string
mapping: "$.Open_Opportunity_Count__c"
- name: last_order_date
type: string
mapping: "$.Last_Order_Date__c"
consumes:
- type: http
namespace: salesforce
baseUri: "https://loreal.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: accounts
path: "/sobjects/Account/{{account_id}}"
inputParameters:
- name: account_id
in: path
operations:
- name: get-account
method: GET
Processes a salon professional order by creating a Salesforce order, triggering SAP sales order creation, and sending an order confirmation via email through Microsoft Graph.
naftiko: "0.5"
info:
label: "Salon Professional Order Processing"
description: "Processes a salon professional order by creating a Salesforce order, triggering SAP sales order creation, and sending an order confirmation via email through Microsoft Graph."
tags:
- sales
- supply-chain
- salesforce
- sap
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: salon-sales
port: 8080
tools:
- name: process-salon-order
description: "Process a salon professional order by creating CRM and ERP records and sending confirmation."
inputParameters:
- name: salon_account_id
type: string
description: "Salesforce salon account ID."
- name: product_list
type: string
description: "JSON array of products and quantities."
steps:
- name: create-sf-order
type: call
call: salesforce.create-order
with:
AccountId: "{{salon_account_id}}"
Status: "Draft"
products: "{{product_list}}"
- name: create-sap-order
type: call
call: sap.create-sales-order
with:
customer: "{{salon_account_id}}"
items: "{{product_list}}"
sf_reference: "{{create-sf-order.id}}"
- name: send-confirmation
type: call
call: msgraph.send-mail
with:
to: "{{create-sf-order.contact_email}}"
subject: "Order confirmation: {{create-sf-order.OrderNumber}}"
body: "Your order {{create-sf-order.OrderNumber}} has been placed. SAP reference: {{create-sap-order.order_number}}."
consumes:
- type: http
namespace: salesforce
baseUri: "https://loreal.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: orders
path: "/sobjects/Order"
operations:
- name: create-order
method: POST
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_SALES_ORDER_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: sales-orders
path: "/A_SalesOrder"
operations:
- name: create-sales-order
method: POST
- type: http
namespace: msgraph
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: mail
path: "/me/sendMail"
operations:
- name: send-mail
method: POST
Registers a new supplier in SAP Ariba, creates a vendor master record in SAP S/4HANA, and notifies the procurement team via Teams.
naftiko: "0.5"
info:
label: "SAP Ariba Supplier Onboarding"
description: "Registers a new supplier in SAP Ariba, creates a vendor master record in SAP S/4HANA, and notifies the procurement team via Teams."
tags:
- procurement
- sap-ariba
- sap
- supplier-management
capability:
exposes:
- type: mcp
namespace: procurement-ops
port: 8080
tools:
- name: onboard-supplier
description: "Given supplier details, register the supplier in SAP Ariba sourcing, create the corresponding vendor master in SAP S/4HANA, and notify the procurement manager via Teams."
inputParameters:
- name: supplier_name
type: string
description: "Legal name of the supplier company."
- name: supplier_country
type: string
description: "Two-letter ISO country code for the supplier."
- name: procurement_manager_upn
type: string
description: "UPN of the procurement manager for Teams notification."
steps:
- name: register-in-ariba
type: call
call: sap-ariba.create-supplier
with:
supplierName: "{{supplier_name}}"
country: "{{supplier_country}}"
- name: create-vendor-master
type: call
call: sap.create-vendor
with:
vendorName: "{{supplier_name}}"
country: "{{supplier_country}}"
aribaId: "{{register-in-ariba.supplierId}}"
- name: notify-manager
type: call
call: msteams.send-message
with:
recipient_upn: "{{procurement_manager_upn}}"
text: "Supplier {{supplier_name}} onboarded. Ariba ID: {{register-in-ariba.supplierId}}, SAP Vendor: {{create-vendor-master.vendorId}}"
consumes:
- type: http
namespace: sap-ariba
baseUri: "https://openapi.ariba.com/api/supplier/v1"
authentication:
type: bearer
token: "$secrets.ariba_token"
resources:
- name: suppliers
path: "/suppliers"
operations:
- name: create-supplier
method: POST
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_BUSINESS_PARTNER"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: vendors
path: "/A_Supplier"
operations:
- name: create-vendor
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: chats
path: "/chats"
operations:
- name: send-message
method: POST
Traces a product batch through SAP to retrieve raw material origins, production dates, and distribution records.
naftiko: "0.5"
info:
label: "SAP Batch Traceability Lookup"
description: "Traces a product batch through SAP to retrieve raw material origins, production dates, and distribution records."
tags:
- quality
- supply-chain
- sap
- traceability
capability:
exposes:
- type: mcp
namespace: erp-traceability
port: 8080
tools:
- name: trace-batch
description: "Trace a product batch in SAP to identify raw material lots, production facility, and shipment records. Use for recall investigations or quality audits."
inputParameters:
- name: batch_number
type: string
description: "SAP batch number to trace."
- name: material_number
type: string
description: "SAP material number."
call: sap.get-batch-trace
with:
batch: "{{batch_number}}"
material: "{{material_number}}"
outputParameters:
- name: production_plant
type: string
mapping: "$.d.ProductionPlant"
- name: production_date
type: string
mapping: "$.d.ManufactureDate"
- name: raw_material_lots
type: string
mapping: "$.d.ComponentBatches"
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_BATCH_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: batches
path: "/A_Batch(Material='{{material}}',Batch='{{batch}}')"
inputParameters:
- name: material
in: path
- name: batch
in: path
operations:
- name: get-batch-trace
method: GET
Retrieves the bill of materials for a finished product from SAP including component materials, quantities, and alternates.
naftiko: "0.5"
info:
label: "SAP Bill of Materials Lookup"
description: "Retrieves the bill of materials for a finished product from SAP including component materials, quantities, and alternates."
tags:
- manufacturing
- r-and-d
- sap
- erp
capability:
exposes:
- type: mcp
namespace: erp-engineering
port: 8080
tools:
- name: get-bom
description: "Retrieve bill of materials from SAP for a material number. Returns component list with quantities and item categories."
inputParameters:
- name: material_number
type: string
description: "SAP finished product material number."
- name: plant_code
type: string
description: "SAP plant code."
call: sap.get-bom
with:
material: "{{material_number}}"
plant: "{{plant_code}}"
outputParameters:
- name: bom_number
type: string
mapping: "$.d.BillOfMaterial"
- name: components
type: string
mapping: "$.d.to_BillOfMaterialItem.results"
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_BILL_OF_MATERIAL_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: bom
path: "/MaterialBOM(Material='{{material}}',Plant='{{plant}}')"
inputParameters:
- name: material
in: path
- name: plant
in: path
operations:
- name: get-bom
method: GET
Extracts budget vs. actuals data from SAP S/4HANA by cost center and publishes the variance report to Power BI and SharePoint.
naftiko: "0.5"
info:
label: "SAP Budget Variance Report"
description: "Extracts budget vs. actuals data from SAP S/4HANA by cost center and publishes the variance report to Power BI and SharePoint."
tags:
- finance
- erp
- sap
- power-bi
- reporting
capability:
exposes:
- type: mcp
namespace: finance-reporting
port: 8080
tools:
- name: publish-budget-variance
description: "Given a fiscal period and cost center, extract budget vs. actuals from SAP S/4HANA, push the data to a Power BI dataset, and upload a summary report to SharePoint."
inputParameters:
- name: fiscal_period
type: string
description: "Fiscal period in YYYYMM format (e.g., 202603)."
- name: cost_center
type: string
description: "SAP cost center code."
steps:
- name: get-variance-data
type: call
call: sap.get-cost-center-actuals
with:
fiscalPeriod: "{{fiscal_period}}"
costCenter: "{{cost_center}}"
- name: push-to-powerbi
type: call
call: powerbi.push-rows
with:
datasetId: "$secrets.powerbi_budget_dataset_id"
tableName: "BudgetVariance"
rows: "{{get-variance-data.rows}}"
- name: upload-report
type: call
call: sharepoint.upload-file
with:
site_id: "finance_reports"
folder_path: "BudgetVariance/{{fiscal_period}}"
content: "{{get-variance-data.summary}}"
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/YY1_COSTCENTERACTUALS_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: cost-center-actuals
path: "/CostCenterActuals"
inputParameters:
- name: fiscalPeriod
in: query
- name: costCenter
in: query
operations:
- name: get-cost-center-actuals
method: GET
- type: http
namespace: powerbi
baseUri: "https://api.powerbi.com/v1.0/myorg"
authentication:
type: bearer
token: "$secrets.powerbi_token"
resources:
- name: dataset-rows
path: "/datasets/{{datasetId}}/tables/{{tableName}}/rows"
inputParameters:
- name: datasetId
in: path
- name: tableName
in: path
operations:
- name: push-rows
method: POST
- type: http
namespace: sharepoint
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: files
path: "/sites/{{site_id}}/drive/items/root:/{{folder_path}}:/children"
inputParameters:
- name: site_id
in: path
- name: folder_path
in: path
operations:
- name: upload-file
method: POST
Retrieves pending expense reports from SAP Concur, validates against policy thresholds, and routes high-value reports for manager approval via Teams.
naftiko: "0.5"
info:
label: "SAP Concur Expense Report Approval"
description: "Retrieves pending expense reports from SAP Concur, validates against policy thresholds, and routes high-value reports for manager approval via Teams."
tags:
- finance
- expense-management
- sap-concur
- microsoft-teams
- approval
capability:
exposes:
- type: mcp
namespace: expense-ops
port: 8080
tools:
- name: review-pending-expenses
description: "Fetch pending expense reports from SAP Concur for a given cost center. Flag reports exceeding the policy threshold and send approval requests to the submitter's manager via Teams."
inputParameters:
- name: cost_center
type: string
description: "Cost center code to retrieve pending expenses for."
- name: threshold_eur
type: number
description: "Policy threshold in EUR above which manager approval is required."
steps:
- name: get-reports
type: call
call: concur.list-expense-reports
with:
costCenter: "{{cost_center}}"
approvalStatus: "pending"
- name: notify-manager
type: call
call: msteams.send-message
with:
recipient_upn: "{{get-reports.managerEmail}}"
text: "Expense reports pending your approval for cost center {{cost_center}}. Reports above {{threshold_eur}} EUR require your review."
consumes:
- type: http
namespace: concur
baseUri: "https://www.concursolutions.com/api/v3.0"
authentication:
type: bearer
token: "$secrets.concur_token"
resources:
- name: expense-reports
path: "/expense/reports"
inputParameters:
- name: costCenter
in: query
- name: approvalStatus
in: query
operations:
- name: list-expense-reports
method: GET
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: chats
path: "/chats"
operations:
- name: send-message
method: POST
Monitors cost center budget consumption by pulling actuals from SAP, comparing with plan data in Snowflake, and alerting budget owners via Teams when thresholds are exceeded.
naftiko: "0.5"
info:
label: "SAP Cost Center Budget Monitor"
description: "Monitors cost center budget consumption by pulling actuals from SAP, comparing with plan data in Snowflake, and alerting budget owners via Teams when thresholds are exceeded."
tags:
- finance
- operations
- sap
- snowflake
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: budget-monitoring
port: 8080
tools:
- name: monitor-budget
description: "Monitor cost center budget consumption and alert when spending exceeds thresholds."
inputParameters:
- name: cost_center
type: string
description: "SAP cost center ID."
- name: period
type: string
description: "Fiscal period in YYYY-MM format."
- name: threshold_pct
type: number
description: "Alert threshold as percentage of budget consumed."
steps:
- name: get-actuals
type: call
call: sap.get-cost-center-actuals
with:
cost_center: "{{cost_center}}"
period: "{{period}}"
- name: get-plan
type: call
call: snowflake.execute-query
with:
warehouse: "FINANCE_WH"
query: "SELECT planned_amount, consumed_pct FROM budget_plan WHERE cost_center='{{cost_center}}' AND period='{{period}}'"
- name: alert-owner
type: call
call: msteams.send-message
with:
channel_id: "finance-budget"
text: "Budget alert for {{cost_center}} ({{period}}): Actual spend {{get-actuals.total_amount}}. Plan: {{get-plan.planned_amount}}. Consumed: {{get-plan.consumed_pct}}%."
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_OPLACCTGDOCITEMCUBE_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: actuals
path: "/A_OperationalAcctgDocItemCube"
operations:
- name: get-cost-center-actuals
method: GET
- type: http
namespace: snowflake
baseUri: "https://loreal.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: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST
Processes credit memos by validating the original invoice in SAP, creating the credit memo, and updating the Salesforce account with the credit balance.
naftiko: "0.5"
info:
label: "SAP Credit Memo Processing Workflow"
description: "Processes credit memos by validating the original invoice in SAP, creating the credit memo, and updating the Salesforce account with the credit balance."
tags:
- finance
- sales
- sap
- salesforce
capability:
exposes:
- type: mcp
namespace: finance-ar
port: 8080
tools:
- name: process-credit-memo
description: "Process a credit memo by validating the original invoice, creating the credit document, and updating the customer account."
inputParameters:
- name: invoice_number
type: string
description: "Original SAP invoice number."
- name: credit_amount
type: number
description: "Credit amount to issue."
- name: reason
type: string
description: "Reason for credit memo."
steps:
- name: validate-invoice
type: call
call: sap.get-invoice
with:
invoice_number: "{{invoice_number}}"
- name: create-credit-memo
type: call
call: sap.create-credit-memo
with:
reference_invoice: "{{invoice_number}}"
amount: "{{credit_amount}}"
reason: "{{reason}}"
- name: update-sf-account
type: call
call: salesforce.update-account
with:
account_id: "{{validate-invoice.customer_id}}"
Credit_Balance__c: "{{credit_amount}}"
Last_Credit_Memo__c: "{{create-credit-memo.document_number}}"
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_BILLING_DOCUMENT_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: billing
path: "/A_BillingDocument"
operations:
- name: get-invoice
method: GET
- name: create-credit-memo
method: POST
- type: http
namespace: salesforce
baseUri: "https://loreal.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: accounts
path: "/sobjects/Account/{{account_id}}"
inputParameters:
- name: account_id
in: path
operations:
- name: update-account
method: PATCH
Analyzes customer return patterns by pulling return data from SAP, correlating with quality data in Snowflake, and creating improvement tasks in Jira.
naftiko: "0.5"
info:
label: "SAP Customer Returns Analysis"
description: "Analyzes customer return patterns by pulling return data from SAP, correlating with quality data in Snowflake, and creating improvement tasks in Jira."
tags:
- quality
- sales
- sap
- snowflake
- jira
capability:
exposes:
- type: mcp
namespace: returns-analytics
port: 8080
tools:
- name: analyze-customer-returns
description: "Analyze customer return patterns to identify quality issues and create improvement actions."
inputParameters:
- name: material_number
type: string
description: "SAP material number."
- name: period
type: string
description: "Analysis period in YYYY-QN format."
steps:
- name: get-returns
type: call
call: sap.get-return-orders
with:
material: "{{material_number}}"
period: "{{period}}"
- name: get-quality-data
type: call
call: snowflake.execute-query
with:
warehouse: "QUALITY_WH"
query: "SELECT return_reason, count, pct_of_sales FROM return_analysis WHERE material='{{material_number}}' AND period='{{period}}'"
- name: create-improvement
type: call
call: jira.create-issue
with:
project_key: "QUAL"
issuetype: "Task"
summary: "Returns analysis: {{material_number}} ({{period}})"
description: "Return count: {{get-returns.count}}. Top reason: {{get-quality-data.top_reason}}. Rate: {{get-quality-data.return_rate}}%."
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_RETURNS_DELIVERY_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: returns
path: "/A_ReturnsDeliveryHeader"
operations:
- name: get-return-orders
method: GET
- type: http
namespace: snowflake
baseUri: "https://loreal.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://loreal.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
Orchestrates the monthly financial close by running SAP period close tasks, validating balances in Snowflake, and posting completion status to the finance Teams channel.
naftiko: "0.5"
info:
label: "SAP Financial Period Close Orchestrator"
description: "Orchestrates the monthly financial close by running SAP period close tasks, validating balances in Snowflake, and posting completion status to the finance Teams channel."
tags:
- finance
- operations
- sap
- snowflake
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: finance-close
port: 8080
tools:
- name: orchestrate-period-close
description: "Orchestrate the monthly financial period close process across ERP validation, data reconciliation, and team notification."
inputParameters:
- name: period
type: string
description: "Fiscal period in YYYY-MM format."
- name: company_code
type: string
description: "SAP company code."
steps:
- name: check-open-items
type: call
call: sap.get-open-items
with:
company_code: "{{company_code}}"
period: "{{period}}"
- name: validate-balances
type: call
call: snowflake.execute-query
with:
warehouse: "FINANCE_WH"
query: "SELECT account, gl_balance, sub_ledger_balance, variance FROM balance_reconciliation WHERE company_code='{{company_code}}' AND period='{{period}}' AND variance != 0"
- name: post-status
type: call
call: msteams.send-message
with:
channel_id: "finance-close"
text: "Period close {{period}} for {{company_code}}: Open items: {{check-open-items.count}}. Balance variances: {{validate-balances.variance_count}}."
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_OPLACCTGDOCITEMCUBE_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: items
path: "/A_OperationalAcctgDocItemCube"
operations:
- name: get-open-items
method: GET
- type: http
namespace: snowflake
baseUri: "https://loreal.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: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST
Confirms goods receipt in SAP S/4HANA for a given purchase order, returning receipt status and quantity received.
naftiko: "0.5"
info:
label: "SAP Goods Receipt Confirmation"
description: "Confirms goods receipt in SAP S/4HANA for a given purchase order, returning receipt status and quantity received."
tags:
- supply-chain
- manufacturing
- sap
- erp
capability:
exposes:
- type: mcp
namespace: erp-logistics
port: 8080
tools:
- name: confirm-goods-receipt
description: "Confirm goods receipt against a purchase order in SAP. Returns receipt document number, quantity received, and posting date."
inputParameters:
- name: po_number
type: string
description: "SAP purchase order number."
- name: plant_code
type: string
description: "SAP plant code where goods are received."
call: sap.post-goods-receipt
with:
po_number: "{{po_number}}"
plant: "{{plant_code}}"
outputParameters:
- name: receipt_doc
type: string
mapping: "$.d.MaterialDocumentNumber"
- name: quantity
type: string
mapping: "$.d.QuantityReceived"
- name: posting_date
type: string
mapping: "$.d.PostingDate"
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_MATERIAL_DOCUMENT_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: material-documents
path: "/A_MaterialDocumentHeader"
operations:
- name: post-goods-receipt
method: POST
Checks hazardous material compliance for shipping by querying SAP material safety data, validating against regulations in Snowflake, and creating a ServiceNow task for non-compliance.
naftiko: "0.5"
info:
label: "SAP Hazardous Material Compliance Check"
description: "Checks hazardous material compliance for shipping by querying SAP material safety data, validating against regulations in Snowflake, and creating a ServiceNow task for non-compliance."
tags:
- quality
- regulatory
- sap
- snowflake
- servicenow
capability:
exposes:
- type: mcp
namespace: hazmat-compliance
port: 8080
tools:
- name: check-hazmat-compliance
description: "Verify hazardous material compliance for a shipment by checking safety data and regulatory requirements."
inputParameters:
- name: material_number
type: string
description: "SAP material number."
- name: destination_country
type: string
description: "Destination country code."
steps:
- name: get-safety-data
type: call
call: sap.get-material-safety
with:
material: "{{material_number}}"
- name: check-regulations
type: call
call: snowflake.execute-query
with:
warehouse: "REGULATORY_WH"
query: "SELECT regulation, compliant, required_docs FROM hazmat_regulations WHERE un_number='{{get-safety-data.un_number}}' AND country='{{destination_country}}'"
- name: create-task
type: call
call: servicenow.create-task
with:
short_description: "Hazmat compliance: {{material_number}} to {{destination_country}}"
description: "UN number: {{get-safety-data.un_number}}. Compliance status: {{check-regulations.compliant}}."
category: "regulatory"
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_PRODUCT_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: materials
path: "/A_Product('{{material}}')/to_ProductSafetyData"
inputParameters:
- name: material
in: path
operations:
- name: get-material-safety
method: GET
- type: http
namespace: snowflake
baseUri: "https://loreal.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
baseUri: "https://loreal.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: tasks
path: "/table/sc_task"
operations:
- name: create-task
method: POST
Creates an intercompany stock transfer in SAP between plants, updates the receiving plant inventory forecast in Snowflake, and notifies both plant teams via Teams.
naftiko: "0.5"
info:
label: "SAP Intercompany Transfer Order Workflow"
description: "Creates an intercompany stock transfer in SAP between plants, updates the receiving plant inventory forecast in Snowflake, and notifies both plant teams via Teams."
tags:
- supply-chain
- logistics
- sap
- snowflake
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: intercompany-logistics
port: 8080
tools:
- name: create-intercompany-transfer
description: "Create an intercompany stock transfer between plants, update forecasts, and notify plant teams."
inputParameters:
- name: material_number
type: string
description: "SAP material number."
- name: source_plant
type: string
description: "Source plant code."
- name: target_plant
type: string
description: "Target plant code."
- name: quantity
type: number
description: "Transfer quantity."
steps:
- name: create-transfer
type: call
call: sap.create-stock-transfer
with:
material: "{{material_number}}"
from_plant: "{{source_plant}}"
to_plant: "{{target_plant}}"
quantity: "{{quantity}}"
- name: update-forecast
type: call
call: snowflake.execute-query
with:
warehouse: "SUPPLY_CHAIN_WH"
query: "CALL update_plant_forecast('{{target_plant}}', '{{material_number}}', {{quantity}})"
- name: notify-plants
type: call
call: msteams.send-message
with:
channel_id: "supply-chain-ops"
text: "Intercompany transfer {{create-transfer.document_number}}: {{quantity}} units of {{material_number}} from {{source_plant}} to {{target_plant}}."
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_STOCK_TRANSFER_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: transfers
path: "/A_StockTransfer"
operations:
- name: create-stock-transfer
method: POST
- type: http
namespace: snowflake
baseUri: "https://loreal.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: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST
Creates a plant maintenance order in SAP based on a ServiceNow request, assigns technicians, and notifies the maintenance team via Teams.
naftiko: "0.5"
info:
label: "SAP Maintenance Order Creation Workflow"
description: "Creates a plant maintenance order in SAP based on a ServiceNow request, assigns technicians, and notifies the maintenance team via Teams."
tags:
- manufacturing
- operations
- sap
- servicenow
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: plant-maintenance
port: 8080
tools:
- name: create-maintenance-order
description: "Create a maintenance order from a ServiceNow request, assign resources, and notify the team."
inputParameters:
- name: snow_ticket
type: string
description: "ServiceNow request number."
- name: equipment_id
type: string
description: "SAP equipment ID."
- name: priority
type: string
description: "Maintenance priority: emergency, high, normal, low."
steps:
- name: get-request
type: call
call: servicenow.get-request
with:
number: "{{snow_ticket}}"
- name: create-order
type: call
call: sap.create-maintenance-order
with:
equipment: "{{equipment_id}}"
priority: "{{priority}}"
description: "{{get-request.short_description}}"
- name: notify-team
type: call
call: msteams.send-message
with:
channel_id: "maintenance-ops"
text: "Maintenance order {{create-order.order_number}} created for equipment {{equipment_id}}. Priority: {{priority}}. Source: {{snow_ticket}}."
consumes:
- type: http
namespace: servicenow
baseUri: "https://loreal.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: requests
path: "/table/sc_request/{{number}}"
inputParameters:
- name: number
in: path
operations:
- name: get-request
method: GET
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_MAINTENANCEORDER_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: orders
path: "/MaintenanceOrder"
operations:
- name: create-maintenance-order
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST
Checks current material stock levels in SAP for a given material and plant, returning available and unrestricted quantities.
naftiko: "0.5"
info:
label: "SAP Material Stock Level Check"
description: "Checks current material stock levels in SAP for a given material and plant, returning available and unrestricted quantities."
tags:
- supply-chain
- inventory
- sap
- erp
capability:
exposes:
- type: mcp
namespace: erp-inventory
port: 8080
tools:
- name: check-stock-level
description: "Query SAP for current stock level of a material at a specific plant. Returns unrestricted use, quality inspection, and blocked stock quantities."
inputParameters:
- name: material_number
type: string
description: "SAP material number."
- name: plant_code
type: string
description: "SAP plant code."
call: sap.get-stock
with:
material: "{{material_number}}"
plant: "{{plant_code}}"
outputParameters:
- name: unrestricted_qty
type: string
mapping: "$.d.MatlWrhsStkQtyInMatlBaseUnit"
- name: quality_inspection_qty
type: string
mapping: "$.d.QualityInspectionStockQty"
- name: blocked_qty
type: string
mapping: "$.d.BlockedStockQty"
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_MATERIAL_STOCK_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: stock
path: "/A_MatlStkInAcctMod(Material='{{material}}',Plant='{{plant}}')"
inputParameters:
- name: material
in: path
- name: plant
in: path
operations:
- name: get-stock
method: GET
Generates a plant maintenance schedule report by pulling upcoming maintenance orders from SAP, enriching with equipment history from Snowflake, and posting to Teams.
naftiko: "0.5"
info:
label: "SAP Plant Maintenance Schedule Report"
description: "Generates a plant maintenance schedule report by pulling upcoming maintenance orders from SAP, enriching with equipment history from Snowflake, and posting to Teams."
tags:
- manufacturing
- operations
- sap
- snowflake
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: maintenance-reporting
port: 8080
tools:
- name: generate-maintenance-report
description: "Generate a maintenance schedule report combining upcoming orders with equipment history."
inputParameters:
- name: plant_code
type: string
description: "SAP plant code."
- name: weeks_ahead
type: number
description: "Number of weeks to look ahead."
steps:
- name: get-schedule
type: call
call: sap.get-maintenance-orders
with:
plant: "{{plant_code}}"
horizon_weeks: "{{weeks_ahead}}"
- name: get-equipment-history
type: call
call: snowflake.execute-query
with:
warehouse: "MANUFACTURING_WH"
query: "SELECT equipment_id, mtbf_hours, last_failure_date FROM equipment_history WHERE plant='{{plant_code}}' AND equipment_id IN ({{get-schedule.equipment_ids}})"
- name: post-report
type: call
call: msteams.send-message
with:
channel_id: "maintenance-planning"
text: "Maintenance schedule for {{plant_code}} (next {{weeks_ahead}} weeks): {{get-schedule.order_count}} orders. Equipment at risk: {{get-equipment-history.at_risk_count}}."
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_MAINTENANCEORDER_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: orders
path: "/MaintenanceOrder"
operations:
- name: get-maintenance-orders
method: GET
- type: http
namespace: snowflake
baseUri: "https://loreal.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: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST
Retrieves the current status and progress of a manufacturing production order from SAP S/4HANA.
naftiko: "0.5"
info:
label: "SAP Production Order Status Lookup"
description: "Retrieves the current status and progress of a manufacturing production order from SAP S/4HANA."
tags:
- manufacturing
- production
- sap
- erp
capability:
exposes:
- type: mcp
namespace: erp-manufacturing
port: 8080
tools:
- name: get-production-order
description: "Look up a production order in SAP by order number. Returns status, planned quantity, confirmed quantity, and target completion date."
inputParameters:
- name: order_number
type: string
description: "SAP production order number."
call: sap.get-production-order
with:
order_number: "{{order_number}}"
outputParameters:
- name: status
type: string
mapping: "$.d.ManufacturingOrderStatus"
- name: planned_qty
type: string
mapping: "$.d.TotalPlannedQuantity"
- name: confirmed_qty
type: string
mapping: "$.d.TotalConfirmedYieldQuantity"
- name: target_end_date
type: string
mapping: "$.d.MfgOrderPlannedEndDate"
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_PRODUCTION_ORDER_2_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: production-orders
path: "/A_ProductionOrder('{{order_number}}')"
inputParameters:
- name: order_number
in: path
operations:
- name: get-production-order
method: GET
Optimizes production scheduling by pulling demand signals from Snowflake, checking plant capacity in SAP, and creating optimized schedule proposals in Jira.
naftiko: "0.5"
info:
label: "SAP Production Scheduling Optimizer"
description: "Optimizes production scheduling by pulling demand signals from Snowflake, checking plant capacity in SAP, and creating optimized schedule proposals in Jira."
tags:
- manufacturing
- supply-chain
- snowflake
- sap
- jira
capability:
exposes:
- type: mcp
namespace: production-planning
port: 8080
tools:
- name: optimize-production-schedule
description: "Optimize production scheduling by balancing demand signals with plant capacity constraints."
inputParameters:
- name: plant_code
type: string
description: "SAP plant code."
- name: planning_period
type: string
description: "Planning period in YYYY-WW format."
steps:
- name: get-demand
type: call
call: snowflake.execute-query
with:
warehouse: "DEMAND_PLANNING_WH"
query: "SELECT sku, required_units, priority FROM demand_signals WHERE plant='{{plant_code}}' AND week='{{planning_period}}'"
- name: get-capacity
type: call
call: sap.get-plant-capacity
with:
plant: "{{plant_code}}"
period: "{{planning_period}}"
- name: create-schedule
type: call
call: jira.create-issue
with:
project_key: "PROD"
issuetype: "Task"
summary: "Production schedule: {{plant_code}} week {{planning_period}}"
description: "Demand: {{get-demand.total_units}} units across {{get-demand.sku_count}} SKUs. Available capacity: {{get-capacity.available_hours}} hours."
consumes:
- type: http
namespace: snowflake
baseUri: "https://loreal.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: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_PRODUCTION_ORDER_2_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: capacity
path: "/A_ProductionOrderCapacity"
operations:
- name: get-plant-capacity
method: GET
- type: http
namespace: jira
baseUri: "https://loreal.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
Analyzes production yield by comparing planned vs actual output in SAP, identifying waste trends in Snowflake, and creating improvement tasks in Jira.
naftiko: "0.5"
info:
label: "SAP Production Yield Analysis"
description: "Analyzes production yield by comparing planned vs actual output in SAP, identifying waste trends in Snowflake, and creating improvement tasks in Jira."
tags:
- manufacturing
- quality
- sap
- snowflake
- jira
capability:
exposes:
- type: mcp
namespace: production-analytics
port: 8080
tools:
- name: analyze-production-yield
description: "Analyze production yield to identify waste and efficiency improvement opportunities."
inputParameters:
- name: production_line
type: string
description: "Production line identifier."
- name: plant_code
type: string
description: "SAP plant code."
- name: period
type: string
description: "Analysis period in YYYY-MM format."
steps:
- name: get-yield-data
type: call
call: sap.get-production-confirmations
with:
plant: "{{plant_code}}"
line: "{{production_line}}"
period: "{{period}}"
- name: get-waste-trends
type: call
call: snowflake.execute-query
with:
warehouse: "MANUFACTURING_WH"
query: "SELECT waste_category, waste_pct, trend FROM production_waste WHERE line='{{production_line}}' AND plant='{{plant_code}}' AND period='{{period}}'"
- name: create-improvement
type: call
call: jira.create-issue
with:
project_key: "MFG"
issuetype: "Task"
summary: "Yield improvement: {{production_line}} at {{plant_code}} ({{period}})"
description: "Yield: {{get-yield-data.yield_pct}}%. Top waste: {{get-waste-trends.top_category}} at {{get-waste-trends.top_pct}}%."
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_PRODUCTION_ORDER_2_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: confirmations
path: "/A_ProdnOrdConf2"
operations:
- name: get-production-confirmations
method: GET
- type: http
namespace: snowflake
baseUri: "https://loreal.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://loreal.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
Looks up a purchase order in SAP S/4HANA by PO number and returns header status, vendor, and total value.
naftiko: "0.5"
info:
label: "SAP Purchase Order Lookup"
description: "Looks up a purchase order in SAP S/4HANA by PO number and returns header status, vendor, and total value."
tags:
- finance
- procurement
- sap
- erp
capability:
exposes:
- type: mcp
namespace: erp
port: 8080
tools:
- name: get-purchase-order
description: "Look up an SAP purchase order by PO number. Returns header status, vendor name, total value, and currency. Use for procurement approval workflows and spend visibility."
inputParameters:
- name: po_number
type: string
description: "SAP purchase order number (10-digit numeric string)."
call: sap.get-po
with:
po_number: "{{po_number}}"
outputParameters:
- name: status
type: string
mapping: "$.d.OverallStatus"
- name: vendor
type: string
mapping: "$.d.Supplier.CompanyName"
- name: total_value
type: string
mapping: "$.d.TotalAmount"
- name: currency
type: string
mapping: "$.d.TransactionCurrency"
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-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 quality inspection lot details from SAP QM for a given batch or material to check inspection status and results.
naftiko: "0.5"
info:
label: "SAP Quality Inspection Lot Lookup"
description: "Retrieves quality inspection lot details from SAP QM for a given batch or material to check inspection status and results."
tags:
- quality
- manufacturing
- sap
- erp
capability:
exposes:
- type: mcp
namespace: erp-quality
port: 8080
tools:
- name: get-inspection-lot
description: "Look up a quality inspection lot in SAP by material number and batch. Returns inspection status, usage decision, and defect count."
inputParameters:
- name: material_number
type: string
description: "SAP material number."
- name: batch
type: string
description: "Batch number for the material."
call: sap.get-inspection-lot
with:
material: "{{material_number}}"
batch: "{{batch}}"
outputParameters:
- name: inspection_lot
type: string
mapping: "$.d.InspectionLot"
- name: status
type: string
mapping: "$.d.InspectionLotStatus"
- name: usage_decision
type: string
mapping: "$.d.UsageDecision"
- name: defect_count
type: string
mapping: "$.d.NumberOfDefects"
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_INSPECTIONLOT_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: inspection-lots
path: "/A_InspectionLot"
inputParameters:
- name: material
in: query
- name: batch
in: query
operations:
- name: get-inspection-lot
method: GET
Tracks outbound shipments by querying SAP delivery documents, checking carrier status, and updating the Salesforce order with tracking information.
naftiko: "0.5"
info:
label: "SAP Transport Shipment Tracker"
description: "Tracks outbound shipments by querying SAP delivery documents, checking carrier status, and updating the Salesforce order with tracking information."
tags:
- supply-chain
- logistics
- sap
- salesforce
capability:
exposes:
- type: mcp
namespace: logistics-tracking
port: 8080
tools:
- name: track-shipment
description: "Track an outbound shipment by pulling delivery data from SAP and updating the CRM order record."
inputParameters:
- name: delivery_number
type: string
description: "SAP outbound delivery number."
- name: sf_order_id
type: string
description: "Salesforce order ID."
steps:
- name: get-delivery
type: call
call: sap.get-delivery
with:
delivery: "{{delivery_number}}"
- name: update-order
type: call
call: salesforce.update-order
with:
order_id: "{{sf_order_id}}"
Tracking_Number__c: "{{get-delivery.tracking_number}}"
Carrier__c: "{{get-delivery.carrier}}"
Ship_Date__c: "{{get-delivery.actual_ship_date}}"
- name: notify-customer
type: call
call: salesforce.send-notification
with:
order_id: "{{sf_order_id}}"
message: "Your order has shipped via {{get-delivery.carrier}}. Tracking: {{get-delivery.tracking_number}}."
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-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://loreal.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: orders
path: "/sobjects/Order/{{order_id}}"
inputParameters:
- name: order_id
in: path
operations:
- name: update-order
method: PATCH
- name: send-notification
method: POST
Retrieves vendor master data from SAP S/4HANA including payment terms, contact details, and compliance status.
naftiko: "0.5"
info:
label: "SAP Vendor Master Lookup"
description: "Retrieves vendor master data from SAP S/4HANA including payment terms, contact details, and compliance status."
tags:
- procurement
- supply-chain
- sap
- erp
capability:
exposes:
- type: mcp
namespace: erp-procurement
port: 8080
tools:
- name: get-vendor
description: "Look up vendor master record in SAP by vendor number. Returns company name, payment terms, and purchasing organization data."
inputParameters:
- name: vendor_number
type: string
description: "SAP vendor account number."
call: sap.get-vendor
with:
vendor: "{{vendor_number}}"
outputParameters:
- name: vendor_name
type: string
mapping: "$.d.SupplierName"
- name: payment_terms
type: string
mapping: "$.d.PaymentTerms"
- name: purchasing_org
type: string
mapping: "$.d.PurchasingOrganization"
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_BUSINESS_PARTNER"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: suppliers
path: "/A_Supplier('{{vendor}}')"
inputParameters:
- name: vendor
in: path
operations:
- name: get-vendor
method: GET
Posts a warehouse transfer between storage locations in SAP, updates inventory visibility in Snowflake, and sends a confirmation to the warehouse team via Teams.
naftiko: "0.5"
info:
label: "SAP Warehouse Transfer Posting"
description: "Posts a warehouse transfer between storage locations in SAP, updates inventory visibility in Snowflake, and sends a confirmation to the warehouse team via Teams."
tags:
- supply-chain
- logistics
- sap
- snowflake
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: warehouse-ops
port: 8080
tools:
- name: post-warehouse-transfer
description: "Post a warehouse transfer between storage locations and update visibility systems."
inputParameters:
- name: material_number
type: string
description: "SAP material number."
- name: from_location
type: string
description: "Source storage location."
- name: to_location
type: string
description: "Target storage location."
- name: quantity
type: number
description: "Transfer quantity."
steps:
- name: post-transfer
type: call
call: sap.post-transfer
with:
material: "{{material_number}}"
from_sloc: "{{from_location}}"
to_sloc: "{{to_location}}"
quantity: "{{quantity}}"
- name: update-visibility
type: call
call: snowflake.execute-query
with:
warehouse: "SUPPLY_CHAIN_WH"
query: "CALL update_inventory_visibility('{{material_number}}', '{{to_location}}', {{quantity}})"
- name: confirm
type: call
call: msteams.send-message
with:
channel_id: "warehouse-ops"
text: "Transfer complete: {{quantity}} units of {{material_number}} from {{from_location}} to {{to_location}}. Doc: {{post-transfer.document_number}}."
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_MATERIAL_DOCUMENT_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: transfers
path: "/A_MaterialDocumentHeader"
operations:
- name: post-transfer
method: POST
- type: http
namespace: snowflake
baseUri: "https://loreal.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: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST
Creates a ServiceNow change request for a planned infrastructure change, routes it to the CAB approver, and notifies the requester via Teams on approval.
naftiko: "0.5"
info:
label: "ServiceNow Change Request Approval"
description: "Creates a ServiceNow change request for a planned infrastructure change, routes it to the CAB approver, and notifies the requester via Teams on approval."
tags:
- itsm
- change-management
- servicenow
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: itsm
port: 8080
tools:
- name: create-change-request
description: "Given a change description, risk level, and implementation date, create a ServiceNow change request, assign it to the CAB, and notify the requester via Teams when created."
inputParameters:
- name: short_description
type: string
description: "Brief description of the infrastructure change."
- name: risk
type: string
description: "Risk level: low, medium, or high."
- name: implementation_date
type: string
description: "Planned implementation date in YYYY-MM-DD format."
- name: requester_upn
type: string
description: "UPN of the change requester for Teams notification."
steps:
- name: create-change
type: call
call: servicenow.create-change
with:
short_description: "{{short_description}}"
risk: "{{risk}}"
start_date: "{{implementation_date}}"
assignment_group: "CAB"
- name: notify-requester
type: call
call: msteams.send-message
with:
recipient_upn: "{{requester_upn}}"
text: "Change request {{create-change.number}} created and assigned to CAB for review. Risk: {{risk}}, Date: {{implementation_date}}"
consumes:
- type: http
namespace: servicenow
baseUri: "https://loreal.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: changes
path: "/table/change_request"
operations:
- name: create-change
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: chats
path: "/chats"
operations:
- name: send-message
method: POST
Retrieves IT asset details from ServiceNow CMDB by asset tag or serial number.
naftiko: "0.5"
info:
label: "ServiceNow IT Asset Lookup"
description: "Retrieves IT asset details from ServiceNow CMDB by asset tag or serial number."
tags:
- operations
- it-asset
- servicenow
- cmdb
capability:
exposes:
- type: mcp
namespace: it-assets
port: 8080
tools:
- name: get-asset
description: "Look up an IT asset in ServiceNow CMDB by asset tag. Returns asset name, status, assigned user, and warranty expiration."
inputParameters:
- name: asset_tag
type: string
description: "ServiceNow asset tag identifier."
call: servicenow.get-asset
with:
asset_tag: "{{asset_tag}}"
outputParameters:
- name: name
type: string
mapping: "$.result.name"
- name: status
type: string
mapping: "$.result.install_status"
- name: assigned_to
type: string
mapping: "$.result.assigned_to.display_value"
- name: warranty_expiry
type: string
mapping: "$.result.warranty_expiration"
consumes:
- type: http
namespace: servicenow
baseUri: "https://loreal.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: assets
path: "/table/alm_hardware"
inputParameters:
- name: asset_tag
in: query
operations:
- name: get-asset
method: GET
Searches SharePoint for regulatory compliance documents matching a keyword and returns document titles, URLs, and last modified dates.
naftiko: "0.5"
info:
label: "SharePoint Regulatory Document Search"
description: "Searches SharePoint for regulatory compliance documents matching a keyword and returns document titles, URLs, and last modified dates."
tags:
- quality
- regulatory
- sharepoint
- documents
capability:
exposes:
- type: mcp
namespace: doc-management
port: 8080
tools:
- name: search-regulatory-docs
description: "Search SharePoint regulatory library for documents matching a keyword. Returns title, URL, and last modified date."
inputParameters:
- name: keyword
type: string
description: "Search keyword for regulatory documents."
- name: site_id
type: string
description: "SharePoint site ID for the regulatory library."
call: sharepoint.search
with:
siteId: "{{site_id}}"
queryText: "{{keyword}}"
outputParameters:
- name: results
type: string
mapping: "$.value"
consumes:
- type: http
namespace: sharepoint
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: search
path: "/sites/{{siteId}}/drive/root/search(q='{{queryText}}')"
inputParameters:
- name: siteId
in: path
- name: queryText
in: path
operations:
- name: search
method: GET
Executes a consumer analytics query in Snowflake and returns aggregated purchase behavior data for a product category.
naftiko: "0.5"
info:
label: "Snowflake Consumer Insights Query"
description: "Executes a consumer analytics query in Snowflake and returns aggregated purchase behavior data for a product category."
tags:
- analytics
- marketing
- snowflake
- data
capability:
exposes:
- type: mcp
namespace: consumer-analytics
port: 8080
tools:
- name: query-consumer-insights
description: "Query Snowflake consumer analytics warehouse for purchase frequency, basket size, and brand affinity by product category."
inputParameters:
- name: category
type: string
description: "Product category to analyze (e.g., skincare, haircare)."
- name: region
type: string
description: "Market region code."
call: snowflake.execute-query
with:
warehouse: "CONSUMER_ANALYTICS_WH"
query: "SELECT * FROM consumer_insights WHERE category='{{category}}' AND region='{{region}}'"
outputParameters:
- name: avg_basket_size
type: string
mapping: "$.data[0].avg_basket_size"
- name: purchase_frequency
type: string
mapping: "$.data[0].purchase_frequency"
- name: brand_affinity_score
type: string
mapping: "$.data[0].brand_affinity"
consumes:
- type: http
namespace: snowflake
baseUri: "https://loreal.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: execute-query
method: POST
Checks Snowflake data pipeline task status and query failure counts, then creates a Jira issue and alerts Teams if thresholds are exceeded.
naftiko: "0.5"
info:
label: "Snowflake Data Pipeline Health Check"
description: "Checks Snowflake data pipeline task status and query failure counts, then creates a Jira issue and alerts Teams if thresholds are exceeded."
tags:
- data
- analytics
- snowflake
- jira
- monitoring
capability:
exposes:
- type: mcp
namespace: data-ops
port: 8080
tools:
- name: check-pipeline-health
description: "Query Snowflake for failed tasks and long-running queries in the past N hours. If failures exceed the threshold, create a Jira issue and alert the data engineering Teams channel."
inputParameters:
- name: database
type: string
description: "Snowflake database name to check."
- name: hours_back
type: integer
description: "Number of hours to look back for failures (e.g. 4)."
- name: failure_threshold
type: integer
description: "Number of failures above which an alert is created."
steps:
- name: get-task-history
type: call
call: snowflake.query-task-history
with:
database: "{{database}}"
hoursBack: "{{hours_back}}"
- name: create-issue
type: call
call: jira.create-issue
with:
project_key: "DATA"
issuetype: "Bug"
summary: "Snowflake pipeline failures detected in {{database}}"
description: "Failed tasks in last {{hours_back}}h: {{get-task-history.failureCount}}"
- name: alert-team
type: call
call: msteams.post-channel-message
with:
channel_id: "data-engineering-alerts"
text: "Pipeline alert: {{get-task-history.failureCount}} failures in {{database}} (last {{hours_back}}h). Jira: {{create-issue.key}}"
consumes:
- type: http
namespace: snowflake
baseUri: "https://loreal.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: task-history
path: "/databases/{{database}}/schemas/information_schema/tasks"
inputParameters:
- name: database
in: path
operations:
- name: query-task-history
method: GET
- type: http
namespace: jira
baseUri: "https://loreal.atlassian.net/rest/api/3"
authentication:
type: basic
username: "$secrets.jira_user"
password: "$secrets.jira_api_token"
resources:
- name: issues
path: "/issue"
operations:
- name: create-issue
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/data/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Pulls engagement metrics from LinkedIn and Meta for L'Oréal brand accounts and posts a weekly summary to a Teams channel.
naftiko: "0.5"
info:
label: "Social Media Performance Report"
description: "Pulls engagement metrics from LinkedIn and Meta for L'Oréal brand accounts and posts a weekly summary to a Teams channel."
tags:
- marketing
- social
- linkedin
- meta
- reporting
capability:
exposes:
- type: mcp
namespace: social-reporting
port: 8080
tools:
- name: digest-social-performance
description: "Fetch weekly post engagement metrics from LinkedIn and Meta brand pages and post a combined summary to the specified Teams channel. Use for weekly brand performance reviews."
inputParameters:
- name: linkedin_org_id
type: string
description: "LinkedIn organization URN for the brand page."
- name: meta_page_id
type: string
description: "Meta (Facebook) page ID for the brand."
- name: teams_channel_id
type: string
description: "Microsoft Teams channel ID to post the report to."
steps:
- name: get-linkedin-stats
type: call
call: linkedin.get-org-stats
with:
org_id: "{{linkedin_org_id}}"
- name: get-meta-stats
type: call
call: meta.get-page-insights
with:
page_id: "{{meta_page_id}}"
- name: post-report
type: call
call: msteams.post-message
with:
channel_id: "{{teams_channel_id}}"
text: "Weekly Social Report — LinkedIn impressions: {{get-linkedin-stats.impressionCount}}, Meta reach: {{get-meta-stats.reach}}"
consumes:
- type: http
namespace: linkedin
baseUri: "https://api.linkedin.com/v2"
authentication:
type: bearer
token: "$secrets.linkedin_token"
resources:
- name: org-stats
path: "/organizationalEntityShareStatistics"
inputParameters:
- name: org_id
in: query
operations:
- name: get-org-stats
method: GET
- type: http
namespace: meta
baseUri: "https://graph.facebook.com/v18.0"
authentication:
type: bearer
token: "$secrets.meta_token"
resources:
- name: page-insights
path: "/{{page_id}}/insights"
inputParameters:
- name: page_id
in: path
operations:
- name: get-page-insights
method: GET
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/marketing/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: post-message
method: POST
Pulls supplier delivery and quality data from SAP Ariba, enriches with Snowflake analytics, and posts the scorecard summary to a Teams channel.
naftiko: "0.5"
info:
label: "Supplier Performance Scorecard Generator"
description: "Pulls supplier delivery and quality data from SAP Ariba, enriches with Snowflake analytics, and posts the scorecard summary to a Teams channel."
tags:
- procurement
- supply-chain
- sap
- snowflake
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: procurement-analytics
port: 8080
tools:
- name: generate-supplier-scorecard
description: "Generate a supplier performance scorecard by combining SAP Ariba delivery data with Snowflake quality analytics and posting results to Teams."
inputParameters:
- name: supplier_id
type: string
description: "SAP Ariba supplier ID."
- name: period
type: string
description: "Reporting period in YYYY-QN format (e.g., 2026-Q1)."
steps:
- name: get-delivery-metrics
type: call
call: ariba.get-supplier-performance
with:
supplier_id: "{{supplier_id}}"
period: "{{period}}"
- name: get-quality-metrics
type: call
call: snowflake.execute-query
with:
warehouse: "PROCUREMENT_WH"
query: "SELECT defect_rate, return_rate FROM supplier_quality WHERE supplier_id='{{supplier_id}}' AND period='{{period}}'"
- name: post-scorecard
type: call
call: msteams.send-message
with:
channel_id: "procurement-reviews"
text: "Supplier {{supplier_id}} scorecard for {{period}}: On-time delivery {{get-delivery-metrics.on_time_rate}}%, Defect rate {{get-quality-metrics.defect_rate}}%."
consumes:
- type: http
namespace: ariba
baseUri: "https://openapi.ariba.com/api/supplier-management/v1"
authentication:
type: bearer
token: "$secrets.ariba_token"
resources:
- name: performance
path: "/suppliers/{{supplier_id}}/performance"
inputParameters:
- name: supplier_id
in: path
operations:
- name: get-supplier-performance
method: GET
- type: http
namespace: snowflake
baseUri: "https://loreal.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: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST
Assesses supply chain risk by analyzing supplier concentration in Snowflake, checking SAP Ariba supplier status, and posting risk alerts to Teams.
naftiko: "0.5"
info:
label: "Supply Chain Risk Assessment Workflow"
description: "Assesses supply chain risk by analyzing supplier concentration in Snowflake, checking SAP Ariba supplier status, and posting risk alerts to Teams."
tags:
- supply-chain
- procurement
- snowflake
- sap
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: supply-risk
port: 8080
tools:
- name: assess-supply-chain-risk
description: "Assess supply chain risk by analyzing supplier concentration and geopolitical exposure."
inputParameters:
- name: material_group
type: string
description: "SAP material group to assess."
steps:
- name: get-concentration
type: call
call: snowflake.execute-query
with:
warehouse: "SUPPLY_CHAIN_WH"
query: "SELECT supplier_id, spend_share_pct, country, risk_score FROM supplier_concentration WHERE material_group='{{material_group}}' ORDER BY spend_share_pct DESC"
- name: get-supplier-status
type: call
call: ariba.get-supplier-risk
with:
material_group: "{{material_group}}"
- name: post-alert
type: call
call: msteams.send-message
with:
channel_id: "supply-chain-risk"
text: "Supply chain risk for {{material_group}}: Top supplier share {{get-concentration.top_share}}%. High-risk suppliers: {{get-supplier-status.high_risk_count}}."
consumes:
- type: http
namespace: snowflake
baseUri: "https://loreal.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: ariba
baseUri: "https://openapi.ariba.com/api/supplier-management/v1"
authentication:
type: bearer
token: "$secrets.ariba_token"
resources:
- name: risk
path: "/suppliers/risk"
operations:
- name: get-supplier-risk
method: GET
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST
Triggers a Terraform Cloud workspace run to provision or update infrastructure, then posts run status to the DevOps Teams channel and creates a Jira tracking task.
naftiko: "0.5"
info:
label: "Terraform Cloud Infrastructure Provisioning"
description: "Triggers a Terraform Cloud workspace run to provision or update infrastructure, then posts run status to the DevOps Teams channel and creates a Jira tracking task."
tags:
- cloud
- devops
- terraform
- jira
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: infra-provisioning
port: 8080
tools:
- name: trigger-terraform-run
description: "Given a Terraform Cloud workspace ID, trigger a new plan-and-apply run, create a Jira task to track the provisioning change, and post status to the DevOps Teams channel."
inputParameters:
- name: workspace_id
type: string
description: "Terraform Cloud workspace ID."
- name: message
type: string
description: "Commit message or description of the infrastructure change."
- name: teams_channel_id
type: string
description: "Teams channel ID for DevOps notifications."
steps:
- name: create-run
type: call
call: terraform.create-run
with:
workspaceId: "{{workspace_id}}"
message: "{{message}}"
- name: create-task
type: call
call: jira.create-issue
with:
project_key: "CLOUD"
issuetype: "Task"
summary: "Terraform run: {{message}}"
description: "Workspace: {{workspace_id}} | Run ID: {{create-run.runId}}"
- name: notify-team
type: call
call: msteams.post-channel-message
with:
channel_id: "{{teams_channel_id}}"
text: "Terraform run triggered: {{message}} | Workspace: {{workspace_id}} | Jira: {{create-task.key}}"
consumes:
- type: http
namespace: terraform
baseUri: "https://app.terraform.io/api/v2"
authentication:
type: bearer
token: "$secrets.terraform_token"
resources:
- name: runs
path: "/runs"
operations:
- name: create-run
method: POST
- type: http
namespace: jira
baseUri: "https://loreal.atlassian.net/rest/api/3"
authentication:
type: basic
username: "$secrets.jira_user"
password: "$secrets.jira_api_token"
resources:
- name: issues
path: "/issue"
operations:
- name: create-issue
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/devops/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Pulls trade promotion data from Salesforce, correlates with actual sales from Snowflake, and generates an effectiveness report posted to Power BI and Teams.
naftiko: "0.5"
info:
label: "Trade Promotion Effectiveness Report"
description: "Pulls trade promotion data from Salesforce, correlates with actual sales from Snowflake, and generates an effectiveness report posted to Power BI and Teams."
tags:
- sales
- marketing
- salesforce
- snowflake
- power-bi
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: trade-analytics
port: 8080
tools:
- name: generate-tpe-report
description: "Generate a trade promotion effectiveness report by combining promotion data with sales results and publishing to Power BI."
inputParameters:
- name: promotion_id
type: string
description: "Salesforce trade promotion ID."
- name: date_from
type: string
description: "Promotion start date."
- name: date_to
type: string
description: "Promotion end date."
steps:
- name: get-promotion
type: call
call: salesforce.get-promotion
with:
promotion_id: "{{promotion_id}}"
- name: get-sales-data
type: call
call: snowflake.execute-query
with:
warehouse: "SALES_ANALYTICS_WH"
query: "SELECT sum(revenue) as actual_revenue, sum(units) as actual_units FROM pos_sales WHERE promotion_id='{{promotion_id}}' AND sale_date BETWEEN '{{date_from}}' AND '{{date_to}}'"
- name: refresh-report
type: call
call: powerbi.refresh-dataset
with:
datasetId: "trade-promotion-effectiveness"
- name: notify-team
type: call
call: msteams.send-message
with:
channel_id: "trade-marketing"
text: "TPE Report ready for promotion {{promotion_id}}: Actual revenue ${{get-sales-data.actual_revenue}} vs planned ${{get-promotion.planned_revenue}}."
consumes:
- type: http
namespace: salesforce
baseUri: "https://loreal.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: promotions
path: "/sobjects/Trade_Promotion__c/{{promotion_id}}"
inputParameters:
- name: promotion_id
in: path
operations:
- name: get-promotion
method: GET
- type: http
namespace: snowflake
baseUri: "https://loreal.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: powerbi
baseUri: "https://api.powerbi.com/v1.0/myorg"
authentication:
type: bearer
token: "$secrets.powerbi_token"
resources:
- name: datasets
path: "/datasets/{{datasetId}}/refreshes"
inputParameters:
- name: datasetId
in: path
operations:
- name: refresh-dataset
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST
Performs a three-way match between SAP purchase order, goods receipt, and vendor invoice, flagging discrepancies and routing to accounts payable via ServiceNow.
naftiko: "0.5"
info:
label: "Vendor Invoice Three-Way Match"
description: "Performs a three-way match between SAP purchase order, goods receipt, and vendor invoice, flagging discrepancies and routing to accounts payable via ServiceNow."
tags:
- finance
- procurement
- sap
- servicenow
capability:
exposes:
- type: mcp
namespace: ap-automation
port: 8080
tools:
- name: three-way-match
description: "Perform a three-way match for a vendor invoice by comparing PO, goods receipt, and invoice amounts, then routing exceptions."
inputParameters:
- name: invoice_number
type: string
description: "Vendor invoice number."
- name: po_number
type: string
description: "SAP purchase order number."
steps:
- name: get-po
type: call
call: sap.get-purchase-order
with:
po_number: "{{po_number}}"
- name: get-receipt
type: call
call: sap.get-goods-receipt
with:
po_number: "{{po_number}}"
- name: get-invoice
type: call
call: sap.get-invoice
with:
invoice_number: "{{invoice_number}}"
- name: create-exception
type: call
call: servicenow.create-incident
with:
short_description: "Invoice mismatch: {{invoice_number}} vs PO {{po_number}}"
category: "accounts_payable"
description: "PO amount: {{get-po.total_value}}. Receipt qty: {{get-receipt.quantity}}. Invoice amount: {{get-invoice.amount}}."
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-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"
operations:
- name: get-purchase-order
method: GET
- name: get-goods-receipt
method: GET
- name: get-invoice
method: GET
- type: http
namespace: servicenow
baseUri: "https://loreal.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: incidents
path: "/table/incident"
operations:
- name: create-incident
method: POST
Analyzes warehouse utilization by querying SAP warehouse data, pulling demand forecasts from Snowflake, and generating a capacity report in Power BI.
naftiko: "0.5"
info:
label: "Warehouse Capacity Planning Orchestrator"
description: "Analyzes warehouse utilization by querying SAP warehouse data, pulling demand forecasts from Snowflake, and generating a capacity report in Power BI."
tags:
- supply-chain
- logistics
- sap
- snowflake
- power-bi
capability:
exposes:
- type: mcp
namespace: warehouse-planning
port: 8080
tools:
- name: plan-warehouse-capacity
description: "Analyze warehouse capacity by combining current utilization with demand forecasts and refreshing the capacity planning dashboard."
inputParameters:
- name: warehouse_id
type: string
description: "SAP warehouse number."
- name: planning_weeks
type: number
description: "Number of weeks to forecast."
steps:
- name: get-utilization
type: call
call: sap.get-warehouse-stock
with:
warehouse: "{{warehouse_id}}"
- name: get-forecast
type: call
call: snowflake.execute-query
with:
warehouse: "SUPPLY_CHAIN_WH"
query: "SELECT week, forecasted_pallets FROM warehouse_demand_forecast WHERE warehouse_id='{{warehouse_id}}' AND weeks_ahead<={{planning_weeks}}"
- name: refresh-dashboard
type: call
call: powerbi.refresh-dataset
with:
datasetId: "warehouse-capacity-planning"
consumes:
- type: http
namespace: sap
baseUri: "https://loreal-s4.sap.com/sap/opu/odata/sap/API_WAREHOUSE_STOCK_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: stock
path: "/A_WarehouseStock"
operations:
- name: get-warehouse-stock
method: GET
- type: http
namespace: snowflake
baseUri: "https://loreal.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: powerbi
baseUri: "https://api.powerbi.com/v1.0/myorg"
authentication:
type: bearer
token: "$secrets.powerbi_token"
resources:
- name: datasets
path: "/datasets/{{datasetId}}/refreshes"
inputParameters:
- name: datasetId
in: path
operations:
- name: refresh-dataset
method: POST
Pulls current compensation data for an employee from Workday including base pay, bonus eligibility, and pay grade.
naftiko: "0.5"
info:
label: "Workday Compensation Review Snapshot"
description: "Pulls current compensation data for an employee from Workday including base pay, bonus eligibility, and pay grade."
tags:
- hr
- compensation
- workday
- reporting
capability:
exposes:
- type: mcp
namespace: hr-compensation
port: 8080
tools:
- name: get-compensation-snapshot
description: "Retrieve compensation details for a Workday employee including base salary, bonus target, and pay grade."
inputParameters:
- name: employee_id
type: string
description: "Workday employee ID."
call: workday.get-compensation
with:
worker_id: "{{employee_id}}"
outputParameters:
- name: base_salary
type: string
mapping: "$.compensation.base_pay"
- name: bonus_target
type: string
mapping: "$.compensation.bonus_target_percent"
- name: pay_grade
type: string
mapping: "$.compensation.pay_grade"
consumes:
- 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: "/loreal/workers/{{worker_id}}/compensation"
inputParameters:
- name: worker_id
in: path
operations:
- name: get-compensation
method: GET
Generates workforce diversity metrics by pulling demographic data from Workday, enriching with analytics from Snowflake, and refreshing the Power BI diversity dashboard.
naftiko: "0.5"
info:
label: "Workday Diversity Metrics Report Generator"
description: "Generates workforce diversity metrics by pulling demographic data from Workday, enriching with analytics from Snowflake, and refreshing the Power BI diversity dashboard."
tags:
- hr
- analytics
- workday
- snowflake
- power-bi
capability:
exposes:
- type: mcp
namespace: hr-analytics
port: 8080
tools:
- name: generate-diversity-report
description: "Generate workforce diversity metrics combining HR data with analytics and publishing to the dashboard."
inputParameters:
- name: business_unit
type: string
description: "Business unit for the report."
- name: period
type: string
description: "Reporting period in YYYY-QN format."
steps:
- name: get-demographics
type: call
call: workday.get-demographics
with:
business_unit: "{{business_unit}}"
- name: get-analytics
type: call
call: snowflake.execute-query
with:
warehouse: "HR_ANALYTICS_WH"
query: "SELECT gender_pct, ethnicity_pct, leadership_diversity FROM diversity_metrics WHERE bu='{{business_unit}}' AND period='{{period}}'"
- name: refresh-dashboard
type: call
call: powerbi.refresh-dataset
with:
datasetId: "diversity-inclusion-dashboard"
consumes:
- type: http
namespace: workday
baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: demographics
path: "/loreal/workers/demographics"
operations:
- name: get-demographics
method: GET
- type: http
namespace: snowflake
baseUri: "https://loreal.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: powerbi
baseUri: "https://api.powerbi.com/v1.0/myorg"
authentication:
type: bearer
token: "$secrets.powerbi_token"
resources:
- name: datasets
path: "/datasets/{{datasetId}}/refreshes"
inputParameters:
- name: datasetId
in: path
operations:
- name: refresh-dataset
method: POST
Creates a new job requisition in Workday when a headcount request is approved and opens the corresponding Jira ticket for the recruiting team.
naftiko: "0.5"
info:
label: "Workday Open Position Requisition"
description: "Creates a new job requisition in Workday when a headcount request is approved and opens the corresponding Jira ticket for the recruiting team."
tags:
- hr
- recruiting
- workday
- jira
capability:
exposes:
- type: mcp
namespace: talent-acquisition
port: 8080
tools:
- name: open-job-requisition
description: "Given headcount request details, create a job requisition in Workday Recruiting and open a Jira ticket in the TA board to track sourcing progress."
inputParameters:
- name: job_title
type: string
description: "Job title for the open position."
- name: department
type: string
description: "Department requesting the headcount."
- name: hiring_manager_id
type: string
description: "Workday worker ID of the hiring manager."
steps:
- name: create-requisition
type: call
call: workday.create-job-requisition
with:
jobTitle: "{{job_title}}"
department: "{{department}}"
hiringManagerId: "{{hiring_manager_id}}"
- name: create-ta-ticket
type: call
call: jira.create-issue
with:
project_key: "TA"
issuetype: "Task"
summary: "Recruit for: {{job_title}} ({{department}})"
description: "Workday requisition: {{create-requisition.requisitionId}}"
consumes:
- type: http
namespace: workday
baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: job-requisitions
path: "/loreal/jobRequisitions"
operations:
- name: create-job-requisition
method: POST
- type: http
namespace: jira
baseUri: "https://loreal.atlassian.net/rest/api/3"
authentication:
type: basic
username: "$secrets.jira_user"
password: "$secrets.jira_api_token"
resources:
- name: issues
path: "/issue"
operations:
- name: create-issue
method: POST
When an employee changes roles in Workday, updates their Okta group assignments, adjusts Microsoft 365 license, and notifies the employee and manager via Teams.
naftiko: "0.5"
info:
label: "Workday Role Change Provisioning"
description: "When an employee changes roles in Workday, updates their Okta group assignments, adjusts Microsoft 365 license, and notifies the employee and manager via Teams."
tags:
- hr
- identity
- workday
- okta
- access-management
capability:
exposes:
- type: mcp
namespace: hr-identity
port: 8080
tools:
- name: sync-role-change
description: "Given a Workday employee ID and new role details, update Okta group memberships to reflect the new role, adjust Microsoft 365 license tier, and notify both the employee and their new manager via Teams."
inputParameters:
- name: employee_id
type: string
description: "Workday worker ID."
- name: new_role
type: string
description: "New job role or title."
- name: okta_new_group_id
type: string
description: "Okta group ID for the new role."
- name: okta_old_group_id
type: string
description: "Okta group ID of the previous role to remove."
steps:
- name: get-worker
type: call
call: workday.get-worker
with:
worker_id: "{{employee_id}}"
- name: remove-old-group
type: call
call: okta.remove-user-from-group
with:
groupId: "{{okta_old_group_id}}"
userId: "{{get-worker.work_email}}"
- name: add-new-group
type: call
call: okta.add-user-to-group
with:
groupId: "{{okta_new_group_id}}"
userId: "{{get-worker.work_email}}"
- name: notify-employee
type: call
call: msteams.send-message
with:
recipient_upn: "{{get-worker.work_email}}"
text: "Your role has been updated to {{new_role}}. System access has been adjusted accordingly."
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: "/loreal/workers/{{worker_id}}"
inputParameters:
- name: worker_id
in: path
operations:
- name: get-worker
method: GET
- type: http
namespace: okta
baseUri: "https://loreal.okta.com/api/v1"
authentication:
type: apikey
key: "Authorization"
value: "$secrets.okta_api_token"
placement: header
resources:
- name: group-members
path: "/groups/{{groupId}}/users/{{userId}}"
inputParameters:
- name: groupId
in: path
- name: userId
in: path
operations:
- name: remove-user-from-group
method: DELETE
- name: add-user-to-group
method: PUT
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: chats
path: "/chats"
operations:
- name: send-message
method: POST
Pulls YouTube channel analytics, compares with campaign targets in Salesforce, and posts a performance digest to the marketing Teams channel.
naftiko: "0.5"
info:
label: "YouTube Brand Channel Performance Digest"
description: "Pulls YouTube channel analytics, compares with campaign targets in Salesforce, and posts a performance digest to the marketing Teams channel."
tags:
- marketing
- social
- youtube
- salesforce
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: video-analytics
port: 8080
tools:
- name: generate-youtube-digest
description: "Generate a YouTube brand channel performance digest by combining analytics with campaign targets."
inputParameters:
- name: channel_id
type: string
description: "YouTube channel ID."
- name: campaign_id
type: string
description: "Salesforce campaign ID."
steps:
- name: get-channel-stats
type: call
call: youtube.get-channel-analytics
with:
channel_id: "{{channel_id}}"
- name: get-campaign-targets
type: call
call: salesforce.get-campaign
with:
campaign_id: "{{campaign_id}}"
- name: post-digest
type: call
call: msteams.send-message
with:
channel_id: "marketing-digital"
text: "YouTube digest: Views {{get-channel-stats.views}}, Subs {{get-channel-stats.subscribers}}. Target views: {{get-campaign-targets.video_target}}."
consumes:
- type: http
namespace: youtube
baseUri: "https://www.googleapis.com/youtube/v3"
authentication:
type: bearer
token: "$secrets.google_youtube_token"
resources:
- name: analytics
path: "/channels"
operations:
- name: get-channel-analytics
method: GET
- type: http
namespace: salesforce
baseUri: "https://loreal.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: campaigns
path: "/sobjects/Campaign/{{campaign_id}}"
inputParameters:
- name: campaign_id
in: path
operations:
- name: get-campaign
method: GET
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/teams/channels/messages"
operations:
- name: send-message
method: POST