mcpField
C
catalog-items

catalog-items

github.com/serac-labs開発7762 回インストール9 週間前に更新
リポジトリ

catalog-items について

ServiceNow の開発者向けサービスカタログスキルです。カタログ項目、変数、クライアントスクリプト、承認、履行を説明し、レコードプロデューサーやオーダーガイドの例も含みます。

主な機能

  1. 01カタログ、カテゴリ、申請項目の設計
  2. 02変数と再利用可能な変数セットの設定
  3. 03クライアントスクリプトとフォーム検証の作成
  4. 04価格、承認、履行フローの設定
  5. 05レコードプロデューサーとオーダーガイドの作成

活用シーン

  1. 01セルフサービス申請フォームの構築
  2. 02複数のカタログ項目で項目グループを再利用
  3. 03条件に応じた申請検証と価格計算
  4. 04複数項目を含む入社申請ウィザードの作成

MCP 対応

README では、snow_create_variable と snow_create_catalog_variable など、カタログ変数を作成する MCP ツールに触れています。

インストール

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

$npx skills add https://github.com/serac-labs/serac --skill catalog-items

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

詳細

ServiceNow のサービスカタログ開発

サービスカタログでは、セルフサービスポータルを通じてユーザーがサービスやアイテムをリクエストできます。

カタログの構成要素

構成要素目的例
カタログカテゴリのコンテナーIT サービスカタログ
カテゴリアイテムのグループハードウェア、ソフトウェア
アイテムリクエスト可能なサービス新しいノート PC のリクエスト
変数アイテム上のフォームフィールドノート PC モデルのドロップダウン
変数セット再利用可能な変数グループユーザー詳細
プロデューサーレコードを直接作成しますインシデントの報告
オーダーガイド複数アイテムのウィザード新入社員のセットアップ

カタログアイテムの構造

Catalog Item: Request New Laptop
├── Variables
│   ├── laptop_model (Reference: cmdb_model)
│   ├── reason (Multi-line text)
│   └── urgency (Choice: Low, Medium, High)
├── Variable Sets
│   └── Delivery Information (Address, Contact)
├── Catalog Client Scripts
│   ├── onLoad: Set defaults
│   └── onChange: Update price
├── Workflows/Flows
│   └── Laptop Approval Flow
└── Fulfillment
    └── Creates Task for IT

変数の種類

種類使用例例
単一行テキスト短い入力従業員 ID
複数行テキスト長い入力業務上の正当な理由
選択ボックス単一選択優先度
チェックボックスはい/いいえ速達配送
参照テーブルへのリンクリクエスト対象者
日付日付ピッカー必要日付
ルックアップ選択ボックスフィルターされた参照カテゴリ別のモデル
リストコレクター複数選択CC 受信者
コンテナー開始/終了視覚的なグループ化ハードウェアオプション
マクロカスタムウィジェットコスト計算ツール

カタログ変数の作成

基本的な変数
// Via MCP (snow_create_variable supports reference, checkbox, etc.;
// snow_create_catalog_variable covers text/choice types only)
snow_create_variable({
  cat_item: "<catalog item sys_id>",
  name: "laptop_model",
  question_text: "Laptop Model",
  type: "reference",
  mandatory: true,
  order: 100,
})

// Set the reference table and qualifier on the created variable
snow_record_manage({
  action: "update",
  table: "item_option_new",
  sys_id: "<variable sys_id>",
  data: { reference: "cmdb_model", reference_qual: "category=computer" },
})
動的なデフォルト値を持つ変数
// Variable: requested_for
// Type: Reference (sys_user)
// Default value (script):
javascript: gs.getUserID()
参照修飾子を持つ変数
// Variable: assignment_group
// Type: Reference (sys_user_group)
// Reference Qualifier:

// Simple:
active=true^type=it

// Dynamic (Script):
javascript: 'active=true^manager=' + gs.getUserID()

// Advanced (using current variables):
javascript: 'u_department=' + current.variables.department

カタログクライアントスクリプト

onLoad 時にデフォルト値を設定
function onLoad() {
  // Set default values
  g_form.setValue("urgency", "low")

  // Hide admin-only fields
  if (!g_user.hasRole("catalog_admin")) {
    g_form.setDisplay("cost_center", false)
  }

  // Set default date to tomorrow
  var tomorrow = new GlideDateTime()
  tomorrow.addDays(1)
  g_form.setValue("needed_by", tomorrow.getDate().getValue())
}
onChange 時に価格を動的に設定
function onChange(control, oldValue, newValue, isLoading) {
  if (isLoading) return

  // Get price from selected model
  var ga = new GlideAjax("CatalogUtils")
  ga.addParam("sysparm_name", "getModelPrice")
  ga.addParam("sysparm_model", newValue)
  ga.getXMLAnswer(function (price) {
    g_form.setValue("item_price", price)
    updateTotal()
  })
}

function updateTotal() {
  var price = parseFloat(g_form.getValue("item_price")) || 0
  var quantity = parseInt(g_form.getValue("quantity")) || 1
  g_form.setValue("total_cost", (price * quantity).toFixed(2))
}
onSubmit 時に検証
function onSubmit() {
  // Validate business justification for high-cost items
  var cost = parseFloat(g_form.getValue("total_cost"))
  var justification = g_form.getValue("business_justification")

  if (cost > 1000 && !justification) {
    g_form.showFieldMsg("business_justification", "Required for items over $1000", "error")
    return false
  }

  // Validate date is in future
  var neededBy = g_form.getValue("needed_by")
  var today = new GlideDateTime().getDate().getValue()
  if (neededBy < today) {
    g_form.showFieldMsg("needed_by", "Date must be in the future", "error")
    return false
  }

  return true
}

変数セット

再利用可能な変数セットの作成
Variable Set: User Contact Information
├── contact_name (Single Line Text)
├── contact_email (Email)
├── contact_phone (Single Line Text)
└── preferred_contact (Choice: Email, Phone, Either)

Use in multiple catalog items:
- New Laptop Request
- Software Installation
- Network Access Request
変数セットの値へのアクセス
// In workflow or script
var ritm = current // sc_req_item

// Access variable from variable set
var contactEmail = ritm.variables.contact_email
var preferredContact = ritm.variables.preferred_contact

カタログのワークフロー/フロー

承認パターン
Flow Trigger: sc_req_item created
├── If: Total cost > $5000
│   └── Request Approval: Department Manager
│   └── If: Rejected
│       └── Update: RITM state = Closed Incomplete
├── If: Total cost > $25000
│   └── Request Approval: VP
├── Create: Catalog Task for Fulfillment
└── Wait: Task completion
フルフィルメントスクリプト
// In catalog item's "Execution Plan" or workflow

var ritm = current // sc_req_item

// Create an incident from catalog request
var inc = new GlideRecord("incident")
inc.initialize()
inc.setValue("short_description", ritm.short_description)
inc.setValue("description", ritm.description)
inc.setValue("caller_id", ritm.request.requested_for)
inc.setValue("category", ritm.variables.category)
inc.setValue("priority", ritm.variables.urgency)
inc.insert()

// Link incident to request
ritm.setValue("u_fulfillment_record", inc.getUniqueValue())
ritm.update()

レコードプロデューサー

カタログからインシデントを作成
// Record Producer: Report an Issue
// Table: incident
// Script:

// Map variables to incident fields
current.short_description = producer.short_description
current.description = producer.description
current.caller_id = gs.getUserID()
current.category = producer.category
current.subcategory = producer.subcategory
current.priority = producer.urgency == "urgent" ? "2" : "3"

// Set assignment based on category
if (producer.category == "network") {
  current.assignment_group.setDisplayValue("Network Support")
} else {
  current.assignment_group.setDisplayValue("Service Desk")
}

オーダーガイド

複数ステップのリクエストウィザード
Order Guide: New Employee Onboarding
├── Step 1: Employee Information
│   └── Variable Set: Employee Details
├── Step 2: Hardware Selection
│   ├── Catalog Item: Laptop
│   ├── Catalog Item: Monitor
│   └── Catalog Item: Peripherals
├── Step 3: Software Requests
│   └── Rule: Show software based on department
├── Step 4: Access Requests
│   └── Cascade Variable: Copy employee info
└── Submit: Creates multiple RITMs
オーダーガイドのルール
// Rule: Show software items based on department
function rule(item, guide_variables) {
  var dept = guide_variables.department

  // Show engineering software only for Engineering
  if (item.name == "Engineering Software Suite") {
    return dept == "engineering"
  }

  // Show finance software only for Finance
  if (item.name == "Financial Tools") {
    return dept == "finance"
  }

  return true // Show all other items
}

価格設定と承認

動的な価格設定
// Catalog Item Script (Pricing)
// Runs when item is added to cart

var basePrice = parseFloat(current.price) || 0
var quantity = parseInt(current.variables.quantity) || 1
var expedited = current.variables.expedited == "true"

var total = basePrice * quantity
if (expedited) {
  total *= 1.5 // 50% rush fee
}

current.recurring_price = 0
current.price = total
承認ルール
Approval Definition: High-Value Purchases
Condition: total_cost > 5000
Approver: requested_for.manager
Wait for: Approval
Rejection action: Cancel request

ベストプラクティス

  1. 変数の命名 - わかりやすい小文字の名前を使用します(スペースなし)
  2. 変数セット - 共通の変数グループを再利用します
  3. 参照修飾子 - 関連するレコードのみをフィルターします
  4. クライアントスクリプト - サーバー呼び出しを最小限に抑えます(GlideAjax は控えめに使用します)
  5. フルフィルメント - タスクを作成し、直接完了しないようにします
  6. テスト - 異なるユーザーロールでテストします
  7. モバイル - カタログアイテムをモバイル/タブレットでテストします
  8. ドキュメント - 変数にヘルプテキストを追加します

コメント