# ๐Ÿ“˜ 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 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 ` โ†’ sets `SN_INSTANCE_CONFIG` - `--verbose` โ†’ sets `SN_MCP_VERBOSE=true` - `--github-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 --- ## ๐Ÿค 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.