@01.software/cli 0.9.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.
- package/dist/index.js +205 -28
- package/dist/index.js.map +1 -1
- package/dist/mcp/{chunk-GJOQ4SE2.js → chunk-CADO6WG6.js} +657 -391
- package/dist/mcp/chunk-CADO6WG6.js.map +1 -0
- package/dist/mcp/http.js +30 -8
- package/dist/mcp/http.js.map +1 -1
- package/dist/mcp/stdio.js +1 -1
- package/dist/mcp/vercel.js +678 -396
- package/package.json +2 -2
- package/dist/mcp/chunk-GJOQ4SE2.js.map +0 -1
|
@@ -88,6 +88,285 @@ var MCP_CONSOLE_SERVICE_AUDIENCE = "https://api.01.software/internal/mcp";
|
|
|
88
88
|
var MCP_CONSOLE_SERVICE_SCOPE = "console:mcp_proxy";
|
|
89
89
|
var MCP_SERVICE_TOKEN_LIFETIME_SECONDS = 60;
|
|
90
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
|
+
|
|
91
370
|
// src/tool-policy.ts
|
|
92
371
|
var READ_ONLY_ANNOTATION = {
|
|
93
372
|
readOnly: true,
|
|
@@ -344,14 +623,14 @@ var TOOL_POLICY_MANIFEST = {
|
|
|
344
623
|
}
|
|
345
624
|
};
|
|
346
625
|
function evaluateToolPolicy(toolName, scopes) {
|
|
347
|
-
|
|
348
|
-
if (!entry) {
|
|
626
|
+
if (!isMcpToolName(toolName)) {
|
|
349
627
|
return {
|
|
350
628
|
allowed: false,
|
|
351
629
|
reason: "tool_policy_missing",
|
|
352
630
|
message: `No tool-policy entry for ${toolName}`
|
|
353
631
|
};
|
|
354
632
|
}
|
|
633
|
+
const entry = TOOL_POLICY_MANIFEST[toolName];
|
|
355
634
|
if (!scopes.includes(entry.oauthScope)) {
|
|
356
635
|
return {
|
|
357
636
|
allowed: false,
|
|
@@ -362,17 +641,12 @@ function evaluateToolPolicy(toolName, scopes) {
|
|
|
362
641
|
return { allowed: true, entry };
|
|
363
642
|
}
|
|
364
643
|
|
|
365
|
-
// src/
|
|
366
|
-
import {
|
|
644
|
+
// src/lib/mcp-telemetry.ts
|
|
645
|
+
import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
|
|
646
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
367
647
|
|
|
368
|
-
// src/lib/
|
|
369
|
-
import {
|
|
370
|
-
CollectionClient,
|
|
371
|
-
CommunityClient,
|
|
372
|
-
ModerationApi,
|
|
373
|
-
ServerCommerceClient,
|
|
374
|
-
createServerClient
|
|
375
|
-
} from "@01.software/sdk";
|
|
648
|
+
// src/lib/console-api.ts
|
|
649
|
+
import { createHash } from "crypto";
|
|
376
650
|
|
|
377
651
|
// src/service-auth.ts
|
|
378
652
|
import { createPrivateKey, randomUUID, sign as signBytes } from "crypto";
|
|
@@ -501,43 +775,209 @@ function signMcpServiceToken(context) {
|
|
|
501
775
|
return `${signingInput}.${signature.toString("base64url")}`;
|
|
502
776
|
}
|
|
503
777
|
|
|
504
|
-
// src/lib/
|
|
778
|
+
// src/lib/console-api.ts
|
|
779
|
+
var BASE_URL = process.env.SOFTWARE_API_URL || "http://localhost:3000";
|
|
780
|
+
var TIMEOUT_MS = 5e3;
|
|
505
781
|
var MISSING_HTTP_AUTH_CONTEXT_ERROR = "MCP HTTP requests require a validated OAuth tenant context before tool execution.";
|
|
506
|
-
function
|
|
782
|
+
function resolveAuthHeaderContext() {
|
|
507
783
|
const oauthContext = tenantAuthContext();
|
|
508
784
|
if (oauthContext) {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
commerce: void 0,
|
|
513
|
-
collections: void 0,
|
|
514
|
-
community: void 0
|
|
515
|
-
};
|
|
516
|
-
const onRequestId = (id) => {
|
|
517
|
-
client.lastRequestId = id;
|
|
785
|
+
return {
|
|
786
|
+
apiKey: signMcpServiceToken(oauthContext),
|
|
787
|
+
mode: "oauth"
|
|
518
788
|
};
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
789
|
+
}
|
|
790
|
+
if (hasRequestContext()) throw new Error(MISSING_HTTP_AUTH_CONTEXT_ERROR);
|
|
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") {
|
|
800
|
+
throw new Error(
|
|
801
|
+
"Authentication required. Set SOFTWARE_SECRET_KEY for stdio transport."
|
|
529
802
|
);
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
803
|
+
}
|
|
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;
|
|
813
|
+
}
|
|
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);
|
|
822
|
+
}
|
|
823
|
+
if (typeof b.message === "string") return b.message;
|
|
824
|
+
return void 0;
|
|
825
|
+
}
|
|
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
|
|
537
834
|
});
|
|
538
|
-
|
|
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);
|
|
539
843
|
}
|
|
540
|
-
|
|
844
|
+
}
|
|
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);
|
|
864
|
+
}
|
|
865
|
+
}
|
|
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}`);
|
|
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);
|
|
541
981
|
const secretKey = process.env.SOFTWARE_SECRET_KEY;
|
|
542
982
|
const publishableKey = process.env.SOFTWARE_PUBLISHABLE_KEY || process.env.NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY;
|
|
543
983
|
if (!secretKey) {
|
|
@@ -560,15 +1000,18 @@ function getClient() {
|
|
|
560
1000
|
}
|
|
561
1001
|
|
|
562
1002
|
// src/tools/query-collection.ts
|
|
563
|
-
import {
|
|
1003
|
+
import { SERVER_COLLECTIONS } from "@01.software/sdk";
|
|
564
1004
|
var schema = {
|
|
565
|
-
collection:
|
|
566
|
-
where:
|
|
1005
|
+
collection: z3.enum(SERVER_COLLECTIONS).describe("Collection name (required)"),
|
|
1006
|
+
where: z3.string().optional().describe(
|
|
567
1007
|
`Filter conditions (JSON string, optional). Pass the Payload query condition object as a JSON string. Example: '{"title":{"equals":"Product name"}}'`
|
|
568
1008
|
),
|
|
569
|
-
limit:
|
|
570
|
-
page:
|
|
571
|
-
sort:
|
|
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(
|
|
572
1015
|
'Sort field (optional). Use "fieldName" for ascending or "-fieldName" for descending. Example: "createdAt" or "-createdAt"'
|
|
573
1016
|
)
|
|
574
1017
|
};
|
|
@@ -622,11 +1065,11 @@ async function queryCollection({
|
|
|
622
1065
|
}
|
|
623
1066
|
|
|
624
1067
|
// src/tools/get-collection-by-id.ts
|
|
625
|
-
import { z as
|
|
626
|
-
import {
|
|
1068
|
+
import { z as z4 } from "zod";
|
|
1069
|
+
import { SERVER_COLLECTIONS as SERVER_COLLECTIONS2 } from "@01.software/sdk";
|
|
627
1070
|
var schema2 = {
|
|
628
|
-
collection:
|
|
629
|
-
id:
|
|
1071
|
+
collection: z4.enum(SERVER_COLLECTIONS2).describe("Collection name (required)"),
|
|
1072
|
+
id: z4.string().min(1).describe("Item ID (required)")
|
|
630
1073
|
};
|
|
631
1074
|
var metadata2 = {
|
|
632
1075
|
name: "get-collection-by-id",
|
|
@@ -652,9 +1095,9 @@ async function getCollectionById({
|
|
|
652
1095
|
}
|
|
653
1096
|
|
|
654
1097
|
// src/tools/get-order.ts
|
|
655
|
-
import { z as
|
|
1098
|
+
import { z as z5 } from "zod";
|
|
656
1099
|
var schema3 = {
|
|
657
|
-
orderNumber:
|
|
1100
|
+
orderNumber: z5.string().min(1).describe("Order number to look up (required)")
|
|
658
1101
|
};
|
|
659
1102
|
var metadata3 = {
|
|
660
1103
|
name: "get-order",
|
|
@@ -684,24 +1127,24 @@ async function getOrder({
|
|
|
684
1127
|
}
|
|
685
1128
|
|
|
686
1129
|
// src/tools/create-order.ts
|
|
687
|
-
import { z as
|
|
1130
|
+
import { z as z6 } from "zod";
|
|
688
1131
|
var schema4 = {
|
|
689
|
-
pgPaymentId:
|
|
690
|
-
orderNumber:
|
|
691
|
-
customerSnapshot:
|
|
692
|
-
name:
|
|
693
|
-
email:
|
|
694
|
-
phone:
|
|
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")
|
|
695
1138
|
}).describe("Customer snapshot at time of order (required)"),
|
|
696
|
-
shippingAddress:
|
|
1139
|
+
shippingAddress: z6.record(z6.string(), z6.unknown()).describe(
|
|
697
1140
|
"Shipping address object (required). Fields: postalCode, address1, address2, deliveryMessage, recipientName, phone"
|
|
698
1141
|
),
|
|
699
|
-
orderItems:
|
|
1142
|
+
orderItems: z6.array(z6.record(z6.string(), z6.unknown())).describe(
|
|
700
1143
|
"Array of order item objects (required). Each: { product, variant, option, quantity, unitPrice?, totalPrice? }"
|
|
701
1144
|
),
|
|
702
|
-
totalAmount:
|
|
703
|
-
shippingAmount:
|
|
704
|
-
discountCode:
|
|
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)")
|
|
705
1148
|
};
|
|
706
1149
|
var metadata4 = {
|
|
707
1150
|
name: "create-order",
|
|
@@ -726,10 +1169,10 @@ async function createOrder(params) {
|
|
|
726
1169
|
}
|
|
727
1170
|
|
|
728
1171
|
// src/tools/update-order.ts
|
|
729
|
-
import { z as
|
|
1172
|
+
import { z as z7 } from "zod";
|
|
730
1173
|
var schema5 = {
|
|
731
|
-
orderNumber:
|
|
732
|
-
status:
|
|
1174
|
+
orderNumber: z7.string().min(1).describe("Order number (required)"),
|
|
1175
|
+
status: z7.enum([
|
|
733
1176
|
"pending",
|
|
734
1177
|
"paid",
|
|
735
1178
|
"failed",
|
|
@@ -766,15 +1209,15 @@ async function updateOrder({
|
|
|
766
1209
|
}
|
|
767
1210
|
|
|
768
1211
|
// src/tools/checkout.ts
|
|
769
|
-
import { z as
|
|
1212
|
+
import { z as z8 } from "zod";
|
|
770
1213
|
var schema6 = {
|
|
771
|
-
cartId:
|
|
772
|
-
pgPaymentId:
|
|
773
|
-
orderNumber:
|
|
774
|
-
customerSnapshot:
|
|
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(
|
|
775
1218
|
"Customer snapshot object (required). Fields: { name?, email, phone? }"
|
|
776
1219
|
),
|
|
777
|
-
discountCode:
|
|
1220
|
+
discountCode: z8.string().optional().describe("Discount code to apply (optional)")
|
|
778
1221
|
};
|
|
779
1222
|
var metadata6 = {
|
|
780
1223
|
name: "checkout",
|
|
@@ -799,17 +1242,17 @@ async function checkout(params) {
|
|
|
799
1242
|
}
|
|
800
1243
|
|
|
801
1244
|
// src/tools/create-fulfillment.ts
|
|
802
|
-
import { z as
|
|
1245
|
+
import { z as z9 } from "zod";
|
|
803
1246
|
var schema7 = {
|
|
804
|
-
orderNumber:
|
|
805
|
-
carrier:
|
|
806
|
-
trackingNumber:
|
|
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(
|
|
807
1250
|
'Tracking number (optional). Setting carrier + tracking triggers "shipped" status'
|
|
808
1251
|
),
|
|
809
|
-
items:
|
|
810
|
-
|
|
811
|
-
orderItem:
|
|
812
|
-
quantity:
|
|
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")
|
|
813
1256
|
})
|
|
814
1257
|
).describe("Array of items to fulfill (required)")
|
|
815
1258
|
};
|
|
@@ -844,16 +1287,16 @@ async function createFulfillment({
|
|
|
844
1287
|
}
|
|
845
1288
|
|
|
846
1289
|
// src/tools/update-fulfillment.ts
|
|
847
|
-
import { z as
|
|
1290
|
+
import { z as z10 } from "zod";
|
|
848
1291
|
var schema8 = {
|
|
849
|
-
fulfillmentId:
|
|
850
|
-
status:
|
|
1292
|
+
fulfillmentId: z10.string().min(1).describe("Fulfillment ID (required)"),
|
|
1293
|
+
status: z10.enum(["packed", "shipped", "delivered", "failed"]).describe(
|
|
851
1294
|
"New fulfillment status (required). FSM: pending\u2192packed/shipped/failed, packed\u2192shipped/failed, shipped\u2192delivered/failed"
|
|
852
1295
|
),
|
|
853
|
-
carrier:
|
|
1296
|
+
carrier: z10.string().optional().describe(
|
|
854
1297
|
"Shipping carrier (optional, changeable only in pending/packed status)"
|
|
855
1298
|
),
|
|
856
|
-
trackingNumber:
|
|
1299
|
+
trackingNumber: z10.string().optional().describe(
|
|
857
1300
|
"Tracking number (optional, changeable only in pending/packed status)"
|
|
858
1301
|
)
|
|
859
1302
|
};
|
|
@@ -887,131 +1330,6 @@ async function updateFulfillment({
|
|
|
887
1330
|
}
|
|
888
1331
|
}
|
|
889
1332
|
|
|
890
|
-
// ../../packages/contracts/src/tenant/index.ts
|
|
891
|
-
import { z as z9 } from "zod";
|
|
892
|
-
var tenantFieldConfigStateSchema = z9.object({
|
|
893
|
-
hiddenFields: z9.array(z9.string()),
|
|
894
|
-
isHidden: z9.boolean()
|
|
895
|
-
}).strict();
|
|
896
|
-
var tenantContextQuerySchema = z9.object({
|
|
897
|
-
counts: z9.literal("true").optional()
|
|
898
|
-
}).strict();
|
|
899
|
-
var tenantContextToolInputSchema = z9.object({
|
|
900
|
-
includeCounts: z9.boolean().optional().default(false).describe(
|
|
901
|
-
"Include per-collection document counts and config status (bypasses cache, slower)"
|
|
902
|
-
)
|
|
903
|
-
}).strict();
|
|
904
|
-
var tenantContextResponseSchema = z9.object({
|
|
905
|
-
tenant: z9.object({
|
|
906
|
-
id: z9.string(),
|
|
907
|
-
name: z9.string(),
|
|
908
|
-
plan: z9.string(),
|
|
909
|
-
planSource: z9.string().optional(),
|
|
910
|
-
authoritative: z9.boolean().optional(),
|
|
911
|
-
capabilityVersion: z9.string().optional(),
|
|
912
|
-
isDevMode: z9.boolean()
|
|
913
|
-
}).strict(),
|
|
914
|
-
features: z9.array(z9.string()),
|
|
915
|
-
collections: z9.object({
|
|
916
|
-
active: z9.array(z9.string()),
|
|
917
|
-
inactive: z9.array(z9.string())
|
|
918
|
-
}).strict(),
|
|
919
|
-
fieldConfigs: z9.record(z9.string(), tenantFieldConfigStateSchema),
|
|
920
|
-
counts: z9.record(z9.string(), z9.number()).optional(),
|
|
921
|
-
config: z9.object({
|
|
922
|
-
webhookConfigured: z9.boolean()
|
|
923
|
-
}).strict().optional()
|
|
924
|
-
}).strict();
|
|
925
|
-
var COLLECTION_SCHEMA_CONTRACT_VERSION = 1;
|
|
926
|
-
var collectionSchemaEndpointParamsSchema = z9.object({
|
|
927
|
-
collectionSlug: z9.string().min(1, "collectionSlug is required")
|
|
928
|
-
}).strict();
|
|
929
|
-
function createCollectionSchemaToolInputSchema(collections) {
|
|
930
|
-
return z9.object({
|
|
931
|
-
collection: z9.enum(collections).describe("Collection name (required)")
|
|
932
|
-
}).strict();
|
|
933
|
-
}
|
|
934
|
-
var collectionFieldOptionSchema = z9.object({
|
|
935
|
-
label: z9.string(),
|
|
936
|
-
value: z9.string()
|
|
937
|
-
}).strict();
|
|
938
|
-
var collectionFieldSchema = z9.lazy(
|
|
939
|
-
() => z9.object({
|
|
940
|
-
name: z9.string(),
|
|
941
|
-
path: z9.string(),
|
|
942
|
-
type: z9.string(),
|
|
943
|
-
required: z9.literal(true).optional(),
|
|
944
|
-
unique: z9.literal(true).optional(),
|
|
945
|
-
hasMany: z9.literal(true).optional(),
|
|
946
|
-
relationTo: z9.union([z9.string(), z9.array(z9.string())]).optional(),
|
|
947
|
-
options: z9.array(collectionFieldOptionSchema).optional(),
|
|
948
|
-
hidden: z9.literal(true).optional(),
|
|
949
|
-
systemManaged: z9.literal(true).optional(),
|
|
950
|
-
writable: z9.boolean().optional(),
|
|
951
|
-
fields: z9.array(collectionFieldSchema).optional()
|
|
952
|
-
}).strict()
|
|
953
|
-
);
|
|
954
|
-
var collectionSchemaResponseSchema = z9.object({
|
|
955
|
-
contractVersion: z9.literal(COLLECTION_SCHEMA_CONTRACT_VERSION),
|
|
956
|
-
mode: z9.literal("effective"),
|
|
957
|
-
collection: z9.object({
|
|
958
|
-
slug: z9.string(),
|
|
959
|
-
timestamps: z9.boolean(),
|
|
960
|
-
alwaysActive: z9.boolean(),
|
|
961
|
-
feature: z9.string().nullable(),
|
|
962
|
-
systemFields: z9.array(z9.string()),
|
|
963
|
-
visibility: z9.object({
|
|
964
|
-
collectionHidden: z9.boolean(),
|
|
965
|
-
hiddenFields: z9.array(z9.string())
|
|
966
|
-
}).strict(),
|
|
967
|
-
fields: z9.array(collectionFieldSchema)
|
|
968
|
-
}).strict()
|
|
969
|
-
}).strict();
|
|
970
|
-
|
|
971
|
-
// ../../packages/contracts/src/ecommerce/index.ts
|
|
972
|
-
import { z as z10 } from "zod";
|
|
973
|
-
var transactionStatusSchema = z10.enum([
|
|
974
|
-
"pending",
|
|
975
|
-
"paid",
|
|
976
|
-
"failed",
|
|
977
|
-
"canceled"
|
|
978
|
-
]);
|
|
979
|
-
var updateTransactionSchema = z10.object({
|
|
980
|
-
pgPaymentId: z10.string().min(1, "pgPaymentId is required").describe("PG payment ID (required)"),
|
|
981
|
-
status: transactionStatusSchema.describe(
|
|
982
|
-
"New transaction status (required)"
|
|
983
|
-
),
|
|
984
|
-
paymentMethod: z10.string().optional().describe("Payment method (optional)"),
|
|
985
|
-
receiptUrl: z10.string().optional().describe("Receipt URL (optional)"),
|
|
986
|
-
paymentKey: z10.string().min(1).optional().describe("Provider payment key for verified paid confirmation"),
|
|
987
|
-
amount: z10.number().int().positive().optional().describe("Provider-confirmed amount for verified paid confirmation")
|
|
988
|
-
}).strict();
|
|
989
|
-
var UpdateTransactionSchema = updateTransactionSchema;
|
|
990
|
-
var returnReasonSchema = z10.enum([
|
|
991
|
-
"change_of_mind",
|
|
992
|
-
"defective",
|
|
993
|
-
"wrong_delivery",
|
|
994
|
-
"damaged",
|
|
995
|
-
"other"
|
|
996
|
-
]);
|
|
997
|
-
var restockActionSchema = z10.enum(["return_to_stock", "discard"]);
|
|
998
|
-
var returnWithRefundItemSchema = z10.object({
|
|
999
|
-
orderItem: z10.union([z10.string(), z10.number()]).transform(String),
|
|
1000
|
-
quantity: z10.number().int().positive("quantity must be a positive integer"),
|
|
1001
|
-
restockAction: restockActionSchema.default("return_to_stock")
|
|
1002
|
-
}).strict();
|
|
1003
|
-
var returnWithRefundSchema = z10.object({
|
|
1004
|
-
orderNumber: z10.string().min(1, "orderNumber is required").describe("Order number (required)"),
|
|
1005
|
-
reason: returnReasonSchema.optional().describe("Return reason (optional)"),
|
|
1006
|
-
reasonDetail: z10.string().optional().describe("Detailed reason text (optional)"),
|
|
1007
|
-
returnItems: z10.array(returnWithRefundItemSchema).min(1, "At least one return item is required").max(100, "Too many return items").describe("Array of products to return (required)"),
|
|
1008
|
-
refundAmount: z10.number().min(0, "refundAmount must be non-negative").describe("Refund amount (required, min 0)"),
|
|
1009
|
-
pgPaymentId: z10.string().min(1, "pgPaymentId is required").describe("PG payment ID for refund (required)"),
|
|
1010
|
-
paymentKey: z10.string().min(1).optional().describe("Provider payment key for verified refund"),
|
|
1011
|
-
refundReceiptUrl: z10.string().optional().describe("Refund receipt URL (optional)")
|
|
1012
|
-
}).strict();
|
|
1013
|
-
var ReturnWithRefundSchema = returnWithRefundSchema;
|
|
1014
|
-
|
|
1015
1333
|
// src/tools/update-transaction.ts
|
|
1016
1334
|
var schema9 = UpdateTransactionSchema.shape;
|
|
1017
1335
|
var metadata9 = {
|
|
@@ -1449,97 +1767,7 @@ async function stockCheck({
|
|
|
1449
1767
|
}
|
|
1450
1768
|
|
|
1451
1769
|
// src/tools/get-collection-schema.ts
|
|
1452
|
-
import {
|
|
1453
|
-
|
|
1454
|
-
// src/lib/console-api.ts
|
|
1455
|
-
import { createHash } from "crypto";
|
|
1456
|
-
var BASE_URL = process.env.SOFTWARE_API_URL || "http://localhost:3000";
|
|
1457
|
-
var TIMEOUT_MS = 5e3;
|
|
1458
|
-
var MISSING_HTTP_AUTH_CONTEXT_ERROR2 = "MCP HTTP requests require a validated OAuth tenant context before tool execution.";
|
|
1459
|
-
function resolveAuthHeaderContext() {
|
|
1460
|
-
const oauthContext = tenantAuthContext();
|
|
1461
|
-
if (oauthContext) {
|
|
1462
|
-
return {
|
|
1463
|
-
apiKey: signMcpServiceToken(oauthContext),
|
|
1464
|
-
mode: "oauth"
|
|
1465
|
-
};
|
|
1466
|
-
}
|
|
1467
|
-
if (hasRequestContext()) throw new Error(MISSING_HTTP_AUTH_CONTEXT_ERROR2);
|
|
1468
|
-
return {
|
|
1469
|
-
apiKey: process.env.SOFTWARE_SECRET_KEY,
|
|
1470
|
-
mode: "stdio",
|
|
1471
|
-
publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY ?? process.env.NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY
|
|
1472
|
-
};
|
|
1473
|
-
}
|
|
1474
|
-
function resolveApiKey() {
|
|
1475
|
-
const { apiKey } = resolveAuthHeaderContext();
|
|
1476
|
-
if (!apiKey || typeof apiKey !== "string") {
|
|
1477
|
-
throw new Error(
|
|
1478
|
-
"Authentication required. Set SOFTWARE_SECRET_KEY for stdio transport."
|
|
1479
|
-
);
|
|
1480
|
-
}
|
|
1481
|
-
return apiKey;
|
|
1482
|
-
}
|
|
1483
|
-
function buildAuthHeaders(apiKey) {
|
|
1484
|
-
const { mode, publishableKey } = resolveAuthHeaderContext();
|
|
1485
|
-
const headers = {
|
|
1486
|
-
Authorization: `Bearer ${apiKey}`
|
|
1487
|
-
};
|
|
1488
|
-
if (mode === "stdio" && publishableKey) {
|
|
1489
|
-
headers["X-Publishable-Key"] = publishableKey;
|
|
1490
|
-
}
|
|
1491
|
-
return headers;
|
|
1492
|
-
}
|
|
1493
|
-
function extractErrorMessage(body) {
|
|
1494
|
-
if (!body || typeof body !== "object") return void 0;
|
|
1495
|
-
const b = body;
|
|
1496
|
-
if (typeof b.error === "string") return b.error;
|
|
1497
|
-
if (Array.isArray(b.errors) && b.errors[0]?.message) {
|
|
1498
|
-
return String(b.errors[0].message);
|
|
1499
|
-
}
|
|
1500
|
-
if (typeof b.message === "string") return b.message;
|
|
1501
|
-
return void 0;
|
|
1502
|
-
}
|
|
1503
|
-
async function consoleGet(path, apiKey) {
|
|
1504
|
-
const authHeaders = buildAuthHeaders(apiKey);
|
|
1505
|
-
const controller = new AbortController();
|
|
1506
|
-
const timeoutId = setTimeout(() => controller.abort(), TIMEOUT_MS);
|
|
1507
|
-
try {
|
|
1508
|
-
const res = await fetch(`${BASE_URL}${path}`, {
|
|
1509
|
-
headers: authHeaders,
|
|
1510
|
-
signal: controller.signal
|
|
1511
|
-
});
|
|
1512
|
-
if (!res.ok) {
|
|
1513
|
-
const body = await res.json().catch(() => ({}));
|
|
1514
|
-
const msg = extractErrorMessage(body);
|
|
1515
|
-
throw new Error(msg || `Console GET ${path} failed: ${res.status}`);
|
|
1516
|
-
}
|
|
1517
|
-
return res.json();
|
|
1518
|
-
} finally {
|
|
1519
|
-
clearTimeout(timeoutId);
|
|
1520
|
-
}
|
|
1521
|
-
}
|
|
1522
|
-
async function consolePost(path, body, apiKey) {
|
|
1523
|
-
const authHeaders = buildAuthHeaders(apiKey);
|
|
1524
|
-
const controller = new AbortController();
|
|
1525
|
-
const timeoutId = setTimeout(() => controller.abort(), TIMEOUT_MS);
|
|
1526
|
-
try {
|
|
1527
|
-
const res = await fetch(`${BASE_URL}${path}`, {
|
|
1528
|
-
method: "POST",
|
|
1529
|
-
headers: { ...authHeaders, "Content-Type": "application/json" },
|
|
1530
|
-
body: JSON.stringify(body),
|
|
1531
|
-
signal: controller.signal
|
|
1532
|
-
});
|
|
1533
|
-
if (!res.ok) {
|
|
1534
|
-
const errBody = await res.json().catch(() => ({}));
|
|
1535
|
-
const msg = extractErrorMessage(errBody);
|
|
1536
|
-
throw new Error(msg || `Console POST ${path} failed: ${res.status}`);
|
|
1537
|
-
}
|
|
1538
|
-
return res.json();
|
|
1539
|
-
} finally {
|
|
1540
|
-
clearTimeout(timeoutId);
|
|
1541
|
-
}
|
|
1542
|
-
}
|
|
1770
|
+
import { SERVER_COLLECTIONS as SERVER_COLLECTIONS3 } from "@01.software/sdk";
|
|
1543
1771
|
|
|
1544
1772
|
// src/lib/collection-schema.ts
|
|
1545
1773
|
async function getCollectionSchema(collection) {
|
|
@@ -1552,7 +1780,7 @@ async function getCollectionSchema(collection) {
|
|
|
1552
1780
|
}
|
|
1553
1781
|
|
|
1554
1782
|
// src/tools/get-collection-schema.ts
|
|
1555
|
-
var schema22 = createCollectionSchemaToolInputSchema(
|
|
1783
|
+
var schema22 = createCollectionSchemaToolInputSchema(SERVER_COLLECTIONS3).shape;
|
|
1556
1784
|
var metadata22 = {
|
|
1557
1785
|
name: "get-collection-schema",
|
|
1558
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.",
|
|
@@ -2272,7 +2500,7 @@ var docIndex = [
|
|
|
2272
2500
|
{
|
|
2273
2501
|
title: "Browser Client vs Server Client",
|
|
2274
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"],
|
|
2275
|
-
summary: "createClient() for browser with publishableKey (read-only pk01_), createServerClient() for server with SOFTWARE_SECRET_KEY (usually sk01_, sometimes pat01_ in
|
|
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.",
|
|
2276
2504
|
resourceUri: "docs://sdk/getting-started"
|
|
2277
2505
|
},
|
|
2278
2506
|
// Query Builder
|
|
@@ -2638,9 +2866,9 @@ function handler4({
|
|
|
2638
2866
|
|
|
2639
2867
|
// src/tools/sdk-get-collection-pattern.ts
|
|
2640
2868
|
import { z as z27 } from "zod";
|
|
2641
|
-
import { COLLECTIONS as
|
|
2869
|
+
import { COLLECTIONS, SERVER_COLLECTIONS as SERVER_COLLECTIONS4 } from "@01.software/sdk";
|
|
2642
2870
|
var schema29 = {
|
|
2643
|
-
collection: z27.enum(
|
|
2871
|
+
collection: z27.enum(SERVER_COLLECTIONS4).describe("Collection name"),
|
|
2644
2872
|
operation: z27.enum(["read", "write", "full-crud"]).default("read").describe("What operations are needed"),
|
|
2645
2873
|
surface: z27.enum(["query-builder", "react-query", "server-api"]).default("query-builder").describe("Preferred API surface")
|
|
2646
2874
|
};
|
|
@@ -2655,7 +2883,15 @@ var metadata29 = {
|
|
|
2655
2883
|
}
|
|
2656
2884
|
};
|
|
2657
2885
|
function generatePattern(collection, operation, surface) {
|
|
2886
|
+
const isPublicCollection = COLLECTIONS.includes(
|
|
2887
|
+
collection
|
|
2888
|
+
);
|
|
2658
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
|
+
}
|
|
2659
2895
|
const parts2 = [];
|
|
2660
2896
|
if (operation === "read") {
|
|
2661
2897
|
parts2.push(
|
|
@@ -2767,17 +3003,29 @@ function generatePattern(collection, operation, surface) {
|
|
|
2767
3003
|
}
|
|
2768
3004
|
const parts = [];
|
|
2769
3005
|
if (operation === "read" || operation === "full-crud") {
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
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
|
+
}
|
|
2781
3029
|
}
|
|
2782
3030
|
if (operation === "write" || operation === "full-crud") {
|
|
2783
3031
|
parts.push(
|
|
@@ -2792,6 +3040,7 @@ function generatePattern(collection, operation, surface) {
|
|
|
2792
3040
|
code: parts.join("\n"),
|
|
2793
3041
|
notes: [
|
|
2794
3042
|
"Query Builder works with both Client and ServerClient for reads",
|
|
3043
|
+
!isPublicCollection ? "This collection is server-only" : "",
|
|
2795
3044
|
operation !== "read" ? "Write operations require ServerClient" : ""
|
|
2796
3045
|
].filter(Boolean)
|
|
2797
3046
|
};
|
|
@@ -2969,9 +3218,9 @@ You can perform the "${goal}" task by following the patterns above.`;
|
|
|
2969
3218
|
|
|
2970
3219
|
// src/prompts/collection-query-help.ts
|
|
2971
3220
|
import { z as z29 } from "zod";
|
|
2972
|
-
import { COLLECTIONS as
|
|
3221
|
+
import { COLLECTIONS as COLLECTIONS2, SERVER_COLLECTIONS as SERVER_COLLECTIONS5 } from "@01.software/sdk";
|
|
2973
3222
|
var schema31 = {
|
|
2974
|
-
collection: z29.enum(
|
|
3223
|
+
collection: z29.enum(SERVER_COLLECTIONS5).describe("Collection name"),
|
|
2975
3224
|
operation: z29.enum(["find", "create", "update", "delete"]).describe("Operation to perform (find, create, update, delete)"),
|
|
2976
3225
|
filters: z29.string().optional().describe("Filter conditions (JSON string, optional)")
|
|
2977
3226
|
};
|
|
@@ -2992,6 +3241,11 @@ Filter conditions:
|
|
|
2992
3241
|
\`\`\`json
|
|
2993
3242
|
${filters}
|
|
2994
3243
|
\`\`\`` : "";
|
|
3244
|
+
const isPublicCollection = COLLECTIONS2.includes(
|
|
3245
|
+
collection
|
|
3246
|
+
);
|
|
3247
|
+
const readClientName = isPublicCollection ? "client" : "serverClient";
|
|
3248
|
+
const readClientNote = isPublicCollection ? "Client or ServerClient" : "ServerClient only";
|
|
2995
3249
|
return `How to perform "${operation}" operation on "${collection}" collection:${filterExample}
|
|
2996
3250
|
|
|
2997
3251
|
## Collection: ${collection}
|
|
@@ -3002,26 +3256,26 @@ ${filters}
|
|
|
3002
3256
|
\`\`\`typescript
|
|
3003
3257
|
import { createClient, createServerClient } from '@01.software/sdk'
|
|
3004
3258
|
|
|
3005
|
-
// Client (read-only)
|
|
3259
|
+
// Client (read-only public collections)
|
|
3006
3260
|
const client = createClient({
|
|
3007
3261
|
publishableKey: process.env.NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY!
|
|
3008
3262
|
})
|
|
3009
3263
|
|
|
3010
|
-
// Server client (full CRUD)
|
|
3264
|
+
// Server client (server/public collections, full CRUD)
|
|
3011
3265
|
const serverClient = createServerClient({
|
|
3012
3266
|
publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,
|
|
3013
3267
|
secretKey: process.env.SOFTWARE_SECRET_KEY!
|
|
3014
3268
|
})
|
|
3015
3269
|
|
|
3016
|
-
${operation === "find" ? `// Query ${collection} collection with Query Builder
|
|
3270
|
+
${operation === "find" ? `// Query ${collection} collection with Query Builder (${readClientNote})
|
|
3017
3271
|
// find() returns PayloadFindResponse with docs array and pagination
|
|
3018
|
-
const result = await
|
|
3272
|
+
const result = await ${readClientName}.collections.from('${collection}').find(${filters ? `{
|
|
3019
3273
|
where: ${filters}
|
|
3020
3274
|
}` : ""})
|
|
3021
3275
|
// result.docs - array of items
|
|
3022
3276
|
// result.totalDocs, result.page, result.totalPages, result.hasNextPage, ...
|
|
3023
3277
|
|
|
3024
|
-
|
|
3278
|
+
${isPublicCollection ? `// Using React Hook
|
|
3025
3279
|
const { data, isLoading, error } = client.query.useQuery({
|
|
3026
3280
|
collection: '${collection}',
|
|
3027
3281
|
options: { limit: 10 }
|
|
@@ -3031,19 +3285,19 @@ const { data, isLoading, error } = client.query.useQuery({
|
|
|
3031
3285
|
const { data } = client.query.useSuspenseQuery({
|
|
3032
3286
|
collection: '${collection}',
|
|
3033
3287
|
options: { limit: 10 }
|
|
3034
|
-
})` : 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)
|
|
3035
3289
|
// create() returns PayloadMutationResponse with doc and message
|
|
3036
|
-
const result = await serverClient.from('${collection}').create({
|
|
3290
|
+
const result = await serverClient.collections.from('${collection}').create({
|
|
3037
3291
|
// Enter fields
|
|
3038
3292
|
})
|
|
3039
3293
|
// result.doc - created item, result.message` : operation === "update" ? `// Update ${collection} item (ServerClient only)
|
|
3040
3294
|
// update() returns PayloadMutationResponse with doc and message
|
|
3041
|
-
const result = await serverClient.from('${collection}').update(id, {
|
|
3295
|
+
const result = await serverClient.collections.from('${collection}').update(id, {
|
|
3042
3296
|
// Fields to update
|
|
3043
3297
|
})
|
|
3044
3298
|
// result.doc - updated item, result.message` : `// Delete ${collection} item (ServerClient only)
|
|
3045
3299
|
// remove() returns the deleted document directly
|
|
3046
|
-
await serverClient.from('${collection}').remove(id)`}
|
|
3300
|
+
await serverClient.collections.from('${collection}').remove(id)`}
|
|
3047
3301
|
\`\`\`
|
|
3048
3302
|
|
|
3049
3303
|
### Useful Tips
|
|
@@ -3051,7 +3305,7 @@ await serverClient.from('${collection}').remove(id)`}
|
|
|
3051
3305
|
${operation === "find" ? `- Use \`where\` option for filtering (Payload query syntax)
|
|
3052
3306
|
- Use \`limit\` and \`page\` for pagination
|
|
3053
3307
|
- Use \`sort\` for sorting (prefix with "-" for descending)
|
|
3054
|
-
- 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"}
|
|
3055
3309
|
- Cache utilities: invalidateQueries, prefetchQuery, getQueryData, setQueryData` : operation === "create" ? `- Requires ServerClient with secretKey
|
|
3056
3310
|
- Check required fields
|
|
3057
3311
|
- TypeScript recommended for type safety` : operation === "update" ? `- Requires ServerClient with secretKey
|
|
@@ -3287,7 +3541,7 @@ var FEATURES = {
|
|
|
3287
3541
|
### Required Collections (count > 0)
|
|
3288
3542
|
|
|
3289
3543
|
1. **products** \u2014 Create via Console UI or SDK \`client.collections.from('products').create({ ... })\`
|
|
3290
|
-
- Minimum fields: \`{ title, slug, status: 'published'
|
|
3544
|
+
- Minimum fields: \`{ title, slug, status: 'published' }\`
|
|
3291
3545
|
|
|
3292
3546
|
2. **product-variants** \u2014 At least 1 sellable variant per product
|
|
3293
3547
|
- Minimum fields: \`{ product, title, price, stock }\`
|
|
@@ -3320,7 +3574,8 @@ customer-addresses
|
|
|
3320
3574
|
|
|
3321
3575
|
### Optional Collections
|
|
3322
3576
|
|
|
3323
|
-
customer-groups \u2014
|
|
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')\`.
|
|
3324
3579
|
|
|
3325
3580
|
### Config
|
|
3326
3581
|
|
|
@@ -3331,10 +3586,10 @@ customer-groups \u2014 Create via Console UI or SDK \`client.collections.from('c
|
|
|
3331
3586
|
### Required Collections (count > 0)
|
|
3332
3587
|
|
|
3333
3588
|
1. **articles** \u2014 At least 1 article
|
|
3334
|
-
- Minimum fields: \`{ title, slug }\`
|
|
3589
|
+
- Minimum fields: \`{ title, slug, status: 'published' }\`
|
|
3335
3590
|
|
|
3336
3591
|
2. **article-authors** \u2014 At least 1 author
|
|
3337
|
-
- Minimum fields: \`{ title, slug }\`
|
|
3592
|
+
- Minimum fields: \`{ title, slug, status: 'published' }\`
|
|
3338
3593
|
- Link authors to articles via the \`authors\` relationship field
|
|
3339
3594
|
|
|
3340
3595
|
### Optional Collections
|
|
@@ -3349,7 +3604,7 @@ article-categories, article-tags`,
|
|
|
3349
3604
|
|
|
3350
3605
|
2. **document-types** \u2014 At least 1 type
|
|
3351
3606
|
- Minimum fields: \`{ title, slug }\`
|
|
3352
|
-
- Link document type via \`
|
|
3607
|
+
- Link document type via \`type\` relationship field
|
|
3353
3608
|
|
|
3354
3609
|
### Optional Collections
|
|
3355
3610
|
|
|
@@ -3359,10 +3614,10 @@ document-categories`,
|
|
|
3359
3614
|
### Required Collections (count > 0)
|
|
3360
3615
|
|
|
3361
3616
|
1. **playlists** \u2014 At least 1 playlist
|
|
3362
|
-
- Minimum fields: \`{ title, slug, status: 'published'
|
|
3617
|
+
- Minimum fields: \`{ title, slug, status: 'published' }\`
|
|
3363
3618
|
|
|
3364
3619
|
2. **tracks** \u2014 At least 1 track
|
|
3365
|
-
- Minimum fields: \`{ title, sourceUrl, status: 'published'
|
|
3620
|
+
- Minimum fields: \`{ title, sourceUrl, status: 'published' }\`
|
|
3366
3621
|
|
|
3367
3622
|
3. **playlists.tracks** \u2014 Link at least 1 track from a playlist
|
|
3368
3623
|
- Minimum fields: \`{ tracks: [trackId] }\`
|
|
@@ -3375,11 +3630,11 @@ playlist-categories, playlist-tags, track-categories, track-tags, track-assets`,
|
|
|
3375
3630
|
### Required Collections (count > 0)
|
|
3376
3631
|
|
|
3377
3632
|
1. **galleries** \u2014 At least 1 gallery
|
|
3378
|
-
- Minimum fields: \`{ title, slug, status: 'published'
|
|
3633
|
+
- Minimum fields: \`{ title, slug, status: 'published' }\`
|
|
3379
3634
|
|
|
3380
3635
|
2. **gallery-items** \u2014 At least 1 item per gallery
|
|
3381
3636
|
- References \`images\` collection (non-upload)
|
|
3382
|
-
- Minimum fields: \`{ gallery, image,
|
|
3637
|
+
- Minimum fields: \`{ gallery, image, status: 'published' }\`
|
|
3383
3638
|
|
|
3384
3639
|
### Optional Collections
|
|
3385
3640
|
|
|
@@ -3389,7 +3644,7 @@ gallery-categories, gallery-tags`,
|
|
|
3389
3644
|
### Required Collections (count > 0)
|
|
3390
3645
|
|
|
3391
3646
|
1. **links** \u2014 At least 1 link
|
|
3392
|
-
- Minimum fields: \`{ title, slug, url, status: 'published'
|
|
3647
|
+
- Minimum fields: \`{ title, slug, url, status: 'published' }\`
|
|
3393
3648
|
|
|
3394
3649
|
### Optional Collections
|
|
3395
3650
|
|
|
@@ -3461,9 +3716,11 @@ comments, reactions, bookmarks, reports, community-bans
|
|
|
3461
3716
|
|
|
3462
3717
|
### Optional Collections
|
|
3463
3718
|
|
|
3464
|
-
post-categories`
|
|
3719
|
+
post-categories, customer-profile-lists`
|
|
3465
3720
|
};
|
|
3466
|
-
function featureSetupGuide({
|
|
3721
|
+
function featureSetupGuide({
|
|
3722
|
+
feature
|
|
3723
|
+
}) {
|
|
3467
3724
|
return `# Feature Setup Guide: ${feature}
|
|
3468
3725
|
|
|
3469
3726
|
${FEATURES[feature] || "Unknown feature."}
|
|
@@ -3486,7 +3743,8 @@ function handler6() {
|
|
|
3486
3743
|
## Server Info
|
|
3487
3744
|
- **Name**: 01.software MCP Server
|
|
3488
3745
|
- **Version**: 0.1.0
|
|
3489
|
-
- **
|
|
3746
|
+
- **Hosted transport**: HTTP (Streamable)
|
|
3747
|
+
- **Local transport**: stdio through \`npx @01.software/cli mcp\`
|
|
3490
3748
|
|
|
3491
3749
|
## Authentication
|
|
3492
3750
|
|
|
@@ -3497,42 +3755,9 @@ HTTP MCP uses OAuth discovery and Authorization Code + PKCE.
|
|
|
3497
3755
|
url = "https://mcp.01.software/mcp"
|
|
3498
3756
|
\`\`\`
|
|
3499
3757
|
|
|
3500
|
-
##
|
|
3501
|
-
|
|
3502
|
-
> Generic write tools (create/update/delete/update-many/delete-many) are intentionally absent. Use the dedicated workflow tools below or the SDK (\`client.collections.from(slug).create()\` / \`update()\` / \`remove()\` / \`updateMany()\` / \`removeMany()\`) for stateful mutations.
|
|
3503
|
-
|
|
3504
|
-
### Generic Read (2)
|
|
3505
|
-
- \`query-collection\` - Query collection with filters, pagination, sorting
|
|
3506
|
-
- \`get-collection-by-id\` - Get single item by ID
|
|
3507
|
-
|
|
3508
|
-
### Orders (7)
|
|
3509
|
-
- \`create-order\` - Create a new order with products and shipping
|
|
3510
|
-
- \`get-order\` - Get order details by order number
|
|
3511
|
-
- \`update-order\` - Update order status
|
|
3512
|
-
- \`checkout\` - Convert cart to order
|
|
3513
|
-
- \`create-fulfillment\` - Create fulfillment for order items
|
|
3514
|
-
- \`update-fulfillment\` - Update fulfillment status, carrier, and tracking
|
|
3515
|
-
- \`update-transaction\` - Update transaction status
|
|
3516
|
-
|
|
3517
|
-
### Returns (3)
|
|
3518
|
-
- \`create-return\` - Create a return request
|
|
3519
|
-
- \`update-return\` - Update return status
|
|
3520
|
-
- \`return-with-refund\` - Process return with refund atomically
|
|
3521
|
-
|
|
3522
|
-
### Cart (6)
|
|
3523
|
-
- \`add-cart-item\` - Add item to cart
|
|
3524
|
-
- \`update-cart-item\` - Update cart item quantity
|
|
3525
|
-
- \`remove-cart-item\` - Remove item from cart
|
|
3526
|
-
- \`apply-discount\` - Apply discount code to cart
|
|
3527
|
-
- \`remove-discount\` - Remove discount from cart
|
|
3528
|
-
- \`clear-cart\` - Remove all items from cart
|
|
3758
|
+
## Hosted HTTP OAuth Tools (8)
|
|
3529
3759
|
|
|
3530
|
-
|
|
3531
|
-
- \`validate-discount\` - Validate discount code
|
|
3532
|
-
- \`calculate-shipping\` - Calculate shipping fee
|
|
3533
|
-
|
|
3534
|
-
### Product (1)
|
|
3535
|
-
- \`stock-check\` - Check product option stock availability
|
|
3760
|
+
The hosted HTTP MCP endpoint at https://mcp.01.software/mcp exposes only these OAuth-safe tools:
|
|
3536
3761
|
|
|
3537
3762
|
### Schema (1)
|
|
3538
3763
|
- \`get-collection-schema\` - Get authoritative tenant-aware collection schema
|
|
@@ -3550,6 +3775,16 @@ url = "https://mcp.01.software/mcp"
|
|
|
3550
3775
|
- \`sdk-get-auth-setup\` - Get framework-specific auth setup guidance
|
|
3551
3776
|
- \`sdk-get-collection-pattern\` - Get collection-specific usage patterns
|
|
3552
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
|
+
|
|
3553
3788
|
## Rate Limits
|
|
3554
3789
|
|
|
3555
3790
|
Rate limits depend on your tenant plan:
|
|
@@ -3561,7 +3796,7 @@ Rate limits depend on your tenant plan:
|
|
|
3561
3796
|
}
|
|
3562
3797
|
|
|
3563
3798
|
// src/resources/(collections)/schema.ts
|
|
3564
|
-
import { COLLECTIONS as
|
|
3799
|
+
import { COLLECTIONS as COLLECTIONS3 } from "@01.software/sdk";
|
|
3565
3800
|
var metadata35 = {
|
|
3566
3801
|
name: "collections-schema",
|
|
3567
3802
|
title: "Collection Schema Info",
|
|
@@ -3590,13 +3825,18 @@ var COLLECTIONS_BY_CATEGORY = {
|
|
|
3590
3825
|
Customers: [
|
|
3591
3826
|
"customers",
|
|
3592
3827
|
"customer-profiles",
|
|
3593
|
-
"customer-
|
|
3594
|
-
"customer-
|
|
3828
|
+
"customer-profile-lists",
|
|
3829
|
+
"customer-addresses"
|
|
3595
3830
|
],
|
|
3596
3831
|
Carts: ["carts", "cart-items"],
|
|
3597
3832
|
"Discounts & Promotions": ["discounts", "promotions"],
|
|
3598
3833
|
Documents: ["documents", "document-categories", "document-types"],
|
|
3599
|
-
Articles: [
|
|
3834
|
+
Articles: [
|
|
3835
|
+
"articles",
|
|
3836
|
+
"article-authors",
|
|
3837
|
+
"article-categories",
|
|
3838
|
+
"article-tags"
|
|
3839
|
+
],
|
|
3600
3840
|
Community: [
|
|
3601
3841
|
"posts",
|
|
3602
3842
|
"comments",
|
|
@@ -3615,7 +3855,12 @@ var COLLECTIONS_BY_CATEGORY = {
|
|
|
3615
3855
|
"track-categories",
|
|
3616
3856
|
"track-tags"
|
|
3617
3857
|
],
|
|
3618
|
-
Galleries: [
|
|
3858
|
+
Galleries: [
|
|
3859
|
+
"galleries",
|
|
3860
|
+
"gallery-items",
|
|
3861
|
+
"gallery-categories",
|
|
3862
|
+
"gallery-tags"
|
|
3863
|
+
],
|
|
3619
3864
|
Links: ["links", "link-categories", "link-tags"],
|
|
3620
3865
|
Canvas: [
|
|
3621
3866
|
"canvases",
|
|
@@ -3640,7 +3885,7 @@ var COLLECTIONS_BY_CATEGORY = {
|
|
|
3640
3885
|
};
|
|
3641
3886
|
function handler7() {
|
|
3642
3887
|
const categoryDocs = Object.entries(COLLECTIONS_BY_CATEGORY).map(([category, collections]) => {
|
|
3643
|
-
const collectionList = collections.filter((c) =>
|
|
3888
|
+
const collectionList = collections.filter((c) => COLLECTIONS3.includes(c)).map((c) => `- **${c}**`).join("\n");
|
|
3644
3889
|
return `## ${category}
|
|
3645
3890
|
${collectionList}`;
|
|
3646
3891
|
}).join("\n\n");
|
|
@@ -3661,8 +3906,9 @@ Each collection supports the following operations:
|
|
|
3661
3906
|
- \`updateMany(where, data)\` - Bulk update items matching filter
|
|
3662
3907
|
- \`removeMany(where)\` - Bulk delete items matching filter
|
|
3663
3908
|
|
|
3664
|
-
|
|
3665
|
-
publishable-key reads unless server-side access explicitly includes
|
|
3909
|
+
Status-managed public collections expose only \`status: 'published'\` rows to
|
|
3910
|
+
publishable-key reads unless server-side access explicitly includes
|
|
3911
|
+
unpublished statuses.
|
|
3666
3912
|
|
|
3667
3913
|
## Query Examples
|
|
3668
3914
|
|
|
@@ -3685,7 +3931,7 @@ publishable-key reads unless server-side access explicitly includes drafts.
|
|
|
3685
3931
|
}
|
|
3686
3932
|
\`\`\`
|
|
3687
3933
|
|
|
3688
|
-
Total available collections: ${
|
|
3934
|
+
Total available collections: ${COLLECTIONS3.length}`;
|
|
3689
3935
|
}
|
|
3690
3936
|
|
|
3691
3937
|
// src/resources/(docs)/getting-started.ts
|
|
@@ -5573,8 +5819,25 @@ function registerTool(server, schema34, meta, handler18) {
|
|
|
5573
5819
|
};
|
|
5574
5820
|
}
|
|
5575
5821
|
}
|
|
5576
|
-
const
|
|
5577
|
-
|
|
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
|
+
}
|
|
5578
5841
|
}
|
|
5579
5842
|
);
|
|
5580
5843
|
}
|
|
@@ -5676,6 +5939,9 @@ export {
|
|
|
5676
5939
|
MCP_SCOPES,
|
|
5677
5940
|
requestContext,
|
|
5678
5941
|
mcpServicePublicJwks,
|
|
5942
|
+
createMcpTelemetrySummary,
|
|
5943
|
+
runWithMcpTelemetry,
|
|
5944
|
+
flushMcpTelemetrySummary,
|
|
5679
5945
|
createServer
|
|
5680
5946
|
};
|
|
5681
|
-
//# sourceMappingURL=chunk-
|
|
5947
|
+
//# sourceMappingURL=chunk-CADO6WG6.js.map
|