ebay-mcp 1.4.3

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.
Files changed (205) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +586 -0
  3. package/build/api/account-management/account.d.ts +216 -0
  4. package/build/api/account-management/account.js +305 -0
  5. package/build/api/analytics-and-report/analytics.d.ts +33 -0
  6. package/build/api/analytics-and-report/analytics.js +102 -0
  7. package/build/api/client.d.ts +89 -0
  8. package/build/api/client.js +343 -0
  9. package/build/api/communication/feedback.d.ts +45 -0
  10. package/build/api/communication/feedback.js +119 -0
  11. package/build/api/communication/message.d.ts +55 -0
  12. package/build/api/communication/message.js +131 -0
  13. package/build/api/communication/negotiation.d.ts +39 -0
  14. package/build/api/communication/negotiation.js +97 -0
  15. package/build/api/communication/notification.d.ts +128 -0
  16. package/build/api/communication/notification.js +373 -0
  17. package/build/api/index.d.ts +96 -0
  18. package/build/api/index.js +121 -0
  19. package/build/api/listing-management/inventory.d.ts +216 -0
  20. package/build/api/listing-management/inventory.js +633 -0
  21. package/build/api/listing-metadata/metadata.d.ts +154 -0
  22. package/build/api/listing-metadata/metadata.js +485 -0
  23. package/build/api/listing-metadata/taxonomy.d.ts +38 -0
  24. package/build/api/listing-metadata/taxonomy.js +58 -0
  25. package/build/api/marketing-and-promotions/marketing.d.ts +395 -0
  26. package/build/api/marketing-and-promotions/marketing.js +565 -0
  27. package/build/api/marketing-and-promotions/recommendation.d.ts +20 -0
  28. package/build/api/marketing-and-promotions/recommendation.js +32 -0
  29. package/build/api/order-management/dispute.d.ts +65 -0
  30. package/build/api/order-management/dispute.js +69 -0
  31. package/build/api/order-management/fulfillment.d.ts +80 -0
  32. package/build/api/order-management/fulfillment.js +89 -0
  33. package/build/api/other/compliance.d.ts +26 -0
  34. package/build/api/other/compliance.js +47 -0
  35. package/build/api/other/edelivery.d.ts +153 -0
  36. package/build/api/other/edelivery.js +219 -0
  37. package/build/api/other/identity.d.ts +17 -0
  38. package/build/api/other/identity.js +24 -0
  39. package/build/api/other/translation.d.ts +14 -0
  40. package/build/api/other/translation.js +22 -0
  41. package/build/api/other/vero.d.ts +30 -0
  42. package/build/api/other/vero.js +48 -0
  43. package/build/auth/oauth-metadata.d.ts +46 -0
  44. package/build/auth/oauth-metadata.js +59 -0
  45. package/build/auth/oauth-middleware.d.ts +35 -0
  46. package/build/auth/oauth-middleware.js +99 -0
  47. package/build/auth/oauth-types.d.ts +66 -0
  48. package/build/auth/oauth-types.js +4 -0
  49. package/build/auth/oauth.d.ts +93 -0
  50. package/build/auth/oauth.js +383 -0
  51. package/build/auth/scope-utils.d.ts +70 -0
  52. package/build/auth/scope-utils.js +304 -0
  53. package/build/auth/token-verifier.d.ts +57 -0
  54. package/build/auth/token-verifier.js +172 -0
  55. package/build/config/environment.d.ts +61 -0
  56. package/build/config/environment.js +260 -0
  57. package/build/index.d.ts +1 -0
  58. package/build/index.js +98 -0
  59. package/build/schemas/account-management/account.d.ts +5324 -0
  60. package/build/schemas/account-management/account.js +366 -0
  61. package/build/schemas/analytics/analytics.d.ts +167 -0
  62. package/build/schemas/analytics/analytics.js +191 -0
  63. package/build/schemas/communication/messages.d.ts +1872 -0
  64. package/build/schemas/communication/messages.js +348 -0
  65. package/build/schemas/fulfillment/orders.d.ts +4655 -0
  66. package/build/schemas/fulfillment/orders.js +317 -0
  67. package/build/schemas/index.d.ts +2100 -0
  68. package/build/schemas/index.js +68 -0
  69. package/build/schemas/inventory-management/inventory.d.ts +6419 -0
  70. package/build/schemas/inventory-management/inventory.js +450 -0
  71. package/build/schemas/marketing/marketing.d.ts +14181 -0
  72. package/build/schemas/marketing/marketing.js +1088 -0
  73. package/build/schemas/metadata/metadata.d.ts +5259 -0
  74. package/build/schemas/metadata/metadata.js +614 -0
  75. package/build/schemas/other/other-apis.d.ts +257 -0
  76. package/build/schemas/other/other-apis.js +372 -0
  77. package/build/schemas/taxonomy/taxonomy.d.ts +215 -0
  78. package/build/schemas/taxonomy/taxonomy.js +571 -0
  79. package/build/scripts/auto-setup.d.ts +12 -0
  80. package/build/scripts/auto-setup.js +277 -0
  81. package/build/scripts/diagnostics.d.ts +8 -0
  82. package/build/scripts/diagnostics.js +299 -0
  83. package/build/scripts/download-specs.d.ts +1 -0
  84. package/build/scripts/download-specs.js +116 -0
  85. package/build/scripts/interactive-setup.d.ts +21 -0
  86. package/build/scripts/interactive-setup.js +723 -0
  87. package/build/server-http.d.ts +11 -0
  88. package/build/server-http.js +361 -0
  89. package/build/tools/definitions/account-with-schemas.d.ts +39 -0
  90. package/build/tools/definitions/account-with-schemas.js +170 -0
  91. package/build/tools/definitions/account.d.ts +12 -0
  92. package/build/tools/definitions/account.js +428 -0
  93. package/build/tools/definitions/analytics.d.ts +25 -0
  94. package/build/tools/definitions/analytics.js +66 -0
  95. package/build/tools/definitions/communication.d.ts +12 -0
  96. package/build/tools/definitions/communication.js +151 -0
  97. package/build/tools/definitions/fulfillment.d.ts +12 -0
  98. package/build/tools/definitions/fulfillment.js +326 -0
  99. package/build/tools/definitions/index.d.ts +25 -0
  100. package/build/tools/definitions/index.js +37 -0
  101. package/build/tools/definitions/inventory.d.ts +12 -0
  102. package/build/tools/definitions/inventory.js +429 -0
  103. package/build/tools/definitions/marketing.d.ts +12 -0
  104. package/build/tools/definitions/marketing.js +1095 -0
  105. package/build/tools/definitions/metadata.d.ts +12 -0
  106. package/build/tools/definitions/metadata.js +188 -0
  107. package/build/tools/definitions/other.d.ts +13 -0
  108. package/build/tools/definitions/other.js +309 -0
  109. package/build/tools/definitions/taxonomy.d.ts +25 -0
  110. package/build/tools/definitions/taxonomy.js +64 -0
  111. package/build/tools/definitions/token-management.d.ts +35 -0
  112. package/build/tools/definitions/token-management.js +103 -0
  113. package/build/tools/index.d.ts +11 -0
  114. package/build/tools/index.js +1003 -0
  115. package/build/tools/schemas.d.ts +14764 -0
  116. package/build/tools/schemas.js +667 -0
  117. package/build/tools/tool-definitions.d.ts +35 -0
  118. package/build/tools/tool-definitions.js +3534 -0
  119. package/build/types/application-settings/developerAnalyticsV1BetaOas3.d.ts +197 -0
  120. package/build/types/application-settings/developerAnalyticsV1BetaOas3.js +5 -0
  121. package/build/types/application-settings/developerClientRegistrationV1Oas3.d.ts +155 -0
  122. package/build/types/application-settings/developerClientRegistrationV1Oas3.js +5 -0
  123. package/build/types/application-settings/developerKeyManagementV1Oas3.d.ts +246 -0
  124. package/build/types/application-settings/developerKeyManagementV1Oas3.js +5 -0
  125. package/build/types/ebay-enums.d.ts +1204 -0
  126. package/build/types/ebay-enums.js +1330 -0
  127. package/build/types/ebay.d.ts +143 -0
  128. package/build/types/ebay.js +123 -0
  129. package/build/types/index.d.ts +6 -0
  130. package/build/types/index.js +10 -0
  131. package/build/types/sell-apps/account-management/sellAccountV1Oas3.d.ts +2579 -0
  132. package/build/types/sell-apps/account-management/sellAccountV1Oas3.js +5 -0
  133. package/build/types/sell-apps/analytics-and-report/sellAnalyticsV1Oas3.d.ts +446 -0
  134. package/build/types/sell-apps/analytics-and-report/sellAnalyticsV1Oas3.js +5 -0
  135. package/build/types/sell-apps/communication/commerceFeedbackV1BetaOas3.d.ts +705 -0
  136. package/build/types/sell-apps/communication/commerceFeedbackV1BetaOas3.js +5 -0
  137. package/build/types/sell-apps/communication/commerceMessageV1Oas3.d.ts +590 -0
  138. package/build/types/sell-apps/communication/commerceMessageV1Oas3.js +5 -0
  139. package/build/types/sell-apps/communication/commerceNotificationV1Oas3.d.ts +1276 -0
  140. package/build/types/sell-apps/communication/commerceNotificationV1Oas3.js +5 -0
  141. package/build/types/sell-apps/communication/sellNegotiationV1Oas3.d.ts +277 -0
  142. package/build/types/sell-apps/communication/sellNegotiationV1Oas3.js +5 -0
  143. package/build/types/sell-apps/listing-management/sellInventoryV1Oas3.d.ts +3133 -0
  144. package/build/types/sell-apps/listing-management/sellInventoryV1Oas3.js +5 -0
  145. package/build/types/sell-apps/listing-metadata/sellMetadataV1Oas3.d.ts +2289 -0
  146. package/build/types/sell-apps/listing-metadata/sellMetadataV1Oas3.js +5 -0
  147. package/build/types/sell-apps/markeitng-and-promotions/sellMarketingV1Oas3.d.ts +6650 -0
  148. package/build/types/sell-apps/markeitng-and-promotions/sellMarketingV1Oas3.js +5 -0
  149. package/build/types/sell-apps/markeitng-and-promotions/sellRecommendationV1Oas3.d.ts +172 -0
  150. package/build/types/sell-apps/markeitng-and-promotions/sellRecommendationV1Oas3.js +5 -0
  151. package/build/types/sell-apps/order-management/sellFulfillmentV1Oas3.d.ts +1869 -0
  152. package/build/types/sell-apps/order-management/sellFulfillmentV1Oas3.js +5 -0
  153. package/build/types/sell-apps/other-apis/commerceIdentityV1Oas3.d.ts +178 -0
  154. package/build/types/sell-apps/other-apis/commerceIdentityV1Oas3.js +5 -0
  155. package/build/types/sell-apps/other-apis/commerceTranslationV1BetaOas3.d.ts +128 -0
  156. package/build/types/sell-apps/other-apis/commerceTranslationV1BetaOas3.js +5 -0
  157. package/build/types/sell-apps/other-apis/commerceVeroV1Oas3.d.ts +417 -0
  158. package/build/types/sell-apps/other-apis/commerceVeroV1Oas3.js +5 -0
  159. package/build/types/sell-apps/other-apis/sellComplianceV1Oas3.d.ts +273 -0
  160. package/build/types/sell-apps/other-apis/sellComplianceV1Oas3.js +5 -0
  161. package/build/types/sell-apps/other-apis/sellEdeliveryInternationalShippingOas3.d.ts +2537 -0
  162. package/build/types/sell-apps/other-apis/sellEdeliveryInternationalShippingOas3.js +5 -0
  163. package/build/types/sell-apps/other-apis/sellMarketingV1Oas3.d.ts +6650 -0
  164. package/build/types/sell-apps/other-apis/sellMarketingV1Oas3.js +5 -0
  165. package/build/types/sell-apps/other-apis/sellRecommendationV1Oas3.d.ts +172 -0
  166. package/build/types/sell-apps/other-apis/sellRecommendationV1Oas3.js +5 -0
  167. package/build/utils/account-management/account.d.ts +1094 -0
  168. package/build/utils/account-management/account.js +831 -0
  169. package/build/utils/communication/feedback.d.ts +152 -0
  170. package/build/utils/communication/feedback.js +216 -0
  171. package/build/utils/communication/message.d.ts +174 -0
  172. package/build/utils/communication/message.js +242 -0
  173. package/build/utils/communication/negotiation.d.ts +123 -0
  174. package/build/utils/communication/negotiation.js +150 -0
  175. package/build/utils/communication/notification.d.ts +370 -0
  176. package/build/utils/communication/notification.js +369 -0
  177. package/build/utils/date-converter.d.ts +59 -0
  178. package/build/utils/date-converter.js +160 -0
  179. package/build/utils/llm-client-detector.d.ts +54 -0
  180. package/build/utils/llm-client-detector.js +318 -0
  181. package/build/utils/oauth-helper.d.ts +37 -0
  182. package/build/utils/oauth-helper.js +315 -0
  183. package/build/utils/order-management/dispute.d.ts +346 -0
  184. package/build/utils/order-management/dispute.js +369 -0
  185. package/build/utils/order-management/fulfillment.d.ts +200 -0
  186. package/build/utils/order-management/fulfillment.js +205 -0
  187. package/build/utils/other/compliance.d.ts +49 -0
  188. package/build/utils/other/compliance.js +76 -0
  189. package/build/utils/other/edelivery.d.ts +310 -0
  190. package/build/utils/other/edelivery.js +241 -0
  191. package/build/utils/other/identity.d.ts +13 -0
  192. package/build/utils/other/identity.js +13 -0
  193. package/build/utils/other/translation.d.ts +28 -0
  194. package/build/utils/other/translation.js +41 -0
  195. package/build/utils/other/vero.d.ts +61 -0
  196. package/build/utils/other/vero.js +90 -0
  197. package/build/utils/scope-helper.d.ts +49 -0
  198. package/build/utils/scope-helper.js +207 -0
  199. package/build/utils/security-checker.d.ts +46 -0
  200. package/build/utils/security-checker.js +248 -0
  201. package/build/utils/setup-validator.d.ts +25 -0
  202. package/build/utils/setup-validator.js +305 -0
  203. package/build/utils/token-utils.d.ts +40 -0
  204. package/build/utils/token-utils.js +40 -0
  205. package/package.json +115 -0
@@ -0,0 +1,723 @@
1
+ /**
2
+ * Interactive Setup for eBay API MCP Server - Complete Optimized Version
3
+ *
4
+ * Features:
5
+ * - Pre-flight security checks
6
+ * - First-time developer guidance
7
+ * - Interactive OAuth flow with local callback server
8
+ * - Scope selection and verification
9
+ * - Auto-generate access tokens
10
+ * - Multi-environment support
11
+ * - Enhanced LLM client detection and configuration
12
+ * - Docker setup option
13
+ * - Post-setup quick start guide
14
+ *
15
+ * Usage:
16
+ * npx ebay-mcp Interactive setup wizard
17
+ * npx ebay-mcp --help Show help
18
+ * npx ebay-mcp --diagnose Run diagnostics
19
+ * npx ebay-mcp --first-time First-time developer guide
20
+ */
21
+ /* eslint-disable @typescript-eslint/naming-convention */
22
+ /* eslint-disable @typescript-eslint/explicit-function-return-type */
23
+ /* eslint-disable n/no-process-exit */
24
+ import prompts from 'prompts';
25
+ import chalk from 'chalk';
26
+ import { readFileSync, writeFileSync, existsSync } from 'fs';
27
+ import { join, dirname } from 'path';
28
+ import { fileURLToPath } from 'url';
29
+ import { runSecurityChecks, displaySecurityResults, hasCriticalFailures, } from '../utils/security-checker.js';
30
+ import { displayFirstTimeDeveloperGuide, getRuNameHelp, interactiveOAuthFlow, displayManualOAuthInstructions, } from '../utils/oauth-helper.js';
31
+ import { displayScopeCategories, getRecommendedScopes, displayScopeVerification, } from '../utils/scope-helper.js';
32
+ import { detectLLMClients, configureLLMClient } from '../utils/llm-client-detector.js';
33
+ import { validateSetup, displayRecommendations } from '../utils/setup-validator.js';
34
+ import { EbaySellerApi } from '../api/index.js';
35
+ import { EbayOAuthClient } from '../auth/oauth.js';
36
+ const __filename = fileURLToPath(import.meta.url);
37
+ const __dirname = dirname(__filename);
38
+ const PROJECT_ROOT = join(__dirname, '../..');
39
+ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
40
+ // eBay Brand Colors
41
+ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
42
+ const ebayColors = {
43
+ red: chalk.hex('#E53238'),
44
+ blue: chalk.hex('#0064D2'),
45
+ yellow: chalk.hex('#F5AF02'),
46
+ green: chalk.hex('#85B716'),
47
+ };
48
+ function parseArgs() {
49
+ const args = process.argv.slice(2);
50
+ const envArg = args.find((arg) => arg.startsWith('--env='));
51
+ return {
52
+ help: args.includes('--help') || args.includes('-h'),
53
+ diagnose: args.includes('--diagnose') || args.includes('-d'),
54
+ firstTime: args.includes('--first-time') || args.includes('-f'),
55
+ skipChecks: args.includes('--skip-checks'),
56
+ environment: envArg
57
+ ? envArg.split('=')[1]
58
+ : undefined,
59
+ };
60
+ }
61
+ function showHelp() {
62
+ console.log(chalk.bold.cyan('\n๐Ÿ“– eBay API MCP Server Setup Help\n'));
63
+ console.log(chalk.white('Usage:'));
64
+ console.log(chalk.gray(' npx ebay-mcp [options]\n'));
65
+ console.log(chalk.white('Options:'));
66
+ console.log(chalk.yellow(' --help, -h ') + chalk.gray('Show this help message'));
67
+ console.log(chalk.yellow(' --diagnose, -d ') + chalk.gray('Run system diagnostics'));
68
+ console.log(chalk.yellow(' --first-time, -f ') + chalk.gray('Show first-time developer guide'));
69
+ console.log(chalk.yellow(' --skip-checks ') + chalk.gray('Skip pre-flight security checks'));
70
+ console.log(chalk.yellow(' --env=ENV ') +
71
+ chalk.gray('Set environment (sandbox|production)'));
72
+ console.log(chalk.yellow(' (no options) ') + chalk.gray('Run interactive setup wizard\n'));
73
+ console.log(chalk.white('Examples:'));
74
+ console.log(chalk.gray(' npx ebay-mcp # Interactive wizard'));
75
+ console.log(chalk.gray(' npx ebay-mcp --first-time # First-time guide'));
76
+ console.log(chalk.gray(' npx ebay-mcp --diagnose # Run diagnostics'));
77
+ console.log(chalk.gray(' npx ebay-mcp --env=production # Setup for production\n'));
78
+ console.log(chalk.white('Learn more:'));
79
+ console.log(chalk.blue(' https://github.com/YosefHayim/ebay-mcp#readme\n'));
80
+ }
81
+ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
82
+ // eBay Logo and Branding
83
+ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
84
+ function createClickableLink(text, url) {
85
+ return `\x1b]8;;${url}\x1b\\${text}\x1b]8;;\x1b\\`;
86
+ }
87
+ const EBAY_LOGO = `
88
+ ${ebayColors.red('โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—')}${ebayColors.blue('โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— ')} ${ebayColors.yellow('โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— ')}${ebayColors.green('โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•—')}
89
+ ${ebayColors.red('โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•')}${ebayColors.blue('โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—')}${ebayColors.yellow('โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—')}${ebayColors.green('โ•šโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•”โ•')}
90
+ ${ebayColors.red('โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— ')}${ebayColors.blue('โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•')}${ebayColors.yellow('โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•‘')}${ebayColors.green(' โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ• ')}
91
+ ${ebayColors.red('โ–ˆโ–ˆโ•”โ•โ•โ• ')}${ebayColors.blue('โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—')}${ebayColors.yellow('โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•‘')}${ebayColors.green(' โ•šโ–ˆโ–ˆโ•”โ• ')}
92
+ ${ebayColors.red('โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—')}${ebayColors.blue('โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•')}${ebayColors.yellow('โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ•‘')}${ebayColors.green(' โ–ˆโ–ˆโ•‘ ')}
93
+ ${ebayColors.red('โ•šโ•โ•โ•โ•โ•โ•โ•')}${ebayColors.blue('โ•šโ•โ•โ•โ•โ•โ• ')}${ebayColors.yellow('โ•šโ•โ• โ•šโ•โ•')}${ebayColors.green(' โ•šโ•โ• ')}
94
+
95
+ ${chalk.bold.white('API MCP Server Setup')}
96
+ `;
97
+ const CREATOR_CREDIT = `
98
+ Creator: ${chalk.bold('YosefHayim')}
99
+ ${createClickableLink(chalk.underline('linkedin.com/in/yosef-hayim-sabag'), 'https://www.linkedin.com/in/yosef-hayim-sabag/')}
100
+ `;
101
+ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
102
+ // Helper Functions
103
+ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
104
+ function displayLogo() {
105
+ console.clear();
106
+ console.log(EBAY_LOGO);
107
+ console.log(CREATOR_CREDIT);
108
+ }
109
+ function validateRequired(value) {
110
+ return value.trim().length > 0 || 'This field is required';
111
+ }
112
+ function loadExistingConfig() {
113
+ const envPath = join(PROJECT_ROOT, '.env');
114
+ const config = {};
115
+ if (existsSync(envPath)) {
116
+ const envContent = readFileSync(envPath, 'utf-8');
117
+ const lines = envContent.split('\n');
118
+ for (const line of lines) {
119
+ if (line.trim() && !line.startsWith('#')) {
120
+ const [key, ...valueParts] = line.split('=');
121
+ const value = valueParts.join('=').trim();
122
+ if (key && value && !value.includes('_here')) {
123
+ config[key.trim()] = value;
124
+ }
125
+ }
126
+ }
127
+ }
128
+ return config;
129
+ }
130
+ function generateEnvFile(config, environment) {
131
+ const envPath = join(PROJECT_ROOT, `.env${environment === 'sandbox' ? '' : `.${environment}`}`);
132
+ const content = `# eBay API MCP Server Configuration
133
+ # Generated on ${new Date().toISOString()}
134
+ # Environment: ${environment}
135
+
136
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
137
+ # eBay App Credentials (Required)
138
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
139
+
140
+ EBAY_CLIENT_ID=${config.EBAY_CLIENT_ID || 'your_client_id_here'}
141
+ EBAY_CLIENT_SECRET=${config.EBAY_CLIENT_SECRET || 'your_client_secret_here'}
142
+ EBAY_REDIRECT_URI=${config.EBAY_REDIRECT_URI || 'http://localhost:3000/oauth/callback'}
143
+
144
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
145
+ # Environment (sandbox or production)
146
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
147
+
148
+ EBAY_ENVIRONMENT=${config.EBAY_ENVIRONMENT || 'sandbox'}
149
+
150
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
151
+ # User Tokens (Auto-generated from refresh token)
152
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
153
+ # The refresh token is the only token you need to provide manually.
154
+ # Access tokens are automatically generated and refreshed.
155
+
156
+ EBAY_USER_REFRESH_TOKEN=${config.EBAY_USER_REFRESH_TOKEN || ''}
157
+ EBAY_USER_ACCESS_TOKEN=${config.EBAY_USER_ACCESS_TOKEN || ''}
158
+ EBAY_APP_ACCESS_TOKEN=${config.EBAY_APP_ACCESS_TOKEN || ''}
159
+
160
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
161
+ # Logging (Optional)
162
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
163
+ LOG_LEVEL=${config.LOG_LEVEL || 'info'}
164
+ `;
165
+ writeFileSync(envPath, content, 'utf-8');
166
+ console.log(chalk.green(`โœ“ Configuration saved to ${envPath}`));
167
+ }
168
+ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
169
+ // Token Acquisition & Validation
170
+ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
171
+ async function acquireRefreshToken(config, useInteractiveFlow) {
172
+ if (useInteractiveFlow) {
173
+ console.log(chalk.bold.cyan('\n๐Ÿ” Starting Interactive OAuth Flow\n'));
174
+ const scopes = getRecommendedScopes(config.environment);
175
+ const authCode = await interactiveOAuthFlow(config, scopes);
176
+ if (!authCode) {
177
+ return null;
178
+ }
179
+ // Exchange code for tokens
180
+ console.log(chalk.cyan('\n๐Ÿ”„ Exchanging authorization code for tokens...\n'));
181
+ try {
182
+ const oauthClient = new EbayOAuthClient(config);
183
+ const tokenData = await oauthClient.exchangeCodeForToken(authCode);
184
+ console.log(chalk.green('โœ“ Successfully obtained tokens!\n'));
185
+ return tokenData.refresh_token;
186
+ }
187
+ catch (error) {
188
+ console.log(chalk.red(`โœ— Failed to exchange code: ${error instanceof Error ? error.message : error}\n`));
189
+ return null;
190
+ }
191
+ }
192
+ else {
193
+ // Manual flow
194
+ displayManualOAuthInstructions(config.clientId, config.redirectUri || 'http://localhost:3000/oauth/callback', config.environment, getRecommendedScopes(config.environment));
195
+ const response = await prompts({
196
+ type: 'text',
197
+ name: 'refreshToken',
198
+ message: 'Paste your refresh token here:',
199
+ validate: (value) => {
200
+ if (!value || value.trim() === '') {
201
+ return 'Refresh token is required';
202
+ }
203
+ const cleanValue = value.trim().replace(/^["']|["']$/g, '');
204
+ if (!cleanValue.startsWith('v^1.1#')) {
205
+ return 'Token should start with "v^1.1#"';
206
+ }
207
+ return true;
208
+ },
209
+ });
210
+ if (!response.refreshToken) {
211
+ return null;
212
+ }
213
+ return response.refreshToken.trim().replace(/^["']|["']$/g, '');
214
+ }
215
+ }
216
+ async function validateAndGenerateTokens(config) {
217
+ console.log(chalk.bold.cyan('\n๐Ÿ”„ Validating Credentials & Generating Tokens...\n'));
218
+ try {
219
+ const ebayConfig = {
220
+ clientId: config.EBAY_CLIENT_ID,
221
+ clientSecret: config.EBAY_CLIENT_SECRET,
222
+ redirectUri: config.EBAY_REDIRECT_URI,
223
+ environment: (config.EBAY_ENVIRONMENT || 'sandbox'),
224
+ };
225
+ // Set up OAuth client with refresh token
226
+ const oauthClient = new EbayOAuthClient(ebayConfig);
227
+ // Set the refresh token
228
+ if (config.EBAY_USER_REFRESH_TOKEN) {
229
+ // Manually set tokens to trigger initialization
230
+ process.env.EBAY_USER_REFRESH_TOKEN = config.EBAY_USER_REFRESH_TOKEN;
231
+ process.env.EBAY_USER_ACCESS_TOKEN = '';
232
+ console.log(chalk.cyan(' โ†’ Initializing OAuth client...'));
233
+ await oauthClient.initialize();
234
+ // Get tokens (this will auto-refresh if needed)
235
+ console.log(chalk.cyan(' โ†’ Refreshing access token from refresh token...'));
236
+ const accessToken = await oauthClient.getAccessToken();
237
+ // Store the generated access token
238
+ config.EBAY_USER_ACCESS_TOKEN = accessToken;
239
+ console.log(chalk.green(' โœ“ Access token generated successfully'));
240
+ // Generate app access token
241
+ console.log(chalk.cyan(' โ†’ Generating app access token...'));
242
+ const appToken = await oauthClient.getOrRefreshAppAccessToken();
243
+ config.EBAY_APP_ACCESS_TOKEN = appToken;
244
+ console.log(chalk.green(' โœ“ App access token generated successfully'));
245
+ // Test with Identity API
246
+ console.log(chalk.cyan(' โ†’ Verifying credentials with eBay Identity API...'));
247
+ const api = new EbaySellerApi(ebayConfig);
248
+ await api.initialize();
249
+ const userInfo = await api.identity.getUser();
250
+ if (userInfo) {
251
+ console.log(chalk.green('\nโœ“ Successfully validated credentials!\n'));
252
+ console.log(chalk.bold.white('๐Ÿ“‹ Your eBay Account Information:\n'));
253
+ console.log(userInfo);
254
+ console.log('');
255
+ }
256
+ // Display scope verification
257
+ const authClient = api.getAuthClient();
258
+ const tokenInfo = authClient.getTokenInfo();
259
+ if (tokenInfo.scopeInfo) {
260
+ displayScopeVerification(tokenInfo.scopeInfo.tokenScopes, ebayConfig.environment);
261
+ }
262
+ return true;
263
+ }
264
+ else {
265
+ console.log(chalk.yellow('โš ๏ธ No refresh token provided, skipping validation\n'));
266
+ return false;
267
+ }
268
+ }
269
+ catch (error) {
270
+ console.log(chalk.red('\nโœ— Validation failed\n'));
271
+ if (error instanceof Error) {
272
+ console.log(chalk.yellow(` Error: ${error.message}\n`));
273
+ if (error.message.includes('401') || error.message.includes('Unauthorized')) {
274
+ console.log(chalk.gray(' Possible causes:'));
275
+ console.log(chalk.gray(' โ€ข Invalid or expired refresh token'));
276
+ console.log(chalk.gray(' โ€ข Token from different environment (sandbox vs production)'));
277
+ console.log(chalk.gray(' โ€ข Incorrect client credentials\n'));
278
+ }
279
+ }
280
+ const retry = await prompts({
281
+ type: 'confirm',
282
+ name: 'retry',
283
+ message: 'Would you like to retry with different credentials?',
284
+ initial: true,
285
+ });
286
+ return retry.retry === true;
287
+ }
288
+ }
289
+ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
290
+ // LLM Client Detection and Configuration
291
+ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
292
+ async function detectAndConfigureLLMClients() {
293
+ console.log(chalk.bold.cyan('\nโ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”'));
294
+ console.log(chalk.bold.cyan('โ”‚ ๐Ÿค– LLM Client Detection & Configuration โ”‚'));
295
+ console.log(chalk.bold.cyan('โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜\n'));
296
+ const clients = detectLLMClients();
297
+ const detectedClients = clients.filter((c) => c.detected);
298
+ if (detectedClients.length === 0) {
299
+ console.log(chalk.yellow('โš ๏ธ No compatible LLM clients detected on your system.\n'));
300
+ console.log(chalk.white('Supported clients:'));
301
+ console.log(chalk.gray(' โ€ข Claude Desktop (Anthropic\'s desktop app)'));
302
+ console.log(chalk.gray(' โ€ข Cline (VSCode extension)'));
303
+ console.log(chalk.gray(' โ€ข Continue.dev (VSCode/JetBrains extension)\n'));
304
+ console.log(chalk.cyan('๐Ÿ’ก You can manually configure your MCP client later.'));
305
+ console.log(chalk.gray(' See: https://github.com/YosefHayim/ebay-mcp#setup\n'));
306
+ return;
307
+ }
308
+ const clientCount = detectedClients.length;
309
+ const plural = clientCount === 1 ? 'client' : 'clients';
310
+ console.log(chalk.green.bold(`โœ“ Found ${clientCount} compatible ${plural} on your system:\n`));
311
+ // Display each client in a nice box
312
+ for (const client of detectedClients) {
313
+ const boxWidth = 61;
314
+ const topBorder = chalk.gray('โ”Œโ”€') + chalk.white(client.displayName) + chalk.gray('โ”€'.repeat(boxWidth - client.displayName.length - 3) + 'โ”');
315
+ console.log(topBorder);
316
+ // Status line
317
+ const statusIcon = chalk.green('โœ“');
318
+ const statusText = 'Installed';
319
+ console.log(chalk.gray('โ”‚ ') + chalk.gray('Status: ') + statusIcon + ' ' + chalk.white(statusText) + ' '.repeat(boxWidth - 23) + chalk.gray('โ”‚'));
320
+ // Config status line
321
+ const configIcon = client.configExists ? chalk.yellow('โš ') : chalk.gray('โ—‹');
322
+ const configText = client.configExists ? chalk.yellow('Already configured') : chalk.gray('Not configured');
323
+ const configPadding = client.configExists ? 39 : 43;
324
+ console.log(chalk.gray('โ”‚ ') + chalk.gray('Config: ') + configIcon + ' ' + configText + ' '.repeat(boxWidth - configPadding) + chalk.gray('โ”‚'));
325
+ // Path line (truncated if too long)
326
+ const maxPathLength = boxWidth - 14;
327
+ let displayPath = client.configPath;
328
+ if (displayPath.length > maxPathLength) {
329
+ displayPath = '...' + displayPath.substring(displayPath.length - maxPathLength + 3);
330
+ }
331
+ console.log(chalk.gray('โ”‚ ') + chalk.gray('Path: ') + chalk.dim(displayPath) + ' '.repeat(boxWidth - displayPath.length - 13) + chalk.gray('โ”‚'));
332
+ console.log(chalk.gray('โ””' + 'โ”€'.repeat(boxWidth - 1) + 'โ”˜\n'));
333
+ }
334
+ // Ask user which clients to configure
335
+ console.log(chalk.white.bold('Configure eBay MCP for these clients?\n'));
336
+ console.log(chalk.gray(' ๐Ÿ’ก Recommended: Select clients that are ') + chalk.yellow('not configured') + chalk.gray(' yet'));
337
+ console.log(chalk.gray(' ๐Ÿ“ Use ') + chalk.cyan('Space') + chalk.gray(' to select, ') + chalk.cyan('Enter') + chalk.gray(' to confirm\n'));
338
+ const response = await prompts({
339
+ type: 'multiselect',
340
+ name: 'selectedClients',
341
+ message: 'Select clients to configure:',
342
+ choices: detectedClients.map((client) => {
343
+ const statusBadge = client.configExists
344
+ ? chalk.yellow(' [Already configured]')
345
+ : chalk.green(' [Recommended]');
346
+ return {
347
+ title: client.displayName + statusBadge,
348
+ value: client.name,
349
+ selected: !client.configExists, // Auto-select unconfigured clients
350
+ };
351
+ }),
352
+ hint: 'โ† โ†’ or Space to toggle โ€ข Enter to confirm',
353
+ instructions: false,
354
+ });
355
+ if (!response.selectedClients || response.selectedClients.length === 0) {
356
+ console.log(chalk.gray('\nโญ๏ธ Skipping LLM client configuration.\n'));
357
+ return;
358
+ }
359
+ // Configure selected clients
360
+ console.log(chalk.bold.cyan('\nโ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”'));
361
+ console.log(chalk.bold.cyan('โ”‚ โš™๏ธ Configuring Selected Clients โ”‚'));
362
+ console.log(chalk.bold.cyan('โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜\n'));
363
+ for (const clientName of response.selectedClients) {
364
+ const client = detectedClients.find((c) => c.name === clientName);
365
+ if (!client)
366
+ continue;
367
+ console.log(chalk.cyan(`Configuring ${client.displayName}...`));
368
+ const success = configureLLMClient(clientName, PROJECT_ROOT);
369
+ if (success) {
370
+ console.log(chalk.green(` โœ“ Successfully configured ${client.displayName}`));
371
+ console.log(chalk.gray(` ๐Ÿ“ Config file: ${client.configPath}`));
372
+ console.log(chalk.dim(` ๐Ÿ”— MCP server added to configuration\n`));
373
+ }
374
+ else {
375
+ console.log(chalk.red(` โœ— Failed to configure ${client.displayName}`));
376
+ console.log(chalk.yellow(` โš ๏ธ Manual setup required`));
377
+ console.log(chalk.gray(` ๐Ÿ“„ Config path: ${client.configPath}\n`));
378
+ }
379
+ }
380
+ // Success message
381
+ console.log(chalk.bold.green('โœจ LLM client configuration complete!\n'));
382
+ console.log(chalk.white.bold('๐Ÿ“Œ Next Steps:\n'));
383
+ console.log(chalk.gray(' 1. ') + chalk.white('Restart') + chalk.gray(' your LLM client(s) to load the new configuration'));
384
+ console.log(chalk.gray(' 2. The ') + chalk.cyan('eBay MCP server') + chalk.gray(' should appear in the MCP tools list'));
385
+ console.log(chalk.gray(' 3. Try asking: ') + chalk.cyan('"Show me my eBay user information"') + chalk.gray('\n'));
386
+ }
387
+ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
388
+ // Docker Setup
389
+ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
390
+ async function setupDocker() {
391
+ const wantDocker = await prompts({
392
+ type: 'confirm',
393
+ name: 'value',
394
+ message: 'Would you like to generate Docker configuration?',
395
+ initial: false,
396
+ });
397
+ if (!wantDocker.value) {
398
+ return;
399
+ }
400
+ console.log(chalk.bold.cyan('\n๐Ÿณ Generating Docker Configuration...\n'));
401
+ const dockerComposePath = join(PROJECT_ROOT, 'docker-compose.yml');
402
+ const dockerComposeContent = `version: '3.8'
403
+
404
+ services:
405
+ ebay-mcp-server:
406
+ build:
407
+ context: .
408
+ dockerfile: Dockerfile
409
+ container_name: ebay-mcp-server
410
+ restart: unless-stopped
411
+ env_file:
412
+ - .env
413
+ ports:
414
+ - "3000:3000"
415
+ healthcheck:
416
+ test: ["CMD", "node", "-e", "process.exit(0)"]
417
+ interval: 30s
418
+ timeout: 10s
419
+ retries: 3
420
+ start_period: 40s
421
+ volumes:
422
+ - ./logs:/app/logs
423
+ networks:
424
+ - ebay-mcp-network
425
+
426
+ networks:
427
+ ebay-mcp-network:
428
+ driver: bridge
429
+ `;
430
+ writeFileSync(dockerComposePath, dockerComposeContent, 'utf-8');
431
+ console.log(chalk.green(` โœ“ Generated docker-compose.yml`));
432
+ console.log(chalk.bold.white('\n๐Ÿ“– Docker Usage:\n'));
433
+ console.log(chalk.gray(' Build and start: ') + chalk.cyan('docker-compose up -d'));
434
+ console.log(chalk.gray(' View logs: ') + chalk.cyan('docker-compose logs -f'));
435
+ console.log(chalk.gray(' Stop: ') + chalk.cyan('docker-compose down'));
436
+ console.log(chalk.gray(' Rebuild: ') + chalk.cyan('docker-compose up -d --build\n'));
437
+ }
438
+ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
439
+ // Post-Setup Quick Start
440
+ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
441
+ function displayQuickStart() {
442
+ console.log(chalk.bold.cyan('\n๐Ÿš€ Quick Start Guide\n'));
443
+ console.log(chalk.bold.white('Try these commands in your LLM client:\n'));
444
+ console.log(chalk.cyan(' ๐Ÿ’ฌ "Get my eBay user info"'));
445
+ console.log(chalk.cyan(' ๐Ÿ“ฆ "Show my active inventory listings"'));
446
+ console.log(chalk.cyan(' ๐Ÿ“Š "Get my sales analytics for this month"'));
447
+ console.log(chalk.cyan(' ๐ŸŽฏ "Help me create a new listing"\n'));
448
+ console.log(chalk.bold.white('Available Tools:\n'));
449
+ console.log(chalk.gray(' โ€ข 230+ eBay API tools across 8 categories'));
450
+ console.log(chalk.gray(' โ€ข Inventory Management'));
451
+ console.log(chalk.gray(' โ€ข Order Fulfillment'));
452
+ console.log(chalk.gray(' โ€ข Marketing & Promotions'));
453
+ console.log(chalk.gray(' โ€ข Analytics & Reports'));
454
+ console.log(chalk.gray(' โ€ข And more...\n'));
455
+ console.log(chalk.bold.white('Resources:\n'));
456
+ console.log(chalk.gray(' ๐Ÿ“– Documentation: ') +
457
+ chalk.blue.underline('https://github.com/YosefHayim/ebay-mcp#readme'));
458
+ console.log(chalk.gray(' ๐Ÿ› Report Issues: ') +
459
+ chalk.blue.underline('https://github.com/YosefHayim/ebay-mcp/issues'));
460
+ console.log(chalk.gray(' ๐Ÿ’ฌ Get Support: ') +
461
+ chalk.blue.underline('https://github.com/YosefHayim/ebay-mcp/discussions\n'));
462
+ }
463
+ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
464
+ // Main Setup Flow
465
+ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
466
+ async function runInteractiveSetup(args) {
467
+ displayLogo();
468
+ // Pre-flight security checks
469
+ if (!args.skipChecks) {
470
+ console.log(chalk.bold.cyan('\n๐Ÿ”’ Running Pre-Flight Security Checks...\n'));
471
+ const securityResults = await runSecurityChecks(PROJECT_ROOT);
472
+ displaySecurityResults(securityResults);
473
+ if (hasCriticalFailures(securityResults)) {
474
+ const continueAnyway = await prompts({
475
+ type: 'confirm',
476
+ name: 'value',
477
+ message: 'Critical issues found. Continue anyway?',
478
+ initial: false,
479
+ });
480
+ if (!continueAnyway.value) {
481
+ console.log(chalk.yellow('\nโš ๏ธ Setup cancelled. Please fix critical issues first.\n'));
482
+ process.exit(1);
483
+ }
484
+ }
485
+ }
486
+ // Check if user needs first-time guide
487
+ const existingConfig = loadExistingConfig();
488
+ const hasExisting = Object.keys(existingConfig).length > 0;
489
+ if (!hasExisting) {
490
+ const needsGuide = await prompts({
491
+ type: 'confirm',
492
+ name: 'value',
493
+ message: 'Is this your first time setting up eBay Developer credentials?',
494
+ initial: false,
495
+ });
496
+ if (needsGuide.value) {
497
+ displayFirstTimeDeveloperGuide();
498
+ await prompts({
499
+ type: 'text',
500
+ name: 'continue',
501
+ message: 'Press Enter when ready to continue...',
502
+ });
503
+ console.clear();
504
+ displayLogo();
505
+ }
506
+ }
507
+ else {
508
+ console.log(chalk.cyan('\n๐Ÿ“‹ Found existing configuration.\n'));
509
+ }
510
+ // Environment selection
511
+ let environment = args.environment || existingConfig.EBAY_ENVIRONMENT || 'sandbox';
512
+ if (!args.environment) {
513
+ const envResponse = await prompts({
514
+ type: 'select',
515
+ name: 'environment',
516
+ message: 'Select eBay environment:',
517
+ choices: [
518
+ { title: '๐Ÿงช Sandbox (Development & Testing)', value: 'sandbox' },
519
+ { title: '๐Ÿš€ Production (Live Trading)', value: 'production' },
520
+ ],
521
+ initial: environment === 'production' ? 1 : 0,
522
+ });
523
+ if (!envResponse.environment) {
524
+ console.log(chalk.yellow('\nโš ๏ธ Setup cancelled.\n'));
525
+ process.exit(0);
526
+ }
527
+ environment = envResponse.environment;
528
+ }
529
+ console.log(chalk.bold.cyan(`\nโš™๏ธ Setting up for: ${environment.toUpperCase()}\n`));
530
+ // Collect credentials
531
+ const credentials = await prompts([
532
+ {
533
+ type: 'text',
534
+ name: 'EBAY_CLIENT_ID',
535
+ message: 'eBay Client ID (App ID):',
536
+ initial: existingConfig.EBAY_CLIENT_ID || '',
537
+ validate: validateRequired,
538
+ },
539
+ {
540
+ type: 'text',
541
+ name: 'EBAY_CLIENT_SECRET',
542
+ message: 'eBay Client Secret (Cert ID):',
543
+ initial: existingConfig.EBAY_CLIENT_SECRET || '',
544
+ validate: validateRequired,
545
+ },
546
+ {
547
+ type: 'text',
548
+ name: 'EBAY_REDIRECT_URI',
549
+ message: 'eBay Redirect URI (RuName):',
550
+ initial: existingConfig.EBAY_REDIRECT_URI || 'http://localhost:3000/oauth/callback',
551
+ validate: validateRequired,
552
+ },
553
+ ]);
554
+ if (!credentials.EBAY_CLIENT_ID) {
555
+ console.log(chalk.yellow('\nโš ๏ธ Setup cancelled.\n'));
556
+ process.exit(0);
557
+ }
558
+ // Need help with RuName?
559
+ const needsRuNameHelp = await prompts({
560
+ type: 'confirm',
561
+ name: 'value',
562
+ message: 'Need help understanding RuName (Redirect URI)?',
563
+ initial: false,
564
+ });
565
+ if (needsRuNameHelp.value) {
566
+ console.log(getRuNameHelp());
567
+ await prompts({
568
+ type: 'text',
569
+ name: 'continue',
570
+ message: 'Press Enter to continue...',
571
+ });
572
+ }
573
+ // Token acquisition
574
+ console.log(chalk.bold.cyan('\n๐Ÿ”‘ User Token Setup\n'));
575
+ console.log(chalk.white('You need a refresh token to access user-specific APIs.\n'));
576
+ // Show scope information
577
+ const viewScopes = await prompts({
578
+ type: 'confirm',
579
+ name: 'value',
580
+ message: 'Would you like to see available OAuth scopes?',
581
+ initial: false,
582
+ });
583
+ if (viewScopes.value) {
584
+ displayScopeCategories();
585
+ }
586
+ const tokenMethod = await prompts({
587
+ type: 'select',
588
+ name: 'method',
589
+ message: 'How would you like to obtain your refresh token?',
590
+ choices: [
591
+ { title: '๐Ÿ”„ Interactive OAuth Flow (Recommended)', value: 'interactive' },
592
+ { title: '๐Ÿ“ Manual OAuth Flow (I\'ll get it myself)', value: 'manual' },
593
+ { title: 'โœ๏ธ I already have a refresh token', value: 'existing' },
594
+ { title: 'โญ๏ธ Skip (configure later)', value: 'skip' },
595
+ ],
596
+ initial: 0,
597
+ });
598
+ let refreshToken = existingConfig.EBAY_USER_REFRESH_TOKEN || '';
599
+ const ebayConfig = {
600
+ clientId: credentials.EBAY_CLIENT_ID,
601
+ clientSecret: credentials.EBAY_CLIENT_SECRET,
602
+ redirectUri: credentials.EBAY_REDIRECT_URI,
603
+ environment: environment,
604
+ };
605
+ if (tokenMethod.method === 'interactive' || tokenMethod.method === 'manual') {
606
+ const token = await acquireRefreshToken(ebayConfig, tokenMethod.method === 'interactive');
607
+ if (token) {
608
+ refreshToken = token;
609
+ }
610
+ else {
611
+ console.log(chalk.yellow('\nโš ๏ธ Could not acquire refresh token.\n'));
612
+ }
613
+ }
614
+ else if (tokenMethod.method === 'existing') {
615
+ const existingToken = await prompts({
616
+ type: 'text',
617
+ name: 'token',
618
+ message: 'Paste your refresh token:',
619
+ initial: refreshToken,
620
+ validate: (value) => {
621
+ if (!value || value.trim() === '') {
622
+ return 'Refresh token is required';
623
+ }
624
+ const cleanValue = value.trim().replace(/^["']|["']$/g, '');
625
+ if (!cleanValue.startsWith('v^1.1#')) {
626
+ return 'Token should start with "v^1.1#"';
627
+ }
628
+ return true;
629
+ },
630
+ });
631
+ if (existingToken.token) {
632
+ refreshToken = existingToken.token.trim().replace(/^["']|["']$/g, '');
633
+ }
634
+ }
635
+ // Build configuration object
636
+ const config = {
637
+ EBAY_CLIENT_ID: credentials.EBAY_CLIENT_ID,
638
+ EBAY_CLIENT_SECRET: credentials.EBAY_CLIENT_SECRET,
639
+ EBAY_REDIRECT_URI: credentials.EBAY_REDIRECT_URI,
640
+ EBAY_ENVIRONMENT: environment,
641
+ EBAY_USER_REFRESH_TOKEN: refreshToken,
642
+ EBAY_USER_ACCESS_TOKEN: '',
643
+ EBAY_APP_ACCESS_TOKEN: '',
644
+ LOG_LEVEL: existingConfig.LOG_LEVEL || 'info',
645
+ };
646
+ // Validate and generate tokens
647
+ if (refreshToken) {
648
+ const validated = await validateAndGenerateTokens(config);
649
+ if (!validated) {
650
+ console.log(chalk.yellow('\nโš ๏ธ Setup will continue but tokens may not be valid.\n'));
651
+ }
652
+ }
653
+ else {
654
+ console.log(chalk.yellow('\nโš ๏ธ No refresh token configured. Some APIs will not be available.\n'));
655
+ }
656
+ // Review configuration
657
+ console.log(chalk.bold.cyan('\n๐Ÿ“‹ Configuration Review:\n'));
658
+ console.log(` ${chalk.gray('Client ID:')} ${config.EBAY_CLIENT_ID}`);
659
+ console.log(` ${chalk.gray('Client Secret:')} ${'*'.repeat(Math.min(config.EBAY_CLIENT_SECRET.length, 20))}`);
660
+ console.log(` ${chalk.gray('Redirect URI:')} ${config.EBAY_REDIRECT_URI}`);
661
+ console.log(` ${chalk.gray('Environment:')} ${chalk.bold(config.EBAY_ENVIRONMENT)}`);
662
+ console.log(` ${chalk.gray('User Refresh Token:')} ${config.EBAY_USER_REFRESH_TOKEN ? chalk.green('โœ“ Configured') : chalk.yellow('โœ— Not set')}`);
663
+ console.log(` ${chalk.gray('User Access Token:')} ${config.EBAY_USER_ACCESS_TOKEN ? chalk.green('โœ“ Generated') : chalk.yellow('โœ— Not generated')}`);
664
+ console.log(` ${chalk.gray('App Access Token:')} ${config.EBAY_APP_ACCESS_TOKEN ? chalk.green('โœ“ Generated') : chalk.yellow('โœ— Not generated')}\n`);
665
+ const confirmation = await prompts({
666
+ type: 'confirm',
667
+ name: 'confirm',
668
+ message: 'Save this configuration?',
669
+ initial: true,
670
+ });
671
+ if (!confirmation.confirm) {
672
+ console.log(chalk.yellow('\nโš ๏ธ Configuration not saved.\n'));
673
+ process.exit(0);
674
+ }
675
+ // Save .env file
676
+ generateEnvFile(config, environment);
677
+ // Configure LLM clients
678
+ await detectAndConfigureLLMClients();
679
+ // Docker setup
680
+ await setupDocker();
681
+ // Run final validation
682
+ console.log(chalk.bold.cyan('\n๐Ÿงช Running Final Validation...\n'));
683
+ const summary = await validateSetup(PROJECT_ROOT);
684
+ displayRecommendations(summary);
685
+ // Display quick start guide
686
+ displayQuickStart();
687
+ console.log(chalk.bold.green('โœ… Setup complete!\n'));
688
+ console.log(chalk.gray('Next steps:'));
689
+ console.log(chalk.gray(' 1. Restart your LLM client (Claude Desktop, Cline, etc.)'));
690
+ console.log(chalk.gray(' 2. The eBay MCP server should now be available'));
691
+ console.log(chalk.gray(' 3. Try the commands in the Quick Start guide above\n'));
692
+ console.log(chalk.bold.white('๐ŸŽ‰ Happy selling on eBay!\n'));
693
+ }
694
+ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
695
+ // Main Entry Point
696
+ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
697
+ async function main() {
698
+ const args = parseArgs();
699
+ if (args.help) {
700
+ showHelp();
701
+ process.exit(0);
702
+ }
703
+ if (args.firstTime) {
704
+ displayFirstTimeDeveloperGuide();
705
+ process.exit(0);
706
+ }
707
+ if (args.diagnose) {
708
+ // Diagnostics is handled by a separate script
709
+ console.log(chalk.cyan('Run diagnostics with: npm run diagnose\n'));
710
+ process.exit(0);
711
+ }
712
+ await runInteractiveSetup(args);
713
+ }
714
+ // Handle Ctrl+C gracefully
715
+ process.on('SIGINT', () => {
716
+ console.log(chalk.yellow('\n\nโš ๏ธ Setup interrupted by user.\n'));
717
+ process.exit(0);
718
+ });
719
+ // Run main
720
+ main().catch((error) => {
721
+ console.error(chalk.red('\nโŒ Setup failed:'), error);
722
+ process.exit(1);
723
+ });