@sap-ux/fiori-mcp-server 0.1.0 → 0.1.1
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/index.js +101 -40
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -48905,12 +48905,14 @@ var require_info = __commonJS({
|
|
|
48905
48905
|
}
|
|
48906
48906
|
const capProjectType = await (0, cap_1.getCapProjectType)(root);
|
|
48907
48907
|
const projectType = capProjectType ?? "EDMXBackend";
|
|
48908
|
+
const capCustomPaths = projectType === "EDMXBackend" ? void 0 : await (0, cap_1.getCapCustomPaths)(root);
|
|
48908
48909
|
const appFolders = await getAppFolders(root, memFs);
|
|
48909
48910
|
const apps = await getApps(root, appFolders, memFs);
|
|
48910
48911
|
return {
|
|
48911
48912
|
root: (0, path_2.normalizePath)(root),
|
|
48912
48913
|
projectType,
|
|
48913
|
-
apps
|
|
48914
|
+
apps,
|
|
48915
|
+
capCustomPaths
|
|
48914
48916
|
};
|
|
48915
48917
|
}
|
|
48916
48918
|
async function getAppFolders(root, memFs) {
|
|
@@ -184597,7 +184599,7 @@ var require_package8 = __commonJS({
|
|
|
184597
184599
|
"../telemetry/package.json"(exports2, module2) {
|
|
184598
184600
|
module2.exports = {
|
|
184599
184601
|
name: "@sap-ux/telemetry",
|
|
184600
|
-
version: "0.6.
|
|
184602
|
+
version: "0.6.21",
|
|
184601
184603
|
description: "Library for sending usage telemetry data",
|
|
184602
184604
|
repository: {
|
|
184603
184605
|
type: "git",
|
|
@@ -203868,7 +203870,7 @@ var StdioServerTransport = class {
|
|
|
203868
203870
|
};
|
|
203869
203871
|
|
|
203870
203872
|
// package.json
|
|
203871
|
-
var version = "0.1.
|
|
203873
|
+
var version = "0.1.1";
|
|
203872
203874
|
var package_default = {
|
|
203873
203875
|
name: "@sap-ux/fiori-mcp-server",
|
|
203874
203876
|
description: "SAP Fiori - Model Context Protocol (MCP) server",
|
|
@@ -209102,7 +209104,8 @@ var import_promises3 = __toESM(require("fs/promises"));
|
|
|
209102
209104
|
var import_path4 = __toESM(require("path"));
|
|
209103
209105
|
var SimpleVectorService = class {
|
|
209104
209106
|
connection = null;
|
|
209105
|
-
|
|
209107
|
+
tables = [];
|
|
209108
|
+
tableIndex = null;
|
|
209106
209109
|
metadata = null;
|
|
209107
209110
|
dataPath;
|
|
209108
209111
|
/**
|
|
@@ -209131,7 +209134,31 @@ var SimpleVectorService = class {
|
|
|
209131
209134
|
logger.log(` Total vectors: ${this?.metadata?.totalVectors}`);
|
|
209132
209135
|
logger.log(` Created: ${this?.metadata?.createdAt}`);
|
|
209133
209136
|
this.connection = await (0, import_lancedb.connect)(this.dataPath);
|
|
209134
|
-
|
|
209137
|
+
const tableIndexPath = import_path4.default.join(this.dataPath, "table_index.json");
|
|
209138
|
+
try {
|
|
209139
|
+
const tableIndexContent = await import_promises3.default.readFile(tableIndexPath, "utf-8");
|
|
209140
|
+
this.tableIndex = JSON.parse(tableIndexContent);
|
|
209141
|
+
this.tables = [];
|
|
209142
|
+
for (const tableName of this.tableIndex?.tables || []) {
|
|
209143
|
+
const table = await this.connection.openTable(tableName);
|
|
209144
|
+
this.tables.push(table);
|
|
209145
|
+
}
|
|
209146
|
+
logger.log(`\u2713 Loaded ${this.tables.length} split tables`);
|
|
209147
|
+
} catch {
|
|
209148
|
+
logger.log("No table index found, trying single table...");
|
|
209149
|
+
try {
|
|
209150
|
+
const table = await this.connection.openTable("documents");
|
|
209151
|
+
this.tables = [table];
|
|
209152
|
+
this.tableIndex = {
|
|
209153
|
+
tables: ["documents"],
|
|
209154
|
+
totalTables: 1,
|
|
209155
|
+
maxVectorsPerTable: -1,
|
|
209156
|
+
totalVectors: this.metadata?.totalVectors || 0
|
|
209157
|
+
};
|
|
209158
|
+
} catch (fallbackError) {
|
|
209159
|
+
throw new Error(`No tables found: ${fallbackError}`);
|
|
209160
|
+
}
|
|
209161
|
+
}
|
|
209135
209162
|
logger.log("\u2713 Vector database loaded and ready");
|
|
209136
209163
|
} catch (error2) {
|
|
209137
209164
|
throw new Error(`Failed to load vector database: ${error2}`);
|
|
@@ -209146,16 +209173,22 @@ var SimpleVectorService = class {
|
|
|
209146
209173
|
* @returns Promise resolving to search results
|
|
209147
209174
|
*/
|
|
209148
209175
|
async semanticSearch(queryVector, limit = 10, category) {
|
|
209149
|
-
if (
|
|
209176
|
+
if (this.tables.length === 0) {
|
|
209150
209177
|
throw new Error("Vector database not initialized");
|
|
209151
209178
|
}
|
|
209152
209179
|
try {
|
|
209153
|
-
|
|
209154
|
-
|
|
209155
|
-
query =
|
|
209156
|
-
|
|
209157
|
-
|
|
209158
|
-
|
|
209180
|
+
const allResults = [];
|
|
209181
|
+
for (const table of this.tables) {
|
|
209182
|
+
let query = table.vectorSearch(queryVector).limit(limit * 2);
|
|
209183
|
+
if (category) {
|
|
209184
|
+
query = query.where(`category = "${category}"`);
|
|
209185
|
+
}
|
|
209186
|
+
const tableResults = await query.toArray();
|
|
209187
|
+
allResults.push(...tableResults);
|
|
209188
|
+
}
|
|
209189
|
+
allResults.sort((a, b) => (a._distance || 0) - (b._distance || 0));
|
|
209190
|
+
const topResults = allResults.slice(0, limit);
|
|
209191
|
+
return topResults.map((result) => ({
|
|
209159
209192
|
document: {
|
|
209160
209193
|
id: result.document_id,
|
|
209161
209194
|
// Use document_id instead of chunk id
|
|
@@ -209166,11 +209199,11 @@ var SimpleVectorService = class {
|
|
|
209166
209199
|
path: result.path,
|
|
209167
209200
|
chunk_index: result.chunk_index,
|
|
209168
209201
|
metadata: {
|
|
209169
|
-
tags: result.
|
|
209170
|
-
headers: result.
|
|
209171
|
-
lastModified: new Date(result.
|
|
209172
|
-
wordCount: result.
|
|
209173
|
-
excerpt: result.
|
|
209202
|
+
tags: this.parseJsonField(result.tags_json) || [],
|
|
209203
|
+
headers: this.parseJsonField(result.headers_json) || [],
|
|
209204
|
+
lastModified: new Date(result.lastModified),
|
|
209205
|
+
wordCount: result.wordCount,
|
|
209206
|
+
excerpt: result.excerpt
|
|
209174
209207
|
}
|
|
209175
209208
|
},
|
|
209176
209209
|
score: 1 - (result._distance || 0),
|
|
@@ -209200,18 +209233,28 @@ var SimpleVectorService = class {
|
|
|
209200
209233
|
* @returns Promise resolving to similar documents
|
|
209201
209234
|
*/
|
|
209202
209235
|
async findSimilarToDocument(documentId, limit = 5) {
|
|
209203
|
-
if (
|
|
209236
|
+
if (this.tables.length === 0) {
|
|
209204
209237
|
throw new Error("Vector database not initialized");
|
|
209205
209238
|
}
|
|
209206
209239
|
try {
|
|
209207
|
-
|
|
209208
|
-
|
|
209240
|
+
let referenceVector = null;
|
|
209241
|
+
for (const table of this.tables) {
|
|
209242
|
+
const referenceResults = await table.search("").where(`document_id = "${documentId}" AND chunk_index = 0`).limit(1).toArray();
|
|
209243
|
+
if (referenceResults.length > 0) {
|
|
209244
|
+
referenceVector = referenceResults[0].vector;
|
|
209245
|
+
break;
|
|
209246
|
+
}
|
|
209247
|
+
}
|
|
209248
|
+
if (!referenceVector) {
|
|
209209
209249
|
return [];
|
|
209210
209250
|
}
|
|
209211
|
-
const
|
|
209212
|
-
const
|
|
209251
|
+
const allResults = [];
|
|
209252
|
+
for (const table of this.tables) {
|
|
209253
|
+
const results = await table.vectorSearch(referenceVector).where(`document_id != "${documentId}"`).limit(limit * 2).toArray();
|
|
209254
|
+
allResults.push(...results);
|
|
209255
|
+
}
|
|
209213
209256
|
const documentScores = /* @__PURE__ */ new Map();
|
|
209214
|
-
for (const result of
|
|
209257
|
+
for (const result of allResults) {
|
|
209215
209258
|
const docId = result.document_id;
|
|
209216
209259
|
const score = 1 - (result._distance || 0);
|
|
209217
209260
|
if (!documentScores.has(docId) || documentScores.get(docId).score < score) {
|
|
@@ -209232,11 +209275,11 @@ var SimpleVectorService = class {
|
|
|
209232
209275
|
path: result.path,
|
|
209233
209276
|
chunk_index: result.chunk_index,
|
|
209234
209277
|
metadata: {
|
|
209235
|
-
tags: result.
|
|
209236
|
-
headers: result.
|
|
209237
|
-
lastModified: new Date(result.
|
|
209238
|
-
wordCount: result.
|
|
209239
|
-
excerpt: result.
|
|
209278
|
+
tags: this.parseJsonField(result.tags_json) || [],
|
|
209279
|
+
headers: this.parseJsonField(result.headers_json) || [],
|
|
209280
|
+
lastModified: new Date(result.lastModified),
|
|
209281
|
+
wordCount: result.wordCount,
|
|
209282
|
+
excerpt: result.excerpt
|
|
209240
209283
|
}
|
|
209241
209284
|
},
|
|
209242
209285
|
score: result.score,
|
|
@@ -209256,15 +209299,20 @@ var SimpleVectorService = class {
|
|
|
209256
209299
|
* @returns Promise resolving to documents in the category
|
|
209257
209300
|
*/
|
|
209258
209301
|
async getDocumentsByCategory(category, limit) {
|
|
209259
|
-
if (
|
|
209302
|
+
if (this.tables.length === 0) {
|
|
209260
209303
|
throw new Error("Vector database not initialized");
|
|
209261
209304
|
}
|
|
209262
209305
|
try {
|
|
209263
|
-
|
|
209264
|
-
|
|
209265
|
-
query =
|
|
209306
|
+
const allResults = [];
|
|
209307
|
+
for (const table of this.tables) {
|
|
209308
|
+
let query = table.search("").where(`category = "${category}" AND chunk_index = 0`);
|
|
209309
|
+
if (limit) {
|
|
209310
|
+
query = query.limit(Math.ceil(limit / this.tables.length) + 10);
|
|
209311
|
+
}
|
|
209312
|
+
const tableResults = await query.toArray();
|
|
209313
|
+
allResults.push(...tableResults);
|
|
209266
209314
|
}
|
|
209267
|
-
const results =
|
|
209315
|
+
const results = limit ? allResults.slice(0, limit) : allResults;
|
|
209268
209316
|
return results.map((result) => ({
|
|
209269
209317
|
document: {
|
|
209270
209318
|
id: result.document_id,
|
|
@@ -209275,11 +209323,11 @@ var SimpleVectorService = class {
|
|
|
209275
209323
|
path: result.path,
|
|
209276
209324
|
chunk_index: result.chunk_index,
|
|
209277
209325
|
metadata: {
|
|
209278
|
-
tags: result.
|
|
209279
|
-
headers: result.
|
|
209280
|
-
lastModified: new Date(result.
|
|
209281
|
-
wordCount: result.
|
|
209282
|
-
excerpt: result.
|
|
209326
|
+
tags: this.parseJsonField(result.tags_json) || [],
|
|
209327
|
+
headers: this.parseJsonField(result.headers_json) || [],
|
|
209328
|
+
lastModified: new Date(result.lastModified),
|
|
209329
|
+
wordCount: result.wordCount,
|
|
209330
|
+
excerpt: result.excerpt
|
|
209283
209331
|
}
|
|
209284
209332
|
},
|
|
209285
209333
|
score: 1,
|
|
@@ -209299,18 +209347,31 @@ var SimpleVectorService = class {
|
|
|
209299
209347
|
getMetadata() {
|
|
209300
209348
|
return this.metadata;
|
|
209301
209349
|
}
|
|
209350
|
+
/**
|
|
209351
|
+
* Helper method to parse JSON fields safely.
|
|
209352
|
+
*
|
|
209353
|
+
* @param jsonString The JSON string to parse
|
|
209354
|
+
* @returns Parsed array or null if parsing fails
|
|
209355
|
+
*/
|
|
209356
|
+
parseJsonField(jsonString) {
|
|
209357
|
+
try {
|
|
209358
|
+
return jsonString ? JSON.parse(jsonString) : [];
|
|
209359
|
+
} catch {
|
|
209360
|
+
return [];
|
|
209361
|
+
}
|
|
209362
|
+
}
|
|
209302
209363
|
/**
|
|
209303
209364
|
* Checks if the vector store is initialized.
|
|
209304
209365
|
*
|
|
209305
209366
|
* @returns True if initialized, false otherwise
|
|
209306
209367
|
*/
|
|
209307
209368
|
isInitialized() {
|
|
209308
|
-
return this.
|
|
209369
|
+
return this.tables.length > 0 && this.metadata !== null;
|
|
209309
209370
|
}
|
|
209310
209371
|
async close() {
|
|
209311
209372
|
if (this.connection) {
|
|
209312
209373
|
this.connection = null;
|
|
209313
|
-
this.
|
|
209374
|
+
this.tables = [];
|
|
209314
209375
|
logger.log("Vector database connection closed");
|
|
209315
209376
|
}
|
|
209316
209377
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sap-ux/fiori-mcp-server",
|
|
3
3
|
"description": "SAP Fiori - Model Context Protocol (MCP) server",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.1",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"SAP Fiori tools",
|
|
7
7
|
"SAP Fiori elements",
|
|
@@ -38,17 +38,17 @@
|
|
|
38
38
|
"i18next": "25.3.0",
|
|
39
39
|
"os-name": "4.0.1",
|
|
40
40
|
"zod": "4.1.5",
|
|
41
|
-
"@sap-ux/project-access": "1.
|
|
42
|
-
"@sap-ux/fiori-
|
|
41
|
+
"@sap-ux/project-access": "1.31.0",
|
|
42
|
+
"@sap-ux/fiori-docs-embeddings": "0.0.2",
|
|
43
|
+
"@sap-ux/fiori-annotation-api": "0.6.21",
|
|
43
44
|
"@sap-ux/i18n": "0.3.3",
|
|
44
|
-
"@sap-ux/fiori-docs-embeddings": "0.0.1",
|
|
45
45
|
"@sap-ux/odata-annotation-core-types": "0.4.6",
|
|
46
46
|
"@sap-ux/odata-entity-model": "0.3.1",
|
|
47
47
|
"@sap-ux/text-document-utils": "0.3.1",
|
|
48
48
|
"@sap-ux/btp-utils": "1.1.1",
|
|
49
49
|
"@sap-ux/feature-toggle": "0.3.1",
|
|
50
50
|
"@sap-ux/nodejs-utils": "0.2.3",
|
|
51
|
-
"@sap-ux/telemetry": "0.6.
|
|
51
|
+
"@sap-ux/telemetry": "0.6.21"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@lancedb/lancedb": "0.22.0"
|