clishop 1.5.2 → 1.5.4

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/README.md CHANGED
@@ -33,7 +33,7 @@ CLISHOP is an open-source CLI that lets AI agents and humans search for products
33
33
 
34
34
  - One query searches every store in the network. Results are filtered to what actually ships to your address.
35
35
  - Set spending caps per order, require email confirmation before anything ships, or let it go through automatically — your call.
36
- - Ships as a native [MCP server](https://modelcontextprotocol.io/) with 44 tools. Works with VS Code Copilot, Claude, Cursor, Windsurf, and anything else that speaks MCP.
36
+ - Ships as a native [MCP server](https://modelcontextprotocol.io/) with 46 tools. Works with VS Code Copilot, Claude, Cursor, Windsurf, and anything else that speaks MCP.
37
37
  - Can't find what you need? Post an advertise request and let vendors compete to fulfill it.
38
38
  - Support tickets, product reviews, store reviews — all from the terminal.
39
39
  - Anyone can sell on CLISHOP by deploying a [Dark Store](https://github.com/DavooxBv2/CLISHOP-DARKSTORE). No website needed.
@@ -76,33 +76,21 @@ npm link
76
76
 
77
77
  You can create your account on [clishop.ai](https://clishop.ai) or do everything from the CLI.
78
78
 
79
- ### Human-friendly setup
79
+ ### Setup
80
80
 
81
- ```bash
82
- clishop setup
83
- ```
84
-
85
- This starts the interactive setup flow, creates a resumable setup session, shows a secure payment link, and waits for completion.
81
+ Setup only needs an email address. Search first, then add your address and payment method when you're ready to buy.
86
82
 
87
- ### Agent-safe setup
88
-
89
- For OpenClaw, MCP clients, Claude-style shells, and other tool runners, use the explicit setup session commands instead of scraping terminal output:
83
+ For OpenClaw, MCP clients, Claude-style shells, and other tool runners, use:
90
84
 
91
85
  ```bash
92
86
  clishop setup start --email user@example.com --json
93
- clishop setup status --setup-id <setup_id> --json
94
- clishop setup wait --setup-id <setup_id> --timeout 300 --json
95
- clishop setup cancel --setup-id <setup_id> --json
96
87
  ```
97
88
 
98
- `setup start` returns immediately with:
99
-
100
- - `setup_id`: the resumable setup session handle for the agent
101
- - `setup_url`: the link the human must open in a browser
102
- - `expires_at`: when the session expires
103
- - `poll_after_seconds`: suggested polling interval
89
+ `setup start` returns immediately with account-ready status and stores auth locally.
104
90
 
105
- The agent sends `setup_url` to the human and keeps `setup_id` locally for `status`, `wait`, or `cancel`.
91
+ - Search products right away with `clishop search <query>`
92
+ - Add a shipping address later with `clishop address add`
93
+ - Add a payment method later with `clishop payment add`
106
94
 
107
95
  After setup is complete, add a shipping address and start ordering:
108
96
 
@@ -196,17 +184,17 @@ npm run lint # Type-check
196
184
 
197
185
  ## MCP Server
198
186
 
199
- CLISHOP ships as a native MCP server with 44 tools. Any MCP-compatible client gets shopping capabilities out of the box.
187
+ CLISHOP ships as a native MCP server with 46 tools. Any MCP-compatible client gets shopping capabilities out of the box.
200
188
 
201
189
  ```bash
202
190
  clishop-mcp # If installed globally
203
191
  npx -y clishop --mcp # Without installing
204
192
  ```
205
193
 
206
- The MCP onboarding tools now follow the same resumable setup session model:
194
+ The MCP onboarding tools now follow the same email-first model:
207
195
 
208
- - `setup` starts the session and returns `setup_id` plus `setup_url`
209
- - `setup_status` checks progress and finalizes auth when setup is complete
196
+ - `setup` creates the account immediately from the email address
197
+ - `setup_status` remains available only for legacy setup IDs
210
198
 
211
199
  See the [MCP setup guides](https://clishop.ai/docs#mcp-overview) for VS Code, Claude Desktop, Cursor, and Windsurf configuration.
212
200
 
@@ -155,10 +155,27 @@ async function postSetupRequest(path, body) {
155
155
  }
156
156
  async function startSetupSession(email) {
157
157
  const data = await postSetupRequest("/auth/setup-link", { email });
158
- if (!data.setupUrl || !(data.setupId || data.deviceCode) || !data.expiresIn || !data.pollInterval) {
158
+ const setupId = data.setupId || data.deviceCode || data.user?.id;
159
+ if (data.token && data.refreshToken && data.user && setupId) {
160
+ await storeAuthFromSetup({
161
+ token: data.token,
162
+ refreshToken: data.refreshToken,
163
+ user: data.user
164
+ });
165
+ return {
166
+ ok: true,
167
+ setup_id: setupId,
168
+ status: "completed",
169
+ next_action: "search_products",
170
+ expires_at: data.expiresAt,
171
+ poll_after_seconds: 0,
172
+ account_id: data.accountId || data.user.id,
173
+ human_message: data.humanMessage || "Account ready. Search now, then add address and payment when you are ready to buy."
174
+ };
175
+ }
176
+ if (!data.setupUrl || !setupId || !data.expiresIn || !data.pollInterval) {
159
177
  throw new Error(data?.message || "Failed to create setup session.");
160
178
  }
161
- const setupId = data.setupId || data.deviceCode;
162
179
  const expiresAt = data.expiresAt || new Date(Date.now() + data.expiresIn * 1e3).toISOString();
163
180
  return {
164
181
  ok: true,
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  resolveBackend,
15
15
  startSetupSession,
16
16
  waitForSetupSession
17
- } from "./chunk-EM4ZGZOU.js";
17
+ } from "./chunk-UO2N5F5R.js";
18
18
  import {
19
19
  createAgent,
20
20
  deleteAgent,
@@ -785,7 +785,6 @@ import ora3 from "ora";
785
785
 
786
786
  // src/commands/setup.ts
787
787
  import chalk4 from "chalk";
788
- import inquirer3 from "inquirer";
789
788
  import open from "open";
790
789
  import { execFileSync } from "child_process";
791
790
  var DEFAULT_SETUP_TIMEOUT_MS = 30 * 60 * 1e3;
@@ -846,24 +845,51 @@ function printSetupLink(message, setupUrl) {
846
845
  function printSetupEmailInstructions() {
847
846
  console.log(chalk4.yellow(" Email is required to start setup."));
848
847
  console.log();
849
- console.log(chalk4.dim(" Human-friendly:"));
850
- console.log(chalk4.white(" clishop setup user@example.com"));
851
- console.log();
852
- console.log(chalk4.dim(" Agent-safe JSON:"));
848
+ console.log(chalk4.dim(" Start setup with:"));
853
849
  console.log(chalk4.white(" clishop setup start --email user@example.com --json"));
854
850
  console.log();
855
851
  }
856
852
  function printSetupStartResult(result) {
853
+ if (result.status === "completed") {
854
+ console.log();
855
+ console.log(chalk4.bold(" Account created."));
856
+ if (result.account_id) {
857
+ console.log(chalk4.dim(` Account: ${result.account_id}`));
858
+ }
859
+ console.log();
860
+ console.log(chalk4.dim(result.human_message));
861
+ console.log();
862
+ return;
863
+ }
857
864
  console.log();
858
865
  console.log(chalk4.bold(" Setup session created."));
859
866
  console.log(chalk4.dim(` Setup ID: ${result.setup_id}`));
860
- console.log(chalk4.dim(` Expires: ${new Date(result.expires_at).toLocaleString()}`));
867
+ if (result.expires_at) {
868
+ console.log(chalk4.dim(` Expires: ${new Date(result.expires_at).toLocaleString()}`));
869
+ }
861
870
  printSetupLink("Give this link to your human to configure the payment method:", result.setup_url);
862
871
  console.log(chalk4.dim(" Check progress later with:"));
863
872
  console.log(chalk4.white(` clishop setup status --setup-id ${result.setup_id}`));
864
873
  console.log(chalk4.white(` clishop setup wait --setup-id ${result.setup_id}`));
865
874
  console.log();
866
875
  }
876
+ function printSetupReadyBanner(userLabel) {
877
+ console.log();
878
+ divider(chalk4.green);
879
+ console.log();
880
+ console.log(chalk4.bold.green(` \u2713 Account ready${userLabel ? ` for ${userLabel}` : ""}`));
881
+ console.log();
882
+ console.log(chalk4.dim(" Search first. Add an address and payment method only when you're ready to buy."));
883
+ console.log();
884
+ console.log(chalk4.dim(" Next steps:"));
885
+ console.log(chalk4.white(" clishop search <query> ") + chalk4.dim("Search for products"));
886
+ console.log(chalk4.white(" clishop address add ") + chalk4.dim("Add a shipping address later"));
887
+ console.log(chalk4.white(" clishop payment add ") + chalk4.dim("Add a payment method when needed"));
888
+ console.log(chalk4.white(" clishop buy <id> ") + chalk4.dim("Buy after choosing address + payment"));
889
+ console.log();
890
+ divider(chalk4.green);
891
+ console.log();
892
+ }
867
893
  function printSetupStatusResult(result) {
868
894
  console.log();
869
895
  if (!result.ok) {
@@ -884,7 +910,7 @@ function printSetupStatusResult(result) {
884
910
  console.log();
885
911
  break;
886
912
  case "completed":
887
- console.log(chalk4.green(" \u2713 Payment linked and account activated!"));
913
+ console.log(chalk4.green(" \u2713 Setup complete."));
888
914
  console.log(chalk4.dim(` Setup ID: ${result.setup_id}`));
889
915
  if (result.account_id) {
890
916
  console.log(chalk4.dim(` Account: ${result.account_id}`));
@@ -947,6 +973,9 @@ async function runSetupStartCommand(email, json = false) {
947
973
  }
948
974
  try {
949
975
  const result = await startSetupSession(normalizedEmail);
976
+ if (result.ok && result.status === "completed") {
977
+ getConfig().set("setupCompleted", true);
978
+ }
950
979
  if (json) {
951
980
  writeJson(sanitizeSetupPayload(result));
952
981
  return;
@@ -1046,10 +1075,10 @@ async function runSetupWaitCommand(setupId, timeoutSeconds, json = false) {
1046
1075
  }
1047
1076
  }
1048
1077
  function registerSetupCommand(program2) {
1049
- const setup = program2.command("setup").description("Set up your CLISHOP account or manage setup sessions").argument("[email]", "Email address for the human-friendly wrapper").action(async (email) => {
1078
+ const setup = program2.command("setup").description("Create your CLISHOP account or manage legacy setup sessions").argument("[email]", "Email address").action(async (email) => {
1050
1079
  await runSetupWizard(email);
1051
1080
  });
1052
- setup.command("start").description("Create a setup session and return immediately").requiredOption("--email <email>", "Email address").option("--json", "Output machine-readable JSON").action(async (opts) => {
1081
+ setup.command("start").description("Create your account and return immediately").requiredOption("--email <email>", "Email address").option("--json", "Output machine-readable JSON").action(async (opts) => {
1053
1082
  await runSetupStartCommand(opts.email, opts.json);
1054
1083
  });
1055
1084
  setup.command("status").description("Check the status of a setup session").requiredOption("--setup-id <setupId>", "Setup session ID").option("--json", "Output machine-readable JSON").action(async (opts) => {
@@ -1076,25 +1105,8 @@ async function runSetupWizard(emailArg, { json = false } = {}) {
1076
1105
  const loggedIn = await isLoggedIn();
1077
1106
  if (loggedIn) {
1078
1107
  const user = await getUserInfo();
1079
- try {
1080
- const api = getApiClient();
1081
- const agent = getActiveAgent();
1082
- const pmRes = await api.get("/payment-methods", { params: { agent: agent.name } });
1083
- const methods = pmRes.data.paymentMethods || [];
1084
- if (methods.length > 0) {
1085
- console.log();
1086
- console.log(chalk4.green(` \u2713 Already set up as ${chalk4.bold(user?.name || user?.email || "unknown")} with a payment method linked.`));
1087
- console.log(chalk4.dim(" Nothing to do. Run ") + chalk4.white("clishop search <query>") + chalk4.dim(" to get started."));
1088
- console.log();
1089
- return;
1090
- }
1091
- } catch {
1092
- }
1093
- console.log();
1094
- console.log(chalk4.green(` \u2713 Logged in as ${chalk4.bold(user?.name || user?.email || "unknown")}`));
1095
- console.log(chalk4.dim(" No payment method linked yet. Let's fix that."));
1096
- console.log();
1097
- await runPaymentLinkFlow(config);
1108
+ config.set("setupCompleted", true);
1109
+ printSetupReadyBanner(user?.name || user?.email || "unknown");
1098
1110
  return;
1099
1111
  }
1100
1112
  console.log();
@@ -1102,14 +1114,14 @@ async function runSetupWizard(emailArg, { json = false } = {}) {
1102
1114
  console.log();
1103
1115
  console.log(chalk4.bold.cyan(" W E L C O M E T O C L I S H O P"));
1104
1116
  console.log(chalk4.dim(" Order anything from your terminal."));
1105
- console.log(chalk4.dim(` npm: v${"1.5.2"}`));
1106
- console.log(chalk4.dim(` Build: ${"2026-04-04T20:51:01.276Z"}`));
1117
+ console.log(chalk4.dim(` npm: v${"1.5.4"}`));
1118
+ console.log(chalk4.dim(` Build: ${"2026-04-05T11:19:52.708Z"}`));
1107
1119
  console.log();
1108
1120
  divider(chalk4.cyan);
1109
1121
  console.log();
1110
- console.log(chalk4.dim(" Set up your account in one step. You'll get a link to"));
1111
- console.log(chalk4.dim(" securely link your payment method in the browser."));
1112
- console.log(chalk4.dim(" Your AI agent can then add addresses and place orders for you."));
1122
+ console.log(chalk4.dim(" Set up your account with your email first."));
1123
+ console.log(chalk4.dim(" Search for products right away."));
1124
+ console.log(chalk4.dim(" Add your address and payment method later, only when you're ready to buy."));
1113
1125
  console.log();
1114
1126
  console.log(chalk4.dim(" By creating an account you agree to the CLISHOP"));
1115
1127
  console.log(chalk4.dim(" Terms & Conditions: ") + chalk4.cyan.underline("https://clishop.ai/terms"));
@@ -1128,7 +1140,7 @@ async function runSetupWizard(emailArg, { json = false } = {}) {
1128
1140
  }
1129
1141
  let startResult;
1130
1142
  try {
1131
- console.log(chalk4.dim(" Creating your account and payment link..."));
1143
+ console.log(chalk4.dim(" Creating your account..."));
1132
1144
  startResult = await startSetupSession(email);
1133
1145
  } catch (error) {
1134
1146
  console.log(chalk4.red(` \u2717 Setup failed: ${error?.message || "Unknown error"}`));
@@ -1138,6 +1150,11 @@ async function runSetupWizard(emailArg, { json = false } = {}) {
1138
1150
  process.exitCode = 1;
1139
1151
  return;
1140
1152
  }
1153
+ if (startResult.status === "completed") {
1154
+ config.set("setupCompleted", true);
1155
+ printSetupReadyBanner(email);
1156
+ return;
1157
+ }
1141
1158
  printSetupStartResult(startResult);
1142
1159
  console.log(chalk4.dim(" Waiting for you to complete payment setup..."));
1143
1160
  console.log(chalk4.dim(" You can resume later with the setup ID shown above."));
@@ -1151,57 +1168,7 @@ async function runSetupWizard(emailArg, { json = false } = {}) {
1151
1168
  return;
1152
1169
  }
1153
1170
  config.set("setupCompleted", true);
1154
- console.log();
1155
- divider(chalk4.green);
1156
- console.log();
1157
- console.log(chalk4.bold.green(" \u2713 You're all set!"));
1158
- console.log();
1159
- console.log(chalk4.dim(" Your agent can now add addresses and place orders."));
1160
- console.log(chalk4.dim(" To add a shipping address manually:"));
1161
- console.log(chalk4.white(" clishop address add"));
1162
- console.log();
1163
- console.log(chalk4.dim(" Here are some commands to get you started:"));
1164
- console.log();
1165
- console.log(chalk4.white(" clishop search <query> ") + chalk4.dim("Search for products"));
1166
- console.log(chalk4.white(" clishop buy <id> ") + chalk4.dim("Quick-buy a product"));
1167
- console.log(chalk4.white(" clishop order list ") + chalk4.dim("View your orders"));
1168
- console.log(chalk4.white(" clishop --help ") + chalk4.dim("See all commands"));
1169
- console.log();
1170
- divider(chalk4.green);
1171
- console.log();
1172
- }
1173
- async function runPaymentLinkFlow(config) {
1174
- console.log(chalk4.dim(" Requesting secure payment setup link..."));
1175
- try {
1176
- const api = getApiClient();
1177
- const agent = getActiveAgent();
1178
- await ensureAgentOnBackend(agent.name);
1179
- const res = await api.post("/payment-methods/setup", { agent: agent.name });
1180
- const { setupUrl } = res.data;
1181
- printSetupLink("Open this link to link your payment method:", setupUrl);
1182
- const opened = await openBrowser(setupUrl);
1183
- if (opened) {
1184
- console.log(chalk4.dim(" (Browser opened automatically)"));
1185
- }
1186
- console.log();
1187
- await inquirer3.prompt([
1188
- { type: "input", name: "done", message: "Press Enter after completing payment setup in your browser..." }
1189
- ]);
1190
- console.log(chalk4.dim(" Checking for your payment method..."));
1191
- const pmRes = await api.get("/payment-methods", { params: { agent: agent.name } });
1192
- const methods = pmRes.data.paymentMethods || [];
1193
- if (methods.length > 0) {
1194
- const latest = methods[methods.length - 1];
1195
- updateAgent(agent.name, { defaultPaymentMethodId: latest.id });
1196
- console.log(chalk4.green(` \u2713 Payment method "${latest.label}" linked and set as default.`));
1197
- config.set("setupCompleted", true);
1198
- } else {
1199
- console.log(chalk4.yellow(" \u26A0 No payment method found yet. Run ") + chalk4.white("clishop setup") + chalk4.yellow(" to try again."));
1200
- }
1201
- } catch (error) {
1202
- console.log(chalk4.red(` \u2717 Could not get setup link: ${error?.response?.data?.message || error.message}`));
1203
- }
1204
- console.log();
1171
+ printSetupReadyBanner(email);
1205
1172
  }
1206
1173
 
1207
1174
  // src/commands/payment.ts
@@ -1219,7 +1186,7 @@ function registerPaymentCommands(program2) {
1219
1186
  spinner.stop();
1220
1187
  const methods = res.data.paymentMethods;
1221
1188
  if (methods.length === 0) {
1222
- console.log(chalk5.yellow("\nNo payment methods found. Run: clishop setup\n"));
1189
+ console.log(chalk5.yellow("\nNo payment methods found. Run: clishop payment add\n"));
1223
1190
  return;
1224
1191
  }
1225
1192
  console.log(chalk5.bold(`
@@ -1235,7 +1202,7 @@ Payment methods for agent "${agent.name}":
1235
1202
  handleApiError(error);
1236
1203
  }
1237
1204
  });
1238
- payment.command("add").description("Add an additional payment method (opens browser). First-time setup? Use 'clishop setup' instead.").action(async () => {
1205
+ payment.command("add").description("Add a payment method (opens browser)").action(async () => {
1239
1206
  try {
1240
1207
  const agent = getActiveAgent();
1241
1208
  await ensureAgentOnBackend(agent.name);
@@ -1252,8 +1219,8 @@ Payment methods for agent "${agent.name}":
1252
1219
  `));
1253
1220
  console.log(chalk5.dim("The CLI never collects raw card details. Payment is set up via the secure web portal."));
1254
1221
  console.log(chalk5.dim("Press Enter after completing the setup in your browser.\n"));
1255
- const inquirer10 = (await import("inquirer")).default;
1256
- await inquirer10.prompt([
1222
+ const inquirer9 = (await import("inquirer")).default;
1223
+ await inquirer9.prompt([
1257
1224
  { type: "input", name: "done", message: "Press Enter when done..." }
1258
1225
  ]);
1259
1226
  const checkSpinner = ora3("Checking for your payment method...").start();
@@ -1299,7 +1266,7 @@ Payment methods for agent "${agent.name}":
1299
1266
  // src/commands/search.ts
1300
1267
  import chalk6 from "chalk";
1301
1268
  import ora4 from "ora";
1302
- import inquirer4 from "inquirer";
1269
+ import inquirer3 from "inquirer";
1303
1270
  function formatPrice(cents, currency) {
1304
1271
  return new Intl.NumberFormat("en-US", {
1305
1272
  style: "currency",
@@ -2092,7 +2059,7 @@ Results for "${query}" \u2014 ${result.total} found (page ${result.page})
2092
2059
  short: p.name.length > 40 ? p.name.slice(0, 37) + "..." : p.name
2093
2060
  };
2094
2061
  });
2095
- const { selectedIds } = await inquirer4.prompt([
2062
+ const { selectedIds } = await inquirer3.prompt([
2096
2063
  {
2097
2064
  type: "checkbox",
2098
2065
  name: "selectedIds",
@@ -2328,7 +2295,7 @@ Product Information \u2014 ${total} result(s)
2328
2295
  // src/commands/order.ts
2329
2296
  import chalk7 from "chalk";
2330
2297
  import ora5 from "ora";
2331
- import inquirer5 from "inquirer";
2298
+ import inquirer4 from "inquirer";
2332
2299
  function formatPrice2(cents, currency) {
2333
2300
  return new Intl.NumberFormat("en-US", { style: "currency", currency }).format(cents / 100);
2334
2301
  }
@@ -2406,7 +2373,10 @@ function registerOrderCommands(program2) {
2406
2373
  return;
2407
2374
  }
2408
2375
  if (!paymentId) {
2409
- console.error(chalk7.red("\n\u2717 No payment method linked. Run: clishop setup"));
2376
+ console.error(chalk7.red("\n\u2717 No payment method linked for this agent."));
2377
+ console.error();
2378
+ console.error(chalk7.dim(" Add one when you're ready to buy with:"));
2379
+ console.error(chalk7.white(" clishop payment add"));
2410
2380
  process.exitCode = 1;
2411
2381
  return;
2412
2382
  }
@@ -2467,7 +2437,7 @@ function registerOrderCommands(program2) {
2467
2437
  console.log(` Total: ${chalk7.bold(formatPrice2(totalCents, product.currency))}`);
2468
2438
  console.log(` Agent: ${agent.name}`);
2469
2439
  console.log();
2470
- const { confirm } = await inquirer5.prompt([
2440
+ const { confirm } = await inquirer4.prompt([
2471
2441
  {
2472
2442
  type: "confirm",
2473
2443
  name: "confirm",
@@ -2614,7 +2584,7 @@ function registerOrderCommands(program2) {
2614
2584
  });
2615
2585
  order.command("cancel <id>").description("Cancel an order").action(async (id) => {
2616
2586
  try {
2617
- const { confirm } = await inquirer5.prompt([
2587
+ const { confirm } = await inquirer4.prompt([
2618
2588
  {
2619
2589
  type: "confirm",
2620
2590
  name: "confirm",
@@ -2636,7 +2606,7 @@ function registerOrderCommands(program2) {
2636
2606
  // src/commands/review.ts
2637
2607
  import chalk8 from "chalk";
2638
2608
  import ora6 from "ora";
2639
- import inquirer6 from "inquirer";
2609
+ import inquirer5 from "inquirer";
2640
2610
  function renderStars2(rating) {
2641
2611
  const filled = Math.round(rating);
2642
2612
  const empty = 10 - filled;
@@ -2689,7 +2659,7 @@ function registerReviewCommands(program2) {
2689
2659
  let storeReview = void 0;
2690
2660
  for (const item of unreviewedItems) {
2691
2661
  console.log(chalk8.bold(` Product: ${item.productName}`));
2692
- const { wantReview } = await inquirer6.prompt([
2662
+ const { wantReview } = await inquirer5.prompt([
2693
2663
  {
2694
2664
  type: "confirm",
2695
2665
  name: "wantReview",
@@ -2698,7 +2668,7 @@ function registerReviewCommands(program2) {
2698
2668
  }
2699
2669
  ]);
2700
2670
  if (!wantReview) continue;
2701
- const answers = await inquirer6.prompt([
2671
+ const answers = await inquirer5.prompt([
2702
2672
  {
2703
2673
  type: "select",
2704
2674
  name: "rating",
@@ -2729,7 +2699,7 @@ function registerReviewCommands(program2) {
2729
2699
  }
2730
2700
  if (!storeAlreadyReviewed) {
2731
2701
  console.log(chalk8.bold(` Store: ${reviewable.store.name}`));
2732
- const { wantStoreReview } = await inquirer6.prompt([
2702
+ const { wantStoreReview } = await inquirer5.prompt([
2733
2703
  {
2734
2704
  type: "confirm",
2735
2705
  name: "wantStoreReview",
@@ -2738,7 +2708,7 @@ function registerReviewCommands(program2) {
2738
2708
  }
2739
2709
  ]);
2740
2710
  if (wantStoreReview) {
2741
- const storeAnswers = await inquirer6.prompt([
2711
+ const storeAnswers = await inquirer5.prompt([
2742
2712
  {
2743
2713
  type: "select",
2744
2714
  name: "rating",
@@ -2798,7 +2768,7 @@ function registerReviewCommands(program2) {
2798
2768
  });
2799
2769
  review.command("add <productId>").description("Write a review for a product").option("--order <orderId>", "Associate with an order").action(async (productId, opts) => {
2800
2770
  try {
2801
- const answers = await inquirer6.prompt([
2771
+ const answers = await inquirer5.prompt([
2802
2772
  {
2803
2773
  type: "select",
2804
2774
  name: "rating",
@@ -2831,7 +2801,7 @@ function registerReviewCommands(program2) {
2831
2801
  });
2832
2802
  review.command("store <storeId>").description("Write a review for a store").option("--order <orderId>", "Associate with an order").action(async (storeId, opts) => {
2833
2803
  try {
2834
- const answers = await inquirer6.prompt([
2804
+ const answers = await inquirer5.prompt([
2835
2805
  {
2836
2806
  type: "select",
2837
2807
  name: "rating",
@@ -2933,7 +2903,7 @@ function registerReviewCommands(program2) {
2933
2903
  });
2934
2904
  review.command("delete <reviewId>").alias("rm").description("Delete one of your reviews").option("--store", "Delete a store review").action(async (reviewId, opts) => {
2935
2905
  try {
2936
- const { confirm } = await inquirer6.prompt([
2906
+ const { confirm } = await inquirer5.prompt([
2937
2907
  {
2938
2908
  type: "confirm",
2939
2909
  name: "confirm",
@@ -3245,7 +3215,7 @@ function registerStatusCommand(program2) {
3245
3215
  console.log();
3246
3216
  console.log(chalk11.bold(` \u{1F4B3} Payment Methods (${agent.paymentMethods.length})`));
3247
3217
  if (agent.paymentMethods.length === 0) {
3248
- console.log(chalk11.dim(" None \u2014 run: clishop setup"));
3218
+ console.log(chalk11.dim(" None \u2014 run: clishop payment add"));
3249
3219
  } else {
3250
3220
  for (const pm of agent.paymentMethods) {
3251
3221
  const isDefault = pm.id === agent.defaultPaymentMethodId;
@@ -3269,7 +3239,7 @@ function registerStatusCommand(program2) {
3269
3239
  // src/commands/advertise.ts
3270
3240
  import chalk12 from "chalk";
3271
3241
  import ora9 from "ora";
3272
- import inquirer7 from "inquirer";
3242
+ import inquirer6 from "inquirer";
3273
3243
  function formatPrice4(cents, currency) {
3274
3244
  return new Intl.NumberFormat("en-US", { style: "currency", currency }).format(cents / 100);
3275
3245
  }
@@ -3293,7 +3263,7 @@ function registerAdvertiseCommands(program2) {
3293
3263
  const agent = getActiveAgent();
3294
3264
  console.log(chalk12.bold("\n \u{1F4E2} Advertise a Request\n"));
3295
3265
  console.log(chalk12.dim(" Can't find what you need? Describe it and vendors will bid to fulfill it.\n"));
3296
- const answers = await inquirer7.prompt([
3266
+ const answers = await inquirer6.prompt([
3297
3267
  {
3298
3268
  type: "input",
3299
3269
  name: "title",
@@ -3340,7 +3310,7 @@ function registerAdvertiseCommands(program2) {
3340
3310
  ]);
3341
3311
  let recurringNote;
3342
3312
  if (answers.recurring) {
3343
- const recAnswer = await inquirer7.prompt([
3313
+ const recAnswer = await inquirer6.prompt([
3344
3314
  {
3345
3315
  type: "input",
3346
3316
  name: "recurringNote",
@@ -3349,7 +3319,7 @@ function registerAdvertiseCommands(program2) {
3349
3319
  ]);
3350
3320
  recurringNote = recAnswer.recurringNote || void 0;
3351
3321
  }
3352
- const priceAnswers = await inquirer7.prompt([
3322
+ const priceAnswers = await inquirer6.prompt([
3353
3323
  {
3354
3324
  type: "input",
3355
3325
  name: "bidPrice",
@@ -3358,7 +3328,7 @@ function registerAdvertiseCommands(program2) {
3358
3328
  ]);
3359
3329
  let currency = "USD";
3360
3330
  if (priceAnswers.bidPrice && parseFloat(priceAnswers.bidPrice) > 0) {
3361
- const currencyAnswer = await inquirer7.prompt([
3331
+ const currencyAnswer = await inquirer6.prompt([
3362
3332
  {
3363
3333
  type: "list",
3364
3334
  name: "currency",
@@ -3379,7 +3349,7 @@ function registerAdvertiseCommands(program2) {
3379
3349
  }
3380
3350
  ]);
3381
3351
  if (currencyAnswer.currency === "OTHER") {
3382
- const customCurrency = await inquirer7.prompt([
3352
+ const customCurrency = await inquirer6.prompt([
3383
3353
  {
3384
3354
  type: "input",
3385
3355
  name: "code",
@@ -3392,14 +3362,14 @@ function registerAdvertiseCommands(program2) {
3392
3362
  currency = currencyAnswer.currency;
3393
3363
  }
3394
3364
  }
3395
- const speedAnswer = await inquirer7.prompt([
3365
+ const speedAnswer = await inquirer6.prompt([
3396
3366
  {
3397
3367
  type: "input",
3398
3368
  name: "speedDays",
3399
3369
  message: "Desired delivery speed in days (optional):"
3400
3370
  }
3401
3371
  ]);
3402
- const returnAnswers = await inquirer7.prompt([
3372
+ const returnAnswers = await inquirer6.prompt([
3403
3373
  {
3404
3374
  type: "confirm",
3405
3375
  name: "freeReturns",
@@ -3431,7 +3401,7 @@ function registerAdvertiseCommands(program2) {
3431
3401
  addrChoices.push({ name: chalk12.dim(skipOption), value: skipOption });
3432
3402
  const defaultAddr = addresses.find((a) => a.id === agent.defaultAddressId);
3433
3403
  const defaultDisplay = defaultAddr ? `${defaultAddr.label} \u2014 ${defaultAddr.line1}` : "";
3434
- const { selectedAddress } = await inquirer7.prompt([
3404
+ const { selectedAddress } = await inquirer6.prompt([
3435
3405
  {
3436
3406
  type: "list",
3437
3407
  name: "selectedAddress",
@@ -3465,7 +3435,7 @@ function registerAdvertiseCommands(program2) {
3465
3435
  // Default: all user's payment methods selected
3466
3436
  }))
3467
3437
  ];
3468
- const { selectedPayments } = await inquirer7.prompt([
3438
+ const { selectedPayments } = await inquirer6.prompt([
3469
3439
  {
3470
3440
  type: "checkbox",
3471
3441
  name: "selectedPayments",
@@ -3479,7 +3449,7 @@ function registerAdvertiseCommands(program2) {
3479
3449
  paymentMethods = JSON.stringify(selectedPayments);
3480
3450
  }
3481
3451
  } else {
3482
- console.log(chalk12.dim(" No payment methods found. Run: clishop setup"));
3452
+ console.log(chalk12.dim(" No payment methods found. Run: clishop payment add"));
3483
3453
  }
3484
3454
  } catch {
3485
3455
  paySpinner.stop();
@@ -3732,7 +3702,7 @@ function registerAdvertiseCommands(program2) {
3732
3702
  if (bid.shippingDays != null) console.log(` Delivery: ${bid.shippingDays}-day`);
3733
3703
  if (bid.note) console.log(` Note: ${bid.note}`);
3734
3704
  console.log();
3735
- const { confirm } = await inquirer7.prompt([
3705
+ const { confirm } = await inquirer6.prompt([
3736
3706
  {
3737
3707
  type: "confirm",
3738
3708
  name: "confirm",
@@ -3753,7 +3723,7 @@ function registerAdvertiseCommands(program2) {
3753
3723
  });
3754
3724
  advertise.command("reject <advertiseId> <bidId>").description("Reject a vendor's bid").action(async (advertiseId, bidId) => {
3755
3725
  try {
3756
- const { confirm } = await inquirer7.prompt([
3726
+ const { confirm } = await inquirer6.prompt([
3757
3727
  {
3758
3728
  type: "confirm",
3759
3729
  name: "confirm",
@@ -3772,7 +3742,7 @@ function registerAdvertiseCommands(program2) {
3772
3742
  });
3773
3743
  advertise.command("cancel <id>").description("Cancel an advertised request").action(async (id) => {
3774
3744
  try {
3775
- const { confirm } = await inquirer7.prompt([
3745
+ const { confirm } = await inquirer6.prompt([
3776
3746
  {
3777
3747
  type: "confirm",
3778
3748
  name: "confirm",
@@ -3794,7 +3764,7 @@ function registerAdvertiseCommands(program2) {
3794
3764
  // src/commands/support.ts
3795
3765
  import chalk13 from "chalk";
3796
3766
  import ora10 from "ora";
3797
- import inquirer8 from "inquirer";
3767
+ import inquirer7 from "inquirer";
3798
3768
  var CATEGORY_CHOICES = [
3799
3769
  { name: "General question", value: "general" },
3800
3770
  { name: "Damaged item", value: "damaged" },
@@ -3828,7 +3798,7 @@ function registerSupportCommands(program2) {
3828
3798
  const support = program2.command("support").description("Manage support tickets for orders");
3829
3799
  support.command("create <orderId>").alias("new").description("Create a support ticket for an order").action(async (orderId) => {
3830
3800
  try {
3831
- const answers = await inquirer8.prompt([
3801
+ const answers = await inquirer7.prompt([
3832
3802
  {
3833
3803
  type: "select",
3834
3804
  name: "category",
@@ -3959,7 +3929,7 @@ function registerSupportCommands(program2) {
3959
3929
  });
3960
3930
  support.command("reply <ticketId>").description("Reply to a support ticket").action(async (ticketId) => {
3961
3931
  try {
3962
- const { message } = await inquirer8.prompt([
3932
+ const { message } = await inquirer7.prompt([
3963
3933
  {
3964
3934
  type: "editor",
3965
3935
  name: "message",
@@ -3984,7 +3954,7 @@ function registerSupportCommands(program2) {
3984
3954
  });
3985
3955
  support.command("close <ticketId>").description("Close a resolved ticket").action(async (ticketId) => {
3986
3956
  try {
3987
- const { confirm } = await inquirer8.prompt([
3957
+ const { confirm } = await inquirer7.prompt([
3988
3958
  {
3989
3959
  type: "confirm",
3990
3960
  name: "confirm",
@@ -4006,7 +3976,7 @@ function registerSupportCommands(program2) {
4006
3976
  // src/commands/feedback.ts
4007
3977
  import chalk14 from "chalk";
4008
3978
  import ora11 from "ora";
4009
- import inquirer9 from "inquirer";
3979
+ import inquirer8 from "inquirer";
4010
3980
  var STATUS_COLORS4 = {
4011
3981
  open: chalk14.green,
4012
3982
  acknowledged: chalk14.cyan,
@@ -4039,7 +4009,7 @@ function registerFeedbackCommands(program2) {
4039
4009
  if (!title || !description || !stepsToReproduce || !actualBehavior || !expectedBehavior) {
4040
4010
  console.log(chalk14.bold("\n\u{1F41B} Report a Bug\n"));
4041
4011
  console.log(chalk14.dim("Help us fix issues by describing what went wrong.\n"));
4042
- const answers = await inquirer9.prompt([
4012
+ const answers = await inquirer8.prompt([
4043
4013
  ...!title ? [{
4044
4014
  type: "input",
4045
4015
  name: "title",
@@ -4111,7 +4081,7 @@ function registerFeedbackCommands(program2) {
4111
4081
  if (!title || !description) {
4112
4082
  console.log(chalk14.bold("\n\u{1F4A1} Suggest an Improvement\n"));
4113
4083
  console.log(chalk14.dim("Tell us how we can make CLISHOP better.\n"));
4114
- const answers = await inquirer9.prompt([
4084
+ const answers = await inquirer8.prompt([
4115
4085
  ...!title ? [{
4116
4086
  type: "input",
4117
4087
  name: "title",
@@ -4291,11 +4261,10 @@ function registerDoctorCommand(program2) {
4291
4261
 
4292
4262
  // src/index.ts
4293
4263
  var program = new Command();
4294
- program.name("clishop").version("1.5.2").description(
4264
+ program.name("clishop").version("1.5.4").description(
4295
4265
  chalk16.bold("CLISHOP") + ` \u2014 Order anything from your terminal.
4296
4266
 
4297
- Run 'clishop setup' for the human-friendly flow, or
4298
- 'clishop setup start --email <email> --json' for agent-safe setup.
4267
+ Run 'clishop setup <email>' or 'clishop setup start --email <email> --json' to create your account.
4299
4268
  Use agents to set safety limits, addresses, and payment methods.
4300
4269
  The "default" agent is used when no agent is specified.`
4301
4270
  ).option("--agent <name>", "Use a specific agent for this command").hook("preAction", (thisCommand) => {
@@ -4340,7 +4309,7 @@ async function main() {
4340
4309
  }
4341
4310
  console.error(
4342
4311
  chalk16.yellow(
4343
- "CLISHOP setup is incomplete. Run 'clishop setup start --email <email> --json' in non-interactive environments."
4312
+ "CLISHOP setup is incomplete. Run 'clishop setup start --email <email> --json' in non-interactive environments, or 'clishop setup <email>' in the CLI."
4344
4313
  )
4345
4314
  );
4346
4315
  process.exit(1);
package/dist/mcp.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  getUserInfo,
7
7
  isLoggedIn,
8
8
  startSetupSession
9
- } from "./chunk-EM4ZGZOU.js";
9
+ } from "./chunk-UO2N5F5R.js";
10
10
  import {
11
11
  __export,
12
12
  getActiveAgent,
@@ -13813,7 +13813,7 @@ function safeCall(fn) {
13813
13813
  var server = new McpServer(
13814
13814
  {
13815
13815
  name: "clishop",
13816
- version: "1.2.3"
13816
+ version: "1.5.4"
13817
13817
  },
13818
13818
  {
13819
13819
  capabilities: {
@@ -13823,7 +13823,7 @@ var server = new McpServer(
13823
13823
  );
13824
13824
  server.registerTool("setup", {
13825
13825
  title: "Setup",
13826
- description: "Start a resumable setup session. Returns a setup URL for the human and a setup_id for the agent to check later. After the human completes the link, call setup_status with the returned setup_id.",
13826
+ description: "Create or sign in a CLISHOP account using an email address. Setup now completes immediately; add address and payment later when the user is ready to buy.",
13827
13827
  inputSchema: {
13828
13828
  email: external_exports.string().email().describe("User's email address")
13829
13829
  },
@@ -13835,15 +13835,18 @@ server.registerTool("setup", {
13835
13835
  }, async (args) => {
13836
13836
  return safeCall(async () => {
13837
13837
  const data = await startSetupSession(args.email);
13838
+ if (data.ok && data.status === "completed") {
13839
+ getConfig().set("setupCompleted", true);
13840
+ }
13838
13841
  return {
13839
13842
  ...data,
13840
- message: "Give this link to your human to configure their payment method in the browser. Then call setup_status with the setup_id to check when they're done."
13843
+ message: data.status === "completed" ? "Account ready. Search products now. Only add address and payment once the user decides to buy." : "Legacy setup session created. Call setup_status with the setup_id if you still need to wait for completion."
13841
13844
  };
13842
13845
  });
13843
13846
  });
13844
13847
  server.registerTool("setup_status", {
13845
13848
  title: "Setup Status",
13846
- description: "Check the current setup state using the setup_id returned by the setup tool. If setup is complete, auth is stored locally so later CLISHOP calls can proceed.",
13849
+ description: "Check a legacy setup session by setup_id. Modern email-only setup completes immediately and usually does not need this tool.",
13847
13850
  inputSchema: {
13848
13851
  setupId: external_exports.string().describe("The setup_id returned by the setup tool")
13849
13852
  },
@@ -13994,7 +13997,7 @@ server.registerTool("buy_product", {
13994
13997
  throw new Error("No shipping address set. Add one first via the add_address tool.");
13995
13998
  }
13996
13999
  if (!paymentId) {
13997
- throw new Error("No payment method linked. Use the setup tool to onboard the user first.");
14000
+ throw new Error("No payment method linked. Add one with the payment method tools before placing the order.");
13998
14001
  }
13999
14002
  const api = getApiClient();
14000
14003
  let product;
@@ -14330,7 +14333,7 @@ server.registerTool("account_status", {
14330
14333
  return safeCall(async () => {
14331
14334
  const loggedIn = await isLoggedIn();
14332
14335
  if (!loggedIn) {
14333
- return { loggedIn: false, message: "Not set up yet. Use the setup tool to onboard the user with a payment link." };
14336
+ return { loggedIn: false, message: "Not set up yet. Use the setup tool with an email address to create the account." };
14334
14337
  }
14335
14338
  const api = getApiClient();
14336
14339
  const cfg = getConfig();
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "clishop": {
4
+ "command": "npx",
5
+ "args": ["-y", "clishop", "--mcp"]
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,150 @@
1
+ ---
2
+ name: clishop
3
+ description: "Order anything from your terminal — search products, compare prices across stores, place orders, manage addresses and payments. Built for AI agents and humans."
4
+ ---
5
+
6
+ # CLISHOP — Buy anything from your terminal
7
+
8
+ CLISHOP is an open-source MCP server and CLI that lets AI agents search for products across multiple stores, compare prices, and place real orders — all from the terminal.
9
+
10
+ **46 MCP tools** for the full shopping lifecycle: search → compare → buy → track → review → return.
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ npm install -g clishop
16
+ ```
17
+
18
+ Use the email-first setup command:
19
+
20
+ ```bash
21
+ clishop setup start --email user@example.com --json
22
+ ```
23
+
24
+ Then search products, and only add an address or payment method when the user is ready to buy.
25
+
26
+ ### MCP Server
27
+
28
+ ```bash
29
+ clishop-mcp # If installed globally
30
+ npx -y clishop --mcp # Without installing
31
+ ```
32
+
33
+ ## Tools
34
+
35
+ | Tool | Description | Read-only |
36
+ |------|-------------|-----------|
37
+ | `setup` | Create or sign in with an email address (completes immediately) | ❌ |
38
+ | `setup_status` | Check a legacy setup session by setup_id | ✅ |
39
+ | `search_products` | Search across all connected stores with filters (price, brand, category, shipping, ratings) | ✅ |
40
+ | `get_product` | Get detailed info about a specific product | ✅ |
41
+ | `buy_product` | Place an order (respects agent safety limits) | ❌ |
42
+ | `list_orders` | List orders, optionally filtered by status | ✅ |
43
+ | `get_order` | Full order details including tracking and shipments | ✅ |
44
+ | `cancel_order` | Cancel a pending or confirmed order | ❌ |
45
+ | `list_addresses` | List saved shipping addresses | ✅ |
46
+ | `add_address` | Add a new shipping address | ❌ |
47
+ | `remove_address` | Remove a saved address | ❌ |
48
+ | `set_default_address` | Set the default shipping address for the active agent | ❌ |
49
+ | `list_payment_methods` | List saved payment methods | ✅ |
50
+ | `remove_payment_method` | Remove a saved payment method | ❌ |
51
+ | `set_default_payment_method` | Set the default payment method for the active agent | ❌ |
52
+ | `list_stores` | Browse available stores | ✅ |
53
+ | `get_store` | View store details | ✅ |
54
+ | `store_catalog` | Browse a store's product catalog | ✅ |
55
+ | `account_status` | Full account overview (user, agents, addresses, payments) | ✅ |
56
+ | `list_agents` | List safety profiles (spending limits, allowed categories) | ✅ |
57
+ | `get_agent` | View details of a specific agent | ✅ |
58
+ | `create_agent` | Create a new agent (safety profile) with spending limits | ❌ |
59
+ | `update_agent` | Update an agent's settings (limits, categories, defaults) | ❌ |
60
+ | `switch_agent` | Switch the active agent | ❌ |
61
+ | `get_spending_limit` | View the current monthly spending limit | ✅ |
62
+ | `set_spending_limit` | Change the monthly spending limit | ❌ |
63
+ | `add_product_review` | Write a product review (1-10 rating) | ❌ |
64
+ | `add_store_review` | Write a store review (1-10 rating) | ❌ |
65
+ | `list_reviews` | List all your product and store reviews | ✅ |
66
+ | `get_product_rating` | View rating details for a product | ✅ |
67
+ | `get_store_rating` | View rating details for a store | ✅ |
68
+ | `delete_review` | Delete one of your reviews | ❌ |
69
+ | `create_advertise_request` | Post a request for vendors to bid on | ❌ |
70
+ | `list_advertise_requests` | List your advertised requests | ✅ |
71
+ | `get_advertise_request` | View an advertised request and its bids | ✅ |
72
+ | `accept_advertise_bid` | Accept a vendor's bid | ❌ |
73
+ | `reject_advertise_bid` | Reject a vendor's bid | ❌ |
74
+ | `cancel_advertise_request` | Cancel an open advertised request | ❌ |
75
+ | `create_support_ticket` | Create a support ticket for an order | ❌ |
76
+ | `list_support_tickets` | List support tickets | ✅ |
77
+ | `get_support_ticket` | View a support ticket and its message history | ✅ |
78
+ | `reply_to_support_ticket` | Send a reply to a support ticket | ❌ |
79
+ | `close_support_ticket` | Close a resolved support ticket | ❌ |
80
+ | `submit_feedback` | Report a bug or suggest an improvement | ❌ |
81
+ | `list_feedback` | List your submitted bug reports and suggestions | ✅ |
82
+ | `get_feedback` | View details of a specific feedback item | ✅ |
83
+
84
+ ## External Endpoints
85
+
86
+ All network requests go to the CLISHOP API:
87
+
88
+ | Endpoint | Method | Data sent | Purpose |
89
+ |----------|--------|-----------|---------|
90
+ | `/auth/setup-link` | POST | Email address | Create account / sign in |
91
+ | `/products/search` | GET | Search query, filters (category, brand, price range, country) | Product search |
92
+ | `/products/:id` | GET | Product ID | Product details |
93
+ | `/products/extended/:id` | GET | Product ID | Extended product lookup across vendor stores |
94
+ | `/orders` | GET | Status filter, page | List user's orders |
95
+ | `/orders` | POST | Product ID, quantity, address ID, payment ID, agent name | Place an order |
96
+ | `/orders/:id` | GET | Order ID | Order details |
97
+ | `/orders/:id/tracking` | GET | Order ID | Shipment tracking |
98
+ | `/orders/:id/cancel` | POST | Order ID | Cancel an order |
99
+ | `/addresses` | GET | Agent name | List addresses |
100
+ | `/addresses` | POST | Full address fields (name, street, city, country, etc.) | Add address |
101
+ | `/addresses/:id` | DELETE | Address ID | Remove address |
102
+ | `/payment-methods` | GET | Agent name | List payment methods |
103
+ | `/payment-methods/:id` | DELETE | Payment method ID | Remove payment method |
104
+ | `/stores` | GET | Query, filters | Browse stores |
105
+ | `/stores/:id` | GET | Store ID/slug | Store details |
106
+ | `/stores/:id/products` | GET | Query, filters | Store catalog |
107
+ | `/agents` | GET | — | List agents |
108
+ | `/spending-limit` | GET/PATCH | Limit in cents | Get/set spending limit |
109
+ | `/products/:id/reviews` | POST | Rating, title, body | Product review |
110
+ | `/stores/:id/reviews` | POST | Rating, title, body | Store review |
111
+ | `/reviews/mine` | GET | — | List own reviews |
112
+ | `/products/:id/rating` | GET | — | Product rating details |
113
+ | `/stores/:id/rating` | GET | — | Store rating details |
114
+ | `/advertise` | GET/POST | Title, description, brand, quantity, max bid price | Advertise requests |
115
+ | `/advertise/:id` | GET | — | Advertise request details |
116
+ | `/advertise/:id/bids/:id/accept` | POST | — | Accept bid |
117
+ | `/advertise/:id/bids/:id/reject` | POST | — | Reject bid |
118
+ | `/advertise/:id/cancel` | POST | — | Cancel advertise request |
119
+ | `/support` | GET/POST | Ticket details or status filter | Support tickets |
120
+ | `/support/:id` | GET | — | Support ticket details |
121
+ | `/support/:id/reply` | POST | Message | Reply to support ticket |
122
+ | `/support/:id/status` | PATCH | Status | Close support ticket |
123
+ | `/feedback` | GET/POST | Feedback type, title, description | Feedback |
124
+ | `/feedback/:id` | GET | — | Feedback details |
125
+
126
+ All requests are sent over **HTTPS** to `https://clishop-backend.vercel.app/api`.
127
+
128
+ ## Security & Privacy
129
+
130
+ - **Authentication:** Session tokens are stored in the OS keychain via [keytar](https://github.com/nicknisi/keytar), never in plain-text config files.
131
+ - **No local data collection:** CLISHOP does not collect analytics, telemetry, or tracking data locally.
132
+ - **Agent safety profiles:** Spending limits (`maxOrderAmount`), category allow/block lists, and confirmation requirements are enforced client-side before any order is placed.
133
+ - **Data sent to API:** Only the data required for each operation (search queries, addresses, order details) is sent to the CLISHOP backend API. No additional metadata is collected.
134
+ - **Vendor stores:** When extended search is enabled, the CLISHOP backend fans out search queries to registered vendor Dark Stores in real-time. Product data flows through the CLISHOP API — the CLI never contacts vendor stores directly.
135
+
136
+ ## Trust Statement
137
+
138
+ By using this skill, your search queries, shipping addresses, payment method references, and order details are sent to the CLISHOP API (`clishop-backend.vercel.app`). The API acts as a gateway to registered vendor stores. No data is sold or shared with third parties beyond what is necessary to fulfill orders.
139
+
140
+ ## Model Invocation Note
141
+
142
+ This skill is designed for autonomous invocation by AI agents via the Model Context Protocol (MCP). When an MCP client (e.g. Claude Desktop, Cursor, VS Code Copilot) calls these tools, the agent may search for products, place orders, and manage account data on the user's behalf — subject to the safety thresholds configured in the user's agent profile.
143
+
144
+ ## Links
145
+
146
+ - 🌐 [clishop.ai](https://clishop.ai)
147
+ - 📖 [Docs](https://clishop.ai/docs)
148
+ - 💬 [Discord](https://discord.gg/vwXMbzD4bx)
149
+ - 🏪 [Dark Store template](https://github.com/DavooxBv2/CLISHOP-DARKSTORE)
150
+ - 📦 [npm](https://www.npmjs.com/package/clishop)
package/package.json CHANGED
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "clishop",
3
- "version": "1.5.2",
3
+ "version": "1.5.4",
4
4
  "mcpName": "io.github.StefDCL/clishop",
5
5
  "description": "CLISHOP — Order anything from your terminal",
6
6
  "main": "dist/index.js",
7
7
  "files": [
8
- "dist"
8
+ "dist",
9
+ "openclaw",
10
+ "server.json"
9
11
  ],
10
12
  "bin": {
11
13
  "clishop": "dist/index.js",
package/server.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
+ "name": "io.github.StefDCL/clishop",
4
+ "description": "Order anything from your terminal — search, buy, track, and manage via MCP tools.",
5
+ "repository": {
6
+ "url": "https://github.com/DavooxBv2/CLISHOP",
7
+ "source": "github"
8
+ },
9
+ "version": "1.5.4",
10
+ "packages": [
11
+ {
12
+ "registryType": "npm",
13
+ "identifier": "clishop",
14
+ "version": "1.5.4",
15
+ "runtime": "node",
16
+ "args": ["--mcp"],
17
+ "transport": {
18
+ "type": "stdio"
19
+ },
20
+ "environmentVariables": []
21
+ }
22
+ ]
23
+ }