@dypai-ai/mcp 1.5.4 → 1.5.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dypai-ai/mcp",
3
- "version": "1.5.4",
3
+ "version": "1.5.5",
4
4
  "description": "DYPAI MCP Server — AI agent toolkit for building and deploying full-stack apps",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/index.js CHANGED
@@ -166,7 +166,7 @@ const REMOTE_TOOLS = [
166
166
  // and fail to learn the contract. Mirrors the validation the remote does.
167
167
  {
168
168
  name: "manage_users",
169
- description: `Manage authenticated users (better-auth backed).
169
+ description: `Manage authenticated users.
170
170
 
171
171
  Operations:
172
172
  - list: Paginated user listing. Optional: search, limit (1-100, default 20), offset, sort_by, sort_order.
@@ -177,14 +177,14 @@ Operations:
177
177
  - delete: Permanently remove a user (user_id).
178
178
  - ban / unban: Block / unblock login (user_id; ban supports ban_reason and ban_expires_in seconds).
179
179
 
180
- NOTE: user IDs are TEXT (better-auth nanoids like "G1LIBXsbMLxUrs99ebCaL9X4auxW26AC"), NOT UUIDs.`,
180
+ NOTE: user IDs are TEXT alphanumeric strings (~32 chars, like "G1LIBXsbMLxUrs99ebCaL9X4auxW26AC"), NOT UUIDs. They live in auth."user".id.`,
181
181
  inputSchema: {
182
182
  type: "object",
183
183
  properties: {
184
184
  project_id: { type: "string", description: "Project UUID. Required for user tokens; auto-detected for project tokens." },
185
185
  operation: { type: "string", enum: ["list", "get", "create", "set_password", "update_role", "delete", "ban", "unban"] },
186
186
  // Fields used by various operations
187
- user_id: { type: "string", description: "User ID (TEXT, better-auth nanoid). Required for: get, set_password, update_role, delete, ban, unban." },
187
+ user_id: { type: "string", description: "User ID (TEXT alphanumeric, NOT a UUID; from auth.\"user\".id). Required for: get, set_password, update_role, delete, ban, unban." },
188
188
  email: { type: "string", description: "User email. Required for: create." },
189
189
  password: { type: "string", description: "User password (min 6 chars). Required for: create, set_password." },
190
190
  name: { type: "string", description: "Display name. Optional for: create." },
@@ -477,7 +477,7 @@ const SERVER_INSTRUCTIONS = `You are building full-stack applications on the DYP
477
477
  - ❌ *"¿Prefieres Tailwind o CSS Modules?"*
478
478
  - ❌ Asking "which framework" unless the user explicitly says *"I want to compare platforms"* or *"what are my options"*.
479
479
 
480
- These are ALL dead signals: Next.js is already what DYPAI scaffolds. The DB is already PostgreSQL (via DYPAI engine). Auth is already better-auth (built in). Tailwind is already in the templates. Prisma / ORMs are not used — you write SQL directly in workflow endpoints.
480
+ These are ALL dead signals: Next.js is already what DYPAI scaffolds. The DB is already PostgreSQL (via DYPAI engine). Auth is built in. Tailwind is already in the templates. Prisma / ORMs are not used — you write SQL directly in workflow endpoints.
481
481
 
482
482
  ## What to do when the user says "I want to build X"
483
483
 
@@ -861,7 +861,7 @@ Mental translations: "edge function" → workflow with one code node; "cron" →
861
861
 
862
862
  ## Common app recipes (one-liners)
863
863
 
864
- - **Auth-gated CRUD**: table with \`user_id UUID\`, jwt endpoints, SQL always filters by \`\${current_user_id}\`, frontend \`<ProtectedRoute>\`.
864
+ - **Auth-gated CRUD**: table with \`user_id TEXT\` (auth IDs are TEXT, not UUID), jwt endpoints, SQL always filters by \`\${current_user_id}\`, frontend \`<ProtectedRoute>\`.
865
865
  - **Admin panel**: endpoints with \`allowed_roles: [admin]\`. Same SQL, no user filter (admin sees all). Promote via \`manage_users(update_role)\`.
866
866
  - **AI chat**: single endpoint with \`agent\` node + \`memory_key: "chat:\${current_user_id}"\`. Frontend \`dypai.api.stream()\`.
867
867
  - **Payments (Stripe)**: \`stripe\` node for ops. Webhook endpoint with \`trigger.webhook\` + \`stripe_webhook: true\` (auto-verifies signature).
@@ -889,7 +889,7 @@ SDK is pre-configured at \`src/lib/dypai.ts\` (or \`src/dypai.ts\`). Import \`dy
889
889
 
890
890
  - \`bulk_upsert\` — CSV/JSON → table. Seed data.
891
891
  - \`manage_domain\` — custom domains. \`add\` returns CNAME to configure. \`verify\` rechecks DNS/SSL. → \`search_docs("manage domain")\`.
892
- - \`manage_users\` / \`manage_roles\` — app-level RBAC (better-auth). Create/ban/assign roles.
892
+ - \`manage_users\` / \`manage_roles\` — app-level RBAC. Create/ban/assign roles.
893
893
  - \`manage_schedules\` / \`manage_webhooks\` — pause/resume/history. To change the DEFINITION, edit the YAML and push.
894
894
  - \`manage_storage\` — buckets + objects. \`upload_file\` reads local path, signs URL, PUTs, registers. Max 100MB/file. → \`search_docs("file storage")\`.
895
895
  - \`manage_drafts\` — universal draft/publish. \`list\` before \`publish\` so the user sees what's shipping. \`discard\` to throw away. Always pair with \`dypai_test_endpoint(mode:'draft')\` before publish.
@@ -18,7 +18,7 @@
18
18
 
19
19
  // Schemas the agent must not modify. SELECT against them stays allowed.
20
20
  const PROTECTED_SCHEMAS = new Set([
21
- "auth", // better-auth user/session tables — engine-owned
21
+ "auth", // auth user/session tables — engine-owned
22
22
  "storage", // file upload metadata — engine-owned
23
23
  "system", // DYPAI internals (endpoints, credentials, etc.)
24
24
  "information_schema", // PG metadata catalog
@@ -127,7 +127,7 @@ export const dypaiDescribeTool = {
127
127
  placeholders_available: [
128
128
  "${input.<field>} — request body / query params",
129
129
  "${nodes.<node_id>.<field>} — output of a previous node",
130
- "${current_user_id} — uuid of the authenticated user (jwt auth only)",
130
+ "${current_user_id} — id of the authenticated user (TEXT, NOT a UUID; jwt auth only)",
131
131
  "${current_user_role} — role name of the authenticated user",
132
132
  ],
133
133
 
@@ -206,7 +206,7 @@ output:
206
206
  #
207
207
  # \${input.<field>} — the request body / query params
208
208
  # \${nodes.<id>.<field>} — output of a previous node
209
- # \${current_user_id} — UUID of the JWT-authenticated user
209
+ # \${current_user_id} — ID of the JWT-authenticated user (TEXT, NOT a UUID — match against TEXT columns)
210
210
  # \${current_user_role} — role name from the JWT
211
211
  #
212
212
  # Expressions inside placeholders work: arithmetic, comparisons, JS-ish.
@@ -218,8 +218,9 @@ output:
218
218
  # plain object/array → binds as ::jsonb
219
219
  # Date instance → binds as ::timestamptz
220
220
  # text / int / bool → binds without an explicit cast (Postgres infers)
221
- # So you write SQL naturally — DON'T add '\${current_user_id}'::uuid manually.
222
- # Just write: WHERE user_id = \${current_user_id}
221
+ # So you write SQL naturally — DON'T add type casts manually like
222
+ # '\${input.product_id}'::uuid. Just write: WHERE id = \${input.product_id}
223
+ # (and remember: \${current_user_id} is TEXT, so user_id columns must be TEXT too).
223
224
  workflow:
224
225
  nodes:
225
226
 
@@ -243,7 +243,7 @@ export const dypaiTestEndpointTool = {
243
243
  },
244
244
  as_user: {
245
245
  type: "string",
246
- description: "User UUID to impersonate. Required for jwt endpoints that read ${current_user_id}.",
246
+ description: "User ID to impersonate. Required for jwt endpoints that read ${current_user_id}. NOTE: user IDs are stored in auth.\"user\".id as a TEXT alphanumeric string (e.g. '9KxggvkPhgpYXITE6koY0vYWJqQzSwaw'), NOT a UUID. Discover IDs with manage_users(operation:'list') or execute_sql(\"SELECT id, email FROM auth.\\\"user\\\" LIMIT 5\"). Common mistake: passing a UUID copied from system.users or a business table.",
247
247
  },
248
248
  trace_mode: {
249
249
  type: "string",
@@ -1175,7 +1175,7 @@ export async function runValidation(rootDir, projectId) {
1175
1175
  ` user_id TEXT NOT NULL,\\n` +
1176
1176
  ` created_at TIMESTAMPTZ DEFAULT NOW()\\n` +
1177
1177
  ` );" })\n` +
1178
- `IMPORTANT: user_id must be TEXT (not UUID) — better-auth's auth.user.id is a 32-char nanoid stored as TEXT. ` +
1178
+ `IMPORTANT: user_id must be TEXT (not UUID) — auth.\"user\".id is a TEXT alphanumeric string (~32 chars). ` +
1179
1179
  `(Add other columns matching what your endpoint INSERTs.) ` +
1180
1180
  `schema.sql will auto-refresh after the DDL. Existing tables: ${knownTablesList}`,
1181
1181
  })