npm install -g servicenow-mcp-ai
Drive ServiceNow from your AI assistant.
servicenow-mcp-ai is an MCP server that turns any MCP-capable AI client — Claude Desktop, Claude Code, VS Code Chat — into a ServiceNow power user. It reads and writes across the full REST surface, understands the instance's own code, and keeps least-privilege guardrails between the model and your data.
Three things the platform makes hard.
One call each — all read-only, against any instance (a free PDI included). The IDE-grade answers ServiceNow has no button for.
Find usages, instance-wide.
Every script, business rule, client script, UI policy/action and ACL that touches a field — as JSON or a Mermaid graph. The IDE-grade find usages ServiceNow has no button for.
readservicenow_where_used
{ "kind": "field", "name": "u_cost_center", "mermaid": true }
Trace the automation chain.
The full chain in execution order — display → before → after → async business rules, then flows, workflows and notifications — each with its condition. A logical test that runs nothing.
readservicenow_trace_table_event
{ "table": "incident", "operation": "update" }
Diff two instances.
A Markdown diff of tables, columns, scripts (by SHA-256) and plugins between two configured profiles, with a CI-friendly exit code so a pipeline can block a risky deploy.
readservicenow-mcp-ai drift
servicenow-mcp-ai drift dev prod
What is this, exactly?
The Model Context Protocol (MCP) is an open standard that lets an AI assistant call external tools and read external resources. This project is an MCP server for ServiceNow: you register it with your MCP client once, and from then on the assistant can run real actions against your instance — query a table, create a change, inspect a business rule, compare two environments — instead of just talking about them.
You never call the tools by hand. You talk to your AI assistant in
natural language; it picks the right
servicenow_* tool, fills in the arguments, and shows
you the result. The server's job is to make that safe and
accurate.
Capabilities
Breadth of the platform, plus three things a generic CRUD connector doesn't give you.
Full REST surface
Table (CRUD + encoded queries + pagination), Aggregate, Attachment, Import Set, Batch, CMDB/IRE, plus the Catalog, Change, Knowledge and Email plugin APIs.
Script intelligence
Read and search the instance's own code — business rules, script includes, client scripts, UI policies/actions, ACLs — and get a table's full automation picture. Read-only.
Flow & code checking
Trace what a table operation would run (ordered, with a Mermaid flowchart), read Flow Designer flows and run history, lint scripts against a local rule set, and run ATF tests via the CI/CD API.
Multi-instance
Named profiles (dev / test / prod) with per-call routing,
per-profile policy, plus snapshot_instance and
compare_instances to catch environment drift.
Self-documentation
A local Markdown knowledge base and deterministic Mermaid generators (ER diagrams, record-lifecycle flowcharts) so the assistant builds durable, reusable context.
Governance by design
Two-axis policy (tables + packages), global read-only mode, SSRF guard, host allow-list, and an elicitation confirm before credentials change.
Resilience
Per-request timeout, retry with backoff and
Retry-After, a concurrency semaphore, schema
caching, and a result-size guard against oversized payloads.
Connected in under a minute.
Install once, point it at your instance, and add it to any MCP client. You need Node.js 20+ and a ServiceNow instance you can reach (a free Personal Developer Instance works great).
export SN_INSTANCE=dev12345.service-now.com
export SN_USER=admin
export SN_PASSWORD=••••••
servicenow_test_connection
{
"mcpServers": {
"servicenow": {
"command": "servicenow-mcp-ai"
}
}
}
SN_INSTANCE accepts dev12345,
dev12345.service-now.com or a full https://
URL. Credentials can also live in a .env file
(~/.config/servicenow-mcp-ai/.env or the project root)
and be rotated at runtime via
servicenow_set_credentials. Step 3 isn't a shell
command — it's the servicenow_test_connection tool; ask
your assistant to call it once the server is wired up.
Don't want a global install? Use
"command": "npx", "args": ["-y", "servicenow-mcp-ai"]
instead. On the Claude Code CLI it's a one-liner:
claude mcp add servicenow -- npx -y servicenow-mcp-ai.
Talk to your assistant
That's it. Try something like:
The assistant calls servicenow_query_table with the
right encoded query and returns the rows.
First time? Start safe. Set
SN_READONLY=true so the assistant can read and explore
but never writes, and keep the default
SN_TOOL_PACKAGES=core to expose a small tool set.
Loosen both once you trust the workflow.
Developing from source instead?
npm install && npm run build, then
npm run inspector to drive it from the MCP Inspector,
or npm start to run it directly.
Credentials & where they live
The env file is resolved in this order:
SN_ENV_FILE— an explicit path, if set.-
~/.config/servicenow-mcp-ai/.env(XDG) — if it exists. A global /npxinstall writes here, not intonode_modules. - The project-root
.env(local development).
Real environment variables always win over the file. The file is
written owner-only (0600) because it
holds a plaintext password, and it is git-ignored — never commit real
credentials.
The password / token is never logged and never
returned by any tool. servicenow_get_status reports
only whether a password is set.
Authentication
Basic auth works out of the box from the three required variables. For OAuth the recommended path is OAuth 2.1 — Authorization Code + PKCE via a one-time interactive login (no password is ever stored):
# 1) Register an "Authorization Code" OAuth endpoint in ServiceNow with a
# loopback redirect, e.g. http://localhost:53682/callback
# 2) Set the client id (and secret for a confidential client):
SN_OAUTH_CLIENT_ID=your-client-id
SN_OAUTH_CLIENT_SECRET=your-client-secret
# 3) Log in once — opens the browser, captures the redirect, stores a refresh token:
npx servicenow-mcp-ai login
PKCE (S256) is always used, the loopback listener captures the
redirect automatically, and the obtained refresh token
is persisted — the server then runs non-interactively
(refresh_token grant). The OAuth 2.0
password grant (ROPC) is deprecated and disabled on
many instances; client_credentials and
refresh_token remain available for service accounts.
Tokens are cached per host until just before expiry and are dropped
automatically on a credential change or a server-side
401 (one transparent re-auth, then a real error). With
named profiles you can even mix modes — prod on OAuth,
dev on Basic — via the
SN_PROFILE_<NAME>_AUTH /
_OAUTH_* keys.
Every method ServiceNow supports
| Method | SN_AUTH | How |
|---|---|---|
| Basic | basic | SN_USER / SN_PASSWORD (default). |
| OAuth 2.1 — Auth Code + PKCE | oauth | login (recommended). |
| OAuth — Client Credentials | oauth | SN_OAUTH_GRANT=client_credentials. |
| OAuth — Refresh Token | oauth | refresh_token + SN_OAUTH_REFRESH_TOKEN. |
| OAuth — JWT Bearer | oauth | jwt_bearer + SN_OAUTH_JWT_KEY (RS256). |
| OAuth — Password (ROPC) | oauth | password — deprecated. |
| API Key | apikey | SN_API_KEY → x-sn-apikey. |
| Bearer token | token | SN_BEARER_TOKEN, used verbatim. |
| Mutual TLS (client cert) | none | SN_TLS_CLIENT_CERT / _KEY (optional undici). |
Multiple instances (dev + prod)
Define a profile per environment. A great default is a read-only prod and a full-access dev in one server:
# dev — full access (the default profile)
SN_PROFILE_DEV_INSTANCE=dev12345.service-now.com
SN_PROFILE_DEV_USER=admin
SN_PROFILE_DEV_PASSWORD=••••••
# prod — read-only
SN_PROFILE_PROD_INSTANCE=acme.service-now.com
SN_PROFILE_PROD_USER=svc.readonly
SN_PROFILE_PROD_PASSWORD=••••••
SN_PROFILE_PROD_READONLY=true
SN_ACTIVE_PROFILE=dev
Switch the active one with servicenow_use_instance, or
target a single call by passing the automatic
instance argument — every tool accepts it.
Command-line interface
The published servicenow-mcp-ai binary — run it directly
or via npx servicenow-mcp-ai — has three invocations. All
connection settings come from environment variables (see
Environment variables); only
drift takes positional arguments.
| Command | Positional parameters | What it does | Exit codes |
|---|---|---|---|
servicenow-mcp-ai |
none | Starts the MCP server; the transport (stdio default, or http) is chosen by SN_TRANSPORT. Runs until SIGINT/SIGTERM. |
0 clean shutdown · 1 fatal startup error |
servicenow-mcp-ai login |
none — the active profile | One-time OAuth 2.1 Authorization Code + PKCE login: opens the browser, captures the loopback redirect, stores a refresh token. | 0 success · 1 login failed |
servicenow-mcp-ai drift <profileA> <profileB> |
two configured profile names | DF-3 CI drift gate: compares the two instances and writes a Markdown diff report to stdout. | 0 no drift · 1 drift found · 2 usage / error |
login — interactive OAuth
Operates on the active profile (SN_ACTIVE_PROFILE,
default default) and reads, for that profile:
SN_INSTANCE— required; the target instance.SN_OAUTH_CLIENT_ID— required; client id of an Authorization Code OAuth API endpoint.SN_OAUTH_CLIENT_SECRET— optional; for a confidential client.SN_OAUTH_REDIRECT_URI— optional; loopback URL, defaulthttp://localhost:53682/callback. Must match the redirect registered on the endpoint.SN_OAUTH_SCOPE— optional; requested OAuth scope.
On success it writes SN_AUTH=oauth,
SN_OAUTH_GRANT=refresh_token and
SN_OAUTH_REFRESH_TOKEN back to the env file
(profile-prefixed when the profile is not default). The
authorization URL is printed on stderr in case the browser does not
open automatically.
npx servicenow-mcp-ai login
drift — CI drift gate (DF-3)
Takes two positional profile names; each must resolve to a configured
profile (SN_PROFILE_<NAME>_*, or the bare
SN_INSTANCE / SN_USER /
SN_PASSWORD keys for default). The Markdown
report goes to stdout (capture it as a CI artifact); a
one-line drift summary goes to stderr — so a pipeline can block a
deploy on configuration drift.
servicenow-mcp-ai drift dev prod # report on stdout; exit 1 on drift, 0 if clean, 2 on error
Environment variables
Only the first three are required; the rest are optional tuning knobs. See .env.example for a template.
| Variable | Default | Description |
|---|---|---|
SN_INSTANCE * |
— | Instance name, host, or https:// URL. |
SN_USER * |
— | ServiceNow username for Basic auth. |
SN_PASSWORD * |
— | Password. Never logged or returned. |
SN_TIMEOUT_MS |
30000 |
Per-request timeout (ms). |
SN_MAX_RETRIES |
2 |
Retries for transient failures (429/5xx, network). Writes retried only on connect errors. |
SN_MAX_RECORDS |
10000 |
Hard cap on a fetchAll query. |
SN_MAX_RESULT_CHARS |
100000 |
Character budget before a result is truncated. |
SN_ALLOWED_HOSTS |
— |
Allow-list of hosts. Unset → only
*.service-now.com is reachable (SSRF guard).
|
SN_AUTH |
auto | basic or oauth. |
SN_OAUTH_CLIENT_ID |
— | OAuth client id (its presence enables OAuth). |
SN_OAUTH_CLIENT_SECRET |
— | OAuth client secret. |
SN_OAUTH_GRANT |
password |
password · client_credentials · refresh_token. |
SN_OAUTH_REFRESH_TOKEN |
— | Required only for the refresh_token grant. |
SN_TABLES_ALLOW |
— | Allowlist; when set, only these tables are reachable. |
SN_TABLES_DENY |
— | Denylist; always wins over the allowlist. |
SN_READONLY |
false |
When truthy, refuse every create/update/delete. |
SN_WRITE_MODE |
plan |
plan (default) previews a write as a
before/after diff without mutating;
apply executes. A tool's
apply:true forces one call.
|
SN_LOG_LEVEL |
info |
error · warn · info · debug (stderr). |
SN_ENV_FILE |
— | Explicit path to the env file. |
SN_TOOL_PACKAGES |
core |
Packages/profiles to enable (see below). |
SN_PACKAGES_DENY |
— | Drop whole packages — the only way to block plugin APIs. |
SN_PACKAGES_READONLY |
— | Register only a package's read tools. |
SN_SCHEMA_CACHE_TTL_SEC |
300 |
TTL for the schema-read cache. 0 disables. |
SN_MAX_CONCURRENT |
4 |
Max parallel HTTP requests to the instance. |
SN_INCLUDE_REF_LINKS |
false |
Include reference-field link URLs (token cost). |
SN_RESULT_PRETTY |
false |
Pretty-print results (≈2× tokens). |
SN_DOCS_DIR |
docs/instance |
Where the docs package reads/writes Markdown. |
SN_CODESEARCH |
false |
Use the Code Search API for search_code when
true (FT-7); falls back to the LIKE search.
|
SN_PROFILE_<NAME>_* |
— |
Named profiles: SN_PROFILE_DEV_INSTANCE /
_USER / _PASSWORD (+ optional
_AUTH / _OAUTH_* / _READONLY /
_TABLES_*).
|
SN_ACTIVE_PROFILE |
default |
Which profile tools use; switch with servicenow_use_instance. |
* required.
Tool packages
Tools are grouped into packages so you expose only what a given
client needs — fewer tools keep the model focused. Set
SN_TOOL_PACKAGES to a comma/space-separated list of
profiles or package names:
-
core(default) —table,schema,aggregate,attachment. all— every package.-
Individual:
table,schema,aggregate,attachment,importset,batch,catalog,change,knowledge,cmdb,scripts,flows,codecheck,docs,instance,email,atf.
# Only table + batch tools (the admin tools are always on)
SN_TOOL_PACKAGES=table,batch
The admin tools are always registered regardless of packages.
Unknown names are ignored, and
servicenow_get_status reports the resolved
enabledPackages.
Tools reference
67 tools across 18 packages. read tools never mutate the instance; write tools respect the read-only and policy guards. Click any tool to expand its full parameter list — name, type, whether it is required and any allowed values.
No tools match that search.
table
servicenow_query_table readRead records from any ServiceNow table through the Table API. Supports encoded queries, field selection and pagination.
| Parameter | Type | Notes | |
|---|---|---|---|
table | string | required | Table name, e.g. 'incident', 'sys_user', 'change_request'. |
query | string | optional | |
fields | array | optional | |
limit | number | optional | |
offset | number | optional | |
displayValue | enum | optional | one of: true · false · all |
fetchAll | boolean | optional |
servicenow_get_record readRead a single record from a table by its sys_id.
| Parameter | Type | Notes | |
|---|---|---|---|
table | string | required | Table name, e.g. 'incident'. |
sys_id | string | required | The sys_id of the record to read. |
fields | array | optional |
servicenow_create_record writeCreate a new record in a table with the given field values.
| Parameter | Type | Notes | |
|---|---|---|---|
table | string | required | Table name, e.g. 'incident'. |
fields | object | required | Field name/value pairs for the new record, e.g. { "short_description": "Printer down", "urgency": "2" }. |
servicenow_update_record writeUpdate fields on an existing record identified by its sys_id.
| Parameter | Type | Notes | |
|---|---|---|---|
table | string | required | Table name, e.g. 'incident'. |
sys_id | string | required | The sys_id of the record to update. |
fields | object | required | Field name/value pairs to change on the record. |
servicenow_delete_record writeDelete a record from a table by its sys_id.
| Parameter | Type | Notes | |
|---|---|---|---|
table | string | required | Table name, e.g. 'incident'. |
sys_id | string | required | The sys_id of the record to delete. |
schema
servicenow_list_tables readList tables from sys_db_object, optionally filtered by a name or label fragment.
| Parameter | Type | Notes | |
|---|---|---|---|
filter | string | optional |
servicenow_describe_table readList a table's columns (name, label, type, mandatory, reference) from sys_dictionary.
| Parameter | Type | Notes | |
|---|---|---|---|
table | string | required | Table name to describe, e.g. 'incident'. |
aggregate
servicenow_aggregate readCompute server-side aggregates (count, avg, min, max, sum) over a table via the Stats API, with optional grouping. Avoids pulling individual rows.
| Parameter | Type | Notes | |
|---|---|---|---|
table | string | required | Table name, e.g. 'incident'. |
query | string | optional | |
count | boolean | optional | |
avg_fields | array | optional | |
min_fields | array | optional | |
max_fields | array | optional | |
sum_fields | array | optional | |
group_by | array | optional | |
having | string | optional |
attachment
servicenow_list_attachments readList attachment metadata, optionally scoped to a specific record (table + sys_id).
| Parameter | Type | Notes | |
|---|---|---|---|
table | string | optional | |
sys_id | string | optional |
servicenow_get_attachment readRead a single attachment's metadata by its sys_id.
| Parameter | Type | Notes | |
|---|---|---|---|
attachment_sys_id | string | required | The sys_id of the attachment record. |
servicenow_download_attachment readDownload an attachment's bytes, returned as base64. Large files are refused (see SN_MAX_RESULT_CHARS).
| Parameter | Type | Notes | |
|---|---|---|---|
attachment_sys_id | string | required | The sys_id of the attachment to download. |
servicenow_upload_attachment writeAttach a file (provided as base64) to a record identified by table + sys_id.
| Parameter | Type | Notes | |
|---|---|---|---|
table | string | required | Table the record belongs to. |
sys_id | string | required | sys_id of the record to attach to. |
file_name | string | required | File name to store, e.g. 'log.txt'. |
content_base64 | string | required | File contents, base64-encoded. |
content_type | string | optional |
servicenow_delete_attachment writeDelete an attachment by its sys_id.
| Parameter | Type | Notes | |
|---|---|---|---|
attachment_sys_id | string | required | The sys_id of the attachment to delete. |
importset
servicenow_insert_import_set_row writeInsert a single row into a staging table and run its transform map. Returns the transform result.
| Parameter | Type | Notes | |
|---|---|---|---|
staging_table | string | required | Import staging table, e.g. 'u_imp_incident'. |
fields | object | required | Column name/value pairs for the staging row. |
servicenow_get_import_set_row readRead the transform outcome for a previously inserted staging row by its sys_id.
| Parameter | Type | Notes | |
|---|---|---|---|
staging_table | string | required | Import staging table name. |
sys_id | string | required | sys_id of the staging row. |
batch
servicenow_batch writeExecute several ServiceNow REST sub-requests in a single HTTP round-trip via the Batch API. Each sub-request runs through the same read-only and table-access policy as a direct call.
| Parameter | Type | Notes | |
|---|---|---|---|
requests | array | required | The sub-requests to run together. |
catalog
servicenow_list_catalogs readList the Service Catalogs available on the instance (Service Catalog API).
No parameters.
servicenow_list_catalog_categories readList the categories within a service catalog.
| Parameter | Type | Notes | |
|---|---|---|---|
catalog_sys_id | string | required | sys_id of the catalog. |
servicenow_list_catalog_items readSearch/list orderable catalog items, optionally by text or category.
| Parameter | Type | Notes | |
|---|---|---|---|
text | string | optional | |
category | string | optional | |
limit | number | optional | |
offset | number | optional |
servicenow_get_catalog_item readGet a catalog item, including its order variables, by sys_id.
| Parameter | Type | Notes | |
|---|---|---|---|
item_sys_id | string | required | sys_id of the catalog item. |
servicenow_order_catalog_item writeOrder a catalog item directly ('order now'). Creates a request/RITM. Provide variable values keyed by their names.
| Parameter | Type | Notes | |
|---|---|---|---|
item_sys_id | string | required | sys_id of the catalog item. |
quantity | number | optional | |
variables | object | optional |
change
servicenow_list_changes readList change requests through the Change Management API. Supports an encoded query, field selection and paging.
| Parameter | Type | Notes | |
|---|---|---|---|
query | string | optional | |
fields | array | optional | |
limit | number | optional | |
offset | number | optional |
servicenow_get_change readGet a single change request by sys_id.
| Parameter | Type | Notes | |
|---|---|---|---|
sys_id | string | required | sys_id of the change request. |
servicenow_create_change writeCreate a normal, standard or emergency change. Standard changes require a template_id.
| Parameter | Type | Notes | |
|---|---|---|---|
type | enum | required | Change type. — one of: normal · standard · emergency |
template_id | string | optional | |
fields | object | optional | Change field name/value pairs, e.g. { "short_description": "Patch DB", "risk": "low" }. |
servicenow_update_change writeUpdate fields on a change request by sys_id.
| Parameter | Type | Notes | |
|---|---|---|---|
sys_id | string | required | sys_id of the change request. |
fields | object | required | Change field name/value pairs, e.g. { "short_description": "Patch DB", "risk": "low" }. |
servicenow_change_conflicts writeRead schedule conflicts for a change, or recalculate them (calculate=true). Recalculation is a write and is blocked in read-only mode.
| Parameter | Type | Notes | |
|---|---|---|---|
sys_id | string | required | sys_id of the change request. |
calculate | boolean | optional |
knowledge
servicenow_search_knowledge readFull-text search of knowledge articles (Knowledge API), with optional encoded query and paging.
| Parameter | Type | Notes | |
|---|---|---|---|
search | string | optional | |
query | string | optional | |
fields | array | optional | |
limit | number | optional | |
offset | number | optional |
servicenow_get_knowledge_article readGet a knowledge article (content and metadata) by sys_id.
| Parameter | Type | Notes | |
|---|---|---|---|
sys_id | string | required | sys_id of the knowledge article. |
servicenow_knowledge_highlights readList featured or most-viewed knowledge articles for the current user.
| Parameter | Type | Notes | |
|---|---|---|---|
mode | enum | required | Which highlight list to return. — one of: featured · most_viewed |
limit | number | optional |
cmdb
servicenow_list_cis readList configuration items of a CMDB class through the class-aware CMDB Instance API.
| Parameter | Type | Notes | |
|---|---|---|---|
class_name | string | required | CMDB class/table, e.g. 'cmdb_ci_server'. |
query | string | optional | |
limit | number | optional | |
offset | number | optional |
servicenow_get_ci readGet a CI with its attributes and inbound/outbound relations by class and sys_id.
| Parameter | Type | Notes | |
|---|---|---|---|
class_name | string | required | CMDB class, e.g. 'cmdb_ci_server'. |
sys_id | string | required | sys_id of the CI. |
servicenow_create_ci writeCreate a CI via the CMDB Instance API (routed through Identification & Reconciliation).
| Parameter | Type | Notes | |
|---|---|---|---|
class_name | string | required | CMDB class, e.g. 'cmdb_ci_server'. |
attributes | object | required | CI attribute name/value pairs. |
source | string | optional |
servicenow_update_ci writeUpdate a CI's attributes via the CMDB Instance API (IRE).
| Parameter | Type | Notes | |
|---|---|---|---|
class_name | string | required | CMDB class, e.g. 'cmdb_ci_server'. |
sys_id | string | required | sys_id of the CI. |
attributes | object | required | CI attribute name/value pairs. |
source | string | optional |
servicenow_get_cmdb_meta readGet the schema/metadata of a CMDB class (attributes, relationship rules) from the CMDB Meta API.
| Parameter | Type | Notes | |
|---|---|---|---|
class_name | string | required | CMDB class, e.g. 'cmdb_ci_server'. |
scripts
servicenow_list_scripts readList script artefacts of one type as compact metadata (no source code). Types: business_rule, script_include, client_script, ui_policy, ui_action, scheduled_job, transform, rest_operation, acl. Filter by applied table, name fragment, active flag, or a raw encoded query.
| Parameter | Type | Notes | |
|---|---|---|---|
type | enum | required | Script type. One of: business_rule, script_include, client_script, ui_policy, ui_action, scheduled_job, transform, rest_operation, acl. — one of: business_rule · script_include · client_script · ui_policy · ui_action · scheduled_job · transform · rest_operation · acl |
table | string | optional | |
name | string | optional | |
active | boolean | optional | |
query | string | optional | |
limit | number | optional | |
offset | number | optional |
servicenow_get_script readRead one script artefact in full, including its source code and execution context.
| Parameter | Type | Notes | |
|---|---|---|---|
type | enum | required | Script type. One of: business_rule, script_include, client_script, ui_policy, ui_action, scheduled_job, transform, rest_operation, acl. — one of: business_rule · script_include · client_script · ui_policy · ui_action · scheduled_job · transform · rest_operation · acl |
sys_id | string | required | sys_id of the script record. |
servicenow_search_code readSearch script source for a literal substring across one or all script types. Returns a short snippet per match (not whole scripts). Answers 'where is X used?'.
| Parameter | Type | Notes | |
|---|---|---|---|
text | string | required | Substring to search for in script source. |
type | enum | optional | one of: business_rule · script_include · client_script · ui_policy · ui_action · scheduled_job · transform · rest_operation · acl |
table | string | optional | |
limit | number | optional |
servicenow_table_logic readAssemble the automation that runs on a table: business rules (ordered by when+order), client scripts, UI policies, UI actions and ACLs. Metadata only.
| Parameter | Type | Notes | |
|---|---|---|---|
table | string | required | Table to analyse, e.g. 'incident'. |
servicenow_where_used readFind where a table, field or script is referenced across the instance's code: textual references in every script source, plus (for a table) the business rules, client scripts, UI policies/actions and ACLs attached to it. Read-only; optionally renders a Mermaid reference graph.
| Parameter | Type | Notes | |
|---|---|---|---|
kind | enum | required | What to look up: one of table · field · script. |
name | string | required | The table/field/script name to find usages of. |
mermaid | boolean | optional | Also render a Mermaid reference graph. |
flows
servicenow_trace_table_event readDeterministically trace what ServiceNow would run for a table operation, in execution order: display/before/after/async business rules, then flows, workflows and notifications — each with its condition, plus a Mermaid flowchart. A logical test without executing anything.
| Parameter | Type | Notes | |
|---|---|---|---|
table | string | required | Table to trace, e.g. 'incident'. |
operation | enum | required | The database operation to simulate. — one of: insert · update · delete · query |
servicenow_list_flows readList Flow Designer flows (sys_hub_flow) or legacy workflows (kind: 'workflow') as compact metadata. Filter by applied table, active flag or a name fragment.
| Parameter | Type | Notes | |
|---|---|---|---|
kind | enum | optional | one of: flow · workflow |
table | string | optional | |
active | boolean | optional | |
name | string | optional | |
limit | number | optional |
servicenow_get_flow readGet a structured view of one flow or workflow: its trigger (table/condition/when) and ordered steps. Not a full decompilation — enough to reason about the logic.
| Parameter | Type | Notes | |
|---|---|---|---|
sys_id | string | required | sys_id of the flow or workflow. |
kind | enum | optional | one of: flow · workflow |
servicenow_get_flow_runs readRead flow execution evidence from sys_flow_context — by flow sys_id or by the record (document) it ran against: when it started, its state and the outcome.
| Parameter | Type | Notes | |
|---|---|---|---|
flow | string | optional | |
record | string | optional | |
limit | number | optional |
codecheck
servicenow_lint_script readRun deterministic code-quality rules over one script artefact (hard-coded sys_ids/URLs, unbounded or in-loop GlideRecord queries, eval, gs.sleep, setWorkflow(false), client-side GlideRecord, sync getReference, …). Returns findings with rule, severity, line and a fix hint.
| Parameter | Type | Notes | |
|---|---|---|---|
type | enum | required | Script type. One of: business_rule, script_include, client_script, ui_policy, ui_action, scheduled_job, transform, rest_operation, acl. — one of: business_rule · script_include · client_script · ui_policy · ui_action · scheduled_job · transform · rest_operation · acl |
sys_id | string | required | sys_id of the script record. |
servicenow_lint_table readLint every active business rule, client script and UI policy of a table (via table_logic), returning per-script findings and a severity summary.
| Parameter | Type | Notes | |
|---|---|---|---|
table | string | required | Table to lint, e.g. 'incident'. |
servicenow_code_health writeAggregate code-health picture: script counts by type, and (when a table scope is given) the lint findings by severity with the top offenders. Writes a Markdown report to SN_DOCS_DIR/<profile>/code-health.md.
| Parameter | Type | Notes | |
|---|---|---|---|
scope | string | optional |
docs
servicenow_docs_list readList the Markdown documents in the local instance-documentation folder (SN_DOCS_DIR).
No parameters.
servicenow_docs_read readRead one Markdown document from the local instance-documentation folder.
| Parameter | Type | Notes | |
|---|---|---|---|
path | string | required | Document path relative to the docs folder, e.g. 'tables/incident.md'. |
servicenow_docs_search readSearch the local instance documentation for a substring; returns a snippet per match.
| Parameter | Type | Notes | |
|---|---|---|---|
text | string | required | Substring to search for across all documents. |
servicenow_docs_write writeCreate or overwrite a Markdown document in the local docs folder and refresh index.md. Use this to record durable knowledge (descriptions, Mermaid diagrams, instance quirks).
| Parameter | Type | Notes | |
|---|---|---|---|
path | string | required | Target document path relative to the docs folder, e.g. 'tables/incident.md'. |
content | string | required | Full Markdown content to write. |
servicenow_generate_er_diagram readBuild a Mermaid erDiagram from sys_dictionary: an entity per table plus a relationship for every reference field. Returns Mermaid markup ready to embed in Markdown.
| Parameter | Type | Notes | |
|---|---|---|---|
tables | array | required | Tables to include, e.g. ['incident', 'problem']. |
servicenow_generate_table_flow readBuild a Mermaid flowchart of a record's lifecycle on a table, grouping active business rules by phase (display/before/after/async) in execution order.
| Parameter | Type | Notes | |
|---|---|---|---|
table | string | required | Table to diagram, e.g. 'incident'. |
instance
servicenow_snapshot_instance writeDownload the instance's structural metadata into the local docs folder (SN_DOCS_DIR/<profile>/): tables.md+json, schema/<table>.md for the given tables, plugins, installed apps and script-automation statistics, plus an index.md. Markdown is for humans/LLMs, the JSON companions feed instance comparison. Idempotent: re-running overwrites the previous snapshot of the same profile.
| Parameter | Type | Notes | |
|---|---|---|---|
tables | array | optional |
servicenow_compare_instances writeDiff two connection profiles: tables present in only one, common columns whose type/mandatory/reference differ, scripts (per type+name) missing or with different source (compared by SHA-256, always live), and plugin/app inventory differences. Writes a Markdown report to _compare/<a>-vs-<b>.md in the docs folder and returns the structured summary. With from_snapshot, tables/plugins/apps are read from the profiles' stored snapshots when available.
| Parameter | Type | Notes | |
|---|---|---|---|
a | string | required | First connection profile, e.g. 'dev'. |
b | string | required | Second connection profile, e.g. 'prod'. |
from_snapshot | boolean | optional |
servicenow_send_email writeSend an email through the instance's Email API, optionally associated with a record (table + sys_id). Requires the Email API plugin to be active.
| Parameter | Type | Notes | |
|---|---|---|---|
to | array | required | Recipient email addresses. |
subject | string | required | Email subject. |
body | string | required | Plain-text email body. |
cc | array | optional | |
bcc | array | optional | |
table | string | optional | |
sys_id | string | optional |
servicenow_get_email readRead a sent/received email record by its sys_id (Email API).
| Parameter | Type | Notes | |
|---|---|---|---|
sys_id | string | required | sys_id of the email record. |
atf
servicenow_list_atf_tests readList Automated Test Framework tests (sys_atf_test) as metadata: name, active flag, description.
| Parameter | Type | Notes | |
|---|---|---|---|
active | boolean | optional | |
query | string | optional | |
limit | number | optional |
servicenow_list_atf_suites readList Automated Test Framework test suites (sys_atf_test_suite) as metadata.
| Parameter | Type | Notes | |
|---|---|---|---|
active | boolean | optional | |
query | string | optional | |
limit | number | optional |
servicenow_run_atf_test writeRun a single ATF test through the CI/CD API. EXECUTES CODE on the instance — use only on a non-production instance with the sn_cicd plugin active. Returns an execution id to poll with servicenow_get_atf_result.
| Parameter | Type | Notes | |
|---|---|---|---|
test_sys_id | string | required | sys_id of the ATF test (sys_atf_test). |
servicenow_run_atf_suite writeRun an ATF test suite through the CI/CD API. EXECUTES CODE on the instance. Returns an execution id to poll with servicenow_get_atf_result.
| Parameter | Type | Notes | |
|---|---|---|---|
suite_sys_id | string | required | sys_id of the ATF test suite (sys_atf_test_suite). |
servicenow_get_atf_result readPoll an ATF run by its execution id: status, percent complete and message (CI/CD progress API).
| Parameter | Type | Notes | |
|---|---|---|---|
execution_id | string | required | The execution/progress id returned by a run tool. |
admin
servicenow_set_credentials writeSave or update the ServiceNow connection credentials. Values are persisted to the env file and used for all subsequent requests. Provide any subset of fields.
| Parameter | Type | Notes | |
|---|---|---|---|
instance | string | optional | |
user | string | optional | |
password | string | optional | |
profile | string | optional |
servicenow_list_instances readList the configured ServiceNow connection profiles (instances): name, host, user, read-only flag and whether credentials are complete. Passwords are never included.
No parameters.
servicenow_use_instance writeSwitch the active ServiceNow connection profile (persisted to the env file). All identity-scoped caches (OAuth tokens, schema, plugin availability) are cleared.
| Parameter | Type | Notes | |
|---|---|---|---|
name | string | required | Profile to activate, e.g. 'default' or 'dev'. |
servicenow_get_status readShow the configured instance, user, auth mode and access policy, and whether credentials are complete. The password is never revealed.
No parameters.
servicenow_test_connection readVerify that the configured credentials actually work: reads one sys_user record and reports ok/status/latency. Auth and connectivity problems are returned structurally (ok:false), not as errors.
No parameters.
servicenow_check_capabilities readPreflight which admin-restricted sys_* tables the connected user can actually read, and report which higher-level capabilities (schema reads, script intelligence, ACL audit) are achievable. Run this before relying on the scripts/flows/codecheck tools on a governed instance — on a least-privilege account those reads may be silently empty.
No parameters.
Use cases
What you'd actually ask your assistant to do. Each example is plain English — the server maps it to the right tools.
🚨 Incident triage
Summarise an incident, sanity-check its priority/urgency/impact,
suggest a category and assignment group, find similar resolved
incidents and recommend next steps — in one shot via the built-in
servicenow_incident_triage prompt.
servicenow_get_record
→ servicenow_query_table
→
servicenow_search_knowledge
🔁 Change impact analysis
Pull a change, identify affected CIs, check schedule conflicts,
list overlapping changes in the same window and produce a go/no-go
call with mitigations — the
servicenow_change_impact_analysis prompt.
servicenow_get_change
→ servicenow_change_conflicts
→ servicenow_list_changes
🧭 Catch dev → prod drift
Configure two profiles and let
servicenow_compare_instances diff them: tables present
in only one, columns whose type/mandatory/reference differ, scripts
that are missing or changed (compared by SHA-256), and plugin/app
inventory. It writes a Markdown report you can attach to a release.
servicenow_list_instances →
servicenow_compare_instances
📚 Document a table
Combine schema, automation and diagrams into a durable Markdown
page saved to the local docs store — via the
servicenow_document_table prompt (uses
describe_table, table_logic and both
Mermaid generators).
servicenow_describe_table
→ servicenow_table_logic
→
servicenow_generate_er_diagram
→
servicenow_generate_table_flow
→ servicenow_docs_write
🔎 "Where is this used?"
Search the instance's own code for a function, table or API call
with servicenow_search_code, or get the full
automation picture for a table with
servicenow_table_logic — without opening Studio.
GlideRecordSecure."
servicenow_search_code
→ servicenow_table_logic
🛒 Order from the catalog
Browse catalogs and categories, inspect an item's variables, and place an order — the Service Catalog API, plugin-aware so it tells you clearly if the plugin isn't active.
servicenow_list_catalogs
→
servicenow_list_catalog_items
→ servicenow_get_catalog_item
→ servicenow_order_catalog_item
How it compares
ServiceNow now ships its own MCP Server Console — a governed, on-instance service for production AI agents. This project is a different tool for a different job: an external, self-run server for developers and consultants who need to understand and safely change an instance — any instance, with the model and client they choose.
| Dimension | servicenow-mcp-ai (this) | Official MCP Server Console |
|---|---|---|
| Where it runs | Locally, next to your MCP client | Remote, hosted on the instance |
| Requirements | Just credentials — any instance, incl. a free PDI | Paid Now Assist SKU + a recent release |
| AI model | Bring your own — any client, any model incl. local | Inside ServiceNow's governed AI layer |
| Cost | Free (MIT), plain REST calls | Metered via Assist currency |
| Surface | Raw REST breadth + script intelligence + cross-instance diff | Curated Now Assist skills, flows, scripted REST |
| Governance | Client-side policy, read-only, SSRF guard | Native ACLs + AI Control Tower (enterprise audit) |
Choose this when…
You're developing, consulting or exploring; you work against PDIs or many instances; you want code-level insight — what runs on save, where a field is used, dev↔prod drift — or you want your own model (cloud or local) at no licence cost.
Choose the official when…
You're running production enterprise agents that need native ACL enforcement, approval workflows, enterprise audit and metering, and vendor support for governed catalog/approval/playbook actions.
Not affiliated with ServiceNow, Inc. This is an independent, community-built project; “ServiceNow” is a trademark of ServiceNow, Inc., used here only to indicate compatibility.
Resources & prompts
MCP resources
Read-only metadata is also exposed as resources, so clients can attach it declaratively instead of calling a tool.
| URI | Description |
|---|---|
servicenow://status | Connection status, auth mode, access policy. |
servicenow://tables | Tables from sys_db_object. |
servicenow://schema/{table} | Columns of a table from sys_dictionary. |
servicenow://instances | Configured connection profiles (no passwords). |
servicenow://{profile}/schema/{table} | A table's schema read through a named profile. |
servicenow://docs/{path} | A Markdown document from the local docs store. |
Prompts
| Prompt | Argument | Purpose |
|---|---|---|
servicenow_incident_triage | incident | Summarise, assess priority, categorise, recommend. |
servicenow_change_impact_analysis | change | Affected CIs, conflicts, go/no-go. |
servicenow_document_table | table | Schema + automation + diagrams → saved Markdown. |
Security & governance
An AI with write access to ServiceNow is high-stakes by definition. The server is built to keep that safe and auditable.
Two-axis policy
SN_TABLES_ALLOW/_DENY guard the Table
API; SN_PACKAGES_DENY/_READONLY guard
the plugin APIs the table policy can't see. The Batch API obeys
both — a batch can't be used to bypass either.
Read-only deployments
SN_READONLY=true refuses every write globally;
per-package read-only registers only the read tools. Ideal for a
prod profile.
Host & SSRF guard
Without an allow-list, only *.service-now.com hosts
are contacted; internal/loopback are always blocked. A
redirected or mistyped host can't silently receive credentials.
Confirm before change
When the client supports it, a credential change asks for explicit confirmation (MCP elicitation) before anything is written.
Denying a table does not stop the plugin APIs.
SN_TABLES_DENY=change_request blocks the Table API
path, but the Change Management API (sn_chg_rest) can
still read/write changes. Use SN_PACKAGES_DENY or
SN_PACKAGES_READONLY to restrict the plugin-backed
surfaces.
Full details — including the reporting channel — are in SECURITY.md.
Architecture
A small, layered TypeScript codebase with one-way dependencies (enforced at lint time), so each concern stays testable in isolation. Each layer may use only the layers beneath it:
api → mcp
import fails the lint.
Tools are data: a declarative manifest drives MCP registration, the generated docs and the contract snapshot tests, so adding a package touches exactly one list. A single tool call then flows through the same guards every time:
Tools are data: a declarative manifest drives MCP
registration, the generated docs and the contract snapshot tests, so
adding a package touches exactly one list. Quality is enforced by a
single gate — npm run check (build, type-checked lint,
format, coverage-gated tests, prod audit) — and a CI matrix across
Node 20/22/24 + macOS. See
ARCHITECTURE.md
for the diagrams and ADRs.
Troubleshooting
Errors come back structured (with an HTTP status), so your assistant can usually explain them — but here are the common ones and their fix.
| Symptom | Likely cause | Fix |
|---|---|---|
401 Unauthorized |
Wrong username/password, or an expired OAuth token. |
Re-check SN_USER/SN_PASSWORD; run
servicenow_test_connection. Update with
servicenow_set_credentials.
|
403 Forbidden |
A ServiceNow ACL, or the table is blocked by
SN_TABLES_DENY / not in
SN_TABLES_ALLOW, or read-only mode.
|
Check the user's roles; review the policy in
servicenow_get_status; relax the allow/deny
list or SN_READONLY.
|
| "…API/plugin may not be active" | A plugin-scoped API (Catalog/Change/Knowledge/Email) is not installed on the instance. |
Activate the plugin in ServiceNow, or remove that package
from SN_TOOL_PACKAGES.
|
"not a *.service-now.com instance" |
A custom or sovereign-cloud host, blocked by the SSRF guard. |
Add it to SN_ALLOWED_HOSTS (comma-separated).
|
| A tool is missing from the client | Its package isn't enabled, or it's a write tool in a read-only package. |
Add the package to SN_TOOL_PACKAGES (or use
all); check
enabledPackages in
servicenow_get_status.
|
Result says truncated |
The read hit SN_MAX_RECORDS or
SN_MAX_RESULT_CHARS.
|
Narrow the query / select fewer fields, or raise the cap. |
Set SN_LOG_LEVEL=debug for verbose
stderr logging (no secrets, no raw queries), and ask
for servicenow_get_status to see the live config,
policy and per-host telemetry.
FAQ
How is this different from ServiceNow's own MCP Server?
ServiceNow's MCP Server Console is a governed, on-instance service for production agents (paid Now Assist SKU, metered). This is an external, self-run server for developers and consultants: it works against any instance — incl. a free PDI — with the model and client you choose, at no licence cost, and adds code intelligence and cross-instance diffing the platform service doesn't. See How it compares.
Does the AI run code on my instance?
No arbitrary code execution. There is no background-script
evaluation; everything goes through documented REST APIs, and writes
obey the policy and read-only guards. The one exception is the
opt-in, non-default atf package, which runs your own
existing Automated Test Framework tests through the official CI/CD
API — it executes code on the instance by design, so it is meant for
non-production environments.
Why is the npm package servicenow-mcp-ai?
The unscoped servicenow-mcp name was already taken on
npm, so the package ships as servicenow-mcp-ai. The
GitHub repository is
IvanBBaev/servicenow-mcp-ai. The difference is cosmetic. This is an independent project, not
affiliated with or endorsed by ServiceNow, Inc.; "ServiceNow" is a
trademark of ServiceNow, Inc., used here only to indicate
compatibility.
Can I run prod and dev from one server?
Yes — that's what named profiles are for. Define
SN_PROFILE_PROD_* and SN_PROFILE_DEV_*,
make prod read-only, and route a single call to a specific instance
with the automatic instance argument, or switch the
active one with servicenow_use_instance.
Which clients work?
Any MCP client over stdio — Claude Desktop, Claude Code, VS Code Chat, the MCP Inspector, and others. The server declares tool annotations so clients can apply the right confirmation UX for destructive actions.
Is it production-ready?
The engineering is: clean gates, ~200 tests, type-checked lint, a CI matrix and a security model. It is an open-source project under the MIT license — review the security model for your own deployment.