@genlobe/mcp-server 3.7.0 → 3.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +46 -25
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3504,11 +3504,11 @@ const ENTITY_SCHEMA_RECIPES = {
|
|
|
3504
3504
|
description: "Catalog product with price, stock, category, description.",
|
|
3505
3505
|
fields_definition: {
|
|
3506
3506
|
name: { type: "string", required: true, max_length: 200 },
|
|
3507
|
-
price: { type: "
|
|
3508
|
-
stock: { type: "
|
|
3507
|
+
price: { type: "float", required: true, min: 0 },
|
|
3508
|
+
stock: { type: "integer", required: true, min: 0, default: 0 },
|
|
3509
3509
|
currency: { type: "string", required: false, default: "USD", max_length: 3 },
|
|
3510
3510
|
category: { type: "string", required: false, max_length: 100 },
|
|
3511
|
-
description: { type: "
|
|
3511
|
+
description: { type: "text", required: false },
|
|
3512
3512
|
is_active: { type: "boolean", required: false, default: true },
|
|
3513
3513
|
},
|
|
3514
3514
|
bulk_seed_example: [
|
|
@@ -3525,15 +3525,15 @@ const ENTITY_SCHEMA_RECIPES = {
|
|
|
3525
3525
|
fields_definition: {
|
|
3526
3526
|
name: { type: "string", required: true, max_length: 200 },
|
|
3527
3527
|
phone: { type: "string", required: false, max_length: 50 },
|
|
3528
|
-
email: { type: "
|
|
3529
|
-
notes: { type: "
|
|
3530
|
-
tags: { type: "
|
|
3528
|
+
email: { type: "email", required: false, max_length: 200 },
|
|
3529
|
+
notes: { type: "text", required: false },
|
|
3530
|
+
tags: { type: "text", required: false },
|
|
3531
3531
|
},
|
|
3532
3532
|
bulk_seed_example: [
|
|
3533
3533
|
{ name: "Ana Pérez", phone: "+1-809-555-0100" },
|
|
3534
3534
|
{ name: "Walk-in", notes: "no-data anonymous buyer" },
|
|
3535
3535
|
],
|
|
3536
|
-
notes: "Common mistake: registering each store customer as a Genlobe end-user. Don't — that requires real email + SES delivery. Keep store customers as this custom entity unless they need to log into the storefront.",
|
|
3536
|
+
notes: "Common mistake: registering each store customer as a Genlobe end-user. Don't — that requires real email + SES delivery. Keep store customers as this custom entity unless they need to log into the storefront. `tags` is a comma-separated string (the schema validator does NOT support `array` as a field type — see the global notes at the top of every recipe).",
|
|
3537
3537
|
},
|
|
3538
3538
|
order: {
|
|
3539
3539
|
slug: "order",
|
|
@@ -3546,28 +3546,17 @@ const ENTITY_SCHEMA_RECIPES = {
|
|
|
3546
3546
|
required: false,
|
|
3547
3547
|
on_delete: "set_null",
|
|
3548
3548
|
},
|
|
3549
|
-
|
|
3550
|
-
type: "
|
|
3549
|
+
items_json: {
|
|
3550
|
+
type: "text",
|
|
3551
3551
|
required: true,
|
|
3552
|
-
item_schema: {
|
|
3553
|
-
product_id: {
|
|
3554
|
-
type: "reference",
|
|
3555
|
-
target_schema_slug: "product",
|
|
3556
|
-
required: true,
|
|
3557
|
-
on_delete: "restrict",
|
|
3558
|
-
},
|
|
3559
|
-
name_snapshot: { type: "string", required: true },
|
|
3560
|
-
price_snapshot: { type: "number", required: true, min: 0 },
|
|
3561
|
-
qty: { type: "number", required: true, min: 1 },
|
|
3562
|
-
},
|
|
3563
3552
|
},
|
|
3564
|
-
total: { type: "
|
|
3553
|
+
total: { type: "float", required: true, min: 0 },
|
|
3565
3554
|
currency: { type: "string", required: false, default: "USD" },
|
|
3566
3555
|
paid: { type: "boolean", required: true, default: false },
|
|
3567
3556
|
paid_at: { type: "datetime", required: false },
|
|
3568
|
-
notes: { type: "
|
|
3557
|
+
notes: { type: "text", required: false },
|
|
3569
3558
|
},
|
|
3570
|
-
notes: "
|
|
3559
|
+
notes: "**Line items modeling — important.** Genlobe's schema validator does NOT support `array` as a field type (validated types: string, integer, float, boolean, datetime, text, enum, email, url, phone, reference). Two ways to model line items:\n\n**Option A — simple, recommended for MVP**: store the items as a JSON string in `items_json` (type=text). Parse client-side. Each item should already include `product_id`, `name_snapshot`, `price_snapshot`, `qty`. Trade-off: you cannot search/filter by items via `POST /v1/entity/records/search` — items are opaque to the engine.\n\n**Option B — queryable, for production**: create a separate `order_item` schema with `order_id: reference->order`, `product_id: reference->product`, `name_snapshot`, `price_snapshot`, `qty`. Cross-schema joins (ADR-0009) make `\"top 5 products sold this month\"` a single search call.\n\nEither way: **always snapshot `name` and `price` at write time** so editing the product later does NOT mutate past orders.",
|
|
3571
3560
|
},
|
|
3572
3561
|
post: {
|
|
3573
3562
|
slug: "post",
|
|
@@ -3583,7 +3572,7 @@ const ENTITY_SCHEMA_RECIPES = {
|
|
|
3583
3572
|
enum: ["draft", "published", "archived"],
|
|
3584
3573
|
default: "draft",
|
|
3585
3574
|
},
|
|
3586
|
-
tags: { type: "
|
|
3575
|
+
tags: { type: "text", required: false },
|
|
3587
3576
|
published_at: { type: "datetime", required: false },
|
|
3588
3577
|
cover_image_url: { type: "string", required: false },
|
|
3589
3578
|
},
|
|
@@ -3658,7 +3647,7 @@ const ENTITY_SCHEMA_RECIPES = {
|
|
|
3658
3647
|
fields_definition: {
|
|
3659
3648
|
title: { type: "string", required: false, max_length: 200 },
|
|
3660
3649
|
body: { type: "string", required: true },
|
|
3661
|
-
tags: { type: "
|
|
3650
|
+
tags: { type: "text", required: false },
|
|
3662
3651
|
is_pinned: { type: "boolean", required: false, default: false },
|
|
3663
3652
|
},
|
|
3664
3653
|
notes: "Perfect for ADR-0007 row-level scope: regular end-users see only their own notes via `GET /v1/entity/records/mine` (no extra filter needed in the frontend).",
|
|
@@ -3685,6 +3674,14 @@ function ENTITY_SCHEMA_RECIPE(entityType) {
|
|
|
3685
3674
|
|
|
3686
3675
|
${recipe.description}
|
|
3687
3676
|
|
|
3677
|
+
## Schema field types — what the backend actually accepts
|
|
3678
|
+
|
|
3679
|
+
The Custom Entities validator only accepts these types in \`fields_definition\`:
|
|
3680
|
+
|
|
3681
|
+
\`string\`, \`text\`, \`integer\`, \`float\`, \`boolean\`, \`datetime\`, \`enum\`, \`email\`, \`url\`, \`phone\`, \`reference\` (ADR-0009).
|
|
3682
|
+
|
|
3683
|
+
**There is no \`array\` type and no \`number\` type.** Use \`integer\`/\`float\` instead of \`number\`. For list-shaped data either (a) store as a comma-separated \`text\` (simple, not queryable), or (b) model as a separate entity with a \`reference\` field pointing back (queryable, ADR-0009 cross-schema search).
|
|
3684
|
+
|
|
3688
3685
|
## Step 1 — Create the schema
|
|
3689
3686
|
|
|
3690
3687
|
\`\`\`http
|
|
@@ -3734,6 +3731,30 @@ End-to-end recipe to wire a chatbot agent that answers from a knowledge base
|
|
|
3734
3731
|
populated by a snapshot of your custom-entity catalog (typical "store
|
|
3735
3732
|
assistant" / "product Q&A" / "support deflection" use case).
|
|
3736
3733
|
|
|
3734
|
+
## Auth context — clarification (frequent confusion)
|
|
3735
|
+
|
|
3736
|
+
The end-user chat endpoint \`POST /v1/user/agents/{agent_id}/chat\` requires
|
|
3737
|
+
an end-user JWT. **There are two legitimate ways to obtain that JWT**, and a
|
|
3738
|
+
public-facing bot needs option (b):
|
|
3739
|
+
|
|
3740
|
+
- **(a) Real human end-user**: customer signs up via \`POST /v1/auth/register\`,
|
|
3741
|
+
logs in, and chats with the agent. The JWT is theirs.
|
|
3742
|
+
- **(b) Bot service account**: register **one real bot user** for the chat
|
|
3743
|
+
surface (use a real email you control, e.g. \`bot@yourshop.com\`), keep its
|
|
3744
|
+
credentials in your server env, log in server-side, attach the resulting
|
|
3745
|
+
JWT to incoming chat requests. This is what "register a bot user" means.
|
|
3746
|
+
|
|
3747
|
+
**What is NOT allowed** (and what some agents mis-read as "no LLM bot is
|
|
3748
|
+
possible"): inventing/synthesizing fake email addresses to bulk-create
|
|
3749
|
+
end-users on the fly. That bypass would route through SES and burn the
|
|
3750
|
+
sender reputation — exactly the incident pattern of #168. Registering one
|
|
3751
|
+
or a few real bot accounts that you actually own is fine.
|
|
3752
|
+
|
|
3753
|
+
If you cannot or do not want to register a bot user, an acceptable fallback
|
|
3754
|
+
for MVP is a deterministic keyword search over the catalog (no LLM, no JWT
|
|
3755
|
+
required) — useful when the storefront has to be live before you set up the
|
|
3756
|
+
LLM layer. The bot user path is still the canonical way to get a real LLM bot.
|
|
3757
|
+
|
|
3737
3758
|
## Architecture in one diagram
|
|
3738
3759
|
|
|
3739
3760
|
\`\`\`
|
package/package.json
CHANGED