ktworkflow-mcp/src/registerTools.ts

379 lines
13 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { z } from 'zod';
import type { McpTextResponse } from './types.js';
import { defaultHistoryRoots, taskTypeValues } from './core/constants.js';
import { createCleanupProcessPlan, cleanupHistoryArtifacts } from './tools/cleanup.js';
import { buildEnvPolicy, scanTaskRisk } from './tools/envRisk.js';
import { buildGuardrails } from './tools/guardrails.js';
import { inspectAllProjects, inspectProject } from './tools/inspect.js';
import { buildGlobalCodeReview, defaultReviewProjects } from './tools/review.js';
import { appendTaskRecord, createCommitChecklist, prepareTask, readWorkflowContext } from './tools/task.js';
import { buildBusinessTestPlan, createApiTestPlan, createPageTestCase } from './tools/testing.js';
import { buildVerificationPlan } from './tools/verification.js';
import { buildCommitPlan, buildComponentWorkflow, buildDbSyncPlan, buildFinishTask, buildPushPlan, buildRemoteHealthCheck } from './tools/workflow.js';
export function response(data: unknown): McpTextResponse {
return {
content: [
{
text: typeof data === 'string' ? data : JSON.stringify(data, null, 2),
type: 'text',
},
],
};
}
export function registerTools(server: McpServer): void {
server.registerTool(
'kt_read_context',
{
description: '读取 KT 根目录紧凑上下文,并返回项目清单和最近任务记录;需要完整文档时显式 includeFullDocs=true。',
inputSchema: {
includeFullDocs: z.boolean().default(false),
taskRecordCount: z.number().int().min(0).max(20).default(3),
},
title: 'Read KT Workflow Context',
},
async (input) => response(readWorkflowContext(input)),
);
server.registerTool(
'kt_inspect_project',
{
description: '检查 KT 子项目的仓库类型、包管理器、Node 版本、env 文件和 Git 状态。',
inputSchema: {
includeGit: z.boolean().default(true),
project: z.string().default('root'),
},
title: 'Inspect KT Project',
},
async (input) => response(await inspectProject(input)),
);
server.registerTool(
'kt_inspect_all_projects',
{
description: '一次性检查 KT 工作区所有已知项目,适合多仓库联动任务开工前使用。',
inputSchema: {
includeGit: z.boolean().default(true),
includeRoot: z.boolean().default(true),
},
title: 'Inspect All KT Projects',
},
async (input) => response(await inspectAllProjects(input)),
);
server.registerTool(
'kt_guardrails',
{
description: '按任务类型生成 KT 防偏差清单,包含开工、改动、禁止项和验证约束。',
inputSchema: {
changeType: z.enum(taskTypeValues).optional(),
includePageTest: z.boolean().default(false),
paths: z.array(z.string()).default([]),
project: z.string().default('root'),
taskType: z.enum(taskTypeValues).default('general'),
userRequest: z.string().optional(),
},
title: 'KT Guardrails',
},
async (input) => response(buildGuardrails(input)),
);
server.registerTool(
'kt_prepare_task',
{
description: '生成一份 KT 任务 work packet上下文、项目检查、防偏差清单、风险扫描和验证计划。',
inputSchema: {
changedFiles: z.array(z.string()).default([]),
entryUrl: z.string().optional(),
includeGit: z.boolean().default(true),
includePageTest: z.boolean().default(false),
paths: z.array(z.string()).default([]),
project: z.string().default('root'),
recordTitle: z.string().optional(),
taskType: z.enum(taskTypeValues).default('general'),
userRequest: z.string().optional(),
},
title: 'Prepare KT Task',
},
async (input) => response(await prepareTask(input)),
);
server.registerTool(
'kt_suggest_verification',
{
description: '按 KT 规则为指定项目和变更类型生成轻量验证命令与注意事项。',
inputSchema: {
changeType: z.enum(taskTypeValues).default('general'),
includePageTest: z.boolean().default(false),
project: z.string().default('root'),
},
title: 'Suggest KT Verification',
},
async (input) => response(buildVerificationPlan(input)),
);
server.registerTool(
'kt_create_page_test_case',
{
description: '生成 KT 页面级可视化测试用例骨架,包含事不过三闭环规则。',
inputSchema: {
account: z.string().optional(),
assertions: z.array(z.string()).default([]),
entryUrl: z.string().optional(),
project: z.string().default('admin'),
steps: z.array(z.string()).default([]),
title: z.string().optional(),
},
title: 'Create KT Page Test Case',
},
async (input) => response(createPageTestCase(input)),
);
server.registerTool(
'kt_api_test_plan',
{
description: '为后端接口改动生成真实调用测试计划和响应结构断言。',
inputSchema: {
auth: z.enum(['none', 'bearer']).default('bearer'),
baseUrl: z.string().default('http://localhost:3000'),
body: z.record(z.any()).optional(),
contentType: z.boolean().default(true),
endpoint: z.string().default('/api/待填写'),
expectedFields: z.array(z.string()).default([]),
method: z.enum(['DELETE', 'GET', 'PATCH', 'POST', 'PUT']).default('GET'),
project: z.string().default('api'),
},
title: 'KT API Test Plan',
},
async (input) => response(createApiTestPlan(input)),
);
server.registerTool(
'kt_cleanup_history',
{
description: '清理 KT 运行态历史产物。默认 dryRun=true只预览执行时按 LastWriteTime 每个 .kt-workspace 历史目录仅保留最近 3 轮,.kt-workspace/test-artifacts/_templates 永久保留。',
inputSchema: {
dryRun: z.boolean().default(true),
keep: z.number().int().min(0).max(50).default(3),
roots: z.array(z.string()).default([...defaultHistoryRoots]),
},
title: 'KT Cleanup History Artifacts',
},
async (input) => response(cleanupHistoryArtifacts(input)),
);
server.registerTool(
'kt_cleanup_process_plan',
{
description: '生成按项目路径和端口清理验证进程的 PowerShell 检查命令,不直接杀进程。',
inputSchema: {
ports: z.array(z.number().int().min(1).max(65_535)).default([]),
project: z.string().default('root'),
},
title: 'KT Cleanup Process Plan',
},
async (input) => response(createCleanupProcessPlan(input)),
);
server.registerTool(
'kt_env_policy',
{
description: '检查指定项目 env 文件现状,并输出 KT 环境配置提交策略。',
inputSchema: {
project: z.string().default('root'),
},
title: 'KT Env Policy',
},
async (input) => response(buildEnvPolicy(input)),
);
server.registerTool(
'kt_risk_scan',
{
description: '按当前变更文件或传入文件列表扫描常见偏差风险和验证提醒。',
inputSchema: {
changedFiles: z.array(z.string()).default([]),
project: z.string().default('root'),
},
title: 'KT Risk Scan',
},
async (input) => response(await scanTaskRisk(input)),
);
server.registerTool(
'kt_global_code_review',
{
description: '对 KT 已知子仓库做只读全局 CodeReview 扫描Git 状态、tracked env/deploy/secrets、冲突标记、调试输出、疑似凭据字面量和当前变更风险。默认只对变更文件做内容扫描避免历史误报污染上下文。',
inputSchema: {
contentScanMode: z.enum(['changed', 'all']).default('changed'),
includeContentScan: z.boolean().default(true),
includeRootScan: z.boolean().default(true),
maxFindingsPerProject: z.number().int().min(1).max(200).default(20),
projects: z.array(z.string()).default([...defaultReviewProjects]),
},
title: 'KT Global Code Review',
},
async (input) => response(await buildGlobalCodeReview(input)),
);
server.registerTool(
'kt_finish_task',
{
description: '一键生成任务收尾包:项目状态、验证计划、可选验证执行、全局 review、历史产物清理预览/执行和停止条件。',
inputSchema: {
changeType: z.enum(taskTypeValues).default('general'),
cleanupHistory: z.boolean().default(false),
contentScanMode: z.enum(['changed', 'all']).default('changed'),
includeRootScan: z.boolean().default(true),
keepHistory: z.number().int().min(0).max(50).default(3),
maxFindingsPerProject: z.number().int().min(1).max(200).default(20),
projects: z.array(z.string()).default([...defaultReviewProjects]),
runValidation: z.boolean().default(false),
},
title: 'KT Finish Task',
},
async (input) => response(await buildFinishTask(input)),
);
server.registerTool(
'kt_commit_plan',
{
description: '按 KT 多仓库约定生成提交计划:按仓库分组、建议 commit message、提交命令和提交前检查。',
inputSchema: {
includePush: z.boolean().default(false),
message: z.string().optional(),
projects: z.array(z.string()).default([...defaultReviewProjects]),
},
title: 'KT Commit Plan',
},
async (input) => response(await buildCommitPlan(input)),
);
server.registerTool(
'kt_push_plan',
{
description: '按 KT 多仓库约定生成推送计划检查本地状态、待推提交、push 命令和远程异常提醒。',
inputSchema: {
branch: z.string().optional(),
projects: z.array(z.string()).default([...defaultReviewProjects]),
remote: z.string().default('origin'),
},
title: 'KT Push Plan',
},
async (input) => response(await buildPushPlan(input)),
);
server.registerTool(
'kt_business_test_plan',
{
description: '生成 KT 固化业务链路测试计划Admin 登录、博客 CRUD、QQBot 扫码/自动回复、Web/Playground 鉴权回跳。',
inputSchema: {
baseUrl: z.string().optional(),
environment: z.enum(['local', 'remote']).default('local'),
flow: z
.enum([
'admin-login',
'blog-crud',
'fflogs-command',
'qqbot-account-scan',
'qqbot-auto-reply',
'qqbot-login-sse',
'system-log-visualization',
'web-playground-auth',
'all',
])
.default('all'),
},
title: 'KT Business Test Plan',
},
async (input) => response(buildBusinessTestPlan(input)),
);
server.registerTool(
'kt_remote_health_check',
{
description: '生成或执行飞牛 NAS 远程只读健康检查SSH、Docker、Gitea、Jenkins、MySQL、MinIO、Mosquitto、NapCat、k3d/K8s。',
inputSchema: {
execute: z.boolean().default(false),
host: z.string().optional(),
port: z.number().int().min(1).max(65_535).default(2202),
services: z.array(z.string()).default([]),
sshTarget: z.string().optional(),
},
title: 'KT Remote Health Check',
},
async (input) => response(await buildRemoteHealthCheck(input)),
);
server.registerTool(
'kt_db_sync_plan',
{
description: '生成 KT 数据库同步安全向导:源/目标确认、GTID 规避、目标备份、行数校验和通过后删除备份库。',
inputSchema: {
backupName: z.string().optional(),
source: z.enum(['local', 'remote']).default('local'),
target: z.enum(['local', 'remote']).default('remote'),
},
title: 'KT DB Sync Plan',
},
async (input) => response(buildDbSyncPlan(input)),
);
server.registerTool(
'kt_component_workflow',
{
description: '按 KT 专项组件/链路输出防踩坑工作流KtTable、BlogArgon、AdminAuth、QQBot、FF14Plugin、NapCatLogin、SystemLog、Knife4jSwagger、FnosK8s。',
inputSchema: {
target: z
.enum([
'AdminAuth',
'BlogArgon',
'FF14Plugin',
'FnosK8s',
'Knife4jSwagger',
'KtTable',
'NapCatLogin',
'QQBot',
'SystemLog',
])
.default('KtTable'),
},
title: 'KT Component Workflow',
},
async (input) => response(buildComponentWorkflow(input)),
);
server.registerTool(
'kt_append_task_record',
{
description: '生成或写入 TASKS.md 改动记录。默认 dryRun=true只预览不落盘。',
inputSchema: {
content: z.string().optional(),
date: z.string().optional(),
dryRun: z.boolean().default(true),
scope: z.array(z.string()).default([]),
testCase: z.string().optional(),
title: z.string(),
verification: z.string().optional(),
},
title: 'Append KT Task Record',
},
async (input) => response(appendTaskRecord(input)),
);
server.registerTool(
'kt_commit_checklist',
{
description: '生成 KT 子仓库提交前检查清单,并校验 commit message 是否符合约定。',
inputSchema: {
message: z.string().optional(),
project: z.string().default('root'),
},
title: 'KT Commit Checklist',
},
async (input) => response(await createCommitChecklist(input)),
);
}