@imenam/mcp-documentor 1.0.67 → 1.0.69
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 +16 -0
- package/dist/src/cli/setup-mcp.d.ts +5 -0
- package/dist/src/cli/setup-mcp.js +98 -0
- package/dist/src/core/log-dir.d.ts +6 -0
- package/dist/src/core/log-dir.js +12 -0
- package/dist/src/gui-worker.js +2 -1
- package/dist/src/index.js +9 -2
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -37,6 +37,21 @@ Global install exposes:
|
|
|
37
37
|
|
|
38
38
|
## MCP Configuration
|
|
39
39
|
|
|
40
|
+
### Quick setup
|
|
41
|
+
|
|
42
|
+
From the repo you want to document, generate a ready-to-fill `.mcp.json` in the current directory:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npx @imenam/mcp-documentor --claude-setup-mcp
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
It creates the `mcp-documentor` entry with the usual environment variables as empty placeholders —
|
|
49
|
+
an empty variable is simply inactive, so the generated config runs as-is and you only fill in what
|
|
50
|
+
you need. An existing `.mcp.json` is merged, other servers are preserved, and an existing
|
|
51
|
+
`mcp-documentor` entry is only replaced when `--force` is passed.
|
|
52
|
+
|
|
53
|
+
### Manual setup
|
|
54
|
+
|
|
40
55
|
Add to your MCP client config (e.g. Cursor `mcp.json`):
|
|
41
56
|
|
|
42
57
|
```json
|
|
@@ -62,6 +77,7 @@ Add to your MCP client config (e.g. Cursor `mcp.json`):
|
|
|
62
77
|
| `PROXY_URL` | No | URL of the proxy server to register and launch the GUI |
|
|
63
78
|
| `APP_GROUP` | No | Groups the app under a collapsible section (folded by default) in the proxy dashboard. Apps sharing the same value appear together; if unset, the app lands in the default "ungrouped" section |
|
|
64
79
|
| `MCP_DATA_DIR` | No | Overrides the default data directory (see Data storage) |
|
|
80
|
+
| `MCP_LOG_DIR` | No | Overrides the log directory of both the server and the GUI worker (default: `<package>/.docs-data/logs`). Must be set in the MCP client config — the package `.env` is loaded after the logger starts |
|
|
65
81
|
| `MCP_DOCUMENTOR_CODE_ROOT` | No | Base directory that tracked-file paths are stored relative to, keeping docs portable across machines (see [Portable tracked-file paths](#portable-tracked-file-paths)) |
|
|
66
82
|
| `MCP_DOCUMENTOR_CODE_ROOTS` | No | JSON map of per-project code-root overrides, e.g. `{"my-proj":"/srv/my-proj"}` |
|
|
67
83
|
| `READ_ONLY` | No | When set to `1`/`true`/`yes`, disables all create/update/delete tools and GUI write actions (read-only mode) |
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
const SERVER_NAME = "mcp-documentor";
|
|
4
|
+
const PACKAGE_NAME = "@imenam/mcp-documentor";
|
|
5
|
+
/**
|
|
6
|
+
* Valeurs volontairement vides : chaque variable est inactive tant qu'elle n'est
|
|
7
|
+
* pas remplie (PROXY_URL vide = GUI désactivée, clé vide = pas d'embeddings),
|
|
8
|
+
* donc le fichier généré est utilisable tel quel, jamais à moitié cassé.
|
|
9
|
+
*/
|
|
10
|
+
/** Slashes POSIX : évite les backslashes échappés dans le JSON, et Node les accepte sous Windows. */
|
|
11
|
+
function toPosixPath(dir) {
|
|
12
|
+
return dir.replace(/\\/g, "/");
|
|
13
|
+
}
|
|
14
|
+
function buildServerEntry(codeRoot) {
|
|
15
|
+
return {
|
|
16
|
+
command: "npx",
|
|
17
|
+
args: ["-y", PACKAGE_NAME],
|
|
18
|
+
env: {
|
|
19
|
+
PROXY_URL: "",
|
|
20
|
+
APP_GROUP: "",
|
|
21
|
+
APP_PATH: "",
|
|
22
|
+
MCP_DATA_DIR: "",
|
|
23
|
+
MCP_LOG_DIR: "",
|
|
24
|
+
MCP_DOCUMENTOR_CODE_ROOT: toPosixPath(codeRoot),
|
|
25
|
+
MCP_DOCUMENTOR_OPENAI_API_KEY: "",
|
|
26
|
+
MCP_DOCUMENTOR_OPENAI_MODEL: "text-embedding-3-small",
|
|
27
|
+
MCP_DOCUMENTOR_SYNC_REMOTE: "",
|
|
28
|
+
MCP_DOCUMENTOR_SYNC_BRANCH: "",
|
|
29
|
+
MCP_DOCUMENTOR_SYNC_TOKEN: "",
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const GENERATED_VARS = [
|
|
34
|
+
["PROXY_URL", "URL du proxy pour exposer la GUI"],
|
|
35
|
+
["APP_GROUP", "groupe d'affichage dans le dashboard du proxy"],
|
|
36
|
+
["APP_PATH", "chemin de montage de la GUI derrière le proxy"],
|
|
37
|
+
["MCP_DATA_DIR", "répertoire de données (défaut : celui du package)"],
|
|
38
|
+
["MCP_LOG_DIR", "répertoire des logs"],
|
|
39
|
+
["MCP_DOCUMENTOR_CODE_ROOT", "racine du code (pré-remplie avec le répertoire courant)"],
|
|
40
|
+
["MCP_DOCUMENTOR_OPENAI_API_KEY", "clé OpenAI (active search_docs)"],
|
|
41
|
+
["MCP_DOCUMENTOR_OPENAI_MODEL", "modèle d'embedding"],
|
|
42
|
+
["MCP_DOCUMENTOR_SYNC_REMOTE", "URL HTTPS du repo privé de sync GitHub"],
|
|
43
|
+
["MCP_DOCUMENTOR_SYNC_BRANCH", "branche de sync (défaut : main)"],
|
|
44
|
+
["MCP_DOCUMENTOR_SYNC_TOKEN", "PAT GitHub fine-grained pour la sync"],
|
|
45
|
+
];
|
|
46
|
+
const OPTIONAL_VARS = [
|
|
47
|
+
["MCP_DOCUMENTOR_CODE_ROOTS", 'code roots par projet, ex: {"my-proj":"/srv/my-proj"}'],
|
|
48
|
+
["READ_ONLY", "1/true pour désactiver toutes les écritures"],
|
|
49
|
+
["SYNC_PULL_ON_START", "false pour désactiver le pull au démarrage"],
|
|
50
|
+
];
|
|
51
|
+
export function runSetupMcp({ cwd, force }) {
|
|
52
|
+
const target = path.join(cwd, ".mcp.json");
|
|
53
|
+
let config = {};
|
|
54
|
+
const exists = fs.existsSync(target);
|
|
55
|
+
if (exists) {
|
|
56
|
+
const raw = fs.readFileSync(target, "utf-8").trim();
|
|
57
|
+
if (raw !== "") {
|
|
58
|
+
try {
|
|
59
|
+
config = JSON.parse(raw);
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
console.error(`Erreur : ${target} contient du JSON invalide (${err.message}).`);
|
|
63
|
+
console.error("Corrigez le fichier ou supprimez-le, puis relancez la commande.");
|
|
64
|
+
return 1;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (typeof config !== "object" || config === null || Array.isArray(config)) {
|
|
68
|
+
console.error(`Erreur : ${target} ne contient pas un objet JSON.`);
|
|
69
|
+
return 1;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (typeof config.mcpServers !== "object" || config.mcpServers === null || Array.isArray(config.mcpServers)) {
|
|
73
|
+
config.mcpServers = {};
|
|
74
|
+
}
|
|
75
|
+
const alreadyPresent = Object.prototype.hasOwnProperty.call(config.mcpServers, SERVER_NAME);
|
|
76
|
+
if (alreadyPresent && !force) {
|
|
77
|
+
console.error(`Le serveur "${SERVER_NAME}" est déjà configuré dans ${target}.`);
|
|
78
|
+
console.error("Relancez avec --force pour écraser cette entrée (les autres serveurs sont préservés).");
|
|
79
|
+
return 1;
|
|
80
|
+
}
|
|
81
|
+
config.mcpServers[SERVER_NAME] = buildServerEntry(cwd);
|
|
82
|
+
fs.writeFileSync(target, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
83
|
+
const action = alreadyPresent ? "remplacée" : exists ? "ajoutée" : "créée";
|
|
84
|
+
console.log(`Configuration ${SERVER_NAME} ${action} dans ${target}`);
|
|
85
|
+
console.log("");
|
|
86
|
+
console.log('À compléter dans le champ "env" :');
|
|
87
|
+
for (const [name, description] of GENERATED_VARS) {
|
|
88
|
+
console.log(` ${name.padEnd(30)} ${description}`);
|
|
89
|
+
}
|
|
90
|
+
console.log("");
|
|
91
|
+
console.log("Variables optionnelles à ajouter au besoin :");
|
|
92
|
+
for (const [name, description] of OPTIONAL_VARS) {
|
|
93
|
+
console.log(` ${name.padEnd(30)} ${description}`);
|
|
94
|
+
}
|
|
95
|
+
console.log("");
|
|
96
|
+
console.log("Une variable laissée vide est simplement inactive.");
|
|
97
|
+
return 0;
|
|
98
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Répertoire des logs : MCP_LOG_DIR s'il est renseigné, sinon <racine>/.docs-data/logs.
|
|
3
|
+
* Lu depuis process.env uniquement (le .env du package est chargé après l'init du
|
|
4
|
+
* logger), donc la variable doit venir de la config du client MCP.
|
|
5
|
+
*/
|
|
6
|
+
export declare function resolveLogDir(rootDir: string): string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
/**
|
|
3
|
+
* Répertoire des logs : MCP_LOG_DIR s'il est renseigné, sinon <racine>/.docs-data/logs.
|
|
4
|
+
* Lu depuis process.env uniquement (le .env du package est chargé après l'init du
|
|
5
|
+
* logger), donc la variable doit venir de la config du client MCP.
|
|
6
|
+
*/
|
|
7
|
+
export function resolveLogDir(rootDir) {
|
|
8
|
+
const configured = process.env.MCP_LOG_DIR?.trim();
|
|
9
|
+
if (configured)
|
|
10
|
+
return path.resolve(configured);
|
|
11
|
+
return path.join(rootDir, ".docs-data", "logs");
|
|
12
|
+
}
|
package/dist/src/gui-worker.js
CHANGED
|
@@ -12,6 +12,7 @@ import { promisify } from "util";
|
|
|
12
12
|
const execFileAsync = promisify(execFile);
|
|
13
13
|
import { fileURLToPath } from "url";
|
|
14
14
|
import { createLogger, setupLogging } from "@imenam/mcp-gui-interface";
|
|
15
|
+
import { resolveLogDir } from "./core/log-dir.js";
|
|
15
16
|
import matter from "gray-matter";
|
|
16
17
|
import JSZip from "jszip";
|
|
17
18
|
import puppeteer from "puppeteer-core";
|
|
@@ -31,7 +32,7 @@ const dataDir = process.env.MCP_DATA_DIR?.trim() || path.join(rootDir, ".docs-da
|
|
|
31
32
|
const staticRoot = path.join(rootDir, "gui/dist");
|
|
32
33
|
const absoluteStaticRoot = path.resolve(staticRoot);
|
|
33
34
|
const configuredAppPath = process.env.APP_PATH || "/documentor-gui";
|
|
34
|
-
setupLogging({ processLabel: "mcp-documentor:GUI", logDir:
|
|
35
|
+
setupLogging({ processLabel: "mcp-documentor:GUI", logDir: resolveLogDir(rootDir) });
|
|
35
36
|
const logger = createLogger("mcp-documentor:GUI");
|
|
36
37
|
process.on("uncaughtException", (err) => {
|
|
37
38
|
logger.error(`Uncaught Exception: ${err.message}`);
|
package/dist/src/index.js
CHANGED
|
@@ -8,6 +8,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
8
8
|
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
9
9
|
import { APP_VERSION } from "./version.js";
|
|
10
10
|
import { GuiLauncher, createLogger, setupLogging } from "@imenam/mcp-gui-interface";
|
|
11
|
+
import { resolveLogDir } from "./core/log-dir.js";
|
|
11
12
|
import { StorageEngine } from "./core/storage-engine.js";
|
|
12
13
|
import { EmbeddingStore } from "./core/embedding-store.js";
|
|
13
14
|
import { EmbeddingEngine } from "./core/embedding-engine.js";
|
|
@@ -45,6 +46,12 @@ import { syncStatus, pullDocs, pushDocs, syncDocs, resolveSyncConflict } from ".
|
|
|
45
46
|
import { isReadOnly, WRITE_TOOLS } from "../shared/read-only.js";
|
|
46
47
|
const __filename = fileURLToPath(import.meta.url);
|
|
47
48
|
const __dirname = path.dirname(__filename);
|
|
49
|
+
// Les flags CLI sont traités avant toute initialisation (storage, sqlite, logs) :
|
|
50
|
+
// ils s'exécutent dans le répertoire de l'utilisateur, pas dans un serveur MCP.
|
|
51
|
+
if (process.argv.slice(2).includes("--claude-setup-mcp")) {
|
|
52
|
+
const { runSetupMcp } = await import("./cli/setup-mcp.js");
|
|
53
|
+
process.exit(runSetupMcp({ cwd: process.cwd(), force: process.argv.slice(2).includes("--force") }));
|
|
54
|
+
}
|
|
48
55
|
function findProjectRoot(startDir) {
|
|
49
56
|
let current = startDir;
|
|
50
57
|
while (current !== path.dirname(current)) {
|
|
@@ -57,7 +64,7 @@ function findProjectRoot(startDir) {
|
|
|
57
64
|
}
|
|
58
65
|
const rootDir = findProjectRoot(__dirname);
|
|
59
66
|
const packageEnvPath = path.join(rootDir, ".env");
|
|
60
|
-
setupLogging({ processLabel: "mcp-documentor", logDir:
|
|
67
|
+
setupLogging({ processLabel: "mcp-documentor", logDir: resolveLogDir(rootDir) });
|
|
61
68
|
const logger = createLogger("mcp-documentor");
|
|
62
69
|
function getConfig() {
|
|
63
70
|
if (fs.existsSync(packageEnvPath)) {
|
|
@@ -784,7 +791,7 @@ async function reconnectGui(args) {
|
|
|
784
791
|
};
|
|
785
792
|
}
|
|
786
793
|
return {
|
|
787
|
-
content: [{ type: "text", text:
|
|
794
|
+
content: [{ type: "text", text: `GUI worker started but did not confirm proxy registration within 15s. Check the logs (${resolveLogDir(rootDir)}), then retry.` }],
|
|
788
795
|
isError: true,
|
|
789
796
|
};
|
|
790
797
|
}
|
package/dist/src/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const APP_VERSION = "1.0.
|
|
1
|
+
export declare const APP_VERSION = "1.0.69";
|
package/dist/src/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Auto-generated version file - do not edit manually
|
|
2
|
-
export const APP_VERSION = '1.0.
|
|
2
|
+
export const APP_VERSION = '1.0.69';
|