From 916962fc7ff88702c6bb8a2cd2f61b2e4f487d99 Mon Sep 17 00:00:00 2001 From: Abdelkader Boudih Date: Tue, 10 Mar 2026 14:14:54 +0000 Subject: [PATCH] feat(mcp): include server instructions in system prompt --- packages/opencode/src/mcp/index.ts | 23 +++++++++++++++++++++++ packages/opencode/src/session/llm.ts | 11 +++++++++++ packages/opencode/src/session/system.ts | 18 ++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/packages/opencode/src/mcp/index.ts b/packages/opencode/src/mcp/index.ts index e48a42a8b345..2b762bf18d82 100644 --- a/packages/opencode/src/mcp/index.ts +++ b/packages/opencode/src/mcp/index.ts @@ -188,7 +188,9 @@ export namespace MCP { const config = cfg.mcp ?? {} const clients: Record = {} const status: Record = {} + const serverInstructions: Record = {} + // Discover all configured MCP servers await Promise.all( Object.entries(config).map(async ([key, mcp]) => { if (!isMcpConfigured(mcp)) { @@ -209,12 +211,17 @@ export namespace MCP { if (result.mcpClient) { clients[key] = result.mcpClient + if (result.instructions) { + serverInstructions[key] = result.instructions + } } }), ) + return { status, clients, + serverInstructions, } }, async (state) => { @@ -319,6 +326,9 @@ export namespace MCP { } s.clients[name] = result.mcpClient s.status[name] = result.status + if (result.instructions) { + s.serverInstructions[name] = result.instructions + } return { status: s.status, @@ -331,6 +341,7 @@ export namespace MCP { return { mcpClient: undefined, status: { status: "disabled" as const }, + instructions: undefined, } } @@ -503,6 +514,7 @@ export namespace MCP { return { mcpClient: undefined, status, + instructions: undefined, } } @@ -522,6 +534,7 @@ export namespace MCP { } return { mcpClient: undefined, + instructions: undefined, status: { status: "failed" as const, error: "Failed to get tools", @@ -529,10 +542,12 @@ export namespace MCP { } } + const instructions = mcpClient.getInstructions()?.trim() || undefined log.info("create() successfully created client", { key, toolCount: result.tools.length }) return { mcpClient, status, + instructions, } } @@ -555,6 +570,10 @@ export namespace MCP { return state().then((state) => state.clients) } + export async function serverInstructions() { + return state().then((state) => state.serverInstructions) + } + export async function connect(name: string) { const cfg = await Config.get() const config = cfg.mcp ?? {} @@ -591,6 +610,9 @@ export namespace MCP { }) } s.clients[name] = result.mcpClient + if (result.instructions) { + s.serverInstructions[name] = result.instructions + } } } @@ -603,6 +625,7 @@ export namespace MCP { }) delete s.clients[name] } + delete s.serverInstructions[name] s.status[name] = { status: "disabled" } } diff --git a/packages/opencode/src/session/llm.ts b/packages/opencode/src/session/llm.ts index bcf1b3e6af6a..4b215d0aa051 100644 --- a/packages/opencode/src/session/llm.ts +++ b/packages/opencode/src/session/llm.ts @@ -66,6 +66,15 @@ export namespace LLM { const isCodex = provider.id === "openai" && auth?.type === "oauth" const system = [] + + // Get MCP server instructions - handle errors gracefully + let mcpInstructions: string[] = [] + try { + mcpInstructions = await SystemPrompt.mcpInstructions() + } catch (error) { + // Silently ignore MCP instruction errors to avoid breaking the system + } + system.push( [ // use agent prompt otherwise provider prompt @@ -75,6 +84,8 @@ export namespace LLM { ...input.system, // any custom prompt from last user message ...(input.user.system ? [input.user.system] : []), + // Include MCP server instructions + ...mcpInstructions, ] .filter((x) => x) .join("\n"), diff --git a/packages/opencode/src/session/system.ts b/packages/opencode/src/session/system.ts index d74f58beff84..96bca89e17f6 100644 --- a/packages/opencode/src/session/system.ts +++ b/packages/opencode/src/session/system.ts @@ -13,6 +13,7 @@ import type { Provider } from "@/provider/provider" import type { Agent } from "@/agent/agent" import { PermissionNext } from "@/permission" import { Skill } from "@/skill" +import { MCP } from "../mcp" export namespace SystemPrompt { export function instructions() { @@ -69,4 +70,21 @@ export namespace SystemPrompt { Skill.fmt(list, { verbose: true }), ].join("\n") } + + export async function mcpInstructions(): Promise { + const status = await MCP.status() + const serverInstructions = await MCP.serverInstructions() + const instructions: string[] = [] + + for (const [serverName, serverStatus] of Object.entries(status)) { + if (serverStatus.status === "connected" && serverInstructions[serverName]) { + const instructionText = serverInstructions[serverName] + if (instructionText?.trim()) { + instructions.push(``) + } + } + } + + return instructions + } }