Skip to main content
Glama
wkoutre

Linear MCP Server

by wkoutre

linear_convertIssueToSubtask

Convert a Linear issue into a subtask by linking it to a parent issue for better project organization and hierarchy management.

Instructions

Convert an issue to a subtask

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
issueIdYesID or identifier of the issue to convert (e.g., ABC-123)
parentIssueIdYesID or identifier of the parent issue (e.g., ABC-456)

Implementation Reference

  • The handler function that executes the tool logic: validates input arguments using a type guard and calls the LinearService.convertIssueToSubtask method to perform the conversion.
    export function handleConvertIssueToSubtask(linearService: LinearService) {
      return async (args: unknown) => {
        try {
          if (!isConvertIssueToSubtaskArgs(args)) {
            throw new Error("Invalid arguments for convertIssueToSubtask");
          }
          
          return await linearService.convertIssueToSubtask(args.issueId, args.parentIssueId);
        } catch (error) {
          logError("Error converting issue to subtask", error);
          throw error;
        }
      };
    }
  • The MCP tool definition/schema specifying the tool name, description, input schema (issueId and parentIssueId required), and output schema.
    export const convertIssueToSubtaskToolDefinition: MCPToolDefinition = {
      name: "linear_convertIssueToSubtask",
      description: "Convert an issue to a subtask",
      input_schema: {
        type: "object",
        properties: {
          issueId: {
            type: "string",
            description: "ID or identifier of the issue to convert (e.g., ABC-123)",
          },
          parentIssueId: {
            type: "string",
            description: "ID or identifier of the parent issue (e.g., ABC-456)",
          },
        },
        required: ["issueId", "parentIssueId"],
      },
      output_schema: {
        type: "object",
        properties: {
          success: { type: "boolean" },
          issue: {
            type: "object",
            properties: {
              id: { type: "string" },
              identifier: { type: "string" },
              title: { type: "string" },
              parent: { type: "object" },
              url: { type: "string" }
            }
          }
        }
      }
    };
  • Registration of the tool in the handlers map returned by registerToolHandlers function, mapping tool name to the handler instance.
    linear_convertIssueToSubtask: handleConvertIssueToSubtask(linearService),
  • Type guard function used by the handler to validate the tool's input arguments (issueId and parentIssueId as strings).
     */
    export function isConvertIssueToSubtaskArgs(args: unknown): args is {
      issueId: string;
      parentIssueId: string;
    } {
      return (
        typeof args === "object" &&
        args !== null &&
        "issueId" in args &&
        typeof (args as { issueId: string }).issueId === "string" &&
        "parentIssueId" in args &&
        typeof (args as { parentIssueId: string }).parentIssueId === "string"
      );
    }
  • LinearService method implementing the core logic: fetches issues, updates the issue's parentId using Linear SDK, and returns formatted success response with updated issue data.
    async convertIssueToSubtask(issueId: string, parentIssueId: string) {
      try {
        // Get both issues
        const issue = await this.client.issue(issueId);
        if (!issue) {
          throw new Error(`Issue with ID ${issueId} not found`);
        }
    
        const parentIssue = await this.client.issue(parentIssueId);
        if (!parentIssue) {
          throw new Error(`Parent issue with ID ${parentIssueId} not found`);
        }
    
        // Convert the issue to a subtask
        const updatedIssue = await issue.update({
          parentId: parentIssueId,
        });
    
        // Get parent data - we need to fetch the updated issue to get relationships
        const updatedIssueData = await this.client.issue(issue.id);
        const parentData =
          updatedIssueData && updatedIssueData.parent ? await updatedIssueData.parent : null;
    
        return {
          success: true,
          issue: {
            id: issue.id,
            identifier: issue.identifier,
            title: issue.title,
            parent: parentData
              ? {
                  id: parentData.id,
                  identifier: parentData.identifier,
                  title: parentData.title,
                }
              : null,
            url: issue.url,
          },
        };
      } catch (error) {
        console.error('Error converting issue to subtask:', error);
        throw error;
      }
    }

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/wkoutre/linear-mcp-server'

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