Skip to main content
Glama

plan_sprint

Plan a new sprint by selecting GitHub issues and defining sprint details including title, dates, and goals to organize project work.

Instructions

Plan a new sprint with selected issues

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
sprintYes
issueIdsYes

Implementation Reference

  • The main handler function for the 'plan_sprint' tool. Validates input, creates a sprint using GitHubSprintRepository, associates provided issue IDs by updating issues with the sprint ID as milestoneId, and handles errors.
    async planSprint(data: {
      sprint: CreateSprint;
      issueIds: number[];
    }): Promise<Sprint> {
      try {
        // Validate input with Zod schema
        const validatedData = PlanSprintSchema.parse(data);
    
        const stringIssueIds = validatedData.issueIds.map(id => id.toString());
    
        // Create sprint with proper error handling
        const sprint = await this.sprintRepo.create({
          ...validatedData.sprint,
          issues: stringIssueIds,
          status: validatedData.sprint.status || ResourceStatus.PLANNED
        });
    
        // Create relationship between issues and sprint
        if (stringIssueIds.length > 0) {
          try {
            await Promise.all(
              stringIssueIds.map(async (issueId) => {
                try {
                  await this.issueRepo.update(issueId, { milestoneId: sprint.id });
                } catch (error) {
                  process.stderr.write(`Failed to associate issue ${issueId} with sprint: ${error}`);
                  throw this.mapErrorToMCPError(error);
                }
              })
            );
          } catch (error) {
            throw this.mapErrorToMCPError(error);
          }
        }
    
        return sprint;
      } catch (error) {
        if (error instanceof z.ZodError) {
          throw new ValidationError(`Invalid sprint data: ${error.message}`);
        }
    
        throw this.mapErrorToMCPError(error);
      }
    }
  • Zod schema definition for plan_sprint tool inputs and the complete ToolDefinition including name, description, schema, and examples.
    // Schema for plan_sprint tool
    export const planSprintSchema = z.object({
      sprint: z.object({
        title: z.string().min(1, "Sprint title 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"),
        goals: z.array(z.string()),
      }),
      issueIds: z.array(z.string()),
    });
    
    export type PlanSprintArgs = z.infer<typeof planSprintSchema>;
    
    // Schema for get_milestone_metrics tool
    export const getMilestoneMetricsSchema = z.object({
      milestoneId: z.string().min(1, "Milestone ID is required"),
      includeIssues: z.boolean(),
    });
    
    export type GetMilestoneMetricsArgs = z.infer<typeof getMilestoneMetricsSchema>;
    
    // Schema for get_sprint_metrics tool
    export const getSprintMetricsSchema = z.object({
      sprintId: z.string().min(1, "Sprint ID is required"),
      includeIssues: z.boolean(),
    });
    
    export type GetSprintMetricsArgs = z.infer<typeof getSprintMetricsSchema>;
    
    // 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_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"
          }
        }
      ]
    };
    
    // 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"],
          },
        },
      ],
    };
  • Registration of the planSprintTool in the ToolRegistry's registerBuiltInTools method.
    this.registerTool(planSprintTool);
  • Dispatch handler in executeToolHandler switch statement that routes 'plan_sprint' tool calls to ProjectManagementService.planSprint method.
    case "plan_sprint":
      return await this.service.planSprint(args);
  • Internal validation schema used within the planSprint handler for input validation.
    const PlanSprintSchema = z.object({
      sprint: z.object({
        title: z.string().min(1, "Sprint title is required"),
        description: z.string(),
        startDate: z.string().refine(val => !isNaN(Date.parse(val)), {
          message: "Start date must be a valid date string"
        }),
        endDate: z.string().refine(val => !isNaN(Date.parse(val)), {
          message: "End date must be a valid date string"
        }),
        status: z.nativeEnum(ResourceStatus).optional(),
        issues: z.array(z.string()).optional()
      }),
      issueIds: z.array(z.number())
    });

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/HarshKumarSharma/MCP'

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