@contiva/sapbtp-docs-mcp 1.0.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.
Files changed (91) hide show
  1. package/LICENSE +395 -0
  2. package/README.md +386 -0
  3. package/build/cache/embedding-cache.d.ts +39 -0
  4. package/build/cache/embedding-cache.d.ts.map +1 -0
  5. package/build/cache/embedding-cache.js +105 -0
  6. package/build/cache/embedding-cache.js.map +1 -0
  7. package/build/cache/file-cache.d.ts +40 -0
  8. package/build/cache/file-cache.d.ts.map +1 -0
  9. package/build/cache/file-cache.js +124 -0
  10. package/build/cache/file-cache.js.map +1 -0
  11. package/build/cache/search-cache.d.ts +39 -0
  12. package/build/cache/search-cache.d.ts.map +1 -0
  13. package/build/cache/search-cache.js +97 -0
  14. package/build/cache/search-cache.js.map +1 -0
  15. package/build/index.d.ts +3 -0
  16. package/build/index.d.ts.map +1 -0
  17. package/build/index.js +17 -0
  18. package/build/index.js.map +1 -0
  19. package/build/indexing/file-registry.d.ts +47 -0
  20. package/build/indexing/file-registry.d.ts.map +1 -0
  21. package/build/indexing/file-registry.js +130 -0
  22. package/build/indexing/file-registry.js.map +1 -0
  23. package/build/indexing/topic-index.d.ts +57 -0
  24. package/build/indexing/topic-index.d.ts.map +1 -0
  25. package/build/indexing/topic-index.js +181 -0
  26. package/build/indexing/topic-index.js.map +1 -0
  27. package/build/parsers/links.d.ts +14 -0
  28. package/build/parsers/links.d.ts.map +1 -0
  29. package/build/parsers/links.js +80 -0
  30. package/build/parsers/links.js.map +1 -0
  31. package/build/parsers/markdown.d.ts +10 -0
  32. package/build/parsers/markdown.d.ts.map +1 -0
  33. package/build/parsers/markdown.js +120 -0
  34. package/build/parsers/markdown.js.map +1 -0
  35. package/build/parsers/metadata.d.ts +19 -0
  36. package/build/parsers/metadata.d.ts.map +1 -0
  37. package/build/parsers/metadata.js +63 -0
  38. package/build/parsers/metadata.js.map +1 -0
  39. package/build/search/fulltext.d.ts +20 -0
  40. package/build/search/fulltext.d.ts.map +1 -0
  41. package/build/search/fulltext.js +117 -0
  42. package/build/search/fulltext.js.map +1 -0
  43. package/build/search/ranking.d.ts +27 -0
  44. package/build/search/ranking.d.ts.map +1 -0
  45. package/build/search/ranking.js +119 -0
  46. package/build/search/ranking.js.map +1 -0
  47. package/build/search/semantic.d.ts +53 -0
  48. package/build/search/semantic.d.ts.map +1 -0
  49. package/build/search/semantic.js +260 -0
  50. package/build/search/semantic.js.map +1 -0
  51. package/build/search/title.d.ts +18 -0
  52. package/build/search/title.d.ts.map +1 -0
  53. package/build/search/title.js +95 -0
  54. package/build/search/title.js.map +1 -0
  55. package/build/server.d.ts +32 -0
  56. package/build/server.d.ts.map +1 -0
  57. package/build/server.js +183 -0
  58. package/build/server.js.map +1 -0
  59. package/build/tools/get-related.d.ts +64 -0
  60. package/build/tools/get-related.d.ts.map +1 -0
  61. package/build/tools/get-related.js +203 -0
  62. package/build/tools/get-related.js.map +1 -0
  63. package/build/tools/list-topics.d.ts +43 -0
  64. package/build/tools/list-topics.d.ts.map +1 -0
  65. package/build/tools/list-topics.js +63 -0
  66. package/build/tools/list-topics.js.map +1 -0
  67. package/build/tools/read-article.d.ts +42 -0
  68. package/build/tools/read-article.d.ts.map +1 -0
  69. package/build/tools/read-article.js +89 -0
  70. package/build/tools/read-article.js.map +1 -0
  71. package/build/tools/search.d.ts +57 -0
  72. package/build/tools/search.d.ts.map +1 -0
  73. package/build/tools/search.js +109 -0
  74. package/build/tools/search.js.map +1 -0
  75. package/build/types/index.d.ts +179 -0
  76. package/build/types/index.d.ts.map +1 -0
  77. package/build/types/index.js +2 -0
  78. package/build/types/index.js.map +1 -0
  79. package/build/utils/docs-downloader.d.ts +9 -0
  80. package/build/utils/docs-downloader.d.ts.map +1 -0
  81. package/build/utils/docs-downloader.js +82 -0
  82. package/build/utils/docs-downloader.js.map +1 -0
  83. package/build/utils/paths.d.ts +67 -0
  84. package/build/utils/paths.d.ts.map +1 -0
  85. package/build/utils/paths.js +132 -0
  86. package/build/utils/paths.js.map +1 -0
  87. package/build/utils/text-processing.d.ts +62 -0
  88. package/build/utils/text-processing.d.ts.map +1 -0
  89. package/build/utils/text-processing.js +214 -0
  90. package/build/utils/text-processing.js.map +1 -0
  91. package/package.json +63 -0
@@ -0,0 +1,82 @@
1
+ import { existsSync } from 'fs';
2
+ import { mkdir } from 'fs/promises';
3
+ import { join } from 'path';
4
+ import { exec } from 'child_process';
5
+ import { promisify } from 'util';
6
+ const execAsync = promisify(exec);
7
+ /**
8
+ * Repository configuration
9
+ */
10
+ const DOCS_REPO = 'https://github.com/SAP-docs/btp-cloud-platform.git';
11
+ /**
12
+ * Checks if documentation exists and downloads it if necessary
13
+ */
14
+ export async function ensureDocsAvailable(docsPath) {
15
+ // Check if docs directory exists and has content
16
+ if (existsSync(docsPath)) {
17
+ const iSuitePath = join(docsPath, 'ISuite');
18
+ const ciPath = join(docsPath, 'ci');
19
+ const apimPath = join(docsPath, 'apim');
20
+ if (existsSync(iSuitePath) && existsSync(ciPath) && existsSync(apimPath)) {
21
+ console.error('Documentation found at:', docsPath);
22
+ return true;
23
+ }
24
+ }
25
+ // Docs not found - download from GitHub
26
+ console.error('\nDocumentation not found. Downloading from GitHub...');
27
+ console.error('This is a one-time operation and may take 1-2 minutes.\n');
28
+ try {
29
+ await downloadDocs(docsPath);
30
+ console.error('\n✓ Documentation downloaded successfully!\n');
31
+ return true;
32
+ }
33
+ catch (error) {
34
+ console.error('\n✗ Failed to download documentation:', error);
35
+ console.error('\nPlease manually clone the official SAP documentation repository:');
36
+ console.error(` git clone ${DOCS_REPO}`);
37
+ console.error(` export MCP_DOCS_PATH=/path/to/btp-integration-suite/docs`);
38
+ console.error('\nThen restart the MCP server.');
39
+ return false;
40
+ }
41
+ }
42
+ /**
43
+ * Downloads documentation from GitHub
44
+ */
45
+ async function downloadDocs(docsPath) {
46
+ const parentDir = join(docsPath, '..');
47
+ // Create parent directory if it doesn't exist
48
+ await mkdir(parentDir, { recursive: true });
49
+ console.error('Cloning SAP Business Technology Platform documentation...');
50
+ const repoDir = join(parentDir, '.docs-repo');
51
+ // Clean up any existing partial download
52
+ if (existsSync(repoDir)) {
53
+ await execAsync(`rm -rf "${repoDir}"`);
54
+ }
55
+ // Clone with sparse checkout for docs folder only
56
+ const commands = [
57
+ `git clone --filter=blob:none --sparse "${DOCS_REPO}" "${repoDir}"`,
58
+ `cd "${repoDir}" && git sparse-checkout set docs`,
59
+ `mv "${repoDir}/docs" "${docsPath}"`,
60
+ `rm -rf "${repoDir}"`
61
+ ];
62
+ for (const cmd of commands) {
63
+ await execAsync(cmd);
64
+ }
65
+ console.error('Documentation download complete.');
66
+ }
67
+ /**
68
+ * Gets the size of the docs directory in MB
69
+ */
70
+ export async function getDocsSize(docsPath) {
71
+ if (!existsSync(docsPath)) {
72
+ return 0;
73
+ }
74
+ try {
75
+ const { stdout } = await execAsync(`du -sm "${docsPath}" | cut -f1`);
76
+ return parseInt(stdout.trim(), 10);
77
+ }
78
+ catch {
79
+ return 0;
80
+ }
81
+ }
82
+ //# sourceMappingURL=docs-downloader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docs-downloader.js","sourceRoot":"","sources":["../../src/utils/docs-downloader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEjC,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAElC;;GAEG;AACH,MAAM,SAAS,GAAG,oDAAoD,CAAC;AAEvE;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,QAAgB;IACxD,iDAAiD;IACjD,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAExC,IAAI,UAAU,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzE,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,QAAQ,CAAC,CAAC;YACnD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,wCAAwC;IACxC,OAAO,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;IACvE,OAAO,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAE1E,IAAI,CAAC;QACH,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;QAC7B,OAAO,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAC9D,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAC;QAC9D,OAAO,CAAC,KAAK,CAAC,oEAAoE,CAAC,CAAC;QACpF,OAAO,CAAC,KAAK,CAAC,eAAe,SAAS,EAAE,CAAC,CAAC;QAC1C,OAAO,CAAC,KAAK,CAAC,4DAA4D,CAAC,CAAC;QAC5E,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;QAChD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,YAAY,CAAC,QAAgB;IAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAEvC,8CAA8C;IAC9C,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE5C,OAAO,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAE3E,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAE9C,yCAAyC;IACzC,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,MAAM,SAAS,CAAC,WAAW,OAAO,GAAG,CAAC,CAAC;IACzC,CAAC;IAED,kDAAkD;IAClD,MAAM,QAAQ,GAAG;QACf,0CAA0C,SAAS,MAAM,OAAO,GAAG;QACnE,OAAO,OAAO,mCAAmC;QACjD,OAAO,OAAO,WAAW,QAAQ,GAAG;QACpC,WAAW,OAAO,GAAG;KACtB,CAAC;IAEF,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;AACpD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,QAAgB;IAChD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,WAAW,QAAQ,aAAa,CAAC,CAAC;QACrE,OAAO,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC"}
@@ -0,0 +1,67 @@
1
+ import type { DocumentArea } from '../types/index.js';
2
+ /**
3
+ * Resolves the docs directory path.
4
+ * Tries environment variable first, then auto-detects from package location.
5
+ * Note: This returns a path even if it doesn't exist yet - existence check happens later.
6
+ */
7
+ export declare function resolveDocsPath(): string;
8
+ /**
9
+ * Resolves cache directory path.
10
+ */
11
+ export declare function resolveCacheDir(): string;
12
+ /**
13
+ * Normalizes a file path (removes trailing slashes, normalizes separators)
14
+ */
15
+ export declare function normalizePath(path: string): string;
16
+ /**
17
+ * Resolves a relative link from a source file to an absolute path.
18
+ *
19
+ * @param sourcePath - Absolute path of the source file containing the link
20
+ * @param linkHref - The href from the markdown link
21
+ * @returns Absolute path to the linked file
22
+ */
23
+ export declare function resolveRelativeLink(sourcePath: string, linkHref: string): string;
24
+ /**
25
+ * Checks if a link is external (http://, https://, etc.)
26
+ */
27
+ export declare function isExternalLink(href: string): boolean;
28
+ /**
29
+ * Extracts the document area from a file path.
30
+ *
31
+ * @param filePath - Absolute or relative file path
32
+ * @returns The document area (ISuite, ci, or apim)
33
+ */
34
+ export declare function getDocumentArea(filePath: string): DocumentArea;
35
+ /**
36
+ * Converts an absolute path to a path relative to the docs directory.
37
+ */
38
+ export declare function getRelativePath(absolutePath: string, docsPath: string): string;
39
+ /**
40
+ * Converts a relative path (from docs directory) to an absolute path.
41
+ */
42
+ export declare function getAbsolutePath(relativePath: string, docsPath: string): string;
43
+ /**
44
+ * Gets the area-specific directory path.
45
+ *
46
+ * @param area - The document area
47
+ * @param docsPath - Base docs directory path
48
+ * @returns Absolute path to the area directory
49
+ */
50
+ export declare function getAreaPath(area: DocumentArea, docsPath: string): string;
51
+ /**
52
+ * Gets the index.md file path for a specific area.
53
+ */
54
+ export declare function getIndexPath(area: DocumentArea, docsPath: string): string;
55
+ /**
56
+ * Checks if a file path belongs to a specific area.
57
+ */
58
+ export declare function isInArea(filePath: string, area: DocumentArea): boolean;
59
+ /**
60
+ * Gets all area paths that should be searched.
61
+ *
62
+ * @param area - The area filter ('all' or specific area)
63
+ * @param docsPath - Base docs directory path
64
+ * @returns Array of area paths to search
65
+ */
66
+ export declare function getAreaPaths(area: DocumentArea | 'all', docsPath: string): string[];
67
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAMtD;;;;GAIG;AACH,wBAAgB,eAAe,IAAI,MAAM,CASxC;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAGxC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAahF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CAa9D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE9E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAK9E;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAExE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEzE;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAGtE;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,KAAK,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAUnF"}
@@ -0,0 +1,132 @@
1
+ import { fileURLToPath } from 'url';
2
+ import { dirname, join, relative, resolve, isAbsolute, normalize } from 'path';
3
+ // Get the directory of the current module
4
+ const __filename = fileURLToPath(import.meta.url);
5
+ const __dirname = dirname(__filename);
6
+ /**
7
+ * Resolves the docs directory path.
8
+ * Tries environment variable first, then auto-detects from package location.
9
+ * Note: This returns a path even if it doesn't exist yet - existence check happens later.
10
+ */
11
+ export function resolveDocsPath() {
12
+ // Check environment variable
13
+ if (process.env.MCP_DOCS_PATH) {
14
+ return resolve(process.env.MCP_DOCS_PATH);
15
+ }
16
+ // Auto-detect: go up from build/utils/ to package root, then to docs/
17
+ const projectRoot = resolve(__dirname, '..', '..');
18
+ return join(projectRoot, 'docs');
19
+ }
20
+ /**
21
+ * Resolves cache directory path.
22
+ */
23
+ export function resolveCacheDir() {
24
+ const cacheDir = process.env.MCP_CACHE_DIR || '.mcp-cache';
25
+ return resolve(cacheDir);
26
+ }
27
+ /**
28
+ * Normalizes a file path (removes trailing slashes, normalizes separators)
29
+ */
30
+ export function normalizePath(path) {
31
+ return normalize(path).replace(/[/\\]+$/, '');
32
+ }
33
+ /**
34
+ * Resolves a relative link from a source file to an absolute path.
35
+ *
36
+ * @param sourcePath - Absolute path of the source file containing the link
37
+ * @param linkHref - The href from the markdown link
38
+ * @returns Absolute path to the linked file
39
+ */
40
+ export function resolveRelativeLink(sourcePath, linkHref) {
41
+ // Remove anchor if present
42
+ const [pathPart] = linkHref.split('#');
43
+ if (!pathPart) {
44
+ // Just an anchor (same page)
45
+ return sourcePath;
46
+ }
47
+ const sourceDir = dirname(sourcePath);
48
+ const resolved = resolve(sourceDir, pathPart);
49
+ return normalizePath(resolved);
50
+ }
51
+ /**
52
+ * Checks if a link is external (http://, https://, etc.)
53
+ */
54
+ export function isExternalLink(href) {
55
+ return /^(https?|ftp|mailto):/.test(href);
56
+ }
57
+ /**
58
+ * Extracts the document area from a file path.
59
+ *
60
+ * @param filePath - Absolute or relative file path
61
+ * @returns The document area (ISuite, ci, or apim)
62
+ */
63
+ export function getDocumentArea(filePath) {
64
+ const normalized = normalizePath(filePath);
65
+ if (normalized.includes('/ISuite/') || normalized.includes('\\ISuite\\')) {
66
+ return 'ISuite';
67
+ }
68
+ else if (normalized.includes('/ci/') || normalized.includes('\\ci\\')) {
69
+ return 'ci';
70
+ }
71
+ else if (normalized.includes('/apim/') || normalized.includes('\\apim\\')) {
72
+ return 'apim';
73
+ }
74
+ // Default to ISuite if can't determine
75
+ return 'ISuite';
76
+ }
77
+ /**
78
+ * Converts an absolute path to a path relative to the docs directory.
79
+ */
80
+ export function getRelativePath(absolutePath, docsPath) {
81
+ return relative(docsPath, absolutePath);
82
+ }
83
+ /**
84
+ * Converts a relative path (from docs directory) to an absolute path.
85
+ */
86
+ export function getAbsolutePath(relativePath, docsPath) {
87
+ if (isAbsolute(relativePath)) {
88
+ return relativePath;
89
+ }
90
+ return join(docsPath, relativePath);
91
+ }
92
+ /**
93
+ * Gets the area-specific directory path.
94
+ *
95
+ * @param area - The document area
96
+ * @param docsPath - Base docs directory path
97
+ * @returns Absolute path to the area directory
98
+ */
99
+ export function getAreaPath(area, docsPath) {
100
+ return join(docsPath, area);
101
+ }
102
+ /**
103
+ * Gets the index.md file path for a specific area.
104
+ */
105
+ export function getIndexPath(area, docsPath) {
106
+ return join(docsPath, area, 'index.md');
107
+ }
108
+ /**
109
+ * Checks if a file path belongs to a specific area.
110
+ */
111
+ export function isInArea(filePath, area) {
112
+ const documentArea = getDocumentArea(filePath);
113
+ return documentArea === area;
114
+ }
115
+ /**
116
+ * Gets all area paths that should be searched.
117
+ *
118
+ * @param area - The area filter ('all' or specific area)
119
+ * @param docsPath - Base docs directory path
120
+ * @returns Array of area paths to search
121
+ */
122
+ export function getAreaPaths(area, docsPath) {
123
+ if (area === 'all') {
124
+ return [
125
+ join(docsPath, 'ISuite'),
126
+ join(docsPath, 'ci'),
127
+ join(docsPath, 'apim'),
128
+ ];
129
+ }
130
+ return [join(docsPath, area)];
131
+ }
132
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import type { TextChunk } from '../types/index.js';
2
+ /**
3
+ * Normalizes text for searching (lowercase, trim, normalize whitespace)
4
+ */
5
+ export declare function normalizeText(text: string): string;
6
+ /**
7
+ * Tokenizes text into words
8
+ */
9
+ export declare function tokenize(text: string): string[];
10
+ /**
11
+ * Extracts a snippet of text around a query match
12
+ *
13
+ * @param content - The full text content
14
+ * @param query - The search query
15
+ * @param contextLength - Number of characters to include before and after match
16
+ * @returns A snippet with the query highlighted in context
17
+ */
18
+ export declare function extractSnippet(content: string, query: string, contextLength?: number): string;
19
+ /**
20
+ * Calculates Levenshtein distance between two strings (for fuzzy matching)
21
+ */
22
+ export declare function levenshteinDistance(a: string, b: string): number;
23
+ /**
24
+ * Calculates fuzzy match score (0-100) based on Levenshtein distance
25
+ * 100 = exact match, lower scores = more different
26
+ */
27
+ export declare function fuzzyMatchScore(str1: string, str2: string): number;
28
+ /**
29
+ * Checks if text contains all words from query
30
+ */
31
+ export declare function containsAllWords(text: string, query: string): boolean;
32
+ /**
33
+ * Counts how many query words appear in the text
34
+ */
35
+ export declare function countMatchingWords(text: string, query: string): number;
36
+ /**
37
+ * Chunks text into smaller pieces with overlap
38
+ *
39
+ * @param text - The text to chunk
40
+ * @param maxTokens - Maximum tokens per chunk (approximate, using word count)
41
+ * @param overlapTokens - Number of tokens to overlap between chunks
42
+ * @returns Array of text chunks with metadata
43
+ */
44
+ export declare function chunkText(text: string, maxTokens?: number, overlapTokens?: number): TextChunk[];
45
+ /**
46
+ * Strips markdown from text (basic implementation)
47
+ * For more robust stripping, use remark-strip-markdown
48
+ */
49
+ export declare function stripMarkdownBasic(text: string): string;
50
+ /**
51
+ * Truncates text to a maximum length, breaking at word boundaries
52
+ */
53
+ export declare function truncateText(text: string, maxLength: number): string;
54
+ /**
55
+ * Creates a hash from a string (simple implementation for cache keys)
56
+ */
57
+ export declare function hashString(str: string): string;
58
+ /**
59
+ * Calculates cosine similarity between two vectors
60
+ */
61
+ export declare function cosineSimilarity(a: number[], b: number[]): number;
62
+ //# sourceMappingURL=text-processing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-processing.d.ts","sourceRoot":"","sources":["../../src/utils/text-processing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAE/C;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,GAAE,MAAY,GAAG,MAAM,CA2BlG;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CA6BhE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAiBlE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAKrE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAKtE;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE,MAAY,EAAE,aAAa,GAAE,MAAW,GAAG,SAAS,EAAE,CA4BxG;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAwBvD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAapE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQ9C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAuBjE"}
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Normalizes text for searching (lowercase, trim, normalize whitespace)
3
+ */
4
+ export function normalizeText(text) {
5
+ return text.toLowerCase().trim().replace(/\s+/g, ' ');
6
+ }
7
+ /**
8
+ * Tokenizes text into words
9
+ */
10
+ export function tokenize(text) {
11
+ return normalizeText(text).split(/\s+/).filter(word => word.length > 0);
12
+ }
13
+ /**
14
+ * Extracts a snippet of text around a query match
15
+ *
16
+ * @param content - The full text content
17
+ * @param query - The search query
18
+ * @param contextLength - Number of characters to include before and after match
19
+ * @returns A snippet with the query highlighted in context
20
+ */
21
+ export function extractSnippet(content, query, contextLength = 100) {
22
+ const normalizedContent = content.toLowerCase();
23
+ const normalizedQuery = query.toLowerCase();
24
+ // Find the first occurrence of the query
25
+ const index = normalizedContent.indexOf(normalizedQuery);
26
+ if (index === -1) {
27
+ // Query not found, return beginning of content
28
+ return content.substring(0, contextLength * 2) + (content.length > contextLength * 2 ? '...' : '');
29
+ }
30
+ // Calculate snippet boundaries
31
+ const start = Math.max(0, index - contextLength);
32
+ const end = Math.min(content.length, index + query.length + contextLength);
33
+ let snippet = content.substring(start, end);
34
+ // Add ellipsis if needed
35
+ if (start > 0) {
36
+ snippet = '...' + snippet;
37
+ }
38
+ if (end < content.length) {
39
+ snippet = snippet + '...';
40
+ }
41
+ return snippet.trim();
42
+ }
43
+ /**
44
+ * Calculates Levenshtein distance between two strings (for fuzzy matching)
45
+ */
46
+ export function levenshteinDistance(a, b) {
47
+ const matrix = [];
48
+ // Initialize first column
49
+ for (let i = 0; i <= b.length; i++) {
50
+ matrix[i] = [i];
51
+ }
52
+ // Initialize first row
53
+ for (let j = 0; j <= a.length; j++) {
54
+ matrix[0][j] = j;
55
+ }
56
+ // Fill the matrix
57
+ for (let i = 1; i <= b.length; i++) {
58
+ for (let j = 1; j <= a.length; j++) {
59
+ if (b.charAt(i - 1) === a.charAt(j - 1)) {
60
+ matrix[i][j] = matrix[i - 1][j - 1];
61
+ }
62
+ else {
63
+ matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // substitution
64
+ matrix[i][j - 1] + 1, // insertion
65
+ matrix[i - 1][j] + 1 // deletion
66
+ );
67
+ }
68
+ }
69
+ }
70
+ return matrix[b.length][a.length];
71
+ }
72
+ /**
73
+ * Calculates fuzzy match score (0-100) based on Levenshtein distance
74
+ * 100 = exact match, lower scores = more different
75
+ */
76
+ export function fuzzyMatchScore(str1, str2) {
77
+ const normalized1 = normalizeText(str1);
78
+ const normalized2 = normalizeText(str2);
79
+ if (normalized1 === normalized2) {
80
+ return 100;
81
+ }
82
+ const maxLen = Math.max(normalized1.length, normalized2.length);
83
+ if (maxLen === 0) {
84
+ return 100;
85
+ }
86
+ const distance = levenshteinDistance(normalized1, normalized2);
87
+ const score = Math.max(0, 100 - (distance / maxLen) * 100);
88
+ return Math.round(score);
89
+ }
90
+ /**
91
+ * Checks if text contains all words from query
92
+ */
93
+ export function containsAllWords(text, query) {
94
+ const textWords = new Set(tokenize(text));
95
+ const queryWords = tokenize(query);
96
+ return queryWords.every(word => textWords.has(word));
97
+ }
98
+ /**
99
+ * Counts how many query words appear in the text
100
+ */
101
+ export function countMatchingWords(text, query) {
102
+ const textWords = new Set(tokenize(text));
103
+ const queryWords = tokenize(query);
104
+ return queryWords.filter(word => textWords.has(word)).length;
105
+ }
106
+ /**
107
+ * Chunks text into smaller pieces with overlap
108
+ *
109
+ * @param text - The text to chunk
110
+ * @param maxTokens - Maximum tokens per chunk (approximate, using word count)
111
+ * @param overlapTokens - Number of tokens to overlap between chunks
112
+ * @returns Array of text chunks with metadata
113
+ */
114
+ export function chunkText(text, maxTokens = 500, overlapTokens = 50) {
115
+ const words = text.split(/\s+/);
116
+ const chunks = [];
117
+ let chunkIndex = 0;
118
+ let currentPosition = 0;
119
+ while (currentPosition < words.length) {
120
+ const chunkWords = words.slice(currentPosition, currentPosition + maxTokens);
121
+ const chunkText = chunkWords.join(' ');
122
+ chunks.push({
123
+ text: chunkText,
124
+ chunkIndex,
125
+ startOffset: currentPosition,
126
+ endOffset: currentPosition + chunkWords.length,
127
+ });
128
+ chunkIndex++;
129
+ currentPosition += maxTokens - overlapTokens;
130
+ // Prevent infinite loop
131
+ if (chunkWords.length === 0) {
132
+ break;
133
+ }
134
+ }
135
+ return chunks;
136
+ }
137
+ /**
138
+ * Strips markdown from text (basic implementation)
139
+ * For more robust stripping, use remark-strip-markdown
140
+ */
141
+ export function stripMarkdownBasic(text) {
142
+ return text
143
+ // Remove HTML comments
144
+ .replace(/<!--[\s\S]*?-->/g, '')
145
+ // Remove code blocks
146
+ .replace(/```[\s\S]*?```/g, '')
147
+ // Remove inline code
148
+ .replace(/`[^`]+`/g, '')
149
+ // Remove images
150
+ .replace(/!\[.*?\]\(.*?\)/g, '')
151
+ // Remove links but keep text
152
+ .replace(/\[([^\]]+)\]\([^\)]+\)/g, '$1')
153
+ // Remove headers
154
+ .replace(/^#+\s+/gm, '')
155
+ // Remove bold/italic
156
+ .replace(/\*\*([^*]+)\*\*/g, '$1')
157
+ .replace(/\*([^*]+)\*/g, '$1')
158
+ .replace(/__([^_]+)__/g, '$1')
159
+ .replace(/_([^_]+)_/g, '$1')
160
+ // Remove blockquotes
161
+ .replace(/^>\s+/gm, '')
162
+ // Normalize whitespace
163
+ .replace(/\n\n+/g, '\n\n')
164
+ .trim();
165
+ }
166
+ /**
167
+ * Truncates text to a maximum length, breaking at word boundaries
168
+ */
169
+ export function truncateText(text, maxLength) {
170
+ if (text.length <= maxLength) {
171
+ return text;
172
+ }
173
+ const truncated = text.substring(0, maxLength);
174
+ const lastSpace = truncated.lastIndexOf(' ');
175
+ if (lastSpace > 0) {
176
+ return truncated.substring(0, lastSpace) + '...';
177
+ }
178
+ return truncated + '...';
179
+ }
180
+ /**
181
+ * Creates a hash from a string (simple implementation for cache keys)
182
+ */
183
+ export function hashString(str) {
184
+ let hash = 0;
185
+ for (let i = 0; i < str.length; i++) {
186
+ const char = str.charCodeAt(i);
187
+ hash = ((hash << 5) - hash) + char;
188
+ hash = hash & hash; // Convert to 32-bit integer
189
+ }
190
+ return Math.abs(hash).toString(36);
191
+ }
192
+ /**
193
+ * Calculates cosine similarity between two vectors
194
+ */
195
+ export function cosineSimilarity(a, b) {
196
+ if (a.length !== b.length) {
197
+ throw new Error('Vectors must have the same length');
198
+ }
199
+ let dotProduct = 0;
200
+ let normA = 0;
201
+ let normB = 0;
202
+ for (let i = 0; i < a.length; i++) {
203
+ dotProduct += a[i] * b[i];
204
+ normA += a[i] * a[i];
205
+ normB += b[i] * b[i];
206
+ }
207
+ normA = Math.sqrt(normA);
208
+ normB = Math.sqrt(normB);
209
+ if (normA === 0 || normB === 0) {
210
+ return 0;
211
+ }
212
+ return dotProduct / (normA * normB);
213
+ }
214
+ //# sourceMappingURL=text-processing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-processing.js","sourceRoot":"","sources":["../../src/utils/text-processing.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@contiva/sapbtp-docs-mcp",
3
+ "version": "1.0.1",
4
+ "description": "MCP server for SAP Business Technology Platform documentation - enables AI assistants to search and navigate SAP Business Technology Platform docs",
5
+ "type": "module",
6
+ "main": "./build/index.js",
7
+ "bin": {
8
+ "sapbtp-docs-mcp": "build/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "prepare": "npm run build",
13
+ "dev": "tsc --watch",
14
+ "start": "node ./build/index.js",
15
+ "prepublishOnly": "npm run build"
16
+ },
17
+ "files": [
18
+ "build/**/*",
19
+ "README.md",
20
+ "LICENSE"
21
+ ],
22
+ "keywords": [
23
+ "mcp",
24
+ "sap",
25
+ "business-technology-platform",
26
+ "documentation",
27
+ "search",
28
+ "ai",
29
+ "claude"
30
+ ],
31
+ "author": "Robert Fels",
32
+ "license": "Apache-2.0",
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/robertfels/sapbtp-docs-mcp.git"
36
+ },
37
+ "homepage": "https://github.com/robertfels/sapbtp-docs-mcp#readme",
38
+ "bugs": {
39
+ "url": "https://github.com/robertfels/sapbtp-docs-mcp/issues"
40
+ },
41
+ "dependencies": {
42
+ "@modelcontextprotocol/sdk": "^1.0.4",
43
+ "@xenova/transformers": "^2.17.2",
44
+ "gray-matter": "^4.0.3",
45
+ "remark": "^15.0.1",
46
+ "remark-gfm": "^4.0.0",
47
+ "strip-markdown": "^6.0.0"
48
+ },
49
+ "optionalDependencies": {
50
+ "voyageai": "^0.0.6",
51
+ "openai": "^4.77.0"
52
+ },
53
+ "devDependencies": {
54
+ "@types/node": "^22.10.2",
55
+ "typescript": "^5.7.2"
56
+ },
57
+ "engines": {
58
+ "node": ">=18.0.0"
59
+ },
60
+ "publishConfig": {
61
+ "access": "public"
62
+ }
63
+ }