---
title: Configuring Tools for Catalog Registration
slug: configuring-tools-for-catalog-registration
docTags: 
createdAt: 2026-08-26T22:50:26.544Z
---

# Add tool to catalog registration&#x20;

After discovering available tools, add them to your agent-catalog-registration.json:

::::WorkflowBlock
:::WorkflowBlockItem
**Run Discovery**

```javascript
python scripts/list_mcp_tools.py --format catalog
```
:::

:::WorkflowBlockItem
**Select required tools**

Choose only the tools your agent needs:

```javascript
{
 "tools": [
 {
 "name": "servicenow_mcp",
 "operations": [
 "servicenow_get_all_incidents",
 "servicenow_search_incidents"
 ]
 },
 {
 "name": "bridge_mcp",
 "operations": [
 "bridge_execute_query",
 "bridge_list_domains",
 "bridge_list_tables",
 "bridge_get_table_details"
 	]
     }
  ]
}
```
:::

:::WorkflowBlockItem
**Update Registration JSON**

Copy the tools configuration to your agent-catalog-registration.json file.
:::
::::

# Using MCP tools in your agent

## Calling tools with MCPClient

```javascript
import os
from bridge_agent_sdk import MCPClient

# Initialize client — base_url is optional (SDK resolves from KAIF_HOST)
mcp = MCPClient(
 agent_payload=state.get("platform_context", {}),
)

# Call a tool
result = await mcp.call_tool(
 tool_name="servicenow_get_all_incidents",
 arguments={"limit": 10}
)

# Process result
incidents = result.get("data", [])
```

## Tool naming convention

MCP tool names follow the pattern: \_

| <font color="#f3f4f6">**Pattern**</font> | <font color="#f3f4f6">**Example**</font> |
| ---------------------------------------- | ---------------------------------------- |
| servicenow\_\*                           | servicenow\_get\_all\_incidents          |
| bridge\_\*                               | bridge\_execute\_query                   |
| azure\_\*                                | azure\_keyvault                          |
| aiops\_\*                                | aiops\_ask\_me\_anything                 |

## Error handling

Try the following:

```javascript
 result = await mcp.call_tool(tool_name="servicenow_search_incidents", arguments={"limit": 10})

 if "error" in result:
 logger.error(f"MCP tool error: {result['error']}")
 return {"error": result["error"]}

 return result.get("data", [])

except Exception as e:
 logger.exception(f"MCP call failed: {{e}}")
 raise
```

## MCP Wire Protocol (JSON-RPC 2.0)

The Bridge MCP server uses the **JSON-RPC 2.0** protocol. While the SDK's MCPClient handles this for you, understanding the wire format is essential for debugging and writing test scripts.

::::WorkflowBlock
:::WorkflowBlockItem
**Listing Tools - tools/list**

```javascript
curl -s -X POST "$BRIDGE_MCP_SERVER_URL" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
 "jsonrpc": "2.0",
 "id": 1,
 "method": "tools/list",
 "params": {}
 }' | jq '.result.tools | length'
```

****
:::

:::WorkflowBlockItem
**Response structure:**

```javascript
{
 "jsonrpc": "2.0",
 "id": 1,
 "result": {
 "tools": [
 {
 "name": "servicenow_search_incidents",
 "description": "Search for incidents...",
 "inputSchema": { "type": "object", "properties": {{...}}, "required": [...] }
 	}
     ]
  }
}
```

****
:::

:::WorkflowBlockItem
**Calling a Tool - tools/call**

```javascript
curl -s -X POST "${{BRIDGE_MCP_SERVER_URL}}?tenant_id=${{ACCOUNT_ID}}&account_id=${{ACCOUNT_ID}}" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -H "accept: application/json" \
 -H "x-instance-id: $DEPLOYMENT_NAME" \
 -H "X-Route-Version: v3" \
 -d '{
 "jsonrpc": "2.0",
 "id": 1,
 "method": "tools/call",
 "params": {
 "name": "servicenow_search_incidents",
 "arguments": {
 "search_term": "INC0010001",
 "search_fields": ["number"]
	 }
     }
 }'
```
:::
::::

:::hint{type="info"}
**Common mistake:** Sending a flat payload like \{"tool\_name": "...", "arguments": } will return 422 Unprocessable Entity. You **must** use the JSON-RPC envelope with jsonrpc, method, and params fields.
:::

## Required headers for MCP calls

When calling MCP tools (either directly or via the SDK), the following HTTP headers are required:

| <font color="#f3f4f6">**Header**</font> | <font color="#f3f4f6">**Required**</font> | <font color="#f3f4f6">**Value**</font>                | <font color="#f3f4f6">**Purpose**</font>                                                                                                  |
| --------------------------------------- | ----------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| Authorization                           | Yes                                       | Bearer \<IAM\_TOKEN>                                  | Authentication — obtained from /api/iam/v4/identity/token                                                                                 |
| Content-Type                            | Yes                                       | application/json                                      | Request body format                                                                                                                       |
| x-instance-id                           | Yes                                       | Your deployment name (e.g., inc-enrichment-deploy-v1) | Routes the call to the correct agent deployment                                                                                           |
| X-Route-Version                         | Yes                                       | v3                                                    | Critical — Tells the MCP gateway to use v3 routing. Without this header you will get 403 — Agent instance not found in default collection |
| accept                                  | Recommended                               | application/json                                      | Response format                                                                                                                           |

### The X-Route-Version: v3 Header

This is the most commonly missed header. The SDK sets it automatically, but when writing test scripts or curl commands you must include it:

```javascript
headers = {
 "Authorization": f"Bearer {{token}}",
 "Content-Type": "application/json",
 "accept": "application/json",
 "x-instance-id": deployment_name,       # your deployment name
 "X-Route-Version": "v3",                # ← CRITICAL — do not omit
}
```

**Without this header**, the MCP gateway falls back to the default routing collection and returns:

```javascript
{
 "detail": "Agent instance not found in default collection",
 "status_code": 403
}
```

## Query parameters

When making direct HTTP calls, append tenant and account IDs as query parameters:

POST ?tenant\_id=\&account\_id=

The SDK's MCPClient appends these automatically (you can see it in the logs: Internal route - adding query params: \['tenant\_id', 'account\_id']).

# Testing MCP tools

### Method 1: Discovery script&#x20;

Always start by discovering what tools are actually available:

```javascript
# List all tools grouped by MCP server
python scripts/list_mcp_tools.py

# Filter to a specific server
python scripts/list_mcp_tools.py --filter servicenow

# Export full schemas to JSON
python scripts/list_mcp_tools.py --output available-tools.json --format raw
```

### Method 2: Get full tool schemas

::::WorkflowBlock
:::WorkflowBlockItem
**Create scripts/get\_tool\_schema.py to inspect exact inputSchema of tools:**

```javascript
#!/usr/bin/env python3
"""Get the full input schema for specific MCP tools."""
import os, json, requests
from dotenv import load_dotenv

load_dotenv()

kaif_host = os.getenv("KAIF_HOST")
service_api_key = os.getenv("SERVICE_API_KEY")
mcp_url = os.getenv("BRIDGE_MCP_SERVER_URL")
```
:::

:::WorkflowBlockItem
**Get Bridge Access Management token**

```javascript
token = requests.post(
 f"{{kaif_host}}/api/iam/v4/identity/token",
 json={"apikey": service_api_key},
 headers={"Content-Type": "application/json"},
 timeout=30,
).json().get("token")
```
:::

:::WorkflowBlockItem
&#x20;**List tools (JSON-RPC 2.0)**

```javascript
resp = requests.post(
 mcp_url,
 headers={
 	"Content-Type": "application/json",
 	"Authorization": f"Bearer {{token}}",
 },
 json={"jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {}},
 timeout=60,
)
tools = resp.json().get("result", {}).get("tools", [])
```
:::

:::WorkflowBlockItem
**Filter and print (change the prefix to inspect other servers)**

```javascript
for t in tools:
 if "servicenow" in t.get("name", ""):
 print(json.dumps(t, indent=2))
 print("---")
```
:::
::::

### Method 3: Direct tool call (test script)

::::WorkflowBlock
:::WorkflowBlockItem
**Test a specific tool call with all required headers**

```javascript
#!/usr/bin/env python3
"""Test a single MCP tool call with full headers."""
import os, json, requests
from dotenv import load_dotenv

load_dotenv()

kaif_host       = os.getenv("KAIF_HOST")
service_api_key = os.getenv("SERVICE_API_KEY")
account_id      = os.getenv("BRIDGE_ACCOUNT_ID")
mcp_url         = os.getenv("BRIDGE_MCP_SERVER_URL")
deployment_name = "inc-enrichment-deploy-v1"   # ← your deployment name
```
:::

:::WorkflowBlockItem
**Authenticate**

```javascript
token = requests.post(
 f"{{kaif_host}}/api/iam/v4/identity/token",
 json={"apikey": service_api_key},
 headers={"Content-Type": "application/json"},
 timeout=30,
).json()["token"]
```
:::

:::WorkflowBlockItem
**Build request&#x20;**

```javascript
headers = {
 "Authorization": f"Bearer {{token}}",
 "Content-Type": "application/json",
 "accept": "application/json",
 "x-instance-id": deployment_name,    # routes to your deployment
 "X-Route-Version": "v3",             # ← CRITICAL
}

payload = {
 "jsonrpc": "2.0",
  "id": 1,
 "method": "tools/call",
 "params": {
 "name": "servicenow_search_incidents",
 "arguments": {
 "search_term": "INC0010001",
 "search_fields": ["number"],
 	},
    },
}

full_url = f"{{mcp_url}}?tenant_id={{account_id}}&account_id={{account_id}}"
```
:::

:::WorkflowBlockItem
**Call**

```javascript
resp = requests.post(full_url, headers=headers, json=payload, timeout=30)

print(f"Status : {{resp.status_code}}")
print(f"Body   : {json.dumps(resp.json(), indent=2)}")
```
:::
::::

### Method 4: Curl one-liner

::::WorkflowBlock
:::WorkflowBlockItem
**Get Bridge Access Management token**

```javascript
TOKEN=$(curl -s -X POST "$KAIF_HOST/api/iam/v4/identity/token" \
 -H "Content-Type: application/json" \
 -d "{\"apikey\": \"$SERVICE_API_KEY\"}" | jq -r '.token')
```
:::

:::WorkflowBlockItem
**Call tool&#x20;**

```javascript
curl -s -X POST "${{BRIDGE_MCP_SERVER_URL}}?tenant_id=${{BRIDGE_ACCOUNT_ID}}&account_id=${{BRIDGE_ACCOUNT_ID}}" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -H "accept: application/json" \
 -H "x-instance-id: inc-enrichment-deploy-v1" \
 -H "X-Route-Version: v3" \
 -d '{
   "jsonrpc": "2.0",
   "id": 1,
   "method": "tools/call",
   "params": {
 	"name": "bridge_execute_query",
 	"arguments": {
 	"query": "SELECT number, short_description FROM \"ITSM\".incident  LIMIT 5"
 }
 }
 }' | jq .
```
:::
::::

