jira_check_user_issues
Verify user project membership and retrieve assigned issues in Jira. Input project key, user name, and authentication details to manage issue tracking efficiently.
Instructions
Checks if a user is a member of a project and lists their assigned issues
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| apiToken | No | API token for Jira authentication | |
| No | Email address associated with the Jira account | ||
| jiraHost | No | The Jira host URL (e.g., 'your-domain.atlassian.net') | |
| projectKey | Yes | The Jira project key (e.g., 'PROJECT') | |
| userName | Yes | The display name of the user to check for in the project |
Implementation Reference
- src/tools/checkUserIssues.ts:60-216 (handler)Core handler function that executes the jira_check_user_issues tool: validates args, authenticates, fetches project roles to check user membership, lists available members if not found, and fetches/lists assigned issues if user is a member.export async function checkUserIssues(args: any) { const validatedArgs = await JiraCheckUserIssuesRequestSchema.validate(args); const jiraHost = validatedArgs.jiraHost || process.env.JIRA_HOST; const email = validatedArgs.email || process.env.JIRA_EMAIL; const apiToken = validatedArgs.apiToken || process.env.JIRA_API_TOKEN; const projectKey = validatedArgs.projectKey; const userName = validatedArgs.userName; if (!jiraHost || !email || !apiToken) { throw new Error('Missing required authentication credentials. Please provide jiraHost, email, and apiToken.'); } validateCredentials(jiraHost, email, apiToken); const authHeader = createAuthHeader(email, apiToken); const rolesResponse = await axios.get(`https://${jiraHost}/rest/api/3/project/${projectKey}/role`, { headers: { 'Authorization': authHeader, 'Accept': 'application/json', }, }); const projectRoles = rolesResponse.data; let formattedResponse = `# Checking User "${userName}" in Project "${projectKey}"\n\n`; const allMembers = new Map<string, { displayName: string; type: string; email: string; roles: string[]; }>(); let userFound = false; if (Object.keys(projectRoles).length > 0) { const roleDetailsPromises: Promise<{ roleName: string; data: ProjectRole; }>[] = []; for (const [roleName, roleUrl] of Object.entries(projectRoles)) { if (typeof roleUrl === 'string') { const roleId = roleUrl.split('/').pop(); const detailUrl = `https://${jiraHost}/rest/api/3/project/${projectKey}/role/${roleId}`; roleDetailsPromises.push( axios.get<ProjectRole>(detailUrl, { headers: { 'Authorization': authHeader, 'Accept': 'application/json', }, }).then(response => ({ roleName, data: response.data })) ); } } const roleDetails = await Promise.all(roleDetailsPromises); for (const { roleName, data } of roleDetails) { if (data.actors && data.actors.length > 0) { data.actors.forEach((actor: RoleActor) => { if (actor.displayName) { if (!allMembers.has(actor.displayName)) { allMembers.set(actor.displayName, { displayName: actor.displayName, type: actor.type, email: actor.emailAddress || 'N/A', roles: [roleName] }); } else { const member = allMembers.get(actor.displayName); if (member) { member.roles.push(roleName); } } if (actor.displayName.toLowerCase() === userName.toLowerCase()) { userFound = true; } } }); } } formattedResponse += `## Step 1: Checking if user "${userName}" is a member of project "${projectKey}"\n\n`; if (userFound) { const userInfo = allMembers.get(Array.from(allMembers.keys()).find( name => name.toLowerCase() === userName.toLowerCase() ) || ""); formattedResponse += `✅ User "${userName}" found in project with the following roles: ${userInfo?.roles.join(', ')}\n\n`; formattedResponse += `## Step 2: Fetching issues assigned to "${userName}" in project "${projectKey}"\n\n`; const jql = `project = "${projectKey}" AND assignee = "${userName}" ORDER BY created DESC`; const response = await axios.get(`https://${jiraHost}/rest/api/3/search`, { params: { jql, maxResults: 50, fields: "summary,status,assignee,created,issuetype,priority", }, headers: { 'Authorization': authHeader, 'Accept': 'application/json', }, }); const searchResults = response.data; const issues = searchResults.issues || []; if (issues.length > 0) { formattedResponse += "| Issue Key | Summary | Status | Type | Created |\n"; formattedResponse += "|-----------|---------|--------|------|--------|\n"; issues.forEach((issue: any) => { const key = issue.key; const summary = issue.fields.summary || 'No summary'; const status = issue.fields.status?.name || 'Unknown'; const type = issue.fields.issuetype?.name || 'Unknown'; const created = new Date(issue.fields.created).toLocaleDateString(); formattedResponse += `| ${key} | ${summary} | ${status} | ${type} | ${created} |\n`; }); } else { formattedResponse += "No issues found assigned to this user in the project."; } } else { formattedResponse += `❌ User "${userName}" is NOT a member of project "${projectKey}". No issues will be fetched.\n\n`; formattedResponse += "### Available Project Members:\n\n"; formattedResponse += "| Name | Roles |\n"; formattedResponse += "|------|-------|\n"; allMembers.forEach(member => { if (member.type !== "atlassian-user-role-actor" || (!member.displayName.includes("for Jira") && !member.displayName.includes("Atlassian"))) { formattedResponse += `| ${member.displayName} | ${member.roles.join(', ')} |\n`; } }); } } else { formattedResponse += "⚠️ No project roles found. Unable to determine project membership."; } return { content: [{ type: "text", text: formattedResponse }], isError: false, }; }
- src/validators/index.ts:79-86 (schema)Yup validation schema for the input parameters of the jira_check_user_issues tool, extending JiraApiRequestSchema with projectKey and userName.export const JiraCheckUserIssuesRequestSchema = JiraApiRequestSchema.shape({ projectKey: yup.string() .required("Project key is required") .matches(/^[A-Z][A-Z0-9_]+$/, "Invalid project key format. Only uppercase letters, numbers, and underscores are allowed"), userName: yup.string() .required("Username is required") .min(2, "Username must be at least 2 characters long"), });
- src/handlers/handlerTools.ts:44-47 (registration)Tool registration in toolConfigs map, associating the tool name with its schema and handler function for use in handleCallTool.jira_check_user_issues: { schema: JiraCheckUserIssuesRequestSchema, handler: checkUserIssues },