Metadata-Version: 2.5
Name: kx-mcp-kxi
Version: 1.20.0
Summary: MCP server for kdb Insights Enterprise — the kx-mcp-kxi backend bundle, served by the kx-mcp container launcher
Project-URL: Homepage, https://code.kx.com/insights/enterprise/
Project-URL: Documentation, https://code.kx.com/insights/enterprise/mcp
Author-email: KX Systems <support@kx.com>
Maintainer-email: KX Systems <support@kx.com>
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: fastmcp,insights,kdb,kx,llm,mcp,model-context-protocol
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Database
Classifier: Topic :: Software Development :: Libraries
Requires-Python: <3.14,>=3.10
Requires-Dist: fastmcp<4,>=3
Requires-Dist: httpx
Requires-Dist: jq>=1.12.0
Requires-Dist: jsonschema
Requires-Dist: kx-mcp-core>=0.5.0b1
Requires-Dist: pydantic-settings
Requires-Dist: pyyaml
Description-Content-Type: text/markdown

# kdb Insights Enterprise MCP Server

An MCP (Model Context Protocol) server that lets LLM clients work with [kdb Insights Enterprise](https://code.kx.com/insights/enterprise/) in natural language: query data, manage packages and pipelines, and debug deployments through your AI assistant.

## Overview

`kx-mcp-kxi` is a discovery/execution surface over the kdb Insights Enterprise REST API. Rather than one MCP tool per endpoint, it ships a handful of generic tools and navigates the OpenAPI spec, so the whole REST API is reachable without the tool list growing with it. These include:

- **Discover and call any REST operation** — search the spec, read one operation's full schema, then execute it.
- **Fast paths for inspecting table data** — list tables, describe a table's schema, and fetch rows over a bounded time range.
- **Documented workflows ("flows")** — markdown documents describing proven multi-step procedures (queries, pipeline testing, package updates, observability & debugging) that the agent can read mid-task.

The package is a **bundle**, mounted and served by the `kx-mcp` launcher that ships with its [`kx-mcp-core`](https://pypi.org/project/kx-mcp-core/) dependency. The launcher owns transport, host, port, and inbound authentication layers.

```
     ┌──────────────────────────┐            ┌──────────────────────────────────┐            ┌──────────────────────────┐
     │                          │            │                                  │            │                          │
     │        LLM client        │    MCP     │             kxi-mcp              │   HTTPS    │ kdb Insights Enterprise  │
     │                          │  ───────▶  │                                  │  ───────▶  │                          │
     │   Claude Code, Desktop   │ http/stdio │      generic tools + flows       │  + bearer  │         REST API         │
     │           IDE            │            │                                  │            │                          │
     └──────────────────────────┘            └──────────────────────────────────┘            └──────────────────────────┘
```

## Prerequisites

- A running kdb Insights Enterprise deployment accessible over HTTP(S)
- Credentials to authenticate against it — a service-account client ID/secret, or a static bearer token


## Quick Start
To run it yourself, requires Python 3.10–3.13:

```bash
pip install kx-mcp-kxi

KXI_DB_URL=https://your-kxi-host \
KXI_DB_OUTBOUND_STRATEGY=static \
KXI_DB_TOKEN=<bearer> \
kx-mcp --bundles kxi
```

Or without installing, using [uv](https://docs.astral.sh/uv/):

```bash
KXI_DB_URL=https://your-kxi-host \
KXI_DB_OUTBOUND_STRATEGY=static \
KXI_DB_TOKEN=<bearer> \
uvx --from kx-mcp-kxi kx-mcp --bundles kxi
```


Or with user login, so every call runs as the logged-in user with their own entitlements.
This needs inbound verification configured as well, and only works over HTTP:

```bash
H=https://your-kxi-host      # your deployment's base URL
R=insights                   # the Keycloak realm

KX_MCP_AUTH=jwks \
KX_MCP_AUTH_JWKS_URI=$H/realms/$R/protocol/openid-connect/certs \
KX_MCP_AUTH_ISSUER=$H/realms/$R \
KX_MCP_AUTH_AUDIENCE=account \
KX_MCP_AUTH_REQUIRED_SCOPES="offline_access profile email" \
KX_MCP_AUTH_RESOURCE_URL=http://127.0.0.1:8000 \
KXI_DB_URL=$H \
KXI_DB_OUTBOUND_STRATEGY=passthrough \
KXI_DB_AUDIENCE=account \
kx-mcp --bundles kxi --transport streamable-http --host 127.0.0.1 --port 8000
```

## Configuration
Since this MCP server is designed to interface with kdb Insights Enterprise via REST, it requires certain environment variables to be set for proper operation.
The following table outlines the necessary configuration:


| Environment variable                        | Purpose                                                 | Default           |
| ------------------------------------------- | ------------------------------------------------------- | ----------------- |
| `KXI_DB_URL`                                | kdb Insights Enterprise base URL                        | **required**      |
| `KXI_DB_OUTBOUND_STRATEGY`                  | `passthrough` / `service_account` / `static`            | `passthrough`     |
| `KXI_DB_TOKEN`                              | Static bearer token (used by `static`)                  | —                 |
| `KXI_DB_CLIENT_ID` / `KXI_DB_CLIENT_SECRET` | Service-account credentials (used by `service_account`) | —                 |
| `KXI_DB_TOKEN_URL` / `KXI_DB_AUDIENCE`      | OIDC token endpoint / target audience                   | —                 |
| `KXI_DB_SCOPES` / `KXI_DB_CLIENT_AUTH`      | Outbound token scopes / token-endpoint client auth      | — / `post`        |
| `KXI_DB_TIMEOUT` / `KXI_DB_SSL_VERIFY`      | HTTP timeout in seconds / TLS verification              | `30.0` / `true`   |
| `KX_MCP_BUNDLES`                            | Bundles to mount — `kxi` for this package               | (or `--bundles`)  |
| `KX_MCP_TRANSPORT`                          | `streamable-http` / `http` / `stdio`                    | `streamable-http` |
| `KX_MCP_HOST` / `KX_MCP_PORT`               | HTTP bind address / port                                | `127.0.0.1`/`8000`|
| `KX_MCP_LOG_LEVEL`                          | Log verbosity                                           | `INFO`            |
| `KX_MCP_AUTH`                               | Inbound verifier: `jwks` / `static` / `entra` / unset   | unset             |
| `KX_MCP_AUTH_ISSUER` / `_JWKS_URI`          | Realm to verify caller tokens against (`jwks`)          | —                 |
| `KX_MCP_AUTH_AUDIENCE` / `_RESOURCE_URL`    | Expected `aud` / this server's URL, for discovery       | —                 |
| `KX_MCP_AUTH_REQUIRED_SCOPES`               | Scopes a caller token must carry (`jwks` / `entra`)     | —                 |

## Tool surface

### Tools

| Name                        | Purpose                                                               |
| --------------------------- | --------------------------------------------------------------------- |
| `search_endpoints`          | Find API operations (and matching flows) by keyword                   |
| `describe_endpoint`         | Full schema for one operation — params, request body, responses       |
| `call_endpoint`             | Execute one operation, forwarded as-is with no local body validation  |
| `view_flow`                 | List available flows, or read one workflow document                   |
| `list_tables`               | List every queryable table with its key routing/query facts           |
| `describe_table`            | Full schema for one table — columns, partition column, assembly, type |
| `query_table`               | Fetch rows from a table over a bounded time range                     |
| `b64_encode` / `b64_decode` | Encode/decode base64 text, for clients with no shell                  |

Parameters and return shapes live in each tool's own description, visible to any MCP client through
its schema. The intended loop is `search_endpoints` → `describe_endpoint` → `call_endpoint`.
`call_endpoint` also accepts an optional `jq_filter` expression to shrink an oversized response
before it reaches the model.

Mounted under the launcher these arrive namespaced: `kxi_search_endpoints`, `kxi_call_endpoint`,
`kxi_query_table`, and so on.

### Flows

Flows are markdown documents describing proven multi-step workflows over the API. List them with
`view_flow()`, read one with `view_flow("<name>")`, then follow its steps via `call_endpoint`:

| Flow                          | Covers                                                                   |
| ----------------------------- | ------------------------------------------------------------------------ |
| `query-data`                  | Every query API against a table                                          |
| `scratchpad-query`            | Ad-hoc SQL, q-SQL, and getData queries through the scratchpad            |
| `uda-query`                   | Discover the registered User-Defined Analytics and invoke one            |
| `pipeline-test`               | Deploy, monitor, trace, and tear down a Stream Processor pipeline        |
| `pipeline-observability`      | Observe running pipelines — status, graph, workers, traces               |
| `update-package`              | Read a deployed package's files, edit them, write them back, redeploy    |
| `stream-publisher-management` | Enrol, inspect, and remove external stream publisher clients             |
| `observability-debug`         | Debug a deployment — pod status, container logs, k8s events, health      |

### Prompts

`pipeline_test`, `update_package`, and `observability_debug` — namespaced under the launcher as
`kxi_pipeline_test` and so on. Each enters as a user turn with the flow document inlined.

### Resources

`spec://insights.yaml` — the full kdb Insights Enterprise OpenAPI 3.1 spec. Prefer the `search_endpoints` / `describe_endpoint` tools over attaching it to save your tokens.

## Usage


### Transport

The server can be launched standalone or as a subprocess of an MCP client. The transport is selected
with `--transport` or `KX_MCP_TRANSPORT`, and defaults to `streamable-http`.

- **Hosted** (`--transport streamable-http`, the default) — a long-running server on a host and
  port, reached over HTTP. This is what runs on a hosted kdb Insights Enterprise release. You can
  also run it this way locally if you want to restart the MCP server without restarting
  your client.
- **Embedded** (`--transport stdio`) — your MCP client launches the server as a subprocess and talks
  to it over stdin/stdout. Nothing to deploy and no port, but also no inbound HTTP request, so
  there is no caller token to forward: use `static` or `service_account`. See [Auth](#auth).
  `--host` and `--port` are ignored in this mode.

### Auth

Not every outbound strategy works on every transport:

| Transport                  | `static` | `service_account` | `passthrough`             |
| -------------------------- | -------- | ----------------- | ------------------------- |
| `stdio`                    | yes      | yes               | **never**                 |
| `streamable-http` / `http` | yes      | yes               | only with `KX_MCP_AUTH`   |

`static` and `service_account` read their credentials from the environment, so the transport is
irrelevant to them.

`passthrough` forwards a *validated inbound principal*, so inbound verification
(`KX_MCP_AUTH`) must be configured too. That is a requirement of the strategy, not of the transport.
The asymmetry is that it is only satisfiable over HTTP, where the caller's token arrives in an
`Authorization` header and is verified via HTTP middleware.

On `stdio` there is no such HTTP request, so the `KX_MCP_AUTH_*` variables are inert.

Which identity a call runs as is determined by `KXI_DB_OUTBOUND_STRATEGY`:

| Strategy          | Calls run as                                                        |
| ----------------- | ------------------------------------------------------------------- |
| `static`          | whoever minted the token — including you, if it is your own bearer  |
| `service_account` | the one service account, with its entitlements                      |
| `passthrough`     | the calling user, with their own entitlements                       |

So user identity over `stdio` is possible - via `static` with user minted bearer token, rather than via `passthrough`, however it will expire and need to be refreshed manually.


### MCP Client Configuration

In order to make use of the MCP server you'll want to connect via a client.

See [kdb Insights Enterprise MCP](https://code.kx.com/insights/enterprise/mcp) for more info on how to configure client connections to this server.

## Support

For questions or issues, contact [KX support](mailto:support@kx.com).

## License

Apache-2.0.
