Skip to main content
Glama

update_issue

Modify GitHub issue details including title, description, status, assignees, labels, and milestone to track project changes and maintain accurate task management.

Instructions

Update a GitHub issue

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
issueIdYes
titleNo
descriptionNo
statusNo
milestoneIdYes
assigneesNo
labelsNo

Implementation Reference

  • Main tool handler in executeToolHandler switch statement. Maps tool arguments and delegates to ProjectManagementService.updateIssue method.
    case "update_issue":
      return await this.service.updateIssue(args.issueId, {
        title: args.title,
        description: args.description,
        status: args.status,
        milestoneId: args.milestoneId,
        assignees: args.assignees,
        labels: args.labels
      });
  • Core business logic for updating GitHub issues. Maps input parameters to Issue partial, handles status conversion and milestone null handling, then delegates to GitHubIssueRepository.update.
    async updateIssue(
      issueId: string,
      updates: {
        title?: string;
        description?: string;
        status?: string;
        milestoneId?: string | null;
        assignees?: string[];
        labels?: string[];
      }
    ): Promise<Issue> {
      try {
        const data: Partial<Issue> = {};
    
        if (updates.title) data.title = updates.title;
        if (updates.description) data.description = updates.description;
        if (updates.status) {
          data.status = updates.status === 'open' ? ResourceStatus.ACTIVE : ResourceStatus.CLOSED;
        }
        if (updates.assignees) data.assignees = updates.assignees;
        if (updates.labels) data.labels = updates.labels;
    
        // Handle milestoneId explicitly
        if (updates.milestoneId === null) {
          data.milestoneId = undefined; // Remove milestone
        } else if (updates.milestoneId !== undefined) {
          data.milestoneId = updates.milestoneId;
        }
    
        return await this.issueRepo.update(issueId, data);
      } catch (error) {
        throw this.mapErrorToMCPError(error);
      }
    }
  • Zod schema definition for update_issue tool input validation (lines 166-176) and complete ToolDefinition including description and examples (380-395).
    // 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"
          }
        }
      ]
    };
  • Imports updateIssueTool from ToolSchemas and registers it in the central ToolRegistry singleton instance.
      getIssueTool,
      updateIssueTool,
      createSprintTool,
      listSprintsTool,
      getCurrentSprintTool,
      createProjectFieldTool,
      createProjectViewTool,
    
      // New project tools
      updateProjectTool,
      deleteProjectTool,
      listProjectFieldsTool,
      updateProjectFieldTool,
    
      // Project item tools
      addProjectItemTool,
      removeProjectItemTool,
      listProjectItemsTool,
    
      // Field values tools
      setFieldValueTool,
      getFieldValueTool,
    
      // View tools
      listProjectViewsTool,
      updateProjectViewTool,
    
      // Milestone tools
      updateMilestoneTool,
      deleteMilestoneTool,
    
      // Sprint tools
      updateSprintTool,
      addIssuesToSprintTool,
      removeIssuesFromSprintTool,
    
      // Label tools
      createLabelTool,
      listLabelsTool,
    
      // AI task management tools
      addFeatureTool,
      generatePRDTool,
      parsePRDTool,
      getNextTaskTool,
      analyzeTaskComplexityTool,
      expandTaskTool,
      enhancePRDTool,
      createTraceabilityMatrixTool,
    } from "./ToolSchemas.js";
    
    /**
     * Central registry of all available tools
     */
    export class ToolRegistry {
      private static _instance: ToolRegistry;
      private _tools: Map<string, ToolDefinition<any>>;
    
      private constructor() {
        this._tools = new Map();
        this.registerBuiltInTools();
      }
    
      /**
       * Get the singleton instance
       */
      public static getInstance(): ToolRegistry {
        if (!ToolRegistry._instance) {
          ToolRegistry._instance = new ToolRegistry();
        }
        return ToolRegistry._instance;
      }
    
      /**
       * Register a new tool
       */
      public registerTool<T>(tool: ToolDefinition<T>): void {
        if (this._tools.has(tool.name)) {
          process.stderr.write(`Tool '${tool.name}' is already registered and will be overwritten.\n`);
        }
        this._tools.set(tool.name, tool);
      }
    
      /**
       * Get a tool by name
       */
      public getTool<T>(name: string): ToolDefinition<T> | undefined {
        return this._tools.get(name) as ToolDefinition<T> | undefined;
      }
    
      /**
       * Get all registered tools
       */
      public getAllTools(): ToolDefinition<any>[] {
        return Array.from(this._tools.values());
      }
    
      /**
       * Convert tools to MCP format for list_tools response
       */
      public getToolsForMCP(): Array<{
        name: string;
        description: string;
        inputSchema: any;
      }> {
        return this.getAllTools().map(tool => ({
          name: tool.name,
          description: tool.description,
          inputSchema: this.convertZodToJsonSchema(tool.schema),
        }));
      }
    
      /**
       * Register all built-in tools
       */
      private registerBuiltInTools(): void {
        // Register roadmap and planning tools
        this.registerTool(createRoadmapTool);
        this.registerTool(planSprintTool);
        this.registerTool(getMilestoneMetricsTool);
        this.registerTool(getSprintMetricsTool);
        this.registerTool(getOverdueMilestonesTool);
        this.registerTool(getUpcomingMilestonesTool);
    
        // Register project tools
        this.registerTool(createProjectTool);
        this.registerTool(listProjectsTool);
        this.registerTool(getProjectTool);
        this.registerTool(updateProjectTool);
        this.registerTool(deleteProjectTool);
    
        // Register milestone tools
        this.registerTool(createMilestoneTool);
        this.registerTool(listMilestonesTool);
        this.registerTool(updateMilestoneTool);
        this.registerTool(deleteMilestoneTool);
    
        // Register issue tools
        this.registerTool(createIssueTool);
        this.registerTool(listIssuesTool);
        this.registerTool(getIssueTool);
        this.registerTool(updateIssueTool);

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