create_card
Create new cards in Codecks project management with configurable properties like title, content, deck assignment, and hierarchical nesting options.
Instructions
Create a new card. Set deck/project to place it. Use parent to nest as sub-card.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | Card title (max 500 chars) | |
| content | No | Card body. Use '- []' for checkboxes | |
| deck | No | Destination deck name | |
| project | No | ||
| severity | No | ||
| doc | No | True for doc card | |
| allow_duplicate | No | ||
| parent | No | Parent card UUID for sub-cards |
Implementation Reference
- src/tools/mutation.ts:18-64 (handler)Complete MCP tool registration for 'create_card', including Zod input schema validation (lines 25-34) and the async handler function (lines 36-62) that validates inputs and calls client.createCard()export function registerMutationTools(server: McpServer, client: CodecksClient): void { server.registerTool( "create_card", { title: "Create Card", description: "Create a new card. Set deck/project to place it. Use parent to nest as sub-card.", inputSchema: z.object({ title: z.string().describe("Card title (max 500 chars)"), content: z.string().optional().describe("Card body. Use '- []' for checkboxes"), deck: z.string().optional().describe("Destination deck name"), project: z.string().optional(), severity: z.enum(["critical", "high", "low", "null"]).optional(), doc: z.boolean().default(false).describe("True for doc card"), allow_duplicate: z.boolean().default(false), parent: z.string().optional().describe("Parent card UUID for sub-cards"), }), }, async (args) => { try { const title = validateInput(args.title, "title"); const content = args.content ? validateInput(args.content, "content") : undefined; const result = await client.createCard({ title, content, deck: args.deck, project: args.project, severity: args.severity, doc: args.doc, allowDuplicate: args.allow_duplicate, parent: args.parent, }); return { content: [{ type: "text", text: JSON.stringify(finalizeToolResult(result)) }], }; } catch (err) { return { content: [ { type: "text", text: JSON.stringify(finalizeToolResult(handleError(err))), }, ], }; } }, );
- src/client.ts:379-401 (handler)Core implementation of createCard method that constructs the payload with title/content, handles severity and doc card type, dispatches to 'cards/create' API endpoint, and returns the created card IDasync createCard(options: { title: string; content?: string; deck?: string; project?: string; severity?: string; doc?: boolean; allowDuplicate?: boolean; parent?: string; }): Promise<Record<string, unknown>> { const payload: Record<string, unknown> = { content: `# ${options.title}${options.content ? "\n\n" + options.content : ""}`, }; if (options.severity && options.severity !== "null") { payload.severity = options.severity; } if (options.doc) payload.cardType = "doc"; const result = await dispatch("cards/create", payload); const cardId = (result.payload as Record<string, unknown>)?.id ?? result.cardId ?? "unknown"; return { ok: true, card_id: cardId, title: options.title }; }
- src/security.ts:161-171 (helper)Input validation helper function used by create_card handler to sanitize text and enforce maximum length limitsexport function validateInput(text: string, field: string): string { if (typeof text !== "string") { throw new CliError(`[ERROR] ${field} must be a string`); } const cleaned = text.replace(CONTROL_RE, ""); const limit = INPUT_LIMITS[field] ?? 50_000; if (cleaned.length > limit) { throw new CliError(`[ERROR] ${field} exceeds maximum length of ${limit} characters`); } return cleaned; }
- src/api.ts:194-196 (helper)dispatch function that routes API requests to the backend, used by createCard to send 'cards/create' commandsexport async function dispatch(path: string, data: unknown): Promise<Record<string, unknown>> { return sessionRequest(`/dispatch/${path}`, data); }
- src/contract.ts:56-75 (helper)finalizeToolResult helper that normalizes the tool response format, used to format create_card results before returning to MCP clientexport function finalizeToolResult(result: unknown): unknown { if (result !== null && typeof result === "object" && !Array.isArray(result)) { const dict = result as Record<string, unknown>; const normalized = ensureContractDict(dict); if (normalized.ok === false) return normalized; if (config.mcpResponseMode === "envelope") { const data = { ...normalized }; delete data.ok; delete data.schema_version; return { ok: true, schema_version: CONTRACT_SCHEMA_VERSION, data, }; } return normalized; }