mirror of https://github.com/openclaw/openclaw.git
98 lines
2.8 KiB
TypeScript
98 lines
2.8 KiB
TypeScript
import { loadConfig } from "../config/config.js";
|
|
import {
|
|
buildMcpToolSchema,
|
|
type McpLoopbackTool,
|
|
type McpToolSchemaEntry,
|
|
} from "./mcp-http.schema.js";
|
|
import { resolveGatewayScopedTools } from "./tool-resolution.js";
|
|
|
|
const TOOL_CACHE_TTL_MS = 30_000;
|
|
const NATIVE_TOOL_EXCLUDE = new Set(["read", "write", "edit", "apply_patch", "exec", "process"]);
|
|
|
|
export type McpLoopbackRuntime = {
|
|
port: number;
|
|
token: string;
|
|
};
|
|
|
|
type CachedScopedTools = {
|
|
tools: McpLoopbackTool[];
|
|
toolSchema: McpToolSchemaEntry[];
|
|
configRef: ReturnType<typeof loadConfig>;
|
|
time: number;
|
|
};
|
|
|
|
let activeRuntime: McpLoopbackRuntime | undefined;
|
|
|
|
export class McpLoopbackToolCache {
|
|
#entries = new Map<string, CachedScopedTools>();
|
|
|
|
resolve(params: {
|
|
cfg: ReturnType<typeof loadConfig>;
|
|
sessionKey: string;
|
|
messageProvider: string | undefined;
|
|
accountId: string | undefined;
|
|
}): CachedScopedTools {
|
|
const cacheKey = [params.sessionKey, params.messageProvider ?? "", params.accountId ?? ""].join(
|
|
"\u0000",
|
|
);
|
|
const now = Date.now();
|
|
const cached = this.#entries.get(cacheKey);
|
|
if (cached && cached.configRef === params.cfg && now - cached.time < TOOL_CACHE_TTL_MS) {
|
|
return cached;
|
|
}
|
|
|
|
const next = resolveGatewayScopedTools({
|
|
cfg: params.cfg,
|
|
sessionKey: params.sessionKey,
|
|
messageProvider: params.messageProvider,
|
|
accountId: params.accountId,
|
|
excludeToolNames: NATIVE_TOOL_EXCLUDE,
|
|
});
|
|
const nextEntry: CachedScopedTools = {
|
|
tools: next.tools,
|
|
toolSchema: buildMcpToolSchema(next.tools),
|
|
configRef: params.cfg,
|
|
time: now,
|
|
};
|
|
this.#entries.set(cacheKey, nextEntry);
|
|
for (const [key, entry] of this.#entries) {
|
|
if (now - entry.time >= TOOL_CACHE_TTL_MS) {
|
|
this.#entries.delete(key);
|
|
}
|
|
}
|
|
return nextEntry;
|
|
}
|
|
}
|
|
|
|
export function getActiveMcpLoopbackRuntime(): McpLoopbackRuntime | undefined {
|
|
return activeRuntime ? { ...activeRuntime } : undefined;
|
|
}
|
|
|
|
export function setActiveMcpLoopbackRuntime(runtime: McpLoopbackRuntime): void {
|
|
activeRuntime = { ...runtime };
|
|
}
|
|
|
|
export function clearActiveMcpLoopbackRuntime(token: string): void {
|
|
if (activeRuntime?.token === token) {
|
|
activeRuntime = undefined;
|
|
}
|
|
}
|
|
|
|
export function createMcpLoopbackServerConfig(port: number) {
|
|
return {
|
|
mcpServers: {
|
|
openclaw: {
|
|
type: "http",
|
|
url: `http://127.0.0.1:${port}/mcp`,
|
|
headers: {
|
|
Authorization: "Bearer ${OPENCLAW_MCP_TOKEN}",
|
|
"x-session-key": "${OPENCLAW_MCP_SESSION_KEY}",
|
|
"x-openclaw-agent-id": "${OPENCLAW_MCP_AGENT_ID}",
|
|
"x-openclaw-account-id": "${OPENCLAW_MCP_ACCOUNT_ID}",
|
|
"x-openclaw-message-channel": "${OPENCLAW_MCP_MESSAGE_CHANNEL}",
|
|
},
|
|
},
|
|
},
|
|
};
|
|
}
|