gmc-mcp 0.2.0__tar.gz

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.
Files changed (51) hide show
  1. gmc_mcp-0.2.0/.gitignore +13 -0
  2. gmc_mcp-0.2.0/CHANGELOG.md +73 -0
  3. gmc_mcp-0.2.0/CONTRIBUTING.md +61 -0
  4. gmc_mcp-0.2.0/LICENSE +21 -0
  5. gmc_mcp-0.2.0/PKG-INFO +351 -0
  6. gmc_mcp-0.2.0/README.md +302 -0
  7. gmc_mcp-0.2.0/examples/README.md +18 -0
  8. gmc_mcp-0.2.0/examples/audit_disapproved.py +67 -0
  9. gmc_mcp-0.2.0/examples/bulk_price_update.py +78 -0
  10. gmc_mcp-0.2.0/examples/claude_desktop_config_snippet.json +14 -0
  11. gmc_mcp-0.2.0/examples/quickstart.py +50 -0
  12. gmc_mcp-0.2.0/pyproject.toml +120 -0
  13. gmc_mcp-0.2.0/src/gmc_mcp/__init__.py +1 -0
  14. gmc_mcp-0.2.0/src/gmc_mcp/_logging.py +52 -0
  15. gmc_mcp-0.2.0/src/gmc_mcp/audit.py +59 -0
  16. gmc_mcp-0.2.0/src/gmc_mcp/auth.py +117 -0
  17. gmc_mcp-0.2.0/src/gmc_mcp/cli.py +279 -0
  18. gmc_mcp-0.2.0/src/gmc_mcp/client.py +202 -0
  19. gmc_mcp-0.2.0/src/gmc_mcp/config.py +126 -0
  20. gmc_mcp-0.2.0/src/gmc_mcp/py.typed +0 -0
  21. gmc_mcp-0.2.0/src/gmc_mcp/server.py +106 -0
  22. gmc_mcp-0.2.0/src/gmc_mcp/tools/__init__.py +45 -0
  23. gmc_mcp-0.2.0/src/gmc_mcp/tools/account_config.py +289 -0
  24. gmc_mcp-0.2.0/src/gmc_mcp/tools/accounts.py +166 -0
  25. gmc_mcp-0.2.0/src/gmc_mcp/tools/bulk.py +124 -0
  26. gmc_mcp-0.2.0/src/gmc_mcp/tools/conversions.py +89 -0
  27. gmc_mcp-0.2.0/src/gmc_mcp/tools/diagnostics.py +222 -0
  28. gmc_mcp-0.2.0/src/gmc_mcp/tools/feeds.py +112 -0
  29. gmc_mcp-0.2.0/src/gmc_mcp/tools/homepage.py +48 -0
  30. gmc_mcp-0.2.0/src/gmc_mcp/tools/inventory.py +140 -0
  31. gmc_mcp-0.2.0/src/gmc_mcp/tools/issues.py +99 -0
  32. gmc_mcp-0.2.0/src/gmc_mcp/tools/lfp.py +114 -0
  33. gmc_mcp-0.2.0/src/gmc_mcp/tools/mca.py +132 -0
  34. gmc_mcp-0.2.0/src/gmc_mcp/tools/notifications.py +61 -0
  35. gmc_mcp-0.2.0/src/gmc_mcp/tools/omnichannel.py +119 -0
  36. gmc_mcp-0.2.0/src/gmc_mcp/tools/products.py +217 -0
  37. gmc_mcp-0.2.0/src/gmc_mcp/tools/promotions.py +45 -0
  38. gmc_mcp-0.2.0/src/gmc_mcp/tools/quotas.py +36 -0
  39. gmc_mcp-0.2.0/src/gmc_mcp/tools/regions.py +99 -0
  40. gmc_mcp-0.2.0/src/gmc_mcp/tools/reports.py +170 -0
  41. gmc_mcp-0.2.0/src/gmc_mcp/tools/return_policies.py +79 -0
  42. gmc_mcp-0.2.0/src/gmc_mcp/tools/reviews.py +99 -0
  43. gmc_mcp-0.2.0/tests/__init__.py +0 -0
  44. gmc_mcp-0.2.0/tests/conftest.py +62 -0
  45. gmc_mcp-0.2.0/tests/test_audit.py +47 -0
  46. gmc_mcp-0.2.0/tests/test_client.py +114 -0
  47. gmc_mcp-0.2.0/tests/test_config.py +106 -0
  48. gmc_mcp-0.2.0/tests/test_tools_issues.py +104 -0
  49. gmc_mcp-0.2.0/tests/test_tools_products.py +96 -0
  50. gmc_mcp-0.2.0/tests/test_tools_reports.py +47 -0
  51. gmc_mcp-0.2.0/tests/test_tools_v2.py +179 -0
@@ -0,0 +1,13 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ .venv/
5
+ venv/
6
+ .env
7
+ secrets/
8
+ logs/
9
+ *.jsonl
10
+ .pytest_cache/
11
+ .ruff_cache/
12
+ dist/
13
+ build/
@@ -0,0 +1,73 @@
1
+ # Changelog — Google Merchant Center MCP (`gmc-mcp`)
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Added
11
+ - `tools/regions.py`: regions CRUD (list / get / create / update / delete) —
12
+ required to set up regional inventory targeting.
13
+ - `tools/accounts.py`: `gmc_update_business_info` (PATCH businessInfo —
14
+ address, phone, customer service, KR business registration number).
15
+ - `tools/accounts.py`: `gmc_request_program_review` and `gmc_get_program_review`
16
+ for re-requesting Shopping Ads / Free Listings approval after fixing issues.
17
+
18
+ ## [0.2.0] - 2026-05-01
19
+
20
+ ### Added — full Merchant API v1 surface
21
+ - `tools/return_policies.py`: list / get / create / update / delete `onlineReturnPolicies` (Google now requires a return policy in US/EU).
22
+ - `tools/homepage.py`: get / update / `claim` / `unclaim` the registered homepage.
23
+ - `tools/account_config.py`: business identity, checkout settings (per program),
24
+ automatic improvements, autofeed settings, account tax, email preferences,
25
+ Terms of Service (latest / agreement states / accept).
26
+ - `tools/quotas.py`: list per-method quota usage and limits.
27
+ - `tools/reviews.py`: merchant + product reviews CRUD.
28
+ - `tools/conversions.py`: conversion sources CRUD + undelete.
29
+ - `tools/omnichannel.py`: omnichannel settings, GBP account linkage,
30
+ `requestInventoryVerification`.
31
+ - `tools/lfp.py`: full Local Feed Partnership API
32
+ (lfpStores / lfpInventories / lfpSales / lfpMerchantStates).
33
+ - `tools/mca.py`: relationships, account aggregation, account services delegation
34
+ (propose / approve / reject).
35
+ - `tools/bulk.py`: `gmc_bulk_update_regional_prices`,
36
+ `gmc_bulk_set_availability` — both gated by `confirm='APPLY'`.
37
+ - `tools/diagnostics.py`: `gmc_health_check`, `gmc_rollback(audit_id)`,
38
+ `gmc_export_all(output_dir)`, `gmc_diff_with_shopify(shopify_csv)`.
39
+ - `tools/products.py`: `gmc_bulk_delete_products` with `confirm='DELETE'` gate
40
+ and automatic `dataSource` extraction (works on orphan products).
41
+ - `tools/reports.py`: 6 new canned queries — revenue by brand, category
42
+ performance, competitive visibility, price insights, demoted products.
43
+ - CLI: `gmc-mcp webhook` — tiny HTTP receiver that decodes Pub/Sub push
44
+ notifications from `gmc_subscribe`. Logs to JSONL with `--out`.
45
+
46
+ ### Fixed
47
+ - `gmc_summarize_product_issues` now reads the v1 `itemIssues` schema
48
+ (`type.code`, `type.canonicalAttribute`, `severity.aggregatedSeverity`,
49
+ `resolution`) instead of the v1beta flat shape.
50
+ - `gmc_list_disapproved_products` now includes the required `id` field in the
51
+ Reports SELECT (v1 requirement).
52
+ - `gmc_update_regional_inventory` / `gmc_update_local_inventory` build the
53
+ `regionalInventoryAttributes` / `localInventoryAttributes` envelope required
54
+ by v1 (v1beta flat fields are no longer accepted).
55
+
56
+ ## [0.1.0] - 2026-04-30
57
+
58
+ ### Added
59
+ - Initial release. Targets **Merchant API v1** (v1beta was shut down 2026-02-28).
60
+ - `gmc-mcp register-gcp` CLI: one-time link of GCP project to Merchant Center,
61
+ required before any v1 call works.
62
+ - 42 MCP tools across 8 modules covering products, inventory, issues, reports,
63
+ promotions, accounts, notifications, and data sources (feeds).
64
+ - Service-account authentication with auto-refresh.
65
+ - OAuth 2.0 user-credential authentication as an alternative.
66
+ - Append-only audit log for every write operation, with `gmc_audit_lookup`
67
+ and `gmc_audit_tail` for inspection.
68
+ - Dry-run mode (`GMC_DRY_RUN=true` or `gmc_set_dry_run`) for safe testing.
69
+ - Both stdio and HTTP/SSE transports.
70
+ - CLI entrypoint `gmc-mcp` with `--transport`, `--host`, `--port`, `--env`.
71
+ - Reports API helpers: raw SQL queries, top performers, price competitiveness,
72
+ best sellers, zero-click outliers.
73
+ - Issue summarization that aggregates problem codes across all products.
@@ -0,0 +1,61 @@
1
+ # Contributing to gmc-mcp
2
+
3
+ Thanks for your interest! Contributions of all sizes are welcome.
4
+
5
+ ## Dev setup
6
+
7
+ ```bash
8
+ git clone https://github.com/<you>/gmc-mcp.git
9
+ cd gmc-mcp
10
+ python -m venv .venv
11
+ . .venv/Scripts/activate # Windows; use 'source .venv/bin/activate' on Unix
12
+ pip install -e ".[dev,test]"
13
+ pre-commit install
14
+ ```
15
+
16
+ ## Running tests
17
+
18
+ ```bash
19
+ pytest # all tests
20
+ pytest -k products # filter
21
+ pytest --cov=gmc_mcp # with coverage
22
+ ```
23
+
24
+ Tests run fully offline using `respx` to mock the Merchant API. They do **not**
25
+ hit Google's servers, so you don't need credentials to develop on this repo.
26
+
27
+ ## Style
28
+
29
+ - `ruff format` + `ruff check --fix` (run automatically by pre-commit).
30
+ - `mypy src/gmc_mcp` should pass.
31
+ - Type-hint everything new.
32
+ - Public tool functions need a docstring; the first line becomes the MCP tool
33
+ description shown to the model.
34
+
35
+ ## Adding a tool
36
+
37
+ 1. Pick (or create) a module under `src/gmc_mcp/tools/`.
38
+ 2. Define the function inside the module's `register(mcp, client)` and decorate
39
+ with `@mcp.tool()`.
40
+ 3. Use `client.request(method, path, ...)` for everything — never call `httpx`
41
+ directly so audit and retries stay consistent.
42
+ 4. For write operations, pass `op="..."` so the audit log has a readable label.
43
+ 5. For tools that read the existing state before mutating, pass `before=...`
44
+ so the audit log can be used to roll back.
45
+ 6. Add a unit test in `tests/test_tools_<module>.py`.
46
+
47
+ ## Releasing
48
+
49
+ Maintainers only.
50
+
51
+ ```bash
52
+ # 1. Bump the version in src/gmc_mcp/__init__.py and pyproject.toml
53
+ # 2. Update CHANGELOG.md (move Unreleased entries to a new dated section)
54
+ # 3. Commit + tag
55
+ git commit -am "release: 0.x.y"
56
+ git tag v0.x.y
57
+ git push origin main --tags
58
+ ```
59
+
60
+ The `publish.yml` workflow then builds and uploads to PyPI via OIDC trusted
61
+ publishing (no API tokens stored in the repo).
gmc_mcp-0.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 eric.eom
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
gmc_mcp-0.2.0/PKG-INFO ADDED
@@ -0,0 +1,351 @@
1
+ Metadata-Version: 2.4
2
+ Name: gmc-mcp
3
+ Version: 0.2.0
4
+ Summary: Google Merchant Center MCP — the first MCP server for Google Merchant Center (Merchant API v1). Drive your Google Shopping feed, products, inventory, reports, promotions, returns, and account in natural language from Claude.
5
+ Project-URL: Homepage, https://github.com/kiwoongeom/gmc-mcp
6
+ Project-URL: Documentation, https://github.com/kiwoongeom/gmc-mcp#readme
7
+ Project-URL: Repository, https://github.com/kiwoongeom/gmc-mcp
8
+ Project-URL: Issues, https://github.com/kiwoongeom/gmc-mcp/issues
9
+ Project-URL: Changelog, https://github.com/kiwoongeom/gmc-mcp/blob/main/CHANGELOG.md
10
+ Author-email: "eric.eom" <eric.eom@gmail.com>
11
+ License: MIT
12
+ License-File: LICENSE
13
+ Keywords: agent-tools,anthropic,claude,claude-desktop,ecommerce,free-listings,gmc,google-merchant-center,google-merchant-center-mcp,google-shopping,google-shopping-ads,llm-tools,mcp,merchant-api,merchant-center,model-context-protocol,shopify,shopping-ads
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Environment :: Console
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: Intended Audience :: Information Technology
18
+ Classifier: License :: OSI Approved :: MIT License
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3 :: Only
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
+ Classifier: Topic :: Internet :: WWW/HTTP
27
+ Classifier: Topic :: Office/Business
28
+ Classifier: Topic :: Software Development :: Libraries
29
+ Classifier: Typing :: Typed
30
+ Requires-Python: >=3.10
31
+ Requires-Dist: click>=8.1.0
32
+ Requires-Dist: google-auth-oauthlib>=1.2.0
33
+ Requires-Dist: google-auth>=2.30.0
34
+ Requires-Dist: httpx>=0.27.0
35
+ Requires-Dist: mcp>=1.2.0
36
+ Requires-Dist: pydantic>=2.7.0
37
+ Requires-Dist: python-dotenv>=1.0.1
38
+ Provides-Extra: dev
39
+ Requires-Dist: build>=1.2; extra == 'dev'
40
+ Requires-Dist: mypy>=1.10; extra == 'dev'
41
+ Requires-Dist: pre-commit>=3.7; extra == 'dev'
42
+ Requires-Dist: ruff>=0.8; extra == 'dev'
43
+ Provides-Extra: test
44
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'test'
45
+ Requires-Dist: pytest-cov>=5.0; extra == 'test'
46
+ Requires-Dist: pytest>=8.0; extra == 'test'
47
+ Requires-Dist: respx>=0.21; extra == 'test'
48
+ Description-Content-Type: text/markdown
49
+
50
+ # Google Merchant Center MCP (`gmc-mcp`)
51
+
52
+ [![PyPI](https://img.shields.io/pypi/v/gmc-mcp.svg)](https://pypi.org/project/gmc-mcp/)
53
+ [![CI](https://github.com/kiwoongeom/gmc-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/kiwoongeom/gmc-mcp/actions/workflows/ci.yml)
54
+ [![Python](https://img.shields.io/pypi/pyversions/gmc-mcp.svg)](https://pypi.org/project/gmc-mcp/)
55
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
56
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
57
+
58
+ > **The first MCP server for Google Merchant Center (GMC).**
59
+ > Drive your Google Shopping feed, products, inventory, Reports, promotions,
60
+ > returns, and account configuration in natural language from Claude Desktop,
61
+ > Claude Code, or any MCP-compatible client.
62
+
63
+ Built on **Merchant API v1** (replaces Content API for Shopping; v1beta was
64
+ discontinued 2026-02-28). Safe by default: every write is recorded to an
65
+ append-only audit log with `before` snapshots, dry-run is one toggle away, and
66
+ destructive bulk operations require an explicit `confirm` parameter.
67
+
68
+ ## Why this exists
69
+
70
+ Google Merchant Center (GMC) is what powers Google Shopping listings, Free
71
+ Listings, Shopping Ads, Buy on Google checkout, YouTube Shopping, and more.
72
+ Until now there was no MCP server for it — managing a feed of thousands of
73
+ products through the GMC web UI is tedious, and writing one-off Python scripts
74
+ against the Merchant API REST endpoints is slow.
75
+
76
+ This package gives Claude (or any MCP client) **126 tools** that map directly
77
+ onto the Merchant API v1 surface, so you can do things like:
78
+
79
+ - *"Show me every disapproved product, grouped by issue code."*
80
+ - *"Bump US prices 5% on these 40 SKUs."*
81
+ - *"Which products had impressions but zero clicks last week?"*
82
+ - *"Roll back audit ID 8fc8dc42… — that update broke something."*
83
+ - *"Compare this Shopify CSV against my GMC feed; what's missing?"*
84
+
85
+ ## What's exposed
86
+
87
+ **126 tools across 19 modules + 4 meta tools.**
88
+
89
+ | Module | Tools |
90
+ |---|---|
91
+ | **products** | `gmc_list_products`, `gmc_get_product`, `gmc_insert_product`, `gmc_update_product`, `gmc_delete_product`, `gmc_bulk_delete_products`, `gmc_list_disapproved_products` |
92
+ | **inventory** | `gmc_update_regional_inventory`, `gmc_update_local_inventory`, `gmc_list_regional_inventories`, `gmc_list_local_inventories` |
93
+ | **issues** | `gmc_list_account_issues`, `gmc_get_product_status`, `gmc_summarize_product_issues` |
94
+ | **reports** | `gmc_query_report`, `gmc_product_performance`, `gmc_price_competitiveness`, `gmc_best_sellers`, `gmc_zero_click_products`, `gmc_revenue_by_brand`, `gmc_category_performance`, `gmc_competitive_visibility_top_merchants`, `gmc_price_insights`, `gmc_demoted_products` |
95
+ | **promotions** | `gmc_list_promotions`, `gmc_get_promotion`, `gmc_insert_promotion` |
96
+ | **accounts** | `gmc_get_account`, `gmc_get_business_info`, `gmc_update_business_info`, `gmc_list_users`, `gmc_add_user`, `gmc_remove_user`, `gmc_get_shipping_settings`, `gmc_update_shipping_settings`, `gmc_list_programs`, `gmc_request_program_review`, `gmc_get_program_review` |
97
+ | **regions** | `gmc_list_regions`, `gmc_get_region`, `gmc_create_region`, `gmc_update_region`, `gmc_delete_region` |
98
+ | **notifications** | `gmc_list_subscriptions`, `gmc_subscribe`, `gmc_unsubscribe` |
99
+ | **feeds** | `gmc_list_datasources`, `gmc_get_datasource`, `gmc_create_supplemental_feed`, `gmc_create_primary_feed`, `gmc_delete_datasource`, `gmc_fetch_datasource` |
100
+ | **return_policies** | `gmc_list_return_policies`, `gmc_get_return_policy`, `gmc_create_return_policy`, `gmc_update_return_policy`, `gmc_delete_return_policy` |
101
+ | **homepage** | `gmc_get_homepage`, `gmc_update_homepage`, `gmc_claim_homepage`, `gmc_unclaim_homepage` |
102
+ | **account_config** | `gmc_get_business_identity`, `gmc_update_business_identity`, `gmc_get_checkout_settings`, `gmc_create_checkout_settings`, `gmc_update_checkout_settings`, `gmc_delete_checkout_settings`, `gmc_get_automatic_improvements`, `gmc_update_automatic_improvements`, `gmc_get_autofeed_settings`, `gmc_update_autofeed_settings`, `gmc_get_account_tax`, `gmc_update_account_tax`, `gmc_get_email_preferences`, `gmc_update_email_preferences`, `gmc_get_latest_tos`, `gmc_list_tos_agreement_states`, `gmc_accept_tos` |
103
+ | **quotas** | `gmc_list_quotas` |
104
+ | **reviews** | `gmc_list_merchant_reviews`, `gmc_get_merchant_review`, `gmc_insert_merchant_review`, `gmc_delete_merchant_review`, `gmc_list_product_reviews`, `gmc_get_product_review`, `gmc_insert_product_review`, `gmc_delete_product_review` |
105
+ | **conversions** | `gmc_list_conversion_sources`, `gmc_get_conversion_source`, `gmc_create_conversion_source`, `gmc_update_conversion_source`, `gmc_delete_conversion_source`, `gmc_undelete_conversion_source` |
106
+ | **omnichannel** | `gmc_list_omnichannel_settings`, `gmc_get_omnichannel_settings`, `gmc_create_omnichannel_settings`, `gmc_update_omnichannel_settings`, `gmc_request_inventory_verification`, `gmc_link_gbp_account`, `gmc_list_gbp_accounts` |
107
+ | **lfp** | `gmc_lfp_list_stores`, `gmc_lfp_get_store`, `gmc_lfp_insert_store`, `gmc_lfp_delete_store`, `gmc_lfp_insert_inventory`, `gmc_lfp_insert_sale`, `gmc_lfp_get_merchant_state` |
108
+ | **mca** | `gmc_list_relationships`, `gmc_get_relationship`, `gmc_update_relationship`, `gmc_create_aggregation`, `gmc_delete_aggregation`, `gmc_list_account_services`, `gmc_propose_account_service`, `gmc_approve_account_service`, `gmc_reject_account_service` |
109
+ | **bulk** | `gmc_bulk_update_regional_prices`, `gmc_bulk_set_availability` |
110
+ | **diagnostics** | `gmc_health_check`, `gmc_rollback`, `gmc_export_all`, `gmc_diff_with_shopify` |
111
+ | **meta** | `gmc_describe_server`, `gmc_audit_lookup`, `gmc_audit_tail`, `gmc_set_dry_run` |
112
+
113
+ CLI also exposes: `gmc-mcp run`, `auth-init`, `register-gcp`, `webhook`, `describe`, `version`.
114
+
115
+ ## Install
116
+
117
+ ```bash
118
+ pip install gmc-mcp
119
+ ```
120
+
121
+ For development:
122
+
123
+ ```bash
124
+ git clone https://github.com/kiwoongeom/gmc-mcp
125
+ cd gmc-mcp
126
+ pip install -e ".[dev,test]"
127
+ pre-commit install
128
+ ```
129
+
130
+ ## Quick start
131
+
132
+ ### 1. Enable the Merchant API and create a service account
133
+
134
+ 1. [console.cloud.google.com](https://console.cloud.google.com) → create / pick a project.
135
+ 2. **APIs & Services → Library** → enable **Merchant API**.
136
+ 3. **IAM & Admin → Service Accounts → Create service account** named `gmc-mcp`.
137
+ 4. Open the new service account → **Keys → Add key → Create new key → JSON**. Save it somewhere safe.
138
+
139
+ ### 2. Add the service account to your Merchant Center
140
+
141
+ 1. [merchants.google.com](https://merchants.google.com) → top-right gear → **Account access → People**.
142
+ 2. **Add user** → enter the `gmc-mcp@PROJECT.iam.gserviceaccount.com` email → grant **Admin**.
143
+ 3. Note the 10-digit Merchant Center ID in the top-right.
144
+
145
+ ### 3. Configure
146
+
147
+ ```bash
148
+ cp .env.example .env
149
+ # edit:
150
+ # GMC_ACCOUNT_ID=1234567890
151
+ # GMC_SERVICE_ACCOUNT_KEY=/abs/path/to/service-account.json
152
+ ```
153
+
154
+ ### 4. One-time GCP registration
155
+
156
+ Required before any v1 Merchant API call works for a new project.
157
+
158
+ ```bash
159
+ gmc-mcp register-gcp --developer-email you@example.com
160
+ ```
161
+
162
+ ### 5. Smoke-test
163
+
164
+ ```bash
165
+ gmc-mcp describe # prints the resolved config
166
+ python examples/quickstart.py # makes one read against the Merchant API
167
+ ```
168
+
169
+ ### 6. Wire into Claude
170
+
171
+ Drop this into `%APPDATA%/Claude/claude_desktop_config.json` (Desktop) or `~/.claude/settings.json` (Code):
172
+
173
+ ```json
174
+ {
175
+ "mcpServers": {
176
+ "gmc": {
177
+ "command": "gmc-mcp",
178
+ "args": ["run"],
179
+ "env": {
180
+ "GMC_ACCOUNT_ID": "1234567890",
181
+ "GMC_SERVICE_ACCOUNT_KEY": "/abs/path/to/service-account.json"
182
+ }
183
+ }
184
+ }
185
+ }
186
+ ```
187
+
188
+ Restart Claude. Ask: *"What account am I connected to?"* — it should call `gmc_describe_server`.
189
+
190
+ ## OAuth instead of a service account
191
+
192
+ For acting on behalf of an end user (e.g. multi-tenant SaaS):
193
+
194
+ ```bash
195
+ # 1. In GCP, create OAuth client credentials (type: Desktop), download client_secret.json.
196
+ gmc-mcp auth-init --client-secrets ./client_secret.json
197
+ # follow the browser flow; a token JSON is saved to secrets/oauth-token.json.
198
+
199
+ # 2. Use it
200
+ export GMC_OAUTH_TOKEN=./secrets/oauth-token.json
201
+ gmc-mcp run
202
+ ```
203
+
204
+ ## Transports
205
+
206
+ ```bash
207
+ gmc-mcp run # stdio (Claude Desktop default)
208
+ gmc-mcp run --transport sse --port 8000 # SSE / HTTP (remote, Docker, hosted)
209
+ ```
210
+
211
+ Or via Docker:
212
+
213
+ ```bash
214
+ docker build -t gmc-mcp .
215
+ docker run --rm -p 8000:8000 \
216
+ -e GMC_ACCOUNT_ID=1234567890 \
217
+ -v $PWD/secrets:/secrets \
218
+ -e GMC_SERVICE_ACCOUNT_KEY=/secrets/service-account.json \
219
+ gmc-mcp
220
+ ```
221
+
222
+ ## Audit log + rollback
223
+
224
+ Every write logs a JSONL entry to `GMC_AUDIT_LOG` (default: `./logs/audit.jsonl`). Each entry contains:
225
+
226
+ - `audit_id` — UUID for lookup
227
+ - `op`, `method`, `url`, `request_body`, `response_status`, `response_body`
228
+ - `before` — pre-write snapshot when the tool fetched it (used by `update_*` and `delete_*`)
229
+ - `dry_run` — whether the request was actually sent
230
+
231
+ Inspect from inside Claude:
232
+
233
+ ```
234
+ > Show me my last 5 GMC writes.
235
+ [gmc_audit_tail(limit=5) → ...]
236
+
237
+ > Look up audit ID abc123.
238
+ [gmc_audit_lookup(audit_id="abc123") → ...]
239
+
240
+ > Roll back audit ID abc123, that update was wrong.
241
+ [gmc_rollback(audit_id="abc123", confirm="ROLLBACK") → ...]
242
+ ```
243
+
244
+ ## Dry-run
245
+
246
+ Two ways to enable:
247
+
248
+ ```bash
249
+ GMC_DRY_RUN=true gmc-mcp run
250
+ ```
251
+
252
+ ```
253
+ > Set dry-run on and update the price of SKU1 to $19.99.
254
+ [gmc_set_dry_run(enabled=True) → ok]
255
+ [gmc_update_regional_inventory(...) → {"_dry_run": true, ...}]
256
+ ```
257
+
258
+ Reads always go through; only writes are skipped.
259
+
260
+ ## Reports query examples
261
+
262
+ Paste into `gmc_query_report`:
263
+
264
+ ```sql
265
+ -- Top 50 by clicks last 7 days
266
+ SELECT offer_id, title, clicks, impressions, ctr
267
+ FROM product_performance_view
268
+ WHERE date BETWEEN '2026-04-23' AND '2026-04-30'
269
+ ORDER BY clicks DESC LIMIT 50
270
+
271
+ -- Disapproved products with reason codes
272
+ SELECT id, offer_id, title, item_issues
273
+ FROM product_view
274
+ WHERE aggregated_reporting_context_status = 'NOT_ELIGIBLE_OR_DISAPPROVED'
275
+
276
+ -- You're priced higher than the benchmark
277
+ SELECT offer_id, title, price, benchmark_price
278
+ FROM price_competitiveness_product_view
279
+ WHERE price > benchmark_price LIMIT 100
280
+ ```
281
+
282
+ ## Configuration reference
283
+
284
+ All config is via env vars (or `.env`). CLI flags `--transport`, `--host`, `--port`, `--env` override.
285
+
286
+ | Var | Required | Default | Notes |
287
+ |---|---|---|---|
288
+ | `GMC_ACCOUNT_ID` | yes | — | 10-digit Merchant Center ID |
289
+ | `GMC_SERVICE_ACCOUNT_KEY` | one of | — | Path to service-account JSON |
290
+ | `GMC_OAUTH_TOKEN` | one of | — | Path to OAuth token JSON |
291
+ | `GMC_SUBACCOUNT_ID` | no | — | When using an MCA |
292
+ | `GMC_AUDIT_LOG` | no | `./logs/audit.jsonl` | Append-only JSONL |
293
+ | `GMC_PAGE_SIZE` | no | `100` | Default list page size |
294
+ | `GMC_TIMEOUT` | no | `30` | Per-request seconds |
295
+ | `GMC_DRY_RUN` | no | `false` | Writes go to audit only |
296
+ | `GMC_LOG_LEVEL` | no | `INFO` | DEBUG/INFO/WARNING/ERROR |
297
+ | `GMC_TRANSPORT` | no | `stdio` | `stdio` or `sse` |
298
+ | `GMC_HOST` | no | `127.0.0.1` | SSE only |
299
+ | `GMC_PORT` | no | `8000` | SSE only |
300
+
301
+ ## Architecture
302
+
303
+ ```
304
+ Claude (any MCP client)
305
+ │ JSON-RPC over stdio or SSE
306
+ ▼
307
+ gmc-mcp server ──► audit.jsonl
308
+ │
309
+ │ HTTP + Bearer token
310
+ ▼
311
+ merchantapi.googleapis.com ──► Google Merchant Center
312
+ ```
313
+
314
+ - `auth.py` — `ServiceAccountAuth` and `OAuthUserAuth` share an `Auth` protocol.
315
+ - `client.py` — single `MerchantClient` with retries (5x w/ jitter), pagination helper, and write-audit hook.
316
+ - `tools/*.py` — each module exposes a `register(mcp, client)` that registers `@mcp.tool()` functions.
317
+ - `audit.py` — append-only JSONL, lookup by ID, supports `before` snapshots.
318
+ - `cli.py` — `gmc-mcp run | auth-init | register-gcp | webhook | describe | version`.
319
+
320
+ ## Testing
321
+
322
+ ```bash
323
+ pytest # 100% offline; uses respx to mock HTTP
324
+ pytest --cov=gmc_mcp # with coverage
325
+ ruff check src tests
326
+ mypy src/gmc_mcp
327
+ ```
328
+
329
+ ## Roadmap
330
+
331
+ - v0.3: webhook handler scaffolding (auto-respond to `gmc_subscribe` callbacks)
332
+ - v0.3: native Merchant API v1 GA migration when Google releases it
333
+ - v0.4: BigQuery export of Reports queries
334
+ - v0.4: rule-based auto-fixers ("on disapproval, retry with corrected attribute")
335
+
336
+ ## Contributing
337
+
338
+ See [CONTRIBUTING.md](CONTRIBUTING.md). PRs and issues welcome — this is the
339
+ first MCP for Google Merchant Center, so there's a lot of room for community
340
+ input on which workflows deserve dedicated tools.
341
+
342
+ ## License
343
+
344
+ MIT — see [LICENSE](LICENSE).
345
+
346
+ ---
347
+
348
+ *Search keywords: Google Merchant Center MCP, GMC MCP, Merchant API MCP,
349
+ Google Shopping MCP, Shopping Ads MCP, free listings MCP, Claude Desktop
350
+ Google Merchant Center, MCP for ecommerce, Shopify Google Merchant Center
351
+ automation.*