diff --git a/CHANGELOG.md b/CHANGELOG.md index b9f2d86..716bdda 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - `connect` command now auto-generates session name when `@session` is omitted (e.g., `mcpc connect mcp.apify.com` creates `@apify`). If a session for the same server already exists with matching auth settings, it is reused instead of creating a duplicate. -- `--max-chars ` global option to truncate large tool/prompt/resource output +- `--max-chars ` global option to truncate output to a given number of characters (ignored in `--json` mode) - `tools-call --help` shows tool parameter schema (shortcut for `tools-get`) - "Did you mean?" suggestions for unknown commands, including reversed names (e.g., `list-tools` → `tools-list`) - `--json` output documentation in `--help` for all commands, describing the MCP object shape returned diff --git a/README.md b/README.md index 500a70a..a9edf2f 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,7 @@ Options: --schema Validate tool/prompt schema against expected schema --schema-mode Schema validation mode: strict, compatible (default), ignore --timeout Request timeout in seconds (default: 300) - --max-chars Truncate tool/prompt output to this many characters + --max-chars Truncate output to n characters (ignored in --json mode) --insecure Skip TLS certificate verification (for self-signed certs) -v, --version Output the version number -h, --help Display help diff --git a/src/cli/commands/prompts.ts b/src/cli/commands/prompts.ts index 1e76aa7..33fc59d 100644 --- a/src/cli/commands/prompts.ts +++ b/src/cli/commands/prompts.ts @@ -3,7 +3,7 @@ */ import type { CommandOptions } from '../../lib/types.js'; -import { formatOutput, formatWarning, truncateOutput } from '../output.js'; +import { formatOutput, formatWarning } from '../output.js'; import { withMcpClient } from '../helpers.js'; import { parseCommandArgs, hasStdinData, readStdinArgs } from '../parser.js'; import { ClientError } from '../../lib/errors.js'; @@ -31,7 +31,11 @@ export async function listPrompts(target: string, options: CommandOptions): Prom cursor = result.nextCursor; } while (cursor); - console.log(formatOutput(allPrompts, options.outputMode)); + console.log( + formatOutput(allPrompts, options.outputMode, { + ...(options.maxChars && { maxChars: options.maxChars }), + }) + ); }); } @@ -107,10 +111,10 @@ export async function getPrompt( const result = await client.getPrompt(name, promptArgs); - let output = formatOutput(result, options.outputMode); - if (options.maxChars) { - output = truncateOutput(output, options.maxChars); - } - console.log(output); + console.log( + formatOutput(result, options.outputMode, { + ...(options.maxChars && { maxChars: options.maxChars }), + }) + ); }); } diff --git a/src/cli/commands/resources.ts b/src/cli/commands/resources.ts index 02d41f5..3810cc6 100644 --- a/src/cli/commands/resources.ts +++ b/src/cli/commands/resources.ts @@ -2,7 +2,7 @@ * Resources command handlers */ -import { formatOutput, formatSuccess, truncateOutput } from '../output.js'; +import { formatOutput, formatSuccess } from '../output.js'; import { withMcpClient } from '../helpers.js'; import type { CommandOptions } from '../../lib/types.js'; @@ -22,7 +22,11 @@ export async function listResources(target: string, options: CommandOptions): Pr cursor = result.nextCursor; } while (cursor); - console.log(formatOutput(allResources, options.outputMode)); + console.log( + formatOutput(allResources, options.outputMode, { + ...(options.maxChars && { maxChars: options.maxChars }), + }) + ); }); } @@ -45,7 +49,11 @@ export async function listResourceTemplates( cursor = result.nextCursor; } while (cursor); - console.log(formatOutput(allTemplates, options.outputMode)); + console.log( + formatOutput(allTemplates, options.outputMode, { + ...(options.maxChars && { maxChars: options.maxChars }), + }) + ); }); } @@ -83,11 +91,11 @@ export async function getResource( return; } - let output = formatOutput(result, options.outputMode); - if (options.maxChars) { - output = truncateOutput(output, options.maxChars); - } - console.log(output); + console.log( + formatOutput(result, options.outputMode, { + ...(options.maxChars && { maxChars: options.maxChars }), + }) + ); }); } diff --git a/src/cli/commands/tools.ts b/src/cli/commands/tools.ts index 850e6c0..ad514b8 100644 --- a/src/cli/commands/tools.ts +++ b/src/cli/commands/tools.ts @@ -12,7 +12,6 @@ import { formatError, formatWarning, formatInfo, - truncateOutput, } from '../output.js'; import { ClientError } from '../../lib/errors.js'; import type { CommandOptions, TaskUpdate } from '../../lib/types.js'; @@ -40,6 +39,7 @@ export async function listTools( console.log( formatOutput(result.tools, options.outputMode, { ...(options.full && { full: true }), + ...(options.maxChars && { maxChars: options.maxChars }), sessionName: target, }) ); @@ -370,11 +370,11 @@ export async function callTool( } } - let output = formatOutput(result, options.outputMode); - if (options.maxChars) { - output = truncateOutput(output, options.maxChars); - } - console.log(output); + console.log( + formatOutput(result, options.outputMode, { + ...(options.maxChars && { maxChars: options.maxChars }), + }) + ); // Show hint for getting tool schema when the tool returned an error if (result.isError && options.outputMode === 'human') { diff --git a/src/cli/index.ts b/src/cli/index.ts index d49fe80..1b0aa5e 100644 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -400,7 +400,7 @@ function createTopLevelProgram(): Command { .option('--schema ', 'Validate tool/prompt schema against expected schema') .option('--schema-mode ', 'Schema validation mode: strict, compatible (default), ignore') .option('--timeout ', 'Request timeout in seconds (default: 300)') - .option('--max-chars ', 'Truncate tool/prompt output to this many characters') + .option('--max-chars ', 'Truncate output to n characters (ignored in --json mode)') .option('--insecure', 'Skip TLS certificate verification (for self-signed certs)') .version(mcpcVersion, '-v, --version', 'Output the version number') .helpOption('-h, --help', 'Display help'); @@ -1176,7 +1176,7 @@ function createSessionProgram(): Command { .option('--schema ', 'Validate tool/prompt schema against expected schema') .option('--schema-mode ', 'Schema validation mode: strict, compatible (default), ignore') .option('--timeout ', 'Request timeout in seconds (default: 300)') - .option('--max-chars ', 'Truncate tool/prompt output to this many characters') + .option('--max-chars ', 'Truncate output to n characters (ignored in --json mode)') .option('--insecure', 'Skip TLS certificate verification (for self-signed certs)') .addHelpText( 'after', diff --git a/src/cli/output.ts b/src/cli/output.ts index daf4c0a..b6482c9 100644 --- a/src/cli/output.ts +++ b/src/cli/output.ts @@ -77,6 +77,8 @@ export interface FormatOptions { full?: boolean; /** Session name for contextual hints (e.g. @apify) */ sessionName?: string; + /** Truncate human-mode output to this many characters */ + maxChars?: number; } /** @@ -91,10 +93,13 @@ export function formatOutput( if (mode === 'json') { return formatJson(data); } - const output = formatHuman(data, options); + let output = formatHuman(data, options); // Ensure trailing newline for visual separation in shell (unless ends with code block) if (!output.endsWith('````') && !output.endsWith('\n')) { - return output + '\n'; + output += '\n'; + } + if (options?.maxChars) { + output = truncateOutput(output, options.maxChars); } return output; }