Skip to main content
Glama
magarcia

Linear MCP Server

linear_update_issue

Modify an existing Linear issue by updating its title, description, state, team assignment, priority level, due date, or assignee.

Instructions

Update an existing Linear issue

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
assigneeIdNoUser ID to assign the issue to
descriptionNoNew issue description (markdown supported)
dueDateNoNew due date
issueIdYesIssue ID to update
priorityNoNew priority level (0-4), where 0=no priority, 1=urgent, 4=low
stateIdNoNew state ID
teamIdNoNew team ID
titleNoNew issue title

Implementation Reference

  • The handler function that executes the tool logic: validates input, fetches the issue, applies updates using linearClient.updateIssue, awaits related data, and returns the updated issue details or an error response.
    export const linearUpdateIssueHandler: ToolHandler = async args => {
      const params = args as {
        issueId: string;
        title?: string;
        description?: string;
        stateId?: string;
        teamId?: string;
        assigneeId?: string;
        priority?: number;
        dueDate?: string;
      };
    
      try {
        // Validate required parameters
        if (!params.issueId) {
          return {
            content: [
              {
                type: 'text',
                text: 'Error: Issue ID is required',
              },
            ],
            isError: true,
          };
        }
    
        // Check if issue exists
        const issue = await linearClient.issue(params.issueId);
        if (!issue) {
          return {
            content: [
              {
                type: 'text',
                text: `Error: Issue with ID ${params.issueId} not found`,
              },
            ],
            isError: true,
          };
        }
    
        // Build update input with proper typing
        const updateInput: {
          title?: string;
          description?: string;
          stateId?: string;
          teamId?: string;
          assigneeId?: string;
          priority?: number;
          dueDate?: string;
        } = {};
    
        // Add optional parameters if provided
        if (params.title) updateInput.title = params.title;
        if (params.description) updateInput.description = params.description;
        if (params.stateId) updateInput.stateId = params.stateId;
        if (params.teamId) updateInput.teamId = params.teamId;
        if (params.assigneeId) updateInput.assigneeId = params.assigneeId;
        if (params.priority !== undefined) updateInput.priority = params.priority;
        if (params.dueDate) updateInput.dueDate = params.dueDate;
    
        // Update the issue
        const updatePayload = await linearClient.updateIssue(params.issueId, updateInput);
    
        if (!updatePayload.success) {
          return {
            content: [
              {
                type: 'text',
                text: 'Error: Failed to update issue',
              },
            ],
            isError: true,
          };
        }
    
        // Get updated issue data with proper awaits
        const updatedIssue = updatePayload.issue;
        if (!updatedIssue) {
          return {
            content: [
              {
                type: 'text',
                text: 'Error: Failed to retrieve updated issue data',
              },
            ],
            isError: true,
          };
        }
    
        // Process all issue data
        const issue_data = await updatedIssue;
    
        // Process related objects if they exist
        const state = await updatedIssue.then(issue => issue.state);
        const team = await updatedIssue.then(issue => issue.team);
        const assignee = await updatedIssue.then(issue => issue.assignee);
    
        const responseData = {
          id: issue_data.id,
          title: issue_data.title,
          description: issue_data.description,
          state: state ? await state.name : null,
          team: team ? await team.name : null,
          assignee: assignee ? await assignee.name : null,
          priority: issue_data.priority,
          url: issue_data.url,
        };
    
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(responseData),
            },
          ],
        };
      } 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,
        };
      }
    };
  • Input schema defining the parameters for updating a Linear issue, with issueId required and others optional.
    inputSchema: {
      type: 'object',
      properties: {
        issueId: {
          type: 'string',
          description: 'Issue ID to update',
        },
        title: {
          type: 'string',
          description: 'New issue title',
        },
        description: {
          type: 'string',
          description: 'New issue description (markdown supported)',
        },
        stateId: {
          type: 'string',
          description: 'New state ID',
        },
        teamId: {
          type: 'string',
          description: 'New team ID',
        },
        assigneeId: {
          type: 'string',
          description: 'User ID to assign the issue to',
        },
        priority: {
          type: 'number',
          description: 'New priority level (0-4), where 0=no priority, 1=urgent, 4=low',
        },
        dueDate: {
          type: 'string',
          description: 'New due date',
        },
      },
      required: ['issueId'],
    },
  • Registers the tool with name 'linear_update_issue', description, input schema, and the handler function.
    export const linearUpdateIssueTool = registerTool(
      {
        name: 'linear_update_issue',
        description: 'Update an existing Linear issue',
        inputSchema: {
          type: 'object',
          properties: {
            issueId: {
              type: 'string',
              description: 'Issue ID to update',
            },
            title: {
              type: 'string',
              description: 'New issue title',
            },
            description: {
              type: 'string',
              description: 'New issue description (markdown supported)',
            },
            stateId: {
              type: 'string',
              description: 'New state ID',
            },
            teamId: {
              type: 'string',
              description: 'New team ID',
            },
            assigneeId: {
              type: 'string',
              description: 'User ID to assign the issue to',
            },
            priority: {
              type: 'number',
              description: 'New priority level (0-4), where 0=no priority, 1=urgent, 4=low',
            },
            dueDate: {
              type: 'string',
              description: 'New due date',
            },
          },
          required: ['issueId'],
        },
      },
      linearUpdateIssueHandler
    );
  • src/tools/index.ts:3-3 (registration)
    Imports the linear_update_issue tool file to ensure it is registered when index is imported.
    import './linear_update_issue.js';
Behavior2/5

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

With no annotations provided, the description carries full burden for behavioral disclosure. 'Update an existing Linear issue' implies a mutation operation but doesn't specify required permissions, whether changes are reversible, rate limits, or what happens to unspecified fields (partial vs. full updates). This leaves significant gaps for a mutation tool.

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 with zero wasted words. It's appropriately sized for a tool with comprehensive schema documentation and gets straight to the point without unnecessary elaboration.

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?

For a mutation tool with 8 parameters, no annotations, and no output schema, the description is insufficient. It doesn't address behavioral aspects like permissions, side effects, or response format. While the schema covers parameters well, the overall context for safe and effective use is incomplete.

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?

Schema description coverage is 100%, providing clear documentation for all 8 parameters. The description adds no parameter-specific information beyond what's in the schema, so it meets the baseline of 3. It doesn't compensate for any gaps since there are none in the schema.

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 action ('Update') and resource ('an existing Linear issue'), making the purpose immediately understandable. It distinguishes from siblings like linear_create_issue (creation vs. update) and linear_update_label (different resource type). However, it doesn't specify what aspects can be updated, which prevents a perfect score.

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 (e.g., needing an existing issue ID), contrast with linear_create_issue for new issues, or specify scenarios where updates are appropriate versus other operations like adding comments or attachments.

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

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