Files
dukang/server/dukang-api/src/integrations/wecom/wecom-plugin-mcp.tools.ts
T

248 lines
9.3 KiB
TypeScript

import { WECOM_PLUGIN_MCP_TOOL_META, type WecomPluginMcpToolName } from '@dukang/shared-types';
import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
import { z } from 'zod';
import { wecomPluginMcpErrorText, wecomPluginQueryArg } from './wecom-plugin.util';
import type { WecomPluginQueryService } from './wecom-plugin-query.service';
import type { WecomPluginRuntime } from './wecom-plugin.types';
const q = (description: string) => z.string().describe(description);
const page = z.number().int().min(1).optional().describe('页码,默认 1');
const pageSize = z.number().int().min(1).max(10).optional().describe('每页条数,默认 5,最大 10');
const from = z.string().optional().describe('起始日期 YYYY-MM-DD 或 ISO');
const to = z.string().optional().describe('结束日期 YYYY-MM-DD 或 ISO(含当天)');
const auditStatus = z
.enum(['PENDING', 'APPROVED', 'REJECTED'])
.optional()
.describe('审核状态,默认 PENDING');
export type WecomPluginMcpToolContext = {
query: WecomPluginQueryService;
plugin: WecomPluginRuntime;
wecomUserId: string;
};
async function jsonResult(run: () => Promise<unknown>): Promise<CallToolResult> {
try {
const data = await run();
return { content: [{ type: 'text', text: JSON.stringify(data) }] };
} catch (e) {
return { content: [{ type: 'text', text: wecomPluginMcpErrorText(e) }], isError: true };
}
}
type ToolDef = {
name: WecomPluginMcpToolName;
description: string;
inputSchema: Record<string, z.ZodTypeAny>;
invoke: (ctx: WecomPluginMcpToolContext, args: Record<string, unknown>) => Promise<CallToolResult>;
};
function str(args: Record<string, unknown>, key: string): string | undefined {
return wecomPluginQueryArg(args[key] as string | number | undefined);
}
export const WECOM_PLUGIN_MCP_TOOL_DEFS: ToolDef[] = [
{
name: 'query_orders',
description: WECOM_PLUGIN_MCP_TOOL_META.query_orders.description,
inputSchema: { q: q('订单号,如 DK20260903xxxx'), page, pageSize },
invoke: (ctx, args) =>
jsonResult(() => ctx.query.queryOrders(ctx.plugin, ctx.wecomUserId, str(args, 'q'), str(args, 'page'), str(args, 'pageSize'))),
},
{
name: 'query_users',
description: WECOM_PLUGIN_MCP_TOOL_META.query_users.description,
inputSchema: { q: q('用户号或 11 位手机号'), page, pageSize },
invoke: (ctx, args) =>
jsonResult(() => ctx.query.queryUsers(ctx.plugin, ctx.wecomUserId, str(args, 'q'), str(args, 'page'), str(args, 'pageSize'))),
},
{
name: 'query_stores',
description: WECOM_PLUGIN_MCP_TOOL_META.query_stores.description,
inputSchema: { q: q('门店名称关键词'), page, pageSize },
invoke: (ctx, args) =>
jsonResult(() => ctx.query.queryStores(ctx.plugin, ctx.wecomUserId, str(args, 'q'), str(args, 'page'), str(args, 'pageSize'))),
},
{
name: 'query_redeems',
description: WECOM_PLUGIN_MCP_TOOL_META.query_redeems.description,
inputSchema: { q: q('核销单号或门店名'), page, pageSize },
invoke: (ctx, args) =>
jsonResult(() => ctx.query.queryRedeems(ctx.plugin, ctx.wecomUserId, str(args, 'q'), str(args, 'page'), str(args, 'pageSize'))),
},
{
name: 'query_promo_codes',
description: WECOM_PLUGIN_MCP_TOOL_META.query_promo_codes.description,
inputSchema: { q: q('推广码或名称'), page, pageSize },
invoke: (ctx, args) =>
jsonResult(() =>
ctx.query.queryPromoCodes(ctx.plugin, ctx.wecomUserId, str(args, 'q'), str(args, 'page'), str(args, 'pageSize')),
),
},
{
name: 'query_promo_code_stats',
description: WECOM_PLUGIN_MCP_TOOL_META.query_promo_code_stats.description,
inputSchema: { code: q('推广码 code') },
invoke: (ctx, args) => jsonResult(() => ctx.query.queryPromoCodeStats(ctx.plugin, ctx.wecomUserId, str(args, 'code'))),
},
{
name: 'query_metrics',
description: WECOM_PLUGIN_MCP_TOOL_META.query_metrics.description,
inputSchema: {
kind: z.enum(['today', 'daily', 'weekly', 'monthly']).optional().describe('默认 today'),
},
invoke: (ctx, args) => jsonResult(() => ctx.query.queryMetrics(ctx.plugin, ctx.wecomUserId, str(args, 'kind'))),
},
{
name: 'query_store_audits',
description: WECOM_PLUGIN_MCP_TOOL_META.query_store_audits.description,
inputSchema: { q: z.string().optional().describe('门店名称'), status: auditStatus, page, pageSize },
invoke: (ctx, args) =>
jsonResult(() =>
ctx.query.queryStoreAudits(
ctx.plugin,
ctx.wecomUserId,
str(args, 'q'),
str(args, 'status'),
str(args, 'page'),
str(args, 'pageSize'),
),
),
},
{
name: 'query_store_info_audits',
description: WECOM_PLUGIN_MCP_TOOL_META.query_store_info_audits.description,
inputSchema: { status: auditStatus, page, pageSize },
invoke: (ctx, args) =>
jsonResult(() =>
ctx.query.queryStoreInfoAudits(ctx.plugin, ctx.wecomUserId, str(args, 'status'), str(args, 'page'), str(args, 'pageSize')),
),
},
{
name: 'query_store_info_audit_detail',
description: WECOM_PLUGIN_MCP_TOOL_META.query_store_info_audit_detail.description,
inputSchema: { id: q('信息变更审核 ID') },
invoke: (ctx, args) =>
jsonResult(() => ctx.query.queryStoreInfoAuditDetail(ctx.plugin, ctx.wecomUserId, str(args, 'id') ?? '')),
},
{
name: 'query_store_package_audits',
description: WECOM_PLUGIN_MCP_TOOL_META.query_store_package_audits.description,
inputSchema: { status: auditStatus, page, pageSize },
invoke: (ctx, args) =>
jsonResult(() =>
ctx.query.queryStorePackageAudits(ctx.plugin, ctx.wecomUserId, str(args, 'status'), str(args, 'page'), str(args, 'pageSize')),
),
},
{
name: 'query_store_package_audit_detail',
description: WECOM_PLUGIN_MCP_TOOL_META.query_store_package_audit_detail.description,
inputSchema: { id: q('套餐审核 ID') },
invoke: (ctx, args) =>
jsonResult(() => ctx.query.queryStorePackageAuditDetail(ctx.plugin, ctx.wecomUserId, str(args, 'id') ?? '')),
},
{
name: 'query_partners',
description: WECOM_PLUGIN_MCP_TOOL_META.query_partners.description,
inputSchema: { q: q('合伙人关键词'), page, pageSize },
invoke: (ctx, args) =>
jsonResult(() =>
ctx.query.queryPartners(ctx.plugin, ctx.wecomUserId, str(args, 'q'), str(args, 'page'), str(args, 'pageSize')),
),
},
{
name: 'query_partner_users',
description: WECOM_PLUGIN_MCP_TOOL_META.query_partner_users.description,
inputSchema: { partnerId: q('合伙人 ID'), from, to, page, pageSize },
invoke: (ctx, args) =>
jsonResult(() =>
ctx.query.queryPartnerUsers(
ctx.plugin,
ctx.wecomUserId,
str(args, 'partnerId') ?? '',
str(args, 'from'),
str(args, 'to'),
str(args, 'page'),
str(args, 'pageSize'),
),
),
},
{
name: 'query_partner_stores',
description: WECOM_PLUGIN_MCP_TOOL_META.query_partner_stores.description,
inputSchema: { partnerId: q('合伙人 ID'), from, to, page, pageSize },
invoke: (ctx, args) =>
jsonResult(() =>
ctx.query.queryPartnerStores(
ctx.plugin,
ctx.wecomUserId,
str(args, 'partnerId') ?? '',
str(args, 'from'),
str(args, 'to'),
str(args, 'page'),
str(args, 'pageSize'),
),
),
},
{
name: 'query_partner_orders',
description: WECOM_PLUGIN_MCP_TOOL_META.query_partner_orders.description,
inputSchema: { partnerId: q('合伙人 ID'), from, to, page, pageSize },
invoke: (ctx, args) =>
jsonResult(() =>
ctx.query.queryPartnerOrders(
ctx.plugin,
ctx.wecomUserId,
str(args, 'partnerId') ?? '',
str(args, 'from'),
str(args, 'to'),
str(args, 'page'),
str(args, 'pageSize'),
),
),
},
{
name: 'query_versions',
description: WECOM_PLUGIN_MCP_TOOL_META.query_versions.description,
inputSchema: {
q: z.string().optional().describe('版本号关键词,如 v3.5.18'),
status: z
.enum(['PENDING', 'IN_PROGRESS', 'TESTING', 'RELEASED', 'STOPPED'])
.optional()
.describe('版本状态:待启动/开发中/测试/已上线/已停止'),
page,
pageSize,
},
invoke: (ctx, args) =>
jsonResult(() =>
ctx.query.queryVersions(ctx.plugin, ctx.wecomUserId, str(args, 'q'), str(args, 'status'), str(args, 'page'), str(args, 'pageSize')),
),
},
{
name: 'query_tasks',
description: WECOM_PLUGIN_MCP_TOOL_META.query_tasks.description,
inputSchema: {
status: z
.enum(['TODO', 'IN_PROGRESS', 'DEVELOPED', 'RELEASED', 'STOPPED'])
.optional()
.describe('任务状态:TODO 待开发、IN_PROGRESS 开发中、DEVELOPED 已开发、RELEASED 已上线、STOPPED 已停止'),
q: z.string().optional().describe('任务编号或内容关键词'),
versionNo: z.string().optional().describe('限定某版本号,如 v3.5.18'),
page,
pageSize,
},
invoke: (ctx, args) =>
jsonResult(() =>
ctx.query.queryTasks(
ctx.plugin,
ctx.wecomUserId,
str(args, 'q'),
str(args, 'status'),
str(args, 'versionNo'),
str(args, 'page'),
str(args, 'pageSize'),
),
),
},
];