[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-convex-convex-authz":3,"mdc-qg7tq2-key":35,"related-org-convex-convex-authz":515,"related-repo-convex-convex-authz":693},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":24,"repoUrl":25,"updatedAt":26,"license":27,"forks":28,"topics":29,"repo":30,"sourceUrl":33,"mdContent":34},"convex-authz","audit and harden Convex authorization","Audit and harden a Convex app's authorization: identity-from-arg impersonation, missing per-document ownership checks, and public queries leaking PII\u002Ffinancial data by a client-supplied id — the single largest real-defect cluster measured against generated Convex backends (44 of 214). Runs a deterministic scan for the 3 shapes, then applies the canonical requireIdentity\u002FrequireOwner pattern, then verifies with tsc. TRIGGER on 'secure my app', 'audit auth', 'add login', 'who can access this data', or an explicit 'audit my authz'. NOT always-on. SKIP when there is no convex\u002F directory.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"convex","Convex","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fconvex.png","get-convex",[13,17,20,21],{"name":14,"slug":15,"type":16},"Security","security","tag",{"name":18,"slug":19,"type":16},"Auth","auth",{"name":9,"slug":8,"type":16},{"name":22,"slug":23,"type":16},"Code Analysis","code-analysis",2,"https:\u002F\u002Fgithub.com\u002Fget-convex\u002Fconvex-codex-plugin","2026-07-12T08:00:04.516752","Apache-2.0",0,[],{"repoUrl":25,"stars":24,"forks":28,"topics":31,"description":32},[],"Codex plugin for the hosted Convex MCP server","https:\u002F\u002Fgithub.com\u002Fget-convex\u002Fconvex-codex-plugin\u002Ftree\u002FHEAD\u002Fplugins\u002Fconvex\u002Fskills\u002Fconvex-authz","---\nname: \"convex-authz\"\ndescription: \"Audit and harden a Convex app's authorization: identity-from-arg impersonation, missing per-document ownership checks, and public queries leaking PII\u002Ffinancial data by a client-supplied id — the single largest real-defect cluster measured against generated Convex backends (44 of 214). Runs a deterministic scan for the 3 shapes, then applies the canonical requireIdentity\u002FrequireOwner pattern, then verifies with tsc. TRIGGER on 'secure my app', 'audit auth', 'add login', 'who can access this data', or an explicit 'audit my authz'. NOT always-on. SKIP when there is no convex\u002F directory.\"\nlicense: \"Apache-2.0\"\n---\n\n# Convex Authz Auditor\u002FHardener\n\nA focused authz specialist, not a general reviewer: it finds and fixes the exact three shapes that account for the largest real-defect cluster measured against generated Convex backends (25 identity-from-arg + 13 missing-ownership-check + 6 PII-leak-by-argument = 44 of 214 confirmed defects). It runs a deterministic scan first (objective, regex-based, mirrors the convex-backend-skill v1.7.9 lint advisory), then applies the canonical requireIdentity\u002FrequireOwner hardening pattern from convex-expert.md to every hit, then verifies with tsc. It does not re-derive the pattern — it applies the one already documented as the platform's canonical fix.\n\n## Steps\n1. SCAN (deterministic, objective-first): for every convex\u002F**\u002F*.ts file (skip convex\u002F_generated\u002F and .d.ts), grep for the three shapes:\n   (a) identity-from-arg: a public `query(`\u002F`mutation(` object whose `args` block declares `userId`\u002F`actorId`\u002F`ownerId`\u002F`authorId`\u002F`accountId` typed `v.id(...)`, where the function's whole block (args + handler) has zero `ctx.auth` reference. Regex: `\u002F\\b(userId|actorId|ownerId|authorId|accountId)\\s*:\\s*v\\.id\\(\u002F` inside an `args: { ... }` block paired with an absent `\u002F\\bctx\\.auth\\b\u002F` anywhere in the enclosing `(query|mutation)\\(\\s*\\{ ... }` block (word-boundary excludes internalQuery\u002FinternalMutation by construction).\n   (b) missing-ownership-check: a public `query(`\u002F`mutation(` whose handler loads a document via `ctx.db.get(args.\u003CxId>)` (an `_id`-typed arg) and then calls `ctx.db.patch`\u002F`ctx.db.delete`\u002F`ctx.db.replace` on that same id, or returns the doc's fields directly, with no comparison of any `\u003Cdoc>.\u003CownerField>` against an identity value anywhere in the block (no `===`\u002F`!==` involving `identity.subject` or a `ctx.auth` derived value).\n   (c) PII-leaking public query: a public `query(` whose `returns` (or the raw doc it returns) includes a sensitive-looking field (`email`, `revenue`, `ssn`, `password`, `token`, `auditLog`, `dashboard`-shaped aggregate) and the query is parameterized by a client-supplied id with no `ctx.auth` check gating access to that id's own scope.\n   Report every hit with file, line, and which of the 3 shapes matched — this is the objective, model-independent baseline; do not skip it in favor of jumping straight to judgment.\n2. HARDEN: for each hit, apply the canonical pattern from content\u002Fconvex-expert.md verbatim — do not invent a new helper. Add (if absent) `convex\u002Fmodel\u002Fauth.ts` exporting `requireIdentity(ctx)` (throws 401 if `ctx.auth.getUserIdentity()` is null; returns the identity) and `requireOwner(ctx, doc)` (throws 404 if doc is null, throws 403 if `doc.ownerId !== identity.subject`, else returns doc). Rewrite each flagged function: replace the client-supplied identity arg with `requireIdentity(ctx)`; wrap each `_id`-keyed read\u002Fmutate with `requireOwner(ctx, await ctx.db.get(args.xId))` before touching the row; scope each PII-returning query through `requireIdentity`\u002F`requireOwner` (or an explicit staff\u002Frole check) before it reads outside the caller's own scope. Never widen scope — an internal\u002Fadmin function that legitimately operates on an arbitrary user stays `internalQuery`\u002F`internalMutation`, never public; leave it unflagged and unchanged.\n3. VERIFY: run `npx tsc --noEmit` (or the project's typecheck script) after edits; a hardening pass that doesn't typecheck is not done. Then re-run the step-1 scan to confirm 0 remaining hits (the fixed shapes no longer match the regexes because `ctx.auth` now appears in-block and ownership comparisons now exist).\n4. Report findings grouped by the 3 rule shapes with file:line, explain why each is exploitable (who could impersonate whom \u002F read whose data), and show the concrete diff applied — never just describe the fix in prose.\n\n## Rules\n- Scan objectively before judging — run the 3 deterministic greps first; don't skip straight to LLM judgment, and don't let a clean scan stop you from still eyeballing internal\u002Fadmin exemptions.\n- Identity always comes from ctx.auth, never from a client-supplied argument — the one legitimate exception is an internalQuery\u002FinternalMutation\u002FinternalAction that is never exposed publicly.\n- Every read or mutate keyed by an _id argument must verify ownership server-side (requireOwner or an inlined equivalent comparison) before touching the row — being logged in is not the same as owning this row.\n- Never leave a public query that returns PII\u002Ffinancial\u002Faudit data reachable by an unauthenticated or cross-account client-supplied id.\n- Reuse requireIdentity\u002FrequireOwner from content\u002Fconvex-expert.md verbatim — do not fork a parallel helper or invent new error semantics.\n- Always verify with tsc after hardening; a fix that doesn't typecheck is not shipped.\n- This is a targeted authz pass, not a general code review — do not expand scope into performance\u002Fschema\u002Fvalidator findings; hand those to convex-reviewer.\n- SKIP entirely when there is no convex\u002F directory in the project.\n",{"data":36,"body":37},{"name":4,"description":6,"license":27},{"type":38,"children":39},"root",[40,49,55,62,465,471],{"type":41,"tag":42,"props":43,"children":45},"element","h1",{"id":44},"convex-authz-auditorhardener",[46],{"type":47,"value":48},"text","Convex Authz Auditor\u002FHardener",{"type":41,"tag":50,"props":51,"children":52},"p",{},[53],{"type":47,"value":54},"A focused authz specialist, not a general reviewer: it finds and fixes the exact three shapes that account for the largest real-defect cluster measured against generated Convex backends (25 identity-from-arg + 13 missing-ownership-check + 6 PII-leak-by-argument = 44 of 214 confirmed defects). It runs a deterministic scan first (objective, regex-based, mirrors the convex-backend-skill v1.7.9 lint advisory), then applies the canonical requireIdentity\u002FrequireOwner hardening pattern from convex-expert.md to every hit, then verifies with tsc. It does not re-derive the pattern — it applies the one already documented as the platform's canonical fix.",{"type":41,"tag":56,"props":57,"children":59},"h2",{"id":58},"steps",[60],{"type":47,"value":61},"Steps",{"type":41,"tag":63,"props":64,"children":65},"ol",{},[66,343,440,460],{"type":41,"tag":67,"props":68,"children":69},"li",{},[70,72,79,81,87,89,95,97,103,104,110,111,117,118,124,125,131,133,139,141,147,149,155,157,163,165,171,173,179,181,186,187,192,194,200,202,208,210,216,217,223,224,230,232,238,240,246,247,253,255,261,263,268,270,275,277,283,285,291,293,299,300,306,307,313,314,320,321,327,328,334,336,341],{"type":47,"value":71},"SCAN (deterministic, objective-first): for every convex\u002F**\u002F*.ts file (skip convex\u002F_generated\u002F and .d.ts), grep for the three shapes:\n(a) identity-from-arg: a public ",{"type":41,"tag":73,"props":74,"children":76},"code",{"className":75},[],[77],{"type":47,"value":78},"query(",{"type":47,"value":80},"\u002F",{"type":41,"tag":73,"props":82,"children":84},{"className":83},[],[85],{"type":47,"value":86},"mutation(",{"type":47,"value":88}," object whose ",{"type":41,"tag":73,"props":90,"children":92},{"className":91},[],[93],{"type":47,"value":94},"args",{"type":47,"value":96}," block declares ",{"type":41,"tag":73,"props":98,"children":100},{"className":99},[],[101],{"type":47,"value":102},"userId",{"type":47,"value":80},{"type":41,"tag":73,"props":105,"children":107},{"className":106},[],[108],{"type":47,"value":109},"actorId",{"type":47,"value":80},{"type":41,"tag":73,"props":112,"children":114},{"className":113},[],[115],{"type":47,"value":116},"ownerId",{"type":47,"value":80},{"type":41,"tag":73,"props":119,"children":121},{"className":120},[],[122],{"type":47,"value":123},"authorId",{"type":47,"value":80},{"type":41,"tag":73,"props":126,"children":128},{"className":127},[],[129],{"type":47,"value":130},"accountId",{"type":47,"value":132}," typed ",{"type":41,"tag":73,"props":134,"children":136},{"className":135},[],[137],{"type":47,"value":138},"v.id(...)",{"type":47,"value":140},", where the function's whole block (args + handler) has zero ",{"type":41,"tag":73,"props":142,"children":144},{"className":143},[],[145],{"type":47,"value":146},"ctx.auth",{"type":47,"value":148}," reference. Regex: ",{"type":41,"tag":73,"props":150,"children":152},{"className":151},[],[153],{"type":47,"value":154},"\u002F\\b(userId|actorId|ownerId|authorId|accountId)\\s*:\\s*v\\.id\\(\u002F",{"type":47,"value":156}," inside an ",{"type":41,"tag":73,"props":158,"children":160},{"className":159},[],[161],{"type":47,"value":162},"args: { ... }",{"type":47,"value":164}," block paired with an absent ",{"type":41,"tag":73,"props":166,"children":168},{"className":167},[],[169],{"type":47,"value":170},"\u002F\\bctx\\.auth\\b\u002F",{"type":47,"value":172}," anywhere in the enclosing ",{"type":41,"tag":73,"props":174,"children":176},{"className":175},[],[177],{"type":47,"value":178},"(query|mutation)\\(\\s*\\{ ... }",{"type":47,"value":180}," block (word-boundary excludes internalQuery\u002FinternalMutation by construction).\n(b) missing-ownership-check: a public ",{"type":41,"tag":73,"props":182,"children":184},{"className":183},[],[185],{"type":47,"value":78},{"type":47,"value":80},{"type":41,"tag":73,"props":188,"children":190},{"className":189},[],[191],{"type":47,"value":86},{"type":47,"value":193}," whose handler loads a document via ",{"type":41,"tag":73,"props":195,"children":197},{"className":196},[],[198],{"type":47,"value":199},"ctx.db.get(args.\u003CxId>)",{"type":47,"value":201}," (an ",{"type":41,"tag":73,"props":203,"children":205},{"className":204},[],[206],{"type":47,"value":207},"_id",{"type":47,"value":209},"-typed arg) and then calls ",{"type":41,"tag":73,"props":211,"children":213},{"className":212},[],[214],{"type":47,"value":215},"ctx.db.patch",{"type":47,"value":80},{"type":41,"tag":73,"props":218,"children":220},{"className":219},[],[221],{"type":47,"value":222},"ctx.db.delete",{"type":47,"value":80},{"type":41,"tag":73,"props":225,"children":227},{"className":226},[],[228],{"type":47,"value":229},"ctx.db.replace",{"type":47,"value":231}," on that same id, or returns the doc's fields directly, with no comparison of any ",{"type":41,"tag":73,"props":233,"children":235},{"className":234},[],[236],{"type":47,"value":237},"\u003Cdoc>.\u003CownerField>",{"type":47,"value":239}," against an identity value anywhere in the block (no ",{"type":41,"tag":73,"props":241,"children":243},{"className":242},[],[244],{"type":47,"value":245},"===",{"type":47,"value":80},{"type":41,"tag":73,"props":248,"children":250},{"className":249},[],[251],{"type":47,"value":252},"!==",{"type":47,"value":254}," involving ",{"type":41,"tag":73,"props":256,"children":258},{"className":257},[],[259],{"type":47,"value":260},"identity.subject",{"type":47,"value":262}," or a ",{"type":41,"tag":73,"props":264,"children":266},{"className":265},[],[267],{"type":47,"value":146},{"type":47,"value":269}," derived value).\n(c) PII-leaking public query: a public ",{"type":41,"tag":73,"props":271,"children":273},{"className":272},[],[274],{"type":47,"value":78},{"type":47,"value":276}," whose ",{"type":41,"tag":73,"props":278,"children":280},{"className":279},[],[281],{"type":47,"value":282},"returns",{"type":47,"value":284}," (or the raw doc it returns) includes a sensitive-looking field (",{"type":41,"tag":73,"props":286,"children":288},{"className":287},[],[289],{"type":47,"value":290},"email",{"type":47,"value":292},", ",{"type":41,"tag":73,"props":294,"children":296},{"className":295},[],[297],{"type":47,"value":298},"revenue",{"type":47,"value":292},{"type":41,"tag":73,"props":301,"children":303},{"className":302},[],[304],{"type":47,"value":305},"ssn",{"type":47,"value":292},{"type":41,"tag":73,"props":308,"children":310},{"className":309},[],[311],{"type":47,"value":312},"password",{"type":47,"value":292},{"type":41,"tag":73,"props":315,"children":317},{"className":316},[],[318],{"type":47,"value":319},"token",{"type":47,"value":292},{"type":41,"tag":73,"props":322,"children":324},{"className":323},[],[325],{"type":47,"value":326},"auditLog",{"type":47,"value":292},{"type":41,"tag":73,"props":329,"children":331},{"className":330},[],[332],{"type":47,"value":333},"dashboard",{"type":47,"value":335},"-shaped aggregate) and the query is parameterized by a client-supplied id with no ",{"type":41,"tag":73,"props":337,"children":339},{"className":338},[],[340],{"type":47,"value":146},{"type":47,"value":342}," check gating access to that id's own scope.\nReport every hit with file, line, and which of the 3 shapes matched — this is the objective, model-independent baseline; do not skip it in favor of jumping straight to judgment.",{"type":41,"tag":67,"props":344,"children":345},{},[346,348,354,356,362,364,370,372,378,380,386,388,393,395,400,402,408,410,416,417,423,425,431,432,438],{"type":47,"value":347},"HARDEN: for each hit, apply the canonical pattern from content\u002Fconvex-expert.md verbatim — do not invent a new helper. Add (if absent) ",{"type":41,"tag":73,"props":349,"children":351},{"className":350},[],[352],{"type":47,"value":353},"convex\u002Fmodel\u002Fauth.ts",{"type":47,"value":355}," exporting ",{"type":41,"tag":73,"props":357,"children":359},{"className":358},[],[360],{"type":47,"value":361},"requireIdentity(ctx)",{"type":47,"value":363}," (throws 401 if ",{"type":41,"tag":73,"props":365,"children":367},{"className":366},[],[368],{"type":47,"value":369},"ctx.auth.getUserIdentity()",{"type":47,"value":371}," is null; returns the identity) and ",{"type":41,"tag":73,"props":373,"children":375},{"className":374},[],[376],{"type":47,"value":377},"requireOwner(ctx, doc)",{"type":47,"value":379}," (throws 404 if doc is null, throws 403 if ",{"type":41,"tag":73,"props":381,"children":383},{"className":382},[],[384],{"type":47,"value":385},"doc.ownerId !== identity.subject",{"type":47,"value":387},", else returns doc). Rewrite each flagged function: replace the client-supplied identity arg with ",{"type":41,"tag":73,"props":389,"children":391},{"className":390},[],[392],{"type":47,"value":361},{"type":47,"value":394},"; wrap each ",{"type":41,"tag":73,"props":396,"children":398},{"className":397},[],[399],{"type":47,"value":207},{"type":47,"value":401},"-keyed read\u002Fmutate with ",{"type":41,"tag":73,"props":403,"children":405},{"className":404},[],[406],{"type":47,"value":407},"requireOwner(ctx, await ctx.db.get(args.xId))",{"type":47,"value":409}," before touching the row; scope each PII-returning query through ",{"type":41,"tag":73,"props":411,"children":413},{"className":412},[],[414],{"type":47,"value":415},"requireIdentity",{"type":47,"value":80},{"type":41,"tag":73,"props":418,"children":420},{"className":419},[],[421],{"type":47,"value":422},"requireOwner",{"type":47,"value":424}," (or an explicit staff\u002Frole check) before it reads outside the caller's own scope. Never widen scope — an internal\u002Fadmin function that legitimately operates on an arbitrary user stays ",{"type":41,"tag":73,"props":426,"children":428},{"className":427},[],[429],{"type":47,"value":430},"internalQuery",{"type":47,"value":80},{"type":41,"tag":73,"props":433,"children":435},{"className":434},[],[436],{"type":47,"value":437},"internalMutation",{"type":47,"value":439},", never public; leave it unflagged and unchanged.",{"type":41,"tag":67,"props":441,"children":442},{},[443,445,451,453,458],{"type":47,"value":444},"VERIFY: run ",{"type":41,"tag":73,"props":446,"children":448},{"className":447},[],[449],{"type":47,"value":450},"npx tsc --noEmit",{"type":47,"value":452}," (or the project's typecheck script) after edits; a hardening pass that doesn't typecheck is not done. Then re-run the step-1 scan to confirm 0 remaining hits (the fixed shapes no longer match the regexes because ",{"type":41,"tag":73,"props":454,"children":456},{"className":455},[],[457],{"type":47,"value":146},{"type":47,"value":459}," now appears in-block and ownership comparisons now exist).",{"type":41,"tag":67,"props":461,"children":462},{},[463],{"type":47,"value":464},"Report findings grouped by the 3 rule shapes with file:line, explain why each is exploitable (who could impersonate whom \u002F read whose data), and show the concrete diff applied — never just describe the fix in prose.",{"type":41,"tag":56,"props":466,"children":468},{"id":467},"rules",[469],{"type":47,"value":470},"Rules",{"type":41,"tag":472,"props":473,"children":474},"ul",{},[475,480,485,490,495,500,505,510],{"type":41,"tag":67,"props":476,"children":477},{},[478],{"type":47,"value":479},"Scan objectively before judging — run the 3 deterministic greps first; don't skip straight to LLM judgment, and don't let a clean scan stop you from still eyeballing internal\u002Fadmin exemptions.",{"type":41,"tag":67,"props":481,"children":482},{},[483],{"type":47,"value":484},"Identity always comes from ctx.auth, never from a client-supplied argument — the one legitimate exception is an internalQuery\u002FinternalMutation\u002FinternalAction that is never exposed publicly.",{"type":41,"tag":67,"props":486,"children":487},{},[488],{"type":47,"value":489},"Every read or mutate keyed by an _id argument must verify ownership server-side (requireOwner or an inlined equivalent comparison) before touching the row — being logged in is not the same as owning this row.",{"type":41,"tag":67,"props":491,"children":492},{},[493],{"type":47,"value":494},"Never leave a public query that returns PII\u002Ffinancial\u002Faudit data reachable by an unauthenticated or cross-account client-supplied id.",{"type":41,"tag":67,"props":496,"children":497},{},[498],{"type":47,"value":499},"Reuse requireIdentity\u002FrequireOwner from content\u002Fconvex-expert.md verbatim — do not fork a parallel helper or invent new error semantics.",{"type":41,"tag":67,"props":501,"children":502},{},[503],{"type":47,"value":504},"Always verify with tsc after hardening; a fix that doesn't typecheck is not shipped.",{"type":41,"tag":67,"props":506,"children":507},{},[508],{"type":47,"value":509},"This is a targeted authz pass, not a general code review — do not expand scope into performance\u002Fschema\u002Fvalidator findings; hand those to convex-reviewer.",{"type":41,"tag":67,"props":511,"children":512},{},[513],{"type":47,"value":514},"SKIP entirely when there is no convex\u002F directory in the project.",{"items":516,"total":692},[517,532,547,562,579,596,609,621,640,654,671,685],{"slug":8,"name":8,"fn":518,"description":519,"org":520,"tags":521,"stars":529,"repoUrl":530,"updatedAt":531},"guide Convex project setup and usage","Routes general Convex requests to the right project skill. Use when the user asks which Convex skill to use or gives an underspecified Convex app task.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[522,525,526],{"name":523,"slug":524,"type":16},"Backend","backend",{"name":9,"slug":8,"type":16},{"name":527,"slug":528,"type":16},"Database","database",34,"https:\u002F\u002Fgithub.com\u002Fget-convex\u002Fagent-skills","2026-07-12T08:00:45.091281",{"slug":533,"name":533,"fn":534,"description":535,"org":536,"tags":537,"stars":529,"repoUrl":530,"updatedAt":546},"convex-create-component","build reusable Convex components","Builds reusable Convex components with isolated tables and app-facing APIs. Use for new components, reusable backend modules, integrations, or component boundary work.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[538,541,544,545],{"name":539,"slug":540,"type":16},"API Development","api-development",{"name":542,"slug":543,"type":16},"Architecture","architecture",{"name":523,"slug":524,"type":16},{"name":9,"slug":8,"type":16},"2026-07-12T08:00:39.428577",{"slug":548,"name":548,"fn":549,"description":550,"org":551,"tags":552,"stars":529,"repoUrl":530,"updatedAt":561},"convex-migration-helper","plan Convex schema and data migrations","Plans Convex schema and data migrations with widen-migrate-narrow and @convex-dev\u002Fmigrations. Use for breaking schema changes, backfills, table reshaping, or zero-downtime rollouts.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[553,554,555,558],{"name":523,"slug":524,"type":16},{"name":9,"slug":8,"type":16},{"name":556,"slug":557,"type":16},"Data Engineering","data-engineering",{"name":559,"slug":560,"type":16},"Migration","migration","2026-07-12T08:00:51.27967",{"slug":563,"name":563,"fn":564,"description":565,"org":566,"tags":567,"stars":529,"repoUrl":530,"updatedAt":578},"convex-performance-audit","audit Convex application performance","Audits Convex performance for reads, subscriptions, write contention, and function limits. Use for slow features, insights findings, OCC conflicts, or read amplification.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[568,569,572,575],{"name":9,"slug":8,"type":16},{"name":570,"slug":571,"type":16},"Debugging","debugging",{"name":573,"slug":574,"type":16},"Monitoring","monitoring",{"name":576,"slug":577,"type":16},"Performance","performance","2026-07-12T08:00:50.02928",{"slug":580,"name":580,"fn":581,"description":582,"org":583,"tags":584,"stars":529,"repoUrl":530,"updatedAt":595},"convex-quickstart","initialize Convex in applications","Creates or adds Convex to an app. Use for new Convex projects, npm create convex@latest, frontend setup, env vars, or the first npx convex dev run.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[585,588,589,592],{"name":586,"slug":587,"type":16},"CLI","cli",{"name":9,"slug":8,"type":16},{"name":590,"slug":591,"type":16},"Frontend","frontend",{"name":593,"slug":594,"type":16},"Onboarding","onboarding","2026-07-12T08:00:43.436152",{"slug":597,"name":597,"fn":598,"description":599,"org":600,"tags":601,"stars":529,"repoUrl":530,"updatedAt":608},"convex-setup-auth","set up authentication and access control","Sets up Convex auth, identity mapping, and access control. Use for login, auth providers, users tables, protected functions, or roles in a Convex app.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[602,605,606,607],{"name":603,"slug":604,"type":16},"Access Control","access-control",{"name":18,"slug":19,"type":16},{"name":523,"slug":524,"type":16},{"name":9,"slug":8,"type":16},"2026-07-12T08:00:48.652641",{"slug":610,"name":610,"fn":611,"description":612,"org":613,"tags":614,"stars":24,"repoUrl":25,"updatedAt":620},"add","add capabilities to Convex applications","Add a capability to the CURRENT Convex + Next.js project — consults the served Convex capability catalog for always-current procedures (billing, crons, auth, agent, search, …); falls back to built-in hosting or @convex-dev component search. TRIGGER when the user runs $add, or asks to add hosting\u002Fpublishing or any backend capability to an existing Convex app.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[615,616,617],{"name":523,"slug":524,"type":16},{"name":9,"slug":8,"type":16},{"name":618,"slug":619,"type":16},"Next.js","next-js","2026-07-12T07:59:59.358004",{"slug":622,"name":622,"fn":623,"description":624,"org":625,"tags":626,"stars":24,"repoUrl":25,"updatedAt":639},"agent","build AI agents with Convex","Build an AI agent \u002F RAG feature on Convex (@convex-dev\u002Fagent: threads, tools, vector search). TRIGGER on an AI-agent\u002Fchatbot\u002FRAG request.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[627,630,633,636],{"name":628,"slug":629,"type":16},"Agents","agents",{"name":631,"slug":632,"type":16},"Engineering","engineering",{"name":634,"slug":635,"type":16},"RAG","rag",{"name":637,"slug":638,"type":16},"Search","search","2026-07-12T08:00:01.921824",{"slug":19,"name":19,"fn":641,"description":642,"org":643,"tags":644,"stars":24,"repoUrl":25,"updatedAt":653},"add authentication to Convex applications","Add sign-in (passkeys by default, OAuth\u002Fpassword optional) to the current Convex app, wired correctly incl. auth.config.ts. TRIGGER on a login\u002Fauth request for an existing app.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[645,646,649,650],{"name":18,"slug":19,"type":16},{"name":647,"slug":648,"type":16},"Authentication","authentication",{"name":9,"slug":8,"type":16},{"name":651,"slug":652,"type":16},"OAuth","oauth","2026-07-18T05:12:54.443056",{"slug":655,"name":655,"fn":656,"description":657,"org":658,"tags":659,"stars":24,"repoUrl":25,"updatedAt":670},"billing","integrate Stripe billing in Convex apps","Add Stripe billing to a Convex app via @convex-dev\u002Fstripe (checkout + auto-verified webhook + subscription gating). TRIGGER on a payments\u002Fbilling\u002Fsubscription request.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[660,661,664,667],{"name":9,"slug":8,"type":16},{"name":662,"slug":663,"type":16},"Payments","payments",{"name":665,"slug":666,"type":16},"Stripe","stripe",{"name":668,"slug":669,"type":16},"Webhooks","webhooks","2026-07-12T08:00:08.123246",{"slug":672,"name":672,"fn":673,"description":674,"org":675,"tags":676,"stars":24,"repoUrl":25,"updatedAt":684},"check-updates","upgrade Convex component versions","Check the CURRENT Convex app's pinned components against the latest recommended versions and offer to upgrade them — e.g. the passkey auth component's new email-first sign-in. TRIGGER when the user runs \u002Fcheck-updates or $check-updates, asks 'are my components up to date', 'any updates', 'upgrade auth', 'upgrade my components', or wants the newest features after a quickstart. Applies each upgrade behind a build gate (verify-or-revert) with the user's consent.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[677,680,681],{"name":678,"slug":679,"type":16},"Configuration","configuration",{"name":9,"slug":8,"type":16},{"name":682,"slug":683,"type":16},"Maintenance","maintenance","2026-07-12T08:00:03.236862",{"slug":4,"name":4,"fn":5,"description":6,"org":686,"tags":687,"stars":24,"repoUrl":25,"updatedAt":26},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[688,689,690,691],{"name":18,"slug":19,"type":16},{"name":22,"slug":23,"type":16},{"name":9,"slug":8,"type":16},{"name":14,"slug":15,"type":16},26,{"items":694,"total":748},[695,701,708,715,722,728,735],{"slug":610,"name":610,"fn":611,"description":612,"org":696,"tags":697,"stars":24,"repoUrl":25,"updatedAt":620},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[698,699,700],{"name":523,"slug":524,"type":16},{"name":9,"slug":8,"type":16},{"name":618,"slug":619,"type":16},{"slug":622,"name":622,"fn":623,"description":624,"org":702,"tags":703,"stars":24,"repoUrl":25,"updatedAt":639},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[704,705,706,707],{"name":628,"slug":629,"type":16},{"name":631,"slug":632,"type":16},{"name":634,"slug":635,"type":16},{"name":637,"slug":638,"type":16},{"slug":19,"name":19,"fn":641,"description":642,"org":709,"tags":710,"stars":24,"repoUrl":25,"updatedAt":653},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[711,712,713,714],{"name":18,"slug":19,"type":16},{"name":647,"slug":648,"type":16},{"name":9,"slug":8,"type":16},{"name":651,"slug":652,"type":16},{"slug":655,"name":655,"fn":656,"description":657,"org":716,"tags":717,"stars":24,"repoUrl":25,"updatedAt":670},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[718,719,720,721],{"name":9,"slug":8,"type":16},{"name":662,"slug":663,"type":16},{"name":665,"slug":666,"type":16},{"name":668,"slug":669,"type":16},{"slug":672,"name":672,"fn":673,"description":674,"org":723,"tags":724,"stars":24,"repoUrl":25,"updatedAt":684},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[725,726,727],{"name":678,"slug":679,"type":16},{"name":9,"slug":8,"type":16},{"name":682,"slug":683,"type":16},{"slug":4,"name":4,"fn":5,"description":6,"org":729,"tags":730,"stars":24,"repoUrl":25,"updatedAt":26},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[731,732,733,734],{"name":18,"slug":19,"type":16},{"name":22,"slug":23,"type":16},{"name":9,"slug":8,"type":16},{"name":14,"slug":15,"type":16},{"slug":736,"name":736,"fn":737,"description":738,"org":739,"tags":740,"stars":24,"repoUrl":25,"updatedAt":747},"convex-expert","develop Convex backend applications","Convex backend rules — consult this whenever writing or editing any code inside a convex\u002F directory (schemas, queries, mutations, actions, HTTP endpoints, crons, file storage, auth, component installation). TRIGGER before touching convex\u002F functions, so the code uses the object-form syntax, validators, indexes, and component patterns that generic models get wrong.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[741,742,743,744],{"name":523,"slug":524,"type":16},{"name":9,"slug":8,"type":16},{"name":527,"slug":528,"type":16},{"name":745,"slug":746,"type":16},"TypeScript","typescript","2026-07-18T05:12:50.448833",19]