@chanaka_nakandala/integration-agent 1.0.0
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/LICENSE +21 -0
- package/README.md +87 -0
- package/dist/cache/file-cache.d.ts +10 -0
- package/dist/cache/file-cache.d.ts.map +1 -0
- package/dist/cache/file-cache.js +79 -0
- package/dist/cache/file-cache.js.map +1 -0
- package/dist/cli/init-command.d.ts +2 -0
- package/dist/cli/init-command.d.ts.map +1 -0
- package/dist/cli/init-command.js +115 -0
- package/dist/cli/init-command.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +493 -0
- package/dist/index.js.map +1 -0
- package/dist/scrapers/docs-scraper.d.ts +28 -0
- package/dist/scrapers/docs-scraper.d.ts.map +1 -0
- package/dist/scrapers/docs-scraper.js +200 -0
- package/dist/scrapers/docs-scraper.js.map +1 -0
- package/dist/search/keyword-search.d.ts +39 -0
- package/dist/search/keyword-search.d.ts.map +1 -0
- package/dist/search/keyword-search.js +127 -0
- package/dist/search/keyword-search.js.map +1 -0
- package/dist/tools/code-generation-tool.d.ts +33 -0
- package/dist/tools/code-generation-tool.d.ts.map +1 -0
- package/dist/tools/code-generation-tool.js +62 -0
- package/dist/tools/code-generation-tool.js.map +1 -0
- package/dist/tools/search-result-formatter.d.ts +27 -0
- package/dist/tools/search-result-formatter.d.ts.map +1 -0
- package/dist/tools/search-result-formatter.js +89 -0
- package/dist/tools/search-result-formatter.js.map +1 -0
- package/dist/tools/search-tool.d.ts +9 -0
- package/dist/tools/search-tool.d.ts.map +1 -0
- package/dist/tools/search-tool.js +32 -0
- package/dist/tools/search-tool.js.map +1 -0
- package/dist/tools/template-loader.d.ts +54 -0
- package/dist/tools/template-loader.d.ts.map +1 -0
- package/dist/tools/template-loader.js +148 -0
- package/dist/tools/template-loader.js.map +1 -0
- package/dist/types/search.d.ts +21 -0
- package/dist/types/search.d.ts.map +1 -0
- package/dist/types/search.js +2 -0
- package/dist/types/search.js.map +1 -0
- package/package.json +63 -0
- package/templates/README.md +98 -0
- package/templates/authenticate/curl.template +97 -0
- package/templates/authenticate/java.template +155 -0
- package/templates/authenticate/python.template +111 -0
- package/templates/authenticate/typescript.template +98 -0
- package/templates/create_menu/curl.template +145 -0
- package/templates/create_menu/java.template +285 -0
- package/templates/create_menu/python.template +159 -0
- package/templates/create_menu/typescript.template +184 -0
- package/templates/receive_order/curl.template +138 -0
- package/templates/receive_order/java.template +263 -0
- package/templates/receive_order/python.template +157 -0
- package/templates/receive_order/typescript.template +194 -0
- package/templates/update_item_availability/curl.template +143 -0
- package/templates/update_item_availability/java.template +279 -0
- package/templates/update_item_availability/python.template +203 -0
- package/templates/update_item_availability/typescript.template +194 -0
- package/templates/update_order_status/curl.template +138 -0
- package/templates/update_order_status/java.template +202 -0
- package/templates/update_order_status/python.template +142 -0
- package/templates/update_order_status/typescript.template +139 -0
@@ -0,0 +1,32 @@
|
|
1
|
+
import { KeywordSearch } from '../search/keyword-search.js';
|
2
|
+
import { SearchResultFormatter } from './search-result-formatter.js';
|
3
|
+
import { FileCache } from '../cache/file-cache.js';
|
4
|
+
export class SearchTool {
|
5
|
+
cache;
|
6
|
+
keywordSearch;
|
7
|
+
formatter;
|
8
|
+
constructor() {
|
9
|
+
this.cache = new FileCache();
|
10
|
+
this.keywordSearch = new KeywordSearch();
|
11
|
+
this.formatter = new SearchResultFormatter();
|
12
|
+
}
|
13
|
+
async search(query, integrationPhase) {
|
14
|
+
const startTime = Date.now();
|
15
|
+
// Load cached documents
|
16
|
+
const docs = await this.cache.getAllCachedDocs();
|
17
|
+
let chunks = docs.flatMap(d => d.chunks);
|
18
|
+
// Filter by integration phase if specified
|
19
|
+
if (integrationPhase) {
|
20
|
+
chunks = chunks.filter(c => c.metadata?.integrationPhase === integrationPhase);
|
21
|
+
}
|
22
|
+
// Perform keyword search
|
23
|
+
const scoredChunks = this.keywordSearch.search(query, chunks, 5);
|
24
|
+
const executionTime = Date.now() - startTime;
|
25
|
+
// Format results
|
26
|
+
const response = this.formatter.formatResults(scoredChunks, query, executionTime, integrationPhase);
|
27
|
+
// Log search metrics
|
28
|
+
console.error(`Search: "${query}" returned ${response.results.length} results in ${executionTime}ms`);
|
29
|
+
return response;
|
30
|
+
}
|
31
|
+
}
|
32
|
+
//# sourceMappingURL=search-tool.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"search-tool.js","sourceRoot":"","sources":["../../src/tools/search-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGnD,MAAM,OAAO,UAAU;IACb,KAAK,CAAY;IACjB,aAAa,CAAgB;IAC7B,SAAS,CAAwB;IAEzC;QACE,IAAI,CAAC,KAAK,GAAG,IAAI,SAAS,EAAE,CAAC;QAC7B,IAAI,CAAC,aAAa,GAAG,IAAI,aAAa,EAAE,CAAC;QACzC,IAAI,CAAC,SAAS,GAAG,IAAI,qBAAqB,EAAE,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,gBAAyB;QACnD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,wBAAwB;QACxB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC;QACjD,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAEzC,2CAA2C;QAC3C,IAAI,gBAAgB,EAAE,CAAC;YACrB,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACzB,CAAC,CAAC,QAAQ,EAAE,gBAAgB,KAAK,gBAAgB,CAClD,CAAC;QACJ,CAAC;QAED,yBAAyB;QACzB,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;QAEjE,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAE7C,iBAAiB;QACjB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAC3C,YAAY,EACZ,KAAK,EACL,aAAa,EACb,gBAAgB,CACjB,CAAC;QAEF,qBAAqB;QACrB,OAAO,CAAC,KAAK,CACX,YAAY,KAAK,cAAc,QAAQ,CAAC,OAAO,CAAC,MAAM,eAAe,aAAa,IAAI,CACvF,CAAC;QAEF,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF"}
|
@@ -0,0 +1,54 @@
|
|
1
|
+
export interface TemplateMetadata {
|
2
|
+
description?: string;
|
3
|
+
author?: string;
|
4
|
+
version?: string;
|
5
|
+
lastModified?: string;
|
6
|
+
}
|
7
|
+
export interface LoadedTemplate {
|
8
|
+
content: string;
|
9
|
+
metadata: TemplateMetadata;
|
10
|
+
filePath: string;
|
11
|
+
}
|
12
|
+
export interface TemplateInfo {
|
13
|
+
operation: string;
|
14
|
+
language: string;
|
15
|
+
filePath: string;
|
16
|
+
}
|
17
|
+
export declare class TemplateLoader {
|
18
|
+
private readonly templateDir;
|
19
|
+
private templateCache;
|
20
|
+
constructor(templateDir?: string);
|
21
|
+
/**
|
22
|
+
* Load a template by operation and language
|
23
|
+
*/
|
24
|
+
loadTemplate(operation: string, language: string): Promise<string>;
|
25
|
+
/**
|
26
|
+
* Load template with metadata
|
27
|
+
*/
|
28
|
+
loadTemplateWithMetadata(operation: string, language: string): Promise<LoadedTemplate>;
|
29
|
+
/**
|
30
|
+
* Substitute variables in template
|
31
|
+
*/
|
32
|
+
substituteVariables(template: string, variables: Record<string, string>): string;
|
33
|
+
/**
|
34
|
+
* List all available templates
|
35
|
+
*/
|
36
|
+
listAvailableTemplates(): Promise<TemplateInfo[]>;
|
37
|
+
/**
|
38
|
+
* Parse metadata from template header comments
|
39
|
+
*/
|
40
|
+
private parseMetadata;
|
41
|
+
/**
|
42
|
+
* Generate cache key for operation/language
|
43
|
+
*/
|
44
|
+
private getCacheKey;
|
45
|
+
/**
|
46
|
+
* Clear template cache
|
47
|
+
*/
|
48
|
+
clearCache(): void;
|
49
|
+
/**
|
50
|
+
* Clear specific template from cache
|
51
|
+
*/
|
52
|
+
clearCacheForTemplate(operation: string, language: string): void;
|
53
|
+
}
|
54
|
+
//# sourceMappingURL=template-loader.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"template-loader.d.ts","sourceRoot":"","sources":["../../src/tools/template-loader.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,aAAa,CAA8B;gBAEvC,WAAW,CAAC,EAAE,MAAM;IAMhC;;OAEG;IACG,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA8CxE;;OAEG;IACG,wBAAwB,CAC5B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,cAAc,CAAC;IAc1B;;OAEG;IACH,mBAAmB,CACjB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,MAAM;IAYT;;OAEG;IACG,sBAAsB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAmCvD;;OAEG;IACH,OAAO,CAAC,aAAa;IAoBrB;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB;;OAEG;IACH,UAAU,IAAI,IAAI;IAIlB;;OAEG;IACH,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;CAIjE"}
|
@@ -0,0 +1,148 @@
|
|
1
|
+
import { promises as fs } from 'fs';
|
2
|
+
import path from 'path';
|
3
|
+
import { fileURLToPath } from 'url';
|
4
|
+
import { dirname } from 'path';
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
6
|
+
const __dirname = dirname(__filename);
|
7
|
+
export class TemplateLoader {
|
8
|
+
templateDir;
|
9
|
+
templateCache;
|
10
|
+
constructor(templateDir) {
|
11
|
+
// Default to templates/ directory in mcp-server package
|
12
|
+
this.templateDir = templateDir || path.join(__dirname, '../../templates');
|
13
|
+
this.templateCache = new Map();
|
14
|
+
}
|
15
|
+
/**
|
16
|
+
* Load a template by operation and language
|
17
|
+
*/
|
18
|
+
async loadTemplate(operation, language) {
|
19
|
+
const cacheKey = this.getCacheKey(operation, language);
|
20
|
+
// Check cache first
|
21
|
+
if (this.templateCache.has(cacheKey)) {
|
22
|
+
return this.templateCache.get(cacheKey).content;
|
23
|
+
}
|
24
|
+
// Construct template file path
|
25
|
+
const templatePath = path.join(this.templateDir, operation, `${language}.template`);
|
26
|
+
try {
|
27
|
+
// Validate template exists
|
28
|
+
await fs.access(templatePath);
|
29
|
+
// Read template content
|
30
|
+
const content = await fs.readFile(templatePath, 'utf-8');
|
31
|
+
// Parse metadata from header comments
|
32
|
+
const metadata = this.parseMetadata(content);
|
33
|
+
// Cache the template
|
34
|
+
const loadedTemplate = {
|
35
|
+
content,
|
36
|
+
metadata,
|
37
|
+
filePath: templatePath,
|
38
|
+
};
|
39
|
+
this.templateCache.set(cacheKey, loadedTemplate);
|
40
|
+
return content;
|
41
|
+
}
|
42
|
+
catch (error) {
|
43
|
+
if (error.code === 'ENOENT') {
|
44
|
+
throw new Error(`Template not found: ${operation}/${language}.template`);
|
45
|
+
}
|
46
|
+
throw new Error(`Failed to load template ${operation}/${language}: ${error.message}`);
|
47
|
+
}
|
48
|
+
}
|
49
|
+
/**
|
50
|
+
* Load template with metadata
|
51
|
+
*/
|
52
|
+
async loadTemplateWithMetadata(operation, language) {
|
53
|
+
const cacheKey = this.getCacheKey(operation, language);
|
54
|
+
// Check cache first
|
55
|
+
if (this.templateCache.has(cacheKey)) {
|
56
|
+
return this.templateCache.get(cacheKey);
|
57
|
+
}
|
58
|
+
// Load template (which will cache it)
|
59
|
+
await this.loadTemplate(operation, language);
|
60
|
+
return this.templateCache.get(cacheKey);
|
61
|
+
}
|
62
|
+
/**
|
63
|
+
* Substitute variables in template
|
64
|
+
*/
|
65
|
+
substituteVariables(template, variables) {
|
66
|
+
let result = template;
|
67
|
+
for (const [key, value] of Object.entries(variables)) {
|
68
|
+
// Replace all occurrences of {{KEY}} with value
|
69
|
+
const regex = new RegExp(`\\{\\{${key}\\}\\}`, 'g');
|
70
|
+
result = result.replace(regex, value);
|
71
|
+
}
|
72
|
+
return result;
|
73
|
+
}
|
74
|
+
/**
|
75
|
+
* List all available templates
|
76
|
+
*/
|
77
|
+
async listAvailableTemplates() {
|
78
|
+
const templates = [];
|
79
|
+
try {
|
80
|
+
// Read operation directories
|
81
|
+
const operations = await fs.readdir(this.templateDir, {
|
82
|
+
withFileTypes: true,
|
83
|
+
});
|
84
|
+
for (const operation of operations) {
|
85
|
+
if (!operation.isDirectory())
|
86
|
+
continue;
|
87
|
+
const operationPath = path.join(this.templateDir, operation.name);
|
88
|
+
// Read template files in operation directory
|
89
|
+
const files = await fs.readdir(operationPath);
|
90
|
+
for (const file of files) {
|
91
|
+
if (file.endsWith('.template')) {
|
92
|
+
const language = file.replace('.template', '');
|
93
|
+
templates.push({
|
94
|
+
operation: operation.name,
|
95
|
+
language,
|
96
|
+
filePath: path.join(operationPath, file),
|
97
|
+
});
|
98
|
+
}
|
99
|
+
}
|
100
|
+
}
|
101
|
+
return templates;
|
102
|
+
}
|
103
|
+
catch (error) {
|
104
|
+
throw new Error(`Failed to list templates: ${error.message}`);
|
105
|
+
}
|
106
|
+
}
|
107
|
+
/**
|
108
|
+
* Parse metadata from template header comments
|
109
|
+
*/
|
110
|
+
parseMetadata(content) {
|
111
|
+
const metadata = {};
|
112
|
+
// Extract header comment block (first 20 lines)
|
113
|
+
const lines = content.split('\n').slice(0, 20);
|
114
|
+
for (const line of lines) {
|
115
|
+
// Look for metadata patterns in comments
|
116
|
+
const descMatch = line.match(/@description\s+(.+)/i);
|
117
|
+
const authorMatch = line.match(/@author\s+(.+)/i);
|
118
|
+
const versionMatch = line.match(/@version\s+(.+)/i);
|
119
|
+
if (descMatch)
|
120
|
+
metadata.description = descMatch[1].trim();
|
121
|
+
if (authorMatch)
|
122
|
+
metadata.author = authorMatch[1].trim();
|
123
|
+
if (versionMatch)
|
124
|
+
metadata.version = versionMatch[1].trim();
|
125
|
+
}
|
126
|
+
return metadata;
|
127
|
+
}
|
128
|
+
/**
|
129
|
+
* Generate cache key for operation/language
|
130
|
+
*/
|
131
|
+
getCacheKey(operation, language) {
|
132
|
+
return `${operation}:${language}`;
|
133
|
+
}
|
134
|
+
/**
|
135
|
+
* Clear template cache
|
136
|
+
*/
|
137
|
+
clearCache() {
|
138
|
+
this.templateCache.clear();
|
139
|
+
}
|
140
|
+
/**
|
141
|
+
* Clear specific template from cache
|
142
|
+
*/
|
143
|
+
clearCacheForTemplate(operation, language) {
|
144
|
+
const cacheKey = this.getCacheKey(operation, language);
|
145
|
+
this.templateCache.delete(cacheKey);
|
146
|
+
}
|
147
|
+
}
|
148
|
+
//# sourceMappingURL=template-loader.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"template-loader.js","sourceRoot":"","sources":["../../src/tools/template-loader.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
export interface SearchResult {
|
2
|
+
title: string;
|
3
|
+
snippet: string;
|
4
|
+
sourceUrl: string;
|
5
|
+
relevanceScore: number;
|
6
|
+
highlights: string[];
|
7
|
+
}
|
8
|
+
export interface SearchResponse {
|
9
|
+
results: SearchResult[];
|
10
|
+
metadata: SearchMetadata;
|
11
|
+
message?: string;
|
12
|
+
suggestions?: string[];
|
13
|
+
}
|
14
|
+
export interface SearchMetadata {
|
15
|
+
queryTime: number;
|
16
|
+
totalResults: number;
|
17
|
+
returned: number;
|
18
|
+
query: string;
|
19
|
+
integrationPhase?: string;
|
20
|
+
}
|
21
|
+
//# sourceMappingURL=search.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/types/search.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,QAAQ,EAAE,cAAc,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/types/search.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
{
|
2
|
+
"name": "@chanaka_nakandala/integration-agent",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"description": "AI-powered MCP server for Grubtech API integration support - provides code generation and documentation search via Claude Code",
|
5
|
+
"type": "module",
|
6
|
+
"main": "./dist/index.js",
|
7
|
+
"types": "./dist/index.d.ts",
|
8
|
+
"bin": {
|
9
|
+
"grubtech-integration-agent": "./dist/index.js",
|
10
|
+
"grubtech-mcp": "./dist/index.js"
|
11
|
+
},
|
12
|
+
"exports": {
|
13
|
+
".": {
|
14
|
+
"types": "./dist/index.d.ts",
|
15
|
+
"import": "./dist/index.js"
|
16
|
+
}
|
17
|
+
},
|
18
|
+
"files": [
|
19
|
+
"dist/",
|
20
|
+
"templates/",
|
21
|
+
"README.md",
|
22
|
+
"LICENSE"
|
23
|
+
],
|
24
|
+
"publishConfig": {
|
25
|
+
"access": "public",
|
26
|
+
"registry": "https://registry.npmjs.org/"
|
27
|
+
},
|
28
|
+
"repository": {
|
29
|
+
"type": "git",
|
30
|
+
"url": "https://github.com/chanaka-nakandala/grubtech-integration-agent.git",
|
31
|
+
"directory": "packages/mcp-server"
|
32
|
+
},
|
33
|
+
"homepage": "https://github.com/chanaka-nakandala/grubtech-integration-agent#readme",
|
34
|
+
"bugs": {
|
35
|
+
"url": "https://github.com/chanaka-nakandala/grubtech-integration-agent/issues"
|
36
|
+
},
|
37
|
+
"scripts": {
|
38
|
+
"build": "node ../../node_modules/typescript/lib/tsc.js",
|
39
|
+
"dev": "node ../../node_modules/typescript/lib/tsc.js --watch",
|
40
|
+
"clean": "rm -rf dist",
|
41
|
+
"test": "echo \"Tests will be added in future iteration\""
|
42
|
+
},
|
43
|
+
"keywords": [
|
44
|
+
"grubtech",
|
45
|
+
"mcp",
|
46
|
+
"integration",
|
47
|
+
"support-agent"
|
48
|
+
],
|
49
|
+
"author": "Grubtech",
|
50
|
+
"license": "MIT",
|
51
|
+
"dependencies": {
|
52
|
+
"@modelcontextprotocol/sdk": "^0.5.0",
|
53
|
+
"axios": "^1.12.2",
|
54
|
+
"cheerio": "^1.1.2"
|
55
|
+
},
|
56
|
+
"devDependencies": {
|
57
|
+
"@types/node": "^20.0.0",
|
58
|
+
"typescript": "^5.9.3"
|
59
|
+
},
|
60
|
+
"engines": {
|
61
|
+
"node": ">=18.0.0"
|
62
|
+
}
|
63
|
+
}
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# Grubtech Integration Code Templates
|
2
|
+
|
3
|
+
This directory contains code templates for generating integration code snippets.
|
4
|
+
|
5
|
+
## Directory Structure
|
6
|
+
|
7
|
+
```
|
8
|
+
templates/
|
9
|
+
├── {operation}/
|
10
|
+
│ ├── {language}.template
|
11
|
+
│ └── ...
|
12
|
+
```
|
13
|
+
|
14
|
+
## Supported Operations
|
15
|
+
|
16
|
+
- `authenticate` - API authentication
|
17
|
+
- `create_menu` - Menu synchronization
|
18
|
+
- `receive_order` - Order webhook endpoint
|
19
|
+
- `update_order_status` - Order status updates
|
20
|
+
- `update_item_availability` - Item availability updates
|
21
|
+
|
22
|
+
## Supported Languages
|
23
|
+
|
24
|
+
- `typescript` - TypeScript/Node.js
|
25
|
+
- `python` - Python 3.8+
|
26
|
+
- `java` - Java 17+ with Spring Boot
|
27
|
+
- `curl` - cURL commands
|
28
|
+
|
29
|
+
## Template Format
|
30
|
+
|
31
|
+
### File Naming
|
32
|
+
|
33
|
+
Templates must follow the naming convention: `{language}.template`
|
34
|
+
|
35
|
+
Example: `typescript.template`, `python.template`
|
36
|
+
|
37
|
+
### Variable Placeholders
|
38
|
+
|
39
|
+
Use double curly braces for variables: `{{VARIABLE_NAME}}`
|
40
|
+
|
41
|
+
Example:
|
42
|
+
```typescript
|
43
|
+
const API_KEY = '{{API_KEY}}';
|
44
|
+
const PARTNER_ID = '{{PARTNER_ID}}';
|
45
|
+
```
|
46
|
+
|
47
|
+
### Metadata (Optional)
|
48
|
+
|
49
|
+
Include metadata in header comments using JSDoc-style tags:
|
50
|
+
|
51
|
+
```typescript
|
52
|
+
/**
|
53
|
+
* @description Grubtech API Authentication - TypeScript
|
54
|
+
* @author Grubtech Integration Team
|
55
|
+
* @version 1.0.0
|
56
|
+
*/
|
57
|
+
```
|
58
|
+
|
59
|
+
Supported metadata tags:
|
60
|
+
- `@description` - Template description
|
61
|
+
- `@author` - Template author
|
62
|
+
- `@version` - Template version
|
63
|
+
|
64
|
+
### Template Requirements
|
65
|
+
|
66
|
+
1. **Syntactically Valid**: Templates must be valid code in their language
|
67
|
+
2. **Comments**: Include explanatory comments for each section
|
68
|
+
3. **Error Handling**: Include error handling examples
|
69
|
+
4. **Complete Examples**: Provide runnable code with example data
|
70
|
+
5. **Placeholders**: Use clear, descriptive placeholder names
|
71
|
+
|
72
|
+
## Adding New Templates
|
73
|
+
|
74
|
+
1. Create operation directory: `templates/{operation}/`
|
75
|
+
2. Add template file: `{language}.template`
|
76
|
+
3. Include header metadata
|
77
|
+
4. Add variable placeholders using `{{VARIABLE}}`
|
78
|
+
5. Test syntax validity
|
79
|
+
6. Update this README
|
80
|
+
|
81
|
+
## Template Loader
|
82
|
+
|
83
|
+
Templates are loaded via the `TemplateLoader` class:
|
84
|
+
|
85
|
+
```typescript
|
86
|
+
import { TemplateLoader } from './tools/template-loader.js';
|
87
|
+
|
88
|
+
const loader = new TemplateLoader();
|
89
|
+
|
90
|
+
// Load template
|
91
|
+
const template = await loader.loadTemplate('authenticate', 'typescript');
|
92
|
+
|
93
|
+
// Substitute variables
|
94
|
+
const code = loader.substituteVariables(template, {
|
95
|
+
API_KEY: 'my-key',
|
96
|
+
PARTNER_ID: 'partner-123',
|
97
|
+
});
|
98
|
+
```
|
@@ -0,0 +1,97 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
# @description Grubtech API Authentication - cURL
|
4
|
+
# @author Grubtech Integration Team
|
5
|
+
# @version 1.0.0
|
6
|
+
#
|
7
|
+
# This example demonstrates how to authenticate with the Grubtech API
|
8
|
+
# using an API key to obtain an access token.
|
9
|
+
#
|
10
|
+
# Prerequisites:
|
11
|
+
# - curl command-line tool
|
12
|
+
# - jq (for JSON parsing, optional but recommended)
|
13
|
+
# - Valid Grubtech API key
|
14
|
+
#
|
15
|
+
# Replace the following placeholders:
|
16
|
+
# - {{API_KEY}}: Your Grubtech API key
|
17
|
+
# - {{PARTNER_ID}}: Your partner identifier
|
18
|
+
|
19
|
+
API_KEY="{{API_KEY}}"
|
20
|
+
PARTNER_ID="{{PARTNER_ID}}"
|
21
|
+
BASE_URL="https://api.grubtech.io"
|
22
|
+
|
23
|
+
# Authenticate with Grubtech API and obtain access token
|
24
|
+
authenticate() {
|
25
|
+
echo "Authenticating with Grubtech API..."
|
26
|
+
|
27
|
+
# Make authentication request
|
28
|
+
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \
|
29
|
+
"${BASE_URL}/v1/auth/token" \
|
30
|
+
-H "Content-Type: application/json" \
|
31
|
+
-H "x-api-key: ${API_KEY}" \
|
32
|
+
-d "{
|
33
|
+
\"partnerId\": \"${PARTNER_ID}\",
|
34
|
+
\"grantType\": \"api_key\"
|
35
|
+
}")
|
36
|
+
|
37
|
+
# Extract HTTP status code and body
|
38
|
+
HTTP_CODE=$(echo "$RESPONSE" | tail -n 1)
|
39
|
+
BODY=$(echo "$RESPONSE" | sed '$d')
|
40
|
+
|
41
|
+
# Check for errors
|
42
|
+
if [ "$HTTP_CODE" -ne 200 ]; then
|
43
|
+
echo "Authentication failed: HTTP $HTTP_CODE"
|
44
|
+
echo "Response: $BODY"
|
45
|
+
return 1
|
46
|
+
fi
|
47
|
+
|
48
|
+
# Extract token from response (using jq if available)
|
49
|
+
if command -v jq &> /dev/null; then
|
50
|
+
TOKEN=$(echo "$BODY" | jq -r '.token')
|
51
|
+
EXPIRES_IN=$(echo "$BODY" | jq -r '.expiresIn')
|
52
|
+
|
53
|
+
echo "Authentication successful!"
|
54
|
+
echo "Token expires in: ${EXPIRES_IN} seconds"
|
55
|
+
else
|
56
|
+
# Fallback: manual parsing (less reliable)
|
57
|
+
TOKEN=$(echo "$BODY" | grep -o '"token":"[^"]*' | cut -d'"' -f4)
|
58
|
+
echo "Authentication successful!"
|
59
|
+
echo "Note: Install jq for better JSON parsing"
|
60
|
+
fi
|
61
|
+
|
62
|
+
echo "$TOKEN"
|
63
|
+
}
|
64
|
+
|
65
|
+
# Example: Use token in subsequent API requests
|
66
|
+
example_api_call() {
|
67
|
+
local TOKEN=$1
|
68
|
+
|
69
|
+
echo "Making example API call..."
|
70
|
+
|
71
|
+
curl -s -X GET \
|
72
|
+
"${BASE_URL}/v1/menus" \
|
73
|
+
-H "Authorization: Bearer ${TOKEN}" \
|
74
|
+
-H "Content-Type: application/json"
|
75
|
+
}
|
76
|
+
|
77
|
+
# Main execution
|
78
|
+
main() {
|
79
|
+
# Authenticate and get token
|
80
|
+
ACCESS_TOKEN=$(authenticate)
|
81
|
+
|
82
|
+
if [ -z "$ACCESS_TOKEN" ]; then
|
83
|
+
echo "Failed to obtain access token"
|
84
|
+
exit 1
|
85
|
+
fi
|
86
|
+
|
87
|
+
echo ""
|
88
|
+
echo "Access Token: ${ACCESS_TOKEN:0:20}..."
|
89
|
+
echo ""
|
90
|
+
|
91
|
+
# Use token for API calls
|
92
|
+
MENUS=$(example_api_call "$ACCESS_TOKEN")
|
93
|
+
echo "Menus: $MENUS"
|
94
|
+
}
|
95
|
+
|
96
|
+
# Run main function
|
97
|
+
main
|