UNPKG

atlas-mcp-server

Version:

ATLAS (Adaptive Task & Logic Automation System): An MCP server enabling LLM agents to manage projects, tasks, and knowledge via a Neo4j-backed, three-tier architecture. Facilitates complex workflow automation and project management through LLM Agents.

132 lines (131 loc) 6.2 kB
import { createToolResponse } from "../../../types/mcp.js"; // Import the new response creator /** * Formatter for single knowledge item addition responses */ export class SingleKnowledgeFormatter { format(data) { // Extract knowledge properties from Neo4j structure or direct data const knowledgeData = data.properties || data; const { id, projectId, domain, createdAt, text, tags, citations, updatedAt, } = knowledgeData; // Create a summary section const summary = `Knowledge Item Added Successfully\n\n` + `ID: ${id || "Unknown ID"}\n` + `Project ID: ${projectId || "Unknown Project"}\n` + `Domain: ${domain || "Uncategorized"}\n` + `Created: ${createdAt ? new Date(createdAt).toLocaleString() : "Unknown Date"}\n`; // Create a comprehensive details section const fieldLabels = { id: "ID", projectId: "Project ID", text: "Content", tags: "Tags", domain: "Domain", citations: "Citations", createdAt: "Created At", updatedAt: "Updated At", // Neo4j specific fields are generally not for direct user display unless needed properties: "Raw Properties", identity: "Neo4j Identity", labels: "Neo4j Labels", elementId: "Neo4j Element ID", }; let details = `Knowledge Item Details\n\n`; // Build details as key-value pairs for relevant fields Object.keys(fieldLabels).forEach((key) => { if (knowledgeData[key] !== undefined && ["properties", "identity", "labels", "elementId"].indexOf(key) === -1) { // Exclude raw Neo4j fields from default display let value = knowledgeData[key]; if (Array.isArray(value)) { value = value.length > 0 ? value.join(", ") : "None"; } else if (typeof value === "string" && (key === "createdAt" || key === "updatedAt")) { try { value = new Date(value).toLocaleString(); } catch (e) { /* Keep original if parsing fails */ } } if (key === "text" && typeof value === "string" && value.length > 100) { value = value.substring(0, 100) + "... (truncated)"; } details += `${fieldLabels[key]}: ${value}\n`; } }); return `${summary}\n${details}`; } } /** * Formatter for bulk knowledge addition responses */ export class BulkKnowledgeFormatter { format(data) { const { success, message, created, errors } = data; const summary = `${success && errors.length === 0 ? "Knowledge Items Added Successfully" : "Knowledge Addition Completed"}\n\n` + `Status: ${success && errors.length === 0 ? "✅ Success" : errors.length > 0 ? "⚠️ Partial Success / Errors" : "✅ Success (No items or no errors)"}\n` + `Summary: ${message}\n` + `Added: ${created.length} item(s)\n` + `Errors: ${errors.length} error(s)\n`; let createdSection = ""; if (created.length > 0) { createdSection = `\n--- Added Knowledge Items (${created.length}) ---\n\n`; createdSection += created .map((item, index) => { const itemData = item.properties || item; return (`${index + 1}. ID: ${itemData.id || "N/A"}\n` + ` Project ID: ${itemData.projectId || "N/A"}\n` + ` Domain: ${itemData.domain || "N/A"}\n` + ` Tags: ${itemData.tags ? itemData.tags.join(", ") : "None"}\n` + ` Created: ${itemData.createdAt ? new Date(itemData.createdAt).toLocaleString() : "N/A"}`); }) .join("\n\n"); } let errorsSection = ""; if (errors.length > 0) { errorsSection = `\n--- Errors Encountered (${errors.length}) ---\n\n`; errorsSection += errors .map((errorDetail, index) => { const itemInput = errorDetail.knowledge; return (`${index + 1}. Error for item (Index: ${errorDetail.index})\n` + ` Input Project ID: ${itemInput?.projectId || "N/A"}\n` + ` Input Domain: ${itemInput?.domain || "N/A"}\n` + ` Error Code: ${errorDetail.error.code}\n` + ` Message: ${errorDetail.error.message}` + (errorDetail.error.details ? `\n Details: ${JSON.stringify(errorDetail.error.details)}` : "")); }) .join("\n\n"); } return `${summary}${createdSection}${errorsSection}`.trim(); } } /** * Create a formatted, human-readable response for the atlas_knowledge_add tool * * @param data The raw knowledge addition response data (can be SingleKnowledgeResponse or BulkKnowledgeResponse) * @param isError Whether this response represents an error condition (primarily for single responses if not inherent in data) * @returns Formatted MCP tool response with appropriate structure */ export function formatKnowledgeAddResponse(data, isError = false) { const isBulkResponse = data.hasOwnProperty("success") && data.hasOwnProperty("created") && data.hasOwnProperty("errors"); let formattedText; let finalIsError; if (isBulkResponse) { const formatter = new BulkKnowledgeFormatter(); formattedText = formatter.format(data); finalIsError = !data.success || data.errors.length > 0; } else { const formatter = new SingleKnowledgeFormatter(); formattedText = formatter.format(data); finalIsError = isError; // For single responses, rely on the passed isError or enhance if data has success field } return createToolResponse(formattedText, finalIsError); }