mcpField
M
mcp-server

mcp-server

github.com/happy-technologies-llcAgent 工作流4143 次安装3 天前更新
代码仓库

关于 mcp-server

该技能说明如何将 ServiceNow 配置为 MCP 服务,让 AI Agent 通过标准协议调用其记录、流程和知识库操作。内容涵盖工具与资源端点设计、OAuth 认证、访问控制、输入验证及测试。

主要功能

  1. 01设计 ServiceNow MCP 工具与资源
  2. 02配置 OAuth 2.0 身份验证
  3. 03设置 ACL、表白名单与限流
  4. 04验证输入并格式化响应
  5. 05记录交互并测试工具

适用场景

  1. 01构建面向 AI Agent 的 ServiceNow 接口
  2. 02开放受控的记录查询与更新
  3. 03为 ITSM 或 HR 流程提供 MCP 工具

MCP 相关

该技能指导将 ServiceNow 实现为 MCP 服务,向 MCP 客户端开放记录查询、创建和更新、流程触发及知识库搜索等工具。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/happy-technologies-llc/happy-platform-skills --skill mcp-server

安装后在 Claude Code 中输入/mcp-server确认已加载。

详细介绍

将 ServiceNow 用作 MCP 服务

概述

本技能介绍如何将 ServiceNow 设置为模型上下文协议(MCP)服务,使 AI Agent 能够通过标准化协议与 ServiceNow 交互:

  • 了解 MCP 架构,以及 ServiceNow 如何作为工具提供方
  • 定义工具能力,让 AI Agent 能够使用 ServiceNow 操作
  • 配置身份验证和授权,确保 Agent 安全访问
  • 构建资源端点,供 Agent 发现和交互
  • 实施输入验证和输出格式化,以便 Agent 使用
  • 为 MCP 交互设置日志记录、速率限制和监控
  • 使用 AI Agent 平台测试 MCP 工具定义

适用场景: 通过 MCP 标准让 AI Agent(Claude、ChatGPT、Cursor 等)与 ServiceNow 数据和操作交互、为 AI 驱动的工作流构建 ServiceNow 集成,或为多 Agent 编排创建标准化 API 层时。

前提条件

  • 角色: admin、rest_api_explorer、web_service_admin
  • 插件: com.glide.rest(REST API)、com.snc.oauth(OAuth 2.0)
  • 访问权限: 对 sys_rest_api、sys_script_include、sys_properties、sys_oauth_entity 表具有写入权限
  • 知识: REST API 设计、OAuth 2.0、JSON Schema、MCP 规范概念
  • 相关技能: 用于 REST API 开发的 development/scripted-rest-apis,以及用于访问控制的 security/acl-management

流程

步骤 1:了解 MCP 架构

模型上下文协议定义了一个标准接口,供 AI Agent 发现和使用工具。ServiceNow 作为 MCP 服务,提供 Agent 可调用的功能。

MCP ARCHITECTURE:

[AI Agent (Client)]
       |
       | MCP Protocol (JSON-RPC 2.0)
       |
[MCP Server (ServiceNow)]
       |
       +-- Tools: Operations the agent can perform
       |     +-- query_records: Search ServiceNow tables
       |     +-- create_record: Create new records
       |     +-- update_record: Modify existing records
       |     +-- run_flow: Trigger Flow Designer flows
       |
       +-- Resources: Data the agent can read
       |     +-- incident://INC0010001: Incident record
       |     +-- kb://KB0010001: Knowledge article
       |     +-- cmdb://ci/server001: Configuration item
       |
       +-- Prompts: Predefined interaction templates
             +-- incident-triage: Guide incident categorization
             +-- change-risk: Assess change request risk
步骤 2:设计工具架构

定义用于提供 ServiceNow 操作的 MCP 工具。

工具定义格式(MCP 标准):

{
  "name": "sn_query_records",
  "description": "Query ServiceNow records from any table using encoded query syntax. Returns matching records with specified fields.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "table": {
        "type": "string",
        "description": "ServiceNow table name (e.g., incident, change_request, sys_user)"
      },
      "query": {
        "type": "string",
        "description": "Encoded query string (e.g., priority=1^state=2)"
      },
      "fields": {
        "type": "string",
        "description": "Comma-separated list of fields to return"
      },
      "limit": {
        "type": "integer",
        "description": "Maximum records to return (default 10, max 100)",
        "default": 10
      }
    },
    "required": ["table"]
  }
}

核心工具定义:

工具名称用途必需参数可选参数
sn_query_records搜索记录tablequery, fields, limit, order_by
sn_read_record获取单条记录table, sys_idfields
sn_create_record创建记录table, data
sn_update_record更新记录table, sys_id, data
sn_get_schema获取表架构table
sn_run_flow触发工作流flow_id, inputs
sn_search_kb搜索知识库querykb_id, limit
sn_add_comment添加工作说明/评论table, sys_id, texttype (work_note/comment)
步骤 3:创建脚本化 REST API

构建用于实现 MCP 工具操作的 REST API 端点。

MCP 方式:

Tool: SN-Create-Record
Parameters:
  table_name: sys_rest_api
  data:
    name: "MCP Server API"
    api_id: "mcp_server"
    namespace: "x_mcp"
    short_description: "Model Context Protocol server endpoint for AI agent integration"
    active: true
    requires_authentication: true

REST 方式:

POST /api/now/table/sys_rest_api
Body: {
  "name": "MCP Server API",
  "api_id": "mcp_server",
  "namespace": "x_mcp",
  "short_description": "Model Context Protocol server endpoint for AI agent integration",
  "active": "true",
  "requires_authentication": "true"
}
步骤 4:创建资源端点

为每项 MCP 工具能力构建 API 资源。

MCP 方式:

Tool: SN-Create-Record
Parameters:
  table_name: sys_rest_api_resource
  data:
    rest_api: [REST_API_SYS_ID]
    name: "Tools List"
    resource_path: "/tools/list"
    http_method: "GET"
    short_description: "Return list of available MCP tools and their schemas"
    script: |
      (function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
        var tools = [];
        tools.push({
          name: 'sn_query_records',
          description: 'Query ServiceNow records from any table',
          inputSchema: {
            type: 'object',
            properties: {
              table: { type: 'string', description: 'Table name' },
              query: { type: 'string', description: 'Encoded query' },
              fields: { type: 'string', description: 'Fields to return' },
              limit: { type: 'integer', description: 'Max results', default: 10 }
            },
            required: ['table']
          }
        });
        // Add more tool definitions...
        response.setBody({ tools: tools });
      })(request, response);

工具执行端点:

Tool: SN-Create-Record
Parameters:
  table_name: sys_rest_api_resource
  data:
    rest_api: [REST_API_SYS_ID]
    name: "Tools Call"
    resource_path: "/tools/call"
    http_method: "POST"
    short_description: "Execute an MCP tool with provided arguments"
    script: |
      (function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
        var body = request.body.data;
        var toolName = body.name;
        var args = body.arguments || {};

        var handler = new x_mcp.MCPToolHandler();
        var result = handler.execute(toolName, args);

        response.setBody({
          content: [{
            type: 'text',
            text: JSON.stringify(result)
          }]
        });
      })(request, response);
步骤 5:实现工具处理程序

创建 Script Include 来处理 MCP 工具执行。

MCP 方式:

Tool: SN-Create-Record
Parameters:
  table_name: sys_script_include
  data:
    name: "MCPToolHandler"
    api_name: "x_mcp.MCPToolHandler"
    script: |
      var MCPToolHandler = Class.create();
      MCPToolHandler.prototype = {
        initialize: function() {},

        execute: function(toolName, args) {
          switch(toolName) {
            case 'sn_query_records':
              return this._queryRecords(args);
            case 'sn_read_record':
              return this._readRecord(args);
            case 'sn_create_record':
              return this._createRecord(args);
            case 'sn_update_record':
              return this._updateRecord(args);
            case 'sn_get_schema':
              return this._getSchema(args);
            default:
              return { error: 'Unknown tool: ' + toolName };
          }
        },

        _queryRecords: function(args) {
          var gr = new GlideRecord(args.table);
          if (!gr.canRead()) return { error: 'Access denied to table: ' + args.table };
          if (args.query) gr.addEncodedQuery(args.query);
          gr.setLimit(Math.min(args.limit || 10, 100));
          gr.query();
          var results = [];
          var fields = args.fields ? args.fields.split(',') : null;
          while (gr.next()) {
            var record = {};
            if (fields) {
              fields.forEach(function(f) {
                record[f.trim()] = gr.getDisplayValue(f.trim());
              });
            } else {
              record.sys_id = gr.getUniqueValue();
              record.display_value = gr.getDisplayValue();
            }
            results.push(record);
          }
          return { records: results, count: results.length };
        },

        _readRecord: function(args) {
          var gr = new GlideRecord(args.table);
          if (!gr.canRead()) return { error: 'Access denied' };
          if (gr.get(args.sys_id)) {
            var record = {};
            var fields = args.fields ? args.fields.split(',') : null;
            if (fields) {
              fields.forEach(function(f) {
                record[f.trim()] = gr.getDisplayValue(f.trim());
              });
            }
            return { record: record };
          }
          return { error: 'Record not found' };
        },

        type: 'MCPToolHandler'
      };
    access: "public"
    active: true
步骤 6:配置身份验证

为安全的 Agent 身份验证设置 OAuth 2.0。请通过获批的本地凭据管理器或模型上下文之外的部署密钥存储来提供身份验证材料。切勿要求 Agent 收集此类材料、将其放入工具调用中、在文档中生成,或添加到 Shell 参数或客户端 JSON 中。

MCP 方式:

Tool: SN-Query-Table
Parameters:
  table_name: sys_oauth_entity
  query: type=client^active=true
  fields: sys_id,name,client_id,redirect_url,token_lifetime,refresh_token_lifetime
  limit: 10

创建 OAuth 应用:

Tool: SN-Create-Record
Parameters:
  table_name: sys_oauth_entity
  data:
    name: "MCP Agent OAuth Client"
    type: "client"
    client_id: "mcp_agent_client"
    redirect_url: "https://agent.example.com/callback"
    token_lifetime: 1800
    refresh_token_lifetime: 86400
    active: true
    comments: "OAuth client for MCP-compliant AI agents"

身份验证流程:

  1. 管理员在 ServiceNow 中注册客户端元数据。
  2. 获批的本地凭据助手在对话和模型上下文之外执行所选的 OAuth 交换。
  3. 集成传输层在不记录日志的情况下提供生成的身份验证状态。
  4. ServiceNow 验证请求,并应用集成用户的 ACL 上下文。
步骤 7:实施访问控制

为 MCP 端点配置 ACL 和速率限制。

表级访问控制:

Tool: SN-Query-Table
Parameters:
  table_name: sys_security_acl
  query: name=sys_rest_api^operation=execute
  fields: sys_id,name,operation,condition,role
  limit: 10

速率限制配置:

Tool: SN-Create-Record
Parameters:
  table_name: sys_properties
  data:
    name: "x_mcp.rate_limit.per_minute"
    value: "60"
    description: "Maximum MCP API calls per minute per client"
    type: "integer"

访问控制矩阵:

工具最低角色表 ACL 检查速率限制
sn_query_recordsitil表读取 ACL60/min
sn_read_recorditil表读取 ACL60/min
sn_create_recorditil表创建 ACL30/min
sn_update_recorditil表写入 ACL30/min
sn_get_schemaitil无10/min
sn_run_flowflow_operatorFlow ACL10/min
步骤 8:实施输入验证

添加验证,以防止滥用并确保数据质量。

VALIDATION RULES:

Table Name Validation:
- Must exist in sys_db_object
- Must not be in blocklist (sys_user_password, sys_certificate, etc.)
- Must be accessible to the authenticated user

Query Validation:
- Maximum query length: 2000 characters
- No script injection (block javascript: in queries for non-admin)
- Validate encoded query syntax

Field Validation:
- Fields must exist on the target table
- Sensitive fields filtered (password, token, secret fields)

Limit Validation:
- Maximum 100 records per query
- Default 10 if not specified

Data Validation (create/update):
- Validate field types match expected values
- Enforce mandatory field requirements
- Sanitize string inputs
步骤 9:设置日志记录和监控

为所有 MCP 交互配置日志记录。

MCP 方案:

Tool: SN-Create-Record
Parameters:
  table_name: sys_properties
  data:
    name: "x_mcp.logging.enabled"
    value: "true"
    description: "Enable logging for all MCP API interactions"
    type: "boolean"

日志条目结构:

MCP INTERACTION LOG:
- Timestamp: [ISO 8601]
- Client ID: [OAuth client]
- Tool: [tool_name]
- Arguments: [sanitized args]
- Response Status: [success/error]
- Response Time: [ms]
- Records Affected: [count]
- User Context: [authenticated user]
步骤 10:测试 MCP 集成

使用 Agent 平台验证 MCP 服务。

**测试工具列表:**通过传输身份验证已由本地运行时配置的 MCP 客户端进行连接,然后检查其公布的工具列表。

**测试工具执行:**通过该 MCP 客户端调用低风险、只读的架构或查询工具。验证允许列表、ACL 强制执行、速率限制、日志脱敏和响应格式。如果必须进行原始传输探测,请使用组织批准的本地凭据助手,并确保所有身份验证状态都保留在命令行和生成的文档之外。

工具用法

工具用途使用时机
SN-Create-Record创建 REST API、资源、脚本包含项构建 MCP 服务组件
SN-Update-Record修改 API 配置、更新脚本迭代实现 MCP
SN-Query-Table查找现有 API、ACL、OAuth 配置发现和验证
SN-Get-Table-Schema为工具架构发现表字段生成架构
SN-Get-Record查看特定 API 或脚本的详细信息调试和验证

最佳实践

  1. 严格遵循 MCP 规范 -- 确保工具架构符合 MCP JSON Schema 格式
  2. 使用 OAuth 2.0 客户端凭据 进行服务器到服务器的 Agent 身份验证
  3. 实施表允许列表 -- 明确指定 Agent 可以访问哪些表
  4. 绝不公开敏感表 -- 阻止访问凭据、证书和密码表
  5. 严格限制速率 -- AI Agent 可能会产生大量请求
  6. 记录所有交互 -- 保留审计跟踪,用于安全和调试
  7. 返回显示值 -- Agent 使用人类可读数据时效果更好
  8. 实施分页 -- 对大型结果集使用基于游标的分页
  9. 为 API 设置版本 -- 在资源路径中包含版本,以保持向后兼容
  10. 使用多个 Agent 平台进行测试 -- 确保与 Claude、ChatGPT 等平台兼容
  11. 将大型参考语料设为可选 -- 默认使用实时/基于源的查找,并将本地索引、SQLite、嵌入和向量搜索明确设为可选项

故障排除

问题原因解决方法
401 未授权OAuth 令牌已过期或无效刷新令牌;验证客户端凭据;检查令牌有效期
403 禁止访问用户缺少表或 API ACL验证分配给 OAuth 用户的角色;检查表 ACL
找不到工具客户端和服务端的工具名称不匹配验证 tools/list 响应中的工具名称是否与客户端配置一致
结果为空查询语法不正确或没有匹配的记录直接在 ServiceNow 中测试查询;检查编码查询语法
大型查询超时查询返回的记录过多减小限制;添加更具体的查询条件
工具处理程序中的脚本错误Script Include 中出现运行时异常检查系统日志(syslog);在处理程序脚本中添加错误处理

示例

示例 1:基础只读 MCP 服务

场景: 搭建一个用于只读查询事件的最小 MCP 服务。

提供的工具:

  • sn_query_incidents - 搜索事件
  • sn_read_incident - 获取事件详情
  • sn_search_kb - 搜索知识库
示例 2:完整 ITSM MCP 服务

场景: 搭建具备创建和更新功能的完整 ITSM MCP 服务。

提供的工具:

  • 查询:事件、变更、问题、配置项
  • 创建:事件、变更请求
  • 更新:事件状态、分配、优先级
  • 操作:添加工作备注、触发流程
  • 知识:搜索和检索知识库文章
示例 3:面向 HR 的限定范围 MCP 服务

场景: 为 HR 服务交付搭建部门限定范围的 MCP 服务。

提供的工具:

  • hr_query_cases - 搜索 HR 案例(仅限请求者自己的案例)
  • hr_create_case - 提交新的 HR 案例
  • hr_search_policies - 搜索 HR 政策知识库
  • hr_check_benefits - 查询福利注册状态

访问控制:

  • 仅允许访问 hr_case 表
  • 用户只能查看自己的案例
  • 创建操作仅限特定案例类别

相关技能

  • development/scripted-rest-apis - 在 ServiceNow 中构建 REST API
  • security/acl-management - 配置访问控制列表
  • admin/application-scope - 限定范围的应用开发
  • genai/build-agent - 构建可使用 MCP 工具的 AI Agent
  • genai/skill-kit-custom - 自定义 Now Assist 技能开发
  • development/servicenow-docs-mcp - 搜索 ServiceNowDocs,并为 Happy Platform MCP 提供可选的本地索引

评论

支持 Markdown