sync-agents-settings 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +348 -0
- package/dist/backup.d.ts +2 -0
- package/dist/backup.js +45 -0
- package/dist/backup.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +178 -0
- package/dist/cli.js.map +1 -0
- package/dist/env.d.ts +6 -0
- package/dist/env.js +11 -0
- package/dist/env.js.map +1 -0
- package/dist/paths.d.ts +12 -0
- package/dist/paths.js +23 -0
- package/dist/paths.js.map +1 -0
- package/dist/reader.d.ts +7 -0
- package/dist/reader.js +151 -0
- package/dist/reader.js.map +1 -0
- package/dist/types.d.ts +73 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/writers/claude-format.d.ts +10 -0
- package/dist/writers/claude-format.js +73 -0
- package/dist/writers/claude-format.js.map +1 -0
- package/dist/writers/codex.d.ts +7 -0
- package/dist/writers/codex.js +89 -0
- package/dist/writers/codex.js.map +1 -0
- package/dist/writers/cursor.d.ts +5 -0
- package/dist/writers/cursor.js +6 -0
- package/dist/writers/cursor.js.map +1 -0
- package/dist/writers/gemini.d.ts +5 -0
- package/dist/writers/gemini.js +81 -0
- package/dist/writers/gemini.js.map +1 -0
- package/dist/writers/kiro.d.ts +5 -0
- package/dist/writers/kiro.js +6 -0
- package/dist/writers/kiro.js.map +1 -0
- package/dist/writers/opencode.d.ts +5 -0
- package/dist/writers/opencode.js +76 -0
- package/dist/writers/opencode.js.map +1 -0
- package/package.json +64 -0
package/dist/paths.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
const HOME = homedir();
|
|
4
|
+
export const PATHS = {
|
|
5
|
+
// Claude Code
|
|
6
|
+
claudeJson: join(HOME, ".claude.json"),
|
|
7
|
+
claudeSettings: join(HOME, ".claude", "settings.json"),
|
|
8
|
+
claudePluginCache: join(HOME, ".claude", "plugins", "cache"),
|
|
9
|
+
// Gemini CLI
|
|
10
|
+
geminiSettings: join(HOME, ".gemini", "settings.json"),
|
|
11
|
+
// Codex CLI
|
|
12
|
+
codexDir: join(HOME, ".codex"),
|
|
13
|
+
codexConfig: join(HOME, ".codex", "config.toml"),
|
|
14
|
+
// OpenCode
|
|
15
|
+
openCodeConfig: join(HOME, ".config", "opencode", "opencode.json"),
|
|
16
|
+
// Kiro CLI
|
|
17
|
+
kiroMcpConfig: join(HOME, ".kiro", "settings", "mcp.json"),
|
|
18
|
+
// Cursor
|
|
19
|
+
cursorMcpConfig: join(HOME, ".cursor", "mcp.json"),
|
|
20
|
+
// Backups
|
|
21
|
+
backupDir: join(HOME, ".sync-agents-backup"),
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;AAEvB,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,cAAc;IACd,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC;IACtC,cAAc,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,eAAe,CAAC;IACtD,iBAAiB,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC;IAE5D,aAAa;IACb,cAAc,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,eAAe,CAAC;IAEtD,YAAY;IACZ,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC;IAC9B,WAAW,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,aAAa,CAAC;IAEhD,WAAW;IACX,cAAc,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,eAAe,CAAC;IAElE,WAAW;IACX,aAAa,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,CAAC;IAE1D,SAAS;IACT,eAAe,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,CAAC;IAElD,UAAU;IACV,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,qBAAqB,CAAC;CACpC,CAAC"}
|
package/dist/reader.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { UnifiedMcpServer } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Read all MCP servers from Claude Code config sources:
|
|
4
|
+
* 1. ~/.claude.json mcpServers (user-configured)
|
|
5
|
+
* 2. Enabled plugin .mcp.json files
|
|
6
|
+
*/
|
|
7
|
+
export declare function readClaudeMcpServers(): UnifiedMcpServer[];
|
package/dist/reader.js
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { readFileSync, existsSync, readdirSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { PATHS } from "./paths.js";
|
|
4
|
+
/**
|
|
5
|
+
* Read all MCP servers from Claude Code config sources:
|
|
6
|
+
* 1. ~/.claude.json mcpServers (user-configured)
|
|
7
|
+
* 2. Enabled plugin .mcp.json files
|
|
8
|
+
*/
|
|
9
|
+
export function readClaudeMcpServers() {
|
|
10
|
+
const servers = [];
|
|
11
|
+
const seenNames = new Set();
|
|
12
|
+
// 1. Read from ~/.claude.json
|
|
13
|
+
const configServers = readFromClaudeJson();
|
|
14
|
+
for (const s of configServers) {
|
|
15
|
+
seenNames.add(s.name);
|
|
16
|
+
}
|
|
17
|
+
servers.push(...configServers);
|
|
18
|
+
// 2. Read from enabled plugins
|
|
19
|
+
servers.push(...readFromPlugins(seenNames));
|
|
20
|
+
return servers;
|
|
21
|
+
}
|
|
22
|
+
function readFromClaudeJson() {
|
|
23
|
+
const servers = [];
|
|
24
|
+
if (!existsSync(PATHS.claudeJson)) {
|
|
25
|
+
console.log(" ⚠ ~/.claude.json not found");
|
|
26
|
+
return servers;
|
|
27
|
+
}
|
|
28
|
+
const raw = JSON.parse(readFileSync(PATHS.claudeJson, "utf-8"));
|
|
29
|
+
const mcpServers = raw.mcpServers ?? {};
|
|
30
|
+
for (const [name, config] of Object.entries(mcpServers)) {
|
|
31
|
+
servers.push(toUnified(name, config, "claude-config"));
|
|
32
|
+
}
|
|
33
|
+
return servers;
|
|
34
|
+
}
|
|
35
|
+
function readFromPlugins(seenNames) {
|
|
36
|
+
const servers = [];
|
|
37
|
+
// Read enabled plugins from settings.json
|
|
38
|
+
if (!existsSync(PATHS.claudeSettings)) {
|
|
39
|
+
return servers;
|
|
40
|
+
}
|
|
41
|
+
const settings = JSON.parse(readFileSync(PATHS.claudeSettings, "utf-8"));
|
|
42
|
+
const enabledPlugins = settings.enabledPlugins ?? {};
|
|
43
|
+
// Walk plugin cache to find .mcp.json files for enabled plugins
|
|
44
|
+
if (!existsSync(PATHS.claudePluginCache)) {
|
|
45
|
+
return servers;
|
|
46
|
+
}
|
|
47
|
+
const marketplaces = readdirSync(PATHS.claudePluginCache, {
|
|
48
|
+
withFileTypes: true,
|
|
49
|
+
}).filter((d) => d.isDirectory());
|
|
50
|
+
for (const marketplace of marketplaces) {
|
|
51
|
+
const marketplacePath = join(PATHS.claudePluginCache, marketplace.name);
|
|
52
|
+
const plugins = readdirSync(marketplacePath, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
53
|
+
for (const plugin of plugins) {
|
|
54
|
+
// Check if this plugin is enabled
|
|
55
|
+
const pluginKey = `${plugin.name}@${marketplace.name}`;
|
|
56
|
+
const isEnabled = enabledPlugins[pluginKey] === true;
|
|
57
|
+
if (!isEnabled)
|
|
58
|
+
continue;
|
|
59
|
+
// Find the latest version directory with .mcp.json
|
|
60
|
+
const pluginPath = join(marketplacePath, plugin.name);
|
|
61
|
+
const versions = readdirSync(pluginPath, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
62
|
+
for (const version of versions) {
|
|
63
|
+
const versionDir = join(pluginPath, version.name);
|
|
64
|
+
let found = false;
|
|
65
|
+
// Source 1: .mcp.json (most plugins)
|
|
66
|
+
const mcpJsonPath = join(versionDir, ".mcp.json");
|
|
67
|
+
if (existsSync(mcpJsonPath)) {
|
|
68
|
+
try {
|
|
69
|
+
const raw = JSON.parse(readFileSync(mcpJsonPath, "utf-8"));
|
|
70
|
+
const mcpEntries = parseMcpJson(raw);
|
|
71
|
+
addPluginServers(servers, seenNames, mcpEntries);
|
|
72
|
+
found = true;
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// skip malformed .mcp.json
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Source 2: .claude-plugin/marketplace.json → mcpServers (e.g. qmd)
|
|
79
|
+
if (!found) {
|
|
80
|
+
const marketplaceJsonPath = join(versionDir, ".claude-plugin", "marketplace.json");
|
|
81
|
+
if (existsSync(marketplaceJsonPath)) {
|
|
82
|
+
try {
|
|
83
|
+
const raw = JSON.parse(readFileSync(marketplaceJsonPath, "utf-8"));
|
|
84
|
+
const plugins = raw.plugins ?? [];
|
|
85
|
+
for (const p of plugins) {
|
|
86
|
+
if (typeof p === "object" && p !== null && "mcpServers" in p) {
|
|
87
|
+
const mcpEntries = p
|
|
88
|
+
.mcpServers;
|
|
89
|
+
addPluginServers(servers, seenNames, mcpEntries);
|
|
90
|
+
found = true;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
// skip malformed marketplace.json
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (found)
|
|
100
|
+
break; // only use first version found
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return servers;
|
|
105
|
+
}
|
|
106
|
+
function addPluginServers(servers, seenNames, mcpEntries) {
|
|
107
|
+
for (const [name, config] of Object.entries(mcpEntries)) {
|
|
108
|
+
if (!seenNames.has(name)) {
|
|
109
|
+
seenNames.add(name);
|
|
110
|
+
servers.push(toUnified(name, config, "claude-plugin"));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/** Plugin .mcp.json has two formats: flat or nested under mcpServers */
|
|
115
|
+
function parseMcpJson(raw) {
|
|
116
|
+
if ("mcpServers" in raw && typeof raw.mcpServers === "object") {
|
|
117
|
+
return raw.mcpServers;
|
|
118
|
+
}
|
|
119
|
+
// Flat format: { "name": { command, args } }
|
|
120
|
+
// Filter out non-server keys
|
|
121
|
+
const result = {};
|
|
122
|
+
for (const [key, val] of Object.entries(raw)) {
|
|
123
|
+
if (typeof val === "object" &&
|
|
124
|
+
val !== null &&
|
|
125
|
+
("command" in val || "type" in val || "url" in val)) {
|
|
126
|
+
result[key] = val;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return result;
|
|
130
|
+
}
|
|
131
|
+
function toUnified(name, config, source) {
|
|
132
|
+
let transport = "stdio";
|
|
133
|
+
if (config.type === "http")
|
|
134
|
+
transport = "http";
|
|
135
|
+
else if (config.type === "sse")
|
|
136
|
+
transport = "sse";
|
|
137
|
+
else if (config.url && !config.command)
|
|
138
|
+
transport = "http";
|
|
139
|
+
return {
|
|
140
|
+
name,
|
|
141
|
+
transport,
|
|
142
|
+
source,
|
|
143
|
+
command: config.command,
|
|
144
|
+
args: config.args,
|
|
145
|
+
env: config.env,
|
|
146
|
+
url: config.url,
|
|
147
|
+
headers: config.headers,
|
|
148
|
+
oauth: config.oauth,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reader.js","sourceRoot":"","sources":["../src/reader.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
export interface ClaudeMcpServer {
|
|
2
|
+
command?: string;
|
|
3
|
+
args?: string[];
|
|
4
|
+
env?: Record<string, string>;
|
|
5
|
+
type?: "http" | "sse";
|
|
6
|
+
url?: string;
|
|
7
|
+
headers?: Record<string, string>;
|
|
8
|
+
oauth?: {
|
|
9
|
+
clientId: string;
|
|
10
|
+
callbackPort?: number;
|
|
11
|
+
};
|
|
12
|
+
description?: string;
|
|
13
|
+
}
|
|
14
|
+
/** Plugin .mcp.json can be either flat or nested under mcpServers */
|
|
15
|
+
export type PluginMcpJson = Record<string, ClaudeMcpServer> | {
|
|
16
|
+
mcpServers: Record<string, ClaudeMcpServer>;
|
|
17
|
+
};
|
|
18
|
+
export interface ClaudeSettings {
|
|
19
|
+
enabledPlugins?: Record<string, boolean>;
|
|
20
|
+
mcpServers?: Record<string, ClaudeMcpServer>;
|
|
21
|
+
[key: string]: unknown;
|
|
22
|
+
}
|
|
23
|
+
export interface GeminiMcpServer {
|
|
24
|
+
command?: string;
|
|
25
|
+
args?: string[];
|
|
26
|
+
cwd?: string;
|
|
27
|
+
env?: Record<string, string>;
|
|
28
|
+
url?: string;
|
|
29
|
+
httpUrl?: string;
|
|
30
|
+
headers?: Record<string, string>;
|
|
31
|
+
timeout?: number;
|
|
32
|
+
trust?: boolean;
|
|
33
|
+
oauth?: {
|
|
34
|
+
enabled?: boolean;
|
|
35
|
+
clientId?: string;
|
|
36
|
+
clientSecret?: string;
|
|
37
|
+
authorizationUrl?: string;
|
|
38
|
+
tokenUrl?: string;
|
|
39
|
+
scopes?: string[];
|
|
40
|
+
redirectUri?: string;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export interface GeminiSettings {
|
|
44
|
+
mcpServers?: Record<string, GeminiMcpServer>;
|
|
45
|
+
[key: string]: unknown;
|
|
46
|
+
}
|
|
47
|
+
export interface OpenCodeMcpServer {
|
|
48
|
+
type: "local" | "remote";
|
|
49
|
+
command?: string[];
|
|
50
|
+
environment?: Record<string, string>;
|
|
51
|
+
url?: string;
|
|
52
|
+
headers?: Record<string, string>;
|
|
53
|
+
oauth?: Record<string, unknown> | false;
|
|
54
|
+
enabled?: boolean;
|
|
55
|
+
timeout?: number;
|
|
56
|
+
}
|
|
57
|
+
export interface OpenCodeConfig {
|
|
58
|
+
mcp?: Record<string, OpenCodeMcpServer>;
|
|
59
|
+
[key: string]: unknown;
|
|
60
|
+
}
|
|
61
|
+
export type McpTransport = "stdio" | "http" | "sse";
|
|
62
|
+
export interface UnifiedMcpServer {
|
|
63
|
+
name: string;
|
|
64
|
+
transport: McpTransport;
|
|
65
|
+
source: "claude-config" | "claude-plugin";
|
|
66
|
+
command?: string;
|
|
67
|
+
args?: string[];
|
|
68
|
+
env?: Record<string, string>;
|
|
69
|
+
url?: string;
|
|
70
|
+
headers?: Record<string, string>;
|
|
71
|
+
oauth?: Record<string, unknown>;
|
|
72
|
+
}
|
|
73
|
+
export type SyncTarget = "gemini" | "codex" | "opencode" | "kiro" | "cursor";
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,2CAA2C"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { UnifiedMcpServer } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Generic writer for targets that use the same MCP format as Claude Code
|
|
4
|
+
* (mcpServers with command/args/env/url/headers).
|
|
5
|
+
* Used by Kiro and Cursor writers.
|
|
6
|
+
*/
|
|
7
|
+
export declare function writeClaudeFormat(servers: UnifiedMcpServer[], dryRun: boolean, configPath: string, targetName: string): {
|
|
8
|
+
added: string[];
|
|
9
|
+
skipped: string[];
|
|
10
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
import { expandEnvVars } from "../env.js";
|
|
4
|
+
/**
|
|
5
|
+
* Generic writer for targets that use the same MCP format as Claude Code
|
|
6
|
+
* (mcpServers with command/args/env/url/headers).
|
|
7
|
+
* Used by Kiro and Cursor writers.
|
|
8
|
+
*/
|
|
9
|
+
export function writeClaudeFormat(servers, dryRun, configPath, targetName) {
|
|
10
|
+
const added = [];
|
|
11
|
+
const skipped = [];
|
|
12
|
+
const configDir = dirname(configPath);
|
|
13
|
+
if (!existsSync(configDir)) {
|
|
14
|
+
return {
|
|
15
|
+
added: [],
|
|
16
|
+
skipped: [
|
|
17
|
+
`all ${servers.length} server(s) (${configDir} does not exist, please install ${targetName} first)`,
|
|
18
|
+
],
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
let config = {};
|
|
22
|
+
if (existsSync(configPath)) {
|
|
23
|
+
const raw = readFileSync(configPath, "utf-8");
|
|
24
|
+
if (raw.trim()) {
|
|
25
|
+
config = JSON.parse(raw);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const existing = config.mcpServers ?? {};
|
|
29
|
+
for (const server of servers) {
|
|
30
|
+
if (server.oauth && !server.command && !server.url) {
|
|
31
|
+
skipped.push(`${server.name} (requires manual OAuth)`);
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const converted = toClaudeFormatServer(server);
|
|
35
|
+
if (!converted) {
|
|
36
|
+
skipped.push(`${server.name} (cannot convert)`);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (existing[server.name]) {
|
|
40
|
+
skipped.push(`${server.name} (already exists)`);
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
existing[server.name] = converted;
|
|
44
|
+
added.push(server.name);
|
|
45
|
+
}
|
|
46
|
+
config.mcpServers = existing;
|
|
47
|
+
if (!dryRun && added.length > 0) {
|
|
48
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
49
|
+
}
|
|
50
|
+
return { added, skipped };
|
|
51
|
+
}
|
|
52
|
+
function toClaudeFormatServer(server) {
|
|
53
|
+
if (server.transport === "stdio" && server.command) {
|
|
54
|
+
const result = {
|
|
55
|
+
command: server.command,
|
|
56
|
+
};
|
|
57
|
+
if (server.args)
|
|
58
|
+
result.args = server.args;
|
|
59
|
+
if (server.env)
|
|
60
|
+
result.env = server.env;
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
if ((server.transport === "http" || server.transport === "sse") && server.url) {
|
|
64
|
+
const result = {
|
|
65
|
+
url: expandEnvVars(server.url),
|
|
66
|
+
};
|
|
67
|
+
if (server.headers)
|
|
68
|
+
result.headers = server.headers;
|
|
69
|
+
return result;
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=claude-format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-format.js","sourceRoot":"","sources":["../../src/writers/claude-format.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { UnifiedMcpServer } from "../types.js";
|
|
2
|
+
export declare function resolveCodexConfigPath(codexHome?: string): string;
|
|
3
|
+
export declare function writeToCodex(servers: UnifiedMcpServer[], dryRun: boolean, codexHome?: string): {
|
|
4
|
+
added: string[];
|
|
5
|
+
skipped: string[];
|
|
6
|
+
configPath: string;
|
|
7
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join, dirname } from "node:path";
|
|
4
|
+
import TOML from "@iarna/toml";
|
|
5
|
+
import { expandEnvVars } from "../env.js";
|
|
6
|
+
const DEFAULT_CODEX_HOME = join(homedir(), ".codex");
|
|
7
|
+
export function resolveCodexConfigPath(codexHome) {
|
|
8
|
+
const dir = codexHome ?? DEFAULT_CODEX_HOME;
|
|
9
|
+
return join(dir, "config.toml");
|
|
10
|
+
}
|
|
11
|
+
export function writeToCodex(servers, dryRun, codexHome) {
|
|
12
|
+
const added = [];
|
|
13
|
+
const skipped = [];
|
|
14
|
+
const configPath = resolveCodexConfigPath(codexHome);
|
|
15
|
+
const codexDir = dirname(configPath);
|
|
16
|
+
// Check if Codex directory exists
|
|
17
|
+
if (!existsSync(codexDir)) {
|
|
18
|
+
return {
|
|
19
|
+
added: [],
|
|
20
|
+
skipped: [
|
|
21
|
+
`all ${servers.length} server(s) (${codexDir} does not exist, please install Codex CLI or use --codex-home)`,
|
|
22
|
+
],
|
|
23
|
+
configPath,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
// Read existing config
|
|
27
|
+
let config = {};
|
|
28
|
+
if (existsSync(configPath)) {
|
|
29
|
+
const raw = readFileSync(configPath, "utf-8");
|
|
30
|
+
if (raw.trim()) {
|
|
31
|
+
config = TOML.parse(raw);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (!config.mcp_servers) {
|
|
35
|
+
config.mcp_servers = {};
|
|
36
|
+
}
|
|
37
|
+
const existing = config.mcp_servers;
|
|
38
|
+
for (const server of servers) {
|
|
39
|
+
// Skip OAuth-only servers
|
|
40
|
+
if (server.oauth && !server.command && !server.url) {
|
|
41
|
+
skipped.push(`${server.name} (requires manual OAuth)`);
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
// Skip if already exists
|
|
45
|
+
if (existing[server.name]) {
|
|
46
|
+
skipped.push(`${server.name} (already exists)`);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
const codexServer = toCodexServer(server);
|
|
50
|
+
if (!codexServer) {
|
|
51
|
+
skipped.push(`${server.name} (cannot convert)`);
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
existing[server.name] = codexServer;
|
|
55
|
+
added.push(server.name);
|
|
56
|
+
}
|
|
57
|
+
if (!dryRun && added.length > 0) {
|
|
58
|
+
writeFileSync(configPath, TOML.stringify(config));
|
|
59
|
+
}
|
|
60
|
+
return { added, skipped, configPath };
|
|
61
|
+
}
|
|
62
|
+
function toCodexServer(server) {
|
|
63
|
+
if (server.transport === "stdio" && server.command) {
|
|
64
|
+
const result = {
|
|
65
|
+
command: server.command,
|
|
66
|
+
};
|
|
67
|
+
if (server.args)
|
|
68
|
+
result.args = server.args;
|
|
69
|
+
if (server.env)
|
|
70
|
+
result.env = server.env;
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
if ((server.transport === "http" || server.transport === "sse") && server.url) {
|
|
74
|
+
const result = {
|
|
75
|
+
url: expandEnvVars(server.url),
|
|
76
|
+
};
|
|
77
|
+
// Extract bearer token env var from Authorization header
|
|
78
|
+
if (server.headers?.["Authorization"]) {
|
|
79
|
+
const auth = server.headers["Authorization"];
|
|
80
|
+
const envMatch = auth.match(/\$\{?(\w+)\}?/);
|
|
81
|
+
if (envMatch?.[1]) {
|
|
82
|
+
result.bearer_token_env_var = envMatch[1];
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return result;
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=codex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/writers/codex.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/writers/cursor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,UAAU,aAAa,CAC3B,OAA2B,EAC3B,MAAe;IAEf,OAAO,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;AAC7E,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
import { PATHS } from "../paths.js";
|
|
4
|
+
export function writeToGemini(servers, dryRun) {
|
|
5
|
+
const added = [];
|
|
6
|
+
const skipped = [];
|
|
7
|
+
// Check if Gemini CLI directory exists
|
|
8
|
+
const geminiDir = dirname(PATHS.geminiSettings);
|
|
9
|
+
if (!existsSync(geminiDir)) {
|
|
10
|
+
return {
|
|
11
|
+
added: [],
|
|
12
|
+
skipped: [
|
|
13
|
+
`all ${servers.length} server(s) (${geminiDir} does not exist, please install Gemini CLI first)`,
|
|
14
|
+
],
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
// Read existing Gemini settings
|
|
18
|
+
let settings = {};
|
|
19
|
+
if (existsSync(PATHS.geminiSettings)) {
|
|
20
|
+
settings = JSON.parse(readFileSync(PATHS.geminiSettings, "utf-8"));
|
|
21
|
+
}
|
|
22
|
+
const existing = settings.mcpServers ?? {};
|
|
23
|
+
for (const server of servers) {
|
|
24
|
+
// Skip OAuth-only servers (need manual auth)
|
|
25
|
+
if (server.oauth && !server.command && !server.url) {
|
|
26
|
+
skipped.push(`${server.name} (requires manual OAuth)`);
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const geminiServer = toGeminiServer(server);
|
|
30
|
+
if (!geminiServer) {
|
|
31
|
+
skipped.push(`${server.name} (cannot convert)`);
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
// Don't overwrite existing config
|
|
35
|
+
if (existing[server.name]) {
|
|
36
|
+
skipped.push(`${server.name} (already exists)`);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
existing[server.name] = geminiServer;
|
|
40
|
+
added.push(server.name);
|
|
41
|
+
}
|
|
42
|
+
settings.mcpServers = existing;
|
|
43
|
+
if (!dryRun && added.length > 0) {
|
|
44
|
+
writeFileSync(PATHS.geminiSettings, JSON.stringify(settings, null, 2) + "\n");
|
|
45
|
+
}
|
|
46
|
+
return { added, skipped };
|
|
47
|
+
}
|
|
48
|
+
function toGeminiServer(server) {
|
|
49
|
+
if (server.transport === "stdio" && server.command) {
|
|
50
|
+
return {
|
|
51
|
+
command: server.command,
|
|
52
|
+
...(server.args && { args: server.args }),
|
|
53
|
+
...(server.env && { env: convertEnvSyntax(server.env) }),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
if (server.transport === "http" && server.url) {
|
|
57
|
+
// Gemini uses httpUrl for HTTP streamable transport
|
|
58
|
+
return {
|
|
59
|
+
httpUrl: server.url,
|
|
60
|
+
...(server.headers && { headers: server.headers }),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
if (server.transport === "sse" && server.url) {
|
|
64
|
+
return {
|
|
65
|
+
url: server.url,
|
|
66
|
+
...(server.headers && { headers: server.headers }),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
/** Convert Claude env var syntax ${VAR} to Gemini syntax $VAR */
|
|
72
|
+
function convertEnvSyntax(env) {
|
|
73
|
+
const result = {};
|
|
74
|
+
for (const [key, val] of Object.entries(env)) {
|
|
75
|
+
// ${VAR:-default} → keep as-is (Gemini also supports this)
|
|
76
|
+
// ${VAR} → $VAR
|
|
77
|
+
result[key] = val.replace(/\$\{([^}:]+)\}/g, "$$$1");
|
|
78
|
+
}
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=gemini.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../src/writers/gemini.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kiro.js","sourceRoot":"","sources":["../../src/writers/kiro.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,UAAU,WAAW,CACzB,OAA2B,EAC3B,MAAe;IAEf,OAAO,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;AAC7E,CAAC"}
|