Skip to main content

MCP server for Sam's Club Sponsored Ads APIs

Project description

mcp-samsclub-ads

MCP server for Sam's Club Sponsored Ads APIs — spec-driven endpoint discovery and a generic authenticated proxy with automatic RSA-SHA256 request signing.

Forked from mcp-walmart-ads: Sam's Club runs on the same Walmart api-proxy backend and uses the same WM_* signing headers, so the auth, HTTP client, discovery, caching, and tool surface carry over. The differences are a single sponsored ad family (vs Walmart's search/display), the Sam's Club base URLs, and a hand-authored OpenAPI spec.

Install & run

uvx mcp-samsclub-ads        # published
uv run mcp-samsclub-ads     # from source

The server speaks MCP over stdio.

Configuration

Create ~/.config/mcp-samsclub-ads/config.json from config.example.json:

{
  "regions": {
    "US": {
      "sandbox": {
        "consumer_id": "your-consumer-id",
        "private_key": "./keys/us/sandbox.pem",
        "private_key_version": "1",
        "bearer_token": "your-bearer-token",
        "base_urls": {
          "sponsored": "https://developer.api.us.stg.walmart.com/api-proxy/service/sp/api-sams/v1"
        }
      }
    }
  }
}

private_key is a path (relative paths resolve against the config dir) to your RSA private key PEM. Each request is signed with WM_CONSUMER.ID, WM_SEC.AUTH_SIGNATURE (Base64 RSA-SHA256), WM_SEC.KEY_VERSION, WM_CONSUMER.INTIMESTAMP (Unix epoch ms), plus Authorization: Bearer <token> — all injected automatically by the client.

Base URLs

  • Sandbox: https://developer.api.us.stg.walmart.com/api-proxy/service/sp/api-sams/v1
  • Production: https://developer.api.us.walmart.com/api-proxy/service/sp/api-sams/v1

Paths in the spec begin /api/v1/... (or /api/v2/...), so the effective URL is <base_url>/api/v1/<resource>.

Tools

  • list_endpoints — list OpenAPI operations for an ad_type, filter by query/tag/method.
  • describe_endpoint — one operation plus its transitive components.schemas closure.
  • call_endpoint — execute a signed request by operation_id or by raw method+path. Raw path also reaches endpoints not yet in the bundled spec.
  • refresh_specs — re-pull the committed spec from its source_url into a user cache that takes precedence over the bundle (ship fixes without a release).

Resources: sca://config, sca://responses/{request_id}, sca://curl/{request_id}.

Spec coverage

The bundled OpenAPI spec is hand-authored from the developer.samsclub.com docs and is partial by design. It covers the core ads surface: Campaigns, Statistics, Ad Groups, Ad Items, Catalog Item Search, Keywords (+ suggestions/analytics), Negative Keywords, Placements, Bid Multipliers, and Snapshot Reports v1/v2 + Latest Report Date. Endpoints not yet modeled (SBA profiles, media, reviews, api-usage, entity/audit snapshots, alerts & recommendations) are still reachable via call_endpoint with a raw method+path.

Status & blocker

Partner credentials are the long pole. Access requires emailing an RSA public key to partner-support@samsclub.com and receiving a consumer id + auth token + key version. Without sandbox credentials the server runs and its discovery/signing are verified offline, but calls cannot be exercised end-to-end.

Spec drift detection

scripts/build_spec.py scrapes the docs into a candidate spec at spec-candidate/ — offline, never at runtime. The Spec drift workflow runs it on a schedule and opens a PR when the docs change; a reviewer then ports real changes into the hand-authored canonical spec. The candidate is intentionally flat and is never shipped or loaded.

uv run --group spec-build python scripts/build_spec.py          # write candidate
uv run --group spec-build python scripts/build_spec.py --check  # exit 1 on drift

Still deferred: flipping a spec's auth flag to fetch the authenticated live Swagger backend once partner credentials exist.

Development

uv sync --group dev
uv run ruff check src/ tests/ && uv run ruff format --check src/ tests/
uv run pyright
uv run pytest

Reference

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcp_samsclub_ads-0.1.0a2.tar.gz (76.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcp_samsclub_ads-0.1.0a2-py3-none-any.whl (21.2 kB view details)

Uploaded Python 3

File details

Details for the file mcp_samsclub_ads-0.1.0a2.tar.gz.

File metadata

  • Download URL: mcp_samsclub_ads-0.1.0a2.tar.gz
  • Upload date:
  • Size: 76.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mcp_samsclub_ads-0.1.0a2.tar.gz
Algorithm Hash digest
SHA256 5dc252c57b87915fd7250addd3331ac1fa4ce83c3bde9c808d9d57279422fb17
MD5 4f9610ae7b7f7d7c87f31ad609b663f1
BLAKE2b-256 7399070f0ae044dead1c27ad5d69041b249d2d508e4cb9411a6043894200303b

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_samsclub_ads-0.1.0a2.tar.gz:

Publisher: ci.yml on alyiox/mcp-samsclub-ads

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mcp_samsclub_ads-0.1.0a2-py3-none-any.whl.

File metadata

File hashes

Hashes for mcp_samsclub_ads-0.1.0a2-py3-none-any.whl
Algorithm Hash digest
SHA256 5a9ee73d0cdc9adc5f95760783dd949be98501db8f979e638bac3e8fd53ea6b4
MD5 c9759caa1ef7279c180fc07951f8844d
BLAKE2b-256 d465f7bc066a827e00fa9bd8b7b9c8c742fb8132c58fbbc22b7fe4b13754fafb

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_samsclub_ads-0.1.0a2-py3-none-any.whl:

Publisher: ci.yml on alyiox/mcp-samsclub-ads

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page