ServiceNow MCP
Use this integration to connect securely with a ServiceNow Model Context Protocol (MCP) server and access its tools in real time.
Case Management · ServiceNow MCP MCP
Details
| ID | ServiceNow MCP |
|---|---|
| Provider | ServiceNow |
| Category | Case Management |
| From Version | 8.13.0 |
| Docker Image | demisto/mcp:1.0.0.10120494 |
| Supported Modules | Attack Surface Management Exposure Management Agentix Cortex Cloud Cloud Runtime Security Cloud Posture Security XSIAM EDR |
Connection settings
| Parameter | Name | Type | Required | Default |
|---|---|---|---|---|
| ServiceNow Instance URL | instance_url |
Short text | Yes | — |
| MCP Server Name | server_name |
Short text | Yes | sn_mcp_server_default |
| Client ID | oauth_credentials |
Credentials | Yes | — |
| Authorization code | auth_code |
Credentials | No | — |
| Redirect URI | redirect_uri |
Short text | No | https://oproxy.demisto.ninja/authcode |
| Trust any certificate (not secure) | insecure |
Boolean | No | — |
Commands (4)
An MCP server publishes no fixed command set: list-tools and
call-tool are the protocol plumbing, and the tools they reach are
discovered from the remote server when the instance connects. The pack cannot name them ahead of time, so
neither can this page.
-
call-toolCalls a specific tool on the MCP server with optional input parameters.
-
list-toolsRetrieves a list of available tools in the ServiceNow MCP server.
-
servicenow-mcp-auth-testTest the authentication configuration with the MCP server.
-
servicenow-mcp-generate-login-urlGenerate an authentication login URL.
import demistomock as demisto from CommonServerPython import * from MCPApiModule import * import asyncio from urllib.parse import unquote SERVICENOW_AUTH_TYPE = AuthMethods.AUTHORIZATION_CODE.value SERVICENOW_SCOPE = "mcp_server" COMMAND_PREFIX = "servicenow-mcp" SERVER_NAME = "ServiceNow MCP" DEFAULT_MCP_SERVER_NAME = "sn_mcp_server_default" def build_servicenow_urls(instance_url: str, server_name: str) -> tuple[str, str, str]: """Builds the ServiceNow MCP server URL and OAuth authorization/token endpoints from the instance URL. Args: instance_url: The full ServiceNow instance URL (e.g., 'https://dev12345.service-now.com'). server_name: The name of the MCP server on the instance. Returns: A tuple of (base_url, authorization_endpoint, token_endpoint). """ instance_url = instance_url.strip().rstrip("/") server_name = (server_name or DEFAULT_MCP_SERVER_NAME).strip() base_url = f"{instance_url}/sncapps/mcp-server/mcp/{server_name}" authorization_endpoint = f"{instance_url}/oauth_auth.do" token_endpoint = f"{instance_url}/oauth_token.do" return base_url, authorization_endpoint, token_endpoint def validate_required_params(instance_url: str, client_id: str, client_secret: str) -> None: """Validates that required parameters are present. Args: instance_url: The full ServiceNow instance URL. client_id: The OAuth Client ID. client_secret: The OAuth Client Secret. """ if not instance_url: raise ValueError("ServiceNow Instance URL must be provided (e.g., 'https://dev12345.service-now.com').") if not all((client_id, client_secret)): raise ValueError("Client ID and Client Secret are required for OAuth authentication.") async def main() -> None: # pragma: no cover params = demisto.params() args = demisto.args() command = demisto.command() client = None try: instance_url = params.get("instance_url", "") server_name = params.get("server_name", "") client_id = params.get("oauth_credentials", {}).get("identifier") client_secret = params.get("oauth_credentials", {}).get("password") auth_code = unquote(params.get("auth_code", {}).get("password") or "") redirect_uri = params.get("redirect_uri", "") or REDIRECT_URI verify: bool = not argToBoolean(params.get("insecure", False)) validate_required_params(instance_url, client_id, client_secret) base_url, authorization_endpoint, token_endpoint = build_servicenow_urls(instance_url, server_name) client = Client( base_url=base_url, auth_type=SERVICENOW_AUTH_TYPE, command_prefix=COMMAND_PREFIX, client_id=client_id, client_secret=client_secret, auth_code=auth_code, token_endpoint=token_endpoint, scope=SERVICENOW_SCOPE, redirect_uri=redirect_uri, verify=verify, ) demisto.debug(f"Command being called is {command}") if command == "test-module": raise DemistoException( "\nTest module is unavailable for this integration. " f"Please use the **!{COMMAND_PREFIX}-auth-test** command to test " "connectivity after setting the Authorization Code.", ) elif command == "list-tools": result = await client.list_tools(SERVER_NAME) return_results(result) elif command == "call-tool": result = await client.call_tool(args["name"], args.get("arguments", "")) return_results(result) elif command == f"{COMMAND_PREFIX}-auth-test": result = await client.test_connection(auth_test=True) return_results(result) elif command == f"{COMMAND_PREFIX}-generate-login-url": result = await generate_login_url( client._oauth_handler, auth_type=SERVICENOW_AUTH_TYPE, authorization_endpoint=authorization_endpoint, redirect_uri=redirect_uri, troubleshooting_redirect=True, ) return_results(result) else: raise NotImplementedError(f"Command {command} is not implemented") except Exception as eg: root_msg = extract_root_error_message(eg) return_error(f"Failed to execute {command} command.\nError:\n{root_msg}") finally: if client: demisto.debug(f"Closing client connection for {command}") await client.close() """ ENTRY POINT """ if __name__ in ("__main__", "__builtin__", "builtins"): asyncio.run(main())