Skip to main content
Glama

dsers.product.import

Import products from AliExpress, Alibaba, or 1688 supplier URLs into DSers for dropshipping. Supports single or batch imports with pricing rules and preview data before store push.

Instructions

Import product(s) from supplier URL(s) into the DSers import list and return a preview bundle with title, prices, images, and variants. Single mode: provide source_url. Batch mode: provide source_urls_json with an array of URLs or objects. Each successful import returns a job_id needed for dsers.product.preview, dsers.product.visibility, and dsers.store.push. Returns: job_id, status, title_before/after, price_range_before/after, images_before/after, variant_count, variant_preview (first 5), warnings.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
source_urlNoSingle supplier product URL. Supports AliExpress (aliexpress.com/item/xxx.html), Alibaba (alibaba.com/product-detail/xxx.html), and 1688 (1688.com/offer/xxx.html).
source_urls_jsonNoBatch import: JSON array of URL strings or objects with {url, rules?, source_hint?, country?, target_store?, visibility_mode?}. Example: ["https://aliexpress.com/item/123.html", {"url": "https://aliexpress.com/item/456.html", "rules": {"pricing": {"mode": "multiplier", "multiplier": 3}}}]
source_hintNoSupplier platform hint. Valid values: auto, aliexpress, alibaba, 1688, accio. Default: auto (detected from URL).auto
countryNoTarget country code for shipping and pricing lookup. Examples: US, GB, DE, FR, AU.US
target_storeNoStore ID or display name from dsers.store.discover. Required when the account has multiple stores.
visibility_modeNoProduct visibility after push. backend_only: saved as draft, not visible to shoppers. sell_immediately: published and visible on the storefront.backend_only
rules_jsonNoOptional rules as JSON string applied to all items. Keys: pricing ({mode, multiplier, fixed_markup, round_digits}), content ({title_override, title_prefix, title_suffix, description_override_html, description_append_html, tags_add}), images ({keep_first_n, drop_indexes}). Example: {"pricing": {"mode": "fixed_markup", "fixed_markup": 5.00}}

Implementation Reference

  • The `prepareSingle` method handles the actual import logic, including rule normalization, supplier URL resolution, and creating a new import job.
    private async prepareSingle(
      payload: Record<string, any>,
    ): Promise<Record<string, any>> {
      const sourceUrl = String(payload.source_url ?? "").trim();
      if (!sourceUrl)
        throw new Error(
          "source_url is required. Provide a supplier product URL (AliExpress, Alibaba, or 1688).",
        );
    
      const sourceHint = String(payload.source_hint ?? "auto").trim() || "auto";
      const country = String(payload.country ?? "US").trim() || "US";
      const visibilityMode =
        String(payload.visibility_mode ?? "backend_only").trim() || "backend_only";
      const targetStore = payload.target_store ?? null;
      const rules = payload.rules ?? {};
    
      const providerCaps =
        await this.provider.getRuleCapabilities(targetStore);
      const validatedRules = normalizeRules(rules, providerCaps.rule_families);
      if (validatedRules.errors?.length) {
        throw new Error(validatedRules.errors.join("; "));
      }
    
      const resolved = await resolveSourceUrl(sourceUrl, sourceHint);
      const prepared = await this.provider.prepareCandidate(
        resolved.resolved_url,
        resolved.source_hint,
        country,
      );
    
      const originalDraft = structuredClone(prepared.draft);
      const effectiveRules = validatedRules.effective_rules ?? {};
      const ruled = applyRules(prepared.draft, effectiveRules);
      const finalDraft = ruled.draft;
    
      const job: Record<string, any> = {
        status: "preview_ready",
        created_at: utcNow(),
        provider_label: prepared.provider_label ?? this.provider.name,
        source_url: sourceUrl,
        resolved_source_url: resolved.resolved_url,
        source_hint: resolved.source_hint,
        resolver_mode: resolved.resolver_mode,
        country,
        target_store: targetStore,
        visibility_mode: visibilityMode,
        requested_rules: validatedRules.requested_rules ?? {},
        effective_rules_snapshot: effectiveRules,
        rules: effectiveRules,
        provider_state: prepared.provider_state,
        original_draft: originalDraft,
        draft: finalDraft,
        warnings: [
          ...(resolved.warnings ?? []),
          ...(prepared.warnings ?? []),
          ...(validatedRules.warnings ?? []),
          ...((ruled.summary?.warnings as string[]) ?? []),
        ],
        rule_summary: ruled.summary ?? {},
      };
      const jobId = this.store.create(job);
      job.job_id = jobId;
      this.store.save(jobId, job);
      return this.preview(job);
    }
  • src/tools.ts:111-213 (registration)
    The MCP tool registration for `dsers.product.import` which parses input arguments and calls the service handler.
    server.registerTool(
      "dsers.product.import",
      {
        title: "AliExpress / Alibaba / 1688 Product Import",
        description:
          "Import product(s) from supplier URL(s) into the DSers import list and return a preview bundle with title, prices, images, and variants. " +
          "Single mode: provide source_url. Batch mode: provide source_urls_json with an array of URLs or objects. " +
          "Each successful import returns a job_id needed for dsers.product.preview, dsers.product.visibility, and dsers.store.push. " +
          "Returns: job_id, status, title_before/after, price_range_before/after, images_before/after, variant_count, variant_preview (first 5), warnings.",
        inputSchema: {
          source_url: z
            .string()
            .optional()
            .describe(
              "Single supplier product URL. Supports AliExpress (aliexpress.com/item/xxx.html), " +
                "Alibaba (alibaba.com/product-detail/xxx.html), and 1688 (1688.com/offer/xxx.html).",
            ),
          source_urls_json: z
            .string()
            .optional()
            .describe(
              "Batch import: JSON array of URL strings or objects with {url, rules?, source_hint?, country?, target_store?, visibility_mode?}. " +
                'Example: ["https://aliexpress.com/item/123.html", ' +
                '{"url": "https://aliexpress.com/item/456.html", "rules": {"pricing": {"mode": "multiplier", "multiplier": 3}}}]',
            ),
          source_hint: z
            .string()
            .default("auto")
            .describe(
              "Supplier platform hint. Valid values: auto, aliexpress, alibaba, 1688, accio. Default: auto (detected from URL).",
            ),
          country: z
            .string()
            .default("US")
            .describe(
              "Target country code for shipping and pricing lookup. Examples: US, GB, DE, FR, AU.",
            ),
          target_store: z
            .string()
            .optional()
            .describe(
              "Store ID or display name from dsers.store.discover. Required when the account has multiple stores.",
            ),
          visibility_mode: z
            .string()
            .default("backend_only")
            .describe(
              "Product visibility after push. " +
                "backend_only: saved as draft, not visible to shoppers. " +
                "sell_immediately: published and visible on the storefront.",
            ),
          rules_json: z
            .string()
            .optional()
            .describe(
              "Optional rules as JSON string applied to all items. " +
                "Keys: pricing ({mode, multiplier, fixed_markup, round_digits}), " +
                "content ({title_override, title_prefix, title_suffix, description_override_html, description_append_html, tags_add}), " +
                "images ({keep_first_n, drop_indexes}). " +
                'Example: {"pricing": {"mode": "fixed_markup", "fixed_markup": 5.00}}',
            ),
        },
        annotations: {
          readOnlyHint: false,
          destructiveHint: false,
          idempotentHint: false,
          openWorldHint: true,
        },
      },
      async (args) => {
        try {
          const payload: Record<string, any> = {};
    
          if (args.source_urls_json) {
            const parsed = safeJsonParse(
              args.source_urls_json, "source_urls_json",
              'Expected a JSON array of URL strings or objects. Example: ["https://aliexpress.com/item/123.html"]',
            );
            if (parsed.error) return fail(new Error(parsed.error));
            payload.source_urls = parsed.value;
          } else if (args.source_url) {
            payload.source_url = args.source_url;
          }
    
          if (args.source_hint) payload.source_hint = args.source_hint;
          if (args.country) payload.country = args.country;
          if (args.target_store) payload.target_store = args.target_store;
          if (args.visibility_mode) payload.visibility_mode = args.visibility_mode;
    
          if (args.rules_json) {
            const parsed = safeJsonParse(
              args.rules_json, "rules_json",
              'Expected a JSON object with optional keys: pricing, content, images. ' +
                'Example: {"pricing": {"mode": "multiplier", "multiplier": 2.0}}',
            );
            if (parsed.error) return fail(new Error(parsed.error));
            payload.rules = parsed.value;
          }
    
          return ok(await svc().prepareImportCandidate(payload));
        } catch (err) { return fail(err); }
      },
    );

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/lofder/dsers-mcp-product'

If you have feedback or need assistance with the MCP directory API, please join our Discord server