ee-mcp-service
Version:
Model Context Protocol Service for Evolution Engineering
511 lines (502 loc) • 23.1 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
// src/services/falkordb.service.ts
var import_falkordb = require("falkordb");
// src/config/index.ts
var import_dotenv = __toESM(require("dotenv"));
import_dotenv.default.config();
var config = {
falkorDB: {
host: "localhost",
port: 6379,
username: "",
password: ""
},
mcp: {
apiKey: process.env.EE_API_KEY || "*",
version: process.env.EE_MCP_VERSION_RESPONSE || "1.0.0 alpha"
}
};
// src/services/falkordb.service.ts
var FalkorDBService = class {
constructor() {
this.client = null;
this.apiKey = null;
this.apiKeyVerificationResult = null;
}
/**
* Returns the API key for MCP
* @returns API key as string
*/
verifyApiKey(apiKey) {
return __async(this, null, function* () {
if (this.apiKey === apiKey) {
return {
valid: true,
data: this.apiKeyVerificationResult,
message: "API KEY verification successful"
};
}
const myHeaders = new Headers();
myHeaders.append("User-Agent", "Apidog/1.0.0 (https://apidog.com)");
myHeaders.append("Content-Type", "application/json");
myHeaders.append("Authorization", "Bearer eyJhbGciOiJIUzI1NiJ9.e30.Ivww_qG4htViuqxXGRVbHVZbMQETOYnfbYf06HsS_B4");
myHeaders.append("Accept", "*/*");
myHeaders.append("Host", "lihiuvyxjttzpdhzafcb.supabase.co");
myHeaders.append("Connection", "keep-alive");
const raw = JSON.stringify({
"apiKey": apiKey
});
const requestOptions = {
method: "POST",
headers: myHeaders,
body: raw,
redirect: "follow"
};
try {
const response = yield fetch("https://lihiuvyxjttzpdhzafcb.supabase.co/functions/v1/check-api-key", requestOptions);
const result = yield response.json();
if (!response.ok) {
throw new Error("Error Status " + response.status.toString());
}
this.apiKeyVerificationResult = result;
this.apiKey = apiKey;
const serverConnectionStatus = yield this.init();
if (!serverConnectionStatus) {
this.apiKeyVerificationResult = null;
this.apiKey = null;
return {
valid: false,
data: {},
message: "API KEY verification successful, EE MCP Server Connection Failed"
};
}
return {
valid: true,
data: result,
message: "API KEY verification successful, EE MCP Server Connected"
};
} catch (error) {
let errorMessage = "Unknown error occurred during API key verification";
if (error instanceof Error) {
errorMessage = error.message;
}
this.apiKeyVerificationResult = null;
this.apiKey = null;
return {
valid: false,
data: {},
message: "API KEY verification failed: " + errorMessage
};
}
});
}
init() {
return __async(this, null, function* () {
var _a, _b, _c, _d, _e, _f, _g, _h;
try {
if (this.apiKey) {
config.falkorDB.password = (_b = (_a = this.apiKeyVerificationResult) == null ? void 0 : _a.data) == null ? void 0 : _b["FALKORDB_PASSWORD"];
config.falkorDB.username = (_d = (_c = this.apiKeyVerificationResult) == null ? void 0 : _c.data) == null ? void 0 : _d["FALKORDB_USERNAME"];
config.falkorDB.host = (_f = (_e = this.apiKeyVerificationResult) == null ? void 0 : _e.data) == null ? void 0 : _f["FALKORDB_HOST"];
config.falkorDB.port = (_h = (_g = this.apiKeyVerificationResult) == null ? void 0 : _g.data) == null ? void 0 : _h["FALKORDB_PORT"];
} else {
this.apiKeyVerificationResult = null;
this.apiKey = null;
throw new Error("Missing API key");
}
if (this.client) {
yield this.client.close();
this.client = null;
}
this.client = yield import_falkordb.FalkorDB.connect({
socket: {
host: config.falkorDB.host,
port: config.falkorDB.port
},
password: config.falkorDB.password,
username: config.falkorDB.username
});
const connection = yield this.client.connection;
yield connection.ping();
return true;
} catch (error) {
return false;
}
});
}
executeGraphQuery(_0, _1) {
return __async(this, arguments, function* (graphName, query, apiKey = config.mcp.apiKey, params) {
if (!query || query.trim() === "") {
return { error: true, result: `Error executing EE MCP Server Graph DB query: No Query Provided` };
}
const connectionParameters = yield falkorDBService.verifyApiKey(apiKey);
if (connectionParameters.valid && this.client !== null) {
const customerGraphName = apiKey + "-" + graphName;
try {
const graph = this.client.selectGraph(customerGraphName);
const result = yield graph.query(query, params);
return { error: false, result };
} catch (error) {
throw new Error(`Error executing EE MCP Server Graph DB query: ${error}`);
}
} else {
throw new Error(`Failed to get Ontology from EE MCP Server: ${connectionParameters.message}`);
}
});
}
executeOntologyGraphQuery(_0, _1) {
return __async(this, arguments, function* (graphName, query, apiKey = config.mcp.apiKey, params) {
if (!query || query.trim() === "") {
return { error: true, result: `Error executing EE MCP Server Ontology Graph DB query: No Query Provided` };
}
const connectionParameters = yield falkorDBService.verifyApiKey(apiKey);
if (connectionParameters.valid && this.client !== null) {
try {
const graph = this.client.selectGraph(graphName);
const result = yield graph.query(query, params);
return { error: false, result };
} catch (error) {
throw new Error(`Error executing EE MCP Server Ontology Graph DB query: ${error}`);
}
} else {
throw new Error(`Failed to get Ontology Data from EE MCP Server: ${connectionParameters.message}`);
}
});
}
getOntology() {
return __async(this, arguments, function* (apiKey = config.mcp.apiKey, params) {
var _a, _b;
const connectionParameters = yield falkorDBService.verifyApiKey(apiKey);
if (connectionParameters.valid && this.client !== null) {
const schemaName = (_b = (_a = this.apiKeyVerificationResult) == null ? void 0 : _a.data) == null ? void 0 : _b["FALKORDB_GRAPH_SEMANTIC"];
const graphName = schemaName.endsWith("_schema") ? schemaName : schemaName + "_schema";
try {
const graph = this.client.selectGraph(graphName);
const result = yield graph.query("MATCH (sourceNode)-[relation]->(targetNode) RETURN sourceNode, relation, targetNode", params);
if (!result.data || result.data.length === 0) {
throw new Error("No Ontology found in EE MCP Server");
}
return result;
} catch (error) {
throw new Error(`Error getting Ontology from EE MCP Server: ${error}`);
}
} else {
throw new Error(`Failed to get Ontology from EE MCP Server: ${connectionParameters.message}`);
}
});
}
// async getSchema(apiKey: string = config.mcp.apiKey, params?: Record<string, any>): Promise<any> {
// const connectionParameters = await falkorDBService.verifyApiKey(apiKey);
// if (connectionParameters.valid && this.client !== null) {
// get the schema name from the api key verification result
// I have to update KG to set correct KG name {SUBSCRIPTION-ID}-KG-{KG-NAME}
// I have to update KG to set correct KG name {SUBSCRIPTION-ID}-KG-{KG-NAME}
// I have to update KG to set correct KG name {SUBSCRIPTION-ID}-KG-{KG-NAME}
// const schemaName = this.apiKeyVerificationResult?.data?.['FALKORDB_GRAPH_DEFAULT'];
// const graphName = schemaName.endsWith('_schema') ? schemaName : schemaName + '_schema';
// try {
// const graph = this.client.selectGraph(graphName);
// const result = await graph.query('MATCH (sourceNode)-[relation]->(targetNode) RETURN sourceNode, relation, targetNode', params);
// if (!result.data || result.data.length === 0) {
// throw new Error('No Ontology found in EE MCP Server');
// }
// return result;
// } catch (error) {
// throw new Error(`Error getting KnowledgeGraph Schema from EE MCP Server: ${error}`);
// }
// } else {
// throw new Error(`Failed to get KnowledgeGraph Schema from EE MCP Server: ${connectionParameters.message}`);
// }
// }
getOntologyMetadata() {
return __async(this, arguments, function* (apiKey = config.mcp.apiKey, params) {
var _a, _b;
const connectionParameters = yield falkorDBService.verifyApiKey(apiKey);
if (connectionParameters.valid && this.client !== null) {
const schemaName = (_b = (_a = this.apiKeyVerificationResult) == null ? void 0 : _a.data) == null ? void 0 : _b["FALKORDB_GRAPH_SEMANTIC"];
const graphName = schemaName;
try {
const graph = this.client.selectGraph(graphName);
const result = yield graph.query("MATCH (metadata:MetaInfo) RETURN metadata.Name,metadata.Prompt", params);
if (!result.data || result.data.length === 0) {
throw new Error("No Ontology Metadata found in EE MCP Server");
}
const instructions = result.data.map((item) => `${item["metadata.Name"]}: ${item["metadata.Prompt"]}`).join("\n");
return instructions;
} catch (error) {
throw new Error(`Error getting Ontology Metadata from EE MCP Server: ${error}`);
}
} else {
throw new Error(`Failed to get Ontology Metadata from EE MCP Server: ${connectionParameters.message}`);
}
});
}
/**
* Lists all available graphs in FalkorDB
* @returns Array of graph names
*/
listGraphs() {
return __async(this, arguments, function* (apiKey = config.mcp.apiKey) {
const connectionParameters = yield falkorDBService.verifyApiKey(apiKey);
if (connectionParameters.valid && this.client !== null) {
try {
return yield this.client.list();
} catch (error) {
console.error("Error listing EE Graphs:", error);
throw error;
}
} else {
throw new Error(`Failed to list graphs: ${connectionParameters.message}`);
}
});
}
close() {
return __async(this, null, function* () {
if (this.client) {
yield this.client.close();
this.client = null;
}
});
}
};
var falkorDBService = new FalkorDBService();
// src/index.ts
var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
// src/tools/mcp-tools.ts
var import_zod = require("zod");
// src/tools/mcp-tool-helpers.ts
var tools = {
"read-me": 'Call "read-me" first to understand how to navigate and use MeTaX MCP functionality',
"is-api-key-valid": "Validates EE API key and tests connection to EE MeTaX Service",
"get-instructions-and-tool-description": "Get instructions about the EE MeTaX Service, description of metadata objects and available tools to call",
"query-metadata-ontology": "Query Semantic Ontology of metadata objects",
"query-business": "Query Business Data",
"query-business-ontology": "Query Semantic Ontology of Business Data",
"query-technology": "Query Technology Data",
"query-technology-ontology": "Query Semantic Ontology of Technology Data",
"query-environment": "Query Environment Data",
"query-environment-ontology": "Query Semantic Ontology of Environment Data",
"query-organization": "Query Organization Data",
"query-organization-ontology": "Query Semantic Ontology of Organization Data",
"query-strategy-scenario": "Query Strategy Scenario Data",
"query-strategy-scenario-ontology": "Query Semantic Ontology of Strategy Scenario Data"
};
function apiExist(apiKey) {
if (apiKey === null || apiKey === void 0 || apiKey === "*") {
return {
"exist": {
content: [
{
type: "text",
text: JSON.stringify({ error: "API key is required" })
}
],
isError: true
}
};
}
return { "exist": true };
}
function formatResult(result, queryTime, source, isError = false, ...otherParam) {
let metadataOtherParam = {};
if (otherParam) {
metadataOtherParam = otherParam[0];
}
const formattedResult = {
data: result,
metadata: __spreadValues({
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
queryTime,
provider: "Evolution Engineering",
source,
version: "1.0.0"
}, metadataOtherParam)
};
return {
content: [
{
type: "text",
text: JSON.stringify(formattedResult)
}
],
_meta: {
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
queryTime
},
isError
};
}
// src/tools/mcp-tools.ts
function queryGraph(toolName, graphName, query, apiKey, params) {
return __async(this, null, function* () {
const apiKeyResult = apiExist(apiKey);
if (!apiKeyResult.exist) {
return apiKeyResult;
}
try {
const startTime = Date.now();
const response = yield falkorDBService.executeGraphQuery(
graphName,
query,
apiKey
);
const queryTime = Date.now() - startTime;
return formatResult(response.result, queryTime, "EE MCP Service #" + toolName, false);
} catch (error) {
return formatResult(error.message, 0, "EE MCP Service #" + toolName, true);
}
});
}
function registerMcpTools(server2, config2) {
server2.tool("read-me", {}, (args, extra) => __async(null, null, function* () {
return formatResult(
"First, test if your API key is valid. If the API key is valid, then get the ontology metadata and instructions.If the API key is not valid, then return an error message.The 'get-instructions-and-tool-description' tool will guide you where to find releavant information, how they are connected and how to construct your query to get the information you need.You can get upper ontology model called 'MeTaX' by providing query 'query-metadata-ontology' tool.All Knowledge graphs are divided into domains: Business, Technology, Environment, Organization.You can get ontology model for a specific domain by providing query to 'query-business-ontology', 'query-technology-ontology', 'query-environment-ontology' and 'query-organization-ontology' tools respectively.You can get knowledge graph for a specific domain by providing query to 'query-business', 'query-technology', 'query-environment' and 'query-organization' tools respectively.Additionally, there are tools to get strategy scenario data by providing query to 'query-strategy-scenario' tool.You can get ontology model for strategy scenario by providing query to 'query-strategy-scenario-ontology' tool.",
0,
"EE MCP Service #read-me",
false
);
}));
server2.tool("is-api-key-valid", { apiKey: import_zod.z.string().default(config2.mcp.apiKey).optional() }, (args, extra) => __async(null, null, function* () {
const apiKeyResult = apiExist(args.apiKey);
if (!apiKeyResult.exist) {
return apiKeyResult;
}
const startTime = Date.now();
const result = yield falkorDBService.verifyApiKey(args.apiKey);
if (!result.valid) {
return formatResult(result.message, 0, "EE MCP Service #is-api-key-valid", true);
}
const queryTime = Date.now() - startTime;
return formatResult(`API key ${args.apiKey} is valid`, queryTime, "EE MCP Service #is-api-key-valid", false);
}));
server2.tool("get-instructions-and-tool-description", { apiKey: import_zod.z.string().default(config2.mcp.apiKey).optional() }, (args, extra) => __async(null, null, function* () {
const apiKeyResult = apiExist(args.apiKey);
if (!apiKeyResult.exist) {
return apiKeyResult;
}
const startTime = Date.now();
const response = yield falkorDBService.getOntologyMetadata(args.apiKey);
const queryTime = Date.now() - startTime;
return formatResult(response, queryTime, "EE MCP Service #get-instructions-and-tool-description", false, { "instructions": response.instructions, tools, "graphTypes": ["property", "directed"], "queryLanguages": ["cypher"] });
}));
server2.tool("query-metadata-ontology", { query: import_zod.z.string(), apiKey: import_zod.z.string().default(config2.mcp.apiKey).optional() }, (args, extra) => __async(null, null, function* () {
return queryGraph("query-metadata-ontology", "MeTaX_schema", args.query, args.apiKey);
}));
server2.tool("query-business", { query: import_zod.z.string(), apiKey: import_zod.z.string().default(config2.mcp.apiKey).optional() }, (args, extra) => __async(null, null, function* () {
return queryGraph("query-business", "KG-BUSINESS", args.query, args.apiKey);
}));
server2.tool("query-business-ontology", { query: import_zod.z.string(), apiKey: import_zod.z.string().default(config2.mcp.apiKey).optional() }, (args, extra) => __async(null, null, function* () {
return queryGraph("query-business-ontology", "KG-BUSINESS_schema", args.query, args.apiKey);
}));
server2.tool("query-technology", { query: import_zod.z.string(), apiKey: import_zod.z.string().default(config2.mcp.apiKey).optional() }, (args, extra) => __async(null, null, function* () {
return queryGraph("query-technology", "KG-TECHNOLOGY", args.query, args.apiKey);
}));
server2.tool("query-technology-ontology", { query: import_zod.z.string(), apiKey: import_zod.z.string().default(config2.mcp.apiKey).optional() }, (args, extra) => __async(null, null, function* () {
return queryGraph("query-technology-ontology", "KG-TECHNOLOGY_schema", args.query, args.apiKey);
}));
server2.tool("query-environment", { query: import_zod.z.string(), apiKey: import_zod.z.string().default(config2.mcp.apiKey).optional() }, (args, extra) => __async(null, null, function* () {
return queryGraph("query-environment", "KG-ENVIRONMENT", args.query, args.apiKey);
}));
server2.tool("query-environment-ontology", { query: import_zod.z.string(), apiKey: import_zod.z.string().default(config2.mcp.apiKey).optional() }, (args, extra) => __async(null, null, function* () {
return queryGraph("query-environment-ontology", "KG-ENVIRONMENT_schema", args.query, args.apiKey);
}));
server2.tool("query-organization", { query: import_zod.z.string(), apiKey: import_zod.z.string().default(config2.mcp.apiKey).optional() }, (args, extra) => __async(null, null, function* () {
return queryGraph("query-organization", "KG-ORGANIZATION", args.query, args.apiKey);
}));
server2.tool("query-organization-ontology", { query: import_zod.z.string(), apiKey: import_zod.z.string().default(config2.mcp.apiKey).optional() }, (args, extra) => __async(null, null, function* () {
return queryGraph("query-organization-ontology", "KG-ORGANIZATION_schema", args.query, args.apiKey);
}));
server2.tool("query-strategy-scenario", { query: import_zod.z.string(), apiKey: import_zod.z.string().default(config2.mcp.apiKey).optional() }, (args, extra) => __async(null, null, function* () {
return queryGraph("query-strategy-scenario", "KG-STRATEGY-SCENARIO", args.query, args.apiKey);
}));
server2.tool("query-strategy-scenario-ontology", { query: import_zod.z.string(), apiKey: import_zod.z.string().default(config2.mcp.apiKey).optional() }, (args, extra) => __async(null, null, function* () {
return queryGraph("query-strategy-scenario-ontology", "KG-STRATEGY-SCENARIO_schema", args.query, args.apiKey);
}));
}
// src/index.ts
var server = new import_mcp.McpServer({
name: "EE-MCP-SERVICE",
version: "1.0.0",
description: "Evolution Engineering MCP Service"
});
registerMcpTools(server, config);
function main() {
return __async(this, null, function* () {
const transport = new import_stdio.StdioServerTransport();
yield server.connect(transport);
console.error("EE MCP Server running on stdio");
});
}
process.on("SIGTERM", () => __async(null, null, function* () {
console.log("SIGTERM received. Shutting down gracefully...");
yield falkorDBService.close();
process.exit(0);
}));
process.on("SIGINT", () => __async(null, null, function* () {
console.log("SIGINT received. Shutting down gracefully...");
yield falkorDBService.close();
process.exit(0);
}));
main().catch((error) => {
console.error("Fatal error in main():", error);
process.exit(1);
});
//# sourceMappingURL=index.js.map