cantrip_init
Initialize a new project in Cantrip by creating it with a name and description, optionally using a product brief to automatically extract key business entities like ICPs and pain points, or starting empty to add entities manually.
Instructions
Create a new project and connect this workspace to it. Pass 'brief_text' (product brief as text) to auto-extract ICPs, pain points, and value props as inferred entities (costs 5 credits). Or pass 'brief_path' (absolute file path) and the file will be read locally. Without a brief, the project is created empty (free) and you add entities manually. Writes .cantrip.json automatically after creation. After creating a project, add a few entities and confirm them with the user before going deeper.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Project name | |
| description | Yes | One-line project description | |
| brief_text | No | Product brief content as text (preferred) | |
| brief_path | No | Absolute path to a product brief file — will be read locally and sent as text |
Implementation Reference
- src/tools.ts:191-208 (handler)The handler function for cantrip_init that creates a new project. It generates a slug from the name, optionally reads a brief file, posts to the 'init' API endpoint, and writes the project context to .cantrip.json.
handler: async (p) => { const slug = String(p.name).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, ""); let briefText = p.brief_text; if (!briefText && p.brief_path) { const { readFileSync } = await import("fs"); briefText = readFileSync(String(p.brief_path), "utf-8"); } const flags = buildFlags({ name: p.name, description: p.description, brief_text: briefText, project: slug, }); const result = await client.post("init", [], flags); writeProjectContext(slug); return result; }, }, - src/tools.ts:179-190 (schema)Zod schema defining the input parameters for cantrip_init: name (required), description (required), brief_text (optional), and brief_path (optional).
shape: { name: z.string().describe("Project name"), description: z.string().describe("One-line project description"), brief_text: z .string() .optional() .describe("Product brief content as text (preferred)"), brief_path: z .string() .optional() .describe("Absolute path to a product brief file — will be read locally and sent as text"), }, - src/tools.ts:169-208 (registration)Tool registration within the createTools function, defining the cantrip_init tool with its name, description, schema, and handler.
// ── Init ── { name: "cantrip_init", description: "Create a new project and connect this workspace to it. " + "Pass 'brief_text' (product brief as text) to auto-extract ICPs, pain points, and value props as inferred entities (costs 5 credits). " + "Or pass 'brief_path' (absolute file path) and the file will be read locally. " + "Without a brief, the project is created empty (free) and you add entities manually. " + "Writes .cantrip.json automatically after creation. " + "After creating a project, add a few entities and confirm them with the user before going deeper.", shape: { name: z.string().describe("Project name"), description: z.string().describe("One-line project description"), brief_text: z .string() .optional() .describe("Product brief content as text (preferred)"), brief_path: z .string() .optional() .describe("Absolute path to a product brief file — will be read locally and sent as text"), }, handler: async (p) => { const slug = String(p.name).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, ""); let briefText = p.brief_text; if (!briefText && p.brief_path) { const { readFileSync } = await import("fs"); briefText = readFileSync(String(p.brief_path), "utf-8"); } const flags = buildFlags({ name: p.name, description: p.description, brief_text: briefText, project: slug, }); const result = await client.post("init", [], flags); writeProjectContext(slug); return result; }, }, - src/tools.ts:27-35 (helper)Helper function that builds a flags object from parameters, filtering out undefined, null, and empty string values.
function buildFlags(params: Record<string, unknown>): Record<string, string> { const flags: Record<string, string> = {}; for (const [k, v] of Object.entries(params)) { if (v !== undefined && v !== null && v !== "") { flags[k] = String(v); } } return flags; } - src/client.ts:48-54 (helper)Helper function that writes the project slug to .cantrip.json file, connecting the workspace to the newly created project.
export function writeProjectContext(project: string): void { writeFileSync( getConfigPath(), JSON.stringify({ project }, null, 2) + "\n", "utf-8", ); }