Agent-first, agent-native

The ServiceNow REST API, plus the context that matters.
Catalog variables, flow subflows, related records. Works standalone or with any AI agent.

View on GitHub

Every feature, shown →

npm install -g @jacebenson/jsn

Cross-platform · Works on Windows, macOS, Linux · Requires Node.js

Requirements
  • Node.js required — that is the only runtime dependency
  • Install: npm install -g @jacebenson/jsn — works on Windows, macOS, Linux
  • AI Agents: jsn skill install after auth
Don't have Node.js?

Install Node.js and npm from the official site:
nodejs.org

Or use a version manager:
brew install node (macOS) · sudo apt install nodejs npm (Ubuntu/Debian) · nvm (all platforms)

What it looks like

$ jsn setup
$ jsn skill install
$ jsn skill install

? Where should the jsn skill be installed?
❯◉ Hermes Agent
 ◯ GitHub Copilot
 ◯ VS Code (Copilot Instructions)
 ◯ Claude Code
 ◉ Cursor
 ◯ Agents (open standard)
 ◯ OpenCode

~/.hermes/profiles/holly/skills/servicenow/SKILL.md
(space to toggle, enter to confirm)
$ jsn docs sync
$ jsn docs serve
jsn docs serve — search results for "bill mcdermott"
jsn docs serve — the doc viewer showing "Design considerations for prompting"
$ jsn records list
$ jsn records list --table incident --limit 4

4 incident(s)


number          short_description                                 priority        state       assigned_to      
--------------  ------------------------------------------------  --------------  ----------  ---------------  
INC0000014      Missing my home directory test-1                  1 - Critical    Closed      Bud Richman      
INC0000601      The USB port on my PC stopped working             5 - Planning    Closed                       
INC0009004      Defect tracking tool is down.                     3 - Moderate    Closed                       
INC0000005      CPU load high for over 10 minutes                 1 - Critical    Closed      Bud Richman      

  → create: jsn inc create --description "..." — Create a new incidents
  → filter: jsn inc list --query "priority=1" — Filter: critical only
  → next: jsn inc list --limit 4 --offset 4 — Next page (offset 4)
$ jsn incidents create
$ jsn incidents create \
    --description "Demo: read me in the hero" \
    --data '{"urgency":"3","impact":"3"}'

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  ⚠  Default update set in scope [x_8821_test]
  Changes are contained to this scope, but a named
  update set is still recommended for tracking.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Created incidents INC0010019


INC0010019 (incident)

─ Core ─
  number:  INC0010019
  sys_id:  3b753e3c83be8f10f7bfc670ceaad3e7
  sys_class_name:  incident
  state:  1
  active:  true
  short_description:  Demo: read me in the hero
  description:  
  priority:  5
  urgency:  3
  impact:  3

─ People ─
  opened_by:  6816f79cc0a8016401c5a33be04be441

─ Status ─
  approval:  not requested
  escalation:  0
  made_sla:  true

─ Dates & Times ─
  opened_at:  2026-08-17 03:13:22
  sys_created_on:  2026-08-17 03:13:22

  → view: jsn inc show INC0010019 — View the new incidents
$ jsn catalogitems create
$ jsn catalogitems create \
    --name "Demo Hero Laptop" \
    --variable "model:string:Model" \
    --variables '{"model":"X1 Carbon"}'

Created: Demo Hero Laptop (1 variable(s))
$ jsn records delete
$ jsn records delete --table incident --sys-id <id>

Error: Delete record from incident (57e8723483fe8f10f7bfc670ceaad3aa) — confirmation required. Pass --force to skip, or set skip_confirmations on the profile to disable prompts.

This is a destructive action. Ask your user to confirm, then re-run:
  jsn records delete --force
Or set skip_confirmations on the profile to disable prompts:
  jsn auth login <instance> --skip-confirmations

$ jsn records delete --table incident --sys-id 57e8723483fe8f10f7bfc670ceaad3aa --force
Deleted record from incident
$ jsn records bulk
$ jsn records bulk \
    --table incident \
    --query "active=true" \
    --set '{"state":"2"}'

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  ⚠  Default update set in scope [x_8821_test]
  Changes are contained to this scope, but a named
  update set is still recommended for tracking.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Dry run: 40 record(s) in incident would be updated
$ jsn cmdb relationships
$ jsn cmdb relationships --ci <sys_id>

CMDB: ThinkStation S20 (Computer)
Sys ID: 01a9ec0d3790200044e0bfc8bcbe5dc3
────────────────────────────────────────────────────────
▶ RELATIONSHIPS (23)
────────────────────────────────────────────────────────
▶ PARENTS
  (none)

**YOU ARE HERE** ThinkStation S20 (Computer)

▶ CHILDREN
└─ ↓ Blackberry (Service) — Applicative Flow To::Applicative Flow From
   ├─ ↓ Email (Service) — Depends on::Used by
   │  ├─ ↓ IronMail-SD-01 (Email Server) — Depends on::Used by
   │  ├─ ↓ IronMail-SD-02 (Email Server) — Depends on::Used by
   │  └─ ↓ EXCHANGE-NY-02 (Email Server) — Depends on::Used by
   └─ ↓ INSIGHT-NY-03 (Server) — Depends on::Used by


  → show: jsn cmdb show 01a9ec0d3790200044e0bfc8bcbe5dc3 — Full record for the root CI
  → impact: jsn cmdb relationships --ci 01a9ec0d3790200044e0bfc8bcbe5dc3 --impact — Impact analysis: upstream only
  → deeper: jsn cmdb relationships --ci 01a9ec0d3790200044e0bfc8bcbe5dc3 --depth 5 — Traverse deeper (max depth 5)
  → filter: jsn cmdb relationships --ci 01a9ec0d3790200044e0bfc8bcbe5dc3 --type "<rel type>" --class "<ci class>" — Filter by relationship type or CI class
$ jsn flows show
$ jsn flows show "Service Catalog item request"

Flow: Service Catalog item request

  Status: Active | Version: 2
  Sys ID: 30f3d26187e92300e0ef0cf888cb0b91
  Link: https://dev227772.service-now.com/sys_hub_flow.do?sys_id=30f3d26187e92300e0ef0cf888cb0b91

▶ TRIGGER
──────────────────────────────────────────────────
  Name: Service Catalog
  Type: Service Catalog

⚡ FLOW STRUCTURE
──────────────────────────────────────────────────
1. ↪ Requested Item Manager Approval
   1. Ask For Approval
     Record: {{subflow.requested_item}}
     Table: Requested Item
     Approval Field: approval
     Journal Field: approval_history
     Rules: ApprovesAnyU[{{subflow.requested_item.requested_for.manager}}]OrRejectsAnyU[{{subflow.requested_item.requested_for.manager}}]
     Due Date: {"action":"none","date_type":"actual","date":"{{}}","duration":1,"duration_type":"days","schedule":"","schedule_label":""}
$ jsn requests show
$ jsn requests show RITM0010001

Request RITM0010001


RITM0010001 (Requested Item)

─ Core ─
  number:  RITM0010001
  sys_id:  02dedb44839e8b10f7bfc670ceaad36c
  sys_class_name:  Requested Item
  state:  Open
  active:  true
  short_description:  Submit a nulledge knowledge speaking session
  description:  
  priority:  4 - Low
  urgency:  3 - Low
  impact:  3 - Low

─ People ─
  opened_by:  System Administrator

─ Status ─
  approval:  Approved
  approval_set:  2026-07-20 18:47:16
  escalation:  Normal
  made_sla:  true

─ Dates & Times ─
  opened_at:  2026-07-20 18:47:11
  sys_created_on:  2026-07-20 18:47:11
  sys_updated_on:  2026-07-20 18:47:16
  due_date:  2026-07-22 18:47:11
  sla_due:  UNKNOWN
  activity_due:  UNKNOWN

─ System ─
  sys_domain:  global
  sys_domain_path:  /
  sys_created_by:  admin
  sys_updated_by:  system
  sys_mod_count:  2

─ Other ─
  backordered:  false
  billable:  false
  business_duration:  
  business_service:  
  calendar_duration:  
  cat_item:  Knowledge Speaking Session
  close_notes:  
  cmdb_ci:  
  comments:  
  comments_and_work_notes:  
  company:  
  configuration_item:  
  contact_type:  
  context:  
  contract:  
  correlation_display:  
  correlation_id:  
  delivery_plan:  DEFAULT
  delivery_task:  
  estimated_delivery:  
  flow_context:  
  follow_up:  
  group_list:  
  knowledge:  false
  location:  
  order:  
  order_guide:  
  parent:  
  price:  $0.00
  quantity:  1
  reassignment_count:  0
  recurring_frequency:  
  recurring_price:  $0.00
  request:  REQ0010001
  requested_for:  System Administrator
  route_reason:  
  sc_catalog:  
  service_offering:  
  skills:  
  stage:  Assess or Scope Task
  task_effective_number:  RITM0010001
  task_for:  
  time_worked:  
  universal_request:  
  upon_approval:  Proceed to Next Task
  upon_reject:  Cancel all future Tasks
  user_input:  
  work_notes:  
  work_notes_list:  

─ Catalog Variables ─
  Topic:  Moveworks!  What is Slate?  He can tell you!
  Speaker:  Teo

Link:  https://dev227772.service-now.com/requested_item.do?sys_id=02dedb44839e8b10f7bfc670ceaad36c


  → update: jsn req update RITM0010001 --data '{...}' — Update this request
  → list: jsn req list — Back to all requests
$ jsn dev updatesets
$ jsn dev updatesets list

3 update set(s)


name                            state       application           application.scope     
------------------------------  ----------  --------------------  --------------------  
Holly Export Test C             In prog...  test                  x_8821_test           
Holly Export Test B             In prog...  test                  x_8821_test           
Holly Export Test A             Complete    test                  x_8821_test
$ jsn atf list
$ jsn atf list

3 record(s)


name                            sys_class_name        active                sys_updated_on          
------------------------------  --------------------  --------------------  ----------------------  
SKILLS MGMT: Skill level in...  Test                  false                 2019-11-23 23:13:07     
CHG:High Risk With Ui Actio...  Test                  false                 2019-09-12 06:32:32     
RecordAction With Mappings      Test                  true                  2016-07-18 15:17:04
$ jsn dev eval
$ jsn dev eval --script 'gs.info("hello");'

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  ⚠  Default update set in scope [x_8821_test]
  Changes are contained to this scope, but a named
  update set is still recommended for tracking.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Script executed ⚠️ Records without explicit sys_scope will land in global. Use $scopeSysId variable.


  → eval: jsn eval --script '...' — Execute a background script on the ServiceNow instance

Why jsn exists

When I started this in March 2026, the ServiceNow SDK couldn't read a record from a live instance. It could only build. So I built what I wanted: a CLI that works with your data across scopes.

now-sdk added live queries in June 2026. Good for them. But reading records was never the whole point.

What it does that plain REST doesn't

Context, not just REST

Load a catalog item and get its variables. Load a flow and get its subflows. Related records, resolved. Plain REST doesn't do that.

Agent-Native

JSON output and breadcrumbs for agents. Works with Hermes, Claude, Codex, Cursor, OpenCode, Copilot. The skill is a markdown file, no MCP server to stand up. CLIs run on a fraction of the context MCP servers eat (why), and even the protocol's own repo admits the bloat problem (discussion #2036).

jsn incidents list --json # Structured output
jsn skill install # Expert knowledge for your agent

The docs, local

All ~50,000 ServiceNow docs, indexed, searchable instantly, offline. Ask the difference between Flow Designer and Playbooks and get an answer from the docs, not a guess.

Auth that just works

OAuth handled. The part raw AI plus REST keeps tripping on.

Safe by default

Read-only by default. Deletes are blocked unless you pass --force. You can even mark a profile read-only and mutations are blocked entirely.

Small by design

They declare 3 dependencies. You end up with 628 packages and 353 MB. We declare 6. You end up with 90 and 41 MB. None of ours are abandoned. Three of theirs are.

Install: npm install -g @jacebenson/jsn · Auth: jsn setup · Agents: jsn skill install

Full setup guide & skill docs →

Open source, MIT. Runs locally. No analytics, nothing phones home. Credentials stay in your config.

Iron sharpens iron — inspired by now-sdk, sn (Rust), Nanda's now-sdk-ext-mcp, and @onlyflows/servicenow-mcp.