From 953b79173b22d0bb40eefbb494f9a21dfecb4975 Mon Sep 17 00:00:00 2001 From: bingshuo <565183519@qq.com> Date: Thu, 14 May 2026 01:37:24 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=80=20repo-mcp-server:=20=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=88=86=E6=94=AF=E6=94=B9=E4=B8=BA=20notion/shuangya?= =?UTF-8?q?n=EF=BC=88Notion=E4=BA=BA=E6=A0=BC=E4=BD=93=E4=B8=93=E5=B1=9E?= =?UTF-8?q?=E5=88=86=E6=94=AF=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mcp-servers/repo-mcp-server/index.js | 33 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/mcp-servers/repo-mcp-server/index.js b/mcp-servers/repo-mcp-server/index.js index a29533a..9d5fd69 100644 --- a/mcp-servers/repo-mcp-server/index.js +++ b/mcp-servers/repo-mcp-server/index.js @@ -29,6 +29,7 @@ const GITEA_TOKEN = process.env.GITEA_TOKEN; const GITEA_URL = process.env.GITEA_URL || 'https://guanghulab.com'; const REPO_OWNER = process.env.REPO_OWNER || 'bingshuo'; const REPO_NAME = process.env.REPO_NAME || 'guanghulab'; +const DEFAULT_BRANCH = process.env.REPO_DEFAULT_BRANCH || 'notion/shuangyan'; // Notion 人格体专属分支 // ─── 常量时间比较(防时序攻击) ─── function safeCompare(a, b) { @@ -92,9 +93,9 @@ function registerTools(server) { server.tool( 'repo_read', '读取仓库文件内容', - { path: z.string().describe('文件路径,如 brain/progress.json'), branch: z.string().optional().describe('分支,默认 main') }, + { path: z.string().describe('文件路径,如 brain/progress.json'), branch: z.string().optional().describe('分支,默认 notion/shuangyan') }, async ({ path, branch }) => { - const data = await repoFetch(`/contents/${encodeURIComponent(path)}?ref=${branch || 'main'}`); + const data = await repoFetch(`/contents/${encodeURIComponent(path)}?ref=${branch || DEFAULT_BRANCH}`); if (data.error) return { content: [{ type: 'text', text: `❌ 读取失败: ${data.message}` }] }; const content = Buffer.from(data.content, 'base64').toString('utf-8'); return { content: [{ type: 'text', text: content }] }; @@ -109,10 +110,10 @@ function registerTools(server) { path: z.string().describe('文件路径'), content: z.string().describe('文件内容'), message: z.string().describe('提交信息'), - branch: z.string().optional().describe('目标分支,默认 main') + branch: z.string().optional().describe('目标分支,默认 notion/shuangyan') }, async ({ path, content, message, branch }) => { - const ref = branch || 'main'; + const ref = branch || DEFAULT_BRANCH; let sha = null; const existing = await repoFetch(`/contents/${encodeURIComponent(path)}?ref=${ref}`); if (!existing.error) sha = existing.sha; @@ -136,10 +137,10 @@ function registerTools(server) { { path: z.string().describe('文件路径'), message: z.string().describe('提交信息'), - branch: z.string().optional().describe('分支,默认 main') + branch: z.string().optional().describe('分支,默认 notion/shuangyan') }, async ({ path, message, branch }) => { - const ref = branch || 'main'; + const ref = branch || DEFAULT_BRANCH; const existing = await repoFetch(`/contents/${encodeURIComponent(path)}?ref=${ref}`); if (existing.error) return { content: [{ type: 'text', text: `❌ 文件不存在: ${path}` }] }; @@ -156,11 +157,11 @@ function registerTools(server) { server.tool( 'repo_list', '列出仓库目录内容', - { path: z.string().optional().describe('目录路径,默认根目录'), branch: z.string().optional().describe('分支,默认 main') }, + { path: z.string().optional().describe('目录路径,默认根目录'), branch: z.string().optional().describe('分支,默认 notion/shuangyan') }, async ({ path, branch }) => { const dir = path || ''; const urlPath = dir ? `/contents/${encodeURIComponent(dir)}` : '/contents'; - const data = await repoFetch(`${urlPath}?ref=${branch || 'main'}`); + const data = await repoFetch(`${urlPath}?ref=${branch || DEFAULT_BRANCH}`); if (data.error) return { content: [{ type: 'text', text: `❌ 列出失败: ${data.message}` }] }; if (!Array.isArray(data)) { return { content: [{ type: 'text', text: `📄 ${dir || '/'} 是一个文件,请用 repo_read 读取` }] }; @@ -236,12 +237,12 @@ function registerTools(server) { title: z.string().describe('PR 标题'), body: z.string().optional().describe('PR 描述'), head: z.string().describe('源分支'), - base: z.string().optional().describe('目标分支,默认 main') + base: z.string().optional().describe('目标分支,默认 notion/shuangyan') }, async ({ title, body, head, base }) => { const result = await repoFetch('/pulls', { method: 'POST', - body: JSON.stringify({ title, body: body || '', head, base: base || 'main' }) + body: JSON.stringify({ title, body: body || '', head, base: base || DEFAULT_BRANCH }) }); if (result.error) return { content: [{ type: 'text', text: `❌ 创建 PR 失败: ${result.message}` }] }; return { @@ -325,12 +326,12 @@ function registerTools(server) { '查看最近提交历史', { limit: z.number().optional().describe('数量,默认 10'), - branch: z.string().optional().describe('分支,默认 main') + branch: z.string().optional().describe('分支,默认 notion/shuangyan') }, async ({ limit, branch }) => { - const data = await repoFetch(`/commits?sha=${branch || 'main'}&limit=${limit || 10}`); + const data = await repoFetch(`/commits?sha=${branch || DEFAULT_BRANCH}&limit=${limit || 10}`); if (data.error) return { content: [{ type: 'text', text: `❌ 获取提交历史失败: ${data.message}` }] }; - let output = `📜 最近提交 (${branch || 'main'}):\n\n`; + let output = `📜 最近提交 (${branch || DEFAULT_BRANCH}):\n\n`; for (const c of data) { const date = c.commit?.committer?.date?.slice(0, 10) || ''; const msg = (c.commit?.message || '').split('\n')[0]; @@ -346,13 +347,13 @@ function registerTools(server) { '递归列出目录结构(探索仓库骨架)', { path: z.string().optional().describe('起始路径,默认 brain'), - branch: z.string().optional().describe('分支,默认 main'), + branch: z.string().optional().describe('分支,默认 notion/shuangyan'), depth: z.number().optional().describe('递归深度,默认 2,最大 4') }, async ({ path, branch, depth }) => { const startPath = path || 'brain'; const maxDepth = Math.min(depth || 2, 4); - const ref = branch || 'main'; + const ref = branch || DEFAULT_BRANCH; async function walk(dirPath, currentDepth) { if (currentDepth > maxDepth) return ''; @@ -425,4 +426,4 @@ app.listen(PORT, () => { console.log(`健康: http://localhost:${PORT}/health`); console.log(`MCP: POST http://localhost:${PORT}/mcp`); console.log(`认证: ${MCP_SECRET ? '✅ Bearer Token' : '⚠️ 本地模式(仅127.0.0.1)'}`); -}); \ No newline at end of file +});