mcp-google-api 0.25.0 → 0.26.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/CHANGELOG.md +32 -0
- package/README.md +1 -1
- package/dist/cli.js +46 -29
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.26.0](https://github.com/Ogekuri/mcp-google-api/compare/v0.25.0..v0.26.0) - 2026-11-08
|
|
4
|
+
### 🚜 Changes
|
|
5
|
+
- add opencode CLI support and alphabetical CLI listing [useReq] *(cliTargets)*
|
|
6
|
+
- REQ-110/DES-017 updated: opencode joins the supported CLI registry; supported-name listings print alphabetically.
|
|
7
|
+
- REQ-112/REQ-113 updated: opencode MCP config at ~/.config/opencode/opencode.json (JSON mcp map) and skills at ~/.config/opencode/skills.
|
|
8
|
+
- REQ-117 updated: show CLI Configuration table covers all seven CLIs in alphabetical order; CLI_TARGETS registry reordered alphabetically.
|
|
9
|
+
- JSON read-modify-write helpers gained a mapKey parameter (default mcpServers, mcp for opencode) preserving unrelated keys; CliTarget gained jsonMcpMapKey.
|
|
10
|
+
- Unit suite 146/146 green; behavioral proof verified paths, mcp-map install/uninstall round-trip, and alphabetical show rows.
|
|
11
|
+
- rebuild dist binaries on every launcher run [useReq] *(mcp-google-api.sh)*
|
|
12
|
+
- PRJ-019 amended: the dev launcher rebuilds dist from the current sources before every execution and aborts non-zero when the rebuild fails; dependency installs stay explicit (npm ci).
|
|
13
|
+
- PRJ-022 added: every argument is forwarded unchanged to the rebuilt dist/cli.js with exit-code propagation via exec.
|
|
14
|
+
- PKG-019 amended: the helper-script no-implicit-install/build rule now carves out the PRJ-018 development launcher.
|
|
15
|
+
- Build output routes to stderr so the exec'd CLI keeps stdout clean for stdio JSON-RPC framing (CTN-003).
|
|
16
|
+
- No src/ changes; unit suite 146/146 green; live proof verified rebuild, exit propagation, and JSON-pure stdout.
|
|
17
|
+
- render show tables as box-drawing grid [useReq] *(cliShow)*
|
|
18
|
+
- REQ-185 added: the show CLI Configuration and Installation Status tables render as box-drawing grids using the specific border characters.
|
|
19
|
+
- REQ-186 added: data rows emit without inter-row border lines, with exactly one header separator and a closing bottom border.
|
|
20
|
+
- renderAsciiTable now builds borders via a parametric borderLine helper (top/header/body/bottom) and pipe-delimited rows; column sizing, cell wrapping, and alignment are unchanged.
|
|
21
|
+
- WORKFLOW.md TRACE-K and EDGE-06 runtime model updated; REFERENCES.md regenerated; no test files modified.
|
|
22
|
+
- print enable/disable result as human-readable confirmation [useReq] *(cli)*
|
|
23
|
+
- PRJ-008 updated: enable and disable join the human-readable stdout operation-report exceptions.
|
|
24
|
+
- REQ-184 added: enable/disable print a human-readable confirmation naming the resolved CLI and the resulting enabled state, exit 0.
|
|
25
|
+
- runEnableDisableCliCommand now writes plain-text confirmations on both success branches (state change and idempotent no-op); the unsupported-name JSON stderr diagnostic and exit 2 are unchanged (REQ-110).
|
|
26
|
+
- WORKFLOW.md TRACE-K and EDGE-06 runtime model updated; REFERENCES.md regenerated; no test files modified.
|
|
27
|
+
- render GitHub probe failure reason in version report [useReq] *(upgradeManager)*
|
|
28
|
+
- REQ-181 added: --ver/--version now prints 'GitHub latest: unknown (<reason>)' when the GitHub releases probe fails, <reason> carrying the probe diagnostic message.
|
|
29
|
+
- REQ-164 updated to reference the REQ-181 failed-probe diagnostic rendering.
|
|
30
|
+
- probeLatestGitHubVersion embeds the GitHub API error message body field (e.g. HTTP 404 rate limit) via the new tolerant readGitHubErrorDetail helper.
|
|
31
|
+
- WORKFLOW.md TRACE-L and EDGE-06/EDGE-10 runtime model updated; REFERENCES.md regenerated; no test files modified.
|
|
32
|
+
|
|
3
33
|
## [0.25.0](https://github.com/Ogekuri/mcp-google-api/compare/v0.24.0..v0.25.0) - 2026-11-08
|
|
4
34
|
### 🐛 Bug Fixes
|
|
5
35
|
- make doctor spawn tests hermetic with isolated home [useReq] *(cliSpawn)*
|
|
@@ -637,6 +667,7 @@
|
|
|
637
667
|
- \[0.23.0\]: https://github.com/Ogekuri/mcp-google-api/releases/tag/v0.23.0
|
|
638
668
|
- \[0.24.0\]: https://github.com/Ogekuri/mcp-google-api/releases/tag/v0.24.0
|
|
639
669
|
- \[0.25.0\]: https://github.com/Ogekuri/mcp-google-api/releases/tag/v0.25.0
|
|
670
|
+
- \[0.26.0\]: https://github.com/Ogekuri/mcp-google-api/releases/tag/v0.26.0
|
|
640
671
|
|
|
641
672
|
[0.2.0]: https://github.com/Ogekuri/mcp-google-api/releases/tag/v0.2.0
|
|
642
673
|
[0.3.0]: https://github.com/Ogekuri/mcp-google-api/compare/v0.2.0..v0.3.0
|
|
@@ -661,3 +692,4 @@
|
|
|
661
692
|
[0.23.0]: https://github.com/Ogekuri/mcp-google-api/compare/v0.22.0..v0.23.0
|
|
662
693
|
[0.24.0]: https://github.com/Ogekuri/mcp-google-api/compare/v0.23.0..v0.24.0
|
|
663
694
|
[0.25.0]: https://github.com/Ogekuri/mcp-google-api/compare/v0.24.0..v0.25.0
|
|
695
|
+
[0.26.0]: https://github.com/Ogekuri/mcp-google-api/compare/v0.25.0..v0.26.0
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
> * **No Support or Feature Requests:** please **do not** open issues, bug reports, or feature requests. They will not be addressed or accepted at this stage.
|
|
11
11
|
> * **No Warranty:** this software is provided **"AS IS"**, without warranty of any kind, express or implied. Use it strictly for testing and evaluation purposes at your own sole risk.
|
|
12
12
|
|
|
13
|
-
# mcp-google-api / MCP Google API server (0.
|
|
13
|
+
# mcp-google-api / MCP Google API server (0.26.0)
|
|
14
14
|
|
|
15
15
|
<p align="center">
|
|
16
16
|
<img src="https://img.shields.io/badge/node-%3E%3D24-339933?style=flat-square&logo=nodedotjs&logoColor=white" alt="Node.js >= 24">
|
package/dist/cli.js
CHANGED
|
@@ -1608,6 +1608,15 @@ var DEFAULT_GITHUB_RELEASES_API_URL = "https://api.github.com/repos/Ogekuri/mcp-
|
|
|
1608
1608
|
function stripReleaseTagPrefix(tag) {
|
|
1609
1609
|
return tag.trim().replace(/^v/i, "");
|
|
1610
1610
|
}
|
|
1611
|
+
async function readGitHubErrorDetail(response) {
|
|
1612
|
+
try {
|
|
1613
|
+
const payload = await response.json();
|
|
1614
|
+
const detail = typeof payload?.message === "string" ? payload.message.trim() : "";
|
|
1615
|
+
return detail.length > 0 ? detail : void 0;
|
|
1616
|
+
} catch {
|
|
1617
|
+
return void 0;
|
|
1618
|
+
}
|
|
1619
|
+
}
|
|
1611
1620
|
async function probeLatestGitHubVersion(deps = {}) {
|
|
1612
1621
|
const releasesUrl = deps.releasesUrl ?? DEFAULT_GITHUB_RELEASES_API_URL;
|
|
1613
1622
|
const timeoutMs = deps.timeoutMs ?? DEFAULT_UPDATE_CHECK_TIMEOUT_MS;
|
|
@@ -1621,9 +1630,11 @@ async function probeLatestGitHubVersion(deps = {}) {
|
|
|
1621
1630
|
signal: AbortSignal.timeout(timeoutMs)
|
|
1622
1631
|
});
|
|
1623
1632
|
if (!response.ok) {
|
|
1633
|
+
const detail = await readGitHubErrorDetail(response);
|
|
1634
|
+
const cause = detail ? `: ${detail.replace(/\.+$/, "")}` : "";
|
|
1624
1635
|
return {
|
|
1625
1636
|
status: "error",
|
|
1626
|
-
message: `GitHub releases API responded with HTTP ${response.status}.`
|
|
1637
|
+
message: `GitHub releases API responded with HTTP ${response.status}${cause}.`
|
|
1627
1638
|
};
|
|
1628
1639
|
}
|
|
1629
1640
|
const payload = await response.json();
|
|
@@ -1959,7 +1970,7 @@ async function runVersionCommand(options, deps = {}) {
|
|
|
1959
1970
|
]);
|
|
1960
1971
|
const installedVersion = options.currentVersion || "unknown";
|
|
1961
1972
|
const npmLatest = resolveProbeLatestVersion(npmProbe);
|
|
1962
|
-
const githubLatest = githubProbe.status === "ok" ? githubProbe.version :
|
|
1973
|
+
const githubLatest = githubProbe.status === "ok" ? githubProbe.version : `unknown (${githubProbe.message})`;
|
|
1963
1974
|
const stdout = deps.stdout ?? process.stdout;
|
|
1964
1975
|
stdout.write(`${installedVersion}
|
|
1965
1976
|
npmjs latest: ${npmLatest}
|
|
@@ -2173,13 +2184,21 @@ var COPILOT_TARGET = {
|
|
|
2173
2184
|
mcpConfigPath: (home) => join3(homeRoot(home), ".copilot", "mcp.json"),
|
|
2174
2185
|
skillsDir: (home) => join3(homeRoot(home), ".copilot", "skills")
|
|
2175
2186
|
};
|
|
2187
|
+
var OPENCODE_TARGET = {
|
|
2188
|
+
id: "opencode",
|
|
2189
|
+
configFormat: "json",
|
|
2190
|
+
jsonMcpMapKey: "mcp",
|
|
2191
|
+
mcpConfigPath: (home) => join3(homeRoot(home), ".config", "opencode", "opencode.json"),
|
|
2192
|
+
skillsDir: (home) => join3(homeRoot(home), ".config", "opencode", "skills")
|
|
2193
|
+
};
|
|
2176
2194
|
var CLI_TARGETS = {
|
|
2177
|
-
pi: PI_TARGET,
|
|
2178
|
-
openclaw: OPENCLAW_TARGET,
|
|
2179
|
-
codex: CODEX_TARGET,
|
|
2180
2195
|
antigravity: ANTIGRAVITY_TARGET,
|
|
2181
2196
|
claude: CLAUDE_TARGET,
|
|
2182
|
-
|
|
2197
|
+
codex: CODEX_TARGET,
|
|
2198
|
+
copilot: COPILOT_TARGET,
|
|
2199
|
+
openclaw: OPENCLAW_TARGET,
|
|
2200
|
+
opencode: OPENCODE_TARGET,
|
|
2201
|
+
pi: PI_TARGET
|
|
2183
2202
|
};
|
|
2184
2203
|
function resolveCliTarget(name) {
|
|
2185
2204
|
return CLI_TARGETS[name.trim().toLowerCase()];
|
|
@@ -2201,35 +2220,35 @@ function writeJsonConfig(configPath, value) {
|
|
|
2201
2220
|
writeFileSync3(temporary, JSON.stringify(value, null, 2) + "\n", "utf-8");
|
|
2202
2221
|
renameSync2(temporary, configPath);
|
|
2203
2222
|
}
|
|
2204
|
-
function writeJsonMcpServerEntry(configPath, serverName, entry) {
|
|
2223
|
+
function writeJsonMcpServerEntry(configPath, serverName, entry, mapKey = "mcpServers") {
|
|
2205
2224
|
const config = readJsonConfig(configPath);
|
|
2206
|
-
const mcpServers = config
|
|
2225
|
+
const mcpServers = config[mapKey] ?? {};
|
|
2207
2226
|
if (mcpServers === null || typeof mcpServers !== "object" || Array.isArray(mcpServers)) {
|
|
2208
|
-
throw new Error(
|
|
2227
|
+
throw new Error(`${mapKey} is not an object: ${configPath}`);
|
|
2209
2228
|
}
|
|
2210
2229
|
mcpServers[serverName] = entry;
|
|
2211
|
-
config
|
|
2230
|
+
config[mapKey] = mcpServers;
|
|
2212
2231
|
writeJsonConfig(configPath, config);
|
|
2213
2232
|
}
|
|
2214
|
-
function removeJsonMcpServerEntry(configPath, serverName) {
|
|
2233
|
+
function removeJsonMcpServerEntry(configPath, serverName, mapKey = "mcpServers") {
|
|
2215
2234
|
if (!existsSync(configPath)) return false;
|
|
2216
2235
|
const config = readJsonConfig(configPath);
|
|
2217
|
-
const mcpServers = config
|
|
2236
|
+
const mcpServers = config[mapKey];
|
|
2218
2237
|
if (mcpServers === void 0) return false;
|
|
2219
2238
|
if (mcpServers === null || typeof mcpServers !== "object" || Array.isArray(mcpServers)) {
|
|
2220
|
-
throw new Error(
|
|
2239
|
+
throw new Error(`${mapKey} is not an object: ${configPath}`);
|
|
2221
2240
|
}
|
|
2222
2241
|
const map = mcpServers;
|
|
2223
2242
|
if (!(serverName in map)) return false;
|
|
2224
2243
|
delete map[serverName];
|
|
2225
|
-
config
|
|
2244
|
+
config[mapKey] = map;
|
|
2226
2245
|
writeJsonConfig(configPath, config);
|
|
2227
2246
|
return true;
|
|
2228
2247
|
}
|
|
2229
|
-
function readJsonMcpServerEntry(configPath, serverName) {
|
|
2248
|
+
function readJsonMcpServerEntry(configPath, serverName, mapKey = "mcpServers") {
|
|
2230
2249
|
try {
|
|
2231
2250
|
const config = readJsonConfig(configPath);
|
|
2232
|
-
const mcpServers = config
|
|
2251
|
+
const mcpServers = config[mapKey];
|
|
2233
2252
|
if (mcpServers === null || typeof mcpServers !== "object" || Array.isArray(mcpServers)) {
|
|
2234
2253
|
return void 0;
|
|
2235
2254
|
}
|
|
@@ -2372,7 +2391,7 @@ function isServerRegistered(target, serverName, home) {
|
|
|
2372
2391
|
if (target.configFormat === "toml") {
|
|
2373
2392
|
return hasTomlMcpServerSection(configPath, serverName);
|
|
2374
2393
|
}
|
|
2375
|
-
return readJsonMcpServerEntry(configPath, serverName) !== void 0;
|
|
2394
|
+
return readJsonMcpServerEntry(configPath, serverName, target.jsonMcpMapKey) !== void 0;
|
|
2376
2395
|
}
|
|
2377
2396
|
function applyServerRegistration(target, serverName, entry, home) {
|
|
2378
2397
|
const configPath = target.mcpConfigPath(home);
|
|
@@ -2385,9 +2404,9 @@ function applyServerRegistration(target, serverName, entry, home) {
|
|
|
2385
2404
|
return;
|
|
2386
2405
|
}
|
|
2387
2406
|
if (entry === void 0) {
|
|
2388
|
-
removeJsonMcpServerEntry(configPath, serverName);
|
|
2407
|
+
removeJsonMcpServerEntry(configPath, serverName, target.jsonMcpMapKey);
|
|
2389
2408
|
} else {
|
|
2390
|
-
writeJsonMcpServerEntry(configPath, serverName, entry);
|
|
2409
|
+
writeJsonMcpServerEntry(configPath, serverName, entry, target.jsonMcpMapKey);
|
|
2391
2410
|
}
|
|
2392
2411
|
}
|
|
2393
2412
|
|
|
@@ -2540,22 +2559,22 @@ function renderAsciiTable(headers, rows, maxWidth = MAX_CELL_WIDTH) {
|
|
|
2540
2559
|
const lengths = [header.length, ...rows.map((row) => (row[index] ?? "").length)];
|
|
2541
2560
|
return Math.max(1, Math.min(Math.max(...lengths), Math.max(1, maxWidth)));
|
|
2542
2561
|
});
|
|
2543
|
-
const
|
|
2562
|
+
const borderLine = (left, middle, right) => left + widths.map((width) => "\u2500".repeat(width + 2)).join(middle) + right;
|
|
2544
2563
|
const renderRow = (cells) => {
|
|
2545
2564
|
const wrapped = cells.map((cell, index) => wrapCell(cell ?? "", widths[index]));
|
|
2546
2565
|
const height = Math.max(...wrapped.map((part) => part.length));
|
|
2547
2566
|
const lines = [];
|
|
2548
2567
|
for (let line = 0; line < height; line += 1) {
|
|
2549
2568
|
const parts = wrapped.map((part, index) => (part[line] ?? "").padEnd(widths[index]));
|
|
2550
|
-
lines.push("
|
|
2569
|
+
lines.push("\u2502 " + parts.join(" \u2502 ") + " \u2502");
|
|
2551
2570
|
}
|
|
2552
2571
|
return lines;
|
|
2553
2572
|
};
|
|
2554
|
-
const output = [
|
|
2573
|
+
const output = [borderLine("\u250C", "\u252C", "\u2510"), ...renderRow(headers), borderLine("\u251C", "\u253C", "\u2524")];
|
|
2555
2574
|
for (const row of rows) {
|
|
2556
2575
|
output.push(...renderRow(row));
|
|
2557
|
-
output.push(border);
|
|
2558
2576
|
}
|
|
2577
|
+
output.push(borderLine("\u2514", "\u2534", "\u2518"));
|
|
2559
2578
|
return output.join("\n");
|
|
2560
2579
|
}
|
|
2561
2580
|
function buildCliRows(home) {
|
|
@@ -2969,16 +2988,14 @@ function runEnableDisableCliCommand(name, enable, options = {}) {
|
|
|
2969
2988
|
const settings = loadCliSettings(options.home);
|
|
2970
2989
|
const already = settings.enabled.includes(target.id);
|
|
2971
2990
|
if (enable === already) {
|
|
2972
|
-
streams.stdout.write(
|
|
2973
|
-
|
|
2974
|
-
);
|
|
2991
|
+
streams.stdout.write(`${target.id} is already ${enable ? "enabled" : "disabled"}.
|
|
2992
|
+
`);
|
|
2975
2993
|
return 0;
|
|
2976
2994
|
}
|
|
2977
2995
|
settings.enabled = enable ? [...settings.enabled, target.id] : settings.enabled.filter((item) => item !== target.id);
|
|
2978
2996
|
saveCliSettings(settings, options.home);
|
|
2979
|
-
streams.stdout.write(
|
|
2980
|
-
|
|
2981
|
-
);
|
|
2997
|
+
streams.stdout.write(`${enable ? "Enabled" : "Disabled"} ${target.id}.
|
|
2998
|
+
`);
|
|
2982
2999
|
return 0;
|
|
2983
3000
|
}
|
|
2984
3001
|
function runApiKeyCommand(key, options) {
|