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())
    });
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden but only states the action without behavioral details. It doesn't disclose if this is a read-only or mutation operation, what permissions are needed, how it handles errors, or what the output looks like. For a tool that likely creates or modifies sprints, this is a significant gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence with no wasted words, making it easy to scan. It's appropriately sized for the tool's apparent complexity, though this conciseness comes at the cost of detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no annotations, 0% schema coverage, no output schema, and a likely mutation operation (planning/creating sprints), the description is incomplete. It lacks details on behavior, parameters, and outcomes, making it inadequate for safe and effective use by an AI agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate but adds no parameter details. It mentions 'selected issues' which hints at 'issueIds', but doesn't explain the 'sprint' object's fields (title, dates, goals) or their formats. With 2 parameters and nested objects, this leaves critical semantics undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Plan a new sprint with selected issues' clearly states the action (plan) and resource (sprint), but it's vague about what 'plan' entails compared to sibling tools like 'create_sprint'. It doesn't specify whether this creates the sprint or just prepares it, leaving ambiguity in differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives like 'create_sprint' or 'add_issues_to_sprint'. The description implies usage for new sprints with issues, but it doesn't clarify prerequisites, exclusions, or specific contexts, offering minimal direction.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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