@01.software/cli 0.8.0 → 0.10.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.
@@ -1,9 +1,6 @@
1
1
  // src/server.ts
2
2
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
3
 
4
- // src/tools/query-collection.ts
5
- import { z } from "zod";
6
-
7
4
  // src/lib/request-context.ts
8
5
  import { AsyncLocalStorage } from "async_hooks";
9
6
  var requestContext = new AsyncLocalStorage();
@@ -14,25 +11,645 @@ function hasRequestContext() {
14
11
  return requestContext.getStore() !== void 0;
15
12
  }
16
13
 
17
- // src/lib/client.ts
18
- import {
19
- CollectionClient,
20
- CommunityClient,
21
- ModerationApi,
22
- ServerCommerceClient,
23
- createServerClient
24
- } from "@01.software/sdk";
14
+ // src/lib/tool-utils.ts
15
+ function toolSuccess(data) {
16
+ return JSON.stringify({ success: true, ...data }, null, 2);
17
+ }
18
+ function toolError(error) {
19
+ const base = { success: false };
20
+ const isStructured = !!error && typeof error === "object" && ("code" in error || "reason" in error);
21
+ if (isStructured) {
22
+ const sdkErr = error;
23
+ base.error = sdkErr.message || "Unknown error";
24
+ if (sdkErr.status) base.status = sdkErr.status;
25
+ if (sdkErr.code) base.code = sdkErr.code;
26
+ if (sdkErr.reason) base.reason = sdkErr.reason;
27
+ if (sdkErr.requestId) base.requestId = sdkErr.requestId;
28
+ if (sdkErr.suggestion) base.suggestion = sdkErr.suggestion;
29
+ if (sdkErr.details?.errors) base.errors = sdkErr.details.errors;
30
+ } else {
31
+ base.error = error instanceof Error ? error.message : "Unknown error";
32
+ }
33
+ return JSON.stringify(base, null, 2);
34
+ }
35
+ var MAX_QUERY_DEPTH = 5;
36
+ function checkDepth(obj, depth = 0) {
37
+ if (depth > MAX_QUERY_DEPTH) return false;
38
+ if (obj && typeof obj === "object") {
39
+ for (const val of Object.values(obj)) {
40
+ if (!checkDepth(val, depth + 1)) return false;
41
+ }
42
+ }
43
+ return true;
44
+ }
45
+ function parseJsonWhere(where) {
46
+ try {
47
+ const parsed = JSON.parse(where);
48
+ if (!checkDepth(parsed)) {
49
+ return {
50
+ success: false,
51
+ error: JSON.stringify(
52
+ {
53
+ success: false,
54
+ error: `Query exceeds maximum nesting depth of ${MAX_QUERY_DEPTH}`
55
+ },
56
+ null,
57
+ 2
58
+ )
59
+ };
60
+ }
61
+ return { success: true, data: parsed };
62
+ } catch {
63
+ return {
64
+ success: false,
65
+ error: JSON.stringify(
66
+ {
67
+ success: false,
68
+ error: `Invalid JSON in "where" parameter: ${where.length > 100 ? where.substring(0, 100) + "..." : where}`
69
+ },
70
+ null,
71
+ 2
72
+ )
73
+ };
74
+ }
75
+ }
76
+
77
+ // ../../packages/auth-contracts/dist/index.js
78
+ var MCP_RESOURCE_AUDIENCE = "https://mcp.01.software/mcp";
79
+ var MCP_OAUTH_ISSUER = "https://01.software";
80
+ var MCP_PROTECTED_RESOURCE_METADATA_PATH = "/.well-known/oauth-protected-resource/mcp";
81
+ var MCP_TENANT_CLAIM = "tenant_id";
82
+ var MCP_TENANT_ROLE_CLAIM = "tenant_role";
83
+ var MCP_SCOPES = {
84
+ read: "mcp:read",
85
+ write: "mcp:write"
86
+ };
87
+ var MCP_CONSOLE_SERVICE_AUDIENCE = "https://api.01.software/internal/mcp";
88
+ var MCP_CONSOLE_SERVICE_SCOPE = "console:mcp_proxy";
89
+ var MCP_SERVICE_TOKEN_LIFETIME_SECONDS = 60;
90
+
91
+ // ../../packages/contracts/src/tenant/index.ts
92
+ import { z } from "zod";
93
+ var tenantFieldConfigStateSchema = z.object({
94
+ hiddenFields: z.array(z.string()),
95
+ isHidden: z.boolean()
96
+ }).strict();
97
+ var tenantContextQuerySchema = z.object({
98
+ counts: z.literal("true").optional()
99
+ }).strict();
100
+ var tenantContextToolInputSchema = z.object({
101
+ includeCounts: z.boolean().optional().default(false).describe(
102
+ "Include per-collection document counts and config status (bypasses cache, slower)"
103
+ )
104
+ }).strict();
105
+ var tenantContextResponseSchema = z.object({
106
+ tenant: z.object({
107
+ id: z.string(),
108
+ name: z.string(),
109
+ plan: z.string(),
110
+ planSource: z.string().optional(),
111
+ authoritative: z.boolean().optional(),
112
+ capabilityVersion: z.string().optional()
113
+ }).strict(),
114
+ features: z.array(z.string()),
115
+ collections: z.object({
116
+ active: z.array(z.string()),
117
+ inactive: z.array(z.string())
118
+ }).strict(),
119
+ fieldConfigs: z.record(z.string(), tenantFieldConfigStateSchema),
120
+ counts: z.record(z.string(), z.number()).optional(),
121
+ config: z.object({
122
+ webhookConfigured: z.boolean()
123
+ }).strict().optional()
124
+ }).strict();
125
+ var COLLECTION_SCHEMA_CONTRACT_VERSION = 1;
126
+ var collectionSchemaEndpointParamsSchema = z.object({
127
+ collectionSlug: z.string().min(1, "collectionSlug is required")
128
+ }).strict();
129
+ function createCollectionSchemaToolInputSchema(collections) {
130
+ return z.object({
131
+ collection: z.enum(collections).describe("Collection name (required)")
132
+ }).strict();
133
+ }
134
+ var collectionFieldOptionSchema = z.object({
135
+ label: z.string(),
136
+ value: z.string()
137
+ }).strict();
138
+ var collectionFieldSchema = z.lazy(
139
+ () => z.object({
140
+ name: z.string(),
141
+ path: z.string(),
142
+ type: z.string(),
143
+ required: z.literal(true).optional(),
144
+ unique: z.literal(true).optional(),
145
+ hasMany: z.literal(true).optional(),
146
+ relationTo: z.union([z.string(), z.array(z.string())]).optional(),
147
+ options: z.array(collectionFieldOptionSchema).optional(),
148
+ hidden: z.literal(true).optional(),
149
+ systemManaged: z.literal(true).optional(),
150
+ writable: z.boolean().optional(),
151
+ fields: z.array(collectionFieldSchema).optional()
152
+ }).strict()
153
+ );
154
+ var collectionSchemaResponseSchema = z.object({
155
+ contractVersion: z.literal(COLLECTION_SCHEMA_CONTRACT_VERSION),
156
+ mode: z.literal("effective"),
157
+ collection: z.object({
158
+ slug: z.string(),
159
+ timestamps: z.boolean(),
160
+ alwaysActive: z.boolean(),
161
+ feature: z.string().nullable(),
162
+ systemFields: z.array(z.string()),
163
+ visibility: z.object({
164
+ collectionHidden: z.boolean(),
165
+ hiddenFields: z.array(z.string())
166
+ }).strict(),
167
+ fields: z.array(collectionFieldSchema)
168
+ }).strict()
169
+ }).strict();
170
+
171
+ // ../../packages/contracts/src/ecommerce/index.ts
172
+ import { z as z2 } from "zod";
173
+ var transactionStatusSchema = z2.enum([
174
+ "pending",
175
+ "paid",
176
+ "failed",
177
+ "canceled"
178
+ ]);
179
+ var updateTransactionSchema = z2.object({
180
+ pgPaymentId: z2.string().min(1, "pgPaymentId is required").describe("PG payment ID (required)"),
181
+ status: transactionStatusSchema.describe(
182
+ "New transaction status (required)"
183
+ ),
184
+ paymentMethod: z2.string().optional().describe("Payment method (optional)"),
185
+ receiptUrl: z2.string().optional().describe("Receipt URL (optional)"),
186
+ paymentKey: z2.string().min(1).optional().describe("Provider payment key for verified paid confirmation"),
187
+ amount: z2.number().int().positive().optional().describe("Provider-confirmed amount for verified paid confirmation")
188
+ }).strict();
189
+ var UpdateTransactionSchema = updateTransactionSchema;
190
+ var returnReasonSchema = z2.enum([
191
+ "change_of_mind",
192
+ "defective",
193
+ "wrong_delivery",
194
+ "damaged",
195
+ "other"
196
+ ]);
197
+ var restockActionSchema = z2.enum(["return_to_stock", "discard"]);
198
+ var returnWithRefundItemSchema = z2.object({
199
+ orderItem: z2.union([z2.string(), z2.number()]).transform(String),
200
+ quantity: z2.number().int().positive("quantity must be a positive integer"),
201
+ restockAction: restockActionSchema.default("return_to_stock")
202
+ }).strict();
203
+ var returnWithRefundSchema = z2.object({
204
+ orderNumber: z2.string().min(1, "orderNumber is required").describe("Order number (required)"),
205
+ reason: returnReasonSchema.optional().describe("Return reason (optional)"),
206
+ reasonDetail: z2.string().optional().describe("Detailed reason text (optional)"),
207
+ returnItems: z2.array(returnWithRefundItemSchema).min(1, "At least one return item is required").max(100, "Too many return items").describe("Array of products to return (required)"),
208
+ refundAmount: z2.number().min(0, "refundAmount must be non-negative").describe("Refund amount (required, min 0)"),
209
+ pgPaymentId: z2.string().min(1, "pgPaymentId is required").describe("PG payment ID for refund (required)"),
210
+ paymentKey: z2.string().min(1).optional().describe("Provider payment key for verified refund"),
211
+ refundReceiptUrl: z2.string().optional().describe("Refund receipt URL (optional)")
212
+ }).strict();
213
+ var ReturnWithRefundSchema = returnWithRefundSchema;
214
+
215
+ // ../../packages/contracts/src/mcp/index.ts
216
+ var MCP_TOOL_CONTRACT = {
217
+ "query-collection": {
218
+ consoleRole: "tenant-viewer",
219
+ oauthScope: "mcp:read",
220
+ readOnly: true
221
+ },
222
+ "get-collection-by-id": {
223
+ consoleRole: "tenant-viewer",
224
+ oauthScope: "mcp:read",
225
+ readOnly: true
226
+ },
227
+ "get-order": {
228
+ consoleRole: "tenant-viewer",
229
+ oauthScope: "mcp:read",
230
+ readOnly: true
231
+ },
232
+ "stock-check": {
233
+ consoleRole: "tenant-viewer",
234
+ oauthScope: "mcp:read",
235
+ readOnly: true
236
+ },
237
+ "validate-discount": {
238
+ consoleRole: "tenant-viewer",
239
+ oauthScope: "mcp:read",
240
+ readOnly: true
241
+ },
242
+ "calculate-shipping": {
243
+ consoleRole: "tenant-viewer",
244
+ oauthScope: "mcp:read",
245
+ readOnly: true
246
+ },
247
+ "get-collection-schema": {
248
+ consoleRole: "tenant-viewer",
249
+ oauthScope: "mcp:read",
250
+ readOnly: true
251
+ },
252
+ "list-configurable-fields": {
253
+ consoleRole: "tenant-viewer",
254
+ oauthScope: "mcp:read",
255
+ readOnly: true
256
+ },
257
+ "get-tenant-context": {
258
+ consoleRole: "tenant-viewer",
259
+ oauthScope: "mcp:read",
260
+ readOnly: true
261
+ },
262
+ "add-cart-item": {
263
+ consoleRole: "tenant-editor",
264
+ oauthScope: "mcp:write",
265
+ readOnly: false
266
+ },
267
+ "update-cart-item": {
268
+ consoleRole: "tenant-editor",
269
+ oauthScope: "mcp:write",
270
+ readOnly: false
271
+ },
272
+ "remove-cart-item": {
273
+ consoleRole: "tenant-editor",
274
+ oauthScope: "mcp:write",
275
+ readOnly: false
276
+ },
277
+ "clear-cart": {
278
+ consoleRole: "tenant-editor",
279
+ oauthScope: "mcp:write",
280
+ readOnly: false
281
+ },
282
+ "apply-discount": {
283
+ consoleRole: "tenant-editor",
284
+ oauthScope: "mcp:write",
285
+ readOnly: false
286
+ },
287
+ "remove-discount": {
288
+ consoleRole: "tenant-editor",
289
+ oauthScope: "mcp:write",
290
+ readOnly: false
291
+ },
292
+ checkout: {
293
+ consoleRole: "tenant-admin",
294
+ oauthScope: "mcp:write",
295
+ readOnly: false
296
+ },
297
+ "create-order": {
298
+ consoleRole: "tenant-admin",
299
+ oauthScope: "mcp:write",
300
+ readOnly: false
301
+ },
302
+ "update-order": {
303
+ consoleRole: "tenant-admin",
304
+ oauthScope: "mcp:write",
305
+ readOnly: false
306
+ },
307
+ "create-fulfillment": {
308
+ consoleRole: "tenant-admin",
309
+ oauthScope: "mcp:write",
310
+ readOnly: false
311
+ },
312
+ "update-fulfillment": {
313
+ consoleRole: "tenant-admin",
314
+ oauthScope: "mcp:write",
315
+ readOnly: false
316
+ },
317
+ "create-return": {
318
+ consoleRole: "tenant-admin",
319
+ oauthScope: "mcp:write",
320
+ readOnly: false
321
+ },
322
+ "update-return": {
323
+ consoleRole: "tenant-admin",
324
+ oauthScope: "mcp:write",
325
+ readOnly: false
326
+ },
327
+ "return-with-refund": {
328
+ consoleRole: "tenant-admin",
329
+ oauthScope: "mcp:write",
330
+ readOnly: false
331
+ },
332
+ "update-transaction": {
333
+ consoleRole: "tenant-admin",
334
+ oauthScope: "mcp:write",
335
+ readOnly: false
336
+ },
337
+ "update-field-config": {
338
+ consoleRole: "tenant-admin",
339
+ oauthScope: "mcp:write",
340
+ readOnly: false
341
+ },
342
+ "sdk-get-recipe": {
343
+ consoleRole: "tenant-viewer",
344
+ oauthScope: "mcp:read",
345
+ readOnly: true
346
+ },
347
+ "sdk-search-docs": {
348
+ consoleRole: "tenant-viewer",
349
+ oauthScope: "mcp:read",
350
+ readOnly: true
351
+ },
352
+ "sdk-get-auth-setup": {
353
+ consoleRole: "tenant-viewer",
354
+ oauthScope: "mcp:read",
355
+ readOnly: true
356
+ },
357
+ "sdk-get-collection-pattern": {
358
+ consoleRole: "tenant-viewer",
359
+ oauthScope: "mcp:read",
360
+ readOnly: true
361
+ }
362
+ };
363
+ var MCP_TOOL_NAMES = Object.keys(
364
+ MCP_TOOL_CONTRACT
365
+ );
366
+ function isMcpToolName(toolName) {
367
+ return Object.prototype.hasOwnProperty.call(MCP_TOOL_CONTRACT, toolName);
368
+ }
369
+
370
+ // src/tool-policy.ts
371
+ var READ_ONLY_ANNOTATION = {
372
+ readOnly: true,
373
+ destructive: false,
374
+ idempotent: true,
375
+ openWorld: false
376
+ };
377
+ var NON_DESTRUCTIVE_MUTATION_ANNOTATION = {
378
+ readOnly: false,
379
+ destructive: false,
380
+ idempotent: false,
381
+ openWorld: false
382
+ };
383
+ var NON_DESTRUCTIVE_IDEMPOTENT_MUTATION_ANNOTATION = {
384
+ readOnly: false,
385
+ destructive: false,
386
+ idempotent: true,
387
+ openWorld: false
388
+ };
389
+ var DESTRUCTIVE_NON_IDEMPOTENT_MUTATION_ANNOTATION = {
390
+ readOnly: false,
391
+ destructive: true,
392
+ idempotent: false,
393
+ openWorld: false
394
+ };
395
+ var DESTRUCTIVE_IDEMPOTENT_MUTATION_ANNOTATION = {
396
+ readOnly: false,
397
+ destructive: true,
398
+ idempotent: true,
399
+ openWorld: false
400
+ };
401
+ var REASON_IDEMPOTENT_DESTRUCTIVE_UPDATE = "Update operations mutate persisted state but converge to the same end state under repeated identical input.";
402
+ var REASON_CART_EPHEMERAL = "Cart is pre-checkout ephemeral state; reversal is possible by reissuing the prior input. Console enforces tenant scope.";
403
+ var TOOL_POLICY_MANIFEST = {
404
+ // ── Read-only collection / validation (mcp:read, tenant-viewer) ──
405
+ "query-collection": {
406
+ category: "read-only-collection",
407
+ oauthScope: MCP_SCOPES.read,
408
+ consoleRole: "tenant-viewer",
409
+ consoleSurface: "GET /api/{collection}",
410
+ annotationPolicy: READ_ONLY_ANNOTATION
411
+ },
412
+ "get-collection-by-id": {
413
+ category: "read-only-collection",
414
+ oauthScope: MCP_SCOPES.read,
415
+ consoleRole: "tenant-viewer",
416
+ consoleSurface: "GET /api/{collection}/{id}",
417
+ annotationPolicy: READ_ONLY_ANNOTATION
418
+ },
419
+ "get-order": {
420
+ category: "read-only-collection",
421
+ oauthScope: MCP_SCOPES.read,
422
+ consoleRole: "tenant-viewer",
423
+ consoleSurface: "GET /api/orders/{id}",
424
+ annotationPolicy: READ_ONLY_ANNOTATION
425
+ },
426
+ "stock-check": {
427
+ category: "read-only-collection",
428
+ oauthScope: MCP_SCOPES.read,
429
+ consoleRole: "tenant-viewer",
430
+ consoleSurface: "GET /api/products/{id}/stock",
431
+ annotationPolicy: READ_ONLY_ANNOTATION
432
+ },
433
+ "validate-discount": {
434
+ category: "read-only-collection",
435
+ oauthScope: MCP_SCOPES.read,
436
+ consoleRole: "tenant-viewer",
437
+ consoleSurface: "POST /api/discounts/validate",
438
+ annotationPolicy: READ_ONLY_ANNOTATION
439
+ },
440
+ "calculate-shipping": {
441
+ category: "read-only-collection",
442
+ oauthScope: MCP_SCOPES.read,
443
+ consoleRole: "tenant-viewer",
444
+ consoleSurface: "POST /api/shipping/calculate",
445
+ annotationPolicy: READ_ONLY_ANNOTATION
446
+ },
447
+ "get-collection-schema": {
448
+ category: "read-only-collection",
449
+ oauthScope: MCP_SCOPES.read,
450
+ consoleRole: "tenant-viewer",
451
+ consoleSurface: "GET /api/tenants/schema/{collectionSlug}",
452
+ annotationPolicy: READ_ONLY_ANNOTATION
453
+ },
454
+ "list-configurable-fields": {
455
+ category: "read-only-collection",
456
+ oauthScope: MCP_SCOPES.read,
457
+ consoleRole: "tenant-viewer",
458
+ consoleSurface: "GET /api/tenants/field-config",
459
+ annotationPolicy: READ_ONLY_ANNOTATION
460
+ },
461
+ // ── Tenant context (mcp:read, tenant-viewer) ──
462
+ "get-tenant-context": {
463
+ category: "read-only-tenant",
464
+ oauthScope: MCP_SCOPES.read,
465
+ consoleRole: "tenant-viewer",
466
+ consoleSurface: "GET /api/tenants/context",
467
+ annotationPolicy: READ_ONLY_ANNOTATION
468
+ },
469
+ // ── Cart mutations (mcp:write, tenant-editor) ──
470
+ "add-cart-item": {
471
+ category: "mutation-cart",
472
+ oauthScope: MCP_SCOPES.write,
473
+ consoleRole: "tenant-editor",
474
+ consoleSurface: "POST /api/carts/{id}/items",
475
+ annotationPolicy: NON_DESTRUCTIVE_IDEMPOTENT_MUTATION_ANNOTATION
476
+ },
477
+ "update-cart-item": {
478
+ category: "mutation-cart",
479
+ oauthScope: MCP_SCOPES.write,
480
+ consoleRole: "tenant-editor",
481
+ consoleSurface: "PATCH /api/carts/{id}/items/{itemId}",
482
+ annotationPolicy: DESTRUCTIVE_IDEMPOTENT_MUTATION_ANNOTATION,
483
+ exemptionReason: REASON_CART_EPHEMERAL
484
+ },
485
+ "remove-cart-item": {
486
+ category: "mutation-cart",
487
+ oauthScope: MCP_SCOPES.write,
488
+ consoleRole: "tenant-editor",
489
+ consoleSurface: "DELETE /api/carts/{id}/items/{itemId}",
490
+ annotationPolicy: DESTRUCTIVE_IDEMPOTENT_MUTATION_ANNOTATION,
491
+ exemptionReason: REASON_CART_EPHEMERAL
492
+ },
493
+ "clear-cart": {
494
+ category: "mutation-cart",
495
+ oauthScope: MCP_SCOPES.write,
496
+ consoleRole: "tenant-editor",
497
+ consoleSurface: "POST /api/carts/{id}/clear",
498
+ annotationPolicy: DESTRUCTIVE_IDEMPOTENT_MUTATION_ANNOTATION,
499
+ exemptionReason: REASON_CART_EPHEMERAL
500
+ },
501
+ "apply-discount": {
502
+ category: "mutation-cart",
503
+ oauthScope: MCP_SCOPES.write,
504
+ consoleRole: "tenant-editor",
505
+ consoleSurface: "POST /api/carts/{id}/discount",
506
+ annotationPolicy: DESTRUCTIVE_IDEMPOTENT_MUTATION_ANNOTATION,
507
+ exemptionReason: REASON_CART_EPHEMERAL
508
+ },
509
+ "remove-discount": {
510
+ category: "mutation-cart",
511
+ oauthScope: MCP_SCOPES.write,
512
+ consoleRole: "tenant-editor",
513
+ consoleSurface: "DELETE /api/carts/{id}/discount",
514
+ annotationPolicy: DESTRUCTIVE_IDEMPOTENT_MUTATION_ANNOTATION,
515
+ exemptionReason: REASON_CART_EPHEMERAL
516
+ },
517
+ // ── Order mutations (mcp:write, tenant-admin) ──
518
+ "checkout": {
519
+ category: "mutation-order",
520
+ oauthScope: MCP_SCOPES.write,
521
+ consoleRole: "tenant-admin",
522
+ consoleSurface: "POST /api/checkout",
523
+ annotationPolicy: DESTRUCTIVE_NON_IDEMPOTENT_MUTATION_ANNOTATION
524
+ },
525
+ "create-order": {
526
+ category: "mutation-order",
527
+ oauthScope: MCP_SCOPES.write,
528
+ consoleRole: "tenant-admin",
529
+ consoleSurface: "POST /api/orders",
530
+ annotationPolicy: DESTRUCTIVE_NON_IDEMPOTENT_MUTATION_ANNOTATION
531
+ },
532
+ "update-order": {
533
+ category: "mutation-order",
534
+ oauthScope: MCP_SCOPES.write,
535
+ consoleRole: "tenant-admin",
536
+ consoleSurface: "PATCH /api/orders/{id}",
537
+ annotationPolicy: DESTRUCTIVE_IDEMPOTENT_MUTATION_ANNOTATION,
538
+ exemptionReason: REASON_IDEMPOTENT_DESTRUCTIVE_UPDATE
539
+ },
540
+ // ── Fulfillment mutations (mcp:write, tenant-admin) ──
541
+ "create-fulfillment": {
542
+ category: "mutation-fulfillment",
543
+ oauthScope: MCP_SCOPES.write,
544
+ consoleRole: "tenant-admin",
545
+ consoleSurface: "POST /api/orders/{id}/fulfillments",
546
+ annotationPolicy: NON_DESTRUCTIVE_MUTATION_ANNOTATION
547
+ },
548
+ "update-fulfillment": {
549
+ category: "mutation-fulfillment",
550
+ oauthScope: MCP_SCOPES.write,
551
+ consoleRole: "tenant-admin",
552
+ consoleSurface: "PATCH /api/fulfillments/{id}",
553
+ annotationPolicy: DESTRUCTIVE_IDEMPOTENT_MUTATION_ANNOTATION,
554
+ exemptionReason: REASON_IDEMPOTENT_DESTRUCTIVE_UPDATE
555
+ },
556
+ // ── Return mutations (mcp:write, tenant-admin) ──
557
+ "create-return": {
558
+ category: "mutation-return",
559
+ oauthScope: MCP_SCOPES.write,
560
+ consoleRole: "tenant-admin",
561
+ consoleSurface: "POST /api/returns",
562
+ annotationPolicy: DESTRUCTIVE_NON_IDEMPOTENT_MUTATION_ANNOTATION
563
+ },
564
+ "update-return": {
565
+ category: "mutation-return",
566
+ oauthScope: MCP_SCOPES.write,
567
+ consoleRole: "tenant-admin",
568
+ consoleSurface: "PATCH /api/returns/{id}",
569
+ annotationPolicy: DESTRUCTIVE_IDEMPOTENT_MUTATION_ANNOTATION,
570
+ exemptionReason: REASON_IDEMPOTENT_DESTRUCTIVE_UPDATE
571
+ },
572
+ "return-with-refund": {
573
+ category: "mutation-return",
574
+ oauthScope: MCP_SCOPES.write,
575
+ consoleRole: "tenant-admin",
576
+ consoleSurface: "POST /api/returns/with-refund",
577
+ annotationPolicy: DESTRUCTIVE_NON_IDEMPOTENT_MUTATION_ANNOTATION
578
+ },
579
+ // ── Transaction mutations (mcp:write, tenant-admin) ──
580
+ "update-transaction": {
581
+ category: "mutation-transaction",
582
+ oauthScope: MCP_SCOPES.write,
583
+ consoleRole: "tenant-admin",
584
+ consoleSurface: "PATCH /api/transactions/{id}",
585
+ annotationPolicy: DESTRUCTIVE_NON_IDEMPOTENT_MUTATION_ANNOTATION
586
+ },
587
+ // ── Field-config mutations (mcp:write, tenant-admin) ──
588
+ "update-field-config": {
589
+ category: "mutation-field-config",
590
+ oauthScope: MCP_SCOPES.write,
591
+ consoleRole: "tenant-admin",
592
+ consoleSurface: "PATCH /api/tenants/field-config",
593
+ annotationPolicy: NON_DESTRUCTIVE_IDEMPOTENT_MUTATION_ANNOTATION
594
+ },
595
+ // ── SDK doc tools (mcp:read, tenant-viewer, sdk-static surface) ──
596
+ "sdk-get-recipe": {
597
+ category: "sdk-doc",
598
+ oauthScope: MCP_SCOPES.read,
599
+ consoleRole: "tenant-viewer",
600
+ consoleSurface: "sdk-static",
601
+ annotationPolicy: READ_ONLY_ANNOTATION
602
+ },
603
+ "sdk-search-docs": {
604
+ category: "sdk-doc",
605
+ oauthScope: MCP_SCOPES.read,
606
+ consoleRole: "tenant-viewer",
607
+ consoleSurface: "sdk-static",
608
+ annotationPolicy: READ_ONLY_ANNOTATION
609
+ },
610
+ "sdk-get-auth-setup": {
611
+ category: "sdk-doc",
612
+ oauthScope: MCP_SCOPES.read,
613
+ consoleRole: "tenant-viewer",
614
+ consoleSurface: "sdk-static",
615
+ annotationPolicy: READ_ONLY_ANNOTATION
616
+ },
617
+ "sdk-get-collection-pattern": {
618
+ category: "sdk-doc",
619
+ oauthScope: MCP_SCOPES.read,
620
+ consoleRole: "tenant-viewer",
621
+ consoleSurface: "sdk-static",
622
+ annotationPolicy: READ_ONLY_ANNOTATION
623
+ }
624
+ };
625
+ function evaluateToolPolicy(toolName, scopes) {
626
+ if (!isMcpToolName(toolName)) {
627
+ return {
628
+ allowed: false,
629
+ reason: "tool_policy_missing",
630
+ message: `No tool-policy entry for ${toolName}`
631
+ };
632
+ }
633
+ const entry = TOOL_POLICY_MANIFEST[toolName];
634
+ if (!scopes.includes(entry.oauthScope)) {
635
+ return {
636
+ allowed: false,
637
+ reason: "insufficient_scope",
638
+ message: `Tool ${toolName} requires ${entry.oauthScope}`
639
+ };
640
+ }
641
+ return { allowed: true, entry };
642
+ }
643
+
644
+ // src/lib/mcp-telemetry.ts
645
+ import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
646
+ import { randomUUID as randomUUID2 } from "crypto";
647
+
648
+ // src/lib/console-api.ts
649
+ import { createHash } from "crypto";
25
650
 
26
651
  // src/service-auth.ts
27
652
  import { createPrivateKey, randomUUID, sign as signBytes } from "crypto";
28
- import {
29
- MCP_CONSOLE_SERVICE_AUDIENCE,
30
- MCP_CONSOLE_SERVICE_SCOPE,
31
- MCP_OAUTH_ISSUER,
32
- MCP_SERVICE_TOKEN_LIFETIME_SECONDS,
33
- MCP_TENANT_CLAIM,
34
- MCP_TENANT_ROLE_CLAIM
35
- } from "@01.software/auth-contracts";
36
653
  var KEYSET_ENV = "MCP_SERVICE_KEYSET";
37
654
  function assertProductionKeysetUse(source) {
38
655
  const vercelEnv = process.env.VERCEL_ENV;
@@ -158,136 +775,243 @@ function signMcpServiceToken(context) {
158
775
  return `${signingInput}.${signature.toString("base64url")}`;
159
776
  }
160
777
 
161
- // src/lib/client.ts
778
+ // src/lib/console-api.ts
779
+ var BASE_URL = process.env.SOFTWARE_API_URL || "http://localhost:3000";
780
+ var TIMEOUT_MS = 5e3;
162
781
  var MISSING_HTTP_AUTH_CONTEXT_ERROR = "MCP HTTP requests require a validated OAuth tenant context before tool execution.";
163
- function getClient() {
782
+ function resolveAuthHeaderContext() {
164
783
  const oauthContext = tenantAuthContext();
165
784
  if (oauthContext) {
166
- const serviceToken = signMcpServiceToken(oauthContext);
167
- const client = {
168
- lastRequestId: null,
169
- commerce: void 0,
170
- collections: void 0,
171
- community: void 0
172
- };
173
- const onRequestId = (id) => {
174
- client.lastRequestId = id;
785
+ return {
786
+ apiKey: signMcpServiceToken(oauthContext),
787
+ mode: "oauth"
175
788
  };
176
- client.commerce = new ServerCommerceClient({
177
- secretKey: serviceToken,
178
- onRequestId
179
- });
180
- client.collections = new CollectionClient(
181
- "",
182
- serviceToken,
183
- void 0,
184
- void 0,
185
- onRequestId
186
- );
187
- const community = new CommunityClient({ secretKey: serviceToken });
188
- const moderation = new ModerationApi({ secretKey: serviceToken, onRequestId });
189
- client.community = Object.assign(community, {
190
- moderation: {
191
- banCustomer: moderation.banCustomer.bind(moderation),
192
- unbanCustomer: moderation.unbanCustomer.bind(moderation)
193
- }
194
- });
195
- return client;
196
789
  }
197
790
  if (hasRequestContext()) throw new Error(MISSING_HTTP_AUTH_CONTEXT_ERROR);
198
- const secretKey = process.env.SOFTWARE_SECRET_KEY;
199
- const publishableKey = process.env.SOFTWARE_PUBLISHABLE_KEY || process.env.NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY;
200
- if (!secretKey) {
791
+ return {
792
+ apiKey: process.env.SOFTWARE_SECRET_KEY,
793
+ mode: "stdio",
794
+ publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY ?? process.env.NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY
795
+ };
796
+ }
797
+ function resolveApiKey() {
798
+ const { apiKey } = resolveAuthHeaderContext();
799
+ if (!apiKey || typeof apiKey !== "string") {
201
800
  throw new Error(
202
801
  "Authentication required. Set SOFTWARE_SECRET_KEY for stdio transport."
203
802
  );
204
803
  }
205
- if (!secretKey.startsWith("sk01_") && !secretKey.startsWith("pat01_")) {
206
- throw new Error("Invalid SOFTWARE_SECRET_KEY format. Expected sk01_ or pat01_ token.");
804
+ return apiKey;
805
+ }
806
+ function buildAuthHeaders(apiKey) {
807
+ const { mode, publishableKey } = resolveAuthHeaderContext();
808
+ const headers = {
809
+ Authorization: `Bearer ${apiKey}`
810
+ };
811
+ if (mode === "stdio" && publishableKey) {
812
+ headers["X-Publishable-Key"] = publishableKey;
207
813
  }
208
- if (!publishableKey) {
209
- throw new Error(
210
- "publishableKey is required. Set SOFTWARE_PUBLISHABLE_KEY for stdio transport. It is used for rate limiting and monthly quota enforcement via the edge proxy."
211
- );
814
+ return headers;
815
+ }
816
+ function extractErrorMessage(body) {
817
+ if (!body || typeof body !== "object") return void 0;
818
+ const b = body;
819
+ if (typeof b.error === "string") return b.error;
820
+ if (Array.isArray(b.errors) && b.errors[0]?.message) {
821
+ return String(b.errors[0].message);
212
822
  }
213
- return createServerClient({
214
- publishableKey,
215
- secretKey
216
- });
823
+ if (typeof b.message === "string") return b.message;
824
+ return void 0;
217
825
  }
218
-
219
- // src/tools/query-collection.ts
220
- import { COLLECTIONS } from "@01.software/sdk";
221
-
222
- // src/lib/tool-utils.ts
223
- function toolSuccess(data) {
224
- return JSON.stringify({ success: true, ...data }, null, 2);
826
+ async function consoleGet(path, apiKey) {
827
+ const authHeaders = buildAuthHeaders(apiKey);
828
+ const controller = new AbortController();
829
+ const timeoutId = setTimeout(() => controller.abort(), TIMEOUT_MS);
830
+ try {
831
+ const res = await fetch(`${BASE_URL}${path}`, {
832
+ headers: authHeaders,
833
+ signal: controller.signal
834
+ });
835
+ if (!res.ok) {
836
+ const body = await res.json().catch(() => ({}));
837
+ const msg = extractErrorMessage(body);
838
+ throw new Error(msg || `Console GET ${path} failed: ${res.status}`);
839
+ }
840
+ return res.json();
841
+ } finally {
842
+ clearTimeout(timeoutId);
843
+ }
225
844
  }
226
- function toolError(error) {
227
- const base = { success: false };
228
- if (error && typeof error === "object" && "code" in error) {
229
- const sdkErr = error;
230
- base.error = sdkErr.message || "Unknown error";
231
- if (sdkErr.status) base.status = sdkErr.status;
232
- if (sdkErr.code) base.code = sdkErr.code;
233
- if (sdkErr.suggestion) base.suggestion = sdkErr.suggestion;
234
- if (sdkErr.details?.errors) base.errors = sdkErr.details.errors;
235
- } else {
236
- base.error = error instanceof Error ? error.message : "Unknown error";
845
+ async function consolePost(path, body, apiKey) {
846
+ const authHeaders = buildAuthHeaders(apiKey);
847
+ const controller = new AbortController();
848
+ const timeoutId = setTimeout(() => controller.abort(), TIMEOUT_MS);
849
+ try {
850
+ const res = await fetch(`${BASE_URL}${path}`, {
851
+ method: "POST",
852
+ headers: { ...authHeaders, "Content-Type": "application/json" },
853
+ body: JSON.stringify(body),
854
+ signal: controller.signal
855
+ });
856
+ if (!res.ok) {
857
+ const errBody = await res.json().catch(() => ({}));
858
+ const msg = extractErrorMessage(errBody);
859
+ throw new Error(msg || `Console POST ${path} failed: ${res.status}`);
860
+ }
861
+ return res.json();
862
+ } finally {
863
+ clearTimeout(timeoutId);
237
864
  }
238
- return JSON.stringify(base, null, 2);
239
865
  }
240
- var MAX_QUERY_DEPTH = 5;
241
- function checkDepth(obj, depth = 0) {
242
- if (depth > MAX_QUERY_DEPTH) return false;
243
- if (obj && typeof obj === "object") {
244
- for (const val of Object.values(obj)) {
245
- if (!checkDepth(val, depth + 1)) return false;
866
+ async function consolePostTelemetry(path, body, apiKey) {
867
+ const authHeaders = buildAuthHeaders(apiKey);
868
+ const controller = new AbortController();
869
+ const timeoutId = setTimeout(() => controller.abort(), TIMEOUT_MS);
870
+ try {
871
+ const res = await fetch(`${BASE_URL}${path}`, {
872
+ method: "POST",
873
+ headers: { ...authHeaders, "Content-Type": "application/json" },
874
+ body: JSON.stringify(body),
875
+ signal: controller.signal
876
+ });
877
+ if (!res.ok) {
878
+ const errBody = await res.json().catch(() => ({}));
879
+ const msg = extractErrorMessage(errBody);
880
+ throw new Error(msg || `Console POST ${path} failed: ${res.status}`);
246
881
  }
882
+ } finally {
883
+ clearTimeout(timeoutId);
884
+ }
885
+ }
886
+
887
+ // src/lib/mcp-telemetry.ts
888
+ var TELEMETRY_ENDPOINT = "/api/tenants/mcp-telemetry";
889
+ var FLUSH_TIMEOUT_MS = 1500;
890
+ var telemetryContext = new AsyncLocalStorage2();
891
+ function createMcpTelemetrySummary(transport) {
892
+ return {
893
+ sessionId: randomUUID2(),
894
+ startedAtMs: Date.now(),
895
+ successfulWriteCount: 0,
896
+ toolCallCount: 0,
897
+ toolCounts: /* @__PURE__ */ new Map(),
898
+ transport
899
+ };
900
+ }
901
+ function currentMcpTelemetrySummary() {
902
+ return telemetryContext.getStore();
903
+ }
904
+ function runWithMcpTelemetry(summary, fn) {
905
+ return telemetryContext.run(summary, fn);
906
+ }
907
+ function recordMcpToolResult(params) {
908
+ if (!isMcpToolName(params.toolName)) return;
909
+ const toolName = params.toolName;
910
+ params.summary.toolCallCount += 1;
911
+ params.summary.toolCounts.set(
912
+ toolName,
913
+ (params.summary.toolCounts.get(toolName) ?? 0) + 1
914
+ );
915
+ if (!MCP_TOOL_CONTRACT[toolName].readOnly && toolResultSucceeded(params.resultText)) {
916
+ params.summary.successfulWriteCount += 1;
917
+ }
918
+ }
919
+ function toMcpTelemetryBody(summary) {
920
+ if (summary.toolCallCount <= 0) return null;
921
+ const durationMs = summary.transport === "http" ? Math.max(0, summary.durationMs ?? Date.now() - summary.startedAtMs) : void 0;
922
+ return {
923
+ converted: summary.successfulWriteCount > 0,
924
+ ...durationMs !== void 0 ? { durationMs } : {},
925
+ sessionId: summary.sessionId,
926
+ successfulWriteCount: summary.successfulWriteCount,
927
+ toolCallCount: summary.toolCallCount,
928
+ toolCounts: Object.fromEntries(summary.toolCounts),
929
+ transport: summary.transport
930
+ };
931
+ }
932
+ async function flushMcpTelemetrySummary(summary) {
933
+ const body = toMcpTelemetryBody(summary);
934
+ if (!body) return;
935
+ await swallow(
936
+ withTimeout(async () => {
937
+ const apiKey = resolveApiKey();
938
+ await consolePostTelemetry(TELEMETRY_ENDPOINT, body, apiKey);
939
+ }, FLUSH_TIMEOUT_MS)
940
+ );
941
+ }
942
+ function toolResultSucceeded(resultText) {
943
+ if (!resultText) return false;
944
+ try {
945
+ const parsed = JSON.parse(resultText);
946
+ return parsed.success === true;
947
+ } catch {
948
+ return false;
949
+ }
950
+ }
951
+ async function withTimeout(fn, timeoutMs) {
952
+ let timer;
953
+ await Promise.race([
954
+ fn(),
955
+ new Promise((resolve) => {
956
+ timer = setTimeout(resolve, timeoutMs);
957
+ })
958
+ ]);
959
+ if (timer) clearTimeout(timer);
960
+ }
961
+ async function swallow(promise) {
962
+ try {
963
+ await promise;
964
+ } catch {
965
+ }
966
+ }
967
+
968
+ // src/tools/query-collection.ts
969
+ import { z as z3 } from "zod";
970
+
971
+ // src/lib/client.ts
972
+ import { createServerClient } from "@01.software/sdk";
973
+ var MISSING_HTTP_AUTH_CONTEXT_ERROR2 = "MCP HTTP requests require a validated OAuth tenant context before tool execution.";
974
+ var HTTP_OAUTH_SDK_CLIENT_ERROR = "MCP HTTP OAuth requests cannot use SDK-backed tools. Use reviewed Console service endpoints for OAuth transport.";
975
+ function getClient() {
976
+ const oauthContext = tenantAuthContext();
977
+ if (oauthContext) {
978
+ throw new Error(HTTP_OAUTH_SDK_CLIENT_ERROR);
979
+ }
980
+ if (hasRequestContext()) throw new Error(MISSING_HTTP_AUTH_CONTEXT_ERROR2);
981
+ const secretKey = process.env.SOFTWARE_SECRET_KEY;
982
+ const publishableKey = process.env.SOFTWARE_PUBLISHABLE_KEY || process.env.NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY;
983
+ if (!secretKey) {
984
+ throw new Error(
985
+ "Authentication required. Set SOFTWARE_SECRET_KEY for stdio transport."
986
+ );
987
+ }
988
+ if (!secretKey.startsWith("sk01_") && !secretKey.startsWith("pat01_")) {
989
+ throw new Error("Invalid SOFTWARE_SECRET_KEY format. Expected sk01_ or pat01_ token.");
247
990
  }
248
- return true;
249
- }
250
- function parseJsonWhere(where) {
251
- try {
252
- const parsed = JSON.parse(where);
253
- if (!checkDepth(parsed)) {
254
- return {
255
- success: false,
256
- error: JSON.stringify(
257
- {
258
- success: false,
259
- error: `Query exceeds maximum nesting depth of ${MAX_QUERY_DEPTH}`
260
- },
261
- null,
262
- 2
263
- )
264
- };
265
- }
266
- return { success: true, data: parsed };
267
- } catch {
268
- return {
269
- success: false,
270
- error: JSON.stringify(
271
- {
272
- success: false,
273
- error: `Invalid JSON in "where" parameter: ${where.length > 100 ? where.substring(0, 100) + "..." : where}`
274
- },
275
- null,
276
- 2
277
- )
278
- };
991
+ if (!publishableKey) {
992
+ throw new Error(
993
+ "publishableKey is required. Set SOFTWARE_PUBLISHABLE_KEY for stdio transport. It is used for rate limiting and monthly quota enforcement via the edge proxy."
994
+ );
279
995
  }
996
+ return createServerClient({
997
+ publishableKey,
998
+ secretKey
999
+ });
280
1000
  }
281
1001
 
282
1002
  // src/tools/query-collection.ts
1003
+ import { SERVER_COLLECTIONS } from "@01.software/sdk";
283
1004
  var schema = {
284
- collection: z.enum(COLLECTIONS).describe("Collection name (required)"),
285
- where: z.string().optional().describe(
1005
+ collection: z3.enum(SERVER_COLLECTIONS).describe("Collection name (required)"),
1006
+ where: z3.string().optional().describe(
286
1007
  `Filter conditions (JSON string, optional). Pass the Payload query condition object as a JSON string. Example: '{"title":{"equals":"Product name"}}'`
287
1008
  ),
288
- limit: z.number().min(1).max(100).default(10).describe("Maximum number of items to return (1-100, default: 10)."),
289
- page: z.number().optional().describe("Page number (optional). Starts from 1. Used for pagination."),
290
- sort: z.string().regex(/^-?[a-zA-Z0-9_.]+$/, 'Sort must be a field name, optionally prefixed with "-" for descending').optional().describe(
1009
+ limit: z3.number().min(1).max(100).default(10).describe("Maximum number of items to return (1-100, default: 10)."),
1010
+ page: z3.number().optional().describe("Page number (optional). Starts from 1. Used for pagination."),
1011
+ sort: z3.string().regex(
1012
+ /^-?[a-zA-Z0-9_.]+$/,
1013
+ 'Sort must be a field name, optionally prefixed with "-" for descending'
1014
+ ).optional().describe(
291
1015
  'Sort field (optional). Use "fieldName" for ascending or "-fieldName" for descending. Example: "createdAt" or "-createdAt"'
292
1016
  )
293
1017
  };
@@ -341,11 +1065,11 @@ async function queryCollection({
341
1065
  }
342
1066
 
343
1067
  // src/tools/get-collection-by-id.ts
344
- import { z as z2 } from "zod";
345
- import { COLLECTIONS as COLLECTIONS2 } from "@01.software/sdk";
1068
+ import { z as z4 } from "zod";
1069
+ import { SERVER_COLLECTIONS as SERVER_COLLECTIONS2 } from "@01.software/sdk";
346
1070
  var schema2 = {
347
- collection: z2.enum(COLLECTIONS2).describe("Collection name (required)"),
348
- id: z2.string().min(1).describe("Item ID (required)")
1071
+ collection: z4.enum(SERVER_COLLECTIONS2).describe("Collection name (required)"),
1072
+ id: z4.string().min(1).describe("Item ID (required)")
349
1073
  };
350
1074
  var metadata2 = {
351
1075
  name: "get-collection-by-id",
@@ -370,201 +1094,12 @@ async function getCollectionById({
370
1094
  }
371
1095
  }
372
1096
 
373
- // src/tools/create-collection.ts
374
- import { z as z3 } from "zod";
375
- import { COLLECTIONS as COLLECTIONS3 } from "@01.software/sdk";
1097
+ // src/tools/get-order.ts
1098
+ import { z as z5 } from "zod";
376
1099
  var schema3 = {
377
- collection: z3.enum(COLLECTIONS3).describe("Collection name (required)"),
378
- data: z3.record(z3.string(), z3.unknown()).describe(
379
- "Data to create (required). Use get-collection-schema first to understand writable fields, hidden fields, and required metadata. Server will validate and reject invalid fields."
380
- )
1100
+ orderNumber: z5.string().min(1).describe("Order number to look up (required)")
381
1101
  };
382
1102
  var metadata3 = {
383
- name: "create-collection",
384
- description: "Create a new collection item",
385
- annotations: {
386
- title: "Create collection item",
387
- readOnlyHint: false,
388
- destructiveHint: false,
389
- idempotentHint: false
390
- }
391
- };
392
- async function createCollection({
393
- collection,
394
- data
395
- }) {
396
- try {
397
- const client = getClient().collections;
398
- const result = await client.from(collection).create(data);
399
- return toolSuccess({ data: result.doc, message: result.message });
400
- } catch (error) {
401
- return toolError(error);
402
- }
403
- }
404
-
405
- // src/tools/update-collection.ts
406
- import { z as z4 } from "zod";
407
- import { COLLECTIONS as COLLECTIONS4 } from "@01.software/sdk";
408
- var schema4 = {
409
- collection: z4.enum(COLLECTIONS4).describe("Collection name (required)"),
410
- id: z4.string().min(1).describe("Item ID (required)"),
411
- data: z4.record(z4.string(), z4.unknown()).describe(
412
- "Data to update (required). Use get-collection-by-id first to check current structure, then get-collection-schema to confirm writable fields and required metadata. Server will validate and reject invalid fields."
413
- )
414
- };
415
- var metadata4 = {
416
- name: "update-collection",
417
- description: "Update an existing collection item",
418
- annotations: {
419
- title: "Update collection item",
420
- readOnlyHint: false,
421
- destructiveHint: true,
422
- idempotentHint: true
423
- }
424
- };
425
- async function updateCollection({
426
- collection,
427
- id,
428
- data
429
- }) {
430
- try {
431
- const client = getClient().collections;
432
- const result = await client.from(collection).update(id, data);
433
- return toolSuccess({ data: result.doc, message: result.message });
434
- } catch (error) {
435
- return toolError(error);
436
- }
437
- }
438
-
439
- // src/tools/delete-collection.ts
440
- import { z as z5 } from "zod";
441
- import { COLLECTIONS as COLLECTIONS5 } from "@01.software/sdk";
442
- var schema5 = {
443
- collection: z5.enum(COLLECTIONS5).describe("Collection name (required)"),
444
- id: z5.string().min(1).describe("Item ID (required)")
445
- };
446
- var metadata5 = {
447
- name: "delete-collection",
448
- description: "Delete a collection item",
449
- annotations: {
450
- title: "Delete collection item",
451
- readOnlyHint: false,
452
- destructiveHint: true,
453
- idempotentHint: true
454
- }
455
- };
456
- async function deleteCollection({
457
- collection,
458
- id
459
- }) {
460
- try {
461
- const client = getClient();
462
- await client.collections.from(collection).remove(id);
463
- return toolSuccess({ message: "Deleted successfully." });
464
- } catch (error) {
465
- return toolError(error);
466
- }
467
- }
468
-
469
- // src/tools/delete-many-collection.ts
470
- import { z as z6 } from "zod";
471
- import { COLLECTIONS as COLLECTIONS6 } from "@01.software/sdk";
472
- var schema6 = {
473
- collection: z6.enum(COLLECTIONS6).describe("Collection name (required)"),
474
- where: z6.string().describe(
475
- `Filter conditions (JSON string, required). Determines which items to delete. Example: '{"status":{"equals":"archived"}}'`
476
- )
477
- };
478
- var metadata6 = {
479
- name: "delete-many-collection",
480
- description: "Bulk delete collection items matching a filter. All matching items will be permanently deleted.",
481
- annotations: {
482
- title: "Bulk delete collection items",
483
- readOnlyHint: false,
484
- destructiveHint: true,
485
- idempotentHint: true
486
- }
487
- };
488
- async function deleteManyCollection({
489
- collection,
490
- where
491
- }) {
492
- try {
493
- const client = getClient().collections;
494
- const parsed = parseJsonWhere(where);
495
- if (!parsed.success) return parsed.error;
496
- if (!parsed.data || typeof parsed.data !== "object" || Object.keys(parsed.data).length === 0) {
497
- return toolError(
498
- new Error(
499
- 'Empty "where" filter is not allowed for bulk deletes. Provide at least one filter condition.'
500
- )
501
- );
502
- }
503
- const result = await client.from(collection).removeMany(parsed.data);
504
- return toolSuccess({
505
- totalDocs: result.totalDocs,
506
- message: `Deleted ${result.totalDocs} item(s).`
507
- });
508
- } catch (error) {
509
- return toolError(error);
510
- }
511
- }
512
-
513
- // src/tools/update-many-collection.ts
514
- import { z as z7 } from "zod";
515
- import { COLLECTIONS as COLLECTIONS7 } from "@01.software/sdk";
516
- var schema7 = {
517
- collection: z7.enum(COLLECTIONS7).describe("Collection name (required)"),
518
- where: z7.string().describe(
519
- `Filter conditions (JSON string, required). Determines which items to update. Example: '{"status":{"equals":"draft"}}'`
520
- ),
521
- data: z7.record(z7.string(), z7.unknown()).describe(
522
- "Data to update (required). Partial updates supported. Server will validate and reject invalid fields."
523
- )
524
- };
525
- var metadata7 = {
526
- name: "update-many-collection",
527
- description: "Bulk update collection items matching a filter. All matching items will be updated with the provided data.",
528
- annotations: {
529
- title: "Bulk update collection items",
530
- readOnlyHint: false,
531
- destructiveHint: true,
532
- idempotentHint: true
533
- }
534
- };
535
- async function updateManyCollection({
536
- collection,
537
- where,
538
- data
539
- }) {
540
- try {
541
- const client = getClient().collections;
542
- const parsed = parseJsonWhere(where);
543
- if (!parsed.success) return parsed.error;
544
- if (!parsed.data || typeof parsed.data !== "object" || Object.keys(parsed.data).length === 0) {
545
- return toolError(
546
- new Error(
547
- 'Empty "where" filter is not allowed for bulk updates. Provide at least one filter condition.'
548
- )
549
- );
550
- }
551
- const result = await client.from(collection).updateMany(parsed.data, data);
552
- return toolSuccess({
553
- data: result.docs,
554
- totalDocs: result.totalDocs,
555
- message: `Updated ${result.totalDocs} item(s).`
556
- });
557
- } catch (error) {
558
- return toolError(error);
559
- }
560
- }
561
-
562
- // src/tools/get-order.ts
563
- import { z as z8 } from "zod";
564
- var schema8 = {
565
- orderNumber: z8.string().min(1).describe("Order number to look up (required)")
566
- };
567
- var metadata8 = {
568
1103
  name: "get-order",
569
1104
  description: "Get order details by order number. Returns order with related data (depth:1).",
570
1105
  annotations: {
@@ -592,26 +1127,26 @@ async function getOrder({
592
1127
  }
593
1128
 
594
1129
  // src/tools/create-order.ts
595
- import { z as z9 } from "zod";
596
- var schema9 = {
597
- pgPaymentId: z9.string().optional().describe("PG payment ID (optional \u2014 omit for free orders)"),
598
- orderNumber: z9.string().min(1).describe("Unique order number (required)"),
599
- customerSnapshot: z9.object({
600
- name: z9.string().optional().describe("Customer name"),
601
- email: z9.string().describe("Customer email (required)"),
602
- phone: z9.string().optional().describe("Customer phone")
1130
+ import { z as z6 } from "zod";
1131
+ var schema4 = {
1132
+ pgPaymentId: z6.string().optional().describe("PG payment ID (optional \u2014 omit for free orders)"),
1133
+ orderNumber: z6.string().min(1).describe("Unique order number (required)"),
1134
+ customerSnapshot: z6.object({
1135
+ name: z6.string().optional().describe("Customer name"),
1136
+ email: z6.string().describe("Customer email (required)"),
1137
+ phone: z6.string().optional().describe("Customer phone")
603
1138
  }).describe("Customer snapshot at time of order (required)"),
604
- shippingAddress: z9.record(z9.string(), z9.unknown()).describe(
1139
+ shippingAddress: z6.record(z6.string(), z6.unknown()).describe(
605
1140
  "Shipping address object (required). Fields: postalCode, address1, address2, deliveryMessage, recipientName, phone"
606
1141
  ),
607
- orderItems: z9.array(z9.record(z9.string(), z9.unknown())).describe(
1142
+ orderItems: z6.array(z6.record(z6.string(), z6.unknown())).describe(
608
1143
  "Array of order item objects (required). Each: { product, variant, option, quantity, unitPrice?, totalPrice? }"
609
1144
  ),
610
- totalAmount: z9.number().nonnegative().describe("Total order amount (required, min 0)"),
611
- shippingAmount: z9.number().nonnegative().optional().describe("Shipping amount (optional, default 0)"),
612
- discountCode: z9.string().optional().describe("Discount code to apply (optional)")
1145
+ totalAmount: z6.number().nonnegative().describe("Total order amount (required, min 0)"),
1146
+ shippingAmount: z6.number().nonnegative().optional().describe("Shipping amount (optional, default 0)"),
1147
+ discountCode: z6.string().optional().describe("Discount code to apply (optional)")
613
1148
  };
614
- var metadata9 = {
1149
+ var metadata4 = {
615
1150
  name: "create-order",
616
1151
  description: "Create a new order with products and shipping information. Supports idempotency.",
617
1152
  annotations: {
@@ -634,10 +1169,10 @@ async function createOrder(params) {
634
1169
  }
635
1170
 
636
1171
  // src/tools/update-order.ts
637
- import { z as z10 } from "zod";
638
- var schema10 = {
639
- orderNumber: z10.string().min(1).describe("Order number (required)"),
640
- status: z10.enum([
1172
+ import { z as z7 } from "zod";
1173
+ var schema5 = {
1174
+ orderNumber: z7.string().min(1).describe("Order number (required)"),
1175
+ status: z7.enum([
641
1176
  "pending",
642
1177
  "paid",
643
1178
  "failed",
@@ -650,7 +1185,7 @@ var schema10 = {
650
1185
  "New order status. Return-related statuses (return_requested, return_processing, returned) must be set via Return endpoints."
651
1186
  )
652
1187
  };
653
- var metadata10 = {
1188
+ var metadata5 = {
654
1189
  name: "update-order",
655
1190
  description: "Update order status. Automatically adjusts stock on status changes (e.g., canceled restores stock).",
656
1191
  annotations: {
@@ -674,17 +1209,17 @@ async function updateOrder({
674
1209
  }
675
1210
 
676
1211
  // src/tools/checkout.ts
677
- import { z as z11 } from "zod";
678
- var schema11 = {
679
- cartId: z11.string().min(1).describe("Cart ID to convert to order (required)"),
680
- pgPaymentId: z11.string().optional().describe("PG payment ID (optional \u2014 omit for free orders)"),
681
- orderNumber: z11.string().min(1).describe("Unique order number (required)"),
682
- customerSnapshot: z11.record(z11.string(), z11.unknown()).describe(
1212
+ import { z as z8 } from "zod";
1213
+ var schema6 = {
1214
+ cartId: z8.string().min(1).describe("Cart ID to convert to order (required)"),
1215
+ pgPaymentId: z8.string().optional().describe("PG payment ID (optional \u2014 omit for free orders)"),
1216
+ orderNumber: z8.string().min(1).describe("Unique order number (required)"),
1217
+ customerSnapshot: z8.record(z8.string(), z8.unknown()).describe(
683
1218
  "Customer snapshot object (required). Fields: { name?, email, phone? }"
684
1219
  ),
685
- discountCode: z11.string().optional().describe("Discount code to apply (optional)")
1220
+ discountCode: z8.string().optional().describe("Discount code to apply (optional)")
686
1221
  };
687
- var metadata11 = {
1222
+ var metadata6 = {
688
1223
  name: "checkout",
689
1224
  description: "Convert a cart to an order. Validates stock, creates order and transaction, marks cart as completed. Supports idempotency.",
690
1225
  annotations: {
@@ -707,21 +1242,21 @@ async function checkout(params) {
707
1242
  }
708
1243
 
709
1244
  // src/tools/create-fulfillment.ts
710
- import { z as z12 } from "zod";
711
- var schema12 = {
712
- orderNumber: z12.string().min(1).describe("Order number (required)"),
713
- carrier: z12.string().optional().describe("Shipping carrier name (optional)"),
714
- trackingNumber: z12.string().optional().describe(
1245
+ import { z as z9 } from "zod";
1246
+ var schema7 = {
1247
+ orderNumber: z9.string().min(1).describe("Order number (required)"),
1248
+ carrier: z9.string().optional().describe("Shipping carrier name (optional)"),
1249
+ trackingNumber: z9.string().optional().describe(
715
1250
  'Tracking number (optional). Setting carrier + tracking triggers "shipped" status'
716
1251
  ),
717
- items: z12.array(
718
- z12.object({
719
- orderItem: z12.string().min(1).describe("Order item ID"),
720
- quantity: z12.number().int().positive().describe("Quantity to fulfill")
1252
+ items: z9.array(
1253
+ z9.object({
1254
+ orderItem: z9.string().min(1).describe("Order item ID"),
1255
+ quantity: z9.number().int().positive().describe("Quantity to fulfill")
721
1256
  })
722
1257
  ).describe("Array of items to fulfill (required)")
723
1258
  };
724
- var metadata12 = {
1259
+ var metadata7 = {
725
1260
  name: "create-fulfillment",
726
1261
  description: "Create a shipment/fulfillment for order items. Auto-updates order status (paid \u2192 preparing \u2192 shipped).",
727
1262
  annotations: {
@@ -752,20 +1287,20 @@ async function createFulfillment({
752
1287
  }
753
1288
 
754
1289
  // src/tools/update-fulfillment.ts
755
- import { z as z13 } from "zod";
756
- var schema13 = {
757
- fulfillmentId: z13.string().min(1).describe("Fulfillment ID (required)"),
758
- status: z13.enum(["packed", "shipped", "delivered", "failed"]).describe(
1290
+ import { z as z10 } from "zod";
1291
+ var schema8 = {
1292
+ fulfillmentId: z10.string().min(1).describe("Fulfillment ID (required)"),
1293
+ status: z10.enum(["packed", "shipped", "delivered", "failed"]).describe(
759
1294
  "New fulfillment status (required). FSM: pending\u2192packed/shipped/failed, packed\u2192shipped/failed, shipped\u2192delivered/failed"
760
1295
  ),
761
- carrier: z13.string().optional().describe(
1296
+ carrier: z10.string().optional().describe(
762
1297
  "Shipping carrier (optional, changeable only in pending/packed status)"
763
1298
  ),
764
- trackingNumber: z13.string().optional().describe(
1299
+ trackingNumber: z10.string().optional().describe(
765
1300
  "Tracking number (optional, changeable only in pending/packed status)"
766
1301
  )
767
1302
  };
768
- var metadata13 = {
1303
+ var metadata8 = {
769
1304
  name: "update-fulfillment",
770
1305
  description: "Update fulfillment status, carrier, and tracking number. Auto-updates order status when all fulfillments are delivered.",
771
1306
  annotations: {
@@ -796,14 +1331,8 @@ async function updateFulfillment({
796
1331
  }
797
1332
 
798
1333
  // src/tools/update-transaction.ts
799
- import { z as z14 } from "zod";
800
- var schema14 = {
801
- pgPaymentId: z14.string().min(1).describe("PG payment ID (required)"),
802
- status: z14.enum(["pending", "paid", "failed", "canceled"]).describe("New transaction status (required)"),
803
- paymentMethod: z14.string().optional().describe("Payment method (optional)"),
804
- receiptUrl: z14.string().optional().describe("Receipt URL (optional)")
805
- };
806
- var metadata14 = {
1334
+ var schema9 = UpdateTransactionSchema.shape;
1335
+ var metadata9 = {
807
1336
  name: "update-transaction",
808
1337
  description: "Update transaction status, payment method, and receipt URL.",
809
1338
  annotations: {
@@ -817,16 +1346,21 @@ async function updateTransaction({
817
1346
  pgPaymentId,
818
1347
  status,
819
1348
  paymentMethod,
820
- receiptUrl
1349
+ receiptUrl,
1350
+ paymentKey,
1351
+ amount
821
1352
  }) {
822
1353
  try {
823
1354
  const client = getClient();
824
- const result = await client.commerce.orders.updateTransaction({
1355
+ const params = {
825
1356
  pgPaymentId,
826
1357
  status,
827
1358
  paymentMethod,
828
- receiptUrl
829
- });
1359
+ receiptUrl,
1360
+ paymentKey,
1361
+ amount
1362
+ };
1363
+ const result = await client.commerce.orders.updateTransaction(params);
830
1364
  return toolSuccess({ data: result });
831
1365
  } catch (error) {
832
1366
  return toolError(error);
@@ -834,20 +1368,20 @@ async function updateTransaction({
834
1368
  }
835
1369
 
836
1370
  // src/tools/create-return.ts
837
- import { z as z15 } from "zod";
838
- var schema15 = {
839
- orderNumber: z15.string().min(1).describe("Order number (required)"),
840
- reason: z15.enum(["change_of_mind", "defective", "wrong_delivery", "damaged", "other"]).optional().describe("Return reason (optional)"),
841
- reasonDetail: z15.string().optional().describe("Detailed reason text (optional)"),
842
- returnItems: z15.array(
843
- z15.object({
844
- orderItem: z15.string().min(1).describe("Order item ID"),
845
- quantity: z15.number().int().positive().describe("Quantity to return")
1371
+ import { z as z11 } from "zod";
1372
+ var schema10 = {
1373
+ orderNumber: z11.string().min(1).describe("Order number (required)"),
1374
+ reason: z11.enum(["change_of_mind", "defective", "wrong_delivery", "damaged", "other"]).optional().describe("Return reason (optional)"),
1375
+ reasonDetail: z11.string().optional().describe("Detailed reason text (optional)"),
1376
+ returnItems: z11.array(
1377
+ z11.object({
1378
+ orderItem: z11.string().min(1).describe("Order item ID"),
1379
+ quantity: z11.number().int().positive().describe("Quantity to return")
846
1380
  })
847
1381
  ).describe("Array of products to return (required)"),
848
- refundAmount: z15.number().nonnegative().describe("Refund amount (required, min 0)")
1382
+ refundAmount: z11.number().nonnegative().describe("Refund amount (required, min 0)")
849
1383
  };
850
- var metadata15 = {
1384
+ var metadata10 = {
851
1385
  name: "create-return",
852
1386
  description: "Create a return request for an order. Only works for delivered/confirmed orders. Updates order status to return_requested.",
853
1387
  annotations: {
@@ -880,14 +1414,14 @@ async function createReturn({
880
1414
  }
881
1415
 
882
1416
  // src/tools/update-return.ts
883
- import { z as z16 } from "zod";
884
- var schema16 = {
885
- returnId: z16.string().min(1).describe("Return ID (required)"),
886
- status: z16.enum(["processing", "approved", "rejected", "completed"]).describe(
1417
+ import { z as z12 } from "zod";
1418
+ var schema11 = {
1419
+ returnId: z12.string().min(1).describe("Return ID (required)"),
1420
+ status: z12.enum(["processing", "approved", "rejected", "completed"]).describe(
887
1421
  "New return status (required). Valid transitions: requested\u2192processing/rejected, processing\u2192approved/rejected, approved\u2192completed"
888
1422
  )
889
1423
  };
890
- var metadata16 = {
1424
+ var metadata11 = {
891
1425
  name: "update-return",
892
1426
  description: "Update return status with FSM validation. Restores inventory on completion, reverts order status on rejection.",
893
1427
  annotations: {
@@ -911,22 +1445,8 @@ async function updateReturn({
911
1445
  }
912
1446
 
913
1447
  // src/tools/return-with-refund.ts
914
- import { z as z17 } from "zod";
915
- var schema17 = {
916
- orderNumber: z17.string().min(1).describe("Order number (required)"),
917
- reason: z17.enum(["change_of_mind", "defective", "wrong_delivery", "damaged", "other"]).optional().describe("Return reason (optional)"),
918
- reasonDetail: z17.string().optional().describe("Detailed reason text (optional)"),
919
- returnItems: z17.array(
920
- z17.object({
921
- orderItem: z17.string().min(1).describe("Order item ID"),
922
- quantity: z17.number().int().positive().describe("Quantity to return")
923
- })
924
- ).describe("Array of products to return (required)"),
925
- refundAmount: z17.number().nonnegative().describe("Refund amount (required, min 0)"),
926
- pgPaymentId: z17.string().min(1).describe("PG payment ID for refund (required)"),
927
- refundReceiptUrl: z17.string().optional().describe("Refund receipt URL (optional)")
928
- };
929
- var metadata17 = {
1448
+ var schema12 = ReturnWithRefundSchema.shape;
1449
+ var metadata12 = {
930
1450
  name: "return-with-refund",
931
1451
  description: "Combined return + refund operation. Creates return, restores stock, cancels transaction, updates order status.",
932
1452
  annotations: {
@@ -943,19 +1463,22 @@ async function returnWithRefund({
943
1463
  returnItems,
944
1464
  refundAmount,
945
1465
  pgPaymentId,
1466
+ paymentKey,
946
1467
  refundReceiptUrl
947
1468
  }) {
948
1469
  try {
949
1470
  const client = getClient();
950
- const result = await client.commerce.orders.returnWithRefund({
1471
+ const params = {
951
1472
  orderNumber,
952
1473
  reason,
953
1474
  reasonDetail,
954
1475
  returnItems,
955
1476
  refundAmount,
956
1477
  pgPaymentId,
1478
+ paymentKey,
957
1479
  refundReceiptUrl
958
- });
1480
+ };
1481
+ const result = await client.commerce.orders.returnWithRefund(params);
959
1482
  return toolSuccess({ data: result });
960
1483
  } catch (error) {
961
1484
  return toolError(error);
@@ -963,15 +1486,15 @@ async function returnWithRefund({
963
1486
  }
964
1487
 
965
1488
  // src/tools/add-cart-item.ts
966
- import { z as z18 } from "zod";
967
- var schema18 = {
968
- cartId: z18.string().min(1).describe("Cart ID (required)"),
969
- product: z18.string().min(1).describe("Product ID (required)"),
970
- variant: z18.string().min(1).describe("Product variant ID (required)"),
971
- option: z18.string().min(1).describe("Product option ID (required)"),
972
- quantity: z18.number().int().positive().describe("Quantity to add (required, positive integer)")
1489
+ import { z as z13 } from "zod";
1490
+ var schema13 = {
1491
+ cartId: z13.string().min(1).describe("Cart ID (required)"),
1492
+ product: z13.string().min(1).describe("Product ID (required)"),
1493
+ variant: z13.string().min(1).describe("Product variant ID (required)"),
1494
+ option: z13.string().min(1).describe("Product option ID (required)"),
1495
+ quantity: z13.number().int().positive().describe("Quantity to add (required, positive integer)")
973
1496
  };
974
- var metadata18 = {
1497
+ var metadata13 = {
975
1498
  name: "add-cart-item",
976
1499
  description: "Add a product to cart. Validates stock, merges quantity if item already exists, recalculates totals.",
977
1500
  annotations: {
@@ -1004,12 +1527,12 @@ async function addCartItem({
1004
1527
  }
1005
1528
 
1006
1529
  // src/tools/update-cart-item.ts
1007
- import { z as z19 } from "zod";
1008
- var schema19 = {
1009
- cartItemId: z19.string().min(1).describe("Cart item ID (required)"),
1010
- quantity: z19.number().int().positive().describe("New quantity (required, positive integer)")
1530
+ import { z as z14 } from "zod";
1531
+ var schema14 = {
1532
+ cartItemId: z14.string().min(1).describe("Cart item ID (required)"),
1533
+ quantity: z14.number().int().positive().describe("New quantity (required, positive integer)")
1011
1534
  };
1012
- var metadata19 = {
1535
+ var metadata14 = {
1013
1536
  name: "update-cart-item",
1014
1537
  description: "Update cart item quantity. Validates stock availability, recalculates cart totals.",
1015
1538
  annotations: {
@@ -1033,11 +1556,11 @@ async function updateCartItem({
1033
1556
  }
1034
1557
 
1035
1558
  // src/tools/remove-cart-item.ts
1036
- import { z as z20 } from "zod";
1037
- var schema20 = {
1038
- cartItemId: z20.string().min(1).describe("Cart item ID to remove (required)")
1559
+ import { z as z15 } from "zod";
1560
+ var schema15 = {
1561
+ cartItemId: z15.string().min(1).describe("Cart item ID to remove (required)")
1039
1562
  };
1040
- var metadata20 = {
1563
+ var metadata15 = {
1041
1564
  name: "remove-cart-item",
1042
1565
  description: "Remove an item from cart. Recalculates cart totals after removal.",
1043
1566
  annotations: {
@@ -1060,12 +1583,12 @@ async function removeCartItem({
1060
1583
  }
1061
1584
 
1062
1585
  // src/tools/apply-discount.ts
1063
- import { z as z21 } from "zod";
1064
- var schema21 = {
1065
- cartId: z21.string().min(1).describe("Cart ID (required)"),
1066
- discountCode: z21.string().describe("Discount code to apply (required)")
1586
+ import { z as z16 } from "zod";
1587
+ var schema16 = {
1588
+ cartId: z16.string().min(1).describe("Cart ID (required)"),
1589
+ discountCode: z16.string().describe("Discount code to apply (required)")
1067
1590
  };
1068
- var metadata21 = {
1591
+ var metadata16 = {
1069
1592
  name: "apply-discount",
1070
1593
  description: "Apply a discount code to a cart. Validates the code, updates cart totals, and sets free shipping if applicable.",
1071
1594
  annotations: {
@@ -1089,11 +1612,11 @@ async function applyDiscount({
1089
1612
  }
1090
1613
 
1091
1614
  // src/tools/remove-discount.ts
1092
- import { z as z22 } from "zod";
1093
- var schema22 = {
1094
- cartId: z22.string().min(1).describe("Cart ID (required)")
1615
+ import { z as z17 } from "zod";
1616
+ var schema17 = {
1617
+ cartId: z17.string().min(1).describe("Cart ID (required)")
1095
1618
  };
1096
- var metadata22 = {
1619
+ var metadata17 = {
1097
1620
  name: "remove-discount",
1098
1621
  description: "Remove the applied discount code from a cart and recalculate totals.",
1099
1622
  annotations: {
@@ -1116,11 +1639,11 @@ async function removeDiscount({
1116
1639
  }
1117
1640
 
1118
1641
  // src/tools/clear-cart.ts
1119
- import { z as z23 } from "zod";
1120
- var schema23 = {
1121
- cartId: z23.string().min(1).describe("Cart ID (required)")
1642
+ import { z as z18 } from "zod";
1643
+ var schema18 = {
1644
+ cartId: z18.string().min(1).describe("Cart ID (required)")
1122
1645
  };
1123
- var metadata23 = {
1646
+ var metadata18 = {
1124
1647
  name: "clear-cart",
1125
1648
  description: "Remove all items from a cart, reset discount and amounts. Shipping fee is preserved.",
1126
1649
  annotations: {
@@ -1143,12 +1666,12 @@ async function clearCart({
1143
1666
  }
1144
1667
 
1145
1668
  // src/tools/validate-discount.ts
1146
- import { z as z24 } from "zod";
1147
- var schema24 = {
1148
- code: z24.string().describe("Discount code to validate (required)"),
1149
- orderAmount: z24.number().describe("Order amount for validation (required)")
1669
+ import { z as z19 } from "zod";
1670
+ var schema19 = {
1671
+ code: z19.string().describe("Discount code to validate (required)"),
1672
+ orderAmount: z19.number().describe("Order amount for validation (required)")
1150
1673
  };
1151
- var metadata24 = {
1674
+ var metadata19 = {
1152
1675
  name: "validate-discount",
1153
1676
  description: "Validate a discount code. Checks active status, date range, usage limits, minimum order amount, and calculates discount.",
1154
1677
  annotations: {
@@ -1175,13 +1698,13 @@ async function validateDiscount({
1175
1698
  }
1176
1699
 
1177
1700
  // src/tools/calculate-shipping.ts
1178
- import { z as z25 } from "zod";
1179
- var schema25 = {
1180
- shippingPolicyId: z25.string().optional().describe("Shipping policy ID (uses default policy if omitted)"),
1181
- orderAmount: z25.number().describe("Order amount for fee calculation (required)"),
1182
- postalCode: z25.string().optional().describe("Postal code for Jeju surcharge detection (63000-63644)")
1701
+ import { z as z20 } from "zod";
1702
+ var schema20 = {
1703
+ shippingPolicyId: z20.string().optional().describe("Shipping policy ID (uses default policy if omitted)"),
1704
+ orderAmount: z20.number().describe("Order amount for fee calculation (required)"),
1705
+ postalCode: z20.string().optional().describe("Postal code for Jeju surcharge detection (63000-63644)")
1183
1706
  };
1184
- var metadata25 = {
1707
+ var metadata20 = {
1185
1708
  name: "calculate-shipping",
1186
1709
  description: "Calculate shipping fee based on order amount and postal code. Supports free shipping threshold and Jeju surcharge.",
1187
1710
  annotations: {
@@ -1210,18 +1733,18 @@ async function calculateShipping({
1210
1733
  }
1211
1734
 
1212
1735
  // src/tools/stock-check.ts
1213
- import { z as z26 } from "zod";
1214
- var schema26 = {
1215
- items: z26.array(
1216
- z26.object({
1217
- variantId: z26.string().describe("Product variant ID"),
1218
- quantity: z26.number().int().positive().describe("Requested quantity")
1736
+ import { z as z21 } from "zod";
1737
+ var schema21 = {
1738
+ items: z21.array(
1739
+ z21.object({
1740
+ variantId: z21.string().describe("Product variant ID"),
1741
+ quantity: z21.number().int().positive().describe("Requested quantity")
1219
1742
  })
1220
1743
  ).describe(
1221
1744
  "Array of items to check stock for (required, max 100). Each: { variantId, quantity }"
1222
1745
  )
1223
1746
  };
1224
- var metadata26 = {
1747
+ var metadata21 = {
1225
1748
  name: "stock-check",
1226
1749
  description: "Batch check product option stock availability. Returns per-item availability and an allAvailable flag.",
1227
1750
  annotations: {
@@ -1244,113 +1767,21 @@ async function stockCheck({
1244
1767
  }
1245
1768
 
1246
1769
  // src/tools/get-collection-schema.ts
1247
- import { z as z27 } from "zod";
1248
- import { COLLECTIONS as COLLECTIONS8 } from "@01.software/sdk";
1249
-
1250
- // src/lib/console-api.ts
1251
- import { createHash } from "crypto";
1252
- var BASE_URL = process.env.SOFTWARE_API_URL || "http://localhost:3000";
1253
- var TIMEOUT_MS = 5e3;
1254
- var MISSING_HTTP_AUTH_CONTEXT_ERROR2 = "MCP HTTP requests require a validated OAuth tenant context before tool execution.";
1255
- function resolveAuthHeaderContext() {
1256
- const oauthContext = tenantAuthContext();
1257
- if (oauthContext) {
1258
- return {
1259
- apiKey: signMcpServiceToken(oauthContext),
1260
- mode: "oauth"
1261
- };
1262
- }
1263
- if (hasRequestContext()) throw new Error(MISSING_HTTP_AUTH_CONTEXT_ERROR2);
1264
- return {
1265
- apiKey: process.env.SOFTWARE_SECRET_KEY,
1266
- mode: "stdio",
1267
- publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY ?? process.env.NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY
1268
- };
1269
- }
1270
- function resolveApiKey() {
1271
- const { apiKey } = resolveAuthHeaderContext();
1272
- if (!apiKey || typeof apiKey !== "string") {
1273
- throw new Error(
1274
- "Authentication required. Set SOFTWARE_SECRET_KEY for stdio transport."
1275
- );
1276
- }
1277
- return apiKey;
1278
- }
1279
- function buildAuthHeaders(apiKey) {
1280
- const { mode, publishableKey } = resolveAuthHeaderContext();
1281
- const headers = {
1282
- Authorization: `Bearer ${apiKey}`
1283
- };
1284
- if (mode === "stdio" && publishableKey) {
1285
- headers["X-Publishable-Key"] = publishableKey;
1286
- }
1287
- return headers;
1288
- }
1289
- function extractErrorMessage(body) {
1290
- if (!body || typeof body !== "object") return void 0;
1291
- const b = body;
1292
- if (typeof b.error === "string") return b.error;
1293
- if (Array.isArray(b.errors) && b.errors[0]?.message) {
1294
- return String(b.errors[0].message);
1295
- }
1296
- if (typeof b.message === "string") return b.message;
1297
- return void 0;
1298
- }
1299
- async function consoleGet(path, apiKey) {
1300
- const authHeaders = buildAuthHeaders(apiKey);
1301
- const controller = new AbortController();
1302
- const timeoutId = setTimeout(() => controller.abort(), TIMEOUT_MS);
1303
- try {
1304
- const res = await fetch(`${BASE_URL}${path}`, {
1305
- headers: authHeaders,
1306
- signal: controller.signal
1307
- });
1308
- if (!res.ok) {
1309
- const body = await res.json().catch(() => ({}));
1310
- const msg = extractErrorMessage(body);
1311
- throw new Error(msg || `Console GET ${path} failed: ${res.status}`);
1312
- }
1313
- return res.json();
1314
- } finally {
1315
- clearTimeout(timeoutId);
1316
- }
1317
- }
1318
- async function consolePost(path, body, apiKey) {
1319
- const authHeaders = buildAuthHeaders(apiKey);
1320
- const controller = new AbortController();
1321
- const timeoutId = setTimeout(() => controller.abort(), TIMEOUT_MS);
1322
- try {
1323
- const res = await fetch(`${BASE_URL}${path}`, {
1324
- method: "POST",
1325
- headers: { ...authHeaders, "Content-Type": "application/json" },
1326
- body: JSON.stringify(body),
1327
- signal: controller.signal
1328
- });
1329
- if (!res.ok) {
1330
- const errBody = await res.json().catch(() => ({}));
1331
- const msg = extractErrorMessage(errBody);
1332
- throw new Error(msg || `Console POST ${path} failed: ${res.status}`);
1333
- }
1334
- return res.json();
1335
- } finally {
1336
- clearTimeout(timeoutId);
1337
- }
1338
- }
1770
+ import { SERVER_COLLECTIONS as SERVER_COLLECTIONS3 } from "@01.software/sdk";
1339
1771
 
1340
1772
  // src/lib/collection-schema.ts
1341
1773
  async function getCollectionSchema(collection) {
1342
1774
  const apiKey = resolveApiKey();
1343
- return consoleGet(
1775
+ const data = await consoleGet(
1344
1776
  `/api/tenants/schema/${encodeURIComponent(collection)}`,
1345
1777
  apiKey
1346
1778
  );
1779
+ return collectionSchemaResponseSchema.parse(data);
1347
1780
  }
1348
1781
 
1349
1782
  // src/tools/get-collection-schema.ts
1350
- var schema27 = {
1351
- collection: z27.enum(COLLECTIONS8).describe("Collection name (required)")
1352
- };
1353
- var metadata27 = {
1783
+ var schema22 = createCollectionSchemaToolInputSchema(SERVER_COLLECTIONS3).shape;
1784
+ var metadata22 = {
1354
1785
  name: "get-collection-schema",
1355
1786
  description: "Get the authoritative tenant-aware collection schema from console. Use this before create/update to understand writable fields, hidden fields, required metadata, and collection-level visibility.",
1356
1787
  annotations: {
@@ -1374,9 +1805,6 @@ async function getCollectionSchemaTool({
1374
1805
  }
1375
1806
  }
1376
1807
 
1377
- // src/tools/get-tenant-context.ts
1378
- import { z as z28 } from "zod";
1379
-
1380
1808
  // src/lib/tenant-context.ts
1381
1809
  function getTenantContextPath(includeCounts) {
1382
1810
  return includeCounts ? "/api/tenants/context?counts=true" : "/api/tenants/context";
@@ -1387,16 +1815,12 @@ async function getTenantContext(includeCounts = false) {
1387
1815
  getTenantContextPath(includeCounts),
1388
1816
  apiKey
1389
1817
  );
1390
- return data;
1391
- }
1392
- function invalidateTenantContextCache() {
1818
+ return tenantContextResponseSchema.parse(data);
1393
1819
  }
1394
1820
 
1395
1821
  // src/tools/get-tenant-context.ts
1396
- var schema28 = {
1397
- includeCounts: z28.boolean().optional().default(false).describe("Include per-collection document counts and config status (bypasses cache, slower)")
1398
- };
1399
- var metadata28 = {
1822
+ var schema23 = tenantContextToolInputSchema.shape;
1823
+ var metadata23 = {
1400
1824
  name: "get-tenant-context",
1401
1825
  description: "Get current tenant features, active collections, and field visibility. Call this at the start of every session. Use includeCounts=true to also get per-collection document counts for setup diagnostics.",
1402
1826
  annotations: {
@@ -1406,7 +1830,9 @@ var metadata28 = {
1406
1830
  idempotentHint: true
1407
1831
  }
1408
1832
  };
1409
- async function handler({ includeCounts }) {
1833
+ async function handler({
1834
+ includeCounts
1835
+ }) {
1410
1836
  try {
1411
1837
  const ctx = await getTenantContext(includeCounts);
1412
1838
  const lines = [
@@ -1459,11 +1885,10 @@ async function handler({ includeCounts }) {
1459
1885
  }
1460
1886
  }
1461
1887
  if (ctx.config) {
1888
+ lines.push("", "## Config Status");
1462
1889
  lines.push(
1463
- "",
1464
- "## Config Status"
1890
+ `- Webhook configured: ${ctx.config.webhookConfigured ? "Yes" : "No"}`
1465
1891
  );
1466
- lines.push(`- Webhook configured: ${ctx.config.webhookConfigured ? "Yes" : "No"}`);
1467
1892
  }
1468
1893
  return toolSuccess({ context: lines.join("\n") });
1469
1894
  } catch (error) {
@@ -1472,7 +1897,7 @@ async function handler({ includeCounts }) {
1472
1897
  }
1473
1898
 
1474
1899
  // src/tools/list-configurable-fields.ts
1475
- import { z as z29 } from "zod";
1900
+ import { z as z22 } from "zod";
1476
1901
 
1477
1902
  // src/lib/field-config.ts
1478
1903
  async function fetchFieldConfigs() {
@@ -1495,12 +1920,12 @@ function invalidateFieldConfigCache() {
1495
1920
  }
1496
1921
 
1497
1922
  // src/tools/list-configurable-fields.ts
1498
- var schema29 = {
1499
- collection: z29.string().optional().describe(
1923
+ var schema24 = {
1924
+ collection: z22.string().optional().describe(
1500
1925
  "Filter by collection slug (optional \u2014 returns all if omitted). Use this filter to reduce response size when you know which collection to check."
1501
1926
  )
1502
1927
  };
1503
- var metadata29 = {
1928
+ var metadata24 = {
1504
1929
  name: "list-configurable-fields",
1505
1930
  description: "List all configurable fields for tenant collections with current visibility state. Shows which fields can be shown/hidden and their current status. Returns all collections including inactive features \u2014 cross-reference with get-tenant-context for active features. Response includes ~300 fields across 47 collections \u2014 use collection filter when possible.",
1506
1931
  annotations: {
@@ -1531,17 +1956,17 @@ async function listConfigurableFields(params) {
1531
1956
  }
1532
1957
 
1533
1958
  // src/tools/update-field-config.ts
1534
- import { z as z30 } from "zod";
1535
- var schema30 = {
1536
- collection: z30.string().min(1).describe("Collection slug (required)"),
1537
- hiddenFields: z30.array(z30.string().min(1).max(200)).max(300).describe(
1959
+ import { z as z23 } from "zod";
1960
+ var schema25 = {
1961
+ collection: z23.string().min(1).describe("Collection slug (required)"),
1962
+ hiddenFields: z23.array(z23.string().min(1).max(200)).max(300).describe(
1538
1963
  "Fields to hide (required). This is a FULL REPLACE \u2014 fields NOT in this list will be shown. Pass [] to show all fields. Use list-configurable-fields first to see available field paths."
1539
1964
  ),
1540
- isHidden: z30.boolean().optional().describe(
1965
+ isHidden: z23.boolean().optional().describe(
1541
1966
  "Hide the entire collection from Admin Panel (optional). When true, individual hiddenFields are irrelevant."
1542
1967
  )
1543
1968
  };
1544
- var metadata30 = {
1969
+ var metadata25 = {
1545
1970
  name: "update-field-config",
1546
1971
  description: "Update field visibility configuration for a tenant collection. Hidden fields are removed from the Admin Panel UI. IMPORTANT: hiddenFields is a full replace, not a merge. Always call list-configurable-fields first to see current state.",
1547
1972
  annotations: {
@@ -1559,7 +1984,6 @@ async function updateFieldConfig(params) {
1559
1984
  isHidden: params.isHidden
1560
1985
  });
1561
1986
  invalidateFieldConfigCache();
1562
- invalidateTenantContextCache();
1563
1987
  return toolSuccess({
1564
1988
  message: `Field config updated for '${params.collection}'`,
1565
1989
  data: result
@@ -1570,7 +1994,7 @@ async function updateFieldConfig(params) {
1570
1994
  }
1571
1995
 
1572
1996
  // src/tools/sdk-get-recipe.ts
1573
- import { z as z31 } from "zod";
1997
+ import { z as z24 } from "zod";
1574
1998
 
1575
1999
  // src/lib/sdk-recipes.ts
1576
2000
  var recipes = {
@@ -1722,7 +2146,7 @@ const result = await client.collections.from('products').create({
1722
2146
  "Returns result.doc (not the document directly)"
1723
2147
  ],
1724
2148
  relatedResources: ["docs://sdk/query-builder"],
1725
- relatedTools: ["create-collection"]
2149
+ relatedTools: ["query-collection", "get-collection-schema"]
1726
2150
  }
1727
2151
  },
1728
2152
  "update-item": {
@@ -1751,7 +2175,7 @@ const result = await client.collections.from('products').update('product-id', {
1751
2175
  "Partial updates are supported \u2014 omitted fields retain their current value"
1752
2176
  ],
1753
2177
  relatedResources: ["docs://sdk/query-builder"],
1754
- relatedTools: ["update-collection"]
2178
+ relatedTools: ["get-collection-by-id", "get-collection-schema"]
1755
2179
  }
1756
2180
  },
1757
2181
  "delete-item": {
@@ -1775,7 +2199,7 @@ console.log('Deleted:', deleted.title)`,
1775
2199
  "Throws if the item does not exist"
1776
2200
  ],
1777
2201
  relatedResources: ["docs://sdk/query-builder"],
1778
- relatedTools: ["delete-collection"]
2202
+ relatedTools: ["get-collection-by-id", "query-collection"]
1779
2203
  }
1780
2204
  },
1781
2205
  "infinite-scroll": {
@@ -1952,7 +2376,7 @@ const result = await client.collections.from('images').create(formData as unknow
1952
2376
  "Always set alt text for accessibility"
1953
2377
  ],
1954
2378
  relatedResources: ["docs://sdk/query-builder"],
1955
- relatedTools: ["create-collection"]
2379
+ relatedTools: ["query-collection", "get-collection-schema"]
1956
2380
  }
1957
2381
  },
1958
2382
  "bulk-operations": {
@@ -1988,7 +2412,7 @@ const removed = await client.collections.from('products').removeMany(
1988
2412
  "Very broad where clauses (or empty) will affect all documents in the collection"
1989
2413
  ],
1990
2414
  relatedResources: ["docs://sdk/query-builder"],
1991
- relatedTools: ["update-many-collection", "delete-many-collection"]
2415
+ relatedTools: ["query-collection", "get-collection-schema"]
1992
2416
  }
1993
2417
  }
1994
2418
  };
@@ -2002,8 +2426,8 @@ function getRecipe(goal, runtime = "both") {
2002
2426
  }
2003
2427
 
2004
2428
  // src/tools/sdk-get-recipe.ts
2005
- var schema31 = {
2006
- goal: z31.enum([
2429
+ var schema26 = {
2430
+ goal: z24.enum([
2007
2431
  "fetch-list",
2008
2432
  "fetch-by-id",
2009
2433
  "create-item",
@@ -2015,11 +2439,11 @@ var schema31 = {
2015
2439
  "file-upload",
2016
2440
  "bulk-operations"
2017
2441
  ]).describe("What the user wants to accomplish"),
2018
- runtime: z31.enum(["browser", "server", "both"]).default("both").describe("Target runtime environment"),
2019
- collection: z31.string().optional().describe("Specific collection name if applicable"),
2020
- includeExample: z31.boolean().default(true).describe("Whether to include a full code example")
2442
+ runtime: z24.enum(["browser", "server", "both"]).default("both").describe("Target runtime environment"),
2443
+ collection: z24.string().optional().describe("Specific collection name if applicable"),
2444
+ includeExample: z24.boolean().default(true).describe("Whether to include a full code example")
2021
2445
  };
2022
- var metadata31 = {
2446
+ var metadata26 = {
2023
2447
  name: "sdk-get-recipe",
2024
2448
  description: "Get a complete SDK code recipe for a specific task. Returns recommended approach, code example, and related documentation links. Use this FIRST when the user asks how to do something with the SDK.",
2025
2449
  annotations: {
@@ -2062,7 +2486,7 @@ function handler2({
2062
2486
  }
2063
2487
 
2064
2488
  // src/tools/sdk-search-docs.ts
2065
- import { z as z32 } from "zod";
2489
+ import { z as z25 } from "zod";
2066
2490
 
2067
2491
  // src/lib/sdk-doc-index.ts
2068
2492
  var docIndex = [
@@ -2076,7 +2500,7 @@ var docIndex = [
2076
2500
  {
2077
2501
  title: "Browser Client vs Server Client",
2078
2502
  keywords: ["browser", "server", "publishable key", "secret key", "createClient", "createServerClient", "NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY", "SOFTWARE_PUBLISHABLE_KEY", "SOFTWARE_SECRET_KEY", "pk01_", "sk01_", "pat01_", "read-only", "full crud"],
2079
- summary: "createClient() for browser with publishableKey (read-only pk01_), createServerClient() for server with SOFTWARE_SECRET_KEY (usually sk01_, sometimes pat01_ in browser-auth-scoped flows). Never expose SECRET_KEY to the browser.",
2503
+ summary: "createClient() for browser with publishableKey (read-only pk01_), createServerClient() for server with matching SOFTWARE_PUBLISHABLE_KEY + SOFTWARE_SECRET_KEY (usually sk01_, sometimes pat01_ in scoped flows). Never expose SECRET_KEY to the browser.",
2080
2504
  resourceUri: "docs://sdk/getting-started"
2081
2505
  },
2082
2506
  // Query Builder
@@ -2237,11 +2661,11 @@ function searchDocs(query, limit = 5) {
2237
2661
  }
2238
2662
 
2239
2663
  // src/tools/sdk-search-docs.ts
2240
- var schema32 = {
2241
- query: z32.string().min(2).describe('Search keyword or phrase (e.g. "infinite scroll", "webhook", "customer login")'),
2242
- limit: z32.number().min(1).max(10).default(5).describe("Maximum results to return (1-10, default: 5)")
2664
+ var schema27 = {
2665
+ query: z25.string().min(2).describe('Search keyword or phrase (e.g. "infinite scroll", "webhook", "customer login")'),
2666
+ limit: z25.number().min(1).max(10).default(5).describe("Maximum results to return (1-10, default: 5)")
2243
2667
  };
2244
- var metadata32 = {
2668
+ var metadata27 = {
2245
2669
  name: "sdk-search-docs",
2246
2670
  description: "Search SDK documentation by keyword. Returns matching topics with summaries and resource links. Use when looking for specific SDK features or patterns.",
2247
2671
  annotations: {
@@ -2276,9 +2700,9 @@ function handler3({
2276
2700
  }
2277
2701
 
2278
2702
  // src/tools/sdk-get-auth-setup.ts
2279
- import { z as z33 } from "zod";
2280
- var schema33 = {
2281
- scenario: z33.enum([
2703
+ import { z as z26 } from "zod";
2704
+ var schema28 = {
2705
+ scenario: z26.enum([
2282
2706
  "browser-client",
2283
2707
  "server-client",
2284
2708
  "customer-auth",
@@ -2287,7 +2711,7 @@ var schema33 = {
2287
2711
  "webhook-verification"
2288
2712
  ]).describe("Authentication scenario")
2289
2713
  };
2290
- var metadata33 = {
2714
+ var metadata28 = {
2291
2715
  name: "sdk-get-auth-setup",
2292
2716
  description: "Get the current authentication setup for a specific scenario. Returns env var names, code snippets, and security notes.",
2293
2717
  annotations: {
@@ -2441,14 +2865,14 @@ function handler4({
2441
2865
  }
2442
2866
 
2443
2867
  // src/tools/sdk-get-collection-pattern.ts
2444
- import { z as z34 } from "zod";
2445
- import { COLLECTIONS as COLLECTIONS9 } from "@01.software/sdk";
2446
- var schema34 = {
2447
- collection: z34.enum(COLLECTIONS9).describe("Collection name"),
2448
- operation: z34.enum(["read", "write", "full-crud"]).default("read").describe("What operations are needed"),
2449
- surface: z34.enum(["query-builder", "react-query", "server-api"]).default("query-builder").describe("Preferred API surface")
2868
+ import { z as z27 } from "zod";
2869
+ import { COLLECTIONS, SERVER_COLLECTIONS as SERVER_COLLECTIONS4 } from "@01.software/sdk";
2870
+ var schema29 = {
2871
+ collection: z27.enum(SERVER_COLLECTIONS4).describe("Collection name"),
2872
+ operation: z27.enum(["read", "write", "full-crud"]).default("read").describe("What operations are needed"),
2873
+ surface: z27.enum(["query-builder", "react-query", "server-api"]).default("query-builder").describe("Preferred API surface")
2450
2874
  };
2451
- var metadata34 = {
2875
+ var metadata29 = {
2452
2876
  name: "sdk-get-collection-pattern",
2453
2877
  description: "Get the recommended CRUD pattern for a specific collection. Returns code examples for the chosen API surface and operation type.",
2454
2878
  annotations: {
@@ -2459,7 +2883,15 @@ var metadata34 = {
2459
2883
  }
2460
2884
  };
2461
2885
  function generatePattern(collection, operation, surface) {
2886
+ const isPublicCollection = COLLECTIONS.includes(
2887
+ collection
2888
+ );
2462
2889
  if (surface === "react-query") {
2890
+ if (!isPublicCollection) {
2891
+ throw new Error(
2892
+ `${collection} is server-only. Use surface="server-api" with createServerClient().`
2893
+ );
2894
+ }
2463
2895
  const parts2 = [];
2464
2896
  if (operation === "read") {
2465
2897
  parts2.push(
@@ -2571,17 +3003,29 @@ function generatePattern(collection, operation, surface) {
2571
3003
  }
2572
3004
  const parts = [];
2573
3005
  if (operation === "read" || operation === "full-crud") {
2574
- parts.push(
2575
- `// Read with any client (Client or ServerClient)`,
2576
- `const result = await client.collections.from('${collection}').find({`,
2577
- ` where: { status: { equals: 'published' } },`,
2578
- ` limit: 10,`,
2579
- ` sort: '-createdAt'`,
2580
- `})`,
2581
- ``,
2582
- `const item = await client.collections.from('${collection}').findById(id)`,
2583
- `const { totalDocs } = await client.collections.from('${collection}').count()`
2584
- );
3006
+ if (isPublicCollection) {
3007
+ parts.push(
3008
+ `// Read with any client (Client or ServerClient)`,
3009
+ `const result = await client.collections.from('${collection}').find({`,
3010
+ ` where: { status: { equals: 'published' } },`,
3011
+ ` limit: 10,`,
3012
+ ` sort: '-createdAt'`,
3013
+ `})`,
3014
+ ``,
3015
+ `const item = await client.collections.from('${collection}').findById(id)`,
3016
+ `const { totalDocs } = await client.collections.from('${collection}').count()`
3017
+ );
3018
+ } else {
3019
+ parts.push(
3020
+ `// Server-only collection: use ServerClient`,
3021
+ `const result = await serverClient.collections.from('${collection}').find({`,
3022
+ ` limit: 10,`,
3023
+ ` sort: '-createdAt'`,
3024
+ `})`,
3025
+ ``,
3026
+ `const item = await serverClient.collections.from('${collection}').findById(id)`
3027
+ );
3028
+ }
2585
3029
  }
2586
3030
  if (operation === "write" || operation === "full-crud") {
2587
3031
  parts.push(
@@ -2596,6 +3040,7 @@ function generatePattern(collection, operation, surface) {
2596
3040
  code: parts.join("\n"),
2597
3041
  notes: [
2598
3042
  "Query Builder works with both Client and ServerClient for reads",
3043
+ !isPublicCollection ? "This collection is server-only" : "",
2599
3044
  operation !== "read" ? "Write operations require ServerClient" : ""
2600
3045
  ].filter(Boolean)
2601
3046
  };
@@ -2615,7 +3060,6 @@ function handler5({
2615
3060
  relatedTools: [
2616
3061
  "query-collection",
2617
3062
  "get-collection-by-id",
2618
- ...operation !== "read" ? ["create-collection", "update-collection", "delete-collection"] : [],
2619
3063
  "get-collection-schema"
2620
3064
  ],
2621
3065
  relatedResources: [
@@ -2629,14 +3073,14 @@ function handler5({
2629
3073
  }
2630
3074
 
2631
3075
  // src/prompts/sdk-usage-guide.ts
2632
- import { z as z35 } from "zod";
2633
- var schema35 = {
2634
- goal: z35.string().describe('What the user wants to accomplish (e.g., "query product list", "create order")'),
2635
- runtime: z35.enum(["browser", "server"]).optional().describe("Target runtime: browser (React/Next.js client) or server (Node.js)"),
2636
- surface: z35.enum(["query-builder", "react-query", "customer-api", "server-api"]).optional().describe("Preferred API surface"),
2637
- collection: z35.string().optional().describe("Specific collection if relevant")
3076
+ import { z as z28 } from "zod";
3077
+ var schema30 = {
3078
+ goal: z28.string().describe('What the user wants to accomplish (e.g., "query product list", "create order")'),
3079
+ runtime: z28.enum(["browser", "server"]).optional().describe("Target runtime: browser (React/Next.js client) or server (Node.js)"),
3080
+ surface: z28.enum(["query-builder", "react-query", "customer-api", "server-api"]).optional().describe("Preferred API surface"),
3081
+ collection: z28.string().optional().describe("Specific collection if relevant")
2638
3082
  };
2639
- var metadata35 = {
3083
+ var metadata30 = {
2640
3084
  name: "sdk-usage-guide",
2641
3085
  title: "SDK Usage Guide",
2642
3086
  description: "Provides guidance on how to perform a specific task using the 01.software SDK",
@@ -2773,14 +3217,14 @@ You can perform the "${goal}" task by following the patterns above.`;
2773
3217
  }
2774
3218
 
2775
3219
  // src/prompts/collection-query-help.ts
2776
- import { z as z36 } from "zod";
2777
- import { COLLECTIONS as COLLECTIONS10 } from "@01.software/sdk";
2778
- var schema36 = {
2779
- collection: z36.enum(COLLECTIONS10).describe("Collection name"),
2780
- operation: z36.enum(["find", "create", "update", "delete"]).describe("Operation to perform (find, create, update, delete)"),
2781
- filters: z36.string().optional().describe("Filter conditions (JSON string, optional)")
3220
+ import { z as z29 } from "zod";
3221
+ import { COLLECTIONS as COLLECTIONS2, SERVER_COLLECTIONS as SERVER_COLLECTIONS5 } from "@01.software/sdk";
3222
+ var schema31 = {
3223
+ collection: z29.enum(SERVER_COLLECTIONS5).describe("Collection name"),
3224
+ operation: z29.enum(["find", "create", "update", "delete"]).describe("Operation to perform (find, create, update, delete)"),
3225
+ filters: z29.string().optional().describe("Filter conditions (JSON string, optional)")
2782
3226
  };
2783
- var metadata36 = {
3227
+ var metadata31 = {
2784
3228
  name: "collection-query-help",
2785
3229
  title: "Collection Query Help",
2786
3230
  description: "Provides guidance on how to write queries for a specific collection",
@@ -2797,6 +3241,11 @@ Filter conditions:
2797
3241
  \`\`\`json
2798
3242
  ${filters}
2799
3243
  \`\`\`` : "";
3244
+ const isPublicCollection = COLLECTIONS2.includes(
3245
+ collection
3246
+ );
3247
+ const readClientName = isPublicCollection ? "client" : "serverClient";
3248
+ const readClientNote = isPublicCollection ? "Client or ServerClient" : "ServerClient only";
2800
3249
  return `How to perform "${operation}" operation on "${collection}" collection:${filterExample}
2801
3250
 
2802
3251
  ## Collection: ${collection}
@@ -2807,26 +3256,26 @@ ${filters}
2807
3256
  \`\`\`typescript
2808
3257
  import { createClient, createServerClient } from '@01.software/sdk'
2809
3258
 
2810
- // Client (read-only)
3259
+ // Client (read-only public collections)
2811
3260
  const client = createClient({
2812
3261
  publishableKey: process.env.NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY!
2813
3262
  })
2814
3263
 
2815
- // Server client (full CRUD)
3264
+ // Server client (server/public collections, full CRUD)
2816
3265
  const serverClient = createServerClient({
2817
3266
  publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,
2818
3267
  secretKey: process.env.SOFTWARE_SECRET_KEY!
2819
3268
  })
2820
3269
 
2821
- ${operation === "find" ? `// Query ${collection} collection with Query Builder
3270
+ ${operation === "find" ? `// Query ${collection} collection with Query Builder (${readClientNote})
2822
3271
  // find() returns PayloadFindResponse with docs array and pagination
2823
- const result = await client.collections.from('${collection}').find(${filters ? `{
3272
+ const result = await ${readClientName}.collections.from('${collection}').find(${filters ? `{
2824
3273
  where: ${filters}
2825
3274
  }` : ""})
2826
3275
  // result.docs - array of items
2827
3276
  // result.totalDocs, result.page, result.totalPages, result.hasNextPage, ...
2828
3277
 
2829
- // Using React Hook
3278
+ ${isPublicCollection ? `// Using React Hook
2830
3279
  const { data, isLoading, error } = client.query.useQuery({
2831
3280
  collection: '${collection}',
2832
3281
  options: { limit: 10 }
@@ -2836,19 +3285,19 @@ const { data, isLoading, error } = client.query.useQuery({
2836
3285
  const { data } = client.query.useSuspenseQuery({
2837
3286
  collection: '${collection}',
2838
3287
  options: { limit: 10 }
2839
- })` : operation === "create" ? `// Create ${collection} item (ServerClient only)
3288
+ })` : `// React hooks are browser/public only and do not support '${collection}'.`}` : operation === "create" ? `// Create ${collection} item (ServerClient only)
2840
3289
  // create() returns PayloadMutationResponse with doc and message
2841
- const result = await serverClient.from('${collection}').create({
3290
+ const result = await serverClient.collections.from('${collection}').create({
2842
3291
  // Enter fields
2843
3292
  })
2844
3293
  // result.doc - created item, result.message` : operation === "update" ? `// Update ${collection} item (ServerClient only)
2845
3294
  // update() returns PayloadMutationResponse with doc and message
2846
- const result = await serverClient.from('${collection}').update(id, {
3295
+ const result = await serverClient.collections.from('${collection}').update(id, {
2847
3296
  // Fields to update
2848
3297
  })
2849
3298
  // result.doc - updated item, result.message` : `// Delete ${collection} item (ServerClient only)
2850
3299
  // remove() returns the deleted document directly
2851
- await serverClient.from('${collection}').remove(id)`}
3300
+ await serverClient.collections.from('${collection}').remove(id)`}
2852
3301
  \`\`\`
2853
3302
 
2854
3303
  ### Useful Tips
@@ -2856,7 +3305,7 @@ await serverClient.from('${collection}').remove(id)`}
2856
3305
  ${operation === "find" ? `- Use \`where\` option for filtering (Payload query syntax)
2857
3306
  - Use \`limit\` and \`page\` for pagination
2858
3307
  - Use \`sort\` for sorting (prefix with "-" for descending)
2859
- - React Query hooks: useQuery, useSuspenseQuery, useInfiniteQuery
3308
+ - ${isPublicCollection ? "React Query hooks: useQuery, useSuspenseQuery, useInfiniteQuery" : "React Query hooks are browser/public only; use ServerClient for this collection"}
2860
3309
  - Cache utilities: invalidateQueries, prefetchQuery, getQueryData, setQueryData` : operation === "create" ? `- Requires ServerClient with secretKey
2861
3310
  - Check required fields
2862
3311
  - TypeScript recommended for type safety` : operation === "update" ? `- Requires ServerClient with secretKey
@@ -2867,16 +3316,16 @@ ${operation === "find" ? `- Use \`where\` option for filtering (Payload query sy
2867
3316
  }
2868
3317
 
2869
3318
  // src/prompts/order-flow-guide.ts
2870
- import { z as z37 } from "zod";
2871
- var schema37 = {
2872
- scenario: z37.enum([
3319
+ import { z as z30 } from "zod";
3320
+ var schema32 = {
3321
+ scenario: z30.enum([
2873
3322
  "simple-order",
2874
3323
  "cart-checkout",
2875
3324
  "return-refund",
2876
3325
  "fulfillment-tracking"
2877
3326
  ]).describe("Order flow scenario")
2878
3327
  };
2879
- var metadata37 = {
3328
+ var metadata32 = {
2880
3329
  name: "order-flow-guide",
2881
3330
  title: "Order Flow Guide",
2882
3331
  description: "Provides step-by-step guidance for ecommerce order flows including creation, checkout, returns, and fulfillment.",
@@ -2891,8 +3340,8 @@ var SCENARIOS = {
2891
3340
  - Provide: orderNumber, customerSnapshot (email required), shippingAddress, orderItems, totalAmount
2892
3341
  - Optional: pgPaymentId (omit for free orders), shippingAmount, discountCode
2893
3342
 
2894
- 2. **Payment Confirmation** \u2192 \`update-order\` tool
2895
- - Update status to \`paid\` after payment gateway confirms
3343
+ 2. **Payment Confirmation** \u2192 \`update-transaction\` tool
3344
+ - Confirm provider payment with pgPaymentId, paymentKey, and amount
2896
3345
  - Stock is automatically adjusted (stock -= qty, reservedStock += qty)
2897
3346
 
2898
3347
  3. **Fulfillment** \u2192 \`create-fulfillment\` tool
@@ -2919,8 +3368,13 @@ const order = await client.commerce.orders.create({
2919
3368
  pgPaymentId: 'pay_xxx' // omit for free orders
2920
3369
  })
2921
3370
 
2922
- // 2. After payment confirmed
2923
- await client.commerce.orders.update({ orderNumber: 'ORD-240101-001', status: 'paid' })
3371
+ // 2. After payment confirmed by provider
3372
+ await client.commerce.orders.updateTransaction({
3373
+ pgPaymentId: 'pay_xxx',
3374
+ status: 'paid',
3375
+ paymentKey: 'payment_key_xxx',
3376
+ amount: 59800
3377
+ })
2924
3378
 
2925
3379
  // 3. Ship items
2926
3380
  await client.commerce.orders.createFulfillment({
@@ -2938,7 +3392,7 @@ await client.commerce.orders.createFulfillment({
2938
3392
  2. **Apply Discount** (optional) \u2192 \`apply-discount\` tool
2939
3393
  3. **Calculate Shipping** \u2192 \`calculate-shipping\` tool
2940
3394
  4. **Checkout** \u2192 \`checkout\` tool (converts cart to order)
2941
- 5. **Payment** \u2192 \`update-order\` or \`update-transaction\`
3395
+ 5. **Payment** \u2192 \`update-transaction\` for provider-verified paid transitions
2942
3396
 
2943
3397
  ### Key Points
2944
3398
  - Cart has a customer linked \u2014 auto-copied to order on checkout
@@ -2975,7 +3429,7 @@ const order = await client.commerce.orders.checkout({
2975
3429
  1. **Return with Refund** \u2192 \`return-with-refund\` tool
2976
3430
  - Handles return + stock restoration + transaction update in one call
2977
3431
  - Return immediately completed (bypasses FSM)
2978
- - Requires pgPaymentId to identify which transaction to refund
3432
+ - Requires pgPaymentId and paymentKey for provider-verified refund
2979
3433
 
2980
3434
  ### Key Points
2981
3435
  - Full refund: original transaction \u2192 \`canceled\`
@@ -2992,7 +3446,8 @@ await client.commerce.orders.returnWithRefund({
2992
3446
  reasonDetail: 'Product arrived damaged',
2993
3447
  returnItems: [{ orderItem: 'oi-id', quantity: 1 }],
2994
3448
  refundAmount: 29900,
2995
- pgPaymentId: 'pay_xxx'
3449
+ pgPaymentId: 'pay_xxx',
3450
+ paymentKey: 'payment_key_xxx'
2996
3451
  })
2997
3452
  \`\`\``,
2998
3453
  "fulfillment-tracking": `## Fulfillment & Tracking
@@ -3055,9 +3510,9 @@ ${SCENARIOS[scenario] || "Unknown scenario."}
3055
3510
  }
3056
3511
 
3057
3512
  // src/prompts/feature-setup-guide.ts
3058
- import { z as z38 } from "zod";
3059
- var schema38 = {
3060
- feature: z38.enum([
3513
+ import { z as z31 } from "zod";
3514
+ var schema33 = {
3515
+ feature: z31.enum([
3061
3516
  "ecommerce",
3062
3517
  "customers",
3063
3518
  "articles",
@@ -3072,7 +3527,7 @@ var schema38 = {
3072
3527
  "community"
3073
3528
  ]).describe("Feature to get setup guide for")
3074
3529
  };
3075
- var metadata38 = {
3530
+ var metadata33 = {
3076
3531
  name: "feature-setup-guide",
3077
3532
  title: "Feature Setup Guide",
3078
3533
  description: "Setup checklist and remediation guide for a tenant feature. Load before using get-tenant-context to diagnose setup gaps.",
@@ -3085,8 +3540,8 @@ var FEATURES = {
3085
3540
 
3086
3541
  ### Required Collections (count > 0)
3087
3542
 
3088
- 1. **products** \u2014 Use \`create-collection\` with \`collection='products'\`
3089
- - Minimum fields: \`{ title, slug, status: 'active' }\`
3543
+ 1. **products** \u2014 Create via Console UI or SDK \`client.collections.from('products').create({ ... })\`
3544
+ - Minimum fields: \`{ title, slug, status: 'published' }\`
3090
3545
 
3091
3546
  2. **product-variants** \u2014 At least 1 sellable variant per product
3092
3547
  - Minimum fields: \`{ product, title, price, stock }\`
@@ -3119,7 +3574,8 @@ customer-addresses
3119
3574
 
3120
3575
  ### Optional Collections
3121
3576
 
3122
- customer-groups \u2014 Use \`create-collection\` with \`collection='customer-groups'\`, \`{ title }\`
3577
+ - customer-groups \u2014 Console/server-scoped segmentation for VIP coupons and campaigns. Use \`createServerClient().collections.from('customer-groups')\`.
3578
+ - customer-profile-lists \u2014 Public profile display/ranking lists for storefronts. Browser reads may use \`client.collections.from('customer-profile-lists')\`.
3123
3579
 
3124
3580
  ### Config
3125
3581
 
@@ -3130,10 +3586,10 @@ customer-groups \u2014 Use \`create-collection\` with \`collection='customer-gro
3130
3586
  ### Required Collections (count > 0)
3131
3587
 
3132
3588
  1. **articles** \u2014 At least 1 article
3133
- - Minimum fields: \`{ title, slug }\`
3589
+ - Minimum fields: \`{ title, slug, status: 'published' }\`
3134
3590
 
3135
3591
  2. **article-authors** \u2014 At least 1 author
3136
- - Minimum fields: \`{ title, slug }\`
3592
+ - Minimum fields: \`{ title, slug, status: 'published' }\`
3137
3593
  - Link authors to articles via the \`authors\` relationship field
3138
3594
 
3139
3595
  ### Optional Collections
@@ -3148,7 +3604,7 @@ article-categories, article-tags`,
3148
3604
 
3149
3605
  2. **document-types** \u2014 At least 1 type
3150
3606
  - Minimum fields: \`{ title, slug }\`
3151
- - Link document type via \`documentType\` relationship field
3607
+ - Link document type via \`type\` relationship field
3152
3608
 
3153
3609
  ### Optional Collections
3154
3610
 
@@ -3158,10 +3614,10 @@ document-categories`,
3158
3614
  ### Required Collections (count > 0)
3159
3615
 
3160
3616
  1. **playlists** \u2014 At least 1 playlist
3161
- - Minimum fields: \`{ title, slug }\`
3617
+ - Minimum fields: \`{ title, slug, status: 'published' }\`
3162
3618
 
3163
3619
  2. **tracks** \u2014 At least 1 track
3164
- - Minimum fields: \`{ title }\`
3620
+ - Minimum fields: \`{ title, sourceUrl, status: 'published' }\`
3165
3621
 
3166
3622
  3. **playlists.tracks** \u2014 Link at least 1 track from a playlist
3167
3623
  - Minimum fields: \`{ tracks: [trackId] }\`
@@ -3174,11 +3630,11 @@ playlist-categories, playlist-tags, track-categories, track-tags, track-assets`,
3174
3630
  ### Required Collections (count > 0)
3175
3631
 
3176
3632
  1. **galleries** \u2014 At least 1 gallery
3177
- - Minimum fields: \`{ title, slug }\`
3633
+ - Minimum fields: \`{ title, slug, status: 'published' }\`
3178
3634
 
3179
3635
  2. **gallery-items** \u2014 At least 1 item per gallery
3180
3636
  - References \`images\` collection (non-upload)
3181
- - Minimum fields: \`{ gallery, image }\`
3637
+ - Minimum fields: \`{ gallery, image, status: 'published' }\`
3182
3638
 
3183
3639
  ### Optional Collections
3184
3640
 
@@ -3188,7 +3644,7 @@ gallery-categories, gallery-tags`,
3188
3644
  ### Required Collections (count > 0)
3189
3645
 
3190
3646
  1. **links** \u2014 At least 1 link
3191
- - Minimum fields: \`{ title, slug, url }\`
3647
+ - Minimum fields: \`{ title, slug, url, status: 'published' }\`
3192
3648
 
3193
3649
  ### Optional Collections
3194
3650
 
@@ -3260,21 +3716,23 @@ comments, reactions, bookmarks, reports, community-bans
3260
3716
 
3261
3717
  ### Optional Collections
3262
3718
 
3263
- post-categories`
3719
+ post-categories, customer-profile-lists`
3264
3720
  };
3265
- function featureSetupGuide({ feature }) {
3721
+ function featureSetupGuide({
3722
+ feature
3723
+ }) {
3266
3724
  return `# Feature Setup Guide: ${feature}
3267
3725
 
3268
3726
  ${FEATURES[feature] || "Unknown feature."}
3269
3727
 
3270
3728
  ## Related MCP Tools
3271
3729
  - \`get-tenant-context\` \u2014 check current collection counts and feature status
3272
- - \`create-collection\` \u2014 create required collection documents
3273
- - \`query-collection\` \u2014 verify existing documents in a collection`;
3730
+ - \`query-collection\` \u2014 verify existing documents in a collection
3731
+ - \`get-collection-schema\` \u2014 inspect tenant-aware fields before creating data via SDK or Console UI`;
3274
3732
  }
3275
3733
 
3276
3734
  // src/resources/(config)/app.ts
3277
- var metadata39 = {
3735
+ var metadata34 = {
3278
3736
  name: "app-config",
3279
3737
  title: "Application Config",
3280
3738
  description: "01.software SDK and MCP server configuration information"
@@ -3285,7 +3743,8 @@ function handler6() {
3285
3743
  ## Server Info
3286
3744
  - **Name**: 01.software MCP Server
3287
3745
  - **Version**: 0.1.0
3288
- - **Transport**: HTTP (Streamable)
3746
+ - **Hosted transport**: HTTP (Streamable)
3747
+ - **Local transport**: stdio through \`npx @01.software/cli mcp\`
3289
3748
 
3290
3749
  ## Authentication
3291
3750
 
@@ -3296,45 +3755,9 @@ HTTP MCP uses OAuth discovery and Authorization Code + PKCE.
3296
3755
  url = "https://mcp.01.software/mcp"
3297
3756
  \`\`\`
3298
3757
 
3299
- ## Available Tools (34)
3300
-
3301
- ### Generic CRUD (7)
3302
- - \`query-collection\` - Query collection with filters, pagination, sorting
3303
- - \`get-collection-by-id\` - Get single item by ID
3304
- - \`create-collection\` - Create new item
3305
- - \`update-collection\` - Update existing item
3306
- - \`delete-collection\` - Delete item (destructive)
3307
- - \`update-many-collection\` - Bulk update items matching filter
3308
- - \`delete-many-collection\` - Bulk delete items matching filter (destructive)
3309
-
3310
- ### Orders (7)
3311
- - \`create-order\` - Create a new order with products and shipping
3312
- - \`get-order\` - Get order details by order number
3313
- - \`update-order\` - Update order status
3314
- - \`checkout\` - Convert cart to order
3315
- - \`create-fulfillment\` - Create fulfillment for order items
3316
- - \`update-fulfillment\` - Update fulfillment status, carrier, and tracking
3317
- - \`update-transaction\` - Update transaction status
3318
-
3319
- ### Returns (3)
3320
- - \`create-return\` - Create a return request
3321
- - \`update-return\` - Update return status
3322
- - \`return-with-refund\` - Process return with refund atomically
3323
-
3324
- ### Cart (6)
3325
- - \`add-cart-item\` - Add item to cart
3326
- - \`update-cart-item\` - Update cart item quantity
3327
- - \`remove-cart-item\` - Remove item from cart
3328
- - \`apply-discount\` - Apply discount code to cart
3329
- - \`remove-discount\` - Remove discount from cart
3330
- - \`clear-cart\` - Remove all items from cart
3331
-
3332
- ### Validation (2)
3333
- - \`validate-discount\` - Validate discount code
3334
- - \`calculate-shipping\` - Calculate shipping fee
3335
-
3336
- ### Product (1)
3337
- - \`stock-check\` - Check product option stock availability
3758
+ ## Hosted HTTP OAuth Tools (8)
3759
+
3760
+ The hosted HTTP MCP endpoint at https://mcp.01.software/mcp exposes only these OAuth-safe tools:
3338
3761
 
3339
3762
  ### Schema (1)
3340
3763
  - \`get-collection-schema\` - Get authoritative tenant-aware collection schema
@@ -3352,6 +3775,16 @@ url = "https://mcp.01.software/mcp"
3352
3775
  - \`sdk-get-auth-setup\` - Get framework-specific auth setup guidance
3353
3776
  - \`sdk-get-collection-pattern\` - Get collection-specific usage patterns
3354
3777
 
3778
+ ## Local CLI Stdio Surface (29)
3779
+
3780
+ For trusted local server-key workflows, start the stdio server:
3781
+
3782
+ \`\`\`bash
3783
+ npx @01.software/cli mcp
3784
+ \`\`\`
3785
+
3786
+ Local stdio can expose generic read, order, return, cart, validation, stock, schema, tenant context, field config, and guidance tools. Generic collection write tools (create/update/delete/update-many/delete-many) are intentionally absent on every transport; use the SDK server client for generic writes.
3787
+
3355
3788
  ## Rate Limits
3356
3789
 
3357
3790
  Rate limits depend on your tenant plan:
@@ -3363,80 +3796,96 @@ Rate limits depend on your tenant plan:
3363
3796
  }
3364
3797
 
3365
3798
  // src/resources/(collections)/schema.ts
3366
- import { COLLECTIONS as COLLECTIONS11 } from "@01.software/sdk";
3367
- var metadata40 = {
3799
+ import { COLLECTIONS as COLLECTIONS3 } from "@01.software/sdk";
3800
+ var metadata35 = {
3368
3801
  name: "collections-schema",
3369
3802
  title: "Collection Schema Info",
3370
3803
  description: "Available collections and their schema information"
3371
3804
  };
3805
+ var COLLECTIONS_BY_CATEGORY = {
3806
+ "Tenant Management": ["tenants", "tenant-metadata", "tenant-logos"],
3807
+ Products: [
3808
+ "products",
3809
+ "product-variants",
3810
+ "product-options",
3811
+ "product-option-values",
3812
+ "product-categories",
3813
+ "product-tags",
3814
+ "product-collections"
3815
+ ],
3816
+ Brands: ["brands", "brand-logos"],
3817
+ "Orders & Fulfillment": [
3818
+ "orders",
3819
+ "order-items",
3820
+ "transactions",
3821
+ "fulfillments",
3822
+ "fulfillment-items"
3823
+ ],
3824
+ "Shipping & Returns": ["returns", "return-items", "shipping-policies"],
3825
+ Customers: [
3826
+ "customers",
3827
+ "customer-profiles",
3828
+ "customer-profile-lists",
3829
+ "customer-addresses"
3830
+ ],
3831
+ Carts: ["carts", "cart-items"],
3832
+ "Discounts & Promotions": ["discounts", "promotions"],
3833
+ Documents: ["documents", "document-categories", "document-types"],
3834
+ Articles: [
3835
+ "articles",
3836
+ "article-authors",
3837
+ "article-categories",
3838
+ "article-tags"
3839
+ ],
3840
+ Community: [
3841
+ "posts",
3842
+ "comments",
3843
+ "reactions",
3844
+ "reaction-types",
3845
+ "bookmarks",
3846
+ "post-categories",
3847
+ "reports",
3848
+ "community-bans"
3849
+ ],
3850
+ Playlists: [
3851
+ "playlists",
3852
+ "tracks",
3853
+ "playlist-categories",
3854
+ "playlist-tags",
3855
+ "track-categories",
3856
+ "track-tags"
3857
+ ],
3858
+ Galleries: [
3859
+ "galleries",
3860
+ "gallery-items",
3861
+ "gallery-categories",
3862
+ "gallery-tags"
3863
+ ],
3864
+ Links: ["links", "link-categories", "link-tags"],
3865
+ Canvas: [
3866
+ "canvases",
3867
+ "canvas-node-types",
3868
+ "canvas-edge-types",
3869
+ "canvas-categories",
3870
+ "canvas-tags",
3871
+ "canvas-nodes",
3872
+ "canvas-edges"
3873
+ ],
3874
+ Videos: ["videos", "video-categories", "video-tags"],
3875
+ "Live Streams": ["live-streams"],
3876
+ Images: ["images"],
3877
+ Forms: ["forms", "form-submissions"],
3878
+ Events: [
3879
+ "event-calendars",
3880
+ "events",
3881
+ "event-categories",
3882
+ "event-occurrences",
3883
+ "event-tags"
3884
+ ]
3885
+ };
3372
3886
  function handler7() {
3373
- const collectionsByCategory = {
3374
- "Tenant Management": ["tenants", "tenant-metadata", "tenant-logos"],
3375
- Products: [
3376
- "products",
3377
- "product-variants",
3378
- "product-options",
3379
- "product-categories",
3380
- "product-tags",
3381
- "product-collections"
3382
- ],
3383
- Brands: ["brands", "brand-logos"],
3384
- "Orders & Fulfillment": [
3385
- "orders",
3386
- "order-items",
3387
- "transactions",
3388
- "fulfillments",
3389
- "fulfillment-items"
3390
- ],
3391
- "Shipping & Returns": [
3392
- "returns",
3393
- "return-items",
3394
- "shipping-policies"
3395
- ],
3396
- Customers: ["customers", "customer-addresses", "customer-groups"],
3397
- Carts: ["carts", "cart-items"],
3398
- Discounts: ["discounts"],
3399
- Documents: ["documents", "document-categories", "document-types"],
3400
- Articles: ["articles", "article-authors", "article-categories", "article-tags"],
3401
- Community: [
3402
- "posts",
3403
- "comments",
3404
- "reactions",
3405
- "reaction-types",
3406
- "bookmarks",
3407
- "post-categories",
3408
- "reports",
3409
- "community-bans"
3410
- ],
3411
- Playlists: [
3412
- "playlists",
3413
- "tracks",
3414
- "track-assets",
3415
- "playlist-categories",
3416
- "playlist-tags",
3417
- "track-categories",
3418
- "track-tags"
3419
- ],
3420
- Galleries: [
3421
- "galleries",
3422
- "gallery-items",
3423
- "gallery-categories",
3424
- "gallery-tags"
3425
- ],
3426
- Canvas: [
3427
- "canvases",
3428
- "canvas-node-types",
3429
- "canvas-edge-types",
3430
- "canvas-categories",
3431
- "canvas-tags"
3432
- ],
3433
- Videos: ["videos", "video-categories", "video-tags"],
3434
- "Live Streams": ["live-streams"],
3435
- Images: ["images"],
3436
- Forms: ["forms", "form-submissions"]
3437
- };
3438
- const categoryDocs = Object.entries(collectionsByCategory).map(([category, collections]) => {
3439
- const collectionList = collections.filter((c) => COLLECTIONS11.includes(c)).map((c) => `- **${c}**`).join("\n");
3887
+ const categoryDocs = Object.entries(COLLECTIONS_BY_CATEGORY).map(([category, collections]) => {
3888
+ const collectionList = collections.filter((c) => COLLECTIONS3.includes(c)).map((c) => `- **${c}**`).join("\n");
3440
3889
  return `## ${category}
3441
3890
  ${collectionList}`;
3442
3891
  }).join("\n\n");
@@ -3457,6 +3906,10 @@ Each collection supports the following operations:
3457
3906
  - \`updateMany(where, data)\` - Bulk update items matching filter
3458
3907
  - \`removeMany(where)\` - Bulk delete items matching filter
3459
3908
 
3909
+ Status-managed public collections expose only \`status: 'published'\` rows to
3910
+ publishable-key reads unless server-side access explicitly includes
3911
+ unpublished statuses.
3912
+
3460
3913
  ## Query Examples
3461
3914
 
3462
3915
  ### Filtering
@@ -3478,11 +3931,11 @@ Each collection supports the following operations:
3478
3931
  }
3479
3932
  \`\`\`
3480
3933
 
3481
- Total available collections: ${COLLECTIONS11.length}`;
3934
+ Total available collections: ${COLLECTIONS3.length}`;
3482
3935
  }
3483
3936
 
3484
3937
  // src/resources/(docs)/getting-started.ts
3485
- var metadata41 = {
3938
+ var metadata36 = {
3486
3939
  name: "docs-getting-started",
3487
3940
  title: "Getting Started",
3488
3941
  description: "01.software SDK getting started guide"
@@ -3527,7 +3980,7 @@ const result = await client.collections.from('products').find({
3527
3980
  }
3528
3981
 
3529
3982
  // src/resources/(docs)/guides.ts
3530
- var metadata42 = {
3983
+ var metadata37 = {
3531
3984
  name: "docs-guides",
3532
3985
  title: "Guides",
3533
3986
  description: "01.software SDK usage guides"
@@ -3738,7 +4191,7 @@ For more detailed guides, see the [Guides page](/docs/guides).`;
3738
4191
  }
3739
4192
 
3740
4193
  // src/resources/(docs)/api.ts
3741
- var metadata43 = {
4194
+ var metadata38 = {
3742
4195
  name: "docs-api",
3743
4196
  title: "API Reference",
3744
4197
  description: "01.software SDK API reference documentation"
@@ -4024,7 +4477,7 @@ For more details, see the [full API documentation](/docs/api).`;
4024
4477
  }
4025
4478
 
4026
4479
  // src/resources/(docs)/query-builder.ts
4027
- var metadata44 = {
4480
+ var metadata39 = {
4028
4481
  name: "docs-query-builder",
4029
4482
  title: "Query Builder",
4030
4483
  description: "01.software SDK Query Builder API reference (client.collections.from)"
@@ -4218,7 +4671,7 @@ console.log(result.hasNextPage) // true
4218
4671
  }
4219
4672
 
4220
4673
  // src/resources/(docs)/react-query.ts
4221
- var metadata45 = {
4674
+ var metadata40 = {
4222
4675
  name: "docs-react-query",
4223
4676
  title: "React Query Hooks",
4224
4677
  description: "01.software SDK React Query hooks reference (client.query)"
@@ -4466,7 +4919,7 @@ export function ProductList() {
4466
4919
  }
4467
4920
 
4468
4921
  // src/resources/(docs)/server-api.ts
4469
- var metadata46 = {
4922
+ var metadata41 = {
4470
4923
  name: "docs-server-api",
4471
4924
  title: "Server-side API",
4472
4925
  description: "01.software SDK server-side API reference (client.commerce) for orders, fulfillments, returns, carts, and validation"
@@ -4607,7 +5060,7 @@ const ret = await client.commerce.orders.updateReturn({
4607
5060
  \`\`\`
4608
5061
 
4609
5062
  ### returnWithRefund()
4610
- Create a return and process refund in one atomic operation.
5063
+ Create a return and process a provider-verified refund in one atomic operation.
4611
5064
 
4612
5065
  \`\`\`typescript
4613
5066
  const result = await client.commerce.orders.returnWithRefund({
@@ -4619,6 +5072,7 @@ const result = await client.commerce.orders.returnWithRefund({
4619
5072
  ],
4620
5073
  refundAmount: 29900,
4621
5074
  pgPaymentId: 'toss-payment-id', // required
5075
+ paymentKey: 'toss-payment-key', // required for provider refund
4622
5076
  refundReceiptUrl?: 'https://...',
4623
5077
  })
4624
5078
  \`\`\`
@@ -4626,12 +5080,15 @@ const result = await client.commerce.orders.returnWithRefund({
4626
5080
  ## Transaction API
4627
5081
 
4628
5082
  ### updateTransaction()
4629
- Update a transaction status (after PG callback).
5083
+ Confirm or annotate a transaction. Paid transitions require provider
5084
+ verification; non-financial annotations can still update pending transactions.
4630
5085
 
4631
5086
  \`\`\`typescript
4632
5087
  const tx = await client.commerce.orders.updateTransaction({
4633
5088
  pgPaymentId: 'toss-payment-id',
4634
- status: 'paid', // paid | failed | canceled
5089
+ status: 'paid', // pending | paid | failed | canceled
5090
+ paymentKey: 'toss-payment-key', // required when status is paid
5091
+ amount: 29900, // required when status is paid
4635
5092
  })
4636
5093
  \`\`\`
4637
5094
 
@@ -4724,7 +5181,7 @@ const result = await client.commerce.shipping.calculate({
4724
5181
  }
4725
5182
 
4726
5183
  // src/resources/(docs)/customer-auth.ts
4727
- var metadata47 = {
5184
+ var metadata42 = {
4728
5185
  name: "docs-customer-auth",
4729
5186
  title: "Customer Auth API",
4730
5187
  description: "01.software SDK Customer Auth API reference (client.customer)"
@@ -4902,7 +5359,7 @@ async function loadProfile() {
4902
5359
  }
4903
5360
 
4904
5361
  // src/resources/(docs)/browser-vs-server.ts
4905
- var metadata48 = {
5362
+ var metadata43 = {
4906
5363
  name: "docs-browser-vs-server",
4907
5364
  title: "Client vs ServerClient",
4908
5365
  description: "When to use Client (createClient) vs ServerClient (createServerClient) in the 01.software SDK"
@@ -5061,7 +5518,7 @@ export function ProductList() {
5061
5518
  }
5062
5519
 
5063
5520
  // src/resources/(docs)/file-upload.ts
5064
- var metadata49 = {
5521
+ var metadata44 = {
5065
5522
  name: "docs-file-upload",
5066
5523
  title: "File Upload",
5067
5524
  description: "01.software SDK file upload patterns using the images collection"
@@ -5212,7 +5669,7 @@ The platform stores files in Cloudflare R2 and serves via CDN (\`cdn.01.software
5212
5669
  }
5213
5670
 
5214
5671
  // src/resources/(docs)/webhook.ts
5215
- var metadata50 = {
5672
+ var metadata45 = {
5216
5673
  name: "docs-webhook",
5217
5674
  title: "Webhooks",
5218
5675
  description: "01.software SDK webhook verification and event handling"
@@ -5326,28 +5783,71 @@ Configure webhook URLs in the 01.software console under Tenant Settings > Webhoo
5326
5783
  }
5327
5784
 
5328
5785
  // src/server.ts
5329
- function registerTool(server, schema39, meta, handler18) {
5786
+ var REGISTERED_TOOLS_BY_SERVER = /* @__PURE__ */ new WeakMap();
5787
+ function registerTool(server, schema34, meta, handler18) {
5788
+ let registered = REGISTERED_TOOLS_BY_SERVER.get(server);
5789
+ if (!registered) {
5790
+ registered = /* @__PURE__ */ new Set();
5791
+ REGISTERED_TOOLS_BY_SERVER.set(server, registered);
5792
+ }
5793
+ registered.add(meta.name);
5330
5794
  server.registerTool(
5331
5795
  meta.name,
5332
5796
  {
5333
5797
  description: meta.description,
5334
- inputSchema: schema39,
5798
+ inputSchema: schema34,
5335
5799
  annotations: meta.annotations
5336
5800
  },
5337
5801
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
5338
5802
  async (params) => {
5339
- const result = await handler18(params);
5340
- return { content: [{ type: "text", text: result }] };
5803
+ const ctx = tenantAuthContext();
5804
+ if (ctx) {
5805
+ const decision = evaluateToolPolicy(meta.name, ctx.scopes);
5806
+ if (!decision.allowed) {
5807
+ const status = decision.reason === "insufficient_scope" ? 403 : 500;
5808
+ return {
5809
+ content: [
5810
+ {
5811
+ type: "text",
5812
+ text: toolError({
5813
+ status,
5814
+ reason: decision.reason,
5815
+ message: decision.message
5816
+ })
5817
+ }
5818
+ ]
5819
+ };
5820
+ }
5821
+ }
5822
+ const activeSummary = currentMcpTelemetrySummary();
5823
+ const ownSummary = activeSummary || hasRequestContext() ? null : createMcpTelemetrySummary("stdio");
5824
+ const summary = activeSummary ?? ownSummary;
5825
+ let result = null;
5826
+ try {
5827
+ result = await handler18(params);
5828
+ return { content: [{ type: "text", text: result }] };
5829
+ } finally {
5830
+ if (summary) {
5831
+ recordMcpToolResult({
5832
+ resultText: result,
5833
+ summary,
5834
+ toolName: meta.name
5835
+ });
5836
+ }
5837
+ if (ownSummary) {
5838
+ void flushMcpTelemetrySummary(ownSummary);
5839
+ }
5840
+ }
5341
5841
  }
5342
5842
  );
5343
5843
  }
5344
- function registerPrompt(server, schema39, meta, handler18) {
5844
+ function registerPrompt(server, schema34, meta, handler18) {
5345
5845
  server.registerPrompt(
5346
5846
  meta.name,
5347
5847
  {
5348
5848
  title: meta.title,
5349
5849
  description: meta.description,
5350
- argsSchema: schema39
5850
+ argsSchema: schema34
5351
5851
  },
5352
5852
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
5353
5853
  (params) => ({
@@ -5383,61 +5883,65 @@ function createServer(options = {}) {
5383
5883
  if (toolSurface === "full") {
5384
5884
  registerTool(server, schema, metadata, queryCollection);
5385
5885
  registerTool(server, schema2, metadata2, getCollectionById);
5386
- registerTool(server, schema3, metadata3, createCollection);
5387
- registerTool(server, schema4, metadata4, updateCollection);
5388
- registerTool(server, schema5, metadata5, deleteCollection);
5389
- registerTool(server, schema6, metadata6, deleteManyCollection);
5390
- registerTool(server, schema7, metadata7, updateManyCollection);
5391
- registerTool(server, schema8, metadata8, getOrder);
5392
- registerTool(server, schema9, metadata9, createOrder);
5393
- registerTool(server, schema10, metadata10, updateOrder);
5394
- registerTool(server, schema11, metadata11, checkout);
5395
- registerTool(server, schema12, metadata12, createFulfillment);
5396
- registerTool(server, schema13, metadata13, updateFulfillment);
5397
- registerTool(server, schema14, metadata14, updateTransaction);
5398
- registerTool(server, schema15, metadata15, createReturn);
5399
- registerTool(server, schema16, metadata16, updateReturn);
5400
- registerTool(server, schema17, metadata17, returnWithRefund);
5401
- registerTool(server, schema18, metadata18, addCartItem);
5402
- registerTool(server, schema19, metadata19, updateCartItem);
5403
- registerTool(server, schema20, metadata20, removeCartItem);
5404
- registerTool(server, schema21, metadata21, applyDiscount);
5405
- registerTool(server, schema22, metadata22, removeDiscount);
5406
- registerTool(server, schema23, metadata23, clearCart);
5407
- registerTool(server, schema24, metadata24, validateDiscount);
5408
- registerTool(server, schema25, metadata25, calculateShipping);
5409
- registerTool(server, schema26, metadata26, stockCheck);
5886
+ registerTool(server, schema3, metadata3, getOrder);
5887
+ registerTool(server, schema4, metadata4, createOrder);
5888
+ registerTool(server, schema5, metadata5, updateOrder);
5889
+ registerTool(server, schema6, metadata6, checkout);
5890
+ registerTool(server, schema7, metadata7, createFulfillment);
5891
+ registerTool(server, schema8, metadata8, updateFulfillment);
5892
+ registerTool(server, schema9, metadata9, updateTransaction);
5893
+ registerTool(server, schema10, metadata10, createReturn);
5894
+ registerTool(server, schema11, metadata11, updateReturn);
5895
+ registerTool(server, schema12, metadata12, returnWithRefund);
5896
+ registerTool(server, schema13, metadata13, addCartItem);
5897
+ registerTool(server, schema14, metadata14, updateCartItem);
5898
+ registerTool(server, schema15, metadata15, removeCartItem);
5899
+ registerTool(server, schema16, metadata16, applyDiscount);
5900
+ registerTool(server, schema17, metadata17, removeDiscount);
5901
+ registerTool(server, schema18, metadata18, clearCart);
5902
+ registerTool(server, schema19, metadata19, validateDiscount);
5903
+ registerTool(server, schema20, metadata20, calculateShipping);
5904
+ registerTool(server, schema21, metadata21, stockCheck);
5410
5905
  }
5411
- registerTool(server, schema27, metadata27, getCollectionSchemaTool);
5412
- registerTool(server, schema28, metadata28, handler);
5413
- registerTool(server, schema29, metadata29, listConfigurableFields);
5414
- registerTool(server, schema30, metadata30, updateFieldConfig);
5415
- registerTool(server, schema31, metadata31, handler2);
5416
- registerTool(server, schema32, metadata32, handler3);
5417
- registerTool(server, schema33, metadata33, handler4);
5418
- registerTool(server, schema34, metadata34, handler5);
5419
- registerPrompt(server, schema35, metadata35, sdkUsageGuide);
5420
- registerPrompt(server, schema36, metadata36, collectionQueryHelp);
5421
- registerPrompt(server, schema37, metadata37, orderFlowGuide);
5422
- registerPrompt(server, schema38, metadata38, featureSetupGuide);
5423
- registerStaticResource(server, "config://app", metadata39, handler6);
5424
- registerStaticResource(server, "collections://schema", metadata40, handler7);
5425
- registerStaticResource(server, "docs://sdk/getting-started", metadata41, handler8);
5426
- registerStaticResource(server, "docs://sdk/guides", metadata42, handler9);
5427
- registerStaticResource(server, "docs://sdk/api", metadata43, handler10);
5428
- registerStaticResource(server, "docs://sdk/query-builder", metadata44, handler11);
5429
- registerStaticResource(server, "docs://sdk/react-query", metadata45, handler12);
5430
- registerStaticResource(server, "docs://sdk/server-api", metadata46, handler13);
5431
- registerStaticResource(server, "docs://sdk/customer-auth", metadata47, handler14);
5432
- registerStaticResource(server, "docs://sdk/browser-vs-server", metadata48, handler15);
5433
- registerStaticResource(server, "docs://sdk/file-upload", metadata49, handler16);
5434
- registerStaticResource(server, "docs://sdk/webhook", metadata50, handler17);
5906
+ registerTool(server, schema22, metadata22, getCollectionSchemaTool);
5907
+ registerTool(server, schema23, metadata23, handler);
5908
+ registerTool(server, schema24, metadata24, listConfigurableFields);
5909
+ registerTool(server, schema25, metadata25, updateFieldConfig);
5910
+ registerTool(server, schema26, metadata26, handler2);
5911
+ registerTool(server, schema27, metadata27, handler3);
5912
+ registerTool(server, schema28, metadata28, handler4);
5913
+ registerTool(server, schema29, metadata29, handler5);
5914
+ registerPrompt(server, schema30, metadata30, sdkUsageGuide);
5915
+ registerPrompt(server, schema31, metadata31, collectionQueryHelp);
5916
+ registerPrompt(server, schema32, metadata32, orderFlowGuide);
5917
+ registerPrompt(server, schema33, metadata33, featureSetupGuide);
5918
+ registerStaticResource(server, "config://app", metadata34, handler6);
5919
+ registerStaticResource(server, "collections://schema", metadata35, handler7);
5920
+ registerStaticResource(server, "docs://sdk/getting-started", metadata36, handler8);
5921
+ registerStaticResource(server, "docs://sdk/guides", metadata37, handler9);
5922
+ registerStaticResource(server, "docs://sdk/api", metadata38, handler10);
5923
+ registerStaticResource(server, "docs://sdk/query-builder", metadata39, handler11);
5924
+ registerStaticResource(server, "docs://sdk/react-query", metadata40, handler12);
5925
+ registerStaticResource(server, "docs://sdk/server-api", metadata41, handler13);
5926
+ registerStaticResource(server, "docs://sdk/customer-auth", metadata42, handler14);
5927
+ registerStaticResource(server, "docs://sdk/browser-vs-server", metadata43, handler15);
5928
+ registerStaticResource(server, "docs://sdk/file-upload", metadata44, handler16);
5929
+ registerStaticResource(server, "docs://sdk/webhook", metadata45, handler17);
5435
5930
  return server;
5436
5931
  }
5437
5932
 
5438
5933
  export {
5934
+ MCP_RESOURCE_AUDIENCE,
5935
+ MCP_OAUTH_ISSUER,
5936
+ MCP_PROTECTED_RESOURCE_METADATA_PATH,
5937
+ MCP_TENANT_CLAIM,
5938
+ MCP_TENANT_ROLE_CLAIM,
5939
+ MCP_SCOPES,
5439
5940
  requestContext,
5440
5941
  mcpServicePublicJwks,
5942
+ createMcpTelemetrySummary,
5943
+ runWithMcpTelemetry,
5944
+ flushMcpTelemetrySummary,
5441
5945
  createServer
5442
5946
  };
5443
- //# sourceMappingURL=chunk-45ZCPS57.js.map
5947
+ //# sourceMappingURL=chunk-CADO6WG6.js.map