servicenow-mcp
servicenow-mcp
一个轻量级的 MCP 服务器,让 AI 代理能够通过 Table API 创建、搜索和更新 ServiceNow 事件。基于官方 Python mcp 包(FastMCP 风格装饰器)、httpx 和 python-dotenv 构建。通过 stdio 运行。
所有代码都集中在一个文件中:server.py。
设置
需要 Python 3.12+ 和 uv。
uv sync在 server.py 旁边创建一个 .env 文件(已被 git 忽略),其中包含你实例的基本认证凭据——使用 个人开发者实例 即可:
SNOW_INSTANCE_URL=https://devXXXXXX.service-now.com
SNOW_USERNAME=admin
SNOW_PASSWORD=your-password
# optional, default 15
SNOW_TIMEOUT_SECONDS=15运行服务器(它通过 stdin/stdout 使用 MCP 协议通信,因此没有可见输出——必须由 MCP 客户端启动):
uv run server.py注册到 MCP 客户端
将客户端指向 uv 和项目目录,以便正确加载 .venv 和 .env:
{
"mcpServers": {
"servicenow": {
"command": "uv",
"args": ["--directory", "/absolute/path/to/servicenow-mcp", "run", "server.py"]
}
}
}对于 Claude Code:claude mcp add servicenow -- uv --directory /absolute/path/to/servicenow-mcp run server.py。
客户端环境中已设置的环境变量优先级高于 .env。
Related MCP server: sn-mcp-bridge
工具
工具 | 参数 | 功能 | 返回结果 |
|
| 创建新事件。 |
|
|
| 按最新时间列出事件。 |
|
|
| 按编号查找事件,追加工作备注和/或设置状态。 |
|
所有工具在出错时都会返回可读的工具错误(以 isError 形式呈现给代理),而不是堆栈跟踪,例如:
Authentication failed (401): check SNOW_USERNAME and SNOW_PASSWORD. ServiceNow said: User is not authenticated …Could not connect to https://…: [Errno 8] nodename nor servname provided … Check SNOW_INSTANCE_URL and your network connection.Timed out after 15s talking to https://… The instance may be hibernating (PDI) or unreachable.Incident 'INC9999999' was not found on https://….Forbidden (403): the user lacks permission … or the update was rejected by a business rule. ServiceNow said: …(例如,在未填写解决字段的情况下解决事件)。
设计说明
ServiceNowClient封装了一个httpx.AsyncClient(基本认证、JSON 头、超时),并暴露了create_record / query_records / get_record_by_number / update_record方法。所有错误都被转换为带有可读消息的ServiceNowError。工具通过
get_client()获取客户端;在测试中调用set_client(fake)即可替换为模拟对象,无需访问网络。记录通过
sysparm_display_value=all获取,因此状态/紧急程度标签来自实例本身,而非硬编码映射(友好名称别名仅用于输入)。mcp2.x 将FastMCP重命名为MCPServer;server.py会导入存在的版本,因此可在 1.x 和 2.x 上运行。
冒烟测试
针对真实实例运行(会写入一个事件):
uv run python -c "
import asyncio, server
async def main():
c = await server.create_incident('MCP server smoke test', 'created by smoke test')
print(c)
print(await server.query_incidents(query_text='MCP server smoke test'))
print(await server.update_incident(c['number'], work_notes='hello from MCP'))
asyncio.run(main())
"Available Tools
3 toolscreate_incidentA
Create a new ServiceNow incident and return its number and sys_id.
Use this when a user reports a problem that should be tracked as a ticket.
Args:
short_description: One-line summary of the issue (required, shown in lists).
description: Longer free-text details, steps to reproduce, impact, etc.
urgency: "1" (High), "2" (Medium) or "3" (Low). Defaults to "3".
Returns:
{"number": "INC0010001", "sys_id": "...", "short_description": ..., "state": ..., "urgency": ...}
The `number` is what humans reference; `sys_id` is the stable record id.
| Name | Required | Description | Default |
|---|---|---|---|
| urgency | No | 3 | |
| description | No | ||
| short_description | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It discloses that the tool creates a record and returns specific fields. It could add potential side effects or permissions needed, but is adequate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured, front-loaded with clear purpose and usage. Each sentence adds value, no fluff. Parameters and return value explained efficiently.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Tool has 3 parameters and output schema exists. Description covers parameter semantics, return format, and usage context. No gaps given complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so description must compensate. It does so by explaining each parameter's purpose and format (e.g., urgency values, description use). Adds meaning beyond schema (e.g., 'shown in lists'). Could note default for short_description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool creates a ServiceNow incident and returns its number and sys_id. It distinguishes itself from siblings by specifying creation, not querying or updating.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use this tool: 'when a user reports a problem that should be tracked as a ticket.' No exclusion of siblings but clear context for usage, and siblings are named for differentiation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
query_incidentsA
List ServiceNow incidents, newest first, optionally filtered by text and/or state.
Use this to find existing tickets before creating a new one, to check on a
ticket by number, or to answer "what incidents are open about X?".
Args:
query_text: What to search for. An incident number ("INC0010001") matches
exactly; anything else runs ServiceNow's keyword search over the
incident's text fields, falling back to a substring match on
short_description/description. Leave empty to list the most recent incidents.
state: Filter by state. Accepts a numeric code ("1".."8") or a name such as
"New", "In Progress", "On Hold", "Resolved", "Closed", "Canceled".
Leave empty for any state.
limit: Maximum number of incidents to return (1-100). Defaults to 5.
Returns:
A list of {"number", "sys_id", "short_description", "state", "state_code",
"urgency", "created_on"}; an empty list means nothing matched.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| state | No | ||
| query_text | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behavioral details: search semantics (exact number matching vs. keyword search with substring fallback), state filter format (numeric or name), limit behavior with default, and return format. It also explains the meaning of an empty list. This is comprehensive and goes beyond a simple 'lists incidents.'
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is organized into clear sections: a one-line summary, usage guidance, parameter details, and return format. Every sentence serves a purpose, from explaining search fallback to specifying defaults. It is appropriately sized given the behavioral complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete for a read-only query tool: it defines input semantics, output structure, and edge cases (empty list, empty query). The presence of an output schema is complemented by a human-readable description of the return fields. Given the sibling tools, it clearly fits into the workflow as the search/read operation. No gaps are apparent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must fully explain parameters. The 'Args' section does exactly that: query_text, state, and limit are each described with accepted formats, defaults, and special behavior (e.g., prefix matching for incident numbers, state code ranges). This adds significant meaning beyond the raw schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List ServiceNow incidents, newest first, optionally filtered by text and/or state.' This uses a specific verb, names the resource (ServiceNow incidents), and distinguishes it from sibling tools like create_incident and update_incident by focusing on listing/querying.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly provides use cases: 'Use this to find existing tickets before creating a new one, to check on a ticket by number, or to answer "what incidents are open about X?".' This gives clear when-to-use guidance. It implies when-not-to-use (e.g., before creating) but does not explicitly name alternatives or exclude other tools, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_incidentA
Update an existing incident by number: append a work note and/or change its state.
Use this to record progress on a ticket or move it through its lifecycle.
At least one of `work_notes` or `state` must be provided.
Args:
number: The incident number, e.g. "INC0010001".
work_notes: Text to append to the (internal) work notes journal.
state: New state as a numeric code ("1".."8") or a name such as "In Progress",
"On Hold", "Resolved", "Closed". Note: resolving/closing on most instances
also requires resolution fields and will be rejected by ServiceNow if missing.
Returns:
{"number", "sys_id", "changed": {field: new value, ...}, "state": <current state>}
describing exactly what was applied.
| Name | Required | Description | Default |
|---|---|---|---|
| state | No | ||
| number | Yes | ||
| work_notes | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description bears full responsibility for behavioral disclosure. It clearly states that this is a mutating operation (update), explains the effect of each parameter, and warns that resolving/closing may be rejected by the backend. It does not mention idempotency, error handling for missing incidents, or authentication requirements, but the provided details are sufficient for safe invocation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured. It starts with a one-sentence summary of the action, then a one-sentence usage context, then a constraint, then a clear Args/Returns section. Every sentence adds unique information; there is no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers all parameters, provides a return format, and includes a key behavioral caveat (rejection on missing resolution fields). It is almost complete for a mutation tool with no annotations, but it does not specify what happens if the incident number does not exist or whether the operation is idempotent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must fully explain each parameter. It does so: number is given an example ('INC0010001'), work_notes is described as 'append to the (internal) work notes journal', and state is documented with both numeric codes and names, plus a note about additional fields required by ServiceNow. This adds significant semantic value beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description specifies a clear verb ('update'), resource ('existing incident'), and method ('by number'). It explicitly lists the two possible actions (append work notes and/or change state), which distinguishes it from siblings create_incident and query_incidents.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description advises when to use the tool ('record progress on a ticket or move it through its lifecycle') and states a critical constraint ('at least one of work_notes or state must be provided'). It also warns about potential rejection when resolving/closing if resolution fields are missing. However, it does not explicitly contrast with alternatives like create_incident or query_incidents.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.1.0- First observed
create_incident - First observed
query_incidents - First observed
update_incident
TDQS
Scored across 3 tools
Each tool targets a distinct operation: create, query (list/search), and update. There is no overlap in purpose; an agent can clearly differentiate when to use each.
All tools follow a consistent verb_noun pattern using snake_case (create_incident, query_incidents, update_incident), with plural nouns for collection queries and singular for single-item operations, which is predictable.
With 3 tools, the set is minimal but covers the core incident lifecycle (create, read/search, update). It is slightly thin—missing a dedicated get_incident or delete_incident—but still well-scoped for a focused incident-only server.
The tools cover create, list/search, and update, but lack an explicit 'get by ID' tool (though query_incidents can filter by number) and a delete/close operation. The update tool warns about missing resolution fields for closing, indicating gaps in full lifecycle support.
Maintenance
Related MCP Connectors
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
MCP server for OpenAI API (chat completions, image generation, embeddings) via AceDataCloud
MCP server for AI dialogue using various LLM models via AceDataCloud
MCP server that lets AI assistants use all OneSchema features exposed via the public API.
Related MCP Servers
- FlicenseAqualityDmaintenanceA production-ready MCP server that turns any MCP-compatible AI assistant into an AI-powered ServiceNow Incident Management Assistant, exposing incidents, users, CMDB records, and knowledge articles through validated tools.12-
- AlicenseNot gradedqualityCmaintenanceA lightweight MCP server that gives AI coding assistants full development capability on ServiceNow through the Table API, enabling CRUD and script execution without local installation.6 npmMIT
- FlicenseNot gradedqualityCmaintenanceMCP server that enables LLMs to interact with ServiceNow instances for managing incidents, users, stories, workflows, knowledge base articles, and script includes via the FastMCP framework.-
- AlicenseAqualityDmaintenanceAn MCP server for interacting with a ServiceNow instance via its Table API, enabling CRUD operations on incident, request, and requested item tables, as well as generic operations on any table by name.22MIT