Skip to main content
Glama

create-issue

Create new issues in Plane projects by providing title, description, priority level, assignees, and state information to track project tasks effectively.

Instructions

Create a new issue in a project

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
assigneesNoArray of user IDs to assign to this issue (optional)
description_htmlNoHTML description of the issue (required by Plane API)
nameYesTitle of the issue
priorityNoPriority of the issue (urgent, high, medium, low, none)
project_idYesID of the project where the issue should be created
state_idNoID of the state for this issue (optional)

Implementation Reference

  • Handler for the 'create-issue' tool: validates project_id, processes assignees array, calls Plane API POST /projects/{project_id}/issues/ to create issue, returns JSON response.
    case "create-issue": { if (!args || typeof args.project_id !== "string") { throw new Error("Project ID is required"); } const { project_id, ...issueData } = args; // Ensure assignees is properly formatted as an array if (issueData.assignees) { // Special case: detect if entire issue is nested in assignees if ( typeof issueData.assignees === "object" && !Array.isArray(issueData.assignees) && (issueData.assignees as Record<string, any>).project_id && (issueData.assignees as Record<string, any>).name ) { // Issue is nested inside assignees, remove it completely delete issueData.assignees; } else if (!Array.isArray(issueData.assignees)) { if (typeof issueData.assignees === "string") { // Convert single string to array issueData.assignees = [issueData.assignees]; } else if (typeof issueData.assignees === "object") { // Convert object to array of values issueData.assignees = Object.values(issueData.assignees); } else { // Remove invalid assignees delete issueData.assignees; } } } const issue = await callPlaneAPI( `/projects/${project_id}/issues/`, "POST", issueData ); return { content: [{ type: "text", text: JSON.stringify(issue, null, 2) }], isError: false, }; }
  • Tool schema definition including name, description, and detailed inputSchema with properties, types, enums, and required fields for create-issue.
    const CREATE_ISSUE_TOOL: Tool = { name: "create-issue", description: "Create a new issue in a project", inputSchema: { type: "object", properties: { project_id: { type: "string", description: "ID of the project where the issue should be created", }, name: { type: "string", description: "Title of the issue", }, description_html: { type: "string", description: "HTML description of the issue (required by Plane API)", }, priority: { type: "string", description: "Priority of the issue (urgent, high, medium, low, none)", enum: ["urgent", "high", "medium", "low", "none"], }, state_id: { type: "string", description: "ID of the state for this issue (optional)", }, assignees: { type: "array", items: { type: "string", }, description: "Array of user IDs to assign to this issue (optional)", }, }, required: ["project_id", "name"], }, };
  • src/index.ts:261-270 (registration)
    Registration of available tools list for ListToolsRequest, including CREATE_ISSUE_TOOL.
    server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ LIST_PROJECTS_TOOL, GET_PROJECT_TOOL, CREATE_ISSUE_TOOL, LIST_ISSUES_TOOL, GET_ISSUE_TOOL, UPDATE_ISSUE_TOOL, ], }));
  • Helper function callPlaneAPI used by create-issue handler to make authenticated HTTP requests to Plane API endpoints.
    async function callPlaneAPI( endpoint: string, method: string, body?: any ): Promise<any> { const baseUrl = `https://api.plane.so/api/v1/workspaces/${PLANE_WORKSPACE_SLUG}`; const url = `${baseUrl}${endpoint}`; const options: RequestInit = { method, headers: { "Content-Type": "application/json", "X-API-Key": PLANE_API_KEY as string, }, }; if (body && (method === "POST" || method === "PATCH")) { options.body = JSON.stringify(body); } try { const response = await fetch(url, options); if (!response.ok) { let errorText; try { errorText = await response.text(); } catch (parseError) { errorText = "Unable to parse error response"; } throw new Error( `Plane API error: ${response.status} ${response.statusText}\n${errorText}` ); } // For DELETE requests that return 204 No Content if (response.status === 204) { return { success: true }; } return await response.json(); } catch (error) { throw new Error( `Error calling Plane API: ${ error instanceof Error ? error.message : String(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/kelvin6365/plane-mcp-server'

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