@apify/mcpc 0.2.4 → 0.3.0-beta.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 +64 -1
- package/CONTRIBUTING.md +12 -0
- package/NOTICE +27 -0
- package/README.md +219 -226
- package/_config.yml +30 -0
- package/client-logo.svg +79 -0
- package/client-metadata.json +16 -0
- package/dist/bridge/index.js +51 -4
- package/dist/bridge/index.js.map +1 -1
- package/dist/cli/commands/auth.d.ts +2 -0
- package/dist/cli/commands/auth.d.ts.map +1 -1
- package/dist/cli/commands/auth.js +32 -10
- package/dist/cli/commands/auth.js.map +1 -1
- package/dist/cli/commands/clean.d.ts.map +1 -1
- package/dist/cli/commands/clean.js +13 -2
- package/dist/cli/commands/clean.js.map +1 -1
- package/dist/cli/commands/grep.d.ts.map +1 -1
- package/dist/cli/commands/grep.js +39 -8
- package/dist/cli/commands/grep.js.map +1 -1
- package/dist/cli/commands/prompts.d.ts.map +1 -1
- package/dist/cli/commands/prompts.js +7 -26
- package/dist/cli/commands/prompts.js.map +1 -1
- package/dist/cli/commands/resources.d.ts.map +1 -1
- package/dist/cli/commands/resources.js +9 -3
- package/dist/cli/commands/resources.js.map +1 -1
- package/dist/cli/commands/sessions.d.ts +45 -2
- package/dist/cli/commands/sessions.d.ts.map +1 -1
- package/dist/cli/commands/sessions.js +493 -27
- package/dist/cli/commands/sessions.js.map +1 -1
- package/dist/cli/commands/tasks.d.ts +1 -0
- package/dist/cli/commands/tasks.d.ts.map +1 -1
- package/dist/cli/commands/tasks.js +15 -1
- package/dist/cli/commands/tasks.js.map +1 -1
- package/dist/cli/commands/tools.d.ts +6 -1
- package/dist/cli/commands/tools.d.ts.map +1 -1
- package/dist/cli/commands/tools.js +66 -14
- package/dist/cli/commands/tools.js.map +1 -1
- package/dist/cli/commands/x402.d.ts.map +1 -1
- package/dist/cli/commands/x402.js +7 -7
- package/dist/cli/commands/x402.js.map +1 -1
- package/dist/cli/helpers.d.ts.map +1 -1
- package/dist/cli/helpers.js +3 -6
- package/dist/cli/helpers.js.map +1 -1
- package/dist/cli/index.js +370 -131
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/output.d.ts +18 -5
- package/dist/cli/output.d.ts.map +1 -1
- package/dist/cli/output.js +275 -89
- package/dist/cli/output.js.map +1 -1
- package/dist/cli/parser.d.ts +4 -0
- package/dist/cli/parser.d.ts.map +1 -1
- package/dist/cli/parser.js +68 -24
- package/dist/cli/parser.js.map +1 -1
- package/dist/cli/shell.d.ts.map +1 -1
- package/dist/cli/shell.js +44 -21
- package/dist/cli/shell.js.map +1 -1
- package/dist/cli/tool-result.d.ts +1 -1
- package/dist/cli/tool-result.d.ts.map +1 -1
- package/dist/cli/tool-result.js +20 -15
- package/dist/cli/tool-result.js.map +1 -1
- package/dist/core/factory.d.ts +1 -0
- package/dist/core/factory.d.ts.map +1 -1
- package/dist/core/factory.js +3 -0
- package/dist/core/factory.js.map +1 -1
- package/dist/core/mcp-client.d.ts +1 -0
- package/dist/core/mcp-client.d.ts.map +1 -1
- package/dist/core/mcp-client.js +14 -0
- package/dist/core/mcp-client.js.map +1 -1
- package/dist/core/transports.d.ts +5 -1
- package/dist/core/transports.d.ts.map +1 -1
- package/dist/core/transports.js +26 -4
- package/dist/core/transports.js.map +1 -1
- package/dist/lib/auth/auth-page.d.ts +13 -0
- package/dist/lib/auth/auth-page.d.ts.map +1 -0
- package/dist/lib/auth/auth-page.js +129 -0
- package/dist/lib/auth/auth-page.js.map +1 -0
- package/dist/lib/auth/oauth-flow.d.ts +2 -1
- package/dist/lib/auth/oauth-flow.d.ts.map +1 -1
- package/dist/lib/auth/oauth-flow.js +65 -58
- package/dist/lib/auth/oauth-flow.js.map +1 -1
- package/dist/lib/auth/oauth-provider.d.ts +2 -0
- package/dist/lib/auth/oauth-provider.d.ts.map +1 -1
- package/dist/lib/auth/oauth-provider.js +6 -0
- package/dist/lib/auth/oauth-provider.js.map +1 -1
- package/dist/lib/auth/oauth-utils.d.ts +3 -0
- package/dist/lib/auth/oauth-utils.d.ts.map +1 -1
- package/dist/lib/auth/oauth-utils.js +32 -1
- package/dist/lib/auth/oauth-utils.js.map +1 -1
- package/dist/lib/auth/profiles.d.ts.map +1 -1
- package/dist/lib/auth/profiles.js +3 -3
- package/dist/lib/auth/profiles.js.map +1 -1
- package/dist/lib/bridge-manager.d.ts.map +1 -1
- package/dist/lib/bridge-manager.js +43 -28
- package/dist/lib/bridge-manager.js.map +1 -1
- package/dist/lib/cleanup.d.ts +5 -0
- package/dist/lib/cleanup.d.ts.map +1 -1
- package/dist/lib/cleanup.js +38 -1
- package/dist/lib/cleanup.js.map +1 -1
- package/dist/lib/config.d.ts +21 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +99 -5
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/errors.d.ts +1 -0
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +4 -1
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/session-client.d.ts +1 -0
- package/dist/lib/session-client.d.ts.map +1 -1
- package/dist/lib/session-client.js +7 -4
- package/dist/lib/session-client.js.map +1 -1
- package/dist/lib/sessions.d.ts.map +1 -1
- package/dist/lib/sessions.js +18 -9
- package/dist/lib/sessions.js.map +1 -1
- package/dist/lib/types.d.ts +2 -0
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/utils.d.ts +16 -2
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +112 -8
- package/dist/lib/utils.js.map +1 -1
- package/dist/lib/wallets.js +3 -3
- package/dist/lib/wallets.js.map +1 -1
- package/docs/TODOs.md +5 -0
- package/package.json +7 -6
package/dist/cli/output.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { extractAllTextContent } from './tool-result.js';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { getLogsDir } from '../lib/utils.js';
|
|
4
5
|
import { getSession } from '../lib/sessions.js';
|
|
5
|
-
export {
|
|
6
|
+
export { extractAllTextContent } from './tool-result.js';
|
|
6
7
|
function hslToHex(h, s, l) {
|
|
7
8
|
s /= 100;
|
|
8
9
|
l /= 100;
|
|
@@ -16,6 +17,19 @@ function hslToHex(h, s, l) {
|
|
|
16
17
|
};
|
|
17
18
|
return `#${f(0)}${f(8)}${f(4)}`;
|
|
18
19
|
}
|
|
20
|
+
const RAINBOW_HUE_START = 12;
|
|
21
|
+
const RAINBOW_HUE_SPAN = 270;
|
|
22
|
+
const RAINBOW_SATURATION = 45;
|
|
23
|
+
const RAINBOW_LIGHTNESS = 62;
|
|
24
|
+
const themeHex = (hue) => hslToHex(hue, RAINBOW_SATURATION, RAINBOW_LIGHTNESS);
|
|
25
|
+
export const theme = {
|
|
26
|
+
red: chalk.hex(themeHex(12)),
|
|
27
|
+
yellow: chalk.hex(themeHex(60)),
|
|
28
|
+
green: chalk.hex(hslToHex(135, 65, 52)),
|
|
29
|
+
cyan: chalk.hex(themeHex(190)),
|
|
30
|
+
blue: chalk.hex(themeHex(230)),
|
|
31
|
+
magenta: chalk.hex(themeHex(282)),
|
|
32
|
+
};
|
|
19
33
|
export function rainbow(text) {
|
|
20
34
|
const len = text.length;
|
|
21
35
|
if (len === 0)
|
|
@@ -23,9 +37,8 @@ export function rainbow(text) {
|
|
|
23
37
|
return text
|
|
24
38
|
.split('')
|
|
25
39
|
.map((char, i) => {
|
|
26
|
-
const hue =
|
|
27
|
-
|
|
28
|
-
return chalk.hex(hex)(char);
|
|
40
|
+
const hue = RAINBOW_HUE_START + (i / (len - 1)) * RAINBOW_HUE_SPAN;
|
|
41
|
+
return chalk.hex(themeHex(hue))(char);
|
|
29
42
|
})
|
|
30
43
|
.join('');
|
|
31
44
|
}
|
|
@@ -33,9 +46,12 @@ export function formatOutput(data, mode = 'human', options) {
|
|
|
33
46
|
if (mode === 'json') {
|
|
34
47
|
return formatJson(data);
|
|
35
48
|
}
|
|
36
|
-
|
|
49
|
+
let output = formatHuman(data, options);
|
|
37
50
|
if (!output.endsWith('````') && !output.endsWith('\n')) {
|
|
38
|
-
|
|
51
|
+
output += '\n';
|
|
52
|
+
}
|
|
53
|
+
if (options?.maxChars) {
|
|
54
|
+
output = truncateOutput(output, options.maxChars);
|
|
39
55
|
}
|
|
40
56
|
return output;
|
|
41
57
|
}
|
|
@@ -49,16 +65,16 @@ export function formatJson(data) {
|
|
|
49
65
|
function highlightJson(json) {
|
|
50
66
|
return json.replace(/("(?:\\.|[^"\\])*")\s*:|("(?:\\.|[^"\\])*")|(\b(?:true|false|null)\b)|(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)/g, (match, key, str, bool, num) => {
|
|
51
67
|
if (key) {
|
|
52
|
-
return
|
|
68
|
+
return theme.cyan(key) + ':';
|
|
53
69
|
}
|
|
54
70
|
if (str) {
|
|
55
|
-
return
|
|
71
|
+
return theme.green(str);
|
|
56
72
|
}
|
|
57
73
|
if (bool) {
|
|
58
|
-
return
|
|
74
|
+
return theme.magenta(bool);
|
|
59
75
|
}
|
|
60
76
|
if (num) {
|
|
61
|
-
return
|
|
77
|
+
return theme.yellow(num);
|
|
62
78
|
}
|
|
63
79
|
return match;
|
|
64
80
|
});
|
|
@@ -67,9 +83,9 @@ export function formatHuman(data, options) {
|
|
|
67
83
|
if (data === null || data === undefined) {
|
|
68
84
|
return chalk.gray('(no data)');
|
|
69
85
|
}
|
|
70
|
-
const
|
|
71
|
-
if (
|
|
72
|
-
return `${chalk.gray('````')}\n${
|
|
86
|
+
const textContent = extractAllTextContent(data);
|
|
87
|
+
if (textContent !== undefined) {
|
|
88
|
+
return `${chalk.gray('````')}\n${textContent}\n${chalk.gray('````')}`;
|
|
73
89
|
}
|
|
74
90
|
if (Array.isArray(data)) {
|
|
75
91
|
if (data.length === 0) {
|
|
@@ -111,7 +127,7 @@ export function formatToolAnnotations(annotations) {
|
|
|
111
127
|
parts.push('read-only');
|
|
112
128
|
}
|
|
113
129
|
else if (annotations.destructiveHint === true) {
|
|
114
|
-
parts.push(
|
|
130
|
+
parts.push(theme.red('destructive'));
|
|
115
131
|
}
|
|
116
132
|
if (annotations.idempotentHint === true) {
|
|
117
133
|
parts.push('idempotent');
|
|
@@ -121,6 +137,21 @@ export function formatToolAnnotations(annotations) {
|
|
|
121
137
|
}
|
|
122
138
|
return parts.length > 0 ? parts.join(', ') : null;
|
|
123
139
|
}
|
|
140
|
+
export function getToolTaskSupport(tool) {
|
|
141
|
+
const toolAny = tool;
|
|
142
|
+
const execution = toolAny.execution;
|
|
143
|
+
return execution?.taskSupport;
|
|
144
|
+
}
|
|
145
|
+
export function formatToolHints(tool) {
|
|
146
|
+
const parts = [];
|
|
147
|
+
const annotationsStr = formatToolAnnotations(tool.annotations);
|
|
148
|
+
if (annotationsStr)
|
|
149
|
+
parts.push(annotationsStr);
|
|
150
|
+
const taskSupport = getToolTaskSupport(tool);
|
|
151
|
+
if (taskSupport && taskSupport !== 'forbidden')
|
|
152
|
+
parts.push(`task:${taskSupport}`);
|
|
153
|
+
return parts.length > 0 ? parts.join(', ') : null;
|
|
154
|
+
}
|
|
124
155
|
export function formatSchemaType(schema) {
|
|
125
156
|
if (!schema || typeof schema !== 'object') {
|
|
126
157
|
return 'any';
|
|
@@ -161,7 +192,7 @@ export function grayBacktick() {
|
|
|
161
192
|
return chalk.gray('`');
|
|
162
193
|
}
|
|
163
194
|
export function inBackticks(text) {
|
|
164
|
-
return `${grayBacktick()}${
|
|
195
|
+
return `${grayBacktick()}${theme.cyan(text)}${grayBacktick()}`;
|
|
165
196
|
}
|
|
166
197
|
export function formatSimplifiedArgs(schema, indent = '') {
|
|
167
198
|
const lines = [];
|
|
@@ -181,9 +212,9 @@ export function formatSimplifiedArgs(schema, indent = '') {
|
|
|
181
212
|
const isRequired = required.includes(name);
|
|
182
213
|
const description = propSchema.description;
|
|
183
214
|
const defaultValue = propSchema.default;
|
|
184
|
-
let line = `${indent}${bullet} ${inBackticks(name)}: ${
|
|
215
|
+
let line = `${indent}${bullet} ${inBackticks(name)}: ${theme.yellow(typeStr)}`;
|
|
185
216
|
if (isRequired) {
|
|
186
|
-
line += ` ${
|
|
217
|
+
line += ` ${theme.red('[required]')}`;
|
|
187
218
|
}
|
|
188
219
|
if (defaultValue !== undefined) {
|
|
189
220
|
line += chalk.dim(` (default: ${JSON.stringify(defaultValue)})`);
|
|
@@ -262,17 +293,9 @@ export function formatToolParamsInline(schema) {
|
|
|
262
293
|
export function formatToolLine(tool) {
|
|
263
294
|
const bullet = chalk.dim('*');
|
|
264
295
|
const params = formatToolParamsInline(tool.inputSchema);
|
|
265
|
-
const
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
parts.push(annotationsStr);
|
|
269
|
-
const toolAny = tool;
|
|
270
|
-
const execution = toolAny.execution;
|
|
271
|
-
const taskSupport = execution?.taskSupport;
|
|
272
|
-
if (taskSupport)
|
|
273
|
-
parts.push(`task:${taskSupport}`);
|
|
274
|
-
const suffix = parts.length > 0 ? ` ${chalk.gray(`[${parts.join(', ')}]`)}` : '';
|
|
275
|
-
return `${bullet} ${grayBacktick()}${chalk.cyan(tool.name)} ${params}${grayBacktick()}${suffix}`;
|
|
296
|
+
const hintsStr = formatToolHints(tool);
|
|
297
|
+
const suffix = hintsStr ? ` ${chalk.gray(`[${hintsStr}]`)}` : '';
|
|
298
|
+
return `${bullet} ${grayBacktick()}${theme.cyan(tool.name)} ${params}${grayBacktick()}${suffix}`;
|
|
276
299
|
}
|
|
277
300
|
function formatToolsSummary(tools) {
|
|
278
301
|
const lines = [];
|
|
@@ -304,9 +327,9 @@ export function formatToolDetail(tool) {
|
|
|
304
327
|
if (title) {
|
|
305
328
|
lines.push(chalk.bold(`# ${title}`));
|
|
306
329
|
}
|
|
307
|
-
const
|
|
308
|
-
const
|
|
309
|
-
lines.push(`${chalk.bold('Tool:')} ${inBackticks(tool.name)}${
|
|
330
|
+
const hintsStr = formatToolHints(tool);
|
|
331
|
+
const hintsSuffix = hintsStr ? ` ${chalk.gray(`[${hintsStr}]`)}` : '';
|
|
332
|
+
lines.push(`${chalk.bold('Tool:')} ${inBackticks(tool.name)}${hintsSuffix}`);
|
|
310
333
|
lines.push('');
|
|
311
334
|
lines.push(chalk.bold('Input:'));
|
|
312
335
|
const inputArgs = formatSimplifiedArgs(tool.inputSchema, '');
|
|
@@ -327,6 +350,69 @@ export function formatToolDetail(tool) {
|
|
|
327
350
|
}
|
|
328
351
|
return lines.join('\n');
|
|
329
352
|
}
|
|
353
|
+
function exampleValue(propSchema) {
|
|
354
|
+
if (propSchema.default !== undefined) {
|
|
355
|
+
return JSON.stringify(propSchema.default);
|
|
356
|
+
}
|
|
357
|
+
if (propSchema.enum && Array.isArray(propSchema.enum) && propSchema.enum.length > 0) {
|
|
358
|
+
return JSON.stringify(propSchema.enum[0]);
|
|
359
|
+
}
|
|
360
|
+
const schemaType = propSchema.type;
|
|
361
|
+
if (schemaType === 'string')
|
|
362
|
+
return '"something"';
|
|
363
|
+
if (schemaType === 'number')
|
|
364
|
+
return '1';
|
|
365
|
+
if (schemaType === 'integer') {
|
|
366
|
+
const min = propSchema.minimum;
|
|
367
|
+
return String(min ?? 1);
|
|
368
|
+
}
|
|
369
|
+
if (schemaType === 'boolean')
|
|
370
|
+
return 'true';
|
|
371
|
+
if (Array.isArray(schemaType)) {
|
|
372
|
+
const nonNull = schemaType.filter((t) => t !== 'null');
|
|
373
|
+
if (nonNull.includes('string'))
|
|
374
|
+
return '"something"';
|
|
375
|
+
if (nonNull.includes('number') || nonNull.includes('integer'))
|
|
376
|
+
return '1';
|
|
377
|
+
if (nonNull.includes('boolean'))
|
|
378
|
+
return 'true';
|
|
379
|
+
}
|
|
380
|
+
return '"something"';
|
|
381
|
+
}
|
|
382
|
+
function shellSafeExampleValue(jsonValue) {
|
|
383
|
+
if (/^[a-zA-Z0-9_.+-]+$/.test(jsonValue)) {
|
|
384
|
+
return jsonValue;
|
|
385
|
+
}
|
|
386
|
+
return `'${jsonValue.replace(/'/g, `'\\''`)}'`;
|
|
387
|
+
}
|
|
388
|
+
export function formatToolCallExample(tool, sessionName) {
|
|
389
|
+
const schema = tool.inputSchema;
|
|
390
|
+
const properties = schema?.properties;
|
|
391
|
+
const session = sessionName || '<@session>';
|
|
392
|
+
const taskSupport = getToolTaskSupport(tool);
|
|
393
|
+
const taskFlag = taskSupport === 'required' ? ' --task' : taskSupport === 'optional' ? ' [--task]' : '';
|
|
394
|
+
const bullet = chalk.dim('*');
|
|
395
|
+
if (!properties || Object.keys(properties).length === 0) {
|
|
396
|
+
const cmd = `mcpc ${session} tools-call ${tool.name}${taskFlag}`;
|
|
397
|
+
return `${chalk.bold('Call example:')}\n${bullet} ${grayBacktick()}${theme.cyan(cmd)}${grayBacktick()}`;
|
|
398
|
+
}
|
|
399
|
+
const requiredNames = schema?.required || [];
|
|
400
|
+
const allNames = Object.keys(properties);
|
|
401
|
+
const requiredInOrder = allNames.filter((n) => requiredNames.includes(n));
|
|
402
|
+
const optionalInOrder = allNames.filter((n) => !requiredNames.includes(n));
|
|
403
|
+
const MAX_EXAMPLE_PARAMS = 3;
|
|
404
|
+
const params = [...requiredInOrder];
|
|
405
|
+
if (params.length < MAX_EXAMPLE_PARAMS) {
|
|
406
|
+
const remaining = MAX_EXAMPLE_PARAMS - params.length;
|
|
407
|
+
params.push(...optionalInOrder.slice(0, remaining));
|
|
408
|
+
}
|
|
409
|
+
const argParts = params.map((name) => {
|
|
410
|
+
const val = shellSafeExampleValue(exampleValue(properties[name] ?? {}));
|
|
411
|
+
return `${name}:=${val}`;
|
|
412
|
+
});
|
|
413
|
+
const cmd = `mcpc ${session} tools-call ${tool.name} ${argParts.join(' ')}${taskFlag}`;
|
|
414
|
+
return `${chalk.bold('Call example:')}\n${bullet} ${grayBacktick()}${theme.cyan(cmd)}${grayBacktick()}`;
|
|
415
|
+
}
|
|
330
416
|
export function formatResources(resources) {
|
|
331
417
|
const lines = [];
|
|
332
418
|
lines.push(chalk.bold(`Resources (${resources.length}):`));
|
|
@@ -348,7 +434,7 @@ export function formatResourceDetail(resource) {
|
|
|
348
434
|
lines.push(`${chalk.bold('Name:')} ${resource.name}`);
|
|
349
435
|
}
|
|
350
436
|
if (resource.mimeType) {
|
|
351
|
-
lines.push(`${chalk.bold('MIME type:')} ${
|
|
437
|
+
lines.push(`${chalk.bold('MIME type:')} ${theme.yellow(resource.mimeType)}`);
|
|
352
438
|
}
|
|
353
439
|
const description = (resource.description || '').trim();
|
|
354
440
|
if (description) {
|
|
@@ -381,7 +467,7 @@ export function formatResourceTemplateDetail(template) {
|
|
|
381
467
|
lines.push(`${chalk.bold('Name:')} ${template.name}`);
|
|
382
468
|
}
|
|
383
469
|
if (template.mimeType) {
|
|
384
|
-
lines.push(`${chalk.bold('MIME type:')} ${
|
|
470
|
+
lines.push(`${chalk.bold('MIME type:')} ${theme.yellow(template.mimeType)}`);
|
|
385
471
|
}
|
|
386
472
|
const description = (template.description || '').trim();
|
|
387
473
|
if (description) {
|
|
@@ -414,8 +500,8 @@ export function formatPromptDetail(prompt) {
|
|
|
414
500
|
lines.push(chalk.bold('Arguments:'));
|
|
415
501
|
if (prompt.arguments && prompt.arguments.length > 0) {
|
|
416
502
|
for (const arg of prompt.arguments) {
|
|
417
|
-
const typePart =
|
|
418
|
-
const requiredPart = arg.required ? ` ${
|
|
503
|
+
const typePart = theme.yellow('string');
|
|
504
|
+
const requiredPart = arg.required ? ` ${theme.red('[required]')}` : '';
|
|
419
505
|
const description = arg.description ? ` ${chalk.dim('-')} ${arg.description}` : '';
|
|
420
506
|
lines.push(` ${inBackticks(arg.name)}: ${typePart}${requiredPart}${description}`);
|
|
421
507
|
}
|
|
@@ -457,7 +543,7 @@ function formatPromptResult(result) {
|
|
|
457
543
|
lines.push(chalk.bold(`Messages (${result.messages.length}):`));
|
|
458
544
|
for (const message of result.messages) {
|
|
459
545
|
lines.push('');
|
|
460
|
-
lines.push(`${chalk.bold('Role:')} ${
|
|
546
|
+
lines.push(`${chalk.bold('Role:')} ${theme.cyan(message.role)}`);
|
|
461
547
|
lines.push(formatPromptContent(message.content));
|
|
462
548
|
}
|
|
463
549
|
return lines.join('\n');
|
|
@@ -509,26 +595,27 @@ function formatPromptContent(content) {
|
|
|
509
595
|
}
|
|
510
596
|
return lines.join('\n');
|
|
511
597
|
}
|
|
512
|
-
function
|
|
598
|
+
function taskStatusLabel(status) {
|
|
599
|
+
const label = (icon) => `${icon} ${status}`;
|
|
513
600
|
switch (status) {
|
|
514
601
|
case 'working':
|
|
515
|
-
return
|
|
602
|
+
return theme.cyan(label('⟳'));
|
|
516
603
|
case 'input_required':
|
|
517
|
-
return
|
|
604
|
+
return theme.yellow(label('?'));
|
|
518
605
|
case 'completed':
|
|
519
|
-
return
|
|
606
|
+
return theme.green(label('✔'));
|
|
520
607
|
case 'failed':
|
|
521
|
-
return
|
|
608
|
+
return theme.red(label('✖'));
|
|
522
609
|
case 'cancelled':
|
|
523
|
-
return chalk.gray('⊘');
|
|
610
|
+
return chalk.gray(label('⊘'));
|
|
524
611
|
default:
|
|
525
|
-
return chalk.gray('·');
|
|
612
|
+
return chalk.gray(label('·'));
|
|
526
613
|
}
|
|
527
614
|
}
|
|
528
615
|
export function formatTask(task) {
|
|
529
616
|
const lines = [];
|
|
530
|
-
lines.push(`${chalk.bold('Task:')} ${inBackticks(task.taskId)}`);
|
|
531
|
-
lines.push(`${chalk.bold('Status:')} ${
|
|
617
|
+
lines.push(`${chalk.bold('Task ID:')} ${inBackticks(task.taskId)}`);
|
|
618
|
+
lines.push(`${chalk.bold('Status:')} ${taskStatusLabel(task.status)}`);
|
|
532
619
|
if (task.statusMessage) {
|
|
533
620
|
lines.push(`${chalk.bold('Message:')} ${task.statusMessage}`);
|
|
534
621
|
}
|
|
@@ -545,16 +632,115 @@ export function formatTasks(taskList) {
|
|
|
545
632
|
lines.push(chalk.bold(`Tasks (${taskList.length}):`));
|
|
546
633
|
const bullet = chalk.dim('*');
|
|
547
634
|
for (const task of taskList) {
|
|
548
|
-
const statusStr =
|
|
635
|
+
const statusStr = taskStatusLabel(task.status);
|
|
549
636
|
const msgStr = task.statusMessage ? chalk.dim(` - ${task.statusMessage}`) : '';
|
|
550
637
|
lines.push(`${bullet} ${inBackticks(task.taskId)} ${statusStr}${msgStr}`);
|
|
551
638
|
}
|
|
552
639
|
return lines.join('\n');
|
|
553
640
|
}
|
|
641
|
+
function formatContentBlock(block, lines) {
|
|
642
|
+
const bullet = chalk.dim('*');
|
|
643
|
+
switch (block.type) {
|
|
644
|
+
case 'text':
|
|
645
|
+
lines.push(chalk.gray('````'));
|
|
646
|
+
lines.push(block.text);
|
|
647
|
+
lines.push(chalk.gray('````'));
|
|
648
|
+
break;
|
|
649
|
+
case 'resource_link':
|
|
650
|
+
lines.push(chalk.bold('Resource link'));
|
|
651
|
+
lines.push(`${bullet} URI: ${block.uri}`);
|
|
652
|
+
if (block.name)
|
|
653
|
+
lines.push(`${bullet} Name: ${block.name}`);
|
|
654
|
+
if (block.description) {
|
|
655
|
+
lines.push(`${bullet} Description: ${chalk.gray('````')}${block.description}${chalk.gray('````')}`);
|
|
656
|
+
}
|
|
657
|
+
if (block.mimeType)
|
|
658
|
+
lines.push(`${bullet} MIME type: ${block.mimeType}`);
|
|
659
|
+
break;
|
|
660
|
+
case 'image':
|
|
661
|
+
lines.push(`[Image: ${block.mimeType || 'unknown type'}${block.data ? `, ${block.data.length} chars base64` : ''}]`);
|
|
662
|
+
break;
|
|
663
|
+
case 'audio':
|
|
664
|
+
lines.push(`[Audio: ${block.mimeType || 'unknown type'}${block.data ? `, ${block.data.length} chars base64` : ''}]`);
|
|
665
|
+
break;
|
|
666
|
+
case 'resource':
|
|
667
|
+
lines.push(chalk.bold('Embedded resource'));
|
|
668
|
+
if (block.resource) {
|
|
669
|
+
lines.push(`${bullet} URI: ${block.resource.uri}`);
|
|
670
|
+
if (block.resource.mimeType)
|
|
671
|
+
lines.push(`${bullet} MIME type: ${block.resource.mimeType}`);
|
|
672
|
+
if ('text' in block.resource && block.resource.text) {
|
|
673
|
+
lines.push(chalk.gray('````'));
|
|
674
|
+
lines.push(block.resource.text);
|
|
675
|
+
lines.push(chalk.gray('````'));
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
break;
|
|
679
|
+
default:
|
|
680
|
+
lines.push(JSON.stringify(block, null, 2));
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
function findDuplicateTextBlocks(content, structuredContent) {
|
|
684
|
+
const dupes = new Set();
|
|
685
|
+
const canonical = JSON.stringify(structuredContent);
|
|
686
|
+
for (let i = 0; i < content.length; i++) {
|
|
687
|
+
const block = content[i];
|
|
688
|
+
if (!block || block.type !== 'text')
|
|
689
|
+
continue;
|
|
690
|
+
try {
|
|
691
|
+
const parsed = JSON.parse(block.text.trim());
|
|
692
|
+
if (JSON.stringify(parsed) === canonical)
|
|
693
|
+
dupes.add(i);
|
|
694
|
+
}
|
|
695
|
+
catch {
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
return dupes;
|
|
699
|
+
}
|
|
700
|
+
export function formatCallToolResultHuman(result) {
|
|
701
|
+
const lines = [];
|
|
702
|
+
const sc = result.structuredContent;
|
|
703
|
+
const hasStructuredContent = !!sc && Object.keys(sc).length > 0;
|
|
704
|
+
const content = result.content;
|
|
705
|
+
let skipIndices = new Set();
|
|
706
|
+
if (hasStructuredContent && content && sc) {
|
|
707
|
+
skipIndices = findDuplicateTextBlocks(content, sc);
|
|
708
|
+
}
|
|
709
|
+
if (content && content.length > 0) {
|
|
710
|
+
const visible = content.filter((_, i) => !skipIndices.has(i));
|
|
711
|
+
if (visible.length > 0) {
|
|
712
|
+
lines.push(chalk.bold('Content:'));
|
|
713
|
+
for (let i = 0; i < visible.length; i++) {
|
|
714
|
+
if (i > 0)
|
|
715
|
+
lines.push('');
|
|
716
|
+
formatContentBlock(visible[i], lines);
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
if (hasStructuredContent) {
|
|
721
|
+
if (lines.length > 0)
|
|
722
|
+
lines.push('');
|
|
723
|
+
lines.push(chalk.bold('Structured content:'));
|
|
724
|
+
const scJson = JSON.stringify(sc, null, 2);
|
|
725
|
+
lines.push(process.stdout.isTTY ? highlightJson(scJson) : scJson);
|
|
726
|
+
}
|
|
727
|
+
const meta = result._meta;
|
|
728
|
+
if (meta && typeof meta === 'object' && Object.keys(meta).length > 0) {
|
|
729
|
+
if (lines.length > 0)
|
|
730
|
+
lines.push('');
|
|
731
|
+
lines.push(chalk.bold('Metadata:'));
|
|
732
|
+
const metaJson = JSON.stringify(meta, null, 2);
|
|
733
|
+
lines.push(process.stdout.isTTY ? highlightJson(metaJson) : metaJson);
|
|
734
|
+
}
|
|
735
|
+
if (lines.length === 0) {
|
|
736
|
+
return chalk.gray('(no content)');
|
|
737
|
+
}
|
|
738
|
+
return lines.join('\n');
|
|
739
|
+
}
|
|
554
740
|
export function formatObject(obj) {
|
|
555
741
|
const lines = [];
|
|
556
742
|
for (const [key, value] of Object.entries(obj)) {
|
|
557
|
-
const formattedKey =
|
|
743
|
+
const formattedKey = theme.cyan(`${key}:`);
|
|
558
744
|
let formattedValue;
|
|
559
745
|
if (value === null || value === undefined) {
|
|
560
746
|
formattedValue = chalk.gray(String(value));
|
|
@@ -575,16 +761,35 @@ export function formatObject(obj) {
|
|
|
575
761
|
return lines.join('\n');
|
|
576
762
|
}
|
|
577
763
|
export function formatSuccess(message) {
|
|
578
|
-
return
|
|
764
|
+
return theme.green(`✓ ${message}`);
|
|
579
765
|
}
|
|
580
766
|
export function formatError(message) {
|
|
581
|
-
return
|
|
767
|
+
return theme.red(`✗ ${message}`);
|
|
582
768
|
}
|
|
583
769
|
export function formatWarning(message) {
|
|
584
|
-
return
|
|
770
|
+
return theme.yellow(`⚠ ${message}`);
|
|
585
771
|
}
|
|
586
772
|
export function formatInfo(message) {
|
|
587
|
-
return
|
|
773
|
+
return theme.cyan(`ℹ ${message}`);
|
|
774
|
+
}
|
|
775
|
+
export function formatTaskCommandsHint(target, taskId, status) {
|
|
776
|
+
const id = taskId ?? '<taskId>';
|
|
777
|
+
const lines = [
|
|
778
|
+
'\nAvailable commands:',
|
|
779
|
+
` mcpc ${target} tasks-get ${id}`,
|
|
780
|
+
` mcpc ${target} tasks-result ${id}`,
|
|
781
|
+
];
|
|
782
|
+
if (status === undefined || status === 'working' || status === 'input_required') {
|
|
783
|
+
lines.push(` mcpc ${target} tasks-cancel ${id}`);
|
|
784
|
+
}
|
|
785
|
+
return lines.join('\n');
|
|
786
|
+
}
|
|
787
|
+
export function truncateOutput(output, maxChars) {
|
|
788
|
+
if (output.length <= maxChars)
|
|
789
|
+
return output;
|
|
790
|
+
const truncated = output.substring(0, maxChars);
|
|
791
|
+
const totalSize = output.length >= 1024 ? `${(output.length / 1024).toFixed(1)}KB` : `${output.length} chars`;
|
|
792
|
+
return `${truncated}\n\n... output truncated (${totalSize} total, showing first ${maxChars} chars). Use --max-chars to adjust.`;
|
|
588
793
|
}
|
|
589
794
|
function truncateWithEllipsis(str, maxLen) {
|
|
590
795
|
if (str.length <= maxLen + 3)
|
|
@@ -592,7 +797,7 @@ function truncateWithEllipsis(str, maxLen) {
|
|
|
592
797
|
return str.substring(0, maxLen - 1) + '…';
|
|
593
798
|
}
|
|
594
799
|
export function formatSessionLine(session) {
|
|
595
|
-
const nameStr =
|
|
800
|
+
const nameStr = theme.cyan(session.name);
|
|
596
801
|
let target;
|
|
597
802
|
if (session.server.url) {
|
|
598
803
|
target = session.server.url;
|
|
@@ -604,54 +809,29 @@ export function formatSessionLine(session) {
|
|
|
604
809
|
}
|
|
605
810
|
}
|
|
606
811
|
const targetStr = truncateWithEllipsis(target, 80);
|
|
607
|
-
|
|
608
|
-
if (session.server.command) {
|
|
609
|
-
|
|
812
|
+
let infoStr = '';
|
|
813
|
+
if (!session.server.command && session.profileName) {
|
|
814
|
+
infoStr = chalk.dim('(OAuth: ') + theme.magenta(session.profileName) + chalk.dim(')');
|
|
610
815
|
}
|
|
611
|
-
else {
|
|
612
|
-
parts.push('HTTP');
|
|
613
|
-
if (session.profileName) {
|
|
614
|
-
parts.push('OAuth: ' + chalk.magenta(session.profileName) + chalk.dim(''));
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
const infoStr = chalk.dim('(') + chalk.dim(parts.join(', ')) + chalk.dim(')');
|
|
618
816
|
let proxyStr = '';
|
|
619
817
|
if (session.proxy) {
|
|
620
818
|
proxyStr =
|
|
621
819
|
' ' +
|
|
622
|
-
|
|
820
|
+
theme.green('[proxy: ') +
|
|
623
821
|
chalk.greenBright(`${session.proxy.host}:${session.proxy.port}`) +
|
|
624
|
-
|
|
822
|
+
theme.green(']');
|
|
625
823
|
}
|
|
626
|
-
|
|
824
|
+
const suffix = [infoStr, proxyStr].filter(Boolean).join(' ');
|
|
825
|
+
return `${nameStr} → ${targetStr}${suffix ? ' ' + suffix : ''}`;
|
|
627
826
|
}
|
|
628
827
|
export async function logTarget(target, options) {
|
|
629
828
|
if (options.outputMode !== 'human' || options.hide) {
|
|
630
829
|
return;
|
|
631
830
|
}
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
console.log(`[${formatSessionLine(session)}]\n`);
|
|
636
|
-
}
|
|
637
|
-
return;
|
|
638
|
-
}
|
|
639
|
-
const tc = options.serverConfig;
|
|
640
|
-
if (tc?.command) {
|
|
641
|
-
let targetStr = tc.command;
|
|
642
|
-
if (tc.args && tc.args.length > 0) {
|
|
643
|
-
targetStr += ' ' + tc.args.join(' ');
|
|
644
|
-
}
|
|
645
|
-
targetStr = truncateWithEllipsis(targetStr, 80);
|
|
646
|
-
console.log(`[→ ${targetStr} ${chalk.dim('(stdio)')}]`);
|
|
647
|
-
return;
|
|
648
|
-
}
|
|
649
|
-
const serverStr = tc?.url || target;
|
|
650
|
-
const parts = ['HTTP'];
|
|
651
|
-
if (options.profileName) {
|
|
652
|
-
parts.push('OAuth: ' + chalk.magenta(options.profileName));
|
|
831
|
+
const session = await getSession(target);
|
|
832
|
+
if (session) {
|
|
833
|
+
console.log(`[${formatSessionLine(session)}]\n`);
|
|
653
834
|
}
|
|
654
|
-
console.log(`[→ ${serverStr} ${chalk.dim('(' + parts.join(', ') + ')')}]\n`);
|
|
655
835
|
}
|
|
656
836
|
export function formatJsonError(error, code) {
|
|
657
837
|
return formatJson({
|
|
@@ -736,6 +916,7 @@ export function formatServerDetails(details, target, tools) {
|
|
|
736
916
|
if (capabilities?.tasks) {
|
|
737
917
|
commands.push(`${bullet} ${bt}mcpc ${target} tasks-list${bt}`);
|
|
738
918
|
commands.push(`${bullet} ${bt}mcpc ${target} tasks-get <taskId>${bt}`);
|
|
919
|
+
commands.push(`${bullet} ${bt}mcpc ${target} tasks-result <taskId>${bt}`);
|
|
739
920
|
commands.push(`${bullet} ${bt}mcpc ${target} tasks-cancel <taskId>${bt}`);
|
|
740
921
|
}
|
|
741
922
|
if (capabilities?.logging) {
|
|
@@ -744,6 +925,11 @@ export function formatServerDetails(details, target, tools) {
|
|
|
744
925
|
commands.push(`${bullet} ${bt}mcpc ${target} shell${bt}`);
|
|
745
926
|
lines.push(commands.join('\n'));
|
|
746
927
|
lines.push('');
|
|
928
|
+
if (target.startsWith('@')) {
|
|
929
|
+
const logPath = join(getLogsDir(), `bridge-${target}.log`);
|
|
930
|
+
lines.push(chalk.dim(`Session log for debugging: ${logPath}`));
|
|
931
|
+
lines.push('');
|
|
932
|
+
}
|
|
747
933
|
return lines.join('\n');
|
|
748
934
|
}
|
|
749
935
|
//# sourceMappingURL=output.js.map
|