How to integrate ServiceNow MCP with LlamaIndex

Trusted by
AWS
Glean
Zoom
Airtable

30 min · no commitment · see it on your stack

ServiceNow logo
LlamaIndex logo
divider

Introduction

This guide walks you through connecting ServiceNow to LlamaIndex using the Composio tool router. By the end, you'll have a working ServiceNow agent that can list all open incidents assigned to me, create a new servicenow change request, update priority of ticket inc0012345 to high through natural language commands.

This guide will help you understand how to give your LlamaIndex agent real control over a ServiceNow account through Composio's ServiceNow MCP server.

Before we dive in, let's take a quick look at the key ideas and tools involved.

Also integrate ServiceNow with

TL;DR

Here's what you'll learn:
  • Set your OpenAI and Composio API keys
  • Install LlamaIndex and Composio packages
  • Create a Composio Tool Router session for ServiceNow
  • Connect LlamaIndex to the ServiceNow MCP server
  • Build a ServiceNow-powered agent using LlamaIndex
  • Interact with ServiceNow through natural language

What is LlamaIndex?

LlamaIndex is a data framework for building LLM applications. It provides tools for connecting LLMs to external data sources and services through agents and tools.

Key features include:

  • ReAct Agent: Reasoning and acting pattern for tool-using agents
  • MCP Tools: Native support for Model Context Protocol
  • Context Management: Maintain conversation context across interactions
  • Async Support: Built for async/await patterns

What is the ServiceNow MCP server, and what's possible with it?

The ServiceNow MCP server is an implementation of the Model Context Protocol that connects your AI agent and assistants like Claude, Cursor, etc directly to your ServiceNow account. It provides structured and secure access so your agent can perform ServiceNow operations on your behalf.

Supported Tools & Triggers

Tools
Attach file to recordAttaches a file to a specified record in a ServiceNow table.
Cancel change conflict checkCancels the running conflict checking process for a specified ServiceNow change request.
Create a recordCreates a new record in a specified ServiceNow table with the provided field values.
Create attachment uploadUploads a file as a multipart form-data attachment to a specified record in ServiceNow.
Create CI Lifecycle Management ActionAdds a specified configuration item (CI) action using the ServiceNow CI Lifecycle Management API.
Create ci lifecycle mgmt operatorsRegisters a new operator for a non-workflow user in the ServiceNow CI Lifecycle Management system.
Set CI Operational StateSets the operational state for one or more configuration items (CIs) using the ServiceNow CI Lifecycle Management API.
Create CMDB Application ServiceCreates an application service in ServiceNow CMDB or updates an existing one if a service with the same name already exists.
Create CMDB Linux ServerCreates a new Linux server configuration item (CI) in the ServiceNow CMDB.
Ingest CMDB RecordsInserts multiple records into a ServiceNow Import Set staging table.
Create CMDB InstanceCreates a single Configuration Item (CI) in ServiceNow CMDB with the specified attributes.
Create CMDB Instance RelationCreates an inbound and/or outbound relation for a specific configuration item (CI) in the ServiceNow CMDB.
Create data classification classifyAssigns pre-defined or user-defined data classification labels to records in ServiceNow tables.
Create data classification clearRemoves all data classifications for a specific record in a ServiceNow table.
Enhanced CI Identify/ReconcileInserts or updates configuration items (CIs) in ServiceNow CMDB using the enhanced Identification and Reconciliation API.
Query CMDB Identify ReconcileQueries the ServiceNow Identify and Reconcile API to determine whether a Configuration Item (CI) should be inserted (created) or updated in the CMDB based on identity matching rules.
CMDB Identify Reconcile QueryEnhancedPerforms identification and reconciliation of configuration items (CIs) in the ServiceNow CMDB.
Create Import SetInserts incoming data into a specified ServiceNow staging table and triggers the associated transform map to move the data into the production table.
Create incidentCreates a new incident record in ServiceNow with the provided details.
Create IncidentCreates a new incident record in ServiceNow with the provided field values.
Create ServiceNow InteractionCreates a new interaction record in ServiceNow that can be linked to records in other tables (e.
Close InteractionCloses an existing interaction record in ServiceNow by changing its state to closed.
Create push installationRegisters or updates a device token for receiving push notifications through ServiceNow.
Remove Push InstallationDeactivates a mobile device installation from receiving push notifications using the ServiceNow Push Installation API.
Create servic catalog items add to cartAdds a specified catalog item to the current user's ServiceNow shopping cart.
Submit Service Catalog Producer ItemSubmits a ServiceNow Service Catalog item using the submit_producer endpoint.
Checkout Service Catalog CartChecks out the Service Catalog shopping cart and submits the order as a request.
Submit Service Catalog Cart OrderSubmits the Service Catalog shopping cart and creates a service catalog request.
Create servicecatalog items checkout guideChecks out an order guide by updating variable values for selected catalog items.
Order Service Catalog Item NowOrders a specified ServiceNow Service Catalog item immediately.
Insert Multiple Import Set RecordsInserts multiple records into a specified ServiceNow staging table and triggers the associated transform map.
Create sn chg rest changeCreates a new change request in ServiceNow using the Change Management REST API.
Create Change Request CI AssociationCreates an association between a change request and one or more configuration items (CIs) in ServiceNow.
Start Change Conflict CheckStarts the conflict checking process for a ServiceNow change request, identifying scheduling conflicts with other changes or blackout windows.
Create sn chg rest change emergencyCreates an emergency change request in ServiceNow using the Change Management API.
Create Normal Change RequestCreates a normal change request in ServiceNow using the Change Management REST API.
Create sn chg rest change standardCreates a new standard change request in ServiceNow using a pre-approved standard change template.
Create Change TaskCreates a new task for a ServiceNow change request using the Change Management REST API.
Create sn cicd app batch installInstalls two or more ServiceNow application packages in a single batch operation via the CICD API.
Install App from RepositoryInstalls the specified application from the ServiceNow app repository.
Run Full Instance ScanInitiates a full instance scan by running all active checks present in the ServiceNow instance.
Create sn cicd instance scan suite scan comboRuns a CI/CD scan using a suite and target (scoped app) combination in ServiceNow.
Activate PluginActivates the specified plugin in ServiceNow's CICD Plugin API.
Run Test SuiteStarts a specified automated test suite using ServiceNow's CI/CD Pipeline API.
Create SD-WAN Trouble TicketCreates a new trouble ticket in ServiceNow using the Service Operations Workspace Trouble Ticket Open API.
Create TMF Service CategoryCreates a new service category record in the ServiceNow TMF Service Catalog API.
Create tableInserts a new record into the specified ServiceNow table with the provided field values.
Create ServiceNow IncidentCreates a new incident record in the ServiceNow incident table using the Table API.
Create or Update CMDB CI via IRECreates or updates CMDB configuration items (CIs) using the ServiceNow Identification and Reconciliation Engine (IRE) via the identify-reconcile endpoint.
Delete a recordPermanently deletes a specific record from a ServiceNow table using its sys_id.
Delete attachment byPermanently deletes a specific attachment from ServiceNow using its sys_id.
Delete attachment by id v1Permanently deletes a specific attachment from ServiceNow using its sys_id via the v1 API endpoint.
Delete attachment csmPermanently deletes a specific CSM (Customer Service Management) attachment from ServiceNow using its sys_id.
Delete change taskPermanently deletes a specific task from a ServiceNow change request using its sys_id.
Delete ci lifecycle mgmt actionPermanently deletes a specific CI Lifecycle Management action from ServiceNow using its sys_id.
Delete ci lifecycle mgmt operatorsPermanently unregisters an operator from the ServiceNow CI Lifecycle Management system.
Delete cmdb instance relationPermanently deletes a specific CMDB CI (Configuration Item) relation using its sys_id.
Delete emergency change requestPermanently deletes a specific emergency change request from ServiceNow using its sys_id.
Delete incident byPermanently deletes a specific incident from ServiceNow using its sys_id.
Delete incident by id2Permanently deletes a specific incident from ServiceNow using its sys_id via the Table API.
Delete servicecatalog cartRemoves a specific item from the current ServiceNow Service Portal shopping cart.
Delete service catalog cart emptyEmpties all items from a specified Service Catalog shopping cart using its sys_id.
Delete sn chg rest changePermanently deletes a specific change request using its sys_id via the Change Management REST API.
Delete Normal Change RequestPermanently deletes a normal change request identified by its sys_id using the ServiceNow Change Management REST API.
Delete sn chg rest change standardPermanently deletes a standard change request from ServiceNow using its sys_id.
Delete tablePermanently deletes a specific record from a ServiceNow table using its sys_id.
Delete table incidentPermanently deletes a specific incident record from ServiceNow using its sys_id.
Find fileRetrieves attachment metadata from ServiceNow's sys_attachment table.
Get Activity Subscription ActivitiesRetrieves activity records from the ServiceNow ActivitySubscription API.
Get Activity Subscription FacetsRetrieves facets configured for an activity context in ServiceNow.
Get Agent Intelligence Solution PredictionPredicts an output field value using a trained Agent Intelligence solution model.
List Agent Intelligence Solution PredictionsRetrieves a list of solution predictions from ServiceNow's Agent Intelligence engine.
Get All Data ClassesRetrieves all data classification records from the ServiceNow Data Classification API.
Get App Service CMDB ContentRetrieves a list of configuration items (CIs) associated with a specific application service in ServiceNow CMDB.
Get attachment byRetrieves metadata for a specific attachment by its sys_id from ServiceNow.
Get Attachment by IDRetrieves metadata for a specific attachment by its sys_id from ServiceNow.
Get attachment fileDownloads the binary file attachment with the specified sys_id from ServiceNow.
Get attachment file fileDownloads the binary file attachment with the specified sys_id from ServiceNow using the v1 API endpoint.
Get Attachment ListRetrieves metadata for multiple file attachments from ServiceNow's Attachment API.
Get change ci scheduleRetrieves available time slots for scheduling changes against a specific Configuration Item (CI).
Get Change Conflict StatusRetrieves the conflict status for a ServiceNow change request, identifying scheduling conflicts with other changes or blackout windows.
Get change nextstatesRetrieves a list of available next states for a specified change request based on the current state and workflow.
Get Change Request Configuration ItemsRetrieves configuration items (CIs) associated with a specific change request in ServiceNow.
Get change scheduleRetrieves available time slots for scheduling a ServiceNow change request.
Get CI Lifecycle Management ActionRetrieves a specific CI Lifecycle Management action from ServiceNow using its sys_id.
Check CI CompatibilityDetermines whether two specified Configuration Items (CIs) in the ServiceNow CMDB are compatible using the CI Lifecycle Management compatActions endpoint.
Check CI Lease Expiration StatusDetermines whether a CI Lifecycle Management lease has expired for the specified lease record.
Check CI Not Allowed Ops TransitionDetermines whether a configuration item (CI) can be transitioned based on CI lifecycle management rules.
Validate CI Lifecycle Management RequestorValidates whether a specified active workflow requestor exists and is valid in ServiceNow CI Lifecycle Management.
Get CI Lifecycle Mgmt StatusRetrieves the current operational status for a Configuration Item (CI) in ServiceNow CMDB using the CI Lifecycle Management API.
Get CMDB Linux Server by IDRetrieves a single CMDB Linux server configuration item (CI) by its sys_id, including its attributes and relationship information.
Find CSDM Application ServiceFinds and returns basic information about one or more application services in the ServiceNow CMDB using the CSDM (Common Service Data Model) app_service find_service endpoint.
Get CMDB Instance by ClassRetrieves configuration items (CIs) from a specified CMDB class using the ServiceNow CMDB Instance API.
Get CMDB Instance by IDRetrieves a single CMDB configuration item (CI) by its class name and sys_id, including its attributes and relationship information.
Get CMDB Class MetadataRetrieves metadata and schema information for a specified CMDB (Configuration Management Database) class.
Get Cloud Catalog ServicesRetrieves a list of catalog items from the ServiceNow Cloud Services Catalog API.
Get Email by IDRetrieves a specific email record from ServiceNow's Email [sys_email] table by its sys_id.
Get Global User Role InheritanceRetrieves the granted and inherited roles for a specified ServiceNow user using the Global User Role Inheritance API.
Get importRetrieves the specified import staging record and its associated target records.
Get incident byRetrieves a specific incident from ServiceNow by its sys_id.
Get incident by id2Retrieves a specific incident from ServiceNow by its sys_id using the Table API.
Get IncidentsRetrieves incidents from the ServiceNow incident table using the Table API.
Get Performance Analytics ScorecardsRetrieves details about indicators from the Analytics Hub, including scorecard information for performance analytics.
Get recordsRetrieves multiple records from a specified ServiceNow table with optional filtering and pagination.
Get Record TypesRetrieves all available table record types from the ServiceNow instance using the Table API documentation endpoint.
Get Rows from TableRetrieves records from a specified ServiceNow table using the Table API v2.
Get servicatalog items byRetrieves a specific Service Catalog item from ServiceNow using its sys_id.
Get Catalog Item VariablesRetrieves the list of variables defined for a ServiceNow Service Catalog item.
Get Service Catalog CartRetrieves the details of all items within the logged-in user's Service Catalog shopping cart.
Get Service Catalog Cart Delivery AddressRetrieves the delivery/shipping address configured for a user's Service Catalog shopping cart.
Get Service Catalog Catalog by IDRetrieves the available information for a specified service catalog by its sys_id.
Get Service Catalog Catalog CategoriesRetrieves the list of available categories for a specified ServiceNow Service Catalog.
Get Service Catalog Category by IDRetrieves the available information for a specified service catalog category by its sys_id.
Get Service Catalog Item DelegationVerifies whether a delegated user has access to a specific ServiceNow Service Catalog item.
Get Service Catalog Items ListRetrieves a list of catalog items from ServiceNow's Service Catalog API.
Get Service Catalog Wishlist ListRetrieves the list of items in the logged-in user's ServiceNow Service Catalog wishlist.
Get sn cdm shared libraries upload statusRetrieves the current status of a shared library upload operation in ServiceNow.
Get sn chg rest change byRetrieves a specific change request from ServiceNow using its sys_id.
Get sn chg rest change emergency byRetrieves a specific emergency change request from ServiceNow using its sys_id.
Get sn chg rest change emergency listRetrieves one or more emergency change requests from ServiceNow using the Change Management API.
List ServiceNow Change RequestsRetrieves one or more change requests from ServiceNow based on specified filter criteria.
Get sn chg rest change model byRetrieves a specific change model from ServiceNow using its sys_id.
Get sn chg rest change model listRetrieves one or more change models from ServiceNow's Change Management API.
Get Normal Change Request by IDRetrieves a specific normal change request from ServiceNow using its sys_id via the Change Management REST API.
List ServiceNow Normal Change RequestsRetrieves one or more normal change requests from ServiceNow's Change Management API.
Get sn chg rest change standard byRetrieves a specific standard change request from ServiceNow using its sys_id.
Get sn chg rest change standard listRetrieves one or more standard change requests from ServiceNow using the Change Management API.
Get ServiceNow Standard Change Template by IDRetrieves a specific standard change template from ServiceNow using its sys_id.
List ServiceNow Standard Change TemplatesRetrieves one or more standard change templates from ServiceNow's Change Management API.
Get Change TasksRetrieves one or more tasks associated with a specific ServiceNow change request.
Get sn cicd app batch resultsRetrieves the results of a batch application install operation from ServiceNow CI/CD.
Get Instance Scan ResultRetrieves the current progress and status of a CI/CD instance scan operation in ServiceNow.
Get CI/CD ProgressRetrieves the current progress and status of a CI/CD operation in ServiceNow.
Get sn cicd testsuite resultsRetrieves the results of a test suite run from ServiceNow CI/CD based on the result ID.
Get statsRetrieves aggregate statistics for a specified ServiceNow table, including COUNT, AVG, MIN, MAX, and SUM calculations.
Get Table Records by IDRetrieves multiple records from a specified ServiceNow table using the Table API.
Get Table Record by IDRetrieves the record identified by the specified sys_id from the specified table.
Get table incident byRetrieves a single incident record from ServiceNow by its sys_id using the Table API.
List ServiceNow IncidentsRetrieves one or more incident records from the ServiceNow incident table using the Table API.
Get ServiceNow TablesRetrieves one or more records from a ServiceNow table using the Table API (GET /api/now/v2/table).
Get userRetrieves a specific user record from ServiceNow using its sys_id.
Get usersRetrieves multiple user records from the ServiceNow sys_user table with optional filtering and pagination.
List ServiceNow AttachmentsRetrieves metadata for multiple file attachments from ServiceNow's Attachment API.
List CMDB Linux ServersRetrieves Linux server configuration items (CIs) from the ServiceNow CMDB using the cmdb_ci_linux_server class.
List CMDB Configuration ItemsRetrieves configuration items (CIs) from the ServiceNow CMDB using the base cmdb_ci class.
List CMDB Relationship TypesRetrieves CMDB relationship types from the ServiceNow cmdb_rel_type table using the Table API.
List Service Catalog CatalogsRetrieves a list of ServiceNow Service Catalog catalogs to which the user has access.
Refresh Impacted Services for ChangeRefreshes and repopulates the impacted services/configuration items for a change request in ServiceNow using the Change Management REST API.
Retrieve sn cicd update setRetrieves an update set with a given sys_id from the ServiceNow CICD (Continuous Integration/Continuous Delivery) plugin.
Schedule change first availableUpdates the planned start and end times of a ServiceNow change request to the first available schedule slot.
Update cmdb csdm app service populate servicePopulates an Application Service with CI (Configuration Item) relationships based on the CSDM (Common Service Data Model) model.
Update CMDB CSDM App Service Service DetailsUpdates the service details for a specific application service in the CMDB CSDM (Common Service Data Model).
Update cmdb instance byUpdates an existing configuration item (CI) record in the ServiceNow CMDB by its sys_id.
Update CMDB Instance by IDUpdates an existing Configuration Item (CI) instance in the ServiceNow CMDB.
Update conversation member dropDrops an agent from a conversation in ServiceNow using the Conversation Member API.
Update incident byUpdates an existing incident in ServiceNow identified by its sys_id using the Table API.
Update incident by id2Updates an existing incident record in ServiceNow using the Table API.
Update openframe voice interactionUpdates an existing voice interaction record in ServiceNow OpenFrame.
Update servicecatalog cartUpdates an existing item in the ServiceNow Service Portal shopping cart.
Update servicecatalog items submit guideSubmits an order guide in ServiceNow's Service Catalog with the specified variable values.
Update sn chg rest changeUpdates an existing change request in ServiceNow using the Change Management REST API.
Update sn chg rest change emergencyUpdates an existing emergency change request in ServiceNow using the Change Management API.
Update Normal Change RequestUpdates a normal change request identified by its sys_id using the ServiceNow Change Management REST API.
Update ServiceNow Standard Change RequestUpdates a standard change request in ServiceNow using its sys_id.
Update sn chg rest change taskUpdates an existing change request task in ServiceNow using the Change Management REST API.
Update SD-WAN Trouble TicketUpdates an existing trouble ticket in ServiceNow using the Service Operations Workspace Trouble Ticket Open API.
Update Trouble TicketUpdates an existing trouble ticket in ServiceNow using the Trouble Ticket Open API.
Update table byUpdates an existing record in a specified ServiceNow table by its sys_id using the Table API.
Update table by id2Updates an existing record in a specified ServiceNow table using its sys_id with the provided field values.
Update table incidentUpdates an existing incident record in ServiceNow using the Table API.
Update table recordUpdates an existing record in a specified ServiceNow table using the Table API.
Upload Attachment to ServiceNow RecordUploads a file as an attachment to a specified record in ServiceNow.

What is the Composio tool router, and how does it fit here?

What is Composio SDK?

Composio's Composio SDK helps agents find the right tools for a task at runtime. You can plug in multiple toolkits (like Gmail, HubSpot, and GitHub), and the agent will identify the relevant app and action to complete multi-step workflows. This can reduce token usage and improve the reliability of tool calls. Read more here: Getting started with Composio SDK

The tool router generates a secure MCP URL that your agents can access to perform actions.

How the Composio SDK works

The Composio SDK follows a three-phase workflow:

  1. Discovery: Searches for tools matching your task and returns relevant toolkits with their details.
  2. Authentication: Checks for active connections. If missing, creates an auth config and returns a connection URL via Auth Link.
  3. Execution: Executes the action using the authenticated connection.

Step-by-step Guide

Prerequisites

Before you begin, make sure you have:
  • Python 3.8/Node 16 or higher installed
  • A Composio account with the API key
  • An OpenAI API key
  • A ServiceNow account and project
  • Basic familiarity with async Python/Typescript

Getting API Keys for OpenAI, Composio, and ServiceNow

OpenAI API key (OPENAI_API_KEY)
  • Go to the OpenAI dashboard
  • Create an API key if you don't have one
  • Assign it to OPENAI_API_KEY in .env
Composio API key and user ID
  • Log into the Composio dashboard
  • Copy your API key from Settings
    • Use this as COMPOSIO_API_KEY
  • Pick a stable user identifier (email or ID)
    • Use this as COMPOSIO_USER_ID

Installing dependencies

pip install composio-llamaindex llama-index llama-index-llms-openai llama-index-tools-mcp python-dotenv

Create a new Python project and install the necessary dependencies:

  • composio-llamaindex: Composio's LlamaIndex integration
  • llama-index: Core LlamaIndex framework
  • llama-index-llms-openai: OpenAI LLM integration
  • llama-index-tools-mcp: MCP client for LlamaIndex
  • python-dotenv: Environment variable management

Set environment variables

bash
OPENAI_API_KEY=your-openai-api-key
COMPOSIO_API_KEY=your-composio-api-key
COMPOSIO_USER_ID=your-user-id

Create a .env file in your project root:

These credentials will be used to:

  • Authenticate with OpenAI's GPT-5 model
  • Connect to Composio's Tool Router
  • Identify your Composio user session for ServiceNow access

Import modules

import asyncio
import os
import dotenv

from composio import Composio
from composio_llamaindex import LlamaIndexProvider
from llama_index.core.agent.workflow import ReActAgent
from llama_index.core.workflow import Context
from llama_index.llms.openai import OpenAI
from llama_index.tools.mcp import BasicMCPClient, McpToolSpec

dotenv.load_dotenv()

Create a new file called servicenow_llamaindex_agent.py and import the required modules:

Key imports:

  • asyncio: For async/await support
  • Composio: Main client for Composio services
  • LlamaIndexProvider: Adapts Composio tools for LlamaIndex
  • ReActAgent: LlamaIndex's reasoning and action agent
  • BasicMCPClient: Connects to MCP endpoints
  • McpToolSpec: Converts MCP tools to LlamaIndex format

Load environment variables and initialize Composio

OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
COMPOSIO_API_KEY = os.getenv("COMPOSIO_API_KEY")
COMPOSIO_USER_ID = os.getenv("COMPOSIO_USER_ID")

if not OPENAI_API_KEY:
    raise ValueError("OPENAI_API_KEY is not set in the environment")
if not COMPOSIO_API_KEY:
    raise ValueError("COMPOSIO_API_KEY is not set in the environment")
if not COMPOSIO_USER_ID:
    raise ValueError("COMPOSIO_USER_ID is not set in the environment")

What's happening:

This ensures missing credentials cause early, clear errors before the agent attempts to initialise.

Create a Tool Router session and build the agent function

async def build_agent() -> ReActAgent:
    composio_client = Composio(
        api_key=COMPOSIO_API_KEY,
        provider=LlamaIndexProvider(),
    )

    session = composio_client.create(
        user_id=COMPOSIO_USER_ID,
        toolkits=["servicenow"],
    )

    mcp_url = session.mcp.url
    print(f"Composio MCP URL: {mcp_url}")

    mcp_client = BasicMCPClient(mcp_url, headers={"x-api-key": COMPOSIO_API_KEY})
    mcp_tool_spec = McpToolSpec(client=mcp_client)
    tools = await mcp_tool_spec.to_tool_list_async()

    llm = OpenAI(model="gpt-5")

    description = "An agent that uses Composio Tool Router MCP tools to perform ServiceNow actions."
    system_prompt = """
    You are a helpful assistant connected to Composio Tool Router.
    Use the available tools to answer user queries and perform ServiceNow actions.
    """
    return ReActAgent(tools=tools, llm=llm, description=description, system_prompt=system_prompt, verbose=True)

What's happening here:

  • We create a Composio client using your API key and configure it with the LlamaIndex provider
  • We then create a tool router MCP session for your user, specifying the toolkits we want to use (in this case, servicenow)
  • The session returns an MCP HTTP endpoint URL that acts as a gateway to all your configured tools
  • LlamaIndex will connect to this endpoint to dynamically discover and use the available ServiceNow tools.
  • The MCP tools are mapped to LlamaIndex-compatible tools and plug them into the Agent.

Create an interactive chat loop

async def chat_loop(agent: ReActAgent) -> None:
    ctx = Context(agent)
    print("Type 'quit', 'exit', or Ctrl+C to stop.")

    while True:
        try:
            user_input = input("\nYou: ").strip()
        except (KeyboardInterrupt, EOFError):
            print("\nBye!")
            break

        if not user_input or user_input.lower() in {"quit", "exit"}:
            print("Bye!")
            break

        try:
            print("Agent: ", end="", flush=True)
            handler = agent.run(user_input, ctx=ctx)

            async for event in handler.stream_events():
                # Stream token-by-token from LLM responses
                if hasattr(event, "delta") and event.delta:
                    print(event.delta, end="", flush=True)
                # Show tool calls as they happen
                elif hasattr(event, "tool_name"):
                    print(f"\n[Using tool: {event.tool_name}]", flush=True)

            # Get final response
            response = await handler
            print()  # Newline after streaming
        except KeyboardInterrupt:
            print("\n[Interrupted]")
            continue
        except Exception as e:
            print(f"\nError: {e}")

What's happening here:

  • We're creating a direct terminal interface to chat with your ServiceNow database
  • The LLM's responses are streamed to the CLI for faster interaction.
  • The agent uses context to maintain conversation history
  • You can type 'quit' or 'exit' to stop the chat loop gracefully
  • Agent responses and any errors are displayed in a clear, readable format

Define the main entry point

async def main() -> None:
    agent = await build_agent()
    await chat_loop(agent)

if __name__ == "__main__":
    # Handle Ctrl+C gracefully
    signal.signal(signal.SIGINT, lambda s, f: (print("\nBye!"), exit(0)))
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        print("\nBye!")

What's happening here:

  • We're orchestrating the entire application flow
  • The agent gets built with proper error handling
  • Then we kick off the interactive chat loop so you can start talking to ServiceNow

Run the agent

npx ts-node llamaindex-agent.ts

When prompted, authenticate and authorise your agent with ServiceNow, then start asking questions.

Complete Code

Here's the complete code to get you started with ServiceNow and LlamaIndex:

import asyncio
import os
import signal
import dotenv

from composio import Composio
from composio_llamaindex import LlamaIndexProvider
from llama_index.core.agent.workflow import ReActAgent
from llama_index.core.workflow import Context
from llama_index.llms.openai import OpenAI
from llama_index.tools.mcp import BasicMCPClient, McpToolSpec

dotenv.load_dotenv()

OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
COMPOSIO_API_KEY = os.getenv("COMPOSIO_API_KEY")
COMPOSIO_USER_ID = os.getenv("COMPOSIO_USER_ID")

if not OPENAI_API_KEY:
    raise ValueError("OPENAI_API_KEY is not set")
if not COMPOSIO_API_KEY:
    raise ValueError("COMPOSIO_API_KEY is not set")
if not COMPOSIO_USER_ID:
    raise ValueError("COMPOSIO_USER_ID is not set")

async def build_agent() -> ReActAgent:
    composio_client = Composio(
        api_key=COMPOSIO_API_KEY,
        provider=LlamaIndexProvider(),
    )

    session = composio_client.create(
        user_id=COMPOSIO_USER_ID,
        toolkits=["servicenow"],
    )

    mcp_url = session.mcp.url
    print(f"Composio MCP URL: {mcp_url}")

    mcp_client = BasicMCPClient(mcp_url, headers={"x-api-key": COMPOSIO_API_KEY})
    mcp_tool_spec = McpToolSpec(client=mcp_client)
    tools = await mcp_tool_spec.to_tool_list_async()

    llm = OpenAI(model="gpt-5")
    description = "An agent that uses Composio Tool Router MCP tools to perform ServiceNow actions."
    system_prompt = """
    You are a helpful assistant connected to Composio Tool Router.
    Use the available tools to answer user queries and perform ServiceNow actions.
    """
    return ReActAgent(
        tools=tools,
        llm=llm,
        description=description,
        system_prompt=system_prompt,
        verbose=True,
    );

async def chat_loop(agent: ReActAgent) -> None:
    ctx = Context(agent)
    print("Type 'quit', 'exit', or Ctrl+C to stop.")

    while True:
        try:
            user_input = input("\nYou: ").strip()
        except (KeyboardInterrupt, EOFError):
            print("\nBye!")
            break

        if not user_input or user_input.lower() in {"quit", "exit"}:
            print("Bye!")
            break

        try:
            print("Agent: ", end="", flush=True)
            handler = agent.run(user_input, ctx=ctx)

            async for event in handler.stream_events():
                # Stream token-by-token from LLM responses
                if hasattr(event, "delta") and event.delta:
                    print(event.delta, end="", flush=True)
                # Show tool calls as they happen
                elif hasattr(event, "tool_name"):
                    print(f"\n[Using tool: {event.tool_name}]", flush=True)

            # Get final response
            response = await handler
            print()  # Newline after streaming
        except KeyboardInterrupt:
            print("\n[Interrupted]")
            continue
        except Exception as e:
            print(f"\nError: {e}")

async def main() -> None:
    agent = await build_agent()
    await chat_loop(agent)

if __name__ == "__main__":
    # Handle Ctrl+C gracefully
    signal.signal(signal.SIGINT, lambda s, f: (print("\nBye!"), exit(0)))
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        print("\nBye!")

Conclusion

You've successfully connected ServiceNow to LlamaIndex through Composio's Tool Router MCP layer. Key takeaways:
  • Tool Router dynamically exposes ServiceNow tools through an MCP endpoint
  • LlamaIndex's ReActAgent handles reasoning and orchestration; Composio handles integrations
  • The agent becomes more capable without increasing prompt size
  • Async Python provides clean, efficient execution of agent workflows
You can easily extend this to other toolkits like Gmail, Notion, Stripe, GitHub, and more by adding them to the toolkits parameter.

How to build ServiceNow MCP Agent with another framework

FAQ

What are the differences in Tool Router MCP and ServiceNow MCP?

With a standalone ServiceNow MCP server, the agents and LLMs can only access a fixed set of ServiceNow tools tied to that server. However, with the Composio Tool Router, agents can dynamically load tools from ServiceNow and many other apps based on the task at hand, all through a single MCP endpoint.

Can I use Tool Router MCP with LlamaIndex?

Yes, you can. LlamaIndex fully supports MCP integration. You get structured tool calling, message history handling, and model orchestration while Tool Router takes care of discovering and serving the right ServiceNow tools.

Can I manage the permissions and scopes for ServiceNow while using Tool Router?

Yes, absolutely. You can configure which ServiceNow scopes and actions are allowed when connecting your account to Composio. You can also bring your own OAuth credentials or API configuration so you keep full control over what the agent can do.

How safe is my data with Composio Tool Router?

All sensitive data such as tokens, keys, and configuration is fully encrypted at rest and in transit. Composio is SOC 2 Type 2 compliant and follows strict security practices so your ServiceNow data and credentials are handled as safely as possible.

Used by agents from

Context
Letta
glean
HubSpot
Agent.ai
Altera
DataStax
Entelligence
Rolai
Context
Letta
glean
HubSpot
Agent.ai
Altera
DataStax
Entelligence
Rolai
Context
Letta
glean
HubSpot
Agent.ai
Altera
DataStax
Entelligence
Rolai

Never worry about agent reliability

We handle tool reliability, observability, and security so you never have to second-guess an agent action.