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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. 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.2",
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: paste the full CSV content (from the ' +
64
- '"--- CSV ---" block of the response) into your reply inside a fenced ' +
65
- 'code block so the user can copy it directly into their CMS. ' +
66
- 'Also state the saved file path and a one-line summary of how many ' +
67
- 'stores were extracted. Do NOT summarize away the CSV — show it in full.',
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.2';
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
- // Order matters Claude is more likely to surface the first content
235
- // blocks. Lead with the CSV so it can't be summarized away.
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 {