@alcyone-labs/arg-parser 1.1.0 → 2.0.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/README.md +460 -1179
- package/dist/assets/.dxtignore.template +38 -0
- package/dist/assets/logo_1_small.jpg +0 -0
- package/dist/assets/tsdown.dxt.config.ts +37 -0
- package/dist/index.cjs +23702 -2315
- package/dist/index.cjs.map +1 -1
- package/dist/index.min.mjs +16360 -1725
- package/dist/index.min.mjs.map +1 -1
- package/dist/index.mjs +23694 -2315
- package/dist/index.mjs.map +1 -1
- package/dist/src/config/ConfigurationManager.d.ts +74 -0
- package/dist/src/config/ConfigurationManager.d.ts.map +1 -0
- package/dist/src/config/plugins/ConfigPlugin.d.ts +60 -0
- package/dist/src/config/plugins/ConfigPlugin.d.ts.map +1 -0
- package/dist/src/config/plugins/ConfigPluginRegistry.d.ts +72 -0
- package/dist/src/config/plugins/ConfigPluginRegistry.d.ts.map +1 -0
- package/dist/src/config/plugins/TomlConfigPlugin.d.ts +30 -0
- package/dist/src/config/plugins/TomlConfigPlugin.d.ts.map +1 -0
- package/dist/src/config/plugins/YamlConfigPlugin.d.ts +29 -0
- package/dist/src/config/plugins/YamlConfigPlugin.d.ts.map +1 -0
- package/dist/src/config/plugins/index.d.ts +5 -0
- package/dist/src/config/plugins/index.d.ts.map +1 -0
- package/dist/src/core/ArgParser.d.ts +332 -0
- package/dist/src/core/ArgParser.d.ts.map +1 -0
- package/dist/src/{ArgParserBase.d.ts → core/ArgParserBase.d.ts} +84 -3
- package/dist/src/core/ArgParserBase.d.ts.map +1 -0
- package/dist/src/core/FlagManager.d.ts.map +1 -0
- package/dist/src/{types.d.ts → core/types.d.ts} +40 -0
- package/dist/src/core/types.d.ts.map +1 -0
- package/dist/src/dxt/DxtGenerator.d.ts +115 -0
- package/dist/src/dxt/DxtGenerator.d.ts.map +1 -0
- package/dist/src/index.d.ts +10 -6
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/mcp/ArgParserMcp.d.ts +21 -0
- package/dist/src/mcp/ArgParserMcp.d.ts.map +1 -0
- package/dist/src/mcp/mcp-integration.d.ts +83 -0
- package/dist/src/mcp/mcp-integration.d.ts.map +1 -0
- package/dist/src/mcp/mcp-notifications.d.ts +138 -0
- package/dist/src/mcp/mcp-notifications.d.ts.map +1 -0
- package/dist/src/mcp/mcp-prompts.d.ts +132 -0
- package/dist/src/mcp/mcp-prompts.d.ts.map +1 -0
- package/dist/src/mcp/mcp-resources.d.ts +133 -0
- package/dist/src/mcp/mcp-resources.d.ts.map +1 -0
- package/dist/src/testing/fuzzy-test-cli.d.ts +5 -0
- package/dist/src/testing/fuzzy-test-cli.d.ts.map +1 -0
- package/dist/src/{fuzzy-tester.d.ts → testing/fuzzy-tester.d.ts} +1 -1
- package/dist/src/testing/fuzzy-tester.d.ts.map +1 -0
- package/package.json +51 -17
- package/dist/examples/fuzzy-demo.d.ts +0 -8
- package/dist/examples/fuzzy-demo.d.ts.map +0 -1
- package/dist/examples/fuzzy-test-example.d.ts +0 -8
- package/dist/examples/fuzzy-test-example.d.ts.map +0 -1
- package/dist/examples/fzf-search-cli.d.ts +0 -8
- package/dist/examples/fzf-search-cli.d.ts.map +0 -1
- package/dist/examples/getting-started.d.ts +0 -27
- package/dist/examples/getting-started.d.ts.map +0 -1
- package/dist/examples/mcp-preset-transports.d.ts +0 -19
- package/dist/examples/mcp-preset-transports.d.ts.map +0 -1
- package/dist/examples/simple-cli.d.ts +0 -26
- package/dist/examples/simple-cli.d.ts.map +0 -1
- package/dist/examples/v1.1.0-showcase.d.ts +0 -16
- package/dist/examples/v1.1.0-showcase.d.ts.map +0 -1
- package/dist/examples/with-env-example.d.ts +0 -3
- package/dist/examples/with-env-example.d.ts.map +0 -1
- package/dist/index-6G9StDO_.js +0 -6445
- package/dist/index-6G9StDO_.js.map +0 -1
- package/dist/index-CqU7Fj3C.cjs +0 -6444
- package/dist/index-CqU7Fj3C.cjs.map +0 -1
- package/dist/index-Dx_q1msW.js +0 -4682
- package/dist/index-Dx_q1msW.js.map +0 -1
- package/dist/src/ArgParser.d.ts +0 -156
- package/dist/src/ArgParser.d.ts.map +0 -1
- package/dist/src/ArgParserBase.d.ts.map +0 -1
- package/dist/src/FlagManager.d.ts.map +0 -1
- package/dist/src/fuzzy-test-cli.d.ts +0 -5
- package/dist/src/fuzzy-test-cli.d.ts.map +0 -1
- package/dist/src/fuzzy-tester.d.ts.map +0 -1
- package/dist/src/mcp-integration.d.ts +0 -31
- package/dist/src/mcp-integration.d.ts.map +0 -1
- package/dist/src/types.d.ts.map +0 -1
- package/dist/sse-B5Jf_YpG.cjs +0 -121
- package/dist/sse-B5Jf_YpG.cjs.map +0 -1
- package/dist/sse-BDL3h2Ll.js +0 -121
- package/dist/sse-BDL3h2Ll.js.map +0 -1
- package/dist/sse-DSjLfGFo.js +0 -107
- package/dist/sse-DSjLfGFo.js.map +0 -1
- package/dist/stdio-Cf19UQO7.js +0 -70
- package/dist/stdio-Cf19UQO7.js.map +0 -1
- package/dist/stdio-DESvSONI.cjs +0 -94
- package/dist/stdio-DESvSONI.cjs.map +0 -1
- package/dist/stdio-DLOResWr.js +0 -94
- package/dist/stdio-DLOResWr.js.map +0 -1
- package/dist/streamableHttp-DXIdDSbF.js +0 -342
- package/dist/streamableHttp-DXIdDSbF.js.map +0 -1
- package/dist/streamableHttp-DsXlAnqJ.cjs +0 -456
- package/dist/streamableHttp-DsXlAnqJ.cjs.map +0 -1
- package/dist/streamableHttp-Vd4Qsgko.js +0 -456
- package/dist/streamableHttp-Vd4Qsgko.js.map +0 -1
- package/dist/types-DSxPEImy.cjs +0 -943
- package/dist/types-DSxPEImy.cjs.map +0 -1
- package/dist/types-DdsPVLQ5.js +0 -846
- package/dist/types-DdsPVLQ5.js.map +0 -1
- package/dist/types-DpK81FWv.js +0 -944
- package/dist/types-DpK81FWv.js.map +0 -1
- /package/dist/src/{FlagManager.d.ts → core/FlagManager.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,1373 +1,655 @@
|
|
|
1
1
|
# ArgParser - Type-Safe Command Line Argument Parser
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A modern, type-safe command line argument parser with built-in MCP (Model Context Protocol) integration and automatic Claude Desktop Extension (DXT) generation.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Features Overview](#features-overview)
|
|
8
|
+
- [Installation](#installation)
|
|
9
|
+
- [Quick Start: The Unified `addTool` API](#quick-start-the-unified-addtool-api)
|
|
10
|
+
- [How to Run It](#how-to-run-it)
|
|
11
|
+
- [Setting Up System-Wide CLI Access](#setting-up-system-wide-cli-access)
|
|
12
|
+
- [Parsing Command-Line Arguments](#parsing-command-line-arguments)
|
|
13
|
+
- [Cannonical Usage Pattern](#cannonical-usage-pattern)
|
|
14
|
+
- [Top-level await](#top-level-await)
|
|
15
|
+
- [Promise-based parsing](#promise-based-parsing)
|
|
16
|
+
- [Migrating from v1.x to the v2.0 `addTool` API](#migrating-from-v1x-to-the-v20-addtool-api)
|
|
17
|
+
- [Before v2.0: Separate Definitions](#before-v20-separate-definitions)
|
|
18
|
+
- [After v2.0: The Unified `addTool()` Method](#after-v20-the-unified-addtool-method)
|
|
19
|
+
- [Core Concepts](#core-concepts)
|
|
20
|
+
- [Defining Flags](#defining-flags)
|
|
21
|
+
- [Type Handling and Validation](#type-handling-and-validation)
|
|
22
|
+
- [Hierarchical CLIs (Sub-Commands)](#hierarchical-clis-sub-commands)
|
|
23
|
+
- [MCP Exposure Control](#mcp-exposure-control)
|
|
24
|
+
- [Flag Inheritance (`inheritParentFlags`)](#flag-inheritance-inheritparentflags)
|
|
25
|
+
- [MCP & Claude Desktop Integration](#mcp--claude-desktop-integration)
|
|
26
|
+
- [Automatic MCP Server Mode (`--s-mcp-serve`)](#automatic-mcp-server-mode---s-mcp-serve)
|
|
27
|
+
- [MCP Transports](#mcp-transports)
|
|
28
|
+
- [Automatic Console Safety](#automatic-console-safety)
|
|
29
|
+
- [Generating DXT Packages (`--s-build-dxt`)](#generating-dxt-packages---s-build-dxt)
|
|
30
|
+
- [Logo Configuration](#logo-configuration)
|
|
31
|
+
- [How DXT Generation Works](#how-dxt-generation-works)
|
|
32
|
+
- [System Flags & Configuration](#system-flags--configuration)
|
|
33
|
+
- [Changelog](#changelog)
|
|
34
|
+
- [Backlog](#backlog)
|
|
35
|
+
|
|
36
|
+
## Features Overview
|
|
37
|
+
|
|
38
|
+
- **Unified Tool Architecture**: Define tools once with `addTool()` and they automatically function as both CLI subcommands and MCP tools.
|
|
39
|
+
- **Type-safe flag definitions** with full TypeScript support and autocompletion.
|
|
40
|
+
- **Automatic MCP Integration**: Transform any CLI into a compliant MCP server with a single command (`--s-mcp-serve`).
|
|
41
|
+
- **Console Safe**: `console.log` and other methods
|
|
42
|
+
are automatically handled in MCP mode to prevent protocol contamination, requiring no changes to your code.
|
|
43
|
+
- **DXT Package Generation**: Generate complete, ready-to-install Claude Desktop Extension (`.dxt`) packages with the `--s-build-dxt` command.
|
|
44
|
+
- **Hierarchical Sub-commands**: Create complex, nested sub-command structures (e.g., `git commit`, `docker container ls`) with flag inheritance.
|
|
45
|
+
- **Configuration Management**: Easily load (`--s-with-env`) and save (`--s-save-to-env`) configurations from/to `.env`, `.json`, `.yaml`, and `.toml` files.
|
|
46
|
+
- **Automatic Help & Error Handling**: Context-aware help text and user-friendly error messages are generated automatically.
|
|
47
|
+
- **Debugging Tools**: Built-in system flags like `--s-debug` and `--s-debug-print` for easy troubleshooting.
|
|
4
48
|
|
|
5
|
-
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Installation
|
|
6
52
|
|
|
7
|
-
|
|
53
|
+
```bash
|
|
54
|
+
# Using PNPM (recommended)
|
|
55
|
+
pnpm add @alcyone-labs/arg-parser
|
|
56
|
+
```
|
|
8
57
|
|
|
9
|
-
|
|
58
|
+
---
|
|
10
59
|
|
|
11
|
-
|
|
12
|
-
- **System Flags**: Built-in `--s-debug-print`, `--s-with-env`, `--s-save-to-env`, and `--s-enable-fuzzy` for enhanced debugging, configuration, and testing
|
|
13
|
-
- **Environment Loading**: Load configuration from `.env`, `.yaml`, `.json`, and `.toml` files
|
|
14
|
-
- **Enhanced Debugging**: Comprehensive runtime debugging and configuration export tools
|
|
60
|
+
## Quick Start: The Unified `addTool` API
|
|
15
61
|
|
|
16
|
-
|
|
62
|
+
The modern way to build with ArgParser is using the `.addTool()` method. It creates a single, self-contained unit that works as both a CLI subcommand and an MCP tool.
|
|
17
63
|
|
|
18
64
|
```typescript
|
|
19
65
|
import { ArgParser } from "@alcyone-labs/arg-parser";
|
|
20
66
|
|
|
67
|
+
// Use ArgParser.withMcp to enable MCP and DXT features
|
|
21
68
|
const cli = ArgParser.withMcp({
|
|
22
|
-
appName: "My CLI
|
|
23
|
-
appCommandName: "
|
|
24
|
-
description: "A
|
|
25
|
-
|
|
69
|
+
appName: "My Awesome CLI",
|
|
70
|
+
appCommandName: "mycli",
|
|
71
|
+
description: "A tool that works in both CLI and MCP mode",
|
|
72
|
+
mcp: {
|
|
73
|
+
serverInfo: { name: "my-awesome-mcp-server", version: "1.0.0" },
|
|
74
|
+
},
|
|
26
75
|
})
|
|
27
|
-
|
|
28
|
-
{
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
- **Flag Inheritance:** Share common flags between parent and child commands with an intuitive inheritance mechanism
|
|
61
|
-
- **Error Handling:** Built-in, user-friendly error reporting for common parsing issues, with an option to handle errors manually
|
|
62
|
-
|
|
63
|
-
### **MCP Integration (v1.1.0+)**
|
|
64
|
-
- **Automatic MCP Server Creation:** Transform any CLI into an MCP server with a single method call
|
|
65
|
-
- **Multiple Transport Support:** Run stdio, SSE, and HTTP transports simultaneously on different ports
|
|
66
|
-
- **Type-Safe Tool Generation:** Automatically generate MCP tools with Zod schema validation from CLI definitions
|
|
67
|
-
- **Flexible Configuration:** Support for single transport or complex multi-transport JSON configurations
|
|
68
|
-
|
|
69
|
-
### **System & Configuration Features (v1.1.0+)**
|
|
70
|
-
- **Environment Loading:** Load configuration from `.env`, `.yaml`, `.json`, and `.toml` files with `--s-with-env`
|
|
71
|
-
- **Configuration Export:** Save current configuration to various formats with `--s-save-to-env`
|
|
72
|
-
- **Advanced Debugging:** Runtime debugging with `--s-debug` and configuration inspection with `--s-debug-print`
|
|
73
|
-
- **CLI Precedence:** Command line arguments always override file configuration
|
|
76
|
+
// Define a tool that works everywhere
|
|
77
|
+
.addTool({
|
|
78
|
+
name: "greet",
|
|
79
|
+
description: "A tool to greet someone",
|
|
80
|
+
flags: [
|
|
81
|
+
{
|
|
82
|
+
name: "name",
|
|
83
|
+
type: "string",
|
|
84
|
+
mandatory: true,
|
|
85
|
+
options: ["--name"],
|
|
86
|
+
description: "Name to greet",
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: "style",
|
|
90
|
+
type: "string",
|
|
91
|
+
enum: ["formal", "casual"],
|
|
92
|
+
defaultValue: "casual",
|
|
93
|
+
description: "Greeting style",
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
handler: async (ctx) => {
|
|
97
|
+
// Use console.log freely - it's automatically safe in MCP mode!
|
|
98
|
+
console.log(`Greeting ${ctx.args.name} in a ${ctx.args.style} style...`);
|
|
99
|
+
|
|
100
|
+
const greeting =
|
|
101
|
+
ctx.args.style === "formal"
|
|
102
|
+
? `Good day, ${ctx.args.name}.`
|
|
103
|
+
: `Hey ${ctx.args.name}!`;
|
|
104
|
+
|
|
105
|
+
console.log(greeting);
|
|
106
|
+
return { success: true, greeting, name: ctx.args.name };
|
|
107
|
+
},
|
|
108
|
+
});
|
|
74
109
|
|
|
75
|
-
|
|
110
|
+
// parse() is async and works with both sync and async handlers
|
|
111
|
+
async function main() {
|
|
112
|
+
try {
|
|
113
|
+
await cli.parse(process.argv.slice(2));
|
|
114
|
+
} catch (error) {
|
|
115
|
+
console.error("Error:", error.message);
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
76
119
|
|
|
77
|
-
|
|
120
|
+
main();
|
|
78
121
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
npm install @alcyone-labs/arg-parser
|
|
83
|
-
# or
|
|
84
|
-
yarn add @alcyone-labs/arg-parser
|
|
85
|
-
# or
|
|
86
|
-
bun add @alcyone-labs/arg-parser
|
|
87
|
-
# or
|
|
88
|
-
deno install npm:@alcyone-labs/arg-parser
|
|
122
|
+
// Export if you want to test, use the CLI programmatically
|
|
123
|
+
// or use the --s-enable-fuzzing system flag to run fuzzy tests on your CLI
|
|
124
|
+
export default cli;
|
|
89
125
|
```
|
|
90
126
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
If you plan to use MCP server features, install the additional dependencies:
|
|
127
|
+
## How to Run It
|
|
94
128
|
|
|
95
129
|
```bash
|
|
96
|
-
|
|
97
|
-
# or
|
|
98
|
-
npm install @modelcontextprotocol/sdk express
|
|
99
|
-
```
|
|
130
|
+
# This assumes `mycli` is your CLI's entry point
|
|
100
131
|
|
|
101
|
-
|
|
132
|
+
# 1. As a standard CLI subcommand
|
|
133
|
+
mycli greet --name Jane --style formal
|
|
102
134
|
|
|
103
|
-
|
|
135
|
+
# 2. As an MCP server, exposing the 'greet' tool
|
|
136
|
+
mycli --s-mcp-serve
|
|
104
137
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
### **BunJS**
|
|
108
|
-
```bash
|
|
109
|
-
# Run TypeScript directly
|
|
110
|
-
bun your-cli.ts --flag value
|
|
111
|
-
|
|
112
|
-
# Or compile and run
|
|
113
|
-
bun build your-cli.ts --outdir ./dist
|
|
114
|
-
bun ./dist/your-cli.js --flag value
|
|
138
|
+
# 3. Generate a DXT package for Claude Desktop (2-steps)
|
|
139
|
+
mycli --s-build-dxt ./my-dxt-package
|
|
115
140
|
```
|
|
116
141
|
|
|
117
|
-
|
|
118
|
-
```bash
|
|
119
|
-
# Using tsx for TypeScript
|
|
120
|
-
npx tsx your-cli.ts --flag value
|
|
142
|
+
Read more on generating the DXT package here: [Generating DXT Packages](#generating-dxt-packages---s-build-dxt)
|
|
121
143
|
|
|
122
|
-
|
|
123
|
-
npx ts-node your-cli.ts --flag value
|
|
144
|
+
### Setting Up System-Wide CLI Access
|
|
124
145
|
|
|
125
|
-
|
|
126
|
-
npx tsc your-cli.ts
|
|
127
|
-
node your-cli.js --flag value
|
|
128
|
-
```
|
|
146
|
+
To make your CLI available system-wide as a binary command, you need to configure the `bin` field in your `package.json` and use package linking:
|
|
129
147
|
|
|
130
|
-
|
|
131
|
-
```bash
|
|
132
|
-
# Run with required permissions
|
|
133
|
-
deno run --unstable-sloppy-imports --allow-read --allow-write --allow-env your-cli.ts --flag value
|
|
148
|
+
**1. Configure your package.json:**
|
|
134
149
|
|
|
135
|
-
|
|
136
|
-
|
|
150
|
+
```json
|
|
151
|
+
{
|
|
152
|
+
"name": "my-cli-app",
|
|
153
|
+
"version": "1.0.0",
|
|
154
|
+
"type": "module",
|
|
155
|
+
"bin": {
|
|
156
|
+
"mycli": "./cli.js"
|
|
157
|
+
}
|
|
158
|
+
}
|
|
137
159
|
```
|
|
138
160
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
After building your project with `pnpm build` (or your preferred build tool), you can use the compiled JavaScript files directly:
|
|
161
|
+
**2. Make your CLI file executable:**
|
|
142
162
|
|
|
143
163
|
```bash
|
|
144
|
-
|
|
145
|
-
node dist/index.cjs
|
|
146
|
-
|
|
147
|
-
# ES Modules (Node.js with "type": "module" in package.json)
|
|
148
|
-
node dist/index.mjs
|
|
149
|
-
|
|
150
|
-
# Minified ES Modules (production)
|
|
151
|
-
node dist/index.min.mjs
|
|
152
|
-
|
|
153
|
-
# Import in your own projects
|
|
154
|
-
const { ArgParser } = require('./dist/index.cjs'); // CommonJS
|
|
155
|
-
import { ArgParser } from './dist/index.mjs'; // ES Modules
|
|
156
|
-
|
|
157
|
-
# Example: Using built artifacts in production
|
|
158
|
-
node -e "
|
|
159
|
-
const { ArgParser } = require('./dist/index.cjs');
|
|
160
|
-
const cli = new ArgParser({
|
|
161
|
-
appName: 'Production CLI',
|
|
162
|
-
handler: (ctx) => console.log('Production ready!', ctx.args)
|
|
163
|
-
}).addFlags([
|
|
164
|
-
{ name: 'env', options: ['--env'], type: 'string', mandatory: true, description: 'Environment' }
|
|
165
|
-
]);
|
|
166
|
-
cli.parse(['--env', 'production']);
|
|
167
|
-
"
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
All examples in this repository work seamlessly across all three runtimes, ensuring maximum compatibility for your CLI applications.
|
|
171
|
-
|
|
172
|
-
## Basic Usage
|
|
173
|
-
|
|
174
|
-
### **Standard CLI Usage**
|
|
175
|
-
|
|
176
|
-
Here's a simple example demonstrating how to define flags and parse arguments:
|
|
177
|
-
|
|
178
|
-
```typescript
|
|
179
|
-
import { ArgParser } from "@alcyone-labs/arg-parser";
|
|
180
|
-
|
|
181
|
-
const parser = new ArgParser({
|
|
182
|
-
appName: "Data Processor",
|
|
183
|
-
appCommandName: "data-proc", // Used in help text and error messages
|
|
184
|
-
description: "A tool for processing data phases",
|
|
185
|
-
handler: async (ctx) => {
|
|
186
|
-
console.log("Processing data with phase:", ctx.args.phase);
|
|
187
|
-
return { success: true, phase: ctx.args.phase };
|
|
188
|
-
},
|
|
189
|
-
}).addFlags([
|
|
190
|
-
{
|
|
191
|
-
name: "phase",
|
|
192
|
-
options: ["--phase"],
|
|
193
|
-
type: "string", // Use "string", "number", "boolean", or native types
|
|
194
|
-
mandatory: true,
|
|
195
|
-
enum: ["chunking", "pairing", "analysis"],
|
|
196
|
-
description: "Processing phase to execute",
|
|
197
|
-
},
|
|
198
|
-
{
|
|
199
|
-
name: "batch",
|
|
200
|
-
options: ["-b", "--batch-number"],
|
|
201
|
-
type: "number",
|
|
202
|
-
mandatory: (args) => args.phase !== "analysis", // Conditional requirement
|
|
203
|
-
defaultValue: 0,
|
|
204
|
-
description: "Batch number (required except for analysis phase)",
|
|
205
|
-
},
|
|
206
|
-
{
|
|
207
|
-
name: "verbose",
|
|
208
|
-
options: ["-v", "--verbose"],
|
|
209
|
-
flagOnly: true, // This flag does not expect a value
|
|
210
|
-
description: "Enable verbose logging",
|
|
211
|
-
},
|
|
212
|
-
]);
|
|
213
|
-
|
|
214
|
-
// Parse and execute
|
|
215
|
-
const result = parser.parse(process.argv.slice(2));
|
|
216
|
-
console.log("Result:", result);
|
|
164
|
+
chmod +x cli.js
|
|
217
165
|
```
|
|
218
166
|
|
|
219
|
-
|
|
167
|
+
**3. Add a shebang to your CLI file:**
|
|
220
168
|
|
|
221
|
-
|
|
169
|
+
```javascript
|
|
170
|
+
#!/usr/bin/env node
|
|
171
|
+
# or #!/usr/bin/env bun for native typescript runtime
|
|
222
172
|
|
|
223
|
-
|
|
224
|
-
import { ArgParser } from "@alcyone-labs/arg-parser";
|
|
173
|
+
import { ArgParser } from '@alcyone-labs/arg-parser';
|
|
225
174
|
|
|
226
175
|
const cli = ArgParser.withMcp({
|
|
227
|
-
appName: "
|
|
228
|
-
appCommandName: "
|
|
229
|
-
|
|
230
|
-
handler: async (ctx) => {
|
|
231
|
-
console.log("Processing data with phase:", ctx.args.phase);
|
|
232
|
-
return { success: true, phase: ctx.args.phase, batch: ctx.args.batch };
|
|
233
|
-
},
|
|
234
|
-
})
|
|
235
|
-
.addFlags([
|
|
236
|
-
{
|
|
237
|
-
name: "phase",
|
|
238
|
-
options: ["--phase"],
|
|
239
|
-
type: "string",
|
|
240
|
-
mandatory: true,
|
|
241
|
-
enum: ["chunking", "pairing", "analysis"],
|
|
242
|
-
description: "Processing phase to execute",
|
|
243
|
-
},
|
|
244
|
-
{
|
|
245
|
-
name: "batch",
|
|
246
|
-
options: ["-b", "--batch-number"],
|
|
247
|
-
type: "number",
|
|
248
|
-
defaultValue: 0,
|
|
249
|
-
description: "Batch number for processing",
|
|
250
|
-
},
|
|
251
|
-
])
|
|
252
|
-
.addMcpSubCommand("serve", {
|
|
253
|
-
name: "data-processor-mcp",
|
|
254
|
-
version: "1.1.0",
|
|
255
|
-
description: "Data Processor MCP Server",
|
|
176
|
+
appName: "My CLI",
|
|
177
|
+
appCommandName: "mycli",
|
|
178
|
+
// ... your configuration
|
|
256
179
|
});
|
|
257
180
|
|
|
258
|
-
//
|
|
259
|
-
|
|
260
|
-
// Use with custom transport: data-proc serve --transport sse --port 3001
|
|
181
|
+
// Parse command line arguments
|
|
182
|
+
await cli.parse(process.argv.slice(2));
|
|
261
183
|
```
|
|
262
184
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
ArgParser v1.1.0 introduces powerful Model Context Protocol (MCP) integration, allowing you to expose any CLI as an MCP server with minimal code changes.
|
|
266
|
-
|
|
267
|
-
### **Quick MCP Setup**
|
|
268
|
-
|
|
269
|
-
1. **Import the MCP-enabled class:**
|
|
270
|
-
```typescript
|
|
271
|
-
import { ArgParser } from "@alcyone-labs/arg-parser";
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
2. **Create your CLI with MCP support:**
|
|
275
|
-
```typescript
|
|
276
|
-
const cli = ArgParser.withMcp({
|
|
277
|
-
appName: "My Tool",
|
|
278
|
-
appCommandName: "my-tool",
|
|
279
|
-
handler: async (ctx) => ({ result: "success", args: ctx.args }),
|
|
280
|
-
})
|
|
281
|
-
.addFlags([/* your flags */])
|
|
282
|
-
.addMcpSubCommand("serve", {
|
|
283
|
-
name: "my-mcp-server",
|
|
284
|
-
version: "1.0.0",
|
|
285
|
-
});
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
3. **Use as CLI or MCP server:**
|
|
289
|
-
```bash
|
|
290
|
-
# CLI usage
|
|
291
|
-
my-tool --input data.txt --verbose
|
|
292
|
-
|
|
293
|
-
# MCP server (stdio)
|
|
294
|
-
my-tool serve
|
|
295
|
-
|
|
296
|
-
# MCP server (HTTP)
|
|
297
|
-
my-tool serve --transport sse --port 3001
|
|
298
|
-
|
|
299
|
-
# Multiple transports
|
|
300
|
-
my-tool serve --transports '[{"type":"stdio"},{"type":"sse","port":3001}]'
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
### **MCP Transport Options**
|
|
304
|
-
|
|
305
|
-
- **`stdio`** (default): Standard input/output for CLI tools
|
|
306
|
-
- **`sse`**: Server-Sent Events over HTTP for web applications
|
|
307
|
-
- **`streamable-http`**: HTTP with streaming support for advanced integrations
|
|
308
|
-
|
|
309
|
-
### **Multiple Transports Simultaneously**
|
|
310
|
-
|
|
311
|
-
Run multiple transport types at once for maximum flexibility:
|
|
185
|
+
**4. Link the package globally:**
|
|
312
186
|
|
|
313
187
|
```bash
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
{"type":"sse","port":3001,"path":"/sse"},
|
|
317
|
-
{"type":"streamable-http","port":3002,"path":"/mcp","host":"0.0.0.0"}
|
|
318
|
-
]'
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
### **Automatic Tool Generation**
|
|
322
|
-
|
|
323
|
-
Your CLI flags are automatically converted to MCP tools with:
|
|
324
|
-
- **Type-safe schemas** using Zod validation
|
|
325
|
-
- **Automatic documentation** from flag descriptions
|
|
326
|
-
- **Enum validation** for restricted values
|
|
327
|
-
- **Error handling** with detailed messages
|
|
328
|
-
|
|
329
|
-
## Core Concepts
|
|
188
|
+
# Using npm
|
|
189
|
+
npm link
|
|
330
190
|
|
|
331
|
-
|
|
191
|
+
# Using pnpm
|
|
192
|
+
pnpm link --global
|
|
332
193
|
|
|
333
|
-
|
|
194
|
+
# Using bun
|
|
195
|
+
bun link
|
|
334
196
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
name: string; // Internal name for accessing the value in parsed args
|
|
338
|
-
options: string[]; // Array of command-line options (e.g., ["-v", "--verbose"])
|
|
339
|
-
type:
|
|
340
|
-
| "string"
|
|
341
|
-
| "boolean"
|
|
342
|
-
| "number"
|
|
343
|
-
| "array"
|
|
344
|
-
| "object"
|
|
345
|
-
| ((value: string) => any)
|
|
346
|
-
| Constructor; // Expected type or a parsing function
|
|
347
|
-
description: string | string[]; // Text description for help output
|
|
348
|
-
mandatory?: boolean | ((args: TParsedArgs) => boolean); // Whether the flag is required, or a function that determines this
|
|
349
|
-
defaultValue?: any; // Default value if the flag is not provided
|
|
350
|
-
default?: any; // Alias for defaultValue
|
|
351
|
-
flagOnly?: boolean; // If true, the flag does not consume the next argument as its value (e.g., `--verbose`)
|
|
352
|
-
allowMultiple?: boolean; // If true, the flag can be provided multiple times (values are collected in an array)
|
|
353
|
-
enum?: any[]; // Array of allowed values. Parser validates input against this list.
|
|
354
|
-
validate?: (value: any) => boolean | string | void; // Custom validation function
|
|
355
|
-
required?: boolean | ((args: any) => boolean); // Alias for mandatory
|
|
356
|
-
}
|
|
197
|
+
# Using yarn
|
|
198
|
+
yarn link
|
|
357
199
|
```
|
|
358
200
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
ArgParser handles type conversion automatically based on the `type` property. You can use standard string types (`"string"`, `"number"`, `"boolean"`, `"array"`, `"object`), native constructors (`String`, `Number`, `Boolean`, `Array`, `Object`), or provide a custom function:
|
|
201
|
+
**5. Use your CLI from anywhere:**
|
|
362
202
|
|
|
363
|
-
```
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
type: Number, // Automatically converts value to a number
|
|
368
|
-
})
|
|
369
|
-
.addFlag({
|
|
370
|
-
name: "data",
|
|
371
|
-
options: ["--data"],
|
|
372
|
-
type: JSON.parse, // Use a function to parse complex types like JSON strings
|
|
373
|
-
description: "JSON data to process"
|
|
374
|
-
})
|
|
375
|
-
.addFlag({
|
|
376
|
-
name: "environment",
|
|
377
|
-
options: ["--env"],
|
|
378
|
-
type: "string",
|
|
379
|
-
enum: ["dev", "staging", "prod"], // Validate value against this list
|
|
380
|
-
description: "Deployment environment",
|
|
381
|
-
})
|
|
382
|
-
.addFlag({
|
|
383
|
-
name: "id",
|
|
384
|
-
options: ["--id"],
|
|
385
|
-
type: "string",
|
|
386
|
-
validate: (value) => /^[a-f0-9]+$/.test(value), // Custom validation function
|
|
387
|
-
description: "Hexadecimal ID",
|
|
388
|
-
})
|
|
389
|
-
.addFlag({
|
|
390
|
-
name: "config",
|
|
391
|
-
options: ["-c"],
|
|
392
|
-
allowMultiple: true,
|
|
393
|
-
type: path => require(path), // Load config from path (example)
|
|
394
|
-
description: "Load multiple configuration files"
|
|
395
|
-
})
|
|
396
|
-
```
|
|
397
|
-
|
|
398
|
-
### Mandatory Flags
|
|
399
|
-
|
|
400
|
-
Flags can be made mandatory using the `mandatory` property, or its alias "required". This can be a boolean or a function that receives the currently parsed arguments and returns a boolean.
|
|
203
|
+
```bash
|
|
204
|
+
# Now you can run your CLI from any directory
|
|
205
|
+
mycli --help
|
|
206
|
+
mycli greet --name "World"
|
|
401
207
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
options: ["--in"],
|
|
406
|
-
type: String,
|
|
407
|
-
mandatory: true, // Always mandatory
|
|
408
|
-
description: "Input file path",
|
|
409
|
-
})
|
|
410
|
-
.addFlag({
|
|
411
|
-
name: "output",
|
|
412
|
-
options: ["--out"],
|
|
413
|
-
type: String,
|
|
414
|
-
mandatory: (args) => args.format === "json", // Mandatory only if --format is "json"
|
|
415
|
-
description: "Output file path (required for JSON output)",
|
|
416
|
-
})
|
|
208
|
+
# Or use with npx/pnpx if you prefer
|
|
209
|
+
npx mycli --help
|
|
210
|
+
pnpx mycli greet --name "World"
|
|
417
211
|
```
|
|
418
212
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
### Default Values
|
|
213
|
+
**To unlink later:**
|
|
422
214
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
.addFlag({
|
|
427
|
-
name: "port",
|
|
428
|
-
options: ["-p", "--port"],
|
|
429
|
-
type: Number,
|
|
430
|
-
defaultValue: 3000, // Default port is 3000 if -p or --port is not used
|
|
431
|
-
description: "Server port",
|
|
432
|
-
})
|
|
433
|
-
```
|
|
215
|
+
```bash
|
|
216
|
+
# Using npm
|
|
217
|
+
npm unlink --global my-cli-app
|
|
434
218
|
|
|
435
|
-
|
|
219
|
+
# Using pnpm
|
|
220
|
+
pnpm unlink --global
|
|
436
221
|
|
|
437
|
-
|
|
222
|
+
# Using bun
|
|
223
|
+
bun unlink
|
|
438
224
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
name: "verbose",
|
|
442
|
-
options: ["-v"],
|
|
443
|
-
type: Boolean, // Typically boolean for flag-only flags
|
|
444
|
-
flagOnly: true,
|
|
445
|
-
description: "Enable verbose output",
|
|
446
|
-
})
|
|
225
|
+
# Using yarn
|
|
226
|
+
yarn unlink
|
|
447
227
|
```
|
|
448
228
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
For convenience, `ArgParser` supports aliases for some flag properties:
|
|
452
|
-
|
|
453
|
-
- `default` is an alias for `defaultValue`.
|
|
454
|
-
- `required` is an alias for `mandatory`.
|
|
455
|
-
If both the original property and its alias are provided, the original property (`defaultValue`, `mandatory`) takes precedence.
|
|
456
|
-
|
|
457
|
-
## Hierarchical CLIs (Sub-Commands)
|
|
458
|
-
|
|
459
|
-
ArgParser excels at building CLIs with nested commands, like `git clone` or `docker build`.
|
|
229
|
+
---
|
|
460
230
|
|
|
461
|
-
|
|
231
|
+
## Parsing Command-Line Arguments
|
|
462
232
|
|
|
463
|
-
|
|
233
|
+
ArgParser's `parse()` method is async and automatically handles both synchronous and asynchronous handlers:
|
|
464
234
|
|
|
465
|
-
|
|
235
|
+
### Cannonical Usage Pattern
|
|
466
236
|
|
|
467
237
|
```typescript
|
|
468
|
-
|
|
469
|
-
ArgParser,
|
|
470
|
-
HandlerContext,
|
|
471
|
-
ISubCommand,
|
|
472
|
-
} from "@alcyone-labs/arg-parser";
|
|
473
|
-
|
|
474
|
-
const deployParser = new ArgParser().addFlags([
|
|
475
|
-
{ name: "target", options: ["-t"], type: String, mandatory: true },
|
|
476
|
-
]);
|
|
477
|
-
|
|
478
|
-
const monitorLogsParser = new ArgParser().addFlags([
|
|
479
|
-
{ name: "follow", options: ["-f"], flagOnly: true, type: Boolean },
|
|
480
|
-
]);
|
|
481
|
-
|
|
482
|
-
const monitorParser = new ArgParser().addSubCommand({
|
|
483
|
-
name: "logs",
|
|
484
|
-
description: "Show logs",
|
|
485
|
-
parser: monitorLogsParser,
|
|
486
|
-
handler: ({ args }) => {
|
|
487
|
-
console.log(`Showing logs... Follow: ${args.follow}`);
|
|
488
|
-
},
|
|
489
|
-
});
|
|
490
|
-
|
|
491
|
-
const cli = new ArgParser({
|
|
238
|
+
const cli = ArgParser.withMcp({
|
|
492
239
|
appName: "My CLI",
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
{
|
|
497
|
-
|
|
498
|
-
description: "Deploy resources",
|
|
499
|
-
parser: deployParser,
|
|
500
|
-
handler: ({ args }) => {
|
|
501
|
-
console.log(`Deploying to ${args.target}`);
|
|
502
|
-
},
|
|
503
|
-
},
|
|
504
|
-
{
|
|
505
|
-
name: "monitor",
|
|
506
|
-
description: "Monitoring commands",
|
|
507
|
-
parser: monitorParser,
|
|
508
|
-
},
|
|
509
|
-
],
|
|
240
|
+
handler: async (ctx) => {
|
|
241
|
+
// Works with both sync and async operations
|
|
242
|
+
const result = await someAsyncOperation(ctx.args.input);
|
|
243
|
+
return { success: true, result };
|
|
244
|
+
},
|
|
510
245
|
});
|
|
511
246
|
|
|
512
|
-
//
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
**By default, after successful parsing, ArgParser will execute the handler associated with the _final command_ matched in the argument chain.** For example, running `my-cli service start` will execute the handler for the `start` command, not `my-cli` or `service`.
|
|
524
|
-
|
|
525
|
-
If you need to parse arguments but _prevent_ handler execution, you can pass the `skipHandlers: true` option to the `parse()` method:
|
|
526
|
-
|
|
527
|
-
```typescript
|
|
528
|
-
const args = parser.parse(process.argv.slice(2), { skipHandlers: true });
|
|
529
|
-
// Handlers will NOT be executed, you can inspect 'args' and decide what to do
|
|
530
|
-
```
|
|
531
|
-
|
|
532
|
-
### Handler Context
|
|
533
|
-
|
|
534
|
-
Handler functions receive a single argument, a `HandlerContext` object, containing information about the parsing result and the command chain:
|
|
535
|
-
|
|
536
|
-
```typescript
|
|
537
|
-
type HandlerContext = {
|
|
538
|
-
args: TParsedArgs<any>; // Arguments parsed by and defined for the FINAL command's parser
|
|
539
|
-
parentArgs?: TParsedArgs<any>; // Combined arguments from PARENT parsers (less relevant with inheritParentFlags)
|
|
540
|
-
commandChain: string[]; // Array of command names from root to final command
|
|
541
|
-
};
|
|
247
|
+
// parse() is async and works with both sync and async handlers
|
|
248
|
+
async function main() {
|
|
249
|
+
try {
|
|
250
|
+
const result = await cli.parse(process.argv.slice(2));
|
|
251
|
+
// Handler results are automatically awaited and merged
|
|
252
|
+
console.log(result.success); // true
|
|
253
|
+
} catch (error) {
|
|
254
|
+
console.error("Error:", error.message);
|
|
255
|
+
process.exit(1);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
542
258
|
```
|
|
543
259
|
|
|
544
|
-
|
|
260
|
+
### Top-level await
|
|
545
261
|
|
|
546
|
-
|
|
262
|
+
Works in ES modules or Node.js >=18 with top-level await
|
|
547
263
|
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
// ... command logic ...
|
|
556
|
-
});
|
|
557
|
-
|
|
558
|
-
// You can also retrieve a sub-parser and set its handler:
|
|
559
|
-
const subParser = cli.getSubCommand("deploy")?.parser;
|
|
560
|
-
if (subParser) {
|
|
561
|
-
subParser.setHandler((ctx) => {
|
|
562
|
-
console.log("Overridden deploy handler!");
|
|
563
|
-
// ... new deploy logic ...
|
|
564
|
-
});
|
|
264
|
+
```javascript
|
|
265
|
+
try {
|
|
266
|
+
const result = await cli.parse(process.argv.slice(2));
|
|
267
|
+
console.log("Success:", result);
|
|
268
|
+
} catch (error) {
|
|
269
|
+
console.error("Error:", error.message);
|
|
270
|
+
process.exit(1);
|
|
565
271
|
}
|
|
566
272
|
```
|
|
567
273
|
|
|
568
|
-
###
|
|
274
|
+
### Promise-based parsing
|
|
569
275
|
|
|
570
|
-
|
|
276
|
+
If you need synchronous contexts, you can simply rely on promise-based APIs
|
|
571
277
|
|
|
572
|
-
```
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
options: ["--force"],
|
|
582
|
-
flagOnly: true,
|
|
583
|
-
type: Boolean,
|
|
278
|
+
```javascript
|
|
279
|
+
cli
|
|
280
|
+
.parse(process.argv.slice(2))
|
|
281
|
+
.then((result) => {
|
|
282
|
+
console.log("Success:", result);
|
|
283
|
+
})
|
|
284
|
+
.catch((error) => {
|
|
285
|
+
console.error("Error:", error.message);
|
|
286
|
+
process.exit(1);
|
|
584
287
|
});
|
|
585
|
-
}
|
|
586
288
|
```
|
|
587
289
|
|
|
588
|
-
|
|
290
|
+
---
|
|
589
291
|
|
|
590
|
-
|
|
292
|
+
## Migrating from v1.x to the v2.0 `addTool` API
|
|
591
293
|
|
|
592
|
-
|
|
294
|
+
Version 2.0 introduces the `addTool()` method to unify CLI subcommand and MCP tool creation. This simplifies development by removing boilerplate and conditional logic.
|
|
593
295
|
|
|
594
|
-
|
|
595
|
-
const parentParser = new ArgParser().addFlags([
|
|
596
|
-
{ name: "verbose", options: ["-v"], type: Boolean, flagOnly: true },
|
|
597
|
-
{ name: "config", options: ["-c"], type: String }, // Common config flag
|
|
598
|
-
]);
|
|
296
|
+
### Before v2.0: Separate Definitions
|
|
599
297
|
|
|
600
|
-
|
|
601
|
-
{ name: "local", options: ["-l"], type: String }, // Child-specific flag
|
|
602
|
-
{ name: "config", options: ["--child-config"], type: Number }, // Override config flag
|
|
603
|
-
]);
|
|
298
|
+
Previously, you had to define CLI handlers and MCP tools separately, often with conditional logic inside the handler to manage different output formats.
|
|
604
299
|
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
300
|
+
```javascript
|
|
301
|
+
const cli = ArgParser.withMcp({
|
|
302
|
+
appName: "My Awesome CLI",
|
|
303
|
+
appCommandName: "mycli",
|
|
304
|
+
description: "A tool that works in both CLI and MCP mode",
|
|
305
|
+
mcp: {
|
|
306
|
+
serverInfo: { name: "my-awesome-mcp-server", version: "1.0.0" },
|
|
307
|
+
},
|
|
609
308
|
});
|
|
610
309
|
|
|
611
|
-
//
|
|
612
|
-
|
|
310
|
+
// Old way: Separate CLI subcommands and MCP tools
|
|
311
|
+
cli
|
|
312
|
+
.addSubCommand({
|
|
313
|
+
name: "search",
|
|
314
|
+
handler: async (ctx) => {
|
|
315
|
+
// Manual MCP detection was required
|
|
316
|
+
if (ctx.isMcp) {
|
|
317
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
318
|
+
} else {
|
|
319
|
+
console.log("Search results...");
|
|
320
|
+
return result;
|
|
321
|
+
}
|
|
322
|
+
},
|
|
323
|
+
})
|
|
324
|
+
// And a separate command to start the server
|
|
325
|
+
.addMcpSubCommand("serve", {
|
|
326
|
+
/* MCP config */
|
|
327
|
+
});
|
|
613
328
|
```
|
|
614
329
|
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
ArgParser provides robust automatic help generation.
|
|
330
|
+
### After v2.0: The Unified `addTool()` Method
|
|
618
331
|
|
|
619
|
-
|
|
332
|
+
Now, a single `addTool()` definition creates both the CLI subcommand and the MCP tool. Console output is automatically managed, flags are converted to MCP schemas, and the server is started with a universal system flag.
|
|
620
333
|
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
# Shows help for the root command
|
|
631
|
-
my-cli --help
|
|
632
|
-
|
|
633
|
-
# Shows help for the 'deploy' sub-command
|
|
634
|
-
my-cli deploy --help
|
|
635
|
-
```
|
|
636
|
-
|
|
637
|
-
### `helpText()` Method
|
|
334
|
+
```javascript
|
|
335
|
+
const cli = ArgParser.withMcp({
|
|
336
|
+
appName: "My Awesome CLI",
|
|
337
|
+
appCommandName: "mycli",
|
|
338
|
+
description: "A tool that works in both CLI and MCP mode",
|
|
339
|
+
mcp: {
|
|
340
|
+
serverInfo: { name: "my-awesome-mcp-server", version: "1.0.0" },
|
|
341
|
+
},
|
|
342
|
+
});
|
|
638
343
|
|
|
639
|
-
|
|
344
|
+
// New way: A single tool definition for both CLI and MCP
|
|
345
|
+
cli.addTool({
|
|
346
|
+
name: "search",
|
|
347
|
+
description: "Search for items",
|
|
348
|
+
flags: [
|
|
349
|
+
{ name: "query", type: "string", mandatory: true },
|
|
350
|
+
{ name: "apiKey", type: "string", env: "API_KEY" }, // For DXT integration
|
|
351
|
+
],
|
|
352
|
+
handler: async (ctx) => {
|
|
353
|
+
// No more MCP detection! Use console.log freely.
|
|
354
|
+
console.log(`Searching for: ${ctx.args.query}`);
|
|
355
|
+
const results = await performSearch(ctx.args.query, ctx.args.apiKey);
|
|
356
|
+
console.log(`Found ${results.length} results`);
|
|
357
|
+
return { success: true, results };
|
|
358
|
+
},
|
|
359
|
+
});
|
|
640
360
|
|
|
641
|
-
|
|
642
|
-
|
|
361
|
+
// CLI usage: mycli search --query "test"
|
|
362
|
+
// MCP usage: mycli --s-mcp-serve
|
|
643
363
|
```
|
|
644
364
|
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
For the root command, if you invoke the script **without any arguments** and the root parser **does not have a handler defined**, ArgParser will automatically display the root help text and exit cleanly (code 0). This provides immediate guidance for users who just type the script name.
|
|
648
|
-
|
|
649
|
-
If the root parser _does_ have a handler, it's assumed that the handler will manage the empty invocation case, and auto-help will not trigger.
|
|
650
|
-
|
|
651
|
-
## Error Handling
|
|
365
|
+
**Benefits of Migrating:**
|
|
652
366
|
|
|
653
|
-
|
|
367
|
+
- **Less Code**: A single definition replaces two or more complex ones.
|
|
368
|
+
- **Simpler Logic**: No more manual MCP mode detection or response formatting.
|
|
369
|
+
- **Automatic Schemas**: Flags are automatically converted into the `input_schema` for MCP tools.
|
|
370
|
+
- **Automatic Console Safety**: `console.log` is automatically redirected in MCP mode.
|
|
654
371
|
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
1. A descriptive, colored error message is printed to `stderr`.
|
|
658
|
-
2. A suggestion to use `--help` is included, showing the correct command path.
|
|
659
|
-
3. The process exits with status code 1.
|
|
372
|
+
---
|
|
660
373
|
|
|
661
|
-
|
|
662
|
-
// Example (assuming 'data-proc' is appCommandName and 'phase' is mandatory)
|
|
663
|
-
// Running `data-proc` would output:
|
|
374
|
+
## Core Concepts
|
|
664
375
|
|
|
665
|
-
|
|
666
|
-
//
|
|
667
|
-
// Try 'data-proc --help' for usage details.
|
|
668
|
-
```
|
|
376
|
+
### Defining Flags
|
|
669
377
|
|
|
670
|
-
|
|
378
|
+
Flags are defined using the `IFlag` interface within the `flags` array of a tool or command.
|
|
671
379
|
|
|
672
380
|
```typescript
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
if (
|
|
685
|
-
console.error(`\nCustom Parse Error: ${error.message}`);
|
|
686
|
-
// Implement custom logic (e.g., logging, different exit codes)
|
|
687
|
-
process.exit(1);
|
|
688
|
-
} else {
|
|
689
|
-
// Handle unexpected errors
|
|
690
|
-
console.error("An unexpected error occurred:", error);
|
|
691
|
-
process.exit(1);
|
|
692
|
-
}
|
|
381
|
+
interface IFlag {
|
|
382
|
+
name: string; // Internal name (e.g., 'verbose')
|
|
383
|
+
options: string[]; // Command-line options (e.g., ['--verbose', '-v'])
|
|
384
|
+
type: "string" | "number" | "boolean" | "array" | "object" | Function;
|
|
385
|
+
description?: string; // Help text
|
|
386
|
+
mandatory?: boolean | ((args: any) => boolean); // Whether the flag is required
|
|
387
|
+
defaultValue?: any; // Default value if not provided
|
|
388
|
+
flagOnly?: boolean; // A flag that doesn't consume a value (like --help)
|
|
389
|
+
enum?: any[]; // An array of allowed values
|
|
390
|
+
validate?: (value: any, parsedArgs?: any) => boolean | string | void; // Custom validation function
|
|
391
|
+
allowMultiple?: boolean; // Allow the flag to be provided multiple times
|
|
392
|
+
env?: string; // Links the flag to an environment variable for DXT packages, will automatically generate user_config entries in the DXT manifest and fill the flag value to the ENV value if found (process.env)
|
|
693
393
|
}
|
|
694
394
|
```
|
|
695
395
|
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
ArgParser includes a built-in system flag `--s-save-to-env` that allows you to export the current parser's configuration and parsed arguments to various file formats. This is useful for creating configuration templates, documenting CLI usage, or generating environment files for deployment.
|
|
699
|
-
|
|
700
|
-
### Usage
|
|
701
|
-
|
|
702
|
-
```bash
|
|
703
|
-
# Export to .env format (default for no extension)
|
|
704
|
-
your-cli --flag1 value1 --flag2 --s-save-to-env config.env
|
|
705
|
-
|
|
706
|
-
# Export to YAML format
|
|
707
|
-
your-cli --flag1 value1 --flag2 --s-save-to-env config.yaml
|
|
708
|
-
|
|
709
|
-
# Export to JSON format
|
|
710
|
-
your-cli --flag1 value1 --flag2 --s-save-to-env config.json
|
|
711
|
-
|
|
712
|
-
# Export to TOML format
|
|
713
|
-
your-cli --flag1 value1 --flag2 --s-save-to-env config.toml
|
|
714
|
-
```
|
|
715
|
-
|
|
716
|
-
### Supported Formats
|
|
717
|
-
|
|
718
|
-
The format is automatically detected based on the file extension:
|
|
396
|
+
### Type Handling and Validation
|
|
719
397
|
|
|
720
|
-
|
|
721
|
-
- **`.yaml` / `.yml`**: YAML format
|
|
722
|
-
- **`.json` / `.jsonc`**: JSON format with metadata
|
|
723
|
-
- **`.toml` / `.tml`**: TOML format
|
|
398
|
+
ArgParser automatically handles type conversion and validation:
|
|
724
399
|
|
|
725
|
-
|
|
400
|
+
- **String flags**: `--name value` or `--name="quoted value"`
|
|
401
|
+
- **Number flags**: `--count 42` (automatically parsed)
|
|
402
|
+
- **Boolean flags**: `--verbose` (presence implies `true`)
|
|
403
|
+
- **Array flags**: `--tags tag1,tag2,tag3` or multiple `--tag value1 --tag value2` (requires `allowMultiple: true`)
|
|
726
404
|
|
|
727
|
-
|
|
728
|
-
- **Includes inherited flags**: Shows flags from the current parser and all parent parsers in the chain
|
|
729
|
-
- **Comments optional flags**: Flags that are optional and not set are commented out but still documented
|
|
730
|
-
- **Preserves values**: Set flags show their actual values, unset flags show default values or are commented out
|
|
731
|
-
- **Rich documentation**: Each flag includes its description, options, type, and constraints
|
|
405
|
+
### Hierarchical CLIs (Sub-Commands)
|
|
732
406
|
|
|
733
|
-
|
|
407
|
+
While `addTool()` is the recommended way to create subcommands that are also MCP-compatible, you can use `.addSubCommand()` for traditional CLI hierarchies.
|
|
734
408
|
|
|
735
|
-
|
|
409
|
+
> **Note**: By default, subcommands created with `.addSubCommand()` are exposed to MCP as tools. If you want to create CLI-only subcommands, set `includeSubCommands: false` when adding tools.
|
|
736
410
|
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
# verbose: Enable verbose output
|
|
743
|
-
# Options: -v, --verbose
|
|
744
|
-
# Type: Boolean
|
|
745
|
-
# Default: false
|
|
746
|
-
VERBOSE="true"
|
|
747
|
-
|
|
748
|
-
# output: Output file path
|
|
749
|
-
# Options: -o, --output
|
|
750
|
-
# Type: String
|
|
751
|
-
OUTPUT="file.txt"
|
|
752
|
-
|
|
753
|
-
# count: Number of items to process
|
|
754
|
-
# Options: -c, --count
|
|
755
|
-
# Type: Number
|
|
756
|
-
# Default: 10
|
|
757
|
-
COUNT="5"
|
|
758
|
-
```
|
|
411
|
+
```typescript
|
|
412
|
+
// Create a parser for a nested command
|
|
413
|
+
const logsParser = new ArgParser().addFlags([
|
|
414
|
+
{ name: "follow", options: ["-f"], type: "boolean", flagOnly: true },
|
|
415
|
+
]);
|
|
759
416
|
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
417
|
+
// This creates a command group: `my-cli monitor`
|
|
418
|
+
const monitorParser = new ArgParser().addSubCommand({
|
|
419
|
+
name: "logs",
|
|
420
|
+
description: "Show application logs",
|
|
421
|
+
parser: logsParser,
|
|
422
|
+
handler: ({ args }) => console.log(`Following logs: ${args.follow}`),
|
|
423
|
+
});
|
|
764
424
|
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
425
|
+
// Attach the command group to the main CLI
|
|
426
|
+
const cli = new ArgParser().addSubCommand({
|
|
427
|
+
name: "monitor",
|
|
428
|
+
description: "Monitoring commands",
|
|
429
|
+
parser: monitorParser,
|
|
430
|
+
});
|
|
769
431
|
|
|
770
|
-
|
|
771
|
-
output: "file.txt"
|
|
772
|
-
count: 5
|
|
432
|
+
// Usage: my-cli monitor logs -f
|
|
773
433
|
```
|
|
774
434
|
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
ArgParser includes several built-in system flags that provide debugging, configuration management, and introspection capabilities. These flags are processed before normal argument parsing and will cause the program to exit after execution.
|
|
435
|
+
#### MCP Exposure Control
|
|
778
436
|
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
- **`--s-debug`**: Runtime debugging with step-by-step parsing analysis
|
|
784
|
-
- **`--s-with-env <file>`**: Load configuration from files (`.env`, `.yaml`, `.json`, `.toml`)
|
|
785
|
-
- **`--s-save-to-env <file>`**: Export current configuration to various formats
|
|
786
|
-
- **`--s-debug-print`**: Export complete parser configuration for inspection
|
|
787
|
-
- **`--s-enable-fuzzy`**: Enable fuzzy testing mode (dry-run with no side effects)
|
|
788
|
-
|
|
789
|
-
### `--s-save-to-env <file>`
|
|
790
|
-
|
|
791
|
-
Exports the current parser's configuration and parsed arguments to various file formats.
|
|
792
|
-
|
|
793
|
-
```bash
|
|
794
|
-
# Export to .env format (default for no extension)
|
|
795
|
-
your-cli --flag1 value1 --flag2 --s-save-to-env config.env
|
|
796
|
-
|
|
797
|
-
# Export to YAML format
|
|
798
|
-
your-cli --flag1 value1 --flag2 --s-save-to-env config.yaml
|
|
437
|
+
```typescript
|
|
438
|
+
// By default, subcommands are exposed to MCP
|
|
439
|
+
const mcpTools = parser.toMcpTools(); // Includes all subcommands
|
|
799
440
|
|
|
800
|
-
|
|
801
|
-
|
|
441
|
+
// To exclude subcommands from MCP (CLI-only)
|
|
442
|
+
const mcpToolsOnly = parser.toMcpTools({ includeSubCommands: false });
|
|
802
443
|
|
|
803
|
-
|
|
804
|
-
|
|
444
|
+
// Name conflicts: You cannot have both addSubCommand("name") and addTool({ name: "name" })
|
|
445
|
+
// This will throw an error:
|
|
446
|
+
parser.addSubCommand({ name: "process", parser: subParser });
|
|
447
|
+
parser.addTool({ name: "process", handler: async () => {} }); // ❌ Error: Sub-command 'process' already exists
|
|
805
448
|
```
|
|
806
449
|
|
|
807
|
-
|
|
808
|
-
- Works at any parser level (root command or sub-commands)
|
|
809
|
-
- Includes inherited flags from parent parsers in the chain
|
|
810
|
-
- Comments out optional flags that are not set
|
|
811
|
-
- Rich documentation for each flag (description, options, type, constraints)
|
|
812
|
-
- Automatic format detection based on file extension
|
|
813
|
-
|
|
814
|
-
### `--s-with-env <file>`
|
|
815
|
-
|
|
816
|
-
Loads configuration from a file and merges it with command line arguments. CLI arguments take precedence over file configuration.
|
|
817
|
-
|
|
818
|
-
```bash
|
|
819
|
-
# Load from .env format (default for no extension)
|
|
820
|
-
your-cli --s-with-env config.env
|
|
450
|
+
### Flag Inheritance (`inheritParentFlags`)
|
|
821
451
|
|
|
822
|
-
|
|
823
|
-
your-cli --s-with-env config.yaml
|
|
452
|
+
To share common flags (like `--verbose` or `--config`) across sub-commands, set `inheritParentFlags: true` in the sub-command's parser.
|
|
824
453
|
|
|
825
|
-
|
|
826
|
-
|
|
454
|
+
```typescript
|
|
455
|
+
const parentParser = new ArgParser().addFlags([
|
|
456
|
+
{ name: "verbose", options: ["-v"], type: "boolean" },
|
|
457
|
+
]);
|
|
827
458
|
|
|
828
|
-
|
|
829
|
-
|
|
459
|
+
// This child parser will automatically have the --verbose flag
|
|
460
|
+
const childParser = new ArgParser({ inheritParentFlags: true }).addFlags([
|
|
461
|
+
{ name: "target", options: ["-t"], type: "string" },
|
|
462
|
+
]);
|
|
830
463
|
|
|
831
|
-
|
|
832
|
-
your-cli --s-with-env config.yaml --verbose --output override.txt
|
|
464
|
+
parentParser.addSubCommand({ name: "deploy", parser: childParser });
|
|
833
465
|
```
|
|
834
466
|
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
The format is automatically detected based on the file extension:
|
|
838
|
-
|
|
839
|
-
- **`.env`** (or no extension): Dotenv format with `KEY=value` pairs
|
|
840
|
-
- **`.yaml` / `.yml`**: YAML format
|
|
841
|
-
- **`.json` / `.jsonc`**: JSON format (metadata is ignored if present)
|
|
842
|
-
- **`.toml` / `.tml`**: TOML format
|
|
467
|
+
---
|
|
843
468
|
|
|
844
|
-
|
|
469
|
+
## MCP & Claude Desktop Integration
|
|
845
470
|
|
|
846
|
-
|
|
847
|
-
- **Type conversion**: Automatically converts values to match flag types (boolean, number, string, array)
|
|
848
|
-
- **Enum validation**: Validates values against allowed enum options
|
|
849
|
-
- **CLI precedence**: Command line arguments override file configuration
|
|
850
|
-
- **Error handling**: Exits with error code 1 if file cannot be loaded or parsed
|
|
851
|
-
- **Flag matching**: Only loads values for flags that exist in the current parser chain
|
|
471
|
+
### Automatic MCP Server Mode (`--s-mcp-serve`)
|
|
852
472
|
|
|
853
|
-
|
|
473
|
+
You don't need to write any server logic. Run your application with the `--s-mcp-serve` flag, and ArgParser will automatically start a compliant MCP server, exposing all tools defined with `.addTool()` and subcommands created with `.addSubCommand()` (unless `includeSubCommands: false` is set).
|
|
854
474
|
|
|
855
|
-
**.env format:**
|
|
856
475
|
```bash
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
COUNT=5
|
|
860
|
-
TAGS=tag1,tag2,tag3
|
|
861
|
-
```
|
|
862
|
-
|
|
863
|
-
**YAML format:**
|
|
864
|
-
```yaml
|
|
865
|
-
verbose: true
|
|
866
|
-
output: file.txt
|
|
867
|
-
count: 5
|
|
868
|
-
tags:
|
|
869
|
-
- tag1
|
|
870
|
-
- tag2
|
|
871
|
-
- tag3
|
|
872
|
-
```
|
|
873
|
-
|
|
874
|
-
**JSON format:**
|
|
875
|
-
```json
|
|
876
|
-
{
|
|
877
|
-
"verbose": true,
|
|
878
|
-
"output": "file.txt",
|
|
879
|
-
"count": 5,
|
|
880
|
-
"tags": ["tag1", "tag2", "tag3"]
|
|
881
|
-
}
|
|
882
|
-
```
|
|
476
|
+
# This single command starts a fully compliant MCP server
|
|
477
|
+
my-cli-app --s-mcp-serve
|
|
883
478
|
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
Prints the complete parser configuration to a JSON file and console for debugging complex parser setups.
|
|
887
|
-
|
|
888
|
-
```bash
|
|
889
|
-
your-cli --s-debug-print
|
|
479
|
+
# You can also override transports and ports using system flags
|
|
480
|
+
my-cli-app --s-mcp-serve --s-mcp-transport sse --s-mcp-port 3001
|
|
890
481
|
```
|
|
891
482
|
|
|
892
|
-
|
|
893
|
-
- Creates `ArgParser.full.json` with the complete parser structure
|
|
894
|
-
- Shows all flags, sub-commands, handlers, and configuration
|
|
895
|
-
- Useful for debugging complex parser hierarchies
|
|
896
|
-
- Human-readable console output with syntax highlighting
|
|
483
|
+
### MCP Transports
|
|
897
484
|
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
Provides detailed runtime debugging information showing how arguments are parsed step-by-step.
|
|
485
|
+
You can define the transports directly in the .withMcp() settings, or override them via the `--s-mcp-transport(s)` flags.
|
|
901
486
|
|
|
902
487
|
```bash
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
**Output:**
|
|
907
|
-
- Shows command chain identification process
|
|
908
|
-
- Step-by-step argument parsing simulation
|
|
909
|
-
- Final parser identification
|
|
910
|
-
- Accumulated arguments at each level
|
|
911
|
-
- Remaining arguments after parsing
|
|
912
|
-
- Complete static configuration of the final parser
|
|
913
|
-
|
|
914
|
-
**Useful for:**
|
|
915
|
-
- Understanding complex command chains
|
|
916
|
-
- Debugging argument parsing issues
|
|
917
|
-
- Seeing how flags are inherited between parsers
|
|
918
|
-
- Troubleshooting sub-command resolution
|
|
919
|
-
|
|
920
|
-
### Usage Notes
|
|
921
|
-
|
|
922
|
-
- System flags are processed before normal argument parsing
|
|
923
|
-
- They cause the program to exit after execution (exit code 0 for success)
|
|
924
|
-
- Can be used with any combination of regular flags and sub-commands
|
|
925
|
-
- Particularly useful during development and debugging
|
|
926
|
-
|
|
927
|
-
## Debugging
|
|
928
|
-
|
|
929
|
-
### Programmatic Debugging
|
|
930
|
-
|
|
931
|
-
The `printAll(filePath?: string)` method is useful for debugging complex parser configurations programmatically. It recursively outputs the structure, options, flags, and handlers of a parser instance and its sub-commands.
|
|
932
|
-
|
|
933
|
-
- `parser.printAll()`: Prints a colored, human-readable output to the console.
|
|
934
|
-
- `parser.printAll('./config.json')`: Writes the configuration as a pretty-printed JSON file.
|
|
935
|
-
- `parser.printAll('./config.log')`: Writes a plain text version to a file.
|
|
936
|
-
|
|
937
|
-
```typescript
|
|
938
|
-
import { ArgParser } from "@alcyone-labs/arg-parser";
|
|
939
|
-
|
|
940
|
-
const parser = new ArgParser({ appName: "Debug App" })
|
|
941
|
-
.addFlags([
|
|
942
|
-
/* ... */
|
|
943
|
-
])
|
|
944
|
-
.addSubCommand(/* ... */);
|
|
945
|
-
|
|
946
|
-
parser.printAll(); // Output to console
|
|
947
|
-
```
|
|
948
|
-
|
|
949
|
-
### Runtime Debugging
|
|
950
|
-
|
|
951
|
-
For runtime debugging, use the system flags documented above:
|
|
952
|
-
|
|
953
|
-
- `--s-debug-print`: Export complete parser configuration
|
|
954
|
-
- `--s-debug`: Show step-by-step argument parsing process
|
|
955
|
-
- `--s-save-to-env <file>`: Export current configuration to various formats
|
|
956
|
-
- `--s-with-env <file>`: Load configuration from file and merge with CLI arguments
|
|
488
|
+
# Single transport
|
|
489
|
+
my-tool --s-mcp-serve --s-mcp-transport stdio
|
|
957
490
|
|
|
958
|
-
|
|
491
|
+
# Multiple transports via JSON
|
|
492
|
+
my-tool --s-mcp-serve --s-mcp-transports '[{"type":"stdio"},{"type":"sse","port":3001}]'
|
|
959
493
|
|
|
960
|
-
|
|
494
|
+
# Single transport with custom options
|
|
495
|
+
my-tool --s-mcp-serve --s-mcp-transport sse --s-mcp-port 3000 --s-mcp-host 0.0.0.0
|
|
961
496
|
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
Input args: [--s-enable-fuzzy --input test.txt --format json]
|
|
981
|
-
Parsed args: {"input":"test.txt","format":"json"}
|
|
497
|
+
# Multiple transports (configured via --s-mcp-serve system flag)
|
|
498
|
+
const cli = ArgParser.withMcp({
|
|
499
|
+
appName: 'multi-tool',
|
|
500
|
+
appCommandName: 'multi-tool',
|
|
501
|
+
mcp: {
|
|
502
|
+
serverInfo: {
|
|
503
|
+
name: 'multi-tool-mcp',
|
|
504
|
+
version: '1.0.0'
|
|
505
|
+
},
|
|
506
|
+
transports: [
|
|
507
|
+
// Can be a single string...
|
|
508
|
+
"stdio",
|
|
509
|
+
// or one of the other transport types supported by @modelcontextprotocol/sdk
|
|
510
|
+
{ type: "sse", port: 3000, host: "0.0.0.0" },
|
|
511
|
+
{ type: "websocket", port: 3001, path: "/ws" }
|
|
512
|
+
]
|
|
513
|
+
}
|
|
514
|
+
});
|
|
982
515
|
```
|
|
983
516
|
|
|
984
|
-
|
|
985
|
-
- Fuzzy testing CLI argument parsing
|
|
986
|
-
- Validating CLI configuration without executing business logic
|
|
987
|
-
- Testing complex command hierarchies safely
|
|
988
|
-
- Automated testing of CLI interfaces
|
|
989
|
-
|
|
990
|
-
These system flags are particularly useful when you need to debug a CLI application without modifying the source code.
|
|
517
|
+
### Automatic Console Safety
|
|
991
518
|
|
|
992
|
-
|
|
519
|
+
A major challenge in MCP is preventing `console.log` from corrupting the JSON-RPC communication over `STDOUT`. ArgParser solves this automatically.
|
|
993
520
|
|
|
994
|
-
|
|
521
|
+
- **How it works**: When `--s-mcp-serve` is active, ArgParser hijacks the global `console` object.
|
|
522
|
+
- **What it does**: It redirects `console.log`, `.info`, `.warn`, and `.debug` to `STDERR` with a prefix, making them visible for debugging without interfering with the protocol. `console.error` is preserved on `STDERR` as expected.
|
|
523
|
+
- **Your benefit**: You can write `console.log` statements freely in your handlers. They will work as expected in CLI mode and be safely handled in MCP mode with **zero code changes**.
|
|
995
524
|
|
|
996
|
-
###
|
|
525
|
+
### Generating DXT Packages (`--s-build-dxt`)
|
|
997
526
|
|
|
998
|
-
|
|
527
|
+
A Desktop Extension (`.dxt`) is a standardized package for installing your tools into Claude Desktop. ArgParser automates this process.
|
|
999
528
|
|
|
1000
529
|
```bash
|
|
1001
|
-
#
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
# Test with custom options and save results
|
|
1005
|
-
bun src/fuzzy-test-cli.ts \
|
|
1006
|
-
--file examples/getting-started.ts \
|
|
1007
|
-
--output test-results.json \
|
|
1008
|
-
--format json \
|
|
1009
|
-
--max-depth 3 \
|
|
1010
|
-
--random-tests 20 \
|
|
1011
|
-
--verbose
|
|
1012
|
-
```
|
|
530
|
+
# 1. Generate the DXT package contents into a directory
|
|
531
|
+
my-cli-app --s-build-dxt ./my-dxt-package
|
|
1013
532
|
|
|
1014
|
-
|
|
533
|
+
# The output folder contains everything needed: manifest.json, entry point, etc.
|
|
534
|
+
# A default logo will be applied if you don't provide one.
|
|
1015
535
|
|
|
1016
|
-
|
|
536
|
+
# 2. (Optional) Pack the folder into a .dxt file for distribution
|
|
537
|
+
npx @anthropic-ai/dxt pack ./my-dxt-package
|
|
1017
538
|
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
```bash
|
|
1021
|
-
# Enable fuzzy mode for safe testing (dry-run with no side effects)
|
|
1022
|
-
your-cli --s-enable-fuzzy --input test.txt --format json
|
|
539
|
+
# 3. (Optional) Sign the DXT package
|
|
540
|
+
npx @anthropic-ai/dxt sign ./my-dxt-package.dxt
|
|
1023
541
|
|
|
1024
|
-
#
|
|
1025
|
-
bun src/fuzzy-test-cli.ts --file your-cli.ts
|
|
542
|
+
# Then drag & drop the .dxt file into Claude Desktop to install it, in the Settings > Extensions screen.
|
|
1026
543
|
```
|
|
1027
544
|
|
|
1028
|
-
|
|
1029
|
-
- **Zero boilerplate**: No conditional logic needed - just `export default cli` and `cli.parse()`
|
|
1030
|
-
- **Automatic prevention**: System automatically prevents CLI execution during fuzzy testing
|
|
1031
|
-
- **Dry-run execution**: Prevents handler function execution (no side effects)
|
|
1032
|
-
- **Error collection**: Disables error handling to collect all parsing errors
|
|
1033
|
-
- **Argument logging**: Shows what each handler would receive for testing visibility
|
|
1034
|
-
- **Safe testing**: Test production CLIs with database operations, file modifications, or API calls
|
|
545
|
+
### Logo Configuration
|
|
1035
546
|
|
|
1036
|
-
|
|
547
|
+
The logo will appear in Claude Desktop's Extensions settings and when users interact with your MCP tools. Note that neither ArgParser nor Anthropic packer will modify the logo, so make sure to use a reasonable size, such as 256x256 pixels or 512x512 pixels maximum. Any image type that can display in a browser is supported.
|
|
1037
548
|
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
- **Valid combinations**: Proper flag usage with correct types and values
|
|
1041
|
-
- **Invalid combinations**: Wrong inputs to verify error handling
|
|
1042
|
-
- **Random combinations**: Pseudo-random flag combinations for edge cases
|
|
1043
|
-
- **Command paths**: All subcommand combinations up to configurable depth
|
|
1044
|
-
- **Performance**: Execution timing for different input complexities
|
|
1045
|
-
|
|
1046
|
-
### **Programmatic Usage**
|
|
549
|
+
You can customize the logo/icon that appears in Claude Desktop for your DXT package by configuring the `logo` property in your `serverInfo`:
|
|
1047
550
|
|
|
1048
551
|
```typescript
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
552
|
+
const cli = ArgParser.withMcp({
|
|
553
|
+
appName: "My CLI",
|
|
554
|
+
appCommandName: "mycli",
|
|
555
|
+
mcp: {
|
|
556
|
+
// This will appear in Claude Desktop's Extensions settings
|
|
557
|
+
serverInfo: {
|
|
558
|
+
name: "my-mcp-server",
|
|
559
|
+
version: "1.0.0",
|
|
560
|
+
description: "My CLI as an MCP server",
|
|
561
|
+
logo: "./assets/my-logo.png", // Local file path
|
|
562
|
+
},
|
|
563
|
+
},
|
|
1058
564
|
});
|
|
1059
|
-
|
|
1060
|
-
const report = await tester.runFuzzyTest();
|
|
1061
|
-
console.log(`Success rate: ${(report.successfulTests / report.totalTests * 100).toFixed(1)}%`);
|
|
1062
565
|
```
|
|
1063
566
|
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
Generate reports in multiple formats:
|
|
567
|
+
If no custom logo is provided or loading fails, a default ArgParser logo is included
|
|
1067
568
|
|
|
1068
|
-
|
|
1069
|
-
# Human-readable console output
|
|
1070
|
-
bun src/fuzzy-test-cli.ts --file my-cli.ts --format text
|
|
569
|
+
#### Supported Logo Sources
|
|
1071
570
|
|
|
1072
|
-
|
|
1073
|
-
bun src/fuzzy-test-cli.ts --file my-cli.ts --format json --output results.json
|
|
571
|
+
**Local File Path:**
|
|
1074
572
|
|
|
1075
|
-
|
|
1076
|
-
|
|
573
|
+
```typescript
|
|
574
|
+
logo: "./assets/my-logo.png"; // Relative to your project
|
|
575
|
+
logo: "/absolute/path/to/logo.jpg"; // Absolute path
|
|
1077
576
|
```
|
|
1078
577
|
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
## API Reference
|
|
1082
|
-
|
|
1083
|
-
This section provides a quick overview of the main components. See the sections above for detailed explanations and examples.
|
|
578
|
+
**HTTP/HTTPS URL:**
|
|
1084
579
|
|
|
1085
|
-
### **Core Classes**
|
|
1086
|
-
|
|
1087
|
-
#### `ArgParserBase`
|
|
1088
|
-
|
|
1089
|
-
Base class providing core CLI parsing functionality without MCP features. Use this for lightweight CLIs that don't need MCP server capabilities.
|
|
1090
|
-
|
|
1091
|
-
**Constructor:**
|
|
1092
|
-
- `new ArgParserBase(options?, initialFlags?)`: Create basic parser instance
|
|
1093
|
-
|
|
1094
|
-
#### `ArgParser` (v1.1.0+)
|
|
1095
|
-
|
|
1096
|
-
Main class with built-in MCP server capabilities. Extends `ArgParserBase` with MCP integration.
|
|
1097
|
-
|
|
1098
|
-
**Constructors:**
|
|
1099
|
-
- `new ArgParser(options?, initialFlags?)`: Create parser with MCP capabilities
|
|
1100
|
-
- `ArgParser.withMcp(options?, initialFlags?)`: Factory method for MCP-enabled parser (same as constructor)
|
|
1101
|
-
- `ArgParser.fromArgParser(parser)`: Convert existing ArgParserBase to MCP-enabled
|
|
1102
|
-
|
|
1103
|
-
**MCP Methods:**
|
|
1104
|
-
- `toMcpTools(options?)`: Generate MCP tool structures from CLI definition
|
|
1105
|
-
- `createMcpServer(serverInfo, toolOptions?)`: Create MCP server instance
|
|
1106
|
-
- `startMcpServer(serverInfo, toolOptions?)`: Start MCP server with stdio transport
|
|
1107
|
-
- `startMcpServerWithTransport(serverInfo, transportType, transportOptions?, toolOptions?)`: Start with specific transport
|
|
1108
|
-
- `startMcpServerWithMultipleTransports(serverInfo, transports, toolOptions?)`: Start with multiple transports (manual approach)
|
|
1109
|
-
- `addMcpSubCommand(name, serverInfo, options?)`: Add MCP server sub-command with optional preset transports (recommended approach)
|
|
1110
|
-
- `parse(args, options?)`: Async version supporting async handlers
|
|
1111
|
-
|
|
1112
|
-
**MCP Types:**
|
|
1113
|
-
- `McpTransportConfig`: Configuration for a single transport (`{ type, port?, host?, path?, sessionIdGenerator? }`)
|
|
1114
|
-
- `McpSubCommandOptions`: Options for MCP sub-command (`{ defaultTransport?, defaultTransports?, toolOptions? }`)
|
|
1115
|
-
|
|
1116
|
-
**Transport Types:**
|
|
1117
|
-
- `"stdio"`: Standard input/output
|
|
1118
|
-
- `"sse"`: Server-Sent Events over HTTP
|
|
1119
|
-
- `"streamable-http"`: HTTP with streaming support
|
|
1120
|
-
|
|
1121
|
-
**Example:**
|
|
1122
580
|
```typescript
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
handler: async (ctx) => ({ result: ctx.args }),
|
|
1126
|
-
})
|
|
1127
|
-
.addFlags([/* flags */])
|
|
1128
|
-
.addMcpSubCommand("serve", {
|
|
1129
|
-
name: "my-mcp-server",
|
|
1130
|
-
version: "1.0.0",
|
|
1131
|
-
});
|
|
1132
|
-
|
|
1133
|
-
// Elegant approach: Configure default transports in addMcpSubCommand
|
|
1134
|
-
const cli = ArgParser.withMcp({
|
|
1135
|
-
appName: "My Tool",
|
|
1136
|
-
handler: async (ctx) => ({ result: ctx.args }),
|
|
1137
|
-
})
|
|
1138
|
-
.addFlags([/* your flags */])
|
|
1139
|
-
.addMcpSubCommand("serve", {
|
|
1140
|
-
name: "my-server",
|
|
1141
|
-
version: "1.0.0",
|
|
1142
|
-
}, {
|
|
1143
|
-
// Default multiple transports - used when no CLI flags provided
|
|
1144
|
-
defaultTransports: [
|
|
1145
|
-
{ type: "stdio" },
|
|
1146
|
-
{ type: "sse", port: 3001 },
|
|
1147
|
-
{ type: "streamable-http", port: 3002 }
|
|
1148
|
-
]
|
|
1149
|
-
});
|
|
1150
|
-
|
|
1151
|
-
// Usage: my-tool serve (uses all default transports)
|
|
1152
|
-
// Usage: my-tool serve --transports '[{"type":"sse","port":4000}]' (overrides defaults)
|
|
581
|
+
logo: "https://example.com/logo.png"; // Downloaded automatically
|
|
582
|
+
logo: "https://cdn.example.com/icon.svg";
|
|
1153
583
|
```
|
|
1154
584
|
|
|
1155
|
-
###
|
|
1156
|
-
|
|
1157
|
-
#### `new ArgParserBase(options?, initialFlags?)`
|
|
1158
|
-
|
|
1159
|
-
Constructor for creating a basic parser instance without MCP capabilities.
|
|
1160
|
-
|
|
1161
|
-
#### `new ArgParser(options?, initialFlags?)`
|
|
1162
|
-
|
|
1163
|
-
Constructor for creating a parser instance with MCP capabilities.
|
|
1164
|
-
|
|
1165
|
-
- `options`: An object (`IArgParserParams`) configuring the parser.
|
|
1166
|
-
- `appName?: string`: Display name.
|
|
1167
|
-
- `appCommandName?: string`: Command name for help/errors.
|
|
1168
|
-
- `description?: string`: Parser description.
|
|
1169
|
-
- `handler?: (ctx: HandlerContext) => void`: Handler function for this parser.
|
|
1170
|
-
- `subCommands?: ISubCommand[]`: Array of sub-command definitions.
|
|
1171
|
-
- `handleErrors?: boolean`: Enable/disable default error handling (default: `true`).
|
|
1172
|
-
- `throwForDuplicateFlags?: boolean`: Throw error for duplicate flags (default: `false`).
|
|
1173
|
-
- `inheritParentFlags?: boolean`: Enable flag inheritance when this parser is a sub-command (default: `false`).
|
|
1174
|
-
- `initialFlags`: Optional array of `IFlag` objects to add during initialization.
|
|
1175
|
-
|
|
1176
|
-
### `parse(args, options?)`
|
|
1177
|
-
|
|
1178
|
-
Parses an array of command-line arguments.
|
|
1179
|
-
|
|
1180
|
-
- `args`: `string[]` - Array of arguments (usually `process.argv.slice(2)`).
|
|
1181
|
-
- `options`: Optional object (`IParseOptions`).
|
|
1182
|
-
- `skipHelpHandling?: boolean`: Prevents automatic help display/exit on `--help` (default: `false`).
|
|
1183
|
-
- `skipHandlers?: boolean`: Prevents execution of any matched command handlers (default: `false`).
|
|
1184
|
-
- Returns: `TParsedArgs & { $commandChain?: string[] }` - An object containing the parsed arguments and optionally the `$commandChain`. Throws `ArgParserError` if `handleErrors` is `false`.
|
|
1185
|
-
|
|
1186
|
-
### `.addFlag(flag)`
|
|
1187
|
-
|
|
1188
|
-
Adds a single flag definition.
|
|
1189
|
-
|
|
1190
|
-
- `flag`: `IFlag` - The flag object.
|
|
1191
|
-
- Returns: `this` for chaining.
|
|
1192
|
-
|
|
1193
|
-
### `.addFlags(flags)`
|
|
1194
|
-
|
|
1195
|
-
Adds multiple flag definitions.
|
|
1196
|
-
|
|
1197
|
-
- `flags`: `IFlag[]` - Array of flag objects.
|
|
1198
|
-
- Returns: `this` for chaining.
|
|
1199
|
-
|
|
1200
|
-
### `.addSubCommand(subCommand)`
|
|
1201
|
-
|
|
1202
|
-
Adds a sub-command definition.
|
|
585
|
+
### How DXT Generation Works
|
|
1203
586
|
|
|
1204
|
-
|
|
1205
|
-
- Returns: `this` for chaining.
|
|
587
|
+
When you run `--s-build-dxt`, ArgParser performs several steps to create a self-contained, autonomous package:
|
|
1206
588
|
|
|
1207
|
-
|
|
589
|
+
1. **Introspection**: It analyzes all tools defined with `.addTool()`.
|
|
590
|
+
2. **Manifest Generation**: It creates a `manifest.json` file.
|
|
591
|
+
- Tool flags are converted into a JSON Schema for the `input_schema`.
|
|
592
|
+
- Flags with an `env` property (e.g., `{ name: 'apiKey', env: 'API_KEY' }`) are automatically added to the `user_config` section, prompting the user for the value upon installation and making it available as an environment variable to your tool.
|
|
593
|
+
3. **Autonomous Build**: It bundles your CLI's source code and its dependencies into a single entry point (e.g., `server.js`) that can run without `node_modules`. This ensures the DXT is portable and reliable.
|
|
594
|
+
4. **Packaging**: It assembles all necessary files (manifest, server bundle, logo, etc.) into the specified output directory, ready to be used by Claude Desktop or packed with `npx @anthropic-ai/dxt`.
|
|
1208
595
|
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
- `handler`: `(ctx: HandlerContext) => void` - The handler function.
|
|
1212
|
-
- Returns: `this` for chaining.
|
|
1213
|
-
|
|
1214
|
-
### `.getSubCommand(name)`
|
|
1215
|
-
|
|
1216
|
-
Retrieves a defined sub-command by name.
|
|
1217
|
-
|
|
1218
|
-
- `name`: `string` - The name of the sub-command.
|
|
1219
|
-
- Returns: `ISubCommand | undefined` - The sub-command definition or `undefined` if not found.
|
|
1220
|
-
|
|
1221
|
-
### `.hasFlag(name)`
|
|
1222
|
-
|
|
1223
|
-
Checks if a flag with the given name exists on this parser instance.
|
|
1224
|
-
|
|
1225
|
-
- `name`: `string` - The name of the flag.
|
|
1226
|
-
- Returns: `boolean`.
|
|
1227
|
-
|
|
1228
|
-
### `helpText()`
|
|
1229
|
-
|
|
1230
|
-
Generates the formatted help text for this parser instance.
|
|
1231
|
-
|
|
1232
|
-
- Returns: `string` - The generated help text.
|
|
1233
|
-
|
|
1234
|
-
### `printAll(filePath?)`
|
|
1235
|
-
|
|
1236
|
-
Recursively prints the parser configuration.
|
|
1237
|
-
|
|
1238
|
-
- `filePath`: `string?` - Optional path to write output to file. `.json` extension saves as JSON.
|
|
1239
|
-
|
|
1240
|
-
### Interfaces
|
|
1241
|
-
|
|
1242
|
-
- `IFlag`: Defines the structure of a command-line flag.
|
|
1243
|
-
- `ISubCommand`: Defines the structure of a sub-command.
|
|
1244
|
-
- `HandlerContext`: The object passed to handler functions.
|
|
1245
|
-
- `IParseOptions`: Options for the `parse()` method.
|
|
1246
|
-
- `IArgParserParams`: Options for the `ArgParser` constructor.
|
|
1247
|
-
- `ArgParserError`: Custom error class thrown on parsing failures when `handleErrors` is `false`.
|
|
1248
|
-
|
|
1249
|
-
## Quick Reference
|
|
1250
|
-
|
|
1251
|
-
### **Basic CLI Setup**
|
|
1252
|
-
```typescript
|
|
1253
|
-
import { ArgParser } from "@alcyone-labs/arg-parser";
|
|
1254
|
-
|
|
1255
|
-
const cli = new ArgParser({
|
|
1256
|
-
appName: "My Tool",
|
|
1257
|
-
appCommandName: "my-tool",
|
|
1258
|
-
handler: async (ctx) => ({ result: ctx.args }),
|
|
1259
|
-
})
|
|
1260
|
-
.addFlags([
|
|
1261
|
-
{ name: "input", options: ["--input", "-i"], type: "string", mandatory: true },
|
|
1262
|
-
{ name: "verbose", options: ["--verbose", "-v"], type: "boolean", flagOnly: true },
|
|
1263
|
-
])
|
|
1264
|
-
.addSubCommand({
|
|
1265
|
-
name: "process",
|
|
1266
|
-
description: "Process data",
|
|
1267
|
-
handler: async (ctx) => ({ processed: true }),
|
|
1268
|
-
parser: new ArgParser({}, [
|
|
1269
|
-
{ name: "format", options: ["--format"], type: "string", enum: ["json", "xml"] },
|
|
1270
|
-
]),
|
|
1271
|
-
});
|
|
1272
|
-
```
|
|
1273
|
-
|
|
1274
|
-
### **MCP Integration**
|
|
1275
|
-
```typescript
|
|
1276
|
-
import { ArgParser } from "@alcyone-labs/arg-parser";
|
|
596
|
+
---
|
|
1277
597
|
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
598
|
+
## System Flags & Configuration
|
|
599
|
+
|
|
600
|
+
ArgParser includes built-in `--s-*` flags for development, debugging, and configuration. They are processed before normal arguments and will cause the program to exit after their task is complete.
|
|
601
|
+
|
|
602
|
+
| Flag | Description |
|
|
603
|
+
| --------------------------- | ---------------------------------------------------------------------------------------------- |
|
|
604
|
+
| **MCP & DXT** | |
|
|
605
|
+
| `--s-mcp-serve` | Starts the application in MCP server mode, exposing all tools. |
|
|
606
|
+
| `--s-build-dxt [dir]` | Generates a complete, autonomous DXT package for Claude Desktop. |
|
|
607
|
+
| `--s-mcp-transport <type>` | Overrides the MCP transport (`stdio`, `sse`, `streamable-http`). |
|
|
608
|
+
| `--s-mcp-transports <json>` | Overrides transports with a JSON array for multi-transport setups. |
|
|
609
|
+
| `--s-mcp-port <number>` | Sets the port for HTTP-based transports (`sse`, `streamable-http`). |
|
|
610
|
+
| `--s-mcp-host <string>` | Sets the host address for HTTP-based transports. |
|
|
611
|
+
| **Configuration** | |
|
|
612
|
+
| `--s-with-env <file>` | Loads configuration from a file (`.env`, `.json`, `.yaml`, `.toml`). CLI args take precedence. |
|
|
613
|
+
| `--s-save-to-env <file>` | Saves the current arguments to a configuration file, perfect for templates. |
|
|
614
|
+
| **Debugging** | |
|
|
615
|
+
| `--s-debug` | Prints a detailed, step-by-step log of the argument parsing process. |
|
|
616
|
+
| `--s-debug-print` | Exports the entire parser configuration to a JSON file for inspection. |
|
|
617
|
+
| `--s-enable-fuzzy` | Enables fuzzy testing mode—a dry run that parses args but skips handler execution. |
|
|
1284
618
|
|
|
1285
|
-
|
|
1286
|
-
// MCP: my-tool serve --transport sse --port 3001
|
|
1287
|
-
```
|
|
619
|
+
---
|
|
1288
620
|
|
|
1289
|
-
|
|
1290
|
-
Configure default transports that will be used when no CLI transport flags are provided:
|
|
621
|
+
## Changelog
|
|
1291
622
|
|
|
1292
|
-
|
|
1293
|
-
import { ArgParser, McpTransportConfig } from "@alcyone-labs/arg-parser";
|
|
623
|
+
### v2.0.0
|
|
1294
624
|
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
.addMcpSubCommand("serve", {
|
|
1301
|
-
name: "my-server",
|
|
1302
|
-
version: "1.0.0",
|
|
1303
|
-
}, {
|
|
1304
|
-
defaultTransport: {
|
|
1305
|
-
type: "sse",
|
|
1306
|
-
port: 3001,
|
|
1307
|
-
host: "0.0.0.0"
|
|
1308
|
-
}
|
|
1309
|
-
});
|
|
625
|
+
- **Unified Tool Architecture**: Introduced `.addTool()` to define CLI subcommands and MCP tools in a single declaration.
|
|
626
|
+
- **Environment Variables Support**: The `env` property on any IFlag now automatically pull value from the `process.env[${ENV}]` key and generates `user_config` entries in the DXT manifest and fills the flag value to the ENV value if found (process.env).
|
|
627
|
+
- **Enhanced DXT Generation**: The `env` property on flags now automatically generates `user_config` entries in the DXT manifest.
|
|
628
|
+
- **Automatic Console Safety**: Console output is automatically and safely redirected in MCP mode to prevent protocol contamination.
|
|
629
|
+
- **Breaking Changes**: The `addMcpSubCommand()` and separate `addSubCommand()` for MCP tools are deprecated in favor of `addTool()` and `--s-mcp-serve`.
|
|
1310
630
|
|
|
1311
|
-
|
|
1312
|
-
const cliWithMultiplePresets = ArgParser.withMcp({
|
|
1313
|
-
appName: "Multi-Transport Tool",
|
|
1314
|
-
handler: async (ctx) => ({ result: ctx.args }),
|
|
1315
|
-
})
|
|
1316
|
-
.addMcpSubCommand("serve", {
|
|
1317
|
-
name: "multi-server",
|
|
1318
|
-
version: "1.0.0",
|
|
1319
|
-
}, {
|
|
1320
|
-
defaultTransports: [
|
|
1321
|
-
{ type: "stdio" },
|
|
1322
|
-
{ type: "sse", port: 3001 },
|
|
1323
|
-
{ type: "streamable-http", port: 3002, path: "/api/mcp" }
|
|
1324
|
-
],
|
|
1325
|
-
toolOptions: {
|
|
1326
|
-
includeSubCommands: true
|
|
1327
|
-
}
|
|
1328
|
-
});
|
|
631
|
+
### v1.3.0
|
|
1329
632
|
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
```
|
|
633
|
+
- **Plugin System & Architecture**: Refactored to a dependency-injection model, making the core library dependency-free. Optional plugins for TOML/YAML.
|
|
634
|
+
- **Global Console Replacement**: Implemented the first version of automatic console suppression for MCP compliance.
|
|
635
|
+
- **Autonomous Build Improvements**: Significantly reduced DXT bundle size and removed dynamic `require` issues.
|
|
1334
636
|
|
|
1335
|
-
###
|
|
1336
|
-
```bash
|
|
1337
|
-
# Debug parsing
|
|
1338
|
-
my-tool --s-debug --input data.txt process
|
|
637
|
+
### v1.2.0
|
|
1339
638
|
|
|
1340
|
-
|
|
1341
|
-
|
|
639
|
+
- **Critical MCP Fixes**: Resolved issues where MCP tools with output schemas would fail. Ensured correct JSON-RPC 2.0 response formatting.
|
|
640
|
+
- **Enhanced Handler Context**: Added `isMcp` flag to the handler context for more reliable mode detection.
|
|
1342
641
|
|
|
1343
|
-
|
|
1344
|
-
my-tool --input data.txt --s-save-to-env template.yaml
|
|
1345
|
-
```
|
|
642
|
+
### v1.1.0
|
|
1346
643
|
|
|
1347
|
-
|
|
1348
|
-
```bash
|
|
1349
|
-
# Single transport
|
|
1350
|
-
my-tool serve --transport sse --port 3001
|
|
1351
|
-
|
|
1352
|
-
# Multiple transports
|
|
1353
|
-
my-tool serve --transports '[
|
|
1354
|
-
{"type":"stdio"},
|
|
1355
|
-
{"type":"sse","port":3001},
|
|
1356
|
-
{"type":"streamable-http","port":3002}
|
|
1357
|
-
]'
|
|
1358
|
-
```
|
|
644
|
+
- **Major Features**: First release with MCP Integration, System Flags (`--s-debug`, `--s-with-env`, etc.), and environment loading from files.
|
|
1359
645
|
|
|
1360
646
|
---
|
|
1361
647
|
|
|
1362
|
-
**📖 For complete examples and tutorials, see the [`examples/`](./examples/) directory.**
|
|
1363
|
-
|
|
1364
|
-
---
|
|
1365
|
-
|
|
1366
648
|
## Backlog
|
|
1367
649
|
|
|
1368
650
|
- [x] Publish as an open-source library
|
|
1369
651
|
- [x] Make ArgParser compatible with MCP out-of-the-box
|
|
1370
|
-
- [x] Rename --LIB
|
|
652
|
+
- [x] Rename --LIB-\* flags to --s-\*
|
|
1371
653
|
- [x] Make it possible to pass a `--s-save-to-env /path/to/file` parameter that saves all the parameters to a file (works with Bash-style .env, JSON, YAML, TOML)
|
|
1372
654
|
- [x] Make it possible to pass a `--s-with-env /path/to/file` parameter that loads all the parameters from a file (works with Bash-style .env, JSON, YAML, TOML)
|
|
1373
655
|
- [ ] Add System flags to args.systemArgs
|
|
@@ -1380,4 +662,3 @@ my-tool serve --transports '[
|
|
|
1380
662
|
### (known) Bugs / DX improvement points
|
|
1381
663
|
|
|
1382
664
|
- [ ] When a flag with `flagOnly: false` is going to consume a value that appears like a valid flag from the set, raise the appropriate warning
|
|
1383
|
-
- [ ] When a flag with `allowMultiple: false` and `flagOnly: true` is passed multiple times (regardless of the options, for example "-1" and later "--one", both being valid), raise the correct error
|