-
Notifications
You must be signed in to change notification settings - Fork 1.9k
ServiceNow MCP #44291
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
ServiceNow MCP #44291
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| https://myinstance.service-now.com | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,90 @@ | ||||||
| Use this integration to connect securely with a ServiceNow Model Context Protocol (MCP) server and access its tools in real time. | ||||||
| This integration was integrated and tested with version xx of ServiceNow MCP. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please replace the placeholder |
||||||
|
|
||||||
| ## Configure ServiceNow MCP in Cortex | ||||||
|
|
||||||
| | **Parameter** | **Description** | **Required** | | ||||||
| | --- | --- | --- | | ||||||
| | Server URL | The full MCP server URL for your ServiceNow instance. For example, https://<instance>.service-now.com/sncapps/mcp-server/mcp/<server-name>. | True | | ||||||
| | Client ID | The Client ID and Client Secret from the OAuth inbound integration configured on your ServiceNow instance. | True | | ||||||
| | Client Secret | | True | | ||||||
| | Authorization code | The authorization code obtained by running the \!servicenow-mcp-generate-login-url command. | | | ||||||
| | Redirect URI | The redirect URI configured in your ServiceNow OAuth inbound integration. Must match the Redirect URL set in ServiceNow. | | | ||||||
| | Trust any certificate (not secure) | | | | ||||||
|
|
||||||
| ## Commands | ||||||
|
|
||||||
| You can execute these commands from the CLI, as part of an automation, or in a playbook. | ||||||
| After you successfully execute a command, a DBot message appears in the War Room with the command details. | ||||||
|
|
||||||
| ### list-tools | ||||||
|
|
||||||
| *** | ||||||
| Retrieves a list of available tools in the ServiceNow MCP server. | ||||||
|
|
||||||
| #### Base Command | ||||||
|
|
||||||
| `list-tools` | ||||||
|
|
||||||
| #### Input | ||||||
|
|
||||||
| | **Argument Name** | **Description** | **Required** | | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The input table is empty. It should be replaced with the standard text indicating no input arguments. Additionally, this command (and others in this file) is missing the standard Please apply the suggestion below to fix the empty table (and remove the table separator on line 32), and then run the
Suggested change
To regenerate the documentation, run: demisto-sdk generate-docs --insecure -e Packs/ServiceNowMCP/Integrations/ServiceNowMCP/command_examples.txt -i Packs/ServiceNowMCP/Integrations/ServiceNowMCP/ServiceNowMCP.ymlFor more details, refer to the Command Examples - Integration Documentation guidelines. |
||||||
| | --- | --- | --- | | ||||||
|
|
||||||
| #### Context Output | ||||||
|
|
||||||
| There is no context output for this command. | ||||||
|
|
||||||
| ### call-tool | ||||||
|
|
||||||
| *** | ||||||
| Calls a specific tool on the ServiceNow MCP server with optional input parameters. | ||||||
|
|
||||||
| #### Base Command | ||||||
|
|
||||||
| `call-tool` | ||||||
|
|
||||||
| #### Input | ||||||
|
|
||||||
| | **Argument Name** | **Description** | **Required** | | ||||||
| | --- | --- | --- | | ||||||
| | name | The name of the tool to call. | Required | | ||||||
| | arguments | Parameters for the tool execution. | Optional | | ||||||
|
|
||||||
| #### Context Output | ||||||
|
|
||||||
| There is no context output for this command. | ||||||
|
|
||||||
| ### servicenow-mcp-auth-test | ||||||
|
|
||||||
| *** | ||||||
| Test the authentication configuration with the MCP server. | ||||||
|
|
||||||
| #### Base Command | ||||||
|
|
||||||
| `servicenow-mcp-auth-test` | ||||||
|
|
||||||
| #### Input | ||||||
|
|
||||||
| There are no input arguments for this command. | ||||||
|
|
||||||
| #### Context Output | ||||||
|
|
||||||
| There is no context output for this command. | ||||||
|
|
||||||
| ### servicenow-mcp-generate-login-url | ||||||
|
|
||||||
| *** | ||||||
| Generate an authentication login URL. | ||||||
|
|
||||||
| #### Base Command | ||||||
|
|
||||||
| `servicenow-mcp-generate-login-url` | ||||||
|
|
||||||
| #### Input | ||||||
|
|
||||||
| There are no input arguments for this command. | ||||||
|
|
||||||
| #### Context Output | ||||||
|
|
||||||
| There is no context output for this command. | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| import demistomock as demisto | ||
| from CommonServerPython import * | ||
| from MCPApiModule import * | ||
|
|
||
| import asyncio | ||
|
|
||
|
|
||
| from urllib.parse import unquote, urlparse | ||
|
|
||
|
|
||
| SERVICENOW_AUTH_TYPE = AuthMethods.AUTHORIZATION_CODE.value | ||
| SERVICENOW_SCOPE = "mcp_server" | ||
| COMMAND_PREFIX = "servicenow-mcp" | ||
| SERVER_NAME = "ServiceNow MCP" | ||
|
|
||
|
|
||
| def derive_oauth_endpoints(base_url: str) -> tuple[str, str]: | ||
| """Derives the OAuth authorization and token endpoints from the ServiceNow MCP server URL. | ||
|
|
||
| ServiceNow OAuth endpoints follow the pattern: | ||
| - Authorization: https://<instance>.service-now.com/oauth_auth.do | ||
| - Token: https://<instance>.service-now.com/oauth_token.do | ||
| """ | ||
| parsed = urlparse(base_url) | ||
| origin = f"{parsed.scheme}://{parsed.netloc}" | ||
| return f"{origin}/oauth_auth.do", f"{origin}/oauth_token.do" | ||
|
|
||
|
|
||
| async def main() -> None: # pragma: no cover | ||
| params = demisto.params() | ||
| args = demisto.args() | ||
| command = demisto.command() | ||
|
|
||
| client = None | ||
| try: | ||
| base_url = params.get("base_url", "") | ||
| 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)) | ||
|
|
||
| authorization_endpoint, token_endpoint = derive_oauth_endpoints(base_url) | ||
|
|
||
| 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 BaseException as eg: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use |
||
| root_msg = extract_root_error_message(eg) | ||
| return_error(f"Failed to execute {command} command.\nError:\n{root_msg}") | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add traceback logging for comprehensive error tracking. |
||
|
|
||
| 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()) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| category: IT Services | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. CRITICAL: The first key defined at the root level of the Please move |
||
| provider: ServiceNow | ||
| sectionorder: | ||
| - Connect | ||
| commonfields: | ||
| id: ServiceNow MCP | ||
| version: -1 | ||
| configuration: | ||
| - name: base_url | ||
| section: Connect | ||
| display: Server URL | ||
| type: 0 | ||
| required: true | ||
| additionalinfo: The full MCP server URL for your ServiceNow instance. For example, https://<instance>.service-now.com/sncapps/mcp-server/mcp/<server-name>. | ||
| - name: oauth_credentials | ||
| type: 9 | ||
| display: Client ID | ||
| displaypassword: Client Secret | ||
| section: Connect | ||
| required: true | ||
| additionalinfo: The Client ID and Client Secret from the OAuth inbound integration configured on your ServiceNow instance. | ||
| - name: auth_code | ||
| type: 9 | ||
| displaypassword: Authorization code | ||
| hiddenusername: true | ||
| section: Connect | ||
| additionalinfo: The authorization code obtained by running the !servicenow-mcp-generate-login-url command. | ||
| - name: redirect_uri | ||
| section: Connect | ||
| defaultvalue: https://oproxy.demisto.ninja/authcode | ||
| display: Redirect URI | ||
| type: 0 | ||
| advanced: true | ||
| additionalinfo: The redirect URI configured in your ServiceNow OAuth inbound integration. Must match the Redirect URL set in ServiceNow. | ||
| - name: insecure | ||
| section: Connect | ||
| display: Trust any certificate (not secure) | ||
| type: 8 | ||
| advanced: true | ||
| description: Use this integration to connect securely with a ServiceNow Model Context Protocol (MCP) server and access its tools in real time. | ||
| display: ServiceNow MCP | ||
| name: ServiceNow MCP | ||
| script: | ||
| commands: | ||
| - arguments: [] | ||
| description: Retrieves a list of available tools in the ServiceNow MCP server. | ||
| name: list-tools | ||
| hidden: true | ||
| outputs: [] | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can context outputs be defined for this command? |
||
| - arguments: | ||
| - name: name | ||
| description: The name of the tool to call. | ||
| required: true | ||
| - name: arguments | ||
| description: Parameters for the tool execution. | ||
| description: Calls a specific tool on the ServiceNow MCP server with optional input parameters. | ||
| name: call-tool | ||
| hidden: true | ||
| outputs: [] | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can context outputs be defined for this command? |
||
| - description: Test the authentication configuration with the MCP server. | ||
| name: servicenow-mcp-auth-test | ||
| - description: Generate an authentication login URL. | ||
| name: servicenow-mcp-generate-login-url | ||
| script: '-' | ||
| type: python | ||
| subtype: python3 | ||
| dockerimage: demisto/mcp:1.0.0.6978288 | ||
| mcp: true | ||
| fromversion: 8.13.0 | ||
| tests: | ||
| - No tests (auto formatted) | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,31 @@ | ||||||||||||||
| ## ServiceNow MCP Server URL | ||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Update the initial header and add a brief purpose/scope section. According to the Integration Description File guidelines, the description should begin with
Suggested change
|
||||||||||||||
|
|
||||||||||||||
| The Server URL follows the format: `https://<instance>.service-now.com/sncapps/mcp-server/mcp/<server-name>` | ||||||||||||||
|
|
||||||||||||||
| To connect to the preconfigured Quickstart Server, use: `https://<instance>.service-now.com/sncapps/mcp-server/mcp/sn_mcp_server_default` | ||||||||||||||
|
|
||||||||||||||
| Replace `<instance>` with your ServiceNow instance name. | ||||||||||||||
|
|
||||||||||||||
| ## OAuth Setup | ||||||||||||||
|
|
||||||||||||||
| Before configuring this integration, you must create an OAuth inbound integration on your ServiceNow instance: | ||||||||||||||
|
|
||||||||||||||
| 1. In ServiceNow, navigate to **All > MCP Server Console**. | ||||||||||||||
| 2. From the **Configuration** tab, select **Servers**. | ||||||||||||||
| 3. Select **Set up OAuth** from the banner, or navigate to **All > Machine Identity Console** and select the **Inbound integrations** tab. | ||||||||||||||
| 4. Select **New integration** > **OAuth - Authorization code grant**. | ||||||||||||||
| 5. Fill in the required fields: | ||||||||||||||
| - **Name**: Enter a name for the OAuth integration. | ||||||||||||||
| - **Redirect URLs**: Enter the Redirect URI configured in this integration instance (default: `https://oproxy.demisto.ninja/authcode`). | ||||||||||||||
| 6. Under **Advanced options**, set **Token Format** to **JWT**. | ||||||||||||||
| 7. Select **Save**. | ||||||||||||||
| 8. Copy the generated **Client ID** and **Client Secret**. | ||||||||||||||
|
|
||||||||||||||
| ## Authorization Code | ||||||||||||||
|
|
||||||||||||||
| To obtain the Authorization code, follow these steps: | ||||||||||||||
|
|
||||||||||||||
| 1. Enter the **Server URL**, **Client ID**, and **Client Secret** in this integration instance and save. | ||||||||||||||
| 2. Run the integration command `!servicenow-mcp-generate-login-url` from the Playground and follow its instructions. | ||||||||||||||
| 3. Copy the generated Authorization code into the integration instance and save the integration instance. | ||||||||||||||
| 4. Run the integration command `!servicenow-mcp-auth-test` from the Playground to verify that everything is configured correctly. | ||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
.secrets-ignorefile should contain domain names, not full URLs. Please remove thehttps://prefix.