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.

168 lines (167 loc) 8.51 kB
import { ProjectService } from "../../../services/neo4j/projectService.js"; import { ProjectDependencyType } from "../../../services/neo4j/types.js"; // Import the enum import { BaseErrorCode, McpError, ProjectErrorCode, } from "../../../types/errors.js"; import { ResponseFormat, createToolResponse } from "../../../types/mcp.js"; import { logger, requestContextService } from "../../../utils/index.js"; // Import requestContextService import { AtlasProjectCreateSchema } from "./types.js"; import { formatProjectCreateResponse } from "./responseFormat.js"; export const atlasCreateProject = async (input, context) => { let validatedInput; const reqContext = context.requestContext ?? requestContextService.createRequestContext({ toolName: "atlasCreateProject", }); try { // Parse and validate input against schema validatedInput = AtlasProjectCreateSchema.parse(input); // Handle single vs bulk project creation based on mode if (validatedInput.mode === "bulk") { // Execute bulk creation operation logger.info("Initializing multiple projects", { ...reqContext, count: validatedInput.projects.length, }); const results = { success: true, message: `Successfully created ${validatedInput.projects.length} projects`, created: [], errors: [], }; // Process each project sequentially to maintain consistency for (let i = 0; i < validatedInput.projects.length; i++) { const projectData = validatedInput.projects[i]; try { const createdProject = await ProjectService.createProject({ name: projectData.name, description: projectData.description, status: projectData.status || "active", urls: projectData.urls || [], completionRequirements: projectData.completionRequirements, outputFormat: projectData.outputFormat, taskType: projectData.taskType, id: projectData.id, // Use client-provided ID if available }); results.created.push(createdProject); // Create dependency relationships if specified if (projectData.dependencies && projectData.dependencies.length > 0) { for (const dependencyId of projectData.dependencies) { try { await ProjectService.addProjectDependency(createdProject.id, dependencyId, ProjectDependencyType.REQUIRES, // Use enum member "Dependency created during project creation"); } catch (error) { const depErrorContext = requestContextService.createRequestContext({ ...reqContext, originalErrorMessage: error instanceof Error ? error.message : String(error), originalErrorStack: error instanceof Error ? error.stack : undefined, projectId: createdProject.id, dependencyIdAttempted: dependencyId, }); logger.warning(`Failed to create dependency for project ${createdProject.id} to ${dependencyId}`, depErrorContext); } } } } catch (error) { results.success = false; results.errors.push({ index: i, project: projectData, error: { code: error instanceof McpError ? error.code : BaseErrorCode.INTERNAL_ERROR, message: error instanceof Error ? error.message : "Unknown error", details: error instanceof McpError ? error.details : undefined, }, }); } } if (results.errors.length > 0) { results.message = `Created ${results.created.length} of ${validatedInput.projects.length} projects with ${results.errors.length} errors`; } logger.info("Bulk project initialization completed", { ...reqContext, successCount: results.created.length, errorCount: results.errors.length, projectIds: results.created.map((p) => p.id), }); // Conditionally format response if (validatedInput.responseFormat === ResponseFormat.JSON) { return createToolResponse(JSON.stringify(results, null, 2)); } else { return formatProjectCreateResponse(results); } } else { // Process single project creation const { mode, id, name, description, status, urls, completionRequirements, dependencies, outputFormat, taskType, } = validatedInput; logger.info("Initializing new project", { ...reqContext, name, status, }); const project = await ProjectService.createProject({ id, // Use client-provided ID if available name, description, status: status || "active", urls: urls || [], completionRequirements, outputFormat, taskType, }); // Create dependency relationships if specified if (dependencies && dependencies.length > 0) { for (const dependencyId of dependencies) { try { await ProjectService.addProjectDependency(project.id, dependencyId, ProjectDependencyType.REQUIRES, // Use enum member "Dependency created during project creation"); } catch (error) { const depErrorContext = requestContextService.createRequestContext({ ...reqContext, originalErrorMessage: error instanceof Error ? error.message : String(error), originalErrorStack: error instanceof Error ? error.stack : undefined, projectId: project.id, dependencyIdAttempted: dependencyId, }); logger.warning(`Failed to create dependency for project ${project.id} to ${dependencyId}`, depErrorContext); } } } logger.info("Project initialized successfully", { ...reqContext, projectId: project.id, }); // Conditionally format response if (validatedInput.responseFormat === ResponseFormat.JSON) { return createToolResponse(JSON.stringify(project, null, 2)); } else { return formatProjectCreateResponse(project); } } } catch (error) { // Handle specific error cases if (error instanceof McpError) { throw error; } logger.error("Failed to initialize project(s)", error, { ...reqContext, inputReceived: validatedInput ?? input, // Log validated or raw input }); // Handle duplicate name error specifically if (error instanceof Error && error.message.includes("duplicate")) { throw new McpError(ProjectErrorCode.DUPLICATE_NAME, `A project with this name already exists`, { name: validatedInput?.mode === "single" ? validatedInput?.name : validatedInput?.projects?.[0]?.name, }); } // Convert other errors to McpError throw new McpError(BaseErrorCode.INTERNAL_ERROR, `Error creating project(s): ${error instanceof Error ? error.message : "Unknown error"}`); } };