Skip to main content
Glama

update_issue

Modify GitHub issues directly by updating titles, descriptions, statuses, milestones, assignees, and labels. Streamline project management tasks and keep issue tracking in sync with project workflows.

Instructions

Update a GitHub issue

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
assigneesNo
descriptionNo
issueIdYes
labelsNo
milestoneIdYes
statusNo
titleNo

Implementation Reference

  • Zod input schema and complete ToolDefinition for the update_issue tool, including description and examples
    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" } } ] };
  • Registration of the updateIssueTool in the central ToolRegistry singleton
    this.registerTool(updateIssueTool);
  • MCP tool dispatch handler in main server that maps tool args to service call
    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 service method implementing update_issue logic, mapping parameters and calling repository
    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); } }
  • Repository layer executing GitHub GraphQL updateIssue mutation - the actual API call implementation
    async update(id: IssueId, data: Partial<Issue>): Promise<Issue> { const mutation = ` mutation($input: UpdateIssueInput!) { updateIssue(input: $input) { issue { id number title body state updatedAt assignees(first: 100) { nodes { login } } labels(first: 100) { nodes { name } } milestone { id } } } } `; const response = await this.graphql<UpdateIssueResponse>(mutation, { input: { id, title: data.title, body: data.description, state: data.status === ResourceStatus.CLOSED ? "CLOSED" : "OPEN", assigneeIds: data.assignees, labelIds: data.labels, milestoneId: data.milestoneId, }, }); return this.mapGitHubIssueToIssue(response.updateIssue.issue); }

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/kunwarVivek/mcp-github-project-manager'

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