Maybe fix gemini
This commit is contained in:
+53
-26
@@ -1,4 +1,6 @@
|
|||||||
import { spawnSync } from "node:child_process";
|
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
||||||
|
import { homedir } from "node:os";
|
||||||
|
import { join } from "node:path";
|
||||||
import { log } from "../utils/cli.ts";
|
import { log } from "../utils/cli.ts";
|
||||||
import { spawn } from "../utils/subprocess.ts";
|
import { spawn } from "../utils/subprocess.ts";
|
||||||
import { addInstructions } from "./instructions.ts";
|
import { addInstructions } from "./instructions.ts";
|
||||||
@@ -265,35 +267,60 @@ export const gemini = agent({
|
|||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure MCP servers for Gemini using the CLI.
|
* Configure MCP servers for Gemini by writing to settings.json.
|
||||||
* Gemini CLI syntax: gemini mcp add <name> <commandOrUrl> [args...] --transport <type>
|
* Gemini CLI uses `httpUrl` for HTTP/streamable transport, `url` for SSE transport.
|
||||||
* For HTTP-based servers, use: gemini mcp add <name> <url> --transport http
|
* See: https://github.com/google-gemini/gemini-cli/blob/main/docs/get-started/configuration.md
|
||||||
*/
|
*/
|
||||||
function configureGeminiMcpServers({ mcpServers, cliPath }: ConfigureMcpServersParams): void {
|
function configureGeminiMcpServers({ mcpServers }: ConfigureMcpServersParams): void {
|
||||||
|
const realHome = homedir();
|
||||||
|
const geminiConfigDir = join(realHome, ".gemini");
|
||||||
|
const settingsPath = join(geminiConfigDir, "settings.json");
|
||||||
|
mkdirSync(geminiConfigDir, { recursive: true });
|
||||||
|
|
||||||
|
// read existing settings if present
|
||||||
|
let existingSettings: Record<string, unknown> = {};
|
||||||
|
try {
|
||||||
|
const content = readFileSync(settingsPath, "utf-8");
|
||||||
|
existingSettings = JSON.parse(content);
|
||||||
|
} catch {
|
||||||
|
// file doesn't exist or is invalid - start fresh
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert to Gemini's expected format (httpUrl for HTTP transport, no type field)
|
||||||
|
type GeminiMcpServerConfig = {
|
||||||
|
command?: string;
|
||||||
|
args?: string[];
|
||||||
|
env?: Record<string, string>;
|
||||||
|
cwd?: string;
|
||||||
|
url?: string;
|
||||||
|
httpUrl?: string;
|
||||||
|
headers?: Record<string, string>;
|
||||||
|
timeout?: number;
|
||||||
|
trust?: boolean;
|
||||||
|
description?: string;
|
||||||
|
includeTools?: string[];
|
||||||
|
excludeTools?: string[];
|
||||||
|
};
|
||||||
|
const geminiMcpServers: Record<string, GeminiMcpServerConfig> = {};
|
||||||
for (const [serverName, serverConfig] of Object.entries(mcpServers)) {
|
for (const [serverName, serverConfig] of Object.entries(mcpServers)) {
|
||||||
if (serverConfig.type === "http") {
|
if (serverConfig.type !== "http") {
|
||||||
// HTTP-based MCP server - use URL with --transport http flag
|
|
||||||
const addArgs = ["mcp", "add", serverName, serverConfig.url, "--transport", "http"];
|
|
||||||
|
|
||||||
log.info(`Adding MCP server '${serverName}' at ${serverConfig.url}...`);
|
|
||||||
const addResult = spawnSync("node", [cliPath, ...addArgs], {
|
|
||||||
stdio: "pipe",
|
|
||||||
encoding: "utf-8",
|
|
||||||
env: {
|
|
||||||
...process.env,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (addResult.status !== 0) {
|
|
||||||
throw new Error(
|
|
||||||
`gemini mcp add failed: ${addResult.stderr || addResult.stdout || "Unknown error"}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
log.info(`✓ MCP server '${serverName}' configured`);
|
|
||||||
} else {
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Unsupported MCP server type for Gemini: ${(serverConfig as any).type || "unknown"}`
|
`Unsupported MCP server type for Gemini: ${(serverConfig as { type?: string }).type || "unknown"}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
geminiMcpServers[serverName] = {
|
||||||
|
httpUrl: serverConfig.url,
|
||||||
|
trust: true, // trust our own MCP server to avoid confirmation prompts
|
||||||
|
};
|
||||||
|
log.info(`Adding MCP server '${serverName}' at ${serverConfig.url}...`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// merge with existing settings, overwriting mcpServers
|
||||||
|
const newSettings = {
|
||||||
|
...existingSettings,
|
||||||
|
mcpServers: geminiMcpServers,
|
||||||
|
};
|
||||||
|
|
||||||
|
writeFileSync(settingsPath, JSON.stringify(newSettings, null, 2), "utf-8");
|
||||||
|
log.info(`» MCP config written to ${settingsPath}`);
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -37,11 +37,12 @@ export async function retry<T>(fn: () => Promise<T>, options: RetryOptions = {})
|
|||||||
}
|
}
|
||||||
|
|
||||||
const delay = delayMs * attempt;
|
const delay = delayMs * attempt;
|
||||||
log.warning(`» ${label} failed (attempt ${attempt}/${maxAttempts}), retrying in ${delay}ms...`);
|
log.warning(
|
||||||
|
`» ${label} failed (attempt ${attempt}/${maxAttempts}), retrying in ${delay}ms...`
|
||||||
|
);
|
||||||
await new Promise((resolve) => setTimeout(resolve, delay));
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw lastError;
|
throw lastError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user