Skip to main content
Glama

jira_search_issues

Search for Jira issues by project and assignee to track tasks and manage workflow efficiently.

Instructions

Searches for Jira issues by project and assignee

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')
assigneeNameNoThe display name of the assignee to filter by (e.g., 'John Doe')

Implementation Reference

  • The main handler function `searchIssues` that implements the core logic for the `jira_search_issues` tool. It validates input arguments, constructs a JQL query for searching issues by project key and optional assignee, makes an API call to Jira's search endpoint, and formats the results as a markdown table.
    export async function searchIssues(args: any) {
        const validatedArgs = await JiraSearchIssuesRequestSchema.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 assigneeName = validatedArgs.assigneeName;
    
        if (!jiraHost || !email || !apiToken) {
            throw new Error('Missing required authentication credentials. Please provide jiraHost, email, and apiToken.');
        }
    
        validateCredentials(jiraHost, email, apiToken);
    
        let jql = `project = "${projectKey}"`;
        if (assigneeName) {
            jql += ` AND assignee ~ "${assigneeName}"`;
        }
        jql += ` ORDER BY created DESC`;
    
        const authHeader = createAuthHeader(email, apiToken);
    
        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 || [];
    
        let formattedResponse = `# Issues for Project: ${projectKey}`;
        if (assigneeName) {
            formattedResponse += ` assigned to ${assigneeName}`;
        }
        formattedResponse += "\n\n";
    
        if (issues.length > 0) {
            formattedResponse += "| Issue Key | Summary | Status | Type | Assignee | 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 assignee = issue.fields.assignee?.displayName || 'Unassigned';
                const created = new Date(issue.fields.created).toLocaleDateString();
    
                formattedResponse += `| ${key} | ${summary} | ${status} | ${type} | ${assignee} | ${created} |\n`;
            });
        } else {
            formattedResponse += "No issues found matching the specified criteria.";
        }
    
        return {
            content: [{ type: "text", text: formattedResponse }],
            isError: false,
        };
    }
  • Registers the `jira_search_issues` tool in the `toolConfigs` mapping, associating it with `JiraSearchIssuesRequestSchema` for validation and the `searchIssues` handler for execution. This is used in `handleCallTool` to dispatch tool calls.
    jira_search_issues: {
        schema: JiraSearchIssuesRequestSchema,
        handler: searchIssues
    },
  • Defines `JiraSearchIssuesRequestSchema`, a Yup schema extending `JiraApiRequestSchema` to validate required `projectKey` and optional `assigneeName` for the `jira_search_issues` tool inputs.
    export const JiraSearchIssuesRequestSchema = 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"),
        assigneeName: yup.string()
            .optional()
            .min(2, "Assignee name must be at least 2 characters long"),
    });
  • Exports `searchIssuesToolDescription` object containing the tool name, description, and JSON schema for input parameters, used potentially for tool metadata.
    export const searchIssuesToolDescription = {
        name: "jira_search_issues",
        description: "Searches for Jira issues by project and assignee",
        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')",
                },
                assigneeName: {
                    type: "string",
                    description: "The display name of the assignee to filter by (e.g., 'John Doe')",
                },
            },
            required: ["projectKey"],
        },
    };
    
    /**
     * Searches for Jira issues by project key and optional assignee name
     * 
     * @async
     * @param {Object} args - The arguments for the search
     * @param {string} args.jiraHost - The Jira host URL
     * @param {string} args.email - Email for authentication
     * @param {string} args.apiToken - API token for authentication
     * @param {string} args.projectKey - The project key to search in
     * @param {string} [args.assigneeName] - Optional assignee name to filter by
     * @returns {Promise<Object>} A formatted response with the search results
     * @throws {Error} If the required credentials are missing or the request fails
     */
    export async function searchIssues(args: any) {
        const validatedArgs = await JiraSearchIssuesRequestSchema.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 assigneeName = validatedArgs.assigneeName;
    
        if (!jiraHost || !email || !apiToken) {
            throw new Error('Missing required authentication credentials. Please provide jiraHost, email, and apiToken.');
        }
    
        validateCredentials(jiraHost, email, apiToken);
    
        let jql = `project = "${projectKey}"`;
        if (assigneeName) {
            jql += ` AND assignee ~ "${assigneeName}"`;
        }
        jql += ` ORDER BY created DESC`;
    
        const authHeader = createAuthHeader(email, apiToken);
    
        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 || [];
    
        let formattedResponse = `# Issues for Project: ${projectKey}`;
        if (assigneeName) {
            formattedResponse += ` assigned to ${assigneeName}`;
        }
        formattedResponse += "\n\n";
    
        if (issues.length > 0) {
            formattedResponse += "| Issue Key | Summary | Status | Type | Assignee | 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 assignee = issue.fields.assignee?.displayName || 'Unassigned';
                const created = new Date(issue.fields.created).toLocaleDateString();
    
                formattedResponse += `| ${key} | ${summary} | ${status} | ${type} | ${assignee} | ${created} |\n`;
            });
        } else {
            formattedResponse += "No issues found matching the specified criteria.";
        }
    
        return {
            content: [{ type: "text", text: formattedResponse }],
            isError: false,
        };
    }
  • Lists the `jira_search_issues` tool in `handleListTools` response, providing description and input schema for MCP client tool discovery.
        name: "jira_search_issues",
        description: "Searches for Jira issues by project and assignee",
        inputSchema: {
            type: "object",
            properties: {
                ...getCommonJiraProperties(),
                projectKey: {
                    type: "string",
                    description: "The Jira project key (e.g., 'PROJECT')",
                },
                assigneeName: {
                    type: "string",
                    description: "The display name of the assignee to filter by (e.g., 'John Doe')",
                },
            },
            required: ["projectKey"],
        },
    },
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It states the search action but lacks critical details: it doesn't specify if this is a read-only operation (likely, but not confirmed), mention rate limits, describe the return format (e.g., list of issues with fields), or note any constraints like pagination. This leaves significant gaps for a tool with 5 parameters and no output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that directly states the tool's purpose without unnecessary words. It's front-loaded with the core action and filtering criteria, making it easy to parse quickly, which is ideal for conciseness in tool selection.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of a search tool with 5 parameters, no annotations, and no output schema, the description is incomplete. It doesn't explain the return values (e.g., what data the search yields), behavioral traits like safety or performance, or how it integrates with sibling tools, leaving the agent with insufficient context for effective use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description mentions filtering 'by project and assignee', which aligns with the 'projectKey' and 'assigneeName' parameters in the schema. However, with 100% schema description coverage, the schema already fully documents all 5 parameters (including authentication details like 'jiraHost', 'email', and 'apiToken'), so the description adds minimal value beyond restating what's in the structured data, meeting the baseline for high coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('Searches for') and resource ('Jira issues') with specific filtering criteria ('by project and assignee'), which provides a concrete purpose. However, it doesn't explicitly differentiate from sibling tools like 'jira_check_user_issues' or 'jira_list_projects', which might also involve issue-related queries, leaving some ambiguity about its unique role.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention prerequisites like authentication (implied by parameters but not stated), nor does it compare to siblings such as 'jira_check_user_issues' for user-specific queries or 'jira_list_projects' for broader project info, leaving the agent to infer usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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