Sanofi Capabilities
Naftiko 0.5 capability definitions for Sanofi - 100 capabilities showing integration workflows and service orchestrations.
When Datadog detects API rate limit breaches, creates a Jira investigation ticket, logs the event in Snowflake, and alerts the platform engineering team via Teams.
naftiko: "0.5"
info:
label: "API Gateway Rate Limit Breach Handler"
description: "When Datadog detects API rate limit breaches, creates a Jira investigation ticket, logs the event in Snowflake, and alerts the platform engineering team via Teams."
tags:
- platform-engineering
- datadog
- jira
- snowflake
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: platform-api-health
port: 8080
tools:
- name: handle-rate-limit-breach
description: "Handle API rate limit breach: create Jira ticket, log event, and alert platform team."
inputParameters:
- name: api_name
in: body
type: string
description: "The API name that breached rate limits."
- name: client_id
in: body
type: string
description: "The client ID that exceeded the limit."
steps:
- name: get-breach-details
type: call
call: "datadog.get-events"
with:
tags: "api:{{api_name}},client:{{client_id}}"
- name: create-ticket
type: call
call: "jira.create-issue"
with:
project: "PLATFORM"
summary: "API rate limit breach: {{api_name}} by {{client_id}}"
issue_type: "Task"
- name: log-event
type: call
call: "snowflake.run-query"
with:
statement: "INSERT INTO platform.rate_limit_breaches (api_name, client_id, ticket_key, detected_at) VALUES ('{{api_name}}', '{{client_id}}', '{{create-ticket.key}}', CURRENT_TIMESTAMP())"
- name: alert-platform
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.platform_team_id"
channel_id: "$secrets.platform_channel_id"
body: "Rate limit breach: {{api_name}} by client {{client_id}}. Jira: {{create-ticket.key}}."
consumes:
- type: http
namespace: datadog
baseUri: "https://api.datadoghq.com/api/v1"
authentication:
type: apiKey
key: "$secrets.datadog_api_key"
resources:
- name: events
path: "/events"
operations:
- name: get-events
method: GET
- type: http
namespace: jira
baseUri: "https://sanofi.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: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Audits Microsoft Entra conditional access policies, compares against compliance baselines in Snowflake, and creates a ServiceNow audit finding for any deviations.
naftiko: "0.5"
info:
label: "Azure AD Conditional Access Policy Audit"
description: "Audits Microsoft Entra conditional access policies, compares against compliance baselines in Snowflake, and creates a ServiceNow audit finding for any deviations."
tags:
- security
- identity
- microsoft-entra
- snowflake
- servicenow
capability:
exposes:
- type: mcp
namespace: security-identity-audit
port: 8080
tools:
- name: audit-conditional-access
description: "Audit conditional access policies: pull Entra policies, compare baselines, and log findings."
inputParameters:
- name: policy_scope
in: body
type: string
description: "The scope of policies to audit (e.g., all, gxp, corporate)."
steps:
- name: get-policies
type: call
call: "msgraph.get-ca-policies"
with:
scope: "{{policy_scope}}"
- name: get-baselines
type: call
call: "snowflake.run-query"
with:
statement: "SELECT policy_name, required_controls FROM security.ca_policy_baselines WHERE scope='{{policy_scope}}'"
- name: create-audit-finding
type: call
call: "servicenow.create-incident"
with:
short_description: "Conditional access policy audit: {{policy_scope}} scope"
category: "security_audit"
assigned_group: "Identity_Security"
consumes:
- type: http
namespace: msgraph
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: ca-policies
path: "/identity/conditionalAccess/policies"
operations:
- name: get-ca-policies
method: GET
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: servicenow
baseUri: "https://sanofi.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: incidents
path: "/table/incident"
operations:
- name: create-incident
method: POST
Retrieves month-to-date cost for a specified Azure resource group, used for cloud FinOps reporting and budget tracking.
naftiko: "0.5"
info:
label: "Azure Resource Group Cost Lookup"
description: "Retrieves month-to-date cost for a specified Azure resource group, used for cloud FinOps reporting and budget tracking."
tags:
- finops
- microsoft-azure
capability:
exposes:
- type: mcp
namespace: finops-cloud
port: 8080
tools:
- name: get-resource-group-cost
description: "Look up Azure month-to-date cost for a resource group. Returns total cost and currency."
inputParameters:
- name: resource_group
in: body
type: string
description: "The Azure resource group name."
call: "azure-cost.get-cost"
with:
resource_group: "{{resource_group}}"
outputParameters:
- name: total_cost
type: string
mapping: "$.properties.rows[0][0]"
- name: currency
type: string
mapping: "$.properties.rows[0][1]"
consumes:
- type: http
namespace: azure-cost
baseUri: "https://management.azure.com"
authentication:
type: bearer
token: "$secrets.azure_mgmt_token"
resources:
- name: cost-query
path: "/subscriptions/$secrets.azure_subscription_id/resourceGroups/{{resource_group}}/providers/Microsoft.CostManagement/query"
inputParameters:
- name: resource_group
in: path
operations:
- name: get-cost
method: POST
Checks the Azure Recovery Services vault for failed or missed VM backups and creates a ServiceNow alert for any failures found in the Sanofi production subscription.
naftiko: "0.5"
info:
label: "Azure VM Backup Verification"
description: "Checks the Azure Recovery Services vault for failed or missed VM backups and creates a ServiceNow alert for any failures found in the Sanofi production subscription."
tags:
- cloud
- azure
- servicenow
- backup
- operations
capability:
exposes:
- type: mcp
namespace: cloud-backup
port: 8080
tools:
- name: verify-vm-backups
description: "Check the Azure Recovery Services vault for failed or missed VM backup jobs in the past 24 hours and create a ServiceNow incident for each failure."
inputParameters:
- name: subscription_id
in: body
type: string
description: "The Azure subscription ID to check for backup failures."
- name: vault_name
in: body
type: string
description: "The Azure Recovery Services vault name."
- name: resource_group
in: body
type: string
description: "The Azure resource group containing the vault."
steps:
- name: get-backup-jobs
type: call
call: "azure-backup.list-backup-jobs"
with:
subscriptionId: "{{subscription_id}}"
vaultName: "{{vault_name}}"
resourceGroup: "{{resource_group}}"
- name: create-alert
type: call
call: "servicenow-backup.create-incident"
with:
short_description: "Azure VM backup failure in vault {{vault_name}}"
description: "Failed jobs: {{get-backup-jobs.failedJobs}}"
urgency: "2"
consumes:
- type: http
namespace: azure-backup
baseUri: "https://management.azure.com"
authentication:
type: bearer
token: "$secrets.azure_token"
resources:
- name: backup-jobs
path: "/subscriptions/{{subscriptionId}}/resourceGroups/{{resourceGroup}}/providers/Microsoft.RecoveryServices/vaults/{{vaultName}}/backupJobs"
inputParameters:
- name: subscriptionId
in: path
- name: resourceGroup
in: path
- name: vaultName
in: path
operations:
- name: list-backup-jobs
method: GET
- type: http
namespace: servicenow-backup
baseUri: "https://sanofi.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
Monitors data freshness for Power BI reports by checking Snowflake pipeline timestamps, verifying refresh status in Power BI, and alerting the BI team via Teams if data is stale.
naftiko: "0.5"
info:
label: "BI Report Data Freshness Monitor"
description: "Monitors data freshness for Power BI reports by checking Snowflake pipeline timestamps, verifying refresh status in Power BI, and alerting the BI team via Teams if data is stale."
tags:
- analytics
- snowflake
- power-bi
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: analytics-freshness
port: 8080
tools:
- name: monitor-data-freshness
description: "Monitor BI data freshness: check pipeline timestamps, verify refresh status, and alert on staleness."
inputParameters:
- name: dataset_id
in: body
type: string
description: "The Power BI dataset ID."
- name: pipeline_name
in: body
type: string
description: "The Snowflake pipeline name."
steps:
- name: check-pipeline
type: call
call: "snowflake.run-query"
with:
statement: "SELECT last_run_at, status FROM data_ops.pipeline_runs WHERE pipeline_name='{{pipeline_name}}' ORDER BY last_run_at DESC LIMIT 1"
- name: check-refresh
type: call
call: "powerbi.get-refresh-history"
with:
dataset_id: "{{dataset_id}}"
- name: alert-bi-team
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.bi_team_id"
channel_id: "$secrets.bi_channel_id"
body: "Data freshness check for dataset {{dataset_id}}: Pipeline {{pipeline_name}} last ran at {{check-pipeline.last_run_at}}. Power BI refresh status: {{check-refresh.status}}."
consumes:
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: powerbi
baseUri: "https://api.powerbi.com/v1.0/myorg"
authentication:
type: bearer
token: "$secrets.powerbi_token"
resources:
- name: refresh-history
path: "/datasets/{{dataset_id}}/refreshes"
inputParameters:
- name: dataset_id
in: path
operations:
- name: get-refresh-history
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
Integrates biomarker assay results by loading data into Snowflake from lab systems, updating the clinical database status in Veeva Vault, and notifying the biostatistics team via Teams.
naftiko: "0.5"
info:
label: "Clinical Biomarker Data Integration"
description: "Integrates biomarker assay results by loading data into Snowflake from lab systems, updating the clinical database status in Veeva Vault, and notifying the biostatistics team via Teams."
tags:
- clinical
- research
- snowflake
- veeva
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: clinical-biomarker
port: 8080
tools:
- name: integrate-biomarker-data
description: "Integrate biomarker data: load to Snowflake, update Veeva status, and notify biostatistics."
inputParameters:
- name: study_id
in: body
type: string
description: "The clinical study ID."
- name: assay_batch_id
in: body
type: string
description: "The assay batch identifier."
steps:
- name: load-assay-results
type: call
call: "snowflake.run-query"
with:
statement: "INSERT INTO clinical.biomarker_results (study_id, assay_batch_id, loaded_at) VALUES ('{{study_id}}', '{{assay_batch_id}}', CURRENT_TIMESTAMP())"
- name: update-vault-status
type: call
call: "veeva-vault.update-document"
with:
doc_id: "{{assay_batch_id}}"
status: "data_loaded"
- name: notify-biostats
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.biostats_team_id"
channel_id: "$secrets.biostats_channel_id"
body: "Biomarker data loaded for study {{study_id}}, batch {{assay_batch_id}}. Ready for analysis."
consumes:
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: veeva-vault
baseUri: "https://sanofi.veevavault.com/api/v24.1"
authentication:
type: bearer
token: "$secrets.veeva_vault_token"
resources:
- name: documents
path: "/objects/documents/{{doc_id}}"
inputParameters:
- name: doc_id
in: path
operations:
- name: update-document
method: PUT
- 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
Validates clinical trial data lock readiness by running quality checks in Snowflake, verifying edit checks in Veeva Vault, and generating a lock-readiness report posted to Teams.
naftiko: "0.5"
info:
label: "Clinical Data Lock Validation"
description: "Validates clinical trial data lock readiness by running quality checks in Snowflake, verifying edit checks in Veeva Vault, and generating a lock-readiness report posted to Teams."
tags:
- clinical
- data-management
- snowflake
- veeva
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: clinical-data-lock
port: 8080
tools:
- name: validate-data-lock
description: "Validate clinical data lock readiness: run quality checks, verify edit checks, and generate report."
inputParameters:
- name: trial_id
in: body
type: string
description: "The clinical trial ID."
- name: database_name
in: body
type: string
description: "The clinical database name."
steps:
- name: run-quality-checks
type: call
call: "snowflake.run-query"
with:
statement: "SELECT check_name, status, error_count FROM clinical.data_quality_checks WHERE trial_id='{{trial_id}}' AND database_name='{{database_name}}'"
- name: verify-edit-checks
type: call
call: "veeva-vault.query-documents"
with:
query: "SELECT id, status__v FROM documents WHERE trial_id__v='{{trial_id}}' AND type__v='edit_check_report'"
- name: post-report
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.clinical_dm_team_id"
channel_id: "$secrets.clinical_dm_channel_id"
body: "Data lock validation for trial {{trial_id}}, database {{database_name}}: quality checks and edit checks completed. Review results for lock readiness."
consumes:
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: veeva-vault
baseUri: "https://sanofi.veevavault.com/api/v24.1"
authentication:
type: bearer
token: "$secrets.veeva_vault_token"
resources:
- name: query
path: "/query"
operations:
- name: query-documents
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Tracks clinical trial site activation by checking Veeva Vault for regulatory documents, verifying site readiness in Snowflake, and updating the project manager via Teams.
naftiko: "0.5"
info:
label: "Clinical Site Activation Tracker"
description: "Tracks clinical trial site activation by checking Veeva Vault for regulatory documents, verifying site readiness in Snowflake, and updating the project manager via Teams."
tags:
- clinical
- veeva
- snowflake
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: clinical-site-mgmt
port: 8080
tools:
- name: check-site-activation
description: "Check site activation readiness: verify regulatory documents in Veeva, check site milestones in Snowflake, and notify the project manager."
inputParameters:
- name: site_id
in: body
type: string
description: "The clinical trial site identifier."
- name: trial_id
in: body
type: string
description: "The clinical trial ID."
steps:
- name: check-regulatory-docs
type: call
call: "veeva-vault.query-documents"
with:
query: "SELECT id, status__v FROM documents WHERE site_id__v = '{{site_id}}' AND type__v = 'regulatory_essential'"
- name: check-milestones
type: call
call: "snowflake.run-query"
with:
statement: "SELECT milestone_name, status FROM clinical.site_milestones WHERE site_id = '{{site_id}}' AND trial_id = '{{trial_id}}'"
- name: notify-pm
type: call
call: "msteams.post-message"
with:
recipient: "$secrets.clinical_pm_email"
message: "Site {{site_id}} for trial {{trial_id}}: regulatory docs checked, milestones reviewed. Ready for activation assessment."
consumes:
- type: http
namespace: veeva-vault
baseUri: "https://sanofi.veevavault.com/api/v24.1"
authentication:
type: bearer
token: "$secrets.veeva_vault_token"
resources:
- name: query
path: "/query"
operations:
- name: query-documents
method: POST
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-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: "/chats/{{chat_id}}/messages"
inputParameters:
- name: chat_id
in: path
operations:
- name: post-message
method: POST
When an adverse event is logged in Veeva Vault, creates a safety case in the pharmacovigilance system, notifies the medical safety officer via Teams, and updates the clinical trial tracker in Snowflake.
naftiko: "0.5"
info:
label: "Clinical Trial Adverse Event Reporting"
description: "When an adverse event is logged in Veeva Vault, creates a safety case in the pharmacovigilance system, notifies the medical safety officer via Teams, and updates the clinical trial tracker in Snowflake."
tags:
- clinical
- pharmacovigilance
- veeva
- microsoft-teams
- snowflake
capability:
exposes:
- type: mcp
namespace: clinical-safety
port: 8080
tools:
- name: report-adverse-event
description: "Orchestrate adverse event reporting: retrieve event details from Veeva Vault, create a safety case, notify the medical officer, and log in Snowflake."
inputParameters:
- name: event_id
in: body
type: string
description: "The Veeva Vault adverse event document ID."
- name: trial_id
in: body
type: string
description: "The clinical trial identifier."
steps:
- name: get-event
type: call
call: "veeva-vault.get-document"
with:
doc_id: "{{event_id}}"
- name: create-safety-case
type: call
call: "veeva-vault.create-document"
with:
type: "safety_case"
trial_id: "{{trial_id}}"
source_event: "{{event_id}}"
severity: "{{get-event.severity__v}}"
- name: notify-safety-officer
type: call
call: "msteams.post-message"
with:
recipient: "{{get-event.safety_officer_email}}"
message: "Adverse event {{event_id}} reported for trial {{trial_id}} with severity {{get-event.severity__v}}. Safety case {{create-safety-case.id}} created."
- name: log-to-snowflake
type: call
call: "snowflake.run-query"
with:
statement: "INSERT INTO clinical.adverse_events (event_id, trial_id, severity, case_id, reported_at) VALUES ('{{event_id}}', '{{trial_id}}', '{{get-event.severity__v}}', '{{create-safety-case.id}}', CURRENT_TIMESTAMP())"
consumes:
- type: http
namespace: veeva-vault
baseUri: "https://sanofi.veevavault.com/api/v24.1"
authentication:
type: bearer
token: "$secrets.veeva_vault_token"
resources:
- name: documents
path: "/objects/documents/{{doc_id}}"
inputParameters:
- name: doc_id
in: path
operations:
- name: get-document
method: GET
- name: create-document
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/chats/{{chat_id}}/messages"
inputParameters:
- name: chat_id
in: path
operations:
- name: post-message
method: POST
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
Queries Veeva Vault for clinical trial data completeness issues and posts a data quality digest to the clinical data management team channel in Teams.
naftiko: "0.5"
info:
label: "Clinical Trial Data Quality Check"
description: "Queries Veeva Vault for clinical trial data completeness issues and posts a data quality digest to the clinical data management team channel in Teams."
tags:
- clinical
- veeva
- microsoft-teams
- data-quality
- pharma
capability:
exposes:
- type: mcp
namespace: clinical-data-ops
port: 8080
tools:
- name: check-trial-data-quality
description: "Given a Veeva Vault study ID, retrieve data entry completeness metrics and post a quality digest to the clinical data management Teams channel."
inputParameters:
- name: study_id
in: body
type: string
description: "The Veeva Vault clinical study ID to check."
- name: cutoff_date
in: body
type: string
description: "The data cutoff date for the quality check in YYYY-MM-DD format."
steps:
- name: get-study-metrics
type: call
call: "veeva-cdm.get-study-metrics"
with:
study_id: "{{study_id}}"
cutoff: "{{cutoff_date}}"
- name: post-digest
type: call
call: "msteams-cdm.post-message"
with:
channel: "clinical-data-management"
message: "Data quality digest for study {{study_id}} (cutoff: {{cutoff_date}}): Completeness={{get-study-metrics.completeness}}%, Open queries={{get-study-metrics.openQueries}}"
consumes:
- type: http
namespace: veeva-cdm
baseUri: "https://sanofi.veevavault.com/api/v21.1"
authentication:
type: bearer
token: "$secrets.veeva_token"
resources:
- name: study-metrics
path: "/objects/studies/{{study_id}}/metrics"
inputParameters:
- name: study_id
in: path
operations:
- name: get-study-metrics
method: GET
- type: http
namespace: msteams-cdm
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-message
method: POST
Generates patient enrollment analytics by pulling data from Snowflake, refreshing the Power BI enrollment dashboard, and posting a summary to the clinical ops Teams channel.
naftiko: "0.5"
info:
label: "Clinical Trial Patient Enrollment Dashboard"
description: "Generates patient enrollment analytics by pulling data from Snowflake, refreshing the Power BI enrollment dashboard, and posting a summary to the clinical ops Teams channel."
tags:
- clinical
- analytics
- snowflake
- power-bi
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: clinical-enrollment
port: 8080
tools:
- name: refresh-enrollment-dashboard
description: "Refresh enrollment dashboard: pull Snowflake data, refresh Power BI, and post summary."
inputParameters:
- name: trial_id
in: body
type: string
description: "The clinical trial ID."
steps:
- name: get-enrollment-data
type: call
call: "snowflake.run-query"
with:
statement: "SELECT site_id, enrolled_count, target_count, enrollment_rate FROM clinical.patient_enrollment WHERE trial_id='{{trial_id}}'"
- name: refresh-powerbi
type: call
call: "powerbi.trigger-refresh"
with:
dataset_id: "$secrets.enrollment_dataset_id"
- name: post-summary
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.clinical_ops_team_id"
channel_id: "$secrets.clinical_ops_channel_id"
body: "Enrollment dashboard refreshed for trial {{trial_id}}. Check Power BI for updated site-level metrics."
consumes:
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: powerbi
baseUri: "https://api.powerbi.com/v1.0/myorg"
authentication:
type: bearer
token: "$secrets.powerbi_token"
resources:
- name: dataset-refresh
path: "/datasets/{{dataset_id}}/refreshes"
inputParameters:
- name: dataset_id
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/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
When AWS spend anomalies exceed the configured threshold, creates a ServiceNow change request to investigate and notifies the cloud FinOps team in Teams.
naftiko: "0.5"
info:
label: "Cloud Cost Anomaly Alert"
description: "When AWS spend anomalies exceed the configured threshold, creates a ServiceNow change request to investigate and notifies the cloud FinOps team in Teams."
tags:
- cloud
- finops
- aws
- servicenow
- microsoft-teams
- cost-management
capability:
exposes:
- type: mcp
namespace: cloud-finops
port: 8080
tools:
- name: handle-cost-anomaly
description: "Given an AWS account ID, service name, and anomaly amount, create a ServiceNow investigation request and alert the FinOps team in Teams."
inputParameters:
- name: account_id
in: body
type: string
description: "The AWS account ID where the cost anomaly was detected."
- name: service_name
in: body
type: string
description: "The AWS service with anomalous spend."
- name: anomaly_amount
in: body
type: number
description: "The unexpected spend amount in USD."
steps:
- name: create-change
type: call
call: "servicenow-cost.create-change"
with:
short_description: "AWS cost anomaly: ${{anomaly_amount}} on {{service_name}} in account {{account_id}}"
category: "cloud_finops"
priority: "2"
- name: notify-finops
type: call
call: "msteams-cost.post-message"
with:
channel: "cloud-cost-ops"
message: "Cost anomaly: {{service_name}} in {{account_id}} — ${{anomaly_amount}} | SNOW: {{create-change.number}}"
consumes:
- type: http
namespace: servicenow-cost
baseUri: "https://sanofi.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-cost
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-message
method: POST
Realigns sales territories by updating Veeva CRM assignments, syncing changes to Snowflake analytics, and notifying field managers via Teams.
naftiko: "0.5"
info:
label: "Commercial Field Force Territory Realignment"
description: "Realigns sales territories by updating Veeva CRM assignments, syncing changes to Snowflake analytics, and notifying field managers via Teams."
tags:
- commercial
- veeva
- snowflake
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: commercial-territory
port: 8080
tools:
- name: realign-territory
description: "Realign a sales territory: update Veeva CRM, sync to Snowflake, and notify field managers."
inputParameters:
- name: rep_id
in: body
type: string
description: "The sales representative ID."
- name: new_territory
in: body
type: string
description: "The new territory code."
steps:
- name: update-crm
type: call
call: "veeva-crm.update-territory"
with:
rep_id: "{{rep_id}}"
territory: "{{new_territory}}"
- name: sync-analytics
type: call
call: "snowflake.run-query"
with:
statement: "UPDATE commercial.territory_assignments SET territory_code='{{new_territory}}', updated_at=CURRENT_TIMESTAMP() WHERE rep_id='{{rep_id}}'"
- name: notify-manager
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.commercial_team_id"
channel_id: "$secrets.commercial_channel_id"
body: "Territory realignment: Rep {{rep_id}} reassigned to territory {{new_territory}}."
consumes:
- type: http
namespace: veeva-crm
baseUri: "https://sanofi.veevanetwork.com/api/v1"
authentication:
type: bearer
token: "$secrets.veeva_crm_token"
resources:
- name: territory-assignments
path: "/territories/{{rep_id}}"
inputParameters:
- name: rep_id
in: path
operations:
- name: update-territory
method: PUT
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Collects audit evidence by gathering control test results from ServiceNow, pulling supporting data from Snowflake, and assembling the evidence package in SharePoint.
naftiko: "0.5"
info:
label: "Compliance Audit Evidence Collector"
description: "Collects audit evidence by gathering control test results from ServiceNow, pulling supporting data from Snowflake, and assembling the evidence package in SharePoint."
tags:
- compliance
- audit
- servicenow
- snowflake
- sharepoint
capability:
exposes:
- type: mcp
namespace: compliance-audit
port: 8080
tools:
- name: collect-audit-evidence
description: "Collect audit evidence: gather control results, pull data, and assemble evidence package."
inputParameters:
- name: audit_id
in: body
type: string
description: "The audit identifier."
- name: control_id
in: body
type: string
description: "The control identifier."
steps:
- name: get-control-results
type: call
call: "servicenow.get-control-test"
with:
audit_id: "{{audit_id}}"
control_id: "{{control_id}}"
- name: get-supporting-data
type: call
call: "snowflake.run-query"
with:
statement: "SELECT evidence_type, description, collected_at FROM compliance.audit_evidence WHERE audit_id='{{audit_id}}' AND control_id='{{control_id}}'"
- name: upload-to-sharepoint
type: call
call: "sharepoint.upload-file"
with:
site_id: "$secrets.audit_site_id"
folder: "{{audit_id}}/{{control_id}}"
file_name: "evidence_package.json"
consumes:
- type: http
namespace: servicenow
baseUri: "https://sanofi.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: control-tests
path: "/table/sn_compliance_control_test"
operations:
- name: get-control-test
method: GET
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: sharepoint
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: drive-items
path: "/sites/{{site_id}}/drive/items"
inputParameters:
- name: site_id
in: path
operations:
- name: upload-file
method: PUT
Retrieves the title and body content of a Confluence page by page ID, for knowledge management and documentation queries.
naftiko: "0.5"
info:
label: "Confluence Page Content Lookup"
description: "Retrieves the title and body content of a Confluence page by page ID, for knowledge management and documentation queries."
tags:
- knowledge-management
- confluence
capability:
exposes:
- type: mcp
namespace: km-docs
port: 8080
tools:
- name: get-page-content
description: "Look up a Confluence page by ID. Returns the page title and body content."
inputParameters:
- name: page_id
in: body
type: string
description: "The Confluence page ID."
call: "confluence.get-page"
with:
page_id: "{{page_id}}"
outputParameters:
- name: title
type: string
mapping: "$.title"
- name: body
type: string
mapping: "$.body.storage.value"
consumes:
- type: http
namespace: confluence
baseUri: "https://sanofi.atlassian.net/wiki/rest/api"
authentication:
type: basic
username: "$secrets.confluence_user"
password: "$secrets.confluence_api_token"
resources:
- name: pages
path: "/content/{{page_id}}?expand=body.storage"
inputParameters:
- name: page_id
in: path
operations:
- name: get-page
method: GET
Reviews contract manufacturer quality by pulling batch data from SAP QM, checking quality KPIs in Snowflake, and creating a review report in ServiceNow.
naftiko: "0.5"
info:
label: "Contract Manufacturer Quality Review"
description: "Reviews contract manufacturer quality by pulling batch data from SAP QM, checking quality KPIs in Snowflake, and creating a review report in ServiceNow."
tags:
- quality
- manufacturing
- sap
- snowflake
- servicenow
capability:
exposes:
- type: mcp
namespace: quality-cmo-review
port: 8080
tools:
- name: review-cmo-quality
description: "Review CMO quality: pull batch data, check KPIs, and create review report."
inputParameters:
- name: vendor_id
in: body
type: string
description: "The contract manufacturer vendor ID."
- name: review_period
in: body
type: string
description: "The review period."
steps:
- name: get-batch-data
type: call
call: "sap-qm.get-vendor-lots"
with:
vendor_id: "{{vendor_id}}"
period: "{{review_period}}"
- name: get-quality-kpis
type: call
call: "snowflake.run-query"
with:
statement: "SELECT rejection_rate, deviation_count, otif_score FROM quality.cmo_kpis WHERE vendor_id='{{vendor_id}}' AND period='{{review_period}}'"
- name: create-review-report
type: call
call: "servicenow.create-incident"
with:
short_description: "CMO quality review: vendor {{vendor_id}} for {{review_period}}"
category: "quality_review"
assigned_group: "Quality_Operations"
consumes:
- type: http
namespace: sap-qm
baseUri: "https://sanofi-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"
operations:
- name: get-vendor-lots
method: GET
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: servicenow
baseUri: "https://sanofi.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
When a Databricks job fails, retrieves error logs, creates a Jira ticket for the data engineering team, and posts a failure alert to the data ops Teams channel.
naftiko: "0.5"
info:
label: "Data Pipeline Failure Recovery Orchestrator"
description: "When a Databricks job fails, retrieves error logs, creates a Jira ticket for the data engineering team, and posts a failure alert to the data ops Teams channel."
tags:
- data-engineering
- databricks
- jira
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: data-ops-recovery
port: 8080
tools:
- name: handle-pipeline-failure
description: "Handle data pipeline failure: get error logs, create Jira ticket, and alert data ops."
inputParameters:
- name: run_id
in: body
type: string
description: "The failed Databricks job run ID."
- name: job_name
in: body
type: string
description: "The Databricks job name."
steps:
- name: get-run-details
type: call
call: "databricks.get-run"
with:
run_id: "{{run_id}}"
- name: create-jira-ticket
type: call
call: "jira.create-issue"
with:
project: "DATAENG"
summary: "Pipeline failure: {{job_name}} (run {{run_id}})"
description: "State: {{get-run-details.state.result_state}}. Error: {{get-run-details.state.state_message}}"
issue_type: "Bug"
- name: alert-data-ops
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.dataops_team_id"
channel_id: "$secrets.dataops_channel_id"
body: "Pipeline {{job_name}} failed. Run ID: {{run_id}}. Jira: {{create-jira-ticket.key}}."
consumes:
- type: http
namespace: databricks
baseUri: "https://sanofi.cloud.databricks.com/api/2.1"
authentication:
type: bearer
token: "$secrets.databricks_token"
resources:
- name: job-runs
path: "/jobs/runs/get"
operations:
- name: get-run
method: GET
- type: http
namespace: jira
baseUri: "https://sanofi.atlassian.net/rest/api/3"
authentication:
type: basic
username: "$secrets.jira_user"
password: "$secrets.jira_api_token"
resources:
- name: issues
path: "/issue"
operations:
- name: create-issue
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Checks the status of a Databricks job run by run ID, returning state, start time, and duration for data pipeline monitoring.
naftiko: "0.5"
info:
label: "Databricks Job Run Status Lookup"
description: "Checks the status of a Databricks job run by run ID, returning state, start time, and duration for data pipeline monitoring."
tags:
- data-engineering
- databricks
capability:
exposes:
- type: mcp
namespace: data-pipeline
port: 8080
tools:
- name: get-job-run-status
description: "Check status of a Databricks job run by run ID. Returns state, start time, and execution duration."
inputParameters:
- name: run_id
in: body
type: string
description: "The Databricks job run ID."
call: "databricks.get-run"
with:
run_id: "{{run_id}}"
outputParameters:
- name: state
type: string
mapping: "$.state.life_cycle_state"
- name: start_time
type: string
mapping: "$.start_time"
- name: duration_ms
type: integer
mapping: "$.execution_duration"
consumes:
- type: http
namespace: databricks
baseUri: "https://sanofi.cloud.databricks.com/api/2.1"
authentication:
type: bearer
token: "$secrets.databricks_token"
resources:
- name: job-runs
path: "/jobs/runs/get"
operations:
- name: get-run
method: GET
When a Datadog critical monitor fires for Sanofi infrastructure, automatically creates a P1 ServiceNow incident and notifies the IT operations team in Teams.
naftiko: "0.5"
info:
label: "Datadog Alert to ServiceNow Incident"
description: "When a Datadog critical monitor fires for Sanofi infrastructure, automatically creates a P1 ServiceNow incident and notifies the IT operations team in Teams."
tags:
- itsm
- observability
- datadog
- servicenow
- microsoft-teams
- incident-response
capability:
exposes:
- type: mcp
namespace: itsm-alerting
port: 8080
tools:
- name: handle-datadog-alert
description: "Given a Datadog monitor ID, name, and alert body, create a P1 ServiceNow incident and notify the IT operations team in Teams."
inputParameters:
- name: monitor_id
in: body
type: string
description: "The Datadog monitor ID that fired."
- name: monitor_name
in: body
type: string
description: "The human-readable name of the Datadog monitor."
- name: alert_body
in: body
type: string
description: "The alert message body from Datadog."
steps:
- name: create-incident
type: call
call: "servicenow-dd.create-incident"
with:
short_description: "Datadog Alert: {{monitor_name}}"
description: "{{alert_body}}"
urgency: "1"
impact: "1"
- name: notify-it-ops
type: call
call: "msteams-dd.post-message"
with:
channel: "it-incidents"
message: "P1 Incident: {{monitor_name}} | SNOW: {{create-incident.number}} | Monitor: {{monitor_id}}"
consumes:
- type: http
namespace: servicenow-dd
baseUri: "https://sanofi.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-dd
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-message
method: POST
Queries Datadog for the current health status of a monitored service, returning overall state and last check timestamp.
naftiko: "0.5"
info:
label: "Datadog Service Status Check"
description: "Queries Datadog for the current health status of a monitored service, returning overall state and last check timestamp."
tags:
- observability
- datadog
capability:
exposes:
- type: mcp
namespace: observability-health
port: 8080
tools:
- name: get-service-status
description: "Check the health status of a Datadog-monitored service by service name. Returns current state and last evaluation time."
inputParameters:
- name: service_name
in: body
type: string
description: "The Datadog service name."
call: "datadog.get-monitor-status"
with:
service: "{{service_name}}"
outputParameters:
- name: status
type: string
mapping: "$.overall_state"
- name: last_check
type: string
mapping: "$.overall_state_modified"
consumes:
- type: http
namespace: datadog
baseUri: "https://api.datadoghq.com/api/v1"
authentication:
type: apiKey
key: "$secrets.datadog_api_key"
resources:
- name: monitors
path: "/monitor"
operations:
- name: get-monitor-status
method: GET
Retrieves SLO compliance burn rates from Datadog across Sanofi's digital platforms and posts a weekly digest to the engineering leadership channel in Teams.
naftiko: "0.5"
info:
label: "Datadog SLO Compliance Digest"
description: "Retrieves SLO compliance burn rates from Datadog across Sanofi's digital platforms and posts a weekly digest to the engineering leadership channel in Teams."
tags:
- observability
- datadog
- microsoft-teams
- slo
- reporting
capability:
exposes:
- type: mcp
namespace: observability-reporting
port: 8080
tools:
- name: digest-slo-compliance
description: "Retrieve active SLO compliance percentages from Datadog filtered by team tag and post a weekly digest to the Teams engineering leadership channel."
inputParameters:
- name: slo_tag
in: body
type: string
description: "A Datadog tag to filter SLOs by (e.g., team:digital-health)."
steps:
- name: get-slos
type: call
call: "datadog-slo.list-slos"
with:
tags_query: "{{slo_tag}}"
- name: post-digest
type: call
call: "msteams-slo.post-message"
with:
channel: "engineering-leadership"
message: "Weekly SLO digest for {{slo_tag}}: {{get-slos.summary}}"
consumes:
- type: http
namespace: datadog-slo
baseUri: "https://api.datadoghq.com/api/v1"
authentication:
type: apikey
key: "DD-API-KEY"
value: "$secrets.datadog_api_key"
placement: header
resources:
- name: slos
path: "/slo"
operations:
- name: list-slos
method: GET
- type: http
namespace: msteams-slo
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-message
method: POST
Syncs digital marketing campaign performance from HubSpot to Snowflake analytics, refreshes the Power BI marketing dashboard, and posts highlights to the marketing Teams channel.
naftiko: "0.5"
info:
label: "Digital Marketing Campaign Performance Sync"
description: "Syncs digital marketing campaign performance from HubSpot to Snowflake analytics, refreshes the Power BI marketing dashboard, and posts highlights to the marketing Teams channel."
tags:
- marketing
- hubspot
- snowflake
- power-bi
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: marketing-analytics
port: 8080
tools:
- name: sync-campaign-performance
description: "Sync campaign performance: pull HubSpot data, load to Snowflake, refresh dashboard, and notify marketing."
inputParameters:
- name: campaign_id
in: body
type: string
description: "The HubSpot campaign ID."
steps:
- name: get-campaign-data
type: call
call: "hubspot.get-campaign"
with:
campaign_id: "{{campaign_id}}"
- name: load-to-snowflake
type: call
call: "snowflake.run-query"
with:
statement: "INSERT INTO marketing.campaign_metrics (campaign_id, impressions, clicks, conversions, synced_at) VALUES ('{{campaign_id}}', '{{get-campaign-data.counters.impressions}}', '{{get-campaign-data.counters.clicks}}', '{{get-campaign-data.counters.conversions}}', CURRENT_TIMESTAMP())"
- name: refresh-dashboard
type: call
call: "powerbi.trigger-refresh"
with:
dataset_id: "$secrets.marketing_dataset_id"
- name: notify-marketing
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.marketing_team_id"
channel_id: "$secrets.marketing_channel_id"
body: "Campaign {{campaign_id}} metrics synced. Dashboard refreshing."
consumes:
- type: http
namespace: hubspot
baseUri: "https://api.hubapi.com"
authentication:
type: bearer
token: "$secrets.hubspot_token"
resources:
- name: campaigns
path: "/marketing/v3/campaigns/{{campaign_id}}"
inputParameters:
- name: campaign_id
in: path
operations:
- name: get-campaign
method: GET
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: powerbi
baseUri: "https://api.powerbi.com/v1.0/myorg"
authentication:
type: bearer
token: "$secrets.powerbi_token"
resources:
- name: dataset-refresh
path: "/datasets/{{dataset_id}}/refreshes"
inputParameters:
- name: dataset_id
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/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Orchestrates batch release by pulling QC results from SAP QM, checking compliance in Veeva Vault, notifying QA via Teams, and updating the batch record in Snowflake.
naftiko: "0.5"
info:
label: "Drug Product Batch Release Workflow"
description: "Orchestrates batch release by pulling QC results from SAP QM, checking compliance in Veeva Vault, notifying QA via Teams, and updating the batch record in Snowflake."
tags:
- manufacturing
- quality
- sap
- veeva
- microsoft-teams
- snowflake
capability:
exposes:
- type: mcp
namespace: mfg-batch-release
port: 8080
tools:
- name: release-batch
description: "Orchestrate drug product batch release: pull QC results, verify compliance documents, notify QA team, and update analytics."
inputParameters:
- name: batch_number
in: body
type: string
description: "The manufacturing batch number."
- name: material_number
in: body
type: string
description: "The SAP material number for the drug product."
steps:
- name: get-qc-results
type: call
call: "sap-qm.get-inspection-lot"
with:
batch: "{{batch_number}}"
material: "{{material_number}}"
- name: check-compliance-doc
type: call
call: "veeva-vault.get-document"
with:
doc_id: "{{get-qc-results.compliance_doc_id}}"
- name: notify-qa
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.qa_team_id"
channel_id: "$secrets.qa_channel_id"
body: "Batch {{batch_number}} QC complete. Status: {{get-qc-results.inspection_result}}. Compliance doc: {{check-compliance-doc.status__v}}."
- name: update-analytics
type: call
call: "snowflake.run-query"
with:
statement: "UPDATE manufacturing.batch_records SET qc_status='{{get-qc-results.inspection_result}}', released_at=CURRENT_TIMESTAMP() WHERE batch_number='{{batch_number}}'"
consumes:
- type: http
namespace: sap-qm
baseUri: "https://sanofi-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"
operations:
- name: get-inspection-lot
method: GET
- type: http
namespace: veeva-vault
baseUri: "https://sanofi.veevavault.com/api/v24.1"
authentication:
type: bearer
token: "$secrets.veeva_vault_token"
resources:
- name: documents
path: "/objects/documents/{{doc_id}}"
inputParameters:
- name: doc_id
in: path
operations:
- name: get-document
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
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
Generates periodic safety update reports by pulling aggregate data from Snowflake, creating the report document in Veeva Vault, and notifying the drug safety team via Teams.
naftiko: "0.5"
info:
label: "Drug Safety Periodic Report Generation"
description: "Generates periodic safety update reports by pulling aggregate data from Snowflake, creating the report document in Veeva Vault, and notifying the drug safety team via Teams."
tags:
- pharmacovigilance
- snowflake
- veeva
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: pv-periodic-report
port: 8080
tools:
- name: generate-safety-report
description: "Generate periodic safety report: aggregate data, create Veeva document, and notify safety team."
inputParameters:
- name: product_name
in: body
type: string
description: "The drug product name."
- name: report_period
in: body
type: string
description: "The reporting period (e.g., 2026-Q1)."
steps:
- name: aggregate-safety-data
type: call
call: "snowflake.run-query"
with:
statement: "SELECT event_type, COUNT(*) as event_count, severity FROM pv.adverse_events WHERE product_name='{{product_name}}' AND report_period='{{report_period}}' GROUP BY event_type, severity"
- name: create-report-doc
type: call
call: "veeva-vault.create-document"
with:
type: "periodic_safety_report"
product: "{{product_name}}"
period: "{{report_period}}"
- name: notify-safety-team
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.pv_team_id"
channel_id: "$secrets.pv_channel_id"
body: "Periodic safety report for {{product_name}} ({{report_period}}) generated. Document ID: {{create-report-doc.id}}."
consumes:
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: veeva-vault
baseUri: "https://sanofi.veevavault.com/api/v24.1"
authentication:
type: bearer
token: "$secrets.veeva_vault_token"
resources:
- name: documents
path: "/objects/documents"
operations:
- name: create-document
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
When an employee departure is recorded in Workday, disables the Microsoft 365 account, revokes SAP access, and notifies the IT security team in Teams.
naftiko: "0.5"
info:
label: "Employee Offboarding Workflow"
description: "When an employee departure is recorded in Workday, disables the Microsoft 365 account, revokes SAP access, and notifies the IT security team in Teams."
tags:
- hr
- offboarding
- workday
- microsoft-365
- sap
- microsoft-teams
- identity
capability:
exposes:
- type: mcp
namespace: hr-offboarding
port: 8080
tools:
- name: trigger-offboarding
description: "Given a Workday employee ID and termination date, disable the Microsoft 365 account, lock SAP credentials, and alert the IT security team in Teams."
inputParameters:
- name: employee_id
in: body
type: string
description: "The Workday worker ID of the departing employee."
- name: termination_date
in: body
type: string
description: "The employee's last working day in YYYY-MM-DD format."
steps:
- name: get-employee
type: call
call: "workday-off.get-worker"
with:
worker_id: "{{employee_id}}"
- name: disable-m365
type: call
call: "msgraph-off.disable-user"
with:
userPrincipalName: "{{get-employee.workEmail}}"
- name: lock-sap-user
type: call
call: "sap-off.lock-user"
with:
userId: "{{get-employee.sapUserId}}"
- name: notify-security
type: call
call: "msteams-off.post-message"
with:
channel: "it-security-alerts"
message: "Offboarding complete for {{get-employee.displayName}} ({{termination_date}}). M365 disabled, SAP locked."
consumes:
- type: http
namespace: workday-off
baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: workers
path: "/sanofi/workers/{{worker_id}}"
inputParameters:
- name: worker_id
in: path
operations:
- name: get-worker
method: GET
- type: http
namespace: msgraph-off
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: users
path: "/users/{{userPrincipalName}}"
inputParameters:
- name: userPrincipalName
in: path
operations:
- name: disable-user
method: PATCH
- type: http
namespace: sap-off
baseUri: "https://sanofi-s4.sap.com/sap/opu/odata/sap/API_USERACCOUNT_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: user-accounts
path: "/A_UserAccount('{{userId}}')"
inputParameters:
- name: userId
in: path
operations:
- name: lock-user
method: POST
- type: http
namespace: msteams-off
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-message
method: POST
When an employee transfers departments in Workday, updates their cost center in SAP, reassigns ServiceNow groups, and notifies both old and new managers via Teams.
naftiko: "0.5"
info:
label: "Employee Transfer Cross-System Update"
description: "When an employee transfers departments in Workday, updates their cost center in SAP, reassigns ServiceNow groups, and notifies both old and new managers via Teams."
tags:
- hr
- workday
- sap
- servicenow
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: hr-transfer
port: 8080
tools:
- name: process-transfer
description: "Process employee department transfer: update SAP cost center, reassign ServiceNow groups, and notify managers."
inputParameters:
- name: worker_id
in: body
type: string
description: "The Workday worker ID."
- name: new_department
in: body
type: string
description: "The new department name."
- name: new_cost_center
in: body
type: string
description: "The new SAP cost center."
steps:
- name: get-employee
type: call
call: "workday.get-worker"
with:
worker_id: "{{worker_id}}"
- name: update-cost-center
type: call
call: "sap-hr.update-cost-center"
with:
employee_id: "{{get-employee.sapEmployeeId}}"
cost_center: "{{new_cost_center}}"
- name: update-servicenow-group
type: call
call: "servicenow.update-user"
with:
user_name: "{{get-employee.workEmail}}"
department: "{{new_department}}"
- name: notify-managers
type: call
call: "msteams.post-message"
with:
recipient: "{{get-employee.manager.email}}"
message: "{{get-employee.displayName}} has transferred to {{new_department}}. SAP cost center updated to {{new_cost_center}}."
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: "/sanofi/workers/{{worker_id}}"
inputParameters:
- name: worker_id
in: path
operations:
- name: get-worker
method: GET
- type: http
namespace: sap-hr
baseUri: "https://sanofi-s4.sap.com/sap/opu/odata/sap/API_BUSINESS_PARTNER"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: employees
path: "/A_BusinessPartner"
operations:
- name: update-cost-center
method: PATCH
- type: http
namespace: servicenow
baseUri: "https://sanofi.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: users
path: "/table/sys_user"
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: messages
path: "/chats/{{chat_id}}/messages"
inputParameters:
- name: chat_id
in: path
operations:
- name: post-message
method: POST
Reviews enterprise software license utilization by pulling usage data from Microsoft Entra, comparing against entitlements in Snowflake, and creating optimization recommendations in ServiceNow.
naftiko: "0.5"
info:
label: "Enterprise License Optimization Review"
description: "Reviews enterprise software license utilization by pulling usage data from Microsoft Entra, comparing against entitlements in Snowflake, and creating optimization recommendations in ServiceNow."
tags:
- finops
- identity
- microsoft-entra
- snowflake
- servicenow
capability:
exposes:
- type: mcp
namespace: finops-license
port: 8080
tools:
- name: review-license-utilization
description: "Review license utilization: pull usage data, compare entitlements, and create optimization tickets."
inputParameters:
- name: application_name
in: body
type: string
description: "The enterprise application name."
steps:
- name: get-usage-data
type: call
call: "msgraph.get-app-usage"
with:
app_name: "{{application_name}}"
- name: compare-entitlements
type: call
call: "snowflake.run-query"
with:
statement: "SELECT licensed_count, active_users, utilization_pct FROM finops.license_entitlements WHERE application_name='{{application_name}}'"
- name: create-optimization-ticket
type: call
call: "servicenow.create-incident"
with:
short_description: "License optimization: {{application_name}}"
category: "finops_license"
assigned_group: "IT_Asset_Management"
consumes:
- type: http
namespace: msgraph
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: app-usage
path: "/reports/getOffice365ActiveUserDetail"
operations:
- name: get-app-usage
method: GET
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: servicenow
baseUri: "https://sanofi.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
Handles EHS incidents by creating a record in ServiceNow, logging details in Snowflake for trend analysis, and alerting the EHS team via Teams.
naftiko: "0.5"
info:
label: "Environmental Health Safety Incident Handler"
description: "Handles EHS incidents by creating a record in ServiceNow, logging details in Snowflake for trend analysis, and alerting the EHS team via Teams."
tags:
- ehs
- servicenow
- snowflake
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: ehs-incident
port: 8080
tools:
- name: handle-ehs-incident
description: "Handle EHS incident: create ServiceNow record, log to Snowflake, and alert EHS team."
inputParameters:
- name: incident_type
in: body
type: string
description: "Type of EHS incident."
- name: location
in: body
type: string
description: "Facility location."
- name: description
in: body
type: string
description: "Incident description."
steps:
- name: create-ehs-record
type: call
call: "servicenow.create-incident"
with:
short_description: "EHS incident: {{incident_type}} at {{location}}"
category: "ehs"
description: "{{description}}"
- name: log-to-analytics
type: call
call: "snowflake.run-query"
with:
statement: "INSERT INTO ehs.incidents (type, location, description, ticket_number, reported_at) VALUES ('{{incident_type}}', '{{location}}', '{{description}}', '{{create-ehs-record.number}}', CURRENT_TIMESTAMP())"
- name: alert-ehs-team
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.ehs_team_id"
channel_id: "$secrets.ehs_channel_id"
body: "EHS incident reported at {{location}}: {{incident_type}}. Ticket: {{create-ehs-record.number}}."
consumes:
- type: http
namespace: servicenow
baseUri: "https://sanofi.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: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Automates period-end close by pulling trial balance from SAP, comparing against Snowflake analytics, and posting the reconciliation summary to the finance Teams channel.
naftiko: "0.5"
info:
label: "Financial Period Close Reconciliation"
description: "Automates period-end close by pulling trial balance from SAP, comparing against Snowflake analytics, and posting the reconciliation summary to the finance Teams channel."
tags:
- finance
- sap
- snowflake
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: finance-close
port: 8080
tools:
- name: reconcile-period-close
description: "Reconcile financial period close: pull SAP trial balance, compare with Snowflake, and notify finance."
inputParameters:
- name: fiscal_period
in: body
type: string
description: "The fiscal period (e.g., 2026-03)."
- name: company_code
in: body
type: string
description: "The SAP company code."
steps:
- name: get-trial-balance
type: call
call: "sap-fi.get-trial-balance"
with:
period: "{{fiscal_period}}"
company_code: "{{company_code}}"
- name: get-analytics-totals
type: call
call: "snowflake.run-query"
with:
statement: "SELECT account_group, SUM(amount) as total FROM finance.gl_entries WHERE period = '{{fiscal_period}}' GROUP BY account_group"
- name: post-reconciliation
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.finance_team_id"
channel_id: "$secrets.finance_channel_id"
body: "Period {{fiscal_period}} reconciliation complete for company code {{company_code}}. SAP trial balance and Snowflake analytics compared."
consumes:
- type: http
namespace: sap-fi
baseUri: "https://sanofi-s4.sap.com/sap/opu/odata/sap/API_JOURNALENTRYITEMBASIC_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: journal-entries
path: "/A_JournalEntryItemBasic"
operations:
- name: get-trial-balance
method: GET
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
When a GitHub release is published, creates a ServiceNow change record with release notes, links the CI, and notifies the release management channel in Teams.
naftiko: "0.5"
info:
label: "GitHub Release to ServiceNow Change Record"
description: "When a GitHub release is published, creates a ServiceNow change record with release notes, links the CI, and notifies the release management channel in Teams."
tags:
- devops
- github
- servicenow
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: devops-release
port: 8080
tools:
- name: process-release
description: "Process a GitHub release: create ServiceNow change record and notify release management."
inputParameters:
- name: repo_name
in: body
type: string
description: "The GitHub repository (org/repo)."
- name: release_tag
in: body
type: string
description: "The release tag name."
steps:
- name: get-release
type: call
call: "github.get-release"
with:
repo: "{{repo_name}}"
tag: "{{release_tag}}"
- name: create-change-record
type: call
call: "servicenow.create-change"
with:
short_description: "Release {{release_tag}} for {{repo_name}}"
description: "{{get-release.body}}"
category: "software_release"
- name: notify-release-mgmt
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.release_team_id"
channel_id: "$secrets.release_channel_id"
body: "Release {{release_tag}} for {{repo_name}} published. Change record: {{create-change-record.number}}."
consumes:
- type: http
namespace: github
baseUri: "https://api.github.com"
authentication:
type: bearer
token: "$secrets.github_token"
resources:
- name: releases
path: "/repos/{{repo}}/releases/tags/{{tag}}"
inputParameters:
- name: repo
in: path
- name: tag
in: path
operations:
- name: get-release
method: GET
- type: http
namespace: servicenow
baseUri: "https://sanofi.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: change-requests
path: "/table/change_request"
operations:
- name: create-change
method: POST
- type: http
namespace: msteams
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
Checks whether branch protection rules are enabled on the main branch of a GitHub repository, returning required reviews and status checks.
naftiko: "0.5"
info:
label: "GitHub Repository Branch Protection Check"
description: "Checks whether branch protection rules are enabled on the main branch of a GitHub repository, returning required reviews and status checks."
tags:
- devops
- github
capability:
exposes:
- type: mcp
namespace: devops-compliance
port: 8080
tools:
- name: check-branch-protection
description: "Check branch protection settings for the main branch of a GitHub repo. Returns required reviewers and status check enforcement."
inputParameters:
- name: repo_name
in: body
type: string
description: "The GitHub repository name (org/repo)."
call: "github.get-branch-protection"
with:
repo: "{{repo_name}}"
outputParameters:
- name: required_reviews
type: integer
mapping: "$.required_pull_request_reviews.required_approving_review_count"
- name: enforce_status_checks
type: boolean
mapping: "$.required_status_checks.strict"
consumes:
- type: http
namespace: github
baseUri: "https://api.github.com"
authentication:
type: bearer
token: "$secrets.github_token"
resources:
- name: branch-protection
path: "/repos/{{repo}}/branches/main/protection"
inputParameters:
- name: repo
in: path
operations:
- name: get-branch-protection
method: GET
Performs periodic GxP system access reviews by pulling user lists from Microsoft Entra, cross-referencing with Workday active employees, and creating ServiceNow tasks for orphaned accounts.
naftiko: "0.5"
info:
label: "GxP System Access Review Workflow"
description: "Performs periodic GxP system access reviews by pulling user lists from Microsoft Entra, cross-referencing with Workday active employees, and creating ServiceNow tasks for orphaned accounts."
tags:
- compliance
- gxp
- microsoft-entra
- workday
- servicenow
capability:
exposes:
- type: mcp
namespace: compliance-access-review
port: 8080
tools:
- name: review-gxp-access
description: "Review GxP system access: pull Entra users, validate against Workday, and create tasks for orphaned accounts."
inputParameters:
- name: application_id
in: body
type: string
description: "The Microsoft Entra application ID for the GxP system."
steps:
- name: get-app-users
type: call
call: "msgraph.get-app-users"
with:
app_id: "{{application_id}}"
- name: validate-employees
type: call
call: "workday.get-active-workers"
with:
department: "all"
- name: create-review-task
type: call
call: "servicenow.create-incident"
with:
short_description: "GxP access review: orphaned accounts found for app {{application_id}}"
category: "compliance_review"
assigned_group: "GxP_Compliance"
consumes:
- type: http
namespace: msgraph
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: app-role-assignments
path: "/servicePrincipals/{{app_id}}/appRoleAssignedTo"
inputParameters:
- name: app_id
in: path
operations:
- name: get-app-users
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: "/sanofi/workers"
operations:
- name: get-active-workers
method: GET
- type: http
namespace: servicenow
baseUri: "https://sanofi.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
Validates healthcare professional engagements by checking Veeva CRM interaction records, verifying compliance limits in Snowflake, and logging the audit trail in ServiceNow.
naftiko: "0.5"
info:
label: "HCP Engagement Compliance Orchestrator"
description: "Validates healthcare professional engagements by checking Veeva CRM interaction records, verifying compliance limits in Snowflake, and logging the audit trail in ServiceNow."
tags:
- compliance
- commercial
- veeva
- snowflake
- servicenow
capability:
exposes:
- type: mcp
namespace: compliance-hcp
port: 8080
tools:
- name: validate-hcp-engagement
description: "Validate HCP engagement compliance: check CRM records, verify spend limits, and log audit trail."
inputParameters:
- name: hcp_id
in: body
type: string
description: "The healthcare professional ID."
- name: engagement_type
in: body
type: string
description: "Type of engagement (e.g., advisory_board, speaker_program)."
steps:
- name: get-interactions
type: call
call: "veeva-crm.get-interactions"
with:
hcp_id: "{{hcp_id}}"
type: "{{engagement_type}}"
- name: check-spend-limits
type: call
call: "snowflake.run-query"
with:
statement: "SELECT SUM(amount) as total_spend, max_annual_limit FROM compliance.hcp_spend_tracking WHERE hcp_id='{{hcp_id}}' AND year=YEAR(CURRENT_DATE()) GROUP BY max_annual_limit"
- name: log-audit
type: call
call: "servicenow.create-incident"
with:
short_description: "HCP engagement compliance check: {{hcp_id}} - {{engagement_type}}"
category: "compliance_audit"
assigned_group: "Compliance_Team"
consumes:
- type: http
namespace: veeva-crm
baseUri: "https://sanofi.veevanetwork.com/api/v1"
authentication:
type: bearer
token: "$secrets.veeva_crm_token"
resources:
- name: interactions
path: "/interactions"
operations:
- name: get-interactions
method: GET
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: servicenow
baseUri: "https://sanofi.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
Plans infrastructure capacity by pulling Datadog metrics, comparing against thresholds in Snowflake, and creating ServiceNow capacity requests for over-utilized resources.
naftiko: "0.5"
info:
label: "IT Infrastructure Capacity Planning"
description: "Plans infrastructure capacity by pulling Datadog metrics, comparing against thresholds in Snowflake, and creating ServiceNow capacity requests for over-utilized resources."
tags:
- infrastructure
- datadog
- snowflake
- servicenow
capability:
exposes:
- type: mcp
namespace: infra-capacity
port: 8080
tools:
- name: plan-capacity
description: "Plan infrastructure capacity: pull metrics, compare thresholds, and create capacity requests."
inputParameters:
- name: service_name
in: body
type: string
description: "The service name to evaluate."
steps:
- name: get-metrics
type: call
call: "datadog.get-metrics"
with:
service: "{{service_name}}"
metric: "system.cpu.user"
- name: check-thresholds
type: call
call: "snowflake.run-query"
with:
statement: "SELECT cpu_threshold, memory_threshold FROM infrastructure.capacity_thresholds WHERE service_name='{{service_name}}'"
- name: create-capacity-request
type: call
call: "servicenow.create-incident"
with:
short_description: "Capacity planning: {{service_name}} approaching resource limits"
category: "infrastructure_capacity"
assigned_group: "Cloud_Infrastructure"
consumes:
- type: http
namespace: datadog
baseUri: "https://api.datadoghq.com/api/v1"
authentication:
type: apiKey
key: "$secrets.datadog_api_key"
resources:
- name: metrics
path: "/query"
operations:
- name: get-metrics
method: GET
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: servicenow
baseUri: "https://sanofi.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
When a critical vulnerability is detected, creates a ServiceNow security incident, assigns it to the responsible team based on CMDB ownership, and alerts the security channel in Teams.
naftiko: "0.5"
info:
label: "IT Security Vulnerability Remediation"
description: "When a critical vulnerability is detected, creates a ServiceNow security incident, assigns it to the responsible team based on CMDB ownership, and alerts the security channel in Teams."
tags:
- security
- servicenow
- microsoft-teams
- datadog
capability:
exposes:
- type: mcp
namespace: security-vuln
port: 8080
tools:
- name: remediate-vulnerability
description: "Orchestrate vulnerability remediation: look up asset owner in CMDB, create security incident, and alert the security team."
inputParameters:
- name: cve_id
in: body
type: string
description: "The CVE identifier."
- name: asset_tag
in: body
type: string
description: "The affected asset tag."
steps:
- name: get-asset-owner
type: call
call: "servicenow.get-ci"
with:
sysparm_query: "asset_tag={{asset_tag}}"
- name: create-security-incident
type: call
call: "servicenow.create-incident"
with:
short_description: "Critical vulnerability {{cve_id}} on {{asset_tag}}"
category: "security"
assigned_group: "{{get-asset-owner.support_group}}"
priority: "1"
- name: alert-security-channel
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.security_team_id"
channel_id: "$secrets.security_channel_id"
body: "CRITICAL: {{cve_id}} detected on {{asset_tag}}. Incident {{create-security-incident.number}} created and assigned to {{get-asset-owner.support_group}}."
consumes:
- type: http
namespace: servicenow
baseUri: "https://sanofi.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: cmdb-ci
path: "/table/cmdb_ci"
operations:
- name: get-ci
method: GET
- 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: 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
Retrieves the current status, assignee, and priority of a Jira issue by key, for project tracking and developer inquiries.
naftiko: "0.5"
info:
label: "Jira Issue Status Lookup"
description: "Retrieves the current status, assignee, and priority of a Jira issue by key, for project tracking and developer inquiries."
tags:
- project-management
- jira
capability:
exposes:
- type: mcp
namespace: pm-tracking
port: 8080
tools:
- name: get-issue-status
description: "Look up a Jira issue by key. Returns current status, assignee, and priority."
inputParameters:
- name: issue_key
in: body
type: string
description: "The Jira issue key (e.g., PROJ-1234)."
call: "jira.get-issue"
with:
issue_key: "{{issue_key}}"
outputParameters:
- name: status
type: string
mapping: "$.fields.status.name"
- name: assignee
type: string
mapping: "$.fields.assignee.displayName"
- name: priority
type: string
mapping: "$.fields.priority.name"
consumes:
- type: http
namespace: jira
baseUri: "https://sanofi.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
Tracks lab instrument calibration schedules by querying SAP PM for upcoming calibrations, creating ServiceNow work orders, and notifying the lab manager via Teams.
naftiko: "0.5"
info:
label: "Lab Instrument Calibration Tracking"
description: "Tracks lab instrument calibration schedules by querying SAP PM for upcoming calibrations, creating ServiceNow work orders, and notifying the lab manager via Teams."
tags:
- quality
- manufacturing
- sap
- servicenow
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: quality-calibration
port: 8080
tools:
- name: track-calibration
description: "Track upcoming instrument calibrations: query SAP PM, create work orders, and notify lab manager."
inputParameters:
- name: plant
in: body
type: string
description: "The SAP plant code."
- name: days_ahead
in: body
type: integer
description: "Number of days to look ahead."
steps:
- name: get-upcoming-calibrations
type: call
call: "sap-pm.get-maintenance-orders"
with:
plant: "{{plant}}"
order_type: "calibration"
- name: create-work-order
type: call
call: "servicenow.create-incident"
with:
short_description: "Lab instrument calibration due at plant {{plant}}"
category: "lab_calibration"
assigned_group: "Lab_Maintenance"
- name: notify-lab-manager
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.lab_team_id"
channel_id: "$secrets.lab_channel_id"
body: "Upcoming calibrations at plant {{plant}}: work order {{create-work-order.number}} created."
consumes:
- type: http
namespace: sap-pm
baseUri: "https://sanofi-s4.sap.com/sap/opu/odata/sap/API_MAINTENANCEORDER"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: maintenance-orders
path: "/MaintenanceOrder"
operations:
- name: get-maintenance-orders
method: GET
- type: http
namespace: servicenow
baseUri: "https://sanofi.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: 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
Tracks mandatory training compliance by pulling completion data from Workday Learning, comparing against requirements in Snowflake, and notifying managers of non-compliant employees via Teams.
naftiko: "0.5"
info:
label: "Learning Management Training Compliance Tracker"
description: "Tracks mandatory training compliance by pulling completion data from Workday Learning, comparing against requirements in Snowflake, and notifying managers of non-compliant employees via Teams."
tags:
- hr
- compliance
- workday
- snowflake
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: hr-training-compliance
port: 8080
tools:
- name: track-training-compliance
description: "Track training compliance: pull completions, compare requirements, and notify managers."
inputParameters:
- name: department
in: body
type: string
description: "The department to check."
- name: training_code
in: body
type: string
description: "The mandatory training course code."
steps:
- name: get-completions
type: call
call: "workday.get-training-completions"
with:
department: "{{department}}"
course_code: "{{training_code}}"
- name: check-requirements
type: call
call: "snowflake.run-query"
with:
statement: "SELECT employee_id, due_date FROM hr.training_requirements WHERE department='{{department}}' AND course_code='{{training_code}}' AND completed=false"
- name: notify-managers
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.hr_team_id"
channel_id: "$secrets.hr_compliance_channel_id"
body: "Training compliance check for {{training_code}} in {{department}}: review non-compliant employees."
consumes:
- type: http
namespace: workday
baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: training
path: "/sanofi/learning/completions"
operations:
- name: get-training-completions
method: GET
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Retrieves approved job requisition details from Workday and publishes the role to LinkedIn, enabling faster candidate sourcing for Sanofi positions.
naftiko: "0.5"
info:
label: "LinkedIn Job Posting Publication"
description: "Retrieves approved job requisition details from Workday and publishes the role to LinkedIn, enabling faster candidate sourcing for Sanofi positions."
tags:
- hr
- recruiting
- linkedin
- workday
- talent-acquisition
capability:
exposes:
- type: mcp
namespace: hr-recruiting
port: 8080
tools:
- name: publish-job-to-linkedin
description: "Given a Workday job requisition ID, fetch its approved details and publish a structured job posting to Sanofi's LinkedIn company page."
inputParameters:
- name: requisition_id
in: body
type: string
description: "The Workday job requisition ID to publish."
- name: linkedin_company_id
in: body
type: string
description: "Sanofi's LinkedIn company page ID."
steps:
- name: get-requisition
type: call
call: "workday-jobs.get-job-requisition"
with:
requisition_id: "{{requisition_id}}"
- name: post-job
type: call
call: "linkedin-jobs.create-job-posting"
with:
companyId: "{{linkedin_company_id}}"
title: "{{get-requisition.jobTitle}}"
description: "{{get-requisition.jobDescription}}"
location: "{{get-requisition.location}}"
consumes:
- type: http
namespace: workday-jobs
baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: job-requisitions
path: "/sanofi/jobRequisitions/{{requisition_id}}"
inputParameters:
- name: requisition_id
in: path
operations:
- name: get-job-requisition
method: GET
- type: http
namespace: linkedin-jobs
baseUri: "https://api.linkedin.com/v2"
authentication:
type: bearer
token: "$secrets.linkedin_token"
resources:
- name: job-postings
path: "/jobPostings"
operations:
- name: create-job-posting
method: POST
Sources candidates from LinkedIn Recruiter, creates candidate profiles in Workday Recruiting, and notifies hiring managers via Teams.
naftiko: "0.5"
info:
label: "LinkedIn Talent Pipeline to Workday"
description: "Sources candidates from LinkedIn Recruiter, creates candidate profiles in Workday Recruiting, and notifies hiring managers via Teams."
tags:
- hr
- recruiting
- linkedin
- workday
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: hr-recruiting
port: 8080
tools:
- name: pipeline-candidate
description: "Pipeline a LinkedIn candidate: source profile, create Workday candidate, and notify hiring manager."
inputParameters:
- name: linkedin_profile_url
in: body
type: string
description: "The LinkedIn profile URL."
- name: job_requisition_id
in: body
type: string
description: "The Workday job requisition ID."
steps:
- name: get-linkedin-profile
type: call
call: "linkedin.get-profile"
with:
profile_url: "{{linkedin_profile_url}}"
- name: create-candidate
type: call
call: "workday.create-candidate"
with:
name: "{{get-linkedin-profile.fullName}}"
email: "{{get-linkedin-profile.emailAddress}}"
requisition_id: "{{job_requisition_id}}"
- name: notify-hiring-manager
type: call
call: "msteams.post-message"
with:
recipient: "$secrets.hiring_manager_email"
message: "New candidate {{get-linkedin-profile.fullName}} added to requisition {{job_requisition_id}} from LinkedIn."
consumes:
- type: http
namespace: linkedin
baseUri: "https://api.linkedin.com/v2"
authentication:
type: bearer
token: "$secrets.linkedin_token"
resources:
- name: profiles
path: "/people/{{profile_url}}"
inputParameters:
- name: profile_url
in: path
operations:
- name: get-profile
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: candidates
path: "/sanofi/recruiting/candidates"
operations:
- name: create-candidate
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/chats/{{chat_id}}/messages"
inputParameters:
- name: chat_id
in: path
operations:
- name: post-message
method: POST
Initiates a deviation investigation by creating a quality event in Veeva Vault, pulling batch parameters from SAP, and assigning a CAPA to the quality team via ServiceNow.
naftiko: "0.5"
info:
label: "Manufacturing Deviation Investigation Workflow"
description: "Initiates a deviation investigation by creating a quality event in Veeva Vault, pulling batch parameters from SAP, and assigning a CAPA to the quality team via ServiceNow."
tags:
- manufacturing
- quality
- veeva
- sap
- servicenow
capability:
exposes:
- type: mcp
namespace: mfg-quality
port: 8080
tools:
- name: investigate-deviation
description: "Orchestrate deviation investigation: create quality event, retrieve batch data, and assign CAPA."
inputParameters:
- name: batch_number
in: body
type: string
description: "The batch number with the deviation."
- name: deviation_description
in: body
type: string
description: "Description of the deviation."
steps:
- name: create-quality-event
type: call
call: "veeva-vault.create-document"
with:
type: "quality_event"
batch_number: "{{batch_number}}"
description: "{{deviation_description}}"
- name: get-batch-params
type: call
call: "sap-qm.get-inspection-lot"
with:
batch: "{{batch_number}}"
- name: create-capa
type: call
call: "servicenow.create-incident"
with:
short_description: "CAPA required: Deviation on batch {{batch_number}}"
category: "quality_capa"
assigned_group: "QA_Investigations"
description: "{{deviation_description}}. Quality event: {{create-quality-event.id}}."
consumes:
- type: http
namespace: veeva-vault
baseUri: "https://sanofi.veevavault.com/api/v24.1"
authentication:
type: bearer
token: "$secrets.veeva_vault_token"
resources:
- name: documents
path: "/objects/documents"
operations:
- name: create-document
method: POST
- type: http
namespace: sap-qm
baseUri: "https://sanofi-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"
operations:
- name: get-inspection-lot
method: GET
- type: http
namespace: servicenow
baseUri: "https://sanofi.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
Processes drug pricing updates by retrieving current pricing from SAP SD, updating reference prices in Snowflake, and notifying the market access team via Teams.
naftiko: "0.5"
info:
label: "Market Access Pricing Update Workflow"
description: "Processes drug pricing updates by retrieving current pricing from SAP SD, updating reference prices in Snowflake, and notifying the market access team via Teams."
tags:
- commercial
- market-access
- sap
- snowflake
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: commercial-pricing
port: 8080
tools:
- name: update-pricing
description: "Update drug pricing: get SAP pricing, update Snowflake reference tables, and notify market access."
inputParameters:
- name: material_number
in: body
type: string
description: "The SAP material number for the drug product."
- name: new_price
in: body
type: string
description: "The new list price."
- name: market
in: body
type: string
description: "The market/country code."
steps:
- name: get-current-pricing
type: call
call: "sap-sd.get-pricing"
with:
material: "{{material_number}}"
market: "{{market}}"
- name: update-reference-price
type: call
call: "snowflake.run-query"
with:
statement: "UPDATE commercial.reference_pricing SET price='{{new_price}}', effective_date=CURRENT_DATE(), previous_price='{{get-current-pricing.list_price}}' WHERE material='{{material_number}}' AND market='{{market}}'"
- name: notify-market-access
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.market_access_team_id"
channel_id: "$secrets.market_access_channel_id"
body: "Pricing update for {{material_number}} in {{market}}: {{get-current-pricing.list_price}} -> {{new_price}}."
consumes:
- type: http
namespace: sap-sd
baseUri: "https://sanofi-s4.sap.com/sap/opu/odata/sap/API_SLSPRICINGCONDITIONRECORD_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: pricing-conditions
path: "/A_SlsPrcgCndnRecdValidity"
operations:
- name: get-pricing
method: GET
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Processes master data change requests by validating against SAP MDG rules, creating a ServiceNow approval workflow, and logging the change in Snowflake.
naftiko: "0.5"
info:
label: "Master Data Governance Change Request"
description: "Processes master data change requests by validating against SAP MDG rules, creating a ServiceNow approval workflow, and logging the change in Snowflake."
tags:
- data-governance
- sap
- servicenow
- snowflake
capability:
exposes:
- type: mcp
namespace: mdg-change
port: 8080
tools:
- name: process-mdg-change
description: "Process master data change: validate SAP rules, create approval workflow, and log change."
inputParameters:
- name: entity_type
in: body
type: string
description: "The master data entity type (material, vendor, customer)."
- name: entity_id
in: body
type: string
description: "The entity identifier."
- name: change_description
in: body
type: string
description: "Description of the requested change."
steps:
- name: validate-entity
type: call
call: "sap-mdg.validate-change"
with:
entity_type: "{{entity_type}}"
entity_id: "{{entity_id}}"
- name: create-approval
type: call
call: "servicenow.create-change"
with:
short_description: "MDG change: {{entity_type}} {{entity_id}}"
description: "{{change_description}}"
category: "master_data"
- name: log-change
type: call
call: "snowflake.run-query"
with:
statement: "INSERT INTO governance.mdg_changes (entity_type, entity_id, description, approval_ticket, requested_at) VALUES ('{{entity_type}}', '{{entity_id}}', '{{change_description}}', '{{create-approval.number}}', CURRENT_TIMESTAMP())"
consumes:
- type: http
namespace: sap-mdg
baseUri: "https://sanofi-s4.sap.com/sap/opu/odata/sap/API_BUSINESS_PARTNER"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: validation
path: "/A_BusinessPartner"
operations:
- name: validate-change
method: GET
- type: http
namespace: servicenow
baseUri: "https://sanofi.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: change-requests
path: "/table/change_request"
operations:
- name: create-change
method: POST
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
Tracks medical publication milestones by querying Veeva Vault for manuscript status, updating Snowflake tracking tables, and alerting the medical affairs team via Teams.
naftiko: "0.5"
info:
label: "Medical Affairs Publication Tracker"
description: "Tracks medical publication milestones by querying Veeva Vault for manuscript status, updating Snowflake tracking tables, and alerting the medical affairs team via Teams."
tags:
- medical-affairs
- veeva
- snowflake
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: medaffairs-pubs
port: 8080
tools:
- name: track-publication
description: "Track publication progress: check Veeva Vault manuscript status, update Snowflake tracker, and notify medical affairs."
inputParameters:
- name: manuscript_id
in: body
type: string
description: "The Veeva Vault manuscript document ID."
steps:
- name: get-manuscript
type: call
call: "veeva-vault.get-document"
with:
doc_id: "{{manuscript_id}}"
- name: update-tracker
type: call
call: "snowflake.run-query"
with:
statement: "UPDATE medical_affairs.publication_tracker SET status='{{get-manuscript.status__v}}', updated_at=CURRENT_TIMESTAMP() WHERE manuscript_id='{{manuscript_id}}'"
- name: notify-team
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.medaffairs_team_id"
channel_id: "$secrets.medaffairs_channel_id"
body: "Manuscript {{manuscript_id}} status: {{get-manuscript.status__v}}. Tracker updated."
consumes:
- type: http
namespace: veeva-vault
baseUri: "https://sanofi.veevavault.com/api/v24.1"
authentication:
type: bearer
token: "$secrets.veeva_vault_token"
resources:
- name: documents
path: "/objects/documents/{{doc_id}}"
inputParameters:
- name: doc_id
in: path
operations:
- name: get-document
method: GET
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Assigns the appropriate Microsoft 365 license SKU to a newly provisioned Sanofi employee in Microsoft Entra ID based on their role and department.
naftiko: "0.5"
info:
label: "Microsoft Entra User License Assignment"
description: "Assigns the appropriate Microsoft 365 license SKU to a newly provisioned Sanofi employee in Microsoft Entra ID based on their role and department."
tags:
- identity
- microsoft-365
- azure
- hr
- license-management
capability:
exposes:
- type: mcp
namespace: identity-licensing
port: 8080
tools:
- name: assign-user-license
description: "Given a user principal name and Microsoft 365 license SKU ID, assign the license in Entra ID. Use after provisioning a new Sanofi employee account."
inputParameters:
- name: user_upn
in: body
type: string
description: "The UPN of the newly provisioned employee (e.g., firstname.lastname@sanofi.com)."
- name: sku_id
in: body
type: string
description: "The Microsoft 365 license SKU GUID to assign."
call: "msgraph-lic.assign-license"
with:
userPrincipalName: "{{user_upn}}"
skuId: "{{sku_id}}"
outputParameters:
- name: assigned_licenses
type: array
mapping: "$.assignedLicenses"
consumes:
- type: http
namespace: msgraph-lic
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: user-licenses
path: "/users/{{userPrincipalName}}/assignLicense"
inputParameters:
- name: userPrincipalName
in: path
operations:
- name: assign-license
method: POST
Retrieves user account status from Microsoft Entra ID by UPN, returning account enabled state, last sign-in, and assigned licenses.
naftiko: "0.5"
info:
label: "Microsoft Entra User Status Lookup"
description: "Retrieves user account status from Microsoft Entra ID by UPN, returning account enabled state, last sign-in, and assigned licenses."
tags:
- identity
- microsoft-entra
capability:
exposes:
- type: mcp
namespace: identity-mgmt
port: 8080
tools:
- name: get-user-status
description: "Look up a Microsoft Entra user by UPN. Returns account enabled flag, last sign-in time, and license assignments."
inputParameters:
- name: user_principal_name
in: body
type: string
description: "The user principal name (email)."
call: "msgraph.get-user"
with:
upn: "{{user_principal_name}}"
outputParameters:
- name: account_enabled
type: boolean
mapping: "$.accountEnabled"
- name: last_sign_in
type: string
mapping: "$.signInActivity.lastSignInDateTime"
consumes:
- type: http
namespace: msgraph
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: users
path: "/users/{{upn}}"
inputParameters:
- name: upn
in: path
operations:
- name: get-user
method: GET
Posts a message to a specified Microsoft Teams channel, used for automated notifications and alerts.
naftiko: "0.5"
info:
label: "Microsoft Teams Channel Message Post"
description: "Posts a message to a specified Microsoft Teams channel, used for automated notifications and alerts."
tags:
- collaboration
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: collab-messaging
port: 8080
tools:
- name: post-channel-message
description: "Post a message to a Microsoft Teams channel. Provide team ID, channel ID, and message body."
inputParameters:
- name: team_id
in: body
type: string
description: "The Microsoft Teams team ID."
- name: channel_id
in: body
type: string
description: "The Teams channel ID."
- name: message
in: body
type: string
description: "The message content to post."
call: "msteams.post-channel-message"
with:
team_id: "{{team_id}}"
channel_id: "{{channel_id}}"
body: "{{message}}"
outputParameters:
- name: message_id
type: string
mapping: "$.id"
consumes:
- 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
When a new employee is created in Workday, opens a ServiceNow onboarding ticket, provisions Microsoft 365 access, and sends a Teams welcome message to kick off the onboarding journey.
naftiko: "0.5"
info:
label: "New Hire Onboarding Orchestrator"
description: "When a new employee is created in Workday, opens a ServiceNow onboarding ticket, provisions Microsoft 365 access, and sends a Teams welcome message to kick off the onboarding journey."
tags:
- hr
- onboarding
- workday
- servicenow
- microsoft-teams
- microsoft-365
capability:
exposes:
- type: mcp
namespace: hr-onboarding
port: 8080
tools:
- name: trigger-onboarding
description: "Given a Workday employee ID and start date, orchestrate the full onboarding sequence: create a ServiceNow IT ticket, provision Microsoft 365, and send a Teams welcome message."
inputParameters:
- name: employee_id
in: body
type: string
description: "The Workday worker ID for the new hire."
- name: start_date
in: body
type: string
description: "The employee's start date in YYYY-MM-DD format."
- name: department
in: body
type: string
description: "The department the new hire is joining."
steps:
- name: get-employee
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-employee.displayName}}"
category: "hr_onboarding"
assigned_group: "IT_Onboarding"
- name: provision-m365
type: call
call: "msgraph.create-user"
with:
displayName: "{{get-employee.displayName}}"
userPrincipalName: "{{get-employee.workEmail}}"
department: "{{department}}"
- name: send-welcome
type: call
call: "msteams.post-message"
with:
recipient: "{{get-employee.workEmail}}"
message: "Welcome to Sanofi, {{get-employee.firstName}}! Your IT 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: "/sanofi/workers/{{worker_id}}"
inputParameters:
- name: worker_id
in: path
operations:
- name: get-worker
method: GET
- type: http
namespace: servicenow
baseUri: "https://sanofi.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: messages
path: "/chats/{{chat_id}}/messages"
inputParameters:
- name: chat_id
in: path
operations:
- name: post-message
method: POST
Runs safety signal detection queries in Snowflake, creates a safety review record in Veeva Vault, and escalates findings to the pharmacovigilance team via Teams.
naftiko: "0.5"
info:
label: "Pharmacovigilance Signal Detection Alert"
description: "Runs safety signal detection queries in Snowflake, creates a safety review record in Veeva Vault, and escalates findings to the pharmacovigilance team via Teams."
tags:
- pharmacovigilance
- snowflake
- veeva
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: pv-signal-detection
port: 8080
tools:
- name: detect-safety-signal
description: "Detect safety signals: query adverse event data, create review record, and escalate to PV team."
inputParameters:
- name: product_name
in: body
type: string
description: "The drug product name."
- name: signal_type
in: body
type: string
description: "The type of safety signal to detect."
steps:
- name: run-signal-query
type: call
call: "snowflake.run-query"
with:
statement: "SELECT event_type, COUNT(*) as cnt FROM pv.adverse_events WHERE product_name='{{product_name}}' AND reported_date > DATEADD(month, -3, CURRENT_DATE()) GROUP BY event_type HAVING cnt > 10"
- name: create-review-record
type: call
call: "veeva-vault.create-document"
with:
type: "safety_signal_review"
product: "{{product_name}}"
signal_type: "{{signal_type}}"
- name: escalate-to-pv
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.pv_team_id"
channel_id: "$secrets.pv_channel_id"
body: "Safety signal detected for {{product_name}}. Signal type: {{signal_type}}. Review record: {{create-review-record.id}}."
consumes:
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: veeva-vault
baseUri: "https://sanofi.veevavault.com/api/v24.1"
authentication:
type: bearer
token: "$secrets.veeva_vault_token"
resources:
- name: documents
path: "/objects/documents"
operations:
- name: create-document
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Checks the last refresh status of a Power BI dataset, returning completion time and success or failure state.
naftiko: "0.5"
info:
label: "Power BI Dataset Refresh Status"
description: "Checks the last refresh status of a Power BI dataset, returning completion time and success or failure state."
tags:
- analytics
- power-bi
capability:
exposes:
- type: mcp
namespace: analytics-refresh
port: 8080
tools:
- name: get-dataset-refresh-status
description: "Check the last refresh status of a Power BI dataset. Returns refresh time and status."
inputParameters:
- name: dataset_id
in: body
type: string
description: "The Power BI dataset ID."
call: "powerbi.get-refresh-history"
with:
dataset_id: "{{dataset_id}}"
outputParameters:
- name: status
type: string
mapping: "$.value[0].status"
- name: end_time
type: string
mapping: "$.value[0].endTime"
consumes:
- type: http
namespace: powerbi
baseUri: "https://api.powerbi.com/v1.0/myorg"
authentication:
type: bearer
token: "$secrets.powerbi_token"
resources:
- name: refresh-history
path: "/datasets/{{dataset_id}}/refreshes"
inputParameters:
- name: dataset_id
in: path
operations:
- name: get-refresh-history
method: GET
Triggers a Power BI dataset refresh for the Sanofi financial KPI dashboard and notifies the finance team in Teams when data is ready.
naftiko: "0.5"
info:
label: "Power BI Financial Dashboard Refresh"
description: "Triggers a Power BI dataset refresh for the Sanofi financial KPI dashboard and notifies the finance team in Teams when data is ready."
tags:
- finance
- analytics
- power-bi
- microsoft-teams
- reporting
capability:
exposes:
- type: mcp
namespace: finance-reporting
port: 8080
tools:
- name: refresh-financial-dashboard
description: "Trigger a Power BI dataset refresh for the financial KPI dashboard and notify the finance team in Teams upon completion."
inputParameters:
- name: dataset_id
in: body
type: string
description: "The Power BI dataset ID for the financial dashboard."
- name: workspace_id
in: body
type: string
description: "The Power BI workspace (group) ID containing the dataset."
steps:
- name: trigger-refresh
type: call
call: "powerbi.refresh-dataset"
with:
groupId: "{{workspace_id}}"
datasetId: "{{dataset_id}}"
- name: notify-finance
type: call
call: "msteams-pbi.post-message"
with:
channel: "finance-analytics"
message: "Power BI financial dashboard refresh triggered for dataset {{dataset_id}}. Updated data will be available shortly."
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/{{groupId}}/datasets/{{datasetId}}/refreshes"
inputParameters:
- name: groupId
in: path
- name: datasetId
in: path
operations:
- name: refresh-dataset
method: POST
- type: http
namespace: msteams-pbi
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-message
method: POST
Converts an approved SAP Ariba requisition into a SAP S/4HANA purchase order, assigns the vendor, and sends a confirmation to the requestor via Teams.
naftiko: "0.5"
info:
label: "Procurement Requisition to PO Workflow"
description: "Converts an approved SAP Ariba requisition into a SAP S/4HANA purchase order, assigns the vendor, and sends a confirmation to the requestor via Teams."
tags:
- procurement
- sap-ariba
- sap
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: procurement-req-to-po
port: 8080
tools:
- name: convert-requisition-to-po
description: "Convert an approved Ariba requisition to a SAP PO, assign vendor, and confirm with requestor."
inputParameters:
- name: requisition_id
in: body
type: string
description: "The SAP Ariba requisition ID."
steps:
- name: get-requisition
type: call
call: "ariba.get-requisition"
with:
req_id: "{{requisition_id}}"
- name: create-po
type: call
call: "sap-po.create-po"
with:
vendor: "{{get-requisition.supplier.id}}"
material: "{{get-requisition.lineItems[0].material}}"
quantity: "{{get-requisition.lineItems[0].quantity}}"
plant: "{{get-requisition.deliverTo.plant}}"
- name: notify-requestor
type: call
call: "msteams.post-message"
with:
recipient: "{{get-requisition.requester.email}}"
message: "Your requisition {{requisition_id}} has been converted to PO {{create-po.PurchaseOrder}}."
consumes:
- type: http
namespace: ariba
baseUri: "https://openapi.ariba.com/api/procurement/v1"
authentication:
type: bearer
token: "$secrets.ariba_token"
resources:
- name: requisitions
path: "/requisitions/{{req_id}}"
inputParameters:
- name: req_id
in: path
operations:
- name: get-requisition
method: GET
- type: http
namespace: sap-po
baseUri: "https://sanofi-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: create-po
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/chats/{{chat_id}}/messages"
inputParameters:
- name: chat_id
in: path
operations:
- name: post-message
method: POST
Tracks patent filing status by querying Snowflake IP databases, updating Veeva Vault document metadata, and notifying the IP legal team via Teams.
naftiko: "0.5"
info:
label: "R&D Patent Filing Status Tracker"
description: "Tracks patent filing status by querying Snowflake IP databases, updating Veeva Vault document metadata, and notifying the IP legal team via Teams."
tags:
- research
- legal
- snowflake
- veeva
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: rd-ip-tracking
port: 8080
tools:
- name: track-patent-filing
description: "Track patent filing status: query IP database, update document metadata, and notify legal team."
inputParameters:
- name: patent_id
in: body
type: string
description: "The patent application identifier."
steps:
- name: get-filing-status
type: call
call: "snowflake.run-query"
with:
statement: "SELECT filing_date, jurisdiction, status, examiner_notes FROM ip.patent_filings WHERE patent_id='{{patent_id}}'"
- name: update-vault-doc
type: call
call: "veeva-vault.update-document"
with:
doc_id: "{{patent_id}}"
status: "{{get-filing-status.status}}"
- name: notify-ip-team
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.ip_team_id"
channel_id: "$secrets.ip_channel_id"
body: "Patent {{patent_id}} filing update: Status is {{get-filing-status.status}}."
consumes:
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: veeva-vault
baseUri: "https://sanofi.veevavault.com/api/v24.1"
authentication:
type: bearer
token: "$secrets.veeva_vault_token"
resources:
- name: documents
path: "/objects/documents/{{doc_id}}"
inputParameters:
- name: doc_id
in: path
operations:
- name: update-document
method: PUT
- 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
Refreshes real-world evidence datasets by triggering Databricks ETL pipelines, validating data quality in Snowflake, and notifying the RWE team via Teams.
naftiko: "0.5"
info:
label: "Real World Evidence Data Refresh"
description: "Refreshes real-world evidence datasets by triggering Databricks ETL pipelines, validating data quality in Snowflake, and notifying the RWE team via Teams."
tags:
- research
- data-engineering
- databricks
- snowflake
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: rwe-data-refresh
port: 8080
tools:
- name: refresh-rwe-data
description: "Refresh RWE data: trigger Databricks pipeline, validate quality, and notify team."
inputParameters:
- name: dataset_name
in: body
type: string
description: "The RWE dataset name."
steps:
- name: trigger-etl
type: call
call: "databricks.run-job"
with:
job_name: "rwe_{{dataset_name}}_refresh"
- name: validate-quality
type: call
call: "snowflake.run-query"
with:
statement: "SELECT check_name, status FROM rwe.data_quality_checks WHERE dataset_name='{{dataset_name}}' ORDER BY run_date DESC LIMIT 10"
- name: notify-rwe-team
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.rwe_team_id"
channel_id: "$secrets.rwe_channel_id"
body: "RWE dataset {{dataset_name}} refresh triggered. Databricks job: {{trigger-etl.run_id}}. Quality validation in progress."
consumes:
- type: http
namespace: databricks
baseUri: "https://sanofi.cloud.databricks.com/api/2.1"
authentication:
type: bearer
token: "$secrets.databricks_token"
resources:
- name: jobs
path: "/jobs/run-now"
operations:
- name: run-job
method: POST
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Assembles a regulatory submission package by collecting documents from Veeva Vault, generating a compliance checklist from Snowflake, and posting the submission summary to the regulatory team's Teams channel.
naftiko: "0.5"
info:
label: "Regulatory Submission Document Assembly"
description: "Assembles a regulatory submission package by collecting documents from Veeva Vault, generating a compliance checklist from Snowflake, and posting the submission summary to the regulatory team's Teams channel."
tags:
- regulatory
- veeva
- snowflake
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: regulatory-submission
port: 8080
tools:
- name: assemble-submission
description: "Assemble a regulatory submission: collect Veeva Vault documents, generate compliance checklist, and notify the regulatory team."
inputParameters:
- name: submission_id
in: body
type: string
description: "The regulatory submission identifier."
- name: product_name
in: body
type: string
description: "The drug product name."
steps:
- name: get-submission-docs
type: call
call: "veeva-vault.query-documents"
with:
query: "SELECT id, name__v, status__v FROM documents WHERE submission_id__v = '{{submission_id}}'"
- name: get-checklist
type: call
call: "snowflake.run-query"
with:
statement: "SELECT requirement, status FROM regulatory.submission_checklist WHERE submission_id = '{{submission_id}}'"
- name: notify-regulatory-team
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.regulatory_team_id"
channel_id: "$secrets.regulatory_channel_id"
body: "Submission {{submission_id}} for {{product_name}} assembled. {{get-submission-docs.responseDetails.total}} documents collected."
consumes:
- type: http
namespace: veeva-vault
baseUri: "https://sanofi.veevavault.com/api/v24.1"
authentication:
type: bearer
token: "$secrets.veeva_vault_token"
resources:
- name: query
path: "/query"
operations:
- name: query-documents
method: POST
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Retrieves contract details from SAP Ariba by contract ID, returning effective dates, supplier name, and contract value.
naftiko: "0.5"
info:
label: "SAP Ariba Contract Detail Lookup"
description: "Retrieves contract details from SAP Ariba by contract ID, returning effective dates, supplier name, and contract value."
tags:
- procurement
- sap-ariba
capability:
exposes:
- type: mcp
namespace: procurement-contracts
port: 8080
tools:
- name: get-contract-detail
description: "Look up a SAP Ariba contract by ID. Returns effective date, expiry date, supplier, and total contract value."
inputParameters:
- name: contract_id
in: body
type: string
description: "The SAP Ariba contract ID."
call: "ariba.get-contract"
with:
contract_id: "{{contract_id}}"
outputParameters:
- name: effective_date
type: string
mapping: "$.effectiveDate"
- name: expiry_date
type: string
mapping: "$.expirationDate"
- name: supplier
type: string
mapping: "$.supplier.name"
- name: contract_value
type: string
mapping: "$.amount.value"
consumes:
- type: http
namespace: ariba
baseUri: "https://openapi.ariba.com/api/contract-compliance/v1"
authentication:
type: bearer
token: "$secrets.ariba_token"
resources:
- name: contracts
path: "/contracts/{{contract_id}}"
inputParameters:
- name: contract_id
in: path
operations:
- name: get-contract
method: GET
Queries SAP Ariba for supplier contracts expiring within 90 days and notifies the procurement team in Teams to initiate renewal processes.
naftiko: "0.5"
info:
label: "SAP Ariba Contract Expiry Alert"
description: "Queries SAP Ariba for supplier contracts expiring within 90 days and notifies the procurement team in Teams to initiate renewal processes."
tags:
- procurement
- sap-ariba
- microsoft-teams
- contract-management
- alerts
capability:
exposes:
- type: mcp
namespace: procurement-contracts
port: 8080
tools:
- name: alert-expiring-contracts
description: "Query SAP Ariba for contracts expiring within the specified threshold and notify the procurement team in Teams. Use for proactive supplier contract renewal."
inputParameters:
- name: days_threshold
in: body
type: integer
description: "Number of days ahead to check for contract expiry (e.g., 90)."
steps:
- name: get-contracts
type: call
call: "ariba-exp.get-expiring-contracts"
with:
expiryDays: "{{days_threshold}}"
- name: notify-procurement
type: call
call: "msteams-proc.post-message"
with:
channel: "procurement-ops"
message: "Contracts expiring within {{days_threshold}} days in SAP Ariba: {{get-contracts.summary}}. Please initiate renewal."
consumes:
- type: http
namespace: ariba-exp
baseUri: "https://openapi.ariba.com/api/contract/v1"
authentication:
type: apikey
key: "APIKey"
value: "$secrets.ariba_api_key"
placement: header
resources:
- name: contracts
path: "/contracts"
operations:
- name: get-expiring-contracts
method: GET
- type: http
namespace: msteams-proc
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-message
method: POST
When a supplier invoice is received in SAP Ariba, validates it against the matched PO in SAP S/4HANA and posts it for payment if within tolerance.
naftiko: "0.5"
info:
label: "SAP Ariba Invoice Approval and Posting"
description: "When a supplier invoice is received in SAP Ariba, validates it against the matched PO in SAP S/4HANA and posts it for payment if within tolerance."
tags:
- finance
- procurement
- sap-ariba
- sap
- invoice
- approval
capability:
exposes:
- type: mcp
namespace: finance-invoicing
port: 8080
tools:
- name: process-invoice
description: "Given an SAP Ariba invoice ID, fetch details, validate against the SAP S/4HANA PO, and post for payment if within the approved tolerance threshold."
inputParameters:
- name: invoice_id
in: body
type: string
description: "The SAP Ariba invoice ID to process."
- name: tolerance_pct
in: body
type: number
description: "Acceptable variance percentage between invoice and PO amount (e.g., 2.0)."
steps:
- name: get-invoice
type: call
call: "ariba-inv.get-invoice"
with:
invoice_id: "{{invoice_id}}"
- name: get-po
type: call
call: "sap-inv.get-po"
with:
po_number: "{{get-invoice.purchaseOrderId}}"
- name: post-payment
type: call
call: "sap-inv.post-invoice"
with:
po_number: "{{get-invoice.purchaseOrderId}}"
invoice_amount: "{{get-invoice.totalAmount}}"
vendor_id: "{{get-po.vendorId}}"
consumes:
- type: http
namespace: ariba-inv
baseUri: "https://openapi.ariba.com/api/invoice/v1"
authentication:
type: apikey
key: "APIKey"
value: "$secrets.ariba_api_key"
placement: header
resources:
- name: invoices
path: "/invoices/{{invoice_id}}"
inputParameters:
- name: invoice_id
in: path
operations:
- name: get-invoice
method: GET
- type: http
namespace: sap-inv
baseUri: "https://sanofi-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
outputRawFormat: xml
- name: invoice-postings
path: "/A_SupplierInvoice"
operations:
- name: post-invoice
method: POST
Generates batch traceability reports by querying SAP for batch genealogy, enriching with quality data from Snowflake, and posting the report to the quality team via Teams.
naftiko: "0.5"
info:
label: "SAP Batch Traceability Report"
description: "Generates batch traceability reports by querying SAP for batch genealogy, enriching with quality data from Snowflake, and posting the report to the quality team via Teams."
tags:
- quality
- manufacturing
- sap
- snowflake
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: quality-traceability
port: 8080
tools:
- name: generate-traceability-report
description: "Generate batch traceability report: query SAP genealogy, enrich with quality data, and post report."
inputParameters:
- name: batch_number
in: body
type: string
description: "The batch number to trace."
- name: material_number
in: body
type: string
description: "The SAP material number."
steps:
- name: get-batch-genealogy
type: call
call: "sap-qm.get-batch-where-used"
with:
batch: "{{batch_number}}"
material: "{{material_number}}"
- name: get-quality-data
type: call
call: "snowflake.run-query"
with:
statement: "SELECT test_name, result, specification FROM quality.batch_test_results WHERE batch_number='{{batch_number}}'"
- name: post-report
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.quality_team_id"
channel_id: "$secrets.quality_channel_id"
body: "Batch traceability report for {{batch_number}} (material {{material_number}}) generated. Genealogy and quality data compiled."
consumes:
- type: http
namespace: sap-qm
baseUri: "https://sanofi-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: "/Batch"
operations:
- name: get-batch-where-used
method: GET
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Retrieves pending SAP Concur expense reports above threshold and routes each to the employee's manager in Teams for one-click review and approval.
naftiko: "0.5"
info:
label: "SAP Concur Expense Report Approval Routing"
description: "Retrieves pending SAP Concur expense reports above threshold and routes each to the employee's manager in Teams for one-click review and approval."
tags:
- finance
- expense-management
- sap-concur
- microsoft-teams
- approval
capability:
exposes:
- type: mcp
namespace: finance-expenses
port: 8080
tools:
- name: route-expense-approval
description: "Given an SAP Concur expense report ID and approver email, retrieve report details and send an approval notification to the manager in Teams."
inputParameters:
- name: report_id
in: body
type: string
description: "The SAP Concur expense report ID to route for approval."
- name: approver_email
in: body
type: string
description: "The Teams UPN of the approving manager."
steps:
- name: get-report
type: call
call: "concur.get-expense-report"
with:
report_id: "{{report_id}}"
- name: notify-approver
type: call
call: "msteams-expense.post-message"
with:
recipient: "{{approver_email}}"
message: "Expense report {{report_id}} from {{get-report.employeeName}} — Total: {{get-report.total}} {{get-report.currency}}. Please review in Concur."
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/reportdigests/{{report_id}}"
inputParameters:
- name: report_id
in: path
operations:
- name: get-expense-report
method: GET
- type: http
namespace: msteams-expense
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/chats/{{chat_id}}/messages"
inputParameters:
- name: chat_id
in: path
operations:
- name: post-message
method: POST
Reviews a SAP Concur travel request against corporate travel policy in Snowflake, flags exceptions, and routes non-compliant requests to the travel manager via Teams.
naftiko: "0.5"
info:
label: "SAP Concur Travel Request Compliance Check"
description: "Reviews a SAP Concur travel request against corporate travel policy in Snowflake, flags exceptions, and routes non-compliant requests to the travel manager via Teams."
tags:
- travel
- sap-concur
- snowflake
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: travel-compliance
port: 8080
tools:
- name: check-travel-compliance
description: "Check travel request compliance: get request details from Concur, validate against policy, and flag exceptions."
inputParameters:
- name: request_id
in: body
type: string
description: "The SAP Concur travel request ID."
steps:
- name: get-request
type: call
call: "concur.get-travel-request"
with:
request_id: "{{request_id}}"
- name: check-policy
type: call
call: "snowflake.run-query"
with:
statement: "SELECT max_daily_hotel, max_flight_class FROM corporate.travel_policy WHERE region = '{{get-request.region}}'"
- name: notify-travel-manager
type: call
call: "msteams.post-message"
with:
recipient: "$secrets.travel_manager_email"
message: "Travel request {{request_id}} for {{get-request.traveler_name}} reviewed. Destination: {{get-request.destination}}. Policy check complete."
consumes:
- type: http
namespace: concur
baseUri: "https://us.api.concursolutions.com/api/v3.0"
authentication:
type: bearer
token: "$secrets.concur_token"
resources:
- name: travel-requests
path: "/travelrequest/requests/{{request_id}}"
inputParameters:
- name: request_id
in: path
operations:
- name: get-travel-request
method: GET
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-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: "/chats/{{chat_id}}/messages"
inputParameters:
- name: chat_id
in: path
operations:
- name: post-message
method: POST
Retrieves budget allocation and current spend for a SAP S/4HANA cost center, used for finance and planning inquiries.
naftiko: "0.5"
info:
label: "SAP Cost Center Budget Lookup"
description: "Retrieves budget allocation and current spend for a SAP S/4HANA cost center, used for finance and planning inquiries."
tags:
- finance
- sap
- erp
capability:
exposes:
- type: mcp
namespace: finance-budget
port: 8080
tools:
- name: get-cost-center-budget
description: "Look up budget vs. actual spend for a SAP cost center. Returns allocated budget, actual spend, and remaining balance."
inputParameters:
- name: cost_center
in: body
type: string
description: "The SAP cost center ID."
- name: fiscal_year
in: body
type: string
description: "Fiscal year in YYYY format."
call: "sap-fi.get-cost-center"
with:
cost_center: "{{cost_center}}"
fiscal_year: "{{fiscal_year}}"
outputParameters:
- name: allocated_budget
type: string
mapping: "$.d.PlannedAmount"
- name: actual_spend
type: string
mapping: "$.d.ActualAmount"
- name: remaining
type: string
mapping: "$.d.RemainingBudget"
consumes:
- type: http
namespace: sap-fi
baseUri: "https://sanofi-s4.sap.com/sap/opu/odata/sap/API_COSTCENTER_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: cost-centers
path: "/A_CostCenter(CostCenter='{{cost_center}}',FiscalYear='{{fiscal_year}}')"
inputParameters:
- name: cost_center
in: path
- name: fiscal_year
in: path
operations:
- name: get-cost-center
method: GET
Checks SAP S/4HANA for the goods receipt status of a purchase order, returning posting date and quantity received.
naftiko: "0.5"
info:
label: "SAP Goods Receipt Status Lookup"
description: "Checks SAP S/4HANA for the goods receipt status of a purchase order, returning posting date and quantity received."
tags:
- supply-chain
- sap
- erp
capability:
exposes:
- type: mcp
namespace: scm-receiving
port: 8080
tools:
- name: get-goods-receipt-status
description: "Look up goods receipt status for a SAP purchase order. Returns posting date, received quantity, and delivery status."
inputParameters:
- name: po_number
in: body
type: string
description: "The SAP purchase order number."
call: "sap-gr.get-receipt"
with:
po_number: "{{po_number}}"
outputParameters:
- name: posting_date
type: string
mapping: "$.d.PostingDate"
- name: quantity_received
type: string
mapping: "$.d.QuantityInEntryUnit"
- name: delivery_completed
type: boolean
mapping: "$.d.DeliveryCompleted"
consumes:
- type: http
namespace: sap-gr
baseUri: "https://sanofi-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: get-receipt
method: GET
Reconciles intercompany billing by comparing SAP S/4HANA company codes, posting variances to Snowflake, and notifying the finance controller via Teams.
naftiko: "0.5"
info:
label: "SAP Intercompany Billing Reconciliation"
description: "Reconciles intercompany billing by comparing SAP S/4HANA company codes, posting variances to Snowflake, and notifying the finance controller via Teams."
tags:
- finance
- sap
- snowflake
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: finance-interco
port: 8080
tools:
- name: reconcile-intercompany
description: "Reconcile intercompany billing: compare SAP balances, log variances, and notify controller."
inputParameters:
- name: sending_company
in: body
type: string
description: "The sending SAP company code."
- name: receiving_company
in: body
type: string
description: "The receiving SAP company code."
- name: period
in: body
type: string
description: "The fiscal period."
steps:
- name: get-sending-balance
type: call
call: "sap-fi.get-interco-balance"
with:
company_code: "{{sending_company}}"
partner: "{{receiving_company}}"
period: "{{period}}"
- name: get-receiving-balance
type: call
call: "sap-fi.get-interco-balance"
with:
company_code: "{{receiving_company}}"
partner: "{{sending_company}}"
period: "{{period}}"
- name: log-variance
type: call
call: "snowflake.run-query"
with:
statement: "INSERT INTO finance.interco_reconciliation (sending, receiving, period, variance, reconciled_at) VALUES ('{{sending_company}}', '{{receiving_company}}', '{{period}}', '{{get-sending-balance.amount}}', CURRENT_TIMESTAMP())"
- name: notify-controller
type: call
call: "msteams.post-message"
with:
recipient: "$secrets.finance_controller_email"
message: "Intercompany reconciliation complete: {{sending_company}} vs {{receiving_company}} for period {{period}}."
consumes:
- type: http
namespace: sap-fi
baseUri: "https://sanofi-s4.sap.com/sap/opu/odata/sap/API_JOURNALENTRYITEMBASIC_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: journal-entries
path: "/A_JournalEntryItemBasic"
operations:
- name: get-interco-balance
method: GET
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-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: "/chats/{{chat_id}}/messages"
inputParameters:
- name: chat_id
in: path
operations:
- name: post-message
method: POST
Retrieves SAP S/4HANA material master data by material number, returning description, base unit, material group, and plant availability.
naftiko: "0.5"
info:
label: "SAP Material Master Lookup"
description: "Retrieves SAP S/4HANA material master data by material number, returning description, base unit, material group, and plant availability."
tags:
- supply-chain
- sap
- erp
capability:
exposes:
- type: mcp
namespace: scm-material
port: 8080
tools:
- name: get-material-master
description: "Look up a SAP material master record by material number. Returns description, base unit, material group, and plant data."
inputParameters:
- name: material_number
in: body
type: string
description: "The SAP material number."
call: "sap-mm.get-material"
with:
material_number: "{{material_number}}"
outputParameters:
- name: description
type: string
mapping: "$.d.MaterialDescription"
- name: base_unit
type: string
mapping: "$.d.BaseUnit"
- name: material_group
type: string
mapping: "$.d.MaterialGroup"
consumes:
- type: http
namespace: sap-mm
baseUri: "https://sanofi-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_number}}')"
inputParameters:
- name: material_number
in: path
operations:
- name: get-material
method: GET
Retrieves a SAP plant maintenance order by number, returning equipment details, work center, and order status for manufacturing operations.
naftiko: "0.5"
info:
label: "SAP Plant Maintenance Order Lookup"
description: "Retrieves a SAP plant maintenance order by number, returning equipment details, work center, and order status for manufacturing operations."
tags:
- manufacturing
- sap
- erp
capability:
exposes:
- type: mcp
namespace: mfg-maintenance
port: 8080
tools:
- name: get-maintenance-order
description: "Look up a SAP plant maintenance order. Returns equipment, work center, priority, and status."
inputParameters:
- name: order_number
in: body
type: string
description: "The SAP maintenance order number."
call: "sap-pm.get-order"
with:
order_number: "{{order_number}}"
outputParameters:
- name: equipment
type: string
mapping: "$.d.Equipment"
- name: work_center
type: string
mapping: "$.d.MainWorkCenter"
- name: status
type: string
mapping: "$.d.OrderStatus"
consumes:
- type: http
namespace: sap-pm
baseUri: "https://sanofi-s4.sap.com/sap/opu/odata/sap/API_MAINTENANCEORDER"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: maintenance-orders
path: "/MaintenanceOrder('{{order_number}}')"
inputParameters:
- name: order_number
in: path
operations:
- name: get-order
method: GET
Optimizes production scheduling by pulling current orders from SAP PP, analyzing capacity in Snowflake, and updating the manufacturing team via Teams.
naftiko: "0.5"
info:
label: "SAP Production Order Scheduling Optimizer"
description: "Optimizes production scheduling by pulling current orders from SAP PP, analyzing capacity in Snowflake, and updating the manufacturing team via Teams."
tags:
- manufacturing
- sap
- snowflake
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: mfg-scheduling
port: 8080
tools:
- name: optimize-schedule
description: "Optimize production scheduling: pull SAP orders, analyze capacity, and update team."
inputParameters:
- name: plant
in: body
type: string
description: "The SAP plant code."
- name: production_line
in: body
type: string
description: "The production line identifier."
steps:
- name: get-production-orders
type: call
call: "sap-pp.get-orders"
with:
plant: "{{plant}}"
production_line: "{{production_line}}"
- name: analyze-capacity
type: call
call: "snowflake.run-query"
with:
statement: "SELECT available_hours, utilization_pct FROM manufacturing.capacity WHERE plant='{{plant}}' AND line='{{production_line}}'"
- name: notify-mfg-team
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.mfg_team_id"
channel_id: "$secrets.mfg_channel_id"
body: "Production schedule optimized for plant {{plant}}, line {{production_line}}. Capacity utilization analyzed."
consumes:
- type: http
namespace: sap-pp
baseUri: "https://sanofi-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_2"
operations:
- name: get-orders
method: GET
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Retrieves a SAP S/4HANA purchase order by number, returning header status, vendor details, and total amount for procurement and finance review.
naftiko: "0.5"
info:
label: "SAP Purchase Order Lookup"
description: "Retrieves a SAP S/4HANA purchase order by number, returning header status, vendor details, and total amount for procurement and finance review."
tags:
- finance
- procurement
- sap
- erp
capability:
exposes:
- type: mcp
namespace: erp-procurement
port: 8080
tools:
- name: get-purchase-order
description: "Look up a SAP S/4HANA purchase order by PO number. Returns overall status, vendor name, total amount, and currency. Use for procurement approval or spend visibility."
inputParameters:
- name: po_number
in: body
type: string
description: "The SAP purchase order number (e.g., 4500098765)."
call: "sap-po.get-po"
with:
po_number: "{{po_number}}"
outputParameters:
- name: status
type: string
mapping: "$.d.OverallStatus"
- name: vendor
type: string
mapping: "$.d.Supplier.CompanyName"
- name: total_amount
type: string
mapping: "$.d.TotalAmount"
- name: currency
type: string
mapping: "$.d.TransactionCurrency"
consumes:
- type: http
namespace: sap-po
baseUri: "https://sanofi-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
outputRawFormat: xml
Pulls cost center budget and actual spend from SAP S/4HANA for a specified fiscal period and posts a variance summary to the finance leadership channel in Teams.
naftiko: "0.5"
info:
label: "SAP S/4HANA Budget vs Actuals Report"
description: "Pulls cost center budget and actual spend from SAP S/4HANA for a specified fiscal period and posts a variance summary to the finance leadership channel in Teams."
tags:
- finance
- sap
- microsoft-teams
- reporting
- budget
capability:
exposes:
- type: mcp
namespace: finance-budget
port: 8080
tools:
- name: report-budget-variance
description: "Given an SAP cost center and fiscal period, retrieve budget vs. actuals from SAP S/4HANA and post a variance digest to the finance Teams channel."
inputParameters:
- name: cost_center
in: body
type: string
description: "The SAP cost center ID (e.g., CC2001)."
- name: fiscal_period
in: body
type: string
description: "The fiscal period in YYYYMM format (e.g., 202503)."
steps:
- name: get-actuals
type: call
call: "sap-budget.get-cost-center-actuals"
with:
costCenter: "{{cost_center}}"
fiscalPeriod: "{{fiscal_period}}"
- name: post-report
type: call
call: "msteams-budget.post-message"
with:
channel: "finance-leadership"
message: "Budget vs Actuals for {{cost_center}} ({{fiscal_period}}): Budget={{get-actuals.budget}}, Actual={{get-actuals.actual}}, Variance={{get-actuals.variance}}"
consumes:
- type: http
namespace: sap-budget
baseUri: "https://sanofi-s4.sap.com/sap/opu/odata/sap/API_COSTCENTER_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: cost-center-actuals
path: "/A_CostCenter('{{costCenter}}')"
inputParameters:
- name: costCenter
in: path
operations:
- name: get-cost-center-actuals
method: GET
outputRawFormat: xml
- type: http
namespace: msteams-budget
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-message
method: POST
Promotes SAP transport requests through landscapes by verifying approvals in ServiceNow, executing the transport in SAP, and logging the promotion in Snowflake for audit.
naftiko: "0.5"
info:
label: "SAP Transport Request Promotion Workflow"
description: "Promotes SAP transport requests through landscapes by verifying approvals in ServiceNow, executing the transport in SAP, and logging the promotion in Snowflake for audit."
tags:
- devops
- sap
- servicenow
- snowflake
capability:
exposes:
- type: mcp
namespace: sap-transport
port: 8080
tools:
- name: promote-transport
description: "Promote SAP transport: verify approval, execute transport, and log for audit."
inputParameters:
- name: transport_number
in: body
type: string
description: "The SAP transport request number."
- name: target_system
in: body
type: string
description: "The target SAP system (QAS, PRD)."
steps:
- name: verify-approval
type: call
call: "servicenow.get-change"
with:
transport: "{{transport_number}}"
- name: execute-transport
type: call
call: "sap-basis.import-transport"
with:
transport: "{{transport_number}}"
target: "{{target_system}}"
- name: log-promotion
type: call
call: "snowflake.run-query"
with:
statement: "INSERT INTO sap_ops.transport_promotions (transport_number, target_system, approval_ticket, promoted_at) VALUES ('{{transport_number}}', '{{target_system}}', '{{verify-approval.number}}', CURRENT_TIMESTAMP())"
consumes:
- type: http
namespace: servicenow
baseUri: "https://sanofi.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: change-requests
path: "/table/change_request"
operations:
- name: get-change
method: GET
- type: http
namespace: sap-basis
baseUri: "https://sanofi-s4.sap.com/sap/opu/odata/sap/API_TRANSPORT_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: transports
path: "/TransportRequest"
operations:
- name: import-transport
method: POST
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
Retrieves SAP S/4HANA vendor master record details for a given vendor ID, surfacing payment terms, compliance flags, and company information.
naftiko: "0.5"
info:
label: "SAP Vendor Master Data Lookup"
description: "Retrieves SAP S/4HANA vendor master record details for a given vendor ID, surfacing payment terms, compliance flags, and company information."
tags:
- finance
- procurement
- sap
- vendor-management
capability:
exposes:
- type: mcp
namespace: erp-vendor
port: 8080
tools:
- name: get-vendor-record
description: "Look up a SAP S/4HANA vendor master record by vendor ID. Returns company name, payment terms, and compliance status. Use before approving new supplier engagements."
inputParameters:
- name: vendor_id
in: body
type: string
description: "The SAP vendor (supplier) ID to look up."
call: "sap-vendor.get-vendor"
with:
vendor_id: "{{vendor_id}}"
outputParameters:
- name: company_name
type: string
mapping: "$.d.BusinessPartnerFullName"
- name: payment_terms
type: string
mapping: "$.d.PaymentTerms"
- name: currency
type: string
mapping: "$.d.Currency"
consumes:
- type: http
namespace: sap-vendor
baseUri: "https://sanofi-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('{{vendor_id}}')"
inputParameters:
- name: vendor_id
in: path
operations:
- name: get-vendor
method: GET
outputRawFormat: xml
Orchestrates inter-plant stock transfers by creating transfer orders in SAP, updating inventory projections in Snowflake, and notifying warehouse managers via Teams.
naftiko: "0.5"
info:
label: "SAP Warehouse Stock Transfer Orchestrator"
description: "Orchestrates inter-plant stock transfers by creating transfer orders in SAP, updating inventory projections in Snowflake, and notifying warehouse managers via Teams."
tags:
- supply-chain
- sap
- snowflake
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: scm-stock-transfer
port: 8080
tools:
- name: transfer-stock
description: "Orchestrate stock transfer: create SAP transfer order, update projections, and notify managers."
inputParameters:
- name: material_number
in: body
type: string
description: "The SAP material number."
- name: source_plant
in: body
type: string
description: "The source plant code."
- name: target_plant
in: body
type: string
description: "The target plant code."
- name: quantity
in: body
type: string
description: "The transfer quantity."
steps:
- name: create-transfer-order
type: call
call: "sap-mm.create-transfer"
with:
material: "{{material_number}}"
source: "{{source_plant}}"
target: "{{target_plant}}"
quantity: "{{quantity}}"
- name: update-projections
type: call
call: "snowflake.run-query"
with:
statement: "UPDATE supply_chain.inventory_projections SET projected_qty=projected_qty-{{quantity}} WHERE material='{{material_number}}' AND plant='{{source_plant}}'"
- name: notify-managers
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.warehouse_team_id"
channel_id: "$secrets.warehouse_channel_id"
body: "Stock transfer initiated: {{quantity}} units of {{material_number}} from {{source_plant}} to {{target_plant}}. Transfer order: {{create-transfer-order.order_id}}."
consumes:
- type: http
namespace: sap-mm
baseUri: "https://sanofi-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: "/StockTransferOrder"
operations:
- name: create-transfer
method: POST
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Advances a ServiceNow change request to CAB approval state and notifies the requester in Teams with review timeline and next steps.
naftiko: "0.5"
info:
label: "ServiceNow Change Request Approval"
description: "Advances a ServiceNow change request to CAB approval state and notifies the requester in Teams with review timeline and next steps."
tags:
- itsm
- change-management
- servicenow
- microsoft-teams
- approval
capability:
exposes:
- type: mcp
namespace: itsm-change
port: 8080
tools:
- name: submit-change-for-approval
description: "Given a ServiceNow change request number, advance it to CAB approval state and notify the requester in Teams."
inputParameters:
- name: change_number
in: body
type: string
description: "The ServiceNow change request number (e.g., CHG0099887)."
- name: requester_email
in: body
type: string
description: "The Teams UPN of the change requester."
steps:
- name: get-change
type: call
call: "servicenow-chg.get-change"
with:
number: "{{change_number}}"
- name: submit-approval
type: call
call: "servicenow-chg.update-change"
with:
sys_id: "{{get-change.sys_id}}"
state: "approval"
- name: notify-requester
type: call
call: "msteams-chg.post-message"
with:
recipient: "{{requester_email}}"
message: "Your change request {{change_number}} has been submitted for CAB approval."
consumes:
- type: http
namespace: servicenow-chg
baseUri: "https://sanofi.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: changes
path: "/table/change_request"
operations:
- name: get-change
method: GET
- name: update-change
method: PATCH
- type: http
namespace: msteams-chg
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/chats/{{chat_id}}/messages"
inputParameters:
- name: chat_id
in: path
operations:
- name: post-message
method: POST
Retrieves a configuration item from the ServiceNow CMDB by asset tag, returning owner, status, and location.
naftiko: "0.5"
info:
label: "ServiceNow CMDB Asset Lookup"
description: "Retrieves a configuration item from the ServiceNow CMDB by asset tag, returning owner, status, and location."
tags:
- it-asset-management
- servicenow
capability:
exposes:
- type: mcp
namespace: itsm-cmdb
port: 8080
tools:
- name: get-cmdb-asset
description: "Look up a ServiceNow CMDB configuration item by asset tag. Returns owner, operational status, and physical location."
inputParameters:
- name: asset_tag
in: body
type: string
description: "The asset tag identifier."
call: "servicenow.get-ci"
with:
sysparm_query: "asset_tag={{asset_tag}}"
outputParameters:
- name: owner
type: string
mapping: "$.result[0].owned_by.display_value"
- name: status
type: string
mapping: "$.result[0].operational_status"
- name: location
type: string
mapping: "$.result[0].location.display_value"
consumes:
- type: http
namespace: servicenow
baseUri: "https://sanofi.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: cmdb-ci
path: "/table/cmdb_ci"
operations:
- name: get-ci
method: GET
Returns the current state, priority, assignment group, and short description of a ServiceNow incident by number for rapid triage.
naftiko: "0.5"
info:
label: "ServiceNow Incident Status Lookup"
description: "Returns the current state, priority, assignment group, and short description of a ServiceNow incident by number for rapid triage."
tags:
- itsm
- servicenow
- triage
- operations
capability:
exposes:
- type: mcp
namespace: itsm-lookup
port: 8080
tools:
- name: get-incident-status
description: "Given a ServiceNow incident number, return its current state, priority, assignment group, and description. Use for rapid triage or pre-war-room briefing."
inputParameters:
- name: incident_number
in: body
type: string
description: "The ServiceNow incident number (e.g., INC0123456)."
call: "servicenow-lookup.get-incident"
with:
number: "{{incident_number}}"
outputParameters:
- name: state
type: string
mapping: "$.result[0].state"
- name: priority
type: string
mapping: "$.result[0].priority"
- name: assignment_group
type: string
mapping: "$.result[0].assignment_group.display_value"
- name: short_description
type: string
mapping: "$.result[0].short_description"
consumes:
- type: http
namespace: servicenow-lookup
baseUri: "https://sanofi.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: incidents
path: "/table/incident"
operations:
- name: get-incident
method: GET
Searches ServiceNow knowledge base by keyword, returning matching articles with titles, summaries, and links for employee self-service.
naftiko: "0.5"
info:
label: "ServiceNow Knowledge Article Lookup"
description: "Searches ServiceNow knowledge base by keyword, returning matching articles with titles, summaries, and links for employee self-service."
tags:
- it-service-management
- servicenow
capability:
exposes:
- type: mcp
namespace: itsm-knowledge
port: 8080
tools:
- name: search-knowledge-articles
description: "Search ServiceNow knowledge base articles by keyword. Returns matching article titles, short descriptions, and URLs."
inputParameters:
- name: query
in: body
type: string
description: "The search keyword or phrase."
call: "servicenow.search-kb"
with:
sysparm_query: "short_descriptionLIKE{{query}}"
outputParameters:
- name: articles
type: array
mapping: "$.result"
consumes:
- type: http
namespace: servicenow
baseUri: "https://sanofi.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: knowledge-articles
path: "/table/kb_knowledge"
operations:
- name: search-kb
method: GET
Lists documents in a SharePoint document library by site and library name, returning file names, sizes, and last modified dates.
naftiko: "0.5"
info:
label: "SharePoint Document Library Listing"
description: "Lists documents in a SharePoint document library by site and library name, returning file names, sizes, and last modified dates."
tags:
- collaboration
- sharepoint
capability:
exposes:
- type: mcp
namespace: collab-docs
port: 8080
tools:
- name: list-documents
description: "List files in a SharePoint document library. Returns file names, sizes, and last modified dates."
inputParameters:
- name: site_id
in: body
type: string
description: "The SharePoint site ID."
- name: library_name
in: body
type: string
description: "The document library name."
call: "sharepoint.list-items"
with:
site_id: "{{site_id}}"
library: "{{library_name}}"
outputParameters:
- name: files
type: array
mapping: "$.value"
consumes:
- type: http
namespace: sharepoint
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: drive-items
path: "/sites/{{site_id}}/drives"
inputParameters:
- name: site_id
in: path
operations:
- name: list-items
method: GET
Identifies SOPs due for periodic review in SharePoint, creates review tasks in Jira, and notifies document owners via Teams.
naftiko: "0.5"
info:
label: "SharePoint SOP Review Reminder"
description: "Identifies SOPs due for periodic review in SharePoint, creates review tasks in Jira, and notifies document owners via Teams."
tags:
- quality
- compliance
- sharepoint
- jira
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: quality-sop-review
port: 8080
tools:
- name: trigger-sop-review
description: "Trigger SOP review cycle: find due SOPs in SharePoint, create Jira tasks, and notify owners."
inputParameters:
- name: site_id
in: body
type: string
description: "The SharePoint site ID containing SOPs."
steps:
- name: get-due-sops
type: call
call: "sharepoint.list-items"
with:
site_id: "{{site_id}}"
filter: "reviewDueDate le today"
- name: create-review-task
type: call
call: "jira.create-issue"
with:
project: "QUALITY"
summary: "SOP periodic review due"
issue_type: "Task"
- name: notify-owners
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.quality_team_id"
channel_id: "$secrets.quality_channel_id"
body: "SOP review cycle initiated. Review tasks created in Jira. Please check your assignments."
consumes:
- type: http
namespace: sharepoint
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: drive-items
path: "/sites/{{site_id}}/drives"
inputParameters:
- name: site_id
in: path
operations:
- name: list-items
method: GET
- type: http
namespace: jira
baseUri: "https://sanofi.atlassian.net/rest/api/3"
authentication:
type: basic
username: "$secrets.jira_user"
password: "$secrets.jira_api_token"
resources:
- name: issues
path: "/issue"
operations:
- name: create-issue
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Queries Snowflake for recent pipeline execution failures and posts a health digest to the data engineering channel in Microsoft Teams.
naftiko: "0.5"
info:
label: "Snowflake Data Pipeline Health Check"
description: "Queries Snowflake for recent pipeline execution failures and posts a health digest to the data engineering channel in Microsoft Teams."
tags:
- data
- snowflake
- microsoft-teams
- monitoring
- analytics
capability:
exposes:
- type: mcp
namespace: data-ops
port: 8080
tools:
- name: check-pipeline-health
description: "Query Snowflake task execution history for failures or delays in the past 24 hours and post a pipeline health summary to the data engineering Teams channel."
inputParameters:
- name: database
in: body
type: string
description: "The Snowflake database to check pipeline health for."
- name: hours_back
in: body
type: integer
description: "Number of hours of task history to review (e.g., 24)."
steps:
- name: get-task-history
type: call
call: "snowflake-ops.query-task-history"
with:
database: "{{database}}"
hoursBack: "{{hours_back}}"
- name: post-summary
type: call
call: "msteams-data.post-message"
with:
channel: "data-engineering"
message: "Snowflake pipeline health for {{database}} (last {{hours_back}}h): {{get-task-history.summary}}"
consumes:
- type: http
namespace: snowflake-ops
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: task-history
path: "/databases/{{database}}/tasks/history"
inputParameters:
- name: database
in: path
operations:
- name: query-task-history
method: GET
- type: http
namespace: msteams-data
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-message
method: POST
Grants Snowflake data sharing access by validating the request in ServiceNow, executing the share command in Snowflake, and logging the grant in the governance audit trail.
naftiko: "0.5"
info:
label: "Snowflake Data Sharing Access Grant"
description: "Grants Snowflake data sharing access by validating the request in ServiceNow, executing the share command in Snowflake, and logging the grant in the governance audit trail."
tags:
- data-governance
- snowflake
- servicenow
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: data-sharing
port: 8080
tools:
- name: grant-data-share
description: "Grant data share access: validate request, execute share, and log for governance."
inputParameters:
- name: share_name
in: body
type: string
description: "The Snowflake share name."
- name: consumer_account
in: body
type: string
description: "The consumer Snowflake account."
- name: approval_ticket
in: body
type: string
description: "The ServiceNow approval ticket number."
steps:
- name: validate-approval
type: call
call: "servicenow.get-change"
with:
number: "{{approval_ticket}}"
- name: execute-share
type: call
call: "snowflake.run-query"
with:
statement: "ALTER SHARE {{share_name}} ADD ACCOUNTS = {{consumer_account}}"
- name: log-governance
type: call
call: "snowflake.run-query"
with:
statement: "INSERT INTO governance.data_sharing_log (share_name, consumer_account, approval_ticket, granted_at) VALUES ('{{share_name}}', '{{consumer_account}}', '{{approval_ticket}}', CURRENT_TIMESTAMP())"
- name: notify-governance
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.governance_team_id"
channel_id: "$secrets.governance_channel_id"
body: "Data share {{share_name}} granted to {{consumer_account}}. Approval: {{approval_ticket}}."
consumes:
- type: http
namespace: servicenow
baseUri: "https://sanofi.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: change-requests
path: "/table/change_request"
operations:
- name: get-change
method: GET
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Identifies the slowest-running Snowflake queries in the past 24 hours and posts an optimization digest to the data engineering channel in Teams.
naftiko: "0.5"
info:
label: "Snowflake Query Performance Digest"
description: "Identifies the slowest-running Snowflake queries in the past 24 hours and posts an optimization digest to the data engineering channel in Teams."
tags:
- data
- snowflake
- microsoft-teams
- performance
- analytics
capability:
exposes:
- type: mcp
namespace: data-performance
port: 8080
tools:
- name: digest-slow-queries
description: "Query Snowflake's query history to identify the 10 slowest-running queries in the last 24 hours and post an optimization digest to the data engineering Teams channel."
inputParameters:
- name: warehouse
in: body
type: string
description: "The Snowflake virtual warehouse to analyze query performance for."
steps:
- name: get-slow-queries
type: call
call: "snowflake-perf.query-history"
with:
warehouse: "{{warehouse}}"
- name: post-digest
type: call
call: "msteams-perf.post-message"
with:
channel: "data-engineering"
message: "Top slow queries in warehouse {{warehouse}} (last 24h): {{get-slow-queries.summary}}"
consumes:
- type: http
namespace: snowflake-perf
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: query-history
path: "/warehouses/{{warehouse}}/queries"
inputParameters:
- name: warehouse
in: path
operations:
- name: query-history
method: GET
- type: http
namespace: msteams-perf
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-message
method: POST
Queries Snowflake to return the row count for a specified table, used for data pipeline validation and monitoring.
naftiko: "0.5"
info:
label: "Snowflake Table Row Count Check"
description: "Queries Snowflake to return the row count for a specified table, used for data pipeline validation and monitoring."
tags:
- data-engineering
- snowflake
capability:
exposes:
- type: mcp
namespace: data-quality
port: 8080
tools:
- name: get-table-row-count
description: "Query Snowflake for the row count of a given table. Use for data pipeline completeness checks."
inputParameters:
- name: table_name
in: body
type: string
description: "Fully qualified Snowflake table name (database.schema.table)."
call: "snowflake.run-query"
with:
statement: "SELECT COUNT(*) AS row_count FROM {{table_name}}"
outputParameters:
- name: row_count
type: integer
mapping: "$.data[0][0]"
consumes:
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
Assesses supplier risk by pulling vendor data from SAP, checking compliance scores in Snowflake, and creating risk review tickets in ServiceNow.
naftiko: "0.5"
info:
label: "Supplier Risk Assessment Orchestrator"
description: "Assesses supplier risk by pulling vendor data from SAP, checking compliance scores in Snowflake, and creating risk review tickets in ServiceNow."
tags:
- procurement
- risk-management
- sap
- snowflake
- servicenow
capability:
exposes:
- type: mcp
namespace: procurement-risk
port: 8080
tools:
- name: assess-supplier-risk
description: "Assess supplier risk: get vendor data, check compliance scores, and create risk review."
inputParameters:
- name: vendor_id
in: body
type: string
description: "The SAP vendor ID."
steps:
- name: get-vendor-data
type: call
call: "sap-mm.get-vendor"
with:
vendor_id: "{{vendor_id}}"
- name: get-compliance-score
type: call
call: "snowflake.run-query"
with:
statement: "SELECT risk_score, last_audit_date, compliance_status FROM procurement.supplier_risk WHERE vendor_id='{{vendor_id}}'"
- name: create-risk-review
type: call
call: "servicenow.create-incident"
with:
short_description: "Supplier risk review: {{get-vendor-data.CompanyName}} ({{vendor_id}})"
category: "supplier_risk"
assigned_group: "Procurement_Risk"
consumes:
- type: http
namespace: sap-mm
baseUri: "https://sanofi-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_BusinessPartner('{{vendor_id}}')"
inputParameters:
- name: vendor_id
in: path
operations:
- name: get-vendor
method: GET
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: servicenow
baseUri: "https://sanofi.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
Monitors SAP inventory levels, triggers a purchase requisition when stock falls below threshold, and alerts the supply chain team via Teams.
naftiko: "0.5"
info:
label: "Supply Chain Inventory Reorder Trigger"
description: "Monitors SAP inventory levels, triggers a purchase requisition when stock falls below threshold, and alerts the supply chain team via Teams."
tags:
- supply-chain
- sap
- sap-ariba
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: scm-reorder
port: 8080
tools:
- name: trigger-reorder
description: "Check inventory levels and trigger reorder if below threshold."
inputParameters:
- name: material_number
in: body
type: string
description: "The SAP material number."
- name: plant
in: body
type: string
description: "The SAP plant code."
steps:
- name: check-inventory
type: call
call: "sap-mm.get-stock"
with:
material: "{{material_number}}"
plant: "{{plant}}"
- name: create-requisition
type: call
call: "ariba.create-requisition"
with:
material: "{{material_number}}"
quantity: "{{check-inventory.reorder_quantity}}"
plant: "{{plant}}"
- name: notify-supply-chain
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.scm_team_id"
channel_id: "$secrets.scm_channel_id"
body: "Reorder triggered for material {{material_number}} at plant {{plant}}. Requisition {{create-requisition.id}} created."
consumes:
- type: http
namespace: sap-mm
baseUri: "https://sanofi-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
- 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
- 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
Handles temperature excursions in vaccine cold chain by logging the event in SAP QM, creating a quality deviation in Veeva Vault, and alerting supply chain quality via Teams.
naftiko: "0.5"
info:
label: "Vaccine Cold Chain Temperature Excursion Handler"
description: "Handles temperature excursions in vaccine cold chain by logging the event in SAP QM, creating a quality deviation in Veeva Vault, and alerting supply chain quality via Teams."
tags:
- supply-chain
- quality
- sap
- veeva
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: scm-cold-chain
port: 8080
tools:
- name: handle-temperature-excursion
description: "Handle cold chain temperature excursion: log in SAP, create deviation, and alert quality team."
inputParameters:
- name: shipment_id
in: body
type: string
description: "The shipment identifier."
- name: max_temperature
in: body
type: string
description: "The maximum recorded temperature."
- name: location
in: body
type: string
description: "The location where excursion occurred."
steps:
- name: log-excursion
type: call
call: "sap-qm.create-notification"
with:
type: "temperature_excursion"
shipment: "{{shipment_id}}"
temperature: "{{max_temperature}}"
location: "{{location}}"
- name: create-deviation
type: call
call: "veeva-vault.create-document"
with:
type: "quality_deviation"
description: "Temperature excursion on shipment {{shipment_id}} at {{location}}. Max temp: {{max_temperature}}"
- name: alert-quality
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.scm_quality_team_id"
channel_id: "$secrets.scm_quality_channel_id"
body: "ALERT: Temperature excursion on shipment {{shipment_id}} at {{location}}. Max temp: {{max_temperature}}. SAP notification: {{log-excursion.notification_id}}. Deviation: {{create-deviation.id}}."
consumes:
- type: http
namespace: sap-qm
baseUri: "https://sanofi-s4.sap.com/sap/opu/odata/sap/API_QUALITYNOTIFICATION_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: notifications
path: "/QualityNotification"
operations:
- name: create-notification
method: POST
- type: http
namespace: veeva-vault
baseUri: "https://sanofi.veevavault.com/api/v24.1"
authentication:
type: bearer
token: "$secrets.veeva_vault_token"
resources:
- name: documents
path: "/objects/documents"
operations:
- name: create-document
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Retrieves healthcare professional account details from Veeva CRM by account ID, returning specialty, address, and territory.
naftiko: "0.5"
info:
label: "Veeva CRM Account Detail Lookup"
description: "Retrieves healthcare professional account details from Veeva CRM by account ID, returning specialty, address, and territory."
tags:
- commercial
- veeva
capability:
exposes:
- type: mcp
namespace: commercial-crm
port: 8080
tools:
- name: get-hcp-account
description: "Look up a Veeva CRM HCP account by ID. Returns specialty, primary address, and territory assignment."
inputParameters:
- name: account_id
in: body
type: string
description: "The Veeva CRM account ID."
call: "veeva-crm.get-account"
with:
account_id: "{{account_id}}"
outputParameters:
- name: specialty
type: string
mapping: "$.Specialty_1_vod__c"
- name: address
type: string
mapping: "$.Primary_Address_vod__c"
- name: territory
type: string
mapping: "$.Territory_vod__c"
consumes:
- type: http
namespace: veeva-crm
baseUri: "https://sanofi.veevanetwork.com/api/v1"
authentication:
type: bearer
token: "$secrets.veeva_crm_token"
resources:
- name: accounts
path: "/accounts/{{account_id}}"
inputParameters:
- name: account_id
in: path
operations:
- name: get-account
method: GET
When a sales territory is reorganized, updates Veeva CRM account assignments for the affected medical representatives and notifies the commercial ops team in Teams.
naftiko: "0.5"
info:
label: "Veeva CRM Territory Assignment Update"
description: "When a sales territory is reorganized, updates Veeva CRM account assignments for the affected medical representatives and notifies the commercial ops team in Teams."
tags:
- crm
- veeva
- microsoft-teams
- sales-ops
- pharma
- territory-management
capability:
exposes:
- type: mcp
namespace: crm-territory
port: 8080
tools:
- name: update-territory-assignment
description: "Given a Veeva CRM territory ID and new representative ID, update all account assignments in the territory and notify the commercial operations team in Teams."
inputParameters:
- name: territory_id
in: body
type: string
description: "The Veeva CRM territory ID being reassigned."
- name: new_rep_id
in: body
type: string
description: "The Veeva CRM user ID of the new medical representative."
- name: effective_date
in: body
type: string
description: "The effective date of the territory change in YYYY-MM-DD format."
steps:
- name: get-territory
type: call
call: "veeva-crm.get-territory"
with:
territory_id: "{{territory_id}}"
- name: update-assignment
type: call
call: "veeva-crm.update-territory-rep"
with:
territory_id: "{{territory_id}}"
rep_id: "{{new_rep_id}}"
effectiveDate: "{{effective_date}}"
- name: notify-commercial-ops
type: call
call: "msteams-crm.post-message"
with:
channel: "commercial-operations"
message: "Territory {{territory_id}} ({{get-territory.name}}) reassigned to rep {{new_rep_id}} effective {{effective_date}}."
consumes:
- type: http
namespace: veeva-crm
baseUri: "https://sanofi.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.veeva_crm_token"
resources:
- name: territories
path: "/sobjects/Territory2/{{territory_id}}"
inputParameters:
- name: territory_id
in: path
operations:
- name: get-territory
method: GET
- name: update-territory-rep
method: PATCH
- type: http
namespace: msteams-crm
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-message
method: POST
Manages promotional material review by checking document status in Veeva Vault, verifying compliance claims in Snowflake, and routing approval notifications via Teams.
naftiko: "0.5"
info:
label: "Veeva PromoMats Review and Approval"
description: "Manages promotional material review by checking document status in Veeva Vault, verifying compliance claims in Snowflake, and routing approval notifications via Teams."
tags:
- commercial
- compliance
- veeva
- snowflake
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: commercial-promomats
port: 8080
tools:
- name: review-promomat
description: "Review promotional material: check Veeva status, verify claims, and route approval."
inputParameters:
- name: document_id
in: body
type: string
description: "The Veeva Vault promotional material document ID."
steps:
- name: get-promomat
type: call
call: "veeva-vault.get-document"
with:
doc_id: "{{document_id}}"
- name: verify-claims
type: call
call: "snowflake.run-query"
with:
statement: "SELECT claim_text, approved, reference_id FROM commercial.promomat_claims WHERE document_id='{{document_id}}'"
- name: route-approval
type: call
call: "msteams.post-message"
with:
recipient: "{{get-promomat.reviewer_email}}"
message: "Promotional material {{document_id}} ready for review. Status: {{get-promomat.status__v}}. Claims verification complete."
consumes:
- type: http
namespace: veeva-vault
baseUri: "https://sanofi.veevavault.com/api/v24.1"
authentication:
type: bearer
token: "$secrets.veeva_vault_token"
resources:
- name: documents
path: "/objects/documents/{{doc_id}}"
inputParameters:
- name: doc_id
in: path
operations:
- name: get-document
method: GET
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-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: "/chats/{{chat_id}}/messages"
inputParameters:
- name: chat_id
in: path
operations:
- name: post-message
method: POST
When a clinical document is approved in Veeva Vault, retrieves its metadata and posts a Teams notification to the regulatory affairs team to initiate submission workflows.
naftiko: "0.5"
info:
label: "Veeva Vault Clinical Document Submission"
description: "When a clinical document is approved in Veeva Vault, retrieves its metadata and posts a Teams notification to the regulatory affairs team to initiate submission workflows."
tags:
- regulatory
- veeva
- microsoft-teams
- clinical-operations
- pharma
capability:
exposes:
- type: mcp
namespace: regulatory-submissions
port: 8080
tools:
- name: notify-document-approval
description: "Given a Veeva Vault document ID, retrieve its approval status and metadata, then notify the regulatory affairs team in Teams to proceed with submission activities."
inputParameters:
- name: document_id
in: body
type: string
description: "The Veeva Vault document ID that has been approved."
- name: submission_type
in: body
type: string
description: "The regulatory submission type (e.g., IND, NDA, MAA)."
steps:
- name: get-document
type: call
call: "veeva.get-document"
with:
doc_id: "{{document_id}}"
- name: notify-reg-affairs
type: call
call: "msteams-reg.post-message"
with:
channel: "regulatory-affairs"
message: "Document {{document_id}} ({{get-document.name}}) approved in Veeva. Submission type: {{submission_type}}. Please initiate filing workflow."
consumes:
- type: http
namespace: veeva
baseUri: "https://sanofi.veevavault.com/api/v21.1"
authentication:
type: bearer
token: "$secrets.veeva_token"
resources:
- name: documents
path: "/objects/documents/{{doc_id}}"
inputParameters:
- name: doc_id
in: path
operations:
- name: get-document
method: GET
- type: http
namespace: msteams-reg
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-message
method: POST
Retrieves clinical trial milestone status from Veeva Vault for a given study, returning milestone completion dates, upcoming deadlines, and at-risk indicators.
naftiko: "0.5"
info:
label: "Veeva Vault Clinical Trial Milestone Tracker"
description: "Retrieves clinical trial milestone status from Veeva Vault for a given study, returning milestone completion dates, upcoming deadlines, and at-risk indicators."
tags:
- clinical-trials
- veeva
- regulatory
- milestones
capability:
exposes:
- type: mcp
namespace: vault-milestones
port: 8080
tools:
- name: get-trial-milestones
description: "Look up clinical trial milestone status for a study by study number in Veeva Vault."
inputParameters:
- name: study_number
in: body
type: string
description: "The clinical study number."
call: "veeva.get-milestones"
with:
study_number: "{{study_number}}"
outputParameters:
- name: milestones
type: array
mapping: "$.data"
- name: at_risk_count
type: number
mapping: "$.summary.atRiskCount"
- name: next_deadline
type: string
mapping: "$.summary.nextDeadline"
consumes:
- type: http
namespace: veeva
baseUri: "https://sanofi.veevavault.com/api/v24.1"
authentication:
type: bearer
token: "$secrets.veeva_vault_token"
resources:
- name: milestones
path: "/query?q=SELECT+milestone_name__v,+status__v,+planned_date__v,+actual_date__v+FROM+study_milestone__v+WHERE+study__vr.name__v='{{study_number}}'"
inputParameters:
- name: study_number
in: query
operations:
- name: get-milestones
method: GET
Retrieves the lifecycle status of a document in Veeva Vault by document ID, returning current state, owner, and last modified date.
naftiko: "0.5"
info:
label: "Veeva Vault Document Status Lookup"
description: "Retrieves the lifecycle status of a document in Veeva Vault by document ID, returning current state, owner, and last modified date."
tags:
- regulatory
- veeva
capability:
exposes:
- type: mcp
namespace: regulatory-docs
port: 8080
tools:
- name: get-document-status
description: "Look up a Veeva Vault document status by document ID. Returns lifecycle state, owner, and last modification timestamp."
inputParameters:
- name: document_id
in: body
type: string
description: "The Veeva Vault document ID."
call: "veeva-vault.get-document"
with:
doc_id: "{{document_id}}"
outputParameters:
- name: status
type: string
mapping: "$.document.status__v"
- name: owner
type: string
mapping: "$.document.owner__v"
- name: last_modified
type: string
mapping: "$.document.modified_date__v"
consumes:
- type: http
namespace: veeva-vault
baseUri: "https://sanofi.veevavault.com/api/v24.1"
authentication:
type: bearer
token: "$secrets.veeva_vault_token"
resources:
- name: documents
path: "/objects/documents/{{doc_id}}"
inputParameters:
- name: doc_id
in: path
operations:
- name: get-document
method: GET
Retrieves the current regulatory submission status for a given dossier from Veeva Vault, returning lifecycle state, country, and last update date.
naftiko: "0.5"
info:
label: "Veeva Vault Regulatory Submission Status Lookup"
description: "Retrieves the current regulatory submission status for a given dossier from Veeva Vault, returning lifecycle state, country, and last update date."
tags:
- regulatory
- veeva
- pharma
- compliance
- reporting
capability:
exposes:
- type: mcp
namespace: regulatory-lookup
port: 8080
tools:
- name: get-submission-status
description: "Look up the regulatory submission status for a Veeva Vault dossier by ID. Returns lifecycle state, target country, and last modified date. Use for regulatory timeline tracking."
inputParameters:
- name: dossier_id
in: body
type: string
description: "The Veeva Vault dossier document ID."
call: "veeva-reg.get-submission"
with:
doc_id: "{{dossier_id}}"
outputParameters:
- name: lifecycle_state
type: string
mapping: "$.data[0].lifecycle_state__v"
- name: country
type: string
mapping: "$.data[0].country__v"
- name: last_modified
type: string
mapping: "$.data[0].modified_date__v"
consumes:
- type: http
namespace: veeva-reg
baseUri: "https://sanofi.veevavault.com/api/v21.1"
authentication:
type: bearer
token: "$secrets.veeva_token"
resources:
- name: submissions
path: "/objects/documents/{{doc_id}}"
inputParameters:
- name: doc_id
in: path
operations:
- name: get-submission
method: GET
Performs automated three-way matching of a vendor invoice against the SAP purchase order and goods receipt, then routes discrepancies to ServiceNow for resolution.
naftiko: "0.5"
info:
label: "Vendor Invoice Three-Way Match"
description: "Performs automated three-way matching of a vendor invoice against the SAP purchase order and goods receipt, then routes discrepancies to ServiceNow for resolution."
tags:
- finance
- procurement
- sap
- servicenow
capability:
exposes:
- type: mcp
namespace: finance-ap
port: 8080
tools:
- name: three-way-match
description: "Perform three-way match for a vendor invoice: retrieve PO, check goods receipt, compare amounts, and create a ServiceNow ticket if discrepancies exist."
inputParameters:
- name: invoice_number
in: body
type: string
description: "The vendor invoice number."
- name: po_number
in: body
type: string
description: "The SAP purchase order number."
steps:
- name: get-po
type: call
call: "sap-po.get-po"
with:
po_number: "{{po_number}}"
- name: get-receipt
type: call
call: "sap-gr.get-receipt"
with:
po_number: "{{po_number}}"
- name: get-invoice
type: call
call: "sap-fi.get-invoice"
with:
invoice_number: "{{invoice_number}}"
- name: create-discrepancy-ticket
type: call
call: "servicenow.create-incident"
with:
short_description: "Invoice {{invoice_number}} three-way match discrepancy for PO {{po_number}}"
category: "finance_ap"
assigned_group: "AP_Resolution"
consumes:
- type: http
namespace: sap-po
baseUri: "https://sanofi-s4.sap.com/sap/opu/odata/sap/MM_PUR_PO_MAINT_V2_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: purchase-orders
path: "/A_PurchaseOrder('{{po_number}}')"
inputParameters:
- name: po_number
in: path
operations:
- name: get-po
method: GET
- type: http
namespace: sap-gr
baseUri: "https://sanofi-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: get-receipt
method: GET
- type: http
namespace: sap-fi
baseUri: "https://sanofi-s4.sap.com/sap/opu/odata/sap/API_SUPPLIERINVOICE_PROCESS_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: invoices
path: "/A_SupplierInvoice('{{invoice_number}}')"
inputParameters:
- name: invoice_number
in: path
operations:
- name: get-invoice
method: GET
- type: http
namespace: servicenow
baseUri: "https://sanofi.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
Syncs benefits enrollment data from Workday to the insurance carrier via SAP, updates tracking in Snowflake, and confirms enrollment to the employee via Teams.
naftiko: "0.5"
info:
label: "Workday Benefits Enrollment Sync"
description: "Syncs benefits enrollment data from Workday to the insurance carrier via SAP, updates tracking in Snowflake, and confirms enrollment to the employee via Teams."
tags:
- hr
- benefits
- workday
- sap
- snowflake
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: hr-benefits
port: 8080
tools:
- name: sync-benefits-enrollment
description: "Sync benefits enrollment: extract from Workday, send to carrier, update tracking, and confirm."
inputParameters:
- name: worker_id
in: body
type: string
description: "The Workday worker ID."
- name: plan_code
in: body
type: string
description: "The benefits plan code."
steps:
- name: get-enrollment
type: call
call: "workday.get-benefits-enrollment"
with:
worker_id: "{{worker_id}}"
plan: "{{plan_code}}"
- name: send-to-carrier
type: call
call: "sap-hr.submit-benefits"
with:
employee_id: "{{get-enrollment.sapId}}"
plan: "{{plan_code}}"
coverage_level: "{{get-enrollment.coverageLevel}}"
- name: update-tracking
type: call
call: "snowflake.run-query"
with:
statement: "INSERT INTO hr.benefits_enrollment_log (worker_id, plan_code, coverage_level, synced_at) VALUES ('{{worker_id}}', '{{plan_code}}', '{{get-enrollment.coverageLevel}}', CURRENT_TIMESTAMP())"
- name: confirm-enrollment
type: call
call: "msteams.post-message"
with:
recipient: "{{get-enrollment.email}}"
message: "Your benefits enrollment for plan {{plan_code}} has been synced successfully."
consumes:
- type: http
namespace: workday
baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: benefits
path: "/sanofi/workers/{{worker_id}}/benefits"
inputParameters:
- name: worker_id
in: path
operations:
- name: get-benefits-enrollment
method: GET
- type: http
namespace: sap-hr
baseUri: "https://sanofi-s4.sap.com/sap/opu/odata/sap/API_BUSINESS_PARTNER"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: benefits
path: "/A_BusinessPartner"
operations:
- name: submit-benefits
method: POST
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-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: "/chats/{{chat_id}}/messages"
inputParameters:
- name: chat_id
in: path
operations:
- name: post-message
method: POST
Retrieves base pay, bonus target, and pay grade for a Workday employee by worker ID, for total rewards inquiries.
naftiko: "0.5"
info:
label: "Workday Compensation Detail Lookup"
description: "Retrieves base pay, bonus target, and pay grade for a Workday employee by worker ID, for total rewards inquiries."
tags:
- hr
- compensation
- workday
capability:
exposes:
- type: mcp
namespace: hr-compensation
port: 8080
tools:
- name: get-compensation
description: "Look up Workday compensation details by worker ID. Returns base pay, bonus target percentage, and pay grade."
inputParameters:
- name: worker_id
in: body
type: string
description: "The Workday worker ID."
call: "workday.get-compensation"
with:
worker_id: "{{worker_id}}"
outputParameters:
- name: base_pay
type: string
mapping: "$.compensation.basePay"
- name: bonus_target
type: string
mapping: "$.compensation.bonusTarget"
- name: pay_grade
type: string
mapping: "$.compensation.payGrade"
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: "/sanofi/workers/{{worker_id}}/compensation"
inputParameters:
- name: worker_id
in: path
operations:
- name: get-compensation
method: GET
Retrieves an employee profile from Workday by worker ID, returning name, department, job title, and manager for HR inquiries.
naftiko: "0.5"
info:
label: "Workday Employee Profile Lookup"
description: "Retrieves an employee profile from Workday by worker ID, returning name, department, job title, and manager for HR inquiries."
tags:
- hr
- workday
capability:
exposes:
- type: mcp
namespace: hr-employee
port: 8080
tools:
- name: get-employee-profile
description: "Look up a Workday employee profile by worker ID. Returns display name, department, job title, and manager. Use for HR data inquiries."
inputParameters:
- name: worker_id
in: body
type: string
description: "The Workday worker ID."
call: "workday.get-worker"
with:
worker_id: "{{worker_id}}"
outputParameters:
- name: display_name
type: string
mapping: "$.worker.displayName"
- name: department
type: string
mapping: "$.worker.department"
- name: job_title
type: string
mapping: "$.worker.jobTitle"
- name: manager
type: string
mapping: "$.worker.manager.displayName"
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: "/sanofi/workers/{{worker_id}}"
inputParameters:
- name: worker_id
in: path
operations:
- name: get-worker
method: GET
Captures a point-in-time headcount snapshot from Workday, loads it into Snowflake for trend analysis, and generates a Power BI dashboard refresh with summary posted to Teams.
naftiko: "0.5"
info:
label: "Workday Headcount Planning Snapshot"
description: "Captures a point-in-time headcount snapshot from Workday, loads it into Snowflake for trend analysis, and generates a Power BI dashboard refresh with summary posted to Teams."
tags:
- hr
- workforce-planning
- workday
- snowflake
- power-bi
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: hr-workforce-planning
port: 8080
tools:
- name: capture-headcount-snapshot
description: "Capture headcount snapshot: pull from Workday, load to Snowflake, refresh Power BI, and notify HR."
inputParameters:
- name: snapshot_date
in: body
type: string
description: "The snapshot date in YYYY-MM-DD format."
steps:
- name: get-headcount
type: call
call: "workday.get-headcount"
with:
effective_date: "{{snapshot_date}}"
- name: load-to-snowflake
type: call
call: "snowflake.run-query"
with:
statement: "INSERT INTO hr.headcount_snapshots (snapshot_date, total_headcount, captured_at) VALUES ('{{snapshot_date}}', '{{get-headcount.total}}', CURRENT_TIMESTAMP())"
- name: refresh-dashboard
type: call
call: "powerbi.trigger-refresh"
with:
dataset_id: "$secrets.headcount_dataset_id"
- name: notify-hr
type: call
call: "msteams.post-channel-message"
with:
team_id: "$secrets.hr_team_id"
channel_id: "$secrets.hr_channel_id"
body: "Headcount snapshot for {{snapshot_date}}: {{get-headcount.total}} employees. Dashboard refreshing."
consumes:
- type: http
namespace: workday
baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: headcount
path: "/sanofi/workers"
operations:
- name: get-headcount
method: GET
- type: http
namespace: snowflake
baseUri: "https://sanofi.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: run-query
method: POST
- type: http
namespace: powerbi
baseUri: "https://api.powerbi.com/v1.0/myorg"
authentication:
type: bearer
token: "$secrets.powerbi_token"
resources:
- name: dataset-refresh
path: "/datasets/{{dataset_id}}/refreshes"
inputParameters:
- name: dataset_id
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/{{team_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: team_id
in: path
- name: channel_id
in: path
operations:
- name: post-channel-message
method: POST
Exports current active headcount by department and cost center from Workday for quarterly financial planning and workforce reporting.
naftiko: "0.5"
info:
label: "Workday Payroll Headcount Snapshot"
description: "Exports current active headcount by department and cost center from Workday for quarterly financial planning and workforce reporting."
tags:
- hr
- finance
- workday
- reporting
- headcount
capability:
exposes:
- type: mcp
namespace: hr-reporting
port: 8080
tools:
- name: get-headcount-snapshot
description: "Returns active headcount grouped by department and cost center from Workday. Use for quarterly planning, budgeting, or workforce analytics."
call: "workday-hc.get-workers"
outputParameters:
- name: employees
type: array
mapping: "$.data"
items:
- name: employee_id
type: string
mapping: "$.workdayId"
- name: full_name
type: string
mapping: "$.name"
- name: department
type: string
mapping: "$.department"
- name: cost_center
type: string
mapping: "$.costCenter"
consumes:
- type: http
namespace: workday-hc
baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: workers-export
path: "/sanofi/workers"
operations:
- name: get-workers
method: GET
When an employee's role changes in Workday, updates Microsoft Entra ID group memberships and notifies IT of any elevated permissions requiring security review.
naftiko: "0.5"
info:
label: "Workday Role Change Access Sync"
description: "When an employee's role changes in Workday, updates Microsoft Entra ID group memberships and notifies IT of any elevated permissions requiring security review."
tags:
- hr
- identity
- workday
- microsoft-365
- microsoft-teams
- access-management
- role-change
capability:
exposes:
- type: mcp
namespace: hr-access-sync
port: 8080
tools:
- name: sync-role-change-access
description: "Given a Workday employee ID and new role, update Microsoft Entra ID group memberships and notify the IT access review team in Teams."
inputParameters:
- name: employee_id
in: body
type: string
description: "The Workday worker ID of the employee whose role changed."
- name: new_role
in: body
type: string
description: "The new job title or role name."
- name: old_role
in: body
type: string
description: "The previous job title or role name."
steps:
- name: get-employee
type: call
call: "workday-role.get-worker"
with:
worker_id: "{{employee_id}}"
- name: update-groups
type: call
call: "msgraph-role.update-member-groups"
with:
userId: "{{get-employee.entraObjectId}}"
newRole: "{{new_role}}"
- name: notify-it
type: call
call: "msteams-role.post-message"
with:
channel: "it-access-reviews"
message: "Role change: {{get-employee.displayName}} moved from {{old_role}} to {{new_role}}. Entra groups updated. Review if privileged access changed."
consumes:
- type: http
namespace: workday-role
baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: workers
path: "/sanofi/workers/{{worker_id}}"
inputParameters:
- name: worker_id
in: path
operations:
- name: get-worker
method: GET
- type: http
namespace: msgraph-role
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: user-groups
path: "/users/{{userId}}/memberOf"
inputParameters:
- name: userId
in: path
operations:
- name: update-member-groups
method: POST
- type: http
namespace: msteams-role
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-message
method: POST
When a time-off request is submitted in Workday, notifies the employee's manager in Microsoft Teams so they can plan coverage proactively.
naftiko: "0.5"
info:
label: "Workday Time-Off Request Manager Notification"
description: "When a time-off request is submitted in Workday, notifies the employee's manager in Microsoft Teams so they can plan coverage proactively."
tags:
- hr
- workday
- microsoft-teams
- leave-management
capability:
exposes:
- type: mcp
namespace: hr-leave
port: 8080
tools:
- name: notify-timeoff-request
description: "Given a Workday time-off request ID, retrieve the request details and send a notification to the manager in Teams."
inputParameters:
- name: request_id
in: body
type: string
description: "The Workday time-off request ID."
steps:
- name: get-request
type: call
call: "workday-leave.get-timeoff-request"
with:
request_id: "{{request_id}}"
- name: notify-manager
type: call
call: "msteams-leave.post-message"
with:
recipient: "{{get-request.managerEmail}}"
message: "{{get-request.employeeName}} has submitted a time-off request from {{get-request.startDate}} to {{get-request.endDate}}. Please review in Workday."
consumes:
- type: http
namespace: workday-leave
baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: timeoff-requests
path: "/sanofi/timeOffRequests/{{request_id}}"
inputParameters:
- name: request_id
in: path
operations:
- name: get-timeoff-request
method: GET
- type: http
namespace: msteams-leave
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/chats/{{chat_id}}/messages"
inputParameters:
- name: chat_id
in: path
operations:
- name: post-message
method: POST