import crypto from "node:crypto"; import type { AgentToolResult } from "@mariozechner/pi-agent-core"; import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { logWarn } from "../logger.js"; import { setPluginToolMeta } from "../plugins/tools.js"; import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js"; import {
buildSafeToolName,
normalizeReservedToolNames,
TOOL_NAME_SEPARATOR,
} from "./pi-bundle-mcp-names.js"; import type { BundleMcpToolRuntime, SessionMcpRuntime } from "./pi-bundle-mcp-types.js"; import type { AnyAgentTool } from "./tools/common.js";
for (const tool of sortedCatalogTools) { const originalName = tool.toolName.trim(); if (!originalName) { continue;
} const safeToolName = buildSafeToolName({
serverName: tool.safeServerName,
toolName: originalName,
reservedNames,
}); if (safeToolName !== `${tool.safeServerName}${TOOL_NAME_SEPARATOR}${originalName}`) {
logWarn(
`bundle-mcp: tool "${tool.toolName}" from server "${tool.serverName}" registered as "${safeToolName}" to keep the tool name provider-safe.`,
);
}
reservedNames.add(normalizeLowercaseStringOrEmpty(safeToolName)); const agentTool: AnyAgentTool = {
name: safeToolName,
label: tool.title ?? tool.toolName,
description: tool.description || tool.fallbackDescription,
parameters: tool.inputSchema,
execute: async (_toolCallId: string, input: unknown) => {
params.runtime.markUsed(); const result = await params.runtime.callTool(tool.serverName, tool.toolName, input); return toAgentToolResult({
serverName: tool.serverName,
toolName: tool.toolName,
result,
});
},
};
setPluginToolMeta(agentTool, {
pluginId: "bundle-mcp",
optional: false,
});
tools.push(agentTool);
}
// Sort tools deterministically by name so the tools block in API requests is stable across // turns (defensive — listTools() order is usually stable but not guaranteed). // Cannot fix name collisions: collision suffixes above are order-dependent.
tools.sort((a, b) => a.name.localeCompare(b.name));
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.