@donkeylabs/mcp 0.4.3 → 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/server.ts +41 -59
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@donkeylabs/mcp",
3
- "version": "0.4.3",
3
+ "version": "0.4.5",
4
4
  "description": "MCP server for AI-assisted development with @donkeylabs/server",
5
5
  "type": "module",
6
6
  "main": "./src/server.ts",
package/src/server.ts CHANGED
@@ -624,7 +624,7 @@ const tools = [
624
624
  },
625
625
  {
626
626
  name: "add_migration",
627
- description: "Create a numbered SQL migration file for a plugin's database schema.",
627
+ description: "Create a numbered Kysely migration file for a plugin's database schema. Use Kysely schema builder - NOT raw SQL.",
628
628
  inputSchema: {
629
629
  type: "object" as const,
630
630
  properties: {
@@ -636,16 +636,16 @@ const tools = [
636
636
  type: "string",
637
637
  description: "Descriptive name (e.g., 'create_users', 'add_email_column')",
638
638
  },
639
- upSql: {
639
+ upCode: {
640
640
  type: "string",
641
- description: "SQL for the up migration (CREATE TABLE, ALTER TABLE, etc.)",
641
+ description: "Kysely schema builder code for up migration. Example: 'await db.schema.createTable(\"users\").addColumn(\"id\", \"text\", (col) => col.primaryKey()).addColumn(\"email\", \"text\", (col) => col.notNull().unique()).execute();'",
642
642
  },
643
- downSql: {
643
+ downCode: {
644
644
  type: "string",
645
- description: "SQL for the down migration (DROP TABLE, etc.)",
645
+ description: "Kysely schema builder code for down migration. Example: 'await db.schema.dropTable(\"users\").execute();'",
646
646
  },
647
647
  },
648
- required: ["pluginName", "migrationName", "upSql"],
648
+ required: ["pluginName", "migrationName", "upCode"],
649
649
  },
650
650
  },
651
651
  {
@@ -972,7 +972,7 @@ async function getArchitectureGuidance(args: { task: string }): Promise<string>
972
972
  guidance += `\`\`\`\nTool: create_plugin\n name: "auth"\n hasSchema: true\n\`\`\`\n\n`;
973
973
 
974
974
  guidance += `### Step 2: Add Database Migration\n`;
975
- guidance += `\`\`\`\nTool: add_migration\n pluginName: "auth"\n migrationName: "create_users"\n upSql: "CREATE TABLE users (id INTEGER PRIMARY KEY, email TEXT UNIQUE, password_hash TEXT, created_at TEXT DEFAULT CURRENT_TIMESTAMP)"\n\`\`\`\n\n`;
975
+ guidance += `\`\`\`\nTool: add_migration\n pluginName: "auth"\n migrationName: "create_users"\n upCode: 'await db.schema.createTable("users").addColumn("id", "integer", (col) => col.primaryKey().autoIncrement()).addColumn("email", "text", (col) => col.notNull().unique()).addColumn("password_hash", "text", (col) => col.notNull()).addColumn("created_at", "text", (col) => col.defaultTo("CURRENT_TIMESTAMP")).execute();'\n downCode: 'await db.schema.dropTable("users").execute();'\n\`\`\`\n\n`;
976
976
 
977
977
  guidance += `### Step 3: Add Service Methods\n`;
978
978
  guidance += `Add these methods using \`add_service_method\`:\n`;
@@ -1192,9 +1192,7 @@ async function createPlugin(args: {
1192
1192
  // Generate imports
1193
1193
  let imports = `import { createPlugin } from "@donkeylabs/server";\n`;
1194
1194
  imports += `import { z } from "zod";\n`;
1195
- if (dependencies.length > 0) {
1196
- imports += dependencies.map(d => `import { ${d}Plugin } from "../${d}";`).join("\n") + "\n";
1197
- }
1195
+ // Note: dependencies are just string names, no imports needed
1198
1196
  if (hasSchema) {
1199
1197
  // Note: schema.ts is auto-generated after running `donkeylabs generate`
1200
1198
  // Once generated, uncomment this import:
@@ -1209,7 +1207,7 @@ async function createPlugin(args: {
1209
1207
  }
1210
1208
 
1211
1209
  const depsArray = dependencies.length > 0
1212
- ? `\n dependencies: [${dependencies.map(d => `${d}Plugin`).join(", ")}] as const,`
1210
+ ? `\n dependencies: [${dependencies.map(d => `"${d}"`).join(", ")}] as const,`
1213
1211
  : "";
1214
1212
 
1215
1213
  // Build the service context comment based on what's available
@@ -1258,34 +1256,9 @@ ${ctxComment}
1258
1256
 
1259
1257
  // Create migrations folder if plugin has schema
1260
1258
  // Note: schema.ts is auto-generated by `donkeylabs generate` from migrations
1259
+ // No initial migration is created - use add_migration tool to add migrations
1261
1260
  if (hasSchema) {
1262
1261
  mkdirSync(join(pluginDir, "migrations"), { recursive: true });
1263
-
1264
- const migrationContent = `import { Kysely, sql } from "kysely";
1265
-
1266
- /**
1267
- * Migration: 001_initial
1268
- * Created: ${new Date().toISOString()}
1269
- * Plugin: ${name}
1270
- */
1271
-
1272
- export async function up(db: Kysely<any>): Promise<void> {
1273
- // Create your tables here
1274
- // Example:
1275
- // await db.schema
1276
- // .createTable("${name}")
1277
- // .addColumn("id", "integer", (col) => col.primaryKey().autoIncrement())
1278
- // .addColumn("name", "text", (col) => col.notNull())
1279
- // .addColumn("created_at", "text", (col) => col.defaultTo(sql\`CURRENT_TIMESTAMP\`))
1280
- // .execute();
1281
- }
1282
-
1283
- export async function down(db: Kysely<any>): Promise<void> {
1284
- // Drop your tables here
1285
- // await db.schema.dropTable("${name}").execute();
1286
- }
1287
- `;
1288
- await Bun.write(join(pluginDir, "migrations", "001_initial.ts"), migrationContent);
1289
1262
  }
1290
1263
 
1291
1264
  // Build registration example based on plugin type
@@ -1308,7 +1281,7 @@ server.registerPlugin(${name}Plugin);
1308
1281
 
1309
1282
  **Location:** ${projectConfig.pluginsDir}/${name}/
1310
1283
  **Files created:**
1311
- - index.ts (plugin definition)${hasSchema ? "\n- schema.ts (database types)\n- migrations/001_initial.sql" : ""}
1284
+ - index.ts (plugin definition)${hasSchema ? "\n- migrations/ (empty - use add_migration to add)" : ""}
1312
1285
 
1313
1286
  **Plugin features:**
1314
1287
  ${hasSchema ? "- ✅ Database schema (withSchema<>)\n" : ""}${hasConfig ? "- ✅ Configurable (withConfig<>)\n" : ""}- Service with ctx.core (logger, cache, events, cron, jobs, sse, rateLimiter)
@@ -1320,9 +1293,9 @@ ${registrationExample}
1320
1293
 
1321
1294
  ### Next Steps
1322
1295
 
1323
- 1. ${hasSchema ? "Edit the migration file with your schema" : "Add service methods using `add_service_method`"}
1324
- 2. ${hasSchema ? "Run \`donkeylabs generate\` to create types" : "Register the plugin in your server"}
1325
- 3. Use \`extend_plugin\` to add errors, events, or middleware
1296
+ 1. ${hasSchema ? "Use \\`add_migration\\` to create your database schema" : "Add service methods using `add_service_method`"}
1297
+ 2. ${hasSchema ? "**IMPORTANT:** Run \\`donkeylabs generate\\` after migrations to generate schema types" : "Register the plugin in your server"}
1298
+ 3. ${hasSchema ? "Update plugin to use generated DB type: \\`.withSchema<DB>()\\` and import from ./schema" : "Use \\`extend_plugin\\` to add errors, events, or middleware"}
1326
1299
 
1327
1300
  ### Example Usage
1328
1301
 
@@ -1410,10 +1383,10 @@ const result = await ctx.plugins.${pluginName}.${methodName}(${params ? "..." :
1410
1383
  async function addMigration(args: {
1411
1384
  pluginName: string;
1412
1385
  migrationName: string;
1413
- upSql: string;
1414
- downSql?: string;
1386
+ upCode: string;
1387
+ downCode?: string;
1415
1388
  }): Promise<string> {
1416
- const { pluginName, migrationName, upSql, downSql = "" } = args;
1389
+ const { pluginName, migrationName, upCode, downCode = "" } = args;
1417
1390
 
1418
1391
  const pluginValid = validatePluginExists(pluginName);
1419
1392
  if (!pluginValid.valid) {
@@ -1426,9 +1399,9 @@ async function addMigration(args: {
1426
1399
  mkdirSync(migrationsDir, { recursive: true });
1427
1400
  }
1428
1401
 
1429
- // Find next migration number - check both .ts and .sql files for backwards compatibility
1402
+ // Find next migration number
1430
1403
  const existing = readdirSync(migrationsDir)
1431
- .filter((f) => f.endsWith(".ts") || f.endsWith(".sql"))
1404
+ .filter((f) => f.endsWith(".ts"))
1432
1405
  .map((f) => parseInt(f.split("_")[0], 10))
1433
1406
  .filter((n) => !isNaN(n));
1434
1407
 
@@ -1436,11 +1409,7 @@ async function addMigration(args: {
1436
1409
  const numStr = String(nextNum).padStart(3, "0");
1437
1410
  const filename = `${numStr}_${migrationName}.ts`;
1438
1411
 
1439
- // Escape backticks in SQL for template literal
1440
- const escapedUpSql = upSql.replace(/`/g, "\\`");
1441
- const escapedDownSql = (downSql || "").replace(/`/g, "\\`");
1442
-
1443
- const content = `import { Kysely, sql } from "kysely";
1412
+ const content = `import { Kysely } from "kysely";
1444
1413
 
1445
1414
  /**
1446
1415
  * Migration: ${numStr}_${migrationName}
@@ -1449,11 +1418,11 @@ async function addMigration(args: {
1449
1418
  */
1450
1419
 
1451
1420
  export async function up(db: Kysely<any>): Promise<void> {
1452
- await sql\`${escapedUpSql}\`.execute(db);
1421
+ ${upCode}
1453
1422
  }
1454
1423
 
1455
1424
  export async function down(db: Kysely<any>): Promise<void> {
1456
- ${escapedDownSql ? `await sql\`${escapedDownSql}\`.execute(db);` : "// Add rollback logic here"}
1425
+ ${downCode || "// Add rollback logic here"}
1457
1426
  }
1458
1427
  `;
1459
1428
 
@@ -1464,14 +1433,27 @@ export async function down(db: Kysely<any>): Promise<void> {
1464
1433
  **Plugin:** ${pluginName}
1465
1434
  **Path:** ${projectConfig.pluginsDir}/${pluginName}/migrations/${filename}
1466
1435
 
1467
- ### Next Steps
1436
+ ### ⚠️ REQUIRED: Run Codegen
1437
+
1438
+ After creating/editing migrations, you MUST run:
1439
+ \`\`\`bash
1440
+ donkeylabs generate
1441
+ \`\`\`
1468
1442
 
1469
- 1. Review the migration
1470
- 2. Run \`donkeylabs generate\` to update schema types
1471
- 3. The migration will run automatically on server start
1443
+ This generates \`${pluginName}/schema.ts\` with typed DB interfaces.
1444
+
1445
+ ### After Codegen
1446
+
1447
+ Update the plugin to use the generated types:
1448
+ \`\`\`typescript
1449
+ import type { DB } from "./schema";
1450
+
1451
+ export const ${pluginName}Plugin = createPlugin
1452
+ .withSchema<DB>()
1453
+ .define({ ... });
1454
+ \`\`\`
1472
1455
 
1473
- ### Note
1474
- Make sure to update the plugin's schema.ts file with the new table types.
1456
+ The migration will run automatically on server start.
1475
1457
  `;
1476
1458
  }
1477
1459