Files
Arcrun/mcp/src/tools/u6u_search_workflows.ts
T
uncle6me-web 934b9265d9 feat: KBDB self-hosted 查詢 + embed 模組 + thin-shell 收窄 + search_workflow(code done 待端到端)
按 issue 分段標明(檔 #5/#8 改動交疊處無法乾淨拆檔,故併一個 commit):

#4 thin-shell §3.1 自力救濟階梯 + code-node 規則(純文檔/規則,code-node 零件未實作)
#5 KBDB source filter(json_extract metadata_json 零建表)+ 能力對照;documents 聚合與
   DELETE proxy 部分擱置等頂層 T8
#7 base embed 模組(kbdb/src/embed.ts)+ vectorize 開關(deploy/config/wrangler.toml 註解範本)
   + 語義查詢降級閉環(mode=semantic 未開→LIKE+capability_hint)
#8 部分(workflow-discovery):
   - KBDB /entries/search 加 base 通用 entry_type filter(entry-crud/embed/route/kbdb-proxy 透傳)
   - /webhooks/named 強制 description(空→400,訊息要求操盤 AI 據實寫一句)
   - 部署雙寫 entry_type=workflow embeddable entry(waitUntil 非阻塞,供 search)
   - cypher GET /workflows/search + MCP u6u_search_workflows(優先語意、降級 hint)
   - cypher POST /workflows/backfill-search-entries(無 desc 列出不編造)
   - GET /webhooks/named 補回 description/created_at 欄位(為 list 來源收斂備)

⚠️ tsc 綠 = code done,非完成(mindset §7 禁假綠):
- #7/#8 端到端待 leo21c 部署驗(Vectorize 需官方憑證、CC 跑不了)
- #8 ①-a(MCP deploy 改打 /webhooks/named)未做、MCP deploy 那半仍 404
- #8 端到端(強制填擋空/語義命中/租戶隔離/降級 hint)未驗

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 17:52:52 +08:00

87 lines
3.4 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 { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
import { Env } from "../types.js";
/**
* u6u_search_workflows — 用自然語言找現成工作流(workflow-discovery R2
*
* 北極星入口:AI 先查「有沒有現成工作流能做這件事」→ 找到就執行,別重造。
* 呼叫 cypher GET /workflows/search → 轉發 KBDB /entries/searchentry_type=workflow + 本租戶)。
* 優先語意搜尋;KBDB 未開 Vectorize → 自動降級關鍵字 + 回 capability_hint(不假裝語義)。
*
* 薄殼(rule 07):只做參數轉換 + 呼叫 + 格式化,零業務邏輯。形態對齊 u6u_search_components。
* flag 安全:AI 收到意圖時主動 call 一次,無輪詢/排程。
*/
export function registerSearchWorkflows(
server: McpServer,
env: Env,
orgNamespace: string,
partnerToken: string,
) {
server.tool(
"u6u_search_workflows",
"用自然語言找現成的工作流(先查有沒有現成的能做這件事,找到就用,別重造)。例如:「把資料寫進 Google Sheets」、「每天抓 RSS 發通知」、「webhook 轉發到別的 API」。回傳本帳號下符合的工作流清單。",
{
query: z.string().describe("自然語言描述要找的工作流,如「把資料寫進 Google Sheets」"),
},
async ({ query }) => {
try {
if (!env.CYPHER_EXECUTOR) {
return {
content: [{ type: "text", text: "Error: CYPHER_EXECUTOR service binding is not configured." }],
isError: true,
};
}
const response = await env.CYPHER_EXECUTOR.fetch(
`http://cypher-executor/workflows/search?q=${encodeURIComponent(query)}`,
{ method: "GET", headers: { "X-Arcrun-API-Key": partnerToken } },
);
if (!response.ok) {
const errorText = await response.text();
return {
content: [{ type: "text", text: `Search failed: ${errorText}` }],
isError: true,
};
}
const result = await response.json() as {
entries?: Array<{ page_name?: string; content?: string }>;
count?: number;
mode?: string;
capability_hint?: string;
};
const entries = result.entries ?? [];
const count = result.count ?? entries.length;
if (count === 0) {
const hint = result.capability_hint ? `\n\n${result.capability_hint}` : "";
return {
content: [{
type: "text",
text: `找不到符合「${query}」的現成工作流。可以用 u6u_deploy_workflow 部署一個新的。${hint}`,
}],
};
}
// capability_hint 透傳給 AI:未開語義時 AI 看到就能主動問用戶要不要開 Vectorize(R2.3 閉環)。
const hintLine = result.capability_hint
? `\n\n⚠️ ${result.capability_hint}`
: "";
return {
content: [{
type: "text",
text: `找到 ${count} 個工作流(mode: ${result.mode ?? "keyword"}):\n${JSON.stringify(entries, null, 2)}${hintLine}`,
}],
};
} catch (error) {
return {
content: [{ type: "text", text: `Internal Error: ${error instanceof Error ? error.message : String(error)}` }],
isError: true,
};
}
}
);
}