ktworkflow-mcp/src/registerTools.ts

706 lines
28 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 { buildBlockerResolution } from './tools/blocker.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 { buildWorkflowLoopAudit } from './tools/loop.js';
import { readObsidianContext, syncObsidianWorkflow, validateObsidianVault } from './tools/obsidian.js';
import { buildGlobalCodeReview, defaultReviewProjects } from './tools/review.js';
import { appendTaskRecord, createCommitChecklist, prepareTask, readWorkflowContext } from './tools/task.js';
import {
buildBusinessTestPlan,
buildNapcatDeviceProfileCheck,
createApiTestPlan,
createPageTestCase,
} from './tools/testing.js';
import { buildVerificationPlan } from './tools/verification.js';
import { buildWorkstreamCloseout } from './tools/closeout.js';
import { buildChangeDocSync } from './tools/docSync.js';
import { buildDeployObservation } from './tools/deployObservation.js';
import {
buildNapcatRemoteDevHandoff,
buildNapcatRuntimeReleaseReadiness,
buildNapcatSyncCandidateReview,
buildNapcatUpstreamAudit,
buildNasCodexBootstrapPlan,
napcatAutomationDefaults,
} from './tools/napcatAutomation.js';
import { buildCommitPlan, buildComponentWorkflow, buildDbSyncPlan, buildFinishTask, buildPushPlan, buildRemoteHealthCheck } from './tools/workflow.js';
import { workstreamReusablePatternValues } from './core/constants.js';
export function response(data: unknown): McpTextResponse {
return {
content: [
{
text: typeof data === 'string' ? data : JSON.stringify(data, null, 2),
type: 'text',
},
],
};
}
/**
* Registers every ktWorkflow MCP tool against the provided MCP server instance.
* @param server - MCP SDK server that owns tool names, schemas, descriptions, and async handlers.
* @returns Nothing; handlers are attached to `server` for later stdio transport use.
*/
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 轮;可复用模板和参考资产应迁入 workspace-assets。',
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: '生成按项目路径和端口检查验证进程的 Debian Bash 只读命令,不直接杀进程。',
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_workstream_closeout',
{
description: '生成大方向完结闭环审计开发、测试证据、KT 全局 review、问题记录、稳定解法和 ktWorkflow 升级是否齐备。',
inputSchema: {
changedProjects: z.array(z.string()).default([]),
cleanupEvidence: z.array(z.string()).default([]),
cleanupFinalDeleted: z.number().int().min(0).optional(),
docSyncEvidence: z.array(z.string()).default([]),
ktWorkflowUpdated: z.boolean().default(false),
problemRecords: z.array(z.string()).default([]),
reviewEvidence: z.array(z.string()).default([]),
reusablePatterns: z.array(z.enum(workstreamReusablePatternValues)).default(['none']),
stableSolutions: z.array(z.string()).default([]),
title: z.string().optional(),
upgradeNotes: z.string().optional(),
verificationEvidence: z.array(z.string()).default([]),
},
title: 'KT Workstream Closeout',
},
async (input) => response(buildWorkstreamCloseout(input)),
);
server.registerTool(
'kt_workflow_loop_audit',
{
description: '审计 KT 自动化闭环上下文锚定、测试用例、验证证据、历史清理、问题固化、ktWorkflow 升级和 KT 全局 review 是否齐备。',
inputSchema: {
changedProjects: z.array(z.string()).default([]),
cleanupExecuted: z.boolean().default(false),
cleanupEvidence: z.array(z.string()).default([]),
cleanupFinalDeleted: z.number().int().min(0).optional(),
cleanupPreviewDeleted: z.number().int().min(0).optional(),
docSyncEvidence: z.array(z.string()).default([]),
failureRecords: z.array(z.string()).default([]),
ktWorkflowUpdated: z.boolean().default(false),
problemRecords: z.array(z.string()).default([]),
requireCompletion: z.boolean().default(true),
reusablePattern: z.boolean().default(false),
reviewEvidence: z.array(z.string()).default([]),
stableSolutions: z.array(z.string()).default([]),
stage: z.enum(['failure', 'finish', 'start', 'test']).default('finish'),
taskTitle: z.string().optional(),
testCases: z.array(z.string()).default([]),
verificationEvidence: z.array(z.string()).default([]),
},
title: 'KT Workflow Loop Audit',
},
async (input) => response(buildWorkflowLoopAudit(input)),
);
server.registerTool(
'kt_change_doc_sync',
{
description: '根据代码改动路径生成必须检查/同步的 README、API、AGENTS、docs、Obsidian、skill 和 ktWorkflow 文档入口。',
inputSchema: {
changedFiles: z.array(z.string()).default([]),
project: z.string().default('root'),
taskType: z.enum(taskTypeValues).optional(),
},
title: 'KT Change Doc Sync',
},
async (input) => response(await buildChangeDocSync(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_napcat_upstream_audit',
{
description:
'生成或执行 NapCatQQ 上游 release 审计:默认 dry-run只读输出 hot zone、fork patch overlap、dry merge 和 Codex 审计入口execute/useCodex 均需显式开启才会运行 Codex。',
inputSchema: {
artifactRoot: z
.string()
.default('.kt-workspace/test-artifacts/napcat-upstream-audit'),
codexHome: z.string().optional(),
createCandidateBranch: z.boolean().default(false),
dryMergeConflict: z.boolean().default(false),
execute: z.boolean().default(false),
forkBranch: z.string().default(napcatAutomationDefaults.forkBranch),
forkPatchFiles: z.array(z.string()).default([]),
forkRepo: z.string().default(napcatAutomationDefaults.forkRepo),
lastAcceptedUpstreamBase: z
.string()
.default(napcatAutomationDefaults.lastAcceptedUpstreamBase),
outputSchemaPath: z.string().optional(),
upstreamChangedFiles: z.array(z.string()).default([]),
upstreamReleaseTag: z.string().default(napcatAutomationDefaults.upstreamReleaseRef),
upstreamRepo: z.string().default(napcatAutomationDefaults.upstreamRepo),
useCodex: z.boolean().default(false),
workspaceRoot: z.string().default(napcatAutomationDefaults.workspaceRoot),
},
title: 'KT NapCat Upstream Audit',
},
async (input) => response(buildNapcatUpstreamAudit(input)),
);
server.registerTool(
'kt_napcat_sync_candidate_review',
{
description:
'生成 NapCatQQ sync candidate 人工/Codex 复审的 dry-run prompt、上下文和只读命令骨架Task 5 不执行 Codex 或 Git 写操作。',
inputSchema: {
artifactRoot: z
.string()
.default('.kt-workspace/test-artifacts/napcat-automation/sync-candidate-review'),
candidateBranch: z.string().default(napcatAutomationDefaults.candidateBranch),
execute: z.boolean().default(false),
forkBranch: z.string().default(napcatAutomationDefaults.forkBranch),
forkRepo: z.string().default(napcatAutomationDefaults.forkRepo),
lastAcceptedUpstreamBase: z
.string()
.default(napcatAutomationDefaults.lastAcceptedUpstreamBase),
upstreamReleaseTag: z.string().default(napcatAutomationDefaults.upstreamReleaseRef),
upstreamRepo: z.string().default(napcatAutomationDefaults.upstreamRepo),
useCodex: z.boolean().default(false),
workspaceRoot: z.string().default(napcatAutomationDefaults.workspaceRoot),
},
title: 'KT NapCat Sync Candidate Review',
},
async (input) => response(buildNapcatSyncCandidateReview(input)),
);
server.registerTool(
'kt_napcat_runtime_release_readiness',
{
description:
'生成 NapCat runtime release readiness dry-run prompt、上下文和只读检查骨架不自动构建镜像、不调用 kubectl、不发布。',
inputSchema: {
apiImageTag: z.string().default(napcatAutomationDefaults.apiImageTag),
artifactRoot: z
.string()
.default('.kt-workspace/test-artifacts/napcat-automation/runtime-release-readiness'),
candidateBranch: z.string().default(napcatAutomationDefaults.candidateBranch),
execute: z.boolean().default(false),
forkBranch: z.string().default(napcatAutomationDefaults.forkBranch),
forkRepo: z.string().default(napcatAutomationDefaults.forkRepo),
napcatImageTag: z.string().default(napcatAutomationDefaults.runtimeImageTag),
profile: z.string().default(napcatAutomationDefaults.runtimeProfile),
upstreamReleaseTag: z.string().default(napcatAutomationDefaults.upstreamReleaseRef),
upstreamRepo: z.string().default(napcatAutomationDefaults.upstreamRepo),
useCodex: z.boolean().default(false),
workspaceRoot: z.string().default(napcatAutomationDefaults.workspaceRoot),
},
title: 'KT NapCat Runtime Release Readiness',
},
async (input) => response(buildNapcatRuntimeReleaseReadiness(input)),
);
server.registerTool(
'kt_napcat_remote_dev_handoff',
{
description:
'生成 NapCat 自动化远程开发 handoff 的 dry-run prompt 和上下文骨架;不创建线程、不执行 Codex、不同步仓库。',
inputSchema: {
artifactRoot: z
.string()
.default('.kt-workspace/test-artifacts/napcat-automation/remote-dev-handoff'),
candidateBranch: z.string().default(napcatAutomationDefaults.candidateBranch),
execute: z.boolean().default(false),
forkBranch: z.string().default(napcatAutomationDefaults.forkBranch),
forkRepo: z.string().default(napcatAutomationDefaults.forkRepo),
targetHost: z.string().default(napcatAutomationDefaults.targetHost),
upstreamReleaseTag: z.string().default(napcatAutomationDefaults.upstreamReleaseRef),
upstreamRepo: z.string().default(napcatAutomationDefaults.upstreamRepo),
useCodex: z.boolean().default(false),
workspaceRoot: z.string().default(napcatAutomationDefaults.workspaceRoot),
},
title: 'KT NapCat Remote Dev Handoff',
},
async (input) => response(buildNapcatRemoteDevHandoff(input)),
);
server.registerTool(
'kt_nas_codex_bootstrap_plan',
{
description:
'生成可信 NAS Codex 自动化环境 bootstrap 的 dry-run planTask 5 仅输出只读检查和占位计划,不安装、不同步、不写 systemd。',
inputSchema: {
artifactRoot: z
.string()
.default('.kt-workspace/test-artifacts/napcat-automation/nas-codex-bootstrap'),
codexHome: z.string().default(napcatAutomationDefaults.codexHome),
execute: z.boolean().default(false),
serviceName: z.string().default(napcatAutomationDefaults.bootstrapServiceName),
workspaceRoot: z.string().default(napcatAutomationDefaults.workspaceRoot),
},
title: 'KT NAS Codex Bootstrap Plan',
},
async (input) => response(buildNasCodexBootstrapPlan(input)),
);
server.registerTool(
'kt_napcat_device_profile_check',
{
description:
'静态检查 API NapCat 设备身份护栏QQNT 可见 hostname、实体 OUI MAC、machine-info、runtime dir 和 DB_TIMEZONE。',
inputSchema: {
project: z.string().default('api'),
},
title: 'KT NapCat Device Profile Check',
},
async (input) => response(buildNapcatDeviceProfileCheck(input)),
);
server.registerTool(
'kt_blocker_resolution',
{
description: '生成或写入卡点固化记录:问题点、稳定解法、后续入口、验证证据,并给出停止原样重试的下一步动作。',
inputSchema: {
attempts: z.number().int().min(0).max(20).default(1),
command: z.string().optional(),
dryRun: z.boolean().default(true),
evidence: z.string().optional(),
nextEntry: z.string().optional(),
problem: z.string().optional(),
project: z.string().default('root'),
solution: z.string().optional(),
title: z.string().optional(),
},
title: 'KT Blocker Resolution',
},
async (input) => response(buildBlockerResolution(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_deploy_observation',
{
description:
'生成或执行 API 发布后的只读部署观测Jenkins、K8s Deployment、Pod、/health/runtime 和任务 smoke并输出运行态证据。',
inputSchema: {
artifactRoot: z.string().optional(),
buildNumber: z.string().optional(),
container: z.string().default('api'),
deployment: z.string().default('kt-template-online-api'),
execute: z.boolean().default(false),
expectedCommit: z.string().optional(),
healthUrl: z.string().default('http://127.0.0.1:48085/health/runtime'),
imageTag: z.string().optional(),
jenkinsHome: z.string().default('/vol1/docker/jenkins/jenkins_home'),
jobName: z.string().default('KT-Template/KT-Template-API/main'),
kubeconfigPath: z
.string()
.default('/vol1/docker/kt-k8s/kubeconfig/kt-nas.jenkins.yaml'),
namespace: z.string().default('kt-prod'),
project: z.string().default('api'),
selector: z.string().default('app=kt-template-online-api'),
smoke: z.string().optional(),
sshPort: z.number().int().min(1).max(65_535).optional(),
sshTarget: z.string().default('nas'),
},
title: 'KT Deploy Observation',
},
async (input) => response(await buildDeployObservation(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_obsidian_context',
{
description: '读取 KT Obsidian 索引上下文:总入口、模块索引、文档矩阵、工作流关系,并可按 module/query 定向返回相关模块页摘要。',
inputSchema: {
includeCanvas: z.boolean().default(true),
includeContent: z.boolean().default(true),
maxDocuments: z.number().int().min(1).max(30).default(8),
module: z.string().optional(),
query: z.string().optional(),
},
title: 'KT Obsidian Context',
},
async (input) => response(readObsidianContext(input)),
);
server.registerTool(
'kt_obsidian_validate',
{
description: '只读校验 KT Obsidian vaultJSON、Canvas、Base、Wiki 链接、Markdown 相对链接和旧引用。',
inputSchema: {
checkLayout: z.boolean().default(true),
failOnWarnings: z.boolean().default(false),
includeMarkdownLinks: z.boolean().default(true),
includeStaleReferences: z.boolean().default(true),
},
title: 'KT Obsidian Validate',
},
async (input) => response(validateObsidianVault(input)),
);
server.registerTool(
'kt_obsidian_sync',
{
description: '审计 KT Obsidian 工作流入口是否连通:必备文档、书签、核心插件、忽略目录和校验结果。',
inputSchema: {
checkLayout: z.boolean().default(true),
failOnWarnings: z.boolean().default(false),
includeMarkdownLinks: z.boolean().default(true),
includeStaleReferences: z.boolean().default(true),
includeValidation: z.boolean().default(true),
},
title: 'KT Obsidian Sync',
},
async (input) => response(syncObsidianWorkflow(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)),
);
}