MCPcopy
hub / github.com/codeaashu/claude-code / getMcpInstructionsDelta

Function getMcpInstructionsDelta

src/utils/mcpInstructionsDelta.ts:55–130  ·  view source on GitHub ↗
(
  mcpClients: MCPServerConnection[],
  messages: Message[],
  clientSideInstructions: ClientSideInstruction[],
)

Source from the content-addressed store, hash-verified

53 * handshake), so the scan diffs on server NAME, not on content.
54 */
55export function getMcpInstructionsDelta(
56 mcpClients: MCPServerConnection[],
57 messages: Message[],
58 clientSideInstructions: ClientSideInstruction[],
59): McpInstructionsDelta | null {
60 const announced = new Set<string>()
61 let attachmentCount = 0
62 let midCount = 0
63 for (const msg of messages) {
64 if (msg.type !== 'attachment') continue
65 attachmentCount++
66 if (msg.attachment.type !== 'mcp_instructions_delta') continue
67 midCount++
68 for (const n of msg.attachment.addedNames) announced.add(n)
69 for (const n of msg.attachment.removedNames) announced.delete(n)
70 }
71
72 const connected = mcpClients.filter(
73 (c): c is ConnectedMCPServer => c.type === 'connected',
74 )
75 const connectedNames = new Set(connected.map(c => c.name))
76
77 // Servers with instructions to announce (either channel). A server can
78 // have both: server-authored instructions + a client-side block appended.
79 const blocks = new Map<string, string>()
80 for (const c of connected) {
81 if (c.instructions) blocks.set(c.name, `## ${c.name}\n${c.instructions}`)
82 }
83 for (const ci of clientSideInstructions) {
84 if (!connectedNames.has(ci.serverName)) continue
85 const existing = blocks.get(ci.serverName)
86 blocks.set(
87 ci.serverName,
88 existing
89 ? `${existing}\n\n${ci.block}`
90 : `## ${ci.serverName}\n${ci.block}`,
91 )
92 }
93
94 const added: Array<{ name: string; block: string }> = []
95 for (const [name, block] of blocks) {
96 if (!announced.has(name)) added.push({ name, block })
97 }
98
99 // A previously-announced server that is no longer connected → removed.
100 // There is no "announced but now has no instructions" case for a still-
101 // connected server: InitializeResult is immutable, and client-side
102 // instruction gates are session-stable in practice. (/model can flip
103 // the model gate, but deferred_tools_delta has the same property and
104 // we treat history as historical — no retroactive retractions.)
105 const removed: string[] = []
106 for (const n of announced) {
107 if (!connectedNames.has(n)) removed.push(n)
108 }
109
110 if (added.length === 0 && removed.length === 0) return null
111
112 // Same diagnostic fields as tengu_deferred_tools_pool_change — same

Callers 1

Calls 7

logEventFunction · 0.85
deleteMethod · 0.65
getMethod · 0.65
addMethod · 0.45
setMethod · 0.45
hasMethod · 0.45
pushMethod · 0.45

Tested by

no test coverage detected