Skip to main content
The Linear plugin lets your MCP tools read and create issues in Linear on behalf of your users. You can list issues across the workspace or narrow results by team and project, and create new issues with a title, description, and priority. All requests go through Toolshed’s encrypted auth layer — your tools never handle Linear tokens directly.

Authentication

The plugin uses OAuth 2.0 with Linear’s read and write scopes. To connect a user’s Linear account, redirect them to the login endpoint:
GET /api/auth/linear/login?userId=YOUR_USER_ID
Toolshed handles the OAuth redirect, code exchange, and encrypted token storage. After the user authorizes the app, the callback stores their credentials and they are ready to use Linear tools.
YOUR_USER_ID is the identifier your application uses to track users. It is stored alongside the encrypted token so Toolshed can retrieve the right credentials at tool invocation time.

Connecting a user

1

Initiate the OAuth flow

Send the user to the login URL. In a web app this is typically a redirect; in a CLI you can open it in the browser.
GET /api/auth/linear/login?userId=user_abc123
2

User authorizes in Linear

Linear presents the standard OAuth consent screen. The user approves the read and write scopes for their workspace.
3

Toolshed stores the token

The callback handler exchanges the code, encrypts the access token, and stores it against the userId. No further action is required.

Disconnecting

To revoke and remove a user’s Linear connection, send:
DELETE /api/auth/linear?userId=YOUR_USER_ID
Toolshed attempts to revoke the token at Linear and removes the stored credentials.

Available tools

The Linear plugin exposes two tools. linear.issues.list is a read-only query and is safe to auto-approve by MCP clients. linear.issues.create is marked destructive and requires explicit user confirmation via the MCP elicitation flow before the issue is created.
Lists Linear issues visible to the authenticated user. You can scope results to a specific team or project, or omit both filters to retrieve issues across the workspace. Results are returned up to the specified limit.Parameters:
ParameterTypeRequiredDefaultDescription
teamIdstringNoFilter to issues belonging to this team ID
projectIdstringNoFilter to issues belonging to this project ID
limitintegerNo25Maximum number of issues to return (must be positive)
Returns:An object with an issues array. Each issue contains:
FieldTypeDescription
idstringLinear internal UUID for the issue
identifierstringHuman-readable identifier (e.g. ENG-123)
titlestringIssue title
statestringCurrent workflow state name (e.g. "In Progress")
urlstringURL to view the issue in Linear
Example invocation:
{
  "tool": "linear.issues.list",
  "input": {
    "teamId": "TEAM-ID-HERE",
    "limit": 10
  }
}
Creates a new issue in Linear. You must specify the team the issue belongs to and a title. Description, project assignment, and priority are optional.This tool is marked destructive — Toolshed will pause and ask the user to confirm before creating the issue. If the user declines or cancels the elicitation prompt, the operation is aborted and no issue is created.
This tool requires user confirmation via the MCP elicitation flow. Your MCP host must support elicitation for this tool to complete successfully.
Parameters:
ParameterTypeRequiredDescription
teamIdstringYesID of the team the issue should be created in
titlestringYesIssue title
descriptionstringNoIssue description (Markdown supported)
projectIdstringNoID of the project to assign the issue to
priorityinteger (0–4)NoPriority level: 0 = No priority, 1 = Urgent, 2 = High, 3 = Medium, 4 = Low
Returns:
FieldTypeDescription
idstringLinear internal UUID of the created issue
identifierstringHuman-readable identifier (e.g. ENG-124)
urlstringURL to view the new issue in Linear
Example invocation:
{
  "tool": "linear.issues.create",
  "input": {
    "teamId": "TEAM-ID-HERE",
    "title": "API gateway returns 503 under load",
    "description": "Observed during load test at 500 RPS. Logs attached.",
    "priority": 1
  }
}

Composing tools

A typical workflow is to list existing issues first to check for duplicates, then create a new one if needed:
// 1. List open issues for a team
{ "tool": "linear.issues.list", "input": { "teamId": "TEAM-ID-HERE", "limit": 25 } }

// 2. Create a new issue if none match (requires user confirmation)
{ "tool": "linear.issues.create", "input": { "teamId": "TEAM-ID-HERE", "title": "New issue title", "priority": 2 } }
The identifier field (e.g. ENG-123) is the human-readable issue reference your team uses day-to-day. Surface this to users rather than the internal id UUID.