Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/mcp/tool-bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import type { McpClientManager } from "./client-manager.js";

const log = createLogger("mcp:tool-bridge");

export const MCP_TOOL_PREFIX = "mcp__";

interface DiscoveredMcpTool {
name: string;
serverName: string;
Expand Down Expand Up @@ -79,7 +81,7 @@ export function buildMcpToolDefinitions(tools: DiscoveredMcpTool[]): any[] {
function namespaceMcpTool(serverName: string, toolName: string): string {
const sanitizedServer = serverName.replace(/[^a-zA-Z0-9]/g, "_");
const sanitizedTool = toolName.replace(/[^a-zA-Z0-9]/g, "_");
return `mcp__${sanitizedServer}__${sanitizedTool}`;
return `${MCP_TOOL_PREFIX}${sanitizedServer}__${sanitizedTool}`;
}

function mcpSchemaToZod(inputSchema: Record<string, unknown> | undefined, z: any): any {
Expand Down
10 changes: 3 additions & 7 deletions src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { SkillResolver } from "./tools/skills/resolver.js";
import { autoRefreshModels } from "./models/sync.js";
import { readMcpConfigs, readSubagentNames } from "./mcp/config.js";
import { McpClientManager } from "./mcp/client-manager.js";
import { MCP_TOOL_PREFIX } from "./mcp/tool-bridge.js";
import { buildMcpToolHookEntries, buildMcpToolDefinitions } from "./mcp/tool-bridge.js";
import { createOpencodeClient } from "@opencode-ai/sdk";
import { ToolRegistry as CoreRegistry } from "./tools/core/registry.js";
Expand Down Expand Up @@ -93,8 +94,8 @@ export function buildAvailableToolsSystemMessage(
}

const lines: string[] = [
"MCP TOOLS — Use via Shell with the `mcptool` CLI.",
"Syntax: mcptool call <server> <tool> [json-args]",
`MCP TOOLS — Use via direct tool calls (\`${MCP_TOOL_PREFIX}<server>__<tool>\`).`,
"These tools are exposed as first-class tool calls (e.g. mcp__filesystem__read_file).",
"",
];

Expand All @@ -104,11 +105,6 @@ export function buildAvailableToolsSystemMessage(
const paramHint = t.params?.length ? ` (params: ${t.params.join(", ")})` : "";
lines.push(` - ${t.toolName}${paramHint}${t.description ? " — " + t.description : ""}`);
}
if (tools.length > 0) {
const ex = tools[0];
const exArgs = ex.params?.length ? ` '{"${ex.params[0]}":"..."}'` : "";
lines.push(` Example: mcptool call ${server} ${ex.toolName}${exArgs}`);
}
lines.push("");
}

Expand Down
8 changes: 4 additions & 4 deletions tests/unit/plugin-mcp-system-transform.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe("Plugin MCP system transform", () => {
expect(systemMessage).toContain("skill_search -> search");
});

it("includes mcptool Shell instructions when summaries provided", () => {
it("includes direct MCP tool call instructions when summaries provided", () => {
const systemMessage = buildAvailableToolsSystemMessage(
["read", "write"],
[],
Expand All @@ -37,15 +37,15 @@ describe("Plugin MCP system transform", () => {
],
);

expect(systemMessage).toContain("mcptool call");
expect(systemMessage).toContain("direct tool calls");
expect(systemMessage).toContain("mcp__");
expect(systemMessage).toContain("hybrid-memory");
expect(systemMessage).toContain("memory_search");
expect(systemMessage).toContain("memory_stats");
expect(systemMessage).toContain("query, limit");
expect(systemMessage).toContain("Shell");
});

it("includes multiple servers in Shell instructions", () => {
it("includes multiple servers in MCP tool instructions", () => {
const systemMessage = buildAvailableToolsSystemMessage(
[],
[],
Expand Down