@oisincoveney/pipeline 1.16.1 → 1.16.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/dist/config.d.ts +4 -3
- package/dist/config.js +2 -1
- package/dist/mcp/gateway.js +19 -4
- package/dist/mcp/launch-plan.js +5 -2
- package/dist/pipeline-init.js +1 -1
- package/docs/config-architecture.md +2 -1
- package/docs/mcp-gateway.md +2 -1
- package/docs/operator-guide.md +5 -3
- package/package.json +1 -1
package/dist/config.d.ts
CHANGED
|
@@ -223,8 +223,8 @@ declare const configSchema: z.ZodObject<{
|
|
|
223
223
|
policy: z.ZodOptional<z.ZodObject<{
|
|
224
224
|
commands: z.ZodOptional<z.ZodEnum<{
|
|
225
225
|
allow: "allow";
|
|
226
|
-
"trusted-only": "trusted-only";
|
|
227
226
|
deny: "deny";
|
|
227
|
+
"trusted-only": "trusted-only";
|
|
228
228
|
}>>;
|
|
229
229
|
modules: z.ZodOptional<z.ZodEnum<{
|
|
230
230
|
allow: "allow";
|
|
@@ -240,6 +240,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
240
240
|
}>;
|
|
241
241
|
provider: z.ZodLiteral<"toolhive">;
|
|
242
242
|
token_env: z.ZodDefault<z.ZodString>;
|
|
243
|
+
url: z.ZodOptional<z.ZodString>;
|
|
243
244
|
url_env: z.ZodDefault<z.ZodString>;
|
|
244
245
|
}, z.core.$strict>>;
|
|
245
246
|
mcp_servers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
@@ -278,10 +279,10 @@ declare const configSchema: z.ZodObject<{
|
|
|
278
279
|
}, z.core.$strict>>;
|
|
279
280
|
output: z.ZodOptional<z.ZodObject<{
|
|
280
281
|
format: z.ZodEnum<{
|
|
282
|
+
json_schema: "json_schema";
|
|
281
283
|
text: "text";
|
|
282
284
|
json: "json";
|
|
283
285
|
jsonl: "jsonl";
|
|
284
|
-
json_schema: "json_schema";
|
|
285
286
|
}>;
|
|
286
287
|
repair: z.ZodOptional<z.ZodObject<{
|
|
287
288
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -325,10 +326,10 @@ declare const configSchema: z.ZodObject<{
|
|
|
325
326
|
disabled: "disabled";
|
|
326
327
|
}>>>;
|
|
327
328
|
output_formats: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
329
|
+
json_schema: "json_schema";
|
|
328
330
|
text: "text";
|
|
329
331
|
json: "json";
|
|
330
332
|
jsonl: "jsonl";
|
|
331
|
-
json_schema: "json_schema";
|
|
332
333
|
}>>>;
|
|
333
334
|
rules: z.ZodOptional<z.ZodBoolean>;
|
|
334
335
|
skills: z.ZodOptional<z.ZodBoolean>;
|
package/dist/config.js
CHANGED
|
@@ -132,7 +132,8 @@ const mcpGatewaySchema = z.object({
|
|
|
132
132
|
default_profile: z.string().min(1).optional(),
|
|
133
133
|
mode: z.enum(["hosted", "local"]),
|
|
134
134
|
provider: z.literal("toolhive"),
|
|
135
|
-
token_env: z.string().min(1).default("
|
|
135
|
+
token_env: z.string().min(1).default("MEMORY_MCP_BASIC_AUTH"),
|
|
136
|
+
url: z.string().url().refine((value) => ["http:", "https:"].includes(new URL(value).protocol), { message: "MCP gateway url must use http or https" }).optional(),
|
|
136
137
|
url_env: z.string().min(1).default("PIPELINE_MCP_GATEWAY_URL")
|
|
137
138
|
}).strict();
|
|
138
139
|
const instructionsSchema = z.object({
|
package/dist/mcp/gateway.js
CHANGED
|
@@ -5,6 +5,7 @@ import { execa } from "execa";
|
|
|
5
5
|
//#region src/mcp/gateway.ts
|
|
6
6
|
const PIPELINE_GATEWAY_SERVER_ID = "pipeline-gateway";
|
|
7
7
|
const DEFAULT_LOCAL_GATEWAY_URL = "http://127.0.0.1:4483/mcp";
|
|
8
|
+
const AUTHORIZATION_ENV_RE = /\{env:([A-Za-z_][A-Za-z0-9_]*)\}/g;
|
|
8
9
|
const LEGACY_CODEX_MCP_RE = /\[mcp_servers\./;
|
|
9
10
|
const LEGACY_OPENCODE_MCP_RE = /"mcp"\s*:\s*{(?!\s*"pipeline-gateway")/s;
|
|
10
11
|
const LEGACY_PIPELINE_MCP_RE = /path:\s*\.mcp\.json|uvx\s+mcpm|mcpm\s+run/;
|
|
@@ -25,7 +26,7 @@ function gatewayServer(config, env = process.env) {
|
|
|
25
26
|
const gateway = configuredGateway(config);
|
|
26
27
|
const url = gatewayUrl(gateway, env);
|
|
27
28
|
return {
|
|
28
|
-
|
|
29
|
+
headers: { Authorization: gatewayAuthorizationHeader(gateway) },
|
|
29
30
|
url
|
|
30
31
|
};
|
|
31
32
|
}
|
|
@@ -36,6 +37,7 @@ function configuredGateway(config) {
|
|
|
36
37
|
function gatewayUrl(gateway, env = process.env) {
|
|
37
38
|
const url = env[gateway.url_env];
|
|
38
39
|
if (url) return url;
|
|
40
|
+
if (gateway.url) return gateway.url;
|
|
39
41
|
if (gateway.mode === "local") return DEFAULT_LOCAL_GATEWAY_URL;
|
|
40
42
|
throw new PipelineMcpGatewayError(`MCP gateway URL is required. Set ${gateway.url_env}.`);
|
|
41
43
|
}
|
|
@@ -44,6 +46,7 @@ function renderGatewayConfig(config) {
|
|
|
44
46
|
return [
|
|
45
47
|
`provider: ${gateway.provider}`,
|
|
46
48
|
`mode: ${gateway.mode}`,
|
|
49
|
+
gateway.url ? `url: ${gateway.url}` : "",
|
|
47
50
|
`url_env: ${gateway.url_env}`,
|
|
48
51
|
`token_env: ${gateway.token_env}`,
|
|
49
52
|
gateway.default_profile ? `default_profile: ${gateway.default_profile}` : "",
|
|
@@ -67,7 +70,7 @@ function renderOpenCodeGatewayConfig(config) {
|
|
|
67
70
|
$schema: "https://opencode.ai/config.json",
|
|
68
71
|
mcp: { [PIPELINE_GATEWAY_SERVER_ID]: {
|
|
69
72
|
enabled: true,
|
|
70
|
-
headers:
|
|
73
|
+
headers: gatewayOpenCodeHeaders(gateway),
|
|
71
74
|
type: "remote",
|
|
72
75
|
url: gatewayUrl(gateway)
|
|
73
76
|
} }
|
|
@@ -171,6 +174,17 @@ function checkGatewayToken(gateway) {
|
|
|
171
174
|
passed: false
|
|
172
175
|
};
|
|
173
176
|
}
|
|
177
|
+
function gatewayAuthorizationHeader(gateway) {
|
|
178
|
+
return `Basic {env:${gateway.token_env}}`;
|
|
179
|
+
}
|
|
180
|
+
function resolveHeaderEnvPlaceholders(value, env = process.env) {
|
|
181
|
+
return value.replace(AUTHORIZATION_ENV_RE, (_match, envVar) => {
|
|
182
|
+
return env[envVar] || `{env:${envVar}}`;
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
function gatewayOpenCodeHeaders(gateway) {
|
|
186
|
+
return { Authorization: gatewayAuthorizationHeader(gateway) };
|
|
187
|
+
}
|
|
174
188
|
async function checkThv(cwd) {
|
|
175
189
|
try {
|
|
176
190
|
await execa("thv", ["version"], {
|
|
@@ -240,11 +254,12 @@ async function checkGatewayHealth(gateway) {
|
|
|
240
254
|
}
|
|
241
255
|
}
|
|
242
256
|
async function firstHealthyGatewayResponse(url, gateway) {
|
|
257
|
+
const authorization = process.env[gateway.token_env] ? `Basic ${process.env[gateway.token_env]}` : void 0;
|
|
243
258
|
for (const healthUrl of gatewayHealthUrls(url)) {
|
|
244
259
|
const response = await fetch(healthUrl, {
|
|
245
260
|
headers: {
|
|
246
261
|
Accept: "application/json, text/event-stream",
|
|
247
|
-
...
|
|
262
|
+
...authorization ? { Authorization: authorization } : {}
|
|
248
263
|
},
|
|
249
264
|
method: "GET"
|
|
250
265
|
});
|
|
@@ -287,4 +302,4 @@ function legacyContentHit(cwd, path, pattern) {
|
|
|
287
302
|
return pattern.test(readFileSync(fullPath, "utf8")) ? path : void 0;
|
|
288
303
|
}
|
|
289
304
|
//#endregion
|
|
290
|
-
export { configureGatewayHosts, gatewayServerForProfile, localGatewayStatus, renderGatewayConfig, runGatewayDoctor, startLocalGateway };
|
|
305
|
+
export { configureGatewayHosts, gatewayServerForProfile, localGatewayStatus, renderGatewayConfig, resolveHeaderEnvPlaceholders, runGatewayDoctor, startLocalGateway };
|
package/dist/mcp/launch-plan.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { gatewayServerForProfile } from "./gateway.js";
|
|
1
|
+
import { gatewayServerForProfile, resolveHeaderEnvPlaceholders } from "./gateway.js";
|
|
2
2
|
import { mkdtempSync } from "node:fs";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { tmpdir } from "node:os";
|
|
@@ -74,7 +74,7 @@ function codexMcpArgs(servers) {
|
|
|
74
74
|
if (isRemoteMcpServer(server)) return [
|
|
75
75
|
"--config",
|
|
76
76
|
`mcp_servers.${id}.url=${tomlValue(server.url)}`,
|
|
77
|
-
...server.headers ? ["--config", `mcp_servers.${id}.http_headers=${tomlValue(server.headers)}`] : [],
|
|
77
|
+
...server.headers ? ["--config", `mcp_servers.${id}.http_headers=${tomlValue(codexHttpHeaders(server.headers))}`] : [],
|
|
78
78
|
...server.bearer_token_env_var ? ["--config", `mcp_servers.${id}.bearer_token_env_var=${tomlValue(server.bearer_token_env_var)}`] : []
|
|
79
79
|
];
|
|
80
80
|
return [
|
|
@@ -85,6 +85,9 @@ function codexMcpArgs(servers) {
|
|
|
85
85
|
];
|
|
86
86
|
});
|
|
87
87
|
}
|
|
88
|
+
function codexHttpHeaders(headers) {
|
|
89
|
+
return Object.fromEntries(Object.entries(headers).map(([key, value]) => [key, resolveHeaderEnvPlaceholders(value)]));
|
|
90
|
+
}
|
|
88
91
|
function tomlValue(value) {
|
|
89
92
|
if (Array.isArray(value)) return `[${value.map(tomlValue).join(", ")}]`;
|
|
90
93
|
if (value && typeof value === "object") return `{ ${Object.entries(value).map(([key, item]) => `${tomlKey(key)} = ${tomlValue(item)}`).join(", ")} }`;
|
package/dist/pipeline-init.js
CHANGED
|
@@ -150,8 +150,9 @@ MCP-enabled profiles use one gateway grant:
|
|
|
150
150
|
mcp_gateway:
|
|
151
151
|
provider: toolhive
|
|
152
152
|
mode: hosted
|
|
153
|
+
url: https://pipeline-mcp.momokaya.ee/mcp/
|
|
153
154
|
url_env: PIPELINE_MCP_GATEWAY_URL
|
|
154
|
-
token_env:
|
|
155
|
+
token_env: MEMORY_MCP_BASIC_AUTH
|
|
155
156
|
default_profile: default
|
|
156
157
|
|
|
157
158
|
profiles:
|
package/docs/mcp-gateway.md
CHANGED
|
@@ -52,8 +52,9 @@ Example profile config:
|
|
|
52
52
|
mcp_gateway:
|
|
53
53
|
provider: toolhive
|
|
54
54
|
mode: hosted
|
|
55
|
+
url: https://pipeline-mcp.momokaya.ee/mcp/
|
|
55
56
|
url_env: PIPELINE_MCP_GATEWAY_URL
|
|
56
|
-
token_env:
|
|
57
|
+
token_env: MEMORY_MCP_BASIC_AUTH
|
|
57
58
|
default_profile: default
|
|
58
59
|
|
|
59
60
|
profiles:
|
package/docs/operator-guide.md
CHANGED
|
@@ -378,8 +378,9 @@ Use the same client config shape for hosted and local gateways:
|
|
|
378
378
|
mcp_gateway:
|
|
379
379
|
provider: toolhive
|
|
380
380
|
mode: hosted
|
|
381
|
+
url: https://pipeline-mcp.momokaya.ee/mcp/
|
|
381
382
|
url_env: PIPELINE_MCP_GATEWAY_URL
|
|
382
|
-
token_env:
|
|
383
|
+
token_env: MEMORY_MCP_BASIC_AUTH
|
|
383
384
|
default_profile: default
|
|
384
385
|
```
|
|
385
386
|
|
|
@@ -422,7 +423,7 @@ startup:
|
|
|
422
423
|
# Codex pipeline runs receive MCP gateway config through runtime launch args.
|
|
423
424
|
# Persistent Codex MCP config is intentionally left empty to avoid startup-time MCP fan-out.
|
|
424
425
|
# gateway_url = "https://gateway.example/mcp"
|
|
425
|
-
# token_env = "
|
|
426
|
+
# token_env = "MEMORY_MCP_BASIC_AUTH"
|
|
426
427
|
```
|
|
427
428
|
|
|
428
429
|
OpenCode receives:
|
|
@@ -526,8 +527,9 @@ singleton gateway server to profiles that need MCP.
|
|
|
526
527
|
mcp_gateway:
|
|
527
528
|
provider: toolhive
|
|
528
529
|
mode: hosted
|
|
530
|
+
url: https://pipeline-mcp.momokaya.ee/mcp/
|
|
529
531
|
url_env: PIPELINE_MCP_GATEWAY_URL
|
|
530
|
-
token_env:
|
|
532
|
+
token_env: MEMORY_MCP_BASIC_AUTH
|
|
531
533
|
|
|
532
534
|
profiles:
|
|
533
535
|
pipeline-router:
|
package/package.json
CHANGED
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
"prepack": "bun run build:cli"
|
|
100
100
|
},
|
|
101
101
|
"type": "module",
|
|
102
|
-
"version": "1.16.
|
|
102
|
+
"version": "1.16.2",
|
|
103
103
|
"description": "Config-driven multi-agent pipeline runner for repository work",
|
|
104
104
|
"main": "./dist/index.js",
|
|
105
105
|
"types": "./dist/index.d.ts",
|