@imenam/simple-scraper 1.0.16 → 1.0.17

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/README.md CHANGED
@@ -31,6 +31,23 @@ npm install -g @imenam/simple-scraper
31
31
  simple-scraper
32
32
  ```
33
33
 
34
+ ## MCP Configuration
35
+
36
+ ### Quick setup
37
+
38
+ From the repo you want to scrape from, generate a ready-to-fill `.mcp.json` in the current directory:
39
+
40
+ ```bash
41
+ npx @imenam/simple-scraper --claude-setup-mcp
42
+ ```
43
+
44
+ It creates the `simple-scraper-mcp` entry with the proxy variables pre-filled from the current
45
+ folder name (`PROXY_URL`, `APP_GROUP`, `PROXY_APP_NAME`, `PROXY_APP_PATH`) plus a 1920x1080
46
+ viewport, and prints the remaining optional variables. An empty variable is simply inactive
47
+ (no `PROXY_URL` = no GUI), so the generated config runs as-is. An existing `.mcp.json` is merged,
48
+ other servers are preserved, and an existing `simple-scraper-mcp` entry is only replaced when
49
+ `--force` is passed.
50
+
34
51
  ## Environment Variables
35
52
 
36
53
  | Variable | Required | Default | Description |
@@ -0,0 +1,103 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ const SERVER_NAME = 'simple-scraper-mcp';
4
+ const PACKAGE_NAME = '@imenam/simple-scraper';
5
+ /** "simple-scraper" -> "Simple-scraper" */
6
+ function capitalize(value) {
7
+ return value.charAt(0).toUpperCase() + value.slice(1);
8
+ }
9
+ /** "my_project-web" -> "My Project Web" */
10
+ function toDisplayName(folder) {
11
+ return folder
12
+ .split(/[-_]+/)
13
+ .filter(Boolean)
14
+ .map(capitalize)
15
+ .join(' ');
16
+ }
17
+ /**
18
+ * Valeurs volontairement vides : chaque variable est inactive tant qu'elle n'est
19
+ * pas remplie (PROXY_URL vide = GUI désactivée), donc le fichier généré est
20
+ * utilisable tel quel, jamais à moitié cassé. Le viewport fait exception : un
21
+ * défaut 1920x1080 évite les layouts mobiles/tablette sur la plupart des sites.
22
+ */
23
+ function buildServerEntry(codeRoot) {
24
+ // Le nom du dossier courant sert de base aux identifiants d'affichage côté proxy.
25
+ const folder = path.basename(codeRoot) || 'scraper';
26
+ return {
27
+ command: 'npx',
28
+ args: ['-y', PACKAGE_NAME],
29
+ env: {
30
+ PROXY_URL: 'http://localhost:',
31
+ APP_GROUP: capitalize(folder),
32
+ PROXY_APP_NAME: `Simple Scraper ${toDisplayName(folder)}`,
33
+ PROXY_APP_PATH: `/simple-scraper-${folder}`,
34
+ PUPPETEER_VIEWPORT_WIDTH: '1920',
35
+ PUPPETEER_VIEWPORT_HEIGHT: '1080',
36
+ },
37
+ };
38
+ }
39
+ const GENERATED_VARS = [
40
+ ['PROXY_URL', 'URL du proxy pour exposer la GUI (compléter le port)'],
41
+ ['APP_GROUP', 'groupe d\'affichage dans le dashboard du proxy'],
42
+ ['PROXY_APP_NAME', 'nom affiché de la GUI dans le dashboard du proxy'],
43
+ ['PROXY_APP_PATH', 'chemin de montage de la GUI derrière le proxy'],
44
+ ['PUPPETEER_VIEWPORT_WIDTH', 'largeur du viewport en pixels CSS'],
45
+ ['PUPPETEER_VIEWPORT_HEIGHT', 'hauteur du viewport en pixels CSS'],
46
+ ];
47
+ const OPTIONAL_VARS = [
48
+ ['PUPPETEER_DEVICE_SCALE_FACTOR', 'pixels physiques par pixel CSS (2 = screenshots retina)'],
49
+ ['PUPPETEER_HEADLESS', 'false pour afficher la fenêtre Chromium'],
50
+ ['PUPPETEER_TIMEOUT', 'timeout de navigation en ms (défaut : 30000)'],
51
+ ['COOKIES_DIR', 'dossier de fichiers cookies au format Netscape (.txt)'],
52
+ ['MCP_LOG_DIR', 'répertoire des logs'],
53
+ ['SCRAPER_MAX_SESSIONS', 'nombre max de sessions interactives (défaut : 5)'],
54
+ ['SCRAPER_SESSION_TTL_MS', 'TTL d\'inactivité des sessions en ms (défaut : 600000)'],
55
+ ];
56
+ export function runSetupMcp({ cwd, force }) {
57
+ const target = path.join(cwd, '.mcp.json');
58
+ let config = {};
59
+ const exists = fs.existsSync(target);
60
+ if (exists) {
61
+ const raw = fs.readFileSync(target, 'utf-8').trim();
62
+ if (raw !== '') {
63
+ try {
64
+ config = JSON.parse(raw);
65
+ }
66
+ catch (err) {
67
+ console.error(`Erreur : ${target} contient du JSON invalide (${err.message}).`);
68
+ console.error('Corrigez le fichier ou supprimez-le, puis relancez la commande.');
69
+ return 1;
70
+ }
71
+ }
72
+ if (typeof config !== 'object' || config === null || Array.isArray(config)) {
73
+ console.error(`Erreur : ${target} ne contient pas un objet JSON.`);
74
+ return 1;
75
+ }
76
+ }
77
+ if (typeof config.mcpServers !== 'object' || config.mcpServers === null || Array.isArray(config.mcpServers)) {
78
+ config.mcpServers = {};
79
+ }
80
+ const alreadyPresent = Object.prototype.hasOwnProperty.call(config.mcpServers, SERVER_NAME);
81
+ if (alreadyPresent && !force) {
82
+ console.error(`Le serveur "${SERVER_NAME}" est déjà configuré dans ${target}.`);
83
+ console.error('Relancez avec --force pour écraser cette entrée (les autres serveurs sont préservés).');
84
+ return 1;
85
+ }
86
+ config.mcpServers[SERVER_NAME] = buildServerEntry(cwd);
87
+ fs.writeFileSync(target, JSON.stringify(config, null, 2) + '\n', 'utf-8');
88
+ const action = alreadyPresent ? 'remplacée' : exists ? 'ajoutée' : 'créée';
89
+ console.log(`Configuration ${SERVER_NAME} ${action} dans ${target}`);
90
+ console.log('');
91
+ console.log('À compléter dans le champ "env" :');
92
+ for (const [name, description] of GENERATED_VARS) {
93
+ console.log(` ${name.padEnd(32)} ${description}`);
94
+ }
95
+ console.log('');
96
+ console.log('Variables optionnelles à ajouter au besoin :');
97
+ for (const [name, description] of OPTIONAL_VARS) {
98
+ console.log(` ${name.padEnd(32)} ${description}`);
99
+ }
100
+ console.log('');
101
+ console.log('Une variable laissée vide est simplement inactive.');
102
+ return 0;
103
+ }
package/dist/index.js CHANGED
@@ -15,6 +15,12 @@ import { registerSessionRpc } from './session-rpc.js';
15
15
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
16
16
  const rootDir = path.resolve(__dirname, '..');
17
17
  const envPath = path.join(rootDir, '.env');
18
+ // Les flags CLI sont traités avant toute initialisation (dotenv, logs, GUI) :
19
+ // ils s'exécutent dans le répertoire de l'utilisateur, pas dans un serveur MCP.
20
+ if (process.argv.slice(2).includes('--claude-setup-mcp')) {
21
+ const { runSetupMcp } = await import('./cli/setup-mcp.js');
22
+ process.exit(runSetupMcp({ cwd: process.cwd(), force: process.argv.slice(2).includes('--force') }));
23
+ }
18
24
  dotenv.config({ path: envPath, override: true });
19
25
  setupLogging('MASTER');
20
26
  const launcher = new GuiLauncher({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imenam/simple-scraper",
3
- "version": "1.0.16",
3
+ "version": "1.0.17",
4
4
  "description": "MCP server for web scraping and JavaScript execution using Puppeteer",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",