> For the complete documentation index, see [llms.txt](https://k-ai.gitbook.io/knowledge-ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://k-ai.gitbook.io/knowledge-ai/k-ai-mcp/retrieval-tools.md).

# Retrieval tools (stable)

Server: `https://api-retrieval.kai-studio.ai/mcp`. **Status: stable.** Five tools that replace the removed `/search` endpoint of the K-AI Instance API and expose K-AI knowledge primitives to MCP clients. Each tool maps one-to-one to a REST operation on the K-AI Retrieval API; the K-AI MCP server forwards calls through the same OAuth 2.1 Bearer token used by the host.

Every response is wrapped as `{"response": <payload>}`. Identifiers are prefixed (`ki_` for K-AI instances, `kd_` for documents, `kn_` for semantic nodes) and must be passed back as-is — the server validates the exact prefix and rejects anything else with HTTP 400.

## Tools overview

| operationId                                    | Purpose                                                                                               | Underlying REST endpoint                             |
| ---------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ---------------------------------------------------- |
| `retrieval_instances_list_available_instances` | Discover the K-AI instances the user can access, their relationships, and the user's persona context. | `POST /retrieval/instances/list-available-instances` |
| `retrieval_documents_list`                     | Paginate through every document of a K-AI instance.                                                   | `POST /retrieval/documents/list`                     |
| `retrieval_documents_get_document`             | Fetch the full body and metadata of a single document.                                                | `POST /retrieval/documents/get-document`             |
| `retrieval_documents_list_by_ids`              | Batch-fetch the full body of multiple documents in one call.                                          | `POST /retrieval/documents/list-by-ids`              |
| `retrieval_semantic_nodes_search`              | Semantic search inside a K-AI instance; returns matched nodes with their source documents inlined.    | `POST /retrieval/semantic-nodes/search`              |

The canonical call order is: `retrieval_instances_list_available_instances` -> `retrieval_semantic_nodes_search` on the chosen instance(s) -> `retrieval_documents_list_by_ids` to expand the documents behind the matched nodes. `retrieval_documents_list` and `retrieval_documents_get_document` are auxiliary surfaces for browsing.

## retrieval\_instances\_list\_available\_instances

Returns the K-AI instances the authenticated user can access (with names and descriptions), the admin-defined relationships between those instances (natural-language descriptions of specialisation, scope override, complementarity, language or geography scoping, deprecation, etc.), and the persona context derived from the user's groups. Call this first to get the full picture, then route subsequent searches based on the relationship hints. When the relationships indicate overlap or specialisation, issue parallel searches across the relevant instances in the same turn.

The user is identified by the access token or cookie; no request body fields are required.

### Input schema

| Field    | Type | Required | Description        |
| -------- | ---- | -------- | ------------------ |
| *(none)* | —    | —        | Empty object `{}`. |

### Output schema

| Field                                  | Type                | Description                                                                                                                                 |
| -------------------------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `response.persona`                     | string \| null      | Composed persona text built from the user's groups. Acts as a lens on tone and emphasis; it does NOT filter which instances are searchable. |
| `response.instances`                   | array               | Accessible K-AI instances.                                                                                                                  |
| `response.instances[].id`              | string (`ki_*`)     | K-AI instance identifier.                                                                                                                   |
| `response.instances[].name`            | string              | Display name.                                                                                                                               |
| `response.instances[].description`     | string \| null      | Free-form description of the instance content.                                                                                              |
| `response.instances[].organization_id` | string \| null      | Owning organisation identifier.                                                                                                             |
| `response.relationships`               | array               | Admin-defined links between accessible instances.                                                                                           |
| `response.relationships[].between`     | array\[2] of string | Pair of `ki_*` ids the relationship connects.                                                                                               |
| `response.relationships[].description` | string              | Natural-language description of the relationship.                                                                                           |

### Example

{% tabs %}
{% tab title="Python (MCP SDK)" %}

```python
import asyncio
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

async def main():
    url = "https://api-retrieval.kai-studio.ai/mcp"
    headers = {"Authorization": "Bearer YOUR_TOKEN"}
    async with streamablehttp_client(url, headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()
            result = await session.call_tool(
                "retrieval_instances_list_available_instances", {}
            )
            print(result.structuredContent)

asyncio.run(main())
```

{% endtab %}

{% tab title="TypeScript (MCP SDK)" %}

```ts
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const transport = new StreamableHTTPClientTransport(
  new URL("https://api-retrieval.kai-studio.ai/mcp"),
  { requestInit: { headers: { Authorization: "Bearer YOUR_TOKEN" } } }
);
const client = new Client({ name: "demo", version: "1.0.0" });
await client.connect(transport);
const result = await client.callTool({
  name: "retrieval_instances_list_available_instances",
  arguments: {},
});
console.log(result.structuredContent);
```

{% endtab %}

{% tab title="Raw HTTP" %}

```bash
curl -X POST https://api-retrieval.kai-studio.ai/retrieval/instances/list-available-instances \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'
```

{% endtab %}
{% endtabs %}

## retrieval\_documents\_list

Returns a paginated list of all documents in a K-AI instance. Use after a semantic search to explore additional content from the same instance, or for catalog-style browsing when the user does not have a specific query.

### Input schema

| Field         | Type               | Required | Description                                                                     |
| ------------- | ------------------ | -------- | ------------------------------------------------------------------------------- |
| `instance_id` | string (`ki_*`)    | yes      | K-AI instance identifier (from `retrieval_instances_list_available_instances`). |
| `offset`      | integer (0–100000) | yes      | Number of documents to skip.                                                    |
| `limit`       | integer (1–1000)   | yes      | Maximum number of documents to return.                                          |

### Output schema

| Field             | Type            | Description                                                     |
| ----------------- | --------------- | --------------------------------------------------------------- |
| `response`        | array           | Document objects.                                               |
| `response[].id`   | string (`kd_*`) | K-AI document identifier.                                       |
| `response[].name` | string          | Document name (filename or extracted title).                    |
| `response[].*`    | any             | Additional metadata fields depending on instance configuration. |

### Example

{% tabs %}
{% tab title="Python (MCP SDK)" %}

```python
import asyncio
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

async def main():
    url = "https://api-retrieval.kai-studio.ai/mcp"
    headers = {"Authorization": "Bearer YOUR_TOKEN"}
    async with streamablehttp_client(url, headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()
            result = await session.call_tool(
                "retrieval_documents_list",
                {"instance_id": "ki_abc123", "offset": 0, "limit": 50},
            )
            print(result.structuredContent)

asyncio.run(main())
```

{% endtab %}

{% tab title="TypeScript (MCP SDK)" %}

```ts
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const transport = new StreamableHTTPClientTransport(
  new URL("https://api-retrieval.kai-studio.ai/mcp"),
  { requestInit: { headers: { Authorization: "Bearer YOUR_TOKEN" } } }
);
const client = new Client({ name: "demo", version: "1.0.0" });
await client.connect(transport);
const result = await client.callTool({
  name: "retrieval_documents_list",
  arguments: { instance_id: "ki_abc123", offset: 0, limit: 50 },
});
console.log(result.structuredContent);
```

{% endtab %}

{% tab title="Raw HTTP" %}

```bash
curl -X POST https://api-retrieval.kai-studio.ai/retrieval/documents/list \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"instance_id": "ki_abc123", "offset": 0, "limit": 50}'
```

{% endtab %}
{% endtabs %}

## retrieval\_documents\_get\_document

Returns the full body and metadata of a specific document found via a semantic search or via `retrieval_documents_list`. Use when the host LLM needs the complete content of a single document (e.g. to quote a passage, summarise the document, or expose a citation link).

### Input schema

| Field         | Type            | Required | Description               |
| ------------- | --------------- | -------- | ------------------------- |
| `instance_id` | string (`ki_*`) | yes      | K-AI instance identifier. |
| `document_id` | string (`kd_*`) | yes      | K-AI document identifier. |

### Output schema

| Field           | Type            | Description                                                                                           |
| --------------- | --------------- | ----------------------------------------------------------------------------------------------------- |
| `response.id`   | string (`kd_*`) | K-AI document identifier.                                                                             |
| `response.name` | string          | Document name.                                                                                        |
| `response.*`    | any             | Additional fields (body, MIME type, source URL, custom metadata) depending on instance configuration. |

### Example

{% tabs %}
{% tab title="Python (MCP SDK)" %}

```python
import asyncio
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

async def main():
    url = "https://api-retrieval.kai-studio.ai/mcp"
    headers = {"Authorization": "Bearer YOUR_TOKEN"}
    async with streamablehttp_client(url, headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()
            result = await session.call_tool(
                "retrieval_documents_get_document",
                {"instance_id": "ki_abc123", "document_id": "kd_def456"},
            )
            print(result.structuredContent)

asyncio.run(main())
```

{% endtab %}

{% tab title="TypeScript (MCP SDK)" %}

```ts
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const transport = new StreamableHTTPClientTransport(
  new URL("https://api-retrieval.kai-studio.ai/mcp"),
  { requestInit: { headers: { Authorization: "Bearer YOUR_TOKEN" } } }
);
const client = new Client({ name: "demo", version: "1.0.0" });
await client.connect(transport);
const result = await client.callTool({
  name: "retrieval_documents_get_document",
  arguments: { instance_id: "ki_abc123", document_id: "kd_def456" },
});
console.log(result.structuredContent);
```

{% endtab %}

{% tab title="Raw HTTP" %}

```bash
curl -X POST https://api-retrieval.kai-studio.ai/retrieval/documents/get-document \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"instance_id": "ki_abc123", "document_id": "kd_def456"}'
```

{% endtab %}
{% endtabs %}

## retrieval\_documents\_list\_by\_ids

Batch-fetches the full content of multiple documents in a single call. Use with the `kd_*` identifiers returned by `retrieval_semantic_nodes_search` to expand the documents behind the matched nodes without issuing one request per document.

### Input schema

| Field          | Type                                 | Required | Description                                                 |
| -------------- | ------------------------------------ | -------- | ----------------------------------------------------------- |
| `instance_id`  | string (`ki_*`)                      | yes      | K-AI instance identifier.                                   |
| `document_ids` | array of string (`kd_*`), minItems 1 | yes      | Document IDs to retrieve. Each must carry the `kd_` prefix. |

### Output schema

| Field             | Type            | Description                            |
| ----------------- | --------------- | -------------------------------------- |
| `response`        | array           | Document objects in unspecified order. |
| `response[].id`   | string (`kd_*`) | K-AI document identifier.              |
| `response[].name` | string          | Document name.                         |
| `response[].*`    | any             | Additional metadata fields.            |

### Example

{% tabs %}
{% tab title="Python (MCP SDK)" %}

```python
import asyncio
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

async def main():
    url = "https://api-retrieval.kai-studio.ai/mcp"
    headers = {"Authorization": "Bearer YOUR_TOKEN"}
    async with streamablehttp_client(url, headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()
            result = await session.call_tool(
                "retrieval_documents_list_by_ids",
                {"instance_id": "ki_abc123",
                 "document_ids": ["kd_def456", "kd_ghi789"]},
            )
            print(result.structuredContent)

asyncio.run(main())
```

{% endtab %}

{% tab title="TypeScript (MCP SDK)" %}

```ts
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const transport = new StreamableHTTPClientTransport(
  new URL("https://api-retrieval.kai-studio.ai/mcp"),
  { requestInit: { headers: { Authorization: "Bearer YOUR_TOKEN" } } }
);
const client = new Client({ name: "demo", version: "1.0.0" });
await client.connect(transport);
const result = await client.callTool({
  name: "retrieval_documents_list_by_ids",
  arguments: {
    instance_id: "ki_abc123",
    document_ids: ["kd_def456", "kd_ghi789"],
  },
});
console.log(result.structuredContent);
```

{% endtab %}

{% tab title="Raw HTTP" %}

```bash
curl -X POST https://api-retrieval.kai-studio.ai/retrieval/documents/list-by-ids \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"instance_id": "ki_abc123", "document_ids": ["kd_def456", "kd_ghi789"]}'
```

{% endtab %}
{% endtabs %}

## retrieval\_semantic\_nodes\_search

Performs a semantic search inside a K-AI instance and returns the matched nodes from the Neural Semantic Graph along with the document content they originate from. Unlike the legacy `/search` endpoint of the K-AI Instance API, this operation does **not** call an LLM server-side: it returns raw semantic nodes and document content, letting the host LLM synthesise the final answer with full control over prompt and model.

### Input schema

| Field         | Type                 | Required | Description                                                                     |
| ------------- | -------------------- | -------- | ------------------------------------------------------------------------------- |
| `query`       | string (minLength 1) | yes      | Natural-language query.                                                         |
| `instance_id` | string (`ki_*`)      | yes      | K-AI instance identifier (from `retrieval_instances_list_available_instances`). |

### Output schema

| Field                         | Type            | Description                                                                                        |
| ----------------------------- | --------------- | -------------------------------------------------------------------------------------------------- |
| `response`                    | array           | Matched semantic nodes.                                                                            |
| `response[].id`               | string (`kn_*`) | Semantic node identifier.                                                                          |
| `response[].documents`        | array           | Documents that contributed to this node, inlined.                                                  |
| `response[].documents[].id`   | string (`kd_*`) | K-AI document identifier.                                                                          |
| `response[].documents[].name` | string          | Document name.                                                                                     |
| `response[].*`                | any             | Additional node fields (relevance score, excerpts, positions) depending on instance configuration. |

### Example

{% tabs %}
{% tab title="Python (MCP SDK)" %}

```python
import asyncio
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

async def main():
    url = "https://api-retrieval.kai-studio.ai/mcp"
    headers = {"Authorization": "Bearer YOUR_TOKEN"}
    async with streamablehttp_client(url, headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()
            result = await session.call_tool(
                "retrieval_semantic_nodes_search",
                {"instance_id": "ki_abc123",
                 "query": "refund policy for damaged goods"},
            )
            print(result.structuredContent)

asyncio.run(main())
```

{% endtab %}

{% tab title="TypeScript (MCP SDK)" %}

```ts
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const transport = new StreamableHTTPClientTransport(
  new URL("https://api-retrieval.kai-studio.ai/mcp"),
  { requestInit: { headers: { Authorization: "Bearer YOUR_TOKEN" } } }
);
const client = new Client({ name: "demo", version: "1.0.0" });
await client.connect(transport);
const result = await client.callTool({
  name: "retrieval_semantic_nodes_search",
  arguments: {
    instance_id: "ki_abc123",
    query: "refund policy for damaged goods",
  },
});
console.log(result.structuredContent);
```

{% endtab %}

{% tab title="Raw HTTP" %}

```bash
curl -X POST https://api-retrieval.kai-studio.ai/retrieval/semantic-nodes/search \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"instance_id": "ki_abc123", "query": "refund policy for damaged goods"}'
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://k-ai.gitbook.io/knowledge-ai/k-ai-mcp/retrieval-tools.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
