mcpField
V
vendor-management

vendor-management

github.com/serac-labsその他77105 回インストール9 週間前に更新
リポジトリ

vendor-management について

ServiceNow のベンダー管理スキルです。ベンダー情報、契約、SLA、リスク評価、実績管理を、ES5 の例と MCP ツールのワークフローで扱います。

主な機能

  1. 01ベンダー情報の管理
  2. 02契約作成と期限の追跡
  3. 03契約 SLA の定義と監視
  4. 04ベンダーリスクの評価
  5. 05実績スコアカードの作成
  6. 06MCP ツールでの検索とテスト

活用シーン

  1. 01有効なベンダーの登録と検索
  2. 02期限が近い契約の確認
  3. 03SLA 測定値の記録
  4. 04ベンダーのリスクと実績の評価

MCP 対応

snow_query_table でベンダー関連テーブルを検索し、snow_execute_script でスクリプトをテストできます。snow_artifact_manage で構成を検索します。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/serac-labs/serac --skill vendor-management

インストール後、Claude Code で/vendor-managementを入力して読み込まれたか確認します。

詳細

ServiceNow のベンダー管理

ベンダー管理では、サプライヤー、契約、パフォーマンス、リスクを追跡します。

ベンダーアーキテクチャ

Vendor (core_company)
    ├── Contracts (ast_contract)
    │   ├── Contract Terms
    │   └── SLAs
    ├── Contacts
    ├── Assessments
    └── Performance Metrics

主要なテーブル

テーブル用途
core_companyベンダー/企業
ast_contract契約
ast_contract_sla契約 SLA
vendor_risk_assessmentリスク評価
procurement_vendorベンダーの詳細

ベンダー(ES5)

ベンダーの作成
// Create vendor (ES5 ONLY!)
var vendor = new GlideRecord("core_company")
vendor.initialize()

// Basic info
vendor.setValue("name", "Acme Technology Solutions")
vendor.setValue("vendor", true)

// Contact info
vendor.setValue("phone", "+1-555-123-4567")
vendor.setValue("email", "[email protected]")
vendor.setValue("website", "https://www.acmetech.com")

// Address
vendor.setValue("street", "456 Vendor Ave")
vendor.setValue("city", "San Francisco")
vendor.setValue("state", "CA")
vendor.setValue("zip", "94105")
vendor.setValue("country", "US")

// Classification
vendor.setValue("vendor_type", "technology")
vendor.setValue("u_vendor_tier", "strategic")

// Primary contact
vendor.setValue("contact", primaryContactSysId)

vendor.insert()
ベンダーの検索
// Search vendors (ES5 ONLY!)
function searchVendors(criteria) {
  var vendors = []

  var gr = new GlideRecord("core_company")
  gr.addQuery("vendor", true)
  gr.addQuery("vendor_active", true)

  if (criteria.name) {
    gr.addQuery("name", "CONTAINS", criteria.name)
  }
  if (criteria.type) {
    gr.addQuery("vendor_type", criteria.type)
  }
  if (criteria.tier) {
    gr.addQuery("u_vendor_tier", criteria.tier)
  }

  gr.query()

  while (gr.next()) {
    vendors.push({
      sys_id: gr.getUniqueValue(),
      name: gr.getValue("name"),
      type: gr.getValue("vendor_type"),
      tier: gr.getValue("u_vendor_tier"),
      contact: gr.contact.getDisplayValue(),
      active_contracts: countActiveContracts(gr.getUniqueValue()),
    })
  }

  return vendors
}

function countActiveContracts(vendorSysId) {
  var ga = new GlideAggregate("ast_contract")
  ga.addQuery("vendor", vendorSysId)
  ga.addQuery("state", "active")
  ga.addAggregate("COUNT")
  ga.query()

  if (ga.next()) {
    return parseInt(ga.getAggregate("COUNT"), 10)
  }
  return 0
}

契約(ES5)

契約の作成
// Create vendor contract (ES5 ONLY!)
var contract = new GlideRecord("ast_contract")
contract.initialize()

// Basic info
contract.setValue("short_description", "Cloud Hosting Services")
contract.setValue("vendor", vendorSysId)
contract.setValue("contract_model", "service_agreement")

// Dates
contract.setValue("starts", "2024-01-01")
contract.setValue("ends", "2025-12-31")

// Financial
contract.setValue("contract_value", 500000)
contract.setValue("payment_terms", "net_30")
contract.setValue("currency", "USD")

// Renewal
contract.setValue("renewal_type", "auto")
contract.setValue("renewal_notice_period", 90) // days

// Owner
contract.setValue("contract_administrator", adminSysId)
contract.setValue("stakeholders", stakeholderSysIds)

// Status
contract.setValue("state", "active")

contract.insert()
契約更新アラート
// Find contracts expiring soon (ES5 ONLY!)
function getExpiringContracts(daysAhead) {
  var expiringContracts = []
  var futureDate = new GlideDateTime()
  futureDate.addDaysLocalTime(daysAhead)

  var contract = new GlideRecord("ast_contract")
  contract.addQuery("state", "active")
  contract.addQuery("ends", "<=", futureDate)
  contract.addQuery("ends", ">=", new GlideDateTime())
  contract.orderBy("ends")
  contract.query()

  while (contract.next()) {
    expiringContracts.push({
      sys_id: contract.getUniqueValue(),
      number: contract.getValue("number"),
      description: contract.getValue("short_description"),
      vendor: contract.vendor.getDisplayValue(),
      ends: contract.getValue("ends"),
      value: contract.getValue("contract_value"),
      renewal_type: contract.getValue("renewal_type"),
    })
  }

  return expiringContracts
}

// Scheduled job to send alerts
;(function executeScheduledJob() {
  var expiring = getExpiringContracts(90)

  for (var i = 0; i < expiring.length; i++) {
    var contract = new GlideRecord("ast_contract")
    if (contract.get(expiring[i].sys_id)) {
      gs.eventQueue("contract.expiring.soon", contract, "90", "")
    }
  }
})()

契約 SLA(ES5)

契約 SLA の定義
// Create contract SLA (ES5 ONLY!)
var sla = new GlideRecord("ast_contract_sla")
sla.initialize()

sla.setValue("contract", contractSysId)
sla.setValue("name", "Uptime Guarantee")
sla.setValue("description", "99.9% uptime guarantee")

// Metrics
sla.setValue("metric_type", "availability")
sla.setValue("target_value", "99.9")
sla.setValue("measurement_period", "monthly")

// Penalties/Credits
sla.setValue("penalty_type", "credit")
sla.setValue("penalty_description", "10% credit for each 0.1% below target")

sla.insert()
SLA パフォーマンスの追跡
// Record SLA measurement (ES5 ONLY!)
function recordSLAMeasurement(slaSysId, period, actualValue) {
  var measurement = new GlideRecord("u_sla_measurement")
  measurement.initialize()

  measurement.setValue("sla", slaSysId)
  measurement.setValue("period", period)
  measurement.setValue("actual_value", actualValue)
  measurement.setValue("measured_date", new GlideDateTime())

  // Get target
  var sla = new GlideRecord("ast_contract_sla")
  if (sla.get(slaSysId)) {
    var target = parseFloat(sla.getValue("target_value"))
    var actual = parseFloat(actualValue)

    measurement.setValue("target_value", target)
    measurement.setValue("met", actual >= target)

    if (actual < target) {
      // Calculate penalty/credit
      var shortfall = target - actual
      measurement.setValue("shortfall", shortfall)
      measurement.work_notes = "SLA not met. Shortfall: " + shortfall + "%"
    }
  }

  return measurement.insert()
}

ベンダーのリスク評価(ES5)

リスク評価の作成
// Create vendor risk assessment (ES5 ONLY!)
function createVendorAssessment(vendorSysId, assessmentData) {
  var assessment = new GlideRecord("vendor_risk_assessment")
  assessment.initialize()

  assessment.setValue("vendor", vendorSysId)
  assessment.setValue("assessment_date", new GlideDateTime())
  assessment.setValue("assessor", gs.getUserID())

  // Risk scores (1-5 scale)
  assessment.setValue("financial_risk", assessmentData.financial)
  assessment.setValue("operational_risk", assessmentData.operational)
  assessment.setValue("security_risk", assessmentData.security)
  assessment.setValue("compliance_risk", assessmentData.compliance)
  assessment.setValue("strategic_risk", assessmentData.strategic)

  // Calculate overall score
  var scores = [
    assessmentData.financial,
    assessmentData.operational,
    assessmentData.security,
    assessmentData.compliance,
    assessmentData.strategic,
  ]
  var total = 0
  for (var i = 0; i < scores.length; i++) {
    total += parseInt(scores[i], 10)
  }
  var average = total / scores.length
  assessment.setValue("overall_risk_score", average.toFixed(1))

  // Risk rating
  var rating = "low"
  if (average >= 4) rating = "critical"
  else if (average >= 3) rating = "high"
  else if (average >= 2) rating = "medium"
  assessment.setValue("risk_rating", rating)

  // Notes
  assessment.setValue("notes", assessmentData.notes)

  return assessment.insert()
}
ベンダーのパフォーマンス・スコアカード
// Calculate vendor performance score (ES5 ONLY!)
function getVendorScorecard(vendorSysId) {
  var scorecard = {
    vendor_sys_id: vendorSysId,
    sla_performance: 0,
    ticket_metrics: {},
    risk_rating: "",
    overall_score: 0,
  }

  // SLA performance
  var slaMeasurements = new GlideAggregate("u_sla_measurement")
  slaMeasurements.addQuery("sla.contract.vendor", vendorSysId)
  slaMeasurements.addQuery("measured_date", ">=", gs.monthsAgo(12))
  slaMeasurements.addAggregate("AVG", "met")
  slaMeasurements.query()

  if (slaMeasurements.next()) {
    scorecard.sla_performance = Math.round(slaMeasurements.getAggregate("AVG", "met") * 100)
  }

  // Incident metrics
  var incidents = new GlideAggregate("incident")
  incidents.addQuery("vendor", vendorSysId)
  incidents.addQuery("opened_at", ">=", gs.monthsAgo(12))
  incidents.addAggregate("COUNT")
  incidents.addAggregate("AVG", "calendar_duration")
  incidents.query()

  if (incidents.next()) {
    scorecard.ticket_metrics.count = parseInt(incidents.getAggregate("COUNT"), 10)
    scorecard.ticket_metrics.avg_resolution = incidents.getAggregate("AVG", "calendar_duration")
  }

  // Latest risk assessment
  var assessment = new GlideRecord("vendor_risk_assessment")
  assessment.addQuery("vendor", vendorSysId)
  assessment.orderByDesc("assessment_date")
  assessment.setLimit(1)
  assessment.query()

  if (assessment.next()) {
    scorecard.risk_rating = assessment.getValue("risk_rating")
  }

  // Calculate overall score
  scorecard.overall_score = calculateOverallScore(scorecard)

  return scorecard
}

MCP ツールの統合

利用可能なツール
ツール用途
snow_query_tableベンダーテーブルのクエリ
snow_execute_scriptベンダースクリプトのテスト
snow_artifact_manage (action='find')構成の検索
ワークフローの例
// 1. Query active vendors
await snow_query_table({
  table: "core_company",
  query: "vendor=true^vendor_active=true",
  fields: "name,vendor_type,u_vendor_tier,contact",
})

// 2. Find expiring contracts
await snow_execute_script({
  script: `
        var expiring = getExpiringContracts(60);
        gs.info(JSON.stringify(expiring));
    `,
})

// 3. Get vendor scorecard
await snow_execute_script({
  script: `
        var scorecard = getVendorScorecard('vendor_sys_id');
        gs.info(JSON.stringify(scorecard));
    `,
})

ベストプラクティス

  1. ベンダーの分類 - 重要度に応じて階層化します
  2. 契約の追跡 - 有効期限を監視します
  3. SLA の監視 - パフォーマンスを追跡します
  4. リスク評価 - 定期的に評価します
  5. パフォーマンスレビュー - 四半期ごとにスコアカードを作成します
  6. ドキュメント化 - 記録を完全に整備します
  7. コンプライアンス - 認証を確認します
  8. ES5 のみ - 最新の JavaScript 構文は使用しません

コメント