Skip to main content
Glama
handlers.ts4.7 kB
/** * Project and board tool handlers. * @module tools/projects/handlers */ import type { z } from 'zod'; import * as projects from '../../jira/endpoints/projects.js'; import * as boards from '../../jira/endpoints/boards.js'; import { simplifyProject } from '../../formatters/toon.js'; import { createSuccessResult, createPaginatedResult, } from '../../formatters/response.js'; import { formatErrorForMcp } from '../../utils/errors.js'; import { createLogger } from '../../utils/logger.js'; import type { ToolResult } from '../../types/mcp.js'; import type { listProjectsSchema, getProjectSchema, getProjectStatusesSchema, listBoardsSchema, getBoardSchema, getBoardConfigSchema, } from './schemas.js'; const logger = createLogger('project-handlers'); /** * Handles listing projects. */ export async function handleListProjects( args: z.infer<typeof listProjectsSchema> ): Promise<ToolResult> { try { logger.debug('Listing projects'); const result = await projects.listProjects(args.startAt, args.maxResults); const simplified = result.values.map(simplifyProject); return createPaginatedResult( simplified, result.total, result.startAt, 'projects' ); } catch (error) { logger.error('Failed to list projects', error as Error); return formatErrorForMcp(error); } } /** * Handles getting a project. */ export async function handleGetProject( args: z.infer<typeof getProjectSchema> ): Promise<ToolResult> { try { logger.debug('Getting project', { projectKey: args.projectKey }); const project = await projects.getProject(args.projectKey); const simplified = simplifyProject(project); return createSuccessResult(simplified); } catch (error) { logger.error('Failed to get project', error as Error); return formatErrorForMcp(error); } } /** * Handles getting project statuses. */ export async function handleGetProjectStatuses( args: z.infer<typeof getProjectStatusesSchema> ): Promise<ToolResult> { try { logger.debug('Getting project statuses', { projectKey: args.projectKey }); const statuses = await projects.getProjectStatuses(args.projectKey); const simplified = statuses.map((s) => ({ issueType: s.issueType.name, statuses: s.statuses.map((st) => ({ id: st.id, name: st.name, category: st.statusCategory?.name, })), })); return createSuccessResult({ projectKey: args.projectKey, statusesByType: simplified, }); } catch (error) { logger.error('Failed to get project statuses', error as Error); return formatErrorForMcp(error); } } /** * Handles listing boards. */ export async function handleListBoards( args: z.infer<typeof listBoardsSchema> ): Promise<ToolResult> { try { logger.debug('Listing boards', { projectKey: args.projectKey }); const result = await boards.listBoards( args.projectKey, args.type, 0, args.maxResults ); const simplified = result.values.map((b) => ({ id: b.id, name: b.name, type: b.type, project: b.location?.projectKey, })); return createPaginatedResult( simplified, result.total, result.startAt, 'boards' ); } catch (error) { logger.error('Failed to list boards', error as Error); return formatErrorForMcp(error); } } /** * Handles getting a board. */ export async function handleGetBoard( args: z.infer<typeof getBoardSchema> ): Promise<ToolResult> { try { logger.debug('Getting board', { boardId: args.boardId }); const board = await boards.getBoard(args.boardId); return createSuccessResult({ id: board.id, name: board.name, type: board.type, project: board.location?.projectKey, }); } catch (error) { logger.error('Failed to get board', error as Error); return formatErrorForMcp(error); } } /** * Handles getting board configuration. */ export async function handleGetBoardConfig( args: z.infer<typeof getBoardConfigSchema> ): Promise<ToolResult> { try { logger.debug('Getting board configuration', { boardId: args.boardId }); const config = await boards.getBoardConfiguration(args.boardId); const simplified = { id: config.id, name: config.name, type: config.type, columns: config.columnConfig.columns.map((c) => ({ name: c.name, statusCount: c.statuses.length, })), estimation: config.estimation?.type, }; return createSuccessResult(simplified); } catch (error) { logger.error('Failed to get board configuration', error as Error); return formatErrorForMcp(error); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/icy-r/jira-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server