Skip to main content

MCP server for ServiceNow - table, CMDB, system, and update set operations

Project description

mcp-server-servicenow

Python 3.11+ FastMCP MCP Protocol License: MIT 18 Tools

Connect Claude AI to ServiceNow. 18 MCP tools for incidents, CMDB, update sets, and more — accessible from Claude Desktop, Claude Code, or any MCP client over stdio or Streamable HTTP.

What This Does

This MCP server lets AI assistants interact directly with a ServiceNow instance. Instead of copy-pasting between ServiceNow and your AI tool, Claude can query incidents, create records, explore CMDB relationships, and manage update sets through natural conversation.

Built with FastMCP 3.0 for decorator-based tool definitions and dual transport support.

Native vs Community

ServiceNow shipped a native MCP Server in Zurich (2025). Here's when to use each:

Native (Zurich+) This project
SN version Zurich+ only Any version (Tokyo+)
Entitlement Requires Now Assist SKU None (MIT, free)
Auth model OAuth 2.1 + PKCE via AI Control Tower OAuth 2.1 + PKCE via FastMCP proxy
Governance AI Control Tower policies Self-managed
Table access Governed by CT config Full table API access
AI models Now Assist models + approved Any MCP client (Claude, GPT, etc.)
Custom tools Requires SN development Python — add tools in minutes

Use native if you're on Zurich+ with Now Assist and need AI Control Tower governance. Use this if you're on an older version, don't have the entitlement, need custom table access, or want to use any AI model.

Getting Started

1. Get a ServiceNow Instance

Sign up for a free Personal Developer Instance (PDI) — it comes pre-loaded with demo data. Wake it from the developer portal if it's hibernating.

2. Install

# From PyPI (recommended)
pip install mcp-server-servicenow

# Or run directly with uvx (no install needed)
uvx mcp-server-servicenow --help

3. Configure Your MCP Client

Copy .mcp.json.example to .mcp.json and fill in your credentials, or use the Claude Code CLI:

claude mcp add servicenow -- uvx mcp-server-servicenow \
  --instance-url https://your-instance.service-now.com \
  --auth-type basic --username admin --password your-password

4. Verify

Ask Claude: "List the 5 most recent incidents" — if it returns data, you're connected.

From Source

git clone https://github.com/jschuller/mcp-server-servicenow.git
cd mcp-server-servicenow
pip install -e .

# Run with stdio (Claude Desktop / Claude Code)
mcp-server-servicenow \
  --instance-url https://your-instance.service-now.com \
  --auth-type basic \
  --username admin \
  --password your-password

# Or run with HTTP (remote access / Cloud Run)
mcp-server-servicenow \
  --transport streamable-http \
  --port 8080 \
  --instance-url https://your-instance.service-now.com \
  --auth-type basic \
  --username admin \
  --password your-password

Available Tools

Table API (5 tools)

Tool Description
list_records List records from any table with filtering, field selection, and pagination
get_record Get a single record by sys_id
create_record Create a new record in any table
update_record Update an existing record
delete_record Delete a record by sys_id

CMDB (5 tools)

Tool Description
list_ci List configuration items with class and query filtering
get_ci Get a single CI by sys_id
create_ci Create a new configuration item
update_ci Update a configuration item
get_ci_relationships Get parent/child relationships for a CI

System (3 tools)

Tool Description
get_system_properties Query system properties
get_current_user Get authenticated user info
get_table_schema Get table data dictionary (field definitions)

Update Sets (5 tools)

Tool Description
list_update_sets List update sets with state filtering
get_update_set Get update set details
create_update_set Create a new update set
set_current_update_set Set the active update set
list_update_set_changes List changes within an update set

Architecture

Claude / MCP Client
       │
       │  stdio or Streamable HTTP
       ▼
┌─────────────────────────┐
│   FastMCP 3.0 Server    │
│   (server.py)           │
├─────────────────────────┤
│  @mcp.tool() decorators │
│  ┌───────────────────┐  │
│  │ table_tools (5)   │  │
│  │ cmdb_tools  (5)   │  │
│  │ system_tools (3)  │  │
│  │ update_set_tools(5)│  │
│  └───────────────────┘  │
├─────────────────────────┤
│  auth_manager + http.py │
└────────────┬────────────┘
             │  REST API
             ▼
     ServiceNow Instance
      /api/now/table/*

Configuration Examples

Copy .mcp.json.example to .mcp.json and fill in your credentials. The JSON format is the same for Claude Code (.mcp.json) and Claude Desktop (claude_desktop_config.json).

Basic Auth (stdio)

{
  "mcpServers": {
    "servicenow": {
      "command": "uvx",
      "args": ["mcp-server-servicenow"],
      "env": {
        "SERVICENOW_INSTANCE_URL": "https://your-instance.service-now.com",
        "SERVICENOW_AUTH_TYPE": "basic",
        "SERVICENOW_USERNAME": "admin",
        "SERVICENOW_PASSWORD": "your-password"
      }
    }
  }
}

OAuth Password Grant (stdio)

{
  "mcpServers": {
    "servicenow": {
      "command": "uvx",
      "args": ["mcp-server-servicenow"],
      "env": {
        "SERVICENOW_INSTANCE_URL": "https://your-instance.service-now.com",
        "SERVICENOW_AUTH_TYPE": "oauth",
        "SERVICENOW_CLIENT_ID": "your-client-id",
        "SERVICENOW_CLIENT_SECRET": "your-client-secret",
        "SERVICENOW_USERNAME": "admin",
        "SERVICENOW_PASSWORD": "your-password"
      }
    }
  }
}

Multiple Instances

{
  "mcpServers": {
    "servicenow-dev": {
      "command": "uvx",
      "args": ["mcp-server-servicenow"],
      "env": {
        "SERVICENOW_INSTANCE_URL": "https://dev12345.service-now.com",
        "SERVICENOW_AUTH_TYPE": "basic",
        "SERVICENOW_USERNAME": "admin",
        "SERVICENOW_PASSWORD": "dev-password"
      }
    },
    "servicenow-prod": {
      "command": "uvx",
      "args": ["mcp-server-servicenow"],
      "env": {
        "SERVICENOW_INSTANCE_URL": "https://prod12345.service-now.com",
        "SERVICENOW_AUTH_TYPE": "oauth",
        "SERVICENOW_CLIENT_ID": "prod-client-id",
        "SERVICENOW_CLIENT_SECRET": "prod-client-secret",
        "SERVICENOW_USERNAME": "svc-account",
        "SERVICENOW_PASSWORD": "prod-password"
      }
    }
  }
}

Deployment

Docker / Cloud Run

# Build
docker build -t mcp-server-servicenow .

# Run locally
docker run -p 8080:8080 \
  -e SERVICENOW_INSTANCE_URL=https://your-instance.service-now.com \
  -e SERVICENOW_AUTH_TYPE=basic \
  -e SERVICENOW_USERNAME=admin \
  -e SERVICENOW_PASSWORD=your-password \
  mcp-server-servicenow

# Deploy to Cloud Run with global creds (requires GCP IAM for access)
gcloud run deploy servicenow-mcp \
  --source . \
  --region us-east1 \
  --port 8080 \
  --no-allow-unauthenticated \
  --set-env-vars "SERVICENOW_INSTANCE_URL=..." \
  --set-env-vars "SERVICENOW_AUTH_TYPE=basic" \
  --set-env-vars "SERVICENOW_USERNAME=..." \
  --set-env-vars "SERVICENOW_PASSWORD=..." \
  --set-env-vars "MCP_TRANSPORT=streamable-http"

# Deploy to Cloud Run with OAuth (per-user auth, publicly accessible)
gcloud run deploy servicenow-mcp \
  --source . \
  --region us-east1 \
  --port 8080 \
  --allow-unauthenticated \
  --set-env-vars "SERVICENOW_INSTANCE_URL=..." \
  --set-env-vars "MCP_OAUTH_CLIENT_ID=..." \
  --set-env-vars "MCP_OAUTH_CLIENT_SECRET=..." \
  --set-env-vars "MCP_BASE_URL=https://servicenow-mcp-xxxxx.run.app" \
  --set-env-vars "MCP_TRANSPORT=streamable-http"

Verify HTTP Transport

# Local testing
curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}},"id":1}'

# Cloud Run (requires GCP auth token)
curl -X POST https://your-service-url.run.app/mcp \
  -H "Authorization: Bearer $(gcloud auth print-identity-token)" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}},"id":1}'

Security Model

Three deployment modes with increasing security:

Mode MCP Endpoint Auth SN Backend Auth Use Case
stdio None (local process) Global creds (env vars) Claude Desktop, Claude Code
HTTP (open) None Global creds (env vars) Development, testing
HTTP + OAuth OAuth 2.1 + PKCE Per-user SN token Production, Cloud Run

OAuth 2.1 + PKCE (recommended for production)

When deployed with OAuth, each user authenticates with their own ServiceNow credentials. The server acts as an OAuth proxy: it handles DCR and consent locally, redirects users to ServiceNow for login, then exchanges the auth code for SN tokens server-side.

Defense in depth: OAuth 2.1 + PKCE on the MCP endpoint, per-user SN ACLs on every API call, encrypted token storage, CSRF-protected consent screen.

Setup:

  1. In ServiceNow, go to System OAuth > Application Registry and create an OAuth API endpoint for external clients
  2. Set the redirect URI to {your-server-url}/auth/callback
  3. Deploy with OAuth env vars:
SERVICENOW_INSTANCE_URL=https://your-instance.service-now.com
MCP_OAUTH_CLIENT_ID=<from Application Registry>
MCP_OAUTH_CLIENT_SECRET=<from Application Registry>
MCP_BASE_URL=https://your-mcp-server.run.app
MCP_TRANSPORT=streamable-http
  1. In Claude.ai, add the server URL as an MCP connector — the OAuth flow handles the rest

Requires: ServiceNow San Diego+ (2022) for PKCE support.

Configuration Reference

All settings can be passed as CLI args or environment variables. See .env.example.

Variable CLI Arg Description
SERVICENOW_INSTANCE_URL --instance-url ServiceNow instance URL
SERVICENOW_AUTH_TYPE --auth-type basic, oauth, or api_key
SERVICENOW_USERNAME --username Username for basic/OAuth auth
SERVICENOW_PASSWORD --password Password for basic/OAuth auth
SERVICENOW_CLIENT_ID --client-id OAuth client ID
SERVICENOW_CLIENT_SECRET --client-secret OAuth client secret
SERVICENOW_API_KEY --api-key API key for api_key auth
SERVICENOW_API_KEY_HEADER --api-key-header API key header name (default: X-ServiceNow-API-Key)
MCP_TRANSPORT --transport stdio (default) or streamable-http
PORT --port HTTP port (default: 8080)
MCP_OAUTH_CLIENT_ID --mcp-oauth-client-id SN OAuth app client ID for MCP endpoint auth
MCP_OAUTH_CLIENT_SECRET --mcp-oauth-client-secret SN OAuth app client secret for MCP endpoint auth
MCP_BASE_URL --mcp-base-url Public URL of this MCP server

Troubleshooting

Instance is hibernating

PDIs hibernate after inactivity. Wake it at developer.servicenow.com — click your instance and select "Wake Up". You'll get HTML login pages instead of JSON until it's awake.

401 Unauthorized

  • Basic auth: Verify username/password are correct; check that the user has the rest_api_explorer or admin role
  • OAuth: Ensure the OAuth Application Registry entry is active and the redirect URI matches. Try regenerating the client secret
  • Expired token: OAuth tokens expire; the server retries once automatically, but if both attempts fail, check your credentials

OAuth get_current_user returns different fields

With OAuth bearer tokens, get_current_user uses a Table API fallback (the UI endpoint requires session auth). The response fields are the same but sourced from sys_user instead of the UI API.

CLI TypeError on stdio transport

Fixed in v0.3.1. If you see TypeError: unexpected keyword argument 'host', upgrade: pip install --upgrade mcp-server-servicenow.

Development

# Install with dev dependencies
pip install -e ".[dev]"

# Run unit tests
python -m pytest tests/ -v --ignore=tests/integration

# Run integration tests (requires PDI credentials)
SERVICENOW_INSTANCE_URL=https://your-pdi.service-now.com \
SERVICENOW_USERNAME=admin \
SERVICENOW_PASSWORD=your-password \
python -m pytest tests/integration/ -v

# Lint
ruff check src/ tests/

Roadmap

  • Phase 1 ✅ Foundation — 18 tools, OAuth retry, structured error handling
  • Phase 2 ✅ Remote access — FastMCP 3.0, Streamable HTTP, Cloud Run deployment
  • Phase 3 ✅ Security — OAuth 2.1 + PKCE proxy, per-user SN auth, matches native Zurich model
  • Phase 4 🔜 Skills & workflows — CMDB Data Foundations, incident triage, change management
  • Phase 5 🚧 Distribution — PyPI package, MCP Registry listing, Claude Code skills

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcp_server_servicenow-0.3.1.tar.gz (27.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcp_server_servicenow-0.3.1-py3-none-any.whl (23.8 kB view details)

Uploaded Python 3

File details

Details for the file mcp_server_servicenow-0.3.1.tar.gz.

File metadata

  • Download URL: mcp_server_servicenow-0.3.1.tar.gz
  • Upload date:
  • Size: 27.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for mcp_server_servicenow-0.3.1.tar.gz
Algorithm Hash digest
SHA256 8a4729f153b60c39461665622aad2e50c1a2387af96f092a38e9c6daa1cec195
MD5 7911ada44b45ea250b2c2de4d9a9ce00
BLAKE2b-256 71a4a5626c01a8881a20545b29d558ecf9e33153fb6ee078bbc71f3da146dd0d

See more details on using hashes here.

File details

Details for the file mcp_server_servicenow-0.3.1-py3-none-any.whl.

File metadata

File hashes

Hashes for mcp_server_servicenow-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 174211d91ed1f204765a28d456bcd803065786d05e4c166ec608e2eb8d0a531a
MD5 5002d8a2b03676e09bc285e9edfe6bab
BLAKE2b-256 ef3d535ca3601d4cf5b72cb280290dc8788318468c658fe789d2f65172118643

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page