Skip to main content
Glama

jira_list_project_members

Retrieve all members of a Jira project to identify team participants and manage project access by providing the project key and authentication details.

Instructions

Lists all members of a specific Jira project

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
jiraHostNoThe Jira host URL (e.g., 'your-domain.atlassian.net')
emailNoEmail address associated with the Jira account
apiTokenNoAPI token for Jira authentication
projectKeyYesThe Jira project key (e.g., 'PROJECT')

Implementation Reference

  • The main handler function that lists all members of a Jira project. It fetches project roles, retrieves detailed actors for each role, deduplicates members by displayName, and formats the output as a Markdown table with columns for Name, Type, Email, and Roles.
    export async function listProjectMembers(args: any) {
        const validatedArgs = await JiraProjectMembersRequestSchema.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;
    
        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 = `# Project Members for ${projectKey}\n\n`;
    
        if (Object.keys(projectRoles).length > 0) {
    
            const allMembers = new Map<string, {
                displayName: string;
                type: string;
                email: string;
                roles: string[];
            }>();
            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 (allMembers.size > 0) {
                formattedResponse += "| Name | Type | Email | Roles |\n";
                formattedResponse += "|------|------|-------|-------|\n";
    
                allMembers.forEach(member => {
                    formattedResponse += `| ${member.displayName} | ${member.type} | ${member.email} | ${member.roles.join(', ')} |\n`;
                });
            } else {
                formattedResponse += "No project members found.";
            }
        } else {
            formattedResponse += "No project roles found.";
        }
    
        return {
            content: [{ type: "text", text: formattedResponse }],
            isError: false,
        };
    }
  • The toolConfigs object registers 'jira_list_project_members' by mapping it to its validation schema (JiraProjectMembersRequestSchema) and handler function (listProjectMembers), used by handleCallTool to dispatch tool calls.
    const toolConfigs: Record<string, ToolConfig> = {
        jira_list_projects: {
            schema: JiraApiRequestSchema,
            handler: listProjects
        },
        jira_get_issue: {
            schema: JiraIssueRequestSchema,
            handler: getIssue
        },
        jira_search_issues: {
            schema: JiraSearchIssuesRequestSchema,
            handler: searchIssues
        },
        jira_list_project_members: {
            schema: JiraProjectMembersRequestSchema,
            handler: listProjectMembers
        },
        jira_check_user_issues: {
            schema: JiraCheckUserIssuesRequestSchema,
            handler: checkUserIssues
        },
        jira_create_issue: {
            schema: JiraCreateIssueRequestSchema,
            handler: createIssue
        },
        jira_list_sprints: {
            schema: JiraSprintRequestSchema,
            handler: listSprints
        }
    };
  • Yup schema for validating the tool's input parameters. Extends JiraApiRequestSchema with a required projectKey field that matches the Jira project key format (/^[A-Z][A-Z0-9_]+$/).
    export const JiraProjectMembersRequestSchema = 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"),
    });
  • Tool description object including name, description, and inputSchema defining properties like jiraHost, email, apiToken (with defaults), and required projectKey.
    export const listProjectMembersToolDescription = {
        name: "jira_list_project_members",
        description: "Lists all members of a specific Jira project",
        inputSchema: {
            type: "object",
            properties: {
                jiraHost: {
                    type: "string",
                    description: "The Jira host URL (e.g., 'your-domain.atlassian.net')",
                    default: process.env.JIRA_HOST || "",
                },
                email: {
                    type: "string",
                    description: "Email address associated with the Jira account",
                    default: process.env.JIRA_EMAIL || "",
                },
                apiToken: {
                    type: "string",
                    description: "API token for Jira authentication",
                    default: process.env.JIRA_API_TOKEN || "",
                },
                projectKey: {
                    type: "string",
                    description: "The Jira project key (e.g., 'PROJECT')",
                },
            },
            required: ["projectKey"],
        },
    };
  • The tool is listed in handleListTools response with its name, description, and inline inputSchema for MCP tool listing.
        name: "jira_list_project_members",
        description: "Lists all members of a specific Jira project",
        inputSchema: {
            type: "object",
            properties: {
                ...getCommonJiraProperties(),
                projectKey: {
                    type: "string",
                    description: "The Jira project key (e.g., 'PROJECT')",
                },
            },
            required: ["projectKey"],
        },
    },

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/samuelrizzo/jira-mcp-server'

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