ebay-mcp 1.18.0 → 1.18.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -35
- package/build/api/account-management/accountV2.js +22 -22
- package/build/api/account-management/finances.js +10 -10
- package/build/api/analytics-and-report/analytics.js +1 -1
- package/build/api/{client.js → client/ebayApiClient.js} +37 -41
- package/build/api/{clientTrading.js → client/tradingApiClient.js} +22 -22
- package/build/api/communication/feedback.js +21 -21
- package/build/api/communication/message.js +23 -23
- package/build/api/communication/negotiation.js +7 -7
- package/build/api/communication/notification.js +52 -52
- package/build/api/developer/developer.js +3 -3
- package/build/api/{index.js → ebaySellerApi.js} +4 -4
- package/build/api/listing-management/feedReportTasks.js +6 -6
- package/build/api/listing-management/feedRequest.js +6 -6
- package/build/api/listing-management/feedSchedules.js +4 -4
- package/build/api/listing-management/feedTasks.js +2 -2
- package/build/api/listing-management/items.js +22 -22
- package/build/api/listing-management/locations.js +4 -4
- package/build/api/listing-management/media.js +14 -14
- package/build/api/listing-management/mediaAttach.js +14 -14
- package/build/api/listing-management/mediaResources.js +15 -13
- package/build/api/listing-management/offerFormat.js +1 -1
- package/build/api/listing-management/offers.js +23 -23
- package/build/api/listing-management/stores.js +9 -9
- package/build/api/listing-metadata/metadata.js +10 -10
- package/build/api/marketing-and-promotions/ads.js +34 -34
- package/build/api/marketing-and-promotions/campaigns.js +19 -19
- package/build/api/marketing-and-promotions/promotions.js +22 -22
- package/build/api/marketing-and-promotions/reports.js +7 -7
- package/build/api/order-management/dispute.js +11 -9
- package/build/api/order-management/fulfillment.js +4 -4
- package/build/api/order-management/logistics.js +7 -7
- package/build/api/other/browseMappers.js +15 -13
- package/build/api/other/browseValidators.js +4 -4
- package/build/api/other/edelivery.js +19 -19
- package/build/api/other/finding.js +13 -13
- package/build/api/other/translation.js +2 -2
- package/build/api/other/vero.js +2 -2
- package/build/api/shared/download.js +7 -7
- package/build/api/shared/request.js +28 -19
- package/build/api/trading/listingFormat.js +37 -30
- package/build/api/trading/trading.js +33 -33
- package/build/auth/credentialSession.js +5 -5
- package/build/auth/oauth.js +3 -3
- package/build/auth/oauthHelper.js +24 -24
- package/build/auth/oauthMetadata.js +4 -4
- package/build/auth/oauthMiddleware.js +16 -16
- package/build/auth/scopeUtils.js +2 -2
- package/build/auth/tokenVerifier.js +23 -23
- package/build/config/environment.js +4 -45
- package/build/config/oauthScopes.js +132 -0
- package/build/index.js +5 -5
- package/build/mcp/httpTransport.js +32 -20
- package/build/mcp/runtime.js +12 -12
- package/build/mcp/toolGating.js +6 -12
- package/build/mcp/uiBridge.js +3 -3
- package/build/schemas/account-management/account.js +2 -52
- package/build/schemas/account-management/accountV2.js +2 -2
- package/build/schemas/account-management/finances.js +1 -1
- package/build/schemas/analytics/analytics.js +2 -48
- package/build/schemas/communication/messages.js +2 -46
- package/build/schemas/developer/developer.js +1 -27
- package/build/schemas/fulfillment/logistics.js +1 -1
- package/build/schemas/fulfillment/orders.js +2 -47
- package/build/schemas/inventory-management/feed.js +1 -1
- package/build/schemas/inventory-management/inventory.js +2 -50
- package/build/schemas/inventory-management/media.js +2 -2
- package/build/schemas/inventory-management/mediaDocuments.js +1 -1
- package/build/schemas/inventory-management/stores.js +1 -1
- package/build/schemas/marketing/ads.js +2 -2
- package/build/schemas/marketing/campaigns.js +2 -2
- package/build/schemas/marketing/common.js +2 -2
- package/build/schemas/marketing/marketing.js +0 -1
- package/build/schemas/marketing/promotions.js +2 -2
- package/build/schemas/marketing/reports.js +2 -2
- package/build/schemas/metadata/metadata.js +2 -90
- package/build/schemas/metadata/shipping.js +1 -1
- package/build/schemas/other/browse.js +2 -2
- package/build/schemas/other/finding.js +2 -2
- package/build/schemas/other/otherApis.js +2 -114
- package/build/schemas/taxonomy/categoryTree.js +1 -1
- package/build/schemas/taxonomy/charity.js +1 -1
- package/build/schemas/taxonomy/taxonomy.js +2 -69
- package/build/scripts/autoSetup.js +3 -3
- package/build/scripts/{buildUi.js → buildMcpApps.js} +13 -13
- package/build/scripts/devSync.js +19 -68
- package/build/scripts/diagnostics.js +15 -16
- package/build/scripts/interactiveSetup.js +25 -25
- package/build/scripts/scopeHelper.js +2 -2
- package/build/scripts/securityChecker.js +20 -20
- package/build/scripts/setup.js +76 -76
- package/build/scripts/setupShared.js +5 -30
- package/build/scripts/setupValidator.js +9 -9
- package/build/scripts/setupWizard.js +23 -23
- package/build/scripts/skills.js +14 -17
- package/build/scripts/specRefs.js +1 -1
- package/build/scripts/specSources.js +144 -0
- package/build/serverHttp.js +4 -7
- package/build/skills/content.js +13 -13
- package/build/skills/install.js +9 -9
- package/build/skills/render.js +2 -2
- package/build/tools/categories/communication.js +1 -1
- package/build/tools/categories/connector.js +19 -16
- package/build/tools/categories/fulfillment.js +4 -4
- package/build/tools/categories/inventory.js +1 -1
- package/build/tools/categories/metadata.js +1 -1
- package/build/tools/categories/taxonomy.js +1 -1
- package/build/tools/categories/tokenManagement.js +8 -8
- package/build/tools/contracts.js +2 -2
- package/build/tools/defineTool.js +27 -12
- package/build/tools/registry.js +2 -2
- package/build/tools/schemas.js +2 -2
- package/build/tools/ui/mapHelpers.js +12 -12
- package/build/tools/ui/maps.js +101 -97
- package/build/tools/ui/viewModels.js +2 -2
- package/build/utils/apiStatusFeed.js +12 -12
- package/build/utils/communication/feedback.js +3 -3
- package/build/utils/communication/message.js +3 -3
- package/build/utils/communication/negotiation.js +3 -3
- package/build/utils/communication/notification.js +3 -3
- package/build/utils/entryModule.js +33 -0
- package/build/utils/envFile.js +47 -0
- package/build/utils/envParser.js +5 -5
- package/build/utils/errors.js +4 -4
- package/build/utils/http.js +38 -38
- package/build/utils/localFeedFiles.js +3 -3
- package/build/utils/logRedaction.js +21 -0
- package/build/utils/logger.js +49 -35
- package/build/utils/other/compliance.js +3 -3
- package/build/utils/other/identity.js +3 -3
- package/build/utils/other/translation.js +3 -3
- package/build/utils/other/vero.js +3 -3
- package/build/utils/schemaHelpers.js +2 -2
- package/build/utils/tokenUtils.js +2 -2
- package/build/utils/trading/trading.js +1 -1
- package/build/utils/version.js +1 -1
- package/build/utils/zodIssues.js +14 -0
- package/package.json +8 -11
- package/README.de.md +0 -426
- package/README.es.md +0 -426
- package/README.fr.md +0 -426
- package/README.ja.md +0 -426
- package/README.ko.md +0 -426
- package/README.pt-BR.md +0 -426
- package/README.ru.md +0 -426
- package/README.zh-CN.md +0 -426
- package/build/schemas/index.js +0 -76
- package/build/schemas/marketing/jsonSchemas.js +0 -118
- package/build/scripts/downloadSpecs.js +0 -117
- package/build/scripts/updateApiStatusDoc.js +0 -71
- package/build/utils/effectSchema.js +0 -203
- package/build/utils/effectSchemaAdapter.js +0 -121
- package/build/utils/effectSchemaChainMethods.js +0 -146
- package/build/utils/effectSchemaRefinements.js +0 -104
- package/build/utils/effectSchemaStringMethods.js +0 -63
- package/build/utils/effectSchemaTypes.js +0 -47
- package/docs/auth/production_scopes.json +0 -111
- package/docs/auth/sandbox_scopes.json +0 -142
- /package/build/api/{clientRequestError.js → client/ebayClientRequestError.js} +0 -0
- /package/build/api/{rateLimitTracker.js → client/rateLimitTracker.js} +0 -0
- /package/build/api/{clientTradingError.js → client/tradingApiFailure.js} +0 -0
package/build/scripts/skills.js
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { resolve } from 'path';
|
|
3
|
-
import { fileURLToPath } from 'url';
|
|
4
2
|
import prompts from 'prompts';
|
|
5
3
|
import { ALL_PROVIDERS, applyWrite, buildRegistrySnapshot, detectProvider, planWrite, providerLabel, renderSkillTargets, } from '../skills/index.js';
|
|
6
4
|
import { ebayPalette, printHeading, printInfo, printRule, printSuccess, printWarning, ui, } from '../utils/cliUi.js';
|
|
7
5
|
import { getErrorMessage } from '../utils/errors.js';
|
|
8
6
|
import { Effect, Either } from 'effect';
|
|
9
7
|
import process from 'node:process';
|
|
8
|
+
import { isEntryModule } from '../utils/entryModule.js';
|
|
10
9
|
const ALL_LAYERS = ['using', 'contributing'];
|
|
11
10
|
/** Splits a comma list flag value into trimmed, non-empty tokens. */
|
|
12
|
-
const parseList = (
|
|
11
|
+
const parseList = (rawList) => (rawList ?? '')
|
|
13
12
|
.split(',')
|
|
14
13
|
.map((token) => token.trim())
|
|
15
14
|
.filter(Boolean);
|
|
@@ -25,8 +24,8 @@ const readFlagValue = (argv, flag) => {
|
|
|
25
24
|
/** Parses skills CLI flags, ignoring the leading `skills` subcommand token. */
|
|
26
25
|
const parseFlags = (argv) => {
|
|
27
26
|
const args = argv.filter((arg) => arg !== 'skills');
|
|
28
|
-
const providers = parseList(readFlagValue(args, '--providers')).filter((
|
|
29
|
-
const layers = parseList(readFlagValue(args, '--layer') ?? readFlagValue(args, '--layers')).filter((
|
|
27
|
+
const providers = parseList(readFlagValue(args, '--providers')).filter((token) => ALL_PROVIDERS.includes(token));
|
|
28
|
+
const layers = parseList(readFlagValue(args, '--layer') ?? readFlagValue(args, '--layers')).filter((token) => ALL_LAYERS.includes(token));
|
|
30
29
|
return {
|
|
31
30
|
help: args.includes('--help') || args.includes('-h'),
|
|
32
31
|
yes: args.includes('--yes') || args.includes('-y'),
|
|
@@ -188,7 +187,7 @@ export const runSkillsWizard = async (options = {}) => {
|
|
|
188
187
|
}
|
|
189
188
|
}
|
|
190
189
|
const rendered = renderSkillTargets({ providers, layers, scope, cwd, home, snapshot });
|
|
191
|
-
const plans = rendered.map((
|
|
190
|
+
const plans = rendered.map((renderedTarget) => planWrite(renderedTarget.target, renderedTarget.payload));
|
|
192
191
|
printPreview(plans);
|
|
193
192
|
if (flags.dryRun) {
|
|
194
193
|
printInfo('Dry run — no files written.');
|
|
@@ -220,26 +219,24 @@ export const runSkillsWizard = async (options = {}) => {
|
|
|
220
219
|
// targets sharing one file (both Codex layers → one AGENTS.md) compose instead
|
|
221
220
|
// of the second clobbering the first.
|
|
222
221
|
let written = 0;
|
|
223
|
-
for (const
|
|
224
|
-
const plan = planWrite(
|
|
225
|
-
const
|
|
226
|
-
if (
|
|
222
|
+
for (const renderedTarget of rendered) {
|
|
223
|
+
const plan = planWrite(renderedTarget.target, renderedTarget.payload);
|
|
224
|
+
const applied = applyWrite(plan, { dryRun: false, force: flags.force });
|
|
225
|
+
if (applied.written) {
|
|
227
226
|
written += 1;
|
|
228
|
-
printSuccess(`${
|
|
227
|
+
printSuccess(`${applied.action} ${plan.target.path}`);
|
|
229
228
|
}
|
|
230
229
|
}
|
|
231
230
|
printHeading('Done');
|
|
232
231
|
printInfo(`${written} file(s) written. Restart your AI tool so it picks up the new skills.`);
|
|
233
232
|
};
|
|
234
|
-
|
|
235
|
-
const modulePath = resolve(fileURLToPath(import.meta.url));
|
|
236
|
-
if (entryPath && modulePath === entryPath) {
|
|
233
|
+
if (isEntryModule(import.meta.url)) {
|
|
237
234
|
void Effect.runPromise(Effect.either(Effect.tryPromise({
|
|
238
235
|
try: () => runSkillsWizard(),
|
|
239
236
|
catch: (error) => error,
|
|
240
|
-
}))).then((
|
|
241
|
-
if (Either.isLeft(
|
|
242
|
-
console.error(ui.error('\n Skills install failed:'), getErrorMessage(
|
|
237
|
+
}))).then((skillsOutcome) => {
|
|
238
|
+
if (Either.isLeft(skillsOutcome)) {
|
|
239
|
+
console.error(ui.error('\n Skills install failed:'), getErrorMessage(skillsOutcome.left));
|
|
243
240
|
process.exitCode = 1;
|
|
244
241
|
}
|
|
245
242
|
});
|
|
@@ -48,7 +48,7 @@ export const replaceDanglingSchemaRefs = (spec) => {
|
|
|
48
48
|
return { description: `Undefined upstream schema ${name}` };
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
return Object.fromEntries(Object.entries(node).map(([key,
|
|
51
|
+
return Object.fromEntries(Object.entries(node).map(([key, child]) => [key, rewrite(child)]));
|
|
52
52
|
};
|
|
53
53
|
const rewritten = rewrite(spec);
|
|
54
54
|
return { spec: dangling.size > 0 ? rewritten : spec, danglingRefs: [...dangling] };
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Official eBay OpenAPI specs that `pnpm sync` downloads into the local spec cache.
|
|
3
|
+
*
|
|
4
|
+
* Each spec lands in `.cache/ebay-specs/<folder>/`, and its generated types land in
|
|
5
|
+
* `src/types/<folder>/`, so `folder` must match the existing generated-type layout.
|
|
6
|
+
*/
|
|
7
|
+
/** Every spec `pnpm sync` downloads, grouped the same way as `src/types/`. */
|
|
8
|
+
export const specSources = [
|
|
9
|
+
{
|
|
10
|
+
api: 'Developer Analytics API',
|
|
11
|
+
folder: 'application-settings',
|
|
12
|
+
url: 'https://developer.ebay.com/api-docs/master/developer/analytics/openapi/3/developer_analytics_v1_beta_oas3.json',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
api: 'Key Management API',
|
|
16
|
+
folder: 'application-settings',
|
|
17
|
+
url: 'https://developer.ebay.com/api-docs/master/developer/key-management/openapi/3/developer_key_management_v1_oas3.json',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
api: 'Client Registration API',
|
|
21
|
+
folder: 'application-settings',
|
|
22
|
+
url: 'https://developer.ebay.com/api-docs/master/developer/client-registration/openapi/3/developer_client_registration_v1_oas3.json',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
api: 'Inventory API',
|
|
26
|
+
folder: 'sell-apps/listing-management',
|
|
27
|
+
url: 'https://developer.ebay.com/api-docs/master/sell/inventory/openapi/3/sell_inventory_v1_oas3.json',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
api: 'Feed API',
|
|
31
|
+
folder: 'sell-apps/listing-management',
|
|
32
|
+
url: 'https://developer.ebay.com/api-docs/master/sell/feed/openapi/3/sell_feed_v1_oas3.json',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
api: 'Media API',
|
|
36
|
+
folder: 'sell-apps/listing-management',
|
|
37
|
+
url: 'https://developer.ebay.com/api-docs/master/commerce/media/openapi/3/commerce_media_v1_beta_oas3.json',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
api: 'Stores API',
|
|
41
|
+
folder: 'sell-apps/listing-management',
|
|
42
|
+
url: 'https://developer.ebay.com/api-docs/master/sell/stores/openapi/3/sell_stores_v1_oas3.json',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
api: 'Metadata API',
|
|
46
|
+
folder: 'sell-apps/listing-metadata',
|
|
47
|
+
url: 'https://developer.ebay.com/api-docs/master/sell/metadata/openapi/3/sell_metadata_v1_oas3.json',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
api: 'Taxonomy API',
|
|
51
|
+
folder: 'sell-apps/listing-metadata',
|
|
52
|
+
url: 'https://developer.ebay.com/api-docs/master/commerce/taxonomy/openapi/3/commerce_taxonomy_v1_oas3.json',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
api: 'Charity API',
|
|
56
|
+
folder: 'sell-apps/listing-metadata',
|
|
57
|
+
url: 'https://developer.ebay.com/api-docs/master/commerce/charity/openapi/3/commerce_charity_v1_oas3.json',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
api: 'Account API (v1)',
|
|
61
|
+
folder: 'sell-apps/account-management',
|
|
62
|
+
url: 'https://developer.ebay.com/api-docs/master/sell/account/openapi/3/sell_account_v1_oas3.json',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
api: 'Account API (v2)',
|
|
66
|
+
folder: 'sell-apps/account-management',
|
|
67
|
+
url: 'https://developer.ebay.com/api-docs/master/sell/account/v2/openapi/3/sell_account_v2_oas3.json',
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
api: 'Finances API',
|
|
71
|
+
folder: 'sell-apps/account-management',
|
|
72
|
+
url: 'https://developer.ebay.com/api-docs/master/sell/finances/openapi/3/sell_finances_v1_oas3.json',
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
api: 'Message API',
|
|
76
|
+
folder: 'sell-apps/communication',
|
|
77
|
+
url: 'https://developer.ebay.com/api-docs/master/commerce/message/openapi/3/commerce_message_v1_oas3.json',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
api: 'Notification API',
|
|
81
|
+
folder: 'sell-apps/communication',
|
|
82
|
+
url: 'https://developer.ebay.com/api-docs/master/commerce/notification/openapi/3/commerce_notification_v1_oas3.json',
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
api: 'Negotiation API',
|
|
86
|
+
folder: 'sell-apps/communication',
|
|
87
|
+
url: 'https://developer.ebay.com/api-docs/master/sell/negotiation/openapi/3/sell_negotiation_v1_oas3.json',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
api: 'Feedback API',
|
|
91
|
+
folder: 'sell-apps/communication',
|
|
92
|
+
url: 'https://developer.ebay.com/api-docs/master/commerce/feedback/openapi/3/commerce_feedback_v1_beta_oas3.json',
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
api: 'Fulfillment API',
|
|
96
|
+
folder: 'sell-apps/order-management',
|
|
97
|
+
url: 'https://developer.ebay.com/api-docs/master/sell/fulfillment/openapi/3/sell_fulfillment_v1_oas3.json',
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
api: 'Logistics API',
|
|
101
|
+
folder: 'sell-apps/order-management',
|
|
102
|
+
url: 'https://developer.ebay.com/api-docs/master/sell/logistics/openapi/3/sell_logistics_v1_oas3.json',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
api: 'Marketing API',
|
|
106
|
+
folder: 'sell-apps/marketing-and-promotions',
|
|
107
|
+
url: 'https://developer.ebay.com/api-docs/master/sell/marketing/openapi/3/sell_marketing_v1_oas3.json',
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
api: 'Recommendation API',
|
|
111
|
+
folder: 'sell-apps/marketing-and-promotions',
|
|
112
|
+
url: 'https://developer.ebay.com/api-docs/master/sell/recommendation/openapi/3/sell_recommendation_v1_oas3.json',
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
api: 'Analytics API',
|
|
116
|
+
folder: 'sell-apps/analytics-and-report',
|
|
117
|
+
url: 'https://developer.ebay.com/api-docs/master/sell/analytics/openapi/3/sell_analytics_v1_oas3.json',
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
api: 'Translation API',
|
|
121
|
+
folder: 'sell-apps/other-apis',
|
|
122
|
+
url: 'https://developer.ebay.com/api-docs/master/commerce/translation/openapi/3/commerce_translation_v1_beta_oas3.json',
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
api: 'Compliance API',
|
|
126
|
+
folder: 'sell-apps/other-apis',
|
|
127
|
+
url: 'https://developer.ebay.com/api-docs/master/sell/compliance/openapi/3/sell_compliance_v1_oas3.json',
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
api: 'Identity API',
|
|
131
|
+
folder: 'sell-apps/other-apis',
|
|
132
|
+
url: 'https://developer.ebay.com/api-docs/master/commerce/identity/openapi/3/commerce_identity_v1_oas3.json',
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
api: 'eDelivery International Shipping API',
|
|
136
|
+
folder: 'sell-apps/other-apis',
|
|
137
|
+
url: 'https://developer.ebay.com/api-docs/master/sell/edelivery_international_shipping/openapi/3/sell_edelivery_international_shipping_oas3.json',
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
api: 'Vero API',
|
|
141
|
+
folder: 'sell-apps/other-apis',
|
|
142
|
+
url: 'https://developer.ebay.com/api-docs/master/commerce/vero/openapi/3/commerce_vero_v1_oas3.json',
|
|
143
|
+
},
|
|
144
|
+
];
|
package/build/serverHttp.js
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* eBay API MCP Server with HTTP Transport and OAuth 2.1 Authorization.
|
|
3
3
|
*/
|
|
4
|
-
import { resolve } from 'path';
|
|
5
|
-
import { fileURLToPath } from 'url';
|
|
6
4
|
import { validateEnvironmentConfig } from './config/environment.js';
|
|
7
5
|
import { createHttpMcpApp, createHttpTransportConfigFromEnv, getHttpServerUrl, } from './mcp/httpTransport.js';
|
|
8
6
|
import { getErrorMessage } from './utils/errors.js';
|
|
9
7
|
import { serverLogger } from './utils/logger.js';
|
|
10
8
|
import { Effect, Either } from 'effect';
|
|
11
9
|
import process from 'node:process';
|
|
10
|
+
import { isEntryModule } from './utils/entryModule.js';
|
|
12
11
|
const CONFIG = createHttpTransportConfigFromEnv(process.env);
|
|
13
12
|
function logEnvironmentValidation() {
|
|
14
13
|
const validation = validateEnvironmentConfig();
|
|
15
|
-
validation.infos.forEach((
|
|
16
|
-
serverLogger.info(
|
|
14
|
+
validation.infos.forEach((notice) => {
|
|
15
|
+
serverLogger.info(notice);
|
|
17
16
|
});
|
|
18
17
|
if (validation.warnings.length > 0) {
|
|
19
18
|
serverLogger.warn('Environment Configuration Warnings:');
|
|
@@ -83,8 +82,6 @@ async function main() {
|
|
|
83
82
|
process.exit(1);
|
|
84
83
|
}
|
|
85
84
|
}
|
|
86
|
-
|
|
87
|
-
const modulePath = resolve(fileURLToPath(import.meta.url));
|
|
88
|
-
if (entryPath && modulePath === entryPath) {
|
|
85
|
+
if (isEntryModule(import.meta.url)) {
|
|
89
86
|
await main();
|
|
90
87
|
}
|
package/build/skills/content.js
CHANGED
|
@@ -87,8 +87,8 @@ export const buildUsingDoc = (snapshot) => ({
|
|
|
87
87
|
});
|
|
88
88
|
/**
|
|
89
89
|
* Builds the "contributing" skill: how an AI working on the ebay-mcp repo should
|
|
90
|
-
* operate
|
|
91
|
-
*
|
|
90
|
+
* operate: validation commands, module map, the add-a-tool flow, and
|
|
91
|
+
* conventions, against the real `src/tools/categories/` layout.
|
|
92
92
|
*
|
|
93
93
|
* @param snapshot Live tool count and family index.
|
|
94
94
|
* @returns The provider-neutral skill document.
|
|
@@ -101,16 +101,16 @@ export const buildUsingDoc = (snapshot) => ({
|
|
|
101
101
|
export const buildContributingDoc = (snapshot) => ({
|
|
102
102
|
slug: 'ebay-mcp-contributing',
|
|
103
103
|
title: 'Contributing to ebay-mcp',
|
|
104
|
-
description: `Work on the ebay-mcp server itself: ${snapshot.toolCount} tools across eBay's Sell APIs (TypeScript/ESM,
|
|
105
|
-
intro: `A local MCP server exposing **${snapshot.toolCount} tools across 100% of eBay's Sell APIs** — TypeScript/Node.js (ESM), \`@modelcontextprotocol/sdk\`,
|
|
104
|
+
description: `Work on the ebay-mcp server itself: ${snapshot.toolCount} tools across eBay's Sell APIs (TypeScript/ESM, Zod tool-input schemas, OpenAPI-generated types). Use when adding or changing eBay tools/endpoints, wiring the registry, or running the project's checks.`,
|
|
105
|
+
intro: `A local MCP server exposing **${snapshot.toolCount} tools across 100% of eBay's Sell APIs** — TypeScript/Node.js (ESM), \`@modelcontextprotocol/sdk\`, Zod tool-input schemas, Effect for typed async errors, OpenAPI-generated types. Entry points: \`src/index.ts\` (STDIO) and \`src/serverHttp.ts\` (HTTP).`,
|
|
106
106
|
sections: [
|
|
107
107
|
{
|
|
108
108
|
heading: 'Validation (run before a PR)',
|
|
109
109
|
body: [
|
|
110
110
|
'```bash',
|
|
111
|
-
'
|
|
112
|
-
'
|
|
113
|
-
'
|
|
111
|
+
'pnpm check # tsc --noEmit (src + mcp-apps) + biome check (must pass)',
|
|
112
|
+
'pnpm test # vitest run',
|
|
113
|
+
'pnpm build # tsc + tsc-alias + MCP Apps views → build/',
|
|
114
114
|
'```',
|
|
115
115
|
].join('\n'),
|
|
116
116
|
},
|
|
@@ -120,12 +120,12 @@ export const buildContributingDoc = (snapshot) => ({
|
|
|
120
120
|
'| Path | Owns |',
|
|
121
121
|
'| --- | --- |',
|
|
122
122
|
'| `index.ts` / `serverHttp.ts` | MCP entry points (STDIO / HTTP) |',
|
|
123
|
-
'| `api/` | eBay API
|
|
123
|
+
'| `api/` | eBay API modules (one area per folder), `client/` (REST and Trading XML clients), and the `ebaySellerApi.ts` facade |',
|
|
124
124
|
'| `auth/` | OAuth 2.0 flow and token management |',
|
|
125
125
|
'| `config/` | Environment loading, constants, marketplace defaults |',
|
|
126
126
|
'| `tools/` | Tool wiring — `registry.ts`, `contracts.ts`, `defineTool.ts`, and `categories/` (13 family files that co-locate each tool definition with its handler via `defineTool`) |',
|
|
127
127
|
"| `skills/` | Agent-skills generator (this skill's source) |",
|
|
128
|
-
'| `schemas/` | Shared
|
|
128
|
+
'| `schemas/` | Shared Zod schemas per API family |',
|
|
129
129
|
"| `types/` | TypeScript types — **auto-generated** from OpenAPI specs (don't hand-edit) |",
|
|
130
130
|
'| `scripts/` | CLI tooling: `setup.ts`, `skills.ts`, `devSync.ts`, `diagnostics.ts` |',
|
|
131
131
|
'| `utils/` | Shared utilities (logging, http, errors) |',
|
|
@@ -134,19 +134,19 @@ export const buildContributingDoc = (snapshot) => ({
|
|
|
134
134
|
{
|
|
135
135
|
heading: 'Add a tool or endpoint',
|
|
136
136
|
body: [
|
|
137
|
-
'1. `
|
|
137
|
+
'1. `pnpm sync` — download the latest eBay specs, regenerate types, report missing endpoints.',
|
|
138
138
|
'2. Add the API method in `src/api/`.',
|
|
139
139
|
'3. Add a `defineTool({ ... handler })` entry in the matching `src/tools/categories/<family>.ts` — definition and handler live together; `registry.ts` derives everything from `categories/index.ts`.',
|
|
140
140
|
'4. Add tests in `tests/`.',
|
|
141
|
-
'5. `
|
|
141
|
+
'5. `pnpm check && pnpm test`.',
|
|
142
142
|
].join('\n'),
|
|
143
143
|
},
|
|
144
144
|
{
|
|
145
145
|
heading: 'Conventions',
|
|
146
146
|
body: [
|
|
147
147
|
'- **No `any`** — specific types; prefer narrowing over assertions. `types/` is generated, so model new shapes from the specs.',
|
|
148
|
-
|
|
149
|
-
'- Commit with Conventional Commits (
|
|
148
|
+
"- Validate tool inputs with Zod schemas (`import { z } from 'zod'`); derive related schemas rather than duplicating fields.",
|
|
149
|
+
'- Commit with Conventional Commits; merged PR labels (`major`/`minor`, else patch) pick the release bump.',
|
|
150
150
|
'- Logs go to **stderr** only — stdout is reserved for the MCP protocol.',
|
|
151
151
|
].join('\n'),
|
|
152
152
|
},
|
package/build/skills/install.js
CHANGED
|
@@ -30,20 +30,20 @@ const mergeManagedBlock = (existing, layer, inner) => {
|
|
|
30
30
|
* always preserved (never `skip-foreign`).
|
|
31
31
|
*
|
|
32
32
|
* @param target Resolved destination.
|
|
33
|
-
* @param
|
|
33
|
+
* @param renderedContent Rendered content — a full file for owned targets, inner block
|
|
34
34
|
* content for managed targets.
|
|
35
35
|
* @returns The planned action and the exact bytes that would be written.
|
|
36
36
|
*
|
|
37
37
|
* @example
|
|
38
38
|
* ```ts
|
|
39
|
-
* const plan = planWrite(target,
|
|
39
|
+
* const plan = planWrite(target, renderedContent);
|
|
40
40
|
* ```
|
|
41
41
|
*/
|
|
42
|
-
export const planWrite = (target,
|
|
42
|
+
export const planWrite = (target, renderedContent) => {
|
|
43
43
|
const exists = existsSync(target.path);
|
|
44
44
|
const previousContents = exists ? readFileSync(target.path, 'utf-8') : undefined;
|
|
45
45
|
if (target.kind === 'managed-block') {
|
|
46
|
-
const nextContents = mergeManagedBlock(previousContents ?? '', target.layer,
|
|
46
|
+
const nextContents = mergeManagedBlock(previousContents ?? '', target.layer, renderedContent);
|
|
47
47
|
let action = 'create';
|
|
48
48
|
if (exists) {
|
|
49
49
|
action = nextContents === previousContents ? 'unchanged' : 'update';
|
|
@@ -52,13 +52,13 @@ export const planWrite = (target, payload) => {
|
|
|
52
52
|
}
|
|
53
53
|
// owned-file
|
|
54
54
|
if (!exists) {
|
|
55
|
-
return { target, action: 'create', nextContents:
|
|
55
|
+
return { target, action: 'create', nextContents: renderedContent };
|
|
56
56
|
}
|
|
57
57
|
if (!isOwnedByUs(previousContents ?? '', target.layer)) {
|
|
58
|
-
return { target, action: 'skip-foreign', nextContents:
|
|
58
|
+
return { target, action: 'skip-foreign', nextContents: renderedContent, previousContents };
|
|
59
59
|
}
|
|
60
|
-
const action = previousContents ===
|
|
61
|
-
return { target, action, nextContents:
|
|
60
|
+
const action = previousContents === renderedContent ? 'unchanged' : 'update';
|
|
61
|
+
return { target, action, nextContents: renderedContent, previousContents };
|
|
62
62
|
};
|
|
63
63
|
/**
|
|
64
64
|
* Applies a write plan. Skips no-op writes (`unchanged`) and refuses to clobber
|
|
@@ -71,7 +71,7 @@ export const planWrite = (target, payload) => {
|
|
|
71
71
|
*
|
|
72
72
|
* @example
|
|
73
73
|
* ```ts
|
|
74
|
-
* const
|
|
74
|
+
* const writeOutcome = applyWrite(plan, { dryRun: true });
|
|
75
75
|
* ```
|
|
76
76
|
*/
|
|
77
77
|
export const applyWrite = (plan, options = {}) => {
|
package/build/skills/render.js
CHANGED
|
@@ -14,7 +14,7 @@ const renderBody = (doc, baseLevel) => {
|
|
|
14
14
|
return parts.join('\n');
|
|
15
15
|
};
|
|
16
16
|
/** YAML frontmatter scalar that is safe for arbitrary text (JSON strings are valid YAML). */
|
|
17
|
-
const yamlString = (
|
|
17
|
+
const yamlString = (text) => JSON.stringify(text);
|
|
18
18
|
/**
|
|
19
19
|
* Renders a Claude Code skill file (`SKILL.md`): YAML frontmatter (`name`,
|
|
20
20
|
* `description`) so the model can invoke it on demand, an ownership marker, then
|
|
@@ -87,7 +87,7 @@ export const renderCodexSection = (doc) => renderBody(doc, 2);
|
|
|
87
87
|
*
|
|
88
88
|
* @example
|
|
89
89
|
* ```ts
|
|
90
|
-
* const
|
|
90
|
+
* const skillContent = renderSkill('codex', doc, 'using');
|
|
91
91
|
* ```
|
|
92
92
|
*/
|
|
93
93
|
export const renderSkill = (provider, doc, layer) => {
|
|
@@ -7,7 +7,7 @@ import { createDestinationSchema, createSubscriptionFilterSchema, createSubscrip
|
|
|
7
7
|
/**
|
|
8
8
|
* Communication API tools for member messages, notifications, and seller feedback.
|
|
9
9
|
*
|
|
10
|
-
* Each tool derives its transport schema from the same
|
|
10
|
+
* Each tool derives its transport schema from the same Zod object whose inferred
|
|
11
11
|
* args are passed directly to the endpoint method. Handlers stay at the MCP
|
|
12
12
|
* boundary: they run one endpoint Effect and avoid response or input reshaping.
|
|
13
13
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { z } from '
|
|
1
|
+
import { z } from 'zod';
|
|
2
2
|
import { Effect } from 'effect';
|
|
3
3
|
import { defineTool } from '../../tools/defineTool.js';
|
|
4
4
|
const connectorSearchInputSchema = z.object({
|
|
@@ -46,19 +46,22 @@ export const connectorEntries = [
|
|
|
46
46
|
const matches = [];
|
|
47
47
|
let offset = 0;
|
|
48
48
|
while (matches.length < limit) {
|
|
49
|
-
const
|
|
50
|
-
|
|
49
|
+
const inventoryPage = yield* api.inventory.getInventoryItems({
|
|
50
|
+
limit: pageSize,
|
|
51
|
+
offset,
|
|
52
|
+
});
|
|
53
|
+
const pageItems = inventoryPage.inventoryItems ?? [];
|
|
51
54
|
if (pageItems.length === 0) {
|
|
52
55
|
break;
|
|
53
56
|
}
|
|
54
57
|
// Only items with valid SKUs can be passed to getInventoryItem later.
|
|
55
|
-
const itemsWithSku = pageItems.filter((
|
|
58
|
+
const itemsWithSku = pageItems.filter((inventoryItem) => typeof inventoryItem.sku === 'string' && inventoryItem.sku.trim() !== '');
|
|
56
59
|
const filtered = query
|
|
57
|
-
? itemsWithSku.filter((
|
|
60
|
+
? itemsWithSku.filter((inventoryItem) => (inventoryItem.product?.title ?? '').toLowerCase().includes(query))
|
|
58
61
|
: itemsWithSku;
|
|
59
62
|
matches.push(...filtered);
|
|
60
63
|
offset += pageSize;
|
|
61
|
-
const total =
|
|
64
|
+
const total = inventoryPage.total;
|
|
62
65
|
if (typeof total === 'number' && offset >= total) {
|
|
63
66
|
break;
|
|
64
67
|
}
|
|
@@ -66,9 +69,9 @@ export const connectorEntries = [
|
|
|
66
69
|
break;
|
|
67
70
|
}
|
|
68
71
|
}
|
|
69
|
-
const results = matches.slice(0, limit).map((
|
|
70
|
-
id:
|
|
71
|
-
title:
|
|
72
|
+
const results = matches.slice(0, limit).map((match) => ({
|
|
73
|
+
id: match.sku,
|
|
74
|
+
title: match.product?.title ?? '',
|
|
72
75
|
url: 'https://www.ebay.com/', // Placeholder: eBay does not expose a canonical item URL here.
|
|
73
76
|
}));
|
|
74
77
|
// The ChatGPT connector spec requires a single text content block.
|
|
@@ -104,23 +107,23 @@ export const connectorEntries = [
|
|
|
104
107
|
},
|
|
105
108
|
handler: (api, args) => Effect.runPromise(Effect.gen(function* () {
|
|
106
109
|
const sku = args.id;
|
|
107
|
-
const
|
|
108
|
-
const
|
|
110
|
+
const inventoryItem = yield* api.inventory.getInventoryItem({ sku });
|
|
111
|
+
const connectorDocument = {
|
|
109
112
|
id: sku,
|
|
110
|
-
title:
|
|
111
|
-
text:
|
|
113
|
+
title: inventoryItem.product?.title ?? '',
|
|
114
|
+
text: inventoryItem.product?.description ?? '',
|
|
112
115
|
url: 'https://www.ebay.com/', // Placeholder: eBay does not expose a canonical item URL here.
|
|
113
116
|
metadata: {
|
|
114
117
|
source: 'ebay_inventory',
|
|
115
|
-
aspects:
|
|
116
|
-
condition:
|
|
118
|
+
aspects: inventoryItem.product?.aspects,
|
|
119
|
+
condition: inventoryItem.condition,
|
|
117
120
|
},
|
|
118
121
|
};
|
|
119
122
|
return {
|
|
120
123
|
content: [
|
|
121
124
|
{
|
|
122
125
|
type: 'text',
|
|
123
|
-
text: JSON.stringify(
|
|
126
|
+
text: JSON.stringify(connectorDocument),
|
|
124
127
|
},
|
|
125
128
|
],
|
|
126
129
|
};
|
|
@@ -81,8 +81,8 @@ export const fulfillmentEntries = [
|
|
|
81
81
|
filter: args.filter,
|
|
82
82
|
limit: args.maxResults ?? DEFAULT_ORDER_SCAN_LIMIT,
|
|
83
83
|
})
|
|
84
|
-
.pipe(Effect.map((
|
|
85
|
-
const orders =
|
|
84
|
+
.pipe(Effect.map((orderPage) => {
|
|
85
|
+
const orders = orderPage.orders ?? [];
|
|
86
86
|
const matches = filterOrdersWithCancellationRequests(orders);
|
|
87
87
|
return {
|
|
88
88
|
totalScanned: orders.length,
|
|
@@ -101,8 +101,8 @@ export const fulfillmentEntries = [
|
|
|
101
101
|
filter: args.filter,
|
|
102
102
|
limit: args.maxResults ?? DEFAULT_ORDER_SCAN_LIMIT,
|
|
103
103
|
})
|
|
104
|
-
.pipe(Effect.map((
|
|
105
|
-
const orders =
|
|
104
|
+
.pipe(Effect.map((orderPage) => {
|
|
105
|
+
const orders = orderPage.orders ?? [];
|
|
106
106
|
const matches = filterRefundedOrders(orders);
|
|
107
107
|
return {
|
|
108
108
|
totalScanned: orders.length,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Effect } from 'effect';
|
|
2
|
-
import { z } from '
|
|
2
|
+
import { z } from 'zod';
|
|
3
3
|
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
4
4
|
import { defineTool } from '../../tools/defineTool.js';
|
|
5
5
|
import { mapInventoryItemsToTable, mapInventoryItemToCard, mapLocationsToTable, mapOffersToTable, mapOfferToCard, } from '../../tools/ui/maps.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { z } from '
|
|
1
|
+
import { z } from 'zod';
|
|
2
2
|
import { MarketplaceId } from '../../types/ebayEnums.js';
|
|
3
3
|
import { shippingMetadataInputSchema } from '../../schemas/metadata/shipping.js';
|
|
4
4
|
import { defineTool } from '../../tools/defineTool.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { z } from '
|
|
1
|
+
import { z } from 'zod';
|
|
2
2
|
import { categoryTreeIdInputSchema } from '../../schemas/taxonomy/categoryTree.js';
|
|
3
3
|
import { defineTool } from '../../tools/defineTool.js';
|
|
4
4
|
import { formatFileResult } from '../../tools/fileResult.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { z } from '
|
|
1
|
+
import { z } from 'zod';
|
|
2
2
|
import { buildCredentialDisplay, maskToken } from '../../auth/credentialSession.js';
|
|
3
3
|
import { getOAuthAuthorizationUrl, validateScopes } from '../../config/environment.js';
|
|
4
4
|
import { defineTool } from '../../tools/defineTool.js';
|
|
@@ -14,11 +14,11 @@ const tokenToolError = (operation, message, error) => new TokenManagementToolErr
|
|
|
14
14
|
...(error === undefined ? {} : { cause: error }),
|
|
15
15
|
});
|
|
16
16
|
/** Convert an optional token expiry value into a timestamp inside the token tool Effect. */
|
|
17
|
-
const optionalTokenExpiryTimestamp = (
|
|
18
|
-
if (
|
|
17
|
+
const optionalTokenExpiryTimestamp = (expiry, operation, message) => {
|
|
18
|
+
if (expiry === undefined) {
|
|
19
19
|
return Effect.succeed(undefined);
|
|
20
20
|
}
|
|
21
|
-
return convertToTimestamp(
|
|
21
|
+
return convertToTimestamp(expiry).pipe(Effect.mapError((error) => tokenToolError(operation, message, error)));
|
|
22
22
|
};
|
|
23
23
|
const missingClientIdError = tokenToolError('getOAuthUrl', 'EBAY_CLIENT_ID environment variable is required to generate OAuth URL');
|
|
24
24
|
const missingRedirectUriError = tokenToolError('getOAuthUrl', 'Redirect URI is required. Either provide it as a parameter or set EBAY_REDIRECT_URI in your .env file.');
|
|
@@ -121,7 +121,7 @@ export const tokenManagementEntries = [
|
|
|
121
121
|
? validateScopes(scopes, config.environment)
|
|
122
122
|
: { warnings: [], validScopes: scopes };
|
|
123
123
|
const authUrl = getOAuthAuthorizationUrl(config.clientId, redirectUri, config.environment, scopeValidation.validScopes, args.state);
|
|
124
|
-
const
|
|
124
|
+
const authorizationDetails = {
|
|
125
125
|
authorizationUrl: authUrl,
|
|
126
126
|
redirectUri,
|
|
127
127
|
instructions: 'Open this URL in a browser to authorize the application. After authorization, you will be redirected to your redirect URI with an authorization code that can be exchanged for an access token.',
|
|
@@ -129,9 +129,9 @@ export const tokenManagementEntries = [
|
|
|
129
129
|
scopes: scopes ?? 'default (all Sell API scopes)',
|
|
130
130
|
};
|
|
131
131
|
if (scopeValidation.warnings.length > 0) {
|
|
132
|
-
|
|
132
|
+
authorizationDetails.warnings = scopeValidation.warnings;
|
|
133
133
|
}
|
|
134
|
-
return
|
|
134
|
+
return authorizationDetails;
|
|
135
135
|
})),
|
|
136
136
|
}),
|
|
137
137
|
defineTool({
|
|
@@ -324,7 +324,7 @@ export const tokenManagementEntries = [
|
|
|
324
324
|
'COMMON ERRORS:\n' +
|
|
325
325
|
'- "invalid or was issued to another client": Code expired, get fresh code\n' +
|
|
326
326
|
'- "Insufficient permissions": Re-run OAuth flow with additional scopes in ebay_get_oauth_url\n\n' +
|
|
327
|
-
'For
|
|
327
|
+
'For scopes and rate limits, see the "Authentication & rate limits" section of the ebay-mcp README.',
|
|
328
328
|
inputSchema: exchangeAuthorizationCodeInputSchema.shape,
|
|
329
329
|
outputSchema: {
|
|
330
330
|
type: 'object',
|
package/build/tools/contracts.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getToolEntries } from '../tools/registry.js';
|
|
2
|
-
import {
|
|
2
|
+
import { z } from 'zod';
|
|
3
3
|
const isJsonObject = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
4
4
|
/**
|
|
5
5
|
* Builds public tool contracts from the validated tool registry entries.
|
|
@@ -47,7 +47,7 @@ export const validateToolContracts = (contracts = getToolContracts()) => {
|
|
|
47
47
|
}
|
|
48
48
|
else {
|
|
49
49
|
for (const [fieldName, schema] of Object.entries(contract.inputSchema)) {
|
|
50
|
-
if (!
|
|
50
|
+
if (!(schema instanceof z.ZodType)) {
|
|
51
51
|
invalidInputSchemaFields.push(`${contract.name}.${fieldName}`);
|
|
52
52
|
}
|
|
53
53
|
}
|