Skip to main content
Glama
magarcia

Linear MCP Server

linear_get_project_issues

Retrieve issues from a Linear project by specifying the project ID, with options to filter by status, priority, include archived issues, and set a result limit.

Instructions

Get issues for a specific project

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
includeArchivedNoInclude archived issues
limitNoMaximum number of issues to return (default: 50)
priorityNoFilter by priority level (0-4), where 0=no priority, 1=urgent, 4=low
projectIdYesProject ID to get issues for
statusNoFilter by issue status name

Implementation Reference

  • The main execution logic for the linear_get_project_issues tool, fetching Linear project issues with optional filters for status, priority, and archived status.
    export const linearGetProjectIssuesHandler: ToolHandler = async args => {
      const params = args as {
        projectId: string;
        includeArchived?: boolean;
        limit?: number;
        status?: string;
        priority?: number;
      };
    
      try {
        // Validate required parameters
        if (!params.projectId) {
          return {
            content: [
              {
                type: 'text',
                text: 'Error: Project ID is required',
              },
            ],
            isError: true,
          };
        }
    
        // Set up query parameters
        const queryParams: {
          first: number;
          includeArchived: boolean;
          filter?: {
            stateId?: { eq: string };
            priority?: { eq: number };
          };
        } = {
          first: params.limit || 50,
          includeArchived: params.includeArchived || false,
        };
    
        // Get the project
        const project = await linearClient.project(params.projectId);
        if (!project) {
          return {
            content: [
              {
                type: 'text',
                text: `Error: Project with ID ${params.projectId} not found`,
              },
            ],
            isError: true,
          };
        }
    
        // Get project issues
        const issuesResponse = await project.issues(queryParams);
        if (!issuesResponse || !issuesResponse.nodes) {
          return {
            content: [
              {
                type: 'text',
                text: 'Error: Failed to fetch project issues',
              },
            ],
            isError: true,
          };
        }
    
        let issues = issuesResponse.nodes;
    
        // Filter by status if provided
        if (params.status && issues.length > 0) {
          const status = params.status.toLowerCase();
          const filteredIssues = [];
    
          for (const issue of issues) {
            const state = await issue.state;
            if (state && typeof state === 'object') {
              const stateName = await state.name;
              if (stateName && stateName.toLowerCase() === status) {
                filteredIssues.push(issue);
              }
            }
          }
    
          issues = filteredIssues;
        }
    
        // Filter by priority if provided
        if (params.priority !== undefined && issues.length > 0) {
          const filteredIssues = [];
    
          for (const issue of issues) {
            const priority = await issue.priority;
            if (priority === params.priority) {
              filteredIssues.push(issue);
            }
          }
    
          issues = filteredIssues;
        }
    
        // Extract issue data
        const issueData = await Promise.all(
          issues.map(async issue => {
            const state = await issue.state;
            const assignee = await issue.assignee;
    
            return {
              id: await issue.id,
              identifier: await issue.identifier,
              title: await issue.title,
              description: await issue.description,
              state: state && typeof state === 'object' ? await state.name : null,
              assignee: assignee && typeof assignee === 'object' ? await assignee.name : null,
              priority: await issue.priority,
              url: await issue.url,
              createdAt: await issue.createdAt,
              updatedAt: await issue.updatedAt,
            };
          })
        );
    
        // Get project data
        const projectStatus = await project.status;
    
        const projectData = {
          id: project.id,
          name: project.name,
          status: projectStatus ? await projectStatus.name : null,
          issues: issueData,
        };
    
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(projectData),
            },
          ],
        };
      } catch (error) {
        const errorMessage =
          error instanceof Error
            ? error.message
            : typeof error === 'string'
              ? error
              : 'Unknown error occurred';
    
        return {
          content: [
            {
              type: 'text',
              text: `Error: ${errorMessage}`,
            },
          ],
          isError: true,
        };
      }
    };
  • Tool registration using registerTool, specifying name, description, inputSchema, and handler reference.
    export const linearGetProjectIssuesTool = registerTool(
      {
        name: 'linear_get_project_issues',
        description: 'Get issues for a specific project',
        inputSchema: {
          type: 'object',
          properties: {
            projectId: {
              type: 'string',
              description: 'Project ID to get issues for',
            },
            includeArchived: {
              type: 'boolean',
              description: 'Include archived issues',
            },
            limit: {
              type: 'number',
              description: 'Maximum number of issues to return (default: 50)',
            },
            status: {
              type: 'string',
              description: 'Filter by issue status name',
            },
            priority: {
              type: 'number',
              description: 'Filter by priority level (0-4), where 0=no priority, 1=urgent, 4=low',
            },
          },
          required: ['projectId'],
        },
      },
      linearGetProjectIssuesHandler
    );
  • Input schema for validating tool arguments, defining properties and required fields.
    inputSchema: {
      type: 'object',
      properties: {
        projectId: {
          type: 'string',
          description: 'Project ID to get issues for',
        },
        includeArchived: {
          type: 'boolean',
          description: 'Include archived issues',
        },
        limit: {
          type: 'number',
          description: 'Maximum number of issues to return (default: 50)',
        },
        status: {
          type: 'string',
          description: 'Filter by issue status name',
        },
        priority: {
          type: 'number',
          description: 'Filter by priority level (0-4), where 0=no priority, 1=urgent, 4=low',
        },
      },
      required: ['projectId'],
    },
  • src/tools/index.ts:9-9 (registration)
    Import statement that loads and registers the tool during module initialization.
    import './linear_get_project_issues.js';

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/magarcia/mcp-server-linearapp'

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