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.
- package/LICENSE +201 -0
- package/README.md +586 -0
- package/build/api/account-management/account.d.ts +216 -0
- package/build/api/account-management/account.js +305 -0
- package/build/api/analytics-and-report/analytics.d.ts +33 -0
- package/build/api/analytics-and-report/analytics.js +102 -0
- package/build/api/client.d.ts +89 -0
- package/build/api/client.js +343 -0
- package/build/api/communication/feedback.d.ts +45 -0
- package/build/api/communication/feedback.js +119 -0
- package/build/api/communication/message.d.ts +55 -0
- package/build/api/communication/message.js +131 -0
- package/build/api/communication/negotiation.d.ts +39 -0
- package/build/api/communication/negotiation.js +97 -0
- package/build/api/communication/notification.d.ts +128 -0
- package/build/api/communication/notification.js +373 -0
- package/build/api/index.d.ts +96 -0
- package/build/api/index.js +121 -0
- package/build/api/listing-management/inventory.d.ts +216 -0
- package/build/api/listing-management/inventory.js +633 -0
- package/build/api/listing-metadata/metadata.d.ts +154 -0
- package/build/api/listing-metadata/metadata.js +485 -0
- package/build/api/listing-metadata/taxonomy.d.ts +38 -0
- package/build/api/listing-metadata/taxonomy.js +58 -0
- package/build/api/marketing-and-promotions/marketing.d.ts +395 -0
- package/build/api/marketing-and-promotions/marketing.js +565 -0
- package/build/api/marketing-and-promotions/recommendation.d.ts +20 -0
- package/build/api/marketing-and-promotions/recommendation.js +32 -0
- package/build/api/order-management/dispute.d.ts +65 -0
- package/build/api/order-management/dispute.js +69 -0
- package/build/api/order-management/fulfillment.d.ts +80 -0
- package/build/api/order-management/fulfillment.js +89 -0
- package/build/api/other/compliance.d.ts +26 -0
- package/build/api/other/compliance.js +47 -0
- package/build/api/other/edelivery.d.ts +153 -0
- package/build/api/other/edelivery.js +219 -0
- package/build/api/other/identity.d.ts +17 -0
- package/build/api/other/identity.js +24 -0
- package/build/api/other/translation.d.ts +14 -0
- package/build/api/other/translation.js +22 -0
- package/build/api/other/vero.d.ts +30 -0
- package/build/api/other/vero.js +48 -0
- package/build/auth/oauth-metadata.d.ts +46 -0
- package/build/auth/oauth-metadata.js +59 -0
- package/build/auth/oauth-middleware.d.ts +35 -0
- package/build/auth/oauth-middleware.js +99 -0
- package/build/auth/oauth-types.d.ts +66 -0
- package/build/auth/oauth-types.js +4 -0
- package/build/auth/oauth.d.ts +93 -0
- package/build/auth/oauth.js +383 -0
- package/build/auth/scope-utils.d.ts +70 -0
- package/build/auth/scope-utils.js +304 -0
- package/build/auth/token-verifier.d.ts +57 -0
- package/build/auth/token-verifier.js +172 -0
- package/build/config/environment.d.ts +61 -0
- package/build/config/environment.js +260 -0
- package/build/index.d.ts +1 -0
- package/build/index.js +98 -0
- package/build/schemas/account-management/account.d.ts +5324 -0
- package/build/schemas/account-management/account.js +366 -0
- package/build/schemas/analytics/analytics.d.ts +167 -0
- package/build/schemas/analytics/analytics.js +191 -0
- package/build/schemas/communication/messages.d.ts +1872 -0
- package/build/schemas/communication/messages.js +348 -0
- package/build/schemas/fulfillment/orders.d.ts +4655 -0
- package/build/schemas/fulfillment/orders.js +317 -0
- package/build/schemas/index.d.ts +2100 -0
- package/build/schemas/index.js +68 -0
- package/build/schemas/inventory-management/inventory.d.ts +6419 -0
- package/build/schemas/inventory-management/inventory.js +450 -0
- package/build/schemas/marketing/marketing.d.ts +14181 -0
- package/build/schemas/marketing/marketing.js +1088 -0
- package/build/schemas/metadata/metadata.d.ts +5259 -0
- package/build/schemas/metadata/metadata.js +614 -0
- package/build/schemas/other/other-apis.d.ts +257 -0
- package/build/schemas/other/other-apis.js +372 -0
- package/build/schemas/taxonomy/taxonomy.d.ts +215 -0
- package/build/schemas/taxonomy/taxonomy.js +571 -0
- package/build/scripts/auto-setup.d.ts +12 -0
- package/build/scripts/auto-setup.js +277 -0
- package/build/scripts/diagnostics.d.ts +8 -0
- package/build/scripts/diagnostics.js +299 -0
- package/build/scripts/download-specs.d.ts +1 -0
- package/build/scripts/download-specs.js +116 -0
- package/build/scripts/interactive-setup.d.ts +21 -0
- package/build/scripts/interactive-setup.js +723 -0
- package/build/server-http.d.ts +11 -0
- package/build/server-http.js +361 -0
- package/build/tools/definitions/account-with-schemas.d.ts +39 -0
- package/build/tools/definitions/account-with-schemas.js +170 -0
- package/build/tools/definitions/account.d.ts +12 -0
- package/build/tools/definitions/account.js +428 -0
- package/build/tools/definitions/analytics.d.ts +25 -0
- package/build/tools/definitions/analytics.js +66 -0
- package/build/tools/definitions/communication.d.ts +12 -0
- package/build/tools/definitions/communication.js +151 -0
- package/build/tools/definitions/fulfillment.d.ts +12 -0
- package/build/tools/definitions/fulfillment.js +326 -0
- package/build/tools/definitions/index.d.ts +25 -0
- package/build/tools/definitions/index.js +37 -0
- package/build/tools/definitions/inventory.d.ts +12 -0
- package/build/tools/definitions/inventory.js +429 -0
- package/build/tools/definitions/marketing.d.ts +12 -0
- package/build/tools/definitions/marketing.js +1095 -0
- package/build/tools/definitions/metadata.d.ts +12 -0
- package/build/tools/definitions/metadata.js +188 -0
- package/build/tools/definitions/other.d.ts +13 -0
- package/build/tools/definitions/other.js +309 -0
- package/build/tools/definitions/taxonomy.d.ts +25 -0
- package/build/tools/definitions/taxonomy.js +64 -0
- package/build/tools/definitions/token-management.d.ts +35 -0
- package/build/tools/definitions/token-management.js +103 -0
- package/build/tools/index.d.ts +11 -0
- package/build/tools/index.js +1003 -0
- package/build/tools/schemas.d.ts +14764 -0
- package/build/tools/schemas.js +667 -0
- package/build/tools/tool-definitions.d.ts +35 -0
- package/build/tools/tool-definitions.js +3534 -0
- package/build/types/application-settings/developerAnalyticsV1BetaOas3.d.ts +197 -0
- package/build/types/application-settings/developerAnalyticsV1BetaOas3.js +5 -0
- package/build/types/application-settings/developerClientRegistrationV1Oas3.d.ts +155 -0
- package/build/types/application-settings/developerClientRegistrationV1Oas3.js +5 -0
- package/build/types/application-settings/developerKeyManagementV1Oas3.d.ts +246 -0
- package/build/types/application-settings/developerKeyManagementV1Oas3.js +5 -0
- package/build/types/ebay-enums.d.ts +1204 -0
- package/build/types/ebay-enums.js +1330 -0
- package/build/types/ebay.d.ts +143 -0
- package/build/types/ebay.js +123 -0
- package/build/types/index.d.ts +6 -0
- package/build/types/index.js +10 -0
- package/build/types/sell-apps/account-management/sellAccountV1Oas3.d.ts +2579 -0
- package/build/types/sell-apps/account-management/sellAccountV1Oas3.js +5 -0
- package/build/types/sell-apps/analytics-and-report/sellAnalyticsV1Oas3.d.ts +446 -0
- package/build/types/sell-apps/analytics-and-report/sellAnalyticsV1Oas3.js +5 -0
- package/build/types/sell-apps/communication/commerceFeedbackV1BetaOas3.d.ts +705 -0
- package/build/types/sell-apps/communication/commerceFeedbackV1BetaOas3.js +5 -0
- package/build/types/sell-apps/communication/commerceMessageV1Oas3.d.ts +590 -0
- package/build/types/sell-apps/communication/commerceMessageV1Oas3.js +5 -0
- package/build/types/sell-apps/communication/commerceNotificationV1Oas3.d.ts +1276 -0
- package/build/types/sell-apps/communication/commerceNotificationV1Oas3.js +5 -0
- package/build/types/sell-apps/communication/sellNegotiationV1Oas3.d.ts +277 -0
- package/build/types/sell-apps/communication/sellNegotiationV1Oas3.js +5 -0
- package/build/types/sell-apps/listing-management/sellInventoryV1Oas3.d.ts +3133 -0
- package/build/types/sell-apps/listing-management/sellInventoryV1Oas3.js +5 -0
- package/build/types/sell-apps/listing-metadata/sellMetadataV1Oas3.d.ts +2289 -0
- package/build/types/sell-apps/listing-metadata/sellMetadataV1Oas3.js +5 -0
- package/build/types/sell-apps/markeitng-and-promotions/sellMarketingV1Oas3.d.ts +6650 -0
- package/build/types/sell-apps/markeitng-and-promotions/sellMarketingV1Oas3.js +5 -0
- package/build/types/sell-apps/markeitng-and-promotions/sellRecommendationV1Oas3.d.ts +172 -0
- package/build/types/sell-apps/markeitng-and-promotions/sellRecommendationV1Oas3.js +5 -0
- package/build/types/sell-apps/order-management/sellFulfillmentV1Oas3.d.ts +1869 -0
- package/build/types/sell-apps/order-management/sellFulfillmentV1Oas3.js +5 -0
- package/build/types/sell-apps/other-apis/commerceIdentityV1Oas3.d.ts +178 -0
- package/build/types/sell-apps/other-apis/commerceIdentityV1Oas3.js +5 -0
- package/build/types/sell-apps/other-apis/commerceTranslationV1BetaOas3.d.ts +128 -0
- package/build/types/sell-apps/other-apis/commerceTranslationV1BetaOas3.js +5 -0
- package/build/types/sell-apps/other-apis/commerceVeroV1Oas3.d.ts +417 -0
- package/build/types/sell-apps/other-apis/commerceVeroV1Oas3.js +5 -0
- package/build/types/sell-apps/other-apis/sellComplianceV1Oas3.d.ts +273 -0
- package/build/types/sell-apps/other-apis/sellComplianceV1Oas3.js +5 -0
- package/build/types/sell-apps/other-apis/sellEdeliveryInternationalShippingOas3.d.ts +2537 -0
- package/build/types/sell-apps/other-apis/sellEdeliveryInternationalShippingOas3.js +5 -0
- package/build/types/sell-apps/other-apis/sellMarketingV1Oas3.d.ts +6650 -0
- package/build/types/sell-apps/other-apis/sellMarketingV1Oas3.js +5 -0
- package/build/types/sell-apps/other-apis/sellRecommendationV1Oas3.d.ts +172 -0
- package/build/types/sell-apps/other-apis/sellRecommendationV1Oas3.js +5 -0
- package/build/utils/account-management/account.d.ts +1094 -0
- package/build/utils/account-management/account.js +831 -0
- package/build/utils/communication/feedback.d.ts +152 -0
- package/build/utils/communication/feedback.js +216 -0
- package/build/utils/communication/message.d.ts +174 -0
- package/build/utils/communication/message.js +242 -0
- package/build/utils/communication/negotiation.d.ts +123 -0
- package/build/utils/communication/negotiation.js +150 -0
- package/build/utils/communication/notification.d.ts +370 -0
- package/build/utils/communication/notification.js +369 -0
- package/build/utils/date-converter.d.ts +59 -0
- package/build/utils/date-converter.js +160 -0
- package/build/utils/llm-client-detector.d.ts +54 -0
- package/build/utils/llm-client-detector.js +318 -0
- package/build/utils/oauth-helper.d.ts +37 -0
- package/build/utils/oauth-helper.js +315 -0
- package/build/utils/order-management/dispute.d.ts +346 -0
- package/build/utils/order-management/dispute.js +369 -0
- package/build/utils/order-management/fulfillment.d.ts +200 -0
- package/build/utils/order-management/fulfillment.js +205 -0
- package/build/utils/other/compliance.d.ts +49 -0
- package/build/utils/other/compliance.js +76 -0
- package/build/utils/other/edelivery.d.ts +310 -0
- package/build/utils/other/edelivery.js +241 -0
- package/build/utils/other/identity.d.ts +13 -0
- package/build/utils/other/identity.js +13 -0
- package/build/utils/other/translation.d.ts +28 -0
- package/build/utils/other/translation.js +41 -0
- package/build/utils/other/vero.d.ts +61 -0
- package/build/utils/other/vero.js +90 -0
- package/build/utils/scope-helper.d.ts +49 -0
- package/build/utils/scope-helper.js +207 -0
- package/build/utils/security-checker.d.ts +46 -0
- package/build/utils/security-checker.js +248 -0
- package/build/utils/setup-validator.d.ts +25 -0
- package/build/utils/setup-validator.js +305 -0
- package/build/utils/token-utils.d.ts +40 -0
- package/build/utils/token-utils.js +40 -0
- 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
|
+
});
|