ServiceNow

Lightweight, dependency-free, in-memory fake of the ServiceNow Table API for testing code that talks to the ServiceNow REST Table API directly.

Default port: 4784

Quick start

import { ServicenowServer } from "./services/servicenow/src/server.js";

const server = new ServicenowServer(4784);
await server.start();
// ... run your app/tests ...
await server.stop();

Point a client at it:

const base = "http://127.0.0.1:4784";
const basic = Buffer.from("admin:pat-parlel").toString("base64");
const res = await fetch(`${base}/api/now/table/incident`, {
  method: "POST",
  headers: { Authorization: `Basic ${basic}`, "Content-Type": "application/json" },
  body: JSON.stringify({ short_description: "Email down", priority: "1" }),
});
// => { result: { sys_id, number: "INC0000001", short_description, ... } }

Access via MCP / preview URL

Plain HTTP at http://127.0.0.1:4784, reachable through the parlel MCP/preview proxy under the slug servicenow.

Implemented operations

All /api/now/table/* routes require Authorization: Basic <...> (or Bearer). State is in-memory and ephemeral.

Records are wrapped under result (single: { result: {...} }; collection: { result: [...] }). Each record gets a 32-char hex sys_id, a number (INC…, PRB…, CHG…, else REC…), and sys_created_on / sys_updated_on.

Table API — /api/now/table/:tableName

Any table name is accepted (incident, problem, change_request, custom tables, …).

Service & inspection operations (parlel extensions)

Surface coverage

This emulator faithfully replicates the API surface most application code and agents exercise. Anything below the supported lines is either an intentional design choice for a fast, zero-cost local emulator (✓ By design) or a candidate for a future release (⟳ Roadmap) — never a silent inaccuracy.

Legend: ✅ fully supported · ◐ accepted (stored, not strictly enforced) · ✓ by design · ⟳ on the roadmap.

FeatureStatus
Table CRUD (any table)✅ Supported
sys_id (32-hex) + auto number✅ Supported
sysparm_query (field=value^...), sysparm_limit/offset✅ Supported
Basic + Bearer auth✅ Supported
Display-value vs raw-value (sysparm_display_value)◐ Raw values only
Reference field resolution / dot-walking⟳ Roadmap — Not resolved
ACLs / business rules / workflows⟳ Roadmap
Aggregate / Import Set / Attachment APIs⟳ Roadmap
Credential validity◐ Any well-formed Basic/Bearer accepted

Error codes & shapes

Errors use the ServiceNow envelope { error: { message, detail }, status: "failure" }.

StatusWhen
400malformed JSON body
401no Basic/Bearer auth
404unknown sys_id / endpoint
405method not allowed for the path

Manifest

See services/servicenow/manifest.json: name servicenow, port 4784, protocol http, healthcheck /health, startup ≈ 100ms, env SERVICENOW_USERNAME, SERVICENOW_PASSWORD, SERVICENOW_BASE_URL.

<!-- parlel:testenv:start -->

Configuration — test.env

Copy these into your test.env (used by the bridge sidecar flow). Tokens are Parlel's seeded test credentials — any non-empty value is accepted by the emulator, so you rarely need to change them. Swap in real credentials only when pointing at the live service in prod.env.

SERVICENOW_USERNAME=admin
SERVICENOW_PASSWORD=pat-parlel
SERVICENOW_BASE_URL=http://parlel-bridge:4784
<!-- parlel:testenv:end -->