Skip to content

Let eBay sellers sign in instead of pasting a refresh token - #1430

Merged
helpcodeai merged 5 commits into
mainfrom
feat/ebay-oauth-signin
Nov 2, 2026
Merged

helpcodeai merged 5 commits into
mainfrom
feat/ebay-oauth-signin

Conversation

@helpcodeai

Copy link
Copy Markdown
Contributor

Summary

The eBay Sell connector could not be connected by a normal seller. It asked for a user refresh token, but eBay's developer portal does not show one: its User Tokens page only gives access tokens that expire after two hours, so the connector failed as soon as the token expired, and the refresh token itself needs an authorization-code exchange that a seller cannot run by hand. A paying Cloud customer hit exactly this on 2 November.

This PR lets the seller sign in to eBay from AnythingMCP ("Authorize with Provider" / the setup page), like Etsy. eBay's OAuth flow has one quirk: its redirect_uri is not a URL but the app's RuName, both in the consent request and in the code exchange; the RuName's "Auth Accepted URL", set in eBay's developer portal, is what sends the browser back to us. A new authConfig.providerRedirectUri option covers that, generically.

Changes

  • authConfig.providerRedirectUri (REST/GraphQL OAuth2): the redirect_uri sent on the authorization request and on the code exchange in place of <SERVER_URL>/api/mcp-oauth/callback. Usually a variable ({{EBAY_RUNAME}}); while it has no value, "Authorize" asks for the variable instead of starting. A row without the key takes the catalog adapter's (same rule as pkce), so connectors installed from the old adapter can be signed in after adding EBAY_RUNAME. The callback route, state check and token storage are unchanged. Adapters without the key send exactly what they sent before.
  • Pending flow: redirectUri now holds what was sent; callbackUrl is added only when they differ, so the invalid_grant message says to check the RuName's accepted URL instead of naming the RuName as a redirect URI.
  • ebay-sell adapter: authorizationUrl https://auth.ebay.com/oauth2/authorize, token URL with Basic client auth (as before), pkce: false (eBay documents no PKCE), grant: refresh_token, scopes sell.inventory sell.fulfillment sell.account sell.payment.dispute (as full scope URLs, what the 10 tools need), new required EBAY_RUNAME, EBAY_REFRESH_TOKEN now optional/advanced ("leave empty"), appRegistrationUrl, prerequisites, an auth_failed verify hint, rewritten instructions, and a three-step setupGuide (Production keyset → RuName with Auth Accepted/Declined URL = {{redirectUri}} → keys, RuName, marketplace, then sign in). Field patterns only reject Sandbox values (-SBX-, SBX-) and a URL pasted as RuName.
  • Connectors that already hold a refresh token pasted by hand keep working unchanged; the instructions say how to switch to the sign-in.
  • docs/tool-definition.md: documents providerRedirectUri and pkce: false.

eBay sources (developer.ebay.com blocks scripted access; read through archived copies of the current pages): "Getting user consent" (api-docs/static/oauth-consent-request.html), "Exchanging the authorization code for a User access token" (oauth-auth-code-grant-request.html), "Getting your redirect_uri value" (oauth-redirect-uri.html), "Using a refresh token to update a User access token" (oauth-refresh-token-request.html), "Create the eBay API keysets" and "Marketplace account deletion".

Cloud and self-hosted: same code path. On Cloud the accepted URL is https://cloud.anythingmcp.com/api/mcp-oauth/callback (the guide fills it in from this instance). Self-hosted instances set their own <SERVER_URL>/api/mcp-oauth/callback; eBay requires https there, so an instance on plain http cannot use the sign-in (a pasted refresh token still works).

Type

  • Bug fix
  • New feature
  • Documentation
  • Refactoring
  • Performance improvement
  • Other (describe below)

Testing

  • Added/updated unit tests
  • Tested manually (describe steps below)
  • No tests needed (explain why)

New: connector-authorization.spec.ts (default path still sends the callback URL on both requests; providerRedirectUri sent on authorize and exchange, Basic auth, no PKCE; missing RuName blocks the start; an old eBay row adopts the catalog's endpoints/redirect and persists the placeholder). Extended: oauth-authorize-settings.spec.ts, ebay-sell.live.spec.ts (static assertions).

Commands, all from the worktree of this branch:

  • node scripts/validate-adapters.mjs --warn (repo root): Validated 705 adapters: 705 passed, 0 failed, 1442 total warnings, none for ebay-sell (existing warnings only).
  • node scripts/regenerate-catalog.mjs: regenerated, no diff in catalog.ts.
  • node scripts/adapter-count.mjs --check: OK: every quoted count equals 691 adapters (34 keyless, 12254 tools).
  • packages/backend: npx prisma generate, then npx tsc --noEmit -p tsconfig.json: exit 0.
  • packages/backend: npm run lint: exit 0, 0 errors, 11 existing warnings in files this PR does not touch; --fix changed nothing.
  • packages/backend: npx jest src/connectors/connector-authorization.spec.ts src/connectors/oauth-authorize-settings.spec.ts src/connectors/mcp-oauth.service.spec.ts src/connectors/mcp-oauth-callback.controller.spec.ts src/connectors/connectors.controller.spec.ts src/connectors/connect-page.controller.spec.ts --maxWorkers=1: 6 suites, 241 tests passed.
  • packages/backend: npx jest src/adapters/intl/ebay-sell.live.spec.ts src/adapters/setup-guide.spec.ts src/adapters/env-var-meta.spec.ts src/connectors/connector-setup-status.util.spec.ts --maxWorkers=1: 4 suites, 41 passed, 1 skipped (the live test, gated by RUN_EBAY_SELL_LIVE=1).
  • packages/backend: npx jest src/adapters/adapters.service.spec.ts src/connectors/catalog-resync.service.spec.ts src/adapters/mcp-adapter.spec.ts --maxWorkers=1: 3 suites, 127 passed.

The full backend suite was not run here (it runs in CI).

Not verified: the live sign-in against eBay. There is no eBay seller or developer account available to this work, so the consent page, the RuName form labels as they look today, and whether every keyset includes sell.payment.dispute by default come from eBay's documentation, not from a real run. The first real customer sign-in is the end-to-end proof.

Checklist

  • My code follows the existing code style
  • I have tested my changes locally
  • I have updated documentation (if applicable)
  • All existing tests pass (npm test) — targeted suites only, see above
  • This PR has a descriptive title

Related Issues

None. Reported by a Cloud customer through support chat (eBay connection refused, 2 November 2026).

The ebay-sell connector asked for a user refresh token, which eBay's
developer portal does not show (its User Tokens page gives 2-hour access
tokens only), so sellers could not connect it.

- authConfig.providerRedirectUri: the redirect_uri sent to the provider
  on the authorization request and the code exchange, in place of the
  callback URL. eBay wants the app's RuName there; the RuName's accepted
  URL brings the browser back to the unchanged callback route. Rows
  without it take the catalog's value, like pkce. Other adapters are
  unaffected.
- ebay-sell: browser sign-in (auth.ebay.com, Basic auth, no PKCE, sell
  scopes), EBAY_RUNAME, the refresh token filled by the sign-in, a
  three-step setup guide, verify hint and updated instructions. Tokens
  pasted earlier keep working.
@helpcodeai
helpcodeai requested a review from D3nisty as a code owner November 2, 2026 07:43
@helpcodeai
helpcodeai enabled auto-merge (squash) November 2, 2026 07:51
@helpcodeai
helpcodeai merged commit b606a1b into main Nov 2, 2026
14 checks passed
@helpcodeai
helpcodeai deleted the feat/ebay-oauth-signin branch November 2, 2026 09:14
@github-actions github-actions Bot locked and limited conversation to collaborators Nov 2, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant