etsy-mcp
A production-grade MCP server that enables AI assistants like Claude to read Etsy shop data—listings, orders, inventory, and stats—through eight read-only tools, using OAuth and automatic pagination.
README
etsy-mcp
The first production-grade Model Context Protocol server for Etsy. Plug Claude into your Etsy shop's listings, inventory, orders, and stats — read-only, in five minutes.
Why this exists
Etsy's Open API v3 is well-documented and stable, but every seller who wants to put an LLM on top of their shop ends up writing the same OAuth-and-pagination glue from scratch. Existing MCP integrations are thin demos, missing token refresh, retry logic, and the per-shop pagination Etsy actually requires.
If you sell on Etsy and you've ever wanted Claude (or any MCP-aware AI assistant) to just know what's in your shop — what's listed, what shipped yesterday, what's running low — that gap is the difference between "summarize today's orders" working out of the box and "summarize today's orders" requiring a custom integration.
etsy-mcp closes that gap. It's a tiny, well-tested, MIT-licensed MCP server that exposes eight read-only Etsy endpoints to any MCP client. Built from years of running production ecommerce automation at scale.
What you can do with it
Wire this server into Claude Code, Claude Desktop, or any MCP host, then ask things like:
- "Search my shop for any listing with the word
vintagein the title and tell me how many are below quantity 5." - "How many orders did I get yesterday? Group by buyer and total revenue."
- "Pull receipt 5550001 and tell me which transactions shipped — and what's left to ship."
- "What were my shop stats over the last 30 days? Compare orders, favorers, and active listings."
- "For listing 1234567890, show me every variation, its SKU, and current quantity."
Claude reads your shop directly. No copy-paste, no spreadsheets, no custom pipelines.
Tools (v0.1, all read-only)
| Tool | What it does |
|---|---|
etsy_search_listings |
Keyword search across active listings, optionally shop-scoped. |
etsy_get_listing |
Fetch one listing by ID. |
etsy_get_shop |
Fetch the shop record (name, currency, counts, vacation). |
etsy_search_orders |
List receipts (orders) in a date window for one shop. |
etsy_get_order |
Fetch one receipt by ID, including line-item transactions. |
etsy_get_inventory |
Variation-level inventory (SKU, quantity, price) for a listing. |
etsy_get_shop_stats |
Composed period rollup: orders, favorers, revenue, listings. |
etsy_get_active_listings |
Paginated list of every active listing in a shop. |
Write endpoints (create draft listing, update inventory, mark receipt shipped) are intentionally not in v0.1. They are planned for v0.2 once read-only ergonomics settle.
Install
pip install etsy-mcp
v0.1 ships from this repository. PyPI publication is pending — for now, install with
pip install git+https://github.com/alveyautomation/etsy-mcpor clone and runpip install -e .locally.
Configure credentials
The server reads everything from environment variables. Copy .env.example to .env and fill in your tenant:
ETSY_API_URL=https://api.etsy.com/v3/application/ # default; usually leave alone
ETSY_API_KEY=your-keystring-from-etsy-developers
ETSY_REFRESH_TOKEN=oauth2-refresh-token-for-your-shop
ETSY_DEFAULT_SHOP_ID= # optional fallback
ETSY_HTTP_TIMEOUT=60 # optional, seconds
ETSY_MAX_RETRIES=3 # optional
Getting an Etsy API key
- Visit https://www.etsy.com/developers/your-apps and register an app.
- Copy the Keystring — that's
ETSY_API_KEY. - Configure the redirect URI for your one-time OAuth bootstrap (e.g.
http://localhost:3000/callback).
Getting a refresh token
Etsy uses OAuth 2.0 with PKCE. To bootstrap, run any standard OAuth-PKCE flow once with these parameters:
response_type=codeclient_id=<your keystring>redirect_uri=<your registered URI>scope=listings_r shops_r transactions_r(read-only — the minimum this server needs)state=<random>code_challenge=<PKCE>andcode_challenge_method=S256
Exchange the resulting authorization code at POST https://api.etsy.com/v3/public/oauth/token for an access + refresh token. Save the refresh token as ETSY_REFRESH_TOKEN. The server will use it to mint short-lived access tokens automatically.
Use minimum-scope read tokens. v0.1 only calls
GETendpoints, but defense in depth means you should never grant write scopes (*_w) to the server's refresh token. When v0.2 lands with write tools, opt-in by minting a fresh higher-scope token — never the other way around.
Wire into Claude Code
Add to ~/.claude/claude_code_config.json (or your project's MCP config):
{
"mcpServers": {
"etsy": {
"command": "etsy-mcp",
"env": {
"ETSY_API_KEY": "your-keystring",
"ETSY_REFRESH_TOKEN": "your-refresh-token",
"ETSY_DEFAULT_SHOP_ID": "12345678"
}
}
}
}
Restart Claude Code. The eight etsy_* tools will appear in any new session.
Wire into Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows) and add the same mcpServers block as above. Restart the desktop app.
Tool reference
Every tool returns a JSON envelope:
{ "ok": true, "data": { ... } }
{ "ok": false, "error": "human-readable message" }
etsy_search_listings
etsy_search_listings(
query: str, # required
shop_id: int | None = None, # scope to a single shop
limit: int = 50, # max 100 (Etsy server cap)
)
When shop_id is provided, this hits /shops/{shop_id}/listings/active. Otherwise it hits the global /listings/active index.
etsy_get_listing
etsy_get_listing(listing_id: int)
Returns the listing record, or data: null on 404.
etsy_get_shop
etsy_get_shop(shop_id: int)
The shop record includes shop_name, currency_code, listing_active_count, num_favorers, is_vacation, and more.
etsy_search_orders
etsy_search_orders(
date_from: str, # ISO date "YYYY-MM-DD"
date_to: str, # ISO date "YYYY-MM-DD"
shop_id: int | None = None, # falls back to default
status: str | None = None, # 'open' | 'unshipped' | 'completed' | 'all'
limit: int = 200, # max 1000
)
Etsy caps page size at 100; pagination is transparent. The response includes limit_reached: true when limit was the truncation point.
etsy_get_order
etsy_get_order(receipt_id: int, shop_id: int | None = None)
Returns the full receipt (with transactions[]), or data: null on 404.
etsy_get_inventory
etsy_get_inventory(listing_id: int)
Returns products[] with sku, property_values, and offerings[] (quantity, price, enabled). Use the offering quantity as the canonical "qty I can sell" number per variation.
etsy_get_shop_stats
etsy_get_shop_stats(shop_id: int, period: str = "30d")
A composed rollup. Etsy doesn't expose a first-class shop/stats endpoint at v3, so this synthesizes one from the shop record (favorers, active-listing count) and the receipts in the window. Returned shape:
{
"shop_id": 12345678,
"period": "30d",
"period_days": 30,
"date_from": "2026-03-27",
"date_to": "2026-04-26",
"favorers": 314,
"active_listings": 87,
"orders": 42,
"revenue_minor_units": 152400,
"currency_code": "USD"
}
period accepts <N>d form, max 365 days.
etsy_get_active_listings
etsy_get_active_listings(shop_id: int, limit: int = 200)
Paginated dump of every active listing in a shop. Useful for catalog-wide reasoning ("audit my titles for missing keywords"). Soft cap is 1000 to keep one tool invocation bounded.
Local development
git clone https://github.com/alveyautomation/etsy-mcp
cd etsy-mcp
python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e ".[dev]"
pytest # 49 tests, ~3s
Pre-commit hooks (gitleaks, trufflehog, ruff, formatter, tenant-fingerprint scrubber):
pip install pre-commit
pre-commit install
Integration tests against a real Etsy sandbox are gated behind ETSY_INTEGRATION_TESTS=1. They are not required for normal contribution.
Troubleshooting
Failed to refresh Etsy access token — your refresh token expired or was revoked. Etsy refresh tokens last 90 days from issue, but only if used regularly. Re-run the OAuth-PKCE bootstrap to mint a new one.
Missing required environment variables — the server tried to start before its .env was loaded. Either export the vars in the parent shell, or ensure your MCP host config includes them in the env block.
HTTP 403 on receipts/transactions — the refresh token's scopes are missing transactions_r. Re-bootstrap with the read scopes listed above.
Empty results despite known data — confirm the shop_id. Etsy's /shops/{shop_id}/... endpoints only return data for shops the OAuth token has been authorized against.
Pagination feels slow — Etsy caps page size at 100 per request, not us. For large date windows (long order histories), expect multiple round-trips. Lower the limit argument to bound the call.
Contributing
Issues and pull requests welcome. Please:
- Run
pytestbefore opening a PR (pip install -e ".[dev]"). - Run
pre-commit run --all-files. - Keep additions to v0.1 scope read-only. Write endpoints land in v0.2.
- Synthetic data only in tests — no real shop names, listing IDs, or receipt numbers.
License
MIT — see LICENSE.
Disclaimer
etsy-mcp is an unofficial, third-party integration. It is not endorsed by, affiliated with, or supported by Etsy, Inc. "Etsy" is a trademark of Etsy, Inc. Use at your own risk; verify behavior against your shop before depending on it for production decisions.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。