@onlyflows/servicenow-mcp
This MCP server lets you operate ServiceNow instances from an AI client, covering CRUD, analytics, CMDB, attachments, logging, discovery, and testing through named profiles with deny-by-default table access.
Query records with filters, field selection, pagination, sorting, and display values (
sn_query)Fetch single records by sys_id (
sn_get)Create, update, and delete records on approved tables; delete and batch operations require explicit confirmation (
sn_create,sn_update,sn_delete,sn_batch)Run bulk update/delete with dry-run safety and a 10,000-record cap (
sn_batch)Perform aggregations: COUNT, AVG, MIN, MAX, SUM with grouping (
sn_aggregate)Inspect table schemas and field definitions (
sn_schema)Check instance health: version, cluster nodes, stuck jobs, and stats (
sn_health)List, download, and upload attachments using inline base64 — no host filesystem access (
sn_attach)Traverse CMDB CI relationships upstream, downstream, or both with configurable depth (
sn_relationships)Query system logs with severity, source, message, and time filters (
sn_syslog)Search code artifacts such as business rules, script includes, UI/client scripts, and REST operations (
sn_codesearch)Discover tables, applications, and plugins (
sn_discover)List and run ATF tests/suites and retrieve results (
sn_atf)Use natural language for queries and writes, with write/bulk operations gated by execute/confirm flags (
sn_nl)Execute background scripts, with destructive operations requiring confirmation and Playwright/admin requirements (
sn_script)
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@@onlyflows/servicenow-mcpshow me all critical incidents from last week"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
@onlyflows/servicenow-mcp
The most comprehensive ServiceNow MCP server. 19 tools for full CRUD, append-only incident journals, CMDB graph traversal, ATF testing, multi-instance profiles, and more.
Built by OnlyFlows · Published by @onlyflowstech
Installation
npm install -g @onlyflows/servicenow-mcp
servicenow-mcp-setupRun bare on a terminal, servicenow-mcp-setup walks you through the whole
thing in one command: it generates the local auth material, asks for your
instance and credential, verifies that credential against the instance,
asks which tables to grant, writes the profile, and registers any supported
client whose CLI is installed. The credential is entered at a hidden prompt —
never an argument, never shell history — and nothing is written to the profile
until the instance has accepted it, so a typo or a wrong password leaves
nothing behind.
ServiceNow MCP setup
This walks through one ServiceNow connection end to end. Nothing is
written to the profile until your credential is verified against the
instance. Press Ctrl+C at any point to stop; nothing will be saved.
Profile name [dev]: dev
ServiceNow instance (for example dev12345.service-now.com): dev12345.service-now.com
Authentication:
1) basic (default)
2) oauth
3) apikey
Choice [1]: 1
How should the credential be stored?:
1) encrypted (default)
2) reference
Choice [1]: 1
ServiceNow username: integration.user
Enter each secret now. Input is hidden — nothing you type from here
is displayed.
credential:
Verifying against the instance...
ok https://dev12345.service-now.com accepted the credential.
Table access is deny-by-default: a profile with no rules denies every
tool call. Grant the narrowest set that does the job; you can add more
later with servicenow-mcp-setup grant.
Tables to allow for READS:
1) Just incident (default)
2) Common ITSM set (incident,change_request,problem,task,sys_user)
3) All tables (*)
4) Enter a custom list
5) None
Choice [1]: 1
Tables to allow for WRITES:
1) Just incident
2) Common ITSM set (incident,change_request,problem,task,sys_user)
3) All tables (*)
4) Enter a custom list
5) None (default)
Choice [5]: 1
Wrote profile dev.
Register this server with codex and claude-code? [Y/n]: y
ServiceNow MCP doctor
ok node: v22.11.0
ok server command: servicenow-mcp resolves on PATH; clients spawn it over stdio
ok config directory: ~/.servicenow-mcp (0700)
ok profile dev: instance: https://dev12345.service-now.com
ok profile dev: credential: basic credential resolves from its encrypted source
ok profile dev: table access: 1 read, 1 write, 1 target(s)
All checks passed.
Setup complete.
Profile dev
Reads incident
Writes incident
Transport stdio (each client spawns its own servicenow-mcp)
Clients codex, claude-code
Start codex or claude-code and it will launch the server itself.
There is nothing to keep running between sessions.There is nothing to start. The server speaks stdio: each registered client
spawns its own copy of servicenow-mcp on demand and talks to it over that
process's stdin and stdout. Setup finishes by running the same checks doctor
runs, so you can re-run them any time:
servicenow-mcp-setup doctor --profile devnpx @onlyflows/servicenow-mcp@latest setup runs the same wizard without a
global install, and servicenow-mcp setup is an alias for
servicenow-mcp-setup.
Scripted setup
Pass any flag, or run without a terminal, and the wizard steps aside for the
original non-interactive behavior — so CI and provisioning scripts are
unaffected. --non-interactive forces it explicitly:
servicenow-mcp-setup --non-interactive --clients none --json
servicenow-mcp-profile create --name dev --instance https://yourinstance.service-now.com \
--auth-type oauth --client-id <client-id> --source reference --provider env
servicenow-mcp-setup grant --profile dev --read incident,problem --write incidentThe servicenow-mcp-setup commands
Command | Purpose |
| Generate local auth material and register supported clients |
| Print copy-pasteable config for a client |
| Add table access rules to a profile |
| Diagnose the install and print remedies |
--force regenerates the owner/client identifiers but deliberately preserves
SN_PROFILE_ENCRYPTION_KEY, which decrypts every credential envelope in
config.json. Add --help to any command for its full options.
The server runs as you, and the client list is the boundary. Nothing listens on a port, so nothing off this machine can reach it and no web page can drive it. What that leaves is the registration: every MCP client registered here can spawn the server and use whatever ServiceNow access your profiles grant, as your integration account. Keep the grants narrow, and remove a client you no longer use with
claude mcp remove servicenow-mcporcodex mcp remove servicenow-mcp. No ServiceNow credential is copied into a client's configuration file — the spawned server reads the profile and its encryption key from the owner-only~/.servicenow-mcpdirectory.
Connecting a client
servicenow-mcp-setup registers Codex and Claude Code automatically when their
CLI is on PATH. For everything else:
servicenow-mcp-setup client --client claude-desktop
servicenow-mcp-setup client --client allEvery supported client speaks stdio natively, so each one is configured the same way: a command to spawn.
claude mcp add servicenow-mcp -- servicenow-mcp
codex mcp add servicenow-mcp -- servicenow-mcpstdio is the default transport for both CLIs, so there is no transport flag to pass. For clients configured by file:
{
"mcpServers": {
"servicenow-mcp": { "command": "servicenow-mcp", "args": [] }
}
}Client | Configured by | Config location |
Claude Code |
| project or |
Codex |
|
|
Cursor | file |
|
VS Code | file ( |
|
Claude Desktop | file |
|
Windsurf | file |
|
No client holds a ServiceNow credential. The spawned server resolves its own
from ~/.servicenow-mcp, which is owner-only.
Full per-client blocks are in V2 service and client setup.
servicenow-mcpmust be on the spawning client'sPATH. A global npm install puts it there. If it is not — a project-local install, or a GUI client with a differentPATH— register the absolute entrypoint instead;servicenow-mcp-setup doctorchecks this and prints the exact command.
Guided profile creation from your client
After the bootstrap, a connected MCP client can walk you through profile creation:
Add a ServiceNow MCP profile for https://yourinstance.service-now.comThe MCP prompt is servicenow-mcp.add-profile. It guides profile naming, auth
mode, and least-privilege default-deny access, and deliberately does not
ask you to paste passwords, API keys, bearer tokens, OAuth client secrets, or
encryption keys into chat.
What gets installed
servicenow-mcp— the MCP server itself, spawned by a client over stdioservicenow-mcp-profile— manages profile credentials out of bandservicenow-mcp-setup— bootstrap, client config, grants, and diagnosis
Manual configuration without the bootstrap
The server keeps configuration explicit. A manual run needs:
audit identity:
MCP_OWNER_IDandMCP_CLIENT_ID(optional; they label audit records and default tolocal-owner/local-client)one named ServiceNow profile, either in
~/.servicenow-mcp/config.jsonor throughSN_PROFILE_NAME+SN_INSTANCE+ auth-specificSN_*variablesper-profile table access rules; unconfigured access denies everything
The SN_* environment path builds a profile only when
~/.servicenow-mcp/config.json does not exist. Once you create a profile
file, SN_ALLOWED_READ_TABLES, SN_ALLOWED_WRITE_TABLES, and
SN_TABLE_ACCESS_TARGETS stop applying and the rules must live on the profile
(servicenow-mcp-setup grant). This is the most common cause of a server that
denies every call; servicenow-mcp-setup doctor detects it.
The server reads ~/.servicenow-mcp/server.env itself at startup, because the
client that spawns it supplies its own environment and will not have sourced
anything. A value already present in the environment always wins over that
file, so container and CI configuration is unaffected.
For a quick environment-only run with no profile file — driving the server by hand over a pipe, or from a client that passes environment variables — inject protected values from your keychain or secret manager and pass only non-secret values on the command line:
MCP_OWNER_ID=local-owner \
MCP_CLIENT_ID=local-client \
SN_PROFILE_NAME=dev \
SN_INSTANCE=https://yourinstance.service-now.com \
SN_USER=your_user \
SN_ALLOWED_READ_TABLES=incident,problem,change_request \
SN_ALLOWED_WRITE_TABLES=incident,change_request \
SN_TABLE_ACCESS_TARGETS='[{"table":"incident","kind":"canonical","tools":["sn_query","sn_get","sn_create","sn_update","sn_incident_add_comment","sn_incident_add_work_note","sn_delete","sn_batch"],"closureComplete":true,"relatedTables":["incident"]},{"table":"problem","kind":"canonical","tools":["sn_query","sn_get"],"closureComplete":true,"relatedTables":["problem"]},{"table":"change_request","kind":"canonical","tools":["sn_query","sn_get"],"closureComplete":true,"relatedTables":["change_request"]}]' \
servicenow-mcpDo not put SN_PASSWORD, OAuth client secrets, or API keys in command history.
Inject them into the server's environment from your approved secret mechanism,
or leave them in the owner-only profile file where the server can resolve them
without any client seeing them.
Source install for development
Use source install only for development or unreleased changes:
git clone https://github.com/onlyflowstech/servicenow-mcp.git
cd servicenow-mcp
npm install
npm run build
npm startFor local development with a rebuild and source maps:
npm run devContainer deployment applies to the dormant HTTP transport rather than a 2.0 stdio install; see Production container deployment and the enterprise boundary.
Related MCP server: snow-mcp
Multi-Instance Profiles
Manage multiple ServiceNow instances (dev, test, prod, PDI) with named profiles. Every tool call must select one configured profile explicitly; V2 has no active-profile or default-profile fallback.
Setup
Create profiles with the CLI rather than by hand — it captures credentials without putting them in argv, and it writes the file with the right ownership and mode:
servicenow-mcp-profile create --name dev --instance https://mydev.service-now.com --auth-type basic --username admin --source reference --provider env
servicenow-mcp-profile create --name prod --instance https://myprod.service-now.com --auth-type basic --username api.user --source reference --provider env
servicenow-mcp-setup grant --profile dev --read incident,problem --write incident
servicenow-mcp-setup grant --profile prod --read incidentThe resulting ~/.servicenow-mcp/config.json looks like this. Note
tableAccess: a profile without it denies every tool call.
{
"version": 2,
"profiles": {
"dev": {
"instance": "https://mydev.service-now.com",
"username": "admin",
"credential": { "type": "secret_ref", "provider": "env", "reference": "SN_PASSWORD_DEV" },
"description": "Development instance",
"tableAccess": {
"readTables": ["incident", "problem"],
"writeTables": ["incident"],
"targets": [
{
"table": "incident",
"kind": "canonical",
"tools": ["sn_query", "sn_get", "sn_aggregate", "sn_schema", "sn_create", "sn_update"],
"closureComplete": true,
"relatedTables": ["incident"]
},
{
"table": "problem",
"kind": "canonical",
"tools": ["sn_query", "sn_get", "sn_aggregate", "sn_schema"],
"closureComplete": true,
"relatedTables": ["problem"]
}
]
}
}
}
}Have the approved supervisor, orchestrator, keychain, or secret manager provide
the values referenced by SN_PASSWORD_DEV and SN_PASSWORD_PROD in the
environment the server is spawned with, or in ~/.servicenow-mcp/server.env,
which the server falls back to. Do not type either value into a shell command,
command argument, dotenv file, or command history.
Each targets entry asserts closureComplete: true, meaning relatedTables
lists every backing, ancestor, and descendant table the operation can reach.
When a table extends another, declare it:
servicenow-mcp-setup grant --profile dev --read change_request --related change_request=task.
Related tables join the allowlist but get no target of their own, so a caller
cannot address them directly.
Credential Options
Format | Example | Description |
Legacy environment reference |
| Read-compatible V1 form; migrated to a structured reference on the next write |
Secret reference |
| Provider-neutral reference resolved only for the selected request |
Encrypted envelope |
| AES-256-GCM value created by the protected administration CLI |
Plaintext profile secrets are rejected. Use the installed servicenow-mcp-profile
operator command to create, inspect, rotate, or remove profiles; it reads secrets
through a protected prompt or bounded standard input and rejects credential-bearing
command-line arguments. Encrypted sources require exactly 32 random bytes encoded
as base64 or base64url in SN_PROFILE_ENCRYPTION_KEY, supplied separately by the
deployment secret mechanism and never stored in the profile file. See the
profile credential and administration guide.
The legacy env:VAR_NAME indirection remains readable for every secret field:
credential, clientSecret, and apiKey.
Using Profiles
Pass the profile parameter on every tool call:
"query incidents on prod" — calls
sn_querywithprofile: "prod""get incident INC0010001 on dev" — calls
sn_getwithprofile: "dev""show me the dev profile endpoint" — calls the read-only
sn_profilediagnostic withprofile: "dev"
Profiles are created and changed out of band by the service operator. Legacy
default_profile metadata is ignored and is not persisted on the next
administrative write; the MCP boundary never consults it.
SN_* configuration compatibility
If no config file exists, canonical SN_* connection values are exposed only
through an explicit SN_PROFILE_NAME mapping. For example, set
SN_PROFILE_NAME=dev with SN_INSTANCE, SN_USER, and SN_PASSWORD, then
call tools with profile: "dev". Without SN_PROFILE_NAME, bare connection
variables create no profile and cannot route a request. Secret values remain
runtime-only environment references and are never persisted as plaintext.
Authentication
Three ServiceNow auth types are available per profile, selected with authType (default: basic). Profile configuration is managed out of band by the service operator. This is the only authentication involved: the transport is stdio, so there is no endpoint in front of the server to protect.
Heads up: ServiceNow's inbound Basic Auth restriction program is phasing out basic auth for API requests — instances can start hard-rejecting it at any time (exemptions: Web-Service-Access-Only accounts or the
snc_basic_auth_api_accessrole). OAuth is the recommended auth type. The server prints a startup warning for basic-auth profiles.
OAuth 2.0 (recommended)
client_credentials grant (default) — create an OAuth API endpoint client in ServiceNow (System OAuth → Application Registry) and reference the secret via env: indirection:
{
"version": 2,
"profiles": {
"dev": {
"instance": "https://mydev.service-now.com",
"authType": "oauth",
"clientId": "your-oauth-client-id",
"clientSecret": "env:SN_CLIENT_SECRET",
"description": "OAuth client_credentials"
}
}
}password grant — set grantType and provide the user credentials as well:
{
"instance": "https://mydev.service-now.com",
"authType": "oauth",
"grantType": "password",
"clientId": "your-oauth-client-id",
"clientSecret": "env:SN_CLIENT_SECRET",
"username": "integration.user",
"credential": "env:SN_PASSWORD_DEV"
}Tokens are cached until shortly before their expires_in expiry and refreshed automatically (including a single refresh + retry on 401). Token responses are never logged.
API key
For instances using Inbound Authentication Profiles with API keys. The header name is configurable (default x-sn-apikey):
{
"instance": "https://mydev.service-now.com",
"authType": "apikey",
"apiKey": "env:SN_API_KEY",
"apiKeyHeader": "x-sn-apikey"
}Basic (default, deprecated by ServiceNow)
{
"instance": "https://mydev.service-now.com",
"username": "admin",
"credential": "env:SN_PASSWORD_DEV"
}On a 401, the error explains the Basic Auth restriction program (KB3096078) and how to move to OAuth.
Timeouts & retries
Every request is bounded by a timeout (default 30s; per-profile timeoutMs or env SN_TIMEOUT_MS) and retried up to twice with exponential backoff on 429/502/503/504, honoring Retry-After. POST requests are only retried on 429 — never after a 5xx that may have executed side effects.
ServiceNow upstream can return HTTP 429 with an empty body, while this server's own HTTP rate-limit rejections return a short JSON body plus Retry-After. Treat the status and Retry-After header as authoritative; do not benchmark or validate tool success from response latency or body shape alone. In normal ServiceNow instances, plan around the Background throttling default of roughly 120 requests per 60 seconds per identity unless the instance limit is explicitly raised.
Why This MCP Server?
Most ServiceNow MCP integrations are read-only and support a handful of tables. This service offers a broader tool catalog behind explicit, deny-by-default table and tool policy:
Feature | Others | @onlyflows/servicenow-mcp |
Query records | ✅ | ✅ |
Create records | ❌ | ✅ |
Update records | ❌ | ✅ |
Delete records | ❌ | ✅ (with safety confirm) |
Bulk operations | ❌ | ✅ (dry-run by default) |
Aggregations (COUNT/AVG/MIN/MAX/SUM) | ❌ | ✅ |
Table schema introspection | ❌ | ✅ |
CMDB relationship traversal | ❌ | ✅ (recursive, configurable depth) |
Instance health monitoring | ❌ | ✅ (version, nodes, jobs, stats) |
Attachment management | ❌ | ✅ (list, upload, download; inline base64, no host filesystem) |
System log queries | ❌ | ✅ |
Code search across artifacts | ❌ | ✅ |
Table/app/plugin discovery | ❌ | ✅ |
ATF test execution | ❌ | 🚧 listing/results available; execution currently policy-denied |
Natural language interface | ❌ | 🚧 currently policy-denied pending a typed access plan |
Background scripts | ❌ | 🚧 on the roadmap (SNS-39) |
Multi-instance profiles | ❌ | ✅ (named profiles, per-call override) |
Total tools | 1–3 | 19 |
Quick Start
The server speaks stdio and requires Node.js 20 or newer. The shortest path is the bootstrap described under Installation:
servicenow-mcp-setupThat registers your clients; each one spawns the server when it needs it.
The rest of this section is the manual environment path, for a deployment that injects everything from a supervisor or secret manager, or for driving the server by hand over a pipe.
Use .env.example only as a non-secret configuration
inventory. Its protected-value assignments are intentionally empty; inject
ServiceNow secrets through a supervisor, orchestrator, keychain, or secret
manager rather than filling a repository dotenv file.
The
SN_ALLOWED_*andSN_PROFILE_NAMEvariables below build a profile only when~/.servicenow-mcp/config.jsondoes not exist. With a profile file present, put the rules on the profile withservicenow-mcp-setup grant.
export MCP_OWNER_ID="your-owner-id"
export MCP_CLIENT_ID="your-client-id"
export SN_ALLOWED_READ_TABLES="incident,problem,change_request"
export SN_ALLOWED_WRITE_TABLES="incident,change_request"
export SN_TABLE_ACCESS_TARGETS='[{"table":"incident","kind":"canonical","tools":["sn_query","sn_get","sn_create","sn_update","sn_incident_add_comment","sn_incident_add_work_note","sn_delete","sn_batch"],"closureComplete":true,"relatedTables":["incident"]},{"table":"problem","kind":"canonical","tools":["sn_query","sn_get"],"closureComplete":true,"relatedTables":["problem"]},{"table":"change_request","kind":"canonical","tools":["sn_query","sn_get"],"closureComplete":true,"relatedTables":["change_request"]}]'
export SN_PROFILE_NAME="dev"
export SN_INSTANCE="https://yourinstance.service-now.com"
export SN_USER="your_username"
npm run build
npm startBefore running those non-secret commands, the approved runtime secret mechanism must already have injected the authentication-specific ServiceNow secret into the process. Do not enter it in this shell block.
A client connects by spawning the command; there is no URL and no header:
{
"mcpServers": {
"servicenow-mcp": { "command": "servicenow-mcp", "args": [] }
}
}JSON-RPC messages travel on the child's stdin and stdout, one newline-delimited message per frame. Everything else the server reports — startup warnings, and one structured JSON-line event per completed tool call — goes to stderr, which your client captures as its server log. There is no per-message size limit imposed by the transport.
For complete official SDK and independent client examples, safe two-profile setup, and crossed profile/result/audit checks, see V2 service and client setup.
Breaking changes in 2.0
Every tool call must name a profile, and table access is deny-by-default.
Those two require action on every install. The transport is stdio, as it was in
1.0.0, so a client configured with a command entry keeps working.
The breaking changes from 1.0.0, each with a before/after example, are in
Migrating to 2.0.
Deployment guides for the dormant HTTP transport
2.0 ships stdio only. The container image, the health and shutdown contract, the operations runbook, and the Secure MCP Tunnel adapter all describe the dormant HTTP transport, which no CLI path reaches. They are kept because that transport is a planned enterprise deployment shape, not because they apply to a 2.0 install — nothing in this section is needed to use this server.
Production container deployment — OCI artifact, non-root runtime, provenance and scanning
Remote operations runbook — health interpretation, telemetry, alerts, rotation, incident response
Private ChatGPT connectivity — outbound-only Secure MCP Tunnel adapter
Tools Reference
Core CRUD
Tool | Description |
| Query an approved table with structured filters, field selection, pagination, and sorting; bounded raw reads require an explicit policy rule |
| Get a single record by sys_id from an approved table |
| Create a record on any table granted for writes, using only field-policy-approved writable fields; |
| Update one record selected by exact |
| Append one bounded customer-visible comment to an incident; repeated calls append again |
| Append one bounded internal work note to an incident; repeated calls append again |
| Delete a record on an approved write table (requires |
| Bulk update/delete using a required structured filter and dry-run safety (raw encoded selectors are prohibited; requires |
Analytics & Schema
Tool | Description |
| COUNT, AVG, MIN, MAX, SUM with grouping |
| Table field definitions, types, references |
| Instance version, cluster nodes, stuck jobs, key stats |
CMDB & Operations
Tool | Description |
| CMDB CI graph traversal — upstream/downstream/both, configurable depth |
| List attachments, return downloads as inline base64, and upload inline base64 content; never touches a host filesystem path |
| Query system logs with severity/source/time filters |
| Search business rules, script includes, client scripts, etc. |
| Discover tables, scoped apps, store apps, plugins |
Testing & Automation
Tool | Description |
| List ATF tests/suites and get results; |
| Currently fails closed until natural-language composition emits a complete typed access plan |
sn_script (background script execution) shipped in 1.0.0 as an unimplemented
stub and is not published in 2.0 — it does not appear in tools/list. Use
sn_query and sn_batch instead. See Roadmap.
Profile Management
Tool | Description |
| Inspect non-secret metadata for one explicitly named profile; profile configuration is operator-managed out of band |
Environment Variables
MCP runtime
Variable | Required | Default | Description |
| ❌ |
| Stable non-secret owner identifier recorded in request/tool context and every audit record. A label, not a credential; it is never checked. |
| ❌ |
| Stable non-secret client identifier recorded in request/tool context and every audit record. A label, not a credential; it is never checked. |
That is the whole list. There is no bind address, port, Host/Origin
allowlist, concurrency cap, connection cap, shutdown grace period, bearer
token, or rate limit, because there is no listener: a client spawns the server
and owns its lifetime.
The server reads these from its environment and falls back to
~/.servicenow-mcp/server.env for any it does not find there. That file is
owner-only (mode 0600) and is where servicenow-mcp-setup writes the
generated identifiers and SN_PROFILE_ENCRYPTION_KEY. It exists because the
client that spawns the server supplies its own environment and will not have
sourced anything. A value already present in the environment always wins, so a
container or CI runner that passes configuration directly is unaffected.
servicenow-mcp-setup doctor reports that file's mode and contents.
Observability
Each completed tool call emits one JSON-line event to stderr, which the spawning client captures as its server log:
{"schemaVersion":1,"type":"mcp_tool","observedAtMs":1737000000000,"latencyMs":42,
"correlationId":"stdio-<session>-<invocation>","ownerIdHash":"sha256:...",
"clientIdHash":"sha256:...","tool":"sn_query","profile":"dev",
"instance":"https://dev00001.service-now.com","outcome":"success","reason":null,
"errorCategory":null,"retry":null,"retryAfterSeconds":null}Tool audits classify request cancellation and request-deadline expiration
separately from handler failures. Configured owner/client identifiers are
represented only by SHA-256 pseudonyms; headers, URLs/query strings, bodies,
credentials, tokens, config objects, and exception text are not event fields.
Telemetry never blocks a tool result: stderr backpressure retains at most 256
pending lines, drops excess events, and emits a
{"type":"telemetry_dropped","count":N} summary after the stream drains.
A correlation ID is stdio-<session>-<invocation>. The session half is fixed
for the life of one spawned server, so every record from one client session
groups together; the invocation half is fresh per call. Neither half is derived
from anything the caller sent.
stdout carries the protocol and nothing else. Every diagnostic goes to
stderr. One stray byte on stdout would desynchronize the client's JSON-RPC
parser and end the session, so there is no such thing as a harmless
console.log on the startup or request path; test/stdio-entrypoint.test.ts
spawns a real server and asserts it.
Arguments that fail a tool's schema are rejected by the MCP SDK before any handler runs, so they return an error to the caller but produce no audit event — the execution context that would issue one is never opened. Every call that reaches a tool is audited.
Body size and concurrency (dormant HTTP runtime only)
None of this applies to the shipped server. It describes the dormant HTTP
runtime, which no CLI path reaches — see
the enterprise release boundary
— and binds only someone embedding this package and calling createHttpRuntime
directly. Over stdio there is no request-body limit and no admission ceiling.
Request body size and concurrency trade directly against each other under the 512 MiB admission ceiling:
| Highest concurrency that starts | Effect |
1 MiB (shipped default) | 2 | 416 MiB budgeted; the intended configuration |
1.75 MiB | 2 | 512 MiB — exactly at the ceiling |
2 MiB | 1 | Single-flight: every tool call serializes |
5.75 MiB | 1 | the last value that starts at all |
above 5.75 MiB | none | startup fails at any concurrency |
Two failure modes are worth knowing:
At 2 MiB and above the server is single-flight. Concurrency 2 no longer fits, so the runtime can only start at 1 and every tool call queues behind every other one. There is no warning and no log line — it presents as "the server got slow", and one large upload blocks every other tool for its duration. Nothing connects the cause to the effect.
Above 5.75 MiB the server refuses to start. A constructor
throw, not a clamp. The message namesmaxConcurrentRequestsandmaxBodyBytesbut gives neither the ceiling, the arithmetic, nor a working value; the table above is the way forward.
maxBodyBytes is not operator-configurable. src/http-entrypoint.ts
builds the request policy with only allowedHosts and allowedOrigins, so the
limit is always 1 MiB and no environment variable changes it.
Metadata cache
Stable ServiceNow metadata reads are cached per instance and credential identity
for 24 hours by default. The default cached table patterns are
sys_glide_object, sys_dictionary, sys_db_object, sys_app, sys_plugins,
sys_metadata*, and sys_flow*. Set metadataCache.ttlMs and
metadataCache.tables on a file-backed profile, or SN_METADATA_CACHE_TTL_MS
/ SN_METADATA_CACHE_TABLES for the explicit environment profile. sn_query,
sn_get, and sn_schema accept force_recache: true to refresh metadata. A
cache hit performs a lightweight sys_updated_on probe and is used only when no
matching metadata rows changed since the previous sync.
Prerequisite: a resolvable session timezone. The freshness probe compares
sys_updated_on, which ServiceNow evaluates in the session user's timezone,
not UTC. Resolving that zone requires the authenticating account's user_name
to look up sys_user.time_zone, falling back to the glide.sys.default.tz
property. When it cannot be resolved the cache disables itself for that
identity rather than assuming UTC — a wrong assumption would silently serve
stale metadata for the length of the offset. The server logs a warning naming
the reads it needs.
This has one consequence worth knowing before you configure it:
Profile auth | Metadata caching |
Basic | works — the profile carries a username |
OAuth password grant | works — the profile carries a username |
OAuth client_credentials | disabled — no username to resolve a timezone from |
API key | disabled — no username to resolve a timezone from |
The profile also needs read access to sys_user (for time_zone) and
sys_properties (for glide.sys.default.tz) for the lookup to succeed at all.
The honest tradeoff: the cache only ever saved payload bytes, never round
trips — a cache hit still costs one freshness probe. So on a client-credentials
or API-key profile the practical loss is bandwidth on sys_dictionary reads,
not latency. If you are choosing an auth mode, this should not be the deciding
factor.
Deletions become visible within one TTL. The freshness probe detects
updates, not deletes, so a row deleted upstream stays served until its entry
expires and is re-fetched — up to 24 hours at the default TTL. This is accepted
behavior, not a defect; lower SN_METADATA_CACHE_TTL_MS or pass
force_recache: true if you need a deletion reflected sooner.
Unrestricted field selection (fields=all, response_format=detailed)
Both resolve to a wildcard selection. They previously dropped sysparm_fields
entirely, so ServiceNow returned every column and a wide table could breach the
1 MiB cumulative upstream cap and fail the call outright. They are now
bounded to at most 100 columns.
The cap bounds the upstream request, not the response — truncating after
receipt would not help, because the bytes have already crossed the wire and
already breached the limit. Columns are resolved from sys_dictionary, walking
super_class so an extended table contributes its inherited fields. Ordering is
deterministic: the table's curated default projection first in its declared
order, then every remaining column alphabetically. Defaults lead so a capped
result stays useful; alphabetical afterwards because dictionary row order is not
stable across instances. Every failure path falls back to the table's bounded
default projection, never to dropping sysparm_fields.
sn_query reports truncation through its hint field. sn_get will carry the
same notice shortly.
Two behavior changes worth stating plainly, because they change what a caller gets back:
Journal fields are now returned.
commentsandwork_notesare included in the resolved set forfields=allanddetailed. See Journal content and field selection.Sensitive-looking field names are excluded from the resolved set entirely. A name matching the sensitive-field pattern is never requested, rather than being requested and scrubbed on arrival. Under the old wildcard behavior the value crossed the wire and was then removed; naming it in
sysparm_fieldswould have pulled it over deliberately, which is worse.
Journal content and field selection
Journal content on incident — comments (customer-visible) and work_notes
(internal) — is readable through fields=all, response_format: "detailed", an
explicit fields=comments, and sn_schema. The default projection still
excludes it, so an ordinary sn_query or sn_get does not return it.
Stated as a fact rather than a warning: journal content on real instances
routinely contains customer PII, so asking for all fields on incident returns
customer-visible commentary along with everything else. Operators granting
incident reads to an agent should know that. If that is not wanted, grant a
narrower read via the field policy rather than relying on the default
projection, since the caller chooses fields.
Attachment payloads
sn_attach never reads from or writes to host filesystem paths. Uploads use a
safe leaf file_name plus content_base64; downloads return
content_base64, file_name, content_type, and size_bytes. Download also
requires the owning table and record sys_id, which are policy-authorized
and verified against attachment metadata before any bytes are returned.
Size limit: 10 MiB decoded, and that is the only one. The stdio transport
frames messages by newline with no size bound, so the tool's own limits are
what apply — 10 MiB of decoded bytes for an upload, and a separate 10 MiB raw
budget for a download. The tool's content_base64 schema description carries
the authoritative figure.
The ~760 KiB practical ceiling documented before 2.1 came from the HTTP body limit, which no longer applies: the client and server share a pipe, not an envelope. Base64 still inflates a file by about a third in the message itself, so a 10 MiB attachment is roughly a 13.3 MiB JSON frame — large, but the transport will carry it.
Treat sn_attach as suitable for logs, configs, screenshots, and documents
rather than bulk transfer; a very large frame still costs memory in both the
client and the server, and ServiceNow's own UI or a dedicated integration is a
better path for bulk file movement.
Table access policy
2.0 denies every ServiceNow table by default. Table access is selected per
profile, not from a process-wide implicit default. File-backed profiles define
tableAccess in ~/.servicenow-mcp/config.json; the explicit SN_PROFILE_NAME
environment profile maps the SN_ALLOWED_* variables into that one profile only
when no profile file exists. If a profile has no table rules, it denies all.
Write the rules with the CLI rather than by hand — it validates the result with the same loader the server uses at request time:
servicenow-mcp-setup grant --profile dev --read incident,problem --write incident
servicenow-mcp-setup grant --profile dev --read cmdb_ci --tools sn_query,sn_relationships
servicenow-mcp-setup grant --profile dev --read change_request --related change_request=taskAllowlist entries may be exact table names or the literal * to allow every
table for that operation. Table names are trimmed, lowercased, deduplicated,
and must be valid ServiceNow identifiers.
tableAccessis the sole table-level authority. There is no longer a built-in list of tables the server refuses unconditionally. A profile that grants a table gets it, subject only to ServiceNow's own per-user ACLs — so a grant ofsys_script,sys_user_role, or a credential table is honored. Writingsys_scriptis server-side script execution under the integration account. Least privilege now lives entirely in the grant and in the roles you give that account; grant the narrowest set that does the job, and prefer an account whose ServiceNow roles cannot reach what the grant does not need.
Variable | Required | Default | Description |
| ❌ | deny all | Tables permitted for read operations on the explicit |
| ❌ | deny all | Tables permitted for create, update, incident journal append, delete, upload, and confirmed batch operations on the explicit |
| Required for exact allowlisted caller-addressable tables; optional with |
| Trusted JSON classification with |
| Required for custom/generic table fields | built-in finite policy | Trusted JSON object keyed by table name or |
| ❌ | deny all | Trusted JSON object containing bounded |
Invalid policy configuration fails startup. A composed tool is admitted only when its complete backing-table plan is allowed before the first ServiceNow client access. Every related target must have the same read or write permission, so a base table, alias, view, or extension cannot bypass an unlisted backing or descendant table. Related permission does not make a dependency directly caller-addressable without its own target entry. Field policy narrows what a granted table exposes; it does not deny a table the operator granted. Sensitive-looking field names remain excluded regardless. Build the complete target catalog from approved ServiceNow metadata and treat it as trusted startup configuration; omit a target when reachability cannot be proven complete. File-backed profile example:
{
"version": 2,
"profiles": {
"dev": {
"instance": "https://dev.service-now.com",
"username": "integration.user",
"credential": "env:SN_PASSWORD",
"tableAccess": {
"readTables": ["incident", "sys_dictionary"],
"writeTables": ["incident"],
"targets": [
{
"table": "incident",
"kind": "canonical",
"tools": ["sn_query", "sn_get", "sn_create", "sn_update"],
"closureComplete": true,
"relatedTables": ["incident"]
}
]
}
}
}
}sn_nl and ATF run/run-suite currently fail closed because they do not emit
a complete typed side-effect plan; use the corresponding typed tool instead.
Incident journal fields are append-only: generic sn_update rejects comments
and work_notes before credentials or client creation. Use
sn_incident_add_comment or sn_incident_add_work_note with exactly
profile, incident sys_id, and bounded content; grant the selected tool
explicitly on the incident target as well as write access to that table.
ServiceNow profiles
Note: A profile file is authoritative when present. Without one,
SN_PROFILE_NAMEmust explicitly map the canonical connection variables to a named profile; there is no synthetic or default profile.
Variable | Required | Default | Description |
| ✅* | — | Explicit name for the process-local environment profile; required before bare connection variables define any profile. |
| ✅* | — | Instance URL (e.g. |
| ✅* | — | ServiceNow username (basic auth / OAuth password grant) |
| ✅* | — | ServiceNow password (basic auth / OAuth password grant) |
| ❌ |
| Auth scheme: |
| ❌ | — | OAuth client id ( |
| ❌ | — | OAuth client secret ( |
| ❌ |
| OAuth grant: |
| ❌ | — | API key ( |
| ❌ |
| Header the API key is sent in |
| ❌ |
| Per-request timeout in milliseconds |
| ❌ |
| Default display value mode ( |
| ❌ |
| Default CMDB relationship traversal depth |
*SN_PROFILE_NAME and SN_INSTANCE are not required when using
~/.servicenow-mcp/config.json. Authentication-specific variables depend on
the selected auth type.
Usage Examples
Once connected, your AI assistant can:
Query incidents:
"On dev, show me all P1 incidents assigned to the Network team" (
profile: "dev")
Create a record:
"On staging, create an incident for the approved VPN test" (
profile: "staging")
Aggregate data:
"On prod, how many incidents are grouped by priority?" (
profile: "prod")
Check health:
"Run the dev instance health check" (
profile: "dev")
CMDB traversal:
"On prod, show upstream dependencies for email-server-01" (
profile: "prod")
Schema introspection:
"On dev, what fields are on change_request?" (
profile: "dev")
Code search:
"On dev, find business rules that reference GlideRecord('incident')" (
profile: "dev")
ATF testing:
"On staging, list the approved ATF suite" (
profile: "staging")
Explicit profile selection:
"Query incidents on dev" (the client sends
profile: "dev"on that call)
The client must translate every example into a tool invocation containing that
exact profile; no prior call creates default, active, or switch-profile state.
Safety Features
This server is designed for production use with multiple safety layers:
Delete operations require explicit
confirm: trueBatch operations run in dry-run mode by default — shows match count without making changes
Bulk operations require
confirm: trueto leave dry-run modeUnclassified composition is denied —
sn_nland ATF execution do not run until they can emit complete typed access plansTable access is deny-by-default with independent exact read/write allowlists and non-configurable sensitive-table denials
User input is neutralized before interpolation into encoded queries (
^is stripped from filter values — ServiceNow's query syntax has no escape sequence)
Development
Have the approved local supervisor or keychain inject the selected ServiceNow authentication secret before starting the process. The commands below contain non-secret configuration only; never prepend or append protected values on the command line.
# Clone
git clone https://github.com/onlyflowstech/servicenow-mcp.git
cd servicenow-mcp
# Install & build
npm install
npm run build
# Run the server directly, speaking stdio on this terminal's pipes
MCP_OWNER_ID=local-owner \
MCP_CLIENT_ID=local-client \
SN_ALLOWED_READ_TABLES=incident,problem,change_request \
SN_ALLOWED_WRITE_TABLES=incident,change_request \
SN_TABLE_ACCESS_TARGETS='[{"table":"incident","kind":"canonical","tools":["sn_query","sn_get","sn_create","sn_update","sn_incident_add_comment","sn_incident_add_work_note","sn_delete","sn_batch"],"closureComplete":true,"relatedTables":["incident"]},{"table":"problem","kind":"canonical","tools":["sn_query","sn_get"],"closureComplete":true,"relatedTables":["problem"]},{"table":"change_request","kind":"canonical","tools":["sn_query","sn_get"],"closureComplete":true,"relatedTables":["change_request"]}]' \
SN_PROFILE_NAME=dev \
SN_INSTANCE=https://yourinstance.service-now.com \
SN_USER=your_user \
npm start
# Build and run with source maps for local development
MCP_OWNER_ID=local-owner \
MCP_CLIENT_ID=local-client \
SN_ALLOWED_READ_TABLES=incident,problem,change_request \
SN_ALLOWED_WRITE_TABLES=incident,change_request \
SN_TABLE_ACCESS_TARGETS='[{"table":"incident","kind":"canonical","tools":["sn_query","sn_get","sn_create","sn_update","sn_incident_add_comment","sn_incident_add_work_note","sn_delete","sn_batch"],"closureComplete":true,"relatedTables":["incident"]},{"table":"problem","kind":"canonical","tools":["sn_query","sn_get"],"closureComplete":true,"relatedTables":["problem"]},{"table":"change_request","kind":"canonical","tools":["sn_query","sn_get"],"closureComplete":true,"relatedTables":["change_request"]}]' \
SN_PROFILE_NAME=dev \
SN_INSTANCE=https://yourinstance.service-now.com \
SN_USER=your_user \
npm run devTesting with MCP Inspector
Use the isolated, exactly locked Inspector toolchain on Node.js 22.19 or newer;
the server itself remains supported on Node.js 20. Set the non-secret
MCP_PROFILE, install from tools/inspector/package-lock.json, and run the
local-only launcher:
MCP_PROFILE=dev npm run inspector(Run npm ci --prefix tools/inspector --engine-strict --ignore-scripts first.)
The launcher prints the exact STDIO command and arguments to enter in the
Inspector UI. There is no endpoint and no bearer to type. Include the explicit
profile in every call. The Inspector spawns the server itself and inherits a
scrubbed environment with every MCP_* and SN_* value removed; the server
still resolves its credential, because it reads the owner-only
~/.servicenow-mcp/server.env at startup rather than relying on what it was
handed. The launcher does not expose Inspector beyond loopback or create a
tunnel.
npm run smoke is the second client. It spawns dist/index.js the same way and
needs only MCP_PROFILE:
MCP_PROFILE=dev npm run smokeSee docs/RELEASE-VALIDATION.md for the release
gates, write confirmation, evidence, and rollback procedure.
Roadmap
stdio transport — the client spawns the server; a Streamable HTTP runtime exists but is dormant
OAuth 2.0 authentication support (client_credentials + password grants, API keys)
sn_script background-script execution (SNS-39) — future state, deliberately not shipped in 2.0; requires automating the
sys.scripts.doUI endpoint with session authStreaming for large result sets
Caching for schema and relationship lookups
License
MIT © OnlyFlows
Available Tools
17 toolssn_aggregateA
Run aggregate queries (COUNT, AVG, MIN, MAX, SUM) on a ServiceNow table with optional grouping.
| Name | Required | Description | Default |
|---|---|---|---|
| type | Yes | Aggregation type | |
| field | No | Field to aggregate on (required for AVG, MIN, MAX, SUM) | |
| query | No | ServiceNow encoded query filter | |
| table | Yes | ServiceNow table name (e.g. incident) | |
| group_by | No | Group results by this field | |
| display_value | No | Display values mode: true, false, or all |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, and the description provides no behavioral details beyond the basic operation. It does not mention that the tool is read-only, what permissions are required, rate limits, or the structure of the returned aggregate results.
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 a single sentence, front-loaded with the action, and contains no redundant words. It efficiently conveys the tool's core functionality.
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?
With 6 parameters and no output schema, the description is minimal. It explains the core purpose but omits details about return format, error behavior, or constraints, which are important for a query tool with grouping and display_value options.
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 descriptions cover all 6 parameters (100% coverage), so the baseline is 3. The description adds only 'optional grouping' which maps to group_by but does not enrich parameter meaning beyond schema definitions.
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 runs aggregate queries (COUNT, AVG, MIN, MAX, SUM) on a ServiceNow table with optional grouping, distinctly differentiating it from sibling tools like sn_query or sn_get that retrieve raw records.
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?
Usage is implied via the aggregation verbs and table context, but no explicit guidance is given about when to choose this tool over alternatives like sn_query for raw data, or any exclusions for unsupported aggregate types or table restrictions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sn_atfA
Automated Test Framework — list, run, and get results for ATF tests and test suites.
| Name | Required | Description | Default |
|---|---|---|---|
| wait | No | Wait for test/suite completion (default true) | |
| limit | No | Max results (default 20) | |
| query | No | ServiceNow encoded query filter | |
| action | Yes | ATF operation: list tests, list suites, run a test, run a suite, or get results | |
| fields | No | Comma-separated fields to return | |
| timeout | No | Max wait time in seconds (default 120 for tests, 300 for suites) | |
| suite_name | No | Filter tests by suite name (for list action) | |
| test_sys_id | No | Test sys_id (required for run) | |
| execution_id | No | Execution/result sys_id (required for results action) | |
| suite_sys_id | No | Suite sys_id (required for run-suite) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of disclosing behavioral traits. It mentions 'run' (mutation) but does not warn about potential side effects like executing test suites, asynchronous behavior, or system impact. The wait/timeout parameters exist in the schema, but the description does not explain the synchronous nature or implications of running tests. This is a significant gap for a tool that triggers executions.
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 a single sentence of 13 words, front-loaded with the tool's name and core operations. It is concise with zero filler, every word contributing to the purpose. The em dash effectively introduces the function list, making it highly scannable.
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?
Given the tool's complexity (10 parameters, multiple actions, no output schema or annotations), the description provides only a minimal overview. The schema fills in parameter details, but the description lacks guidance on the test lifecycle (e.g., list → run → results), potential delays, or error scenarios. It is adequate for basic selection but incomplete for safe and effective invocation in all but the simplest use cases.
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 100%, so the baseline is 3. The description adds a high-level overview but does not enhance the meaning of individual parameters beyond what the schema already provides. For example, 'action' is fully described in the enum, and the description does not add any new semantic context to parameters like 'query', 'wait', or 'timeout'. It neither improves nor harms parameter understanding.
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's domain ('Automated Test Framework') and its primary operations ('list, run, and get results for ATF tests and test suites'). This distinguishes it from sibling tools like sn_query or sn_script, as it is specifically for ATF test management. The verb-resource pairing is explicit and unambiguous.
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 indicates clear use cases: listing, running, and retrieving results for ATF tests/suites. While it doesn't explicitly mention alternatives or when-not-to-use, the ATF-specific naming inherently separates it from generic query or script tools. No exclusions are provided, but the context is clear enough for an agent to infer when this tool is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sn_attachA
Manage attachments on ServiceNow records. List, download, or upload attachments.
| Name | Required | Description | Default |
|---|---|---|---|
| table | No | Table name (required for list and upload) | |
| action | Yes | Attachment operation: list, download, or upload | |
| sys_id | No | Record sys_id (required for list and upload) | |
| file_path | No | Local file path to upload | |
| output_path | No | Local file path to save downloaded attachment | |
| content_type | No | MIME type for upload (default: application/octet-stream) | |
| attachment_sys_id | No | Attachment sys_id (required for download) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It lists the three operations but does not describe potential side effects (e.g., upload overwriting, download requiring specific permissions), authentication requirements, or error handling. This is a notable gap for a tool that includes a mutating action (upload).
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 a single concise sentence that front-loads the tool's purpose and lists the three operations. Every word earns its place with no redundant detail.
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 provides a high-level overview but does not explain which parameters are needed for each action (e.g., table and sys_id for list/upload vs attachment_sys_id for download). With 7 parameters and no output schema, additional context on action-parameter mapping and return values would improve completeness, though the schema partially covers this.
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 100%, so the schema already documents each parameter's purpose and which are required for specific actions. The description adds no additional semantic meaning beyond the operation names, so it meets the baseline but does not exceed it.
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 'Manage attachments on ServiceNow records. List, download, or upload attachments.' clearly identifies the tool's purpose with a specific verb ('manage') and resource ('attachments'), and it enumerates the three distinct operations. This also distinguishes it from sibling tools, which focus on other record operations like querying or creating records.
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 provides clear context that this tool is for attachment operations (list, download, upload), which implies when to use it versus sibling tools focused on other aspects of ServiceNow records. However, it does not explicitly state when not to use it or name alternative tools, so it falls 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.
sn_batchA
Bulk update or delete records matching a query. Runs in dry-run mode by default — set confirm to true to execute. Safety cap at 10,000 records.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max records to affect (default 200, safety cap 10000) | |
| query | Yes | Encoded query to select records (required — refuses to operate on all records) | |
| table | Yes | ServiceNow table name | |
| action | Yes | Operation to perform: update or delete | |
| fields | No | JSON fields to set on each record (required for update action). e.g. {"state":"7","close_notes":"Bulk closed"} | |
| confirm | No | Set to true to actually execute. Default is dry-run. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It transparently reveals the dry-run default, the need to set confirm=true to execute, and the safety cap, which is especially critical for a batch mutation tool. It does not disclose return values or error states, but the safety mechanisms are prominent and well-communicated.
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 two sentences, with the core purpose front-loaded and every word earning its place. It is direct, efficient, and free of fluff, providing the essential operational facts in minimal space.
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?
Given the tool's complexity (batch operations, nested objects, no annotations or output schema), the description covers critical operational context: bulk nature, dry-run behavior, and safety cap. It omits return value/error details, but with no output schema, this is less critical. The schema fills parameter-level gaps, making the description reasonably complete for safe usage.
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 100%, and the schema itself already documents parameters like confirm (default dry-run) and limit (safety cap 10000). The description repeats these points without adding new parameter-level meaning. It does not clarify encoding of query or fields beyond what the schema already provides, so it fails to add value beyond the structured fields.
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's action: 'Bulk update or delete records matching a query.' It uses a specific verb (update/delete) and resource (records), and the 'Bulk' prefix distinguishes it from single-record siblings like sn_update and sn_delete. Additional details about dry-run and safety cap reinforce its unique identity.
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 implies when to use this tool via the 'Bulk' qualifier, contrasting with single-record operations. It also provides clear execution guidance: dry-run by default, set confirm=true to execute, and a 10,000-record safety cap. However, it does not explicitly mention alternatives for single-record operations, so it stops short of full exclusion guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sn_codesearchA
Search across ServiceNow code artifacts — business rules, script includes, UI scripts, client scripts, and scripted REST operations. Returns matching records with code snippets.
| Name | Required | Description | Default |
|---|---|---|---|
| field | No | Specific field to search (default: script) | |
| limit | No | Max total results (default 20) | |
| table | No | Search a specific table only (default: searches all code tables). Options: sys_script, sys_script_include, sys_ui_script, sys_script_client, sys_ws_operation | |
| search_term | Yes | Text to search for in script fields |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses that the tool returns matching records with code snippets, but does not cover permissions, rate limits, or any side effects. As a read-only search, this is adequate but not rich.
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 two sentences, front-loaded with the action and resource, and every word earns its place. It is clear and efficient without 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?
For a search tool with no output schema, the description explains the return value (matching records with code snippets) and the domain. It relies on the well-documented schema for parameter details, which is appropriate. Minor missing details like ordering or pagination are not critical.
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?
The schema descriptions already cover all parameters at 100%, so the tool description adds no extra parameter-level meaning. The baseline of 3 applies.
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 uses a specific verb ('Search across') and identifies a specific resource ('ServiceNow code artifacts') with a clear enumeration of artifact types. This distinguishes it from generic search tools like sn_query and sn_discover.
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 provides clear context for when to use this tool (searching code artifacts) and implies its scope, but it does not explicitly name alternatives or exclusions. Since siblings exist, the absence of explicit 'use this instead of X' guidance prevents a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sn_createB
Create a new record on any ServiceNow table. Pass field values as a JSON object.
| Name | Required | Description | Default |
|---|---|---|---|
| table | Yes | ServiceNow table name (e.g. incident) | |
| fields | Yes | JSON object of field name/value pairs (e.g. {"short_description":"Server down","urgency":"1"}) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description must carry the full burden. It only states the core action and input; it does not disclose return values, permissions, validation behavior, or consequences of invalid fields.
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 two short sentences, direct and front-loaded, with no redundant or filler content.
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 tool is simple and the schema fully covers parameters, but the description omits expected return values, error handling, and any table-specific constraints. Given the lack of annotations and output schema, more context would be helpful.
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 100% for both parameters, including examples. The description adds no substantive meaning beyond the schema; it merely restates that field values are passed as a JSON object.
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 action ('create') and the resource ('record on any ServiceNow table'), and the creation semantics distinguish it from sibling tools like sn_update, sn_delete, and sn_get.
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?
No explicit usage guidance is provided. It does not mention when to use this tool instead of alternatives like sn_update, nor any exclusions or prerequisites beyond the basic action.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sn_deleteA
Delete a ServiceNow record by sys_id. Requires the confirm flag set to true as a safety measure.
| Name | Required | Description | Default |
|---|---|---|---|
| table | Yes | ServiceNow table name (e.g. incident) | |
| sys_id | Yes | The sys_id of the record to delete | |
| confirm | Yes | Must be true to execute the deletion. Safety measure to prevent accidental deletes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Without annotations, the description must disclose behavioral traits. It mentions the confirm flag safety measure but doesn't state that deletion is permanent or irreversible, nor does it mention permissions or consequences.
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 at two sentences, front-loading the action and purpose, with no superfluous information.
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 the core function and the confirm requirement, but given the destructive nature of the operation and lack of an output schema, it omits important context such as whether deletion is permanent or any success/failure return information.
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?
The input schema already provides full descriptions for all three parameters (table, sys_id, confirm). The description adds no additional parameter semantics beyond restating the confirm requirement.
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's function: deleting a ServiceNow record by sys_id. This distinguishes it from sibling tools like sn_create, sn_update, and sn_get, which handle other CRUD operations.
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 clearly implies when to use it — when deleting a record — and notes the confirm flag requirement. However, it doesn't explicitly mention alternatives or when not to use it, such as for bulk deletions (which might be handled by sn_batch).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sn_discoverB
Discover tables, applications, and plugins installed on the ServiceNow instance.
| Name | Required | Description | Default |
|---|---|---|---|
| type | Yes | What to discover: tables, apps, or plugins | |
| limit | No | Max results (default 20) | |
| query | No | Search by name (LIKE match) | |
| active | No | Filter by active status: true or false (apps and plugins only) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fails to disclose important behavioral details such as return format, default limits, or read-only status. It only says 'Discover,' which implies a listing operation, but does not clarify pagination, filtering behavior, or whether results are limited to installed items only.
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 a single, clear sentence that is front-loaded with the verb and resource list. It contains no filler or redundant information, making it highly concise and easy to parse.
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?
Despite the tool having 4 parameters and no output schema, the description offers only a high-level purpose. It lacks essential context about what the output looks like, how pagination or the limit parameter behaves, and how the active filter applies. This makes it incomplete for an agent to fully understand the tool's behavior.
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?
The input schema has 100% coverage with descriptions for all parameters, including the enum for type and explanations for limit, query, and active. The description adds context by stating the resources are 'installed on the ServiceNow instance,' but does not further elaborate on parameter semantics beyond what the schema already provides.
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 uses a specific verb 'Discover' and clearly names the resources: tables, applications, and plugins installed on the ServiceNow instance. This distinguishes it from sibling tools like sn_query or sn_schema by focusing on installed metadata rather than data querying or schema definitions.
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 provides no explicit guidance on when to use this tool versus alternatives. It does not mention what types of questions it answers or when to prefer sn_schema or sn_query instead, leaving the agent to infer usage solely from the tool name and schema.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sn_getA
Get a single ServiceNow record by sys_id. Returns all fields or a specified subset.
| Name | Required | Description | Default |
|---|---|---|---|
| table | Yes | ServiceNow table name (e.g. incident) | |
| fields | No | Comma-separated list of fields to return | |
| sys_id | Yes | The sys_id of the record to retrieve | |
| display_value | No | Display values mode: true, false, or all |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It discloses the return behavior ('Returns all fields or a specified subset') but does not mention error handling, permissions, or the effect of the display_value parameter. Some transparency is present, but gaps remain.
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 two sentences, front-loads the main purpose, and contains no fluff. Every word is informative, making it highly concise and well-structured.
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?
This is a simple get tool with no output schema. The description explains return behavior and scope, which is adequate. However, it doesn't mention the display_value parameter's effect or error behavior, but given the simplicity and schema coverage, it's nearly complete.
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?
The input schema has 100% coverage with descriptions for all four parameters. The description adds no additional meaning beyond the schema, e.g., it doesn't elaborate on the fields parameter beyond 'specified subset.' Baseline of 3 is appropriate.
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's function: 'Get a single ServiceNow record by sys_id.' It uses a specific verb and resource, and the word 'single' distinguishes it from sibling tools like sn_query, which likely retrieves multiple records.
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 implies usage through the word 'single' but does not explicitly state when to use this tool versus alternatives like sn_query, nor does it provide exclusion criteria or mention any prerequisites. The guidance is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sn_healthA
Check ServiceNow instance health: version, cluster nodes, stuck jobs, semaphores, and key stats (active incidents, P1s, changes, problems).
| Name | Required | Description | Default |
|---|---|---|---|
| check | No | Which health check to run (default: all) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of behavioral disclosure. It does state what is checked, which is useful, but it does not explicitly say whether the operation is read-only, whether it requires elevated privileges, or what the response format looks like. It also doesn't mention any potential side effects from the health checks.
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 a single, compact sentence that is front-loaded with the primary action and resource. Every phrase adds relevant detail without padding or repetition.
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?
For a simple tool with one optional enumerated parameter and no output schema, the description provides a solid overview of the health areas covered. It does not explain the return format or error behavior, but given the low complexity, this is a minor gap rather than a critical omission.
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 100% with an enum, so the baseline is 3. The description adds meaning by mapping specific health categories ('version, cluster nodes, stuck jobs, semaphores, key stats') to the enum values, clarifying what each check encompasses beyond the schema's generic 'Which health check to run'.
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 uses the specific verb 'Check' with the clear resource 'ServiceNow instance health' and enumerates concrete sub-areas (version, cluster nodes, stuck jobs, semaphores, key stats). This clearly distinguishes it from sibling tools like sn_query, sn_get, or sn_discover, which serve different purposes.
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 implies usage as a health-monitoring tool, and the enumerated checks give context. However, it provides no explicit guidance on when to use this instead of alternatives (e.g., sn_get or sn_query), no prerequisites, and no mention of when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sn_nlA
Natural language interface for ServiceNow. Translates plain English into ServiceNow API calls. Supports queries, aggregates, schema lookups, creates, updates, and batch operations. Read operations execute immediately; write operations require execute=true.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | Natural language request (e.g. "show all P1 incidents", "how many open changes", "create incident for VPN outage") | |
| force | No | Required for bulk deletes (in addition to confirm) | |
| confirm | No | Required for batch/bulk operations | |
| execute | No | Execute write operations (reads always execute). Default false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It clearly states that read operations execute immediately while write operations require execute=true, which is a critical behavioral distinction. It does not disclose other potential behaviors like failure modes, permissions, or idempotency, but the most important execution semantics are addressed.
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 three sentences, front-loaded with the tool's essence, and contains no redundant or filler content. Every sentence contributes: what it is, what it supports, and the key execution rule.
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?
Given the tool's complexity (supports many operation types) and the lack of annotations or output schema, the description provides a good high-level overview. It covers the range of operations and the critical execute semantics. It does not mention return formats or limitations, but for a natural language interface, this is reasonably complete.
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?
The input schema already provides full descriptions for all four parameters (text, force, confirm, execute), so schema coverage is 100%. The description adds a useful note about execute=true for writes but does not elaborate on force or confirm beyond what the schema states. Thus, the description adds minimal extra meaning over the 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 this is a natural language interface for ServiceNow that translates plain English into API calls. It lists supported operations (queries, aggregates, schema lookups, creates, updates, batch), distinguishing it from the specific sibling tools like sn_query or sn_create. The verb 'translates' and resource 'ServiceNow' make the purpose explicit.
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 implies usage: use this when the user provides a natural language request. It mentions supported operation types and execution semantics (reads execute immediately, writes need execute=true). However, it does not explicitly state when not to use it or explicitly point to sibling tools as alternatives, leaving some ambiguity about whether direct tools are preferred for programmatic or precise operations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sn_queryA
Query any ServiceNow table. Returns records matching the encoded query with support for field selection, pagination, sorting, and display values.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum records to return (default 20) | |
| query | No | ServiceNow encoded query (e.g. active=true^priority=1). Use ^ for AND, ^OR for OR. | |
| table | Yes | ServiceNow table name (e.g. incident, change_request, sys_user) | |
| fields | No | Comma-separated list of fields to return | |
| offset | No | Pagination offset | |
| orderby | No | Sort field. Prefix with - for descending (e.g. -sys_created_on) | |
| display_value | No | Display values mode: true, false, or all (default: true) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It states the tool 'Returns records' and highlights support for field selection, pagination, sorting, and display values, giving useful context about the tool's behavior. While it doesn't explicitly declare this as a read-only operation, the term 'Query' strongly implies it, and no contrary annotations exist. This is more than adequate for a non-destructive tool.
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 a single, well-structured sentence that front-loads the main purpose ('Query any ServiceNow table') and immediately lists the key features. There is zero wasted words or redundancy, making it highly concise and effective.
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?
Given the tool's complexity (7 parameters, no output schema), the description covers the core purpose and capabilities sufficiently. It does not explain the response structure in detail, but the statement 'Returns records' gives a general expectation. Since the schema already documents parameters thoroughly, the description is nearly complete, though a note on response format would make it fully complete.
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 100%, with each parameter having a detailed description (e.g., query syntax, sort prefix, display modes). The tool description itself adds no additional parameter meaning, so the baseline of 3 is appropriate when the schema already documents parameters well.
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 uses the specific verb 'Query' with the resource 'any ServiceNow table', clearly stating the tool's function. It also lists key capabilities (field selection, pagination, sorting, display values) which distinguish it from sibling tools like sn_get or sn_aggregate. This meets the benchmark for a specific and differentiating purpose.
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 implies usage: this is for querying ServiceNow tables. However, it does not explicitly state when to use this tool over alternatives (e.g., sn_get for single records, sn_aggregate for summary queries) or provide any exclusions. The context is clear but lacks explicit guidance about alternatives, so it falls short of a 4.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sn_relationshipsA
Traverse CMDB CI relationships (graph walk). Supports upstream, downstream, or both directions with configurable depth. Use for impact analysis and dependency mapping.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Filter by relationship type name (substring match) | |
| class | No | Filter displayed CIs by class name (substring match) | |
| depth | No | How many levels deep to traverse (1-5, default from SN_REL_DEPTH or 3) | |
| impact | No | Impact analysis mode — walks upstream only | |
| sys_id | No | Sys_id of the CI to start from (alternative to ci_name) | |
| ci_name | No | Name of the CI to start from (resolved via cmdb_ci name field) | |
| direction | No | Traversal direction (default: both) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the full burden of disclosing side effects and behavior. It implies a read-only operation through 'traverse' and 'impact analysis,' but it does not explicitly state that it makes no modifications, nor does it describe the output structure, behavior when no starting point is provided, or resource implications of deep graph walks. This is a significant transparency gap.
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?
Two sentences, front-loaded with the primary action, no filler. Every phrase adds context (graph walk, directions, depth, use cases). Highly concise and well-structured.
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 tool has 7 optional parameters with no required ones, but logically a starting CI (sys_id or ci_name) is necessary for traversal. The description does not state this requirement or what happens if neither is provided. There is no output schema, and the description fails to mention what the return value looks like (e.g., list of relationships, graph nodes, depth-limited results). This is incomplete for a complex graph-walk tool.
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 100%, so the baseline is 3. The description adds no additional parameter semantics beyond what the schema already documents (e.g., direction, depth, impact mode). It mentions 'both directions' and 'depth' in prose, but these are already in the schema. No value added beyond the structured fields.
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 opens with a specific verb and resource: 'Traverse CMDB CI relationships (graph walk)', clearly distinguishing this from sibling tools like sn_query or sn_get that fetch individual CIs. It also names concrete use cases (impact analysis, dependency mapping) and the key modes (upstream/downstream/both, depth).
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 states 'Use for impact analysis and dependency mapping,' providing clear context for when to invoke this tool. It does not explicitly name alternatives or when not to use it, but the differentiation from siblings is inferred by the traversal focus, and the 'Use for' phrase offers concrete guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sn_schemaA
Get the schema (field definitions) for a ServiceNow table. Returns field names, types, max lengths, mandatory flags, and reference targets.
| Name | Required | Description | Default |
|---|---|---|---|
| table | Yes | ServiceNow table name (e.g. incident) | |
| fields_only | No | If true, return only a sorted list of field names |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It states the return contents (field names, types, max lengths, mandatory flags, reference targets) but does not explicitly confirm that it is read-only, mention authorization needs, or describe potential error conditions. The verb 'Get' implies a safe read, but a few edges are missing.
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 a single, front-loaded sentence that immediately states the purpose and then lists the returned fields. There is no redundant or unnecessary wording.
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 tool is simple (2 parameters, no output schema), and the description adequately covers the key aspects: what the tool does and what it returns. It does not mention the fields_only parameter, but the schema covers that, so the description is complete enough for this straightforward tool.
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 100%, so the input schema already fully documents both parameters (table and fields_only). The description does not add any extra parameter semantics beyond what the schema provides, so the baseline of 3 applies.
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 a specific verb ('Get') and resource ('schema (field definitions) for a ServiceNow table'), and lists what is returned. This distinguishes it from siblings like sn_query or sn_get that fetch records rather than table metadata.
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 implies when to use the tool (when needing field definitions for a table) but does not explicitly mention alternatives or exclusions. No guidance is given on when not to use it or how it compares to sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sn_scriptA
Execute a background script on the ServiceNow instance. Runs server-side GlideRecord/GlideSystem JavaScript and returns output from gs.print() calls. Requires admin role. NOTE: This tool requires the optional Playwright dependency.
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | JavaScript code to execute (GlideRecord, GlideSystem, gs.print(), etc.) | |
| scope | No | Application scope to run in (default: global) | |
| confirm | No | Required for scripts containing destructive keywords (deleteRecord, deleteMultiple, setWorkflow(false)) | |
| timeout | No | Timeout in seconds (default 30, max 300) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the transparency burden and discloses key behavioral traits: admin role requirement, server-side execution, gs.print() return behavior, and the optional Playwright dependency. It does not explicitly mention that scripts may modify data, but the schema already covers the confirm parameter for destructive keywords.
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?
Three sentences, front-loaded with the main purpose, followed by execution details and a dependency note. Every sentence adds value with no filler.
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?
For a script execution tool with 4 parameters and no output schema, the description covers the core purpose, output mechanism, auth prerequisite, and a unique dependency. It could mention potential side effects or error handling, but the schema handles the confirm parameter and the description is otherwise comprehensive.
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 100%, so the baseline is 3. The description adds minimal parameter-specific value beyond the schema—it mentions GlideRecord/GlideSystem and gs.print() but does not elaborate on scope, confirm, or timeout behavior. The schema already documents these parameters sufficiently.
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 executes background scripts on the ServiceNow instance, specifically server-side GlideRecord/GlideSystem JavaScript, returning gs.print() output. This verb+resource combination distinguishes it from sibling tools like sn_query or sn_update, which perform standard operations.
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 provides clear context: it is for executing custom server-side JavaScript, requires admin role, and returns gs.print() output. It does not explicitly name alternatives or when-not-to-use, but the custom-script context implicitly differentiates it from CRUD-focused siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sn_syslogA
Query ServiceNow system logs (syslog table) with severity, source, and time-based filters. Results ordered newest first.
| Name | Required | Description | Default |
|---|---|---|---|
| level | No | Filter by severity level | |
| limit | No | Max records (default 25) | |
| query | No | Raw encoded query (overrides individual filters) | |
| since | No | Show logs from last N minutes (default 60) | |
| fields | No | Fields to return (default: sys_id,level,source,message,sys_created_on) | |
| source | No | Filter by source field (LIKE match) | |
| message | No | Filter message contains text (LIKE match) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses ordering ('newest first') and implies read-only via 'Query', but does not mention default limits, raw query override behavior, or any potential limitations. This is adequate but not rich.
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 a single sentence of 18 words, front-loaded with the purpose. It includes a useful behavioral detail (ordering) without any fluff, making it highly concise and well-structured.
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?
Given the tool's simplicity and the thorough parameter schema, the description is sufficient. It does not explain return values, but none is required since there is no output schema. It omits mention of the raw query override and default limits, but these are covered in the schema descriptions, making the overall package complete enough.
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?
The input schema covers all 7 parameters with detailed descriptions (100% coverage), so the baseline is 3. The description's mention of 'severity, source, and time-based filters' partially maps to level, source, and since, but adds minimal value over the schema's existing documentation.
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 uses a specific verb ('Query') and clearly identifies the resource ('ServiceNow system logs (syslog table)') along with the filter dimensions (severity, source, time-based) and result ordering. This distinguishes it from generic sibling tools like sn_query or sn_get.
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 provides clear context for when to use the tool (querying the syslog table) but does not explicitly mention alternatives or exclusions. The sibling list includes sn_query, which could be ambiguous, but the specialization for syslog is evident from the resource designation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sn_updateA
Update an existing ServiceNow record. Pass the sys_id and field values to change.
| Name | Required | Description | Default |
|---|---|---|---|
| table | Yes | ServiceNow table name (e.g. incident) | |
| fields | Yes | JSON object of field name/value pairs to update (e.g. {"state":"6","close_notes":"Fixed"}) | |
| sys_id | Yes | The sys_id of the record to update |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. While it implies a partial update ('field values to change'), it does not disclose side effects, error handling, authorization requirements, or what happens if the record does not exist. For a mutation tool, this is insufficient behavioral disclosure.
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 two sentences, front-loaded with the main purpose, and contains no filler. Every word earns its place, making it highly concise and well-structured.
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?
With no output schema and no annotations, the description should explain return values or failure modes. It does not mention what the tool returns after an update (e.g., updated record, success indicator), nor does it cover edge cases. For a 3-parameter mutation tool, the description feels incomplete.
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?
The input schema has 100% coverage with clear descriptions for all three parameters (table, sys_id, fields). The description adds minimal extra meaning beyond restating 'Pass the sys_id and field values,' so it does not elevate beyond the baseline.
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's function: 'Update an existing ServiceNow record.' The verb 'Update' and resource 'ServiceNow record' are specific, and it distinguishes from sibling tools like sn_create (create) and sn_delete (delete) by explicitly saying 'existing.'
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 provides clear context that this is for updating existing records and instructs to 'Pass the sys_id and field values to change.' However, it does not explicitly mention when not to use it or name alternative tools such as sn_create or sn_batch, so it falls short of full exclusion guidance.
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.
17 tool updates
v1.0.0- First observed
sn_aggregate - First observed
sn_atf - First observed
sn_attach - First observed
sn_batch - First observed
sn_codesearch - First observed
sn_create - First observed
sn_delete - First observed
sn_discover - First observed
sn_get - First observed
sn_health - First observed
sn_nl - First observed
sn_query - First observed
sn_relationships - First observed
sn_schema - First observed
sn_script - First observed
sn_syslog - First observed
sn_update
TDQS
Scored across 17 tools
Each tool targets a distinct ServiceNow resource or operation (e.g., query vs. get, create vs. update vs. delete vs. batch, schema vs. discover). No two tools appear to do the same thing, and descriptions reinforce clear boundaries.
All tools follow the sn_ prefix and use lowercase snake_case with descriptive words. While some names are nouns (schema, health, syslog), the pattern is uniform and predictable across the entire set.
At 17 tools, the count is slightly above the ideal 3-15 range, but each tool serves a distinct and necessary purpose in ServiceNow administration, making the extra weight reasonable rather than redundant.
The set covers comprehensive CRUD, querying, aggregation, schema, health, attachments, relationships, logs, code search, test automation, and scripting. Minor gaps exist—such as no attachment deletion and batch operations not supporting create—but these are edge cases not core to the domain.
Maintenance
Related MCP Connectors
Independent trust scores, tool surfaces and change history for MCP servers.
MCP server for secureFlows: token-free URL builders and integration-linting tools for AI agents.
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
Read-only MCP access to a documented IT fleet: state, changes, posture. 15 tools.
Related MCP Servers
- AlicenseCqualityAmaintenanceThe most advanced & comprehensive ServiceNow MCP server — 150+ production-ready tools across 17 modules (ITSM, ITOM, HRSD, CSM, SecOps, GRC, Agile, ATF, Flow Designer, Now Assist, and more). Supports multi-instance management, four-tier permission control, 10 role-based tool packages, OAuth 2.0 + Basic Auth, and integrates with Claude, GPT-4o, Gemini, Cursor, VS Code, and Codex.496522 npm275Elastic 2.0
- AlicenseNot gradedqualityDmaintenanceA comprehensive MCP server for ServiceNow that provides over 60 pre-built tools for ITSM, ITOM, and App Dev operations, enabling AI agents to manage incidents, changes, users, service catalog, and projects through a unified interface.6MIT
- AlicenseNot gradedqualityAmaintenanceA metadata-driven MCP server that auto-generates 480+ tools across 160+ ServiceNow tables, with multi-instance support, natural language search, and local script development.1,291 npm53Apache 2.0
- FlicenseCqualityAmaintenanceAn MCP server for ServiceNow that supports multi-factor authentication via real browser (Playwright) and provides tools for reading, writing, and managing ServiceNow artifacts with safety guards.322-