@donkeylabs/mcp 0.4.6 → 0.4.7

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 +124 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@donkeylabs/mcp",
3
- "version": "0.4.6",
3
+ "version": "0.4.7",
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
@@ -516,6 +516,66 @@ async function generateProjectAnalysis(): Promise<string> {
516
516
  analysis += `- Not generated yet. Run \`donkeylabs generate\` after adding plugins/routes.\n`;
517
517
  }
518
518
 
519
+ // Generated API Client
520
+ const clientPath = projectConfig.clientOutput || (projectConfig.adapter === "sveltekit" ? "src/lib/api.ts" : null);
521
+ if (clientPath) {
522
+ const fullClientPath = join(projectRoot, clientPath);
523
+ analysis += `\n## Generated API Client\n`;
524
+ if (existsSync(fullClientPath)) {
525
+ analysis += `- Path: ${clientPath}\n`;
526
+
527
+ // Extract available methods from the client
528
+ const clientContent = readFileSync(fullClientPath, "utf-8");
529
+
530
+ // Find namespace properties (e.g., "health = {" or "users = {")
531
+ const namespaceMatches = [...clientContent.matchAll(/^\s+(\w+)\s*=\s*\{/gm)];
532
+ const namespaces: string[] = [];
533
+ for (const match of namespaceMatches) {
534
+ if (match[1] && !["sse", "constructor"].includes(match[1])) {
535
+ namespaces.push(match[1]);
536
+ }
537
+ }
538
+
539
+ if (namespaces.length > 0) {
540
+ analysis += `- Available namespaces: ${namespaces.join(", ")}\n`;
541
+ }
542
+
543
+ // Extract route type namespaces from "export namespace Routes {"
544
+ const routeTypesMatch = clientContent.match(/export namespace Routes \{([^}]+(?:\{[^}]*\}[^}]*)*)\}/s);
545
+ if (routeTypesMatch) {
546
+ const typeNamespaces = [...routeTypesMatch[1].matchAll(/export namespace (\w+)/g)].map(m => m[1]);
547
+ if (typeNamespaces.length > 0) {
548
+ analysis += `- Route types: Routes.${typeNamespaces.join(", Routes.")}\n`;
549
+ }
550
+ }
551
+
552
+ // SvelteKit-specific usage
553
+ if (projectConfig.adapter === "sveltekit") {
554
+ const importPath = clientPath.startsWith("src/lib/") ? "$lib/" + clientPath.slice(8).replace(/\.ts$/, "") : clientPath.replace(/\.ts$/, "");
555
+ analysis += `\n### Usage in SvelteKit\n`;
556
+ analysis += `\`\`\`typescript\n`;
557
+ analysis += `// +page.server.ts (SSR - direct calls, no HTTP)\n`;
558
+ analysis += `import { createApi } from '${importPath}';\n`;
559
+ analysis += `export const load = async ({ locals }) => {\n`;
560
+ analysis += ` const api = createApi({ locals });\n`;
561
+ analysis += ` const data = await api.${namespaces[0] || "namespace"}.methodName({});\n`;
562
+ analysis += ` return { data };\n`;
563
+ analysis += `};\n`;
564
+ analysis += `\`\`\`\n`;
565
+ analysis += `\n\`\`\`svelte\n`;
566
+ analysis += `<!-- +page.svelte (Browser - HTTP calls) -->\n`;
567
+ analysis += `<script>\n`;
568
+ analysis += ` import { createApi } from '${importPath}';\n`;
569
+ analysis += ` const api = createApi();\n`;
570
+ analysis += `</script>\n`;
571
+ analysis += `\`\`\`\n`;
572
+ }
573
+ } else {
574
+ analysis += `- Path: ${clientPath} (not generated yet)\n`;
575
+ analysis += `- Run \`donkeylabs generate\` to create the client\n`;
576
+ }
577
+ }
578
+
519
579
  return analysis;
520
580
  }
521
581
 
@@ -1098,6 +1158,48 @@ async function getArchitectureGuidance(args: { task: string }): Promise<string>
1098
1158
  guidance += `- **Browser:** HTTP calls automatically\n`;
1099
1159
  }
1100
1160
 
1161
+ // Common mistakes section
1162
+ guidance += `\n## ⚠️ Common Mistakes to Avoid\n\n`;
1163
+
1164
+ guidance += `### Database Queries\n`;
1165
+ guidance += `- ❌ **NEVER use raw SQL** - always use Kysely query builder\n`;
1166
+ guidance += `- ❌ \`db.execute(sql\\\`SELECT * FROM users\\\`)\` - WRONG\n`;
1167
+ guidance += `- ✅ \`db.selectFrom("users").selectAll().execute()\` - CORRECT\n\n`;
1168
+
1169
+ guidance += `### After Making Changes\n`;
1170
+ guidance += `- ❌ Forgetting to run \`generate_types\` after adding migrations\n`;
1171
+ guidance += `- ❌ Forgetting to run \`generate_client\` after adding routes\n`;
1172
+ guidance += `- ✅ Always regenerate types after schema/route changes\n\n`;
1173
+
1174
+ guidance += `### Plugin Registration\n`;
1175
+ guidance += `- ❌ Creating a plugin but not registering it with \`server.registerPlugin()\`\n`;
1176
+ guidance += `- ❌ Creating routes but not adding router with \`server.use()\`\n`;
1177
+ guidance += `- ✅ Check server entry file to ensure plugin/router is registered\n\n`;
1178
+
1179
+ if (projectConfig.adapter === "sveltekit") {
1180
+ guidance += `### SvelteKit-Specific\n`;
1181
+ guidance += `- ❌ \`createApi()\` in +page.server.ts - WRONG (won't use direct calls)\n`;
1182
+ guidance += `- ✅ \`createApi({ locals })\` in +page.server.ts - CORRECT\n`;
1183
+ guidance += `- ❌ Importing from relative path instead of \`$lib/api\`\n`;
1184
+ guidance += `- ✅ \`import { createApi } from '$lib/api'\`\n\n`;
1185
+ }
1186
+
1187
+ guidance += `### Route Handlers\n`;
1188
+ guidance += `- ❌ Putting business logic directly in route handlers\n`;
1189
+ guidance += `- ✅ Delegate to plugin service methods, keep routes thin\n`;
1190
+ guidance += `- ❌ Returning raw data without proper typing\n`;
1191
+ guidance += `- ✅ Define output schema with Zod for type safety\n\n`;
1192
+
1193
+ guidance += `## 🛑 When to Stop and Ask the User\n\n`;
1194
+ guidance += `**IMPORTANT:** If you're unsure about any of the following, STOP and ask the user before proceeding:\n\n`;
1195
+ guidance += `- **Architecture decisions** - "Should this be a plugin or just a route?"\n`;
1196
+ guidance += `- **Database schema design** - "What columns/relations do you need?"\n`;
1197
+ guidance += `- **Naming conventions** - "What should this entity/route be called?"\n`;
1198
+ guidance += `- **Business logic** - "How should this calculation/validation work?"\n`;
1199
+ guidance += `- **Integration patterns** - "How does this connect to existing code?"\n`;
1200
+ guidance += `- **Something doesn't work** - Don't keep trying different things, ask for help\n\n`;
1201
+ guidance += `It's better to ask ONE clarifying question than to build something wrong and have to redo it.\n\n`;
1202
+
1101
1203
  guidance += `\n## Documentation Resources\n`;
1102
1204
  guidance += `- \`donkeylabs://docs/database\` - Kysely queries, CRUD, joins, transactions\n`;
1103
1205
  guidance += `- \`donkeylabs://docs/plugins\` - Plugin patterns & When to Create a Plugin vs Route\n`;
@@ -1303,6 +1405,11 @@ ${registrationExample}
1303
1405
  // In your route handler:
1304
1406
  const result = ctx.plugins.${name}.hello();
1305
1407
  \`\`\`
1408
+
1409
+ ### ⚠️ Reminders
1410
+ - **Don't forget** to register the plugin in your server entry file
1411
+ - **Use Kysely** for all database queries, never raw SQL
1412
+ - **Ask the user** if you're unsure about the schema design or business logic
1306
1413
  `;
1307
1414
  }
1308
1415
 
@@ -1454,6 +1561,11 @@ export const ${pluginName}Plugin = createPlugin
1454
1561
  \`\`\`
1455
1562
 
1456
1563
  The migration will run automatically on server start.
1564
+
1565
+ ### ⚠️ Reminders
1566
+ - **Use Kysely schema builder** - never raw SQL in migrations
1567
+ - **Ask the user** if unsure about column types, relations, or schema design
1568
+ - **Test migrations** by running the server and checking for errors
1457
1569
  `;
1458
1570
  }
1459
1571
 
@@ -1532,6 +1644,11 @@ Routes added to this router will be named \`${prefix}.<routeName>\`:
1532
1644
  - ${prefix}.list
1533
1645
  - ${prefix}.get
1534
1646
  - ${prefix}.create
1647
+
1648
+ ### ⚠️ Reminders
1649
+ - **Don't forget** to register the router with \`server.use()\` in your server entry
1650
+ - **Run \`generate_client\`** after adding routes to update the typed client
1651
+ - **Keep routes thin** - delegate business logic to plugin service methods
1535
1652
  `;
1536
1653
  }
1537
1654
 
@@ -1679,8 +1796,14 @@ ${outputType ? `\n**Output:** ${outputType}` : ""}
1679
1796
  ### Next Steps
1680
1797
 
1681
1798
  1. ${useClassHandler ? "Implement the handler logic in the handler file" : "The route is ready to use"}
1682
- 2. Run \`donkeylabs generate\` to update types
1799
+ 2. Run \`donkeylabs generate\` to update types and regenerate the API client
1683
1800
  3. Test the route
1801
+
1802
+ ### ⚠️ Reminders
1803
+ - **Run \`generate_client\`** to update the typed API client after adding routes
1804
+ - **Keep handler thin** - call plugin service methods for business logic
1805
+ - **Use Kysely** for database queries in your service methods, never raw SQL
1806
+ ${projectConfig.adapter === "sveltekit" ? "- **SvelteKit:** Use \\`createApi({ locals })\\` in +page.server.ts for direct calls" : ""}
1684
1807
  `;
1685
1808
  }
1686
1809