mn-docs-mcp 0.2.2 → 0.2.4
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/mcp/cli.mjs +18 -2
- package/mcp/lib.mjs +48 -2
- package/package.json +1 -1
package/mcp/cli.mjs
CHANGED
|
@@ -11,6 +11,7 @@ let port;
|
|
|
11
11
|
let prebuild = false;
|
|
12
12
|
let silent = false;
|
|
13
13
|
let root;
|
|
14
|
+
let resolvedRoot;
|
|
14
15
|
|
|
15
16
|
for (let i = 0; i < args.length; i += 1) {
|
|
16
17
|
const arg = args[i];
|
|
@@ -78,12 +79,27 @@ try {
|
|
|
78
79
|
version = JSON.parse(raw).version || version;
|
|
79
80
|
} catch {}
|
|
80
81
|
|
|
82
|
+
function hasDocsDir(base) {
|
|
83
|
+
try {
|
|
84
|
+
const docsPath = path.join(base, 'src', 'content', 'docs');
|
|
85
|
+
return fs.existsSync(docsPath);
|
|
86
|
+
} catch {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (root) {
|
|
92
|
+
resolvedRoot = root;
|
|
93
|
+
} else if (hasDocsDir(process.cwd())) {
|
|
94
|
+
resolvedRoot = process.cwd();
|
|
95
|
+
}
|
|
96
|
+
|
|
81
97
|
if (mode === 'stdio') {
|
|
82
98
|
process.env.MCP_STDIO = '1';
|
|
83
99
|
process.env.MCP_SILENT = silent ? '1' : '0';
|
|
84
100
|
process.env.MN_DOCS_VERSION = version;
|
|
85
101
|
process.env.MN_DOCS_MODE = 'stdio';
|
|
86
|
-
|
|
102
|
+
if (resolvedRoot) process.env.MN_DOCS_ROOT = resolvedRoot;
|
|
87
103
|
if (prebuild) process.env.MCP_PREBUILD = '1';
|
|
88
104
|
await import('./server.mjs');
|
|
89
105
|
} else {
|
|
@@ -91,7 +107,7 @@ if (mode === 'stdio') {
|
|
|
91
107
|
process.env.MN_DOCS_VERSION = version;
|
|
92
108
|
process.env.MN_DOCS_MODE = 'http';
|
|
93
109
|
if (port) process.env.MN_DOCS_PORT = String(port);
|
|
94
|
-
|
|
110
|
+
if (resolvedRoot) process.env.MN_DOCS_ROOT = resolvedRoot;
|
|
95
111
|
if (prebuild) process.env.MCP_PREBUILD = '1';
|
|
96
112
|
await import('./server-http.mjs');
|
|
97
113
|
}
|
package/mcp/lib.mjs
CHANGED
|
@@ -14,7 +14,7 @@ const DEFAULT_ROOT = path.resolve(__dirname, '..');
|
|
|
14
14
|
|
|
15
15
|
function resolveRootDir() {
|
|
16
16
|
const envRoot = (process.env.MN_DOCS_ROOT || '').trim();
|
|
17
|
-
if (envRoot) return envRoot;
|
|
17
|
+
if (envRoot && fsSyncExists(path.join(envRoot, 'src', 'content', 'docs'))) return envRoot;
|
|
18
18
|
const cwd = process.cwd();
|
|
19
19
|
const docsFromCwd = path.join(cwd, 'src', 'content', 'docs');
|
|
20
20
|
try {
|
|
@@ -43,6 +43,8 @@ let proxyInitialized = false;
|
|
|
43
43
|
const MAX_EXTRACTOR_RETRIES = 3;
|
|
44
44
|
const IS_STDIO = process.env.MCP_STDIO === '1';
|
|
45
45
|
const IS_SILENT = process.env.MCP_SILENT === '1';
|
|
46
|
+
const NO_COLOR = process.env.MCP_NO_COLOR === '1';
|
|
47
|
+
let lastDownloadProgress = -1;
|
|
46
48
|
|
|
47
49
|
function logInfo(message) {
|
|
48
50
|
if (IS_SILENT) return;
|
|
@@ -53,6 +55,47 @@ function logInfo(message) {
|
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
57
|
|
|
58
|
+
function color(text, code) {
|
|
59
|
+
if (NO_COLOR) return text;
|
|
60
|
+
return `\x1b[${code}m${text}\x1b[0m`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function formatBytes(bytes) {
|
|
64
|
+
if (!Number.isFinite(bytes)) return '';
|
|
65
|
+
const units = ['B', 'KB', 'MB', 'GB'];
|
|
66
|
+
let idx = 0;
|
|
67
|
+
let value = bytes;
|
|
68
|
+
while (value >= 1024 && idx < units.length - 1) {
|
|
69
|
+
value /= 1024;
|
|
70
|
+
idx += 1;
|
|
71
|
+
}
|
|
72
|
+
return `${value.toFixed(1)}${units[idx]}`;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function logDownloadProgress(info) {
|
|
76
|
+
if (IS_SILENT) return;
|
|
77
|
+
if (info?.status === 'download') {
|
|
78
|
+
logInfo(color('开始下载模型...', '38;5;45'));
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (info?.status === 'progress' && typeof info.progress === 'number') {
|
|
82
|
+
const pct = Math.max(0, Math.min(100, Math.round(info.progress)));
|
|
83
|
+
if (pct === lastDownloadProgress) return;
|
|
84
|
+
lastDownloadProgress = pct;
|
|
85
|
+
const loaded = formatBytes(info.loaded);
|
|
86
|
+
const total = formatBytes(info.total);
|
|
87
|
+
const suffix = loaded && total ? ` ${loaded}/${total}` : '';
|
|
88
|
+
const line = `${color('模型下载进度', '38;5;45')}: ${pct}%${suffix}`;
|
|
89
|
+
if (IS_STDIO) {
|
|
90
|
+
process.stderr.write(`\r${line}`);
|
|
91
|
+
if (pct === 100) process.stderr.write('\n');
|
|
92
|
+
} else {
|
|
93
|
+
process.stdout.write(`\r${line}`);
|
|
94
|
+
if (pct === 100) process.stdout.write('\n');
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
56
99
|
function loadEnv() {
|
|
57
100
|
dotenv.config({ path: path.join(ROOT_DIR, '.env') });
|
|
58
101
|
}
|
|
@@ -81,7 +124,10 @@ async function getExtractor() {
|
|
|
81
124
|
}
|
|
82
125
|
|
|
83
126
|
const modelDir = path.join(env.cacheDir, 'Xenova', 'bge-small-zh-v1.5');
|
|
84
|
-
const create = async () =>
|
|
127
|
+
const create = async () =>
|
|
128
|
+
pipeline('feature-extraction', MODEL_ID, {
|
|
129
|
+
progress_callback: logDownloadProgress,
|
|
130
|
+
});
|
|
85
131
|
|
|
86
132
|
extractorPromise = (async () => {
|
|
87
133
|
for (let attempt = 1; attempt <= MAX_EXTRACTOR_RETRIES; attempt += 1) {
|