@clicbase/mcp 0.2.0 → 0.3.1

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
@@ -18,9 +18,14 @@ Outils :
18
18
  - `enable_realtime` — active le temps réel sur une table.
19
19
  - `set_oauth_provider` — configure Google OAuth.
20
20
  - `set_email_smtp` — configure un SMTP (sinon SMTP interne Clicbase par défaut).
21
+ - `list_sites` — les sites heberges : c'est ICI qu'on prend le `site_id`.
22
+ - `list_projects` — les projets (bases) visibles par la cle.
21
23
  - `list_site_files` — liste les fichiers d'un site heberge (nom, taille, date).
22
24
  - `read_site_file` — rend le contenu d'UN fichier, en base64 cote API, decode cote outil.
23
25
  - `clicbase_conventions` — les regles de la plateforme : policies RLS, droits, PostgREST.
26
+ - `list_sftp_accounts` — les comptes SFTP dedies d'un site (noms, jamais de mot de passe).
27
+ - `create_sftp_account` — cree un compte SFTP DEDIE, rend ses identifiants une seule fois.
28
+ - `delete_sftp_account` — le supprime.
24
29
 
25
30
  ## Les fichiers d'un site
26
31
 
@@ -51,6 +56,34 @@ SERVIS par le serveur web ; elle protege exactement le bon flanc.
51
56
  Plafond : 2 Mo cote API, 256 Ko cote outil. Au-dela, le telechargement du
52
57
  tableau de bord ou le SFTP.
53
58
 
59
+ ## Le SFTP, sans donner le mot de passe du site
60
+
61
+ `ftpUsername` est l'IDENTITE d'un site : il ouvre tout le dossier, ne se scope
62
+ pas, n'expire pas, ne laisse aucune trace distinguable, et ne se revoque qu'en
63
+ le changeant partout ou il a ete colle. Le confier a un assistant, c'est lui
64
+ donner le site.
65
+
66
+ `create_sftp_account` fabrique un compte ADDITIONNEL sur le meme dossier, rend
67
+ host, port, identifiant et mot de passe UNE SEULE FOIS, et
68
+ `delete_sftp_account` le retire. Preter un badge, pas sa cle.
69
+
70
+ ```
71
+ list_sftp_accounts(site_id) -> les comptes dedies existants
72
+ create_sftp_account(site_id) -> host, port, user, password
73
+ delete_sftp_account(site_id, username) -> on referme
74
+ ```
75
+
76
+ ⚠️ `create_sftp_account` est classe SECRET : il ne modifie aucune donnee et
77
+ rend pourtant de quoi ouvrir tout le dossier. Il disparait donc du mode
78
+ restreint, comme `get_credentials` et `read_site_file`.
79
+
80
+ ⚠️ PLAFOND DE CINQ COMPTES PAR SITE, et cinq creations par tranche de cinq
81
+ minutes. Chaque compte est un utilisateur systeme reel : un agent qui reprend
82
+ sur erreur en recreant au lieu de reutiliser en fabriquerait des dizaines.
83
+
84
+ Pour une simple consultation, `list_site_files` et `read_site_file` suffisent
85
+ et ne creent rien.
86
+
54
87
  ## Lecture seule
55
88
 
56
89
  ```bash
package/clicbase-mcp.mjs CHANGED
@@ -289,6 +289,32 @@ async function admin(chemin, methode = "GET") {
289
289
  return res.json();
290
290
  }
291
291
 
292
+ outils.tool(
293
+ "list_sites",
294
+ "Liste les sites heberges visibles par cette cle : identifiant, slug, domaine, mode de deploiement. C'est ICI qu'on prend le `site_id` des autres outils : ce n'est ni le domaine ni le slug.",
295
+ {},
296
+ async () => {
297
+ try {
298
+ return out(await admin("/sites"));
299
+ } catch (e) {
300
+ return fail(e);
301
+ }
302
+ },
303
+ );
304
+
305
+ outils.tool(
306
+ "list_projects",
307
+ "Liste les projets (bases) visibles par cette cle : identifiant, nom, slug. Utile pour savoir sur quoi on peut agir avant de nommer quoi que ce soit.",
308
+ {},
309
+ async () => {
310
+ try {
311
+ return out(await admin("/projects"));
312
+ } catch (e) {
313
+ return fail(e);
314
+ }
315
+ },
316
+ );
317
+
292
318
  outils.tool(
293
319
  "list_site_files",
294
320
  "Liste les fichiers d'un site heberge (nom, dossier ou non, taille, date). `dossier` pour descendre d'un niveau. L'id du site vient de GET /sites.",
@@ -331,6 +357,50 @@ outils.tool(
331
357
  },
332
358
  );
333
359
 
360
+ outils.tool(
361
+ "list_sftp_accounts",
362
+ "Liste les comptes SFTP DEDIES d'un site (identifiants et dates, jamais les mots de passe). L'id du site vient de GET /sites.",
363
+ { site_id: z.string() },
364
+ async ({ site_id }) => {
365
+ try {
366
+ return out(await admin(`/sites/${encodeURIComponent(site_id)}/sftp`));
367
+ } catch (e) {
368
+ return fail(e);
369
+ }
370
+ },
371
+ );
372
+
373
+ outils.tool(
374
+ "create_sftp_account",
375
+ "Cree un compte SFTP DEDIE sur un site et rend host, port, identifiant et mot de passe UNE SEULE FOIS. Ce n'est jamais le compte principal du site. Supprime-le quand tu as fini. Plafond : 5 comptes par site.",
376
+ { site_id: z.string() },
377
+ async ({ site_id }) => {
378
+ try {
379
+ return out(await admin(`/sites/${encodeURIComponent(site_id)}/sftp`, "POST"));
380
+ } catch (e) {
381
+ return fail(e);
382
+ }
383
+ },
384
+ );
385
+
386
+ outils.tool(
387
+ "delete_sftp_account",
388
+ "Supprime un compte SFTP dedie, par son identifiant. A faire des que le transfert est termine : un compte oublie reste un acces ouvert.",
389
+ { site_id: z.string(), username: z.string() },
390
+ async ({ site_id, username }) => {
391
+ try {
392
+ return out(
393
+ await admin(
394
+ `/sites/${encodeURIComponent(site_id)}/sftp?username=${encodeURIComponent(username)}`,
395
+ "DELETE",
396
+ ),
397
+ );
398
+ } catch (e) {
399
+ return fail(e);
400
+ }
401
+ },
402
+ );
403
+
334
404
  // ⚠️ LE MODE RESTREINT S'ANNONCE, SUR LA SORTIE D'ERREUR. Un serveur qui
335
405
  // retire des outils en silence se decouvre en pleine session : l'assistant
336
406
  // cherche une fonction qui devrait exister, ne la trouve pas, et conclut que le
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clicbase/mcp",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mcp": "clicbase-mcp.mjs",
package/portee.mjs CHANGED
@@ -48,6 +48,14 @@ export const OUTILS = {
48
48
  // restreint qui en a le plus besoin, puisqu'il ne reste alors que trois
49
49
  // outils et qu'un assistant doit deviner le reste.
50
50
  clicbase_conventions: "lecture",
51
+ // --- de quoi savoir sur quoi agir ---
52
+ // ⚠️ SANS EUX, LES OUTILS QUI PRENNENT UN `site_id` SONT INUTILISABLES. Le
53
+ // 2026-09-18, un assistant a essaye le domaine puis le slug, recolte deux
54
+ // 404, et fini par demander l'identifiant a son utilisateur. L'API le
55
+ // publiait depuis toujours ; c'est l'outil qui manquait. Livrer une action
56
+ // sans le moyen de decouvrir sa cible, c'est livrer une porte sans poignee.
57
+ list_sites: "lecture",
58
+ list_projects: "lecture",
51
59
  // --- fichiers d'un site heberge ---
52
60
  // ⚠️ LISTER EST UNE LECTURE, LIRE EST UN SECRET. Le nom et la taille d'un
53
61
  // fichier revelent une structure ; son CONTENU peut porter des identifiants,
@@ -56,6 +64,14 @@ export const OUTILS = {
56
64
  // la maison. Les fichiers caches, eux, sont deja impossibles cote serveur.
57
65
  list_site_files: "lecture",
58
66
  read_site_file: "secret",
67
+ // --- comptes SFTP dedies ---
68
+ // ⚠️ CREER REND UN MOT DE PASSE, DONC C'EST UN SECRET. L'outil ne modifie
69
+ // pas de donnees, mais il rend de quoi ouvrir tout le dossier du site : meme
70
+ // raisonnement que get_credentials. Lister ne rend que des noms, supprimer
71
+ // ne rend rien mais ecrit.
72
+ list_sftp_accounts: "lecture",
73
+ create_sftp_account: "secret",
74
+ delete_sftp_account: "ecriture",
59
75
  };
60
76
 
61
77
  /** Ce qu'on garde en lecture seule. */
package/savoir.mjs CHANGED
@@ -35,7 +35,11 @@ SIX PIÈGES QUI NE LÈVENT AUCUNE ERREUR. Ils répondent tous « 200 OK ».
35
35
  5. Une fonction Edge renvoie \`{ status, body }\`, jamais \`new Response(...)\`.
36
36
  6. Deux authentifications sans rapport coexistent. Celle du PROJET (tes utilisateurs finaux) vit dans le schéma \`auth\` de cette base et alimente \`auth.uid()\` dans les policies. Celle de la PLATEFORME (le compte Clicbase) ne s'écrit jamais dans une policy.
37
37
 
38
- CE QUI N'EXISTE PAS, ET QUE DEUX ASSISTANTS ONT DEJA INVENTE. Il n'y a AUCUN registre Docker : ni \`docker login\`, ni \`docker pull\`, ni \`registry.*.clicbase.com\`. Ne devine aucun nom d'hote. Les fichiers d'un site heberge se lisent par \`list_site_files\` et \`read_site_file\`, et s'ecrivent par POST /sites/<id>/files. Inutile de reclamer un mot de passe SFTP pour cela : le SFTP reste utile pour un transfert volumineux, pas pour consulter. Les fichiers CACHES sont refuses a tout niveau, \`.env\` et \`.git\` compris : ils ne peuvent ni etre deposes ni etre lus. \`read_site_file\` est absent en lecture seule, parce qu'un source peut porter des identifiants dans un fichier non cache.
38
+ CE QUI N'EXISTE PAS, ET QUE DES ASSISTANTS ONT DEJA INVENTE. Aucun registre Docker : ni \`docker login\`, ni \`docker pull\`, ni \`registry.*.clicbase.com\`. Ne devine aucun nom d'hote.
39
+
40
+ COMMENCE PAR \`list_sites\`. Le \`site_id\` des autres outils est un identifiant technique : ni le domaine, ni le slug.
41
+
42
+ FICHIERS D'UN SITE : \`list_site_files\` et \`read_site_file\` pour lire, POST /sites/<id>/files pour ecrire. Les fichiers caches sont refuses a tout niveau, \`.env\` compris. Ne reclame JAMAIS le mot de passe SFTP principal : c'est l'identite du site, elle ouvre tout et ne se revoque pas. \`create_sftp_account\` fabrique un compte DEDIE, a supprimer des que tu as fini.
39
43
 
40
44
  APPELS REST : en-têtes \`apikey\` ET \`Authorization: Bearer\`, la même clé dans les deux. Filtres dans l'URL, façon PostgREST : \`?select=id,title&status=eq.published&order=created_at.desc\`.
41
45