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.

145 lines (144 loc) 6.12 kB
import { ProjectService } from "../../../services/neo4j/projectService.js"; import { BaseErrorCode, McpError, ProjectErrorCode, } from "../../../types/errors.js"; import { logger, requestContextService } from "../../../utils/index.js"; // Import requestContextService import { ResourceTemplates, ResourceURIs, toProjectResource, } from "../types.js"; /** * Register Project Resources * * This function registers resource endpoints for the Projects entity * - GET atlas://projects - List all projects * - GET atlas://projects/{projectId} - Get specific project by ID * * @param server The MCP server instance */ export function registerProjectResources(server) { // List all projects server.resource("projects-list", ResourceURIs.PROJECTS, { name: "All Projects", description: "List of all projects in the Atlas platform with pagination support", mimeType: "application/json", }, async (uri) => { const reqContext = requestContextService.createRequestContext({ operation: "listAllProjects", resourceUri: uri.href, }); try { logger.info("Listing projects", { ...reqContext, uri: uri.href }); // Parse query parameters const queryParams = new URLSearchParams(uri.search); const filters = {}; // Parse status parameter const status = queryParams.get("status"); if (status) { filters.status = String(status); } // Parse taskType parameter const taskType = queryParams.get("taskType"); if (taskType) { filters.taskType = String(taskType); } // Parse pagination parameters const page = queryParams.has("page") ? parseInt(queryParams.get("page") || "1", 10) : 1; const limit = queryParams.has("limit") ? parseInt(queryParams.get("limit") || "20", 10) : 20; // Add pagination to filters filters.page = page; filters.limit = limit; // Use ProjectService instead of direct database access const result = await ProjectService.getProjects(filters); // Convert Neo4j projects to project resources const projectResources = result.data.map(toProjectResource); // Create pagination metadata using result from service const pagination = { total: result.total, page: result.page, limit: result.limit, totalPages: result.totalPages, }; logger.info(`Found ${result.total} projects, returning page ${result.page} with ${projectResources.length} items`, { ...reqContext, totalProjects: result.total, returnedCount: projectResources.length, page: result.page, }); return { contents: [ { uri: uri.href, mimeType: "application/json", text: JSON.stringify({ projects: projectResources, pagination, }, null, 2), }, ], }; } catch (error) { logger.error("Error listing projects", error, { ...reqContext, // error is now part of the Error object passed to logger uri: uri.href, }); throw new McpError(BaseErrorCode.INTERNAL_ERROR, `Failed to list projects: ${error instanceof Error ? error.message : String(error)}`); } }); // Get project by ID server.resource("project-by-id", ResourceTemplates.PROJECT, { name: "Project by ID", description: "Retrieves a single project by its unique identifier", mimeType: "application/json", }, async (uri, params) => { const reqContext = requestContextService.createRequestContext({ operation: "getProjectById", resourceUri: uri.href, projectIdParam: params.projectId, }); try { const projectId = params.projectId; logger.info("Fetching project by ID", { ...reqContext, projectId, // Already in reqContext uri: uri.href, // Already in reqContext }); if (!projectId) { throw new McpError(BaseErrorCode.VALIDATION_ERROR, "Project ID is required"); } // Use ProjectService instead of direct database access const project = await ProjectService.getProjectById(projectId); if (!project) { throw new McpError(ProjectErrorCode.PROJECT_NOT_FOUND, `Project with ID ${projectId} not found`, { projectId }); } // Convert to resource format const projectResource = toProjectResource(project); logger.info("Retrieved project successfully", { ...reqContext, projectId: project.id, // Already in reqContext }); return { contents: [ { uri: uri.href, mimeType: "application/json", text: JSON.stringify(projectResource, null, 2), }, ], }; } catch (error) { // Handle specific error cases if (error instanceof McpError) { throw error; } logger.error("Error fetching project by ID", error, { ...reqContext, // error is now part of the Error object passed to logger parameters: params, }); throw new McpError(BaseErrorCode.INTERNAL_ERROR, `Failed to fetch project: ${error instanceof Error ? error.message : String(error)}`); } }); }