mcpField
K
knowledge-management

knowledge-management

github.com/serac-labs生産性7798 回インストール9 週間前に更新
リポジトリ

knowledge-management について

Knowledge Management for ServiceNow は、ナレッジ記事の作成、整理、検索、共有に関するワークフローと ES5 の例を紹介します。ServiceNow のナレッジベースを管理するチーム向けで、レビュー状態、テンプレート、フィードバック、利用状況の記録を扱います。

主な機能

  1. 01ナレッジベース、カテゴリ、記事の整理
  2. 02記事と添付ファイルの作成
  3. 03レビューと公開状態の管理
  4. 04記事検索とテンプレートの利用
  5. 05フィードバックと利用状況の記録

活用シーン

  1. 01カテゴリ付きナレッジ記事の作成
  2. 02記事のレビュー申請
  3. 03既存のサポート文書の検索
  4. 04評価とコメントの収集

MCP 対応

README には、ナレッジ記事の検索・照会、記事の検索、スクリプトのテストに使う ServiceNow MCP ツールが記載されています。これらのツールは、説明されているナレッジ管理ワークフローを支援します。

インストール

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

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

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

詳細

ServiceNow のナレッジ管理

ナレッジ管理では、ナレッジ記事の作成、整理、共有ができます。

ナレッジアーキテクチャ

Knowledge Base (kb_knowledge_base)
    ├── Category (kb_category)
    │   ├── Article (kb_knowledge)
    │   │   ├── Feedback (kb_feedback)
    │   │   └── Use (kb_use)
    │   └── Article
    └── Category
        └── Article

主要なテーブル

テーブル目的
kb_knowledge_baseナレッジベースの定義
kb_knowledgeナレッジ記事
kb_category記事のカテゴリ
kb_feedback記事に対するユーザーのフィードバック
kb_use記事の利用状況の追跡

記事の作成(ES5)

ナレッジ記事の作成
// Create KB article (ES5 ONLY!)
var article = new GlideRecord("kb_knowledge")
article.initialize()

// Basic info
article.setValue("short_description", "How to Reset Your Password")
article.setValue("kb_knowledge_base", getKnowledgeBaseSysId("IT Knowledge"))
article.setValue("kb_category", getCategorySysId("Self-Service"))

// Content
article.setValue(
  "text",
  "<h2>Password Reset Instructions</h2>" +
    "<p>Follow these steps to reset your password:</p>" +
    "<ol>" +
    "<li>Go to the Self-Service Portal</li>" +
    '<li>Click "Forgot Password"</li>' +
    "<li>Enter your email address</li>" +
    "<li>Check your email for reset link</li>" +
    "<li>Create a new password</li>" +
    "</ol>" +
    "<h3>Password Requirements</h3>" +
    "<ul>" +
    "<li>Minimum 12 characters</li>" +
    "<li>At least one uppercase letter</li>" +
    "<li>At least one number</li>" +
    "<li>At least one special character</li>" +
    "</ul>",
)

// Metadata
article.setValue("author", gs.getUserID())
article.setValue("article_type", "text") // text, wiki, html

// Workflow state
article.setValue("workflow_state", "draft")

article.insert()
添付ファイル付きの記事
// Create article and add attachment (ES5 ONLY!)
var article = new GlideRecord("kb_knowledge")
article.initialize()
article.setValue("short_description", "VPN Setup Guide")
article.setValue("kb_knowledge_base", kbSysId)
article.setValue("text", "<p>See attached PDF for detailed instructions.</p>")
var articleSysId = article.insert()

// Add attachment
var attachment = new GlideSysAttachment()
attachment.copy("kb_knowledge", templateArticleSysId, "kb_knowledge", articleSysId)

記事のワークフロー

ワークフローの状態
状態説明次の状態
draft作成開始review
review承認待ちpublished, draft
publishedユーザーに表示retired
retired表示対象外published
outdated更新が必要draft
レビューへの提出(ES5)
// Submit article for review (ES5 ONLY!)
function submitForReview(articleSysId) {
  var article = new GlideRecord("kb_knowledge")
  if (article.get(articleSysId)) {
    // Validate required fields
    if (!article.getValue("short_description")) {
      gs.addErrorMessage("Short description is required")
      return false
    }
    if (!article.getValue("text")) {
      gs.addErrorMessage("Article content is required")
      return false
    }

    // Change state
    article.setValue("workflow_state", "review")
    article.update()

    // Notify reviewers
    gs.eventQueue("kb.article.review", article, "", "")

    return true
  }
  return false
}
記事の公開(ES5)
// Publish approved article (ES5 ONLY!)
function publishArticle(articleSysId) {
  var article = new GlideRecord("kb_knowledge")
  if (article.get(articleSysId)) {
    // Only publish from review state
    if (article.getValue("workflow_state") !== "review") {
      gs.addErrorMessage("Article must be in review state")
      return false
    }

    // Set publish date
    article.setValue("workflow_state", "published")
    article.setValue("published", new GlideDateTime())

    // Set expiration if configured
    var kb = article.kb_knowledge_base.getRefRecord()
    var expirationDays = parseInt(kb.getValue("article_expiration_days"), 10)
    if (expirationDays > 0) {
      var expDate = new GlideDateTime()
      expDate.addDaysLocalTime(expirationDays)
      article.setValue("valid_to", expDate)
    }

    article.update()

    return true
  }
  return false
}

ナレッジ検索(ES5)

記事の検索
// Search knowledge articles (ES5 ONLY!)
var KnowledgeSearch = Class.create()
KnowledgeSearch.prototype = {
  initialize: function () {},

  /**
   * Search knowledge articles
   * @param {string} query - Search query
   * @param {object} options - Search options
   */
  search: function (query, options) {
    options = options || {}
    var results = []

    var gr = new GlideRecord("kb_knowledge")

    // Only published articles
    gr.addQuery("workflow_state", "published")
    gr.addQuery("active", true)

    // Valid date range
    var now = new GlideDateTime()
    gr.addNullQuery("valid_to").addOrCondition("valid_to", ">", now)

    // Search in title and body
    var qc = gr.addQuery("short_description", "CONTAINS", query)
    qc.addOrCondition("text", "CONTAINS", query)

    // Filter by knowledge base
    if (options.knowledgeBase) {
      gr.addQuery("kb_knowledge_base", options.knowledgeBase)
    }

    // Filter by category
    if (options.category) {
      gr.addQuery("kb_category", options.category)
    }

    // Limit results
    gr.setLimit(options.limit || 10)

    // Order by views/rating
    gr.orderByDesc("sys_view_count")

    gr.query()

    while (gr.next()) {
      results.push({
        sys_id: gr.getUniqueValue(),
        number: gr.getValue("number"),
        title: gr.getValue("short_description"),
        category: gr.kb_category.getDisplayValue(),
        views: gr.getValue("sys_view_count"),
        rating: gr.getValue("rating"),
        snippet: this._getSnippet(gr.getValue("text"), query),
      })
    }

    return results
  },

  _getSnippet: function (text, query) {
    // Strip HTML
    var plainText = text.replace(/<[^>]*>/g, "")

    // Find query position
    var lowerText = plainText.toLowerCase()
    var lowerQuery = query.toLowerCase()
    var pos = lowerText.indexOf(lowerQuery)

    if (pos === -1) {
      return plainText.substring(0, 200) + "..."
    }

    // Extract context around match
    var start = Math.max(0, pos - 50)
    var end = Math.min(plainText.length, pos + query.length + 150)

    var snippet = ""
    if (start > 0) snippet += "..."
    snippet += plainText.substring(start, end)
    if (end < plainText.length) snippet += "..."

    return snippet
  },

  type: "KnowledgeSearch",
}

記事テンプレート(ES5)

テンプレートから記事を作成
// Create article from template (ES5 ONLY!)
function createFromTemplate(templateName, data) {
  // Get template
  var template = new GlideRecord("kb_template")
  template.addQuery("name", templateName)
  template.query()

  if (!template.next()) {
    gs.error("Template not found: " + templateName)
    return null
  }

  // Create article
  var article = new GlideRecord("kb_knowledge")
  article.initialize()

  // Copy template fields
  article.setValue("kb_knowledge_base", template.getValue("kb_knowledge_base"))
  article.setValue("kb_category", template.getValue("kb_category"))
  article.setValue("article_type", template.getValue("article_type"))

  // Process template text with data
  var text = template.getValue("text")
  for (var key in data) {
    if (data.hasOwnProperty(key)) {
      var pattern = new RegExp("\\{\\{" + key + "\\}\\}", "g")
      text = text.replace(pattern, data[key])
    }
  }

  article.setValue("text", text)
  article.setValue("short_description", data.title || "New Article")
  article.setValue("workflow_state", "draft")

  return article.insert()
}

// Usage
var articleId = createFromTemplate("Troubleshooting Guide", {
  title: "Outlook Not Connecting",
  problem: "Outlook shows disconnected",
  solution: "Check network connection and restart Outlook",
  steps: "<ol><li>Close Outlook</li><li>Check WiFi</li><li>Reopen Outlook</li></ol>",
})

フィードバックと評価(ES5)

記事へのフィードバックを記録
// Record user feedback (ES5 ONLY!)
function recordFeedback(articleSysId, rating, comments) {
  var feedback = new GlideRecord("kb_feedback")
  feedback.initialize()
  feedback.setValue("article", articleSysId)
  feedback.setValue("user", gs.getUserID())
  feedback.setValue("rating", rating) // 1-5
  feedback.setValue("comments", comments)
  feedback.setValue("useful", rating >= 4 ? "yes" : "no")
  feedback.insert()

  // Update article rating
  updateArticleRating(articleSysId)
}

function updateArticleRating(articleSysId) {
  var ga = new GlideAggregate("kb_feedback")
  ga.addQuery("article", articleSysId)
  ga.addAggregate("AVG", "rating")
  ga.addAggregate("COUNT")
  ga.query()

  if (ga.next()) {
    var avgRating = parseFloat(ga.getAggregate("AVG", "rating"))
    var count = parseInt(ga.getAggregate("COUNT"), 10)

    var article = new GlideRecord("kb_knowledge")
    if (article.get(articleSysId)) {
      article.setValue("rating", Math.round(avgRating * 10) / 10)
      article.setValue("u_feedback_count", count)
      article.update()
    }
  }
}

MCP ツールの統合

利用可能なツール
ツール目的
snow_knowledge_article_manage (action='search')ナレッジベースを検索
snow_query_tablekb_knowledge をクエリ
snow_artifact_manage (action='find')記事を検索
snow_execute_scriptKB スクリプトをテスト
ワークフローの例
// 1. Search for existing articles
await snow_knowledge_article_manage({
  action: "search",
  query: "password reset",
  limit: 5,
})

// 2. Create new article
await snow_execute_script({
  script: `
        var article = new GlideRecord('kb_knowledge');
        article.initialize();
        article.setValue('short_description', 'New Article');
        article.setValue('text', '<p>Content here</p>');
        article.setValue('workflow_state', 'draft');
        gs.info('Created: ' + article.insert());
    `,
})

// 3. Find articles needing review
await snow_query_table({
  table: "kb_knowledge",
  query: "workflow_state=review",
  fields: "number,short_description,author,sys_created_on",
})

ベストプラクティス

  1. 明確なタイトル - 説明的で検索しやすいタイトルにします
  2. 構造化されたコンテンツ - 見出しとリストを使用します
  3. キーワード - 関連するキーワードを追加します
  4. カテゴリ - 適切に分類します
  5. レビュープロセス - 品質管理のワークフローを設けます
  6. 有効期限 - 記事の有効期間を設定します
  7. フィードバック - ユーザー評価を有効にします
  8. ES5 のみ - 最新の JavaScript 構文は使用しません

コメント