@iflow-mcp/dynamicendpoints-etsy-mcp 1.2.0

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.
@@ -0,0 +1,206 @@
1
+ # Smithery Deployment Checklist
2
+
3
+ Use this checklist to verify your Etsy MCP server is ready for Smithery deployment.
4
+
5
+ ## ✅ Required Files
6
+
7
+ - [x] `smithery.yaml` - Runtime configuration
8
+ - [x] `package.json` - With `module` field pointing to `src/index.ts`
9
+ - [x] `src/index.ts` - Exports default `createServer` function
10
+ - [x] `tsconfig.json` - TypeScript configuration
11
+ - [x] `.gitignore` - Excludes node_modules and build artifacts
12
+
13
+ ## ✅ Code Structure
14
+
15
+ - [x] Default export: `createServer` function
16
+ - [x] Configuration schema: `configSchema` exported with Zod
17
+ - [x] Returns MCP Server object from `createServer`
18
+ - [x] Stdio support: CLI entry point for local execution
19
+ - [x] Config support: Accepts config from Smithery or environment
20
+
21
+ ## ✅ Dependencies
22
+
23
+ - [x] `@modelcontextprotocol/sdk` in dependencies
24
+ - [x] `axios` for HTTP requests
25
+ - [x] `zod` for schema validation
26
+ - [x] `@smithery/cli` in devDependencies
27
+ - [x] TypeScript types installed
28
+
29
+ ## ✅ Scripts
30
+
31
+ - [x] `npm run build` - Uses Smithery CLI
32
+ - [x] `npm run dev` - Opens interactive playground
33
+ - [x] `npm run compile` - TypeScript compilation (for testing)
34
+ - [x] `npm start` - Runs compiled server
35
+
36
+ ## ✅ Testing
37
+
38
+ ### Local Testing
39
+ ```bash
40
+ # Install dependencies
41
+ npm install
42
+
43
+ # Test compilation
44
+ npm run compile
45
+
46
+ # Test with Smithery playground
47
+ npm run dev
48
+
49
+ # Test direct execution
50
+ ETSY_API_KEY=your_key npm start
51
+ ```
52
+
53
+ ### Verify These Work:
54
+ - [ ] Server starts without errors
55
+ - [ ] All 19 tools are listed
56
+ - [ ] Configuration schema shows 3 fields
57
+ - [ ] Tools execute and return responses
58
+
59
+ ## ✅ Configuration Schema
60
+
61
+ The exported `configSchema` includes:
62
+ - [x] `apiKey` (string, required) - With description
63
+ - [x] `shopId` (string, optional) - With description
64
+ - [x] `accessToken` (string, optional) - With description
65
+
66
+ ## ✅ Tools Exported
67
+
68
+ ### Read-Only (10 tools)
69
+ - [x] search_listings
70
+ - [x] get_listing
71
+ - [x] get_shop
72
+ - [x] get_shop_listings
73
+ - [x] search_shops
74
+ - [x] get_listing_inventory
75
+ - [x] get_listing_images
76
+ - [x] get_shop_sections
77
+ - [x] get_trending_listings
78
+ - [x] find_shops
79
+
80
+ ### Shop Management (9 tools)
81
+ - [x] create_listing
82
+ - [x] update_listing
83
+ - [x] delete_listing
84
+ - [x] update_listing_inventory
85
+ - [x] upload_listing_image
86
+ - [x] create_shop_section
87
+ - [x] update_shop_section
88
+ - [x] delete_shop_section
89
+ - [x] update_shop
90
+
91
+ ## ✅ Documentation
92
+
93
+ - [x] README.md - Main documentation
94
+ - [x] SMITHERY_DEPLOYMENT.md - Deployment guide
95
+ - [x] OAUTH_SETUP.md - OAuth setup instructions
96
+ - [x] QUICK_REFERENCE.md - Quick reference guide
97
+ - [x] .env.example - Environment template
98
+
99
+ ## ✅ GitHub Repository
100
+
101
+ Before deploying:
102
+ - [ ] Push all files to GitHub
103
+ - [ ] Repository is public (or accessible to Smithery)
104
+ - [ ] All commits are up to date
105
+ - [ ] .gitignore excludes sensitive files
106
+
107
+ ## 🚀 Deployment Steps
108
+
109
+ 1. **Push to GitHub**
110
+ ```bash
111
+ git add .
112
+ git commit -m "Ready for Smithery deployment"
113
+ git push origin main
114
+ ```
115
+
116
+ 2. **Connect to Smithery**
117
+ - Go to https://smithery.ai/new
118
+ - Connect your GitHub account
119
+ - Select the `etsy_mcp` repository
120
+
121
+ 3. **Configure Server**
122
+ - Name: Etsy MCP Server
123
+ - Description: MCP server for Etsy API integration
124
+ - Category: E-commerce / API Integration
125
+
126
+ 4. **Deploy**
127
+ - Click "Deploy" button
128
+ - Wait for build to complete
129
+ - Test deployed server
130
+
131
+ ## ✅ Post-Deployment Verification
132
+
133
+ After deployment, verify:
134
+ - [ ] Server shows as "Running" in Smithery dashboard
135
+ - [ ] All 19 tools are discoverable
136
+ - [ ] Configuration form displays correctly
137
+ - [ ] Test tools work with valid API key
138
+ - [ ] Error messages are clear and helpful
139
+
140
+ ## 🧪 Testing Deployed Server
141
+
142
+ ### With Claude Desktop
143
+ Add to `claude_desktop_config.json`:
144
+ ```json
145
+ {
146
+ "mcpServers": {
147
+ "etsy": {
148
+ "url": "https://server.smithery.ai/YOUR-USERNAME/etsy-mcp-server/mcp",
149
+ "config": {
150
+ "apiKey": "your_etsy_api_key"
151
+ }
152
+ }
153
+ }
154
+ }
155
+ ```
156
+
157
+ ### With MCP Inspector
158
+ ```bash
159
+ npx @modelcontextprotocol/inspector https://server.smithery.ai/YOUR-USERNAME/etsy-mcp-server/mcp
160
+ ```
161
+
162
+ ### Test These Operations:
163
+ - [ ] Search for listings works
164
+ - [ ] Get listing details works
165
+ - [ ] Get shop information works
166
+ - [ ] Error handling for invalid API key
167
+ - [ ] Error handling for missing resources
168
+
169
+ ## 📊 Monitoring
170
+
171
+ After deployment, check:
172
+ - [ ] View usage metrics in Smithery dashboard
173
+ - [ ] Monitor error logs for issues
174
+ - [ ] Check performance data
175
+ - [ ] Review user feedback
176
+
177
+ ## 🔧 Troubleshooting
178
+
179
+ If deployment fails:
180
+
181
+ 1. **Check build logs** in Smithery dashboard
182
+ 2. **Verify locally** with `npm run build`
183
+ 3. **Test compilation** with `npm run compile`
184
+ 4. **Review errors** and fix TypeScript issues
185
+ 5. **Check dependencies** in package.json
186
+ 6. **Validate structure** matches Smithery requirements
187
+
188
+ ## ✅ Success Criteria
189
+
190
+ Your deployment is successful when:
191
+ - ✅ Build completes without errors
192
+ - ✅ Server shows as "Running"
193
+ - ✅ All tools are listed
194
+ - ✅ Configuration form works
195
+ - ✅ Test queries return results
196
+ - ✅ Error messages are clear
197
+
198
+ ## 🎉 You're Ready!
199
+
200
+ Once all items are checked, your Etsy MCP server is:
201
+ - ✅ **Smithery-compatible**
202
+ - ✅ **Production-ready**
203
+ - ✅ **Fully documented**
204
+ - ✅ **Ready to deploy**
205
+
206
+ Click that Deploy button! 🚀
package/OAUTH_SETUP.md ADDED
@@ -0,0 +1,275 @@
1
+ # Etsy OAuth Setup Guide
2
+
3
+ This guide will help you set up OAuth 2.0 authentication to enable shop management features in the Etsy MCP server.
4
+
5
+ ## Why OAuth?
6
+
7
+ While the Etsy API key allows you to **read** public data (search listings, view shops), you need an **OAuth access token** to:
8
+ - Create new listings
9
+ - Update or delete your listings
10
+ - Manage shop sections
11
+ - Update shop information
12
+ - Manage inventory
13
+
14
+ ## Prerequisites
15
+
16
+ 1. An Etsy account with a shop
17
+ 2. An Etsy developer account ([sign up here](https://www.etsy.com/developers/register))
18
+ 3. A registered app in the Etsy Developer Portal
19
+
20
+ ## Step-by-Step OAuth Setup
21
+
22
+ ### Step 1: Create an Etsy App
23
+
24
+ 1. Go to [Etsy Developer Portal](https://www.etsy.com/developers/your-apps)
25
+ 2. Click **"Create a New App"**
26
+ 3. Fill in the required information:
27
+ - **App Name**: Your MCP Server name
28
+ - **Is this app for production?**: Choose based on your needs
29
+ - **Tell us about your app**: Brief description
30
+ 4. Click **"Read Terms and Create App"**
31
+
32
+ ### Step 2: Configure OAuth Settings
33
+
34
+ 1. In your app dashboard, go to **"API Keys & Access Tokens"**
35
+ 2. Note your **Keystring** (this is your `ETSY_API_KEY`)
36
+ 3. Under **OAuth Settings**, add a redirect URI:
37
+ - For local testing: `http://localhost:3000/callback`
38
+ - For production: Your production callback URL
39
+ 4. Save the settings
40
+
41
+ ### Step 3: Request Authorization
42
+
43
+ Build an authorization URL with the following format:
44
+
45
+ ```
46
+ https://www.etsy.com/oauth/connect?response_type=code&redirect_uri=YOUR_REDIRECT_URI&scope=listings_w%20shops_w%20shops_r%20listings_r&client_id=YOUR_KEYSTRING&state=YOUR_RANDOM_STATE&code_challenge=YOUR_CODE_CHALLENGE&code_challenge_method=S256
47
+ ```
48
+
49
+ **Required Parameters:**
50
+ - `response_type`: Always `code`
51
+ - `redirect_uri`: Must match your registered URI (URL encoded)
52
+ - `scope`: Space-separated permissions (URL encoded):
53
+ - `listings_r` - Read listings
54
+ - `listings_w` - Write/manage listings
55
+ - `shops_r` - Read shop info
56
+ - `shops_w` - Update shop info
57
+ - `transactions_r` - Read orders
58
+ - `transactions_w` - Update orders
59
+ - `client_id`: Your app's Keystring
60
+ - `state`: Random string for security
61
+ - `code_challenge`: PKCE challenge (base64url encoded SHA256 hash)
62
+ - `code_challenge_method`: Always `S256`
63
+
64
+ ### Step 4: Generate PKCE Code Verifier and Challenge
65
+
66
+ PKCE (Proof Key for Code Exchange) is required for security. Here's a Node.js example:
67
+
68
+ ```javascript
69
+ const crypto = require('crypto');
70
+
71
+ // Generate code verifier
72
+ const codeVerifier = crypto.randomBytes(32).toString('base64url');
73
+
74
+ // Generate code challenge
75
+ const codeChallenge = crypto
76
+ .createHash('sha256')
77
+ .update(codeVerifier)
78
+ .digest('base64url');
79
+
80
+ console.log('Code Verifier:', codeVerifier);
81
+ console.log('Code Challenge:', codeChallenge);
82
+ ```
83
+
84
+ **Save the code verifier** - you'll need it in the next step!
85
+
86
+ ### Step 5: User Authorization
87
+
88
+ 1. Open the authorization URL in a browser
89
+ 2. Log in to Etsy (if not already logged in)
90
+ 3. Review the permissions your app is requesting
91
+ 4. Click **"Allow Access"**
92
+ 5. You'll be redirected to your callback URL with a `code` parameter:
93
+ ```
94
+ http://localhost:3000/callback?code=AUTHORIZATION_CODE&state=YOUR_STATE
95
+ ```
96
+
97
+ ### Step 6: Exchange Code for Access Token
98
+
99
+ Make a POST request to exchange the authorization code for an access token:
100
+
101
+ ```bash
102
+ curl -X POST "https://api.etsy.com/v3/public/oauth/token" \
103
+ -H "Content-Type: application/x-www-form-urlencoded" \
104
+ -d "grant_type=authorization_code" \
105
+ -d "client_id=YOUR_KEYSTRING" \
106
+ -d "redirect_uri=YOUR_REDIRECT_URI" \
107
+ -d "code=AUTHORIZATION_CODE" \
108
+ -d "code_verifier=YOUR_CODE_VERIFIER"
109
+ ```
110
+
111
+ **Node.js Example:**
112
+
113
+ ```javascript
114
+ const axios = require('axios');
115
+
116
+ const data = new URLSearchParams({
117
+ grant_type: 'authorization_code',
118
+ client_id: 'YOUR_KEYSTRING',
119
+ redirect_uri: 'http://localhost:3000/callback',
120
+ code: 'AUTHORIZATION_CODE_FROM_CALLBACK',
121
+ code_verifier: 'YOUR_CODE_VERIFIER_FROM_STEP_4'
122
+ });
123
+
124
+ axios.post('https://api.etsy.com/v3/public/oauth/token', data, {
125
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
126
+ })
127
+ .then(response => {
128
+ console.log('Access Token:', response.data.access_token);
129
+ console.log('Refresh Token:', response.data.refresh_token);
130
+ console.log('Expires In:', response.data.expires_in, 'seconds');
131
+ })
132
+ .catch(error => {
133
+ console.error('Error:', error.response?.data || error.message);
134
+ });
135
+ ```
136
+
137
+ **Response:**
138
+ ```json
139
+ {
140
+ "access_token": "YOUR_ACCESS_TOKEN",
141
+ "token_type": "Bearer",
142
+ "expires_in": 3600,
143
+ "refresh_token": "YOUR_REFRESH_TOKEN"
144
+ }
145
+ ```
146
+
147
+ ### Step 7: Add Token to Environment
148
+
149
+ Add the access token to your `.env` file:
150
+
151
+ ```bash
152
+ ETSY_API_KEY=your_keystring_here
153
+ ETSY_SHOP_ID=your_shop_id
154
+ ETSY_ACCESS_TOKEN=your_access_token_here
155
+ ```
156
+
157
+ Or add it to your Claude Desktop config:
158
+
159
+ ```json
160
+ {
161
+ "mcpServers": {
162
+ "etsy": {
163
+ "command": "node",
164
+ "args": ["C:\\path\\to\\etsy_mcp\\build\\index.js"],
165
+ "env": {
166
+ "ETSY_API_KEY": "your_keystring",
167
+ "ETSY_ACCESS_TOKEN": "your_access_token"
168
+ }
169
+ }
170
+ }
171
+ }
172
+ ```
173
+
174
+ ## Token Refresh
175
+
176
+ Access tokens expire after 1 hour. Use the refresh token to get a new access token:
177
+
178
+ ```bash
179
+ curl -X POST "https://api.etsy.com/v3/public/oauth/token" \
180
+ -H "Content-Type: application/x-www-form-urlencoded" \
181
+ -d "grant_type=refresh_token" \
182
+ -d "client_id=YOUR_KEYSTRING" \
183
+ -d "refresh_token=YOUR_REFRESH_TOKEN"
184
+ ```
185
+
186
+ ## Quick Test Script
187
+
188
+ Save this as `oauth-helper.js`:
189
+
190
+ ```javascript
191
+ const crypto = require('crypto');
192
+ const readline = require('readline');
193
+
194
+ const rl = readline.createInterface({
195
+ input: process.stdin,
196
+ output: process.stdout
197
+ });
198
+
199
+ const CLIENT_ID = 'YOUR_KEYSTRING_HERE';
200
+ const REDIRECT_URI = 'http://localhost:3000/callback';
201
+ const STATE = crypto.randomBytes(16).toString('hex');
202
+ const CODE_VERIFIER = crypto.randomBytes(32).toString('base64url');
203
+ const CODE_CHALLENGE = crypto.createHash('sha256').update(CODE_VERIFIER).digest('base64url');
204
+
205
+ const scopes = 'listings_r listings_w shops_r shops_w';
206
+ const authUrl = `https://www.etsy.com/oauth/connect?response_type=code&redirect_uri=${encodeURIComponent(REDIRECT_URI)}&scope=${encodeURIComponent(scopes)}&client_id=${CLIENT_ID}&state=${STATE}&code_challenge=${CODE_CHALLENGE}&code_challenge_method=S256`;
207
+
208
+ console.log('\n=== Etsy OAuth Helper ===\n');
209
+ console.log('1. Open this URL in your browser:\n');
210
+ console.log(authUrl);
211
+ console.log('\n2. After authorization, copy the "code" parameter from the redirect URL\n');
212
+
213
+ rl.question('Enter the authorization code: ', async (code) => {
214
+ const axios = require('axios');
215
+
216
+ try {
217
+ const data = new URLSearchParams({
218
+ grant_type: 'authorization_code',
219
+ client_id: CLIENT_ID,
220
+ redirect_uri: REDIRECT_URI,
221
+ code: code.trim(),
222
+ code_verifier: CODE_VERIFIER
223
+ });
224
+
225
+ const response = await axios.post('https://api.etsy.com/v3/public/oauth/token', data, {
226
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
227
+ });
228
+
229
+ console.log('\n✅ Success! Add these to your .env file:\n');
230
+ console.log(`ETSY_ACCESS_TOKEN=${response.data.access_token}`);
231
+ console.log(`ETSY_REFRESH_TOKEN=${response.data.refresh_token}`);
232
+ console.log(`\nToken expires in: ${response.data.expires_in} seconds`);
233
+ } catch (error) {
234
+ console.error('\n❌ Error:', error.response?.data || error.message);
235
+ }
236
+
237
+ rl.close();
238
+ });
239
+ ```
240
+
241
+ Run it with:
242
+ ```bash
243
+ npm install axios
244
+ node oauth-helper.js
245
+ ```
246
+
247
+ ## Troubleshooting
248
+
249
+ ### "Invalid redirect_uri"
250
+ Make sure the redirect URI in your request exactly matches the one registered in your app settings.
251
+
252
+ ### "Invalid code_verifier"
253
+ Ensure you're using the same code_verifier that was used to generate the code_challenge.
254
+
255
+ ### "Token expired"
256
+ Access tokens expire after 1 hour. Use the refresh token to get a new one.
257
+
258
+ ### "Insufficient scope"
259
+ Request the appropriate scopes during authorization:
260
+ - `listings_w` for creating/updating listings
261
+ - `shops_w` for updating shop info
262
+
263
+ ## Security Best Practices
264
+
265
+ 1. **Never commit tokens** to version control - use `.env` files
266
+ 2. **Store refresh tokens securely** - they don't expire
267
+ 3. **Use PKCE** - always include code_challenge
268
+ 4. **Validate state parameter** - prevents CSRF attacks
269
+ 5. **Use HTTPS in production** - HTTP is only for local testing
270
+
271
+ ## Resources
272
+
273
+ - [Etsy OAuth Documentation](https://developers.etsy.com/documentation/essentials/authentication/)
274
+ - [Etsy API Reference](https://developers.etsy.com/documentation/reference)
275
+ - [OAuth 2.0 PKCE Specification](https://tools.ietf.org/html/rfc7636)