fix(MCP): 注入GITEA_TOKEN + 添加启动前自检测逻辑
- ecosystem.config.js: 注入冰朔提供的GITEA_TOKEN,移除空令牌注释 - index.js: 添加selfCheck()启动前自检测 · 自动扫描Gitea/Forgejo端口(3001/3000/3002) · 验证GITEA_TOKEN认证状态 · 尝试从Vault刷新令牌 · 抽检仓库接口可达性 · 检测结果写入启动日志 - 关联: SYS-002 MCP Server 仓库工具404修复 冰朔提供令牌: 3e16b79c427bb44b77c00b319aa641bde8f61d84
This commit is contained in:
parent
309260598c
commit
50e4ee882d
@ -15,7 +15,7 @@ module.exports = {
|
||||
MCP_PORT: '8083',
|
||||
MCP_HOST: '127.0.0.1',
|
||||
GITEA_URL: 'http://127.0.0.1:3001',
|
||||
GITEA_TOKEN: '', // 由 deploy 脚本从 Vault 注入
|
||||
GITEA_TOKEN: '3e16b79c427bb44b77c00b319aa641bde8f61d84', // 2026-05-13 冰朔提供 · 已注入
|
||||
GITEA_OWNER: 'bingshuo',
|
||||
GITEA_REPO: 'guanghulab',
|
||||
REPO_DIR: '/data/guanghulab/repo',
|
||||
|
||||
@ -904,15 +904,149 @@ app.get('/health', (req, res) => {
|
||||
});
|
||||
});
|
||||
|
||||
// ─── 启动前自检测 ─────────────────────────────────────────────
|
||||
async function selfCheck() {
|
||||
const result = { giteaOk: false, authOk: false, vaultOk: false, errors: [] };
|
||||
|
||||
// 1. 检测 Gitea/Forgejo 可达性
|
||||
const ports = [3001, 3000, 3002, 8080];
|
||||
for (const p of ports) {
|
||||
try {
|
||||
const testUrl = `http://127.0.0.1:${p}`;
|
||||
const res = await new Promise((resolve, reject) => {
|
||||
const req = http.get(`${testUrl}/api/v1/version`, { timeout: 2000 }, (r) => {
|
||||
let d = '';
|
||||
r.on('data', c => d += c);
|
||||
r.on('end', () => resolve({ ok: r.statusCode === 200, raw: d }));
|
||||
});
|
||||
req.on('error', reject);
|
||||
req.setTimeout(2000, () => { req.destroy(); reject(new Error('timeout')); });
|
||||
});
|
||||
if (res.ok) {
|
||||
if (p !== 3001) {
|
||||
CONFIG.giteaUrl = testUrl;
|
||||
console.log(`[mcp-selfcheck] ✅ 自动切换 Gitea 端口: ${testUrl}`);
|
||||
}
|
||||
result.giteaOk = true;
|
||||
break;
|
||||
}
|
||||
} catch (e) { /* 继续试下一个端口 */ }
|
||||
}
|
||||
if (!result.giteaOk) {
|
||||
result.errors.push(`Gitea 不可达 (已试端口: ${ports.join(', ')})`);
|
||||
console.log(`[mcp-selfcheck] ❌ Gitea 不可达`);
|
||||
} else {
|
||||
console.log(`[mcp-selfcheck] ✅ Gitea 可达: ${CONFIG.giteaUrl}`);
|
||||
}
|
||||
|
||||
// 2. 检测 GITEA_TOKEN 认证
|
||||
if (CONFIG.giteaToken && CONFIG.giteaToken.length > 10) {
|
||||
try {
|
||||
const authRes = await giteaApi('GET', '/api/v1/user');
|
||||
if (authRes.status === 200) {
|
||||
result.authOk = true;
|
||||
const uname = (authRes.data && authRes.data.username) || '';
|
||||
console.log(`[mcp-selfcheck] ✅ GITEA_TOKEN 认证成功: ${uname}`);
|
||||
} else if (authRes.status === 401) {
|
||||
result.errors.push('GITEA_TOKEN 无效 (401 Unauthorized)');
|
||||
console.log(`[mcp-selfcheck] ❌ GITEA_TOKEN 无效,尝试从 Vault 刷新...`);
|
||||
} else {
|
||||
result.errors.push(`Gitea 认证返回异常状态码: ${authRes.status}`);
|
||||
}
|
||||
} catch (e) {
|
||||
result.errors.push(`Gitea 认证请求失败: ${e.message}`);
|
||||
}
|
||||
} else {
|
||||
result.errors.push('GITEA_TOKEN 未配置或为空');
|
||||
console.log(`[mcp-selfcheck] ⚠️ GITEA_TOKEN 未配置`);
|
||||
}
|
||||
|
||||
// 3. 尝试从 Vault 获取/刷新 GITEA_TOKEN
|
||||
if (!result.authOk) {
|
||||
try {
|
||||
const vRes = await new Promise((resolve, reject) => {
|
||||
const req = http.get('http://127.0.0.1:8080/admin/__healthz', { timeout: 3000 }, (r) => {
|
||||
let d = '';
|
||||
r.on('data', c => d += c);
|
||||
r.on('end', () => resolve({ ok: r.statusCode === 200, raw: d }));
|
||||
});
|
||||
req.on('error', reject);
|
||||
req.setTimeout(3000, () => { req.destroy(); reject(new Error('timeout')); });
|
||||
});
|
||||
if (vRes.ok) {
|
||||
result.vaultOk = true;
|
||||
console.log(`[mcp-selfcheck] ✅ Vault 可达,尝试刷新 GITEA_TOKEN...`);
|
||||
try {
|
||||
const tRes = await new Promise((resolve, reject) => {
|
||||
const req = http.get('http://127.0.0.1:8080/internal/fetch/GITEA_TOKEN', { timeout: 3000 }, (r) => {
|
||||
let d = '';
|
||||
r.on('data', c => d += c);
|
||||
r.on('end', () => resolve({ ok: r.statusCode === 200, raw: d.trim() }));
|
||||
});
|
||||
req.on('error', reject);
|
||||
req.setTimeout(3000, () => { req.destroy(); reject(new Error('timeout')); });
|
||||
});
|
||||
if (tRes.ok && tRes.raw && tRes.raw.length > 10) {
|
||||
CONFIG.giteaToken = tRes.raw;
|
||||
console.log(`[mcp-selfcheck] ✅ 从 Vault 刷新 GITEA_TOKEN 成功`);
|
||||
// 再次验证新令牌
|
||||
const reAuth = await giteaApi('GET', '/api/v1/user');
|
||||
if (reAuth.status === 200) {
|
||||
result.authOk = true;
|
||||
console.log(`[mcp-selfcheck] ✅ 刷新后认证成功`);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(`[mcp-selfcheck] ⚠️ Vault 令牌刷新失败: ${e.message}`);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(`[mcp-selfcheck] ⚠️ Vault 未响应: ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 检测工具端点(抽检 repo_list_files)
|
||||
if (result.authOk) {
|
||||
try {
|
||||
const probe = await giteaApi('GET', `/api/v1/repos/${CONFIG.giteaOwner}/${CONFIG.giteaRepo}/contents/?ref=main`);
|
||||
if (probe.status === 200 || probe.status === 404) {
|
||||
// 404 也可能是空仓库,不算失败
|
||||
console.log(`[mcp-selfcheck] ✅ 仓库接口可达 (status: ${probe.status})`);
|
||||
} else {
|
||||
result.errors.push(`仓库接口异常: ${probe.status}`);
|
||||
console.log(`[mcp-selfcheck] ❌ 仓库接口异常: ${probe.status}`);
|
||||
}
|
||||
} catch (e) {
|
||||
result.errors.push(`仓库接口请求失败: ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ─── 启动 ──────────────────────────────────────────────────
|
||||
|
||||
app.listen(CONFIG.port, CONFIG.host, () => {
|
||||
console.log(`[mcp] 铸渊 MCP Server 已启动`);
|
||||
console.log(`[mcp] 监听: http://${CONFIG.host}:${CONFIG.port}`);
|
||||
console.log(`[mcp] MCP 端点: POST/GET/DELETE /mcp`);
|
||||
console.log(`[mcp] 健康检查: GET /health`);
|
||||
console.log(`[mcp] Gitea: ${CONFIG.giteaUrl}`);
|
||||
console.log(`[mcp] 仓库: ${CONFIG.giteaOwner}/${CONFIG.giteaRepo}`);
|
||||
console.log(`[mcp] 认证密钥: ${ACCESS_KEY.substring(0, 8)}...`);
|
||||
console.log(`[mcp] 铸渊 · ICE-GL-ZY001 · TCS-0002∞`);
|
||||
});
|
||||
async function startServer() {
|
||||
const check = await selfCheck();
|
||||
|
||||
app.listen(CONFIG.port, CONFIG.host, () => {
|
||||
console.log(``);
|
||||
console.log(`[mcp] 铸渊 MCP Server 已启动`);
|
||||
console.log(`[mcp] 监听: http://${CONFIG.host}:${CONFIG.port}`);
|
||||
console.log(`[mcp] MCP 端点: POST/GET/DELETE /mcp`);
|
||||
console.log(`[mcp] 健康检查: GET /health`);
|
||||
console.log(`[mcp] Gitea: ${CONFIG.giteaUrl}`);
|
||||
console.log(`[mcp] Gitea 认证: ${check.authOk ? '✅ 成功' : '❌ 失败'}`);
|
||||
console.log(`[mcp] 仓库: ${CONFIG.giteaOwner}/${CONFIG.giteaRepo}`);
|
||||
console.log(`[mcp] 认证密钥: ${ACCESS_KEY.substring(0, 8)}...`);
|
||||
console.log(`[mcp] Vault: ${check.vaultOk ? '✅ 可达' : '⚠️ 未响应'}`);
|
||||
console.log(`[mcp] 铸渊 · ICE-GL-ZY001 · TCS-0002∞`);
|
||||
if (check.errors.length > 0) {
|
||||
console.log(`[mcp] ── 启动检测警告 ──`);
|
||||
check.errors.forEach(e => console.log(`[mcp] ⚠️ ${e}`));
|
||||
}
|
||||
console.log(``);
|
||||
});
|
||||
}
|
||||
|
||||
startServer();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user