secondhand-mcp 0.1.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.
- package/LICENSE +21 -0
- package/README.md +201 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +349 -0
- package/dist/index.js.map +1 -0
- package/dist/marketplaces/base.d.ts +31 -0
- package/dist/marketplaces/base.d.ts.map +1 -0
- package/dist/marketplaces/base.js +30 -0
- package/dist/marketplaces/base.js.map +1 -0
- package/dist/marketplaces/ebay.d.ts +24 -0
- package/dist/marketplaces/ebay.d.ts.map +1 -0
- package/dist/marketplaces/ebay.js +197 -0
- package/dist/marketplaces/ebay.js.map +1 -0
- package/dist/marketplaces/facebook.d.ts +25 -0
- package/dist/marketplaces/facebook.d.ts.map +1 -0
- package/dist/marketplaces/facebook.js +252 -0
- package/dist/marketplaces/facebook.js.map +1 -0
- package/dist/marketplaces/index.d.ts +13 -0
- package/dist/marketplaces/index.d.ts.map +1 -0
- package/dist/marketplaces/index.js +57 -0
- package/dist/marketplaces/index.js.map +1 -0
- package/dist/types.d.ts +60 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +48 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# Secondhand MCP
|
|
2
|
+
|
|
3
|
+
An MCP server for searching secondary marketplaces. Lets Claude and other AI assistants search for deals on Facebook Marketplace and eBay.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Search multiple marketplaces from a single interface
|
|
8
|
+
- Price filtering with min/max ranges
|
|
9
|
+
- Location-based search by city
|
|
10
|
+
- Detailed listing inspection (photos, descriptions, seller info)
|
|
11
|
+
- Availability filtering — sold/pending items excluded by default
|
|
12
|
+
- Works with Claude Desktop, Claude Code, Cursor, and other MCP clients
|
|
13
|
+
- Lightweight — no browser dependencies, native HTTP requests
|
|
14
|
+
|
|
15
|
+
## Supported Marketplaces
|
|
16
|
+
|
|
17
|
+
| Marketplace | Status | Auth Required |
|
|
18
|
+
|-------------|--------|---------------|
|
|
19
|
+
| Facebook Marketplace | Working | No |
|
|
20
|
+
| eBay | Working | Yes (API keys) |
|
|
21
|
+
|
|
22
|
+
## Setup
|
|
23
|
+
|
|
24
|
+
### From Source
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
git clone https://github.com/jlsookiki/secondhand-mcp.git
|
|
28
|
+
cd secondhand-mcp
|
|
29
|
+
npm install
|
|
30
|
+
npm run build
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Claude Desktop
|
|
34
|
+
|
|
35
|
+
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"mcpServers": {
|
|
40
|
+
"secondhand": {
|
|
41
|
+
"command": "npx",
|
|
42
|
+
"args": ["-y", "secondhand-mcp"],
|
|
43
|
+
"env": {
|
|
44
|
+
"EBAY_CLIENT_ID": "your-ebay-client-id",
|
|
45
|
+
"EBAY_CLIENT_SECRET": "your-ebay-client-secret"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Claude Code
|
|
53
|
+
|
|
54
|
+
Add to `~/.claude/.mcp.json`:
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"mcpServers": {
|
|
59
|
+
"secondhand": {
|
|
60
|
+
"command": "npx",
|
|
61
|
+
"args": ["-y", "secondhand-mcp"],
|
|
62
|
+
"env": {
|
|
63
|
+
"EBAY_CLIENT_ID": "your-ebay-client-id",
|
|
64
|
+
"EBAY_CLIENT_SECRET": "your-ebay-client-secret"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
eBay credentials are optional — if omitted, eBay will be disabled and only Facebook Marketplace will be available.
|
|
72
|
+
|
|
73
|
+
## Configuration
|
|
74
|
+
|
|
75
|
+
### Choosing Marketplaces
|
|
76
|
+
|
|
77
|
+
By default all marketplaces are enabled. To limit which marketplaces are active, set the `MARKETPLACES` env var (comma-separated):
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"env": {
|
|
82
|
+
"MARKETPLACES": "facebook",
|
|
83
|
+
"EBAY_CLIENT_ID": "...",
|
|
84
|
+
"EBAY_CLIENT_SECRET": "..."
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Valid values: `facebook`, `ebay`
|
|
90
|
+
|
|
91
|
+
### eBay API Keys
|
|
92
|
+
|
|
93
|
+
eBay uses the official [Browse API](https://developer.ebay.com/api-docs/buy/browse/overview.html). You need a free eBay developer account:
|
|
94
|
+
|
|
95
|
+
1. Create an account at [developer.ebay.com](https://developer.ebay.com)
|
|
96
|
+
2. Create an application to get a Client ID and Client Secret
|
|
97
|
+
3. Add them to your MCP config as `EBAY_CLIENT_ID` and `EBAY_CLIENT_SECRET`
|
|
98
|
+
|
|
99
|
+
## Tools
|
|
100
|
+
|
|
101
|
+
### `search_marketplace`
|
|
102
|
+
|
|
103
|
+
Search for items across marketplaces. Returns a summary per listing: **title, price, location, listing ID, and photo count**.
|
|
104
|
+
|
|
105
|
+
| Parameter | Required | Default | Description |
|
|
106
|
+
|-----------|----------|---------|-------------|
|
|
107
|
+
| `query` | Yes | | Search terms |
|
|
108
|
+
| `marketplace` | No | `facebook` | `facebook`, `ebay`, or `all` |
|
|
109
|
+
| `location` | No | `san francisco` | City to search in (Facebook only) |
|
|
110
|
+
| `maxPrice` | No | | Maximum price |
|
|
111
|
+
| `minPrice` | No | | Minimum price |
|
|
112
|
+
| `limit` | No | `20` | Max results |
|
|
113
|
+
| `showSold` | No | `false` | Include sold/unavailable items (Facebook only) |
|
|
114
|
+
| `includeImages` | No | `false` | Include image URLs in output |
|
|
115
|
+
|
|
116
|
+
**Data returned per marketplace:**
|
|
117
|
+
|
|
118
|
+
| Field | Facebook | eBay |
|
|
119
|
+
|-------|----------|------|
|
|
120
|
+
| Title | Yes | Yes |
|
|
121
|
+
| Price | Yes | Yes |
|
|
122
|
+
| Location | City name | City, State |
|
|
123
|
+
| Condition | No | Yes |
|
|
124
|
+
| Photo count | Yes (1 thumbnail) | Yes (1 thumbnail) |
|
|
125
|
+
| Seller | Yes | Yes |
|
|
126
|
+
|
|
127
|
+
### `get_listing_details`
|
|
128
|
+
|
|
129
|
+
Get full details for a specific listing using an ID from search results.
|
|
130
|
+
|
|
131
|
+
| Parameter | Required | Default | Description |
|
|
132
|
+
|-----------|----------|---------|-------------|
|
|
133
|
+
| `listingId` | Yes | | Listing ID from search results |
|
|
134
|
+
| `marketplace` | No | `facebook` | `facebook` or `ebay` |
|
|
135
|
+
|
|
136
|
+
**Data returned per marketplace:**
|
|
137
|
+
|
|
138
|
+
| Field | Facebook | eBay |
|
|
139
|
+
|-------|----------|------|
|
|
140
|
+
| Description | Yes | Yes |
|
|
141
|
+
| All photos | Yes | Yes |
|
|
142
|
+
| Location | City | City, State, Country |
|
|
143
|
+
| Seller | Name | Username |
|
|
144
|
+
| Delivery types | Yes | No |
|
|
145
|
+
| Shipping options | Yes/No flag | Service codes |
|
|
146
|
+
|
|
147
|
+
### `list_marketplaces`
|
|
148
|
+
|
|
149
|
+
List all enabled marketplaces and their status.
|
|
150
|
+
|
|
151
|
+
## Example Output
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
Found 15 listings for "stroller" on facebook
|
|
155
|
+
Location: san francisco
|
|
156
|
+
|
|
157
|
+
**$25** - Baby stroller
|
|
158
|
+
San Francisco, CA
|
|
159
|
+
ID: 123456789
|
|
160
|
+
1 photo
|
|
161
|
+
|
|
162
|
+
**$50** - Thule Urban Glide Jogging Stroller
|
|
163
|
+
San Francisco, CA
|
|
164
|
+
ID: 987654321
|
|
165
|
+
1 photo
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Use `get_listing_details` with a listing ID to see full photos, description, and seller info.
|
|
169
|
+
|
|
170
|
+
## How It Works
|
|
171
|
+
|
|
172
|
+
**Facebook Marketplace** — Uses Facebook's internal GraphQL API to search listings directly. No login, no browser automation. Resolves city names to coordinates, then searches with location/price/query filters. Uses undocumented `doc_id` endpoints that may need updating if Facebook changes their frontend.
|
|
173
|
+
|
|
174
|
+
**eBay** — Uses the official eBay Browse API with OAuth 2.0 client credentials. Tokens are cached and auto-refreshed.
|
|
175
|
+
|
|
176
|
+
## Adding New Marketplaces
|
|
177
|
+
|
|
178
|
+
1. Create a new file in `src/marketplaces/` (e.g., `craigslist.ts`)
|
|
179
|
+
2. Extend `BaseMarketplace` and implement `search()` and optionally `getListingDetails()`
|
|
180
|
+
3. Add the constructor to the `allMarketplaces` registry in `src/marketplaces/index.ts`
|
|
181
|
+
|
|
182
|
+
## Development
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
npm install
|
|
186
|
+
npm run build
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Limitations
|
|
190
|
+
|
|
191
|
+
- **Facebook Marketplace**: Uses undocumented GraphQL API — may break if Facebook changes `doc_id` values (constants in `src/marketplaces/facebook.ts`)
|
|
192
|
+
- **Rate limiting**: Don't make too many requests too quickly
|
|
193
|
+
- **eBay**: Requires developer API keys (free tier available)
|
|
194
|
+
|
|
195
|
+
## License
|
|
196
|
+
|
|
197
|
+
MIT
|
|
198
|
+
|
|
199
|
+
## Disclaimer
|
|
200
|
+
|
|
201
|
+
This tool is for personal use. Respect each marketplace's Terms of Service.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Secondhand MCP Server
|
|
5
|
+
*
|
|
6
|
+
* An MCP server for searching secondary marketplaces like
|
|
7
|
+
* Facebook Marketplace, eBay, Craigslist, and more.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
11
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
12
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
13
|
+
const marketplaces_1 = require("./marketplaces");
|
|
14
|
+
// Initialize marketplaces
|
|
15
|
+
(0, marketplaces_1.initializeMarketplaces)();
|
|
16
|
+
// Define available tools
|
|
17
|
+
const tools = [
|
|
18
|
+
{
|
|
19
|
+
name: 'search_marketplace',
|
|
20
|
+
description: `Search for items on secondary marketplaces. Supports: ${(0, marketplaces_1.listMarketplaceNames)().join(', ')}. Returns listing ID, title, price, location, and photo count. Facebook: location-based search, no auth. eBay: keyword search with condition filter, requires API keys. Use get_listing_details with a listing ID for full description, all photos, seller info, and shipping options.`,
|
|
21
|
+
inputSchema: {
|
|
22
|
+
type: 'object',
|
|
23
|
+
properties: {
|
|
24
|
+
query: {
|
|
25
|
+
type: 'string',
|
|
26
|
+
description: 'Search query (e.g., "stroller", "iPhone 14", "vintage couch")'
|
|
27
|
+
},
|
|
28
|
+
marketplace: {
|
|
29
|
+
type: 'string',
|
|
30
|
+
description: `Marketplace to search. Options: ${(0, marketplaces_1.listMarketplaceNames)().join(', ')}, or "all" to search all marketplaces`,
|
|
31
|
+
default: 'facebook'
|
|
32
|
+
},
|
|
33
|
+
location: {
|
|
34
|
+
type: 'string',
|
|
35
|
+
description: 'City or area to search (e.g., "san francisco", "nyc", "los angeles")',
|
|
36
|
+
default: 'san francisco'
|
|
37
|
+
},
|
|
38
|
+
maxPrice: {
|
|
39
|
+
type: 'number',
|
|
40
|
+
description: 'Maximum price filter (optional)'
|
|
41
|
+
},
|
|
42
|
+
minPrice: {
|
|
43
|
+
type: 'number',
|
|
44
|
+
description: 'Minimum price filter (optional)'
|
|
45
|
+
},
|
|
46
|
+
limit: {
|
|
47
|
+
type: 'number',
|
|
48
|
+
description: 'Maximum number of results to return (default: 20)',
|
|
49
|
+
default: 20
|
|
50
|
+
},
|
|
51
|
+
showSold: {
|
|
52
|
+
type: 'boolean',
|
|
53
|
+
description: 'Include sold/unavailable items in results (default: false)',
|
|
54
|
+
default: false
|
|
55
|
+
},
|
|
56
|
+
includeImages: {
|
|
57
|
+
type: 'boolean',
|
|
58
|
+
description: 'Include full image URLs in results (default: false). Use get_listing_details for full photos.',
|
|
59
|
+
default: false
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
required: ['query']
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: 'get_listing_details',
|
|
67
|
+
description: 'Get full details for a specific listing using an ID from search results. Facebook returns: description, all photos, location, seller name, delivery types, shipping availability. eBay returns: description, all photos, location (city/state/country), seller username, shipping service options.',
|
|
68
|
+
inputSchema: {
|
|
69
|
+
type: 'object',
|
|
70
|
+
properties: {
|
|
71
|
+
listingId: {
|
|
72
|
+
type: 'string',
|
|
73
|
+
description: 'The listing ID (from search results or a marketplace URL)'
|
|
74
|
+
},
|
|
75
|
+
marketplace: {
|
|
76
|
+
type: 'string',
|
|
77
|
+
description: 'Which marketplace the listing is from (default: facebook)',
|
|
78
|
+
default: 'facebook'
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
required: ['listingId']
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: 'list_marketplaces',
|
|
86
|
+
description: 'List all available marketplaces and their status',
|
|
87
|
+
inputSchema: {
|
|
88
|
+
type: 'object',
|
|
89
|
+
properties: {}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
];
|
|
93
|
+
// Create server
|
|
94
|
+
const server = new index_js_1.Server({
|
|
95
|
+
name: 'secondhand-mcp',
|
|
96
|
+
version: '0.1.0',
|
|
97
|
+
}, {
|
|
98
|
+
capabilities: {
|
|
99
|
+
tools: {},
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
// Handle tool listing
|
|
103
|
+
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
|
|
104
|
+
return { tools };
|
|
105
|
+
});
|
|
106
|
+
// Handle tool calls
|
|
107
|
+
server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
108
|
+
const { name, arguments: args } = request.params;
|
|
109
|
+
switch (name) {
|
|
110
|
+
case 'search_marketplace': {
|
|
111
|
+
const params = args;
|
|
112
|
+
const searchParams = {
|
|
113
|
+
query: params.query,
|
|
114
|
+
location: params.location || 'san francisco',
|
|
115
|
+
maxPrice: params.maxPrice,
|
|
116
|
+
minPrice: params.minPrice,
|
|
117
|
+
limit: params.limit || 20,
|
|
118
|
+
showSold: params.showSold || false,
|
|
119
|
+
};
|
|
120
|
+
const marketplaceName = params.marketplace || 'facebook';
|
|
121
|
+
if (marketplaceName === 'all') {
|
|
122
|
+
// Search all marketplaces
|
|
123
|
+
const results = [];
|
|
124
|
+
for (const mp of (0, marketplaces_1.getAllMarketplaces)()) {
|
|
125
|
+
try {
|
|
126
|
+
const result = await mp.search(searchParams);
|
|
127
|
+
results.push(result);
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
results.push({
|
|
131
|
+
marketplace: mp.name,
|
|
132
|
+
success: false,
|
|
133
|
+
listings: [],
|
|
134
|
+
error: String(error)
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
content: [
|
|
140
|
+
{
|
|
141
|
+
type: 'text',
|
|
142
|
+
text: formatMultipleResults(results, searchParams, params.includeImages || false)
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
// Search specific marketplace
|
|
149
|
+
const marketplace = (0, marketplaces_1.getMarketplace)(marketplaceName);
|
|
150
|
+
if (!marketplace) {
|
|
151
|
+
return {
|
|
152
|
+
content: [
|
|
153
|
+
{
|
|
154
|
+
type: 'text',
|
|
155
|
+
text: `Unknown marketplace: ${marketplaceName}. Available: ${(0, marketplaces_1.listMarketplaceNames)().join(', ')}`
|
|
156
|
+
}
|
|
157
|
+
],
|
|
158
|
+
isError: true
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
try {
|
|
162
|
+
const result = await marketplace.search(searchParams);
|
|
163
|
+
return {
|
|
164
|
+
content: [
|
|
165
|
+
{
|
|
166
|
+
type: 'text',
|
|
167
|
+
text: formatSingleResult(result, searchParams, params.includeImages || false)
|
|
168
|
+
}
|
|
169
|
+
]
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
return {
|
|
174
|
+
content: [
|
|
175
|
+
{
|
|
176
|
+
type: 'text',
|
|
177
|
+
text: `Error searching ${marketplace.displayName}: ${error}`
|
|
178
|
+
}
|
|
179
|
+
],
|
|
180
|
+
isError: true
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
case 'get_listing_details': {
|
|
186
|
+
const { listingId, marketplace: mpName } = args;
|
|
187
|
+
if (!listingId) {
|
|
188
|
+
return {
|
|
189
|
+
content: [{ type: 'text', text: 'Missing required parameter: listingId' }],
|
|
190
|
+
isError: true,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
try {
|
|
194
|
+
const targetMp = mpName || 'facebook';
|
|
195
|
+
let details;
|
|
196
|
+
if (targetMp === 'ebay') {
|
|
197
|
+
const ebay = (0, marketplaces_1.getMarketplace)('ebay');
|
|
198
|
+
details = await ebay.getListingDetails(listingId);
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
const fb = (0, marketplaces_1.getMarketplace)('facebook');
|
|
202
|
+
details = await fb.getListingDetails(listingId);
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
content: [{ type: 'text', text: formatListingDetails(details) }],
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
return {
|
|
210
|
+
content: [{ type: 'text', text: `Error fetching listing details: ${error}` }],
|
|
211
|
+
isError: true,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
case 'list_marketplaces': {
|
|
216
|
+
const marketplaces = (0, marketplaces_1.getAllMarketplaces)();
|
|
217
|
+
const info = marketplaces.map(mp => ({
|
|
218
|
+
name: mp.name,
|
|
219
|
+
displayName: mp.displayName,
|
|
220
|
+
requiresAuth: mp.requiresAuth
|
|
221
|
+
}));
|
|
222
|
+
return {
|
|
223
|
+
content: [
|
|
224
|
+
{
|
|
225
|
+
type: 'text',
|
|
226
|
+
text: `Available Marketplaces:\n\n${info.map(m => `• ${m.displayName} (${m.name}) - ${m.requiresAuth ? 'Requires auth' : 'No auth required'}`).join('\n')}`
|
|
227
|
+
}
|
|
228
|
+
]
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
default:
|
|
232
|
+
return {
|
|
233
|
+
content: [{ type: 'text', text: `Unknown tool: ${name}` }],
|
|
234
|
+
isError: true
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
// Format results for display
|
|
239
|
+
function formatSingleResult(result, params, includeImages) {
|
|
240
|
+
if (!result.success) {
|
|
241
|
+
return `❌ ${result.marketplace}: ${result.error}`;
|
|
242
|
+
}
|
|
243
|
+
if (result.listings.length === 0) {
|
|
244
|
+
return `No listings found for "${params.query}" in ${params.location}`;
|
|
245
|
+
}
|
|
246
|
+
const lines = [
|
|
247
|
+
`🔍 Found ${result.listings.length} listings for "${params.query}" on ${result.marketplace}`,
|
|
248
|
+
`📍 Location: ${params.location}`,
|
|
249
|
+
''
|
|
250
|
+
];
|
|
251
|
+
// Sort by price
|
|
252
|
+
const sorted = [...result.listings].sort((a, b) => (a.priceNumeric || 0) - (b.priceNumeric || 0));
|
|
253
|
+
for (const listing of sorted) {
|
|
254
|
+
lines.push(`**${listing.price}** - ${listing.title}`);
|
|
255
|
+
if (listing.location) {
|
|
256
|
+
lines.push(` 📍 ${listing.location}`);
|
|
257
|
+
}
|
|
258
|
+
lines.push(` 🆔 ${listing.id}`);
|
|
259
|
+
if (listing.images && listing.images.length > 0) {
|
|
260
|
+
if (includeImages) {
|
|
261
|
+
lines.push(` 🖼️ Images: ${listing.images.join(' , ')}`);
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
lines.push(` 📷 ${listing.images.length} photo${listing.images.length > 1 ? 's' : ''}`);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
lines.push('');
|
|
268
|
+
}
|
|
269
|
+
return lines.join('\n');
|
|
270
|
+
}
|
|
271
|
+
function formatMultipleResults(results, params, includeImages) {
|
|
272
|
+
const lines = [
|
|
273
|
+
`🔍 Search results for "${params.query}" across all marketplaces`,
|
|
274
|
+
`📍 Location: ${params.location}`,
|
|
275
|
+
''
|
|
276
|
+
];
|
|
277
|
+
for (const result of results) {
|
|
278
|
+
lines.push(`## ${result.marketplace}`);
|
|
279
|
+
if (!result.success) {
|
|
280
|
+
lines.push(`❌ Error: ${result.error}`);
|
|
281
|
+
}
|
|
282
|
+
else if (result.listings.length === 0) {
|
|
283
|
+
lines.push('No listings found');
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
lines.push(`Found ${result.listings.length} listings:`);
|
|
287
|
+
const sorted = [...result.listings].sort((a, b) => (a.priceNumeric || 0) - (b.priceNumeric || 0)).slice(0, 10); // Top 10 per marketplace
|
|
288
|
+
for (const listing of sorted) {
|
|
289
|
+
lines.push(` • **${listing.price}** - ${listing.title}`);
|
|
290
|
+
if (listing.images && listing.images.length > 0) {
|
|
291
|
+
if (includeImages) {
|
|
292
|
+
lines.push(` 🖼️ Images: ${listing.images.join(' , ')}`);
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
lines.push(` 📷 ${listing.images.length} photo${listing.images.length > 1 ? 's' : ''}`);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
lines.push(` 🆔 ${listing.id}`);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
lines.push('');
|
|
302
|
+
}
|
|
303
|
+
return lines.join('\n');
|
|
304
|
+
}
|
|
305
|
+
function formatListingDetails(details) {
|
|
306
|
+
const lines = [
|
|
307
|
+
`📋 Listing Details`,
|
|
308
|
+
`🔗 ${details.url}`,
|
|
309
|
+
'',
|
|
310
|
+
];
|
|
311
|
+
if (details.description) {
|
|
312
|
+
lines.push(`**Description:** ${details.description}`);
|
|
313
|
+
lines.push('');
|
|
314
|
+
}
|
|
315
|
+
if (details.location) {
|
|
316
|
+
lines.push(`📍 ${details.location}`);
|
|
317
|
+
}
|
|
318
|
+
if (details.seller) {
|
|
319
|
+
lines.push(`👤 Seller: ${details.seller}`);
|
|
320
|
+
}
|
|
321
|
+
if (details.deliveryTypes && details.deliveryTypes.length > 0) {
|
|
322
|
+
lines.push(`🚚 Delivery: ${details.deliveryTypes.join(', ')}`);
|
|
323
|
+
}
|
|
324
|
+
if (details.isShippingOffered) {
|
|
325
|
+
lines.push(`📦 Shipping available`);
|
|
326
|
+
}
|
|
327
|
+
if (details.images.length > 0) {
|
|
328
|
+
lines.push('');
|
|
329
|
+
lines.push(`🖼️ Photos (${details.images.length}):`);
|
|
330
|
+
for (const img of details.images) {
|
|
331
|
+
lines.push(` ${img}`);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return lines.join('\n');
|
|
335
|
+
}
|
|
336
|
+
// Start server
|
|
337
|
+
async function main() {
|
|
338
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
339
|
+
await server.connect(transport);
|
|
340
|
+
console.error('Secondhand MCP server started');
|
|
341
|
+
}
|
|
342
|
+
// Clean shutdown
|
|
343
|
+
process.on('SIGINT', () => process.exit(0));
|
|
344
|
+
process.on('SIGTERM', () => process.exit(0));
|
|
345
|
+
main().catch((error) => {
|
|
346
|
+
console.error('Fatal error:', error);
|
|
347
|
+
process.exit(1);
|
|
348
|
+
});
|
|
349
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base interface for all marketplace implementations
|
|
3
|
+
*/
|
|
4
|
+
import { SearchParams, SearchResult, LocationCoordinates } from '../types';
|
|
5
|
+
export interface Marketplace {
|
|
6
|
+
/** Unique identifier for this marketplace */
|
|
7
|
+
readonly name: string;
|
|
8
|
+
/** Human-readable display name */
|
|
9
|
+
readonly displayName: string;
|
|
10
|
+
/** Whether this marketplace requires authentication */
|
|
11
|
+
readonly requiresAuth: boolean;
|
|
12
|
+
/** Search for listings */
|
|
13
|
+
search(params: SearchParams): Promise<SearchResult>;
|
|
14
|
+
/** Get location coordinates for a city/area (if supported) */
|
|
15
|
+
getLocation?(query: string): Promise<LocationCoordinates | null>;
|
|
16
|
+
/** Check if the marketplace is accessible */
|
|
17
|
+
healthCheck(): Promise<boolean>;
|
|
18
|
+
}
|
|
19
|
+
export declare abstract class BaseMarketplace implements Marketplace {
|
|
20
|
+
abstract readonly name: string;
|
|
21
|
+
abstract readonly displayName: string;
|
|
22
|
+
abstract readonly requiresAuth: boolean;
|
|
23
|
+
abstract search(params: SearchParams): Promise<SearchResult>;
|
|
24
|
+
healthCheck(): Promise<boolean>;
|
|
25
|
+
protected parsePrice(priceStr: string): {
|
|
26
|
+
numeric: number;
|
|
27
|
+
currency: string;
|
|
28
|
+
} | null;
|
|
29
|
+
protected createError(message: string): SearchResult;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/marketplaces/base.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAE3E,MAAM,WAAW,WAAW;IAC1B,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,kCAAkC;IAClC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B,uDAAuD;IACvD,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAE/B,0BAA0B;IAC1B,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAEpD,8DAA8D;IAC9D,WAAW,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;IAEjE,6CAA6C;IAC7C,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CACjC;AAED,8BAAsB,eAAgB,YAAW,WAAW;IAC1D,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAExC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAEtD,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAIrC,SAAS,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAWpF,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY;CAQrD"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Base interface for all marketplace implementations
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.BaseMarketplace = void 0;
|
|
7
|
+
class BaseMarketplace {
|
|
8
|
+
async healthCheck() {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
parsePrice(priceStr) {
|
|
12
|
+
// Handle common price formats: $50, $1,234.56, €50, £50
|
|
13
|
+
const match = priceStr.match(/([£€$])?[\s]*([\d,]+(?:\.\d{2})?)/);
|
|
14
|
+
if (!match)
|
|
15
|
+
return null;
|
|
16
|
+
const currency = match[1] || '$';
|
|
17
|
+
const numeric = parseFloat(match[2].replace(/,/g, ''));
|
|
18
|
+
return { numeric, currency };
|
|
19
|
+
}
|
|
20
|
+
createError(message) {
|
|
21
|
+
return {
|
|
22
|
+
marketplace: this.name,
|
|
23
|
+
success: false,
|
|
24
|
+
listings: [],
|
|
25
|
+
error: message
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.BaseMarketplace = BaseMarketplace;
|
|
30
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/marketplaces/base.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAwBH,MAAsB,eAAe;IAOnC,KAAK,CAAC,WAAW;QACf,OAAO,IAAI,CAAC;IACd,CAAC;IAES,UAAU,CAAC,QAAgB;QACnC,wDAAwD;QACxD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;QAClE,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAExB,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;QACjC,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;QAEvD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IAC/B,CAAC;IAES,WAAW,CAAC,OAAe;QACnC,OAAO;YACL,WAAW,EAAE,IAAI,CAAC,IAAI;YACtB,OAAO,EAAE,KAAK;YACd,QAAQ,EAAE,EAAE;YACZ,KAAK,EAAE,OAAO;SACf,CAAC;IACJ,CAAC;CACF;AA9BD,0CA8BC"}
|