mallmaverick-store-scraper 0.1.2 → 0.1.3
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/package.json +1 -1
- package/src/mcp-server.js +39 -15
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mallmaverick-store-scraper",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "MCP server + CLI for scraping shopping mall store directories. Hours-first layered pipeline + image classification.",
|
|
5
5
|
"main": "src/main.js",
|
|
6
6
|
"type": "commonjs",
|
package/src/mcp-server.js
CHANGED
|
@@ -60,11 +60,11 @@ const TOOLS = [
|
|
|
60
60
|
'(name, hours, phone, logo, brand image, categories, etc.). Use this ' +
|
|
61
61
|
'when the user wants to capture a directory like ' +
|
|
62
62
|
'https://grasslands.ca/store-directory/.\n\n' +
|
|
63
|
-
'AFTER RUNNING THIS TOOL:
|
|
64
|
-
'
|
|
65
|
-
'
|
|
66
|
-
'
|
|
67
|
-
'
|
|
63
|
+
'AFTER RUNNING THIS TOOL: give a short summary — how many stores were ' +
|
|
64
|
+
'extracted, hours-layer breakdown, and the saved file path. The CSV is ' +
|
|
65
|
+
'attached as a resource in the tool response (the user can download/' +
|
|
66
|
+
'preview it from there) — do NOT paste the CSV text into your reply. ' +
|
|
67
|
+
'Keep your text reply short.',
|
|
68
68
|
inputSchema: {
|
|
69
69
|
type: 'object',
|
|
70
70
|
properties: {
|
|
@@ -129,7 +129,7 @@ const TOOLS = [
|
|
|
129
129
|
},
|
|
130
130
|
];
|
|
131
131
|
|
|
132
|
-
const PACKAGE_VERSION = '0.1.
|
|
132
|
+
const PACKAGE_VERSION = '0.1.3';
|
|
133
133
|
|
|
134
134
|
const server = new Server(
|
|
135
135
|
{ name: 'mall-scraper-mcp', version: PACKAGE_VERSION },
|
|
@@ -231,20 +231,44 @@ async function handleScrapeDirectory({ directory_url, max_stores = 10, concurren
|
|
|
231
231
|
mcp_version: PACKAGE_VERSION,
|
|
232
232
|
};
|
|
233
233
|
|
|
234
|
-
//
|
|
235
|
-
//
|
|
234
|
+
// Build a short brief + return the CSV as an embedded resource so
|
|
235
|
+
// Claude Desktop can render it as an attachment card instead of inline
|
|
236
|
+
// text. Falls back to inline-rendering if the client doesn't support
|
|
237
|
+
// resources, but most clients (including Claude Desktop) do.
|
|
238
|
+
const host = new URL(directory_url).hostname.replace(/^www\./, '');
|
|
239
|
+
const csvFilename = writtenPaths
|
|
240
|
+
? path.basename(writtenPaths.csv)
|
|
241
|
+
: `stores_v5_${host}.csv`;
|
|
242
|
+
const csvUri = writtenPaths
|
|
243
|
+
? `file://${writtenPaths.csv}`
|
|
244
|
+
: `file:///tmp/${csvFilename}`;
|
|
245
|
+
|
|
246
|
+
const brief =
|
|
247
|
+
`mall-scraper-mcp v${PACKAGE_VERSION}\n` +
|
|
248
|
+
`Scraped ${stores.length} store${stores.length === 1 ? '' : 's'} from ${host}.\n` +
|
|
249
|
+
`Hours-layer breakdown: ${Object.entries(bySource).map(([k, v]) => `${k}=${v}`).join(', ')}.\n` +
|
|
250
|
+
(writtenPaths
|
|
251
|
+
? `Saved to: ${writtenPaths.csv}`
|
|
252
|
+
: `⚠ disk write failed (${writeError}); CSV is in the attached resource only.`);
|
|
253
|
+
|
|
236
254
|
return {
|
|
237
255
|
content: [
|
|
256
|
+
{ type: 'text', text: brief },
|
|
257
|
+
{
|
|
258
|
+
type: 'resource',
|
|
259
|
+
resource: {
|
|
260
|
+
uri: csvUri,
|
|
261
|
+
name: csvFilename,
|
|
262
|
+
mimeType: 'text/csv',
|
|
263
|
+
text: csvText,
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
// Keep the JSON summary at the end for any debugging the user asks for,
|
|
267
|
+
// but it's far enough down that it doesn't dominate the chat.
|
|
238
268
|
{
|
|
239
269
|
type: 'text',
|
|
240
|
-
text:
|
|
241
|
-
`mall-scraper-mcp v${PACKAGE_VERSION}\n` +
|
|
242
|
-
'CSV ready — paste the block below into your CMS. ' +
|
|
243
|
-
`Also saved to: ${writtenPaths ? writtenPaths.csv : '(disk write failed; CSV is inline only)'}.\n\n` +
|
|
244
|
-
'```csv\n' + csvText + '\n```',
|
|
270
|
+
text: '\n--- Run summary ---\n' + JSON.stringify(summary, null, 2),
|
|
245
271
|
},
|
|
246
|
-
{ type: 'text', text: '\n--- Run summary ---\n' + JSON.stringify(summary, null, 2) },
|
|
247
|
-
{ type: 'text', text: '\n--- Stores (JSON for debugging) ---\n' + JSON.stringify(stores, null, 2) },
|
|
248
272
|
],
|
|
249
273
|
};
|
|
250
274
|
} finally {
|