ee-mcp-server
Version:
Model Context Protocol server for Evolution Engineering
564 lines (559 loc) • 19.2 kB
JavaScript
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
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 || "*"
}
};
// 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) {
return __async(this, arguments, function* (query, apiKey = config.mcp.apiKey, params) {
var _a, _b;
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 graphName = (_b = (_a = this.apiKeyVerificationResult) == null ? void 0 : _a.data) == null ? void 0 : _b["FALKORDB_GRAPH_DEFAULT"];
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 Graph DB query: ${error}`);
}
} else {
throw new Error(`Failed to get Ontology from EE MCP Server: ${connectionParameters.message}`);
}
});
}
executeOntologyGraphQuery(_0) {
return __async(this, arguments, function* (query, apiKey = config.mcp.apiKey, params) {
var _a, _b;
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) {
const graphName = (_b = (_a = this.apiKeyVerificationResult) == null ? void 0 : _a.data) == null ? void 0 : _b["FALKORDB_GRAPH_SEMANTIC"];
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}`);
}
});
}
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_zod = require("zod");
var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
var server = new import_mcp.McpServer({
name: "EE-GRAPH-MCP",
version: "1.0.0",
description: "Evolution Engineering Graph MCP Server"
});
server.tool("read-me", {}, (args, extra) => __async(null, null, function* () {
const readMe = {
provider: "EE Graph MCP Server",
version: "1.0.0",
instructions: "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. Metadata and instructions 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 full ontology model using tool get-ontology-model. Use tool query-ontology-semantics to query the ontology semantics and understand the ontology model. Use tool query-knowledge-graph to query real data stored in the knowledge graph."
};
return {
content: [
{
type: "text",
text: JSON.stringify(readMe)
}
]
};
}));
server.tool("is-api-key-valid", { apiKey: import_zod.z.string().default(config.mcp.apiKey).optional() }, (args, extra) => __async(null, null, function* () {
const startTime = Date.now();
if (args.apiKey === null || args.apiKey === void 0 || args.apiKey === "*") {
return {
content: [
{ type: "text", text: JSON.stringify({ error: "API key is required" }) }
],
isError: true
};
}
const result = yield falkorDBService.verifyApiKey(args.apiKey);
if (!result.valid) {
return {
content: [
{ type: "text", text: JSON.stringify({ error: result.message }) }
],
isError: true
};
}
const queryTime = Date.now() - startTime;
const formattedResult = {
data: `API key ${args.apiKey} is valid`,
metadata: {
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
queryTime,
provider: "EE MCP Server",
source: "EE Semantic Graphs"
}
};
return {
content: [
{
type: "text",
text: JSON.stringify(formattedResult)
}
]
};
}));
server.tool("get-ontology-metadata-and-instructions", {}, (args, extra) => __async(null, null, function* () {
const response = yield falkorDBService.getOntologyMetadata(
config.mcp.apiKey
);
const metadata = {
provider: "EE Graph MCP Server",
version: "1.0.0",
instructions: response,
capabilities: [
"get.ontology.instructions",
"get.ontology.metadata",
"get.ontology.model",
"query.ontology.semantics",
"query.knowledge.graph"
],
graphTypes: ["property", "directed"],
queryLanguages: ["cypher"]
};
return {
content: [
{
type: "text",
text: JSON.stringify(metadata)
}
]
};
}));
server.tool("get-ontology-model", { apiKey: import_zod.z.string().default(config.mcp.apiKey).optional() }, (args, extra) => __async(null, null, function* () {
if (args.apiKey === null || args.apiKey === void 0 || args.apiKey === "*") {
return {
content: [
{
type: "text",
text: JSON.stringify({ error: "API key is required" })
}
],
isError: true
};
}
try {
const startTime = Date.now();
const result = yield falkorDBService.getOntology(
args.apiKey
);
const queryTime = Date.now() - startTime;
const formattedResult = {
data: result,
metadata: {
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
queryTime,
provider: "EE MCP Server",
source: "EE Semantic Graphs"
}
};
return {
content: [
{
type: "text",
text: JSON.stringify(formattedResult)
}
],
_meta: {
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
queryTime
}
};
} catch (error) {
return {
content: [
{
type: "text",
text: JSON.stringify({ error: error.message })
}
],
_meta: {
timestamp: (/* @__PURE__ */ new Date()).toISOString()
},
isError: true
};
}
}));
server.tool("query-ontology-semantics", { query: import_zod.z.string(), apiKey: import_zod.z.string().default(config.mcp.apiKey).optional() }, (args, extra) => __async(null, null, function* () {
if (args.apiKey === null || args.apiKey === void 0 || args.apiKey === "*") {
return {
content: [
{
type: "text",
text: JSON.stringify({ error: "API key is required" })
}
],
isError: true
};
}
try {
const startTime = Date.now();
const response = yield falkorDBService.executeOntologyGraphQuery(
args.query,
args.apiKey
);
const queryTime = Date.now() - startTime;
const formattedResult = {
data: response.result,
metadata: {
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
queryTime,
provider: "EE MCP Server",
source: "EE Semantic Graphs"
}
};
return {
content: [
{
type: "text",
text: JSON.stringify(formattedResult)
}
],
_meta: {
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
queryTime
}
};
} catch (error) {
return {
content: [
{
type: "text",
text: JSON.stringify({ error: error.message })
}
],
_meta: {
timestamp: (/* @__PURE__ */ new Date()).toISOString()
},
isError: true
};
}
}));
server.tool("query-knowledge-graph", { query: import_zod.z.string(), apiKey: import_zod.z.string().default(config.mcp.apiKey).optional() }, (args, extra) => __async(null, null, function* () {
if (args.apiKey === null || args.apiKey === void 0 || args.apiKey === "*") {
return {
content: [
{
type: "text",
text: JSON.stringify({ error: "API key is required" })
}
],
isError: true
};
}
try {
const startTime = Date.now();
const response = yield falkorDBService.executeGraphQuery(
args.query,
args.apiKey
);
const queryTime = Date.now() - startTime;
const formattedResult = {
data: response.result,
metadata: {
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
queryTime,
provider: "EE MCP Server",
source: "EE Semantic Graphs"
}
};
return {
content: [
{
type: "text",
text: JSON.stringify(formattedResult)
}
],
_meta: {
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
queryTime
}
};
} catch (error) {
return {
content: [
{
type: "text",
text: JSON.stringify({ error: error.message })
}
],
_meta: {
timestamp: (/* @__PURE__ */ new Date()).toISOString()
},
isError: true
};
}
}));
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