create_project
Generate and initialize a new project by specifying its name and identifier through the Plane MCP Server. Simplifies project setup for efficient management in AI-driven workflows.
Instructions
Create a new project
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| identifier | Yes | The identifier of the project. This is typically a word of around 5 characters derived from the name of the project in uppercase. | |
| name | Yes | The name of the project |
Input Schema (JSON Schema)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"identifier": {
"description": "The identifier of the project. This is typically a word of around 5 characters derived from the name of the project in uppercase.",
"maxLength": 7,
"type": "string"
},
"name": {
"description": "The name of the project",
"type": "string"
}
},
"required": [
"name",
"identifier"
],
"type": "object"
}
Implementation Reference
- src/tools/projects.ts:47-73 (registration)Direct registration of the 'create_project' tool on the MCP server, including schema and handler function.server.tool( "create_project", "Create a new project", { name: z.string().describe("The name of the project"), identifier: z .string() .max(7) .describe( "The identifier of the project. This is typically a word of around 5 characters derived from the name of the project in uppercase." ), }, async ({ name, identifier }) => { const project = await makePlaneRequest("POST", `workspaces/${process.env.PLANE_WORKSPACE_SLUG}/projects/`, { name, identifier: identifier.toUpperCase().replaceAll(" ", ""), }); return { content: [ { type: "text", text: JSON.stringify(project, null, 2), }, ], }; } );
- src/tools/projects.ts:59-72 (handler)The handler logic for creating a project by making a POST request to the Plane API endpoint using the makePlaneRequest helper.async ({ name, identifier }) => { const project = await makePlaneRequest("POST", `workspaces/${process.env.PLANE_WORKSPACE_SLUG}/projects/`, { name, identifier: identifier.toUpperCase().replaceAll(" ", ""), }); return { content: [ { type: "text", text: JSON.stringify(project, null, 2), }, ], }; }
- src/tools/projects.ts:50-58 (schema)Zod-based input schema defining 'name' and 'identifier' parameters for the tool.{ name: z.string().describe("The name of the project"), identifier: z .string() .max(7) .describe( "The identifier of the project. This is typically a word of around 5 characters derived from the name of the project in uppercase." ), },
- src/common/request-helper.ts:3-36 (helper)Utility function makePlaneRequest used by the handler to perform authenticated HTTP requests to the Plane API.export async function makePlaneRequest<T>(method: string, path: string, body: any = null): Promise<T> { const hostUrl = process.env.PLANE_API_HOST_URL || "https://api.plane.so/"; const host = hostUrl.endsWith("/") ? hostUrl : `${hostUrl}/`; const url = `${host}api/v1/${path}`; const headers: Record<string, string> = { "X-API-Key": process.env.PLANE_API_KEY || "", }; // Only add Content-Type for non-GET requests if (method.toUpperCase() !== "GET") { headers["Content-Type"] = "application/json"; } try { const config: AxiosRequestConfig = { url, method, headers, }; // Only include body for non-GET requests if (method.toUpperCase() !== "GET" && body !== null) { config.data = body; } const response = await axios(config); return response.data; } catch (error) { if (axios.isAxiosError(error)) { throw new Error(`Request failed: ${error.message}`); } throw error; } }
- src/tools/index.ts:9-17 (registration)Higher-level registration where registerProjectTools is imported and invoked as part of overall tools registration.import { registerProjectTools } from "./projects.js"; import { registerUserTools } from "./user.js"; import { registerWorkLogTools } from "./work-log.js"; export const registerTools = (server: McpServer) => { registerMetadataTools(server); registerUserTools(server); registerProjectTools(server);