Wrap any CLI as a Model Context Protocol (MCP) server for Claude, ChatGPT, Cursor, Gemini and any MCP-compatible client — schema auto-inferred from --help.
cli2mcp exposes a single dynamically-generated tool (dynamic_cli_tool) that wraps arbitrary CLI commands. While the concept is innovative, the tool suffers from critical definition quality gaps: the tool name is generic and non-actionable (does not start with a clear verb reflecting the actual CLI command being wrapped), the input schema is dynamically inferred from help text rather than explicitly defined in code, parameter descriptions are placeholders without concrete examples or constraints, and there is no documented output schema. The server is STDIO-only, which further limits its production readiness. The tool's description, while lengthy, does not meet LLM-optimization guidelines (50 - 200 chars) and reads more like developer documentation than agent guidance.
Execute any CLI command wrapped by cli2mcp. The tool name, description, input schema, and flags are dynamically generated from the target CLI's --help output. The server exposes a single tool per instance, configured via command-line options (--name, --description). Input schema properties map directly to CLI flags and positional arguments.
Tool name 'dynamic_cli_tool' is non-actionable and does not reflect the wrapped CLI command. Naming should follow verb_noun convention (e.g., 'search_ripgrep', 'transform_jq') and clearly convey intent to the LLM. The current name forces the LLM to read the description to understand what the tool actually does, violating the principle that tool names alone should convey action.
Input schema is dynamically constructed from CLI help text (src/parser/shape.ts and src/schema.ts) rather than statically defined. While visible in the description as a template (with [flag_long] placeholders), the actual schema for each instantiation is generated at runtime and not inspectable in the source code. This violates the principle that tool schemas must be explicit and verifiable. Parameter types are inferred ('string|number|boolean|array') without strong guarantees.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | F | 33 | 2026-07-28+ | v2 |
Parameter descriptions are template placeholders: '[flag_long]', 'Dynamic flag parsed from CLI --help; property name matches long flag name (e.g., 'output', 'verbose', 'pattern'). Type and description inferred from help text.' This is not actionable for an LLM. Descriptions must explain what each parameter does, what values are valid, what happens on edge cases, and when to use it. Template text with 'e.g.' examples is insufficient.
Output schema is undocumented. The tool returns plain-text output from the CLI (src/server.ts, line ~75: 'return { content: [{ type: "text", text }] }'). There is no schema describing what the text contains, how it is structured, what fields an agent should expect, or how to parse the output for downstream operations. This prevents agents from composing this tool with others.
No input validation or error guidance. When a CLI fails (exitCode !== 0), the server returns 'Command failed (exit N): [stderr/stdout]' (src/server.ts, errorText function). This is a raw error message that does not guide the LLM on recovery. There is no classification of errors (retryable vs. user-fixable vs. fatal), no suggestion of alternative tools or parameters, and no actionable remediation path.
Tool description (198 chars) is borderline for LLM optimization. While within the 10 - 1024 range, it reads as developer documentation ('The tool name, description, input schema, and flags are dynamically generated from the target CLI's --help output...') rather than agent guidance ('Use this tool to execute [CLI name] commands. Provide flags and arguments as parameters. See the parameter descriptions for valid options.'). Additionally, the description uses example placeholder text ([flag_long], e.g., 'output', 'verbose'), which LLMs tend to reuse literally in real calls.
No pagination or result limits documented. Although cli2mcp wraps read-only CLIs like ripgrep and jq, there is no guidance on handling large outputs (thousands of lines). The tool description should state 'Results may be large; consider using pagination flags (e.g., --max-count for ripgrep) to limit output and avoid context window exhaustion.'