MCP kbdb_create_record 注入 org_namespace 為 owner_id,配合 base owner-mandatory
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ck8bjuBTLFkiFxqLGHMpqG
This commit is contained in:
@@ -26,11 +26,18 @@ import type { Env } from "../types.js";
|
||||
import { kbdbFetch } from "../lib/kbdb-client.js";
|
||||
import { errorResponse, successResponse } from "../lib/cypher-client.js";
|
||||
|
||||
/** 註冊全部 KBDB 資料層工具(kbdb-base Phase 9.1)。不含建表/SQL tool(鐵律)。 */
|
||||
export function registerAllKbdbDataTools(server: McpServer, env: Env) {
|
||||
/**
|
||||
* 註冊全部 KBDB 資料層工具(kbdb-base Phase 9.1)。不含建表/SQL tool(鐵律)。
|
||||
*
|
||||
* D28(owner-mandatory):base 的 `POST /records` 已把 owner_id 設必填(缺 → 400)。
|
||||
* MCP 是薄殼、是 caller——owner **由機制注入**(org namespace),不靠 AI 記得帶。
|
||||
* 仿 arcrun_report_feedback:把 orgNamespace 傳進寫入 tool,寫入時當 owner_id。
|
||||
* 送到 base 的 owner_id 一定非空 → AI 漏不了。
|
||||
*/
|
||||
export function registerAllKbdbDataTools(server: McpServer, env: Env, orgNamespace: string) {
|
||||
registerCreateTemplate(server, env);
|
||||
registerListTemplates(server, env);
|
||||
registerCreateRecord(server, env);
|
||||
registerCreateRecord(server, env, orgNamespace);
|
||||
registerGetRecord(server, env);
|
||||
registerQuery(server, env);
|
||||
registerSearch(server, env);
|
||||
@@ -92,8 +99,16 @@ export function registerListTemplates(server: McpServer, env: Env) {
|
||||
);
|
||||
}
|
||||
|
||||
/** kbdb_create_record — 依某 template 填一筆 record(slot → 內容)。 */
|
||||
export function registerCreateRecord(server: McpServer, env: Env) {
|
||||
/**
|
||||
* kbdb_create_record — 依某 template 填一筆 record(slot → 內容)。
|
||||
*
|
||||
* D28(owner-mandatory):base 的 `POST /records` owner_id 必填(缺 → 400)。
|
||||
* owner_id 由 MCP **機制注入**(orgNamespace),不靠 AI 帶:
|
||||
* - AI 傳的 owner_id 當「選填覆寫」(想歸到別的租戶/專案時才用)。
|
||||
* - AI 沒傳 → 用注入的 orgNamespace。
|
||||
* - 兩者皆空 → 直接回錯(不送必然 400 的請求),保證送到 base 的 owner_id 一定非空。
|
||||
*/
|
||||
export function registerCreateRecord(server: McpServer, env: Env, orgNamespace: string) {
|
||||
server.tool(
|
||||
"kbdb_create_record",
|
||||
"依某 template 填一筆 record(一列資料)。values 是 {slot名: 內容},slot 名要對得上 template 的 slots。" +
|
||||
@@ -101,14 +116,23 @@ export function registerCreateRecord(server: McpServer, env: Env) {
|
||||
{
|
||||
template: z.string().min(1).describe("template 的 name 或 id"),
|
||||
values: z.record(z.string()).describe("欄位內容 {slot名: 字串內容},如 {name:'Leo', email:'leo@x.com'}"),
|
||||
owner_id: z.string().optional().describe("資料歸屬標記(選填,如專案 id / 用戶 id)"),
|
||||
owner_id: z.string().optional().describe("資料歸屬標記(選填;預設用你的 org namespace,想歸到別的租戶/專案才傳)"),
|
||||
},
|
||||
async ({ template, values, owner_id }) => {
|
||||
try {
|
||||
// 機制注入:AI 傳的 owner_id 覆寫,缺則用 orgNamespace。兩者皆空 → 拒送(避免必然 400)。
|
||||
const resolvedOwner = (owner_id && owner_id.trim()) || orgNamespace;
|
||||
if (!resolvedOwner) {
|
||||
return errorResponse(
|
||||
"owner_missing",
|
||||
"無法決定 owner_id:AI 未傳 owner_id 且 org namespace 為空",
|
||||
["確認 MCP 連線帶了有效的 Authorization(org namespace)", "或明確傳入 owner_id"],
|
||||
);
|
||||
}
|
||||
const res = await kbdbFetch(env, "/records", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ template, values, owner_id }),
|
||||
body: JSON.stringify({ template, values, owner_id: resolvedOwner }),
|
||||
});
|
||||
if (!res.ok) {
|
||||
return errorResponse("create_record_failed", `填 record 失敗`, [
|
||||
|
||||
Reference in New Issue
Block a user