Get Issue Context
get_issue_contextRetrieve all context for an issue in a single call: body, notes, related and closing merge requests, and linked issues.
Instructions
Bundle issue body, all notes (paginated up to maxNotes), related merge requests (mentioning), closing merge requests, linked issues (relates_to/blocks/is_blocked_by) into a single call. Use this instead of fanning out across get_issues + get_notes + search_merge_requests when investigating an issue.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| projectPath | Yes | Full project path (e.g. "my-group/my-project") | |
| iid | Yes | Issue IID (the number shown in the GitLab UI) | |
| maxNotes | No | Cap on notes fetched. Default 100. | |
| includeSystemNotes | No | Include system-generated notes (label changes, assignment events). Default false. | |
| userCredentials | No | Your GitLab credentials (optional — falls back to the configured env token if not provided) |
Implementation Reference
- src/tools.ts:2282-2284 (registration)The 'get_issue_context' tool is registered in the readOnlyTools array, which is then spread into the exports.tools array.
getNotesTool, getIssueContextTool, getMergeRequestContextTool, - src/tools.ts:1027-1032 (schema)Input schema for get_issue_context: projectPath (required), iid (required), maxNotes (default 100, cap 500), includeSystemNotes (default false).
inputSchema: withUserAuth(z.object({ projectPath: z.string().min(1).describe('Full project path (e.g. "my-group/my-project")'), iid: z.string().min(1).describe('Issue IID (the number shown in the GitLab UI)'), maxNotes: z.number().int().min(1).max(500).default(100).describe('Cap on notes fetched. Default 100.'), includeSystemNotes: z.boolean().default(false).describe('Include system-generated notes (label changes, assignment events). Default false.'), })), - src/tools.ts:1033-1086 (handler)Handler function for get_issue_context. Fetches issue detail, notes, related MRs, closing MRs, and linked issues in parallel via Promise.all, then assembles a bundled response.
handler: async (input, client, userConfig) => { const credentials = input.userCredentials ? validateUserConfig(input.userCredentials) : userConfig; const projectPath = input.projectPath.trim(); const iid = input.iid.trim(); const [detail, notesResult, related, closedBy, links] = await Promise.all([ client.getIssueDetail(projectPath, iid, credentials), client.getNotes(projectPath, 'issue', iid, input.maxNotes, undefined, true, credentials), client.getIssueRelatedMergeRequests(projectPath, iid, credentials).catch(() => []), client.getIssueClosedBy(projectPath, iid, credentials).catch(() => []), client.getIssueLinks(projectPath, iid, credentials).catch(() => []), ]); const issue = detail?.project?.issue; if (!issue) { throw new Error(`Issue ${projectPath}#${iid} not found.`); } const allNotes: any[] = Array.isArray(notesResult?.nodes) ? notesResult.nodes : []; const notes = input.includeSystemNotes ? allNotes : allNotes.filter((n) => !n.system); const summarizeMR = (mr: any) => ({ iid: mr.iid, title: mr.title, state: mr.state, webUrl: mr.web_url ?? mr.webUrl, author: mr.author?.username ?? null, sourceBranch: mr.source_branch ?? mr.sourceBranch, targetBranch: mr.target_branch ?? mr.targetBranch, }); const summarizeLink = (l: any) => ({ iid: String(l.iid), title: l.title, state: l.state, linkType: l.link_type ?? null, webUrl: l.web_url ?? null, projectId: l.project_id ?? null, }); return { project: { fullPath: projectPath }, issue, notes: { count: notes.length, truncated: !!notesResult?.hasMore, nodes: notes, }, relatedMergeRequests: related.map(summarizeMR), closingMergeRequests: closedBy.map(summarizeMR), linkedIssues: links.map(summarizeLink), }; }, }; - src/gitlab-client.ts:758-790 (helper)getIssueDetail: GraphQL query to fetch issue details (title, description, state, author, assignees, labels, milestone, votes, etc.)
async getIssueDetail( projectPath: string, iid: string, userConfig?: UserConfig, ): Promise<any> { const query = gql` query getIssueDetail($projectPath: ID!, $iid: String!) { project(fullPath: $projectPath) { fullPath issue(iid: $iid) { id iid title description state confidential createdAt updatedAt closedAt webUrl author { username name } assignees { nodes { username name } } labels { nodes { title color } } milestone { title state dueDate webPath } userNotesCount upvotes downvotes } } } `; return this.query(query, { projectPath, iid }, userConfig); } - src/gitlab-client.ts:2785-2794 (helper)getIssueRelatedMergeRequests, getIssueClosedBy, getIssueLinks: REST API helpers called by the handler to fetch related MRs, closing MRs, and linked issues.
async getIssueRelatedMergeRequests( projectPath: string, iid: string, userConfig?: UserConfig, ): Promise<any[]> { const encodedPath = encodeURIComponent(projectPath); return this.restRequest('GET', `/projects/${encodedPath}/issues/${iid}/related_merge_requests`, { userConfig, }); }