kibi-mcp 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/server.js CHANGED
@@ -15,6 +15,7 @@
15
15
  You should have received a copy of the GNU Affero General Public License
16
16
  along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
  */
18
+ import { createRequire } from "node:module";
18
19
  /*
19
20
  How to apply this header to source files (examples)
20
21
 
@@ -60,9 +61,9 @@ import { handleKbImpact } from "./tools/impact.js";
60
61
  import { handleKbListEntityTypes, handleKbListRelationshipTypes, } from "./tools/list-types.js";
61
62
  import { handleKbQueryRelationships, } from "./tools/query-relationships.js";
62
63
  import { handleKbQuery } from "./tools/query.js";
63
- import { handleKbUpsert } from "./tools/upsert.js";
64
- import { handleKbSymbolsRefresh, } from "./tools/symbols.js";
65
64
  import { handleSuggestSharedFacts, } from "./tools/suggest-shared-facts.js";
65
+ import { handleKbSymbolsRefresh, } from "./tools/symbols.js";
66
+ import { handleKbUpsert } from "./tools/upsert.js";
66
67
  import { resolveKbPath, resolveWorkspaceRoot } from "./workspace.js";
67
68
  function renderToolsDoc() {
68
69
  const lines = [
@@ -319,8 +320,41 @@ async function ensureProlog() {
319
320
  return prologProcess;
320
321
  }
321
322
  debugLog("[KIBI-MCP] Initializing Prolog process...");
322
- prologProcess = new PrologProcess({ timeout: 30000 });
323
+ prologProcess = new PrologProcess({ timeout: 120000 });
323
324
  await prologProcess.start();
325
+ // Startup debug: resolve which kibi-cli is being used and its version (best-effort).
326
+ // Gate all output under KIBI_MCP_DEBUG and write only to stderr via debugLog.
327
+ if (process.env.KIBI_MCP_DEBUG) {
328
+ try {
329
+ const req = createRequire(import.meta.url);
330
+ try {
331
+ const resolved = req.resolve("kibi-cli/prolog");
332
+ debugLog(`[KIBI-MCP] require.resolve('kibi-cli/prolog') -> ${resolved}`);
333
+ }
334
+ catch (resolveErr) {
335
+ debugLog("[KIBI-MCP] require.resolve('kibi-cli/prolog') failed:", resolveErr.message);
336
+ }
337
+ // Try to read package.json for kibi-cli to get version. This may fail if
338
+ // the package uses exports blocking package.json access — log explicit failure.
339
+ try {
340
+ // prefer direct package.json require; createRequire makes this ESM-friendly
341
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
342
+ const pkg = req("kibi-cli/package.json");
343
+ if (pkg && typeof pkg.version === "string") {
344
+ debugLog(`[KIBI-MCP] kibi-cli version: ${pkg.version}`);
345
+ }
346
+ else {
347
+ debugLog("[KIBI-MCP] kibi-cli package.json read but no version field");
348
+ }
349
+ }
350
+ catch (pkgErr) {
351
+ debugLog("[KIBI-MCP] Failed to read kibi-cli package.json (exports may restrict access):", pkgErr.message);
352
+ }
353
+ }
354
+ catch (err) {
355
+ debugLog("[KIBI-MCP] Failed to create require() for debug lookup:", err.message);
356
+ }
357
+ }
324
358
  const workspaceRoot = resolveWorkspaceRoot();
325
359
  let branch = process.env.KIBI_BRANCH || "develop";
326
360
  let gitBranch;
@@ -15,6 +15,9 @@
15
15
  You should have received a copy of the GNU Affero General Public License
16
16
  along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
  */
18
+ function escapeAtom(value) {
19
+ return value.replace(/'/g, "\\'");
20
+ }
18
21
  /**
19
22
  * Handle kb.delete tool calls
20
23
  * Prevents deletion of entities with dependents (referential integrity)
@@ -30,7 +33,7 @@ export async function handleKbDelete(prolog, args) {
30
33
  try {
31
34
  for (const id of ids) {
32
35
  // Check if entity exists
33
- const checkGoal = `kb_entity('${id}', _, _)`;
36
+ const checkGoal = `once(kb_entity('${escapeAtom(id)}', _, _))`;
34
37
  const checkResult = await prolog.query(checkGoal);
35
38
  if (!checkResult.success) {
36
39
  errors.push(`Entity ${id} does not exist`);
@@ -15,10 +15,13 @@
15
15
  You should have received a copy of the GNU Affero General Public License
16
16
  along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
  */
18
+ import Ajv from "ajv";
18
19
  import entitySchema from "kibi-cli/schemas/entity";
19
20
  import relationshipSchema from "kibi-cli/schemas/relationship";
20
- import Ajv from "ajv";
21
21
  import { refreshCoordinatesForSymbolId } from "./symbols.js";
22
+ function escapeAtom(value) {
23
+ return value.replace(/'/g, "\\'");
24
+ }
22
25
  const ajv = new Ajv({ strict: false });
23
26
  const validateEntity = ajv.compile(entitySchema);
24
27
  const validateRelationship = ajv.compile(relationshipSchema);
@@ -80,16 +83,14 @@ export async function handleKbUpsert(prolog, args) {
80
83
  const id = entity.id;
81
84
  const type = entity.type;
82
85
  // Check if entity exists
83
- const checkGoal = `kb_entity('${id}', _, _)`;
86
+ const checkGoal = `once(kb_entity('${escapeAtom(id)}', _, _))`;
84
87
  const checkResult = await prolog.query(checkGoal);
85
88
  const isUpdate = checkResult.success;
86
89
  // Build property list for Prolog
87
90
  const props = buildPropertyList(entity);
88
91
  // Assert entity (upsert)
89
92
  if (isUpdate) {
90
- // Delete old version, then insert new
91
- const retractGoal = `kb_retract_entity('${id}')`;
92
- await prolog.query(retractGoal);
93
+ // Update counter only. kb_assert_entity implements upsert semantics in Prolog.
93
94
  updated++;
94
95
  }
95
96
  else {
@@ -108,7 +109,7 @@ export async function handleKbUpsert(prolog, args) {
108
109
  const to = rel.to;
109
110
  // Build metadata
110
111
  const metadata = buildRelationshipMetadata(rel);
111
- const relGoal = `kb_assert_relationship(${relType}, '${from}', '${to}', ${metadata})`;
112
+ const relGoal = `kb_assert_relationship(${relType}, '${escapeAtom(from)}', '${escapeAtom(to)}', ${metadata})`;
112
113
  const relResult = await prolog.query(relGoal);
113
114
  if (!relResult.success) {
114
115
  throw new Error(`Failed to assert relationship ${relType} from ${from} to ${to}: ${relResult.error || "Unknown error"}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kibi-mcp",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "dependencies": {
5
5
  "@modelcontextprotocol/sdk": "^1.26.0",
6
6
  "ajv": "^8.18.0",
@@ -9,7 +9,8 @@
9
9
  "fast-glob": "^3.2.12",
10
10
  "gray-matter": "^4.0.3",
11
11
  "js-yaml": "^4.1.0",
12
- "kibi-core": "^0.1.5",
12
+ "kibi-cli": "^0.1.7",
13
+ "kibi-core": "^0.1.6",
13
14
  "mcpcat": "^0.1.12",
14
15
  "ts-morph": "^23.0.0",
15
16
  "zod": "^4.3.6"
@@ -18,13 +19,13 @@
18
19
  "description": "Model Context Protocol server for Kibi knowledge base",
19
20
  "main": "./dist/server.js",
20
21
  "bin": {
21
- "kibi-mcp": "./bin/kibi-mcp"
22
+ "kibi-mcp": "bin/kibi-mcp"
22
23
  },
23
24
  "scripts": {
24
25
  "test": "bun test",
25
26
  "dev": "bun run bin/kibi-mcp",
26
27
  "build": "tsc -p tsconfig.json",
27
- "prepublishOnly": "npm run build"
28
+ "prepack": "npm run build"
28
29
  },
29
30
  "files": ["dist", "bin"],
30
31
  "engines": {
@@ -32,10 +33,8 @@
32
33
  "bun": ">=1.0"
33
34
  },
34
35
  "exports": {
35
- ".": "./dist/server.js",
36
- "./src/*": "./src/*.ts"
36
+ ".": "./dist/server.js"
37
37
  },
38
-
39
38
  "devDependencies": {
40
39
  "@types/bun": "latest",
41
40
  "@types/node": "latest"