Share this page

# Build custom integrations

This topic includes raw HTTP/curl examples for connecting to the MCP server, along with the full tool reference needed to build your own client, script, or integration.

In this topic:

## Overview

Use the sections in this topic to build and validate a custom integration:

1. Generic HTTP client (curl): Use the curl requests to verify endpoint access, authenticate, list tools, and run an initial tool call.

2. Tool reference: Implement each tool in your integration using the documented parameters, examples, and response formats.

3. End-to-end workflow example: Use the example sequence as a template for the order of tool calls in your own integration flow.

4. Register the integration: Register the integration in the OpenText Software Delivery Management authorization server with a unique `client_name` and the allowed `redirect_uris`. For details, see Enable MCP and register clients.

## Generic HTTP client (curl)

Use this to test the connection or build custom integrations.

Discover available tools:

    curl -s -X POST https://myoctane.company.com/mcp \
      -H "Authorization: Bearer <your-token>" \
      -H "Content-Type: application/json" \
      -H "Accept: application/json, text/event-stream" \
      -d '{
        "jsonrpc": "2.0",
        "id": "1",
        "method": "tools/list"
      }'

Call a tool:

    curl -s -X POST https://myoctane.company.com/mcp \
      -H "Authorization: Bearer <your-token>" \
      -H "Content-Type: application/json" \
      -H "Accept: application/json, text/event-stream" \
      -d '{
        "jsonrpc": "2.0",
        "id": "2",
        "method": "tools/call",
        "params": {
          "name": "get_entities",
          "arguments": {
            "sharedSpaceId": 1001,
            "workSpaceId": 1002,
            "entityType": "defect",
            "fields": ["id", "name", "severity"],
            "limit": 10
          }
        }
      }'

Successful response shape:

    {
      "jsonrpc": "2.0",
      "id": "2",
      "result": {
        "content": [{ "type": "text", "text": "{ \"entities\": [...] }" }]
      }
    }

Error response shape (business-logic error, HTTP 200):

    {
      "jsonrpc": "2.0",
      "id": "2",
      "result": {
        "content": [{ "type": "text", "text": "User validation failed in shared space 1001" }],
        "isError": true
      }
    }

## Tool reference

All tools require `sharedSpaceId` and `workSpaceId`. Every call is scoped to a single workspace.

### get_entity_types

List all entity types available in the workspace - names, labels, aggregate groups, and descriptors.

Call this first to discover valid `entityType` values for other tools.

#### Parameters

Name | Type | Required | Description
--- | --- | --- | ---
`sharedSpaceId` | number | Yes | Numeric ID of the shared space (tenant).
`workSpaceId` | number | Yes | Numeric ID of the workspace.

#### Example

    {
      "jsonrpc": "2.0",
      "id": "1",
      "method": "tools/call",
      "params": {
        "name": "get_entity_types",
        "arguments": {
          "sharedSpaceId": 1001,
          "workSpaceId": 1002
        }
      }
    }

#### Response (excerpt)

    {
      "result": {
        "content": [{
          "type": "text",
          "text": "{ \"aggregates\": [ { \"name\": \"defect\", \"label\": \"Defect\", ... }, { \"name\": \"story\", \"label\": \"User Story\", ... } ] }"
        }]
      }
    }

### get_entity_field_metadata

Return field definitions for a given entity type - field names, types, labels, and other attributes.

Call this before `get_entities` or `get_entity` to know which fields to request or filter on.

#### Parameters

Name | Type | Description
--- | --- | ---
`sharedSpaceId` | number | Numeric ID of the shared space.
`workSpaceId` | number | Numeric ID of the workspace.
`entityType` | string | Entity type identifier (e.g. `defect`). Use `get_entity_types` to discover valid values.

#### Example

    {
      "jsonrpc": "2.0",
      "id": "1",
      "method": "tools/call",
      "params": {
        "name": "get_entity_field_metadata",
        "arguments": {
          "sharedSpaceId": 1001,
          "workSpaceId": 1002,
          "entityType": "defect"
        }
      }
    }

#### Response (excerpt)

    {
      "result": {
        "content": [{
          "type": "text",
          "text": "{ \"fields\": [ { \"name\": \"severity\", \"label\": \"Severity\", \"field_type\": \"reference\", ... }, { \"name\": \"phase\", \"label\": \"Phase\", ... } ] }"
        }]
      }
    }

### get_filter_metadata

Return the Octane filter query syntax documentation - operators, value formats, logical connectors, and special tokens.

Call this before building any filter expression for `get_entities`.

#### Parameters

Name | Type | Description
--- | --- | ---
`sharedSpaceId` | number | Numeric ID of the shared space.
`workSpaceId` | number | Numeric ID of the workspace.

#### Example

    {
      "jsonrpc": "2.0",
      "id": "1",
      "method": "tools/call",
      "params": {
        "name": "get_filter_metadata",
        "arguments": {
          "sharedSpaceId": 1001,
          "workSpaceId": 1002
        }
      }
    }

### get_entities

Retrieve a paginated list of entities of the same type. Supports structured filtering, full-text keyword search, field selection, sorting, and pagination.

#### Parameters

Name | Type | Description
--- | --- | ---
`sharedSpaceId` | number | Numeric ID of the shared space.
`workSpaceId` | number | Numeric ID of the workspace.
`entityType` | string | Entity type identifier (e.g. `defect`, `story`).
`filter` | string | Structured filter expression. Call `get_filter_metadata` first.
`keywords` | string | Free-text search string. Searches across entity text fields.
`search_fields` | string[] | Restrict keyword search to specific fields. Only effective when `keywords` is provided.
`fields` | string[] | Fields to include in results. Defaults to `id` only if omitted.
`limit` | number | Max entities per page. Default: 100. Maximum: 500.
`offset` | number | Zero-based start index for pagination. Default: 0.
`orderBy` | string | Sort field. Prefix with `-` for descending (e.g. `-name`). Default: ascending by `id`.

#### Example - filter by severity and phase

    {
      "jsonrpc": "2.0",
      "id": "1",
      "method": "tools/call",
      "params": {
        "name": "get_entities",
        "arguments": {
          "sharedSpaceId": 1001,
          "workSpaceId": 1002,
          "entityType": "defect",
          "filter": "(severity EQ {id='list_node.severity.critical'} || severity EQ {id='list_node.severity.high'}) ; !(phase EQ {id='list_node.defect.phase.closed'})",
          "fields": ["id", "name", "severity", "phase", "owner"],
          "orderBy": "-id",
          "limit": 25
        }
      }
    }

#### Example - keyword search

    {
      "jsonrpc": "2.0",
      "id": "1",
      "method": "tools/call",
      "params": {
        "name": "get_entities",
        "arguments": {
          "sharedSpaceId": 1001,
          "workSpaceId": 1002,
          "entityType": "story",
          "keywords": "login performance",
          "fields": ["id", "name", "story_points", "phase"],
          "limit": 10
        }
      }
    }

#### Example - pagination

    {
      "jsonrpc": "2.0",
      "id": "1",
      "method": "tools/call",
      "params": {
        "name": "get_entities",
        "arguments": {
          "sharedSpaceId": 1001,
          "workSpaceId": 1002,
          "entityType": "defect",
          "fields": ["id", "name"],
          "limit": 100,
          "offset": 100
        }
      }
    }

#### Response (excerpt)

    {
      "result": {
        "content": [{
          "type": "text",
          "text": "{ \"entities\": [ { \"id\": 1005, \"name\": \"Login fails on Safari\", \"severity\": { \"id\": \"list_node.severity.critical\" } }, ... ] }"
        }]
      }
    }

### get_entity

Retrieve a single entity by its numeric ID.

#### Parameters

Name | Type | Description
--- | --- | ---
`sharedSpaceId` | number | Numeric ID of the shared space.
`workSpaceId` | number | Numeric ID of the workspace.
`entityType` | string | Entity type identifier (e.g. `defect`, `story`).
`entityId` | number | Numeric ID of the entity to retrieve.
`fields` | string[] | Fields to include. Use `get_entity_field_metadata` to discover valid names.

#### Example

    {
      "jsonrpc": "2.0",
      "id": "1",
      "method": "tools/call",
      "params": {
        "name": "get_entity",
        "arguments": {
          "sharedSpaceId": 1001,
          "workSpaceId": 1002,
          "entityType": "defect",
          "entityId": 3042,
          "fields": ["id", "name", "description", "severity", "phase", "owner", "creation_time"]
        }
      }
    }

#### Response

    {
      "result": {
        "content": [{
          "type": "text",
          "text": "{ \"id\": 3042, \"name\": \"Login fails on Safari\", \"severity\": { \"id\": \"list_node.severity.critical\" }, ... }"
        }]
      }
    }

Entity not found response (not an error, HTTP 200):

    {
      "result": {
        "content": [{ "type": "text", "text": "entity 3042 not found" }]
      }
    }

### create_entity

> MCP clients that respect the `requiresApproval` hint will ask for user confirmation before executing write operations.

Create a new entity with the specified field values.

On success, returns the entity's `id`, `name`, and a direct link to the entity in the Octane UI.

#### Parameters

Name | Type | Description
--- | --- | ---
`sharedSpaceId` | number | Numeric ID of the shared space.
`workSpaceId` | number | Numeric ID of the workspace.
`entityType` | string | Entity type to create (e.g. `defect`, `story`, `task`).
`field_values` | object | JSON object of field names -> values. See field value formats below.

#### Field value formats

Field kind | Format | Example
--- | --- | ---
Scalar (string, boolean) | Plain value | `"name": "Login crash"`
Scalar (number) | Plain value | `"story_points": 5`
Reference (single) | `{"id": <value>}` | `"severity": {"id": "list_node.severity.high"}`
Reference (multi-value) | `{"data": [{"id": <v>}, ...]}` | `"owner": {"data": [{"id": 1001}]}`
Date | ISO-8601 date | `"due_date": "2026-09-01"`
DateTime | UTC ISO-8601 | `"creation_time": "2026-09-01T10:00:00Z"`

Use `get_entity_field_metadata` to discover required fields and their types for a given entity type.

#### Example - create a defect

    {
      "jsonrpc": "2.0",
      "id": "1",
      "method": "tools/call",
      "params": {
        "name": "create_entity",
        "arguments": {
          "sharedSpaceId": 1001,
          "workSpaceId": 1002,
          "entityType": "defect",
          "field_values": {
            "name": "Login button unresponsive on mobile",
            "severity": {"id": "list_node.severity.high"},
            "parent": {"id": 2010}
          }
        }
      }
    }

#### Response

    {
      "result": {
        "content": [{
          "type": "text",
          "text": "{ \"status\": \"created\", \"id\": 4051, \"name\": \"Login button unresponsive on mobile\", \"link\": \"https://myoctane.company.com/ui/?p=1001/1002#/entity-navigation?entityType=defect&id=4051\" }"
        }]
      }
    }

### update_entity

> Beta feature. Requires the `mcp_write_tools_beta` experiment to be enabled by your administrator. MCP clients that respect the `requiresApproval` hint will ask for user confirmation before executing write operations.

Update specific fields on an existing entity. Only the supplied fields are changed - omitted fields keep their current values.

On success, returns the entity's `id`, `name`, and a direct link to the entity in the Octane UI.

#### Parameters

Name | Type | Description
--- | --- | ---
`sharedSpaceId` | number | Numeric ID of the shared space.
`workSpaceId` | number | Numeric ID of the workspace.
`entityType` | string | Entity type (e.g. `defect`, `story`).
`entityId` | number | Numeric ID of the entity to update.
`field_values` | object | JSON object of field names -> new values. Only supplied fields are changed. Same value formats as `create_entity`.

#### Example - change severity and close a defect

    {
      "jsonrpc": "2.0",
      "id": "1",
      "method": "tools/call",
      "params": {
        "name": "update_entity",
        "arguments": {
          "sharedSpaceId": 1001,
          "workSpaceId": 1002,
          "entityType": "defect",
          "entityId": 4051,
          "field_values": {
            "severity": {"id": "list_node.severity.critical"},
            "phase": {"id": "list_node.defect.phase.closed"}
          }
        }
      }
    }

#### Response

    {
      "result": {
        "content": [{
          "type": "text",
          "text": "{ \"status\": \"updated\", \"id\": 4051, \"name\": \"Login button unresponsive on mobile\", \"link\": \"https://myoctane.company.com/ui/?p=1001/1002#/entity-navigation?entityType=defect&id=4051\" }"
        }]
      }
    }

## End-to-end workflow example

This section shows a complete interaction pattern an AI assistant would follow to answer: "List all open critical defects in release 2005, and create a tracking story for the top one."

### Discover entity types

    { "method": "tools/call", "params": { "name": "get_entity_types",
      "arguments": { "sharedSpaceId": 1001, "workSpaceId": 1002 } } }

Confirms `defect` and `story` are valid types.

### Inspect defect fields

    { "method": "tools/call", "params": { "name": "get_entity_field_metadata",
      "arguments": { "sharedSpaceId": 1001, "workSpaceId": 1002, "entityType": "defect" } } }

Learns field names: `severity`, `phase`, `release`, `name`, `description`, `owner`, `id`.

### Learn filter syntax

    { "method": "tools/call", "params": { "name": "get_filter_metadata",
      "arguments": { "sharedSpaceId": 1001, "workSpaceId": 1002 } } }

Confirms operators and reference value format.

### Query open critical defects in release 2005

    {
      "method": "tools/call",
      "params": {
        "name": "get_entities",
        "arguments": {
          "sharedSpaceId": 1001,
          "workSpaceId": 1002,
          "entityType": "defect",
          "filter": "severity EQ {id='list_node.severity.critical'} ; !(phase EQ {id='list_node.defect.phase.closed'}) ; release EQ {id=2005}",
          "fields": ["id", "name", "severity", "phase", "owner"],
          "orderBy": "-id",
          "limit": 10
        }
      }
    }

Returns a list of matching defects.

### Retrieve full details of the top defect

    {
      "method": "tools/call",
      "params": {
        "name": "get_entity",
        "arguments": {
          "sharedSpaceId": 1001,
          "workSpaceId": 1002,
          "entityType": "defect",
          "entityId": 4051,
          "fields": ["id", "name", "description", "severity", "phase", "owner", "release"]
        }
      }
    }

### Inspect story fields

    { "method": "tools/call", "params": { "name": "get_entity_field_metadata",
      "arguments": { "sharedSpaceId": 1001, "workSpaceId": 1002, "entityType": "story" } } }

Learns required fields for creating a story (e.g. `name`, `parent`).

### Create a tracking story

    {
      "method": "tools/call",
      "params": {
        "name": "create_entity",
        "arguments": {
          "sharedSpaceId": 1001,
          "workSpaceId": 1002,
          "entityType": "story",
          "field_values": {
            "name": "Track and resolve critical login defect #4051",
            "parent": {"id": 3001}
          }
        }
      }
    }

Returns `{ "status": "created", "id": 5100, "name": "...", "link": "https://..." }`.

https://admhelp.microfocus.com Software Delivery Management 8942
Tips to improve your search results... OpenText™ Software Delivery Management Help Center OpenText™ Software Delivery Management Help 26.3 All View Local Help Center View Online Help Center Version: