Skip to main content
Glama

Redmine MCP Server

by yonaka15
projects.ts4 kB
import type { RedmineApiResponse, RedmineProject, RedmineIssue } from "../lib/types/index.js"; /** * Convert project status to string */ function formatStatus(status: number): string { switch (status) { case 1: return "active"; case 5: return "archived"; case 9: return "closed"; default: return "unknown"; } } /** * Format a single project */ export function formatProject(project: RedmineProject): string { return `<project> <id>${project.id}</id> <name>${project.name}</name> <identifier>${project.identifier}</identifier> <status>${formatStatus(project.status)}</status> <is_public>${project.is_public ? "yes" : "no"}</is_public> ${project.parent ? `<parent>${project.parent.name}</parent>` : ''} <created_on>${project.created_on}</created_on> ${project.homepage ? `<homepage>${project.homepage}</homepage>` : ''} ${project.description ? `<description>${project.description}</description>` : ''} ${project.enabled_modules?.length ? ` <enabled_modules> ${project.enabled_modules.map(module => `<module>${module}</module>`).join('\n ')} </enabled_modules>` : ''} ${project.trackers?.length ? ` <trackers> ${project.trackers.map(tracker => `<tracker>${tracker.name}</tracker>`).join('\n ')} </trackers>` : ''} ${project.issue_categories?.length ? ` <categories> ${project.issue_categories.map(category => `<category>${category.name}</category>`).join('\n ')} </categories>` : ''} ${project.time_entry_activities?.length ? ` <time_entry_activities> ${project.time_entry_activities.map(activity => `<activity${activity.is_default ? ' default="true"' : ''}${!activity.active ? ' active="false"' : ''}>${activity.name}</activity>` ).join('\n ')} </time_entry_activities>` : ''} ${project.custom_fields?.length ? ` <custom_fields> ${project.custom_fields.map(field => ` <field> <name>${field.name}</name> <value>${Array.isArray(field.value) ? field.value.join(", ") : field.value}</value> </field>`).join('')} </custom_fields>` : ''} </project>`; } /** * Format list of projects */ export function formatProjects(response: RedmineApiResponse<RedmineProject>): string { if (!Array.isArray(response.projects) || response.projects.length === 0) { return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<projects />"; } const projects = response.projects.map(formatProject).join('\n'); return `<?xml version="1.0" encoding="UTF-8"?> <projects total_count="${response.total_count}" offset="${response.offset}" limit="${response.limit}"> ${projects} </projects>`; } /** * Format project create/update result */ export function formatProjectResult(project: RedmineProject, action: "created" | "updated"): string { return `<?xml version="1.0" encoding="UTF-8"?> <response> <message>Project "${project.name}" was successfully ${action}.</message> ${formatProject(project)} </response>`; } /** * Format project deletion result */ export function formatProjectDeleted(id: string | number): string { return `<?xml version="1.0" encoding="UTF-8"?> <response> <message>Project "${id}" was successfully deleted.</message> </response>`; } /** * Format project archive status change result */ export function formatProjectArchiveStatus(id: string | number, archived: boolean): string { return `<?xml version="1.0" encoding="UTF-8"?> <response> <message>Project "${id}" was successfully ${archived ? "archived" : "unarchived"}.</message> </response>`; } /** * Format allowed statuses for an issue */ export function formatAllowedStatuses(statuses: NonNullable<RedmineIssue['allowed_statuses']> ): string { if (!statuses || statuses.length === 0) { return "No allowed statuses found or provided."; } const formattedStatuses = statuses.map(status => `- ${status.name} (ID: ${status.id}${status.is_closed ? ", Closed" : ""})` ).join("\n"); return `Available Issue Statuses:\n${formattedStatuses}`; }

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/yonaka15/mcp-server-redmine'

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