agent-relay-orchestrator 0.91.2 → 0.91.4
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/package.json +3 -2
- package/src/git.ts +14 -0
- package/src/shared-callmux.ts +46 -4
- package/src/terminal-stream.ts +6 -0
- package/src/workspace-probe/merge.ts +90 -9
- package/vendor/callmux/bin/callmux.js +47579 -0
- package/vendor/callmux/package.json +11 -0
- package/vendor/callmux/schema.json +868 -0
|
@@ -0,0 +1,868 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://raw.githubusercontent.com/edimuj/callmux/main/schema.json",
|
|
4
|
+
"title": "callmux configuration",
|
|
5
|
+
"description": "Configuration for the callmux MCP multiplexer proxy",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"oneOf": [
|
|
8
|
+
{
|
|
9
|
+
"required": ["servers"],
|
|
10
|
+
"not": { "required": ["mcpServers"] }
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"required": ["mcpServers"],
|
|
14
|
+
"not": { "required": ["servers"] }
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"allOf": [
|
|
18
|
+
{
|
|
19
|
+
"not": {
|
|
20
|
+
"required": ["metaOnly", "exposeMetaTools"],
|
|
21
|
+
"properties": {
|
|
22
|
+
"metaOnly": { "const": true },
|
|
23
|
+
"exposeMetaTools": { "const": false }
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"properties": {
|
|
29
|
+
"$schema": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"description": "JSON Schema reference for editor autocomplete"
|
|
32
|
+
},
|
|
33
|
+
"servers": {
|
|
34
|
+
"type": "object",
|
|
35
|
+
"description": "Downstream MCP servers to proxy (native format)",
|
|
36
|
+
"additionalProperties": { "$ref": "#/$defs/serverConfig" }
|
|
37
|
+
},
|
|
38
|
+
"mcpServers": {
|
|
39
|
+
"type": "object",
|
|
40
|
+
"description": "Downstream MCP servers to proxy (MCP-compatible format)",
|
|
41
|
+
"additionalProperties": { "$ref": "#/$defs/serverConfig" }
|
|
42
|
+
},
|
|
43
|
+
"recipes": {
|
|
44
|
+
"type": "object",
|
|
45
|
+
"description": "Named reusable callmux meta-tool recipes",
|
|
46
|
+
"additionalProperties": { "$ref": "#/$defs/recipeConfig" }
|
|
47
|
+
},
|
|
48
|
+
"cacheTtlSeconds": {
|
|
49
|
+
"type": "integer",
|
|
50
|
+
"minimum": 0,
|
|
51
|
+
"default": 0,
|
|
52
|
+
"description": "Cache TTL in seconds for read operations (0 = disabled)"
|
|
53
|
+
},
|
|
54
|
+
"cachePolicy": { "$ref": "#/$defs/cachePolicy" },
|
|
55
|
+
"maxConcurrency": {
|
|
56
|
+
"type": "integer",
|
|
57
|
+
"minimum": 1,
|
|
58
|
+
"default": 20,
|
|
59
|
+
"description": "Max concurrent calls for parallel/batch operations"
|
|
60
|
+
},
|
|
61
|
+
"connectTimeoutMs": {
|
|
62
|
+
"type": "integer",
|
|
63
|
+
"minimum": 1,
|
|
64
|
+
"default": 30000,
|
|
65
|
+
"description": "Timeout in milliseconds for downstream startup connect/list-tools"
|
|
66
|
+
},
|
|
67
|
+
"callTimeoutMs": {
|
|
68
|
+
"type": "integer",
|
|
69
|
+
"minimum": 1,
|
|
70
|
+
"default": 180000,
|
|
71
|
+
"description": "Timeout in milliseconds for downstream tool calls"
|
|
72
|
+
},
|
|
73
|
+
"reconnectPolicy": { "$ref": "#/$defs/reconnectPolicy" },
|
|
74
|
+
"sessionCwdIdleTtlSeconds": {
|
|
75
|
+
"type": "integer",
|
|
76
|
+
"minimum": 0,
|
|
77
|
+
"default": 600,
|
|
78
|
+
"description": "Idle TTL in seconds for listener-mode session cwd stdio clients (0 = close after each call)"
|
|
79
|
+
},
|
|
80
|
+
"strictStartup": {
|
|
81
|
+
"type": "boolean",
|
|
82
|
+
"default": false,
|
|
83
|
+
"description": "Fail startup if any downstream server fails to connect (default: degraded mode)"
|
|
84
|
+
},
|
|
85
|
+
"maxCacheEntries": {
|
|
86
|
+
"type": "integer",
|
|
87
|
+
"minimum": 1,
|
|
88
|
+
"default": 1000,
|
|
89
|
+
"description": "Maximum cached entries before oldest entries are evicted"
|
|
90
|
+
},
|
|
91
|
+
"metaOnly": {
|
|
92
|
+
"type": "boolean",
|
|
93
|
+
"default": false,
|
|
94
|
+
"description": "Hide proxied tools, expose only meta-tools (callmux_call, parallel, batch, etc.)"
|
|
95
|
+
},
|
|
96
|
+
"exposeMetaTools": {
|
|
97
|
+
"type": "boolean",
|
|
98
|
+
"default": true,
|
|
99
|
+
"description": "Expose callmux_* meta-tools in tools/list. Set false to expose only proxied downstream tools."
|
|
100
|
+
},
|
|
101
|
+
"descriptionMaxLength": {
|
|
102
|
+
"type": "integer",
|
|
103
|
+
"minimum": 1,
|
|
104
|
+
"description": "Default max chars for tool descriptions in callmux_status (omit = no limit)"
|
|
105
|
+
},
|
|
106
|
+
"outputFormat": {
|
|
107
|
+
"type": "string",
|
|
108
|
+
"enum": ["json", "toon", "auto"],
|
|
109
|
+
"default": "json",
|
|
110
|
+
"description": "Model-facing text format for callmux-owned structured results. structuredContent remains JSON."
|
|
111
|
+
},
|
|
112
|
+
"responseShield": { "$ref": "#/$defs/globalResponseShield" },
|
|
113
|
+
"schemaCompression": { "$ref": "#/$defs/schemaCompression" },
|
|
114
|
+
"requestBodyMaxBytes": {
|
|
115
|
+
"type": "integer",
|
|
116
|
+
"minimum": 0,
|
|
117
|
+
"default": 1048576,
|
|
118
|
+
"description": "Global max inbound request payload bytes (0 = unlimited)"
|
|
119
|
+
},
|
|
120
|
+
"allowRequestBodyMaxOverride": {
|
|
121
|
+
"type": "boolean",
|
|
122
|
+
"default": false,
|
|
123
|
+
"description": "Allow per-request x-callmux-max-body-bytes override header"
|
|
124
|
+
},
|
|
125
|
+
"auth": { "$ref": "#/$defs/authConfig" },
|
|
126
|
+
"authorization": { "$ref": "#/$defs/authorizationConfig" },
|
|
127
|
+
"abuseControls": { "$ref": "#/$defs/abuseControlsConfig" },
|
|
128
|
+
"auditLog": { "$ref": "#/$defs/auditLogConfig" },
|
|
129
|
+
"metrics": { "$ref": "#/$defs/metricsConfig" },
|
|
130
|
+
"dashboard": { "$ref": "#/$defs/dashboardConfig" },
|
|
131
|
+
"eventStore": { "$ref": "#/$defs/eventStoreConfig" },
|
|
132
|
+
"management": { "$ref": "#/$defs/managementConfig" },
|
|
133
|
+
"allowInsecureRemoteListener": {
|
|
134
|
+
"type": "boolean",
|
|
135
|
+
"default": false,
|
|
136
|
+
"description": "Allow non-loopback listener startup without auth (unsafe, not recommended)"
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
"additionalProperties": false,
|
|
140
|
+
"$defs": {
|
|
141
|
+
"serverConfig": {
|
|
142
|
+
"type": "object",
|
|
143
|
+
"description": "Downstream MCP server configuration — either stdio (command) or HTTP (url)",
|
|
144
|
+
"oneOf": [
|
|
145
|
+
{ "$ref": "#/$defs/stdioServerConfig" },
|
|
146
|
+
{ "$ref": "#/$defs/httpServerConfig" }
|
|
147
|
+
]
|
|
148
|
+
},
|
|
149
|
+
"stdioServerConfig": {
|
|
150
|
+
"type": "object",
|
|
151
|
+
"required": ["command"],
|
|
152
|
+
"properties": {
|
|
153
|
+
"command": {
|
|
154
|
+
"type": "string",
|
|
155
|
+
"minLength": 1,
|
|
156
|
+
"description": "Command to launch the MCP server process"
|
|
157
|
+
},
|
|
158
|
+
"args": {
|
|
159
|
+
"type": "array",
|
|
160
|
+
"items": { "type": "string" },
|
|
161
|
+
"description": "Arguments passed to the command"
|
|
162
|
+
},
|
|
163
|
+
"env": {
|
|
164
|
+
"type": "object",
|
|
165
|
+
"additionalProperties": { "type": "string" },
|
|
166
|
+
"description": "Environment variables for the server process"
|
|
167
|
+
},
|
|
168
|
+
"cwd": {
|
|
169
|
+
"type": "string",
|
|
170
|
+
"description": "Working directory for the server process"
|
|
171
|
+
},
|
|
172
|
+
"cwdMode": {
|
|
173
|
+
"type": "string",
|
|
174
|
+
"enum": ["global", "session"],
|
|
175
|
+
"description": "Working directory behavior for listener mode stdio calls. Omit to use per-session cwd when available; set global to always use the configured/process cwd."
|
|
176
|
+
},
|
|
177
|
+
"requireSessionCwd": {
|
|
178
|
+
"type": "boolean",
|
|
179
|
+
"description": "For session-cwd (path-sensitive) servers: refuse a call with an actionable error when the caller's working directory cannot be resolved, instead of silently running relative paths against callmux's own cwd. Default false."
|
|
180
|
+
},
|
|
181
|
+
"tools": {
|
|
182
|
+
"type": "array",
|
|
183
|
+
"items": { "type": "string" },
|
|
184
|
+
"description": "Whitelist of tool names to expose (omit to expose all)"
|
|
185
|
+
},
|
|
186
|
+
"alwaysLoad": {
|
|
187
|
+
"type": "array",
|
|
188
|
+
"items": { "type": "string" },
|
|
189
|
+
"description": "Tool names eagerly loaded by the MCP client (sets _meta anthropic/alwaysLoad)"
|
|
190
|
+
},
|
|
191
|
+
"prefix": {
|
|
192
|
+
"type": "string",
|
|
193
|
+
"pattern": "^[A-Za-z0-9_]*$",
|
|
194
|
+
"description": "Override the multi-server sub-prefix for this server's tools (default: the server key). \"\" drops the prefix entirely. Ignored in single-server mode."
|
|
195
|
+
},
|
|
196
|
+
"cachePolicy": { "$ref": "#/$defs/cachePolicy" },
|
|
197
|
+
"maxConcurrency": {
|
|
198
|
+
"type": "integer",
|
|
199
|
+
"minimum": 1,
|
|
200
|
+
"description": "Max concurrent calls to this server (omit to use global maxConcurrency)"
|
|
201
|
+
},
|
|
202
|
+
"callTimeoutMs": {
|
|
203
|
+
"type": "integer",
|
|
204
|
+
"minimum": 1,
|
|
205
|
+
"description": "Timeout in milliseconds for tool calls to this server (omit to use global callTimeoutMs)"
|
|
206
|
+
},
|
|
207
|
+
"requestBodyMaxBytes": {
|
|
208
|
+
"type": "integer",
|
|
209
|
+
"minimum": 0,
|
|
210
|
+
"description": "Per-server max inbound request payload bytes for calls targeting this server (0 = unlimited, omit = use global)"
|
|
211
|
+
},
|
|
212
|
+
"responseShield": { "$ref": "#/$defs/serverResponseShield" },
|
|
213
|
+
"schemaCompression": { "$ref": "#/$defs/schemaCompression" },
|
|
214
|
+
"disabled": {
|
|
215
|
+
"type": "boolean",
|
|
216
|
+
"default": false,
|
|
217
|
+
"description": "Exclude this server from downstream connection and tool exposure"
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
"not": { "required": ["url"] },
|
|
221
|
+
"additionalProperties": false
|
|
222
|
+
},
|
|
223
|
+
"httpServerConfig": {
|
|
224
|
+
"type": "object",
|
|
225
|
+
"required": ["url"],
|
|
226
|
+
"properties": {
|
|
227
|
+
"url": {
|
|
228
|
+
"type": "string",
|
|
229
|
+
"format": "uri",
|
|
230
|
+
"description": "URL of the remote MCP server"
|
|
231
|
+
},
|
|
232
|
+
"transport": {
|
|
233
|
+
"type": "string",
|
|
234
|
+
"enum": ["streamable-http", "sse"],
|
|
235
|
+
"description": "Transport protocol (auto-detected with fallback if omitted)"
|
|
236
|
+
},
|
|
237
|
+
"headers": {
|
|
238
|
+
"type": "object",
|
|
239
|
+
"additionalProperties": { "type": "string" },
|
|
240
|
+
"description": "HTTP headers sent with requests (e.g. authorization)"
|
|
241
|
+
},
|
|
242
|
+
"forwardHeaders": {
|
|
243
|
+
"type": "array",
|
|
244
|
+
"items": {
|
|
245
|
+
"type": "string",
|
|
246
|
+
"pattern": "^[!#$%&'*+.^_`|~0-9A-Za-z-]+$"
|
|
247
|
+
},
|
|
248
|
+
"description": "Incoming listener headers to forward to this downstream per client session (opaque passthrough)"
|
|
249
|
+
},
|
|
250
|
+
"tools": {
|
|
251
|
+
"type": "array",
|
|
252
|
+
"items": { "type": "string" },
|
|
253
|
+
"description": "Whitelist of tool names to expose (omit to expose all)"
|
|
254
|
+
},
|
|
255
|
+
"alwaysLoad": {
|
|
256
|
+
"type": "array",
|
|
257
|
+
"items": { "type": "string" },
|
|
258
|
+
"description": "Tool names eagerly loaded by the MCP client (sets _meta anthropic/alwaysLoad)"
|
|
259
|
+
},
|
|
260
|
+
"prefix": {
|
|
261
|
+
"type": "string",
|
|
262
|
+
"pattern": "^[A-Za-z0-9_]*$",
|
|
263
|
+
"description": "Override the multi-server sub-prefix for this server's tools (default: the server key). \"\" drops the prefix entirely. Ignored in single-server mode."
|
|
264
|
+
},
|
|
265
|
+
"cachePolicy": { "$ref": "#/$defs/cachePolicy" },
|
|
266
|
+
"maxConcurrency": {
|
|
267
|
+
"type": "integer",
|
|
268
|
+
"minimum": 1,
|
|
269
|
+
"description": "Max concurrent calls to this server (omit to use global maxConcurrency)"
|
|
270
|
+
},
|
|
271
|
+
"callTimeoutMs": {
|
|
272
|
+
"type": "integer",
|
|
273
|
+
"minimum": 1,
|
|
274
|
+
"description": "Timeout in milliseconds for tool calls to this server (omit to use global callTimeoutMs)"
|
|
275
|
+
},
|
|
276
|
+
"requestBodyMaxBytes": {
|
|
277
|
+
"type": "integer",
|
|
278
|
+
"minimum": 0,
|
|
279
|
+
"description": "Per-server max inbound request payload bytes for calls targeting this server (0 = unlimited, omit = use global)"
|
|
280
|
+
},
|
|
281
|
+
"responseShield": { "$ref": "#/$defs/serverResponseShield" },
|
|
282
|
+
"schemaCompression": { "$ref": "#/$defs/schemaCompression" },
|
|
283
|
+
"disabled": {
|
|
284
|
+
"type": "boolean",
|
|
285
|
+
"default": false,
|
|
286
|
+
"description": "Exclude this server from downstream connection and tool exposure"
|
|
287
|
+
}
|
|
288
|
+
},
|
|
289
|
+
"not": { "required": ["command"] },
|
|
290
|
+
"additionalProperties": false
|
|
291
|
+
},
|
|
292
|
+
"cachePolicy": {
|
|
293
|
+
"type": "object",
|
|
294
|
+
"description": "Cache policy controlling which tools are cached. Supports exact names or trailing '*' wildcards.",
|
|
295
|
+
"properties": {
|
|
296
|
+
"allowTools": {
|
|
297
|
+
"type": "array",
|
|
298
|
+
"items": { "type": "string" },
|
|
299
|
+
"description": "Only cache matching tools (exact names or 'prefix*' wildcards)"
|
|
300
|
+
},
|
|
301
|
+
"denyTools": {
|
|
302
|
+
"type": "array",
|
|
303
|
+
"items": { "type": "string" },
|
|
304
|
+
"description": "Never cache matching tools (exact names or 'prefix*' wildcards). Takes precedence over allowTools."
|
|
305
|
+
}
|
|
306
|
+
},
|
|
307
|
+
"additionalProperties": false
|
|
308
|
+
},
|
|
309
|
+
"reconnectPolicy": {
|
|
310
|
+
"type": "object",
|
|
311
|
+
"description": "Downstream reconnect retry/backoff policy. By default callmux retries forever with bounded jittered backoff.",
|
|
312
|
+
"properties": {
|
|
313
|
+
"initialDelayMs": {
|
|
314
|
+
"type": "integer",
|
|
315
|
+
"minimum": 1,
|
|
316
|
+
"default": 250,
|
|
317
|
+
"description": "Initial reconnect backoff in milliseconds"
|
|
318
|
+
},
|
|
319
|
+
"maxDelayMs": {
|
|
320
|
+
"type": "integer",
|
|
321
|
+
"minimum": 1,
|
|
322
|
+
"default": 10000,
|
|
323
|
+
"description": "Maximum reconnect backoff in milliseconds"
|
|
324
|
+
},
|
|
325
|
+
"jitterRatio": {
|
|
326
|
+
"type": "number",
|
|
327
|
+
"minimum": 0,
|
|
328
|
+
"maximum": 1,
|
|
329
|
+
"default": 0.2,
|
|
330
|
+
"description": "Random jitter ratio applied to reconnect delays"
|
|
331
|
+
},
|
|
332
|
+
"maxAttempts": {
|
|
333
|
+
"type": ["integer", "null"],
|
|
334
|
+
"minimum": 1,
|
|
335
|
+
"default": null,
|
|
336
|
+
"description": "Maximum failed reconnect attempts before stopping; null retries forever"
|
|
337
|
+
},
|
|
338
|
+
"fastFailDuringBackoff": {
|
|
339
|
+
"type": "boolean",
|
|
340
|
+
"default": true,
|
|
341
|
+
"description": "Return downstream_unavailable during scheduled backoff instead of blocking each call on connect"
|
|
342
|
+
}
|
|
343
|
+
},
|
|
344
|
+
"additionalProperties": false
|
|
345
|
+
},
|
|
346
|
+
"responseShieldBase": {
|
|
347
|
+
"type": "object",
|
|
348
|
+
"description": "Response shielding policy. Large results are compacted, stored, and returned with a callmux_get_result ref.",
|
|
349
|
+
"properties": {
|
|
350
|
+
"enabled": {
|
|
351
|
+
"type": "boolean",
|
|
352
|
+
"default": true,
|
|
353
|
+
"description": "Enable response shielding"
|
|
354
|
+
},
|
|
355
|
+
"maxResultBytes": {
|
|
356
|
+
"type": "integer",
|
|
357
|
+
"minimum": 1,
|
|
358
|
+
"default": 65536,
|
|
359
|
+
"description": "Store and compact responses larger than this many serialized bytes"
|
|
360
|
+
},
|
|
361
|
+
"maxStringChars": {
|
|
362
|
+
"type": "integer",
|
|
363
|
+
"minimum": 1,
|
|
364
|
+
"default": 8192,
|
|
365
|
+
"description": "Truncate individual string fields longer than this many characters"
|
|
366
|
+
},
|
|
367
|
+
"maxArrayItems": {
|
|
368
|
+
"type": "integer",
|
|
369
|
+
"minimum": 1,
|
|
370
|
+
"default": 50,
|
|
371
|
+
"description": "Truncate arrays longer than this many items"
|
|
372
|
+
},
|
|
373
|
+
"allowTools": {
|
|
374
|
+
"type": "array",
|
|
375
|
+
"items": { "type": "string" },
|
|
376
|
+
"description": "Only shield matching tools (exact names or '*' wildcards)"
|
|
377
|
+
},
|
|
378
|
+
"denyTools": {
|
|
379
|
+
"type": "array",
|
|
380
|
+
"items": { "type": "string" },
|
|
381
|
+
"description": "Never shield matching tools (exact names or '*' wildcards). Takes precedence over allowTools."
|
|
382
|
+
}
|
|
383
|
+
},
|
|
384
|
+
"additionalProperties": false
|
|
385
|
+
},
|
|
386
|
+
"globalResponseShield": {
|
|
387
|
+
"type": "object",
|
|
388
|
+
"description": "Global response shielding policy. Large results are compacted, stored, and returned with a callmux_get_result ref.",
|
|
389
|
+
"properties": {
|
|
390
|
+
"enabled": {
|
|
391
|
+
"type": "boolean",
|
|
392
|
+
"default": true,
|
|
393
|
+
"description": "Enable response shielding"
|
|
394
|
+
},
|
|
395
|
+
"maxResultBytes": {
|
|
396
|
+
"type": "integer",
|
|
397
|
+
"minimum": 1,
|
|
398
|
+
"default": 65536,
|
|
399
|
+
"description": "Store and compact responses larger than this many serialized bytes"
|
|
400
|
+
},
|
|
401
|
+
"maxStringChars": {
|
|
402
|
+
"type": "integer",
|
|
403
|
+
"minimum": 1,
|
|
404
|
+
"default": 8192,
|
|
405
|
+
"description": "Truncate individual string fields longer than this many characters"
|
|
406
|
+
},
|
|
407
|
+
"maxArrayItems": {
|
|
408
|
+
"type": "integer",
|
|
409
|
+
"minimum": 1,
|
|
410
|
+
"default": 50,
|
|
411
|
+
"description": "Truncate arrays longer than this many items"
|
|
412
|
+
},
|
|
413
|
+
"maxStoredResults": {
|
|
414
|
+
"type": "integer",
|
|
415
|
+
"minimum": 1,
|
|
416
|
+
"default": 100,
|
|
417
|
+
"description": "Maximum stored full results before oldest refs are evicted"
|
|
418
|
+
},
|
|
419
|
+
"allowTools": {
|
|
420
|
+
"type": "array",
|
|
421
|
+
"items": { "type": "string" },
|
|
422
|
+
"description": "Only shield matching tools (exact names or '*' wildcards)"
|
|
423
|
+
},
|
|
424
|
+
"denyTools": {
|
|
425
|
+
"type": "array",
|
|
426
|
+
"items": { "type": "string" },
|
|
427
|
+
"description": "Never shield matching tools (exact names or '*' wildcards). Takes precedence over allowTools."
|
|
428
|
+
}
|
|
429
|
+
},
|
|
430
|
+
"additionalProperties": false
|
|
431
|
+
},
|
|
432
|
+
"serverResponseShield": { "$ref": "#/$defs/responseShieldBase" },
|
|
433
|
+
"schemaCompression": {
|
|
434
|
+
"type": "object",
|
|
435
|
+
"description": "Tool schema compression policy. Reduces prompt tokens by minimizing tool and parameter descriptions without changing schema semantics.",
|
|
436
|
+
"properties": {
|
|
437
|
+
"enabled": {
|
|
438
|
+
"type": "boolean",
|
|
439
|
+
"default": true,
|
|
440
|
+
"description": "Enable tool schema compression"
|
|
441
|
+
},
|
|
442
|
+
"mode": {
|
|
443
|
+
"type": "string",
|
|
444
|
+
"enum": ["off", "balanced", "aggressive"],
|
|
445
|
+
"default": "balanced",
|
|
446
|
+
"description": "Compression mode for tool and parameter descriptions"
|
|
447
|
+
},
|
|
448
|
+
"maxDescriptionChars": {
|
|
449
|
+
"type": "integer",
|
|
450
|
+
"minimum": 1,
|
|
451
|
+
"default": 160,
|
|
452
|
+
"description": "Maximum characters for retained descriptions"
|
|
453
|
+
}
|
|
454
|
+
},
|
|
455
|
+
"additionalProperties": false
|
|
456
|
+
},
|
|
457
|
+
"dashboardConfig": {
|
|
458
|
+
"type": "object",
|
|
459
|
+
"description": "Read-only listener dashboard configuration. Disabled by default.",
|
|
460
|
+
"properties": {
|
|
461
|
+
"enabled": {
|
|
462
|
+
"type": "boolean",
|
|
463
|
+
"default": false,
|
|
464
|
+
"description": "Enable read-only dashboard endpoints"
|
|
465
|
+
},
|
|
466
|
+
"path": {
|
|
467
|
+
"type": "string",
|
|
468
|
+
"default": "/dashboard",
|
|
469
|
+
"description": "Dashboard base path"
|
|
470
|
+
},
|
|
471
|
+
"maxEvents": {
|
|
472
|
+
"type": "integer",
|
|
473
|
+
"minimum": 1,
|
|
474
|
+
"default": 500,
|
|
475
|
+
"description": "Maximum runtime events kept in memory"
|
|
476
|
+
}
|
|
477
|
+
},
|
|
478
|
+
"additionalProperties": false
|
|
479
|
+
},
|
|
480
|
+
"eventStoreConfig": {
|
|
481
|
+
"type": "object",
|
|
482
|
+
"description": "Optional node:sqlite call event history store. Disabled by default.",
|
|
483
|
+
"properties": {
|
|
484
|
+
"enabled": {
|
|
485
|
+
"type": "boolean",
|
|
486
|
+
"default": false,
|
|
487
|
+
"description": "Enable SQLite-backed per-call event history"
|
|
488
|
+
},
|
|
489
|
+
"path": {
|
|
490
|
+
"type": "string",
|
|
491
|
+
"minLength": 1,
|
|
492
|
+
"description": "SQLite database path (default: callmux-events.sqlite beside the config file)"
|
|
493
|
+
},
|
|
494
|
+
"maxRows": {
|
|
495
|
+
"type": "integer",
|
|
496
|
+
"minimum": 0,
|
|
497
|
+
"default": 100000,
|
|
498
|
+
"description": "Maximum retained call event rows (0 = age-only retention)"
|
|
499
|
+
},
|
|
500
|
+
"retentionDays": {
|
|
501
|
+
"type": "integer",
|
|
502
|
+
"minimum": 0,
|
|
503
|
+
"default": 14,
|
|
504
|
+
"description": "Maximum retained event age in days (0 = row-count-only retention)"
|
|
505
|
+
},
|
|
506
|
+
"pruneEvery": {
|
|
507
|
+
"type": "integer",
|
|
508
|
+
"minimum": 1,
|
|
509
|
+
"default": 100,
|
|
510
|
+
"description": "Completed calls between retention prune passes"
|
|
511
|
+
}
|
|
512
|
+
},
|
|
513
|
+
"additionalProperties": false
|
|
514
|
+
},
|
|
515
|
+
"managementConfig": {
|
|
516
|
+
"type": "object",
|
|
517
|
+
"description": "Standalone listener management API configuration. Disabled by default.",
|
|
518
|
+
"properties": {
|
|
519
|
+
"enabled": {
|
|
520
|
+
"type": "boolean",
|
|
521
|
+
"default": false,
|
|
522
|
+
"description": "Enable management API endpoints"
|
|
523
|
+
},
|
|
524
|
+
"path": {
|
|
525
|
+
"type": "string",
|
|
526
|
+
"default": "/management/v1",
|
|
527
|
+
"description": "Management API base path"
|
|
528
|
+
},
|
|
529
|
+
"statePath": {
|
|
530
|
+
"type": "string",
|
|
531
|
+
"description": "Persistent managed overlay path. Defaults to <config>.management.json in listener mode."
|
|
532
|
+
},
|
|
533
|
+
"auth": {
|
|
534
|
+
"$ref": "#/$defs/bearerAuthConfig",
|
|
535
|
+
"description": "Bearer auth required for management mutations"
|
|
536
|
+
},
|
|
537
|
+
"allowUnauthenticatedRead": {
|
|
538
|
+
"type": "boolean",
|
|
539
|
+
"default": false,
|
|
540
|
+
"description": "Allow read-only management endpoints without management auth. Mutations still require auth."
|
|
541
|
+
}
|
|
542
|
+
},
|
|
543
|
+
"additionalProperties": false
|
|
544
|
+
},
|
|
545
|
+
"recipeArguments": {
|
|
546
|
+
"type": "object",
|
|
547
|
+
"description": "Arguments object. Use {\"$param\":\"name\"} as a value to substitute callmux_recipe_run arguments.",
|
|
548
|
+
"additionalProperties": true
|
|
549
|
+
},
|
|
550
|
+
"recipeCall": {
|
|
551
|
+
"type": "object",
|
|
552
|
+
"required": ["tool"],
|
|
553
|
+
"properties": {
|
|
554
|
+
"server": { "type": "string", "minLength": 1 },
|
|
555
|
+
"tool": { "type": "string", "minLength": 1 },
|
|
556
|
+
"arguments": { "$ref": "#/$defs/recipeArguments" },
|
|
557
|
+
"timeoutMs": { "type": "integer", "minimum": 1 },
|
|
558
|
+
"cwd": { "type": "string", "minLength": 1 }
|
|
559
|
+
},
|
|
560
|
+
"additionalProperties": false
|
|
561
|
+
},
|
|
562
|
+
"recipeBatchItem": {
|
|
563
|
+
"type": "object",
|
|
564
|
+
"required": ["arguments"],
|
|
565
|
+
"properties": {
|
|
566
|
+
"arguments": { "$ref": "#/$defs/recipeArguments" },
|
|
567
|
+
"timeoutMs": { "type": "integer", "minimum": 1 },
|
|
568
|
+
"cwd": { "type": "string", "minLength": 1 }
|
|
569
|
+
},
|
|
570
|
+
"additionalProperties": false
|
|
571
|
+
},
|
|
572
|
+
"recipePipelineStep": {
|
|
573
|
+
"type": "object",
|
|
574
|
+
"required": ["tool"],
|
|
575
|
+
"properties": {
|
|
576
|
+
"server": { "type": "string", "minLength": 1 },
|
|
577
|
+
"tool": { "type": "string", "minLength": 1 },
|
|
578
|
+
"arguments": { "$ref": "#/$defs/recipeArguments" },
|
|
579
|
+
"timeoutMs": { "type": "integer", "minimum": 1 },
|
|
580
|
+
"cwd": { "type": "string", "minLength": 1 },
|
|
581
|
+
"inputMapping": {
|
|
582
|
+
"type": "object",
|
|
583
|
+
"additionalProperties": { "type": "string" }
|
|
584
|
+
}
|
|
585
|
+
},
|
|
586
|
+
"additionalProperties": false
|
|
587
|
+
},
|
|
588
|
+
"recipeConfig": {
|
|
589
|
+
"type": "object",
|
|
590
|
+
"description": "Reusable named callmux workflow. Runs as callmux_call, callmux_parallel, callmux_batch, or callmux_pipeline.",
|
|
591
|
+
"required": ["mode"],
|
|
592
|
+
"properties": {
|
|
593
|
+
"description": { "type": "string", "minLength": 1 },
|
|
594
|
+
"mode": {
|
|
595
|
+
"type": "string",
|
|
596
|
+
"enum": ["call", "parallel", "batch", "pipeline"]
|
|
597
|
+
},
|
|
598
|
+
"server": { "type": "string", "minLength": 1 },
|
|
599
|
+
"tool": { "type": "string", "minLength": 1 },
|
|
600
|
+
"arguments": { "$ref": "#/$defs/recipeArguments" },
|
|
601
|
+
"timeoutMs": { "type": "integer", "minimum": 1 },
|
|
602
|
+
"cwd": { "type": "string", "minLength": 1 },
|
|
603
|
+
"calls": {
|
|
604
|
+
"type": "array",
|
|
605
|
+
"items": { "$ref": "#/$defs/recipeCall" }
|
|
606
|
+
},
|
|
607
|
+
"items": {
|
|
608
|
+
"type": "array",
|
|
609
|
+
"items": { "$ref": "#/$defs/recipeBatchItem" }
|
|
610
|
+
},
|
|
611
|
+
"steps": {
|
|
612
|
+
"type": "array",
|
|
613
|
+
"minItems": 1,
|
|
614
|
+
"items": { "$ref": "#/$defs/recipePipelineStep" }
|
|
615
|
+
}
|
|
616
|
+
},
|
|
617
|
+
"oneOf": [
|
|
618
|
+
{ "properties": { "mode": { "const": "call" } }, "required": ["tool"] },
|
|
619
|
+
{ "properties": { "mode": { "const": "parallel" } }, "required": ["calls"] },
|
|
620
|
+
{ "properties": { "mode": { "const": "batch" } }, "required": ["tool", "items"] },
|
|
621
|
+
{ "properties": { "mode": { "const": "pipeline" } }, "required": ["steps"] }
|
|
622
|
+
],
|
|
623
|
+
"additionalProperties": false
|
|
624
|
+
},
|
|
625
|
+
"authConfig": {
|
|
626
|
+
"description": "Listener authentication configuration",
|
|
627
|
+
"oneOf": [
|
|
628
|
+
{ "$ref": "#/$defs/bearerAuthConfig" },
|
|
629
|
+
{ "$ref": "#/$defs/oidcJwtAuthConfig" }
|
|
630
|
+
]
|
|
631
|
+
},
|
|
632
|
+
"bearerAuthToken": {
|
|
633
|
+
"type": "object",
|
|
634
|
+
"required": ["id"],
|
|
635
|
+
"properties": {
|
|
636
|
+
"id": {
|
|
637
|
+
"type": "string",
|
|
638
|
+
"minLength": 1,
|
|
639
|
+
"description": "Stable token identifier for audit/logging"
|
|
640
|
+
},
|
|
641
|
+
"hash": {
|
|
642
|
+
"type": "string",
|
|
643
|
+
"minLength": 1,
|
|
644
|
+
"description": "Scrypt hash of bearer token"
|
|
645
|
+
},
|
|
646
|
+
"hashRef": {
|
|
647
|
+
"type": "string",
|
|
648
|
+
"minLength": 1,
|
|
649
|
+
"description": "Secret reference for hash (`env:NAME` or `file:/path`)"
|
|
650
|
+
},
|
|
651
|
+
"token": {
|
|
652
|
+
"type": "string",
|
|
653
|
+
"minLength": 1,
|
|
654
|
+
"description": "Bearer token value (legacy migration mode)"
|
|
655
|
+
},
|
|
656
|
+
"tokenRef": {
|
|
657
|
+
"type": "string",
|
|
658
|
+
"minLength": 1,
|
|
659
|
+
"description": "Secret reference for plaintext token (`env:NAME` or `file:/path`)"
|
|
660
|
+
}
|
|
661
|
+
},
|
|
662
|
+
"oneOf": [
|
|
663
|
+
{ "required": ["hash"], "not": { "anyOf": [{ "required": ["token"] }, { "required": ["hashRef"] }, { "required": ["tokenRef"] }] } },
|
|
664
|
+
{ "required": ["hashRef"], "not": { "anyOf": [{ "required": ["token"] }, { "required": ["hash"] }, { "required": ["tokenRef"] }] } },
|
|
665
|
+
{ "required": ["token"], "not": { "anyOf": [{ "required": ["hash"] }, { "required": ["hashRef"] }, { "required": ["tokenRef"] }] } },
|
|
666
|
+
{ "required": ["tokenRef"], "not": { "anyOf": [{ "required": ["token"] }, { "required": ["hash"] }, { "required": ["hashRef"] }] } }
|
|
667
|
+
],
|
|
668
|
+
"additionalProperties": false
|
|
669
|
+
},
|
|
670
|
+
"bearerAuthConfig": {
|
|
671
|
+
"type": "object",
|
|
672
|
+
"required": ["mode", "tokens"],
|
|
673
|
+
"properties": {
|
|
674
|
+
"mode": {
|
|
675
|
+
"type": "string",
|
|
676
|
+
"enum": ["bearer"],
|
|
677
|
+
"description": "Authentication mode"
|
|
678
|
+
},
|
|
679
|
+
"tokens": {
|
|
680
|
+
"type": "array",
|
|
681
|
+
"minItems": 1,
|
|
682
|
+
"items": { "$ref": "#/$defs/bearerAuthToken" }
|
|
683
|
+
},
|
|
684
|
+
"allowUnauthenticatedHealth": {
|
|
685
|
+
"type": "boolean",
|
|
686
|
+
"default": false,
|
|
687
|
+
"description": "Allow unauthenticated access to /health"
|
|
688
|
+
}
|
|
689
|
+
},
|
|
690
|
+
"additionalProperties": false
|
|
691
|
+
},
|
|
692
|
+
"oidcJwtAuthConfig": {
|
|
693
|
+
"type": "object",
|
|
694
|
+
"required": ["mode", "issuer", "audience", "jwksUri"],
|
|
695
|
+
"properties": {
|
|
696
|
+
"mode": {
|
|
697
|
+
"type": "string",
|
|
698
|
+
"enum": ["oidc_jwt"],
|
|
699
|
+
"description": "OIDC JWT bearer authentication mode"
|
|
700
|
+
},
|
|
701
|
+
"issuer": {
|
|
702
|
+
"type": "string",
|
|
703
|
+
"minLength": 1,
|
|
704
|
+
"description": "Expected issuer claim (`iss`)"
|
|
705
|
+
},
|
|
706
|
+
"audience": {
|
|
707
|
+
"description": "Expected audience claim (`aud`)",
|
|
708
|
+
"oneOf": [
|
|
709
|
+
{ "type": "string", "minLength": 1 },
|
|
710
|
+
{
|
|
711
|
+
"type": "array",
|
|
712
|
+
"minItems": 1,
|
|
713
|
+
"items": { "type": "string", "minLength": 1 }
|
|
714
|
+
}
|
|
715
|
+
]
|
|
716
|
+
},
|
|
717
|
+
"jwksUri": {
|
|
718
|
+
"type": "string",
|
|
719
|
+
"minLength": 1,
|
|
720
|
+
"description": "JWKS endpoint URL for signature verification"
|
|
721
|
+
},
|
|
722
|
+
"algorithms": {
|
|
723
|
+
"type": "array",
|
|
724
|
+
"items": {
|
|
725
|
+
"type": "string",
|
|
726
|
+
"enum": ["RS256", "RS384", "RS512", "ES256", "ES384", "ES512"]
|
|
727
|
+
},
|
|
728
|
+
"description": "Allowed JWT signature algorithms (default: RS256)"
|
|
729
|
+
},
|
|
730
|
+
"clockSkewSeconds": {
|
|
731
|
+
"type": "integer",
|
|
732
|
+
"minimum": 0,
|
|
733
|
+
"description": "Clock skew tolerance for exp/nbf checks"
|
|
734
|
+
},
|
|
735
|
+
"jwksCacheTtlSeconds": {
|
|
736
|
+
"type": "integer",
|
|
737
|
+
"minimum": 0,
|
|
738
|
+
"description": "JWKS cache TTL in seconds"
|
|
739
|
+
},
|
|
740
|
+
"jwksFetchTimeoutMs": {
|
|
741
|
+
"type": "integer",
|
|
742
|
+
"minimum": 1,
|
|
743
|
+
"description": "JWKS fetch timeout in milliseconds"
|
|
744
|
+
},
|
|
745
|
+
"allowUnauthenticatedHealth": {
|
|
746
|
+
"type": "boolean",
|
|
747
|
+
"default": false,
|
|
748
|
+
"description": "Allow unauthenticated access to /health"
|
|
749
|
+
}
|
|
750
|
+
},
|
|
751
|
+
"additionalProperties": false
|
|
752
|
+
},
|
|
753
|
+
"authorizationRuleConfig": {
|
|
754
|
+
"type": "object",
|
|
755
|
+
"required": ["effect"],
|
|
756
|
+
"properties": {
|
|
757
|
+
"id": {
|
|
758
|
+
"type": "string",
|
|
759
|
+
"minLength": 1,
|
|
760
|
+
"description": "Stable policy rule identifier"
|
|
761
|
+
},
|
|
762
|
+
"effect": {
|
|
763
|
+
"type": "string",
|
|
764
|
+
"enum": ["allow", "deny"],
|
|
765
|
+
"description": "Rule effect"
|
|
766
|
+
},
|
|
767
|
+
"principals": {
|
|
768
|
+
"type": "array",
|
|
769
|
+
"items": { "type": "string" },
|
|
770
|
+
"description": "Principal patterns (supports '*' wildcards)"
|
|
771
|
+
},
|
|
772
|
+
"tools": {
|
|
773
|
+
"type": "array",
|
|
774
|
+
"items": { "type": "string" },
|
|
775
|
+
"description": "Tool patterns (supports '*' wildcards, including server__tool)"
|
|
776
|
+
}
|
|
777
|
+
},
|
|
778
|
+
"additionalProperties": false
|
|
779
|
+
},
|
|
780
|
+
"authorizationConfig": {
|
|
781
|
+
"type": "object",
|
|
782
|
+
"required": ["rules"],
|
|
783
|
+
"properties": {
|
|
784
|
+
"defaultEffect": {
|
|
785
|
+
"type": "string",
|
|
786
|
+
"enum": ["allow", "deny"],
|
|
787
|
+
"description": "Default effect when no rule matches"
|
|
788
|
+
},
|
|
789
|
+
"rules": {
|
|
790
|
+
"type": "array",
|
|
791
|
+
"minItems": 1,
|
|
792
|
+
"items": { "$ref": "#/$defs/authorizationRuleConfig" },
|
|
793
|
+
"description": "Ordered authorization policy rules"
|
|
794
|
+
}
|
|
795
|
+
},
|
|
796
|
+
"additionalProperties": false
|
|
797
|
+
},
|
|
798
|
+
"abuseControlsConfig": {
|
|
799
|
+
"type": "object",
|
|
800
|
+
"properties": {
|
|
801
|
+
"globalRequestsPerMinute": {
|
|
802
|
+
"type": "integer",
|
|
803
|
+
"minimum": 1,
|
|
804
|
+
"description": "Max total requests per minute across all principals"
|
|
805
|
+
},
|
|
806
|
+
"principalRequestsPerMinute": {
|
|
807
|
+
"type": "integer",
|
|
808
|
+
"minimum": 1,
|
|
809
|
+
"description": "Max requests per minute for each principal"
|
|
810
|
+
},
|
|
811
|
+
"principalMaxInFlight": {
|
|
812
|
+
"type": "integer",
|
|
813
|
+
"minimum": 1,
|
|
814
|
+
"description": "Max concurrent in-flight requests per principal"
|
|
815
|
+
},
|
|
816
|
+
"cidrAllowlist": {
|
|
817
|
+
"type": "array",
|
|
818
|
+
"items": { "type": "string" },
|
|
819
|
+
"description": "Allowed source CIDRs/IPs for listener requests"
|
|
820
|
+
}
|
|
821
|
+
},
|
|
822
|
+
"additionalProperties": false
|
|
823
|
+
},
|
|
824
|
+
"auditLogConfig": {
|
|
825
|
+
"type": "object",
|
|
826
|
+
"properties": {
|
|
827
|
+
"enabled": {
|
|
828
|
+
"type": "boolean",
|
|
829
|
+
"description": "Enable structured audit logging"
|
|
830
|
+
},
|
|
831
|
+
"includeRequestBody": {
|
|
832
|
+
"type": "boolean",
|
|
833
|
+
"description": "Include redacted request payload details when available"
|
|
834
|
+
},
|
|
835
|
+
"maxPayloadChars": {
|
|
836
|
+
"type": "integer",
|
|
837
|
+
"minimum": 0,
|
|
838
|
+
"description": "Maximum serialized payload chars in audit log (0 = omit payload)"
|
|
839
|
+
},
|
|
840
|
+
"redactKeys": {
|
|
841
|
+
"type": "array",
|
|
842
|
+
"items": { "type": "string" },
|
|
843
|
+
"description": "Additional payload keys to redact"
|
|
844
|
+
}
|
|
845
|
+
},
|
|
846
|
+
"additionalProperties": false
|
|
847
|
+
},
|
|
848
|
+
"metricsConfig": {
|
|
849
|
+
"type": "object",
|
|
850
|
+
"properties": {
|
|
851
|
+
"enabled": {
|
|
852
|
+
"type": "boolean",
|
|
853
|
+
"description": "Enable Prometheus metrics endpoint"
|
|
854
|
+
},
|
|
855
|
+
"path": {
|
|
856
|
+
"type": "string",
|
|
857
|
+
"minLength": 1,
|
|
858
|
+
"description": "Metrics endpoint path (default: /metrics)"
|
|
859
|
+
},
|
|
860
|
+
"allowUnauthenticated": {
|
|
861
|
+
"type": "boolean",
|
|
862
|
+
"description": "Allow unauthenticated metrics access"
|
|
863
|
+
}
|
|
864
|
+
},
|
|
865
|
+
"additionalProperties": false
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
}
|