wandpad-etsy-mcp
# WandPad Etsy MCP-Server
Ein lokaler MCP-Server (Model Context Protocol), über den Claude auf den Etsy-Shop **WandPad** zugreifen kann - Shopdaten, Listings, Bestände, Varianten, Bestellungen lesen, und (optional, explizit freizuschalten) Listings anlegen und bearbeiten. Verwendet die offizielle **Etsy Open API v3** mit OAuth 2.0 (Authorization Code Flow + PKCE).
**Stufe 1: Lesezugriff.** Immer aktiv, unabhängig von jeder Konfiguration.
**Stufe 2: Schreibzugriff.** Standardmäßig deaktiviert (`ETSY_WRITE_ENABLED=false`). Erst nach bewusster lokaler Freischaltung nutzbar - und selbst dann verlangt jede echte Änderung eine explizite Vorschau (`dry_run`) und Bestätigung (`confirm`/`confirm_bulk`) im Chat. Es gibt **keine** Funktion, die Listings löscht - das wird es nie geben.
## Inhalt
- [Zweck der Integration](#zweck-der-integration)
- [Voraussetzungen](#voraussetzungen)
- [Installation](#installation)
- [Etsy Developer App](#etsy-developer-app)
- [Callback-URL](#callback-url)
- [Umgebungsvariablen](#umgebungsvariablen)
- [Etsy-Scopes](#etsy-scopes)
- [OAuth-Anmeldung](#oauth-anmeldung)
- [Start des MCP-Servers](#start-des-mcp-servers)
- [Verbindung zu Claude Desktop](#verbindung-zu-claude-desktop)
- [Verbindung zu Claude Code](#verbindung-zu-claude-code)
- [Erster Lesetest](#erster-lesetest)
- [Verfügbare Tools](#verfügbare-tools)
- [Tokens erneuern](#tokens-erneuern)
- [Tokens zurücksetzen (Logout)](#tokens-zurücksetzen-logout)
- [Fehlerbehebung](#fehlerbehebung)
- [Datenschutz](#datenschutz)
- [Sicherheitsregeln](#sicherheitsregeln)
- [Bekannte Einschränkungen der Etsy API](#bekannte-einschränkungen-der-etsy-api)
- [Schreibmodus aktivieren (Stufe 2)](#schreibmodus-aktivieren-stufe-2)
- [Gehostetes Deployment für Cowork-Agenten](#gehostetes-deployment-für-cowork-agenten)
- [Vollständige Deinstallation](#vollständige-deinstallation)
## Zweck der Integration
WandPad® verkauft individuell gefertigte, 3D-gedruckte Tablet-Wandhalterungen über Etsy. Dieser MCP-Server gibt Claude strukturierten, lesenden Zugriff auf den Shop, damit Claude beim Analysieren von Sortiment, Preisen, Beständen, Tags und Bestellungen helfen kann - ohne selbst etwas am Shop zu verändern.
## Voraussetzungen
- macOS
- Node.js 20 oder neuer (LTS empfohlen) - geprüft mit Node 24
- `openssl` im PATH (auf macOS vorinstalliert) - wird für ein lokales TLS-Zertifikat benötigt
- Eine genehmigte Etsy Developer App mit Produktionszugriff
### Bereits erfolgte Produktionsfreigabe
Etsy hat die Nutzung der Open API v3 in der **Produktionsumgebung** (nicht Sandbox) für diese Integration bereits genehmigt. Der Server verwendet ausschließlich echte Etsy-Endpunkte (`https://api.etsy.com/v3/application/...`), keine Testumgebung.
## Installation
```bash
cd "/Users/Dodo/Library/Mobile Documents/com~apple~CloudDocs/Documents/Claude Code"
npm install
npm run build
npm test
```
`npm test` führt die Tests für sicherheitskritische Funktionen aus (PKCE, Token-Speicher, PII-Redaktion, Audit-Log-Schutz, Eingabevalidierung, Callback-URL-Prüfung).
## Etsy Developer App
Deine App-Zugangsdaten findest du unter [etsy.com/developers/your-apps](https://www.etsy.com/developers/your-apps). Wichtig: Der API-Key-Status muss **"Active"** (bzw. "Personal Access") sein, nicht "Pending" - sonst lehnt Etsy jede Anfrage mit HTTP 403 ab.
Etsy zeigt das **Shared Secret** im Dashboard teils verkürzt an. Klicke explizit auf das Augen-Symbol, um den vollständigen Wert aufzudecken, bevor du ihn kopierst.
## Callback-URL
Etsy verlangt für die OAuth-Callback-URL zwingend ein `https://`-Prefix - auch für `localhost`. Eine reine `http://localhost:3000/...`-Adresse wird von Etsy abgelehnt (offizielle Doku: *"The URL must have the https:// prefix or the request will fail"*, keine Ausnahme für localhost dokumentiert).
**In deiner Etsy-App muss deshalb exakt folgende Callback-URL eingetragen sein:**
```
https://localhost:3000/oauth/callback
```
Da hierfür TLS notwendig ist, erzeugt der Server beim ersten Login automatisch ein **selbstsigniertes Zertifikat** für `localhost` (per `openssl`, liegt danach unter `.secrets/localhost-*.pem`). Der Browser zeigt beim Login deshalb einmalig eine Zertifikatswarnung ("Verbindung ist nicht privat") - für `localhost` unbedenklich, einfach fortfahren/bestätigen.
## Umgebungsvariablen
Kopiere `.env.example` zu `.env` (falls noch nicht geschehen) und trage deine Werte ein:
| Variable | Pflicht | Beschreibung |
|---|---|---|
| `ETSY_API_KEY` | ja | Keystring deiner Etsy-App |
| `ETSY_SHARED_SECRET` | ja | Shared Secret deiner Etsy-App. Seit der Etsy-Änderung vom 2026-02-09 für **jede** Anfrage im `x-api-key`-Header erforderlich (`keystring:secret`), nicht nur für den Token-Austausch |
| `ETSY_REDIRECT_URI` | ja | Muss exakt der in Etsy registrierten Callback-URL entsprechen |
| `ETSY_SHOP_ID` | nein | Wird sonst automatisch beim Login ermittelt |
| `ETSY_SHOP_NAME` | nein | Nur zur Anzeige |
| `ETSY_TOKEN_PATH` | nein | Ablageort der lokalen Tokens (Default: `./.secrets/etsy-tokens.json`) |
| `ETSY_AUDIT_LOG_PATH` | nein | Ablageort des Audit-Logs für spätere Schreibaktionen |
| `ETSY_TLS_CERT_PATH` / `ETSY_TLS_KEY_PATH` | nein | Ablageort des lokalen TLS-Zertifikats |
| `ETSY_WRITE_ENABLED` | nein | `false` (Default) = nur Lesezugriff. `true` schaltet die Stufe-2-Schreib-Tools frei - ersetzt NICHT die Einzelbestätigung vor jeder echten Änderung |
`.env` und alles unter `.secrets/` sind in `.gitignore` eingetragen und werden nie committet.
## Etsy-Scopes
Der Login fordert folgende Scopes an:
- `shops_r` - Shop-Stammdaten, Ankündigung, Sections
- `listings_r` - Listings (inkl. inaktiver/abgelaufener/Entwürfe), Bestand, Varianten, Bilder
- `transactions_r` - Bestellungen (Receipts) und Kaufpositionen (Transaktionen)
- `listings_w` - Listings erstellen/bearbeiten/aktivieren/deaktivieren, Bestand/Preis/Bilder ändern (Stufe 2)
`listings_w` wird bereits beim ersten Login mitangefordert, damit nach späterem Freischalten von `ETSY_WRITE_ENABLED` kein erneuter Login nötig ist - Etsy erlaubt keine nachträgliche Scope-Erweiterung ohne neue Autorisierung. Der Scope allein aktiviert aber **keine** Schreibfunktion; das übernimmt ausschließlich `ETSY_WRITE_ENABLED` zusammen mit der Einzelbestätigung je Tool. Es werden **keine** Lösch-Scopes (`listings_d`) und keine Shop-/Transaktions-Schreib-Scopes (`shops_w`, `transactions_w`) angefragt.
## OAuth-Anmeldung
1. In Claude das Tool `etsy_auth_login` aufrufen (oder direkt: `npm start` und in einem MCP-Client aufrufen).
2. Es öffnet sich automatisch der Browser mit der Etsy-Autorisierungsseite.
3. Bei Etsy anmelden und den Zugriff für den WandPad-Shop bestätigen.
4. Der Browser zeigt "Erfolgreich verbunden" - das Fenster kann geschlossen werden.
5. Access Token und Refresh Token werden lokal unter `.secrets/etsy-tokens.json` mit den Dateirechten `0600` gespeichert.
Technischer Ablauf (zur Nachvollziehbarkeit): PKCE-`code_verifier`/`code_challenge` (SHA-256, RFC 7636) werden lokal erzeugt, ein einmaliger `state`-Wert schützt vor CSRF, der lokale HTTPS-Server nimmt den Callback entgegen, prüft `state` und tauscht den Code serverseitig gegen Tokens - der `code_verifier` verlässt den Rechner nie unverschlüsselt sichtbar in der URL.
## Start des MCP-Servers
Für den eigenständigen Start (z.B. zum Testen):
```bash
npm start
```
Der Server kommuniziert über `stdio` und ist für den Betrieb durch einen MCP-Client (Claude Desktop, Claude Code) gedacht, nicht für interaktive Terminal-Nutzung.
## Verbindung zu Claude Desktop
Eintrag in `~/Library/Application Support/Claude/claude_desktop_config.json` (bereits eingetragen):
```json
{
"mcpServers": {
"wandpad-etsy": {
"command": "node",
"args": [
"/Users/Dodo/Library/Mobile Documents/com~apple~CloudDocs/Documents/Claude Code/dist/index.js"
]
}
}
}
```
**Danach Claude Desktop vollständig neu starten:** Cmd+Q (nicht nur das Fenster schließen), dann erneut öffnen.
**Verbindung prüfen:** In Claude Desktop unten im Chat-Eingabefeld auf das Werkzeug-/Stecker-Symbol klicken - `wandpad-etsy` sollte mit einem grünen Punkt als verbunden erscheinen, mit den Tools aus der Liste unten.
**Fehlerprotokolle:** `~/Library/Logs/Claude/mcp*.log` (bei Verbindungsproblemen dort nachsehen).
**Manueller Start zur Fehlersuche:**
```bash
node "/Users/Dodo/Library/Mobile Documents/com~apple~CloudDocs/Documents/Claude Code/dist/index.js"
```
Läuft der Server, bleibt der Prozess ohne Ausgabe auf stdout hängen (das ist korrekt - stdout ist für das MCP-Protokoll reserviert). Fehler erscheinen auf stderr im Terminal. Mit Ctrl+C beenden.
## Verbindung zu Claude Code
Im Projektordner liegt bereits eine `.mcp.json`:
```json
{
"mcpServers": {
"wandpad-etsy": {
"command": "node",
"args": [
"/Users/Dodo/Library/Mobile Documents/com~apple~CloudDocs/Documents/Claude Code/dist/index.js"
]
}
}
}
```
Öffnest du Claude Code in diesem Ordner, wird der Server automatisch erkannt (ggf. mit Bestätigung beim ersten Start, ob dem Projekt-MCP-Server vertraut wird).
## Erster Lesetest
Nach erfolgreichem Login in Claude z.B. fragen:
- "Zeig mir die Etsy-Shopdaten von WandPad." → `etsy_get_shop`
- "Liste meine aktiven Etsy-Listings auf." → `etsy_list_listings`
- "Wie ist der Bestand von Listing 4393511816?" → `etsy_get_listing_inventory`
- "Analysiere meinen Etsy-Shop." → `etsy_analyze_shop`
### Shopdaten abrufen
`etsy_get_shop` liefert Name, Titel, Währung, Anzahl aktiver Listings, Favoriten, Bewertungsdurchschnitt, Urlaubsmodus.
### Listings abrufen
`etsy_list_listings` (Filter: `state` = active/inactive/draft/expired/sold_out, `limit` max. 100, `offset`), `etsy_get_listing` für ein einzelnes Listing.
### Bestände und Varianten abrufen
`etsy_get_listing_inventory` liefert Varianten (Products/Offerings), SKUs, Preise je Variante, Bestand.
### Bestellungen analysieren
`etsy_get_receipts` (Bestellungen/"Receipts", Zeitraum max. 366 Tage, **ohne** Käufername/Adresse - siehe [Datenschutz](#datenschutz)) und `etsy_get_receipt_transactions` (verkaufte Positionen je Listing/SKU).
## Verfügbare Tools
| Tool | Zweck |
|---|---|
| `etsy_auth_status` | Zeigt Anmeldestatus, Scope, Ablaufzeitpunkt |
| `etsy_auth_login` | Startet OAuth-Login mit PKCE |
| `etsy_auth_logout` | Entfernt lokale Tokens |
| `etsy_get_shop` | Shop-Stammdaten |
| `etsy_get_shop_sections` | Shop-Kategorien |
| `etsy_list_listings` | Listings nach Status auflisten |
| `etsy_get_listing` | Einzelnes Listing |
| `etsy_get_listing_inventory` | Varianten, SKUs, Bestand |
| `etsy_get_listing_images` | Produktbilder inkl. Reihenfolge |
| `etsy_get_receipts` | Bestellungen (ohne PII) |
| `etsy_get_receipt_transactions` | Verkaufte Positionen |
| `etsy_analyze_shop` | Strukturierte Analyse: Fakten + berechnete Kennzahlen (siehe unten) |
| `etsy_create_draft_listing` | **Stufe 2.** Neues Listing als Entwurf erstellen |
| `etsy_update_listing` | **Stufe 2.** Titel/Beschreibung/Materialien/Section/Kategorie ändern |
| `etsy_update_tags` | **Stufe 2.** Tags setzen (auch für mehrere Listings) |
| `etsy_update_price` | **Stufe 2.** Preis ändern (einheitlich oder je Variante) |
| `etsy_update_inventory` | **Stufe 2.** Bestand ändern (einheitlich oder je Variante) |
| `etsy_update_variations` | **Stufe 2.** Varianten-/Angebotsstruktur ersetzen |
| `etsy_upload_listing_image` | **Stufe 2.** Lokales Bild hochladen |
| `etsy_reorder_listing_images` | **Stufe 2.** Bildreihenfolge ändern |
| `etsy_activate_listing` | **Stufe 2.** Listing(s) aktivieren |
| `etsy_deactivate_listing` | **Stufe 2.** Listing(s) deaktivieren |
Alle mit **Stufe 2** markierten Tools sind nur wirksam, wenn `ETSY_WRITE_ENABLED=true` lokal gesetzt ist (siehe [Späteren Schreibmodus aktivieren](#späteren-schreibmodus-aktivieren-stufe-2)), und verlangen unabhängig davon `dry_run`/`confirm`/`confirm_bulk`.
**Hinweis zu Etsy-Terminologie:** Etsy kennt keinen separaten "Order"-Begriff - eine Bestellung heißt in der API "Receipt". `etsy_get_receipts` deckt deshalb sowohl "Bestellungen abrufen" als auch "Receipts abrufen" ab, statt zwei identische Tools zu duplizieren.
`etsy_analyze_shop` trennt strikt:
1. **Fakten** - unverändert von Etsy (Shop, Listings, Sections)
2. **Kennzahlen** - deterministisch berechnet (Preisspanne, Durchschnittspreis, Tag-Anzahl, fehlende Shop-Section, kurze Titel, wenige Tags, mögliche Titel-Duplikate, optional fehlende SKUs/niedriger Bestand)
Das Tool liefert **bewusst keine fertigen Empfehlungen** - Interpretation und Handlungsvorschläge (Topseller, SEO-Optimierungen etc.) soll Claude selbst auf Basis dieser Rohdaten formulieren, damit klar bleibt, was Fakt und was Einschätzung ist.
## Tokens erneuern
Access Tokens laufen nach 1 Stunde ab. Der Server erneuert sie **automatisch** kurz vor Ablauf (über den Refresh Token, gültig 90 Tage) - dafür ist kein manuelles Eingreifen nötig. Nur wenn der Refresh Token selbst abgelaufen/ungültig ist, ist ein erneuter `etsy_auth_login` nötig.
## Tokens zurücksetzen (Logout)
```
etsy_auth_logout
```
entfernt `.secrets/etsy-tokens.json`. Ein erneutes `etsy_auth_login` ist danach jederzeit möglich.
## Fehlerbehebung
**HTTP 403 "Invalid API credentials"** (auch beim unauthentifizierten Ping): Keystring oder Shared Secret falsch/unvollständig kopiert, oder der API-Key-Status ist noch "Pending" statt "Active" im Etsy-Dashboard. Shared Secret im Dashboard über das Augen-Symbol vollständig aufdecken und neu kopieren.
**"Zeitüberschreitung: Es wurde keine Etsy-Autorisierung innerhalb von 5 Minuten empfangen"**: Login-Vorgang im Browser wurde nicht abgeschlossen. `etsy_auth_login` erneut aufrufen.
**"state-Wert stimmte nicht überein"**: Mögliche CSRF-Manipulation oder ein alter, bereits verbrauchter Autorisierungslink wurde erneut geöffnet. Login neu starten.
**Zertifikatswarnung im Browser beim Login**: Erwartet, da selbstsigniert (siehe [Callback-URL](#callback-url)). Für `localhost` unbedenklich bestätigen.
**Claude Desktop zeigt den Server nicht als verbunden**: Prüfe `~/Library/Logs/Claude/mcp*.log`, stelle sicher, dass `npm run build` gelaufen ist (Datei `dist/index.js` muss existieren) und starte Claude Desktop komplett neu (Cmd+Q, nicht nur Fenster schließen).
**Rate-Limit-Fehler (HTTP 429)**: Der Client wiederholt automatisch mit exponentiellem Backoff (bis zu 3 Versuche). Bei dauerhaften 429ern: Etsy-Rate-Limit für diese App im Dashboard prüfen.
## Datenschutz
- `etsy_get_receipts` gibt **keinen** Käufernamen, keine Adresse, keine PLZ/Stadt und keine Kontaktdaten zurück - nur Status, grobes Land, Summen und Zeitstempel.
- Das Audit-Log (nur für Stufe 2 relevant) verweigert das Schreiben, sobald es Tokens, Secrets oder personenbezogene Felder (Name, Adresse, E-Mail, PLZ, Stadt) enthält - technisch erzwungen, nicht nur per Konvention.
- Es werden keine Käuferdaten in Tests, Logs oder Terminal-Ausgaben verwendet.
- Tokens, Secrets und API-Keys werden nie protokolliert (der Logger redigiert entsprechende Felder zusätzlich automatisch als zweite Sicherheitsebene).
## Sicherheitsregeln
- Schreib-Tools sind nur wirksam, wenn `ETSY_WRITE_ENABLED=true` lokal gesetzt ist (Default: `false`). Jedes Schreib-Tool prüft das zusätzlich selbst zur Laufzeit (`assertWriteEnabled`) - ein vergessener Check in einem einzelnen Tool kann das Flag nicht umgehen.
- Jedes Schreib-Tool hat `dry_run:true` als Default und zeigt nur eine Vorschau, bis `dry_run:false` UND `confirm:true` explizit gesetzt sind.
- Betrifft eine Aktion mehr als ein Listing gleichzeitig, ist zusätzlich `confirm_bulk:true` erforderlich.
- Es gibt **keine** Lösch-Funktion für Listings und wird es nie geben.
- Alle echten Schreibaktionen werden im lokalen Audit-Log protokolliert; das Log verweigert technisch das Schreiben, sobald Tokens, Secrets oder personenbezogene Felder darin vorkommen.
- Bild-Uploads akzeptieren ausschließlich lokale Dateipfade, keine URLs - es wird nichts von externen Quellen heruntergeladen.
- `.env`, `.secrets/` (Tokens, TLS-Zertifikat, Audit-Log) sind über `.gitignore` von Git ausgeschlossen.
- Token-Datei und Audit-Log werden mit den Dateirechten `0600` (nur Eigentümer) angelegt.
- stdout ist ausschließlich für das MCP-Protokoll reserviert - alle Log-Ausgaben (inkl. der von `dotenv`) gehen nach stderr, um das Protokoll nicht zu korrumpieren.
- Alle Tool-Eingaben werden mit Zod validiert: IDs müssen numerisch sein, Seitengrößen sind auf max. 100 begrenzt, Bestellzeiträume auf max. 366 Tage.
## Bekannte Einschränkungen der Etsy API
- Seit 2026-02-09 verlangt Etsy für **jede** Anfrage das Shared Secret im `x-api-key`-Header (`keystring:secret`), nicht mehr nur den Keystring allein.
**Korrektur (2026-08-06):** Frühere Recherche (u.a. [github.com/etsy/open-api/discussions/1386](https://github.com/etsy/open-api/discussions/1386)) hatte nahegelegt, dass Etsy keine Aufruf-/Besucherstatistik (`views`) liefert. Ein Livetest gegen die echte API zeigte, dass das Feld `views` tatsächlich sowohl bei `etsy_get_listing` als auch bei `etsy_list_listings` vorhanden ist und korrekte Werte liefert. `etsy_analyze_shop` berücksichtigt `views` deshalb jetzt (Durchschnitt, Listings mit unterdurchschnittlich wenigen Aufrufen).
## Schreibmodus aktivieren (Stufe 2)
1. **Erneut anmelden**, falls der letzte Login vor der Stufe-2-Einführung war (Token muss den Scope `listings_w` enthalten): `etsy_auth_logout` gefolgt von `etsy_auth_login`. `etsy_auth_status` zeigt den aktuellen Scope.
2. In der lokalen `.env` setzen: `ETSY_WRITE_ENABLED=true`.
3. Claude Desktop neu starten (Cmd+Q, dann erneut öffnen), damit der Server die neue Umgebungsvariable liest.
4. Jedes Schreib-Tool danach zuerst **ohne** `confirm` aufrufen lassen (Default `dry_run:true`) - das zeigt nur die geplante Änderung. Erst nach ausdrücklicher Zustimmung im Chat mit `dry_run:false` und `confirm:true` (bei mehreren Listings zusätzlich `confirm_bulk:true`) erneut aufrufen.
**Verfügbare Schreib-Tools:** `etsy_create_draft_listing` (immer als Entwurf), `etsy_update_listing`, `etsy_update_tags`, `etsy_update_price`, `etsy_update_inventory`, `etsy_update_variations`, `etsy_upload_listing_image`, `etsy_reorder_listing_images`, `etsy_activate_listing`, `etsy_deactivate_listing`.
**Design-Hinweis:** Preis- und Bestandsänderungen (`etsy_update_price`, `etsy_update_inventory`) sowie Varianten-Änderungen wirken auf jeweils **ein** Listing pro Aufruf, da Etsys `updateListingInventory`-Endpunkt die komplette Varianten-Struktur eines Listings ersetzt (kein Teil-Update) und sich Varianten zwischen Listings unterscheiden. `etsy_update_tags`, `etsy_activate_listing` und `etsy_deactivate_listing` unterstützen dagegen mehrere Listings gleichzeitig (`listing_ids`), da hier dieselbe Änderung sinnvoll auf viele Listings angewendet werden kann - dafür greift die Sammelbestätigung (`confirm_bulk`).
**Um Stufe 2 wieder zu deaktivieren:** `ETSY_WRITE_ENABLED=false` in der `.env` setzen und Claude Desktop neu starten.
## Gehostetes Deployment für Cowork-Agenten
Claude Desktop/Code verbindet sich lokal über `stdio` (ein Kindprozess pro Verbindung). Cowork-Agenten laufen dagegen nicht auf diesem Mac, sondern brauchen einen über **HTTPS erreichbaren** MCP-Server. Derselbe Code unterstützt deshalb zusätzlich einen **HTTP-Modus** (Streamable HTTP, Pfad `/mcp`) - welcher Modus läuft, wird automatisch anhand der Umgebungsvariable `PORT` entschieden (von Hosting-Plattformen wie Render automatisch gesetzt; lokal nicht vorhanden → stdio).
### Deployment auf Render
1. Auf [render.com](https://render.com) einloggen (gleiches Konto wie beim WooCommerce-Connector) → **New** → **Web Service**
2. Das GitHub-Repo `DodoNic/wandpad-etsy-mcp` verbinden
3. Einstellungen:
- **Build Command:** `npm install && npm run build`
- **Start Command:** `npm start`
- **Region/Plan:** frei wählbar (Free-Plan reicht zum Testen, siehe Hinweis zu persistentem Speicher unten)
4. Unter **Environment** folgende Variablen eintragen (gleiche Werte wie lokal in `.env`, außer wo anders angegeben):
| Variable | Wert |
|---|---|
| `ETSY_API_KEY` | dein Keystring |
| `ETSY_SHARED_SECRET` | dein Shared Secret |
| `ETSY_REDIRECT_URI` | `https://<dein-service-name>.onrender.com/oauth/callback` (Render zeigt dir die Domain nach dem ersten Deploy) |
| `ETSY_SHOP_ID` | wie lokal (optional) |
| `ETSY_SHOP_NAME` | `WandPad` |
| `ETSY_WRITE_ENABLED` | `false` zum Start - erst nach erfolgreichem Test auf `true` |
| `ETSY_MCP_AUTH_TOKEN` | ein langes Zufalls-Token (z.B. mit `openssl rand -hex 32` erzeugen) - schützt den öffentlichen Endpunkt |
`PORT` musst du **nicht** setzen - Render setzt das automatisch.
5. Deployen. Render zeigt danach die öffentliche URL, z.B. `https://wandpad-etsy-mcp.onrender.com`.
### Etsy-App um die neue Callback-URL ergänzen
In deiner Etsy-App unter [etsy.com/developers/your-apps](https://www.etsy.com/developers/your-apps) die Render-Callback-URL **zusätzlich** zur lokalen eintragen (beide können gleichzeitig registriert sein):
```
https://<dein-service-name>.onrender.com/oauth/callback
```
### Anmeldung beim gehosteten Server
Der gehostete Server hat sein **eigenes**, vom lokalen Login unabhängiges Token - einmalig einloggen:
1. `etsy_auth_login` auf dem gehosteten Server aufrufen (z.B. über den Cowork-Connector, sobald verbunden - siehe unten) - liefert sofort eine Autorisierungs-URL zurück (blockiert nicht, da der Server keinen eigenen Browser öffnen kann)
2. Die URL selbst im Browser öffnen und autorisieren
3. Mit `etsy_auth_status` bestätigen, dass die Anmeldung angekommen ist
### Als Cowork-Connector verbinden
In den App-Einstellungen unter **Connectors** → **Hinzufügen** → **Benutzerdefinierten Connector hinzufügen**:
- **Name:** `wandpad-etsy`
- **Remote MCP Server URL:** `https://<dein-service-name>.onrender.com/mcp?token=<dein ETSY_MCP_AUTH_TOKEN>`
Das Token wird hier als Query-Parameter an die URL gehängt, da der Connector-Dialog nur ein URL-Feld ohne separate Header-Konfiguration bietet (die "OAuth Client ID/Secret"-Felder sind für einen vollständigen OAuth-Handshake gedacht, den dieser Server nicht implementiert). Danach kann der Connector einem oder mehreren Agenten im WandPad-Projekt zugewiesen werden, inklusive granularer Tool-Berechtigungen ("Immer erlauben" / Rückfrage / Verboten) pro Tool.
### Wichtige Einschränkungen im Hosted-Modus
- **Persistenter Speicher:** Tokens (`.secrets/etsy-tokens.json`) und Audit-Log liegen auf Renders Dateisystem. Auf dem **Free-Plan ist das Dateisystem flüchtig** - bei jedem Neustart/Redeploy sind die Tokens weg und `etsy_auth_login` muss erneut ausgeführt werden. Für dauerhafte Anmeldung: Render **Persistent Disk** (kostenpflichtiger Plan) hinzufügen, an einen Pfad mounten (z.B. `/data`) und `ETSY_TOKEN_PATH=/data/etsy-tokens.json` sowie `ETSY_AUDIT_LOG_PATH=/data/audit.log` als zusätzliche Umgebungsvariablen setzen.
- **Kein technischer Beweis für menschliche Bestätigung:** `confirm:true` ist weiterhin Pflicht für echte Schreibaktionen, aber der Server kann nicht prüfen, ob wirklich ein Mensch zugestimmt hat - das hängt von der Steuerung des jeweiligen Agenten ab. Nutze die Tool-Berechtigungen im Cowork-Connector (z.B. Schreib-Tools auf "Rückfrage" statt "Immer erlauben"), um hier eine echte Bestätigungsebene zu erzwingen.
- **Ein Token-Speicher pro Deployment:** Der lokale Login (Claude Desktop) und der gehostete Login (Render) sind unabhängig - beide autorisieren denselben Etsy-Account, aber mit getrennten Tokens.
## Vollständige Deinstallation
1. In Claude Desktop/Code den `wandpad-etsy`-Eintrag aus der MCP-Konfiguration entfernen (`claude_desktop_config.json` bzw. `.mcp.json`).
2. Etsy-Autorisierung bei Etsy selbst widerrufen (optional): [etsy.com/your/account/privacy](https://www.etsy.com/your/account/privacy) → "Apps mit Zugriff auf dein Konto".
3. Projektordner löschen (enthält `.secrets/` mit lokalen Tokens und Zertifikat sowie `.env` mit den Zugangsdaten).
4. Claude Desktop komplett neu starten.
TDQS
Scored across 22 tools
Every tool targets a distinct resource or action: auth tools separate from data reads, listing metadata updates separated from price/inventory/tags/variations. Potential overlap between update_inventory and update_variations is clearly delineated by scope (quantity-only vs. full structure replacement).
Predominantly follows etsy_<verb>_<object> (get_listing, update_price, upload_listing_image). Minor deviations exist: auth tools use etsy_auth_status/login/logout instead of a verb-first pattern, and list_listings uses 'list' rather than 'get', but the pattern is still predictable.
At 22 tools, the server is slightly heavy but well-scoped for full Etsy shop management (auth, reads, writes, analysis). Each tool earns its place; the count feels justified rather than bloated.
Covers the core lifecycle: create draft, activate/deactivate, update metadata/tags/price/inventory/variations, manage images, and read shop/listing/order data. Missing delete listing and possibly shipping/taxonomy reads are minor gaps given Etsy's typical workflows.