Skip to content

Commit b1bb0ea

Browse files
committed
Added MCP Logs to AI Context
1 parent ce3e4e8 commit b1bb0ea

File tree

3 files changed

+72
-6
lines changed

3 files changed

+72
-6
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { getMcpServersSection } from "../sections/mcp-servers"
2+
import { McpHub } from "../../../services/mcp/McpHub"
3+
import { ClineProvider } from "../../../core/webview/ClineProvider"
4+
5+
// Mock the ClineProvider and McpHub
6+
jest.mock("../../../core/webview/ClineProvider")
7+
jest.mock("../../../services/mcp/McpHub", () => {
8+
return {
9+
McpHub: jest.fn().mockImplementation(() => {
10+
return {
11+
getServers: jest.fn().mockReturnValue([]),
12+
}
13+
}),
14+
}
15+
})
16+
17+
describe("getMcpServersSection", () => {
18+
// Create a mock provider for McpHub constructor
19+
const mockProvider = {} as ClineProvider
20+
21+
it("should return an empty string when McpHub is not provided", async () => {
22+
const result = await getMcpServersSection(undefined, undefined, true)
23+
expect(result).toBe("")
24+
})
25+
26+
it("should return an empty string when enableMcpServerCreation is false", async () => {
27+
const mockMcpHub = new McpHub(mockProvider) as any
28+
const result = await getMcpServersSection(mockMcpHub, undefined, false)
29+
expect(result).toBe("")
30+
})
31+
32+
it("should return a non-empty string when McpHub is provided and enableMcpServerCreation is true", async () => {
33+
const mockMcpHub = new McpHub(mockProvider) as any
34+
const result = await getMcpServersSection(mockMcpHub, undefined, true)
35+
expect(result).not.toBe("")
36+
expect(result.includes("MCP SERVERS")).toBe(true)
37+
})
38+
})

src/core/prompts/sections/mcp-servers.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ export async function getMcpServersSection(
66
diffStrategy?: DiffStrategy,
77
enableMcpServerCreation?: boolean,
88
): Promise<string> {
9-
if (!mcpHub) {
9+
// Return empty string if no McpHub is provided or MCP server creation is disabled
10+
// This ensures that MCP server logs won't be included in the context when disabled
11+
if (!mcpHub || enableMcpServerCreation === false) {
1012
return ""
1113
}
1214

@@ -37,11 +39,23 @@ export async function getMcpServersSection(
3739
3840
const config = JSON.parse(server.config)
3941
42+
// Include recent console logs (stdout/stderr) if available
43+
const recentLogs = server.errorHistory?.length
44+
? `\n\n### Recent Console Logs\n${server.errorHistory
45+
.slice(-5) // Last 5 logs
46+
.map(
47+
(log) =>
48+
`- [${log.level.toUpperCase()}] ${log.message.split("\n")[0]}${log.message.includes("\n") ? "..." : ""}`,
49+
)
50+
.join("\n")}`
51+
: ""
52+
4053
return (
4154
`## ${server.name} (\`${config.command}${config.args && Array.isArray(config.args) ? ` ${config.args.join(" ")}` : ""}\`)` +
4255
(tools ? `\n\n### Available Tools\n${tools}` : "") +
4356
(templates ? `\n\n### Resource Templates\n${templates}` : "") +
44-
(resources ? `\n\n### Direct Resources\n${resources}` : "")
57+
(resources ? `\n\n### Direct Resources\n${resources}` : "") +
58+
recentLogs
4559
)
4660
})
4761
.join("\n\n")}`

src/services/mcp/McpHub.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -936,10 +936,24 @@ export class McpHub {
936936
})
937937

938938
// Send sorted servers to webview
939-
await this.providerRef.deref()?.postMessageToWebview({
940-
type: "mcpServers",
941-
mcpServers: sortedConnections.map((connection) => connection.server),
942-
})
939+
const provider = this.providerRef.deref()
940+
if (provider) {
941+
await provider.postMessageToWebview({
942+
type: "mcpServers",
943+
mcpServers: sortedConnections.map((connection) => connection.server),
944+
})
945+
946+
// When MCP logs are updated, trigger a system prompt refresh
947+
// by calling postStateToWebview which will re-generate the prompt
948+
console.log("MCP logs updated, triggering context refresh")
949+
950+
// Get the current Cline instance (Task)
951+
if (provider && typeof provider.postStateToWebview === "function") {
952+
// Force the system prompt to be regenerated on the next API request
953+
// by triggering a new state update
954+
await provider.postStateToWebview()
955+
}
956+
}
943957
}
944958

945959
public async toggleServerDisabled(

0 commit comments

Comments
 (0)