@homenshum/convex-mcp-nodebench 0.1.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/README.md +137 -0
- package/dist/__tests__/tools.test.d.ts +1 -0
- package/dist/__tests__/tools.test.js +267 -0
- package/dist/__tests__/tools.test.js.map +1 -0
- package/dist/db.d.ts +10 -0
- package/dist/db.js +125 -0
- package/dist/db.js.map +1 -0
- package/dist/gotchaSeed.d.ts +126 -0
- package/dist/gotchaSeed.js +147 -0
- package/dist/gotchaSeed.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +118 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/componentTools.d.ts +2 -0
- package/dist/tools/componentTools.js +131 -0
- package/dist/tools/componentTools.js.map +1 -0
- package/dist/tools/cronTools.d.ts +2 -0
- package/dist/tools/cronTools.js +142 -0
- package/dist/tools/cronTools.js.map +1 -0
- package/dist/tools/deploymentTools.d.ts +2 -0
- package/dist/tools/deploymentTools.js +222 -0
- package/dist/tools/deploymentTools.js.map +1 -0
- package/dist/tools/functionTools.d.ts +2 -0
- package/dist/tools/functionTools.js +293 -0
- package/dist/tools/functionTools.js.map +1 -0
- package/dist/tools/integrationBridgeTools.d.ts +2 -0
- package/dist/tools/integrationBridgeTools.js +294 -0
- package/dist/tools/integrationBridgeTools.js.map +1 -0
- package/dist/tools/learningTools.d.ts +2 -0
- package/dist/tools/learningTools.js +155 -0
- package/dist/tools/learningTools.js.map +1 -0
- package/dist/tools/methodologyTools.d.ts +2 -0
- package/dist/tools/methodologyTools.js +163 -0
- package/dist/tools/methodologyTools.js.map +1 -0
- package/dist/tools/schemaTools.d.ts +2 -0
- package/dist/tools/schemaTools.js +346 -0
- package/dist/tools/schemaTools.js.map +1 -0
- package/dist/tools/toolRegistry.d.ts +5 -0
- package/dist/tools/toolRegistry.js +308 -0
- package/dist/tools/toolRegistry.js.map +1 -0
- package/dist/types.d.ts +44 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pre-seeded Convex gotchas extracted from convexRules.md and common patterns.
|
|
3
|
+
* These are loaded into the DB on first run.
|
|
4
|
+
*/
|
|
5
|
+
export declare const CONVEX_GOTCHAS: readonly [{
|
|
6
|
+
readonly key: "validator_bigint_deprecated";
|
|
7
|
+
readonly content: "v.bigint() is deprecated for representing signed 64-bit integers. Use v.int64() instead.";
|
|
8
|
+
readonly category: "validator";
|
|
9
|
+
readonly severity: "critical";
|
|
10
|
+
readonly tags: "bigint,int64,deprecated,validator";
|
|
11
|
+
}, {
|
|
12
|
+
readonly key: "undefined_not_valid";
|
|
13
|
+
readonly content: "JavaScript's undefined is not a valid Convex value. Functions that return undefined or do not return will return null when called from a client. Use null instead of undefined.";
|
|
14
|
+
readonly category: "validator";
|
|
15
|
+
readonly severity: "critical";
|
|
16
|
+
readonly tags: "undefined,null,return,value";
|
|
17
|
+
}, {
|
|
18
|
+
readonly key: "system_fields_auto";
|
|
19
|
+
readonly content: "_creationTime (v.number()) and _id (v.id(tableName)) are automatically added to all documents as system fields. Do not include them in your schema definition.";
|
|
20
|
+
readonly category: "schema";
|
|
21
|
+
readonly severity: "warning";
|
|
22
|
+
readonly tags: "_creationTime,_id,system,fields,schema";
|
|
23
|
+
}, {
|
|
24
|
+
readonly key: "index_field_order";
|
|
25
|
+
readonly content: "Index fields must be queried in the same order they are defined. If you want to query by field1 then field2 AND by field2 then field1, you must create separate indexes.";
|
|
26
|
+
readonly category: "schema";
|
|
27
|
+
readonly severity: "critical";
|
|
28
|
+
readonly tags: "index,order,query,field";
|
|
29
|
+
}, {
|
|
30
|
+
readonly key: "no_map_set_validators";
|
|
31
|
+
readonly content: "v.map() and v.set() are not supported. Use v.record(keys, values) for defining record types instead.";
|
|
32
|
+
readonly category: "validator";
|
|
33
|
+
readonly severity: "critical";
|
|
34
|
+
readonly tags: "map,set,record,validator,unsupported";
|
|
35
|
+
}, {
|
|
36
|
+
readonly key: "action_from_action";
|
|
37
|
+
readonly content: "Only call an action from another action if you need to cross runtimes (e.g. from V8 to Node). Otherwise, extract the shared code into a helper async function and call that directly.";
|
|
38
|
+
readonly category: "function";
|
|
39
|
+
readonly severity: "warning";
|
|
40
|
+
readonly tags: "action,runtime,v8,node,helper";
|
|
41
|
+
}, {
|
|
42
|
+
readonly key: "function_ref_not_direct";
|
|
43
|
+
readonly content: "Use api.x.y or internal.x.y function references when calling ctx.runQuery/runMutation/runAction. Do NOT try to pass the callee function directly.";
|
|
44
|
+
readonly category: "function";
|
|
45
|
+
readonly severity: "critical";
|
|
46
|
+
readonly tags: "function,reference,api,internal,runQuery";
|
|
47
|
+
}, {
|
|
48
|
+
readonly key: "new_function_syntax";
|
|
49
|
+
readonly content: "Always use the new function syntax: query({ args: {}, returns: v.null(), handler: async (ctx, args) => { } }). The old style without args/returns objects is deprecated.";
|
|
50
|
+
readonly category: "function";
|
|
51
|
+
readonly severity: "critical";
|
|
52
|
+
readonly tags: "syntax,query,mutation,action,args,returns";
|
|
53
|
+
}, {
|
|
54
|
+
readonly key: "internal_for_private";
|
|
55
|
+
readonly content: "Use internalQuery, internalMutation, and internalAction to register internal functions. These are private and not part of the app's public API. Use query/mutation/action only for functions that should be exposed publicly.";
|
|
56
|
+
readonly category: "function";
|
|
57
|
+
readonly severity: "warning";
|
|
58
|
+
readonly tags: "internal,private,public,security,api";
|
|
59
|
+
}, {
|
|
60
|
+
readonly key: "returns_validator_required";
|
|
61
|
+
readonly content: "Always include argument and return validators for ALL Convex functions (query, internalQuery, mutation, internalMutation, action, internalAction). If a function doesn't return anything, use returns: v.null().";
|
|
62
|
+
readonly category: "function";
|
|
63
|
+
readonly severity: "critical";
|
|
64
|
+
readonly tags: "returns,validator,null,args,required";
|
|
65
|
+
}, {
|
|
66
|
+
readonly key: "no_register_via_api";
|
|
67
|
+
readonly content: "You CANNOT register a function through the api or internal objects. These are only for referencing already-registered functions.";
|
|
68
|
+
readonly category: "function";
|
|
69
|
+
readonly severity: "critical";
|
|
70
|
+
readonly tags: "register,api,internal,function";
|
|
71
|
+
}, {
|
|
72
|
+
readonly key: "circular_type_annotation";
|
|
73
|
+
readonly content: "When using ctx.runQuery, ctx.runMutation, or ctx.runAction to call a function in the same file, specify a type annotation on the return value to work around TypeScript circularity limitations.";
|
|
74
|
+
readonly category: "function";
|
|
75
|
+
readonly severity: "warning";
|
|
76
|
+
readonly tags: "circular,type,annotation,typescript,same-file";
|
|
77
|
+
}, {
|
|
78
|
+
readonly key: "array_max_8192";
|
|
79
|
+
readonly content: "Arrays can have at most 8192 values in Convex.";
|
|
80
|
+
readonly category: "validator";
|
|
81
|
+
readonly severity: "warning";
|
|
82
|
+
readonly tags: "array,limit,8192,size";
|
|
83
|
+
}, {
|
|
84
|
+
readonly key: "object_max_1024";
|
|
85
|
+
readonly content: "Objects can have at most 1024 entries in Convex.";
|
|
86
|
+
readonly category: "validator";
|
|
87
|
+
readonly severity: "warning";
|
|
88
|
+
readonly tags: "object,limit,1024,entries";
|
|
89
|
+
}, {
|
|
90
|
+
readonly key: "field_no_dollar_underscore";
|
|
91
|
+
readonly content: "Field names must be nonempty and not start with '$' or '_'. These prefixes are reserved for system use.";
|
|
92
|
+
readonly category: "schema";
|
|
93
|
+
readonly severity: "critical";
|
|
94
|
+
readonly tags: "field,name,dollar,underscore,reserved";
|
|
95
|
+
}, {
|
|
96
|
+
readonly key: "index_name_include_fields";
|
|
97
|
+
readonly content: "Always include all index fields in the index name. For example, if an index is defined as ['field1', 'field2'], the index name should be 'by_field1_and_field2'.";
|
|
98
|
+
readonly category: "schema";
|
|
99
|
+
readonly severity: "info";
|
|
100
|
+
readonly tags: "index,name,convention,fields";
|
|
101
|
+
}, {
|
|
102
|
+
readonly key: "http_exact_path";
|
|
103
|
+
readonly content: "HTTP endpoints are always registered at the exact path you specify. For example, /api/someRoute registers at /api/someRoute, not as a prefix match.";
|
|
104
|
+
readonly category: "function";
|
|
105
|
+
readonly severity: "info";
|
|
106
|
+
readonly tags: "http,path,route,endpoint,exact";
|
|
107
|
+
}, {
|
|
108
|
+
readonly key: "record_key_restrictions";
|
|
109
|
+
readonly content: "Record keys must be only ASCII characters, nonempty, and not start with '$' or '_'.";
|
|
110
|
+
readonly category: "validator";
|
|
111
|
+
readonly severity: "warning";
|
|
112
|
+
readonly tags: "record,key,ascii,restriction";
|
|
113
|
+
}, {
|
|
114
|
+
readonly key: "string_utf8_1mb";
|
|
115
|
+
readonly content: "Strings are stored as UTF-8 and must be valid Unicode sequences. Strings must be smaller than the 1MB total size limit when encoded as UTF-8.";
|
|
116
|
+
readonly category: "validator";
|
|
117
|
+
readonly severity: "info";
|
|
118
|
+
readonly tags: "string,utf8,size,limit,1mb";
|
|
119
|
+
}, {
|
|
120
|
+
readonly key: "minimize_action_to_query_calls";
|
|
121
|
+
readonly content: "Try to use as few calls from actions to queries and mutations as possible. Queries and mutations are transactions, so splitting logic into multiple calls introduces race condition risk.";
|
|
122
|
+
readonly category: "function";
|
|
123
|
+
readonly severity: "warning";
|
|
124
|
+
readonly tags: "action,query,mutation,transaction,race,condition";
|
|
125
|
+
}];
|
|
126
|
+
export type ConvexGotcha = typeof CONVEX_GOTCHAS[number];
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pre-seeded Convex gotchas extracted from convexRules.md and common patterns.
|
|
3
|
+
* These are loaded into the DB on first run.
|
|
4
|
+
*/
|
|
5
|
+
export const CONVEX_GOTCHAS = [
|
|
6
|
+
{
|
|
7
|
+
key: "validator_bigint_deprecated",
|
|
8
|
+
content: "v.bigint() is deprecated for representing signed 64-bit integers. Use v.int64() instead.",
|
|
9
|
+
category: "validator",
|
|
10
|
+
severity: "critical",
|
|
11
|
+
tags: "bigint,int64,deprecated,validator",
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
key: "undefined_not_valid",
|
|
15
|
+
content: "JavaScript's undefined is not a valid Convex value. Functions that return undefined or do not return will return null when called from a client. Use null instead of undefined.",
|
|
16
|
+
category: "validator",
|
|
17
|
+
severity: "critical",
|
|
18
|
+
tags: "undefined,null,return,value",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
key: "system_fields_auto",
|
|
22
|
+
content: "_creationTime (v.number()) and _id (v.id(tableName)) are automatically added to all documents as system fields. Do not include them in your schema definition.",
|
|
23
|
+
category: "schema",
|
|
24
|
+
severity: "warning",
|
|
25
|
+
tags: "_creationTime,_id,system,fields,schema",
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
key: "index_field_order",
|
|
29
|
+
content: "Index fields must be queried in the same order they are defined. If you want to query by field1 then field2 AND by field2 then field1, you must create separate indexes.",
|
|
30
|
+
category: "schema",
|
|
31
|
+
severity: "critical",
|
|
32
|
+
tags: "index,order,query,field",
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
key: "no_map_set_validators",
|
|
36
|
+
content: "v.map() and v.set() are not supported. Use v.record(keys, values) for defining record types instead.",
|
|
37
|
+
category: "validator",
|
|
38
|
+
severity: "critical",
|
|
39
|
+
tags: "map,set,record,validator,unsupported",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
key: "action_from_action",
|
|
43
|
+
content: "Only call an action from another action if you need to cross runtimes (e.g. from V8 to Node). Otherwise, extract the shared code into a helper async function and call that directly.",
|
|
44
|
+
category: "function",
|
|
45
|
+
severity: "warning",
|
|
46
|
+
tags: "action,runtime,v8,node,helper",
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
key: "function_ref_not_direct",
|
|
50
|
+
content: "Use api.x.y or internal.x.y function references when calling ctx.runQuery/runMutation/runAction. Do NOT try to pass the callee function directly.",
|
|
51
|
+
category: "function",
|
|
52
|
+
severity: "critical",
|
|
53
|
+
tags: "function,reference,api,internal,runQuery",
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
key: "new_function_syntax",
|
|
57
|
+
content: "Always use the new function syntax: query({ args: {}, returns: v.null(), handler: async (ctx, args) => { } }). The old style without args/returns objects is deprecated.",
|
|
58
|
+
category: "function",
|
|
59
|
+
severity: "critical",
|
|
60
|
+
tags: "syntax,query,mutation,action,args,returns",
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
key: "internal_for_private",
|
|
64
|
+
content: "Use internalQuery, internalMutation, and internalAction to register internal functions. These are private and not part of the app's public API. Use query/mutation/action only for functions that should be exposed publicly.",
|
|
65
|
+
category: "function",
|
|
66
|
+
severity: "warning",
|
|
67
|
+
tags: "internal,private,public,security,api",
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
key: "returns_validator_required",
|
|
71
|
+
content: "Always include argument and return validators for ALL Convex functions (query, internalQuery, mutation, internalMutation, action, internalAction). If a function doesn't return anything, use returns: v.null().",
|
|
72
|
+
category: "function",
|
|
73
|
+
severity: "critical",
|
|
74
|
+
tags: "returns,validator,null,args,required",
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
key: "no_register_via_api",
|
|
78
|
+
content: "You CANNOT register a function through the api or internal objects. These are only for referencing already-registered functions.",
|
|
79
|
+
category: "function",
|
|
80
|
+
severity: "critical",
|
|
81
|
+
tags: "register,api,internal,function",
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
key: "circular_type_annotation",
|
|
85
|
+
content: "When using ctx.runQuery, ctx.runMutation, or ctx.runAction to call a function in the same file, specify a type annotation on the return value to work around TypeScript circularity limitations.",
|
|
86
|
+
category: "function",
|
|
87
|
+
severity: "warning",
|
|
88
|
+
tags: "circular,type,annotation,typescript,same-file",
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
key: "array_max_8192",
|
|
92
|
+
content: "Arrays can have at most 8192 values in Convex.",
|
|
93
|
+
category: "validator",
|
|
94
|
+
severity: "warning",
|
|
95
|
+
tags: "array,limit,8192,size",
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
key: "object_max_1024",
|
|
99
|
+
content: "Objects can have at most 1024 entries in Convex.",
|
|
100
|
+
category: "validator",
|
|
101
|
+
severity: "warning",
|
|
102
|
+
tags: "object,limit,1024,entries",
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
key: "field_no_dollar_underscore",
|
|
106
|
+
content: "Field names must be nonempty and not start with '$' or '_'. These prefixes are reserved for system use.",
|
|
107
|
+
category: "schema",
|
|
108
|
+
severity: "critical",
|
|
109
|
+
tags: "field,name,dollar,underscore,reserved",
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
key: "index_name_include_fields",
|
|
113
|
+
content: "Always include all index fields in the index name. For example, if an index is defined as ['field1', 'field2'], the index name should be 'by_field1_and_field2'.",
|
|
114
|
+
category: "schema",
|
|
115
|
+
severity: "info",
|
|
116
|
+
tags: "index,name,convention,fields",
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
key: "http_exact_path",
|
|
120
|
+
content: "HTTP endpoints are always registered at the exact path you specify. For example, /api/someRoute registers at /api/someRoute, not as a prefix match.",
|
|
121
|
+
category: "function",
|
|
122
|
+
severity: "info",
|
|
123
|
+
tags: "http,path,route,endpoint,exact",
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
key: "record_key_restrictions",
|
|
127
|
+
content: "Record keys must be only ASCII characters, nonempty, and not start with '$' or '_'.",
|
|
128
|
+
category: "validator",
|
|
129
|
+
severity: "warning",
|
|
130
|
+
tags: "record,key,ascii,restriction",
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
key: "string_utf8_1mb",
|
|
134
|
+
content: "Strings are stored as UTF-8 and must be valid Unicode sequences. Strings must be smaller than the 1MB total size limit when encoded as UTF-8.",
|
|
135
|
+
category: "validator",
|
|
136
|
+
severity: "info",
|
|
137
|
+
tags: "string,utf8,size,limit,1mb",
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
key: "minimize_action_to_query_calls",
|
|
141
|
+
content: "Try to use as few calls from actions to queries and mutations as possible. Queries and mutations are transactions, so splitting logic into multiple calls introduces race condition risk.",
|
|
142
|
+
category: "function",
|
|
143
|
+
severity: "warning",
|
|
144
|
+
tags: "action,query,mutation,transaction,race,condition",
|
|
145
|
+
},
|
|
146
|
+
];
|
|
147
|
+
//# sourceMappingURL=gotchaSeed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gotchaSeed.js","sourceRoot":"","sources":["../src/gotchaSeed.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* convex-mcp-nodebench — Convex-Specific MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Applies NodeBench self-instruct diligence patterns to Convex development.
|
|
6
|
+
* Schema audit, function compliance, deployment gates, persistent gotcha DB,
|
|
7
|
+
* and methodology guidance.
|
|
8
|
+
*
|
|
9
|
+
* Data stored in ~/.convex-mcp-nodebench/convex.db
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* npx convex-mcp-nodebench (stdio transport)
|
|
13
|
+
* npx tsx src/index.ts (dev mode)
|
|
14
|
+
*/
|
|
15
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* convex-mcp-nodebench — Convex-Specific MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Applies NodeBench self-instruct diligence patterns to Convex development.
|
|
6
|
+
* Schema audit, function compliance, deployment gates, persistent gotcha DB,
|
|
7
|
+
* and methodology guidance.
|
|
8
|
+
*
|
|
9
|
+
* Data stored in ~/.convex-mcp-nodebench/convex.db
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* npx convex-mcp-nodebench (stdio transport)
|
|
13
|
+
* npx tsx src/index.ts (dev mode)
|
|
14
|
+
*/
|
|
15
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
16
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
17
|
+
import { ListToolsRequestSchema, CallToolRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
18
|
+
import { getDb, seedGotchasIfEmpty } from "./db.js";
|
|
19
|
+
import { schemaTools } from "./tools/schemaTools.js";
|
|
20
|
+
import { functionTools } from "./tools/functionTools.js";
|
|
21
|
+
import { deploymentTools } from "./tools/deploymentTools.js";
|
|
22
|
+
import { learningTools } from "./tools/learningTools.js";
|
|
23
|
+
import { methodologyTools } from "./tools/methodologyTools.js";
|
|
24
|
+
import { integrationBridgeTools } from "./tools/integrationBridgeTools.js";
|
|
25
|
+
import { cronTools } from "./tools/cronTools.js";
|
|
26
|
+
import { componentTools } from "./tools/componentTools.js";
|
|
27
|
+
import { CONVEX_GOTCHAS } from "./gotchaSeed.js";
|
|
28
|
+
// ── All tools ───────────────────────────────────────────────────────
|
|
29
|
+
const ALL_TOOLS = [
|
|
30
|
+
...schemaTools,
|
|
31
|
+
...functionTools,
|
|
32
|
+
...deploymentTools,
|
|
33
|
+
...learningTools,
|
|
34
|
+
...methodologyTools,
|
|
35
|
+
...integrationBridgeTools,
|
|
36
|
+
...cronTools,
|
|
37
|
+
...componentTools,
|
|
38
|
+
];
|
|
39
|
+
const toolMap = new Map();
|
|
40
|
+
for (const tool of ALL_TOOLS) {
|
|
41
|
+
toolMap.set(tool.name, tool);
|
|
42
|
+
}
|
|
43
|
+
// ── Server setup ────────────────────────────────────────────────────
|
|
44
|
+
const server = new Server({
|
|
45
|
+
name: "convex-mcp-nodebench",
|
|
46
|
+
version: "0.1.0",
|
|
47
|
+
}, {
|
|
48
|
+
capabilities: {
|
|
49
|
+
tools: {},
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
// ── Initialize DB + seed gotchas ────────────────────────────────────
|
|
53
|
+
getDb();
|
|
54
|
+
seedGotchasIfEmpty(CONVEX_GOTCHAS);
|
|
55
|
+
// ── Tool listing ────────────────────────────────────────────────────
|
|
56
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
57
|
+
return {
|
|
58
|
+
tools: ALL_TOOLS.map((t) => ({
|
|
59
|
+
name: t.name,
|
|
60
|
+
description: t.description,
|
|
61
|
+
inputSchema: t.inputSchema,
|
|
62
|
+
})),
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
// ── Tool execution ──────────────────────────────────────────────────
|
|
66
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
67
|
+
const { name, arguments: args } = request.params;
|
|
68
|
+
const tool = toolMap.get(name);
|
|
69
|
+
if (!tool) {
|
|
70
|
+
return {
|
|
71
|
+
content: [
|
|
72
|
+
{
|
|
73
|
+
type: "text",
|
|
74
|
+
text: JSON.stringify({
|
|
75
|
+
error: `Unknown tool: ${name}`,
|
|
76
|
+
availableTools: ALL_TOOLS.map((t) => t.name),
|
|
77
|
+
}),
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
try {
|
|
83
|
+
const result = await tool.handler(args || {});
|
|
84
|
+
return {
|
|
85
|
+
content: [
|
|
86
|
+
{
|
|
87
|
+
type: "text",
|
|
88
|
+
text: JSON.stringify(result, null, 2),
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
return {
|
|
95
|
+
content: [
|
|
96
|
+
{
|
|
97
|
+
type: "text",
|
|
98
|
+
text: JSON.stringify({
|
|
99
|
+
error: error.message || String(error),
|
|
100
|
+
tool: name,
|
|
101
|
+
}),
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
isError: true,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
// ── Start server ────────────────────────────────────────────────────
|
|
109
|
+
async function main() {
|
|
110
|
+
const transport = new StdioServerTransport();
|
|
111
|
+
await server.connect(transport);
|
|
112
|
+
// Server is now running on stdio
|
|
113
|
+
}
|
|
114
|
+
main().catch((error) => {
|
|
115
|
+
console.error("Fatal error:", error);
|
|
116
|
+
process.exit(1);
|
|
117
|
+
});
|
|
118
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGjD,uEAAuE;AAEvE,MAAM,SAAS,GAAc;IAC3B,GAAG,WAAW;IACd,GAAG,aAAa;IAChB,GAAG,eAAe;IAClB,GAAG,aAAa;IAChB,GAAG,gBAAgB;IACnB,GAAG,sBAAsB;IACzB,GAAG,SAAS;IACZ,GAAG,cAAc;CAClB,CAAC;AAEF,MAAM,OAAO,GAAG,IAAI,GAAG,EAAmB,CAAC;AAC3C,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;IAC7B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED,uEAAuE;AAEvE,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB;IACE,IAAI,EAAE,sBAAsB;IAC5B,OAAO,EAAE,OAAO;CACjB,EACD;IACE,YAAY,EAAE;QACZ,KAAK,EAAE,EAAE;KACV;CACF,CACF,CAAC;AAEF,uEAAuE;AAEvE,KAAK,EAAE,CAAC;AACR,kBAAkB,CAAC,cAMjB,CAAC,CAAC;AAEJ,uEAAuE;AAEvE,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;IAC1D,OAAO;QACL,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC3B,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,WAAW,EAAE,CAAC,CAAC,WAAW;SAC3B,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,uEAAuE;AAEvE,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IAChE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IACjD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAE/B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,KAAK,EAAE,iBAAiB,IAAI,EAAE;wBAC9B,cAAc,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;qBAC7C,CAAC;iBACH;aACF;SACF,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QAC9C,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;iBACtC;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,KAAK,EAAE,KAAK,CAAC,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC;wBACrC,IAAI,EAAE,IAAI;qBACX,CAAC;iBACH;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,uEAAuE;AAEvE,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,iCAAiC;AACnC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import { getQuickRef } from "./toolRegistry.js";
|
|
4
|
+
// ── Helpers ──────────────────────────────────────────────────────────
|
|
5
|
+
function findConvexDir(projectDir) {
|
|
6
|
+
const candidates = [join(projectDir, "convex"), join(projectDir, "src", "convex")];
|
|
7
|
+
for (const c of candidates) {
|
|
8
|
+
if (existsSync(c))
|
|
9
|
+
return c;
|
|
10
|
+
}
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
function parseConvexConfig(content) {
|
|
14
|
+
const components = [];
|
|
15
|
+
const issues = [];
|
|
16
|
+
const lines = content.split("\n");
|
|
17
|
+
// Find all import lines for convex.config
|
|
18
|
+
const importPattern = /import\s+(\w+)\s+from\s+["'](@[\w/-]+)\/convex\.config["']/g;
|
|
19
|
+
let match;
|
|
20
|
+
while ((match = importPattern.exec(content)) !== null) {
|
|
21
|
+
const importName = match[1];
|
|
22
|
+
const packageName = match[2];
|
|
23
|
+
const lineNumber = content.substring(0, match.index).split("\n").length;
|
|
24
|
+
// Check if this component is used (app.use(...))
|
|
25
|
+
const usePattern = new RegExp(`app\\.use\\(${importName}\\)`, "g");
|
|
26
|
+
const isUsed = usePattern.test(content);
|
|
27
|
+
// Check if conditional
|
|
28
|
+
const conditionalPattern = new RegExp(`if\\s*\\([^)]*\\)\\s*\\{[^}]*app\\.use\\(${importName}\\)`, "s");
|
|
29
|
+
const isConditional = conditionalPattern.test(content);
|
|
30
|
+
components.push({
|
|
31
|
+
importName,
|
|
32
|
+
packageName,
|
|
33
|
+
configPath: `${packageName}/convex.config`,
|
|
34
|
+
isUsed,
|
|
35
|
+
isConditional,
|
|
36
|
+
line: lineNumber,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
// Check for unused imports
|
|
40
|
+
for (const comp of components) {
|
|
41
|
+
if (!comp.isUsed) {
|
|
42
|
+
issues.push(`WARNING: Component "${comp.importName}" (${comp.packageName}) is imported but never used with app.use()`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Check for defineApp
|
|
46
|
+
if (!content.includes("defineApp")) {
|
|
47
|
+
issues.push("CRITICAL: Missing defineApp() — convex.config.ts must call defineApp()");
|
|
48
|
+
}
|
|
49
|
+
// Check for default export
|
|
50
|
+
if (!content.includes("export default")) {
|
|
51
|
+
issues.push("CRITICAL: Missing default export — convex.config.ts must export the app");
|
|
52
|
+
}
|
|
53
|
+
// Check for process.env usage (allowed but noteworthy)
|
|
54
|
+
const envUsages = content.match(/process\.env\.\w+/g) || [];
|
|
55
|
+
if (envUsages.length > 0) {
|
|
56
|
+
issues.push(`INFO: ${envUsages.length} environment variable(s) used for conditional component loading: ${envUsages.join(", ")}`);
|
|
57
|
+
}
|
|
58
|
+
return { components, issues };
|
|
59
|
+
}
|
|
60
|
+
// ── Tool Definitions ────────────────────────────────────────────────
|
|
61
|
+
export const componentTools = [
|
|
62
|
+
{
|
|
63
|
+
name: "convex_analyze_components",
|
|
64
|
+
description: "Analyze Convex component imports in convex.config.ts. Lists all installed Convex components (agent, workflow, rag, etc.), checks for unused imports, conditional loading, and configuration issues. Essential before adding new components to avoid conflicts.",
|
|
65
|
+
inputSchema: {
|
|
66
|
+
type: "object",
|
|
67
|
+
properties: {
|
|
68
|
+
projectDir: {
|
|
69
|
+
type: "string",
|
|
70
|
+
description: "Absolute path to the project root",
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
required: ["projectDir"],
|
|
74
|
+
},
|
|
75
|
+
handler: async (args) => {
|
|
76
|
+
const projectDir = resolve(args.projectDir);
|
|
77
|
+
const convexDir = findConvexDir(projectDir);
|
|
78
|
+
if (!convexDir)
|
|
79
|
+
return { error: "No convex/ directory found" };
|
|
80
|
+
const configPath = join(convexDir, "convex.config.ts");
|
|
81
|
+
if (!existsSync(configPath)) {
|
|
82
|
+
return {
|
|
83
|
+
hasConfig: false,
|
|
84
|
+
message: "No convex.config.ts found — project uses no Convex components",
|
|
85
|
+
quickRef: getQuickRef("convex_get_methodology"),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
const content = readFileSync(configPath, "utf-8");
|
|
89
|
+
const { components, issues } = parseConvexConfig(content);
|
|
90
|
+
// Check package.json for component versions
|
|
91
|
+
const pkgPath = join(projectDir, "package.json");
|
|
92
|
+
let componentVersions = {};
|
|
93
|
+
if (existsSync(pkgPath)) {
|
|
94
|
+
try {
|
|
95
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
96
|
+
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
97
|
+
for (const comp of components) {
|
|
98
|
+
if (allDeps[comp.packageName]) {
|
|
99
|
+
componentVersions[comp.packageName] = allDeps[comp.packageName];
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch { /* ignore */ }
|
|
104
|
+
}
|
|
105
|
+
const criticalCount = issues.filter((i) => i.startsWith("CRITICAL")).length;
|
|
106
|
+
const warningCount = issues.filter((i) => i.startsWith("WARNING")).length;
|
|
107
|
+
return {
|
|
108
|
+
hasConfig: true,
|
|
109
|
+
totalComponents: components.length,
|
|
110
|
+
activeComponents: components.filter((c) => c.isUsed).length,
|
|
111
|
+
conditionalComponents: components.filter((c) => c.isConditional).length,
|
|
112
|
+
components: components.map((c) => ({
|
|
113
|
+
name: c.importName,
|
|
114
|
+
package: c.packageName,
|
|
115
|
+
version: componentVersions[c.packageName] || "unknown",
|
|
116
|
+
isUsed: c.isUsed,
|
|
117
|
+
isConditional: c.isConditional,
|
|
118
|
+
line: c.line,
|
|
119
|
+
})),
|
|
120
|
+
issues: {
|
|
121
|
+
total: issues.length,
|
|
122
|
+
critical: criticalCount,
|
|
123
|
+
warnings: warningCount,
|
|
124
|
+
details: issues,
|
|
125
|
+
},
|
|
126
|
+
quickRef: getQuickRef("convex_pre_deploy_gate"),
|
|
127
|
+
};
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
];
|
|
131
|
+
//# sourceMappingURL=componentTools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"componentTools.js","sourceRoot":"","sources":["../../src/tools/componentTools.ts"],"names":[],"mappings":"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"}
|