@@ -129,7 +129,6 @@ export class GcliMcpBridge {
129129 for ( const tool of allTools ) {
130130 this . registerGcliTool ( tool ) ;
131131 }
132- this . registerGeminiApiTool ( ) ;
133132 }
134133
135134 private registerGcliTool ( tool : GcliTool ) {
@@ -149,111 +148,6 @@ export class GcliMcpBridge {
149148 ) ;
150149 }
151150
152- private registerGeminiApiTool ( ) {
153- this . mcpServer . registerTool (
154- 'call_gemini_api' ,
155- {
156- title : 'Gemini API Proxy' ,
157- description :
158- "Proxies a request to the Gemini API through the CLI's authenticated client. Allows dynamic provision of tools and a system prompt for this call." ,
159- inputSchema : {
160- messages : z
161- . any ( )
162- . describe (
163- 'The conversation history or prompt to send to the Gemini API.' ,
164- ) ,
165- tools : z
166- . array ( z . any ( ) )
167- . optional ( )
168- . describe (
169- 'An array of tool definitions (FunctionDeclarations) to make available to the model for this call.' ,
170- ) ,
171- systemInstruction : z
172- . string ( )
173- . optional ( )
174- . describe (
175- "A system prompt to guide the model's behavior for this call." ,
176- ) ,
177- } ,
178- } ,
179- async ( args , { sendNotification, signal } ) => {
180- const { messages, tools, systemInstruction } = args as {
181- messages : Content [ ] ;
182- tools ?: Tool [ ] ;
183- systemInstruction ?: string ;
184- } ;
185-
186- const contentGenerator = this . config
187- . getGeminiClient ( )
188- . getContentGenerator ( ) ;
189-
190- // 1. Prepare the generation config with dynamic tools and system prompt.
191- const generationConfig : GenerateContentConfig = {
192- tools : tools ,
193- systemInstruction : systemInstruction ,
194- } ;
195-
196- // The history for the one-shot chat is all messages except the last one.
197- const history = messages . slice ( 0 , - 1 ) ;
198- // The new prompt is the parts from the last message.
199- const lastMessage = messages [ messages . length - 1 ] ;
200- const newPrompt = lastMessage ?. parts ;
201-
202- if ( ! newPrompt ) {
203- // This should ideally return a proper JSON-RPC error.
204- // For now, we'll let it proceed, which will likely fail downstream
205- // in sendMessageStream if `newPrompt` is undefined.
206- console . error (
207- `${ LOG_PREFIX } ❌ Invalid 'call_gemini_api' arguments: 'messages' array is empty or last message has no parts.` ,
208- ) ;
209- }
210-
211- // 2. Create a new, stateless GeminiChat instance for this single call.
212- const oneShotChat = new GeminiChat (
213- this . config ,
214- contentGenerator ,
215- generationConfig , // Pass dynamic config here
216- history , // Start with the provided history
217- ) ;
218-
219- // 3. Call sendMessageStream on the new instance.
220- const stream = await oneShotChat . sendMessageStream ( {
221- message : newPrompt || [ ] , // Pass only the parts of the new message
222- } ) ;
223-
224- let fullTextResponse = '' ;
225- for await ( const event of stream ) {
226- if ( signal . aborted ) {
227- console . log ( `${ LOG_PREFIX } 🛑 Request was aborted by the client.` ) ;
228- break ;
229- }
230- let chunkText = '' ;
231- if ( event . candidates && event . candidates . length > 0 ) {
232- const parts = event . candidates [ 0 ] . content ?. parts || [ ] ;
233- for ( const part of parts ) {
234- if ( part . text ) {
235- chunkText += part . text ;
236- }
237- }
238- }
239-
240- if ( chunkText ) {
241- fullTextResponse += chunkText ;
242- await sendNotification ( {
243- method : 'notifications/message' ,
244- params : { level : 'info' , data : `[STREAM_CHUNK]${ chunkText } ` } ,
245- } ) ;
246- }
247- // Note: Tool call events from the proxied call are not currently forwarded.
248- // This could be a future enhancement if needed.
249- }
250-
251- return {
252- content : [ { type : 'text' , text : fullTextResponse } ] ,
253- } ;
254- } ,
255- ) ;
256- }
257151
258152 private convertJsonSchemaToZod ( jsonSchema : any ) : any {
259153 // Helper to convert a single JSON schema property to a Zod type.
0 commit comments