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.
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.
Quick start
You need Node.js 20+ and a ServiceNow instance you can reach (a free Personal Developer Instance works great).
1 · Register the server with your MCP client
Point the server command at npx — no clone required.
For Claude Desktop, add this to your
claude_desktop_config.json; for VS Code use
.vscode/mcp.json.
{
"mcpServers": {
"servicenow": {
"command": "npx",
"args": ["-y", "servicenow-mcp-ai"]
}
}
}
Where that file lives:
-
Claude Desktop —
~/Library/Application Support/Claude/claude_desktop_config.json(macOS) ·%APPDATA%\Claude\claude_desktop_config.json(Windows). -
Claude Code (CLI) —
claude mcp add servicenow -- npx -y servicenow-mcp-ai. -
VS Code — a
.vscode/mcp.jsonin your workspace.
2 · Give it credentials
Create a .env file (the server also reads
~/.config/servicenow-mcp-ai/.env and real environment
variables, which take precedence):
SN_INSTANCE=your-instance.service-now.com
SN_USER=your.username@example.com
SN_PASSWORD=your-password
SN_INSTANCE accepts dev12345,
dev12345.service-now.com or a full
https:// URL. You can also set or rotate credentials at
runtime by asking the assistant to use
servicenow_set_credentials.
3 · 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. Want to verify the
connection first? Ask it to run
servicenow_test_connection.
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.
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_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,docs,instance,email.
# 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
65 tools across 18 packages. read tools never mutate the instance; write tools respect the read-only and policy guards.
table — record CRUD
| Tool | Access | Description |
|---|---|---|
servicenow_query_table | read | Read records from any table (encoded queries, fields, paging, fetchAll). |
servicenow_get_record | read | Read a single record by sys_id. |
servicenow_create_record | write | Create a record with the given field values. |
servicenow_update_record | write | Update fields on a record by sys_id. |
servicenow_delete_record | write | Delete a record by sys_id. |
schema — metadata
| Tool | Access | Description |
|---|---|---|
servicenow_list_tables | read | List tables from sys_db_object, optionally filtered. |
servicenow_describe_table | read | A table's columns from sys_dictionary, incl. the inherited super_class chain. |
aggregate · attachment · importset · batch
| Tool | Access | Description |
|---|---|---|
servicenow_aggregate | read | Server-side count/avg/min/max/sum + group_by/having via the Stats API. |
servicenow_list_attachments | read | List attachment metadata, optionally scoped to a record. |
servicenow_get_attachment | read | Read one attachment's metadata by sys_id. |
servicenow_download_attachment | read | Download bytes as base64 (size-guarded). |
servicenow_upload_attachment | write | Attach a base64 file to a record. |
servicenow_delete_attachment | write | Delete an attachment by sys_id. |
servicenow_insert_import_set_row | write | Insert a staging row and run its transform map. |
servicenow_get_import_set_row | read | Read the transform outcome for a staging row. |
servicenow_batch | write | Several REST sub-requests in one round-trip; policy per sub-request. |
cmdb — class-aware CIs (IRE)
| Tool | Access | Description |
|---|---|---|
servicenow_list_cis | read | List CIs of a CMDB class via the Instance API. |
servicenow_get_ci | read | A CI with attributes and relations. |
servicenow_create_ci | write | Create a CI through Identification & Reconciliation. |
servicenow_update_ci | write | Update a CI's attributes via IRE. |
servicenow_get_cmdb_meta | read | A CMDB class's schema/relationship rules. |
catalog · change · knowledge · email — plugin APIs
| Tool | Access | Description |
|---|---|---|
servicenow_list_catalogs | read | List Service Catalogs. |
servicenow_list_catalog_categories | read | Categories within a catalog. |
servicenow_list_catalog_items | read | Search/list orderable items. |
servicenow_get_catalog_item | read | An item with its order variables. |
servicenow_order_catalog_item | write | Order an item ("order now"). |
servicenow_list_changes | read | List change requests. |
servicenow_get_change | read | A change request by sys_id. |
servicenow_create_change | write | Create a normal/standard/emergency change. |
servicenow_update_change | write | Update a change request. |
servicenow_change_conflicts | write | Read or recalculate schedule conflicts. |
servicenow_search_knowledge | read | Full-text knowledge article search. |
servicenow_get_knowledge_article | read | An article's content + metadata. |
servicenow_knowledge_highlights | read | Featured / most-viewed articles. |
servicenow_send_email | write | Send an email via the Email API. |
servicenow_get_email | read | Read an email record by sys_id. |
scripts — code intelligence (read-only)
| Tool | Access | Description |
|---|---|---|
servicenow_list_scripts | read | List artefacts of one type as compact metadata (no source). |
servicenow_get_script | read | One artefact in full, with source and context. |
servicenow_search_code | read | Search script source for a substring across types. |
servicenow_table_logic | read | A table's whole automation: BRs (by when+order), client scripts, UI policies/actions, ACLs. |
flows — flow intelligence (read-only)
| Tool | Access | Description |
|---|---|---|
servicenow_trace_table_event | read | Deterministic, ordered trace of what an operation runs (BRs by phase, flows, workflows, notifications) + a Mermaid flowchart. |
servicenow_list_flows | read | Flow Designer flows (or legacy workflows) as metadata. |
servicenow_get_flow | read | A flow's trigger + ordered steps (structured view). |
servicenow_get_flow_runs | read | Flow execution history by flow or by record. |
codecheck — local code analysis
| Tool | Access | Description |
|---|---|---|
servicenow_lint_script | read | Run deterministic rules over one script (hard-coded ids/URLs, unbounded/in-loop queries, eval, …). |
servicenow_lint_table | read | Lint every active BR / client script / UI policy of a table. |
servicenow_code_health | write | Script inventory + lint summary → a Markdown report in the docs folder. |
docs · instance — documentation & environments
| Tool | Access | Description |
|---|---|---|
servicenow_docs_list | read | List local Markdown docs (SN_DOCS_DIR). |
servicenow_docs_read | read | Read one local Markdown doc. |
servicenow_docs_search | read | Search the local docs for a substring. |
servicenow_docs_write | write | Write/overwrite a local doc; refresh index.md. |
servicenow_generate_er_diagram | read | Mermaid erDiagram from sys_dictionary references. |
servicenow_generate_table_flow | read | Mermaid flowchart of a record lifecycle by BR phase. |
servicenow_snapshot_instance | write | Dump structural metadata (tables/schema/plugins/apps/automation) into the docs folder. |
servicenow_compare_instances | write | Diff two profiles: tables, columns, scripts (by SHA-256), plugins/apps. |
atf — Automated Test Framework (opt-in, non-default)
| Tool | Access | Description |
|---|---|---|
servicenow_list_atf_tests | read | List ATF tests (sys_atf_test). |
servicenow_list_atf_suites | read | List ATF test suites. |
servicenow_run_atf_test | write | Run a test via the CI/CD API — executes on the instance. |
servicenow_run_atf_suite | write | Run a suite via the CI/CD API — executes on the instance. |
servicenow_get_atf_result | read | Poll a run's status / progress by execution id. |
admin — always on
| Tool | Access | Description |
|---|---|---|
servicenow_set_credentials | write | Save/update connection credentials (per profile). |
servicenow_list_instances | read | List configured profiles (no passwords). |
servicenow_use_instance | write | Switch the active profile; clear identity caches. |
servicenow_get_status | read | Instance, user, auth mode, policy, telemetry. |
servicenow_test_connection | read | Verify credentials actually work (reads 1 sys_user). |
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.
🔁 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.
🧭 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.
📚 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).
🔎 "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."
🛒 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.
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
Does the AI run code on my instance?
No. There is no background-script execution. Everything goes through documented REST APIs, and writes obey the policy and read-only guards. Automated test execution (ATF) over the official CI/CD API is a planned future addition.
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
LeassTaTT/servicenow-mcp. 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.