diff --git a/apps/pdfcraft-cli/src/main.rs b/apps/pdfcraft-cli/src/main.rs index e3f1c7a3..1940d63e 100644 --- a/apps/pdfcraft-cli/src/main.rs +++ b/apps/pdfcraft-cli/src/main.rs @@ -26,8 +26,26 @@ use std::time::{Duration, Instant}; use pdfcraft_engine::export::ImageFormat; use pdfcraft_render::{PageRenderer, RenderConfig, RenderRequest, RequestKind, inspect}; +/// The `mcp` lines of [`USAGE`]: only a build with the `mcp` feature has the command. +#[cfg(feature = "mcp")] +macro_rules! mcp_usage { + () => { + "\ +pdfcraft-cli mcp [--root DIR] [--compact] MCP server on stdin/stdout (opt-in) + --compact lists a core set of tools plus tool_search and tool_call +" + }; +} +#[cfg(not(feature = "mcp"))] +macro_rules! mcp_usage { + () => { + "" + }; +} + /// The full usage, printed by `--help` (also after a command, e.g. `render --help`). -const USAGE: &str = "\ +const USAGE: &str = concat!( + "\ pdfcraft-cli info [--password PW] document summary as JSON pdfcraft-cli render --page N [--dpi 96] --out x.png (.png, .jpg, .tif or .pam) pdfcraft-cli text [--page N] extracted text (pages separated by form feeds) @@ -40,11 +58,13 @@ pdfcraft-cli check [--timeout 20] [--dpi 36] [--json out.jso pdfcraft-cli tools automation tools and their JSON Schemas pdfcraft-cli run [key=value …] [--root DIR] [--out image.png] pdfcraft-cli run --script steps.json [--root DIR] [{\"tool\": \"doc_open\", \"args\": {…}}, …] -pdfcraft-cli mcp [--root DIR] [--compact] MCP server on stdin/stdout (opt-in) - --compact lists a core set of tools plus tool_search and tool_call +", + mcp_usage!(), + "\ pdfcraft-cli ui --control FILE [key=value …] [--out shot.png] drive a running app started with --control FILE -help and feedback: https://discord.gg/artcraft"; +help and feedback: https://discord.gg/artcraft" +); fn main() -> ExitCode { let args: Vec = std::env::args().skip(1).collect(); @@ -70,6 +90,8 @@ fn main() -> ExitCode { Some("ui") => ui(&args[1..]), #[cfg(feature = "mcp")] Some("mcp") => mcp(&args[1..]), + #[cfg(not(feature = "mcp"))] + Some("mcp") => Err("mcp: this build leaves out the MCP server (built without the `mcp` feature)".into()), Some("--version") => version(), Some(other) => Err(format!("unknown command '{other}'; see pdfcraft-cli --help").into()), }; diff --git a/apps/pdfcraft-cli/tests/help.rs b/apps/pdfcraft-cli/tests/help.rs index 3a124322..9a86150f 100644 --- a/apps/pdfcraft-cli/tests/help.rs +++ b/apps/pdfcraft-cli/tests/help.rs @@ -34,6 +34,27 @@ fn no_command_fails_with_usage_on_stderr() { assert!(text(&out.stderr).contains("pdfcraft-cli render --page N")); } +/// `mcp` is listed only when the build has it (`--no-default-features` leaves it out). +#[test] +fn usage_lists_mcp_only_when_built_with_it() { + let out = run(&["--help"]); + let stdout = text(&out.stdout); + assert_eq!(stdout.contains("pdfcraft-cli mcp"), cfg!(feature = "mcp"), "{stdout}"); + assert_eq!(stdout.contains("--compact"), cfg!(feature = "mcp"), "{stdout}"); + // The lines around it are still there. + assert!(stdout.contains("pdfcraft-cli run --script steps.json"), "{stdout}"); + assert!(stdout.contains("pdfcraft-cli ui --control FILE"), "{stdout}"); +} + +#[cfg(not(feature = "mcp"))] +#[test] +fn mcp_without_the_feature_says_it_was_left_out() { + let out = run(&["mcp"]); + assert!(!out.status.success()); + let stderr = text(&out.stderr); + assert!(stderr.contains("without the `mcp` feature"), "{stderr}"); +} + #[test] fn unknown_command_names_it_and_points_to_help() { let out = run(&["frobnicate"]);