linear mcp

Local 2025-08-31 23:23:10 0
Developer Tools @ibraheem4/linear-mcp

Enables AI agents to manage issues, projects, and teams on the Linear platform programmatically.


Note: This is a custom implementation. For the official Cline Linear MCP server, see cline/linear-mcp.

A Model Context Protocol (MCP) server that provides tools for interacting with Linear's API, enabling AI agents to manage issues, projects, and teams programmatically through the Linear platform.

Features

  • Issue Management

  • Create new issues with customizable properties (title, description, team, assignee, priority, labels)

  • List issues with flexible filtering options (team, assignee, status)
  • Update existing issues (title, description, status, assignee, priority)

  • Team Management

  • List all teams in the workspace

  • Access team details including ID, name, key, and description

  • Project Management

  • List all projects with optional team filtering
  • View project details including name, description, state, and associated teams

Prerequisites

  • Node.js (v16 or higher)
  • A Linear account with API access
  • Linear API key with appropriate permissions

Quick Start

  1. Get your Linear API key from Linear's Developer Settings

  2. Run with your API key:

LINEAR_API_KEY=your-api-key npx @ibraheem4/linear-mcp

Or set it in your environment:

export LINEAR_API_KEY=your-api-key
npx @ibraheem4/linear-mcp

Development Setup

  1. Clone the repository:
git clone [repository-url]
cd linear-mcp
  1. Install dependencies:
npm install
  1. Build the project:
npm run build

Running with Inspector

For local development and debugging, you can use the MCP Inspector:

  1. Install supergateway:
npm install -g supergateway
  1. Use the included run.sh script:
chmod +x run.sh
LINEAR_API_KEY=your-api-key ./run.sh
  1. Access the Inspector:
  2. Open localhost:1337 in your browser
  3. The Inspector connects via Server-Sent Events (SSE)
  4. Test and debug tool calls through the Inspector interface

Configuration

Configure the MCP server in your settings file based on your client:

For Claude Desktop

  • MacOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "linear-mcp": {
      "command": "node",
      "args": ["/path/to/linear-mcp/build/index.js"],
      "env": {
        "LINEAR_API_KEY": "your-api-key-here"
      },
      "disabled": false,
      "alwaysAllow": []
    }
  }
}

For VS Code Extension (Cline)

Location: ~/Library/Application Support/Code/User/globalStorage/rooveterinaryinc.roo-cline/settings/cline_mcp_settings.json

{
  "mcpServers": {
    "linear-mcp": {
      "command": "node",
      "args": ["/path/to/linear-mcp/build/index.js"],
      "env": {
        "LINEAR_API_KEY": "your-api-key-here"
      },
      "disabled": false,
      "alwaysAllow": []
    }
  }
}

For Cursor (cursor.sh)

For Cursor, the server must be run with the full path:

node /Users/ibraheem/Projects/linear-mcp/build/index.js

Available Tools

create_issue

Creates a new issue in Linear.

{
  title: string;          // Required: Issue title
  description?: string;   // Optional: Issue description (markdown supported)
  teamId: string;        // Required: Team ID
  assigneeId?: string;   // Optional: Assignee user ID
  priority?: number;     // Optional: Priority (0-4)
  labels?: string[];     // Optional: Label IDs to apply
}

list_issues

Lists issues with optional filters.

{
  teamId?: string;      // Optional: Filter by team ID
  assigneeId?: string;  // Optional: Filter by assignee ID
  status?: string;      // Optional: Filter by status
  first?: number;       // Optional: Number of issues to return (default: 50)
}

update_issue

Updates an existing issue.

{
  issueId: string;       // Required: Issue ID
  title?: string;        // Optional: New title
  description?: string;  // Optional: New description
  status?: string;      // Optional: New status
  assigneeId?: string;  // Optional: New assignee ID
  priority?: number;    // Optional: New priority (0-4)
  labels?: string[];   // Optional: Label IDs to apply to the issue
}

list_teams

Lists all teams in the workspace. No parameters required.

list_projects

Lists all projects with optional filtering.

{
  teamId?: string;     // Optional: Filter by team ID
  first?: number;      // Optional: Number of projects to return (default: 50)
}

get_issue

Gets detailed information about a specific issue.

{
  issueId: string; // Required: Issue ID
}

Development

For development with auto-rebuild:

npm run watch

Error Handling

The server includes comprehensive error handling for:

  • Invalid API keys
  • Missing required parameters
  • Linear API errors
  • Invalid tool requests

All errors are properly formatted and returned with descriptive messages.

Technical Details

Built with:

  • TypeScript
  • Linear SDK (@linear/sdk v37.0.0)
  • MCP SDK (@modelcontextprotocol/sdk v0.6.0)

The server uses stdio for communication and implements the Model Context Protocol for seamless integration with AI agents.

License

MIT

[
  {
    "description": "Create a new issue in Linear",
    "inputSchema": {
      "properties": {
        "assigneeId": {
          "description": "Assignee user ID (optional)",
          "type": "string"
        },
        "description": {
          "description": "Issue description (markdown supported)",
          "type": "string"
        },
        "labels": {
          "description": "Label IDs to apply (optional)",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "priority": {
          "description": "Priority (0-4, optional)",
          "maximum": 4,
          "minimum": 0,
          "type": "number"
        },
        "teamId": {
          "description": "Team ID",
          "type": "string"
        },
        "title": {
          "description": "Issue title",
          "type": "string"
        }
      },
      "required": [
        "title",
        "teamId"
      ],
      "type": "object"
    },
    "name": "create_issue"
  },
  {
    "description": "List issues with optional filters",
    "inputSchema": {
      "properties": {
        "assigneeId": {
          "description": "Filter by assignee ID (optional)",
          "type": "string"
        },
        "first": {
          "description": "Number of issues to return (default: 50)",
          "type": "number"
        },
        "status": {
          "description": "Filter by status (optional)",
          "type": "string"
        },
        "teamId": {
          "description": "Filter by team ID (optional)",
          "type": "string"
        }
      },
      "type": "object"
    },
    "name": "list_issues"
  },
  {
    "description": "Update an existing issue",
    "inputSchema": {
      "properties": {
        "assigneeId": {
          "description": "New assignee ID (optional)",
          "type": "string"
        },
        "description": {
          "description": "New description (optional)",
          "type": "string"
        },
        "issueId": {
          "description": "Issue ID",
          "type": "string"
        },
        "priority": {
          "description": "New priority (0-4, optional)",
          "maximum": 4,
          "minimum": 0,
          "type": "number"
        },
        "status": {
          "description": "New status (optional)",
          "type": "string"
        },
        "title": {
          "description": "New title (optional)",
          "type": "string"
        }
      },
      "required": [
        "issueId"
      ],
      "type": "object"
    },
    "name": "update_issue"
  },
  {
    "description": "List all teams in the workspace",
    "inputSchema": {
      "properties": {},
      "type": "object"
    },
    "name": "list_teams"
  },
  {
    "description": "List all projects",
    "inputSchema": {
      "properties": {
        "first": {
          "description": "Number of projects to return (default: 50)",
          "type": "number"
        },
        "teamId": {
          "description": "Filter by team ID (optional)",
          "type": "string"
        }
      },
      "type": "object"
    },
    "name": "list_projects"
  },
  {
    "description": "Search for issues using a text query",
    "inputSchema": {
      "properties": {
        "first": {
          "description": "Number of results to return (default: 50)",
          "type": "number"
        },
        "query": {
          "description": "Search query text",
          "type": "string"
        }
      },
      "required": [
        "query"
      ],
      "type": "object"
    },
    "name": "search_issues"
  },
  {
    "description": "Get detailed information about a specific issue",
    "inputSchema": {
      "properties": {
        "issueId": {
          "description": "Issue ID",
          "type": "string"
        }
      },
      "required": [
        "issueId"
      ],
      "type": "object"
    },
    "name": "get_issue"
  }
]