get_overdue_milestones
Retrieve overdue milestones from GitHub projects to track delayed deadlines and manage project timelines effectively.
Instructions
Get a list of overdue milestones
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| limit | Yes | ||
| includeIssues | Yes |
Implementation Reference
- Main handler function that fetches overdue milestones, filters by due date and status, sorts by due date, limits results, and computes metrics for each.async getOverdueMilestones(limit: number = 10, includeIssues: boolean = false): Promise<MilestoneMetrics[]> { try { const milestones = await this.milestoneRepo.findAll(); const now = new Date(); const overdueMilestones = milestones.filter(milestone => { if (!milestone.dueDate) return false; const dueDate = new Date(milestone.dueDate); return now > dueDate && milestone.status !== ResourceStatus.COMPLETED && milestone.status !== ResourceStatus.CLOSED; }); overdueMilestones.sort((a, b) => { if (!a.dueDate || !b.dueDate) return 0; return new Date(a.dueDate).getTime() - new Date(b.dueDate).getTime(); }); const limitedMilestones = overdueMilestones.slice(0, limit); const milestoneMetrics = await Promise.all( limitedMilestones.map(milestone => this.getMilestoneMetrics(milestone.id, includeIssues) ) ); return milestoneMetrics; } catch (error) { throw this.mapErrorToMCPError(error); }
- Zod input schema and ToolDefinition export for get_overdue_milestones, including name, description, schema, and examples.// Schema for get_overdue_milestones tool export const getOverdueMilestonesSchema = z.object({ limit: z.number().int().positive(), includeIssues: z.boolean(), }); export type GetOverdueMilestonesArgs = z.infer<typeof getOverdueMilestonesSchema>; // Schema for get_upcoming_milestones tool export const getUpcomingMilestonesSchema = z.object({ daysAhead: z.number().int().positive(), limit: z.number().int().positive(), includeIssues: z.boolean(), }); export type GetUpcomingMilestonesArgs = z.infer<typeof getUpcomingMilestonesSchema>; // Schema for create_project tool export const createProjectSchema = z.object({ title: z.string().min(1, "Project title is required"), shortDescription: z.string().optional(), owner: z.string().min(1, "Project owner is required"), visibility: z.enum(["private", "public"]).default("private"), }); export type CreateProjectArgs = z.infer<typeof createProjectSchema>; // Schema for list_projects tool export const listProjectsSchema = z.object({ status: z.enum(["active", "closed", "all"]).default("active"), limit: z.number().int().positive().default(10).optional(), }); export type ListProjectsArgs = z.infer<typeof listProjectsSchema>; // Schema for get_project tool export const getProjectSchema = z.object({ projectId: z.string().min(1, "Project ID is required"), }); export type GetProjectArgs = z.infer<typeof getProjectSchema>; // Schema for create_milestone tool export const createMilestoneSchema = z.object({ title: z.string().min(1, "Milestone title is required"), description: z.string().min(1, "Milestone description is required"), dueDate: z.string().datetime("Due date must be a valid ISO date string").optional(), }); export type CreateMilestoneArgs = z.infer<typeof createMilestoneSchema>; // Schema for list_milestones tool export const listMilestonesSchema = z.object({ status: z.enum(["open", "closed", "all"]).default("open"), sort: z.enum(["due_date", "title", "created_at"]).default("created_at").optional(), direction: z.enum(["asc", "desc"]).default("asc").optional(), }); export type ListMilestonesArgs = z.infer<typeof listMilestonesSchema>; // Schema for create_issue tool export const createIssueSchema = z.object({ title: z.string().min(1, "Issue title is required"), description: z.string().min(1, "Issue description is required"), milestoneId: z.string().optional(), assignees: z.array(z.string()).default([]), labels: z.array(z.string()).default([]), priority: z.enum(["high", "medium", "low"]).default("medium").optional(), type: z.enum(["bug", "feature", "enhancement", "documentation"]).default("feature").optional(), }); export type CreateIssueArgs = z.infer<typeof createIssueSchema>; // Schema for list_issues tool export const listIssuesSchema = z.object({ status: z.enum(["open", "closed", "all"]).default("open"), milestone: z.string().optional(), labels: z.array(z.string()).optional(), assignee: z.string().optional(), sort: z.enum(["created", "updated", "comments"]).default("created").optional(), direction: z.enum(["asc", "desc"]).default("desc").optional(), limit: z.number().int().positive().default(30).optional(), }); export type ListIssuesArgs = z.infer<typeof listIssuesSchema>; // Schema for get_issue tool export const getIssueSchema = z.object({ issueId: z.string().min(1, "Issue ID is required"), }); export type GetIssueArgs = z.infer<typeof getIssueSchema>; // Schema for update_issue tool export const updateIssueSchema = z.object({ issueId: z.string().min(1, "Issue ID is required"), title: z.string().optional(), description: z.string().optional(), status: z.enum(["open", "closed"]).optional(), milestoneId: z.string().optional().nullable(), assignees: z.array(z.string()).optional(), labels: z.array(z.string()).optional(), }); export type UpdateIssueArgs = z.infer<typeof updateIssueSchema>; // Schema for create_issue_comment tool export const createIssueCommentSchema = z.object({ issueNumber: z.number().int().positive("Issue number must be a positive integer"), body: z.string().min(1, "Comment body is required"), }); export type CreateIssueCommentArgs = z.infer<typeof createIssueCommentSchema>; // Schema for update_issue_comment tool export const updateIssueCommentSchema = z.object({ commentId: z.number().int().positive("Comment ID must be a positive integer"), body: z.string().min(1, "Comment body is required"), }); export type UpdateIssueCommentArgs = z.infer<typeof updateIssueCommentSchema>; // Schema for delete_issue_comment tool export const deleteIssueCommentSchema = z.object({ commentId: z.number().int().positive("Comment ID must be a positive integer"), }); export type DeleteIssueCommentArgs = z.infer<typeof deleteIssueCommentSchema>; // Schema for list_issue_comments tool export const listIssueCommentsSchema = z.object({ issueNumber: z.number().int().positive("Issue number must be a positive integer"), perPage: z.number().int().positive().max(100).default(100).optional(), }); export type ListIssueCommentsArgs = z.infer<typeof listIssueCommentsSchema>; // Schema for create_draft_issue tool export const createDraftIssueSchema = z.object({ projectId: z.string().min(1, "Project ID is required"), title: z.string().min(1, "Draft issue title is required"), body: z.string().optional(), assigneeIds: z.array(z.string()).optional(), }); export type CreateDraftIssueArgs = z.infer<typeof createDraftIssueSchema>; // Schema for update_draft_issue tool export const updateDraftIssueSchema = z.object({ draftIssueId: z.string().min(1, "Draft issue ID is required"), title: z.string().optional(), body: z.string().optional(), assigneeIds: z.array(z.string()).optional(), }); export type UpdateDraftIssueArgs = z.infer<typeof updateDraftIssueSchema>; // Schema for delete_draft_issue tool export const deleteDraftIssueSchema = z.object({ draftIssueId: z.string().min(1, "Draft issue ID is required"), }); export type DeleteDraftIssueArgs = z.infer<typeof deleteDraftIssueSchema>; // Schema for create_pull_request tool export const createPullRequestSchema = z.object({ title: z.string().min(1, "Pull request title is required"), body: z.string().optional(), head: z.string().min(1, "Head branch is required"), base: z.string().min(1, "Base branch is required"), draft: z.boolean().optional(), }); export type CreatePullRequestArgs = z.infer<typeof createPullRequestSchema>; // Schema for get_pull_request tool export const getPullRequestSchema = z.object({ pullNumber: z.number().int().positive("Pull request number must be a positive integer"), }); export type GetPullRequestArgs = z.infer<typeof getPullRequestSchema>; // Schema for list_pull_requests tool export const listPullRequestsSchema = z.object({ state: z.enum(["open", "closed", "all"]).default("open").optional(), perPage: z.number().int().positive().max(100).default(30).optional(), }); export type ListPullRequestsArgs = z.infer<typeof listPullRequestsSchema>; // Schema for update_pull_request tool export const updatePullRequestSchema = z.object({ pullNumber: z.number().int().positive("Pull request number must be a positive integer"), title: z.string().optional(), body: z.string().optional(), state: z.enum(["open", "closed"]).optional(), }); export type UpdatePullRequestArgs = z.infer<typeof updatePullRequestSchema>; // Schema for merge_pull_request tool export const mergePullRequestSchema = z.object({ pullNumber: z.number().int().positive("Pull request number must be a positive integer"), commitTitle: z.string().optional(), commitMessage: z.string().optional(), mergeMethod: z.enum(["merge", "squash", "rebase"]).default("merge").optional(), }); export type MergePullRequestArgs = z.infer<typeof mergePullRequestSchema>; // Schema for list_pull_request_reviews tool export const listPullRequestReviewsSchema = z.object({ pullNumber: z.number().int().positive("Pull request number must be a positive integer"), }); export type ListPullRequestReviewsArgs = z.infer<typeof listPullRequestReviewsSchema>; // Schema for create_pull_request_review tool export const createPullRequestReviewSchema = z.object({ pullNumber: z.number().int().positive("Pull request number must be a positive integer"), body: z.string().optional(), event: z.enum(["APPROVE", "REQUEST_CHANGES", "COMMENT"]), comments: z.array(z.object({ path: z.string(), position: z.number().int().optional(), body: z.string(), })).optional(), }); export type CreatePullRequestReviewArgs = z.infer<typeof createPullRequestReviewSchema>; // Schema for create_sprint tool export const createSprintSchema = z.object({ title: z.string().min(1, "Sprint title is required"), description: z.string().min(1, "Sprint description is required"), startDate: z.string().datetime("Start date must be a valid ISO date string"), endDate: z.string().datetime("End date must be a valid ISO date string"), issueIds: z.array(z.string()).default([]), }); export type CreateSprintArgs = z.infer<typeof createSprintSchema>; // Schema for list_sprints tool export const listSprintsSchema = z.object({ status: z.enum(["planned", "active", "completed", "all"]).default("all"), }); export type ListSprintsArgs = z.infer<typeof listSprintsSchema>; // Schema for get_current_sprint tool export const getCurrentSprintSchema = z.object({ includeIssues: z.boolean().default(true), }); export type GetCurrentSprintArgs = z.infer<typeof getCurrentSprintSchema>; // Schema for create_project_field tool export const createProjectFieldSchema = z.object({ projectId: z.string().min(1, "Project ID is required"), name: z.string().min(1, "Field name is required"), type: z.enum([ "text", "number", "date", "single_select", "iteration", "milestone", "assignees", "labels" ]), options: z.array( z.object({ name: z.string().min(1), description: z.string().optional(), color: z.string().optional(), }) ).optional(), description: z.string().optional(), required: z.boolean().optional(), }); export type CreateProjectFieldArgs = z.infer<typeof createProjectFieldSchema>; // Schema for create_project_view tool export const createProjectViewSchema = z.object({ projectId: z.string().min(1, "Project ID is required"), name: z.string().min(1, "View name is required"), layout: z.enum(["board", "table", "timeline", "roadmap"]), }); export type CreateProjectViewArgs = z.infer<typeof createProjectViewSchema>; // Tool definitions with schemas, descriptions, and examples // Project tools export const createProjectTool: ToolDefinition<CreateProjectArgs> = { name: "create_project", description: "Create a new GitHub project", schema: createProjectSchema as unknown as ToolSchema<CreateProjectArgs>, examples: [ { name: "Create private project", description: "Create a new private GitHub project", args: { title: "Backend API Development", shortDescription: "Project for tracking backend API development tasks", owner: "example-owner", visibility: "private" } } ] }; export const listProjectsTool: ToolDefinition<ListProjectsArgs> = { name: "list_projects", description: "List GitHub projects", schema: listProjectsSchema as unknown as ToolSchema<ListProjectsArgs>, examples: [ { name: "List active projects", description: "List all active GitHub projects", args: { status: "active", limit: 5 } } ] }; export const getProjectTool: ToolDefinition<GetProjectArgs> = { name: "get_project", description: "Get details of a specific GitHub project", schema: getProjectSchema as unknown as ToolSchema<GetProjectArgs>, examples: [ { name: "Get project details", description: "Get details for a specific project", args: { projectId: "PVT_kwDOLhQ7gc4AOEbH" } } ] }; // Milestone tools export const createMilestoneTool: ToolDefinition<CreateMilestoneArgs> = { name: "create_milestone", description: "Create a new milestone", schema: createMilestoneSchema as unknown as ToolSchema<CreateMilestoneArgs>, examples: [ { name: "Create milestone with due date", description: "Create a milestone with title, description and due date", args: { title: "Beta Release", description: "Complete all features for beta release", dueDate: "2025-06-30T00:00:00Z" } } ] }; export const listMilestonesTool: ToolDefinition<ListMilestonesArgs> = { name: "list_milestones", description: "List milestones", schema: listMilestonesSchema as unknown as ToolSchema<ListMilestonesArgs>, examples: [ { name: "List open milestones", description: "List all open milestones sorted by due date", args: { status: "open", sort: "due_date", direction: "asc" } } ] }; // Issue tools export const createIssueTool: ToolDefinition<CreateIssueArgs> = { name: "create_issue", description: "Create a new GitHub issue", schema: createIssueSchema as unknown as ToolSchema<CreateIssueArgs>, examples: [ { name: "Create bug issue", description: "Create a bug issue with high priority", args: { title: "Fix authentication bug", description: "Users cannot log in with social media accounts", priority: "high", type: "bug", assignees: ["developer1"], labels: ["bug", "authentication"] } } ] }; export const listIssuesTool: ToolDefinition<ListIssuesArgs> = { name: "list_issues", description: "List GitHub issues", schema: listIssuesSchema as unknown as ToolSchema<ListIssuesArgs>, examples: [ { name: "List open issues for milestone", description: "List open issues assigned to a specific milestone", args: { status: "open", milestone: "1", sort: "updated", direction: "desc", limit: 10 } } ] }; export const getIssueTool: ToolDefinition<GetIssueArgs> = { name: "get_issue", description: "Get details of a specific GitHub issue", schema: getIssueSchema as unknown as ToolSchema<GetIssueArgs>, examples: [ { name: "Get issue details", description: "Get detailed information about an issue", args: { issueId: "42" } } ] }; export const updateIssueTool: ToolDefinition<UpdateIssueArgs> = { name: "update_issue", description: "Update a GitHub issue", schema: updateIssueSchema as unknown as ToolSchema<UpdateIssueArgs>, examples: [ { name: "Update issue status and milestone", description: "Close an issue and assign it to a milestone", args: { issueId: "42", status: "closed", milestoneId: "3" } } ] }; // Issue comment tools export const createIssueCommentTool: ToolDefinition<CreateIssueCommentArgs> = { name: "create_issue_comment", description: "Add a comment to a GitHub issue", schema: createIssueCommentSchema as unknown as ToolSchema<CreateIssueCommentArgs>, examples: [ { name: "Add status update comment", description: "Post a comment to update the team on progress", args: { issueNumber: 42, body: "Working on this issue now. Should have a PR ready by EOD." } } ] }; export const updateIssueCommentTool: ToolDefinition<UpdateIssueCommentArgs> = { name: "update_issue_comment", description: "Update an existing comment on a GitHub issue", schema: updateIssueCommentSchema as unknown as ToolSchema<UpdateIssueCommentArgs>, examples: [ { name: "Correct a comment", description: "Edit a previously posted comment to fix information", args: { commentId: 123456, body: "Updated: PR is ready for review at #45" } } ] }; export const deleteIssueCommentTool: ToolDefinition<DeleteIssueCommentArgs> = { name: "delete_issue_comment", description: "Delete a comment from a GitHub issue", schema: deleteIssueCommentSchema as unknown as ToolSchema<DeleteIssueCommentArgs>, examples: [ { name: "Remove outdated comment", description: "Delete a comment that is no longer relevant", args: { commentId: 123456 } } ] }; export const listIssueCommentsTool: ToolDefinition<ListIssueCommentsArgs> = { name: "list_issue_comments", description: "List all comments on a GitHub issue", schema: listIssueCommentsSchema as unknown as ToolSchema<ListIssueCommentsArgs>, examples: [ { name: "Get all comments", description: "Retrieve all comments for an issue", args: { issueNumber: 42 } }, { name: "Get recent comments", description: "Retrieve the 20 most recent comments", args: { issueNumber: 42, perPage: 20 } } ] }; // Draft issue tools export const createDraftIssueTool: ToolDefinition<CreateDraftIssueArgs> = { name: "create_draft_issue", description: "Create a draft issue in a GitHub project. Draft issues are native to Projects v2 and don't require creating a repository issue first.", schema: createDraftIssueSchema as unknown as ToolSchema<CreateDraftIssueArgs>, examples: [ { name: "Create draft task", description: "Create a draft issue for brainstorming without committing to the repository", args: { projectId: "PVT_kwDOLhQ7gc4AOEbH", title: "Explore new authentication options", body: "Research OAuth providers and compare features" } } ] }; export const updateDraftIssueTool: ToolDefinition<UpdateDraftIssueArgs> = { name: "update_draft_issue", description: "Update an existing draft issue in a GitHub project", schema: updateDraftIssueSchema as unknown as ToolSchema<UpdateDraftIssueArgs>, examples: [ { name: "Update draft details", description: "Refine a draft issue with more information", args: { draftIssueId: "DI_kwDOLhQ7gc4AABB", title: "Implement OAuth 2.0 authentication", body: "Use Auth0 as the provider. See research doc for details." } } ] }; export const deleteDraftIssueTool: ToolDefinition<DeleteDraftIssueArgs> = { name: "delete_draft_issue", description: "Delete a draft issue from a GitHub project", schema: deleteDraftIssueSchema as unknown as ToolSchema<DeleteDraftIssueArgs>, examples: [ { name: "Remove draft", description: "Delete a draft issue that's no longer needed", args: { draftIssueId: "DI_kwDOLhQ7gc4AABB" } } ] }; // Pull Request tools export const createPullRequestTool: ToolDefinition<CreatePullRequestArgs> = { name: "create_pull_request", description: "Create a new pull request in a GitHub repository", schema: createPullRequestSchema as unknown as ToolSchema<CreatePullRequestArgs>, examples: [ { name: "Create feature PR", description: "Create a pull request for a new feature", args: { title: "Add user authentication", body: "Implements OAuth 2.0 authentication with Auth0", head: "feature/auth", base: "main" } } ] }; export const getPullRequestTool: ToolDefinition<GetPullRequestArgs> = { name: "get_pull_request", description: "Get details of a specific pull request", schema: getPullRequestSchema as unknown as ToolSchema<GetPullRequestArgs>, examples: [ { name: "Get PR details", description: "Retrieve information about PR #42", args: { pullNumber: 42 } } ] }; export const listPullRequestsTool: ToolDefinition<ListPullRequestsArgs> = { name: "list_pull_requests", description: "List pull requests in a GitHub repository", schema: listPullRequestsSchema as unknown as ToolSchema<ListPullRequestsArgs>, examples: [ { name: "List open PRs", description: "Get all open pull requests", args: { state: "open" } } ] }; export const updatePullRequestTool: ToolDefinition<UpdatePullRequestArgs> = { name: "update_pull_request", description: "Update a pull request's title, body, or state", schema: updatePullRequestSchema as unknown as ToolSchema<UpdatePullRequestArgs>, examples: [ { name: "Update PR title", description: "Update the title of a pull request", args: { pullNumber: 42, title: "feat: Add OAuth 2.0 authentication" } } ] }; export const mergePullRequestTool: ToolDefinition<MergePullRequestArgs> = { name: "merge_pull_request", description: "Merge a pull request using merge, squash, or rebase", schema: mergePullRequestSchema as unknown as ToolSchema<MergePullRequestArgs>, examples: [ { name: "Squash and merge", description: "Merge a PR with squash strategy", args: { pullNumber: 42, mergeMethod: "squash", commitTitle: "feat: Add authentication" } } ] }; export const listPullRequestReviewsTool: ToolDefinition<ListPullRequestReviewsArgs> = { name: "list_pull_request_reviews", description: "List all reviews on a pull request", schema: listPullRequestReviewsSchema as unknown as ToolSchema<ListPullRequestReviewsArgs>, examples: [ { name: "Get PR reviews", description: "List all reviews for PR #42", args: { pullNumber: 42 } } ] }; export const createPullRequestReviewTool: ToolDefinition<CreatePullRequestReviewArgs> = { name: "create_pull_request_review", description: "Create a review on a pull request (approve, request changes, or comment)", schema: createPullRequestReviewSchema as unknown as ToolSchema<CreatePullRequestReviewArgs>, examples: [ { name: "Approve PR", description: "Approve a pull request", args: { pullNumber: 42, event: "APPROVE", body: "LGTM! Great work on the authentication implementation." } }, { name: "Request changes", description: "Request changes with inline comments", args: { pullNumber: 42, event: "REQUEST_CHANGES", body: "Please address the comments below", comments: [ { path: "src/auth.ts", position: 15, body: "Consider using bcrypt for password hashing" } ] } } ] }; // Sprint tools export const createSprintTool: ToolDefinition<CreateSprintArgs> = { name: "create_sprint", description: "Create a new development sprint", schema: createSprintSchema as unknown as ToolSchema<CreateSprintArgs>, examples: [ { name: "Create two-week sprint", description: "Create a two-week sprint with initial issues", args: { title: "Sprint 1: User Authentication", description: "First sprint focused on user authentication features", startDate: "2025-06-01T00:00:00Z", endDate: "2025-06-15T00:00:00Z", issueIds: ["101", "102", "103"] } } ] }; export const listSprintsTool: ToolDefinition<ListSprintsArgs> = { name: "list_sprints", description: "List all sprints", schema: listSprintsSchema as unknown as ToolSchema<ListSprintsArgs>, examples: [ { name: "List active sprints", description: "List all currently active sprints", args: { status: "active" } } ] }; export const getCurrentSprintTool: ToolDefinition<GetCurrentSprintArgs> = { name: "get_current_sprint", description: "Get the currently active sprint", schema: getCurrentSprintSchema as unknown as ToolSchema<GetCurrentSprintArgs>, examples: [ { name: "Get current sprint with issues", description: "Get details of the current sprint including assigned issues", args: { includeIssues: true } } ] }; // Project field tools export const createProjectFieldTool: ToolDefinition<CreateProjectFieldArgs> = { name: "create_project_field", description: "Create a custom field for a GitHub project", schema: createProjectFieldSchema as unknown as ToolSchema<CreateProjectFieldArgs>, examples: [ { name: "Create status field", description: "Create a status dropdown field for a project", args: { projectId: "PVT_kwDOLhQ7gc4AOEbH", name: "Status", type: "single_select", options: [ { name: "To Do", color: "red" }, { name: "In Progress", color: "yellow" }, { name: "Done", color: "green" } ], description: "Current status of the task", required: true } } ] }; // Project view tools export const createProjectViewTool: ToolDefinition<CreateProjectViewArgs> = { name: "create_project_view", description: "Create a new view for a GitHub project", schema: createProjectViewSchema as unknown as ToolSchema<CreateProjectViewArgs>, examples: [ { name: "Create kanban board view", description: "Create a board view for a project", args: { projectId: "PVT_kwDOLhQ7gc4AOEbH", name: "Development Board", layout: "board" } } ] }; // Tool definitions with schemas, descriptions, and examples export const createRoadmapTool: ToolDefinition<CreateRoadmapArgs> = { name: "create_roadmap", description: "Create a project roadmap with milestones and tasks", schema: createRoadmapSchema as unknown as ToolSchema<CreateRoadmapArgs>, examples: [ { name: "Simple project roadmap", description: "Create a basic project with two milestones", args: { project: { title: "New Mobile App", shortDescription: "Develop a new mobile application for our users", visibility: "private", }, milestones: [ { milestone: { title: "Design Phase", description: "Complete all design work for the mobile app", dueDate: "2025-05-01T00:00:00Z", }, issues: [ { title: "Create wireframes", description: "Create wireframes for all app screens", priority: "high", type: "feature", assignees: ["designer1"], labels: ["design", "ui"], }, { title: "Design system", description: "Develop a consistent design system", priority: "medium", type: "feature", assignees: [], labels: ["design"], }, ], }, { milestone: { title: "Development Phase", description: "Implement the designed features", dueDate: "2025-06-15T00:00:00Z", }, issues: [ { title: "User authentication", description: "Implement user login and registration", priority: "high", type: "feature", assignees: ["developer1"], labels: ["auth", "backend"], }, ], }, ], }, }, ], }; export const planSprintTool: ToolDefinition<PlanSprintArgs> = { name: "plan_sprint", description: "Plan a new sprint with selected issues", schema: planSprintSchema as unknown as ToolSchema<PlanSprintArgs>, examples: [ { name: "Two-week sprint", description: "Plan a two-week sprint with specific issues", args: { sprint: { title: "Sprint 1: Authentication and Onboarding", startDate: "2025-05-01T00:00:00Z", endDate: "2025-05-15T00:00:00Z", goals: [ "Complete user authentication flow", "Implement onboarding screens", ], }, issueIds: ["1", "2", "3", "5"], }, }, ], }; export const getMilestoneMetricsTool: ToolDefinition<GetMilestoneMetricsArgs> = { name: "get_milestone_metrics", description: "Get progress metrics for a specific milestone", schema: getMilestoneMetricsSchema as unknown as ToolSchema<GetMilestoneMetricsArgs>, examples: [ { name: "Get milestone progress", description: "Get progress metrics for milestone #2", args: { milestoneId: "2", includeIssues: true, }, }, ], }; export const getSprintMetricsTool: ToolDefinition<GetSprintMetricsArgs> = { name: "get_sprint_metrics", description: "Get progress metrics for a specific sprint", schema: getSprintMetricsSchema as unknown as ToolSchema<GetSprintMetricsArgs>, examples: [ { name: "Get sprint progress", description: "Get progress metrics for sprint 'sprint_1'", args: { sprintId: "sprint_1", includeIssues: true, }, }, ], }; export const getOverdueMilestonesTool: ToolDefinition<GetOverdueMilestonesArgs> = { name: "get_overdue_milestones", description: "Get a list of overdue milestones", schema: getOverdueMilestonesSchema as unknown as ToolSchema<GetOverdueMilestonesArgs>, examples: [ { name: "List overdue milestones", description: "Get the top 5 overdue milestones", args: { limit: 5, includeIssues: false, }, }, ], };
- src/infrastructure/tools/ToolRegistry.ts:189-189 (registration)Registration of getOverdueMilestonesTool in the central ToolRegistry singleton during built-in tools initialization.this.registerTool(getOverdueMilestonesTool);
- src/index.ts:252-253 (handler)MCP server switch case dispatcher that routes tool calls to ProjectManagementService.getOverdueMilestones.case "get_overdue_milestones": return await this.service.getOverdueMilestones(args.limit, args.includeIssues);
- Supporting getMilestoneMetrics function called by getOverdueMilestones to compute per-milestone statistics including issues, completion %, overdue status.async getMilestoneMetrics(id: string, includeIssues: boolean = false): Promise<MilestoneMetrics> { try { const milestone = await this.milestoneRepo.findById(id); if (!milestone) { throw new ResourceNotFoundError(ResourceType.MILESTONE, id); } const allIssues = await this.issueRepo.findAll(); const issues = allIssues.filter(issue => issue.milestoneId === milestone.id); const totalIssues = issues.length; const closedIssues = issues.filter( issue => issue.status === ResourceStatus.CLOSED || issue.status === ResourceStatus.COMPLETED ).length; const openIssues = totalIssues - closedIssues; const completionPercentage = totalIssues > 0 ? Math.round((closedIssues / totalIssues) * 100) : 0; const now = new Date(); let isOverdue = false; let daysRemaining: number | undefined = undefined; if (milestone.dueDate) { const dueDate = new Date(milestone.dueDate); isOverdue = now > dueDate; daysRemaining = Math.ceil((dueDate.getTime() - now.getTime()) / (1000 * 60 * 60 * 24)); } return { id: milestone.id, title: milestone.title, dueDate: milestone.dueDate, openIssues, closedIssues, totalIssues, completionPercentage, status: milestone.status, issues: includeIssues ? issues : undefined, isOverdue, daysRemaining: daysRemaining && daysRemaining > 0 ? daysRemaining : undefined }; } catch (error) { throw this.mapErrorToMCPError(error); }