sn-mcp-example
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., "@sn-mcp-exampleFind all open incidents with priority 1"
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.
sn-mcp-example — ServiceNow MCP Server on Cloudflare Workers
A deploy-in-minutes Model Context Protocol (MCP) server for ServiceNow, running on Cloudflare Workers. Give any MCP-capable AI agent (Claude Code, Claude Desktop, Cursor, …) safe read/write access to your instance through the Table API — no agents installed on the instance, no MID server, no plugin.
Part of the "AI Engineer 3 Ways" talk — this repo is The MCP Way:
Way | What the AI gets | Repo |
The MCP Way | Curated, typed, documented tools | this repo |
The Table API Way | Raw REST + a great | (separate repo) |
The CLI Way | A lifecycle-driven CLI ( |
Quick start (local)
bun install # or npm install
cp .dev.vars.example .dev.vars # fill in your instance + credentials
bun run dev # http://localhost:8787Test it with the MCP Inspector:
npx @modelcontextprotocol/inspector
# Transport: Streamable HTTP → URL: http://localhost:8787/mcpGotcha: quoting basic-auth values in .dev.vars
wrangler dev parses .dev.vars dotenv-style, and unquoted values are
silently truncated at the first # ($ also gets variable-expanded).
Generated ServiceNow passwords usually contain #, $, = — so an
unquoted password arrives mangled and every call fails with
401 User is not authenticated. Always single-quote the values (single
quotes are taken literally):
SN_INSTANCE='https://dev000000.service-now.com'
SN_USERNAME='mcp_service_user'
SN_PASSWORD='p@ss w1th #$pecial chars'If your .dev.vars credentials are correct but you still get 401s, this is
the first thing to check.
Related MCP server: NowAIKit
Hook it into Claude Code
claude mcp add --transport http servicenow-dev http://localhost:8787/mcpOr add to ~/.claude.json:
{
"mcpServers": {
"servicenow-dev": {
"type": "http",
"url": "http://localhost:8787/mcp"
}
}
}Deploy to Cloudflare
bunx wrangler login
bun run deployThen set your secrets (they become live immediately, no redeploy needed):
bunx wrangler secret put SN_INSTANCE # https://dev000000.service-now.com
bunx wrangler secret put SN_USERNAME # a service account, NOT your admin user
bunx wrangler secret put SN_PASSWORDwrangler deploy prints your worker URL; your MCP endpoint is <url>/mcp.
CI/CD: the included GitHub Actions workflow (
.github/workflows/deploy.yml) deploys on every push tomain— addCLOUDFLARE_API_TOKENandCLOUDFLARE_ACCOUNT_IDas repo secrets and it just works.
Security notes (please read)
Create a dedicated ServiceNow user for the MCP server. For development, you probably want admin. If you wanted to be granular, you could do specific "admin-like" roles - but that is out of scope of this.
Credentials live in Workers secrets /
.dev.vars— never in git, never sent to the AI. The agent talks to this server; only this server talks to ServiceNow.sn_run_scriptis powerful by design — it executes server-side JS. Keep the credential least-privileged, and removetools-script.ts/tools-cicd.tsregistrations insrc/tools.tsif you want a read-only or table-API-only server.If you expose this publicly, put your own auth in front of
/mcp(the MCP spec's HTTP authorization flow, a Cloudflare Access policy in front of the worker, or a simple shared-token check) — an open MCP endpoint is an open door to your instance.
Tools
Tool | What it does |
| Live schema of any table (fields, types, mandatory, references) via |
| Encoded-query search over any table |
| Fetch one record by |
| Insert a record |
| Patch a record by |
| Run server-side JavaScript (GlideRecord) via a one-shot |
| Show the update set the credential is currently capturing into |
| Point the credential at a named update set (GlideRecord script) so agent work is captured and reviewable |
| Trigger an ATF test suite through |
| Scan update sets with an Instance Scan suite through |
The bundled memo://about resource explains the recommended agent flow
(discover schema → query → act) to any client that reads resources.
Context efficiency by design
Modern models tool-call well, MCP is stateless, and clients can defer tools. So the anti-bloat job for this server is narrow: keep the tool surface small, make every tool do more per call, and stay compatible with client-side deferral. (Anthropic's advanced tool use, MCP client best practices.)
Few tools, rich params. Ten tools, each composable at call time —
sn_query_recordstakes an encodedquery,fields,limit,offset, anddisplayValue, so the model filters server-side in one call instead of paginating raw tables through its context. A param is cheaper than a tool.Stateless sessionless transport. Every
POST /mcpis independent — no Durable Objects, no session state,GETanswers 405. Nothing to keep warm, nothing to evict.One call, one result. The CI/CD tools trigger and poll
/api/sn_cicdinside the server; the agent never sees the ~20 progress round-trips.sn_get_table_schemafolds two Table API reads into one compact schema.sn_run_scriptis the escape hatch. For work no param can express, the agent sends one GlideRecord script; intermediates stay on the instance and onlysetScriptOutputreturns (hard-capped at 4 KB with a truncation hint).Compact responses. Record summaries strip the Table API's
{value, display_value, link}envelope; limits cap row counts.Annotations on every tool (
readOnlyHint,destructiveHint,idempotentHint,openWorldHint) so hosts can reason about parallelism, retry safety, and confirmation policies without guessing.Free discovery, cheap listing. Unconfigured servers list zero tools; configured servers list deterministic definitions with 2026-07-28
ttlMs/cacheScopecache hints so host prompt-caching holds.
Deferral and progressive discovery are client features — nothing to
implement server-side. Descriptive sn_* names and keyword-rich
descriptions are what Tool Search matches against; keep that discipline
when adding tools.
If this server grows toward 100 tools
In order of leverage — take each step only when the previous one stops being enough:
Param before tool. Before registering a new tool, try adding a parameter to an existing one (a
kind,mode, orqueryvalue). Ten composable tools beat thirty overlapping ones — in context cost and in tool-selection accuracy.Split by audience into separate workers. Reads vs writes vs CI/CD, each with its own credential scope. Hosts keep the read server always-on and connect the write server only for tasks that need it — server-level deferral beats tool-level deferral.
Add the three-layer discovery pair —
sn_search_tools(name + one-line description) andsn_get_tool_details(one full schema) — once definitions genuinely cost context. Thresholds from the guidance: Anthropic flags >10K tokens of definitions or selection-accuracy problems; the MCP guidance says switch when definitions cross 1-5% of the window. In practice: dozens of tools, not tens.
Project layout
src/
index.ts Workers entrypoint — Hono app, sessionless /mcp endpoint
server.ts McpServer factory: name/version + about resource
tools.ts Shared tool helpers + registration entrypoint
tools-table.ts Table API tools (query/get/create/update/schema)
tools-script.ts sn_run_script + the update-set switcher
tools-cicd.ts ATF suite runs + instance scans via /api/sn_cicd
servicenow.ts Table API + sys_trigger script runner + CI/CD helpers
.github/workflows/deploy.yml Deploy-on-push to Cloudflare
wrangler.jsonc Cloudflare configThe agent-safe CI/CD loop
The tools compose into a closed loop where the agent proves its own work:
sn_switch_update_setinto a dedicatedAGENT-WORKupdate setAgent builds changes (create/update records, run scripts)
sn_run_instance_scanover that update set — code-quality gatesn_run_atf_suite— functional gate (optional)Human reviews the update set and ships it (or
sn validatein the CLI way)
Every change is captured, every change is scanned, every change is tested — by the same AI that made them.
Adding your own tool
src/tools.ts is the only file you need to touch:
server.registerTool("sn_count_open_incidents", {
description: "Count open P1 incidents",
inputSchema: z.object({}),
}, async () => {
const rows = await client.queryTable({
table: "incident",
query: "active=true^priority=1",
fields: ["sys_id"],
limit: 1,
});
return json({ open_p1s: rows.length });
});License
MIT — see LICENSE. Steal this. Build something awesome.
This server cannot be deployed
Maintenance
Related MCP Connectors
Let AI agents query data and act across all your business apps via MCP.
Unified MCP Server is a remote MCP connector for AI agents and vertical AI products that provides access to 22,000+ authorized SaaS tools across 400+ integrations and 24 categories directly inside LLMs (Claude, GPT, Gemini, Cohere). Tools operate only on explicitly authorized customer connections, enabling agents to safely read and write against live third-party systems.
Governed app access for AI agents: 1,000+ apps & 12,000+ tools via Code Mode MCP.
Automate 1,000+ services from any MCP-compatible AI agent: build Applets, run actions and queries.
Related MCP Servers
- AlicenseAqualityAmaintenanceEnables AI agents to interact with ServiceNow through MCP, providing schema inspection, record CRUD, attachments, audit, Flow Designer, and platform investigations with policy-guarded access.15305 PyPI4MIT
- AlicenseCqualityAmaintenanceEnables AI to interact with ServiceNow instances via MCP, providing 400+ tools across all modules for automation, development, and management.5001,107 npm17Elastic 2.0
- AlicenseCqualityBmaintenanceEnables natural language control of ServiceNow from AI clients like Claude and Cursor. Provides 400+ tools for incidents, changes, CMDB, and scripts via MCP protocol.100286 npm2MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with ServiceNow instances for data retrieval, record management, and workflow execution via the ServiceNow API.MIT