@mseep/atlas-mcp-server
Version:
A Model Context Protocol (MCP) server for ATLAS, a Neo4j-powered task management system for LLM Agents - implementing a three-tier architecture (Projects, Tasks, Knowledge) to manage complex workflows.
147 lines (126 loc) • 5.12 kB
text/typescript
import { ProjectService } from "../../../services/neo4j/projectService.js";
import { BaseErrorCode, McpError, ProjectErrorCode } from "../../../types/errors.js";
import { ResponseFormat, createToolResponse } from "../../../types/mcp.js";
import { logger } from "../../../utils/logger.js";
import { ToolContext } from "../../../utils/security.js";
import { AtlasProjectUpdateInput, AtlasProjectUpdateSchema } from "./types.js";
import { formatProjectUpdateResponse } from "./responseFormat.js";
export const atlasUpdateProject = async (
input: unknown,
context: ToolContext
) => {
let validatedInput: AtlasProjectUpdateInput | undefined;
try {
// Parse and validate the input against schema
validatedInput = AtlasProjectUpdateSchema.parse(input);
// Process according to operation mode (single or bulk)
if (validatedInput.mode === 'bulk') {
// Execute bulk update operation
logger.info("Applying updates to multiple projects", {
count: validatedInput.projects.length,
requestId: context.requestContext?.requestId
});
const results = {
success: true,
message: `Successfully updated ${validatedInput.projects.length} projects`,
updated: [] as any[],
errors: [] as any[]
};
// Process each project update sequentially to maintain data consistency
for (let i = 0; i < validatedInput.projects.length; i++) {
const projectUpdate = validatedInput.projects[i];
try {
// First check if project exists
const projectExists = await ProjectService.getProjectById(projectUpdate.id);
if (!projectExists) {
throw new McpError(
ProjectErrorCode.PROJECT_NOT_FOUND,
`Project with ID ${projectUpdate.id} not found`
);
}
// Update the project
const updatedProject = await ProjectService.updateProject(
projectUpdate.id,
projectUpdate.updates
);
results.updated.push(updatedProject);
} catch (error) {
results.success = false;
results.errors.push({
index: i,
project: projectUpdate,
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 = `Updated ${results.updated.length} of ${validatedInput.projects.length} projects with ${results.errors.length} errors`;
}
logger.info("Bulk project modification completed", {
successCount: results.updated.length,
errorCount: results.errors.length,
projectIds: results.updated.map(p => p.id),
requestId: context.requestContext?.requestId
});
// Conditionally format response
if (validatedInput.responseFormat === ResponseFormat.JSON) {
return createToolResponse(JSON.stringify(results, null, 2));
} else {
return formatProjectUpdateResponse(results);
}
} else {
// Process single project modification
const { mode, id, updates } = validatedInput;
logger.info("Modifying project attributes", {
id,
fields: Object.keys(updates),
requestId: context.requestContext?.requestId
});
// First check if project exists
const projectExists = await ProjectService.getProjectById(id);
if (!projectExists) {
throw new McpError(
ProjectErrorCode.PROJECT_NOT_FOUND,
`Project with ID ${id} not found`
);
}
// Update the project
const updatedProject = await ProjectService.updateProject(id, updates);
logger.info("Project modifications applied successfully", {
projectId: id,
requestId: context.requestContext?.requestId
});
// Conditionally format response
if (validatedInput.responseFormat === ResponseFormat.JSON) {
return createToolResponse(JSON.stringify(updatedProject, null, 2));
} else {
return formatProjectUpdateResponse(updatedProject);
}
}
} catch (error) {
// Handle specific error cases
if (error instanceof McpError) {
throw error;
}
logger.error("Failed to modify project(s)", {
error,
requestId: context.requestContext?.requestId
});
// Handle not found error specifically
if (error instanceof Error && error.message.includes('not found')) {
throw new McpError(
ProjectErrorCode.PROJECT_NOT_FOUND,
`Project not found: ${error.message}`
);
}
// Convert generic errors to properly formatted McpError
throw new McpError(
BaseErrorCode.INTERNAL_ERROR,
`Failed to modify project(s): ${error instanceof Error ? error.message : 'Unknown error'}`
);
}
};