pi-mcp-adapter 2.5.2 → 2.5.3
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 +5 -0
- package/README.md +3 -2
- package/metadata-cache.ts +5 -5
- package/package.json +1 -1
- package/server-manager.ts +6 -19
- package/utils.ts +29 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.5.3] - 2026-05-01
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Added environment variable and `~` expansion for stdio server `cwd` values.
|
|
14
|
+
|
|
10
15
|
## [2.5.2] - 2026-04-29
|
|
11
16
|
|
|
12
17
|
### Fixed
|
package/README.md
CHANGED
|
@@ -120,9 +120,10 @@ Pi-specific files are the write targets for imported or shared global servers wh
|
|
|
120
120
|
|-------|-------------|
|
|
121
121
|
| `command` | Executable for stdio transport |
|
|
122
122
|
| `args` | Command arguments |
|
|
123
|
-
| `env` | Environment variables
|
|
124
|
-
| `cwd` | Working directory |
|
|
123
|
+
| `env` | Environment variables; supports `${VAR}` and `$env:VAR` interpolation |
|
|
124
|
+
| `cwd` | Working directory; supports `${VAR}`, `$env:VAR`, and `~` expansion |
|
|
125
125
|
| `url` | HTTP endpoint (StreamableHTTP with SSE fallback) |
|
|
126
|
+
| `headers` | HTTP headers; supports `${VAR}` and `$env:VAR` interpolation |
|
|
126
127
|
| `auth` | `"bearer"` or `"oauth"` |
|
|
127
128
|
| `oauth.grantType` | `"authorization_code"` (default) or `"client_credentials"` for non-interactive machine auth |
|
|
128
129
|
| `bearerToken` / `bearerTokenEnv` | Token or env var name |
|
package/metadata-cache.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { getToolUiResourceUri } from "@modelcontextprotocol/ext-apps/app-bridge"
|
|
|
7
7
|
import type { McpTool, McpResource, ServerEntry, ToolMetadata } from "./types.js";
|
|
8
8
|
import { formatToolName, isToolExcluded } from "./types.js";
|
|
9
9
|
import { resourceNameToToolName } from "./resource-tools.js";
|
|
10
|
-
import { extractToolUiStreamMode } from "./utils.js";
|
|
10
|
+
import { extractToolUiStreamMode, interpolateEnvRecord, resolveConfigPath } from "./utils.js";
|
|
11
11
|
|
|
12
12
|
const CACHE_VERSION = 1;
|
|
13
13
|
const CACHE_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;
|
|
@@ -88,12 +88,12 @@ export function computeServerHash(definition: ServerEntry): string {
|
|
|
88
88
|
const identity: Record<string, unknown> = {
|
|
89
89
|
command: definition.command,
|
|
90
90
|
args: definition.args,
|
|
91
|
-
env: definition.env,
|
|
92
|
-
cwd: definition.cwd,
|
|
91
|
+
env: interpolateEnvRecord(definition.env),
|
|
92
|
+
cwd: resolveConfigPath(definition.cwd),
|
|
93
93
|
url: definition.url,
|
|
94
|
-
headers: definition.headers,
|
|
94
|
+
headers: interpolateEnvRecord(definition.headers),
|
|
95
95
|
auth: definition.auth,
|
|
96
|
-
bearerToken: definition.bearerToken,
|
|
96
|
+
bearerToken: definition.bearerToken ?? (definition.bearerTokenEnv ? process.env[definition.bearerTokenEnv] : undefined),
|
|
97
97
|
bearerTokenEnv: definition.bearerTokenEnv,
|
|
98
98
|
exposeResources: definition.exposeResources,
|
|
99
99
|
excludeTools: definition.excludeTools,
|
package/package.json
CHANGED
package/server-manager.ts
CHANGED
|
@@ -17,6 +17,7 @@ import { logger } from "./logger.js";
|
|
|
17
17
|
import { McpOAuthProvider } from "./mcp-oauth-provider.js";
|
|
18
18
|
import { supportsOAuth } from "./mcp-auth-flow.js";
|
|
19
19
|
import { registerSamplingHandler, type ServerSamplingConfig } from "./sampling-handler.js";
|
|
20
|
+
import { interpolateEnvRecord, resolveConfigPath } from "./utils.js";
|
|
20
21
|
|
|
21
22
|
interface ServerConnection {
|
|
22
23
|
client: Client;
|
|
@@ -91,7 +92,7 @@ export class McpServerManager {
|
|
|
91
92
|
command,
|
|
92
93
|
args,
|
|
93
94
|
env: resolveEnv(definition.env),
|
|
94
|
-
cwd: definition.cwd,
|
|
95
|
+
cwd: resolveConfigPath(definition.cwd),
|
|
95
96
|
stderr: definition.debug ? "inherit" : "ignore",
|
|
96
97
|
});
|
|
97
98
|
} else if (definition.url) {
|
|
@@ -362,28 +363,14 @@ function resolveEnv(env?: Record<string, string>): Record<string, string> {
|
|
|
362
363
|
}
|
|
363
364
|
|
|
364
365
|
if (!env) return resolved;
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
resolved[key] = value
|
|
369
|
-
.replace(/\$\{(\w+)\}/g, (_, name) => process.env[name] ?? "")
|
|
370
|
-
.replace(/\$env:(\w+)/g, (_, name) => process.env[name] ?? "");
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
return resolved;
|
|
366
|
+
|
|
367
|
+
const overrides = interpolateEnvRecord(env);
|
|
368
|
+
return overrides ? { ...resolved, ...overrides } : resolved;
|
|
374
369
|
}
|
|
375
370
|
|
|
376
371
|
/**
|
|
377
372
|
* Resolve headers with environment variable interpolation.
|
|
378
373
|
*/
|
|
379
374
|
function resolveHeaders(headers?: Record<string, string>): Record<string, string> | undefined {
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
const resolved: Record<string, string> = {};
|
|
383
|
-
for (const [key, value] of Object.entries(headers)) {
|
|
384
|
-
resolved[key] = value
|
|
385
|
-
.replace(/\$\{(\w+)\}/g, (_, name) => process.env[name] ?? "")
|
|
386
|
-
.replace(/\$env:(\w+)/g, (_, name) => process.env[name] ?? "");
|
|
387
|
-
}
|
|
388
|
-
return resolved;
|
|
375
|
+
return interpolateEnvRecord(headers);
|
|
389
376
|
}
|
package/utils.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
2
|
-
import { platform } from "node:os";
|
|
2
|
+
import { homedir, platform } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
3
4
|
import type { McpConfig } from "./types.js";
|
|
4
5
|
|
|
5
6
|
async function execOpen(pi: ExtensionAPI, target: string, browser?: string) {
|
|
@@ -58,6 +59,33 @@ export function getConfigPathFromArgv(): string | undefined {
|
|
|
58
59
|
return undefined;
|
|
59
60
|
}
|
|
60
61
|
|
|
62
|
+
export function interpolateEnvVars(value: string): string {
|
|
63
|
+
return value
|
|
64
|
+
.replace(/\$\{(\w+)\}/g, (_, name) => process.env[name] ?? "")
|
|
65
|
+
.replace(/\$env:(\w+)/g, (_, name) => process.env[name] ?? "");
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function interpolateEnvRecord(values: Record<string, string> | undefined): Record<string, string> | undefined {
|
|
69
|
+
if (!values) return undefined;
|
|
70
|
+
|
|
71
|
+
const resolved: Record<string, string> = {};
|
|
72
|
+
for (const [key, value] of Object.entries(values)) {
|
|
73
|
+
resolved[key] = interpolateEnvVars(value);
|
|
74
|
+
}
|
|
75
|
+
return resolved;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function resolveConfigPath(value: string | undefined): string | undefined {
|
|
79
|
+
if (value === undefined) return undefined;
|
|
80
|
+
|
|
81
|
+
const resolved = interpolateEnvVars(value);
|
|
82
|
+
if (resolved === "~") return homedir();
|
|
83
|
+
if (resolved.startsWith("~/") || resolved.startsWith("~\\")) {
|
|
84
|
+
return join(homedir(), resolved.slice(2));
|
|
85
|
+
}
|
|
86
|
+
return resolved;
|
|
87
|
+
}
|
|
88
|
+
|
|
61
89
|
export function truncateAtWord(text: string, target: number): string {
|
|
62
90
|
if (!text || text.length <= target) return text;
|
|
63
91
|
|