Skip to main content
Glama

create_issue

Add tasks, bugs, or feature requests to your Linear workspace with clarity and organization by specifying title, team, description, priority, assignee, and project details.

Instructions

Create a new issue in Linear. This tool is useful for adding new tasks, bugs, or feature requests to your Linear workspace.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
assigneeIdNoThe ID of the user to assign the issue to
debugNoDebug mode to show extra diagnostics
descriptionNoThe detailed description of the issue
priorityNoThe priority of the issue (0-4)
projectIdNoThe ID of the project to associate with the issue
stateIdNoThe ID of the state to set for the issue
teamIdYesThe ID of the Linear team where the issue will be created
titleYesThe title of the issue to create

Implementation Reference

  • Main handler function for the 'create_issue' tool. Handles input, creates Linear client, calls the createIssue helper, formats success response with issue details, and provides detailed error messages with optional debug info.
    const handler = async ( ctx, { title, teamId, description, priority, assigneeId, stateId, projectId, debug, } ) => { const logger = ctx.effects.logger; try { // Log details about config and parameters logger.debug('Create issue called with parameters:', { title, teamId, description: description ? `${description.substring(0, 20)}...` : undefined, priority, assigneeId, stateId, projectId, debug, }); // Debug log for API key (masked) const apiKey = ctx.config.linearApiKey || ''; const maskedKey = apiKey ? apiKey.substring(0, 4) + '...' + apiKey.substring(apiKey.length - 4) : '<not set>'; logger.debug(`Using Linear API key: ${maskedKey}`); if (!ctx.config.linearApiKey) { throw new Error('LINEAR_API_KEY is not configured'); } // Create a Linear client using our effect logger.debug('Creating Linear client'); const linearClient = ctx.effects.linear.createClient( ctx.config.linearApiKey ); // Create the issue using the Linear SDK client logger.debug('Executing Linear API to create issue'); const options = { description, priority, assigneeId, stateId, projectId, }; const result = await createIssue( linearClient, title, teamId, options, logger ); // Log that we created the issue logger.info(`Created issue with ID: ${result.id}`); // Format the output const formatDate = timestamp => { if (!timestamp) return 'Just now'; const date = new Date(timestamp); return date.toLocaleString(); }; let responseText = ''; responseText += `✅ Issue created successfully\n\n`; // Add issue details responseText += `**Issue ID:** ${result.id}\n`; responseText += `**Title:** ${result.title}\n`; if (result.status) { responseText += `**Status:** ${result.status}\n`; } if (result.priority !== undefined) { const priorityLabels = ['No priority', 'Urgent', 'High', 'Medium', 'Low']; responseText += `**Priority:** ${priorityLabels[result.priority]}\n`; } if (result.assignee) { responseText += `**Assigned to:** ${result.assignee.name}\n`; } if (result.project) { responseText += `**Project:** ${result.project.name}\n`; } responseText += `**Created at:** ${formatDate(result.createdAt)}\n\n`; if (result.description) { responseText += `**Description:**\n${result.description}\n`; } logger.debug('Returning formatted issue result'); return { content: [{ type: 'text', text: responseText }], }; } catch (error) { logger.error(`Error creating issue: ${error.message}`); logger.error(error.stack); // Create a user-friendly error message with troubleshooting guidance let errorMessage = `Error creating issue: ${error.message}`; // Add detailed diagnostic information if in debug mode if (debug) { errorMessage += '\n\n=== DETAILED DEBUG INFORMATION ==='; // Add parameters that were used errorMessage += `\nParameters: - title: ${title} - teamId: ${teamId} - description: ${description ? 'provided' : 'not provided'} - priority: ${priority !== undefined ? priority : 'not provided'} - assigneeId: ${assigneeId || 'not provided'} - stateId: ${stateId || 'not provided'} - projectId: ${projectId || 'not provided'}`; // Check if API key is configured const apiKey = ctx.config.linearApiKey || ''; const keyStatus = apiKey ? `API key is configured (${apiKey.substring( 0, 4 )}...${apiKey.substring(apiKey.length - 4)})` : 'API key is NOT configured - set LINEAR_API_KEY'; errorMessage += `\n\nLinear API Status: ${keyStatus}`; // Add error details if (error.name) { errorMessage += `\nError type: ${error.name}`; } if (error.code) { errorMessage += `\nError code: ${error.code}`; } if (error.stack) { errorMessage += `\n\nStack trace: ${error.stack .split('\n') .slice(0, 3) .join('\n')}`; } // Add Linear API info for manual testing errorMessage += `\n\nLinear API: Using official Linear SDK (@linear/sdk) For manual testing, try using the SDK directly or the Linear API Explorer in the Linear UI.`; } // Add a note that debug mode can be enabled for more details if (!debug) { errorMessage += `\n\nFor more detailed diagnostics, retry with debug:true in the input.`; } return { content: [ { type: 'text', text: errorMessage, }, ], isError: true, }; } };
  • Zod input schema defining parameters for the create_issue tool, including title, teamId (required), and optional fields like description, priority, assignee, etc.
    const CreateIssueInputSchema = z.object({ title: z.string().describe('The title of the issue to create'), teamId: z .string() .min(1, { message: 'Team ID is required' }) .describe('The ID of the Linear team where the issue will be created'), description: z .string() .optional() .describe('The detailed description of the issue'), priority: z .number() .min(0) .max(4) .optional() .describe('The priority of the issue (0-4)'), assigneeId: z .string() .optional() .describe('The ID of the user to assign the issue to'), stateId: z .string() .optional() .describe('The ID of the state to set for the issue'), projectId: z .string() .optional() .describe('The ID of the project to associate with the issue'), debug: z .boolean() .default(false) .describe('Debug mode to show extra diagnostics'), });
  • Tool factory using create_tool() that registers the 'create_issue' tool with its name, description, input schema, and handler function.
    export const CreateIssue = create_tool({ name: 'create_issue', description: 'Create a new issue in Linear. This tool is useful for adding new tasks, bugs, or feature requests to your Linear workspace.', inputSchema: CreateIssueInputSchema, handler, });
  • Helper function that performs the actual Linear SDK issue creation, input preparation, response processing with schema validation, and async data loading.
    async function createIssue(client, title, teamId, options = {}, logger) { try { logger?.debug(`Creating new Linear issue with title: ${title}`); // Prepare the issue creation input for the Linear SDK const issueInput = { title, teamId, description: options.description, priority: options.priority, assigneeId: options.assigneeId, stateId: options.stateId, projectId: options.projectId, }; // Filter out undefined values Object.keys(issueInput).forEach(key => { if (issueInput[key] === undefined) { delete issueInput[key]; } }); logger?.debug('Issue creation payload:', issueInput); // Create the issue using the Linear SDK const issueResult = await client.createIssue(issueInput); if (!issueResult) { throw new Error('Failed to create issue, received null response'); } // Linear API returns a promise for the created issue const issueData = await issueResult.issue; if (!issueData) { throw new Error('Failed to retrieve issue data from response'); } logger?.debug(`Successfully created issue: ${issueData.id}`); // Load related data asynchronously let assigneeData = null; let projectData = null; let stateData = null; if (issueData.assignee) { assigneeData = await issueData.assignee; } if (issueData.project) { projectData = await issueData.project; } if (issueData.state) { stateData = await issueData.state; } // Process and validate the issue data using our schema const processedIssue = IssueSchema.parse({ id: issueData.id, title: issueData.title, description: issueData.description || undefined, // Convert null to undefined status: stateData?.name, priority: issueData.priority, assignee: assigneeData ? { id: assigneeData.id, name: assigneeData.name, email: assigneeData.email, } : undefined, project: projectData ? { id: projectData.id, name: projectData.name, } : undefined, createdAt: issueData.createdAt instanceof Date ? issueData.createdAt.toISOString() : issueData.createdAt, updatedAt: issueData.updatedAt instanceof Date ? issueData.updatedAt.toISOString() : issueData.updatedAt, }); return processedIssue; } catch (error) { // Enhanced error logging logger?.error(`Error creating Linear issue: ${error.message}`, { title, teamId, options, stack: error.stack, }); // Check if it's a Zod validation error (formatted differently) if (error.name === 'ZodError') { logger?.error( 'Zod validation error details:', JSON.stringify(error.errors, null, 2) ); } // Rethrow the error for the tool to handle throw error; } }
  • src/index.js:109-118 (registration)
    Instantiation of the CreateIssue tool class with toolContext and addition to the all_tools array for MCP server registration.
    const all_tools = [ new tools.ListIssues(toolContext), new tools.GetIssue(toolContext), new tools.ListMembers(toolContext), new tools.ListProjects(toolContext), new tools.GetProject(toolContext), new tools.ListTeams(toolContext), new tools.AddComment(toolContext), new tools.CreateIssue(toolContext), ];

Other Tools

Related 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/scoutos/mcp-linear'

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