pi-mcp-adapter 5.3.0 → 5.3.2

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 CHANGED
@@ -7,6 +7,42 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [5.3.2] - 2026-10-17
11
+
12
+ ### Highlights
13
+
14
+ - The GitHub preset in `/mcp-adapter setup` now signs in with your GitHub CLI login, so connecting to GitHub works.
15
+ - Saving direct tools in the MCP panel no longer brings back the "Allow project MCP server?" prompt for a server you already allowed.
16
+ - The MCP panel shows a connected server's tools and your saved direct tools, even for servers like GitHub that don't let their tool list be cached.
17
+ - MCP sampling uses your Pi thinking level, so servers that sample through a reasoning-only model stop failing.
18
+
19
+ ### Fixed
20
+
21
+ - The GitHub preset in `/mcp-adapter setup` now signs in with your GitHub CLI login (`gh auth token`). Before, it used MCP OAuth, which GitHub doesn't offer to apps it hasn't registered, so `/mcp-auth github` always failed with "does not support dynamic client registration". Install `gh` and run `gh auth login` first. If you added the old preset, remove its `github` entry and add GitHub again from `/mcp-adapter setup`. Thanks to [@Milor123](https://github.com/Milor123) for [#841](https://github.com/nicobailon/pi-mcp-adapter/issues/841).
22
+ - When one config file gives a server a different `url` than another file that set its headers or token, the adapter still leaves those credentials out so they aren't sent to the new address, but it now tells you at startup which server, which settings and which two files are involved. Before, the credentials disappeared silently and the server failed with sign-in errors. Thanks to [@Milor123](https://github.com/Milor123) for [#841](https://github.com/nicobailon/pi-mcp-adapter/issues/841).
23
+ - The MCP panel now lists the tools of a server you already connected to in this session, with your saved direct tools checked, even when the server doesn't let its tool list be cached, as with GitHub. Before, such a server showed "(not cached)" with no tools every time you opened the panel, so direct tools you had saved looked lost. Thanks to [@Milor123](https://github.com/Milor123) for [#841](https://github.com/nicobailon/pi-mcp-adapter/issues/841).
24
+ - Saving direct tools in the MCP panel for a project server you already allowed no longer makes Pi ask "Allow project MCP server?" again on the next start or `/reload`. Saving used to change the server's config in a way that cancelled your approval. A server you didn't allow still asks, and so does any other change to the server's config. Thanks to [@Milor123](https://github.com/Milor123) for [#841](https://github.com/nicobailon/pi-mcp-adapter/issues/841).
25
+ - Approving a project MCP server now sticks when Pi is started from the same folder spelled with different capitalization, such as `C:\Users\Me` and `c:\users\me` on Windows. Before, each spelling counted as a separate project and asked "Allow project MCP server?" again. An approval saved under a differently capitalized spelling asks once more after this update. Thanks to [@Milor123](https://github.com/Milor123) for [#841](https://github.com/nicobailon/pi-mcp-adapter/issues/841).
26
+ - MCP sampling requests now use your current Pi thinking level, so a server that samples through a model that requires reasoning no longer fails with "Reasoning is mandatory for this endpoint and cannot be disabled". Before, sampling always ran with thinking off. On Pi 0.84 and 0.85 sampling still runs with thinking off. Thanks to [@bardic](https://github.com/bardic) for [#846](https://github.com/nicobailon/pi-mcp-adapter/issues/846).
27
+
28
+ ## [5.3.1] - 2026-10-15
29
+
30
+ ### Highlights
31
+
32
+ - On Windows, `!command` secrets now run with Git Bash when it is installed, so commands like `!$HOME/bin/get-token` work.
33
+ - `"openUi": false` really runs a server's tools without UI, instead of leaving them waiting on a window that never opens.
34
+ - `describe` no longer hides tool input details such as descriptions, limits and integer types behind a short summary.
35
+ - The MCP panel keeps your saved direct tools selected after a ctrl+r reconnect.
36
+ - OpenCode imports accept `env` for server variables and tell you about settings OpenCode ignores.
37
+
38
+ ### Fixed
39
+
40
+ - `describe` in the `mcp` tool now shows a tool's full input schema whenever the short summary would leave something out, such as field descriptions, integer types, minimum and maximum values, or shared definitions. Simple schemas still get the short summary. When search shortens a parameter's description, it points you to `describe` for the full text, and very long descriptions are saved to a file instead of being cut off. Thanks to [@chpock](https://github.com/chpock) for [#833](https://github.com/nicobailon/pi-mcp-adapter/pull/833) and [#834](https://github.com/nicobailon/pi-mcp-adapter/pull/834).
41
+ - After you reconnect a server in the MCP panel with ctrl+r, the tools you had saved as direct tools now show as selected, so toggling one tool and saving no longer drops the rest of your selection. Thanks to [@Milor123](https://github.com/Milor123) for [#829](https://github.com/nicobailon/pi-mcp-adapter/issues/829).
42
+ - `"openUi": false` now runs a server's tools without UI instead of only hiding the window. The adapter no longer tells that server it supports MCP Apps, so a server that checks for MCP Apps support runs its tools and returns the result rather than waiting on a form that never opens. Turning it on or off makes the adapter fetch that server's tool list again. Thanks to [@nicolasgarciac](https://github.com/nicolasgarciac) for [#827](https://github.com/nicobailon/pi-mcp-adapter/issues/827).
43
+ - The OpenCode import now accepts `env` as another name for `environment` on a server, so servers configured with `env` get their variables in Pi instead of failing with "Connection closed". When both are set, `environment` wins. OpenCode itself still reads only `environment`. Other settings outside OpenCode's schema are reported at startup, in `/mcp-adapter` and in `pi-mcp-adapter doctor`. Thanks to [@cbaudino](https://github.com/cbaudino) and [@syf2211](https://github.com/syf2211) for [#828](https://github.com/nicobailon/pi-mcp-adapter/issues/828) and [#830](https://github.com/nicobailon/pi-mcp-adapter/pull/830).
44
+ - On Windows, `!command` values for `headers`, `bearerToken`, `oauth.clientSecret` and stdio `env` now run with Git Bash when it is installed, like Pi does, so commands written with POSIX syntax such as `$HOME` work instead of failing in cmd.exe. Without Git Bash they still run in cmd.exe. If Git Bash is installed and a command uses cmd.exe syntax such as `%MY_SECRET%`, rewrite it in POSIX syntax (`$MY_SECRET`). Thanks to [@estrizhok](https://github.com/estrizhok) for [#840](https://github.com/nicobailon/pi-mcp-adapter/issues/840).
45
+
10
46
  ## [5.3.0] - 2026-10-12
11
47
 
12
48
  ### Highlights
@@ -118,6 +154,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
118
154
  - `/mcp-adapter setup` adds Figma (desktop) to the global config instead of writing `.mcp.json` into whatever project you opened setup from.
119
155
  - `/mcp-adapter setup` warns when a server you add won't be used, because another config file already defines or disables it, or the current config mode doesn't read the file it was written to.
120
156
  - A bearer token or header value that isn't a valid HTTP header value, such as one containing a newline, no longer appears in connection errors. This covers `bearerToken` (including `!command` and `${VAR}` forms), `bearerTokenEnv`, and configured `headers`; the error now names the server and header instead.
157
+
121
158
  ## [4.0.0] - 2026-09-30
122
159
 
123
160
  ### Highlights
@@ -1,4 +1,5 @@
1
- import { spawn } from "node:child_process";
1
+ import { spawn, type SpawnOptionsWithStdioTuple } from "node:child_process";
2
+ import { getWindowsCommandBash } from "./utils.ts";
2
3
 
3
4
  const DEFAULT_TTL_MS = 5 * 60_000;
4
5
  const ENV_TTL_MS = "PI_MCP_ADAPTER_BEARER_COMMAND_TTL_MS";
@@ -20,12 +21,15 @@ function runCommand(command: string, context: string, signal: AbortSignal): Prom
20
21
  let output = Buffer.alloc(0);
21
22
  let settled = false;
22
23
  let terminating = false;
23
- const child = spawn(command.slice(1), {
24
- shell: true,
24
+ const options: SpawnOptionsWithStdioTuple<"ignore", "pipe", "ignore"> = {
25
25
  stdio: ["ignore", "pipe", "ignore"],
26
26
  windowsHide: true,
27
27
  detached: USE_PROCESS_GROUP,
28
- });
28
+ };
29
+ const bash = getWindowsCommandBash();
30
+ const child = bash === undefined
31
+ ? spawn(command.slice(1), { ...options, shell: true })
32
+ : spawn(bash, ["-c", command.slice(1)], { ...options, shell: false });
29
33
 
30
34
  const kill = async (): Promise<void> => {
31
35
  if (child.pid === undefined) return;
package/cli.js CHANGED
@@ -530,9 +530,9 @@ async function runDoctor(argv, log, error) {
530
530
  error("Usage: pi-mcp-adapter doctor [--json]");
531
531
  return 1;
532
532
  }
533
- let config, trust, manager, auth, authFlow, utils, agentDir;
533
+ let config, trust, manager, auth, authFlow, utils, agentDir, types;
534
534
  try {
535
- [config, trust, manager, auth, authFlow, utils, agentDir] = await Promise.all([
535
+ [config, trust, manager, auth, authFlow, utils, agentDir, types] = await Promise.all([
536
536
  import("./dist/config.js"),
537
537
  import("./dist/project-server-trust.js"),
538
538
  import("./dist/server-manager.js"),
@@ -540,6 +540,7 @@ async function runDoctor(argv, log, error) {
540
540
  import("./dist/mcp-auth-flow.js"),
541
541
  import("./dist/utils.js"),
542
542
  import("./dist/agent-dir.js"),
543
+ import("./dist/types.js"),
543
544
  ]);
544
545
  } catch (err) {
545
546
  error("Unable to load doctor command modules.");
@@ -557,6 +558,7 @@ async function runDoctor(argv, log, error) {
557
558
  error("Pi 0.99 or later wasn't found on PATH, so Pi's own mcp.json files were not checked.");
558
559
  }
559
560
  const loaded = config.loadMcpConfigWithSources(undefined, cwd);
561
+ const provenance = config.getServerProvenance(undefined, cwd);
560
562
  let projectTrusted = false;
561
563
  if (loaded.projectServers.size > 0) {
562
564
  try {
@@ -636,11 +638,13 @@ async function runDoctor(argv, log, error) {
636
638
  timedOut,
637
639
  ]);
638
640
  clearTimeout(timer);
641
+ const ignoredSettings = types.describeIgnoredSettings(provenance.get(name));
639
642
  return {
640
643
  name,
641
644
  state: result.state,
642
645
  tools: result.tools ?? null,
643
646
  message: result.message ? utils.sanitizeTerminalText(redactDoctorMessage(result.message, definition, utils)) : null,
647
+ ...(ignoredSettings ? { ignoredSettings: utils.sanitizeTerminalText(ignoredSettings) } : {}),
644
648
  };
645
649
  }));
646
650
 
@@ -654,6 +658,7 @@ async function runDoctor(argv, log, error) {
654
658
  for (const result of results) {
655
659
  const tools = result.tools === null ? "" : `, ${result.tools} tool${result.tools === 1 ? "" : "s"}`;
656
660
  log(`${utils.sanitizeTerminalText(result.name)}: ${result.state}${tools}${result.message ? ` — ${result.message}` : ""}`);
661
+ if (result.ignoredSettings) log(` ${result.ignoredSettings}`);
657
662
  }
658
663
  }
659
664
  } finally {
package/commands.ts CHANGED
@@ -26,7 +26,7 @@ import {
26
26
  } from "./config.ts";
27
27
  import { markKeepAliveAfterConnect, notifyToolMetadataUpdated, updateMetadataCache, updateStatusBar, getFailureAgeSeconds, getFailureMessage, clearFailure, recordFailure } from "./init.ts";
28
28
  import { isServerInActiveFailureBackoff } from "./failure-backoff.ts";
29
- import { loadMetadataCache, reconstructPromptMetadata } from "./metadata-cache.ts";
29
+ import { loadMetadataCache, reconstructPromptMetadata, withSessionMetadata } from "./metadata-cache.ts";
30
30
  import { buildToolMetadata } from "./tool-metadata.ts";
31
31
  import { supportsOAuth, authenticate, removeAuth, type McpOAuthRuntime } from "./mcp-auth-flow.ts";
32
32
  import { getAuthStorageOptions, inspectAuthForUrl } from "./mcp-auth.ts";
@@ -36,7 +36,7 @@ import { findPiSignInImports, importPiSignIn } from "./pi-signin-import.ts";
36
36
  import { formatTerminalError, openPath, providerSignInMessage, resolveServerUrl, sanitizeTerminalText } from "./utils.ts";
37
37
  import { isAbortError } from "./runtime-owner.ts";
38
38
  import { resolveJevCredential } from "./jev-key-store.ts";
39
- import { describeProjectServerBlock } from "./project-server-trust.ts";
39
+ import { describeProjectServerBlock, keepProjectServerApprovals } from "./project-server-trust.ts";
40
40
 
41
41
  function terminalHyperlink(label: string, url: string): string {
42
42
  return `\u001B]8;;${sanitizeTerminalText(url)}\u001B\\${sanitizeTerminalText(label)}\u001B]8;;\u001B\\`;
@@ -792,7 +792,7 @@ export async function openMcpPanel(
792
792
  }
793
793
 
794
794
  const config = state.config;
795
- const cache = loadMetadataCache();
795
+ const cache = withSessionMetadata(loadMetadataCache(), config, state.sessionMetadata);
796
796
  const configPath = pi.getFlag("mcp-config") as string | undefined ?? configOverridePath;
797
797
  const provenanceMap = getServerProvenance(configPath, ctx.cwd);
798
798
  const { lines: noticeLines, fingerprint } = buildSharedConfigNoticeLines(configPath, ctx.cwd);
@@ -838,9 +838,11 @@ export async function openMcpPanel(
838
838
  }
839
839
  }
840
840
  if (!result.cancelled && result.changes.size > 0) {
841
+ const before = loadMcpConfig(configPath, ctx.cwd);
841
842
  writeDirectToolsConfig(result.changes, provenanceMap, config, () => {
842
843
  directToolsFileWritten = true;
843
844
  });
845
+ keepProjectServerApprovals(ctx, before, loadMcpConfig(configPath, ctx.cwd), result.changes.keys());
844
846
  directToolsSaved = true;
845
847
  await onDirectToolsConfigChanged?.(result.changes);
846
848
  ctx.ui.notify("Direct tools updated for this session.", "info");
package/config.ts CHANGED
@@ -79,8 +79,10 @@ export const KNOWN_SERVER_PRESETS: readonly KnownServerPreset[] = [
79
79
  {
80
80
  id: "github",
81
81
  name: "GitHub",
82
- summary: "Work with GitHub through your Copilot account.",
83
- entry: { url: "https://api.githubcopilot.com/mcp", auth: "oauth", protocolVersion: "auto" },
82
+ summary: "Work with GitHub using your GitHub CLI sign-in. Needs `gh` installed and `gh auth login` done.",
83
+ // GitHub's OAuth server has no dynamic client registration, so MCP OAuth can't sign in;
84
+ // the GitHub CLI token works and is read at connect time, never written to config.
85
+ entry: { url: "https://api.githubcopilot.com/mcp/", auth: "bearer", bearerToken: "!gh auth token", protocolVersion: "auto" },
84
86
  },
85
87
  {
86
88
  id: "chrome-devtools",
@@ -269,6 +271,91 @@ function legacyMcpConfigHasContent(filePath: string): boolean {
269
271
  }
270
272
 
271
273
  export function getLegacyMcpMigrationNotices(cwd = process.cwd(), overridePath?: string): string[] {
274
+ return [
275
+ ...getPiMcpConfigNotices(cwd, overridePath),
276
+ ...getOpenCodeImportNotices(cwd, overridePath),
277
+ ...getDroppedCredentialNotices(cwd, overridePath),
278
+ ];
279
+ }
280
+
281
+ /** server name -> credential field -> the file that supplied it. */
282
+ type CredentialFiles = Map<string, Map<string, string>>;
283
+
284
+ function credentialFiles(servers: Record<string, ServerEntry>, fileOf: (name: string, field: string) => string): CredentialFiles {
285
+ return new Map(Object.entries(servers).map(([name, definition]) => [
286
+ name,
287
+ new Map(CREDENTIAL_FIELDS.filter((field) => definition[field] !== undefined).map((field) => [field, fileOf(name, field)])),
288
+ ]));
289
+ }
290
+
291
+ /**
292
+ * Replays the server merges of loadMcpConfigWithSources with the file behind each credential field,
293
+ * and reports the fields mergeServerMaps drops because a later file points the server at another url.
294
+ */
295
+ function getDroppedCredentialNotices(cwd: string, overridePath?: string): string[] {
296
+ const notices: string[] = [];
297
+ const merge = (
298
+ base: Record<string, ServerEntry>,
299
+ baseFiles: CredentialFiles,
300
+ next: Record<string, ServerEntry>,
301
+ nextFiles: CredentialFiles,
302
+ urlFile: (name: string) => string,
303
+ ): [Record<string, ServerEntry>, CredentialFiles] => {
304
+ const files: CredentialFiles = new Map(baseFiles);
305
+ for (const [name, definition] of Object.entries(next)) {
306
+ const existing = base[name];
307
+ const fieldFiles = new Map(files.get(name));
308
+ const byFile = new Map<string, string[]>();
309
+ for (const field of existing ? droppedUrlBoundAuth(existing, definition) : []) {
310
+ const from = fieldFiles.get(field);
311
+ if (from !== undefined) byFile.set(from, [...byFile.get(from) ?? [], field]);
312
+ fieldFiles.delete(field);
313
+ }
314
+ for (const [from, fields] of byFile) {
315
+ notices.push(`"${name}": ignoring ${fields.join(", ")} from ${from}, because ${urlFile(name)} sets a different url for this server. Use one url, or set ${fields.length === 1 ? "it" : "them"} next to that url.`);
316
+ }
317
+ for (const [field, path] of nextFiles.get(name) ?? []) fieldFiles.set(field, path);
318
+ files.set(name, fieldFiles);
319
+ }
320
+ return [mergeServerMaps(base, next), files];
321
+ };
322
+
323
+ const host = !isExclusiveConfigMode() && getConfiguredHostConfigDiscovery(overridePath, cwd) === "on"
324
+ ? loadDiscoveredHostConfigs(cwd)
325
+ : { config: { mcpServers: {} }, serverSources: new Map<string, ImportedServerSource>() };
326
+ const hostFile = (name: string) => host.serverSources.get(name)?.path ?? "a host config";
327
+ let servers = host.config.mcpServers;
328
+ let files = credentialFiles(servers, hostFile);
329
+ const sourceSpecs = getConfigSources(overridePath, cwd);
330
+ const piProjectSource = sourceSpecs.find((source) => source.id === "pi-mcp-project");
331
+ const piProjectNames = Object.keys((piProjectSource && readPiMcpConfig(piProjectSource.readPath))?.mcpServers ?? {});
332
+ for (const source of sourceSpecs) {
333
+ const loaded = readSourceConfig(source.id, source.readPath);
334
+ if (!loaded) continue;
335
+ if (source.id === "pi-mcp-global") {
336
+ for (const name of piProjectNames) delete loaded.mcpServers[name];
337
+ }
338
+ // The same two merges as expandImports and mergeConfigs: the file's own entries over its imports,
339
+ // then the file over the files before it.
340
+ const imported = expandImports({ ...loaded, mcpServers: {} }, cwd);
341
+ // An OpenCode project entry can inherit a credential from the global file, so name the file per key.
342
+ const importFile = (name: string, field: string) =>
343
+ imported.keySources?.get(name)?.get(field) ?? imported.serverSources.get(name)?.path ?? source.readPath;
344
+ const ownFile = () => source.readPath;
345
+ const [fileServers, fileFiles] = merge(
346
+ imported.config.mcpServers,
347
+ credentialFiles(imported.config.mcpServers, importFile),
348
+ loaded.mcpServers,
349
+ credentialFiles(loaded.mcpServers, ownFile),
350
+ ownFile,
351
+ );
352
+ const urlFile = (name: string) => typeof loaded.mcpServers[name]?.url === "string" ? source.readPath : importFile(name, "url");
353
+ [servers, files] = merge(servers, files, fileServers, fileFiles, urlFile);
354
+ }
355
+ return notices;
356
+ }
357
+
358
+ function getPiMcpConfigNotices(cwd: string, overridePath?: string): string[] {
272
359
  if (piMcpConfigEnabled) {
273
360
  return getConfigSources(overridePath, cwd).flatMap((source) => {
274
361
  const file = isPiMcpSource(source.id) ? readPiMcpConfig(source.readPath) : null;
@@ -301,6 +388,31 @@ export function getLegacyMcpMigrationNotices(cwd = process.cwd(), overridePath?:
301
388
  });
302
389
  }
303
390
 
391
+ /** Settings OpenCode drops from an active `opencode` import, grouped by the file that defines each server. */
392
+ function getOpenCodeImportNotices(cwd: string, overridePath?: string): string[] {
393
+ const active = (!isExclusiveConfigMode() && getConfiguredHostConfigDiscovery(overridePath, cwd) === "on")
394
+ || getConfigSources(overridePath, cwd).some((source) => readSourceConfig(source.id, source.readPath)?.imports?.includes("opencode"));
395
+ const imported = active ? loadImportedConfig("opencode", cwd, "Failed to inspect imported MCP config from opencode:") : null;
396
+ if (!imported) return [];
397
+ // Warn only where the OpenCode import is still the server's definition, matching /mcp-adapter.
398
+ const provenance = getServerProvenance(overridePath, cwd);
399
+ // Name the file each key came from: a project entry can inherit a stray key from the global file.
400
+ const byFile = new Map<string, Map<string, string[]>>();
401
+ for (const [name, keys] of getOpenCodeIgnoredSettings(imported.value)) {
402
+ if (provenance.get(name)?.ignoredSettingsSource !== "opencode") continue;
403
+ for (const key of keys) {
404
+ const path = imported.keySources?.get(name)?.get(key) ?? imported.path;
405
+ const servers = byFile.get(path) ?? new Map<string, string[]>();
406
+ servers.set(name, [...servers.get(name) ?? [], key]);
407
+ byFile.set(path, servers);
408
+ }
409
+ }
410
+ return [...byFile].map(([path, servers]) => {
411
+ const ignored = [...servers].map(([name, settings]) => `"${name}": ${settings.join(", ")}`);
412
+ return `${path}: OpenCode ignores these settings, so the import does too (details in /mcp-adapter): ${ignored.join("; ")}.`;
413
+ });
414
+ }
415
+
304
416
  export function getSharedConfigPath(target: SharedConfigTarget, cwd = process.cwd()): string {
305
417
  return target === "project" ? getProjectConfigPath(cwd) : getGenericGlobalConfigPath();
306
418
  }
@@ -447,6 +559,8 @@ interface ImportedServerSource {
447
559
  interface LoadedHostConfig {
448
560
  config: McpConfig;
449
561
  serverSources: Map<string, ImportedServerSource>;
562
+ /** OpenCode imports only: the file that last set each key of each server. */
563
+ keySources?: Map<string, Map<string, string>>;
450
564
  }
451
565
 
452
566
  export const MCP_CONFIG_SOURCE_METADATA = Symbol.for("pi-mcp-adapter/config-source-metadata");
@@ -910,6 +1024,18 @@ function mergeConfigs(base: McpConfig, next: McpConfig): McpConfig {
910
1024
  // otherwise the original endpoint's credentials would be shipped to the new
911
1025
  // url. See the SECURITY note in mergeServerMaps.
912
1026
  const URL_BOUND_AUTH_FIELDS = ["headers", "bearerToken", "bearerTokenEnv", "bearerTokenStore", "requestHeadersCommand", "caFile"] as const;
1027
+ const CREDENTIAL_FIELDS = [...URL_BOUND_AUTH_FIELDS, "auth", "oauth"] as const;
1028
+
1029
+ /** The credential fields of `existing` that mergeServerMaps drops for `definition`'s different url. */
1030
+ function droppedUrlBoundAuth(existing: ServerEntry, definition: ServerEntry): (typeof CREDENTIAL_FIELDS)[number][] {
1031
+ if (typeof definition.url !== "string" || definition.url === existing.url) return [];
1032
+ return CREDENTIAL_FIELDS.filter((field) => {
1033
+ if (Object.hasOwn(definition, field)) return false;
1034
+ if (field === "auth") return typeof existing.auth === "object";
1035
+ if (field === "oauth") return existing.oauth !== undefined && existing.oauth !== false;
1036
+ return existing[field] !== undefined;
1037
+ });
1038
+ }
913
1039
 
914
1040
  function mergeServerMaps(
915
1041
  base: Record<string, ServerEntry>,
@@ -956,14 +1082,11 @@ function mergeServerMaps(
956
1082
  }
957
1083
  if (existing && typeof definition.url === "string" && definition.url !== existing.url) {
958
1084
  if (baseEntry === existing) baseEntry = { ...existing };
959
- for (const field of URL_BOUND_AUTH_FIELDS) {
1085
+ // Provider tokens (object `auth`) and OAuth config are bound to the url too; the startup
1086
+ // notice reports exactly these fields, so both read the one rule.
1087
+ for (const field of droppedUrlBoundAuth(existing, definition)) {
960
1088
  delete baseEntry[field];
961
1089
  }
962
- // A provider token is bound to the url that asked for it, like the fields above.
963
- if (typeof baseEntry.auth === "object") delete baseEntry.auth;
964
- if (baseEntry.oauth !== false) {
965
- delete baseEntry.oauth;
966
- }
967
1090
  }
968
1091
  if (existing && Object.hasOwn(definition, "env") && isBuiltInAgentPlugin(existing, "env") && !Object.hasOwn(definition, "literalEnv")) {
969
1092
  if (baseEntry === existing) baseEntry = { ...existing };
@@ -985,6 +1108,7 @@ function expandImports(config: McpConfig, cwd = process.cwd()): LoadedHostConfig
985
1108
 
986
1109
  const importedServers: Record<string, ServerEntry> = {};
987
1110
  const serverSources = new Map<string, ImportedServerSource>();
1111
+ const keySources = new Map<string, Map<string, string>>();
988
1112
  for (const importKind of config.imports) {
989
1113
  const imported = loadImportedConfig(importKind, cwd, `Failed to import MCP config from ${importKind}:`);
990
1114
  if (!imported) continue;
@@ -994,6 +1118,8 @@ function expandImports(config: McpConfig, cwd = process.cwd()): LoadedHostConfig
994
1118
  if (!importedServers[name]) {
995
1119
  importedServers[name] = definition;
996
1120
  serverSources.set(name, imported.serverSources.get(name) ?? imported.source);
1121
+ const keys = imported.keySources?.get(name);
1122
+ if (keys) keySources.set(name, keys);
997
1123
  }
998
1124
  }
999
1125
  }
@@ -1006,6 +1132,7 @@ function expandImports(config: McpConfig, cwd = process.cwd()): LoadedHostConfig
1006
1132
  mcpServers: mergeServerMaps(importedServers, config.mcpServers),
1007
1133
  },
1008
1134
  serverSources,
1135
+ keySources,
1009
1136
  };
1010
1137
  }
1011
1138
 
@@ -1047,11 +1174,19 @@ function loadImportedConfig(
1047
1174
  importKind: ImportKind,
1048
1175
  cwd: string,
1049
1176
  warningPrefix: string,
1050
- ): { path: string; value: unknown; source: ImportedServerSource; serverSources: Map<string, ImportedServerSource> } | null {
1177
+ ): {
1178
+ path: string;
1179
+ value: unknown;
1180
+ source: ImportedServerSource;
1181
+ serverSources: Map<string, ImportedServerSource>;
1182
+ /** OpenCode only: the file that last set each key of each server, in merge order. */
1183
+ keySources?: Map<string, Map<string, string>>;
1184
+ } | null {
1051
1185
  if (importKind === "opencode") {
1052
1186
  let merged: Record<string, unknown> = {};
1053
1187
  let highestPrecedenceSource: ImportedServerSource | undefined;
1054
1188
  const serverSources = new Map<string, ImportedServerSource>();
1189
+ const keySources = new Map<string, Map<string, string>>();
1055
1190
 
1056
1191
  for (const source of resolveImportCandidates(importKind, cwd)) {
1057
1192
  const { path } = source;
@@ -1067,8 +1202,13 @@ function loadImportedConfig(
1067
1202
  const entries = isRecord(mcp.servers)
1068
1203
  ? { ...Object.fromEntries(Object.entries(mcp).filter(([name]) => name !== "servers" && name !== "timeout")), ...mcp.servers }
1069
1204
  : mcp;
1070
- const normalized = Object.fromEntries(Object.entries(entries).map(([name, entry]) => {
1071
- if (!isRecord(entry) || !isRecord(entry.oauth)) return [name, entry];
1205
+ const normalized = Object.fromEntries(Object.entries(entries).map(([name, raw]) => {
1206
+ if (!isRecord(raw)) return [name, raw];
1207
+ // OpenCode reads only `environment`; the import also accepts the common `env` spelling.
1208
+ // `environment` wins when both are set, since that is what OpenCode runs.
1209
+ const { env, ...rest } = raw;
1210
+ const entry = env !== undefined && rest.environment === undefined ? { ...rest, environment: env } : rest;
1211
+ if (!isRecord(entry.oauth)) return [name, entry];
1072
1212
  const { client_id, client_secret, auth_server_metadata_url, ...oauth } = entry.oauth;
1073
1213
  return [name, {
1074
1214
  ...entry,
@@ -1081,7 +1221,13 @@ function loadImportedConfig(
1081
1221
  }];
1082
1222
  }));
1083
1223
  merged = mergeOpenCodeConfigs(merged, { ...imported, mcp: normalized });
1084
- for (const name of Object.keys(normalized)) serverSources.set(name, source);
1224
+ for (const [name, entry] of Object.entries(normalized)) {
1225
+ serverSources.set(name, source);
1226
+ if (!isRecord(entry)) continue;
1227
+ const keys = keySources.get(name) ?? new Map<string, string>();
1228
+ for (const key of Object.keys(entry)) keys.set(key, path);
1229
+ keySources.set(name, keys);
1230
+ }
1085
1231
  highestPrecedenceSource = source;
1086
1232
  }
1087
1233
  } catch (error) {
@@ -1099,6 +1245,7 @@ function loadImportedConfig(
1099
1245
  value: merged,
1100
1246
  source: highestPrecedenceSource,
1101
1247
  serverSources,
1248
+ keySources,
1102
1249
  };
1103
1250
  }
1104
1251
 
@@ -1385,6 +1532,24 @@ function isStringRecord(value: unknown): value is Record<string, string> {
1385
1532
  return isRecord(value) && Object.values(value).every((entry) => typeof entry === "string");
1386
1533
  }
1387
1534
 
1535
+ // OpenCode's schema allows only these keys on a server (V1 and V2 forms) and silently drops the rest.
1536
+ const OPENCODE_LOCAL_SERVER_KEYS = new Set(["type", "command", "cwd", "environment", "enabled", "disabled", "codemode", "timeout", "protocol"]);
1537
+ const OPENCODE_REMOTE_SERVER_KEYS = new Set(["type", "url", "headers", "oauth", "enabled", "disabled", "codemode", "timeout", "protocol"]);
1538
+
1539
+ /** Keys of imported OpenCode servers that OpenCode ignores, so the import ignores them too. */
1540
+ function getOpenCodeIgnoredSettings(merged: unknown): Map<string, string[]> {
1541
+ const ignored = new Map<string, string[]>();
1542
+ const entries = isRecord(merged) && isRecord(merged.mcp) ? merged.mcp : {};
1543
+ for (const name of Object.keys(extractServers(merged, "opencode"))) {
1544
+ const entry = entries[name];
1545
+ if (!isRecord(entry) || (entry.type !== "local" && entry.type !== "remote")) continue;
1546
+ const allowed = entry.type === "local" ? OPENCODE_LOCAL_SERVER_KEYS : OPENCODE_REMOTE_SERVER_KEYS;
1547
+ const keys = Object.keys(entry).filter((key) => !allowed.has(key));
1548
+ if (keys.length > 0) ignored.set(name, keys);
1549
+ }
1550
+ return ignored;
1551
+ }
1552
+
1388
1553
  function mergeOpenCodeConfigs(base: Record<string, unknown>, next: Record<string, unknown>): Record<string, unknown> {
1389
1554
  const baseMcp = base.mcp;
1390
1555
  const nextMcp = next.mcp;
@@ -1925,16 +2090,21 @@ export function writeSharedServerEntry(filePath: string, serverName: string, ent
1925
2090
  export function getServerProvenance(overridePath?: string, cwd = process.cwd()): Map<string, ServerProvenance> {
1926
2091
  const provenance = new Map<string, ServerProvenance>();
1927
2092
  const userPath = getPiGlobalConfigPath(overridePath);
2093
+ const importProvenance = (importKind: ImportKind, value: unknown): Map<string, ServerProvenance> => {
2094
+ const ignored = importKind === "opencode" ? getOpenCodeIgnoredSettings(value) : new Map<string, string[]>();
2095
+ return new Map(Object.keys(extractServers(value, importKind)).map((name): [string, ServerProvenance] => {
2096
+ const ignoredSettings = ignored.get(name);
2097
+ // Keep writes inside adapter-owned storage even though the source is external.
2098
+ return [name, { path: userPath, kind: "import", importKind, ...(ignoredSettings ? { ignoredSettings, ignoredSettingsSource: "opencode" } : {}) }];
2099
+ }));
2100
+ };
1928
2101
 
1929
2102
  if (getConfiguredHostConfigDiscovery(overridePath, cwd) === "on") {
1930
2103
  for (const importKind of Object.keys(IMPORT_PATHS) as ImportKind[]) {
1931
2104
  const imported = loadImportedConfig(importKind, cwd, `Failed to inspect imported MCP config from ${importKind}:`);
1932
2105
  if (!imported) continue;
1933
- for (const name of Object.keys(extractServers(imported.value, importKind))) {
1934
- // Keep writes inside adapter-owned storage even though the source is external.
1935
- // Later import kinds win in the same deterministic order as loadDiscoveredHostConfigs.
1936
- provenance.set(name, { path: userPath, kind: "import", importKind });
1937
- }
2106
+ // Later import kinds win in the same deterministic order as loadDiscoveredHostConfigs.
2107
+ for (const [name, prov] of importProvenance(importKind, imported.value)) provenance.set(name, prov);
1938
2108
  }
1939
2109
  }
1940
2110
 
@@ -1942,22 +2112,28 @@ export function getServerProvenance(overridePath?: string, cwd = process.cwd()):
1942
2112
  const loaded = readSourceConfig(source.id, source.readPath);
1943
2113
  if (!loaded) continue;
1944
2114
  if (loaded.imports?.length) {
2115
+ // Same precedence as expandImports + mergeConfigs: the first import in a file wins, and a later file replaces earlier ones.
2116
+ const imported = new Set<string>();
1945
2117
  for (const importKind of loaded.imports) {
1946
- const imported = loadImportedConfig(importKind, cwd, `Failed to inspect imported MCP config from ${importKind}:`);
1947
- if (!imported) continue;
2118
+ const importedConfig = loadImportedConfig(importKind, cwd, `Failed to inspect imported MCP config from ${importKind}:`);
2119
+ if (!importedConfig) continue;
1948
2120
 
1949
- const servers = extractServers(imported.value, importKind);
1950
- for (const name of Object.keys(servers)) {
1951
- if (!provenance.has(name)) {
1952
- provenance.set(name, { path: userPath, kind: "import", importKind });
1953
- }
2121
+ for (const [name, prov] of importProvenance(importKind, importedConfig.value)) {
2122
+ if (imported.has(name)) continue;
2123
+ imported.add(name);
2124
+ provenance.set(name, prov);
1954
2125
  }
1955
2126
  }
1956
2127
  }
1957
2128
 
1958
2129
  for (const name of Object.keys(loaded.mcpServers)) {
1959
2130
  // A Pi entry brings its own list; other sources keep the one from the Pi entry below them.
1960
- const ignoredSettings = loaded.ignoredSettings ? loaded.ignoredSettings.get(name) : provenance.get(name)?.ignoredSettings;
2131
+ // A source that defines the server replaces an OpenCode import, so its OpenCode list no longer applies.
2132
+ // (`loaded.mcpServers` holds only the file's own servers, so a plain import keeps its list.)
2133
+ const below = provenance.get(name);
2134
+ const ignoredSettings = loaded.ignoredSettings
2135
+ ? loaded.ignoredSettings.get(name)
2136
+ : below?.ignoredSettingsSource === "opencode" ? undefined : below?.ignoredSettings;
1961
2137
  provenance.set(name, {
1962
2138
  path: source.writePath,
1963
2139
  kind: source.kind,
@@ -1,4 +1,5 @@
1
1
  import { spawn } from "node:child_process";
2
+ import { getWindowsCommandBash } from "./utils.js";
2
3
  const DEFAULT_TTL_MS = 5 * 60_000;
3
4
  const ENV_TTL_MS = "PI_MCP_ADAPTER_BEARER_COMMAND_TTL_MS";
4
5
  const COMMAND_TIMEOUT_MS = 10_000;
@@ -16,12 +17,15 @@ function runCommand(command, context, signal) {
16
17
  let output = Buffer.alloc(0);
17
18
  let settled = false;
18
19
  let terminating = false;
19
- const child = spawn(command.slice(1), {
20
- shell: true,
20
+ const options = {
21
21
  stdio: ["ignore", "pipe", "ignore"],
22
22
  windowsHide: true,
23
23
  detached: USE_PROCESS_GROUP,
24
- });
24
+ };
25
+ const bash = getWindowsCommandBash();
26
+ const child = bash === undefined
27
+ ? spawn(command.slice(1), { ...options, shell: true })
28
+ : spawn(bash, ["-c", command.slice(1)], { ...options, shell: false });
25
29
  const kill = async () => {
26
30
  if (child.pid === undefined)
27
31
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"bearer-command-resolver.js","sourceRoot":"","sources":["../bearer-command-resolver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bearer-command-resolver.js","sourceRoot":"","sources":["../bearer-command-resolver.ts"],"names":[],"mappings":"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"}