@homenshum/convex-mcp-nodebench 0.7.0 → 0.9.0

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.
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@
14
14
  */
15
15
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
16
16
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
17
- import { ListToolsRequestSchema, CallToolRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
17
+ import { ListToolsRequestSchema, CallToolRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
18
18
  import { getDb, seedGotchasIfEmpty } from "./db.js";
19
19
  import { schemaTools } from "./tools/schemaTools.js";
20
20
  import { functionTools } from "./tools/functionTools.js";
@@ -36,6 +36,11 @@ import { paginationTools } from "./tools/paginationTools.js";
36
36
  import { dataModelingTools } from "./tools/dataModelingTools.js";
37
37
  import { devSetupTools } from "./tools/devSetupTools.js";
38
38
  import { migrationTools } from "./tools/migrationTools.js";
39
+ import { reportingTools } from "./tools/reportingTools.js";
40
+ import { vectorSearchTools } from "./tools/vectorSearchTools.js";
41
+ import { schedulerTools } from "./tools/schedulerTools.js";
42
+ import { qualityGateTools } from "./tools/qualityGateTools.js";
43
+ import { architectTools } from "./tools/architectTools.js";
39
44
  import { CONVEX_GOTCHAS } from "./gotchaSeed.js";
40
45
  import { REGISTRY } from "./tools/toolRegistry.js";
41
46
  import { initEmbeddingIndex } from "./tools/embeddingProvider.js";
@@ -61,6 +66,11 @@ const ALL_TOOLS = [
61
66
  ...dataModelingTools,
62
67
  ...devSetupTools,
63
68
  ...migrationTools,
69
+ ...reportingTools,
70
+ ...vectorSearchTools,
71
+ ...schedulerTools,
72
+ ...qualityGateTools,
73
+ ...architectTools,
64
74
  ];
65
75
  const toolMap = new Map();
66
76
  for (const tool of ALL_TOOLS) {
@@ -69,10 +79,12 @@ for (const tool of ALL_TOOLS) {
69
79
  // ── Server setup ────────────────────────────────────────────────────
70
80
  const server = new Server({
71
81
  name: "convex-mcp-nodebench",
72
- version: "0.1.0",
82
+ version: "0.9.0",
73
83
  }, {
74
84
  capabilities: {
75
85
  tools: {},
86
+ resources: {},
87
+ prompts: {},
76
88
  },
77
89
  });
78
90
  // ── Initialize DB + seed gotchas ────────────────────────────────────
@@ -169,6 +181,235 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
169
181
  };
170
182
  }
171
183
  });
184
+ // ── MCP Resources ───────────────────────────────────────────────────
185
+ server.setRequestHandler(ListResourcesRequestSchema, async () => {
186
+ return {
187
+ resources: [
188
+ {
189
+ uri: "convex://project-health",
190
+ name: "Project Health Summary",
191
+ description: "Latest quality gate score, audit coverage, and issue counts across all audit types",
192
+ mimeType: "application/json",
193
+ },
194
+ {
195
+ uri: "convex://recent-audits",
196
+ name: "Recent Audit Results",
197
+ description: "Summary of the 10 most recent audit runs with issue counts and timestamps",
198
+ mimeType: "application/json",
199
+ },
200
+ {
201
+ uri: "convex://gotcha-db",
202
+ name: "Gotcha Knowledge Base",
203
+ description: "All stored Convex gotchas (seeded + user-recorded) with categories and severity",
204
+ mimeType: "application/json",
205
+ },
206
+ ],
207
+ };
208
+ });
209
+ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
210
+ const uri = request.params.uri;
211
+ const db = getDb();
212
+ if (uri === "convex://project-health") {
213
+ // Aggregate across all projects
214
+ const audits = db.prepare("SELECT audit_type, issue_count, audited_at FROM audit_results ORDER BY audited_at DESC LIMIT 50").all();
215
+ const byType = {};
216
+ for (const a of audits) {
217
+ if (!byType[a.audit_type]) {
218
+ byType[a.audit_type] = { count: a.issue_count, latest: a.audited_at };
219
+ }
220
+ }
221
+ const totalIssues = Object.values(byType).reduce((s, v) => s + v.count, 0);
222
+ const auditTypes = Object.keys(byType).length;
223
+ const latestGate = db.prepare("SELECT findings FROM deploy_checks WHERE check_type = 'quality_gate' ORDER BY checked_at DESC LIMIT 1").get();
224
+ let gateResult = null;
225
+ if (latestGate?.findings) {
226
+ try {
227
+ gateResult = JSON.parse(latestGate.findings);
228
+ }
229
+ catch { /* skip */ }
230
+ }
231
+ return {
232
+ contents: [{
233
+ uri,
234
+ mimeType: "application/json",
235
+ text: JSON.stringify({
236
+ totalIssues,
237
+ auditTypesRun: auditTypes,
238
+ issuesByType: byType,
239
+ latestQualityGate: gateResult ? { score: gateResult.score, grade: gateResult.grade, passed: gateResult.passed } : null,
240
+ toolCount: ALL_TOOLS.length,
241
+ }, null, 2),
242
+ }],
243
+ };
244
+ }
245
+ if (uri === "convex://recent-audits") {
246
+ const audits = db.prepare("SELECT id, project_dir, audit_type, issue_count, audited_at FROM audit_results ORDER BY audited_at DESC LIMIT 10").all();
247
+ return {
248
+ contents: [{
249
+ uri,
250
+ mimeType: "application/json",
251
+ text: JSON.stringify({ audits }, null, 2),
252
+ }],
253
+ };
254
+ }
255
+ if (uri === "convex://gotcha-db") {
256
+ const gotchas = db.prepare("SELECT key, category, severity, tags, source, updated_at FROM convex_gotchas ORDER BY updated_at DESC").all();
257
+ return {
258
+ contents: [{
259
+ uri,
260
+ mimeType: "application/json",
261
+ text: JSON.stringify({
262
+ totalGotchas: gotchas.length,
263
+ bySource: {
264
+ seed: gotchas.filter(g => g.source === "seed").length,
265
+ user: gotchas.filter(g => g.source === "user").length,
266
+ },
267
+ gotchas,
268
+ }, null, 2),
269
+ }],
270
+ };
271
+ }
272
+ return {
273
+ contents: [{
274
+ uri,
275
+ mimeType: "text/plain",
276
+ text: `Unknown resource: ${uri}`,
277
+ }],
278
+ };
279
+ });
280
+ // ── MCP Prompts ─────────────────────────────────────────────────────
281
+ server.setRequestHandler(ListPromptsRequestSchema, async () => {
282
+ return {
283
+ prompts: [
284
+ {
285
+ name: "full-audit",
286
+ description: "Run a complete Convex project audit: schema, functions, auth, queries, actions, type safety, transactions, storage, pagination, data modeling, dev setup, vectors, schedulers — then quality gate",
287
+ arguments: [
288
+ {
289
+ name: "projectDir",
290
+ description: "Absolute path to the project root",
291
+ required: true,
292
+ },
293
+ ],
294
+ },
295
+ {
296
+ name: "pre-deploy-checklist",
297
+ description: "Step-by-step pre-deployment verification: audit critical issues, check env vars, review migration plan, run quality gate",
298
+ arguments: [
299
+ {
300
+ name: "projectDir",
301
+ description: "Absolute path to the project root",
302
+ required: true,
303
+ },
304
+ ],
305
+ },
306
+ {
307
+ name: "security-review",
308
+ description: "Security-focused audit: authorization coverage, type safety, action safety, storage permissions",
309
+ arguments: [
310
+ {
311
+ name: "projectDir",
312
+ description: "Absolute path to the project root",
313
+ required: true,
314
+ },
315
+ ],
316
+ },
317
+ ],
318
+ };
319
+ });
320
+ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
321
+ const { name, arguments: promptArgs } = request.params;
322
+ const projectDir = promptArgs?.projectDir ?? ".";
323
+ if (name === "full-audit") {
324
+ return {
325
+ description: "Complete Convex project audit sequence",
326
+ messages: [
327
+ {
328
+ role: "user",
329
+ content: {
330
+ type: "text",
331
+ text: `Run a complete audit of the Convex project at "${projectDir}". Execute these tools in order:
332
+
333
+ 1. convex_audit_schema — Check schema.ts for anti-patterns
334
+ 2. convex_audit_functions — Audit function registration and compliance
335
+ 3. convex_audit_authorization — Check auth coverage on public endpoints
336
+ 4. convex_audit_query_efficiency — Find unbounded queries and missing indexes
337
+ 5. convex_audit_actions — Validate action safety (no ctx.db, error handling)
338
+ 6. convex_check_type_safety — Find as-any casts and type issues
339
+ 7. convex_audit_transaction_safety — Detect race conditions
340
+ 8. convex_audit_storage_usage — Check file storage patterns
341
+ 9. convex_audit_pagination — Validate pagination implementations
342
+ 10. convex_audit_data_modeling — Check schema design quality
343
+ 11. convex_audit_vector_search — Validate vector search setup
344
+ 12. convex_audit_schedulers — Check scheduled function safety
345
+ 13. convex_audit_dev_setup — Verify project setup
346
+ 14. convex_quality_gate — Run configurable quality gate across all results
347
+
348
+ After running all audits, summarize:
349
+ - Total issues by severity (critical/warning/info)
350
+ - Top 5 most impactful issues to fix first
351
+ - Quality gate score and grade
352
+ - Trend direction if previous audits exist (use convex_audit_diff)`,
353
+ },
354
+ },
355
+ ],
356
+ };
357
+ }
358
+ if (name === "pre-deploy-checklist") {
359
+ return {
360
+ description: "Pre-deployment verification sequence",
361
+ messages: [
362
+ {
363
+ role: "user",
364
+ content: {
365
+ type: "text",
366
+ text: `Run pre-deployment checks for the Convex project at "${projectDir}":
367
+
368
+ 1. convex_pre_deploy_gate — Structural checks (schema, auth config, initialization)
369
+ 2. convex_check_env_vars — Verify all required env vars are set
370
+ 3. convex_audit_authorization — Ensure auth coverage is adequate
371
+ 4. convex_audit_actions — No ctx.db access in actions
372
+ 5. convex_snapshot_schema — Capture current schema state
373
+ 6. convex_schema_migration_plan — Compare against previous snapshot for breaking changes
374
+ 7. convex_quality_gate — Final quality check with thresholds
375
+
376
+ Report: DEPLOY or DO NOT DEPLOY with specific blockers to fix.`,
377
+ },
378
+ },
379
+ ],
380
+ };
381
+ }
382
+ if (name === "security-review") {
383
+ return {
384
+ description: "Security-focused audit sequence",
385
+ messages: [
386
+ {
387
+ role: "user",
388
+ content: {
389
+ type: "text",
390
+ text: `Run a security review of the Convex project at "${projectDir}":
391
+
392
+ 1. convex_audit_authorization — Auth coverage on all public endpoints
393
+ 2. convex_check_type_safety — Type safety bypasses (as any)
394
+ 3. convex_audit_actions — Action safety (ctx.db, error handling, "use node")
395
+ 4. convex_audit_storage_usage — Storage permission patterns
396
+ 5. convex_audit_pagination — Unbounded numItems (DoS risk)
397
+ 6. convex_audit_transaction_safety — Race condition risks
398
+
399
+ Focus on: unauthorized data access, unvalidated inputs, missing error boundaries, and potential data corruption vectors.`,
400
+ },
401
+ },
402
+ ],
403
+ };
404
+ }
405
+ return {
406
+ description: "Unknown prompt",
407
+ messages: [{
408
+ role: "user",
409
+ content: { type: "text", text: `Unknown prompt: ${name}` },
410
+ }],
411
+ };
412
+ });
172
413
  // ── Start server ────────────────────────────────────────────────────
173
414
  async function main() {
174
415
  const transport = new StdioServerTransport();
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Architect Tools — Structural code analysis for Convex projects.
3
+ *
4
+ * Convex-specific variant of the mcp-local architect tools. Instead of
5
+ * generic React/Express patterns, these scan for Convex function types,
6
+ * schema constructs, data access patterns, auth guards, storage usage,
7
+ * scheduler calls, and client-side hooks.
8
+ *
9
+ * 3 tools:
10
+ * - convex_scan_capabilities: Analyze a file for Convex structural patterns
11
+ * - convex_verify_concept: Check if a file has required code signatures
12
+ * - convex_generate_plan: Build a plan for missing signatures
13
+ */
14
+ import type { McpTool } from "../types.js";
15
+ export declare const architectTools: McpTool[];