npm package: @imjaineel-dev/sn-mcp-server
Description: Multi-instance read-only MCP server for ServiceNow
Author: ImJaineel
Latest version: 2.1.1

# 📘 SN-MCP-Server

A **read-only Model Context Protocol (MCP) server** for ServiceNow — built for developers, AI workflows, and tools that need deep visibility into ServiceNow across **multiple instances** (Prod, Dev, Test, PDI).

[![npm version](https://img.shields.io/npm/v/@imjaineel-dev/sn-mcp-server)](https://www.npmjs.com/package/@imjaineel-dev/sn-mcp-server)
[![Node.js](https://img.shields.io/badge/node-%3E%3D18.3.0-brightgreen)](https://nodejs.org)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)

---

## ✨ Features

- 🔗 **Multi-instance** — Prod, Dev, Test, PDI in one server
- 🔍 **Powerful querying** — Table, Aggregate, Code Search APIs
- 🧠 **Intelligent record resolution** — INC, CHG, RITM, sys_id
- 🔄 **Flow Designer + Legacy Workflows**
- 🧩 **Schema inspection & discovery**
- 👥 **Identity & access data**
- 🔑 **Multiple Auth Methods** — Basic Auth and OAuth 2.0 (Client Credentials, Password, Auth Code, JWT)
-  **Read-only by design** — safe on production instances
- 📄 **Per-run log files** — one file per server start, stored in OS temp folder
- 🔬 **Verbose tool logging** — per-call called/received debug lines (instance, args, result summary) when `SN_MCP_VERBOSE=true`

---

## 🚀 Quick Start

### Option A — npx (no install needed)

```bash
npx @imjaineel-dev/sn-mcp-server --config ./sn-instance.json
```

### Option B — Local clone

```bash
git clone https://github.com/ImJaineel/SN-MCP-Server.git
cd SN-MCP-Server
npm install
npm start   # auto-detects sn-instance.json in repo root
```

---

## ⚙️ Configuration

### 1. Create `sn-instance.json`

```json
{
  "default": "dev",
  "instances": [
    {
      "alias": "prod",
      "label": "Production",
      "instance": "mycompany-prod",
      "auth": "oauth2",
      "grant_type": "client_credentials",
      "client_id": "your-client-id",
      "client_secret": "your-client-secret"
    },
    {
      "alias": "dev",
      "label": "Development",
      "instance": "mycompany-dev",
      "auth": "basic",
      "username": "svc_mcp_readonly",
      "password": "your-password-here"
    }
  ]
}
```

> 📄 Full example: [sn-instance.example.json](https://raw.githubusercontent.com/ImJaineel/SN-MCP-Server/main/sn-instance.example.json)

#### Common fields

| Field | Required | Description |
|---|---|---|
| `alias` | ✅ | Short name used in tool calls (`"prod"`, `"dev-2"`) |
| `instance` | ✅ | Subdomain (`"mycompany-dev"`) or full URL (`"https://..."`) |
| `auth` | optional | `"basic"` (default) or `"oauth2"` |
| `label` | optional | Human-friendly display name |
| `default` | optional | Top-level field — set to an alias name (e.g. `"dev"`) to make it the default instance |

#### Basic Auth (`auth: "basic"`)

| Field | Required | Description |
|---|---|---|
| `username` | ✅ | Service account username |
| `password` | ✅ | Password or API token |

#### OAuth 2.0 (`auth: "oauth2"`)

| Field | Required | Description |
|---|---|---|
| `grant_type` | ✅ | `"client_credentials"`, `"password"`, `"authorization_code"`, or `"jwt_bearer"` |
| `client_id` / `client_secret` | ✅ | OAuth application credentials |
| `username` / `password` | conditional | Required for `password` grant |
| `refresh_token` | conditional | Required for `authorization_code` grant |
| `jwt_private_key` / `jwt_subject` | conditional | Required for `jwt_bearer` grant (PEM key string & subject user) |
| `token_url` | optional | Override the default token endpoint (default: `/oauth_token.do`) |

The **first entry** is the default unless a top-level `"default"` alias is set.

---

### 2. Environment variables (optional)

All optional — set in your shell, in the MCP client `"env"` block, or using a `.env` file.

> **Note:** If you are running the server from a local clone, you can create a `.env` file in the project root to manage these variables easily.

| Variable | Description | Default |
|---|---|---|
| `SN_INSTANCE_CONFIG` | Path to `sn-instance.json` | Auto-resolved |
| `SN_MCP_VERBOSE` | Set to `"true"` to enable debug logs | `false` |
| `LOGS_TIMEZONE` | IANA timezone for log timestamps | OS timezone |
| `SN_LOG_DIR` | Override log file directory | OS temp folder |

---

## 🔌 MCP Client Setup

### For Anyone, Everyone

> **VS Code:** Press `Ctrl+Shift+P`, select **Add MCP**

> **Claude Desktop:** Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows)

> **Gemini Code Assist:** Create or edit `~/.gemini/mcp.json`

> **Amazon Q:** Create or edit `~/.aws/amazonq/mcp.json`

**Using npx (recommended):**

```json
{
  "mcpServers": {
    "servicenow": {
      "command": "npx",
      "args": ["sn-mcp-server", "--config", "/absolute/path/to/sn-instance.json"],
    }
  }
}
```

**Using local clone:**

```json
{
  "mcpServers": {
    "servicenow": {
      "command": "node",
      "args": ["/absolute/path/to/SN-MCP-Server/src/index.js"]
    }
  }
}
```

> ⚠️ Always use **absolute paths** in MCP client configs.

---

## ▶️ Running locally

```bash
# Standard start (auto-detects ./sn-instance.json)
npm start

# With explicit config path
node src/index.js --config /path/to/sn-instance.json

# With verbose logging
npm run dev
node src/index.js --config ./sn-instance.json --verbose

# Auto-restart on file changes (development)
npm run watch

# Open MCP Inspector UI in browser (test tools interactively)
npm run inspect

# Show help
npx sn-mcp-server --help
```

---

## 🪵 Logs

Each server run creates a new timestamped log file:

```
2026-04-09T14-32-01.123Z.log
```

Stored in the OS temp directory:

| OS | Default log location |
|---|---|
| Windows | `%TEMP%\ImJaineel_SN-MCP-Instance_logs\` |
| macOS | `$TMPDIR/ImJaineel_SN-MCP-Instance_logs/` |
| Linux | `/tmp/ImJaineel_SN-MCP-Instance_logs/` |

Override with `SN_LOG_DIR` env var. Log files are cleaned up automatically by the OS on reboot.

The startup banner always prints the exact log file path:
```
Log file : /tmp/ImJaineel_SN-MCP-Instance_logs/2026-04-09T14-32-01.123Z.log
```

---

## 🧰 Available Tools

| Tool | Description |
|---|---|
| `sn_list_instances` | List all configured instances |
| `sn_ping` | Test connectivity to an instance |
| `sn_get_identity` | Query users, groups, and group membership |
| `sn_inspect_table` | Inspect table schema or search for tables by name |
| `sn_aggregate_table` | Aggregate queries (count, sum, avg, min, max) with group by |
| `sn_query_table` | Generic read from any ServiceNow table |
| `sn_get_record` | Universal record fetcher — by sys_id, number, task table, or CMDB CI class |
| `sn_get_attachment` | Retrieve attachment metadata or content — by sys_id, query, or file name |
| `sn_get_update_sets` | List Update Sets or drill into their contents |
| `sn_code_search` | Search across all scripting artifacts using Code Search API |
| `sn_get_scripted_artifacts` | Fetch Script Includes, Business Rules, Client Scripts, UI Actions, Scheduled Jobs, Fix Scripts, Scripted REST APIs/Resources |
| `sn_legacy_workflow_search` | Search legacy (classic) workflows by keyword — scans activity variable values across all matching records, resolves to published workflow versions, returns grouped results with activity types |
| `sn_get_legacy_workflow_artifacts` | Fetch legacy Workflows, Versions, Activities, Transitions, Contexts |
| `sn_get_workflow_studio_artifacts` | Fetch Flows, Subflows, Actions, Triggers, Playbooks, Decision Tables |

All tools accept an optional `instance` parameter to target a specific alias. Omit to use the default.

---

## 💡 Usage Examples

### Target a specific instance

```
sn_get_scripted_artifacts  table="sys_script_include"  query="nameLIKEMorpheus"  instance="prod"
sn_query_table  table="incident"  query="state=1"  instance="dev"
sn_get_update_sets  instance="pdi"
```

### Query incidents

```json
{ "tool": "sn_query_table", "table": "incident", "query": "active=true", "limit": 5 }
```

### Get record by number

```json
{ "tool": "sn_get_record", "number": "INC0012345" }
```

### Search legacy workflows

```json
{ "tool": "sn_legacy_workflow_search", "query": "morpheus", "instance": "prod" }
```

### Aggregate

```json
{
  "tool": "sn_aggregate_table",
  "table": "incident",
  "aggregates": [{ "field": "priority", "function": "count" }],
  "group_by": ["priority"]
}
```

---

## 📁 Project Structure

```
SN-MCP-Server/
├── src/
│   ├── cli.js            ← npx entrypoint (--config, --verbose, --help)
│   ├── index.js          ← server bootstrap (also works as direct node target)
│   ├── config.js         ← config path resolution
│   ├── validator.js      ← sn-instance.json schema validation
│   ├── constants.js      ← single source of truth for repo/example URLs
│   ├── env-loader.js     ← .env file parser (no external deps)
│   ├── logger.js         ← structured logger, per-run log files
│   ├── multi-client.js   ← multi-instance routing
│   ├── sn-client.js      ← per-instance REST client
│   ├── handler.js        ← tool name → method router
│   └── tools.js          ← MCP tool definitions
├── scripts/
│   └── dev.js            ← Script store log locally in repo folder for developer
├── sn-instance.json          ← your credentials (git-ignored)
├── sn-instance.example.json  ← template
├── .env.example              ← env var documentation
└── package.json
```

---

## ⚠️ Troubleshooting

**Invalid credentials**
- Verify username/password in `sn-instance.json`
- Ensure the account has REST API access enabled in ServiceNow

**Instance unreachable**
- Check the `instance` value format — subdomain or full URL
- Verify VPN / network connectivity

**`sn-instance.json` validation error**
- The server prints a specific error message pointing to the exact field/entry
- See the example: [sn-instance.example.json](https://raw.githubusercontent.com/ImJaineel/SN-MCP-Server/main/sn-instance.example.json)

**MCP client not detecting server**
- Always use absolute paths in MCP client config
- Restart the MCP client after config changes

---

## 🔐 Security Notes

- `sn-instance.json` is in `.gitignore` — never commit it
- Use a dedicated read-only service account per instance
- PDI instances can use `admin` credentials safely since they're isolated
- Do not store credentials in environment variables in shared environments

<!-- ---

## 🧪 Testing before npm publish

```bash
# Verify scripts
npm run watch    # auto-restarts on file changes
npm run inspect  # opens MCP Inspector in browser

# Test with npm link (active development)
npm link
sn-mcp-server --config ./sn-instance.json

# Test exact publish artifact (pre-publish verification)
npm pack
npx ./sn-mcp-server-2.1.1.tgz --config ./sn-instance.json

# Preview what files will be in the package
tar -tzf sn-mcp-server-2.1.1.tgz
``` -->

---

## 🤝 Contributing

PRs welcome! Please open an issue first for larger changes.

---

## 📄 License

MIT