@homenshum/convex-mcp-nodebench 0.9.0 → 0.9.2
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/README.md +233 -195
- package/dist/db.js +101 -101
- package/dist/index.js +41 -41
- package/dist/tools/architectTools.js +35 -31
- package/dist/tools/critterTools.js +13 -13
- package/dist/tools/learningTools.js +5 -5
- package/dist/tools/reportingTools.js +1 -1
- package/package.json +60 -60
package/README.md
CHANGED
|
@@ -1,195 +1,233 @@
|
|
|
1
|
-
# convex-mcp-nodebench
|
|
2
|
-
|
|
3
|
-
Convex-specific MCP server
|
|
4
|
-
|
|
5
|
-
**Complements** Context7 (raw library docs) and the official Convex MCP (deployment introspection) with structured verification workflows and persistent Convex knowledge.
|
|
6
|
-
|
|
7
|
-
##
|
|
8
|
-
|
|
9
|
-
###
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
| `
|
|
14
|
-
| `
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
|
18
|
-
|
|
19
|
-
| `
|
|
20
|
-
| `
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
|
29
|
-
|
|
30
|
-
| `
|
|
31
|
-
| `
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
|
35
|
-
|
|
36
|
-
| `
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
| Tool |
|
|
41
|
-
|------|-------------|
|
|
42
|
-
| `
|
|
43
|
-
| `
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
## Testing
|
|
145
|
-
|
|
146
|
-
```bash
|
|
147
|
-
npm test
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
## Architecture
|
|
153
|
-
|
|
154
|
-
```
|
|
155
|
-
packages/convex-mcp-nodebench/
|
|
156
|
-
src/
|
|
157
|
-
index.ts -- MCP server
|
|
158
|
-
db.ts -- SQLite schema + upsert seed logic
|
|
159
|
-
types.ts -- Tool types, QuickRef interface
|
|
160
|
-
gotchaSeed.ts -- 32 pre-seeded Convex gotchas
|
|
161
|
-
tools/
|
|
162
|
-
schemaTools.ts -- Schema audit, index suggestions, validator coverage
|
|
163
|
-
functionTools.ts -- Function audit, cross-call detection,
|
|
164
|
-
httpTools.ts -- HTTP endpoint analysis
|
|
165
|
-
deploymentTools.ts -- Pre-deploy gate, env var checking
|
|
166
|
-
learningTools.ts -- Gotcha recording + FTS5 search
|
|
167
|
-
methodologyTools.ts -- Methodology guides, BM25 tool discovery
|
|
168
|
-
integrationBridgeTools.ts -- Rules generation, schema snapshots
|
|
169
|
-
cronTools.ts -- Cron job validation
|
|
170
|
-
componentTools.ts -- Component config analysis
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
1
|
+
# convex-mcp-nodebench
|
|
2
|
+
|
|
3
|
+
Convex-specific MCP server that audits, verifies, and guides Convex development. 36 tools across schema audit, function compliance, security, performance, deployment gates, SARIF reporting, persistent gotcha DB, and adaptive architecture planning.
|
|
4
|
+
|
|
5
|
+
**Complements** Context7 (raw library docs) and the official Convex MCP (deployment introspection) with structured verification workflows and persistent Convex knowledge.
|
|
6
|
+
|
|
7
|
+
## 36 Tools
|
|
8
|
+
|
|
9
|
+
### Core Audit (10 tools)
|
|
10
|
+
|
|
11
|
+
| Tool | What it does |
|
|
12
|
+
|------|-------------|
|
|
13
|
+
| `convex_audit_schema` | Scan schema.ts for anti-patterns: deprecated validators, `v.any()`, reserved fields, missing indexes |
|
|
14
|
+
| `convex_suggest_indexes` | Analyze query patterns across all functions and suggest missing indexes |
|
|
15
|
+
| `convex_check_validator_coverage` | Check all exported functions have args + returns validators |
|
|
16
|
+
| `convex_audit_functions` | Audit function registration, validators, public/internal misuse, cross-call violations |
|
|
17
|
+
| `convex_check_function_refs` | Validate `api.x.y` / `internal.x.y` references, detect direct function passing |
|
|
18
|
+
| `convex_check_type_safety` | Find `as any` casts, undefined returns, loose ID types across all files |
|
|
19
|
+
| `convex_audit_authorization` | Audit auth guard coverage: which public functions check `getUserIdentity()` |
|
|
20
|
+
| `convex_audit_actions` | Audit actions for direct DB access, missing error handling, external API patterns |
|
|
21
|
+
| `convex_audit_transaction_safety` | Find read-modify-write races, multiple `runMutation` in single functions |
|
|
22
|
+
| `convex_audit_query_efficiency` | Detect unbounded `.collect()`, `.filter()` without index, mutation-as-read |
|
|
23
|
+
|
|
24
|
+
### Infrastructure Audit (9 tools)
|
|
25
|
+
|
|
26
|
+
| Tool | What it does |
|
|
27
|
+
|------|-------------|
|
|
28
|
+
| `convex_analyze_http` | Analyze http.ts: duplicate routes, missing CORS, OPTIONS preflight handlers |
|
|
29
|
+
| `convex_check_crons` | Validate crons.ts: duplicate names, public handlers, interval issues |
|
|
30
|
+
| `convex_analyze_components` | Parse convex.config.ts: active/conditional components, unused imports |
|
|
31
|
+
| `convex_audit_storage_usage` | Audit storage: stores, deletes, missing null checks on `getUrl()` |
|
|
32
|
+
| `convex_audit_pagination` | Find paginate calls missing validators or without proper cursor handling |
|
|
33
|
+
| `convex_audit_vector_search` | Audit vector indexes, search calls, dimension mismatches |
|
|
34
|
+
| `convex_audit_schedulers` | Find `runAfter`/`runAt` usage, self-scheduling loops, missing termination |
|
|
35
|
+
| `convex_audit_data_modeling` | Audit tables: deep nesting, dangling refs, `v.any()`, arrays-of-arrays |
|
|
36
|
+
| `convex_audit_dev_setup` | Check project hygiene: _generated dir, tsconfig, package deps, env files |
|
|
37
|
+
|
|
38
|
+
### Deployment & Quality Gate (4 tools)
|
|
39
|
+
|
|
40
|
+
| Tool | What it does |
|
|
41
|
+
|------|-------------|
|
|
42
|
+
| `convex_pre_deploy_gate` | Pre-deployment gate: schema, auth, validators, recent audits (blocks on critical) |
|
|
43
|
+
| `convex_check_env_vars` | Check env vars referenced in code exist in .env files (Convex-filtered) |
|
|
44
|
+
| `convex_quality_gate` | Composite quality score (A-F grade) with configurable thresholds |
|
|
45
|
+
| `convex_schema_migration_plan` | Diff schema snapshots and generate migration steps with risk assessment |
|
|
46
|
+
|
|
47
|
+
### Reporting (2 tools)
|
|
48
|
+
|
|
49
|
+
| Tool | What it does |
|
|
50
|
+
|------|-------------|
|
|
51
|
+
| `convex_export_sarif` | Export all audit results as SARIF 2.1.0 (GitHub Code Scanning compatible) |
|
|
52
|
+
| `convex_audit_diff` | Compare current audit against baseline: new issues, fixed issues, trend |
|
|
53
|
+
|
|
54
|
+
### Adaptive Architect (3 tools)
|
|
55
|
+
|
|
56
|
+
| Tool | What it does |
|
|
57
|
+
|------|-------------|
|
|
58
|
+
| `convex_scan_capabilities` | Regex scan of project structure: function types, data access, auth, storage, schema patterns |
|
|
59
|
+
| `convex_verify_concept` | Verify if a concept (e.g. "Vector Search RAG") is implemented via regex signatures |
|
|
60
|
+
| `convex_generate_plan` | Generate Convex-specific implementation steps for missing signatures |
|
|
61
|
+
|
|
62
|
+
**Self-discovery loop**: `scan_capabilities` → `verify_concept` → `generate_plan` → implement → re-verify
|
|
63
|
+
|
|
64
|
+
### Knowledge & Discovery (5 tools)
|
|
65
|
+
|
|
66
|
+
| Tool | What it does |
|
|
67
|
+
|------|-------------|
|
|
68
|
+
| `convex_record_gotcha` | Persist a Convex gotcha/edge case for future reference |
|
|
69
|
+
| `convex_search_gotchas` | Full-text search across known Convex gotchas (BM25 + FTS5) |
|
|
70
|
+
| `convex_get_methodology` | Step-by-step guides: schema audit, function compliance, deploy verification |
|
|
71
|
+
| `convex_discover_tools` | BM25 + optional embedding-enhanced semantic tool discovery |
|
|
72
|
+
| `convex_critter_check` | Accountability check: scores task intent (why/who/what) before starting work |
|
|
73
|
+
|
|
74
|
+
### Integration Bridge (3 tools)
|
|
75
|
+
|
|
76
|
+
| Tool | What it does |
|
|
77
|
+
|------|-------------|
|
|
78
|
+
| `convex_generate_rules_md` | Generate Convex rules markdown from gotcha DB, recent audits, project stats |
|
|
79
|
+
| `convex_snapshot_schema` | Capture schema snapshot for diffing (tables, indexes, size). Auto-diffs against previous |
|
|
80
|
+
| `convex_bootstrap_project` | Comprehensive project health scan with improvement plan |
|
|
81
|
+
|
|
82
|
+
## Quick Start
|
|
83
|
+
|
|
84
|
+
### Install
|
|
85
|
+
```bash
|
|
86
|
+
npm install @homenshum/convex-mcp-nodebench
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Add to MCP config (Claude Code, Cursor, Windsurf)
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"mcpServers": {
|
|
93
|
+
"convex-mcp-nodebench": {
|
|
94
|
+
"command": "npx",
|
|
95
|
+
"args": ["@homenshum/convex-mcp-nodebench"]
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### First prompt
|
|
102
|
+
```
|
|
103
|
+
Audit the schema at /path/to/my-project, then run the quality gate
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Optional: Enable semantic search
|
|
107
|
+
Set `GOOGLE_API_KEY` or `OPENAI_API_KEY` env var. The `convex_discover_tools` tool will automatically use embedding-enhanced search when available (Google `text-embedding-004` or OpenAI `text-embedding-3-small`).
|
|
108
|
+
|
|
109
|
+
## Self-Instruct QuickRefs
|
|
110
|
+
|
|
111
|
+
Every tool response includes a `quickRef` block guiding the agent to the next step:
|
|
112
|
+
|
|
113
|
+
```json
|
|
114
|
+
{
|
|
115
|
+
"nextAction": "Run convex_check_validator_coverage to ensure all functions have validators",
|
|
116
|
+
"nextTools": ["convex_check_validator_coverage", "convex_audit_functions"],
|
|
117
|
+
"methodology": "convex_schema_audit",
|
|
118
|
+
"relatedGotchas": ["returns_validator_required", "new_function_syntax"],
|
|
119
|
+
"confidence": "high"
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Pre-Seeded Gotcha Database
|
|
124
|
+
|
|
125
|
+
Ships with 32 gotchas extracted from Convex best practices, auto-upserted on upgrade:
|
|
126
|
+
|
|
127
|
+
**Critical**: `pagination_cursor_null_first`, `query_no_side_effects`, `use_node_for_external_api`, `validator_bigint_deprecated`
|
|
128
|
+
|
|
129
|
+
**Warnings**: `ctx_auth_returns_null`, `http_cors_manual`, `http_route_no_wildcard`, `avoid_v_any`, `mutation_transaction_atomicity`, `db_get_returns_null`, `storage_get_returns_null`, `convex_1mb_document_limit`, `scheduled_function_must_be_internal`, and 19 more covering index ordering, undefined handling, field naming, action patterns...
|
|
130
|
+
|
|
131
|
+
## Data Storage
|
|
132
|
+
|
|
133
|
+
Persistent SQLite at `~/.convex-mcp-nodebench/convex.db`:
|
|
134
|
+
|
|
135
|
+
| Table | Purpose |
|
|
136
|
+
|-------|---------|
|
|
137
|
+
| `convex_gotchas` | Knowledge base with FTS5 full-text search |
|
|
138
|
+
| `schema_snapshots` | Schema history for table + index diffing |
|
|
139
|
+
| `deploy_checks` | Deployment gate audit trail |
|
|
140
|
+
| `audit_results` | Per-file analysis cache |
|
|
141
|
+
| `concept_verifications` | Architect concept verification history |
|
|
142
|
+
| `critter_checks` | Task accountability records |
|
|
143
|
+
|
|
144
|
+
## Testing
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
npm test
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
63 tests (53 unit + 10 E2E) verify all 36 tools against the real nodebench-ai codebase (3,158 Convex functions, 328 tables, 82 crons, 44 HTTP routes).
|
|
151
|
+
|
|
152
|
+
## Architecture
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
packages/convex-mcp-nodebench/
|
|
156
|
+
src/
|
|
157
|
+
index.ts -- MCP server, tool assembly (36 tools)
|
|
158
|
+
db.ts -- SQLite schema + upsert seed logic
|
|
159
|
+
types.ts -- Tool types, QuickRef interface
|
|
160
|
+
gotchaSeed.ts -- 32 pre-seeded Convex gotchas
|
|
161
|
+
tools/
|
|
162
|
+
schemaTools.ts -- Schema audit, index suggestions, validator coverage
|
|
163
|
+
functionTools.ts -- Function audit, cross-call detection, ref checking
|
|
164
|
+
httpTools.ts -- HTTP endpoint analysis
|
|
165
|
+
deploymentTools.ts -- Pre-deploy gate, env var checking
|
|
166
|
+
learningTools.ts -- Gotcha recording + FTS5 search
|
|
167
|
+
methodologyTools.ts -- Methodology guides, BM25 tool discovery
|
|
168
|
+
integrationBridgeTools.ts -- Rules generation, schema snapshots, project bootstrap
|
|
169
|
+
cronTools.ts -- Cron job validation
|
|
170
|
+
componentTools.ts -- Component config analysis
|
|
171
|
+
critterTools.ts -- Task accountability checking
|
|
172
|
+
authorizationTools.ts -- Auth guard audit
|
|
173
|
+
queryEfficiencyTools.ts -- Query performance audit
|
|
174
|
+
actionAuditTools.ts -- Action anti-pattern detection
|
|
175
|
+
typeSafetyTools.ts -- Type safety audit
|
|
176
|
+
transactionSafetyTools.ts -- Transaction race detection
|
|
177
|
+
storageAuditTools.ts -- Storage usage audit
|
|
178
|
+
paginationTools.ts -- Pagination pattern audit
|
|
179
|
+
dataModelingTools.ts -- Data modeling audit
|
|
180
|
+
devSetupTools.ts -- Dev environment audit
|
|
181
|
+
migrationTools.ts -- Schema migration planning
|
|
182
|
+
reportingTools.ts -- SARIF export, baseline diff
|
|
183
|
+
vectorSearchTools.ts -- Vector search audit
|
|
184
|
+
schedulerTools.ts -- Scheduler audit
|
|
185
|
+
qualityGateTools.ts -- Composite quality gate
|
|
186
|
+
architectTools.ts -- Capability scan, concept verify, plan generation
|
|
187
|
+
toolRegistry.ts -- Central catalog with quickRef + BM25 scoring
|
|
188
|
+
embeddingProvider.ts -- Optional semantic search (Google/OpenAI embeddings)
|
|
189
|
+
__tests__/
|
|
190
|
+
tools.test.ts -- 53 unit/integration tests
|
|
191
|
+
architectE2E.test.ts -- 10 E2E tests (industry-latest concept verification)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Changelog
|
|
195
|
+
|
|
196
|
+
### v0.9.1
|
|
197
|
+
- **Fix**: Strategy matching order in architect tools -- specific patterns (`ctx.db.query`, `ctx.runMutation`) now matched before generic keywords (`query`, `mutation`)
|
|
198
|
+
|
|
199
|
+
### v0.9.0
|
|
200
|
+
- **3 new tools**: `convex_scan_capabilities`, `convex_verify_concept`, `convex_generate_plan` -- adaptive architect with Convex-specific regex patterns, strategies, and file hints
|
|
201
|
+
- **Self-discovery loop**: scan → verify → plan → implement → re-verify
|
|
202
|
+
- **7 Convex pattern categories**: function types, schema, data access, auth, storage, client-side, cross-function calls
|
|
203
|
+
- **~40 Convex-specific strategies** in `inferConvexStrategy()` with correct priority ordering
|
|
204
|
+
- **10 new E2E tests** validating architect tools against industry-latest concepts (Vector Search RAG, Real-Time Collaboration, File Upload Pipeline, Scheduled Retry Queue, Row-Level Security)
|
|
205
|
+
|
|
206
|
+
### v0.8.0
|
|
207
|
+
- **14 new tools**: authorization audit, query efficiency, action audit, type safety, transaction safety, storage audit, pagination audit, data modeling audit, dev setup audit, schema migration planning, SARIF 2.1.0 export, baseline diff, vector search audit, scheduler audit
|
|
208
|
+
- **Quality gate**: Composite A-F scoring with configurable thresholds
|
|
209
|
+
- **SARIF 2.1.0**: GitHub Code Scanning compatible export aggregating all audit types
|
|
210
|
+
- **Baseline diff**: Track audit trends (improving/stable/degrading) over time
|
|
211
|
+
- **MCP Resources**: `project-health`, `recent-audits`, `gotcha-db`
|
|
212
|
+
- **MCP Prompts**: `full-audit`, `pre-deploy-checklist`, `security-review`
|
|
213
|
+
|
|
214
|
+
### v0.4.0
|
|
215
|
+
- **New tool**: `convex_critter_check` -- task accountability with 10 calibrated checks
|
|
216
|
+
- **Cross-call fix**: improved detection of query→mutation violations
|
|
217
|
+
- **v.any() aggregation**: grouped by table for cleaner output
|
|
218
|
+
|
|
219
|
+
### v0.3.0
|
|
220
|
+
- **New tool**: `convex_analyze_http` -- HTTP endpoint analysis
|
|
221
|
+
- **Cross-call detection**: queries calling `ctx.runMutation`/`ctx.runAction` flagged as critical
|
|
222
|
+
- **12 new gotchas**: pagination, ctx.auth, scheduled functions, HTTP routes, CORS, storage, transactions
|
|
223
|
+
- **Schema snapshot diffs** track index additions/removals per table
|
|
224
|
+
- **Gotcha seeding** upgraded to upsert
|
|
225
|
+
|
|
226
|
+
### v0.2.0
|
|
227
|
+
- Schema audit noise reduced (836 -> 163 issues)
|
|
228
|
+
- Function audit severity corrected
|
|
229
|
+
- Deploy gate threshold: only blocks on >10 criticals
|
|
230
|
+
- npm tarball reduced from 45.9kB to 31.5kB
|
|
231
|
+
|
|
232
|
+
### v0.1.0
|
|
233
|
+
- Initial release: 16 tools, 20 gotchas, BM25 discovery, embedding-enhanced search
|
package/dist/db.js
CHANGED
|
@@ -3,99 +3,99 @@ import { homedir } from "node:os";
|
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { mkdirSync } from "node:fs";
|
|
5
5
|
let _db = null;
|
|
6
|
-
const SCHEMA_SQL = `
|
|
7
|
-
PRAGMA journal_mode = WAL;
|
|
8
|
-
PRAGMA busy_timeout = 5000;
|
|
9
|
-
PRAGMA foreign_keys = ON;
|
|
10
|
-
|
|
11
|
-
-- ═══════════════════════════════════════════
|
|
12
|
-
-- CONVEX GOTCHAS (Persistent knowledge base)
|
|
13
|
-
-- ═══════════════════════════════════════════
|
|
14
|
-
|
|
15
|
-
CREATE TABLE IF NOT EXISTS convex_gotchas (
|
|
16
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
17
|
-
key TEXT NOT NULL UNIQUE,
|
|
18
|
-
content TEXT NOT NULL,
|
|
19
|
-
category TEXT NOT NULL DEFAULT 'general',
|
|
20
|
-
severity TEXT NOT NULL DEFAULT 'warning',
|
|
21
|
-
convex_version TEXT,
|
|
22
|
-
tags TEXT,
|
|
23
|
-
source TEXT NOT NULL DEFAULT 'seed',
|
|
24
|
-
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
25
|
-
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
CREATE VIRTUAL TABLE IF NOT EXISTS convex_gotchas_fts USING fts5(
|
|
29
|
-
key,
|
|
30
|
-
content,
|
|
31
|
-
category,
|
|
32
|
-
tags,
|
|
33
|
-
content='convex_gotchas',
|
|
34
|
-
content_rowid='id'
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
CREATE TRIGGER IF NOT EXISTS gotchas_fts_insert AFTER INSERT ON convex_gotchas BEGIN
|
|
38
|
-
INSERT INTO convex_gotchas_fts(rowid, key, content, category, tags)
|
|
39
|
-
VALUES (new.id, new.key, new.content, new.category, COALESCE(new.tags, ''));
|
|
40
|
-
END;
|
|
41
|
-
|
|
42
|
-
CREATE TRIGGER IF NOT EXISTS gotchas_fts_delete AFTER DELETE ON convex_gotchas BEGIN
|
|
43
|
-
INSERT INTO convex_gotchas_fts(convex_gotchas_fts, rowid, key, content, category, tags)
|
|
44
|
-
VALUES ('delete', old.id, old.key, old.content, old.category, COALESCE(old.tags, ''));
|
|
45
|
-
END;
|
|
46
|
-
|
|
47
|
-
CREATE TRIGGER IF NOT EXISTS gotchas_fts_update AFTER UPDATE ON convex_gotchas BEGIN
|
|
48
|
-
INSERT INTO convex_gotchas_fts(convex_gotchas_fts, rowid, key, content, category, tags)
|
|
49
|
-
VALUES ('delete', old.id, old.key, old.content, old.category, COALESCE(old.tags, ''));
|
|
50
|
-
INSERT INTO convex_gotchas_fts(rowid, key, content, category, tags)
|
|
51
|
-
VALUES (new.id, new.key, new.content, new.category, COALESCE(new.tags, ''));
|
|
52
|
-
END;
|
|
53
|
-
|
|
54
|
-
-- ═══════════════════════════════════════════
|
|
55
|
-
-- SCHEMA SNAPSHOTS (for diff/audit history)
|
|
56
|
-
-- ═══════════════════════════════════════════
|
|
57
|
-
|
|
58
|
-
CREATE TABLE IF NOT EXISTS schema_snapshots (
|
|
59
|
-
id TEXT PRIMARY KEY,
|
|
60
|
-
project_dir TEXT NOT NULL,
|
|
61
|
-
schema_json TEXT NOT NULL,
|
|
62
|
-
function_spec TEXT,
|
|
63
|
-
snapshot_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
64
|
-
);
|
|
65
|
-
|
|
66
|
-
CREATE INDEX IF NOT EXISTS idx_schema_snapshots_project ON schema_snapshots(project_dir);
|
|
67
|
-
|
|
68
|
-
-- ═══════════════════════════════════════════
|
|
69
|
-
-- DEPLOYMENT CHECKS (audit trail)
|
|
70
|
-
-- ═══════════════════════════════════════════
|
|
71
|
-
|
|
72
|
-
CREATE TABLE IF NOT EXISTS deploy_checks (
|
|
73
|
-
id TEXT PRIMARY KEY,
|
|
74
|
-
project_dir TEXT NOT NULL,
|
|
75
|
-
check_type TEXT NOT NULL,
|
|
76
|
-
passed INTEGER NOT NULL DEFAULT 0,
|
|
77
|
-
findings TEXT,
|
|
78
|
-
checked_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
79
|
-
);
|
|
80
|
-
|
|
81
|
-
CREATE INDEX IF NOT EXISTS idx_deploy_checks_project ON deploy_checks(project_dir);
|
|
82
|
-
|
|
83
|
-
-- ═══════════════════════════════════════════
|
|
84
|
-
-- AUDIT RESULTS (per-file analysis cache)
|
|
85
|
-
-- ═══════════════════════════════════════════
|
|
86
|
-
|
|
87
|
-
CREATE TABLE IF NOT EXISTS audit_results (
|
|
88
|
-
id TEXT PRIMARY KEY,
|
|
89
|
-
project_dir TEXT NOT NULL,
|
|
90
|
-
audit_type TEXT NOT NULL,
|
|
91
|
-
file_path TEXT,
|
|
92
|
-
issues_json TEXT NOT NULL,
|
|
93
|
-
issue_count INTEGER NOT NULL DEFAULT 0,
|
|
94
|
-
audited_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
95
|
-
);
|
|
96
|
-
|
|
97
|
-
CREATE INDEX IF NOT EXISTS idx_audit_results_project ON audit_results(project_dir);
|
|
98
|
-
CREATE INDEX IF NOT EXISTS idx_audit_results_type ON audit_results(audit_type);
|
|
6
|
+
const SCHEMA_SQL = `
|
|
7
|
+
PRAGMA journal_mode = WAL;
|
|
8
|
+
PRAGMA busy_timeout = 5000;
|
|
9
|
+
PRAGMA foreign_keys = ON;
|
|
10
|
+
|
|
11
|
+
-- ═══════════════════════════════════════════
|
|
12
|
+
-- CONVEX GOTCHAS (Persistent knowledge base)
|
|
13
|
+
-- ═══════════════════════════════════════════
|
|
14
|
+
|
|
15
|
+
CREATE TABLE IF NOT EXISTS convex_gotchas (
|
|
16
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
17
|
+
key TEXT NOT NULL UNIQUE,
|
|
18
|
+
content TEXT NOT NULL,
|
|
19
|
+
category TEXT NOT NULL DEFAULT 'general',
|
|
20
|
+
severity TEXT NOT NULL DEFAULT 'warning',
|
|
21
|
+
convex_version TEXT,
|
|
22
|
+
tags TEXT,
|
|
23
|
+
source TEXT NOT NULL DEFAULT 'seed',
|
|
24
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
25
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS convex_gotchas_fts USING fts5(
|
|
29
|
+
key,
|
|
30
|
+
content,
|
|
31
|
+
category,
|
|
32
|
+
tags,
|
|
33
|
+
content='convex_gotchas',
|
|
34
|
+
content_rowid='id'
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
CREATE TRIGGER IF NOT EXISTS gotchas_fts_insert AFTER INSERT ON convex_gotchas BEGIN
|
|
38
|
+
INSERT INTO convex_gotchas_fts(rowid, key, content, category, tags)
|
|
39
|
+
VALUES (new.id, new.key, new.content, new.category, COALESCE(new.tags, ''));
|
|
40
|
+
END;
|
|
41
|
+
|
|
42
|
+
CREATE TRIGGER IF NOT EXISTS gotchas_fts_delete AFTER DELETE ON convex_gotchas BEGIN
|
|
43
|
+
INSERT INTO convex_gotchas_fts(convex_gotchas_fts, rowid, key, content, category, tags)
|
|
44
|
+
VALUES ('delete', old.id, old.key, old.content, old.category, COALESCE(old.tags, ''));
|
|
45
|
+
END;
|
|
46
|
+
|
|
47
|
+
CREATE TRIGGER IF NOT EXISTS gotchas_fts_update AFTER UPDATE ON convex_gotchas BEGIN
|
|
48
|
+
INSERT INTO convex_gotchas_fts(convex_gotchas_fts, rowid, key, content, category, tags)
|
|
49
|
+
VALUES ('delete', old.id, old.key, old.content, old.category, COALESCE(old.tags, ''));
|
|
50
|
+
INSERT INTO convex_gotchas_fts(rowid, key, content, category, tags)
|
|
51
|
+
VALUES (new.id, new.key, new.content, new.category, COALESCE(new.tags, ''));
|
|
52
|
+
END;
|
|
53
|
+
|
|
54
|
+
-- ═══════════════════════════════════════════
|
|
55
|
+
-- SCHEMA SNAPSHOTS (for diff/audit history)
|
|
56
|
+
-- ═══════════════════════════════════════════
|
|
57
|
+
|
|
58
|
+
CREATE TABLE IF NOT EXISTS schema_snapshots (
|
|
59
|
+
id TEXT PRIMARY KEY,
|
|
60
|
+
project_dir TEXT NOT NULL,
|
|
61
|
+
schema_json TEXT NOT NULL,
|
|
62
|
+
function_spec TEXT,
|
|
63
|
+
snapshot_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
CREATE INDEX IF NOT EXISTS idx_schema_snapshots_project ON schema_snapshots(project_dir);
|
|
67
|
+
|
|
68
|
+
-- ═══════════════════════════════════════════
|
|
69
|
+
-- DEPLOYMENT CHECKS (audit trail)
|
|
70
|
+
-- ═══════════════════════════════════════════
|
|
71
|
+
|
|
72
|
+
CREATE TABLE IF NOT EXISTS deploy_checks (
|
|
73
|
+
id TEXT PRIMARY KEY,
|
|
74
|
+
project_dir TEXT NOT NULL,
|
|
75
|
+
check_type TEXT NOT NULL,
|
|
76
|
+
passed INTEGER NOT NULL DEFAULT 0,
|
|
77
|
+
findings TEXT,
|
|
78
|
+
checked_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
CREATE INDEX IF NOT EXISTS idx_deploy_checks_project ON deploy_checks(project_dir);
|
|
82
|
+
|
|
83
|
+
-- ═══════════════════════════════════════════
|
|
84
|
+
-- AUDIT RESULTS (per-file analysis cache)
|
|
85
|
+
-- ═══════════════════════════════════════════
|
|
86
|
+
|
|
87
|
+
CREATE TABLE IF NOT EXISTS audit_results (
|
|
88
|
+
id TEXT PRIMARY KEY,
|
|
89
|
+
project_dir TEXT NOT NULL,
|
|
90
|
+
audit_type TEXT NOT NULL,
|
|
91
|
+
file_path TEXT,
|
|
92
|
+
issues_json TEXT NOT NULL,
|
|
93
|
+
issue_count INTEGER NOT NULL DEFAULT 0,
|
|
94
|
+
audited_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
CREATE INDEX IF NOT EXISTS idx_audit_results_project ON audit_results(project_dir);
|
|
98
|
+
CREATE INDEX IF NOT EXISTS idx_audit_results_type ON audit_results(audit_type);
|
|
99
99
|
`;
|
|
100
100
|
export function getDb() {
|
|
101
101
|
if (_db)
|
|
@@ -112,14 +112,14 @@ export function genId(prefix) {
|
|
|
112
112
|
export function seedGotchasIfEmpty(gotchas) {
|
|
113
113
|
const db = getDb();
|
|
114
114
|
// Upsert: insert new seed gotchas, skip user-created ones (source != 'seed')
|
|
115
|
-
const upsert = db.prepare(`INSERT INTO convex_gotchas (key, content, category, severity, tags, source)
|
|
116
|
-
VALUES (?, ?, ?, ?, ?, 'seed')
|
|
117
|
-
ON CONFLICT(key) DO UPDATE SET
|
|
118
|
-
content = excluded.content,
|
|
119
|
-
category = excluded.category,
|
|
120
|
-
severity = excluded.severity,
|
|
121
|
-
tags = excluded.tags,
|
|
122
|
-
updated_at = datetime('now')
|
|
115
|
+
const upsert = db.prepare(`INSERT INTO convex_gotchas (key, content, category, severity, tags, source)
|
|
116
|
+
VALUES (?, ?, ?, ?, ?, 'seed')
|
|
117
|
+
ON CONFLICT(key) DO UPDATE SET
|
|
118
|
+
content = excluded.content,
|
|
119
|
+
category = excluded.category,
|
|
120
|
+
severity = excluded.severity,
|
|
121
|
+
tags = excluded.tags,
|
|
122
|
+
updated_at = datetime('now')
|
|
123
123
|
WHERE source = 'seed'`);
|
|
124
124
|
const tx = db.transaction(() => {
|
|
125
125
|
for (const g of gotchas) {
|
package/dist/index.js
CHANGED
|
@@ -79,7 +79,7 @@ for (const tool of ALL_TOOLS) {
|
|
|
79
79
|
// ── Server setup ────────────────────────────────────────────────────
|
|
80
80
|
const server = new Server({
|
|
81
81
|
name: "convex-mcp-nodebench",
|
|
82
|
-
version: "0.9.
|
|
82
|
+
version: "0.9.2",
|
|
83
83
|
}, {
|
|
84
84
|
capabilities: {
|
|
85
85
|
tools: {},
|
|
@@ -328,27 +328,27 @@ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
|
328
328
|
role: "user",
|
|
329
329
|
content: {
|
|
330
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
|
|
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
352
|
- Trend direction if previous audits exist (use convex_audit_diff)`,
|
|
353
353
|
},
|
|
354
354
|
},
|
|
@@ -363,16 +363,16 @@ After running all audits, summarize:
|
|
|
363
363
|
role: "user",
|
|
364
364
|
content: {
|
|
365
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
|
-
|
|
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
376
|
Report: DEPLOY or DO NOT DEPLOY with specific blockers to fix.`,
|
|
377
377
|
},
|
|
378
378
|
},
|
|
@@ -387,15 +387,15 @@ Report: DEPLOY or DO NOT DEPLOY with specific blockers to fix.`,
|
|
|
387
387
|
role: "user",
|
|
388
388
|
content: {
|
|
389
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
|
-
|
|
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
399
|
Focus on: unauthorized data access, unvalidated inputs, missing error boundaries, and potential data corruption vectors.`,
|
|
400
400
|
},
|
|
401
401
|
},
|
|
@@ -444,24 +444,15 @@ function inferConvexStrategy(signature) {
|
|
|
444
444
|
return "Wrap optional fields with v.optional() — avoids runtime errors on missing fields";
|
|
445
445
|
if (/v\.union/i.test(lower))
|
|
446
446
|
return "Use v.union() for discriminated types — add a 'type' field as discriminator for type safety";
|
|
447
|
-
//
|
|
448
|
-
if (/internalmutation/i.test(lower))
|
|
449
|
-
return "Create internalMutation — only callable by other server functions, not from client. Import from _generated/server";
|
|
450
|
-
if (/internalaction/i.test(lower))
|
|
451
|
-
return "Create internalAction — for server-side-only work like API calls. Cannot access ctx.db directly, use ctx.runMutation/ctx.runQuery";
|
|
452
|
-
if (/internalquery/i.test(lower))
|
|
453
|
-
return "Create internalQuery — server-side-only reads. Not subscribable from client";
|
|
454
|
-
if (/httpaction/i.test(lower))
|
|
455
|
-
return "Create httpAction in http.ts — register with httpRouter.route({ method, path, handler })";
|
|
456
|
-
if (/mutation\b/i.test(lower))
|
|
457
|
-
return "Create public mutation — add args validator, return validator, and auth check (ctx.auth.getUserIdentity)";
|
|
458
|
-
if (/action\b/i.test(lower))
|
|
459
|
-
return "Create public action — for external API calls. Wrap in try/catch, use ctx.runMutation for DB writes";
|
|
460
|
-
if (/query\b/i.test(lower))
|
|
461
|
-
return "Create public query — reactive subscription from client. Must be deterministic, no side effects";
|
|
462
|
-
// Data access
|
|
447
|
+
// Data access (BEFORE generic function types — ctx.db.query must match before query)
|
|
463
448
|
if (/ctx\.db\.query/i.test(lower))
|
|
464
449
|
return "Add ctx.db.query('table') — chain .withIndex() for indexed lookups (avoid full-table .filter())";
|
|
450
|
+
if (/ctx\.db\.insert/i.test(lower))
|
|
451
|
+
return "Use ctx.db.insert('table', { ...fields }) — within a mutation for transactional guarantee";
|
|
452
|
+
if (/ctx\.db\.patch/i.test(lower))
|
|
453
|
+
return "Use ctx.db.patch(id, { ...fields }) — partial update, only specified fields change";
|
|
454
|
+
if (/ctx\.db\.delete/i.test(lower))
|
|
455
|
+
return "Use ctx.db.delete(id) — remember to clean up related records and storage files";
|
|
465
456
|
if (/withindex/i.test(lower))
|
|
466
457
|
return "Use .withIndex('indexName', q => q.eq('field', value)) — ensure index exists in schema.ts first";
|
|
467
458
|
if (/withsearchindex/i.test(lower))
|
|
@@ -470,30 +461,31 @@ function inferConvexStrategy(signature) {
|
|
|
470
461
|
return "Add .collect() to get all results — WARNING: add .take(limit) for bounded queries to avoid scanning entire table";
|
|
471
462
|
if (/\.paginate\b/i.test(lower))
|
|
472
463
|
return "Use .paginate(opts) with paginationOptsValidator in args — return { page, isDone, continueCursor }";
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
464
|
+
// Cross-function calls (BEFORE generic function types — ctx.runMutation must match before mutation)
|
|
465
|
+
if (/ctx\.runmutation|runmutation/i.test(lower))
|
|
466
|
+
return "Use ctx.runMutation(internal.module.functionName, args) — prefer internal functions for server-to-server mutation calls";
|
|
467
|
+
if (/ctx\.runquery|runquery/i.test(lower))
|
|
468
|
+
return "Use ctx.runQuery(internal.module.functionName, args) — prefer internal functions for server-to-server query calls";
|
|
469
|
+
if (/ctx\.runaction|runaction/i.test(lower))
|
|
470
|
+
return "Use ctx.runAction(internal.module.functionName, args) — prefer internal functions for server-to-server action calls";
|
|
471
|
+
// Auth (BEFORE generic function types)
|
|
480
472
|
if (/getuseridentity/i.test(lower))
|
|
481
473
|
return "Add `const identity = await ctx.auth.getUserIdentity()` — throw if null for protected endpoints";
|
|
482
474
|
if (/identity.*check|if.*identity/i.test(lower))
|
|
483
475
|
return "Add identity null check after getUserIdentity() — return 401/throw for unauthenticated users";
|
|
484
|
-
// Scheduler
|
|
476
|
+
// Scheduler (BEFORE generic function types)
|
|
485
477
|
if (/scheduler.*runafter/i.test(lower))
|
|
486
478
|
return "Add ctx.scheduler.runAfter(delayMs, api.module.functionName, args) — use at least 1s delay for retries, add termination condition for loops";
|
|
487
479
|
if (/scheduler.*runat/i.test(lower))
|
|
488
480
|
return "Add ctx.scheduler.runAt(timestamp, api.module.functionName, args) — use for one-time future execution";
|
|
489
|
-
// Storage
|
|
481
|
+
// Storage (BEFORE generic function types)
|
|
482
|
+
if (/storage.*generateuploadurl/i.test(lower))
|
|
483
|
+
return "Use ctx.storage.generateUploadUrl() in a mutation — return URL to client for direct upload";
|
|
490
484
|
if (/storage.*store/i.test(lower))
|
|
491
485
|
return "Use ctx.storage.store(blob) — returns storageId, save it to a document for later retrieval";
|
|
492
486
|
if (/storage.*geturl/i.test(lower))
|
|
493
487
|
return "Use ctx.storage.getUrl(storageId) — returns URL or null, always null-check the result";
|
|
494
|
-
|
|
495
|
-
return "Use ctx.storage.generateUploadUrl() in a mutation — return URL to client for direct upload";
|
|
496
|
-
// Client-side
|
|
488
|
+
// Client-side (BEFORE generic function types — useQuery before query)
|
|
497
489
|
if (/usequery/i.test(lower))
|
|
498
490
|
return "Add useQuery(api.module.queryName, args) — reactive subscription, re-renders on data change";
|
|
499
491
|
if (/usemutation/i.test(lower))
|
|
@@ -502,9 +494,21 @@ function inferConvexStrategy(signature) {
|
|
|
502
494
|
return "Add useAction(api.module.actionName) — returns async function, use for external API calls";
|
|
503
495
|
if (/convexprovider|convexreactclient/i.test(lower))
|
|
504
496
|
return "Wrap app with <ConvexProvider client={convex}> — create client with new ConvexReactClient(url)";
|
|
505
|
-
//
|
|
506
|
-
if (/
|
|
507
|
-
return "
|
|
497
|
+
// Function types (GENERIC — must come AFTER all specific patterns above)
|
|
498
|
+
if (/internalmutation/i.test(lower))
|
|
499
|
+
return "Create internalMutation — only callable by other server functions, not from client. Import from _generated/server";
|
|
500
|
+
if (/internalaction/i.test(lower))
|
|
501
|
+
return "Create internalAction — for server-side-only work like API calls. Cannot access ctx.db directly, use ctx.runMutation/ctx.runQuery";
|
|
502
|
+
if (/internalquery/i.test(lower))
|
|
503
|
+
return "Create internalQuery — server-side-only reads. Not subscribable from client";
|
|
504
|
+
if (/httpaction/i.test(lower))
|
|
505
|
+
return "Create httpAction in http.ts — register with httpRouter.route({ method, path, handler })";
|
|
506
|
+
if (/mutation\b/i.test(lower))
|
|
507
|
+
return "Create public mutation — add args validator, return validator, and auth check (ctx.auth.getUserIdentity)";
|
|
508
|
+
if (/action\b/i.test(lower))
|
|
509
|
+
return "Create public action — for external API calls. Wrap in try/catch, use ctx.runMutation for DB writes";
|
|
510
|
+
if (/query\b/i.test(lower))
|
|
511
|
+
return "Create public query — reactive subscription from client. Must be deterministic, no side effects";
|
|
508
512
|
return "Inject this pattern into the appropriate Convex file — check existing patterns with convex_scan_capabilities first";
|
|
509
513
|
}
|
|
510
514
|
function inferTargetFile(signature) {
|
|
@@ -12,18 +12,18 @@ import { getDb } from "../db.js";
|
|
|
12
12
|
// ── DB setup ────────────────────────────────────────────────────────────────
|
|
13
13
|
function ensureCritterTable() {
|
|
14
14
|
const db = getDb();
|
|
15
|
-
db.exec(`
|
|
16
|
-
CREATE TABLE IF NOT EXISTS critter_checks (
|
|
17
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
18
|
-
task TEXT NOT NULL,
|
|
19
|
-
why TEXT NOT NULL,
|
|
20
|
-
who TEXT NOT NULL,
|
|
21
|
-
success_looks_like TEXT,
|
|
22
|
-
score INTEGER NOT NULL,
|
|
23
|
-
verdict TEXT NOT NULL,
|
|
24
|
-
feedback TEXT NOT NULL,
|
|
25
|
-
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
26
|
-
)
|
|
15
|
+
db.exec(`
|
|
16
|
+
CREATE TABLE IF NOT EXISTS critter_checks (
|
|
17
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
18
|
+
task TEXT NOT NULL,
|
|
19
|
+
why TEXT NOT NULL,
|
|
20
|
+
who TEXT NOT NULL,
|
|
21
|
+
success_looks_like TEXT,
|
|
22
|
+
score INTEGER NOT NULL,
|
|
23
|
+
verdict TEXT NOT NULL,
|
|
24
|
+
feedback TEXT NOT NULL,
|
|
25
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
26
|
+
)
|
|
27
27
|
`);
|
|
28
28
|
}
|
|
29
29
|
function scoreCritterCheck(input) {
|
|
@@ -188,7 +188,7 @@ export const critterTools = [
|
|
|
188
188
|
ensureCritterTable();
|
|
189
189
|
const result = scoreCritterCheck(args);
|
|
190
190
|
const db = getDb();
|
|
191
|
-
db.prepare(`INSERT INTO critter_checks (task, why, who, success_looks_like, score, verdict, feedback)
|
|
191
|
+
db.prepare(`INSERT INTO critter_checks (task, why, who, success_looks_like, score, verdict, feedback)
|
|
192
192
|
VALUES (?, ?, ?, ?, ?, ?, ?)`).run(args.task, args.why, args.who, args.success_looks_like ?? null, result.score, result.verdict, JSON.stringify(result.feedback));
|
|
193
193
|
return {
|
|
194
194
|
score: result.score,
|
|
@@ -80,11 +80,11 @@ export const learningTools = [
|
|
|
80
80
|
let results;
|
|
81
81
|
try {
|
|
82
82
|
// FTS5 search
|
|
83
|
-
let sql = `
|
|
84
|
-
SELECT g.*, rank
|
|
85
|
-
FROM convex_gotchas g
|
|
86
|
-
JOIN convex_gotchas_fts fts ON g.id = fts.rowid
|
|
87
|
-
WHERE convex_gotchas_fts MATCH ?
|
|
83
|
+
let sql = `
|
|
84
|
+
SELECT g.*, rank
|
|
85
|
+
FROM convex_gotchas g
|
|
86
|
+
JOIN convex_gotchas_fts fts ON g.id = fts.rowid
|
|
87
|
+
WHERE convex_gotchas_fts MATCH ?
|
|
88
88
|
`;
|
|
89
89
|
const params = [args.query];
|
|
90
90
|
if (args.category) {
|
|
@@ -75,7 +75,7 @@ function buildSarif(projectDir, auditTypes, limit) {
|
|
|
75
75
|
tool: {
|
|
76
76
|
driver: {
|
|
77
77
|
name: "convex-mcp-nodebench",
|
|
78
|
-
version: "0.9.
|
|
78
|
+
version: "0.9.2",
|
|
79
79
|
informationUri: "https://www.npmjs.com/package/@homenshum/convex-mcp-nodebench",
|
|
80
80
|
rules: [...rulesMap.values()],
|
|
81
81
|
},
|
package/package.json
CHANGED
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@homenshum/convex-mcp-nodebench",
|
|
3
|
-
"version": "0.9.
|
|
4
|
-
"description": "Convex-specific MCP server applying NodeBench self-instruct diligence patterns to Convex development. Schema audit, function compliance, deployment gates, persistent gotcha DB, and methodology guidance. Complements Context7 (raw docs) and official Convex MCP (deployment introspection) with structured verification workflows.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"bin": {
|
|
7
|
-
"convex-mcp-nodebench": "./dist/index.js"
|
|
8
|
-
},
|
|
9
|
-
"main": "./dist/index.js",
|
|
10
|
-
"files": [
|
|
11
|
-
"dist/**/*.js",
|
|
12
|
-
"dist/**/*.d.ts",
|
|
13
|
-
"!dist/__tests__",
|
|
14
|
-
"README.md"
|
|
15
|
-
],
|
|
16
|
-
"scripts": {
|
|
17
|
-
"build": "tsc",
|
|
18
|
-
"dev": "tsx src/index.ts",
|
|
19
|
-
"test": "vitest run",
|
|
20
|
-
"test:watch": "vitest",
|
|
21
|
-
"prepublishOnly": "npm run build && npm run test"
|
|
22
|
-
},
|
|
23
|
-
"keywords": [
|
|
24
|
-
"mcp",
|
|
25
|
-
"convex",
|
|
26
|
-
"model-context-protocol",
|
|
27
|
-
"schema-audit",
|
|
28
|
-
"function-compliance",
|
|
29
|
-
"deploy-gates",
|
|
30
|
-
"gotcha-db",
|
|
31
|
-
"self-instruct",
|
|
32
|
-
"ai-agents",
|
|
33
|
-
"verification"
|
|
34
|
-
],
|
|
35
|
-
"repository": {
|
|
36
|
-
"type": "git",
|
|
37
|
-
"url": "https://github.com/HomenShum/nodebench-ai.git",
|
|
38
|
-
"directory": "packages/convex-mcp-nodebench"
|
|
39
|
-
},
|
|
40
|
-
"license": "MIT",
|
|
41
|
-
"author": "HomenShum",
|
|
42
|
-
"dependencies": {
|
|
43
|
-
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
44
|
-
"better-sqlite3": "^11.0.0"
|
|
45
|
-
},
|
|
46
|
-
"optionalDependencies": {
|
|
47
|
-
"@google/genai": "^1.10.0",
|
|
48
|
-
"openai": "^5.8.2"
|
|
49
|
-
},
|
|
50
|
-
"devDependencies": {
|
|
51
|
-
"@types/better-sqlite3": "^7.6.0",
|
|
52
|
-
"@types/node": "^20.11.0",
|
|
53
|
-
"tsx": "^4.7.0",
|
|
54
|
-
"typescript": "^5.3.3",
|
|
55
|
-
"vitest": "^3.2.4"
|
|
56
|
-
},
|
|
57
|
-
"engines": {
|
|
58
|
-
"node": ">=18.0.0"
|
|
59
|
-
}
|
|
60
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@homenshum/convex-mcp-nodebench",
|
|
3
|
+
"version": "0.9.2",
|
|
4
|
+
"description": "Convex-specific MCP server applying NodeBench self-instruct diligence patterns to Convex development. Schema audit, function compliance, deployment gates, persistent gotcha DB, and methodology guidance. Complements Context7 (raw docs) and official Convex MCP (deployment introspection) with structured verification workflows.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"convex-mcp-nodebench": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist/**/*.js",
|
|
12
|
+
"dist/**/*.d.ts",
|
|
13
|
+
"!dist/__tests__",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsc",
|
|
18
|
+
"dev": "tsx src/index.ts",
|
|
19
|
+
"test": "vitest run",
|
|
20
|
+
"test:watch": "vitest",
|
|
21
|
+
"prepublishOnly": "npm run build && npm run test"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"mcp",
|
|
25
|
+
"convex",
|
|
26
|
+
"model-context-protocol",
|
|
27
|
+
"schema-audit",
|
|
28
|
+
"function-compliance",
|
|
29
|
+
"deploy-gates",
|
|
30
|
+
"gotcha-db",
|
|
31
|
+
"self-instruct",
|
|
32
|
+
"ai-agents",
|
|
33
|
+
"verification"
|
|
34
|
+
],
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "https://github.com/HomenShum/nodebench-ai.git",
|
|
38
|
+
"directory": "packages/convex-mcp-nodebench"
|
|
39
|
+
},
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"author": "HomenShum",
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
44
|
+
"better-sqlite3": "^11.0.0"
|
|
45
|
+
},
|
|
46
|
+
"optionalDependencies": {
|
|
47
|
+
"@google/genai": "^1.10.0",
|
|
48
|
+
"openai": "^5.8.2"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@types/better-sqlite3": "^7.6.0",
|
|
52
|
+
"@types/node": "^20.11.0",
|
|
53
|
+
"tsx": "^4.7.0",
|
|
54
|
+
"typescript": "^5.3.3",
|
|
55
|
+
"vitest": "^3.2.4"
|
|
56
|
+
},
|
|
57
|
+
"engines": {
|
|
58
|
+
"node": ">=18.0.0"
|
|
59
|
+
}
|
|
60
|
+
}
|