Merck Capabilities
Naftiko 0.5 capability definitions for Merck - 100 capabilities showing integration workflows and service orchestrations.
Retrieves a clinical study report from Veeva Vault and uses OpenAI to generate a structured executive summary for regulatory reviewers.
naftiko: "0.5"
info:
label: "AI-Assisted Clinical Study Report Summarization"
description: "Retrieves a clinical study report from Veeva Vault and uses OpenAI to generate a structured executive summary for regulatory reviewers."
tags:
- ai
- automation
- openai
- veeva
- clinical-trials
- regulatory
capability:
exposes:
- type: mcp
namespace: ai-clinical
port: 8080
tools:
- name: summarize-clinical-study-report
description: "Given a Veeva Vault document ID for a clinical study report, retrieve the document, generate a structured executive summary using OpenAI, and store the summary back in Veeva Vault as a related document."
inputParameters:
- name: vault_document_id
in: body
type: string
description: "The Veeva Vault document ID for the clinical study report to summarize."
steps:
- name: get-document
type: call
call: "veeva.get-document-content"
with:
document_id: "{{vault_document_id}}"
- name: generate-summary
type: call
call: "openai.create-completion"
with:
model: "gpt-4o"
prompt: "You are a regulatory affairs expert. Create a structured executive summary of this clinical study report with sections for: Study Objectives, Key Efficacy Results, Safety Summary, and Regulatory Conclusions: {{get-document.content}}"
- name: store-summary
type: call
call: "veeva.create-document"
with:
parent_document_id: "{{vault_document_id}}"
document_type: "Executive Summary"
content: "{{generate-summary.choices[0].message.content}}"
consumes:
- type: http
namespace: veeva
baseUri: "https://merck.veevavault.com/api/v21.2"
authentication:
type: bearer
token: "$secrets.veeva_token"
resources:
- name: document-content
path: "/objects/documents/{{document_id}}/file"
inputParameters:
- name: document_id
in: path
operations:
- name: get-document-content
method: GET
- name: documents
path: "/objects/documents"
operations:
- name: create-document
method: POST
- type: http
namespace: openai
baseUri: "https://api.openai.com/v1"
authentication:
type: bearer
token: "$secrets.openai_api_key"
resources:
- name: completions
path: "/chat/completions"
operations:
- name: create-completion
method: POST
Handles Azure Data Factory pipeline failures by creating a ServiceNow incident and notifying the data engineering team for Merck.
naftiko: "0.5"
info:
label: "Azure Data Factory Pipeline Failure Handler"
description: "Handles Azure Data Factory pipeline failures by creating a ServiceNow incident and notifying the data engineering team for Merck."
tags:
- data-engineering
- azure-data-factory
- servicenow
- monitoring
capability:
exposes:
- type: mcp
namespace: data-engineering
port: 8080
tools:
- name: handle-adf-failure
description: "Given a pipeline run ID and failure details, create a ServiceNow incident and notify the team."
inputParameters:
- name: pipeline_name
in: body
type: string
description: "The ADF pipeline name."
- name: run_id
in: body
type: string
description: "The pipeline run ID."
- name: error_message
in: body
type: string
description: "The error message from the failed run."
steps:
- name: create-incident
type: call
call: servicenow.create-incident
with:
short_description: "ADF Pipeline Failure: {{pipeline_name}}"
description: "Pipeline: {{pipeline_name}} | Run: {{run_id}} | Error: {{error_message}}"
- name: notify-team
type: call
call: msteams.send-message
with:
channel_id: "$secrets.data_eng_channel"
text: "ADF Pipeline FAILURE: {{pipeline_name}} (Run: {{run_id}}). Error: {{error_message}}. SNOW: {{create-incident.number}}."
consumes:
- type: http
namespace: servicenow
baseUri: "https://merck.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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Retrieves the latest build status from Azure DevOps for a given pipeline in Merck CI/CD operations.
naftiko: "0.5"
info:
label: "Azure DevOps Build Status Lookup"
description: "Retrieves the latest build status from Azure DevOps for a given pipeline in Merck CI/CD operations."
tags:
- devops
- azure-devops
- ci-cd
- lookup
capability:
exposes:
- type: mcp
namespace: devops-ops
port: 8080
tools:
- name: get-build-status
description: "Given a pipeline ID, return the latest build result, status, and build number."
inputParameters:
- name: pipeline_id
in: body
type: string
description: "The Azure DevOps pipeline definition ID."
call: azdo.get-latest-build
with:
pipeline_id: "{{pipeline_id}}"
outputParameters:
- name: build_number
type: string
mapping: "$.value[0].buildNumber"
- name: result
type: string
mapping: "$.value[0].result"
- name: status
type: string
mapping: "$.value[0].status"
consumes:
- type: http
namespace: azdo
baseUri: "https://dev.azure.com/merck"
authentication:
type: bearer
token: "$secrets.azuredevops_token"
resources:
- name: builds
path: "/_apis/build/builds?definitions={{pipeline_id}}&$top=1&api-version=7.0"
inputParameters:
- name: pipeline_id
in: query
operations:
- name: get-latest-build
method: GET
Orchestrates the clinical database lock process by verifying data completeness in Snowflake, updating status in Veeva Vault, and notifying stakeholders for Merck.
naftiko: "0.5"
info:
label: "Clinical Data Lock Orchestrator"
description: "Orchestrates the clinical database lock process by verifying data completeness in Snowflake, updating status in Veeva Vault, and notifying stakeholders for Merck."
tags:
- clinical-trials
- data-management
- snowflake
- veeva-vault
capability:
exposes:
- type: mcp
namespace: clinical-data-mgmt
port: 8080
tools:
- name: execute-data-lock
description: "Given a study ID and database identifier, verify completeness, update lock status, and notify the team."
inputParameters:
- name: study_id
in: body
type: string
description: "The clinical study protocol number."
- name: database_id
in: body
type: string
description: "The clinical database identifier."
- name: lock_type
in: body
type: string
description: "Lock type (soft-lock, hard-lock)."
steps:
- name: verify-completeness
type: call
call: snowflake.execute-query
with:
statement: "SELECT COUNT(*) as open_queries FROM data_queries WHERE study_id = '{{study_id}}' AND status = 'Open'"
warehouse: "CLINICAL_WH"
- name: update-vault-status
type: call
call: veeva.update-object-record
with:
object_type: "study_database__c"
id: "{{database_id}}"
lock_status__c: "{{lock_type}}"
- name: notify-team
type: call
call: msteams.send-message
with:
channel_id: "$secrets.cdm_channel"
text: "Database Lock: Study {{study_id}} — {{lock_type}} initiated. Open queries: {{verify-completeness.data}}. Vault updated."
consumes:
- type: http
namespace: snowflake
baseUri: "https://merck.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: execute-query
method: POST
- type: http
namespace: veeva
baseUri: "https://merck.veevavault.com/api/v24.1"
authentication:
type: bearer
token: "$secrets.veeva_token"
resources:
- name: object-records
path: "/vobjects/{{object_type}}"
inputParameters:
- name: object_type
in: path
operations:
- name: create-object-record
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Reconciles clinical data between Veeva Vault and Snowflake, logs discrepancies in Jira, and alerts the data management team for Merck.
naftiko: "0.5"
info:
label: "Clinical Data Reconciliation Checker"
description: "Reconciles clinical data between Veeva Vault and Snowflake, logs discrepancies in Jira, and alerts the data management team for Merck."
tags:
- clinical-trials
- data-management
- veeva-vault
- snowflake
capability:
exposes:
- type: mcp
namespace: clinical-data-quality
port: 8080
tools:
- name: reconcile-clinical-data
description: "Given a study ID, compare record counts between Veeva Vault and Snowflake and report discrepancies."
inputParameters:
- name: study_id
in: body
type: string
description: "The clinical study protocol number."
- name: data_domain
in: body
type: string
description: "Data domain to reconcile (demographics, adverse-events, labs)."
steps:
- name: query-vault
type: call
call: veeva.query-submissions
with:
query: "SELECT COUNT(*) FROM {{data_domain}}__c WHERE study_id__c = '{{study_id}}'"
- name: query-snowflake
type: call
call: snowflake.execute-query
with:
statement: "SELECT COUNT(*) as cnt FROM {{data_domain}} WHERE study_id = '{{study_id}}'"
warehouse: "CLINICAL_WH"
- name: log-discrepancy
type: call
call: jira.create-issue
with:
project: "CDM"
summary: "Data Reconciliation: {{study_id}} — {{data_domain}}"
issuetype: "Bug"
- name: alert-team
type: call
call: msteams.send-message
with:
channel_id: "$secrets.cdm_channel"
text: "Data Reconciliation for Study {{study_id}} ({{data_domain}}): Vault={{query-vault.totalCount}}, Snowflake={{query-snowflake.data}}. Jira: {{log-discrepancy.key}}."
consumes:
- type: http
namespace: veeva
baseUri: "https://merck.veevavault.com/api/v24.1"
authentication:
type: bearer
token: "$secrets.veeva_token"
resources:
- name: object-records
path: "/vobjects/{{object_type}}"
inputParameters:
- name: object_type
in: path
operations:
- name: create-object-record
method: POST
- type: http
namespace: snowflake
baseUri: "https://merck.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: execute-query
method: POST
- type: http
namespace: jira
baseUri: "https://merck.atlassian.net/rest/api/3"
authentication:
type: bearer
token: "$secrets.jira_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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Tracks IRB approval status for clinical sites by querying Veeva Vault, updating Jira, and notifying the regulatory team for Merck.
naftiko: "0.5"
info:
label: "Clinical IRB Approval Tracking Orchestrator"
description: "Tracks IRB approval status for clinical sites by querying Veeva Vault, updating Jira, and notifying the regulatory team for Merck."
tags:
- clinical-trials
- regulatory
- veeva-vault
- jira
capability:
exposes:
- type: mcp
namespace: clinical-regulatory
port: 8080
tools:
- name: track-irb-approvals
description: "Given a study ID, check IRB approval status across sites, update tracking, and notify the team."
inputParameters:
- name: study_id
in: body
type: string
description: "The clinical study protocol number."
- name: region
in: body
type: string
description: "The geographic region to check."
steps:
- name: query-irb-status
type: call
call: veeva.query-submissions
with:
query: "SELECT site_id__c, irb_status__c FROM irb_submission__c WHERE study_id__c = '{{study_id}}' AND region__c = '{{region}}'"
- name: update-tracker
type: call
call: jira.create-issue
with:
project: "REG"
summary: "IRB Status Update: Study {{study_id}} — {{region}}"
issuetype: "Task"
- name: notify-team
type: call
call: msteams.send-message
with:
channel_id: "$secrets.regulatory_channel"
text: "IRB Approval Status for Study {{study_id}} ({{region}}): {{query-irb-status.totalCount}} sites tracked. Jira: {{update-tracker.key}}."
consumes:
- type: http
namespace: veeva
baseUri: "https://merck.veevavault.com/api/v24.1"
authentication:
type: bearer
token: "$secrets.veeva_token"
resources:
- name: query
path: "/query"
operations:
- name: query-submissions
method: POST
- type: http
namespace: jira
baseUri: "https://merck.atlassian.net/rest/api/3"
authentication:
type: bearer
token: "$secrets.jira_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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Processes clinical protocol amendments by updating Veeva Vault, creating Jira tracking tasks, and notifying the clinical team for Merck.
naftiko: "0.5"
info:
label: "Clinical Protocol Amendment Processor"
description: "Processes clinical protocol amendments by updating Veeva Vault, creating Jira tracking tasks, and notifying the clinical team for Merck."
tags:
- clinical-trials
- veeva-vault
- jira
- regulatory
capability:
exposes:
- type: mcp
namespace: clinical-regulatory
port: 8080
tools:
- name: process-protocol-amendment
description: "Given protocol amendment details, update the document in Veeva Vault, create a Jira task, and notify affected teams."
inputParameters:
- name: study_id
in: body
type: string
description: "The clinical study protocol number."
- name: amendment_number
in: body
type: string
description: "The amendment version number."
- name: amendment_summary
in: body
type: string
description: "Summary of protocol changes."
- name: impacted_sites
in: body
type: string
description: "Comma-separated list of impacted site IDs."
steps:
- name: update-vault
type: call
call: veeva.create-object-record
with:
object_type: "protocol_amendment__c"
study_id__c: "{{study_id}}"
amendment_number__c: "{{amendment_number}}"
- name: create-jira-task
type: call
call: jira.create-issue
with:
project: "CLIN"
summary: "Protocol Amendment {{amendment_number}} for Study {{study_id}}"
issuetype: "Task"
- name: notify-team
type: call
call: msteams.send-message
with:
channel_id: "$secrets.clinical_ops_channel"
text: "Protocol Amendment {{amendment_number}} for Study {{study_id}} processed. Impacted sites: {{impacted_sites}}. Jira: {{create-jira-task.key}}."
consumes:
- type: http
namespace: veeva
baseUri: "https://merck.veevavault.com/api/v24.1"
authentication:
type: bearer
token: "$secrets.veeva_token"
resources:
- name: object-records
path: "/vobjects/{{object_type}}"
inputParameters:
- name: object_type
in: path
operations:
- name: create-object-record
method: POST
- type: http
namespace: jira
baseUri: "https://merck.atlassian.net/rest/api/3"
authentication:
type: bearer
token: "$secrets.jira_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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Processes Suspected Unexpected Serious Adverse Reactions by logging in Veeva Vault, creating urgent ServiceNow cases, and alerting the DSMB for Merck.
naftiko: "0.5"
info:
label: "Clinical Safety Reporting SUSAR Handler"
description: "Processes Suspected Unexpected Serious Adverse Reactions by logging in Veeva Vault, creating urgent ServiceNow cases, and alerting the DSMB for Merck."
tags:
- drug-safety
- clinical-trials
- veeva-vault
- regulatory
capability:
exposes:
- type: mcp
namespace: clinical-safety
port: 8080
tools:
- name: process-susar
description: "Given SUSAR details, log in Veeva Vault, create an urgent ServiceNow case, and alert the DSMB."
inputParameters:
- name: study_id
in: body
type: string
description: "The clinical study protocol number."
- name: patient_id
in: body
type: string
description: "Anonymized patient identifier."
- name: event_term
in: body
type: string
description: "The adverse event MedDRA preferred term."
- name: seriousness_criteria
in: body
type: string
description: "Seriousness criteria met."
steps:
- name: log-in-vault
type: call
call: veeva.create-object-record
with:
object_type: "safety_case__c"
study_id__c: "{{study_id}}"
patient_id__c: "{{patient_id}}"
event_term__c: "{{event_term}}"
- name: create-urgent-case
type: call
call: servicenow.create-incident
with:
short_description: "SUSAR: {{event_term}} — Study {{study_id}}"
priority: "1"
- name: alert-dsmb
type: call
call: msteams.send-message
with:
channel_id: "$secrets.dsmb_channel"
text: "URGENT SUSAR: {{event_term}} in Study {{study_id}} (Patient {{patient_id}}). Seriousness: {{seriousness_criteria}}. Vault: {{log-in-vault.id}}. SNOW: {{create-urgent-case.number}}."
consumes:
- type: http
namespace: veeva
baseUri: "https://merck.veevavault.com/api/v24.1"
authentication:
type: bearer
token: "$secrets.veeva_token"
resources:
- name: object-records
path: "/vobjects/{{object_type}}"
inputParameters:
- name: object_type
in: path
operations:
- name: create-object-record
method: POST
- type: http
namespace: servicenow
baseUri: "https://merck.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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Creates monitoring visit schedules in Veeva Vault, assigns tasks in Jira, and notifies the CRA team for Merck.
naftiko: "0.5"
info:
label: "Clinical Site Monitoring Visit Scheduler"
description: "Creates monitoring visit schedules in Veeva Vault, assigns tasks in Jira, and notifies the CRA team for Merck."
tags:
- clinical-trials
- veeva-vault
- jira
- scheduling
capability:
exposes:
- type: mcp
namespace: clinical-monitoring
port: 8080
tools:
- name: schedule-monitoring-visit
description: "Given site and visit details, create a Veeva Vault record, a Jira task, and a Teams notification."
inputParameters:
- name: site_id
in: body
type: string
description: "The clinical site identifier."
- name: visit_type
in: body
type: string
description: "Type of monitoring visit (routine, for-cause, closeout)."
- name: visit_date
in: body
type: string
description: "Scheduled date for the visit."
- name: cra_name
in: body
type: string
description: "Name of the assigned CRA."
steps:
- name: create-vault-record
type: call
call: veeva.create-object-record
with:
object_type: "monitoring_visit__c"
site_id__c: "{{site_id}}"
visit_type__c: "{{visit_type}}"
visit_date__c: "{{visit_date}}"
- name: create-jira-task
type: call
call: jira.create-issue
with:
project: "CLIN"
summary: "Monitoring Visit: {{visit_type}} at Site {{site_id}} on {{visit_date}}"
issuetype: "Task"
- name: notify-cra-team
type: call
call: msteams.send-message
with:
channel_id: "$secrets.cra_channel"
text: "New {{visit_type}} monitoring visit at Site {{site_id}} on {{visit_date}}. CRA: {{cra_name}}. Jira: {{create-jira-task.key}}."
consumes:
- type: http
namespace: veeva
baseUri: "https://merck.veevavault.com/api/v24.1"
authentication:
type: bearer
token: "$secrets.veeva_token"
resources:
- name: object-records
path: "/vobjects/{{object_type}}"
inputParameters:
- name: object_type
in: path
operations:
- name: create-object-record
method: POST
- type: http
namespace: jira
baseUri: "https://merck.atlassian.net/rest/api/3"
authentication:
type: bearer
token: "$secrets.jira_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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Tracks clinical study budgets by pulling actuals from SAP, comparing to plan in Snowflake, and notifying finance for Merck.
naftiko: "0.5"
info:
label: "Clinical Study Budget Tracker"
description: "Tracks clinical study budgets by pulling actuals from SAP, comparing to plan in Snowflake, and notifying finance for Merck."
tags:
- clinical-trials
- finance
- sap
- snowflake
capability:
exposes:
- type: mcp
namespace: clinical-finance
port: 8080
tools:
- name: track-study-budget
description: "Given a study ID and fiscal period, pull actuals from SAP, compare to budget, and alert on variances."
inputParameters:
- name: study_id
in: body
type: string
description: "The clinical study protocol number."
- name: fiscal_period
in: body
type: string
description: "The fiscal period to analyze."
steps:
- name: get-actuals
type: call
call: sap.get-cost-report
with:
study_id: "{{study_id}}"
period: "{{fiscal_period}}"
- name: get-budget
type: call
call: snowflake.execute-query
with:
statement: "SELECT budget_amount, study_id FROM clinical_budgets WHERE study_id = '{{study_id}}' AND period = '{{fiscal_period}}'"
warehouse: "FINANCE_WH"
- name: notify-finance
type: call
call: msteams.send-message
with:
channel_id: "$secrets.clinical_finance_channel"
text: "Study Budget Alert: {{study_id}} for {{fiscal_period}}. Actuals: {{get-actuals.total}}. Budget: {{get-budget.data}}."
consumes:
- type: http
namespace: sap
baseUri: "https://merck-s4.sap.com/sap/opu/odata/sap/API_COSTCENTER_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: records
path: "/"
operations:
- name: get-record
method: GET
- type: http
namespace: snowflake
baseUri: "https://merck.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: execute-query
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Queries Snowflake for current enrollment figures by study, generates a summary, and posts to the clinical operations Teams channel for Merck.
naftiko: "0.5"
info:
label: "Clinical Trial Enrollment Status Reporter"
description: "Queries Snowflake for current enrollment figures by study, generates a summary, and posts to the clinical operations Teams channel for Merck."
tags:
- clinical-trials
- snowflake
- microsoft-teams
- reporting
capability:
exposes:
- type: mcp
namespace: clinical-ops
port: 8080
tools:
- name: report-enrollment-status
description: "Given a study ID, query enrollment data, format a summary, and post to the designated Teams channel."
inputParameters:
- name: study_id
in: body
type: string
description: "The clinical study protocol number."
- name: teams_channel_id
in: body
type: string
description: "Teams channel ID for clinical operations."
steps:
- name: query-enrollment
type: call
call: snowflake.execute-query
with:
statement: "SELECT site_id, enrolled_count, target FROM enrollment_tracker WHERE study_id = '{{study_id}}'"
warehouse: "CLINICAL_WH"
- name: post-summary
type: call
call: msteams.send-message
with:
channel_id: "{{teams_channel_id}}"
text: "Enrollment Status for Study {{study_id}}: {{query-enrollment.data}}"
consumes:
- type: http
namespace: snowflake
baseUri: "https://merck.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: execute-query
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
When a new clinical trial site is approved in Veeva Vault, creates a Salesforce account for the site, opens a ServiceNow onboarding task, and notifies the clinical operations team via Microsoft Teams.
naftiko: "0.5"
info:
label: "Clinical Trial Site Activation Orchestrator"
description: "When a new clinical trial site is approved in Veeva Vault, creates a Salesforce account for the site, opens a ServiceNow onboarding task, and notifies the clinical operations team via Microsoft Teams."
tags:
- clinical-trials
- veeva
- salesforce
- servicenow
- microsoft-teams
- onboarding
capability:
exposes:
- type: mcp
namespace: clinical-ops
port: 8080
tools:
- name: activate-trial-site
description: "Given a Veeva Vault clinical site record ID, retrieve site details, create a Salesforce account, open a ServiceNow onboarding task, and notify the clinical operations Microsoft Teams channel."
inputParameters:
- name: vault_site_id
in: body
type: string
description: "The Veeva Vault document or record ID for the newly approved clinical trial site."
- name: study_id
in: body
type: string
description: "The clinical study identifier this site is being activated for."
steps:
- name: get-site
type: call
call: "veeva.get-site-record"
with:
site_id: "{{vault_site_id}}"
- name: create-account
type: call
call: "salesforce.create-account"
with:
name: "{{get-site.site_name}}"
type: "Clinical Site"
country: "{{get-site.country}}"
- name: open-task
type: call
call: "servicenow.create-incident"
with:
short_description: "Site activation: {{get-site.site_name}} for Study {{study_id}}"
category: "clinical_operations"
- name: notify-team
type: call
call: "msteams.post-channel-message"
with:
channel_id: "clinical-operations"
message: "Site Activated: {{get-site.site_name}} for Study {{study_id}}. Salesforce: {{create-account.id}} | ServiceNow: {{open-task.number}}"
consumes:
- type: http
namespace: veeva
baseUri: "https://merck.veevavault.com/api/v21.2"
authentication:
type: bearer
token: "$secrets.veeva_token"
resources:
- name: site-records
path: "/objects/sites/{{site_id}}"
inputParameters:
- name: site_id
in: path
operations:
- name: get-site-record
method: GET
- type: http
namespace: salesforce
baseUri: "https://merck.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: accounts
path: "/sobjects/Account"
operations:
- name: create-account
method: POST
- type: http
namespace: servicenow
baseUri: "https://merck.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: incident
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
Handles cold chain temperature excursions by logging in SAP, creating a quality incident, and alerting logistics and quality teams for Merck.
naftiko: "0.5"
info:
label: "Cold Chain Temperature Excursion Handler"
description: "Handles cold chain temperature excursions by logging in SAP, creating a quality incident, and alerting logistics and quality teams for Merck."
tags:
- supply-chain
- cold-chain
- quality
- sap
capability:
exposes:
- type: mcp
namespace: cold-chain-ops
port: 8080
tools:
- name: handle-temp-excursion
description: "Given temperature excursion details, log in SAP, create a ServiceNow quality incident, and alert teams."
inputParameters:
- name: shipment_id
in: body
type: string
description: "The shipment identifier."
- name: product_name
in: body
type: string
description: "The product being shipped."
- name: temperature_reading
in: body
type: string
description: "The temperature reading."
- name: acceptable_range
in: body
type: string
description: "The acceptable temperature range."
- name: duration_minutes
in: body
type: integer
description: "Duration of excursion in minutes."
steps:
- name: log-sap-excursion
type: call
call: sap.create-quality-notification
with:
notification_type: "Q2"
description: "Cold Chain Excursion: Shipment {{shipment_id}}, Product {{product_name}}, Temp {{temperature_reading}}"
- name: create-quality-incident
type: call
call: servicenow.create-incident
with:
short_description: "Cold Chain Excursion: {{product_name}} — Shipment {{shipment_id}}"
priority: "2"
- name: alert-teams
type: call
call: msteams.send-message
with:
channel_id: "$secrets.cold_chain_channel"
text: "COLD CHAIN ALERT: Temp excursion for {{product_name}} (Shipment {{shipment_id}}). Reading: {{temperature_reading}} (range: {{acceptable_range}}). SAP: {{log-sap-excursion.notification_number}}. SNOW: {{create-quality-incident.number}}."
consumes:
- type: http
namespace: sap
baseUri: "https://merck-s4.sap.com/sap/opu/odata/sap/API_QUALITYNOTIFICATION_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: records
path: "/"
operations:
- name: create-record
method: POST
- type: http
namespace: servicenow
baseUri: "https://merck.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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Searches Merck Confluence knowledge base for regulatory guidance documents by keyword.
naftiko: "0.5"
info:
label: "Confluence Regulatory Knowledge Search"
description: "Searches Merck Confluence knowledge base for regulatory guidance documents by keyword."
tags:
- regulatory
- confluence
- knowledge-management
- search
capability:
exposes:
- type: mcp
namespace: regulatory-kb
port: 8080
tools:
- name: search-regulatory-docs
description: "Given a search query, return matching Confluence pages with titles, space keys, and URLs."
inputParameters:
- name: search_query
in: body
type: string
description: "The search query for regulatory guidance documents."
call: confluence.search-content
with:
search_query: "{{search_query}}"
outputParameters:
- name: results
type: array
mapping: "$.results"
- name: total_size
type: integer
mapping: "$.totalSize"
consumes:
- type: http
namespace: confluence
baseUri: "https://merck.atlassian.net/wiki/rest/api"
authentication:
type: bearer
token: "$secrets.confluence_token"
resources:
- name: search
path: "/content/search?cql=text~'{{search_query}}'"
inputParameters:
- name: search_query
in: query
operations:
- name: search-content
method: GET
Orchestrates ML model deployment by promoting a model in Databricks, updating the model registry, and notifying the data science team for Merck.
naftiko: "0.5"
info:
label: "Databricks ML Model Deployment Pipeline"
description: "Orchestrates ML model deployment by promoting a model in Databricks, updating the model registry, and notifying the data science team for Merck."
tags:
- r-and-d
- databricks
- machine-learning
- deployment
capability:
exposes:
- type: mcp
namespace: rd-ml-ops
port: 8080
tools:
- name: deploy-ml-model
description: "Given a model name and version, promote in Databricks MLflow, register in the model registry, and notify the team."
inputParameters:
- name: model_name
in: body
type: string
description: "The MLflow model name."
- name: model_version
in: body
type: string
description: "The model version to promote."
- name: target_stage
in: body
type: string
description: "Target stage (Staging, Production)."
steps:
- name: promote-model
type: call
call: databricks.transition-model-stage
with:
name: "{{model_name}}"
version: "{{model_version}}"
stage: "{{target_stage}}"
- name: log-deployment
type: call
call: servicenow.create-incident
with:
short_description: "ML Model Deployment: {{model_name}} v{{model_version}} to {{target_stage}}"
category: "ml_ops"
- name: notify-ds-team
type: call
call: msteams.send-message
with:
channel_id: "$secrets.data_science_channel"
text: "ML Model Deployed: {{model_name}} v{{model_version}} promoted to {{target_stage}}. SNOW: {{log-deployment.number}}."
consumes:
- type: http
namespace: databricks
baseUri: "https://merck.cloud.databricks.com/api/2.0"
authentication:
type: bearer
token: "$secrets.databricks_token"
resources:
- name: model-versions
path: "/mlflow/model-versions/transition-stage"
operations:
- name: transition-model-stage
method: POST
- type: http
namespace: servicenow
baseUri: "https://merck.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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
When a Datadog APM monitor triggers for a critical pharmaceutical application, creates a ServiceNow incident and pages the on-call team via PagerDuty.
naftiko: "0.5"
info:
label: "Datadog Application Performance Alert Handler"
description: "When a Datadog APM monitor triggers for a critical pharmaceutical application, creates a ServiceNow incident and pages the on-call team via PagerDuty."
tags:
- observability
- apm
- datadog
- servicenow
- pagerduty
- monitoring
capability:
exposes:
- type: mcp
namespace: apm-monitoring
port: 8080
tools:
- name: handle-apm-alert
description: "Given a Datadog APM alert with service name, error rate, and latency details, open a ServiceNow incident and trigger PagerDuty for the on-call engineer."
inputParameters:
- name: service_name
in: body
type: string
description: "The application service name that triggered the APM alert."
- name: error_rate
in: body
type: number
description: "The current error rate percentage that breached the threshold."
- name: p99_latency_ms
in: body
type: number
description: "The P99 latency in milliseconds that triggered the alert."
- name: alert_url
in: body
type: string
description: "URL to the Datadog APM alert dashboard."
steps:
- name: create-incident
type: call
call: "servicenow.create-incident"
with:
short_description: "APM Alert: {{service_name}} error rate {{error_rate}}%"
urgency: "1"
category: "application_performance"
- name: page-oncall
type: call
call: "pagerduty.create-incident"
with:
title: "APM Alert: {{service_name}} - {{error_rate}}% error rate"
severity: "critical"
body: "P99 latency: {{p99_latency_ms}}ms. Alert: {{alert_url}}. SNOW: {{create-incident.number}}"
consumes:
- type: http
namespace: servicenow
baseUri: "https://merck.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: incident
path: "/table/incident"
operations:
- name: create-incident
method: POST
- type: http
namespace: pagerduty
baseUri: "https://api.pagerduty.com"
authentication:
type: apikey
key: "Authorization"
value: "$secrets.pagerduty_token"
placement: header
resources:
- name: incidents
path: "/incidents"
operations:
- name: create-incident
method: POST
Retrieves the current health status of a monitored service from Datadog for Merck SRE operations.
naftiko: "0.5"
info:
label: "Datadog Service Health Check"
description: "Retrieves the current health status of a monitored service from Datadog for Merck SRE operations."
tags:
- monitoring
- datadog
- sre
- health-check
capability:
exposes:
- type: mcp
namespace: sre-ops
port: 8080
tools:
- name: get-service-health
description: "Given a service name, return the overall status, number of active monitors, and last check time."
inputParameters:
- name: service_name
in: body
type: string
description: "The Datadog service name."
call: datadog.get-service-status
with:
service_name: "{{service_name}}"
outputParameters:
- name: overall_status
type: string
mapping: "$.overall_status"
- name: active_monitors
type: integer
mapping: "$.counts.total"
- name: last_triggered
type: string
mapping: "$.last_triggered_ts"
consumes:
- type: http
namespace: datadog
baseUri: "https://api.datadoghq.com/api/v1"
authentication:
type: bearer
token: "$secrets.datadog_api_key"
resources:
- name: monitors
path: "/monitor/search?query=service:{{service_name}}"
inputParameters:
- name: service_name
in: query
operations:
- name: get-service-status
method: GET
Retrieves Datadog SLO compliance metrics for all critical pharmaceutical applications and posts a weekly compliance report to the reliability engineering Microsoft Teams channel.
naftiko: "0.5"
info:
label: "Datadog SLO Compliance Report"
description: "Retrieves Datadog SLO compliance metrics for all critical pharmaceutical applications and posts a weekly compliance report to the reliability engineering Microsoft Teams channel."
tags:
- observability
- slo
- datadog
- microsoft-teams
- reporting
- reliability
capability:
exposes:
- type: mcp
namespace: slo-reporting
port: 8080
tools:
- name: publish-slo-compliance-report
description: "Retrieve compliance data for all Datadog SLOs tagged as critical pharmaceutical systems and post a formatted weekly compliance summary to the reliability engineering Microsoft Teams channel."
inputParameters:
- name: report_period_days
in: body
type: integer
description: "Number of days to include in the SLO compliance report (e.g., 7 for weekly)."
steps:
- name: get-slo-status
type: call
call: "datadog.list-slos"
with:
tags: "team:pharma-critical"
- name: post-report
type: call
call: "msteams.post-channel-message"
with:
channel_id: "reliability-engineering"
message: "Weekly SLO Report ({{report_period_days}} days): {{get-slo-status.compliant_count}} compliant, {{get-slo-status.breached_count}} breached out of {{get-slo-status.total_count}} SLOs."
consumes:
- type: http
namespace: datadog
baseUri: "https://api.datadoghq.com/api/v1"
authentication:
type: apikey
key: "DD-API-KEY"
value: "$secrets.datadog_api_key"
placement: header
resources:
- name: slos
path: "/slo"
operations:
- name: list-slos
method: GET
- type: http
namespace: 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
Initiates periodic SOP review cycles by identifying documents due for review in Veeva Vault, creating Jira tasks, and notifying owners for Merck.
naftiko: "0.5"
info:
label: "Document Control SOP Review Cycle Initiator"
description: "Initiates periodic SOP review cycles by identifying documents due for review in Veeva Vault, creating Jira tasks, and notifying owners for Merck."
tags:
- quality
- document-control
- veeva-vault
- jira
capability:
exposes:
- type: mcp
namespace: doc-control
port: 8080
tools:
- name: initiate-sop-review-cycle
description: "Given a document category and review period, find SOPs due for review, create tracking tasks, and notify owners."
inputParameters:
- name: document_category
in: body
type: string
description: "The SOP document category (manufacturing, QC, clinical)."
- name: review_due_days
in: body
type: integer
description: "Days until review due date to include."
steps:
- name: find-docs-due
type: call
call: veeva.query-submissions
with:
query: "SELECT id, name__v FROM documents WHERE category__c = '{{document_category}}'"
- name: create-jira-tasks
type: call
call: jira.create-issue
with:
project: "QMS"
summary: "SOP Review Cycle: {{document_category}} — {{find-docs-due.totalCount}} documents"
issuetype: "Task"
- name: notify-owners
type: call
call: msteams.send-message
with:
channel_id: "$secrets.doc_control_channel"
text: "SOP Review Cycle: {{find-docs-due.totalCount}} {{document_category}} documents due within {{review_due_days}} days. Jira: {{create-jira-tasks.key}}."
consumes:
- type: http
namespace: veeva
baseUri: "https://merck.veevavault.com/api/v24.1"
authentication:
type: bearer
token: "$secrets.veeva_token"
resources:
- name: object-records
path: "/vobjects/{{object_type}}"
inputParameters:
- name: object_type
in: path
operations:
- name: create-object-record
method: POST
- type: http
namespace: jira
baseUri: "https://merck.atlassian.net/rest/api/3"
authentication:
type: bearer
token: "$secrets.jira_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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Receives an adverse event report, creates a pharmacovigilance case in ServiceNow, and notifies the drug safety team via Teams for Merck.
naftiko: "0.5"
info:
label: "Drug Safety Adverse Event Report Processor"
description: "Receives an adverse event report, creates a pharmacovigilance case in ServiceNow, and notifies the drug safety team via Teams for Merck."
tags:
- drug-safety
- pharmacovigilance
- servicenow
- compliance
capability:
exposes:
- type: mcp
namespace: drug-safety
port: 8080
tools:
- name: process-adverse-event
description: "Given adverse event details, create a PV case in ServiceNow and send an urgent notification to the drug safety officer."
inputParameters:
- name: patient_id
in: body
type: string
description: "Anonymized patient identifier."
- name: product_name
in: body
type: string
description: "The drug product name."
- name: event_description
in: body
type: string
description: "Description of the adverse event."
- name: severity
in: body
type: string
description: "Severity classification (mild, moderate, severe, life-threatening)."
steps:
- name: create-pv-case
type: call
call: servicenow.create-incident
with:
short_description: "AE Report: {{product_name}} — {{severity}}"
category: "pharmacovigilance"
description: "Patient: {{patient_id}} | Product: {{product_name}} | Event: {{event_description}} | Severity: {{severity}}"
- name: notify-safety-team
type: call
call: msteams.send-message
with:
channel_id: "$secrets.drug_safety_channel"
text: "URGENT: New {{severity}} AE for {{product_name}}. Case: {{create-pv-case.number}}. Patient: {{patient_id}}. Review required within 24 hours."
consumes:
- type: http
namespace: servicenow
baseUri: "https://merck.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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Looks up the current status of a regulatory filing in Veeva Vault and returns submission timeline, review status, and agency correspondence.
naftiko: "0.5"
info:
label: "Drug Safety Regulatory Filing Status"
description: "Looks up the current status of a regulatory filing in Veeva Vault and returns submission timeline, review status, and agency correspondence."
tags:
- regulatory
- veeva
- compliance
- drug-safety
capability:
exposes:
- type: mcp
namespace: regulatory-status
port: 8080
tools:
- name: get-regulatory-filing-status
description: "Look up a regulatory filing in Veeva Vault by submission ID. Returns current review status, target action date, and recent agency correspondence. Use during regulatory review cycles."
inputParameters:
- name: submission_id
in: body
type: string
description: "The Veeva Vault regulatory submission document ID."
call: "veeva.get-submission-status"
with:
submission_id: "{{submission_id}}"
outputParameters:
- name: status
type: string
mapping: "$.status__v"
- name: target_action_date
type: string
mapping: "$.target_action_date__v"
- name: filing_type
type: string
mapping: "$.document_type__v"
consumes:
- type: http
namespace: veeva
baseUri: "https://merck.veevavault.com/api/v21.2"
authentication:
type: bearer
token: "$secrets.veeva_token"
resources:
- name: submissions
path: "/objects/regulatory_submissions/{{submission_id}}"
inputParameters:
- name: submission_id
in: path
operations:
- name: get-submission-status
method: GET
When an employee departure is confirmed in Workday, revokes Okta access, disables the Microsoft 365 account, and creates a ServiceNow offboarding checklist.
naftiko: "0.5"
info:
label: "Employee Offboarding and Access Revocation"
description: "When an employee departure is confirmed in Workday, revokes Okta access, disables the Microsoft 365 account, and creates a ServiceNow offboarding checklist."
tags:
- hr
- offboarding
- workday
- okta
- microsoft-365
- servicenow
capability:
exposes:
- type: mcp
namespace: hr-offboarding
port: 8080
tools:
- name: trigger-offboarding
description: "Given a Workday employee ID and termination date, deactivate the Okta user account, disable the Microsoft 365 account, and create a ServiceNow offboarding checklist task."
inputParameters:
- name: employee_id
in: body
type: string
description: "The Workday employee ID of the departing employee."
- name: termination_date
in: body
type: string
description: "The employee's last working day in ISO 8601 format (YYYY-MM-DD)."
steps:
- name: get-employee
type: call
call: "workday.get-worker"
with:
worker_id: "{{employee_id}}"
- name: deactivate-okta
type: call
call: "okta.deactivate-user"
with:
user_email: "{{get-employee.work_email}}"
- name: disable-m365
type: call
call: "msgraph.disable-user"
with:
user_id: "{{get-employee.work_email}}"
- name: create-checklist
type: call
call: "servicenow.create-incident"
with:
short_description: "Offboarding checklist: {{get-employee.displayName}}"
category: "hr_offboarding"
description: "Termination date: {{termination_date}} | Okta deactivated | M365 disabled"
consumes:
- type: http
namespace: workday
baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
authentication:
type: basic
username: "$secrets.workday_user"
password: "$secrets.workday_password"
resources:
- name: workers
path: "/merck/workers/{{worker_id}}"
inputParameters:
- name: worker_id
in: path
operations:
- name: get-worker
method: GET
- type: http
namespace: okta
baseUri: "https://merck.okta.com/api/v1"
authentication:
type: apikey
key: "Authorization"
value: "$secrets.okta_api_token"
placement: header
resources:
- name: user-lifecycle
path: "/users/{{user_email}}/lifecycle/deactivate"
inputParameters:
- name: user_email
in: path
operations:
- name: deactivate-user
method: POST
- type: http
namespace: msgraph
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: users
path: "/users/{{user_id}}"
inputParameters:
- name: user_id
in: path
operations:
- name: disable-user
method: PATCH
- type: http
namespace: servicenow
baseUri: "https://merck.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: incident
path: "/table/incident"
operations:
- name: create-incident
method: POST
When a new hire is created in Workday, provisions a Microsoft 365 account, opens a ServiceNow onboarding ticket, and sends a Microsoft Teams welcome message.
naftiko: "0.5"
info:
label: "Employee Onboarding Orchestrator"
description: "When a new hire is created in Workday, provisions a Microsoft 365 account, opens a ServiceNow onboarding ticket, and sends a Microsoft Teams welcome message."
tags:
- hr
- onboarding
- workday
- microsoft-365
- servicenow
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: hr-onboarding
port: 8080
tools:
- name: trigger-onboarding
description: "Given a Workday employee ID and start date, orchestrate the full onboarding sequence: provision Microsoft 365, open a ServiceNow ticket, and send a Teams welcome message."
inputParameters:
- name: employee_id
in: body
type: string
description: "The Workday employee ID for the new hire."
- name: start_date
in: body
type: string
description: "The employee's start date in ISO 8601 format (YYYY-MM-DD)."
steps:
- name: get-employee
type: call
call: "workday.get-worker"
with:
worker_id: "{{employee_id}}"
- name: provision-m365
type: call
call: "msgraph.create-user"
with:
displayName: "{{get-employee.displayName}}"
mailNickname: "{{get-employee.userId}}"
- name: open-ticket
type: call
call: "servicenow.create-incident"
with:
short_description: "New hire onboarding: {{get-employee.displayName}}"
category: "hr_onboarding"
- name: send-welcome
type: call
call: "msteams.send-message"
with:
recipient_upn: "{{provision-m365.userPrincipalName}}"
message: "Welcome to Merck, {{get-employee.firstName}}! Your onboarding ticket is {{open-ticket.number}}."
consumes:
- type: http
namespace: workday
baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
authentication:
type: basic
username: "$secrets.workday_user"
password: "$secrets.workday_password"
resources:
- name: workers
path: "/merck/workers/{{worker_id}}"
inputParameters:
- name: worker_id
in: path
operations:
- name: get-worker
method: GET
- 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: servicenow
baseUri: "https://merck.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: incident
path: "/table/incident"
operations:
- name: create-incident
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/users/{{recipient_upn}}/sendMail"
inputParameters:
- name: recipient_upn
in: path
operations:
- name: send-message
method: POST
Processes environmental monitoring excursions in manufacturing by logging in SAP QM, creating a ServiceNow incident, and alerting quality for Merck.
naftiko: "0.5"
info:
label: "Environmental Monitoring Alert Handler"
description: "Processes environmental monitoring excursions in manufacturing by logging in SAP QM, creating a ServiceNow incident, and alerting quality for Merck."
tags:
- manufacturing
- quality
- sap
- environmental-monitoring
capability:
exposes:
- type: mcp
namespace: manufacturing-em
port: 8080
tools:
- name: handle-em-excursion
description: "Given environmental excursion details, log a quality notification in SAP, create a ServiceNow incident, and alert quality."
inputParameters:
- name: area_name
in: body
type: string
description: "The monitored area name."
- name: parameter
in: body
type: string
description: "The environmental parameter."
- name: reading
in: body
type: string
description: "The actual reading value."
- name: limit
in: body
type: string
description: "The acceptable limit value."
- name: plant
in: body
type: string
description: "The plant code."
steps:
- name: log-sap-qn
type: call
call: sap.create-quality-notification
with:
notification_type: "Q2"
description: "EM Excursion: {{area_name}} — {{parameter}} reading {{reading}} exceeds limit {{limit}}"
plant: "{{plant}}"
- name: create-snow-incident
type: call
call: servicenow.create-incident
with:
short_description: "EM Excursion: {{area_name}} — {{parameter}}"
category: "environmental_monitoring"
- name: alert-quality
type: call
call: msteams.send-message
with:
channel_id: "$secrets.em_quality_channel"
text: "EM ALERT: {{parameter}} excursion in {{area_name}} at Plant {{plant}}. Reading: {{reading}} (limit: {{limit}}). SAP QN: {{log-sap-qn.notification_number}}. SNOW: {{create-snow-incident.number}}."
consumes:
- type: http
namespace: sap
baseUri: "https://merck-s4.sap.com/sap/opu/odata/sap/API_QUALITYNOTIFICATION_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: records
path: "/"
operations:
- name: create-record
method: POST
- type: http
namespace: servicenow
baseUri: "https://merck.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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Generates FDA inspection readiness checklists by pulling SOPs from SharePoint, checking training compliance in Workday, and creating Jira tracking for Merck.
naftiko: "0.5"
info:
label: "FDA Inspection Readiness Checklist Generator"
description: "Generates FDA inspection readiness checklists by pulling SOPs from SharePoint, checking training compliance in Workday, and creating Jira tracking for Merck."
tags:
- regulatory
- compliance
- sharepoint
- workday
capability:
exposes:
- type: mcp
namespace: regulatory-compliance
port: 8080
tools:
- name: generate-inspection-checklist
description: "Given a facility and inspection type, compile SOP readiness, training status, and create tracking tasks."
inputParameters:
- name: facility_name
in: body
type: string
description: "The facility being inspected."
- name: inspection_type
in: body
type: string
description: "Type of FDA inspection (pre-approval, routine, for-cause)."
steps:
- name: check-sops
type: call
call: sharepoint.get-document-list
with:
library: "SOPs"
filter: "facility eq '{{facility_name}}'"
- name: check-training
type: call
call: workday.get-training-compliance
with:
facility: "{{facility_name}}"
program: "GMP_Training"
- name: create-epic
type: call
call: jira.create-issue
with:
project: "REG"
summary: "FDA Inspection Readiness: {{facility_name}} — {{inspection_type}}"
issuetype: "Epic"
- name: notify-team
type: call
call: msteams.send-message
with:
channel_id: "$secrets.quality_compliance_channel"
text: "FDA Inspection Readiness for {{facility_name}} ({{inspection_type}}): {{check-sops.count}} SOPs, {{check-training.compliance_rate}}% training compliant. Jira: {{create-epic.key}}."
consumes:
- type: http
namespace: sharepoint
baseUri: "https://merck.sharepoint.com/_api/web"
authentication:
type: bearer
token: "$secrets.sharepoint_token"
resources:
- name: lists
path: "/lists"
operations:
- name: get-document-list
method: GET
- type: http
namespace: workday
baseUri: "https://wd5-services1.myworkday.com/ccx/service/merck/Learning/v42.0"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: training
path: "/learningAssignments"
operations:
- name: get-training-compliance
method: GET
- type: http
namespace: jira
baseUri: "https://merck.atlassian.net/rest/api/3"
authentication:
type: bearer
token: "$secrets.jira_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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Detects GCP cost anomalies via Datadog, creates a ServiceNow change request for cost review, and notifies the cloud FinOps team via Microsoft Teams.
naftiko: "0.5"
info:
label: "GCP Cloud Cost Anomaly Response"
description: "Detects GCP cost anomalies via Datadog, creates a ServiceNow change request for cost review, and notifies the cloud FinOps team via Microsoft Teams."
tags:
- cloud
- finops
- datadog
- servicenow
- microsoft-teams
- gcp
capability:
exposes:
- type: mcp
namespace: cloud-cost-ops
port: 8080
tools:
- name: respond-to-cost-anomaly
description: "Given a Datadog cloud cost anomaly with service and excess amount, create a ServiceNow change request for the FinOps team to investigate and notify the cloud cost Microsoft Teams channel."
inputParameters:
- name: service_name
in: body
type: string
description: "The GCP service or workload generating the cost anomaly."
- name: excess_amount_usd
in: body
type: number
description: "Dollar amount exceeding the expected cost baseline."
- name: anomaly_date
in: body
type: string
description: "Date the anomaly was detected (YYYY-MM-DD)."
steps:
- name: create-change
type: call
call: "servicenow.create-change"
with:
short_description: "GCP cost anomaly: {{service_name}} exceeded by ${{excess_amount_usd}}"
type: "normal"
category: "cloud_cost"
- name: notify-finops
type: call
call: "msteams.post-channel-message"
with:
channel_id: "cloud-finops"
message: "Cost Anomaly: {{service_name}} exceeded baseline by ${{excess_amount_usd}} on {{anomaly_date}}. ServiceNow: {{create-change.number}}"
consumes:
- type: http
namespace: servicenow
baseUri: "https://merck.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: change-request
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
Triggers GxP validation pipelines in GitHub Actions, logs validation events in ServiceNow, and notifies the QA team for Merck.
naftiko: "0.5"
info:
label: "GitHub Actions GxP Validation Pipeline Trigger"
description: "Triggers GxP validation pipelines in GitHub Actions, logs validation events in ServiceNow, and notifies the QA team for Merck."
tags:
- devops
- github-actions
- gxp
- validation
capability:
exposes:
- type: mcp
namespace: gxp-devops
port: 8080
tools:
- name: trigger-gxp-validation
description: "Given a system name and validation type, trigger the pipeline, log in ServiceNow, and notify QA."
inputParameters:
- name: repo_name
in: body
type: string
description: "The GitHub repository name."
- name: validation_type
in: body
type: string
description: "Type of validation (IQ, OQ, PQ)."
- name: system_name
in: body
type: string
description: "The GxP system being validated."
steps:
- name: trigger-pipeline
type: call
call: github.trigger-workflow
with:
repo: "{{repo_name}}"
workflow: "gxp-validation.yml"
- name: log-validation
type: call
call: servicenow.create-incident
with:
short_description: "GxP Validation: {{validation_type}} — {{system_name}}"
category: "gxp_validation"
- name: notify-qa
type: call
call: msteams.send-message
with:
channel_id: "$secrets.gxp_qa_channel"
text: "GxP Validation triggered: {{validation_type}} for {{system_name}}. Repo: {{repo_name}}. SNOW: {{log-validation.number}}."
consumes:
- type: http
namespace: github
baseUri: "https://api.github.com"
authentication:
type: bearer
token: "$secrets.github_token"
resources:
- name: workflows
path: "/repos/{{repo}}/actions/workflows/{{workflow}}/dispatches"
inputParameters:
- name: repo
in: path
- name: workflow
in: path
operations:
- name: trigger-workflow
method: POST
- type: http
namespace: servicenow
baseUri: "https://merck.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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
On a GitHub Actions pipeline failure on a protected branch, creates a Jira bug, logs a Datadog deployment event, and alerts the engineering team via Microsoft Teams.
naftiko: "0.5"
info:
label: "GitHub CI/CD Pipeline Failure Response"
description: "On a GitHub Actions pipeline failure on a protected branch, creates a Jira bug, logs a Datadog deployment event, and alerts the engineering team via Microsoft Teams."
tags:
- devops
- cicd
- github
- jira
- datadog
- microsoft-teams
- incident-response
capability:
exposes:
- type: mcp
namespace: devops-ops
port: 8080
tools:
- name: handle-pipeline-failure
description: "Given a GitHub Actions pipeline failure with repository, branch, and run URL, create a Jira bug, log a Datadog event, and post an alert to the engineering Microsoft Teams channel."
inputParameters:
- name: repository
in: body
type: string
description: "The GitHub repository where the pipeline failed (e.g., merck/research-platform)."
- name: workflow_name
in: body
type: string
description: "The GitHub Actions workflow name that failed."
- name: branch
in: body
type: string
description: "The branch on which the failure occurred."
- name: run_url
in: body
type: string
description: "URL to the failed GitHub Actions run."
- name: commit_sha
in: body
type: string
description: "The commit SHA for the failed run."
steps:
- name: create-bug
type: call
call: "jira.create-issue"
with:
project_key: "ENG"
issuetype: "Bug"
summary: "[CI Failure] {{repository}} / {{branch}} - {{workflow_name}}"
description: "Workflow: {{workflow_name}}\nBranch: {{branch}}\nCommit: {{commit_sha}}\nRun: {{run_url}}"
- name: log-event
type: call
call: "datadog.create-event"
with:
title: "CI Failure: {{repository}}/{{branch}}"
text: "Workflow {{workflow_name}} failed at commit {{commit_sha}}"
alert_type: "error"
- name: notify-team
type: call
call: "msteams.post-channel-message"
with:
channel_id: "engineering-alerts"
message: "Pipeline Failure: {{repository}} | {{branch}} | {{workflow_name}} | Jira: {{create-bug.key}} | Run: {{run_url}}"
consumes:
- type: http
namespace: jira
baseUri: "https://merck.atlassian.net/rest/api/3"
authentication:
type: basic
username: "$secrets.jira_user"
password: "$secrets.jira_api_token"
resources:
- name: issues
path: "/issue"
operations:
- name: create-issue
method: POST
- type: http
namespace: datadog
baseUri: "https://api.datadoghq.com/api/v1"
authentication:
type: apikey
key: "DD-API-KEY"
value: "$secrets.datadog_api_key"
placement: header
resources:
- name: events
path: "/events"
operations:
- name: create-event
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/{{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 GitHub Dependabot alerts for a repository, creates Jira tickets for critical vulnerabilities, and posts a remediation summary to Microsoft Teams.
naftiko: "0.5"
info:
label: "GitHub Code Security Vulnerability Triage"
description: "Retrieves GitHub Dependabot alerts for a repository, creates Jira tickets for critical vulnerabilities, and posts a remediation summary to Microsoft Teams."
tags:
- devops
- security
- github
- jira
- microsoft-teams
- vulnerability-management
capability:
exposes:
- type: mcp
namespace: security-triage
port: 8080
tools:
- name: triage-dependency-vulnerabilities
description: "Given a GitHub repository, retrieve Dependabot security alerts, create Jira tickets for critical and high severity findings, and post a triage summary to the security Microsoft Teams channel."
inputParameters:
- name: repository
in: body
type: string
description: "The GitHub repository to triage (e.g., merck/research-api)."
- name: jira_project_key
in: body
type: string
description: "Jira project key for security vulnerability tickets."
steps:
- name: get-alerts
type: call
call: "github.list-dependabot-alerts"
with:
repository: "{{repository}}"
severity: "critical,high"
- name: create-ticket
type: call
call: "jira.create-issue"
with:
project_key: "{{jira_project_key}}"
issuetype: "Bug"
summary: "Dependency vulnerabilities in {{repository}}: {{get-alerts.critical_count}} critical"
description: "{{get-alerts.alert_summary}}"
- name: notify-security
type: call
call: "msteams.post-channel-message"
with:
channel_id: "security-team"
message: "Vulnerability Triage: {{repository}} has {{get-alerts.critical_count}} critical alerts. Jira: {{create-ticket.key}}"
consumes:
- type: http
namespace: github
baseUri: "https://api.github.com"
authentication:
type: bearer
token: "$secrets.github_token"
resources:
- name: dependabot-alerts
path: "/repos/{{repository}}/dependabot/alerts"
inputParameters:
- name: repository
in: path
operations:
- name: list-dependabot-alerts
method: GET
- type: http
namespace: jira
baseUri: "https://merck.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 a GitHub repository for branch protection rules and required status checks for Merck DevSecOps compliance.
naftiko: "0.5"
info:
label: "GitHub Repository Compliance Check"
description: "Checks a GitHub repository for branch protection rules and required status checks for Merck DevSecOps compliance."
tags:
- devops
- github
- compliance
- security
capability:
exposes:
- type: mcp
namespace: devsecops
port: 8080
tools:
- name: check-repo-compliance
description: "Given a repository name, return branch protection status, required reviews count, and CODEOWNERS presence."
inputParameters:
- name: repo_name
in: body
type: string
description: "The GitHub repository name (org/repo format)."
call: github.get-branch-protection
with:
repo_name: "{{repo_name}}"
outputParameters:
- name: protection_enabled
type: boolean
mapping: "$.enabled"
- name: required_reviews
type: integer
mapping: "$.required_pull_request_reviews.required_approving_review_count"
- name: enforce_admins
type: boolean
mapping: "$.enforce_admins.enabled"
consumes:
- type: http
namespace: github
baseUri: "https://api.github.com"
authentication:
type: bearer
token: "$secrets.github_token"
resources:
- name: branch-protection
path: "/repos/{{repo_name}}/branches/main/protection"
inputParameters:
- name: repo_name
in: path
operations:
- name: get-branch-protection
method: GET
Manages GxP-validated system change requests by creating a ServiceNow change, logging in Veeva Vault audit trail, and notifying approvers for Merck.
naftiko: "0.5"
info:
label: "GxP System Change Approval Workflow"
description: "Manages GxP-validated system change requests by creating a ServiceNow change, logging in Veeva Vault audit trail, and notifying approvers for Merck."
tags:
- compliance
- gxp
- servicenow
- veeva-vault
capability:
exposes:
- type: mcp
namespace: gxp-compliance
port: 8080
tools:
- name: initiate-gxp-change
description: "Given change request details, create a ServiceNow change request, log in Veeva Vault, and notify the CAB."
inputParameters:
- name: system_name
in: body
type: string
description: "Name of the GxP-validated system."
- name: change_description
in: body
type: string
description: "Description of the proposed change."
- name: risk_level
in: body
type: string
description: "Risk classification (low, medium, high, critical)."
steps:
- name: create-change-request
type: call
call: servicenow.create-change
with:
short_description: "GxP Change: {{system_name}} — {{risk_level}} risk"
category: "gxp_change_control"
description: "System: {{system_name}} | Change: {{change_description}} | Risk: {{risk_level}}"
- name: log-vault-audit
type: call
call: veeva.create-object-record
with:
object_type: "change_control__c"
system_name__c: "{{system_name}}"
description__c: "{{change_description}}"
- name: notify-cab
type: call
call: msteams.send-message
with:
channel_id: "$secrets.cab_channel"
text: "GxP Change Request: {{system_name}} ({{risk_level}} risk). SNOW: {{create-change-request.number}}. Vault: {{log-vault-audit.id}}."
consumes:
- type: http
namespace: servicenow
baseUri: "https://merck.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: veeva
baseUri: "https://merck.veevavault.com/api/v24.1"
authentication:
type: bearer
token: "$secrets.veeva_token"
resources:
- name: object-records
path: "/vobjects/{{object_type}}"
inputParameters:
- name: object_type
in: path
operations:
- name: create-object-record
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Coordinates HCP speaker program events by creating events in Salesforce, logging compliance checks, and notifying medical affairs for Merck.
naftiko: "0.5"
info:
label: "HCP Speaker Program Event Coordinator"
description: "Coordinates HCP speaker program events by creating events in Salesforce, logging compliance checks, and notifying medical affairs for Merck."
tags:
- medical-affairs
- salesforce
- compliance
- events
capability:
exposes:
- type: mcp
namespace: medical-affairs-events
port: 8080
tools:
- name: coordinate-speaker-event
description: "Given speaker event details, create the event in Salesforce, verify FMV compliance, and notify the team."
inputParameters:
- name: speaker_name
in: body
type: string
description: "Name of the HCP speaker."
- name: event_title
in: body
type: string
description: "Title of the speaker program event."
- name: event_date
in: body
type: string
description: "Date of the event."
- name: honorarium_amount
in: body
type: string
description: "Speaker honorarium amount."
steps:
- name: create-event
type: call
call: salesforce.create-record
with:
object_type: "Speaker_Event__c"
Speaker_Name__c: "{{speaker_name}}"
Event_Title__c: "{{event_title}}"
- name: check-fmv
type: call
call: servicenow.create-incident
with:
short_description: "FMV Compliance Check: {{speaker_name}} — {{honorarium_amount}}"
category: "compliance"
- name: notify-med-affairs
type: call
call: msteams.send-message
with:
channel_id: "$secrets.med_affairs_events_channel"
text: "Speaker Event: {{event_title}} on {{event_date}}. Speaker: {{speaker_name}}. Honorarium: {{honorarium_amount}}. SFDC: {{create-event.id}}. FMV: {{check-fmv.number}}."
consumes:
- type: http
namespace: salesforce
baseUri: "https://merck.my.salesforce.com/services/data/v59.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: records
path: "/sobjects/Speaker_Event__c"
operations:
- name: create-record
method: POST
- type: http
namespace: servicenow
baseUri: "https://merck.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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Tracks vulnerability remediation by pulling scan results, creating ServiceNow tickets, and reporting to the CISO dashboard for Merck.
naftiko: "0.5"
info:
label: "IT Security Vulnerability Remediation Tracker"
description: "Tracks vulnerability remediation by pulling scan results, creating ServiceNow tickets, and reporting to the CISO dashboard for Merck."
tags:
- security
- servicenow
- compliance
- vulnerability-management
capability:
exposes:
- type: mcp
namespace: security-ops
port: 8080
tools:
- name: track-vulnerability-remediation
description: "Given a scan ID and severity threshold, pull results, create remediation tickets, and update the dashboard."
inputParameters:
- name: scan_id
in: body
type: string
description: "The vulnerability scan identifier."
- name: severity_threshold
in: body
type: string
description: "Minimum severity to track (critical, high, medium)."
steps:
- name: get-findings
type: call
call: servicenow.get-vulnerabilities
with:
scan_id: "{{scan_id}}"
severity: "{{severity_threshold}}"
- name: create-tickets
type: call
call: servicenow.create-incident
with:
short_description: "Vulnerability Remediation: Scan {{scan_id}}"
category: "security"
- name: notify-security
type: call
call: msteams.send-message
with:
channel_id: "$secrets.security_ops_channel"
text: "Vulnerability Scan {{scan_id}}: {{get-findings.count}} findings at {{severity_threshold}}+ severity. Ticket: {{create-tickets.number}}."
consumes:
- type: http
namespace: servicenow
baseUri: "https://merck.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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Retrieves the status and details of a Jira issue by key for Merck clinical operations project tracking.
naftiko: "0.5"
info:
label: "Jira Clinical Issue Status Lookup"
description: "Retrieves the status and details of a Jira issue by key for Merck clinical operations project tracking."
tags:
- clinical-trials
- jira
- project-management
- lookup
capability:
exposes:
- type: mcp
namespace: clinical-pm
port: 8080
tools:
- name: get-issue-status
description: "Given a Jira issue key, return the issue summary, status, assignee, and priority."
inputParameters:
- name: issue_key
in: body
type: string
description: "The Jira issue key (e.g., CLIN-1234)."
call: jira.get-issue
with:
issue_key: "{{issue_key}}"
outputParameters:
- name: summary
type: string
mapping: "$.fields.summary"
- 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://merck.atlassian.net/rest/api/3"
authentication:
type: bearer
token: "$secrets.jira_token"
resources:
- name: issues
path: "/issue/{{issue_key}}"
inputParameters:
- name: issue_key
in: path
operations:
- name: get-issue
method: GET
Generates a weekly sprint summary for a Merck research project in Jira and posts it to the team's Microsoft Teams channel.
naftiko: "0.5"
info:
label: "Jira Research Project Sprint Digest"
description: "Generates a weekly sprint summary for a Merck research project in Jira and posts it to the team's Microsoft Teams channel."
tags:
- devops
- agile
- jira
- microsoft-teams
- reporting
- research
capability:
exposes:
- type: mcp
namespace: research-agile
port: 8080
tools:
- name: digest-research-sprint
description: "Given a Jira board ID and sprint ID for a research project, fetch completed and open issues and post a formatted sprint summary to the research team's Microsoft Teams channel."
inputParameters:
- name: board_id
in: body
type: string
description: "The Jira board ID for the research project sprint."
- name: sprint_id
in: body
type: string
description: "The Jira sprint ID to summarize."
- name: teams_channel_id
in: body
type: string
description: "The Microsoft Teams channel ID to post the summary to."
steps:
- name: get-issues
type: call
call: "jira.list-sprint-issues"
with:
board_id: "{{board_id}}"
sprint_id: "{{sprint_id}}"
- name: post-summary
type: call
call: "msteams.post-channel-message"
with:
channel_id: "{{teams_channel_id}}"
message: "Research Sprint {{sprint_id}} Update: {{get-issues.done_count}} completed, {{get-issues.inprogress_count}} in progress, {{get-issues.todo_count}} remaining."
consumes:
- type: http
namespace: jira
baseUri: "https://merck.atlassian.net/rest/api/3"
authentication:
type: basic
username: "$secrets.jira_user"
password: "$secrets.jira_api_token"
resources:
- name: sprint-issues
path: "/board/{{board_id}}/sprint/{{sprint_id}}/issue"
inputParameters:
- name: board_id
in: path
- name: sprint_id
in: path
operations:
- name: list-sprint-issues
method: GET
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: channel-messages
path: "/teams/{{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 laboratory instrument calibration schedules by querying SAP PM, creating ServiceNow work orders, and notifying lab managers for Merck.
naftiko: "0.5"
info:
label: "Laboratory Instrument Calibration Tracker"
description: "Tracks laboratory instrument calibration schedules by querying SAP PM, creating ServiceNow work orders, and notifying lab managers for Merck."
tags:
- r-and-d
- quality
- sap
- laboratory
capability:
exposes:
- type: mcp
namespace: lab-ops
port: 8080
tools:
- name: track-calibration
description: "Given a lab identifier, find instruments due for calibration, create work orders, and notify lab management."
inputParameters:
- name: lab_id
in: body
type: string
description: "The laboratory identifier."
- name: days_ahead
in: body
type: integer
description: "Days ahead to check for calibration due dates."
steps:
- name: query-instruments
type: call
call: sap.get-equipment-list
with:
lab_id: "{{lab_id}}"
next_calibration_within: "{{days_ahead}}"
- name: create-work-orders
type: call
call: servicenow.create-incident
with:
short_description: "Lab Calibration Due: {{query-instruments.count}} instruments in Lab {{lab_id}}"
category: "lab_operations"
- name: notify-lab-manager
type: call
call: msteams.send-message
with:
channel_id: "$secrets.lab_ops_channel"
text: "Calibration Alert: {{query-instruments.count}} instruments in Lab {{lab_id}} due within {{days_ahead}} days. SNOW: {{create-work-orders.number}}."
consumes:
- type: http
namespace: sap
baseUri: "https://merck-s4.sap.com/sap/opu/odata/sap/API_EQUIPMENT_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: records
path: "/"
operations:
- name: create-record
method: POST
- type: http
namespace: servicenow
baseUri: "https://merck.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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Sources MSL candidates from LinkedIn, creates profiles in Workday recruiting, and notifies the talent acquisition team for Merck.
naftiko: "0.5"
info:
label: "LinkedIn Talent Pipeline for Medical Science Liaisons"
description: "Sources MSL candidates from LinkedIn, creates profiles in Workday recruiting, and notifies the talent acquisition team for Merck."
tags:
- hr
- linkedin
- workday
- talent-acquisition
capability:
exposes:
- type: mcp
namespace: hr-talent-sourcing
port: 8080
tools:
- name: source-msl-candidates
description: "Given search criteria for MSL roles, source candidates from LinkedIn, create prospects in Workday, and notify TA."
inputParameters:
- name: therapeutic_area
in: body
type: string
description: "The target therapeutic area."
- name: location
in: body
type: string
description: "The target geographic location."
- name: experience_years
in: body
type: integer
description: "Minimum years of experience."
steps:
- name: search-linkedin
type: call
call: linkedin.search-candidates
with:
keywords: "Medical Science Liaison {{therapeutic_area}}"
location: "{{location}}"
- name: create-prospects
type: call
call: workday.create-prospect
with:
source: "LinkedIn"
requisition_area: "{{therapeutic_area}}"
- name: notify-ta
type: call
call: msteams.send-message
with:
channel_id: "$secrets.talent_channel"
text: "MSL Talent Pipeline: {{search-linkedin.count}} candidates found for {{therapeutic_area}} in {{location}}."
consumes:
- type: http
namespace: linkedin
baseUri: "https://api.linkedin.com/v2"
authentication:
type: bearer
token: "$secrets.linkedin_token"
resources:
- name: people-search
path: "/people?keywords={{keywords}}"
inputParameters:
- name: keywords
in: query
operations:
- name: search-candidates
method: GET
- type: http
namespace: workday
baseUri: "https://wd5-services1.myworkday.com/ccx/service/merck/Recruiting/v42.0"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: prospects
path: "/prospects"
operations:
- name: create-prospect
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Processes manufacturing deviations by creating a ServiceNow incident, logging in SAP QM, and notifying quality assurance for Merck.
naftiko: "0.5"
info:
label: "Manufacturing Deviation Handler"
description: "Processes manufacturing deviations by creating a ServiceNow incident, logging in SAP QM, and notifying quality assurance for Merck."
tags:
- manufacturing
- quality
- servicenow
- sap
capability:
exposes:
- type: mcp
namespace: manufacturing-qa
port: 8080
tools:
- name: handle-deviation
description: "Given deviation details, create a ServiceNow incident, log in SAP quality management, and notify the QA team."
inputParameters:
- name: batch_number
in: body
type: string
description: "The manufacturing batch number."
- name: deviation_type
in: body
type: string
description: "Type of deviation (process, equipment, material)."
- name: description
in: body
type: string
description: "Detailed description of the deviation."
- name: plant
in: body
type: string
description: "The manufacturing plant code."
steps:
- name: create-snow-incident
type: call
call: servicenow.create-incident
with:
short_description: "MFG Deviation: {{deviation_type}} — Batch {{batch_number}}"
category: "manufacturing_quality"
description: "Plant: {{plant}} | Batch: {{batch_number}} | Type: {{deviation_type}} | Details: {{description}}"
- name: log-sap-notification
type: call
call: sap.create-quality-notification
with:
notification_type: "Q2"
material: "{{batch_number}}"
plant: "{{plant}}"
description: "{{deviation_type}}: {{description}}"
- name: notify-qa
type: call
call: msteams.send-message
with:
channel_id: "$secrets.qa_channel"
text: "MFG Deviation Alert: {{deviation_type}} at Plant {{plant}}, Batch {{batch_number}}. SNOW: {{create-snow-incident.number}}. SAP QN: {{log-sap-notification.notification_number}}."
consumes:
- type: http
namespace: servicenow
baseUri: "https://merck.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: incidents
path: "/table/incident"
operations:
- name: create-incident
method: POST
- type: http
namespace: sap
baseUri: "https://merck-s4.sap.com/sap/opu/odata/sap/API_QUALITYNOTIFICATION_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: records
path: "/"
operations:
- name: create-record
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Processes medical information requests by logging in Salesforce, searching the knowledge base, and notifying the medical affairs team for Merck.
naftiko: "0.5"
info:
label: "Medical Information Request Handler"
description: "Processes medical information requests by logging in Salesforce, searching the knowledge base, and notifying the medical affairs team for Merck."
tags:
- medical-affairs
- salesforce
- knowledge-management
- compliance
capability:
exposes:
- type: mcp
namespace: medical-affairs
port: 8080
tools:
- name: handle-med-info-request
description: "Given a medical information request, log in Salesforce, search the knowledge base, and notify medical affairs."
inputParameters:
- name: requestor_name
in: body
type: string
description: "Name of the healthcare professional."
- name: product_name
in: body
type: string
description: "The product being inquired about."
- name: question
in: body
type: string
description: "The medical information question."
- name: channel
in: body
type: string
description: "Request channel (phone, email, web)."
steps:
- name: log-in-salesforce
type: call
call: salesforce.create-case
with:
subject: "MedInfo Request: {{product_name}}"
description: "Requestor: {{requestor_name}} | Product: {{product_name}} | Question: {{question}}"
type: "Medical_Information"
- name: search-knowledge
type: call
call: confluence.search-content
with:
search_query: "{{product_name}} {{question}}"
- name: notify-med-affairs
type: call
call: msteams.send-message
with:
channel_id: "$secrets.med_affairs_channel"
text: "New MedInfo Request from {{requestor_name}} about {{product_name}}. Case: {{log-in-salesforce.id}}. KB matches: {{search-knowledge.totalSize}}."
consumes:
- type: http
namespace: salesforce
baseUri: "https://merck.my.salesforce.com/services/data/v59.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: cases
path: "/sobjects/Case"
operations:
- name: create-case
method: POST
- type: http
namespace: confluence
baseUri: "https://merck.atlassian.net/wiki/rest/api"
authentication:
type: bearer
token: "$secrets.confluence_token"
resources:
- name: search
path: "/content/search"
operations:
- name: search-content
method: GET
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Launches periodic access certification campaigns by pulling user data from Okta, creating review tasks, and notifying managers for Merck.
naftiko: "0.5"
info:
label: "Okta Access Certification Campaign Launcher"
description: "Launches periodic access certification campaigns by pulling user data from Okta, creating review tasks, and notifying managers for Merck."
tags:
- security
- okta
- servicenow
- compliance
capability:
exposes:
- type: mcp
namespace: identity-governance
port: 8080
tools:
- name: launch-access-certification
description: "Given a certification scope, pull active users from Okta, create review tasks, and notify owners."
inputParameters:
- name: application_name
in: body
type: string
description: "The Okta application name to certify."
- name: campaign_name
in: body
type: string
description: "The certification campaign name."
steps:
- name: get-users
type: call
call: okta.get-app-users
with:
application_name: "{{application_name}}"
- name: create-campaign
type: call
call: servicenow.create-incident
with:
short_description: "Access Certification: {{campaign_name}} — {{application_name}}"
category: "identity_governance"
- name: notify-owners
type: call
call: msteams.send-message
with:
channel_id: "$secrets.iam_channel"
text: "Access Certification: {{campaign_name}} for {{application_name}}. {{get-users.count}} users to review. SNOW: {{create-campaign.number}}."
consumes:
- type: http
namespace: okta
baseUri: "https://merck.okta.com/api/v1"
authentication:
type: bearer
token: "$secrets.okta_token"
resources:
- name: app-users
path: "/apps/{{application_name}}/users"
inputParameters:
- name: application_name
in: path
operations:
- name: get-app-users
method: GET
- type: http
namespace: servicenow
baseUri: "https://merck.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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Provisions Okta access to laboratory information systems for new research scientists and logs the provisioning in ServiceNow.
naftiko: "0.5"
info:
label: "Okta Identity Provisioning for Lab Systems"
description: "Provisions Okta access to laboratory information systems for new research scientists and logs the provisioning in ServiceNow."
tags:
- identity
- security
- okta
- servicenow
- access-management
- research
capability:
exposes:
- type: mcp
namespace: lab-identity
port: 8080
tools:
- name: provision-lab-access
description: "Given a new research scientist's email and lab system list, assign Okta group memberships for laboratory information systems and log the provisioning in a ServiceNow ticket."
inputParameters:
- name: user_email
in: body
type: string
description: "The research scientist's work email address."
- name: lab_systems
in: body
type: string
description: "Comma-separated list of laboratory system identifiers to provision (e.g., LIMS, ELN, ChemDraw)."
- name: research_unit
in: body
type: string
description: "The research unit the scientist belongs to (e.g., Oncology, Vaccines)."
steps:
- name: get-user
type: call
call: "okta.get-user-by-email"
with:
email: "{{user_email}}"
- name: assign-lab-groups
type: call
call: "okta.add-user-to-group"
with:
user_id: "{{get-user.id}}"
group_profile: "{{research_unit}}_lab_access"
- name: log-provisioning
type: call
call: "servicenow.create-incident"
with:
short_description: "Lab system access provisioned for {{user_email}}"
category: "access_management"
description: "Systems: {{lab_systems}} | Research Unit: {{research_unit}}"
consumes:
- type: http
namespace: okta
baseUri: "https://merck.okta.com/api/v1"
authentication:
type: apikey
key: "Authorization"
value: "$secrets.okta_api_token"
placement: header
resources:
- name: users
path: "/users"
operations:
- name: get-user-by-email
method: GET
- name: group-memberships
path: "/groups/{{group_id}}/users/{{user_id}}"
inputParameters:
- name: group_id
in: path
- name: user_id
in: path
operations:
- name: add-user-to-group
method: PUT
- type: http
namespace: servicenow
baseUri: "https://merck.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: incident
path: "/table/incident"
operations:
- name: create-incident
method: POST
Retrieves the current status and profile of an Okta user by login email for Merck identity management.
naftiko: "0.5"
info:
label: "Okta User Status Lookup"
description: "Retrieves the current status and profile of an Okta user by login email for Merck identity management."
tags:
- security
- okta
- identity
- lookup
capability:
exposes:
- type: mcp
namespace: identity-ops
port: 8080
tools:
- name: get-user-status
description: "Given a user email, return the Okta user status, last login, and MFA enrollment status."
inputParameters:
- name: user_email
in: body
type: string
description: "The user login email address."
call: okta.get-user
with:
user_email: "{{user_email}}"
outputParameters:
- name: status
type: string
mapping: "$.status"
- name: last_login
type: string
mapping: "$.lastLogin"
- name: mfa_enrolled
type: boolean
mapping: "$.credentials.provider.type"
consumes:
- type: http
namespace: okta
baseUri: "https://merck.okta.com/api/v1"
authentication:
type: bearer
token: "$secrets.okta_token"
resources:
- name: users
path: "/users/{{user_email}}"
inputParameters:
- name: user_email
in: path
operations:
- name: get-user
method: GET
Processes patient assistance program enrollments by creating cases in Salesforce, verifying eligibility, and notifying patient services for Merck.
naftiko: "0.5"
info:
label: "Patient Assistance Program Enrollment Processor"
description: "Processes patient assistance program enrollments by creating cases in Salesforce, verifying eligibility, and notifying patient services for Merck."
tags:
- commercial
- salesforce
- patient-services
- compliance
capability:
exposes:
- type: mcp
namespace: patient-services
port: 8080
tools:
- name: process-pap-enrollment
description: "Given patient enrollment details, create a Salesforce case, verify eligibility, and notify the patient services team."
inputParameters:
- name: patient_id
in: body
type: string
description: "The patient identifier."
- name: product_name
in: body
type: string
description: "The product for which assistance is requested."
- name: insurance_status
in: body
type: string
description: "Patient insurance status."
steps:
- name: create-case
type: call
call: salesforce.create-case
with:
subject: "PAP Enrollment: {{product_name}} — Patient {{patient_id}}"
type: "Patient_Assistance"
- name: verify-eligibility
type: call
call: snowflake.execute-query
with:
statement: "SELECT eligible FROM pap_eligibility_rules WHERE product = '{{product_name}}'"
warehouse: "COMMERCIAL_WH"
- name: notify-team
type: call
call: msteams.send-message
with:
channel_id: "$secrets.patient_services_channel"
text: "PAP Enrollment: Patient {{patient_id}} for {{product_name}}. Eligibility: {{verify-eligibility.data}}. Case: {{create-case.id}}."
consumes:
- type: http
namespace: salesforce
baseUri: "https://merck.my.salesforce.com/services/data/v59.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: cases
path: "/sobjects/Case"
operations:
- name: create-case
method: POST
- type: http
namespace: snowflake
baseUri: "https://merck.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: execute-query
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
When an adverse event report is received, creates a Veeva Vault safety record, opens a ServiceNow priority incident, and notifies the pharmacovigilance team via Microsoft Teams.
naftiko: "0.5"
info:
label: "Pharmacovigilance Adverse Event Intake"
description: "When an adverse event report is received, creates a Veeva Vault safety record, opens a ServiceNow priority incident, and notifies the pharmacovigilance team via Microsoft Teams."
tags:
- pharmacovigilance
- safety
- veeva
- servicenow
- microsoft-teams
- compliance
capability:
exposes:
- type: mcp
namespace: safety-ops
port: 8080
tools:
- name: intake-adverse-event
description: "Given an adverse event report with patient ID, drug name, and event description, create a Veeva Vault safety case record, open a high-priority ServiceNow incident, and alert the pharmacovigilance Microsoft Teams channel."
inputParameters:
- name: patient_id
in: body
type: string
description: "The anonymized patient identifier from the adverse event report."
- name: drug_name
in: body
type: string
description: "The Merck drug or compound associated with the adverse event."
- name: event_description
in: body
type: string
description: "Clinical description of the adverse event."
- name: severity
in: body
type: string
description: "Event severity classification: mild, moderate, severe, or life-threatening."
steps:
- name: create-safety-case
type: call
call: "veeva.create-safety-case"
with:
patient_id: "{{patient_id}}"
drug_name: "{{drug_name}}"
description: "{{event_description}}"
severity: "{{severity}}"
- name: open-incident
type: call
call: "servicenow.create-incident"
with:
short_description: "Adverse event: {{drug_name}} - {{severity}}"
urgency: "1"
category: "pharmacovigilance"
- name: notify-pv-team
type: call
call: "msteams.post-channel-message"
with:
channel_id: "pharmacovigilance"
message: "NEW ADVERSE EVENT: Drug {{drug_name}} | Severity: {{severity}} | Vault Case: {{create-safety-case.case_id}} | SNOW: {{open-incident.number}}"
consumes:
- type: http
namespace: veeva
baseUri: "https://merck.veevavault.com/api/v21.2"
authentication:
type: bearer
token: "$secrets.veeva_token"
resources:
- name: safety-cases
path: "/objects/safety_cases"
operations:
- name: create-safety-case
method: POST
- type: http
namespace: servicenow
baseUri: "https://merck.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: incident
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
Runs pharmacovigilance signal detection queries in Snowflake, generates summary reports, and alerts the safety review board for Merck.
naftiko: "0.5"
info:
label: "Pharmacovigilance Signal Detection Reporter"
description: "Runs pharmacovigilance signal detection queries in Snowflake, generates summary reports, and alerts the safety review board for Merck."
tags:
- drug-safety
- pharmacovigilance
- snowflake
- analytics
capability:
exposes:
- type: mcp
namespace: pv-analytics
port: 8080
tools:
- name: run-signal-detection
description: "Given a product and time period, run signal detection queries, create a Jira tracking issue, and alert the safety board."
inputParameters:
- name: product_name
in: body
type: string
description: "The drug product name."
- name: period_start
in: body
type: string
description: "Analysis period start date."
- name: period_end
in: body
type: string
description: "Analysis period end date."
steps:
- name: run-detection
type: call
call: snowflake.execute-query
with:
statement: "CALL pv_signal_detection('{{product_name}}', '{{period_start}}', '{{period_end}}')"
warehouse: "PV_WH"
- name: create-review-ticket
type: call
call: jira.create-issue
with:
project: "PV"
summary: "Signal Detection: {{product_name}} ({{period_start}} to {{period_end}})"
issuetype: "Task"
- name: alert-safety-board
type: call
call: msteams.send-message
with:
channel_id: "$secrets.safety_board_channel"
text: "PV Signal Detection: {{product_name}} ({{period_start}} to {{period_end}}). Signals: {{run-detection.signal_count}}. Jira: {{create-review-ticket.key}}."
consumes:
- type: http
namespace: snowflake
baseUri: "https://merck.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: execute-query
method: POST
- type: http
namespace: jira
baseUri: "https://merck.atlassian.net/rest/api/3"
authentication:
type: bearer
token: "$secrets.jira_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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Triggers a Power BI dataset refresh for the global commercial analytics dashboard and notifies the commercial insights team via Microsoft Teams.
naftiko: "0.5"
info:
label: "Power BI Commercial Analytics Refresh"
description: "Triggers a Power BI dataset refresh for the global commercial analytics dashboard and notifies the commercial insights team via Microsoft Teams."
tags:
- analytics
- reporting
- power-bi
- microsoft-teams
- commercial
capability:
exposes:
- type: mcp
namespace: commercial-analytics
port: 8080
tools:
- name: refresh-commercial-dashboard
description: "Given a Power BI dataset ID and workspace ID, trigger a dataset refresh for the Merck commercial analytics dashboard and notify the insights team via Microsoft Teams."
inputParameters:
- name: dataset_id
in: body
type: string
description: "The Power BI dataset ID for the commercial analytics dashboard."
- name: workspace_id
in: body
type: string
description: "The Power BI workspace ID containing the dataset."
steps:
- name: trigger-refresh
type: call
call: "powerbi.refresh-dataset"
with:
dataset_id: "{{dataset_id}}"
workspace_id: "{{workspace_id}}"
- name: notify-team
type: call
call: "msteams.post-channel-message"
with:
channel_id: "commercial-insights"
message: "Commercial analytics refresh initiated for dataset {{dataset_id}}. Expected completion: 15 minutes."
consumes:
- type: http
namespace: powerbi
baseUri: "https://api.powerbi.com/v1.0/myorg"
authentication:
type: bearer
token: "$secrets.powerbi_token"
resources:
- name: dataset-refreshes
path: "/groups/{{workspace_id}}/datasets/{{dataset_id}}/refreshes"
inputParameters:
- name: workspace_id
in: path
- name: dataset_id
in: path
operations:
- name: refresh-dataset
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 for Merck analytics operations.
naftiko: "0.5"
info:
label: "Power BI Dataset Refresh Status"
description: "Checks the last refresh status of a Power BI dataset for Merck analytics operations."
tags:
- analytics
- power-bi
- reporting
- lookup
capability:
exposes:
- type: mcp
namespace: analytics-ops
port: 8080
tools:
- name: get-refresh-status
description: "Given a Power BI dataset ID, return the last refresh status, start time, and end time."
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: start_time
type: string
mapping: "$.value[0].startTime"
- 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: datasets
path: "/datasets/{{dataset_id}}/refreshes?$top=1"
inputParameters:
- name: dataset_id
in: path
operations:
- name: get-refresh-history
method: GET
Coordinates product recall activities by creating cases in Salesforce, notifying logistics via SAP, and alerting leadership for Merck.
naftiko: "0.5"
info:
label: "Product Recall Coordination Workflow"
description: "Coordinates product recall activities by creating cases in Salesforce, notifying logistics via SAP, and alerting leadership for Merck."
tags:
- quality
- product-recall
- salesforce
- sap
capability:
exposes:
- type: mcp
namespace: quality-recall
port: 8080
tools:
- name: initiate-recall
description: "Given product recall details, create a Salesforce case, update SAP batch status, and send urgent notifications."
inputParameters:
- name: product_name
in: body
type: string
description: "The product name being recalled."
- name: batch_numbers
in: body
type: string
description: "Comma-separated affected batch numbers."
- name: recall_reason
in: body
type: string
description: "Reason for the recall."
- name: recall_class
in: body
type: string
description: "Recall classification (Class I, II, III)."
steps:
- name: create-recall-case
type: call
call: salesforce.create-case
with:
subject: "Product Recall: {{product_name}} — {{recall_class}}"
type: "Product_Recall"
- name: update-batch-status
type: call
call: sap.update-batch-status
with:
batch_numbers: "{{batch_numbers}}"
status: "blocked"
- name: alert-leadership
type: call
call: msteams.send-message
with:
channel_id: "$secrets.executive_channel"
text: "URGENT — Product Recall: {{product_name}} ({{recall_class}}). Batches: {{batch_numbers}}. Case: {{create-recall-case.id}}."
consumes:
- type: http
namespace: salesforce
baseUri: "https://merck.my.salesforce.com/services/data/v59.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: cases
path: "/sobjects/Case"
operations:
- name: create-case
method: POST
- type: http
namespace: sap
baseUri: "https://merck-s4.sap.com/sap/opu/odata/sap/API_BATCH_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: records
path: "/"
operations:
- name: create-record
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Refreshes the R&D pipeline dashboard by pulling compound status from Snowflake, updating Power BI, and notifying R&D leadership for Merck.
naftiko: "0.5"
info:
label: "R&D Compound Pipeline Dashboard Refresh"
description: "Refreshes the R&D pipeline dashboard by pulling compound status from Snowflake, updating Power BI, and notifying R&D leadership for Merck."
tags:
- r-and-d
- snowflake
- power-bi
- analytics
capability:
exposes:
- type: mcp
namespace: rd-analytics
port: 8080
tools:
- name: refresh-pipeline-dashboard
description: "Trigger a pipeline data extract from Snowflake, refresh the Power BI dataset, and notify leadership."
inputParameters:
- name: dashboard_id
in: body
type: string
description: "The Power BI dashboard dataset ID."
- name: teams_channel_id
in: body
type: string
description: "Teams channel for R&D leadership."
steps:
- name: extract-pipeline-data
type: call
call: snowflake.execute-query
with:
statement: "CALL refresh_rd_pipeline_snapshot()"
warehouse: "RD_WH"
- name: refresh-powerbi
type: call
call: powerbi.trigger-refresh
with:
dataset_id: "{{dashboard_id}}"
- name: notify-leadership
type: call
call: msteams.send-message
with:
channel_id: "{{teams_channel_id}}"
text: "R&D Pipeline Dashboard refreshed. Data as of {{extract-pipeline-data.timestamp}}."
consumes:
- type: http
namespace: snowflake
baseUri: "https://merck.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: execute-query
method: POST
- type: http
namespace: powerbi
baseUri: "https://api.powerbi.com/v1.0/myorg"
authentication:
type: bearer
token: "$secrets.powerbi_token"
resources:
- name: datasets
path: "/datasets/{{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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Orchestrates RWE data ingestion from external sources into Snowflake, validates data quality, and notifies the HEOR team for Merck.
naftiko: "0.5"
info:
label: "Real-World Evidence Data Ingestion Pipeline"
description: "Orchestrates RWE data ingestion from external sources into Snowflake, validates data quality, and notifies the HEOR team for Merck."
tags:
- r-and-d
- real-world-evidence
- snowflake
- data-engineering
capability:
exposes:
- type: mcp
namespace: rwe-analytics
port: 8080
tools:
- name: ingest-rwe-data
description: "Given a data source and dataset identifier, ingest into Snowflake, run quality checks, and notify HEOR."
inputParameters:
- name: data_source
in: body
type: string
description: "The RWE data source name (claims, EMR, registry)."
- name: dataset_id
in: body
type: string
description: "The dataset identifier."
- name: study_id
in: body
type: string
description: "The associated study ID."
steps:
- name: ingest-data
type: call
call: snowflake.execute-query
with:
statement: "CALL rwe_ingest_pipeline('{{data_source}}', '{{dataset_id}}', '{{study_id}}')"
warehouse: "RWE_WH"
- name: validate-quality
type: call
call: snowflake.execute-query
with:
statement: "CALL rwe_data_quality_check('{{dataset_id}}')"
warehouse: "RWE_WH"
- name: notify-heor
type: call
call: msteams.send-message
with:
channel_id: "$secrets.heor_channel"
text: "RWE Data Ingestion Complete: {{data_source}} ({{dataset_id}}) for Study {{study_id}}. Records: {{ingest-data.row_count}}."
consumes:
- type: http
namespace: snowflake
baseUri: "https://merck.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: execute-query
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Queries Veeva Vault for upcoming regulatory submission deadlines, creates Jira tracking tickets, and alerts the regulatory affairs team for Merck.
naftiko: "0.5"
info:
label: "Regulatory Submission Deadline Tracker"
description: "Queries Veeva Vault for upcoming regulatory submission deadlines, creates Jira tracking tickets, and alerts the regulatory affairs team for Merck."
tags:
- regulatory
- veeva-vault
- jira
- compliance
capability:
exposes:
- type: mcp
namespace: regulatory-ops
port: 8080
tools:
- name: track-submission-deadlines
description: "Given a time horizon in days, find upcoming submission deadlines, create Jira tickets, and post a summary."
inputParameters:
- name: days_ahead
in: body
type: integer
description: "Number of days ahead to check for deadlines."
- name: teams_channel_id
in: body
type: string
description: "Teams channel for regulatory affairs notifications."
steps:
- name: query-deadlines
type: call
call: veeva.query-submissions
with:
query: "SELECT id, name__v, submission_date__c FROM submission__c WHERE submission_date__c <= DATEADD(day,{{days_ahead}},GETDATE())"
- name: create-tracker
type: call
call: jira.create-issue
with:
project: "REG"
summary: "Upcoming Submissions: {{query-deadlines.totalCount}} items within {{days_ahead}} days"
issuetype: "Task"
- name: alert-team
type: call
call: msteams.send-message
with:
channel_id: "{{teams_channel_id}}"
text: "Regulatory Alert: {{query-deadlines.totalCount}} submissions due within {{days_ahead}} days. Jira: {{create-tracker.key}}"
consumes:
- type: http
namespace: veeva
baseUri: "https://merck.veevavault.com/api/v24.1"
authentication:
type: bearer
token: "$secrets.veeva_token"
resources:
- name: object-records
path: "/vobjects/{{object_type}}"
inputParameters:
- name: object_type
in: path
operations:
- name: create-object-record
method: POST
- type: http
namespace: jira
baseUri: "https://merck.atlassian.net/rest/api/3"
authentication:
type: bearer
token: "$secrets.jira_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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Assembles a regulatory submission document package from Veeva Vault, validates completeness, and routes for final approval through SAP S/4HANA workflow.
naftiko: "0.5"
info:
label: "Regulatory Submission Document Package"
description: "Assembles a regulatory submission document package from Veeva Vault, validates completeness, and routes for final approval through SAP S/4HANA workflow."
tags:
- regulatory
- veeva
- sap-s4hana
- compliance
- document-management
capability:
exposes:
- type: mcp
namespace: regulatory-ops
port: 8080
tools:
- name: package-regulatory-submission
description: "Given a Veeva Vault study ID, retrieve all associated regulatory documents, validate package completeness, and create an SAP S/4HANA workflow task for final regulatory affairs approval."
inputParameters:
- name: study_id
in: body
type: string
description: "The Veeva Vault study identifier for which to assemble the regulatory package."
- name: submission_type
in: body
type: string
description: "The regulatory submission type (e.g., NDA, IND, BLA, MAA)."
steps:
- name: get-documents
type: call
call: "veeva.list-study-documents"
with:
study_id: "{{study_id}}"
submission_type: "{{submission_type}}"
- name: create-approval-task
type: call
call: "sap-s4.create-workflow-task"
with:
task_type: "regulatory_submission_review"
description: "{{submission_type}} package for Study {{study_id}} - {{get-documents.document_count}} documents"
priority: "high"
consumes:
- type: http
namespace: veeva
baseUri: "https://merck.veevavault.com/api/v21.2"
authentication:
type: bearer
token: "$secrets.veeva_token"
resources:
- name: study-documents
path: "/objects/documents"
operations:
- name: list-study-documents
method: GET
- type: http
namespace: sap-s4
baseUri: "https://merck-s4.sap.com/sap/opu/odata/sap/WS_TASK_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: workflow-tasks
path: "/WorkflowTaskSet"
operations:
- name: create-workflow-task
method: POST
Orchestrates commercial territory realignment by updating Salesforce territories, adjusting Workday reporting, and notifying the commercial team for Merck.
naftiko: "0.5"
info:
label: "Salesforce Commercial Territory Realignment Orchestrator"
description: "Orchestrates commercial territory realignment by updating Salesforce territories, adjusting Workday reporting, and notifying the commercial team for Merck."
tags:
- commercial
- salesforce
- workday
- territory-management
capability:
exposes:
- type: mcp
namespace: commercial-ops-mgmt
port: 8080
tools:
- name: realign-territories
description: "Given territory changes, update Salesforce assignments, adjust Workday structures, and notify the team."
inputParameters:
- name: territory_id
in: body
type: string
description: "The territory identifier."
- name: new_rep_id
in: body
type: string
description: "The new sales representative employee ID."
- name: effective_date
in: body
type: string
description: "Effective date of the realignment."
steps:
- name: update-salesforce
type: call
call: salesforce.update-record
with:
object_type: "Territory2"
id: "{{territory_id}}"
Assigned_Rep__c: "{{new_rep_id}}"
- name: update-workday
type: call
call: workday.update-assignment
with:
employee_id: "{{new_rep_id}}"
territory: "{{territory_id}}"
- name: notify-commercial
type: call
call: msteams.send-message
with:
channel_id: "$secrets.commercial_ops_channel"
text: "Territory Realignment: Territory {{territory_id}} assigned to Rep {{new_rep_id}} effective {{effective_date}}."
consumes:
- type: http
namespace: salesforce
baseUri: "https://merck.my.salesforce.com/services/data/v59.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: territories
path: "/sobjects/Territory2/{{id}}"
inputParameters:
- name: id
in: path
operations:
- name: update-record
method: PATCH
- type: http
namespace: workday
baseUri: "https://wd5-services1.myworkday.com/ccx/service/merck/Staffing/v42.0"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: assignments
path: "/workers/{{employee_id}}/assignments"
inputParameters:
- name: employee_id
in: path
operations:
- name: update-assignment
method: PUT
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Retrieves healthcare provider account details from Salesforce CRM by account ID for Merck commercial operations.
naftiko: "0.5"
info:
label: "Salesforce HCP Account Lookup"
description: "Retrieves healthcare provider account details from Salesforce CRM by account ID for Merck commercial operations."
tags:
- commercial
- salesforce
- hcp
- lookup
capability:
exposes:
- type: mcp
namespace: commercial-ops
port: 8080
tools:
- name: get-hcp-account
description: "Given a Salesforce account ID, return the HCP name, specialty, prescribing tier, and territory."
inputParameters:
- name: account_id
in: body
type: string
description: "The Salesforce account ID for the healthcare provider."
call: salesforce.get-account
with:
account_id: "{{account_id}}"
outputParameters:
- name: hcp_name
type: string
mapping: "$.Name"
- name: specialty
type: string
mapping: "$.Specialty__c"
- name: tier
type: string
mapping: "$.Prescribing_Tier__c"
- name: territory
type: string
mapping: "$.Territory__c"
consumes:
- type: http
namespace: salesforce
baseUri: "https://merck.my.salesforce.com/services/data/v59.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: accounts
path: "/sobjects/Account/{{account_id}}"
inputParameters:
- name: account_id
in: path
operations:
- name: get-account
method: GET
When a key account NPS survey response is below threshold in Salesforce, creates a follow-up task for the account manager and logs a customer success case.
naftiko: "0.5"
info:
label: "Salesforce Key Account NPS Follow-Up"
description: "When a key account NPS survey response is below threshold in Salesforce, creates a follow-up task for the account manager and logs a customer success case."
tags:
- sales
- crm
- salesforce
- customer-success
- nps
capability:
exposes:
- type: mcp
namespace: customer-success
port: 8080
tools:
- name: handle-low-nps-response
description: "Given a Salesforce survey response record with a low NPS score, create a follow-up task for the account manager and open a customer success case for investigation."
inputParameters:
- name: survey_response_id
in: body
type: string
description: "The Salesforce survey response ID with the low NPS score."
- name: nps_score
in: body
type: integer
description: "The NPS score that triggered this follow-up (0-6 range)."
steps:
- name: get-response
type: call
call: "salesforce-survey.get-survey-response"
with:
response_id: "{{survey_response_id}}"
- name: create-task
type: call
call: "salesforce-task.create-task"
with:
owner_id: "{{get-response.account_manager_id}}"
subject: "NPS Follow-Up: {{get-response.account_name}} scored {{nps_score}}"
due_date: "+3d"
- name: create-case
type: call
call: "salesforce-case.create-case"
with:
account_id: "{{get-response.account_id}}"
subject: "Customer Success: Low NPS {{nps_score}} - {{get-response.account_name}}"
origin: "NPS Survey"
consumes:
- type: http
namespace: salesforce-survey
baseUri: "https://merck.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: survey-responses
path: "/sobjects/SurveyQuestionResponse/{{response_id}}"
inputParameters:
- name: response_id
in: path
operations:
- name: get-survey-response
method: GET
- type: http
namespace: salesforce-task
baseUri: "https://merck.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: tasks
path: "/sobjects/Task"
operations:
- name: create-task
method: POST
- type: http
namespace: salesforce-case
baseUri: "https://merck.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: cases
path: "/sobjects/Case"
operations:
- name: create-case
method: POST
Tracks KOL engagement activities by pulling data from Salesforce, summarizing in Snowflake, and reporting to medical affairs for Merck.
naftiko: "0.5"
info:
label: "Salesforce Key Opinion Leader Engagement Tracker"
description: "Tracks KOL engagement activities by pulling data from Salesforce, summarizing in Snowflake, and reporting to medical affairs for Merck."
tags:
- medical-affairs
- salesforce
- snowflake
- analytics
capability:
exposes:
- type: mcp
namespace: medical-affairs-analytics
port: 8080
tools:
- name: track-kol-engagement
description: "Given a therapeutic area, pull KOL engagement data, aggregate in Snowflake, and post a summary."
inputParameters:
- name: therapeutic_area
in: body
type: string
description: "The therapeutic area (e.g., oncology, immunology)."
- name: period
in: body
type: string
description: "Reporting period (e.g., Q1-2026)."
steps:
- name: pull-kol-data
type: call
call: salesforce.query
with:
q: "SELECT Name, Total_Engagements__c FROM Contact WHERE Therapeutic_Area__c = '{{therapeutic_area}}' AND KOL_Flag__c = true"
- name: aggregate-data
type: call
call: snowflake.execute-query
with:
statement: "INSERT INTO kol_engagement_summary SELECT * FROM staged_kol_data WHERE period = '{{period}}'"
warehouse: "ANALYTICS_WH"
- name: post-summary
type: call
call: msteams.send-message
with:
channel_id: "$secrets.med_affairs_channel"
text: "KOL Engagement Summary for {{therapeutic_area}} ({{period}}): {{pull-kol-data.totalSize}} KOLs tracked."
consumes:
- type: http
namespace: salesforce
baseUri: "https://merck.my.salesforce.com/services/data/v59.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: query
path: "/query"
operations:
- name: query
method: GET
- type: http
namespace: snowflake
baseUri: "https://merck.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: execute-query
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Syncs medical representative call activity from Salesforce CRM to SAP S/4HANA for revenue attribution and territory management reporting.
naftiko: "0.5"
info:
label: "Salesforce Medical Representative Activity Sync"
description: "Syncs medical representative call activity from Salesforce CRM to SAP S/4HANA for revenue attribution and territory management reporting."
tags:
- sales
- crm
- salesforce
- sap-s4hana
- medical-affairs
capability:
exposes:
- type: mcp
namespace: medaffairs-sales
port: 8080
tools:
- name: sync-rep-call-activity
description: "Given a Salesforce activity record ID for a medical representative call, retrieve call details and sync the physician touchpoint to SAP S/4HANA for territory analytics."
inputParameters:
- name: activity_id
in: body
type: string
description: "The Salesforce Activity ID for the medical representative call."
steps:
- name: get-activity
type: call
call: "salesforce.get-activity"
with:
activity_id: "{{activity_id}}"
- name: sync-to-sap
type: call
call: "sap-s4.create-sales-activity"
with:
rep_id: "{{get-activity.owner_id}}"
physician_id: "{{get-activity.contact_id}}"
product: "{{get-activity.product_name}}"
call_date: "{{get-activity.activity_date}}"
consumes:
- type: http
namespace: salesforce
baseUri: "https://merck.my.salesforce.com/services/data/v58.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: activities
path: "/sobjects/Activity/{{activity_id}}"
inputParameters:
- name: activity_id
in: path
operations:
- name: get-activity
method: GET
- type: http
namespace: sap-s4
baseUri: "https://merck-s4.sap.com/sap/opu/odata/sap/SD_ACTIVITY_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: sales-activities
path: "/A_SalesActivity"
operations:
- name: create-sales-activity
method: POST
Queries SAP Ariba for supplier contracts expiring within 90 days and creates Jira procurement tasks for contract renewal negotiations.
naftiko: "0.5"
info:
label: "SAP Ariba Contract Expiry Alert"
description: "Queries SAP Ariba for supplier contracts expiring within 90 days and creates Jira procurement tasks for contract renewal negotiations."
tags:
- procurement
- sap-ariba
- jira
- contract-management
capability:
exposes:
- type: mcp
namespace: contract-renewal
port: 8080
tools:
- name: alert-expiring-contracts
description: "Query SAP Ariba for contracts expiring within a specified number of days, create Jira tasks for each contract requiring renewal, and notify the procurement team via Microsoft Teams."
inputParameters:
- name: days_ahead
in: body
type: integer
description: "Number of days ahead to check for expiring contracts (e.g., 90)."
steps:
- name: get-expiring
type: call
call: "sap-ariba.list-expiring-contracts"
with:
expiry_within_days: "{{days_ahead}}"
- name: create-renewal-task
type: call
call: "jira.create-issue"
with:
project_key: "PROC"
issuetype: "Task"
summary: "Contract renewals due in {{days_ahead}} days: {{get-expiring.contract_count}} contracts"
description: "{{get-expiring.contract_list}}"
- name: notify-procurement
type: call
call: "msteams.post-channel-message"
with:
channel_id: "procurement-ops"
message: "Contract Alert: {{get-expiring.contract_count}} contracts expiring within {{days_ahead}} days. Jira: {{create-renewal-task.key}}"
consumes:
- type: http
namespace: sap-ariba
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: list-expiring-contracts
method: GET
- type: http
namespace: jira
baseUri: "https://merck.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
Manages contract renewal workflows by checking expiring contracts in SAP Ariba, creating ServiceNow tasks, and notifying procurement for Merck.
naftiko: "0.5"
info:
label: "SAP Ariba Contract Renewal Workflow"
description: "Manages contract renewal workflows by checking expiring contracts in SAP Ariba, creating ServiceNow tasks, and notifying procurement for Merck."
tags:
- procurement
- sap-ariba
- servicenow
- contract-management
capability:
exposes:
- type: mcp
namespace: procurement-contracts
port: 8080
tools:
- name: process-contract-renewal
description: "Given a contract ID, check renewal terms, create a ServiceNow task, and notify procurement."
inputParameters:
- name: contract_id
in: body
type: string
description: "The SAP Ariba contract ID."
- name: contract_owner
in: body
type: string
description: "The contract owner name."
steps:
- name: get-contract
type: call
call: ariba.get-contract
with:
contract_id: "{{contract_id}}"
- name: create-renewal-task
type: call
call: servicenow.create-incident
with:
short_description: "Contract Renewal: {{get-contract.title}} — Expires {{get-contract.end_date}}"
category: "procurement"
- name: notify-procurement
type: call
call: msteams.send-message
with:
channel_id: "$secrets.procurement_channel"
text: "Contract Renewal: {{get-contract.title}} ({{contract_id}}) expires {{get-contract.end_date}}. Task: {{create-renewal-task.number}}."
consumes:
- type: http
namespace: ariba
baseUri: "https://openapi.ariba.com/api/procurement/v2/merck"
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
- type: http
namespace: servicenow
baseUri: "https://merck.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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Creates a purchase requisition in SAP Ariba for lab supplies and routes it for approval based on cost center and spend threshold.
naftiko: "0.5"
info:
label: "SAP Ariba Procurement Request"
description: "Creates a purchase requisition in SAP Ariba for lab supplies and routes it for approval based on cost center and spend threshold."
tags:
- procurement
- sap-ariba
- finance
- approval
capability:
exposes:
- type: mcp
namespace: procurement-ops
port: 8080
tools:
- name: create-procurement-request
description: "Given a supplier, item description, quantity, and cost center, create a purchase requisition in SAP Ariba and route it for approval according to Merck spend authority policy."
inputParameters:
- name: supplier_id
in: body
type: string
description: "The SAP Ariba supplier ID for the purchase."
- name: item_description
in: body
type: string
description: "Description of the item or service being procured."
- name: quantity
in: body
type: integer
description: "Quantity of items requested."
- name: unit_price
in: body
type: number
description: "Unit price in USD."
- name: cost_center
in: body
type: string
description: "The cost center code to charge for this purchase."
call: "sap-ariba.create-requisition"
with:
supplier_id: "{{supplier_id}}"
item_description: "{{item_description}}"
quantity: "{{quantity}}"
unit_price: "{{unit_price}}"
cost_center: "{{cost_center}}"
outputParameters:
- name: requisition_id
type: string
mapping: "$.requisitionId"
- name: status
type: string
mapping: "$.status"
consumes:
- type: http
namespace: sap-ariba
baseUri: "https://openapi.ariba.com/api/purchase-req/v1"
authentication:
type: apikey
key: "apiKey"
value: "$secrets.ariba_api_key"
placement: header
resources:
- name: requisitions
path: "/requisitions"
operations:
- name: create-requisition
method: POST
Retrieves batch genealogy and traceability data from SAP for a given batch number in Merck manufacturing.
naftiko: "0.5"
info:
label: "SAP Batch Genealogy Lookup"
description: "Retrieves batch genealogy and traceability data from SAP for a given batch number in Merck manufacturing."
tags:
- manufacturing
- sap
- batch-tracking
- quality
capability:
exposes:
- type: mcp
namespace: manufacturing-ops
port: 8080
tools:
- name: get-batch-genealogy
description: "Given a batch number and plant code, return the batch creation date, material, and expiry date."
inputParameters:
- name: batch_number
in: body
type: string
description: "The SAP batch number."
- name: plant
in: body
type: string
description: "The SAP plant code."
call: sap.get-batch
with:
batch_number: "{{batch_number}}"
plant: "{{plant}}"
outputParameters:
- name: material
type: string
mapping: "$.d.Material"
- name: manufacture_date
type: string
mapping: "$.d.ManufactureDate"
- name: shelf_life_expiry
type: string
mapping: "$.d.ShelfLifeExpirationDate"
consumes:
- type: http
namespace: sap
baseUri: "https://merck-s4.sap.com/sap/opu/odata/sap/API_BATCH_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: batches
path: "/A_Batch(Material='',Batch='{{batch_number}}',Plant='{{plant}}')"
inputParameters:
- name: batch_number
in: path
- name: plant
in: path
operations:
- name: get-batch
method: GET
Audits SAP Concur expense reports for policy compliance, flags violations for manager review, and updates the compliance tracking record.
naftiko: "0.5"
info:
label: "SAP Concur Travel and Expense Audit"
description: "Audits SAP Concur expense reports for policy compliance, flags violations for manager review, and updates the compliance tracking record."
tags:
- finance
- expense-management
- sap-concur
- compliance
- audit
capability:
exposes:
- type: mcp
namespace: expense-audit
port: 8080
tools:
- name: audit-expense-report
description: "Given a SAP Concur expense report ID, retrieve report details, validate each line item against Merck travel and expense policy, and flag non-compliant items for manager review."
inputParameters:
- name: report_id
in: body
type: string
description: "The SAP Concur expense report ID to audit."
steps:
- name: get-report
type: call
call: "concur.get-expense-report"
with:
report_id: "{{report_id}}"
- name: flag-violations
type: call
call: "concur.update-report-status"
with:
report_id: "{{report_id}}"
status: "Pending_Manager_Review"
comment: "Policy review required for items above daily limits"
consumes:
- type: http
namespace: concur
baseUri: "https://www.concursolutions.com/api/v3.0"
authentication:
type: bearer
token: "$secrets.concur_token"
resources:
- name: expense-reports
path: "/expense/reports/{{report_id}}"
inputParameters:
- name: report_id
in: path
operations:
- name: get-expense-report
method: GET
- name: update-report-status
method: PATCH
Checks travel expense reports for policy violations, creates audit findings in ServiceNow, and notifies finance for Merck.
naftiko: "0.5"
info:
label: "SAP Concur Travel Policy Compliance Checker"
description: "Checks travel expense reports for policy violations, creates audit findings in ServiceNow, and notifies finance for Merck."
tags:
- finance
- sap-concur
- compliance
- audit
capability:
exposes:
- type: mcp
namespace: finance-compliance
port: 8080
tools:
- name: check-travel-compliance
description: "Given an expense report ID, check for policy violations, create audit findings, and notify the compliance team."
inputParameters:
- name: report_id
in: body
type: string
description: "The SAP Concur expense report ID."
- name: employee_id
in: body
type: string
description: "The employee ID who submitted the report."
steps:
- name: get-report
type: call
call: concur.get-expense-report
with:
report_id: "{{report_id}}"
- name: log-findings
type: call
call: servicenow.create-incident
with:
short_description: "Travel Compliance Review: Report {{report_id}}"
category: "finance_audit"
- name: notify-finance
type: call
call: msteams.send-message
with:
channel_id: "$secrets.finance_compliance_channel"
text: "Travel Compliance: Report {{report_id}} by Employee {{employee_id}}. Total: {{get-report.total}}. Violations: {{get-report.violations_count}}. SNOW: {{log-findings.number}}."
consumes:
- type: http
namespace: concur
baseUri: "https://us2.api.concursolutions.com/api/v3.0"
authentication:
type: bearer
token: "$secrets.concur_token"
resources:
- name: expense-reports
path: "/expense/reports/{{report_id}}"
inputParameters:
- name: report_id
in: path
operations:
- name: get-expense-report
method: GET
- type: http
namespace: servicenow
baseUri: "https://merck.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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Reports cost center budget variances from SAP, creates finance review tasks, and notifies the finance team for Merck.
naftiko: "0.5"
info:
label: "SAP Cost Center Budget Variance Reporter"
description: "Reports cost center budget variances from SAP, creates finance review tasks, and notifies the finance team for Merck."
tags:
- finance
- sap
- budgeting
- reporting
capability:
exposes:
- type: mcp
namespace: finance-reporting
port: 8080
tools:
- name: report-budget-variance
description: "Given a cost center and period, calculate budget variance, create a review task, and notify finance."
inputParameters:
- name: cost_center
in: body
type: string
description: "The SAP cost center."
- name: fiscal_period
in: body
type: string
description: "The fiscal period (e.g., 2026-03)."
steps:
- name: get-variance
type: call
call: sap.get-budget-variance
with:
cost_center: "{{cost_center}}"
period: "{{fiscal_period}}"
- name: create-review
type: call
call: servicenow.create-incident
with:
short_description: "Budget Variance: CC {{cost_center}} — {{fiscal_period}}"
category: "finance"
- name: notify-finance
type: call
call: msteams.send-message
with:
channel_id: "$secrets.finance_channel"
text: "Budget Variance: CC {{cost_center}} for {{fiscal_period}}. Variance: {{get-variance.variance}}. Review: {{create-review.number}}."
consumes:
- type: http
namespace: sap
baseUri: "https://merck-s4.sap.com/sap/opu/odata/sap/API_COSTCENTER_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: records
path: "/"
operations:
- name: create-record
method: POST
- type: http
namespace: servicenow
baseUri: "https://merck.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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Retrieves cost element master data from SAP for Merck finance and controlling operations.
naftiko: "0.5"
info:
label: "SAP Cost Element Lookup"
description: "Retrieves cost element master data from SAP for Merck finance and controlling operations."
tags:
- finance
- sap
- controlling
- lookup
capability:
exposes:
- type: mcp
namespace: finance-controlling
port: 8080
tools:
- name: get-cost-element
description: "Given a cost element code, return the description, category, and controlling area."
inputParameters:
- name: cost_element
in: body
type: string
description: "The SAP cost element code."
call: sap.get-cost-element
with:
cost_element: "{{cost_element}}"
outputParameters:
- name: description
type: string
mapping: "$.d.CostElementDescription"
- name: category
type: string
mapping: "$.d.CostElementCategory"
consumes:
- type: http
namespace: sap
baseUri: "https://merck-s4.sap.com/sap/opu/odata/sap/API_COSTELEMENT_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: records
path: "/"
operations:
- name: get-record
method: GET
Retrieves outbound delivery document details from SAP by delivery number for Merck logistics operations.
naftiko: "0.5"
info:
label: "SAP Delivery Document Lookup"
description: "Retrieves outbound delivery document details from SAP by delivery number for Merck logistics operations."
tags:
- logistics
- sap
- delivery
- lookup
capability:
exposes:
- type: mcp
namespace: logistics-ops
port: 8080
tools:
- name: get-delivery-document
description: "Given a SAP delivery number, return the ship-to party, delivery date, and total weight."
inputParameters:
- name: delivery_number
in: body
type: string
description: "The SAP delivery document number."
call: sap.get-delivery
with:
delivery_number: "{{delivery_number}}"
outputParameters:
- name: ship_to
type: string
mapping: "$.d.ShipToParty"
- name: delivery_date
type: string
mapping: "$.d.DeliveryDate"
- name: total_weight
type: string
mapping: "$.d.HeaderGrossWeight"
consumes:
- type: http
namespace: sap
baseUri: "https://merck-s4.sap.com/sap/opu/odata/sap/API_OUTBOUND_DELIVERY_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: records
path: "/"
operations:
- name: get-record
method: GET
Creates breakdown maintenance notifications in SAP when equipment failures are reported and notifies the maintenance team for Merck.
naftiko: "0.5"
info:
label: "SAP Equipment Breakdown Incident Creator"
description: "Creates breakdown maintenance notifications in SAP when equipment failures are reported and notifies the maintenance team for Merck."
tags:
- manufacturing
- sap
- maintenance
- incident
capability:
exposes:
- type: mcp
namespace: manufacturing-breakdown
port: 8080
tools:
- name: create-breakdown-incident
description: "Given equipment failure details, create a SAP breakdown notification and a ServiceNow incident."
inputParameters:
- name: equipment_id
in: body
type: string
description: "The SAP equipment ID."
- name: failure_description
in: body
type: string
description: "Description of the equipment failure."
- name: plant
in: body
type: string
description: "The manufacturing plant code."
- name: priority
in: body
type: string
description: "Incident priority (P1-P4)."
steps:
- name: create-sap-notification
type: call
call: sap.create-maintenance-notification
with:
equipment: "{{equipment_id}}"
notification_type: "M2"
description: "{{failure_description}}"
plant: "{{plant}}"
- name: create-snow-incident
type: call
call: servicenow.create-incident
with:
short_description: "Equipment Breakdown: {{equipment_id}} at Plant {{plant}}"
priority: "{{priority}}"
description: "Equipment: {{equipment_id}} | Failure: {{failure_description}} | Plant: {{plant}} | SAP: {{create-sap-notification.notification_number}}"
- name: notify-maintenance
type: call
call: msteams.send-message
with:
channel_id: "$secrets.maintenance_channel"
text: "EQUIPMENT BREAKDOWN: {{equipment_id}} at Plant {{plant}}. Priority: {{priority}}. SAP: {{create-sap-notification.notification_number}}. SNOW: {{create-snow-incident.number}}."
consumes:
- type: http
namespace: sap
baseUri: "https://merck-s4.sap.com/sap/opu/odata/sap/API_MAINTNOTIFICATION_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: records
path: "/"
operations:
- name: get-record
method: GET
- type: http
namespace: servicenow
baseUri: "https://merck.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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
At the start of a financial period close, checks SAP S/4HANA closing status, creates a Jira checklist epic, and notifies the global finance team via Microsoft Teams.
naftiko: "0.5"
info:
label: "SAP Finance Period Close Initiation"
description: "At the start of a financial period close, checks SAP S/4HANA closing status, creates a Jira checklist epic, and notifies the global finance team via Microsoft Teams."
tags:
- finance
- period-close
- sap-s4hana
- jira
- microsoft-teams
- erp
capability:
exposes:
- type: mcp
namespace: finance-close
port: 8080
tools:
- name: initiate-period-close
description: "Given a fiscal period and year, retrieve SAP S/4HANA closing status, create a Jira epic with close checklist tasks, and notify the global finance Microsoft Teams channel."
inputParameters:
- name: fiscal_period
in: body
type: string
description: "The fiscal period number to close (01-12)."
- name: fiscal_year
in: body
type: string
description: "The fiscal year (e.g., 2026)."
steps:
- name: get-close-status
type: call
call: "sap-s4.get-period-status"
with:
fiscal_period: "{{fiscal_period}}"
fiscal_year: "{{fiscal_year}}"
- name: create-epic
type: call
call: "jira.create-issue"
with:
project_key: "FIN"
issuetype: "Epic"
summary: "Period Close {{fiscal_period}}/{{fiscal_year}}"
description: "SAP status: {{get-close-status.status}} | Company: {{get-close-status.company_code}}"
- name: notify-finance
type: call
call: "msteams.post-channel-message"
with:
channel_id: "global-finance"
message: "Period close initiated: FY{{fiscal_year}} Period {{fiscal_period}}. Jira Epic: {{create-epic.key}}"
consumes:
- type: http
namespace: sap-s4
baseUri: "https://merck-s4.sap.com/sap/opu/odata/sap/FI_PERIOD_CLOSE_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: period-status
path: "/PeriodCloseStatusSet"
operations:
- name: get-period-status
method: GET
- type: http
namespace: jira
baseUri: "https://merck.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
Processes goods receipt in SAP, triggers quality inspection, and notifies the warehouse team upon completion for Merck.
naftiko: "0.5"
info:
label: "SAP Goods Receipt and Quality Release"
description: "Processes goods receipt in SAP, triggers quality inspection, and notifies the warehouse team upon completion for Merck."
tags:
- supply-chain
- sap
- quality
- warehouse
capability:
exposes:
- type: mcp
namespace: warehouse-ops
port: 8080
tools:
- name: process-goods-receipt
description: "Given a purchase order and delivery details, post goods receipt, trigger quality inspection, and notify warehouse."
inputParameters:
- name: po_number
in: body
type: string
description: "The SAP purchase order number."
- name: delivery_number
in: body
type: string
description: "The inbound delivery number."
- name: plant
in: body
type: string
description: "The receiving plant code."
steps:
- name: post-goods-receipt
type: call
call: sap.post-goods-receipt
with:
po_number: "{{po_number}}"
delivery: "{{delivery_number}}"
plant: "{{plant}}"
- name: trigger-qi
type: call
call: sap.create-inspection-lot
with:
material_document: "{{post-goods-receipt.material_document}}"
plant: "{{plant}}"
- name: notify-warehouse
type: call
call: msteams.send-message
with:
channel_id: "$secrets.warehouse_channel"
text: "Goods Receipt for PO {{po_number}}, Delivery {{delivery_number}} at Plant {{plant}}. Material Doc: {{post-goods-receipt.material_document}}. QI Lot: {{trigger-qi.inspection_lot}}."
consumes:
- type: http
namespace: sap
baseUri: "https://merck-s4.sap.com/sap/opu/odata/sap/API_MATERIAL_DOCUMENT_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: records
path: "/"
operations:
- name: create-record
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Retrieves current inventory stock levels from SAP for a material at a given plant for Merck supply chain operations.
naftiko: "0.5"
info:
label: "SAP Inventory Stock Lookup"
description: "Retrieves current inventory stock levels from SAP for a material at a given plant for Merck supply chain operations."
tags:
- supply-chain
- sap
- inventory
- manufacturing
capability:
exposes:
- type: mcp
namespace: supply-chain-ops
port: 8080
tools:
- name: get-stock-level
description: "Given a material number and plant code, return the unrestricted stock, quality inspection stock, and blocked stock quantities."
inputParameters:
- name: material_number
in: body
type: string
description: "The SAP material number."
- name: plant
in: body
type: string
description: "The SAP plant code."
call: sap.get-stock
with:
material_number: "{{material_number}}"
plant: "{{plant}}"
outputParameters:
- name: unrestricted
type: string
mapping: "$.d.MatlWrhsStkQtyInMatlBaseUnit"
- name: quality_inspection
type: string
mapping: "$.d.QualityInspectionStockQty"
- name: blocked
type: string
mapping: "$.d.BlockedStockQty"
consumes:
- type: http
namespace: sap
baseUri: "https://merck-s4.sap.com/sap/opu/odata/sap/API_MATERIAL_STOCK_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: stock
path: "/A_MatlStkInAcctMod(Material='{{material_number}}',Plant='{{plant}}')"
inputParameters:
- name: material_number
in: path
- name: plant
in: path
operations:
- name: get-stock
method: GET
Validates invoices by performing three-way matching in SAP, logs exceptions in ServiceNow, and notifies accounts payable for Merck.
naftiko: "0.5"
info:
label: "SAP Invoice Three-Way Match Validator"
description: "Validates invoices by performing three-way matching in SAP, logs exceptions in ServiceNow, and notifies accounts payable for Merck."
tags:
- finance
- sap
- accounts-payable
- compliance
capability:
exposes:
- type: mcp
namespace: finance-ap
port: 8080
tools:
- name: validate-invoice-match
description: "Given an invoice number, perform three-way match validation, log exceptions, and notify AP."
inputParameters:
- name: invoice_number
in: body
type: string
description: "The SAP invoice document number."
- name: company_code
in: body
type: string
description: "The SAP company code."
steps:
- name: check-match
type: call
call: sap.validate-three-way-match
with:
invoice_number: "{{invoice_number}}"
company_code: "{{company_code}}"
- name: log-exception
type: call
call: servicenow.create-incident
with:
short_description: "Invoice Match Exception: {{invoice_number}}"
category: "accounts_payable"
- name: notify-ap
type: call
call: msteams.send-message
with:
channel_id: "$secrets.ap_channel"
text: "Invoice Match: {{invoice_number}} in Company {{company_code}}. Status: {{check-match.status}}. Variance: {{check-match.variance}}. SNOW: {{log-exception.number}}."
consumes:
- type: http
namespace: sap
baseUri: "https://merck-s4.sap.com/sap/opu/odata/sap/API_SUPPLIERINVOICE_PROCESS_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: records
path: "/"
operations:
- name: create-record
method: POST
- type: http
namespace: servicenow
baseUri: "https://merck.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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Retrieves material master data from SAP S/4HANA by material number for Merck manufacturing and supply chain operations.
naftiko: "0.5"
info:
label: "SAP Material Master Lookup"
description: "Retrieves material master data from SAP S/4HANA by material number for Merck manufacturing and supply chain operations."
tags:
- manufacturing
- sap
- supply-chain
- lookup
capability:
exposes:
- type: mcp
namespace: supply-chain
port: 8080
tools:
- name: get-material
description: "Given a SAP material number, return the material description, base unit of measure, and material group."
inputParameters:
- name: material_number
in: body
type: string
description: "The SAP material number (e.g., MAT-001234)."
call: sap.get-material
with:
material_number: "{{material_number}}"
outputParameters:
- name: description
type: string
mapping: "$.d.MaterialDescription"
- name: base_uom
type: string
mapping: "$.d.BaseUnit"
- name: material_group
type: string
mapping: "$.d.MaterialGroup"
consumes:
- type: http
namespace: sap
baseUri: "https://merck-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
Handles MRP run exceptions from SAP by creating supply chain alerts, logging in ServiceNow, and notifying the planning team for Merck.
naftiko: "0.5"
info:
label: "SAP MRP Run Exception Handler"
description: "Handles MRP run exceptions from SAP by creating supply chain alerts, logging in ServiceNow, and notifying the planning team for Merck."
tags:
- supply-chain
- sap
- planning
- manufacturing
capability:
exposes:
- type: mcp
namespace: supply-planning
port: 8080
tools:
- name: handle-mrp-exception
description: "Given MRP exception details, create a ServiceNow alert and notify the supply planning team."
inputParameters:
- name: material_number
in: body
type: string
description: "The material with the MRP exception."
- name: exception_type
in: body
type: string
description: "Type of MRP exception (shortage, excess, rescheduling)."
- name: plant
in: body
type: string
description: "The plant code."
- name: quantity
in: body
type: string
description: "The exception quantity."
steps:
- name: create-alert
type: call
call: servicenow.create-incident
with:
short_description: "MRP Exception: {{exception_type}} — Material {{material_number}}"
category: "supply_planning"
- name: notify-planning
type: call
call: msteams.send-message
with:
channel_id: "$secrets.planning_channel"
text: "MRP Exception: {{exception_type}} for Material {{material_number}} at Plant {{plant}}. Qty: {{quantity}}. SNOW: {{create-alert.number}}."
consumes:
- type: http
namespace: servicenow
baseUri: "https://merck.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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Creates planned maintenance orders in SAP for manufacturing equipment, schedules in ServiceNow, and notifies the maintenance team for Merck.
naftiko: "0.5"
info:
label: "SAP Planned Maintenance Order Creator"
description: "Creates planned maintenance orders in SAP for manufacturing equipment, schedules in ServiceNow, and notifies the maintenance team for Merck."
tags:
- manufacturing
- sap
- maintenance
- servicenow
capability:
exposes:
- type: mcp
namespace: manufacturing-maintenance
port: 8080
tools:
- name: create-maintenance-order
description: "Given equipment details, create a SAP maintenance order, a ServiceNow work order, and notify maintenance."
inputParameters:
- name: equipment_id
in: body
type: string
description: "The SAP equipment ID."
- name: maintenance_type
in: body
type: string
description: "Type of maintenance (preventive, calibration, qualification)."
- name: plant
in: body
type: string
description: "The plant code."
- name: scheduled_date
in: body
type: string
description: "Scheduled maintenance date."
steps:
- name: create-sap-order
type: call
call: sap.create-maintenance-order
with:
equipment: "{{equipment_id}}"
order_type: "{{maintenance_type}}"
plant: "{{plant}}"
- name: create-snow-work-order
type: call
call: servicenow.create-incident
with:
short_description: "Maintenance: {{maintenance_type}} — Equipment {{equipment_id}}"
category: "manufacturing_maintenance"
- name: notify-maintenance
type: call
call: msteams.send-message
with:
channel_id: "$secrets.maintenance_channel"
text: "Maintenance Scheduled: {{maintenance_type}} for Equipment {{equipment_id}} at Plant {{plant}} on {{scheduled_date}}. SAP: {{create-sap-order.order_number}}. SNOW: {{create-snow-work-order.number}}."
consumes:
- type: http
namespace: sap
baseUri: "https://merck-s4.sap.com/sap/opu/odata/sap/API_MAINTENANCEORDER_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: records
path: "/"
operations:
- name: create-record
method: POST
- type: http
namespace: servicenow
baseUri: "https://merck.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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Retrieves production order status and details from SAP for Merck manufacturing operations.
naftiko: "0.5"
info:
label: "SAP Production Order Status Lookup"
description: "Retrieves production order status and details from SAP for Merck manufacturing operations."
tags:
- manufacturing
- sap
- production
- lookup
capability:
exposes:
- type: mcp
namespace: manufacturing-mgmt
port: 8080
tools:
- name: get-production-order
description: "Given a SAP production order number, return the order type, status, planned quantity, and material."
inputParameters:
- name: order_number
in: body
type: string
description: "The SAP production order number."
call: sap.get-prod-order
with:
order_number: "{{order_number}}"
outputParameters:
- name: order_type
type: string
mapping: "$.d.ManufacturingOrderType"
- name: status
type: string
mapping: "$.d.MfgOrderPlannedTotalQty"
- name: material
type: string
mapping: "$.d.Material"
consumes:
- type: http
namespace: sap
baseUri: "https://merck-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('{{order_number}}')"
inputParameters:
- name: order_number
in: path
operations:
- name: get-prod-order
method: GET
Retrieves quality inspection lot details from SAP for Merck quality assurance operations.
naftiko: "0.5"
info:
label: "SAP Quality Inspection Lot Lookup"
description: "Retrieves quality inspection lot details from SAP for Merck quality assurance operations."
tags:
- quality
- sap
- manufacturing
- inspection
capability:
exposes:
- type: mcp
namespace: quality-mgmt
port: 8080
tools:
- name: get-inspection-lot
description: "Given an inspection lot number, return the material, inspection type, lot status, and result."
inputParameters:
- name: inspection_lot
in: body
type: string
description: "The SAP quality inspection lot number."
call: sap.get-inspection-lot
with:
inspection_lot: "{{inspection_lot}}"
outputParameters:
- name: material
type: string
mapping: "$.d.Material"
- name: inspection_type
type: string
mapping: "$.d.InspectionLotType"
- name: lot_status
type: string
mapping: "$.d.InspectionLotStatusID"
consumes:
- type: http
namespace: sap
baseUri: "https://merck-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('{{inspection_lot}}')"
inputParameters:
- name: inspection_lot
in: path
operations:
- name: get-inspection-lot
method: GET
Retrieves purchase order status, vendor details, and line items from SAP S/4HANA for procurement review and invoice matching.
naftiko: "0.5"
info:
label: "SAP S/4HANA Purchase Order Status Lookup"
description: "Retrieves purchase order status, vendor details, and line items from SAP S/4HANA for procurement review and invoice matching."
tags:
- finance
- procurement
- sap-s4hana
- 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 header status, vendor name, total value, and open line items. Use when reviewing procurement status or matching invoices."
inputParameters:
- name: po_number
in: body
type: string
description: "The SAP purchase order number to look up (e.g., 4500012345)."
call: "sap-s4.get-po"
with:
po_number: "{{po_number}}"
outputParameters:
- name: status
type: string
mapping: "$.d.OverallStatus"
- name: vendor
type: string
mapping: "$.d.Supplier.CompanyName"
- name: total_value
type: string
mapping: "$.d.TotalAmount"
- name: currency
type: string
mapping: "$.d.TransactionCurrency"
consumes:
- type: http
namespace: sap-s4
baseUri: "https://merck-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
Tracks outbound shipments in SAP TM, updates delivery status in Salesforce, and notifies the distribution team for Merck.
naftiko: "0.5"
info:
label: "SAP Transport Management Shipment Tracker"
description: "Tracks outbound shipments in SAP TM, updates delivery status in Salesforce, and notifies the distribution team for Merck."
tags:
- supply-chain
- sap
- salesforce
- logistics
capability:
exposes:
- type: mcp
namespace: distribution-ops
port: 8080
tools:
- name: track-shipment
description: "Given a shipment ID, retrieve tracking data from SAP TM, update Salesforce, and notify distribution."
inputParameters:
- name: shipment_id
in: body
type: string
description: "The SAP Transportation Management shipment ID."
- name: salesforce_order_id
in: body
type: string
description: "The related Salesforce order ID."
steps:
- name: get-tracking
type: call
call: sap.get-shipment-status
with:
shipment_id: "{{shipment_id}}"
- name: update-salesforce
type: call
call: salesforce.update-record
with:
object_type: "Order"
id: "{{salesforce_order_id}}"
Shipping_Status__c: "{{get-tracking.status}}"
- name: notify-distribution
type: call
call: msteams.send-message
with:
channel_id: "$secrets.distribution_channel"
text: "Shipment Update: {{shipment_id}} — Status: {{get-tracking.status}}. ETA: {{get-tracking.eta}}. Salesforce updated."
consumes:
- type: http
namespace: sap
baseUri: "https://merck-s4.sap.com/sap/opu/odata/sap/API_FREIGHT_ORDER_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: records
path: "/"
operations:
- name: create-record
method: POST
- type: http
namespace: salesforce
baseUri: "https://merck.my.salesforce.com/services/data/v59.0"
authentication:
type: bearer
token: "$secrets.salesforce_token"
resources:
- name: orders
path: "/sobjects/Order/{{id}}"
inputParameters:
- name: id
in: path
operations:
- name: update-record
method: PATCH
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Retrieves vendor master data from SAP S/4HANA by vendor number for Merck procurement operations.
naftiko: "0.5"
info:
label: "SAP Vendor Master Lookup"
description: "Retrieves vendor master data from SAP S/4HANA by vendor number for Merck procurement operations."
tags:
- procurement
- sap
- vendor-management
- lookup
capability:
exposes:
- type: mcp
namespace: procurement-ops
port: 8080
tools:
- name: get-vendor
description: "Given a SAP vendor number, return the vendor name, payment terms, and purchasing organization."
inputParameters:
- name: vendor_number
in: body
type: string
description: "The SAP vendor account number."
call: sap.get-vendor
with:
vendor_number: "{{vendor_number}}"
outputParameters:
- name: vendor_name
type: string
mapping: "$.d.SupplierName"
- name: payment_terms
type: string
mapping: "$.d.PaymentTerms"
- name: purchasing_org
type: string
mapping: "$.d.PurchasingOrganization"
consumes:
- type: http
namespace: sap
baseUri: "https://merck-s4.sap.com/sap/opu/odata/sap/API_BUSINESS_PARTNER"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: suppliers
path: "/A_Supplier('{{vendor_number}}')"
inputParameters:
- name: vendor_number
in: path
operations:
- name: get-vendor
method: GET
Monitors warehouse capacity levels in SAP, creates planning alerts in ServiceNow, and notifies logistics when thresholds are breached for Merck.
naftiko: "0.5"
info:
label: "SAP Warehouse Capacity Planning Alert"
description: "Monitors warehouse capacity levels in SAP, creates planning alerts in ServiceNow, and notifies logistics when thresholds are breached for Merck."
tags:
- supply-chain
- sap
- warehouse
- capacity-planning
capability:
exposes:
- type: mcp
namespace: logistics-planning
port: 8080
tools:
- name: alert-warehouse-capacity
description: "Given a warehouse and capacity threshold, check current utilization and alert if exceeded."
inputParameters:
- name: warehouse_id
in: body
type: string
description: "The SAP warehouse number."
- name: threshold_percent
in: body
type: integer
description: "Capacity utilization threshold percentage."
- name: plant
in: body
type: string
description: "The SAP plant code."
steps:
- name: check-capacity
type: call
call: sap.get-warehouse-utilization
with:
warehouse: "{{warehouse_id}}"
plant: "{{plant}}"
- name: create-alert
type: call
call: servicenow.create-incident
with:
short_description: "Warehouse Capacity Alert: {{warehouse_id}} at {{check-capacity.utilization}}%"
category: "logistics"
- name: notify-logistics
type: call
call: msteams.send-message
with:
channel_id: "$secrets.logistics_channel"
text: "Warehouse Capacity: {{warehouse_id}} at Plant {{plant}} is at {{check-capacity.utilization}}% (threshold: {{threshold_percent}}%). SNOW: {{create-alert.number}}."
consumes:
- type: http
namespace: sap
baseUri: "https://merck-s4.sap.com/sap/opu/odata/sap/API_WAREHOUSE_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: records
path: "/"
operations:
- name: create-record
method: POST
- type: http
namespace: servicenow
baseUri: "https://merck.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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Retrieves configuration item details from ServiceNow CMDB by asset tag for Merck IT asset management.
naftiko: "0.5"
info:
label: "ServiceNow CMDB Asset Lookup"
description: "Retrieves configuration item details from ServiceNow CMDB by asset tag for Merck IT asset management."
tags:
- it-operations
- servicenow
- cmdb
- lookup
capability:
exposes:
- type: mcp
namespace: it-ops
port: 8080
tools:
- name: get-cmdb-asset
description: "Given an asset tag, return the CI name, class, operational status, and assigned support group."
inputParameters:
- name: asset_tag
in: body
type: string
description: "The ServiceNow asset tag identifier."
call: servicenow.get-ci
with:
asset_tag: "{{asset_tag}}"
outputParameters:
- name: ci_name
type: string
mapping: "$.result.name"
- name: ci_class
type: string
mapping: "$.result.sys_class_name"
- name: operational_status
type: string
mapping: "$.result.operational_status"
consumes:
- type: http
namespace: servicenow
baseUri: "https://merck.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: cmdb-ci
path: "/table/cmdb_ci?sysparm_query=asset_tag={{asset_tag}}"
inputParameters:
- name: asset_tag
in: query
operations:
- name: get-ci
method: GET
Escalates a high-priority ServiceNow IT incident to the on-call engineer via PagerDuty and posts context to the IT ops Microsoft Teams channel.
naftiko: "0.5"
info:
label: "ServiceNow IT Incident Escalation to PagerDuty"
description: "Escalates a high-priority ServiceNow IT incident to the on-call engineer via PagerDuty and posts context to the IT ops Microsoft Teams channel."
tags:
- itsm
- incident-response
- servicenow
- pagerduty
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: itsm-escalation
port: 8080
tools:
- name: escalate-it-incident
description: "Given a ServiceNow incident number and escalation reason, retrieve incident details, trigger a PagerDuty alert to the on-call engineer, and post the incident context to the IT ops Microsoft Teams channel."
inputParameters:
- name: incident_number
in: body
type: string
description: "The ServiceNow incident number to escalate (e.g., INC0012345)."
- name: escalation_reason
in: body
type: string
description: "Reason for escalation, to be included in the PagerDuty alert."
steps:
- name: get-incident
type: call
call: "servicenow.get-incident"
with:
number: "{{incident_number}}"
- name: trigger-page
type: call
call: "pagerduty.create-incident"
with:
title: "Escalated: {{incident_number}} - {{get-incident.short_description}}"
severity: "critical"
body: "{{escalation_reason}}"
- name: notify-team
type: call
call: "msteams.post-channel-message"
with:
channel_id: "it-operations"
message: "Incident Escalated: {{incident_number}} | {{get-incident.short_description}} | PagerDuty: {{trigger-page.incident_id}}"
consumes:
- type: http
namespace: servicenow
baseUri: "https://merck.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: incident
path: "/table/incident"
operations:
- name: get-incident
method: GET
- type: http
namespace: pagerduty
baseUri: "https://api.pagerduty.com"
authentication:
type: apikey
key: "Authorization"
value: "$secrets.pagerduty_token"
placement: header
resources:
- name: incidents
path: "/incidents"
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 standard operating procedure document metadata from SharePoint by document name for Merck quality operations.
naftiko: "0.5"
info:
label: "SharePoint SOP Document Retrieval"
description: "Retrieves standard operating procedure document metadata from SharePoint by document name for Merck quality operations."
tags:
- quality
- sharepoint
- document-management
- sop
capability:
exposes:
- type: mcp
namespace: quality-ops
port: 8080
tools:
- name: get-sop-document
description: "Given an SOP document name or ID, return the document title, version, approval status, and URL."
inputParameters:
- name: document_name
in: body
type: string
description: "The SOP document name or ID."
call: sharepoint.get-document
with:
document_name: "{{document_name}}"
outputParameters:
- name: title
type: string
mapping: "$.d.Title"
- name: version
type: string
mapping: "$.d.UIVersionLabel"
- name: modified
type: string
mapping: "$.d.Modified"
consumes:
- type: http
namespace: sharepoint
baseUri: "https://merck.sharepoint.com/_api/web"
authentication:
type: bearer
token: "$secrets.sharepoint_token"
resources:
- name: files
path: "/GetFileByServerRelativeUrl('/sites/SOPs/{{document_name}}')"
inputParameters:
- name: document_name
in: path
operations:
- name: get-document
method: GET
Executes a predefined SQL query against the Merck clinical data warehouse in Snowflake and returns summary results.
naftiko: "0.5"
info:
label: "Snowflake Clinical Query Runner"
description: "Executes a predefined SQL query against the Merck clinical data warehouse in Snowflake and returns summary results."
tags:
- clinical-trials
- snowflake
- data-warehouse
- analytics
capability:
exposes:
- type: mcp
namespace: clinical-analytics
port: 8080
tools:
- name: run-clinical-query
description: "Given a query identifier and optional study ID filter, execute the corresponding Snowflake query and return results."
inputParameters:
- name: query_id
in: body
type: string
description: "Predefined query identifier (e.g., enrollment-summary, ae-counts)."
- name: study_id
in: body
type: string
description: "Optional clinical study ID filter."
call: snowflake.execute-query
with:
query_id: "{{query_id}}"
study_id: "{{study_id}}"
outputParameters:
- name: row_count
type: integer
mapping: "$.resultSetMetaData.numRows"
- name: data
type: array
mapping: "$.data"
consumes:
- type: http
namespace: snowflake
baseUri: "https://merck.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: execute-query
method: POST
Monitors Snowflake for failed research data ingestion tasks, creates Jira issues, and alerts the data science team via Microsoft Teams.
naftiko: "0.5"
info:
label: "Snowflake Research Data Pipeline Monitor"
description: "Monitors Snowflake for failed research data ingestion tasks, creates Jira issues, and alerts the data science team via Microsoft Teams."
tags:
- data
- research
- snowflake
- jira
- microsoft-teams
- monitoring
capability:
exposes:
- type: mcp
namespace: research-data-ops
port: 8080
tools:
- name: monitor-research-pipelines
description: "Query Snowflake for failed data ingestion tasks in research databases, create Jira issues for critical failures, and post a summary to the data science Microsoft Teams channel."
inputParameters:
- name: database_name
in: body
type: string
description: "The Snowflake database name containing the research data pipelines."
- name: lookback_hours
in: body
type: integer
description: "Number of hours to look back for failures (default 24)."
steps:
- name: get-failures
type: call
call: "snowflake.query-failures"
with:
database_name: "{{database_name}}"
lookback_hours: "{{lookback_hours}}"
- name: create-issue
type: call
call: "jira.create-issue"
with:
project_key: "DATA"
issuetype: "Bug"
summary: "Research data pipeline failures in {{database_name}}"
description: "{{get-failures.failure_count}} pipeline failures detected. Summary: {{get-failures.failure_summary}}"
- name: notify-team
type: call
call: "msteams.post-channel-message"
with:
channel_id: "data-science"
message: "Research Pipeline Alert: {{get-failures.failure_count}} failures in {{database_name}}. Jira: {{create-issue.key}}"
consumes:
- type: http
namespace: snowflake
baseUri: "https://merck.snowflakecomputing.com/api/v2"
authentication:
type: bearer
token: "$secrets.snowflake_token"
resources:
- name: statements
path: "/statements"
operations:
- name: query-failures
method: POST
- type: http
namespace: jira
baseUri: "https://merck.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
Detects shipment delays in SAP, creates a ServiceNow case, and alerts the logistics team for Merck.
naftiko: "0.5"
info:
label: "Supply Chain Shipment Delay Escalation"
description: "Detects shipment delays in SAP, creates a ServiceNow case, and alerts the logistics team for Merck."
tags:
- supply-chain
- sap
- servicenow
- logistics
capability:
exposes:
- type: mcp
namespace: supply-chain-ops
port: 8080
tools:
- name: escalate-shipment-delay
description: "Given a delivery number and delay reason, create a ServiceNow case and notify supply chain leadership."
inputParameters:
- name: delivery_number
in: body
type: string
description: "The SAP delivery number."
- name: delay_reason
in: body
type: string
description: "Reason for the shipment delay."
- name: expected_date
in: body
type: string
description: "Originally expected delivery date."
- name: new_date
in: body
type: string
description: "Revised delivery date."
steps:
- name: create-sc-case
type: call
call: servicenow.create-incident
with:
short_description: "Shipment Delay: Delivery {{delivery_number}}"
category: "supply_chain"
description: "Delivery: {{delivery_number}} | Reason: {{delay_reason}} | Original: {{expected_date}} | Revised: {{new_date}}"
- name: notify-logistics
type: call
call: msteams.send-message
with:
channel_id: "$secrets.supply_chain_channel"
text: "Supply Chain Alert: Delivery {{delivery_number}} delayed from {{expected_date}} to {{new_date}}. Reason: {{delay_reason}}. Case: {{create-sc-case.number}}."
consumes:
- type: http
namespace: servicenow
baseUri: "https://merck.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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Checks the last extract refresh status for a Tableau workbook for Merck analytics operations.
naftiko: "0.5"
info:
label: "Tableau Workbook Refresh Status"
description: "Checks the last extract refresh status for a Tableau workbook for Merck analytics operations."
tags:
- analytics
- tableau
- reporting
- lookup
capability:
exposes:
- type: mcp
namespace: analytics-tableau
port: 8080
tools:
- name: get-workbook-refresh
description: "Given a Tableau workbook ID, return the last refresh status and extract time."
inputParameters:
- name: workbook_id
in: body
type: string
description: "The Tableau workbook ID."
call: tableau.get-extract-refresh
with:
workbook_id: "{{workbook_id}}"
outputParameters:
- name: status
type: string
mapping: "$.extractRefreshes[0].status"
- name: completed_at
type: string
mapping: "$.extractRefreshes[0].completedAt"
consumes:
- type: http
namespace: tableau
baseUri: "https://merck.online.tableau.com/api/3.21"
authentication:
type: bearer
token: "$secrets.tableau_token"
resources:
- name: workbooks
path: "/sites/{{site_id}}/workbooks/{{workbook_id}}/refreshes"
inputParameters:
- name: workbook_id
in: path
operations:
- name: get-extract-refresh
method: GET
Creates a new Terraform Cloud workspace for a research compute environment, links the GitHub repository, and notifies the platform engineering team.
naftiko: "0.5"
info:
label: "Terraform Cloud Infrastructure Provisioning"
description: "Creates a new Terraform Cloud workspace for a research compute environment, links the GitHub repository, and notifies the platform engineering team."
tags:
- cloud
- infrastructure
- terraform
- github
- microsoft-teams
- provisioning
capability:
exposes:
- type: mcp
namespace: infra-provisioning
port: 8080
tools:
- name: provision-research-workspace
description: "Given a research team name, GitHub repository, and target environment, create a Terraform Cloud workspace for research compute infrastructure, link the repository, and notify platform engineering via Microsoft Teams."
inputParameters:
- name: team_name
in: body
type: string
description: "The research team name requesting the workspace."
- name: repository
in: body
type: string
description: "The GitHub repository to link (e.g., merck/oncology-compute)."
- name: environment
in: body
type: string
description: "Target environment: dev, staging, or production."
steps:
- name: create-workspace
type: call
call: "terraform.create-workspace"
with:
name: "{{team_name}}-{{environment}}"
vcs_repo: "{{repository}}"
- name: notify-platform
type: call
call: "msteams.post-channel-message"
with:
channel_id: "platform-engineering"
message: "Workspace created: {{team_name}}-{{environment}} linked to {{repository}}. ID: {{create-workspace.workspace_id}}"
consumes:
- type: http
namespace: terraform
baseUri: "https://app.terraform.io/api/v2"
authentication:
type: bearer
token: "$secrets.terraform_token"
resources:
- name: workspaces
path: "/organizations/merck/workspaces"
operations:
- name: create-workspace
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
Manages infrastructure provisioning by creating ServiceNow change requests, triggering Terraform plans, and notifying the cloud team for Merck.
naftiko: "0.5"
info:
label: "Terraform Infrastructure Provisioning with Approval"
description: "Manages infrastructure provisioning by creating ServiceNow change requests, triggering Terraform plans, and notifying the cloud team for Merck."
tags:
- devops
- terraform
- servicenow
- cloud
capability:
exposes:
- type: mcp
namespace: cloud-ops
port: 8080
tools:
- name: provision-infrastructure
description: "Given infrastructure requirements, create a change request, generate a Terraform plan, and notify cloud engineering."
inputParameters:
- name: environment
in: body
type: string
description: "Target environment (dev, staging, production)."
- name: resource_type
in: body
type: string
description: "Type of resource to provision."
- name: requestor
in: body
type: string
description: "Name of the requestor."
steps:
- name: create-change
type: call
call: servicenow.create-change
with:
short_description: "Infra Provisioning: {{resource_type}} in {{environment}}"
category: "cloud_infrastructure"
- name: trigger-plan
type: call
call: github.trigger-workflow
with:
repo: "infrastructure"
workflow: "terraform-plan.yml"
- name: notify-cloud-team
type: call
call: msteams.send-message
with:
channel_id: "$secrets.cloud_eng_channel"
text: "Infra Request: {{resource_type}} in {{environment}} by {{requestor}}. Change: {{create-change.number}}. Terraform plan triggered."
consumes:
- type: http
namespace: servicenow
baseUri: "https://merck.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: github
baseUri: "https://api.github.com"
authentication:
type: bearer
token: "$secrets.github_token"
resources:
- name: workflows
path: "/repos/{{repo}}/actions/workflows/{{workflow}}/dispatches"
inputParameters:
- name: repo
in: path
- name: workflow
in: path
operations:
- name: trigger-workflow
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Logs a medical information inquiry from the Veeva CRM into a ServiceNow ticket and assigns it to the medical information team for response.
naftiko: "0.5"
info:
label: "Veeva CRM Medical Inquiry Intake"
description: "Logs a medical information inquiry from the Veeva CRM into a ServiceNow ticket and assigns it to the medical information team for response."
tags:
- medical-affairs
- veeva
- servicenow
- crm
- compliance
capability:
exposes:
- type: mcp
namespace: medical-inquiry
port: 8080
tools:
- name: intake-medical-inquiry
description: "Given a Veeva CRM inquiry record ID, retrieve the inquiry details, create a ServiceNow task for the medical information team, and notify the team via Microsoft Teams."
inputParameters:
- name: inquiry_id
in: body
type: string
description: "The Veeva CRM medical inquiry record ID."
steps:
- name: get-inquiry
type: call
call: "veeva.get-inquiry-record"
with:
inquiry_id: "{{inquiry_id}}"
- name: create-task
type: call
call: "servicenow.create-incident"
with:
short_description: "Medical inquiry: {{get-inquiry.product_name}} - {{get-inquiry.inquiry_type}}"
category: "medical_information"
description: "Inquiry: {{get-inquiry.inquiry_text}} | Source: {{get-inquiry.hcp_name}}"
- name: notify-medinfo
type: call
call: "msteams.post-channel-message"
with:
channel_id: "medical-information"
message: "New Medical Inquiry: {{get-inquiry.product_name}} from {{get-inquiry.hcp_name}}. Task: {{create-task.number}}"
consumes:
- type: http
namespace: veeva
baseUri: "https://merck.veevavault.com/api/v21.2"
authentication:
type: bearer
token: "$secrets.veeva_token"
resources:
- name: inquiries
path: "/objects/medical_inquiries/{{inquiry_id}}"
inputParameters:
- name: inquiry_id
in: path
operations:
- name: get-inquiry-record
method: GET
- type: http
namespace: servicenow
baseUri: "https://merck.service-now.com/api/now"
authentication:
type: basic
username: "$secrets.servicenow_user"
password: "$secrets.servicenow_password"
resources:
- name: incident
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 lifecycle status of a document in Veeva Vault by document ID for Merck regulatory operations.
naftiko: "0.5"
info:
label: "Veeva Vault Document Status Lookup"
description: "Retrieves the current lifecycle status of a document in Veeva Vault by document ID for Merck regulatory operations."
tags:
- regulatory
- veeva-vault
- document-management
- lookup
capability:
exposes:
- type: mcp
namespace: regulatory-ops
port: 8080
tools:
- name: get-document-status
description: "Given a Veeva Vault document ID, return the lifecycle state, owner, and last modified date."
inputParameters:
- name: document_id
in: body
type: string
description: "The Veeva Vault document ID."
call: veeva.get-document
with:
document_id: "{{document_id}}"
outputParameters:
- name: lifecycle_state
type: string
mapping: "$.responseDetails.lifecycle__v"
- name: owner
type: string
mapping: "$.responseDetails.owner__v"
- name: last_modified
type: string
mapping: "$.responseDetails.last_modified_date__v"
consumes:
- type: http
namespace: veeva
baseUri: "https://merck.veevavault.com/api/v24.1"
authentication:
type: bearer
token: "$secrets.veeva_token"
resources:
- name: documents
path: "/objects/documents/{{document_id}}"
inputParameters:
- name: document_id
in: path
operations:
- name: get-document
method: GET
Orchestrates vendor qualification reviews by pulling vendor data from SAP, creating a ServiceNow assessment task, and notifying procurement for Merck.
naftiko: "0.5"
info:
label: "Vendor Qualification Review Orchestrator"
description: "Orchestrates vendor qualification reviews by pulling vendor data from SAP, creating a ServiceNow assessment task, and notifying procurement for Merck."
tags:
- procurement
- sap
- servicenow
- vendor-management
capability:
exposes:
- type: mcp
namespace: procurement-ops
port: 8080
tools:
- name: initiate-vendor-review
description: "Given a vendor number, retrieve vendor details from SAP, create an assessment task, and notify procurement."
inputParameters:
- name: vendor_number
in: body
type: string
description: "The SAP vendor number."
- name: review_type
in: body
type: string
description: "Type of qualification review (initial, periodic, for-cause)."
steps:
- name: get-vendor-data
type: call
call: sap.get-vendor
with:
vendor_number: "{{vendor_number}}"
- name: create-assessment
type: call
call: servicenow.create-incident
with:
short_description: "Vendor Qualification: {{get-vendor-data.SupplierName}} — {{review_type}}"
category: "vendor_management"
- name: notify-procurement
type: call
call: msteams.send-message
with:
channel_id: "$secrets.procurement_channel"
text: "Vendor Review initiated for {{get-vendor-data.SupplierName}} ({{vendor_number}}). Type: {{review_type}}. Task: {{create-assessment.number}}."
consumes:
- type: http
namespace: sap
baseUri: "https://merck-s4.sap.com/sap/opu/odata/sap/API_BUSINESS_PARTNER"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: records
path: "/"
operations:
- name: create-record
method: POST
- type: http
namespace: servicenow
baseUri: "https://merck.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.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Retrieves employee absence and leave balance from Workday for Merck HR operations.
naftiko: "0.5"
info:
label: "Workday Absence Balance Lookup"
description: "Retrieves employee absence and leave balance from Workday for Merck HR operations."
tags:
- hr
- workday
- absence
- lookup
capability:
exposes:
- type: mcp
namespace: hr-absence
port: 8080
tools:
- name: get-absence-balance
description: "Given an employee ID, return the PTO balance, sick leave balance, and next scheduled absence."
inputParameters:
- name: employee_id
in: body
type: string
description: "The Workday employee ID."
call: workday.get-absence-balance
with:
employee_id: "{{employee_id}}"
outputParameters:
- name: pto_balance
type: string
mapping: "$.TimeOff.PTO_Balance"
- name: sick_balance
type: string
mapping: "$.TimeOff.Sick_Balance"
consumes:
- type: http
namespace: workday
baseUri: "https://wd5-services1.myworkday.com/ccx/service/merck/Absence_Management/v42.0"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: absences
path: "/workers/{{employee_id}}/absenceBalances"
inputParameters:
- name: employee_id
in: path
operations:
- name: get-absence-balance
method: GET
Retrieves compensation plan details for an employee from Workday for Merck HR total rewards operations.
naftiko: "0.5"
info:
label: "Workday Compensation Lookup"
description: "Retrieves compensation plan details for an employee from Workday for Merck HR total rewards operations."
tags:
- hr
- workday
- compensation
- lookup
capability:
exposes:
- type: mcp
namespace: hr-rewards
port: 8080
tools:
- name: get-compensation
description: "Given an employee ID, return the base pay, bonus target percentage, and compensation grade."
inputParameters:
- name: employee_id
in: body
type: string
description: "The Workday employee ID."
call: workday.get-compensation
with:
employee_id: "{{employee_id}}"
outputParameters:
- name: base_pay
type: string
mapping: "$.Compensation.Base_Pay"
- name: bonus_target
type: string
mapping: "$.Compensation.Bonus_Target_Percent"
- name: grade
type: string
mapping: "$.Compensation.Compensation_Grade"
consumes:
- type: http
namespace: workday
baseUri: "https://wd5-services1.myworkday.com/ccx/service/merck/Compensation/v42.0"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: compensation
path: "/workers/{{employee_id}}/compensationPlans"
inputParameters:
- name: employee_id
in: path
operations:
- name: get-compensation
method: GET
Retrieves employee profile details from Workday by employee ID for Merck HR operations.
naftiko: "0.5"
info:
label: "Workday Employee Profile Lookup"
description: "Retrieves employee profile details from Workday by employee ID for Merck HR operations."
tags:
- hr
- workday
- employee
- lookup
capability:
exposes:
- type: mcp
namespace: hr-ops
port: 8080
tools:
- name: get-employee-profile
description: "Given a Workday employee ID, return the name, department, manager, and hire date."
inputParameters:
- name: employee_id
in: body
type: string
description: "The Workday employee ID."
call: workday.get-worker
with:
employee_id: "{{employee_id}}"
outputParameters:
- name: full_name
type: string
mapping: "$.Worker.Worker_Data.Personal_Data.Name_Data.Legal_Name.Name_Detail_Data.Formatted_Name"
- name: department
type: string
mapping: "$.Worker.Worker_Data.Organization_Data.Worker_Organization_Data[0].Organization_Data.Organization_Name"
- name: hire_date
type: string
mapping: "$.Worker.Worker_Data.Employment_Data.Worker_Status_Data.Hire_Date"
consumes:
- type: http
namespace: workday
baseUri: "https://wd5-services1.myworkday.com/ccx/service/merck/Human_Resources/v42.0"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: workers
path: "/workers/{{employee_id}}"
inputParameters:
- name: employee_id
in: path
operations:
- name: get-worker
method: GET
Retrieves current headcount grouped by department and cost center from Workday for workforce planning, budget review, and finance reporting.
naftiko: "0.5"
info:
label: "Workday Headcount and Payroll Snapshot"
description: "Retrieves current headcount grouped by department and cost center from Workday for workforce planning, budget review, and finance reporting."
tags:
- hr
- finance
- workday
- headcount
- reporting
capability:
exposes:
- type: mcp
namespace: hr-finance-reporting
port: 8080
tools:
- name: get-headcount-snapshot
description: "Returns current headcount grouped by department and cost center from Workday. Use for workforce planning, budget reviews, and executive reporting."
call: "workday.list-workers"
outputParameters:
- name: workers
type: array
mapping: "$.Report_Entry"
items:
- name: employee_id
type: string
mapping: "$.Employee_ID"
- name: full_name
type: string
mapping: "$.Employee_Name"
- name: department
type: string
mapping: "$.Department"
- name: cost_center
type: string
mapping: "$.Cost_Center"
consumes:
- type: http
namespace: workday
baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
authentication:
type: basic
username: "$secrets.workday_user"
password: "$secrets.workday_password"
resources:
- name: workers
path: "/merck/workers"
operations:
- name: list-workers
method: GET
When an employee role change is processed in Workday, notifies the employee and their new manager via Microsoft Teams and updates their Okta group memberships.
naftiko: "0.5"
info:
label: "Workday Job Change Notification"
description: "When an employee role change is processed in Workday, notifies the employee and their new manager via Microsoft Teams and updates their Okta group memberships."
tags:
- hr
- role-change
- workday
- okta
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: hr-role-change
port: 8080
tools:
- name: process-job-change
description: "Given a Workday job change event ID, retrieve the employee and new role details, update Okta group memberships for the new role, and notify both the employee and new manager via Microsoft Teams."
inputParameters:
- name: event_id
in: body
type: string
description: "The Workday job change business process event ID."
steps:
- name: get-job-change
type: call
call: "workday.get-job-change-event"
with:
event_id: "{{event_id}}"
- name: update-okta-groups
type: call
call: "okta.update-user-groups"
with:
user_email: "{{get-job-change.employee_email}}"
new_department: "{{get-job-change.new_department}}"
- name: notify-employee
type: call
call: "msteams.send-message"
with:
recipient_upn: "{{get-job-change.employee_email}}"
message: "Your role change to {{get-job-change.new_job_title}} is effective {{get-job-change.effective_date}}. Welcome to {{get-job-change.new_department}}!"
consumes:
- type: http
namespace: workday
baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
authentication:
type: basic
username: "$secrets.workday_user"
password: "$secrets.workday_password"
resources:
- name: job-change-events
path: "/merck/jobChangeEvents/{{event_id}}"
inputParameters:
- name: event_id
in: path
operations:
- name: get-job-change-event
method: GET
- type: http
namespace: okta
baseUri: "https://merck.okta.com/api/v1"
authentication:
type: apikey
key: "Authorization"
value: "$secrets.okta_api_token"
placement: header
resources:
- name: user-groups
path: "/users/{{user_id}}/groups"
inputParameters:
- name: user_id
in: path
operations:
- name: update-user-groups
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msgraph_token"
resources:
- name: messages
path: "/users/{{recipient_upn}}/sendMail"
inputParameters:
- name: recipient_upn
in: path
operations:
- name: send-message
method: POST
Identifies overdue compliance training assignments in Workday and sends reminder notifications for Merck.
naftiko: "0.5"
info:
label: "Workday Learning Compliance Reminder"
description: "Identifies overdue compliance training assignments in Workday and sends reminder notifications for Merck."
tags:
- hr
- workday
- compliance
- training
capability:
exposes:
- type: mcp
namespace: hr-compliance
port: 8080
tools:
- name: send-compliance-reminders
description: "Given a compliance training program ID, find overdue assignments and send reminders."
inputParameters:
- name: program_id
in: body
type: string
description: "The Workday learning program ID."
- name: days_overdue
in: body
type: integer
description: "Minimum days overdue to trigger reminder."
steps:
- name: get-overdue
type: call
call: workday.get-overdue-training
with:
program_id: "{{program_id}}"
days_overdue: "{{days_overdue}}"
- name: send-reminder
type: call
call: msteams.send-message
with:
channel_id: "$secrets.hr_compliance_channel"
text: "Compliance Training Alert: {{get-overdue.count}} employees overdue for program {{program_id}} (>{{days_overdue}} days)."
consumes:
- type: http
namespace: workday
baseUri: "https://wd5-services1.myworkday.com/ccx/service/merck/Learning/v42.0"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: training
path: "/learningAssignments?overdue=true&program={{program_id}}"
inputParameters:
- name: program_id
in: query
operations:
- name: get-overdue-training
method: GET
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST
Initiates a performance review cycle in Workday for a department, creates Jira tasks for HR coordinators, and notifies all employees in the department via Microsoft Teams.
naftiko: "0.5"
info:
label: "Workday Performance Review Cycle Launch"
description: "Initiates a performance review cycle in Workday for a department, creates Jira tasks for HR coordinators, and notifies all employees in the department via Microsoft Teams."
tags:
- hr
- performance-management
- workday
- jira
- microsoft-teams
capability:
exposes:
- type: mcp
namespace: hr-performance
port: 8080
tools:
- name: launch-performance-review
description: "Given a Workday department ID and review cycle name, initiate the performance review event, create HR coordinator tasks in Jira, and notify all employees in the department via Microsoft Teams."
inputParameters:
- name: department_id
in: body
type: string
description: "The Workday department ID for which to launch the performance review."
- name: cycle_name
in: body
type: string
description: "The name of the performance review cycle (e.g., 2026 Annual Review)."
- name: due_date
in: body
type: string
description: "The performance review completion due date (YYYY-MM-DD)."
steps:
- name: get-department
type: call
call: "workday.get-department"
with:
department_id: "{{department_id}}"
- name: create-hr-task
type: call
call: "jira.create-issue"
with:
project_key: "HR"
issuetype: "Task"
summary: "Performance review coordination: {{cycle_name}} - {{get-department.name}}"
description: "Department: {{get-department.name}} | Due: {{due_date}} | Employees: {{get-department.headcount}}"
- name: notify-department
type: call
call: "msteams.post-channel-message"
with:
channel_id: "{{get-department.teams_channel_id}}"
message: "Performance Review Launched: {{cycle_name}} is open. Please complete your self-assessment by {{due_date}}."
consumes:
- type: http
namespace: workday
baseUri: "https://wd2-impl-services1.workday.com/ccx/api/v1"
authentication:
type: basic
username: "$secrets.workday_user"
password: "$secrets.workday_password"
resources:
- name: departments
path: "/merck/organizations/{{department_id}}"
inputParameters:
- name: department_id
in: path
operations:
- name: get-department
method: GET
- type: http
namespace: jira
baseUri: "https://merck.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
Processes new position requisitions by validating budget in SAP, creating the requisition in Workday, and notifying HR for Merck.
naftiko: "0.5"
info:
label: "Workday Position Requisition Approval Workflow"
description: "Processes new position requisitions by validating budget in SAP, creating the requisition in Workday, and notifying HR for Merck."
tags:
- hr
- workday
- sap
- hiring
capability:
exposes:
- type: mcp
namespace: hr-talent
port: 8080
tools:
- name: process-position-requisition
description: "Given requisition details, validate budget, create the position in Workday, and notify HR."
inputParameters:
- name: department
in: body
type: string
description: "The department requesting the position."
- name: job_title
in: body
type: string
description: "The job title."
- name: cost_center
in: body
type: string
description: "The SAP cost center."
- name: hiring_manager
in: body
type: string
description: "Name of the hiring manager."
steps:
- name: validate-budget
type: call
call: sap.check-budget
with:
cost_center: "{{cost_center}}"
amount_type: "headcount"
- name: create-requisition
type: call
call: workday.create-requisition
with:
department: "{{department}}"
job_title: "{{job_title}}"
hiring_manager: "{{hiring_manager}}"
- name: notify-hr
type: call
call: msteams.send-message
with:
channel_id: "$secrets.hr_recruiting_channel"
text: "New Position Requisition: {{job_title}} in {{department}}. Manager: {{hiring_manager}}. Budget: {{validate-budget.status}}. Workday Req: {{create-requisition.requisition_id}}."
consumes:
- type: http
namespace: sap
baseUri: "https://merck-s4.sap.com/sap/opu/odata/sap/API_BUDGET_SRV"
authentication:
type: basic
username: "$secrets.sap_user"
password: "$secrets.sap_password"
resources:
- name: records
path: "/"
operations:
- name: create-record
method: POST
- type: http
namespace: workday
baseUri: "https://wd5-services1.myworkday.com/ccx/service/merck/Recruiting/v42.0"
authentication:
type: bearer
token: "$secrets.workday_token"
resources:
- name: requisitions
path: "/jobRequisitions"
operations:
- name: create-requisition
method: POST
- type: http
namespace: msteams
baseUri: "https://graph.microsoft.com/v1.0"
authentication:
type: bearer
token: "$secrets.msteams_token"
resources:
- name: messages
path: "/teams/{{channel_id}}/channels/{{channel_id}}/messages"
inputParameters:
- name: channel_id
in: path
operations:
- name: send-message
method: POST