@dependfix/mcp 0.2.0 → 0.3.0

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.en-US.md CHANGED
@@ -16,12 +16,13 @@ pnpm add @dependfix/mcp
16
16
  | Tool | Function | Inputs |
17
17
  |:-----||:---------|:-------|
18
18
  | `fetch_alerts` | Fetch Dependabot security alerts for specified repo (optionally parallel Code Scanning, read-only) | `repo`, `severity?`, `code_scanning?` |
19
- | `discover_repos` | Auto-discover repos by owner / org (read-only) | `owner[]`, `topics?`, `include?`, `exclude?`, `probe_dependabot?` |
19
+ | `discover_repos` | Auto-discover repos by owner / org (read-only) | `owner[]`, `topics?`, `include?`, `exclude?`, `probe_dependabot?`, `max_repos?` |
20
20
  | `run_scan` | Run dependfix scan and fix on target repo | `repo`, `mode?`, `severity?`, `code_scanning?`, `max_alerts?`, `max_concurrency?`, `dry_run?`, `allow_major_upgrade?`, `ai_enabled?`, `ai_provider?`, `ai_model?`, `ai_trigger?` |
21
21
  | `fix_dependency` | Fix single dependency or lockfile (override / direct / lockfile) | `workDir`, `fix_type?`, `packageName?`, `targetVersion?` |
22
22
  | `cleanup_branches` | Clean up merged/closed dependfix branches (non-interactive) | `repo`, `dry_run?` |
23
23
  | `history` | Query history run summary for specified repo (read-only) | `repo` |
24
24
  | `get_last_report` | Read most recent JSON report (read-only) | — |
25
+ | `pnpm_audit` | Local pnpm audit fallback data source (reuses the `GITHUB_TOKEN` check; audit failures return a hard error) | `workDir`, `repository` |
25
26
 
26
27
  Parameter semantics align with CLI (severity is threshold semantics: `high` keeps critical + high; `dry_run` defaults inferred from mode; AI params only pass through switch and model, apiKey read from env var).
27
28
 
@@ -47,7 +48,7 @@ Environment variables:
47
48
 
48
49
  | Variable | Description |
49
50
  |:---------|:------------|
50
- | `GITHUB_TOKEN` | GitHub access credential (required for fetching alerts / running scans / branch cleanup) |
51
+ | `GITHUB_TOKEN` | GitHub access credential (required for fetching alerts / running scans / branch cleanup / `pnpm_audit`) |
51
52
  | `DEPENDFIX_MCP_REPORT_DIR` | JSON report output dir (default `./dependfix-reports`) |
52
53
  | `DEPENDFIX_AI_API_KEY` | AI assessment API Key (required when `run_scan` `ai_enabled` enabled; only via env var, never via tool params) |
53
54
 
package/README.md CHANGED
@@ -16,12 +16,13 @@ pnpm add @dependfix/mcp
16
16
  | Tool | 功能 | 输入 |
17
17
  |:-----|:-----|:-----|
18
18
  | `fetch_alerts` | 拉取指定仓库的 Dependabot 安全告警(可选并行 Code Scanning,只读) | `repo`, `severity?`, `code_scanning?` |
19
- | `discover_repos` | 按 owner / org 自动发现仓库(只读) | `owner[]`, `topics?`, `include?`, `exclude?`, `probe_dependabot?` |
19
+ | `discover_repos` | 按 owner / org 自动发现仓库(只读) | `owner[]`, `topics?`, `include?`, `exclude?`, `probe_dependabot?`, `max_repos?` |
20
20
  | `run_scan` | 对目标仓库执行 dependfix 扫描并修复 | `repo`, `mode?`, `severity?`, `code_scanning?`, `max_alerts?`, `max_concurrency?`, `dry_run?`, `allow_major_upgrade?`, `ai_enabled?`, `ai_provider?`, `ai_model?`, `ai_trigger?` |
21
21
  | `fix_dependency` | 修复单个依赖或 lockfile(override / direct / lockfile) | `workDir`, `fix_type?`, `packageName?`, `targetVersion?` |
22
22
  | `cleanup_branches` | 清理已合并/已关闭的 dependfix 分支(非交互) | `repo`, `dry_run?` |
23
23
  | `history` | 查询指定仓库的历史运行摘要(只读) | `repo` |
24
24
  | `get_last_report` | 读取最近一次 JSON 报告(只读) | — |
25
+ | `pnpm_audit` | 本地 pnpm audit 回退数据源(复用 `GITHUB_TOKEN` 检查;audit 失败硬返回错误) | `workDir`, `repository` |
25
26
 
26
27
  参数语义与 CLI 对齐(severity 为阈值语义:`high` 保留 critical + high;`dry_run` 缺省按 mode 推断;AI 参数仅透传开关与模型,apiKey 从环境变量读取)。
27
28
 
@@ -47,7 +48,7 @@ pnpm add @dependfix/mcp
47
48
 
48
49
  | 变量 | 说明 |
49
50
  |:-----|:-----|
50
- | `GITHUB_TOKEN` | GitHub 访问凭据(拉取告警 / 执行扫描 / 分支清理必需) |
51
+ | `GITHUB_TOKEN` | GitHub 访问凭据(拉取告警 / 执行扫描 / 分支清理 / `pnpm_audit` 必需) |
51
52
  | `DEPENDFIX_MCP_REPORT_DIR` | JSON 报告输出目录(默认 `./dependfix-reports`) |
52
53
  | `DEPENDFIX_AI_API_KEY` | AI 研判 API Key(启用 `run_scan` 的 `ai_enabled` 时必需;仅经 env 读取,禁止经 tool 参数传入) |
53
54
 
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  //#region src/index.d.ts
3
3
  /**
4
- * dependfix MCP Server:向 AI 助手暴露 7 个 tool。
4
+ * dependfix MCP Server:向 AI 助手暴露 8 个 tool。
5
5
  * - fetch_alerts(只读):拉取 Dependabot / Code Scanning 告警
6
6
  * - get_last_report(只读):读取最近 JSON 报告
7
7
  * - run_scan(写入):执行扫描/修复(默认 report-only;支持 AI 研判透传)
@@ -9,6 +9,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
9
9
  * - discover_repos(只读):按 owner / org 自动发现仓库
10
10
  * - cleanup_branches(写入):清理已合并/已关闭的 dependfix 分支(非交互)
11
11
  * - history(只读):查询仓库历史运行摘要
12
+ * - pnpm_audit(只读):本地 pnpm audit 回退数据源
12
13
  * 凭据从 GITHUB_TOKEN 环境变量读取(mcp-server.md §4.3)。
13
14
  */
14
15
  export declare const createMcpServer: () => McpServer;
package/dist/src.mjs CHANGED
@@ -254,7 +254,7 @@ const fixDependency = async (input) => {
254
254
  try {
255
255
  switch (fixType) {
256
256
  case "lockfile": {
257
- const result = repairLockfile({ workDir: input.workDir });
257
+ const result = await repairLockfile({ workDir: input.workDir });
258
258
  if (result.success) return {
259
259
  ok: true,
260
260
  fixType: "lockfile",
@@ -519,7 +519,7 @@ const pnpmAudit = async (input) => {
519
519
  //#endregion
520
520
  //#region src/index.ts
521
521
  /**
522
- * dependfix MCP Server:向 AI 助手暴露 7 个 tool。
522
+ * dependfix MCP Server:向 AI 助手暴露 8 个 tool。
523
523
  * - fetch_alerts(只读):拉取 Dependabot / Code Scanning 告警
524
524
  * - get_last_report(只读):读取最近 JSON 报告
525
525
  * - run_scan(写入):执行扫描/修复(默认 report-only;支持 AI 研判透传)
@@ -527,6 +527,7 @@ const pnpmAudit = async (input) => {
527
527
  * - discover_repos(只读):按 owner / org 自动发现仓库
528
528
  * - cleanup_branches(写入):清理已合并/已关闭的 dependfix 分支(非交互)
529
529
  * - history(只读):查询仓库历史运行摘要
530
+ * - pnpm_audit(只读):本地 pnpm audit 回退数据源
530
531
  * 凭据从 GITHUB_TOKEN 环境变量读取(mcp-server.md §4.3)。
531
532
  */
532
533
  const createMcpServer = () => {
@@ -605,7 +606,7 @@ const createMcpServer = () => {
605
606
  }] };
606
607
  });
607
608
  server.registerTool("pnpm_audit", {
608
- description: "本地 pnpm audit 回退数据源(无需 GitHub token;audit 失败硬返回错误)",
609
+ description: "本地 pnpm audit 回退数据源(复用 GITHUB_TOKEN 检查;audit 失败硬返回错误)",
609
610
  inputSchema: pnpmAuditSchema
610
611
  }, async (input) => {
611
612
  const result = await pnpmAudit(input);
package/dist/src.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"src.mjs","names":[],"sources":["../src/tools/schemas.ts","../src/tools/errors.ts","../src/tools/fetch-alerts.ts","../src/tools/get-last-report.ts","../src/tools/run-scan.ts","../src/tools/fix-dependency.ts","../src/tools/discover-repos.ts","../src/tools/cleanup-branches.ts","../src/tools/history.ts","../src/tools/pnpm-audit.tool.ts","../src/index.ts"],"sourcesContent":["import { z } from 'zod'\nimport { RUNTIME_MODES, SEVERITY_THRESHOLDS } from '@dependfix/engine'\n\n// run_scan 的 mode 子集:排除 cleanup-branches(由独立 cleanup_branches tool 承担;\n// DependfixApp 的该 mode 走交互确认,MCP stdio 不可用——见 mcp-server.md §8.3)。\n// 从 cli RUNTIME_MODES 派生(filter 跟随 cli 演进),非独立硬编码。\n// as unknown 桥接:filter 返回数组类型,z.enum 需要 readonly 元组。\nconst RUN_SCAN_MODES = RUNTIME_MODES.filter((m) => m !== 'cleanup-branches') as unknown as readonly ['report-only', 'fix', 'fix-and-pr']\n\n/** `fetch_alerts` 输入:拉取指定仓库的安全告警(Dependabot + 可选 Code Scanning) */\nexport const fetchAlertsSchema = z.object({\n repo: z.string().describe('目标仓库,格式 owner/repo'),\n severity: z.enum(SEVERITY_THRESHOLDS).default('high').describe('严重级别阈值(high 保留 critical + high,与 CLI 一致)'),\n code_scanning: z.boolean().optional().describe('同时拉取 Code Scanning 告警(与 Dependabot 并行;需要 token 具备 security-events: read)'),\n})\n\n/** `get_last_report` 输入:读取最近一次 JSON 报告 */\nexport const getLastReportSchema = z.object({})\n\n/** `run_scan` 输入:对目标仓库执行 dependfix 扫描并修复 */\nexport const runScanSchema = z.object({\n repo: z.string().describe('目标仓库,格式 owner/repo'),\n mode: z.enum(RUN_SCAN_MODES).default('report-only').describe('执行模式(默认仅报告)'),\n severity: z.enum(SEVERITY_THRESHOLDS).default('high').describe('严重级别阈值'),\n code_scanning: z.boolean().optional().describe('同时拉取 Code Scanning 告警(默认 false)'),\n max_alerts: z.number().int().min(1).max(1000).optional().describe('每仓库最多处理的告警数(默认 20)'),\n max_concurrency: z.number().int().min(1).max(16).optional().describe('多仓库并发窗口(默认 1 保守串行)'),\n dry_run: z.boolean().optional().describe('试运行不实际写入;缺省按 mode 推断(report-only 为 true)。与 mode=fix/fix-and-pr 互斥(会返回配置校验错误)'),\n allow_major_upgrade: z.boolean().optional().describe('跨线 major 升级显式授权(默认 false;仅根直接依赖 + lockfile 单版本,强制完整验证)'),\n ai_enabled: z.boolean().optional().describe('开启 AI breaking change 研判(默认 false;apiKey 从 DEPENDFIX_AI_API_KEY env 读取,禁止经 tool 参数传入)'),\n ai_provider: z.enum(['openai-compatible', 'anthropic']).optional().describe('AI 提供商(默认 openai-compatible)'),\n ai_model: z.string().optional().describe('AI 模型名(默认 deepseek-v4-flash)'),\n ai_trigger: z.enum(['failure', 'major', 'both']).optional().describe('AI 触发范围(默认 both)'),\n})\n\n/** `fix_dependency` 输入:修复单个依赖(多修复类型) */\nexport const fixDependencySchema = z.object({\n /** 本地仓库路径(已 clone 的目录,含 package.json/pnpm-lock.yaml) */\n workDir: z.string().describe('本地仓库工作目录(已 clone,包含 package.json 与 pnpm-lock.yaml)'),\n /** 修复类型:override(间接依赖 overrides)/ direct(直接依赖升级)/ lockfile(frozen-lockfile 漂移修复) */\n fix_type: z.enum(['override', 'direct', 'lockfile']).default('override').describe('修复类型(默认 override)'),\n /** override / direct 必填 */\n packageName: z.string().optional().describe('依赖包名(fix_type=override/direct 必填)'),\n /** override / direct 必填 */\n targetVersion: z.string().optional().describe('目标精确版本,如 4.17.21(fix_type=override/direct 必填)'),\n})\n\n/** `discover_repos` 输入:按 owner / org 自动发现仓库 */\nexport const discoverReposSchema = z.object({\n owner: z.array(z.string()).min(1).describe('owner / org 列表(分别发现后合并)'),\n topics: z.array(z.string()).optional().describe('topic 白名单(AND 语义:必须包含全部指定 topics)'),\n include: z.array(z.string()).optional().describe('仓库白名单 glob(如 owner/*、owner/pkg-*)'),\n exclude: z.array(z.string()).optional().describe('仓库黑名单 glob(与 include 冲突时胜出)'),\n probe_dependabot: z.boolean().optional().describe('探测 .github/dependabot.yml 存在性(默认 true;会额外触达 contents API)'),\n max_repos: z.number().int().min(0).optional().describe('发现规模上限:最多保留的仓库数(默认 100;0 表示不限制)'),\n})\n\n/** `cleanup_branches` 输入:清理已合并/已关闭的 dependfix 分支 */\nexport const cleanupBranchesSchema = z.object({\n repo: z.string().describe('目标仓库,格式 owner/repo'),\n dry_run: z.boolean().optional().describe('仅列出待清理分支,不执行删除(默认 false)'),\n})\n\n/** `history` 输入:查询仓库历史运行摘要 */\nexport const historySchema = z.object({\n repo: z.string().describe('目标仓库,格式 owner/repo'),\n})\n\n/** `pnpm_audit` 输入:本地 pnpm audit 回退数据源 */\nexport const pnpmAuditSchema = z.object({\n /** 本地仓库工作目录(已 clone,包含 pnpm-lock.yaml) */\n workDir: z.string().describe('本地仓库工作目录(已 clone,包含 pnpm-lock.yaml)'),\n /** 仓库标识(owner/repo 或 local 兜底;与 CLI --repo 同源语义) */\n repository: z.string().describe('仓库标识(owner/repo 或 local 兜底;用于归一化 NormalizedSecurityAlert.repository 字段)'),\n})\n","// 统一 tool 错误模板(复用收口):\n// - requireToken:GITHUB_TOKEN 检查。返回 token 字符串或错误对象;\n// 调用方用 `typeof token !== 'string'` 守卫收窄(项目未开 strictNullChecks,\n// truthiness 判别收窄不生效,typeof 守卫是兼容形式)。\n// - toToolError:任意错误 → ok:false(统一 Error.message / String 转换)\n// 各 tool 的返回联合类型均含 `{ ok: false, error: string }` 分支,可安全返回。\n\nexport type ToolError = { ok: false, error: string }\n\nexport const requireToken = (): string | ToolError => {\n const token = process.env.GITHUB_TOKEN\n if (!token) {\n return { ok: false, error: 'GITHUB_TOKEN not set(请配置环境变量)' }\n }\n return token\n}\n\nexport const toToolError = (error: unknown): ToolError => ({\n ok: false,\n error: error instanceof Error ? error.message : String(error),\n})\n","import { createGitHubClient, fetchCodeScanningAlerts, fetchDependabotAlerts, type FetchDependabotAlertsParams } from '@dependfix/engine'\nimport { fromPat } from '@dependfix/engine/auth'\nimport { filterAlerts, isValidRepoIdentifier, type SeverityThreshold } from '@dependfix/core'\nimport { requireToken, toToolError } from './errors'\n\n/** `fetch_alerts` 返回结构 */\nexport type FetchAlertsResult =\n | {\n ok: true\n count: number\n alerts: Array<{\n id: number\n severity: string\n packageName: string\n manifestPath: string\n recommendedVersion: string\n fixable: boolean\n htmlUrl: string\n summary: string\n }>\n }\n | { ok: false, error: string }\n\n/**\n * `fetch_alerts`:拉取指定仓库的 Dependabot 安全告警(只读)。\n * 凭据从 GITHUB_TOKEN 环境变量读取(mcp-server.md §4.3)。\n */\nexport const fetchAlerts = async (input: { repo: string, severity: SeverityThreshold, code_scanning?: boolean }): Promise<FetchAlertsResult> => {\n const token = requireToken()\n if (typeof token !== 'string') {\n return token\n }\n\n // repo 格式校验复用 core(与 CLI 同源,避免自研校验漂移)\n if (!isValidRepoIdentifier(input.repo)) {\n return { ok: false, error: `repo 格式非法(预期 owner/repo,收到 ${input.repo})` }\n }\n const [owner, repo] = input.repo.split('/')\n\n try {\n const client = createGitHubClient({ auth: fromPat(token) })\n const params: FetchDependabotAlertsParams = {\n owner,\n repo,\n state: 'open',\n }\n\n // Dependabot + 可选 Code Scanning 并行(复用 cli fetcher;与 CLI --code-scanning 同源)。\n // 注意:CS 拉取失败(权限/网络)会使整个 tool 失败——与 CLI 现状一致\n // (per-source 错误隔离为 backlog 登记项,暂缓),结果不静默丢弃。\n const codeScanningEnabled = input.code_scanning ?? false\n const [dependabotAlerts, codeScanningAlerts] = await Promise.all([\n fetchDependabotAlerts(client, params),\n codeScanningEnabled\n ? fetchCodeScanningAlerts(client, { owner, repo })\n : Promise.resolve([] as Awaited<ReturnType<typeof fetchDependabotAlerts>>),\n ])\n const alerts = [...dependabotAlerts, ...codeScanningAlerts]\n\n // 严重级别过滤复用 core 阈值语义(与 CLI 一致:high 保留 critical + high;\n // all 不过滤;Code Scanning 源 unknown 恒透传)。不使用相等匹配,避免 high 漏掉 critical。\n const { filtered } = filterAlerts(alerts, { severityThreshold: input.severity })\n\n return {\n ok: true,\n count: filtered.length,\n alerts: filtered.map((a) => ({\n id: a.id,\n severity: a.severity,\n packageName: a.packageName,\n manifestPath: a.manifestPath,\n recommendedVersion: a.recommendedVersion,\n fixable: a.fixable,\n htmlUrl: a.htmlUrl,\n summary: a.summary,\n })),\n }\n } catch (error) {\n return toToolError(error)\n }\n}\n","import { readFileSync, readdirSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { toToolError } from './errors'\n\n/** `get_last_report` 返回结构 */\nexport type GetLastReportResult =\n | { ok: true, file: string, report: unknown }\n | { ok: false, error: string }\n\n/**\n * `get_last_report`:读取最近一次 JSON 报告(只读)。\n * 报告目录默认为 `./dependfix-reports`(可用 `DEPENDFIX_MCP_REPORT_DIR` 覆盖)。\n */\nexport const getLastReport = async (): Promise<GetLastReportResult> => {\n const reportDir = process.env.DEPENDFIX_MCP_REPORT_DIR ?? './dependfix-reports'\n try {\n const files = readdirSync(reportDir)\n .filter((f) => f.endsWith('.json'))\n .sort()\n if (files.length === 0) {\n return { ok: false, error: `未找到报告(目录 ${reportDir} 为空)` }\n }\n const latest = files[files.length - 1]\n const content = readFileSync(join(reportDir, latest), 'utf-8')\n return {\n ok: true,\n file: latest,\n report: JSON.parse(content),\n }\n } catch (error) {\n return toToolError(error)\n }\n}\n","import { DependfixApp, DEFAULT_RUNTIME_CONFIG, type RuntimeConfig } from '@dependfix/engine'\nimport { isValidRepoIdentifier } from '@dependfix/core'\nimport { requireToken, toToolError } from './errors'\n\n/** `run_scan` 返回结构(M28.4 RunResult 对齐 + 向后兼容)\n *\n * 字段对齐 `RunResult` 接口(packages/core/src/report/types.ts):\n * - 8 字段保留(向后兼容——老客户端忽略未知字段):\n * ok / exitCode / runId / summary / repositories / errors\n * - 5 字段新增(M28.4 RunResult 对齐):\n * startedAt / finishedAt / config / alerts / actions\n *\n * 2 字段可选(按 --ai 开启 + 供应链信号决定;不在 RunScanResult 必填):\n * aiUsage? / supplyChainWarnings?(暂不映射——避免 RunScanResult 类型膨胀)\n */\nexport type RunScanResult =\n | {\n ok: true\n exitCode: number\n runId: string\n summary: import('@dependfix/core').RunSummary\n repositories: Array<Record<string, unknown>>\n errors: Array<Record<string, unknown>>\n /** RunResult.startedAt:ISO 8601 字符串 */\n startedAt: string\n /** RunResult.finishedAt:ISO 8601 字符串 */\n finishedAt: string\n /** RunResult.config:本次运行配置快照(RuntimeConfig) */\n config: import('@dependfix/core').RunReportConfig\n /** RunResult.alerts:所有仓库合并归一化告警 */\n alerts: Array<import('@dependfix/core').NormalizedSecurityAlert>\n /** RunResult.actions:所有仓库合并的修复动作 */\n actions: Array<import('@dependfix/core').FixAction>\n }\n | { ok: false, error: string }\n\n/**\n * `run_scan`:对目标仓库执行 dependfix 扫描并修复。\n * 凭据从 GITHUB_TOKEN 环境变量读取;repo 为 GitHub 远程仓库(report-only 无需 clone)。\n */\nexport const runScan = async (input: {\n repo: string\n mode: 'report-only' | 'fix' | 'fix-and-pr'\n severity: string\n code_scanning?: boolean\n max_alerts?: number\n max_concurrency?: number\n dry_run?: boolean\n allow_major_upgrade?: boolean\n ai_enabled?: boolean\n ai_provider?: 'openai-compatible' | 'anthropic'\n ai_model?: string\n ai_trigger?: 'failure' | 'major' | 'both'\n}): Promise<RunScanResult> => {\n const token = requireToken()\n if (typeof token !== 'string') {\n return token\n }\n\n // repo 格式校验复用 core(与 CLI 同源)\n if (!isValidRepoIdentifier(input.repo)) {\n return { ok: false, error: `repo 格式非法(预期 owner/repo,收到 ${input.repo})` }\n }\n const [owner, repo] = input.repo.split('/')\n\n // 展开 cli 默认配置(maxAlerts/maxConcurrency/maxRetries/maxBackoff/alertSource/ai 默认等\n // 与 CLI 单一事实源对齐,避免手写默认值漂移),仅覆盖 tool 参数可控制字段。\n const defaultAi = DEFAULT_RUNTIME_CONFIG.ai\n const config: RuntimeConfig = {\n ...DEFAULT_RUNTIME_CONFIG,\n mode: input.mode,\n severityThreshold: input.severity as 'critical' | 'high' | 'medium' | 'all',\n repositories: [`${owner}/${repo}`],\n // dry-run 显式参数优先,缺省按 mode 推断(report-only 即只读)\n dryRun: input.dry_run ?? (input.mode === 'report-only'),\n createPullRequest: input.mode === 'fix-and-pr',\n commit: input.mode === 'fix',\n cleanupBranches: false,\n cleanupBranchesAuto: false,\n githubToken: token,\n codeScanningEnabled: input.code_scanning ?? DEFAULT_RUNTIME_CONFIG.codeScanningEnabled,\n allowMajorUpgrade: input.allow_major_upgrade ?? DEFAULT_RUNTIME_CONFIG.allowMajorUpgrade,\n maxAlertsPerRepository: input.max_alerts ?? DEFAULT_RUNTIME_CONFIG.maxAlertsPerRepository,\n maxConcurrency: input.max_concurrency ?? DEFAULT_RUNTIME_CONFIG.maxConcurrency,\n // AI 研判:展开 cli 默认(provider/model/baseUrl/trigger 与 CLI 对齐),\n // 仅覆盖开关与显式参数;apiKey 只从 env 读取(DEPENDFIX_AI_API_KEY),\n // 禁止经 tool 参数传入(防客户端日志泄露)。\n // defaultAi 收窄:默认配置缺失时视为未开启(与类型声明一致,运行时恒有值)\n ai: input.ai_enabled && defaultAi\n ? {\n ...defaultAi,\n enabled: true,\n provider: input.ai_provider ?? defaultAi.provider,\n model: input.ai_model ?? defaultAi.model,\n trigger: input.ai_trigger ?? defaultAi.trigger,\n apiKey: process.env.DEPENDFIX_AI_API_KEY,\n }\n : undefined,\n }\n\n try {\n const app = new DependfixApp({\n config,\n workDir: process.cwd(),\n reportOutputDir: process.env.DEPENDFIX_MCP_REPORT_DIR ?? './dependfix-reports',\n })\n const { result, exitCode } = await app.run()\n\n return {\n ok: true,\n exitCode,\n runId: result.runId,\n summary: result.summary,\n repositories: result.repositories.map((r) => ({\n repository: r.repository,\n alertsCount: r.alertsCount,\n fixable: r.fixable,\n fixed: r.fixed,\n failed: r.failed,\n lockfileRepaired: r.lockfileRepaired,\n verificationPassed: r.verificationPassed ?? undefined,\n durationMs: r.durationMs,\n })),\n errors: result.errors.map((e) => ({\n repository: e.repository,\n stage: e.stage,\n category: e.category,\n message: e.message,\n })),\n startedAt: result.startedAt,\n finishedAt: result.finishedAt,\n config: result.config,\n alerts: result.alerts,\n actions: result.actions,\n }\n } catch (error) {\n return toToolError(error)\n }\n}\n","import { overrideTransitiveDependency, repairLockfile, upgradeDependency, type LockfileDiff } from '@dependfix/engine'\nimport { toToolError } from './errors'\n\n/** `fix_dependency` 返回结构(按 fixType 判别) */\nexport type FixDependencyResult =\n | {\n ok: true\n fixType: 'override' | 'direct'\n packageName: string\n fromVersion: string\n toVersion: string\n isMajor: boolean\n warning?: string\n }\n | {\n ok: true\n fixType: 'lockfile'\n strategy?: string\n diff?: LockfileDiff | null\n lockfileVersion?: string\n lockfileVersionChanged?: boolean\n }\n | {\n ok: false\n fixType: 'override' | 'direct' | 'lockfile'\n packageName?: string\n fromVersion?: string\n toVersion?: string\n isMajor?: boolean\n error: string\n }\n\n/**\n * `fix_dependency`:修复单个依赖或 lockfile(按 `fix_type` 分发,复用 cli fixers):\n * - `override`(默认):间接依赖 → `overrideTransitiveDependency`(写入 pnpm overrides)\n * - `direct`:直接依赖 → `upgradeDependency`(改写 manifest + `pnpm install`,失败回滚)\n * - `lockfile`:frozen-lockfile 漂移 → `repairLockfile`(策略链修复,全部失败回滚)\n * 均需本地已 clone 的仓库目录(workDir)。\n */\nexport const fixDependency = async (input: {\n workDir: string\n fix_type?: 'override' | 'direct' | 'lockfile'\n packageName?: string\n targetVersion?: string\n}): Promise<FixDependencyResult> => {\n const fixType = input.fix_type ?? 'override'\n try {\n switch (fixType) {\n case 'lockfile': {\n const result = repairLockfile({ workDir: input.workDir })\n if (result.success) {\n return {\n ok: true,\n fixType: 'lockfile',\n strategy: result.strategy,\n diff: result.diff ?? null,\n lockfileVersion: result.lockfileVersion,\n lockfileVersionChanged: result.lockfileVersionChanged,\n }\n }\n return {\n ok: false,\n fixType: 'lockfile',\n error: result.failureDetail ?? 'lockfile repair failed',\n }\n }\n case 'direct': {\n if (!input.packageName || !input.targetVersion) {\n return { ok: false, fixType: 'direct', error: 'packageName 与 targetVersion 必填(fix_type=direct)' }\n }\n const result = await upgradeDependency({\n packageName: input.packageName,\n targetVersion: input.targetVersion,\n workDir: input.workDir,\n })\n if (result.success) {\n return {\n ok: true,\n fixType: 'direct',\n packageName: result.packageName,\n fromVersion: result.fromVersion,\n toVersion: result.toVersion,\n isMajor: result.isMajor,\n warning: result.warning,\n }\n }\n return {\n ok: false,\n fixType: 'direct',\n packageName: result.packageName,\n fromVersion: result.fromVersion,\n toVersion: result.toVersion,\n isMajor: result.isMajor,\n error: result.error ?? 'upgrade failed',\n }\n }\n case 'override': {\n if (!input.packageName || !input.targetVersion) {\n return { ok: false, fixType: 'override', error: 'packageName 与 targetVersion 必填(fix_type=override)' }\n }\n const result = await overrideTransitiveDependency({\n packageName: input.packageName,\n targetVersion: input.targetVersion,\n workDir: input.workDir,\n })\n if (result.success) {\n return {\n ok: true,\n fixType: 'override',\n packageName: result.packageName,\n fromVersion: result.fromVersion,\n toVersion: result.toVersion,\n isMajor: result.isMajor,\n warning: result.warning,\n }\n }\n return {\n ok: false,\n fixType: 'override',\n packageName: result.packageName,\n fromVersion: result.fromVersion,\n toVersion: result.toVersion,\n isMajor: result.isMajor,\n error: result.error ?? 'override failed',\n }\n }\n }\n } catch (error) {\n return {\n ok: false,\n fixType,\n error: toToolError(error).error,\n }\n }\n}\n","import { createGitHubClient, discoverRepositories, type RepoPolicy } from '@dependfix/engine'\nimport { fromPat } from '@dependfix/engine/auth'\nimport { requireToken, toToolError } from './errors'\n\n/** `discover_repos` 返回结构 */\nexport type DiscoverReposResult =\n | {\n ok: true\n count: number\n repositories: Array<{\n fullName: string\n defaultBranch: string\n topics: string[]\n hasDependabotConfig: boolean\n }>\n }\n | { ok: false, error: string }\n\n/**\n * `discover_repos`:按 owner / org 自动发现仓库(复用 cli discoverRepositories,\n * 与 CLI `--owner` / `--repo-topics` / `--repo-include` / `--repo-exclude` 同源过滤链)。\n * 凭据从 GITHUB_TOKEN 环境变量读取。\n */\nexport const discoverRepos = async (input: {\n owner: string[]\n topics?: string[]\n include?: string[]\n exclude?: string[]\n probe_dependabot?: boolean\n max_repos?: number\n}): Promise<DiscoverReposResult> => {\n const token = requireToken()\n if (typeof token !== 'string') {\n return token\n }\n if (input.owner.length === 0) {\n return { ok: false, error: 'owner 必填(至少一个 owner/org)' }\n }\n\n try {\n const client = createGitHubClient({ auth: fromPat(token) })\n const policy: RepoPolicy = {\n include: input.include && input.include.length > 0 ? input.include : undefined,\n exclude: input.exclude && input.exclude.length > 0 ? input.exclude : undefined,\n }\n const repos = await discoverRepositories({\n client,\n owners: input.owner,\n topics: input.topics,\n policy,\n probeDependabot: input.probe_dependabot ?? true,\n maxRepos: input.max_repos,\n })\n return {\n ok: true,\n count: repos.length,\n repositories: repos.map((r) => ({\n fullName: r.fullName,\n defaultBranch: r.defaultBranch,\n topics: r.topics,\n hasDependabotConfig: r.hasDependabotConfig,\n })),\n }\n } catch (error) {\n return toToolError(error)\n }\n}\n","import { createGitHubClient, deleteRemoteBranch, getBranchPrStatus, listDependfixBranches } from '@dependfix/engine'\nimport { fromPat } from '@dependfix/engine/auth'\nimport { isValidRepoIdentifier } from '@dependfix/core'\nimport { requireToken, toToolError } from './errors'\n\n/** `cleanup_branches` 返回结构 */\nexport type CleanupBranchesResult =\n | {\n ok: true\n dryRun: boolean\n scanned: string[]\n /** 已删除分支(dry_run 时为空) */\n deleted: string[]\n /** 保留分支(open PR / 无 PR 未关闭) */\n kept: string[]\n /** 删除失败分支(best-effort,不中断) */\n failed: string[]\n }\n | { ok: false, error: string }\n\n/**\n * `cleanup_branches`:清理已合并/已关闭的 dependfix 分支(非交互)。\n *\n * 复用 cli pr-creator 底层函数自编排,语义对齐 `autoCleanupMergedBranches`:\n * - 只处理 `dependfix/` 前缀分支(listDependfixBranches 已过滤)\n * - 删除候选 = 已合并(merged)+ 已关闭未合并(orphaned);绝不触碰 open PR 分支\n * - 单分支删除失败记录到 `failed`,不中断其余删除(best-effort)\n * - dry_run 仅列清单(deleted/failed 为空)\n *\n * 刻意不走 DependfixApp 的 cleanup-branches mode:`runBranchCleanupForRepo`\n * 含交互式确认(非 TTY 默认拒绝),MCP stdio 下不可用。\n */\nexport const cleanupBranches = async (input: { repo: string, dry_run?: boolean }): Promise<CleanupBranchesResult> => {\n const token = requireToken()\n if (typeof token !== 'string') {\n return token\n }\n if (!isValidRepoIdentifier(input.repo)) {\n return { ok: false, error: `repo 格式非法(预期 owner/repo,收到 ${input.repo})` }\n }\n const [owner, repo] = input.repo.split('/')\n const dryRun = input.dry_run ?? false\n\n try {\n const client = createGitHubClient({ auth: fromPat(token) })\n const branches = await listDependfixBranches(client, owner, repo)\n const statuses = await Promise.all(\n branches.map((branch) => getBranchPrStatus(client, owner, repo, branch)),\n )\n\n const merged = statuses.filter((s) => s.merged)\n const orphaned = statuses.filter((s) => s.closed && !s.merged)\n const kept = statuses.filter((s) => !s.closed)\n const candidates = [...merged, ...orphaned]\n\n if (dryRun) {\n return {\n ok: true,\n dryRun: true,\n scanned: branches,\n deleted: [],\n kept: kept.map((s) => s.branch),\n failed: [],\n }\n }\n\n const deleted: string[] = []\n const failed: string[] = []\n for (const s of candidates) {\n try {\n await deleteRemoteBranch(client, owner, repo, s.branch)\n deleted.push(s.branch)\n } catch {\n // 单分支删除失败(分支保护/不存在)不中断其余删除,best-effort\n failed.push(s.branch)\n }\n }\n\n return {\n ok: true,\n dryRun: false,\n scanned: branches,\n deleted,\n kept: kept.map((s) => s.branch),\n failed,\n }\n } catch (error) {\n return toToolError(error)\n }\n}\n","import { queryRepoHistory } from '@dependfix/engine'\nimport { isValidRepoIdentifier } from '@dependfix/core'\nimport { toToolError } from './errors'\n\n/** `history` 返回结构 */\nexport type HistoryResult =\n | {\n ok: true\n repo: string\n runs: Array<{\n runId: string\n startedAt: string\n durationMs: number\n repositories: string[]\n summary: Record<string, unknown>\n repoStats: Array<Record<string, unknown>>\n }>\n }\n | { ok: false, error: string }\n\n/**\n * `history`:查询某仓库的历史运行摘要(倒序时间:最新在前)。\n * 复用 cli `queryRepoHistory`(读 dependfix-reports/index.json 聚合索引,\n * 与 `get_last_report` 的单文件语义不同);报告目录可用 `DEPENDFIX_MCP_REPORT_DIR` 覆盖。\n */\nexport const getHistory = async (input: { repo: string }): Promise<HistoryResult> => {\n if (!isValidRepoIdentifier(input.repo)) {\n return { ok: false, error: `repo 格式非法(预期 owner/repo,收到 ${input.repo})` }\n }\n try {\n const reportDir = process.env.DEPENDFIX_MCP_REPORT_DIR ?? './dependfix-reports'\n const entries = queryRepoHistory(input.repo, reportDir)\n return {\n ok: true,\n repo: input.repo,\n runs: entries.map((e) => ({\n runId: e.runId,\n startedAt: e.startedAt,\n durationMs: e.durationMs,\n repositories: e.repositories,\n // 桥接:RunSummary/ArchiveRepoStats 无索引签名,显式转 unknown 再收窄\n summary: e.summary as unknown as Record<string, unknown>,\n repoStats: e.repoStats as unknown as Array<Record<string, unknown>>,\n })),\n }\n } catch (error) {\n return toToolError(error)\n }\n}\n","import { fetchPnpmAuditAlerts, type FetchPnpmAuditAlertsParams } from '@dependfix/engine'\nimport { requireToken, toToolError } from './errors'\n\n/**\n * `pnpm_audit` 返回结构\n *\n * 复用 `fetchAlerts` 的子集结构(id / severity / packageName / manifestPath /\n * recommendedVersion / fixable / htmlUrl / summary),让客户端能以一致形式\n * 消费 Dependabot / Code Scanning / pnpm-audit 三源告警。\n */\nexport type PnpmAuditResult =\n | {\n ok: true\n /** pnpm-audit 归一化后的告警数 */\n count: number\n /** 工作目录(与 input.workDir 一致;方便客户端无需记录入参) */\n workDir: string\n /** 注入的仓库标识(owner/repo 或 local 兜底) */\n repository: string\n alerts: Array<{\n id: number\n severity: string\n packageName: string\n manifestPath: string\n recommendedVersion: string\n fixable: boolean\n htmlUrl: string\n summary: string\n }>\n }\n | { ok: false, error: string }\n\n/**\n * `pnpm_audit`:本地 pnpm audit 回退数据源(无 GitHub token 或 403 场景)。\n *\n * 设计意图(详见 docs/design/pnpm-audit-fallback.md):\n * - 显式 `--alerts-source pnpm-audit` 触发(CLI)或显式调用 `pnpm_audit` tool(MCP)触发\n * - 复用 `fetchPnpmAuditAlerts` 解析 + 归一化逻辑(与 CLI 同源)\n * - audit 自身失败(无 lockfile / pnpm 不可用 / JSON 解析失败)→ 硬失败,绝不静默空跑\n *\n * 凭据:pnpm-audit 不需要 GitHub token(本地命令);但保留 `requireToken()`\n * 调用与其它 tool 一致(保持 pattern 统一,未来如需 pnpm registry token 可扩展)。\n *\n * @param input.workDir 本地仓库工作目录(包含 pnpm-lock.yaml)\n * @param input.repository 仓库标识(owner/repo 或 local 兜底;与 CLI --repo 同源语义)\n */\nexport const pnpmAudit = async (input: FetchPnpmAuditAlertsParams): Promise<PnpmAuditResult> => {\n const token = requireToken()\n if (typeof token !== 'string') {\n return token\n }\n\n try {\n const normalizedAlerts = await fetchPnpmAuditAlerts(input)\n return {\n ok: true,\n count: normalizedAlerts.length,\n workDir: input.workDir,\n repository: input.repository,\n alerts: normalizedAlerts.map((a) => ({\n id: a.id,\n severity: a.severity,\n packageName: a.packageName,\n manifestPath: a.manifestPath,\n recommendedVersion: a.recommendedVersion,\n fixable: a.fixable,\n htmlUrl: a.htmlUrl,\n summary: a.summary,\n })),\n }\n } catch (error) {\n return toToolError(error)\n }\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { fetchAlertsSchema, getLastReportSchema, runScanSchema, fixDependencySchema, discoverReposSchema, cleanupBranchesSchema, historySchema, pnpmAuditSchema } from './tools/schemas'\nimport { fetchAlerts } from './tools/fetch-alerts'\nimport { getLastReport } from './tools/get-last-report'\nimport { runScan } from './tools/run-scan'\nimport { fixDependency } from './tools/fix-dependency'\nimport { discoverRepos } from './tools/discover-repos'\nimport { cleanupBranches } from './tools/cleanup-branches'\nimport { getHistory } from './tools/history'\nimport { pnpmAudit } from './tools/pnpm-audit.tool'\n\n/**\n * dependfix MCP Server:向 AI 助手暴露 7 个 tool。\n * - fetch_alerts(只读):拉取 Dependabot / Code Scanning 告警\n * - get_last_report(只读):读取最近 JSON 报告\n * - run_scan(写入):执行扫描/修复(默认 report-only;支持 AI 研判透传)\n * - fix_dependency(写入):修复单个依赖(override / direct / lockfile)\n * - discover_repos(只读):按 owner / org 自动发现仓库\n * - cleanup_branches(写入):清理已合并/已关闭的 dependfix 分支(非交互)\n * - history(只读):查询仓库历史运行摘要\n * 凭据从 GITHUB_TOKEN 环境变量读取(mcp-server.md §4.3)。\n */\nexport const createMcpServer = (): McpServer => {\n const server = new McpServer({\n name: 'dependfix',\n version: '0.1.0',\n })\n\n server.registerTool(\n 'fetch_alerts',\n {\n description: '拉取指定仓库的 Dependabot 安全告警(可选并行 Code Scanning,只读)',\n inputSchema: fetchAlertsSchema,\n },\n async (input) => {\n const result = await fetchAlerts(input)\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n },\n )\n\n server.registerTool(\n 'get_last_report',\n {\n description: '读取最近一次 dependfix JSON 报告(只读)',\n inputSchema: getLastReportSchema,\n },\n async () => {\n const result = await getLastReport()\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n },\n )\n\n server.registerTool(\n 'run_scan',\n {\n description: '对目标仓库执行 dependfix 扫描并修复(默认 report-only;支持 code-scanning / AI 研判等参数)',\n inputSchema: runScanSchema,\n },\n async (input) => {\n const result = await runScan(input)\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n },\n )\n\n server.registerTool(\n 'fix_dependency',\n {\n description: '修复单个依赖或 lockfile(override / direct / lockfile;需要本地已 clone 仓库目录)',\n inputSchema: fixDependencySchema,\n },\n async (input) => {\n const result = await fixDependency(input)\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n },\n )\n\n server.registerTool(\n 'discover_repos',\n {\n description: '按 owner / org 自动发现仓库(支持 topics / include / exclude 名单策略,只读)',\n inputSchema: discoverReposSchema,\n },\n async (input) => {\n const result = await discoverRepos(input)\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n },\n )\n\n server.registerTool(\n 'cleanup_branches',\n {\n description: '清理已合并/已关闭的 dependfix 分支(非交互;只删 dependfix/ 前缀且 merged/closed,绝不触碰 open PR 分支)',\n inputSchema: cleanupBranchesSchema,\n },\n async (input) => {\n const result = await cleanupBranches(input)\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n },\n )\n\n server.registerTool(\n 'history',\n {\n description: '查询指定仓库的历史运行摘要(倒序时间,只读)',\n inputSchema: historySchema,\n },\n async (input) => {\n const result = await getHistory(input)\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n },\n )\n\n server.registerTool(\n 'pnpm_audit',\n {\n description: '本地 pnpm audit 回退数据源(无需 GitHub token;audit 失败硬返回错误)',\n inputSchema: pnpmAuditSchema,\n },\n async (input) => {\n const result = await pnpmAudit(input)\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n },\n )\n\n return server\n}\n\n/** 连接 stdio 传输(bin 入口调用) */\nexport const connectStdio = async (): Promise<void> => {\n const server = createMcpServer()\n const transport = new StdioServerTransport()\n await server.connect(transport)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"src.mjs","names":[],"sources":["../src/tools/schemas.ts","../src/tools/errors.ts","../src/tools/fetch-alerts.ts","../src/tools/get-last-report.ts","../src/tools/run-scan.ts","../src/tools/fix-dependency.ts","../src/tools/discover-repos.ts","../src/tools/cleanup-branches.ts","../src/tools/history.ts","../src/tools/pnpm-audit.tool.ts","../src/index.ts"],"sourcesContent":["import { z } from 'zod'\nimport { RUNTIME_MODES, SEVERITY_THRESHOLDS } from '@dependfix/engine'\n\n// run_scan 的 mode 子集:排除 cleanup-branches(由独立 cleanup_branches tool 承担;\n// DependfixApp 的该 mode 走交互确认,MCP stdio 不可用——见 mcp-server.md §8.3)。\n// 从 cli RUNTIME_MODES 派生(filter 跟随 cli 演进),非独立硬编码。\n// as unknown 桥接:filter 返回数组类型,z.enum 需要 readonly 元组。\nconst RUN_SCAN_MODES = RUNTIME_MODES.filter((m) => m !== 'cleanup-branches') as unknown as readonly ['report-only', 'fix', 'fix-and-pr']\n\n/** `fetch_alerts` 输入:拉取指定仓库的安全告警(Dependabot + 可选 Code Scanning) */\nexport const fetchAlertsSchema = z.object({\n repo: z.string().describe('目标仓库,格式 owner/repo'),\n severity: z.enum(SEVERITY_THRESHOLDS).default('high').describe('严重级别阈值(high 保留 critical + high,与 CLI 一致)'),\n code_scanning: z.boolean().optional().describe('同时拉取 Code Scanning 告警(与 Dependabot 并行;需要 token 具备 security-events: read)'),\n})\n\n/** `get_last_report` 输入:读取最近一次 JSON 报告 */\nexport const getLastReportSchema = z.object({})\n\n/** `run_scan` 输入:对目标仓库执行 dependfix 扫描并修复 */\nexport const runScanSchema = z.object({\n repo: z.string().describe('目标仓库,格式 owner/repo'),\n mode: z.enum(RUN_SCAN_MODES).default('report-only').describe('执行模式(默认仅报告)'),\n severity: z.enum(SEVERITY_THRESHOLDS).default('high').describe('严重级别阈值'),\n code_scanning: z.boolean().optional().describe('同时拉取 Code Scanning 告警(默认 false)'),\n max_alerts: z.number().int().min(1).max(1000).optional().describe('每仓库最多处理的告警数(默认 20)'),\n max_concurrency: z.number().int().min(1).max(16).optional().describe('多仓库并发窗口(默认 1 保守串行)'),\n dry_run: z.boolean().optional().describe('试运行不实际写入;缺省按 mode 推断(report-only 为 true)。与 mode=fix/fix-and-pr 互斥(会返回配置校验错误)'),\n allow_major_upgrade: z.boolean().optional().describe('跨线 major 升级显式授权(默认 false;仅根直接依赖 + lockfile 单版本,强制完整验证)'),\n ai_enabled: z.boolean().optional().describe('开启 AI breaking change 研判(默认 false;apiKey 从 DEPENDFIX_AI_API_KEY env 读取,禁止经 tool 参数传入)'),\n ai_provider: z.enum(['openai-compatible', 'anthropic']).optional().describe('AI 提供商(默认 openai-compatible)'),\n ai_model: z.string().optional().describe('AI 模型名(默认 deepseek-v4-flash)'),\n ai_trigger: z.enum(['failure', 'major', 'both']).optional().describe('AI 触发范围(默认 both)'),\n})\n\n/** `fix_dependency` 输入:修复单个依赖(多修复类型) */\nexport const fixDependencySchema = z.object({\n /** 本地仓库路径(已 clone 的目录,含 package.json/pnpm-lock.yaml) */\n workDir: z.string().describe('本地仓库工作目录(已 clone,包含 package.json 与 pnpm-lock.yaml)'),\n /** 修复类型:override(间接依赖 overrides)/ direct(直接依赖升级)/ lockfile(frozen-lockfile 漂移修复) */\n fix_type: z.enum(['override', 'direct', 'lockfile']).default('override').describe('修复类型(默认 override)'),\n /** override / direct 必填 */\n packageName: z.string().optional().describe('依赖包名(fix_type=override/direct 必填)'),\n /** override / direct 必填 */\n targetVersion: z.string().optional().describe('目标精确版本,如 4.17.21(fix_type=override/direct 必填)'),\n})\n\n/** `discover_repos` 输入:按 owner / org 自动发现仓库 */\nexport const discoverReposSchema = z.object({\n owner: z.array(z.string()).min(1).describe('owner / org 列表(分别发现后合并)'),\n topics: z.array(z.string()).optional().describe('topic 白名单(AND 语义:必须包含全部指定 topics)'),\n include: z.array(z.string()).optional().describe('仓库白名单 glob(如 owner/*、owner/pkg-*)'),\n exclude: z.array(z.string()).optional().describe('仓库黑名单 glob(与 include 冲突时胜出)'),\n probe_dependabot: z.boolean().optional().describe('探测 .github/dependabot.yml 存在性(默认 true;会额外触达 contents API)'),\n max_repos: z.number().int().min(0).optional().describe('发现规模上限:最多保留的仓库数(默认 100;0 表示不限制)'),\n})\n\n/** `cleanup_branches` 输入:清理已合并/已关闭的 dependfix 分支 */\nexport const cleanupBranchesSchema = z.object({\n repo: z.string().describe('目标仓库,格式 owner/repo'),\n dry_run: z.boolean().optional().describe('仅列出待清理分支,不执行删除(默认 false)'),\n})\n\n/** `history` 输入:查询仓库历史运行摘要 */\nexport const historySchema = z.object({\n repo: z.string().describe('目标仓库,格式 owner/repo'),\n})\n\n/** `pnpm_audit` 输入:本地 pnpm audit 回退数据源 */\nexport const pnpmAuditSchema = z.object({\n /** 本地仓库工作目录(已 clone,包含 pnpm-lock.yaml) */\n workDir: z.string().describe('本地仓库工作目录(已 clone,包含 pnpm-lock.yaml)'),\n /** 仓库标识(owner/repo 或 local 兜底;与 CLI --repo 同源语义) */\n repository: z.string().describe('仓库标识(owner/repo 或 local 兜底;用于归一化 NormalizedSecurityAlert.repository 字段)'),\n})\n","// 统一 tool 错误模板(复用收口):\n// - requireToken:GITHUB_TOKEN 检查。返回 token 字符串或错误对象;\n// 调用方用 `typeof token !== 'string'` 守卫收窄(项目未开 strictNullChecks,\n// truthiness 判别收窄不生效,typeof 守卫是兼容形式)。\n// - toToolError:任意错误 → ok:false(统一 Error.message / String 转换)\n// 各 tool 的返回联合类型均含 `{ ok: false, error: string }` 分支,可安全返回。\n\nexport type ToolError = { ok: false, error: string }\n\nexport const requireToken = (): string | ToolError => {\n const token = process.env.GITHUB_TOKEN\n if (!token) {\n return { ok: false, error: 'GITHUB_TOKEN not set(请配置环境变量)' }\n }\n return token\n}\n\nexport const toToolError = (error: unknown): ToolError => ({\n ok: false,\n error: error instanceof Error ? error.message : String(error),\n})\n","import { createGitHubClient, fetchCodeScanningAlerts, fetchDependabotAlerts, type FetchDependabotAlertsParams } from '@dependfix/engine'\nimport { fromPat } from '@dependfix/engine/auth'\nimport { filterAlerts, isValidRepoIdentifier, type SeverityThreshold } from '@dependfix/core'\nimport { requireToken, toToolError } from './errors'\n\n/** `fetch_alerts` 返回结构 */\nexport type FetchAlertsResult =\n | {\n ok: true\n count: number\n alerts: Array<{\n id: number\n severity: string\n packageName: string\n manifestPath: string\n recommendedVersion: string\n fixable: boolean\n htmlUrl: string\n summary: string\n }>\n }\n | { ok: false, error: string }\n\n/**\n * `fetch_alerts`:拉取指定仓库的 Dependabot 安全告警(只读)。\n * 凭据从 GITHUB_TOKEN 环境变量读取(mcp-server.md §4.3)。\n */\nexport const fetchAlerts = async (input: { repo: string, severity: SeverityThreshold, code_scanning?: boolean }): Promise<FetchAlertsResult> => {\n const token = requireToken()\n if (typeof token !== 'string') {\n return token\n }\n\n // repo 格式校验复用 core(与 CLI 同源,避免自研校验漂移)\n if (!isValidRepoIdentifier(input.repo)) {\n return { ok: false, error: `repo 格式非法(预期 owner/repo,收到 ${input.repo})` }\n }\n const [owner, repo] = input.repo.split('/')\n\n try {\n const client = createGitHubClient({ auth: fromPat(token) })\n const params: FetchDependabotAlertsParams = {\n owner,\n repo,\n state: 'open',\n }\n\n // Dependabot + 可选 Code Scanning 并行(复用 cli fetcher;与 CLI --code-scanning 同源)。\n // 注意:CS 拉取失败(权限/网络)会使整个 tool 失败——与 CLI 现状一致\n // (per-source 错误隔离为 backlog 登记项,暂缓),结果不静默丢弃。\n const codeScanningEnabled = input.code_scanning ?? false\n const [dependabotAlerts, codeScanningAlerts] = await Promise.all([\n fetchDependabotAlerts(client, params),\n codeScanningEnabled\n ? fetchCodeScanningAlerts(client, { owner, repo })\n : Promise.resolve([] as Awaited<ReturnType<typeof fetchDependabotAlerts>>),\n ])\n const alerts = [...dependabotAlerts, ...codeScanningAlerts]\n\n // 严重级别过滤复用 core 阈值语义(与 CLI 一致:high 保留 critical + high;\n // all 不过滤;Code Scanning 源 unknown 恒透传)。不使用相等匹配,避免 high 漏掉 critical。\n const { filtered } = filterAlerts(alerts, { severityThreshold: input.severity })\n\n return {\n ok: true,\n count: filtered.length,\n alerts: filtered.map((a) => ({\n id: a.id,\n severity: a.severity,\n packageName: a.packageName,\n manifestPath: a.manifestPath,\n recommendedVersion: a.recommendedVersion,\n fixable: a.fixable,\n htmlUrl: a.htmlUrl,\n summary: a.summary,\n })),\n }\n } catch (error) {\n return toToolError(error)\n }\n}\n","import { readFileSync, readdirSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { toToolError } from './errors'\n\n/** `get_last_report` 返回结构 */\nexport type GetLastReportResult =\n | { ok: true, file: string, report: unknown }\n | { ok: false, error: string }\n\n/**\n * `get_last_report`:读取最近一次 JSON 报告(只读)。\n * 报告目录默认为 `./dependfix-reports`(可用 `DEPENDFIX_MCP_REPORT_DIR` 覆盖)。\n */\nexport const getLastReport = async (): Promise<GetLastReportResult> => {\n const reportDir = process.env.DEPENDFIX_MCP_REPORT_DIR ?? './dependfix-reports'\n try {\n const files = readdirSync(reportDir)\n .filter((f) => f.endsWith('.json'))\n .sort()\n if (files.length === 0) {\n return { ok: false, error: `未找到报告(目录 ${reportDir} 为空)` }\n }\n const latest = files[files.length - 1]\n const content = readFileSync(join(reportDir, latest), 'utf-8')\n return {\n ok: true,\n file: latest,\n report: JSON.parse(content),\n }\n } catch (error) {\n return toToolError(error)\n }\n}\n","import { DependfixApp, DEFAULT_RUNTIME_CONFIG, type RuntimeConfig } from '@dependfix/engine'\nimport { isValidRepoIdentifier } from '@dependfix/core'\nimport { requireToken, toToolError } from './errors'\n\n/** `run_scan` 返回结构(RunResult 对齐 + 向后兼容)\n *\n * 字段对齐 `RunResult` 接口(packages/core/src/report/types.ts):\n * - 8 字段保留(向后兼容——老客户端忽略未知字段):\n * ok / exitCode / runId / summary / repositories / errors\n * - 5 字段新增(RunResult 对齐):\n * startedAt / finishedAt / config / alerts / actions\n *\n * 2 字段可选(按 --ai 开启 + 供应链信号决定;不在 RunScanResult 必填):\n * aiUsage? / supplyChainWarnings?(暂不映射——避免 RunScanResult 类型膨胀)\n */\nexport type RunScanResult =\n | {\n ok: true\n exitCode: number\n runId: string\n summary: import('@dependfix/core').RunSummary\n repositories: Array<Record<string, unknown>>\n errors: Array<Record<string, unknown>>\n /** RunResult.startedAt:ISO 8601 字符串 */\n startedAt: string\n /** RunResult.finishedAt:ISO 8601 字符串 */\n finishedAt: string\n /** RunResult.config:本次运行配置快照(RuntimeConfig) */\n config: import('@dependfix/core').RunReportConfig\n /** RunResult.alerts:所有仓库合并归一化告警 */\n alerts: Array<import('@dependfix/core').NormalizedSecurityAlert>\n /** RunResult.actions:所有仓库合并的修复动作 */\n actions: Array<import('@dependfix/core').FixAction>\n }\n | { ok: false, error: string }\n\n/**\n * `run_scan`:对目标仓库执行 dependfix 扫描并修复。\n * 凭据从 GITHUB_TOKEN 环境变量读取;repo 为 GitHub 远程仓库(report-only 无需 clone)。\n */\nexport const runScan = async (input: {\n repo: string\n mode: 'report-only' | 'fix' | 'fix-and-pr'\n severity: string\n code_scanning?: boolean\n max_alerts?: number\n max_concurrency?: number\n dry_run?: boolean\n allow_major_upgrade?: boolean\n ai_enabled?: boolean\n ai_provider?: 'openai-compatible' | 'anthropic'\n ai_model?: string\n ai_trigger?: 'failure' | 'major' | 'both'\n}): Promise<RunScanResult> => {\n const token = requireToken()\n if (typeof token !== 'string') {\n return token\n }\n\n // repo 格式校验复用 core(与 CLI 同源)\n if (!isValidRepoIdentifier(input.repo)) {\n return { ok: false, error: `repo 格式非法(预期 owner/repo,收到 ${input.repo})` }\n }\n const [owner, repo] = input.repo.split('/')\n\n // 展开 cli 默认配置(maxAlerts/maxConcurrency/maxRetries/maxBackoff/alertSource/ai 默认等\n // 与 CLI 单一事实源对齐,避免手写默认值漂移),仅覆盖 tool 参数可控制字段。\n const defaultAi = DEFAULT_RUNTIME_CONFIG.ai\n const config: RuntimeConfig = {\n ...DEFAULT_RUNTIME_CONFIG,\n mode: input.mode,\n severityThreshold: input.severity as 'critical' | 'high' | 'medium' | 'all',\n repositories: [`${owner}/${repo}`],\n // dry-run 显式参数优先,缺省按 mode 推断(report-only 即只读)\n dryRun: input.dry_run ?? (input.mode === 'report-only'),\n createPullRequest: input.mode === 'fix-and-pr',\n commit: input.mode === 'fix',\n cleanupBranches: false,\n cleanupBranchesAuto: false,\n githubToken: token,\n codeScanningEnabled: input.code_scanning ?? DEFAULT_RUNTIME_CONFIG.codeScanningEnabled,\n allowMajorUpgrade: input.allow_major_upgrade ?? DEFAULT_RUNTIME_CONFIG.allowMajorUpgrade,\n maxAlertsPerRepository: input.max_alerts ?? DEFAULT_RUNTIME_CONFIG.maxAlertsPerRepository,\n maxConcurrency: input.max_concurrency ?? DEFAULT_RUNTIME_CONFIG.maxConcurrency,\n // AI 研判:展开 cli 默认(provider/model/baseUrl/trigger 与 CLI 对齐),\n // 仅覆盖开关与显式参数;apiKey 只从 env 读取(DEPENDFIX_AI_API_KEY),\n // 禁止经 tool 参数传入(防客户端日志泄露)。\n // defaultAi 收窄:默认配置缺失时视为未开启(与类型声明一致,运行时恒有值)\n ai: input.ai_enabled && defaultAi\n ? {\n ...defaultAi,\n enabled: true,\n provider: input.ai_provider ?? defaultAi.provider,\n model: input.ai_model ?? defaultAi.model,\n trigger: input.ai_trigger ?? defaultAi.trigger,\n apiKey: process.env.DEPENDFIX_AI_API_KEY,\n }\n : undefined,\n }\n\n try {\n const app = new DependfixApp({\n config,\n workDir: process.cwd(),\n reportOutputDir: process.env.DEPENDFIX_MCP_REPORT_DIR ?? './dependfix-reports',\n })\n const { result, exitCode } = await app.run()\n\n return {\n ok: true,\n exitCode,\n runId: result.runId,\n summary: result.summary,\n repositories: result.repositories.map((r) => ({\n repository: r.repository,\n alertsCount: r.alertsCount,\n fixable: r.fixable,\n fixed: r.fixed,\n failed: r.failed,\n lockfileRepaired: r.lockfileRepaired,\n verificationPassed: r.verificationPassed ?? undefined,\n durationMs: r.durationMs,\n })),\n errors: result.errors.map((e) => ({\n repository: e.repository,\n stage: e.stage,\n category: e.category,\n message: e.message,\n })),\n startedAt: result.startedAt,\n finishedAt: result.finishedAt,\n config: result.config,\n alerts: result.alerts,\n actions: result.actions,\n }\n } catch (error) {\n return toToolError(error)\n }\n}\n","import { overrideTransitiveDependency, repairLockfile, upgradeDependency, type LockfileDiff } from '@dependfix/engine'\nimport { toToolError } from './errors'\n\n/** `fix_dependency` 返回结构(按 fixType 判别) */\nexport type FixDependencyResult =\n | {\n ok: true\n fixType: 'override' | 'direct'\n packageName: string\n fromVersion: string\n toVersion: string\n isMajor: boolean\n warning?: string\n }\n | {\n ok: true\n fixType: 'lockfile'\n strategy?: string\n diff?: LockfileDiff | null\n lockfileVersion?: string\n lockfileVersionChanged?: boolean\n }\n | {\n ok: false\n fixType: 'override' | 'direct' | 'lockfile'\n packageName?: string\n fromVersion?: string\n toVersion?: string\n isMajor?: boolean\n error: string\n }\n\n/**\n * `fix_dependency`:修复单个依赖或 lockfile(按 `fix_type` 分发,复用 cli fixers):\n * - `override`(默认):间接依赖 → `overrideTransitiveDependency`(写入 pnpm overrides)\n * - `direct`:直接依赖 → `upgradeDependency`(改写 manifest + `pnpm install`,失败回滚)\n * - `lockfile`:frozen-lockfile 漂移 → `repairLockfile`(策略链修复,全部失败回滚)\n * 均需本地已 clone 的仓库目录(workDir)。\n */\nexport const fixDependency = async (input: {\n workDir: string\n fix_type?: 'override' | 'direct' | 'lockfile'\n packageName?: string\n targetVersion?: string\n}): Promise<FixDependencyResult> => {\n const fixType = input.fix_type ?? 'override'\n try {\n switch (fixType) {\n case 'lockfile': {\n const result = await repairLockfile({ workDir: input.workDir })\n if (result.success) {\n return {\n ok: true,\n fixType: 'lockfile',\n strategy: result.strategy,\n diff: result.diff ?? null,\n lockfileVersion: result.lockfileVersion,\n lockfileVersionChanged: result.lockfileVersionChanged,\n }\n }\n return {\n ok: false,\n fixType: 'lockfile',\n error: result.failureDetail ?? 'lockfile repair failed',\n }\n }\n case 'direct': {\n if (!input.packageName || !input.targetVersion) {\n return { ok: false, fixType: 'direct', error: 'packageName 与 targetVersion 必填(fix_type=direct)' }\n }\n const result = await upgradeDependency({\n packageName: input.packageName,\n targetVersion: input.targetVersion,\n workDir: input.workDir,\n })\n if (result.success) {\n return {\n ok: true,\n fixType: 'direct',\n packageName: result.packageName,\n fromVersion: result.fromVersion,\n toVersion: result.toVersion,\n isMajor: result.isMajor,\n warning: result.warning,\n }\n }\n return {\n ok: false,\n fixType: 'direct',\n packageName: result.packageName,\n fromVersion: result.fromVersion,\n toVersion: result.toVersion,\n isMajor: result.isMajor,\n error: result.error ?? 'upgrade failed',\n }\n }\n case 'override': {\n if (!input.packageName || !input.targetVersion) {\n return { ok: false, fixType: 'override', error: 'packageName 与 targetVersion 必填(fix_type=override)' }\n }\n const result = await overrideTransitiveDependency({\n packageName: input.packageName,\n targetVersion: input.targetVersion,\n workDir: input.workDir,\n })\n if (result.success) {\n return {\n ok: true,\n fixType: 'override',\n packageName: result.packageName,\n fromVersion: result.fromVersion,\n toVersion: result.toVersion,\n isMajor: result.isMajor,\n warning: result.warning,\n }\n }\n return {\n ok: false,\n fixType: 'override',\n packageName: result.packageName,\n fromVersion: result.fromVersion,\n toVersion: result.toVersion,\n isMajor: result.isMajor,\n error: result.error ?? 'override failed',\n }\n }\n }\n } catch (error) {\n return {\n ok: false,\n fixType,\n error: toToolError(error).error,\n }\n }\n}\n","import { createGitHubClient, discoverRepositories, type RepoPolicy } from '@dependfix/engine'\nimport { fromPat } from '@dependfix/engine/auth'\nimport { requireToken, toToolError } from './errors'\n\n/** `discover_repos` 返回结构 */\nexport type DiscoverReposResult =\n | {\n ok: true\n count: number\n repositories: Array<{\n fullName: string\n defaultBranch: string\n topics: string[]\n hasDependabotConfig: boolean\n }>\n }\n | { ok: false, error: string }\n\n/**\n * `discover_repos`:按 owner / org 自动发现仓库(复用 cli discoverRepositories,\n * 与 CLI `--owner` / `--repo-topics` / `--repo-include` / `--repo-exclude` 同源过滤链)。\n * 凭据从 GITHUB_TOKEN 环境变量读取。\n */\nexport const discoverRepos = async (input: {\n owner: string[]\n topics?: string[]\n include?: string[]\n exclude?: string[]\n probe_dependabot?: boolean\n max_repos?: number\n}): Promise<DiscoverReposResult> => {\n const token = requireToken()\n if (typeof token !== 'string') {\n return token\n }\n if (input.owner.length === 0) {\n return { ok: false, error: 'owner 必填(至少一个 owner/org)' }\n }\n\n try {\n const client = createGitHubClient({ auth: fromPat(token) })\n const policy: RepoPolicy = {\n include: input.include && input.include.length > 0 ? input.include : undefined,\n exclude: input.exclude && input.exclude.length > 0 ? input.exclude : undefined,\n }\n const repos = await discoverRepositories({\n client,\n owners: input.owner,\n topics: input.topics,\n policy,\n probeDependabot: input.probe_dependabot ?? true,\n maxRepos: input.max_repos,\n })\n return {\n ok: true,\n count: repos.length,\n repositories: repos.map((r) => ({\n fullName: r.fullName,\n defaultBranch: r.defaultBranch,\n topics: r.topics,\n hasDependabotConfig: r.hasDependabotConfig,\n })),\n }\n } catch (error) {\n return toToolError(error)\n }\n}\n","import { createGitHubClient, deleteRemoteBranch, getBranchPrStatus, listDependfixBranches } from '@dependfix/engine'\nimport { fromPat } from '@dependfix/engine/auth'\nimport { isValidRepoIdentifier } from '@dependfix/core'\nimport { requireToken, toToolError } from './errors'\n\n/** `cleanup_branches` 返回结构 */\nexport type CleanupBranchesResult =\n | {\n ok: true\n dryRun: boolean\n scanned: string[]\n /** 已删除分支(dry_run 时为空) */\n deleted: string[]\n /** 保留分支(open PR / 无 PR 未关闭) */\n kept: string[]\n /** 删除失败分支(best-effort,不中断) */\n failed: string[]\n }\n | { ok: false, error: string }\n\n/**\n * `cleanup_branches`:清理已合并/已关闭的 dependfix 分支(非交互)。\n *\n * 复用 cli pr-creator 底层函数自编排,语义对齐 `autoCleanupMergedBranches`:\n * - 只处理 `dependfix/` 前缀分支(listDependfixBranches 已过滤)\n * - 删除候选 = 已合并(merged)+ 已关闭未合并(orphaned);绝不触碰 open PR 分支\n * - 单分支删除失败记录到 `failed`,不中断其余删除(best-effort)\n * - dry_run 仅列清单(deleted/failed 为空)\n *\n * 刻意不走 DependfixApp 的 cleanup-branches mode:`runBranchCleanupForRepo`\n * 含交互式确认(非 TTY 默认拒绝),MCP stdio 下不可用。\n */\nexport const cleanupBranches = async (input: { repo: string, dry_run?: boolean }): Promise<CleanupBranchesResult> => {\n const token = requireToken()\n if (typeof token !== 'string') {\n return token\n }\n if (!isValidRepoIdentifier(input.repo)) {\n return { ok: false, error: `repo 格式非法(预期 owner/repo,收到 ${input.repo})` }\n }\n const [owner, repo] = input.repo.split('/')\n const dryRun = input.dry_run ?? false\n\n try {\n const client = createGitHubClient({ auth: fromPat(token) })\n const branches = await listDependfixBranches(client, owner, repo)\n const statuses = await Promise.all(\n branches.map((branch) => getBranchPrStatus(client, owner, repo, branch)),\n )\n\n const merged = statuses.filter((s) => s.merged)\n const orphaned = statuses.filter((s) => s.closed && !s.merged)\n const kept = statuses.filter((s) => !s.closed)\n const candidates = [...merged, ...orphaned]\n\n if (dryRun) {\n return {\n ok: true,\n dryRun: true,\n scanned: branches,\n deleted: [],\n kept: kept.map((s) => s.branch),\n failed: [],\n }\n }\n\n const deleted: string[] = []\n const failed: string[] = []\n for (const s of candidates) {\n try {\n await deleteRemoteBranch(client, owner, repo, s.branch)\n deleted.push(s.branch)\n } catch {\n // 单分支删除失败(分支保护/不存在)不中断其余删除,best-effort\n failed.push(s.branch)\n }\n }\n\n return {\n ok: true,\n dryRun: false,\n scanned: branches,\n deleted,\n kept: kept.map((s) => s.branch),\n failed,\n }\n } catch (error) {\n return toToolError(error)\n }\n}\n","import { queryRepoHistory } from '@dependfix/engine'\nimport { isValidRepoIdentifier } from '@dependfix/core'\nimport { toToolError } from './errors'\n\n/** `history` 返回结构 */\nexport type HistoryResult =\n | {\n ok: true\n repo: string\n runs: Array<{\n runId: string\n startedAt: string\n durationMs: number\n repositories: string[]\n summary: Record<string, unknown>\n repoStats: Array<Record<string, unknown>>\n }>\n }\n | { ok: false, error: string }\n\n/**\n * `history`:查询某仓库的历史运行摘要(倒序时间:最新在前)。\n * 复用 cli `queryRepoHistory`(读 dependfix-reports/index.json 聚合索引,\n * 与 `get_last_report` 的单文件语义不同);报告目录可用 `DEPENDFIX_MCP_REPORT_DIR` 覆盖。\n */\nexport const getHistory = async (input: { repo: string }): Promise<HistoryResult> => {\n if (!isValidRepoIdentifier(input.repo)) {\n return { ok: false, error: `repo 格式非法(预期 owner/repo,收到 ${input.repo})` }\n }\n try {\n const reportDir = process.env.DEPENDFIX_MCP_REPORT_DIR ?? './dependfix-reports'\n const entries = queryRepoHistory(input.repo, reportDir)\n return {\n ok: true,\n repo: input.repo,\n runs: entries.map((e) => ({\n runId: e.runId,\n startedAt: e.startedAt,\n durationMs: e.durationMs,\n repositories: e.repositories,\n // 桥接:RunSummary/ArchiveRepoStats 无索引签名,显式转 unknown 再收窄\n summary: e.summary as unknown as Record<string, unknown>,\n repoStats: e.repoStats as unknown as Array<Record<string, unknown>>,\n })),\n }\n } catch (error) {\n return toToolError(error)\n }\n}\n","import { fetchPnpmAuditAlerts, type FetchPnpmAuditAlertsParams } from '@dependfix/engine'\nimport { requireToken, toToolError } from './errors'\n\n/**\n * `pnpm_audit` 返回结构\n *\n * 复用 `fetchAlerts` 的子集结构(id / severity / packageName / manifestPath /\n * recommendedVersion / fixable / htmlUrl / summary),让客户端能以一致形式\n * 消费 Dependabot / Code Scanning / pnpm-audit 三源告警。\n */\nexport type PnpmAuditResult =\n | {\n ok: true\n /** pnpm-audit 归一化后的告警数 */\n count: number\n /** 工作目录(与 input.workDir 一致;方便客户端无需记录入参) */\n workDir: string\n /** 注入的仓库标识(owner/repo 或 local 兜底) */\n repository: string\n alerts: Array<{\n id: number\n severity: string\n packageName: string\n manifestPath: string\n recommendedVersion: string\n fixable: boolean\n htmlUrl: string\n summary: string\n }>\n }\n | { ok: false, error: string }\n\n/**\n * `pnpm_audit`:本地 pnpm audit 回退数据源(无 GitHub token 或 403 场景)。\n *\n * 设计意图(详见 docs/design/pnpm-audit-fallback.md):\n * - 显式 `--alerts-source pnpm-audit` 触发(CLI)或显式调用 `pnpm_audit` tool(MCP)触发\n * - 复用 `fetchPnpmAuditAlerts` 解析 + 归一化逻辑(与 CLI 同源)\n * - audit 自身失败(无 lockfile / pnpm 不可用 / JSON 解析失败)→ 硬失败,绝不静默空跑\n *\n * 凭据:pnpm-audit 不需要 GitHub token(本地命令);但保留 `requireToken()`\n * 调用与其它 tool 一致(保持 pattern 统一,未来如需 pnpm registry token 可扩展)。\n *\n * @param input.workDir 本地仓库工作目录(包含 pnpm-lock.yaml)\n * @param input.repository 仓库标识(owner/repo 或 local 兜底;与 CLI --repo 同源语义)\n */\nexport const pnpmAudit = async (input: FetchPnpmAuditAlertsParams): Promise<PnpmAuditResult> => {\n const token = requireToken()\n if (typeof token !== 'string') {\n return token\n }\n\n try {\n const normalizedAlerts = await fetchPnpmAuditAlerts(input)\n return {\n ok: true,\n count: normalizedAlerts.length,\n workDir: input.workDir,\n repository: input.repository,\n alerts: normalizedAlerts.map((a) => ({\n id: a.id,\n severity: a.severity,\n packageName: a.packageName,\n manifestPath: a.manifestPath,\n recommendedVersion: a.recommendedVersion,\n fixable: a.fixable,\n htmlUrl: a.htmlUrl,\n summary: a.summary,\n })),\n }\n } catch (error) {\n return toToolError(error)\n }\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { fetchAlertsSchema, getLastReportSchema, runScanSchema, fixDependencySchema, discoverReposSchema, cleanupBranchesSchema, historySchema, pnpmAuditSchema } from './tools/schemas'\nimport { fetchAlerts } from './tools/fetch-alerts'\nimport { getLastReport } from './tools/get-last-report'\nimport { runScan } from './tools/run-scan'\nimport { fixDependency } from './tools/fix-dependency'\nimport { discoverRepos } from './tools/discover-repos'\nimport { cleanupBranches } from './tools/cleanup-branches'\nimport { getHistory } from './tools/history'\nimport { pnpmAudit } from './tools/pnpm-audit.tool'\n\n/**\n * dependfix MCP Server:向 AI 助手暴露 8 个 tool。\n * - fetch_alerts(只读):拉取 Dependabot / Code Scanning 告警\n * - get_last_report(只读):读取最近 JSON 报告\n * - run_scan(写入):执行扫描/修复(默认 report-only;支持 AI 研判透传)\n * - fix_dependency(写入):修复单个依赖(override / direct / lockfile)\n * - discover_repos(只读):按 owner / org 自动发现仓库\n * - cleanup_branches(写入):清理已合并/已关闭的 dependfix 分支(非交互)\n * - history(只读):查询仓库历史运行摘要\n * - pnpm_audit(只读):本地 pnpm audit 回退数据源\n * 凭据从 GITHUB_TOKEN 环境变量读取(mcp-server.md §4.3)。\n */\nexport const createMcpServer = (): McpServer => {\n const server = new McpServer({\n name: 'dependfix',\n version: '0.1.0',\n })\n\n server.registerTool(\n 'fetch_alerts',\n {\n description: '拉取指定仓库的 Dependabot 安全告警(可选并行 Code Scanning,只读)',\n inputSchema: fetchAlertsSchema,\n },\n async (input) => {\n const result = await fetchAlerts(input)\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n },\n )\n\n server.registerTool(\n 'get_last_report',\n {\n description: '读取最近一次 dependfix JSON 报告(只读)',\n inputSchema: getLastReportSchema,\n },\n async () => {\n const result = await getLastReport()\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n },\n )\n\n server.registerTool(\n 'run_scan',\n {\n description: '对目标仓库执行 dependfix 扫描并修复(默认 report-only;支持 code-scanning / AI 研判等参数)',\n inputSchema: runScanSchema,\n },\n async (input) => {\n const result = await runScan(input)\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n },\n )\n\n server.registerTool(\n 'fix_dependency',\n {\n description: '修复单个依赖或 lockfile(override / direct / lockfile;需要本地已 clone 仓库目录)',\n inputSchema: fixDependencySchema,\n },\n async (input) => {\n const result = await fixDependency(input)\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n },\n )\n\n server.registerTool(\n 'discover_repos',\n {\n description: '按 owner / org 自动发现仓库(支持 topics / include / exclude 名单策略,只读)',\n inputSchema: discoverReposSchema,\n },\n async (input) => {\n const result = await discoverRepos(input)\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n },\n )\n\n server.registerTool(\n 'cleanup_branches',\n {\n description: '清理已合并/已关闭的 dependfix 分支(非交互;只删 dependfix/ 前缀且 merged/closed,绝不触碰 open PR 分支)',\n inputSchema: cleanupBranchesSchema,\n },\n async (input) => {\n const result = await cleanupBranches(input)\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n },\n )\n\n server.registerTool(\n 'history',\n {\n description: '查询指定仓库的历史运行摘要(倒序时间,只读)',\n inputSchema: historySchema,\n },\n async (input) => {\n const result = await getHistory(input)\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n },\n )\n\n server.registerTool(\n 'pnpm_audit',\n {\n description: '本地 pnpm audit 回退数据源(复用 GITHUB_TOKEN 检查;audit 失败硬返回错误)',\n inputSchema: pnpmAuditSchema,\n },\n async (input) => {\n const result = await pnpmAudit(input)\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n },\n )\n\n return server\n}\n\n/** 连接 stdio 传输(bin 入口调用) */\nexport const connectStdio = async (): Promise<void> => {\n const server = createMcpServer()\n const transport = new StdioServerTransport()\n await server.connect(transport)\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dependfix/mcp",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "dependfix MCP 服务:向 AI 助手暴露扫描/修复能力(stdio)",
5
5
  "author": "CaoMeiYouRen",
6
6
  "license": "MIT",
@@ -27,7 +27,7 @@
27
27
  "dependfix-mcp": "./dist/bin.mjs"
28
28
  },
29
29
  "engines": {
30
- "node": ">=20"
30
+ "node": "^22.23.4 || ^24.22.1"
31
31
  },
32
32
  "exports": {
33
33
  ".": {
@@ -41,15 +41,15 @@
41
41
  "dist"
42
42
  ],
43
43
  "dependencies": {
44
- "@modelcontextprotocol/sdk": "^1.30.0",
45
- "zod": "^4.6.1",
46
- "@dependfix/core": "0.5.0",
47
- "@dependfix/engine": "0.4.0"
44
+ "@modelcontextprotocol/sdk": "^1.32.1",
45
+ "zod": "^4.6.7",
46
+ "@dependfix/core": "0.6.0",
47
+ "@dependfix/engine": "0.5.0"
48
48
  },
49
49
  "devDependencies": {
50
- "nock": "^14.0.17",
50
+ "nock": "^15.0.5",
51
51
  "rimraf": "^6.1.3",
52
- "tsdown": "^0.23.0",
52
+ "tsdown": "^0.23.1",
53
53
  "typescript": "^6.0.3"
54
54
  },
55
55
  "publishConfig": {