# SN-MCP-Server

**Category:** 💻 Developer Tools  
**Repository:** https://github.com/ImJaineel/SN-MCP-Server  
**Views:** 1  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/sn-mcp-server

## Description
Multi-instance read-only MCP server for ServiceNow

## Claude Desktop Quick Installation
Heuristic fallback — verify the package name and runner against the repository README before running it. Uses `npx` (confidence: low):

```json
"mcpServers": {
  "sn-mcp-server": {
    "command": "npx",
    "args": ["-y","sn-mcp-server"]
  }
}
```

## Documentation & README

# 📘 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).

<!-- [![GitHub Package](https://img.shields.io/github/package-json/v/ImJaineel/SN-MCP-Server?label=GitHub%20Packages&logo=github)](https://github.com/ImJaineel/SN-MCP-Server/packages) -->
[![NPM Package](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%3D22.0.0-brightgreen)](https://nodejs.org)
[![License](https://img.shields.io/badge/any_text-Personal_Use_Only-blue?label=License&color=blue)](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)
- 🧰 **ServiceNow SDK support** — optional `sn_sdk_explain` tool is registered when `now-sdk` is installed globally (`npm install -g now-sdk`)
-  **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`
- 📚 **ServiceNow Docs search** — `sn_read_docs` searches the ServiceNowDocs repo, returns `file_path`/`raw_url` for direct reads, and can resolve the selected branch when a non-default version is requested

---

## 🚀 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 | Use either a top-level `"default"` alias or per-entry `"default": true` to select 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) |
| `jwt_issuer` | optional | Optional issuer value for `jwt_bearer` |
| `token_url` | optional | Override the default token endpoint (default: `/oauth_token.do`) |

Default selection is resolved in this order:
1. explicit top-level `"default"` alias in the config object
2. an entry with `"default": true`
3. the first entry in the list

---

### 2. Environment variables (optional)

All optional — set them in your shell, in the MCP client `"env"` block, or in a `.env` file at the project root. Values from the shell take precedence over `.env`.

> **Note:** If you are running the server from a local clone, a root-level `.env` file is loaded automatically at startup.

| 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 (`CURRENT`, `GLOBAL`, or a named zone) | `CURRENT` |
| `SN_LOG_DIR` | Override log file directory | OS temp folder |
| `GITHUB_TOKEN` | GitHub Personal Access Token for `sn_read_docs` (branch lookup and GitHub search) | none |

CLI flags are also supported as an alternative to environment variables:

- `--config <path>` → sets `SN_INSTANCE_CONFIG`
- `--verbose` → sets `SN_MCP_VERBOSE=true`
- `--github-token <token>` → sets `GITHUB_TOKEN`

---

## 🔌 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
# The inspector launcher accepts localhost and 127.0.0.1 origins so the browser can connect reliably.

# 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

The server exposes **16 tools at runtime** when the current environment supports them:

- **14 instance tools** — require a configured `sn-instance.json`
- **2 knowledge tools** — instance-independent tools for docs and SDK guidance

### 14 instance tools

| Tool | Description | Visibility |
|---|---|---|
| `sn_list_instances` | List all configured instances and their aliases, labels, and URLs. | Visible when `sn-instance.json` is configured and loaded. |
| `sn_ping` | Test connectivity to a specific instance or the default instance. | Visible when `sn-instance.json` is configured and loaded. |
| `sn_get_identity` | Query users, groups, and group membership from identity tables. | Visible when `sn-instance.json` is configured and loaded. |
| `sn_inspect_table` | Inspect table schema or search for matching tables by name/label. | Visible when `sn-instance.json` is configured and loaded. |
| `sn_aggregate_table` | Run aggregate queries such as count, sum, avg, min, and max. | Visible when `sn-instance.json` is configured and loaded. |
| `sn_query_table` | Generic read from any ServiceNow table with encoded queries, fields, paging, and display values. | Visible when `sn-instance.json` is configured and loaded. |
| `sn_get_record` | Resolve and fetch a record by sys_id, record number, task table, or CMDB CI class. | Visible when `sn-instance.json` is configured and loaded. |
| `sn_get_attachment` | Fetch attachment metadata or file content from the Attachment API. | Visible when `sn-instance.json` is configured and loaded. |
| `sn_get_update_sets` | List update sets or drill into the files inside a specific update set. | Visible when `sn-instance.json` is configured and loaded. |
| `sn_code_search` | Search scripting artifacts using the native ServiceNow Code Search API. | Visible when `sn-instance.json` is configured and loaded. |
| `sn_get_scripted_artifacts` | Fetch Script Includes, Business Rules, Client Scripts, UI Actions, Scheduled Jobs, Fix Scripts, and Scripted REST artifacts. | Visible when `sn-instance.json` is configured and loaded. |
| `sn_legacy_workflow_search` | Search classic workflow activity variable values and resolve the owning workflow versions. | Visible when `sn-instance.json` is configured and loaded. |
| `sn_get_legacy_workflow_artifacts` | Fetch legacy workflow artifacts from wf_* tables. | Visible when `sn-instance.json` is configured and loaded. |
| `sn_get_workflow_studio_artifacts` | Fetch Workflow Studio and Flow Designer artifacts from sys_hub_* and related tables. | Visible when `sn-instance.json` is configured and loaded. |

### 2 knowledge tools

| Tool | Description | Visibility |
|---|---|---|
| `sn_read_docs` | Search, browse, and read ServiceNowDocs markdown by release branch. Search mode returns `file_path` and `raw_url` values for direct reads, and `get_file` accepts either a raw GitHub URL or a repo-relative path. | Always visible. |
| `sn_sdk_explain` | Query the ServiceNow SDK for explanations of SDK skills, APIs, and concepts via `now-sdk`. | Visible only when `now-sdk` is installed and can be executed successfully. |

### Runtime visibility rules

- **Instance tools (14)** are hidden when the server starts in **config-less mode** (no `sn-instance.json` provided). In that mode, only the **2 knowledge tools** remain visible.
- **`sn_read_docs`** is always registered, because it does not depend on ServiceNow instance credentials.
- **`sn_sdk_explain`** is added only after a successful probe of `now-sdk`; if the package is not installed or cannot be executed, the tool is omitted entirely. Install it globally with: `npm install -g now-sdk`
- Every instance tool accepts an optional `instance` parameter. If omitted, the server uses the configured default instance.

---

## 💡 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 }
```

### Search ServiceNow Docs

```json
{ "tool": "sn_read_docs", "mode": "search", "search": "Install the ServiceNow SDK in an application", "version": "australia" }
```

Use `mode": "get_file"` with the returned `file_path` or `raw_url` to read the matching doc.

### 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, --github-token, --help)
│   ├── index.js          ← server bootstrap and startup banner
│   ├── config.js         ← config path resolution and validation
│   ├── validator.js      ← sn-instance.json schema validation
│   ├── constants.js      ← shared 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 and default-instance resolution
│   ├── sn-client.js      ← per-instance REST client
│   ├── handler.js        ← tool name → method router
│   ├── tools.js          ← MCP tool definitions
│   ├── docs-client.js    ← ServiceNowDocs search/browse/read implementation
│   └── sdk-client.js     ← ServiceNow SDK availability probe and explain helper
├── scripts/
│   ├── dev.js            ← development helper
│   └── inspect.js        ← MCP Inspector launcher with origin allowlist
├── sn-instance.json          ← your credentials (git-ignored)
├── sn-instance.example.json  ← template with supported auth flows
├── .env.example              ← environment variable documentation
├── README.md                 ← full project 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.2.tgz --config ./sn-instance.json

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

---

## 🤝 Contributing

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

## 🐛 Report a bug

If you hit a bug, please open a GitHub issue here:

- https://github.com/ImJaineel/SN-MCP-Server/issues/new

Include the following in your report so it can be fixed quickly:

- what you expected to happen
- what actually happened
- the command or MCP client configuration you used
- the relevant log output or error text
- any redacted snippets from `sn-instance.json` or `.env`

---

## 📄 License

See [LICENSE](LICENSE) for details.

