Skip to content

Commit 3f882a1

Browse files
authored
update to support loading ai-libs as kdbx module (#7)
1 parent 2e2f3f3 commit 3f882a1

File tree

2 files changed

+47
-9
lines changed

2 files changed

+47
-9
lines changed

README.md

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ Before installing and running the KDB-X MCP Server, ensure you have met the foll
5656
- [Cloned this repo](#clone-the-repository)
5757
- A `KDB-X/KDB+` Service listening on a host and port that will be accessible to the MCP Server
5858
- See examples - [KDB-X Setup](#kdb-x-setup) / [KDB+ Setup](#kdb-setup)
59-
- KDB-X can be installed by signing up to the [KDB-X public preview](https://kdb-x.kx.com/sign-in) - see [KDB-X documentation](https://docs.kx.com/public-preview/kdb-x/home.htm) for supporting information
59+
- KDB-X can be installed by signing up to the [KDB-X public preview](https://developer.kx.com/products/kdb-x/install) - see [KDB-X documentation](https://docs.kx.com/public-preview/kdb-x/home.htm) for supporting information
6060
- Windows users can run the KDB-X MCP Server on Windows and connect to a local KDB-X database via WSL or remote KDB-X database running on Linux
6161
- Windows users can run a local KDB-X database by installing KDB-X on [WSL](https://learn.microsoft.com/en-us/windows/wsl/install), and use the default [streamable-http transport](#transport-options) when running the [KDB-X MCP Server](#run-the-server) - both share the same localhost network.
6262
- For details on KDB-X usage restrictions see [documentation](https://docs.kx.com/product/licensing/usage-restrictions.htm#kdb-x-personal-trial-download)
@@ -67,7 +67,7 @@ Before installing and running the KDB-X MCP Server, ensure you have met the foll
6767
- `npx` comes bundled with the [nodejs](https://nodejs.org/en) installer - available on Windows/Mac/Linux/WSL
6868
- See [example configuration with streamable-http](#example-configuration-with-streamable-http)
6969

70-
> Note: ⚠️ KDB-X public preview has recently been extended. If you have installed KDB-X prior to Sept 30th 2025, you will receive an email notification about this update. Please update to the latest [KDB-X](https://kdb-x.kx.com/sign-in) to ensure uninterrupted access, valid through January 4, 2026
70+
> Note: ⚠️ KDB-X public preview has recently been extended. If you have installed KDB-X prior to Sept 30th 2025, you will receive an email notification about this update. Please update to the latest [KDB-X](https://developer.kx.com/products/kdb-x/install) to ensure uninterrupted access, valid through 31st Dec 2025
7171
7272
## Quickstart
7373

@@ -88,7 +88,7 @@ To demonstrate basic usage of the KDB-X MCP Server, using an empty KDB-X databas
8888
2. Load the ai and sql interfaces.
8989

9090
```q
91-
\l ai-libs/init.q
91+
.ai:use`kx.ai
9292
.s.init[]
9393
```
9494

@@ -519,9 +519,19 @@ The below tools can aid in the development, testing and debugging of new MCP too
519519

520520
## Troubleshooting
521521

522+
### Failed to import pykx
523+
524+
The KDB-X MCP Server requires a valid KDB-X license to operate.
525+
526+
If you see an error like "Failed to import pykx", verify the following:
527+
528+
- The `QLIC` environment variable is set and points to your license directory
529+
- Your license directory contains a valid license file
530+
- Your license has not expired
531+
522532
### KDB-X license expired
523533

524-
KDB-X public preview has recently been extended. If you have installed KDB-X prior to Sept 30th 2025, you will receive an email notification about this update. Please update to the latest [KDB-X](https://kdb-x.kx.com/sign-in) to ensure uninterrupted access, valid through January 4, 2026
534+
KDB-X public preview has recently been extended. If you have installed KDB-X prior to Sept 30th 2025, you will receive an email notification about this update. Please update to the latest [KDB-X](https://developer.kx.com/products/kdb-x/install) to ensure uninterrupted access, valid through 31st Dec 2025
525535

526536
### KDB-X connection error
527537

src/mcp_server/server.py

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
1+
import os
12
import sys
23
import logging
34
import socket
5+
from packaging import version
46
from mcp.server.fastmcp import FastMCP
57
from mcp_server.utils.logging import setup_logging
68
from mcp_server.settings import AppSettings
79
from mcp_server.tools import register_tools
810
from mcp_server.prompts import register_prompts
911
from mcp_server.resources import register_resources
1012

13+
# Ensure pykx throws error on import if license is not valid
14+
os.environ["PYKX_LICENSED"] = "true"
15+
1116
# Global flag to track AI Libs availability
1217
_ai_libs_available = False
1318

@@ -66,6 +71,13 @@ def _check_kdb_connection(self):
6671
try:
6772
import pykx as kx
6873
from pykx.exceptions import QError
74+
except Exception as e:
75+
self.logger.error(f"Failed to import pykx: {e}")
76+
self.logger.error("KDB-X Python is required to connect to KDB-X. Please ensure you have a valid license.")
77+
self.logger.error("Set the QLIC environment variable to point to your license directory.")
78+
sys.exit(1)
79+
80+
try:
6981
conn = kx.SyncQConnection(
7082
host=self.db_config.host,
7183
port=self.db_config.port,
@@ -75,7 +87,15 @@ def _check_kdb_connection(self):
7587
tls=self.db_config.tls,
7688

7789
)
78-
self.logger.info(f"KDB-X connectivity check with 'tls={self.db_config.tls}': SUCCESS - {self.db_config.host}:{self.db_config.port} is accessible")
90+
# Try to get kdbx version first, fall back to kdb+ version
91+
try:
92+
kdb_version = conn('.z.v`version').py().decode('utf-8')
93+
kdb_type = "KDB-X"
94+
except (QError, AttributeError):
95+
kdb_version = str(conn('.z.K').py())
96+
kdb_type = "KDB+"
97+
98+
self.logger.info(f"KDB-X connectivity check with 'tls={self.db_config.tls}': SUCCESS - {self.db_config.host}:{self.db_config.port} is accessible. You are running {kdb_type} version: {kdb_version}")
7999

80100
# check if sql interface is loaded on KDB-X service
81101
if not conn('@[{2< count .s};(::);{0b}]').py():
@@ -87,8 +107,16 @@ def _check_kdb_connection(self):
87107
# check if AI libs are loaded on KDB-X service
88108
ai_libs_available = conn('@[{2< count .ai};(::);{0b}]').py()
89109
if not ai_libs_available:
90-
self.logger.warning("KDB-X AI Libs check: NOT AVAILABLE - AI-powered tools (similarity_search, hybrid_search) will be disabled.")
91-
self.logger.warning("To enable AI tools, load the KDB-X AI libraries by running: \l ai-libs/init.q in your KDB-X Session and then restart the MCP server")
110+
111+
# check if KDB-X version supports loading AI libs as a module
112+
if kdb_type == "KDB-X" and version.parse(kdb_version) < version.parse("0.1.2"):
113+
self.logger.warning("KDB-X AI Libs check: NOT AVAILABLE - AI-powered tools (similarity_search, hybrid_search) will be disabled.")
114+
self.logger.warning(f"To use AI tools, you need at least KDB-X version '0.1.2'. Your version is '{kdb_version}'. Please update to the latest KDB-X version.")
115+
elif kdb_type == "KDB+":
116+
self.logger.warning("KDB-X AI Libs check: NOT AVAILABLE - AI-powered tools (similarity_search, hybrid_search) are only available in KDB-X.")
117+
else:
118+
self.logger.warning("KDB-X AI Libs check: NOT LOADED - AI-powered tools (similarity_search, hybrid_search) will be disabled.")
119+
self.logger.warning(r"To enable AI tools, load the KDB-X AI libraries by running: .ai:use`kx.ai in your KDB-X Session and then restart the MCP server")
92120
else:
93121
self.logger.info("KDB-X AI Libs check: SUCCESS - AI Libs are loaded, AI tools will be available")
94122

@@ -148,7 +176,7 @@ def _preload_embedding_models(self):
148176
try:
149177
import asyncio
150178
from mcp_server.utils.embeddings import preload_models_from_config
151-
179+
152180
# Run the async preload function
153181
loop = asyncio.new_event_loop()
154182
asyncio.set_event_loop(loop)
@@ -157,7 +185,7 @@ def _preload_embedding_models(self):
157185
self.logger.info("Embedding models preloaded successfully")
158186
finally:
159187
loop.close()
160-
188+
161189
except Exception as e:
162190
self.logger.warning(f"Failed to preload embedding models: {e}")
163191
self.logger.warning("Models will be loaded on first use, which may cause delays")

0 commit comments

Comments
 (0)