fix(cli): MCP self-hosted discovery + config setup
- deploy.ts: discoverWorkerDirs 掃 mcp worker + 回傳 mcpUrl(對內 /mcp 端點) - init.ts: initSelfHosted 寫入 config.mcp_url + 重跑 cmdMcpSetup - config.ts: DEFAULT_MCP_URL 補 /mcp 後綴 Fixes mcp-account-source §3:self-hosted .mcp.json 必須指自己的 mcp worker,避免連官方失敗。 Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -227,6 +227,9 @@ async function initSelfHosted(
|
|||||||
const deploy = await downloadAndDeploy(deployCtx);
|
const deploy = await downloadAndDeploy(deployCtx);
|
||||||
const cypherUrl = deploy.cypherExecutorUrl
|
const cypherUrl = deploy.cypherExecutorUrl
|
||||||
?? (workerSubdomain ? `https://arcrun-cypher-executor.${workerSubdomain}.workers.dev` : '');
|
?? (workerSubdomain ? `https://arcrun-cypher-executor.${workerSubdomain}.workers.dev` : '');
|
||||||
|
// self-hosted 自己的 MCP worker URL(mcp-account-source §3:.mcp.json 指自己,不 fallback 官方)。
|
||||||
|
const mcpUrl = deploy.mcpUrl
|
||||||
|
?? (workerSubdomain ? `https://arcrun-mcp.${workerSubdomain}.workers.dev/mcp` : '');
|
||||||
// 誠實回報部署結果;但**不**用「全部成功」字串 gate 後續 seed(壓測 §4.1:
|
// 誠實回報部署結果;但**不**用「全部成功」字串 gate 後續 seed(壓測 §4.1:
|
||||||
// registry 一個無關 worker 失敗就連坐讓 seed 永遠被跳過)。seed 只看 cypher-executor 是否可達。
|
// registry 一個無關 worker 失敗就連坐讓 seed 永遠被跳過)。seed 只看 cypher-executor 是否可達。
|
||||||
const deployFullyOk = /全部成功/.test(deploy.message);
|
const deployFullyOk = /全部成功/.test(deploy.message);
|
||||||
@@ -238,6 +241,7 @@ async function initSelfHosted(
|
|||||||
cloudflare_account_id: accountId,
|
cloudflare_account_id: accountId,
|
||||||
cf_api_token: cfApiToken,
|
cf_api_token: cfApiToken,
|
||||||
cypher_executor_url: cypherUrl,
|
cypher_executor_url: cypherUrl,
|
||||||
|
mcp_url: mcpUrl || undefined, // 指自己的 MCP(mcp-account-source §3),無 subdomain 才留空 fallback 官方
|
||||||
webhooks_kv_namespace_id: kvNamespaceIds['WEBHOOKS'],
|
webhooks_kv_namespace_id: kvNamespaceIds['WEBHOOKS'],
|
||||||
credentials_kv_namespace_id: kvNamespaceIds['CREDENTIALS_KV'],
|
credentials_kv_namespace_id: kvNamespaceIds['CREDENTIALS_KV'],
|
||||||
multi_tenant: false,
|
multi_tenant: false,
|
||||||
@@ -245,6 +249,14 @@ async function initSelfHosted(
|
|||||||
saveConfig(config);
|
saveConfig(config);
|
||||||
createCredentialsYamlIfMissing();
|
createCredentialsYamlIfMissing();
|
||||||
|
|
||||||
|
// 6.5 config 寫好後重寫 .mcp.json,讓它指向「自己的」MCP(init 開頭的 cmdMcpSetup 在 config 前跑,
|
||||||
|
// 那時 mcp_url 還沒設 → 會 fallback 官方;這裡 config 已含自己的 mcp_url,重跑一次蓋成自己的)。
|
||||||
|
try {
|
||||||
|
cmdMcpSetup();
|
||||||
|
} catch (e) {
|
||||||
|
console.log(chalk.gray(` (.mcp.json 重寫略過:${e instanceof Error ? e.message : e})`));
|
||||||
|
}
|
||||||
|
|
||||||
// 6. seed recipe(薄殼:呼叫 API 的 /init/seed 一次,由 API 灌 API recipe + auth recipe)。
|
// 6. seed recipe(薄殼:呼叫 API 的 /init/seed 一次,由 API 灌 API recipe + auth recipe)。
|
||||||
// 只要 cypher-executor 可達就 seed——不被無關 worker(registry)的失敗連坐(壓測 §4.1)。
|
// 只要 cypher-executor 可達就 seed——不被無關 worker(registry)的失敗連坐(壓測 §4.1)。
|
||||||
if (cypherUrl) {
|
if (cypherUrl) {
|
||||||
|
|||||||
@@ -65,7 +65,8 @@ const ENV_MAP: Record<string, keyof ArcrunConfig> = {
|
|||||||
* 平台預設 MCP URL(mcp_url 未設時的 fallback,SaaS 用戶用)。
|
* 平台預設 MCP URL(mcp_url 未設時的 fallback,SaaS 用戶用)。
|
||||||
* MCP 搬進 arcrun 主庫後改用 arcrun.dev zone(mcp/wrangler.toml route = mcp.arcrun.dev)。
|
* MCP 搬進 arcrun 主庫後改用 arcrun.dev zone(mcp/wrangler.toml route = mcp.arcrun.dev)。
|
||||||
*/
|
*/
|
||||||
export const DEFAULT_MCP_URL = 'https://mcp.arcrun.dev';
|
// MCP streamable-http 端點是 /mcp(根路徑 404)。少了 /mcp → client 連線 Failed。
|
||||||
|
export const DEFAULT_MCP_URL = 'https://mcp.arcrun.dev/mcp';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 公庫 URL(recipe pull/search/submit-p 的對象,kbdb-base §7.5)。
|
* 公庫 URL(recipe pull/search/submit-p 的對象,kbdb-base §7.5)。
|
||||||
|
|||||||
+11
-1
@@ -53,6 +53,7 @@ export interface DeployContext {
|
|||||||
export interface DeployResult {
|
export interface DeployResult {
|
||||||
implemented: boolean;
|
implemented: boolean;
|
||||||
cypherExecutorUrl?: string;
|
cypherExecutorUrl?: string;
|
||||||
|
mcpUrl?: string; // self-hosted 自己的 MCP worker URL(mcp-account-source §3)
|
||||||
message: string;
|
message: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,11 +133,17 @@ export async function downloadAndDeploy(ctx: DeployContext, ref = 'main'): Promi
|
|||||||
const cypherExecutorUrl = ctx.workerSubdomain
|
const cypherExecutorUrl = ctx.workerSubdomain
|
||||||
? `https://arcrun-cypher-executor.${ctx.workerSubdomain}.workers.dev`
|
? `https://arcrun-cypher-executor.${ctx.workerSubdomain}.workers.dev`
|
||||||
: undefined;
|
: undefined;
|
||||||
|
// self-hosted 自己的 MCP worker URL(mcp-account-source §3:.mcp.json 指自己)。
|
||||||
|
// 端點是 /mcp(streamable http;根路徑 404)。仿 cypher 用 WORKER_SUBDOMAIN 組。
|
||||||
|
const mcpUrl = ctx.workerSubdomain
|
||||||
|
? `https://arcrun-mcp.${ctx.workerSubdomain}.workers.dev/mcp`
|
||||||
|
: undefined;
|
||||||
|
|
||||||
if (failures.length > 0) {
|
if (failures.length > 0) {
|
||||||
return {
|
return {
|
||||||
implemented: true,
|
implemented: true,
|
||||||
cypherExecutorUrl,
|
cypherExecutorUrl,
|
||||||
|
mcpUrl,
|
||||||
message:
|
message:
|
||||||
`部署 ${deployed}/${tier1.length + tier2.length} 成功,${failures.length} 失敗(誠實回報,未假綠):\n` +
|
`部署 ${deployed}/${tier1.length + tier2.length} 成功,${failures.length} 失敗(誠實回報,未假綠):\n` +
|
||||||
failures.map(f => ` ✗ ${f}`).join('\n'),
|
failures.map(f => ` ✗ ${f}`).join('\n'),
|
||||||
@@ -146,6 +153,7 @@ export async function downloadAndDeploy(ctx: DeployContext, ref = 'main'): Promi
|
|||||||
return {
|
return {
|
||||||
implemented: true,
|
implemented: true,
|
||||||
cypherExecutorUrl,
|
cypherExecutorUrl,
|
||||||
|
mcpUrl,
|
||||||
message: `部署完成:${deployed} 個 Worker 全部成功。`,
|
message: `部署完成:${deployed} 個 Worker 全部成功。`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -211,7 +219,9 @@ function discoverWorkerDirs(root: string): { tier1: string[]; tier2: string[] }
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const name of ['cypher-executor', 'registry']) {
|
// self-hosted 也部署自己的 MCP worker(mcp-account-source §5c:codeload 主庫即得 MCP,
|
||||||
|
// .mcp.json 指自己的 mcp 而非官方 mcp.arcrun.dev)。
|
||||||
|
for (const name of ['cypher-executor', 'registry', 'mcp']) {
|
||||||
const dir = join(root, name);
|
const dir = join(root, name);
|
||||||
if (existsSync(join(dir, 'wrangler.toml'))) tier2.push(dir);
|
if (existsSync(join(dir, 'wrangler.toml'))) tier2.push(dir);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user