@alcyone-labs/arg-parser 2.2.1 → 2.4.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 CHANGED
@@ -1,15 +1,17 @@
1
1
  # ArgParser - Type-Safe Command Line Argument Parser
2
2
 
3
- A modern, type-safe command line argument parser with built-in MCP (Model Context Protocol) integration and automatic Claude Desktop Extension (DXT) generation.
3
+ A modern, type-safe command line argument parser with built-in MCP (Model Context Protocol) integration, real-time MCP Resources, and automatic Claude Desktop Extension (DXT) generation.
4
4
 
5
5
  ## Table of Contents
6
6
 
7
7
  - [Features Overview](#features-overview)
8
8
  - [Installation](#installation)
9
9
  - [Quick Start: The Unified `addTool` API](#quick-start-the-unified-addtool-api)
10
+ - [MCP Tool Name Constraints](#mcp-tool-name-constraints)
10
11
  - [How to Run It](#how-to-run-it)
11
12
  - [Setting Up System-Wide CLI Access](#setting-up-system-wide-cli-access)
12
13
  - [Parsing Command-Line Arguments](#parsing-command-line-arguments)
14
+ - [Automatic Argument Detection](#automatic-argument-detection)
13
15
  - [Cannonical Usage Pattern](#cannonical-usage-pattern)
14
16
  - [Top-level await](#top-level-await)
15
17
  - [Promise-based parsing](#promise-based-parsing)
@@ -19,6 +21,11 @@ A modern, type-safe command line argument parser with built-in MCP (Model Contex
19
21
  - [Core Concepts](#core-concepts)
20
22
  - [Defining Flags](#defining-flags)
21
23
  - [Type Handling and Validation](#type-handling-and-validation)
24
+ - [Supported Type Formats](#supported-type-formats)
25
+ - [Runtime Type Validation](#runtime-type-validation)
26
+ - [Automatic Type Processing](#automatic-type-processing)
27
+ - [Async Custom Parser Support](#async-custom-parser-support)
28
+ - [Type Conversion Examples](#type-conversion-examples)
22
29
  - [Hierarchical CLIs (Sub-Commands)](#hierarchical-clis-sub-commands)
23
30
  - [MCP Exposure Control](#mcp-exposure-control)
24
31
  - [Flag Inheritance (`inheritParentFlags`)](#flag-inheritance-inheritparentflags)
@@ -36,13 +43,100 @@ A modern, type-safe command line argument parser with built-in MCP (Model Contex
36
43
  - [Common Pitfalls to Avoid](#common-pitfalls-to-avoid)
37
44
  - [Automatic MCP Server Mode (`--s-mcp-serve`)](#automatic-mcp-server-mode---s-mcp-serve)
38
45
  - [MCP Transports](#mcp-transports)
46
+ - [MCP Logging Configuration](#mcp-logging-configuration)
47
+ - [Enhanced Logging (Recommended)](#enhanced-logging-recommended)
48
+ - [Simple Logging Configuration](#simple-logging-configuration)
49
+ - [Configuration Priority](#configuration-priority)
50
+ - [Configuration Merging](#configuration-merging)
51
+ - [Path Resolution Options](#path-resolution-options)
52
+ - [MCP Resources - Real-Time Data Feeds](#mcp-resources---real-time-data-feeds)
53
+ - [Basic Resource Setup](#basic-resource-setup)
54
+ - [URI Templates with Dynamic Parameters](#uri-templates-with-dynamic-parameters)
55
+ - [MCP Subscription Lifecycle](#mcp-subscription-lifecycle)
56
+ - [Usage Examples](#usage-examples)
57
+ - [Design Patterns](#design-patterns)
39
58
  - [Automatic Console Safety](#automatic-console-safety)
40
59
  - [Generating DXT Packages (`--s-build-dxt`)](#generating-dxt-packages---s-build-dxt)
41
60
  - [Logo Configuration](#logo-configuration)
42
61
  - [Supported Logo Sources](#supported-logo-sources)
62
+ - [Including Additional Files in DXT Packages](#including-additional-files-in-dxt-packages)
63
+ - [Include Options](#include-options)
43
64
  - [How DXT Generation Works](#how-dxt-generation-works)
65
+ - [DXT Bundling Strategies](#dxt-bundling-strategies)
66
+ - [Standard Approach (Recommended for Most Projects)](#standard-approach-recommended-for-most-projects)
67
+ - [Native Dependencies Approach](#native-dependencies-approach)
68
+ - [Typical Errors](#typical-errors)
44
69
  - [System Flags & Configuration](#system-flags--configuration)
45
70
  - [Changelog](#changelog)
71
+ - [v2.4.0](#v240)
72
+ - [v2.3.0](#v230)
73
+ - [v2.2.1](#v221)
74
+ - [v2.2.0](#v220)
75
+ - [v2.1.1](#v211)
76
+ - [v2.1.0](#v210)
77
+ - [v2.0.0](#v200)
78
+ - [v1.3.0](#v130)
79
+ - [v1.2.0](#v120)
80
+ - [v1.1.0](#v110)
81
+ - [Backlog](#backlog)
82
+ - [(known) Bugs / DX improvement points](#known-bugs--dx-improvement-points)
83
+
84
+ - [Features Overview](#features-overview)
85
+ - [Installation](#installation)
86
+ - [Quick Start: The Unified `addTool` API](#quick-start-the-unified-addtool-api)
87
+ - [How to Run It](#how-to-run-it)
88
+ - [Setting Up System-Wide CLI Access](#setting-up-system-wide-cli-access)
89
+ - [Parsing Command-Line Arguments](#parsing-command-line-arguments)
90
+ - [Automatic Argument Detection](#automatic-argument-detection)
91
+ - [Cannonical Usage Pattern](#cannonical-usage-pattern)
92
+ - [Top-level await](#top-level-await)
93
+ - [Promise-based parsing](#promise-based-parsing)
94
+ - [Migrating from v1.x to the v2.0 `addTool` API](#migrating-from-v1x-to-the-v20-addtool-api)
95
+ - [Before v2.0: Separate Definitions](#before-v20-separate-definitions)
96
+ - [After v2.0: The Unified `addTool()` Method](#after-v20-the-unified-addtool-method)
97
+ - [Core Concepts](#core-concepts)
98
+ - [Defining Flags](#defining-flags)
99
+ - [Type Handling and Validation](#type-handling-and-validation)
100
+ - [Supported Type Formats](#supported-type-formats)
101
+ - [Runtime Type Validation](#runtime-type-validation)
102
+ - [Automatic Type Processing](#automatic-type-processing)
103
+ - [Async Custom Parser Support](#async-custom-parser-support)
104
+ - [Type Conversion Examples](#type-conversion-examples)
105
+ - [Hierarchical CLIs (Sub-Commands)](#hierarchical-clis-sub-commands)
106
+ - [MCP Exposure Control](#mcp-exposure-control)
107
+ - [Flag Inheritance (`inheritParentFlags`)](#flag-inheritance-inheritparentflags)
108
+ - [MCP & Claude Desktop Integration](#mcp--claude-desktop-integration)
109
+ - [Output Schema Support](#output-schema-support)
110
+ - [Basic Usage](#basic-usage)
111
+ - [Predefined Schema Patterns](#predefined-schema-patterns)
112
+ - [Custom Zod Schemas](#custom-zod-schemas)
113
+ - [MCP Version Compatibility](#mcp-version-compatibility)
114
+ - [Automatic Error Handling](#automatic-error-handling)
115
+ - [Writing Effective MCP Tool Descriptions](#writing-effective-mcp-tool-descriptions)
116
+ - [Best Practices for Tool Descriptions](#best-practices-for-tool-descriptions)
117
+ - [Complete Example: Well-Documented Tool](#complete-example-well-documented-tool)
118
+ - [Parameter Description Guidelines](#parameter-description-guidelines)
119
+ - [Common Pitfalls to Avoid](#common-pitfalls-to-avoid)
120
+ - [Automatic MCP Server Mode (`--s-mcp-serve`)](#automatic-mcp-server-mode---s-mcp-serve)
121
+ - [MCP Transports](#mcp-transports)
122
+ - [MCP Log Path Configuration](#mcp-log-path-configuration)
123
+ - [MCP Resources - Real-Time Data Feeds](#mcp-resources---real-time-data-feeds) ⭐
124
+ - [Automatic Console Safety](#automatic-console-safety)
125
+ - [Generating DXT Packages (`--s-build-dxt`)](#generating-dxt-packages---s-build-dxt)
126
+ - [Logo Configuration](#logo-configuration)
127
+ - [Supported Logo Sources](#supported-logo-sources)
128
+ - [How DXT Generation Works](#how-dxt-generation-works)
129
+ - [DXT Bundling Strategies](#dxt-bundling-strategies)
130
+ - [Standard Approach (Recommended for Most Projects)](#standard-approach-recommended-for-most-projects)
131
+ - [Native Dependencies Approach](#native-dependencies-approach)
132
+ - [Typical Errors](#typical-errors)
133
+ - [System Flags & Configuration](#system-flags--configuration)
134
+ - [Changelog](#changelog)
135
+ - [v2.3.0](#v230)
136
+ - [v2.2.1](#v221)
137
+ - [v2.2.0](#v220)
138
+ - [v2.1.1](#v211)
139
+ - [v2.1.0](#v210)
46
140
  - [v2.0.0](#v200)
47
141
  - [v1.3.0](#v130)
48
142
  - [v1.2.0](#v120)
@@ -55,9 +149,10 @@ A modern, type-safe command line argument parser with built-in MCP (Model Contex
55
149
  - **Unified Tool Architecture**: Define tools once with `addTool()` and they automatically function as both CLI subcommands and MCP tools.
56
150
  - **Type-safe flag definitions** with full TypeScript support and autocompletion.
57
151
  - **Automatic MCP Integration**: Transform any CLI into a compliant MCP server with a single command (`--s-mcp-serve`).
152
+ - **MCP Resources with Real-Time Feeds** ⭐: Create subscription-based data feeds with URI templates for live notifications to AI assistants.
58
153
  - **Console Safe**: `console.log` and other methods
59
154
  are automatically handled in MCP mode to prevent protocol contamination, requiring no changes to your code.
60
- - **DXT Package Generation**: Generate complete, ready-to-install Claude Desktop Extension (`.dxt`) packages with the `--s-build-dxt` command.
155
+ - **DXT Package Generation**: Generate complete, ready-to-install Claude Desktop Extension (`.dxt`) packages with the `--s-build-dxt` command and `--s-with-node-modules` for platform-dependent builds.
61
156
  - **Hierarchical Sub-commands**: Create complex, nested sub-command structures (e.g., `git commit`, `docker container ls`) with flag inheritance.
62
157
  - **Configuration Management**: Easily load (`--s-with-env`) and save (`--s-save-to-env`) configurations from/to `.env`, `.json`, `.yaml`, and `.toml` files.
63
158
  - **Automatic Help & Error Handling**: Context-aware help text and user-friendly error messages are generated automatically.
@@ -149,6 +244,35 @@ main();
149
244
  export default cli;
150
245
  ```
151
246
 
247
+ ### MCP Tool Name Constraints
248
+
249
+ When using `.addTool()` or `.addMcpTool()`, tool names are automatically sanitized for MCP compatibility. MCP tool names must follow the pattern `^[a-zA-Z0-9_-]{1,64}$` (only alphanumeric characters, underscores, and hyphens, with a maximum length of 64 characters).
250
+
251
+ ```typescript
252
+ // These names will be automatically sanitized:
253
+ cli.addTool({
254
+ name: "test.tool", // → "test_tool"
255
+ // ... rest of config
256
+ });
257
+
258
+ cli.addTool({
259
+ name: "my@tool", // → "my_tool"
260
+ // ... rest of config
261
+ });
262
+
263
+ cli.addTool({
264
+ name: "tool with spaces", // → "tool_with_spaces"
265
+ // ... rest of config
266
+ });
267
+
268
+ cli.addTool({
269
+ name: "very-long-tool-name-that-exceeds-the-64-character-limit-for-mcp", // → truncated to 64 chars
270
+ // ... rest of config
271
+ });
272
+ ```
273
+
274
+ The library will warn you when tool names are sanitized, but your tools will continue to work normally. For CLI usage, the original name is preserved as the subcommand name.
275
+
152
276
  ## How to Run It
153
277
 
154
278
  ```bash
@@ -162,6 +286,18 @@ mycli --s-mcp-serve
162
286
 
163
287
  # 3. Generate a DXT package for Claude Desktop (2-steps)
164
288
  mycli --s-build-dxt ./my-dxt-package
289
+
290
+ # If you use ML models or packages that include binaries such as Sqlite3 or sharp, etc...
291
+ # You need to bundle the node_modules folder with your DXT package
292
+ # In order to do this, you need to use the following flag:
293
+ # First hard-install all the packages
294
+ rm -rf node_moduels
295
+ pnpm install --prod --node-linker=hoisted
296
+ # Then bundle with node_modules
297
+ mycli --s-build-dxt ./my-dxt-package --s-with-node-modules
298
+ # then packages the dxt
299
+ npx @anthropic-ai/dxt pack ./my-dxt-package
300
+ # then upload the dxt bundle to Claude Desktop from the settings > extensions > advanced screen
165
301
  ```
166
302
 
167
303
  Read more on generating the DXT package here: [Generating DXT Packages](#generating-dxt-packages---s-build-dxt)
@@ -268,7 +404,7 @@ const cli = ArgParser.withMcp({
268
404
  handler: async (ctx) => ({ success: true, data: ctx.args }),
269
405
  });
270
406
 
271
- // NEW: Call parse() without arguments
407
+ // You can call parse() without arguments
272
408
  // Automatically detects Node.js environment and uses process.argv.slice(2)
273
409
  async function main() {
274
410
  try {
@@ -961,13 +1097,19 @@ my-cli-app --s-mcp-serve --s-mcp-transport sse --s-mcp-port 3001
961
1097
  # Configure custom log file path for MCP server logs
962
1098
  my-cli-app --s-mcp-serve --s-mcp-log-path ./custom-logs/mcp-server.log
963
1099
 
964
- # Or configure log path programmatically in withMcp()
1100
+ # Or configure logging programmatically in withMcp()
965
1101
  const cli = ArgParser.withMcp({
966
1102
  appName: 'My CLI App',
967
1103
  appCommandName: 'my-cli-app',
968
1104
  mcp: {
969
1105
  serverInfo: { name: 'my-server', version: '1.0.0' },
970
- logPath: './my-logs/mcp-server.log' // Programmatic log path
1106
+ // NEW: Improved logging with level control
1107
+ log: {
1108
+ level: 'info', // Captures info, warn, error
1109
+ logToFile: './my-logs/mcp-server.log',
1110
+ prefix: 'MyApp'
1111
+ }
1112
+ // LEGACY: logPath: './my-logs/mcp-server.log' // Still works
971
1113
  }
972
1114
  });
973
1115
  ```
@@ -989,20 +1131,30 @@ my-tool --s-mcp-serve --s-mcp-transport sse --s-mcp-port 3000 --s-mcp-host 0.0.0
989
1131
  # Custom log path via CLI flag (logs to specified file instead of ./logs/mcp.log)
990
1132
  my-tool --s-mcp-serve --s-mcp-log-path /var/log/my-mcp-server.log
991
1133
 
992
- # Custom log path via programmatic configuration
1134
+ # Improved logging via programmatic configuration
993
1135
  const parser = ArgParser.withMcp({
994
1136
  mcp: {
995
1137
  serverInfo: { name: 'my-tool', version: '1.0.0' },
996
- logPath: '/var/log/my-mcp-server.log'
1138
+ log: {
1139
+ level: 'debug', // Capture all log levels
1140
+ logToFile: '/var/log/my-mcp-server.log',
1141
+ prefix: 'MyTool'
1142
+ }
1143
+ // LEGACY: logPath: '/var/log/my-mcp-server.log' // Still works
997
1144
  }
998
1145
  });
999
1146
 
1000
- # Multiple transports and custom log path (configured via --s-mcp-serve system flag)
1147
+ # Multiple transports and improved logging (configured via --s-mcp-serve system flag)
1001
1148
  const cli = ArgParser.withMcp({
1002
1149
  appName: 'multi-tool',
1003
1150
  appCommandName: 'multi-tool',
1004
1151
  mcp: {
1005
- logPath: './logs/multi-tool-mcp.log', // Custom log path
1152
+ // NEW: improved logging configuration
1153
+ log: {
1154
+ level: 'info',
1155
+ logToFile: './logs/multi-tool-mcp.log',
1156
+ prefix: 'MultiTool'
1157
+ },
1006
1158
  serverInfo: {
1007
1159
  name: 'multi-tool-mcp',
1008
1160
  version: '1.0.0'
@@ -1018,13 +1170,91 @@ const cli = ArgParser.withMcp({
1018
1170
  });
1019
1171
  ```
1020
1172
 
1021
- ### MCP Log Path Configuration
1173
+ ### MCP Logging Configuration
1174
+
1175
+ MCP server logging can be configured with McpLoggerOptions options using `@alcyone-labs/simple-mcp-logger`. You can control log levels, output destinations, and more.
1176
+
1177
+ #### Enhanced Logging (Recommended)
1178
+
1179
+ Use the new `log` property for comprehensive logging control:
1180
+
1181
+ ```typescript
1182
+ const parser = ArgParser.withMcp({
1183
+ appName: "My MCP Server",
1184
+ appCommandName: "my-mcp-server",
1185
+ mcp: {
1186
+ serverInfo: { name: "my-server", version: "1.0.0" },
1187
+ log: {
1188
+ level: "debug", // Captures debug, info, warn, error
1189
+ logToFile: "./logs/comprehensive.log",
1190
+ prefix: "MyServer",
1191
+ mcpMode: true, // MCP compliant (default)
1192
+ },
1193
+ },
1194
+ });
1195
+ ```
1196
+
1197
+ **Available log levels**: `"debug"` | `"info"` | `"warn"` | `"error"` | `"silent"`
1198
+
1199
+ **Type Safety**: The `McpLoggerOptions` type is provided for full TypeScript support and matches the interface from `@alcyone-labs/simple-mcp-logger`.
1200
+
1201
+ #### Simple Logging Configuration
1202
+
1203
+ For basic use cases, you can use a simple string path:
1204
+
1205
+ ```typescript
1206
+ const parser = ArgParser.withMcp({
1207
+ mcp: {
1208
+ serverInfo: { name: "my-server", version: "1.0.0" },
1209
+ log: "./logs/simple.log", // Simple string path
1210
+ },
1211
+ });
1212
+ ```
1022
1213
 
1023
- MCP server logs can be configured through multiple methods with the following priority order:
1214
+ #### Configuration Priority
1215
+
1216
+ Logging configuration follows this priority order:
1024
1217
 
1025
1218
  1. **CLI Flag (Highest Priority)**: `--s-mcp-log-path <path>`
1026
- 2. **Programmatic Configuration**: `mcp.logPath` in `withMcp()`
1027
- 3. **Default Path (Fallback)**: `./logs/mcp.log`
1219
+ 2. **Merging**: When both `mcp.log` and `mcp.logPath` are present:
1220
+ - `mcp.log` provides logger options (level, prefix, mcpMode)
1221
+ - `mcp.logPath` provides flexible path resolution (relativeTo, basePath)
1222
+ - Path resolution: `mcp.logPath` > `mcp.log.logToFile`
1223
+ 3. **Log Config Only**: `mcp.log` object or string in `withMcp()`
1224
+ 4. **Legacy Log Path Only**: `mcp.logPath` in `withMcp()`
1225
+ 5. **Default Path (Fallback)**: `./logs/mcp.log`
1226
+
1227
+ #### Configuration Merging
1228
+
1229
+ When both `log` and `logPath` are specified:
1230
+
1231
+ ```typescript
1232
+ const parser = ArgParser.withMcp({
1233
+ mcp: {
1234
+ serverInfo: { name: "my-server", version: "1.0.0" },
1235
+ // log provides logger options (level, prefix, mcpMode)
1236
+ log: {
1237
+ level: "debug",
1238
+ prefix: "MyServer",
1239
+ mcpMode: true,
1240
+ // logToFile can be omitted when using logPath
1241
+ },
1242
+ // logPath provides flexible path resolution
1243
+ logPath: {
1244
+ path: "./logs/app.log",
1245
+ relativeTo: "entry", // "entry" | "cwd" | "absolute"
1246
+ basePath: "/custom/base", // Optional custom base path
1247
+ },
1248
+ },
1249
+ });
1250
+ ```
1251
+
1252
+ **Merging behavior:**
1253
+
1254
+ - `log` provides logger configuration (level, prefix, mcpMode)
1255
+ - `logPath` provides flexible path resolution with `relativeTo` options
1256
+ - If both specify a file path, `logPath` takes precedence for path resolution
1257
+ - This preserves the powerful `LogPath` features while using `McpLoggerOptions` for logger settings
1028
1258
 
1029
1259
  #### Path Resolution Options
1030
1260
 
@@ -1043,7 +1273,7 @@ const parser = ArgParser.withMcp({
1043
1273
  },
1044
1274
  });
1045
1275
 
1046
- // Object configuration for advanced use cases
1276
+ // Object configuration for more granular use cases
1047
1277
  const parser = ArgParser.withMcp({
1048
1278
  // ... other config
1049
1279
  mcp: {
@@ -1062,6 +1292,143 @@ const parser = ArgParser.withMcp({
1062
1292
 
1063
1293
  The CLI flag always takes precedence, allowing users to override the developer's programmatic configuration when needed. By default, relative paths resolve relative to the application's entry point, making logs predictably located near DXT packages.
1064
1294
 
1295
+ ### MCP Resources - Real-Time Data Feeds
1296
+
1297
+ MCP Resources enable your CLI tools to provide **real-time, subscription-based data feeds** to AI assistants. Unlike tools (which are called once), resources can be subscribed to and provide live updates when data changes.
1298
+
1299
+ **Key Benefits:**
1300
+
1301
+ - **Real-time notifications**: AI assistants get notified when your data changes
1302
+ - **Flexible URI templates**: Support dynamic parameters like `data://alerts/aged/gte:{threshold}`
1303
+ - **Standard MCP pattern**: Full subscription lifecycle support
1304
+ - **Zero CLI impact**: Resources only work in MCP mode, CLI usage unchanged
1305
+
1306
+ #### Basic Resource Setup
1307
+
1308
+ ```typescript
1309
+ const parser = ArgParser.withMcp({
1310
+ appName: "Data Monitor",
1311
+ appCommandName: "data-monitor",
1312
+ mcp: {
1313
+ serverInfo: { name: "data-monitor", version: "1.0.0" },
1314
+ },
1315
+ }).addMcpResource({
1316
+ name: "recent-data",
1317
+ uriTemplate: "data://recent",
1318
+ title: "Recent Data",
1319
+ description: "Get the most recent data entries",
1320
+ mimeType: "application/json",
1321
+ handler: async (uri) => {
1322
+ const recentData = await getRecentData();
1323
+ return {
1324
+ contents: [
1325
+ {
1326
+ uri: uri.href,
1327
+ text: JSON.stringify(recentData, null, 2),
1328
+ mimeType: "application/json",
1329
+ },
1330
+ ],
1331
+ };
1332
+ },
1333
+ });
1334
+ ```
1335
+
1336
+ #### URI Templates with Dynamic Parameters
1337
+
1338
+ Create flexible resources that accept parameters:
1339
+
1340
+ ```typescript
1341
+ .addMcpResource({
1342
+ name: "aged-data-alert",
1343
+ uriTemplate: "data://alerts/aged/gte:{threshold}",
1344
+ title: "Aged Data Alert",
1345
+ description: "Monitor data that has aged past a threshold (in milliseconds)",
1346
+ handler: async (uri, { threshold }) => {
1347
+ const thresholdMs = parseInt(threshold);
1348
+ const agedData = await getDataOlderThan(new Date(Date.now() - thresholdMs));
1349
+
1350
+ return {
1351
+ contents: [{
1352
+ uri: uri.href,
1353
+ text: JSON.stringify({
1354
+ threshold_ms: thresholdMs,
1355
+ query_time: new Date().toISOString(),
1356
+ aged_data: agedData,
1357
+ count: agedData.length
1358
+ }, null, 2),
1359
+ mimeType: "application/json"
1360
+ }]
1361
+ };
1362
+ }
1363
+ });
1364
+ ```
1365
+
1366
+ #### MCP Subscription Lifecycle
1367
+
1368
+ Resources support the full MCP subscription pattern:
1369
+
1370
+ 1. **Client subscribes**: `resources/subscribe` → `"data://alerts/aged/gte:10000"`
1371
+ 2. **Server monitors**: Your application detects data changes
1372
+ 3. **Server notifies**: `notifications/resources/updated` sent to subscribed clients
1373
+ 4. **Client reads fresh data**: `resources/read` → `"data://alerts/aged/gte:10000"`
1374
+ 5. **Client unsubscribes**: `resources/unsubscribe` when done
1375
+
1376
+ #### Usage Examples
1377
+
1378
+ **AI Assistant Integration:**
1379
+
1380
+ ```typescript
1381
+ // AI assistant can subscribe to real-time data
1382
+ await client.request("resources/subscribe", {
1383
+ uri: "data://alerts/aged/gte:60000", // 1 minute threshold
1384
+ });
1385
+
1386
+ // Handle notifications
1387
+ client.on("notifications/resources/updated", async (notification) => {
1388
+ const response = await client.request("resources/read", {
1389
+ uri: notification.uri,
1390
+ });
1391
+ console.log("Fresh data:", JSON.parse(response.contents[0].text));
1392
+ });
1393
+ ```
1394
+
1395
+ **Command Line Testing:**
1396
+
1397
+ ```bash
1398
+ # Start MCP server
1399
+ data-monitor --s-mcp-serve
1400
+
1401
+ # Test resource (in another terminal)
1402
+ echo '{"jsonrpc":"2.0","id":1,"method":"resources/read","params":{"uri":"data://alerts/aged/gte:10000"}}' | data-monitor --s-mcp-serve
1403
+ ```
1404
+
1405
+ #### Design Patterns
1406
+
1407
+ **Static Resources**: Use simple URIs for data that changes content but not structure
1408
+
1409
+ ```typescript
1410
+ uriTemplate: "logs://recent"; // Always available, content updates
1411
+ uriTemplate: "status://system"; // System status, updates in real-time
1412
+ ```
1413
+
1414
+ **Parameterized Resources**: Use URI templates for flexible filtering
1415
+
1416
+ ```typescript
1417
+ uriTemplate: "data://type/{type}"; // Filter by type
1418
+ uriTemplate: "alerts/{severity}/gte:{age}"; // Multiple parameters
1419
+ uriTemplate: "search/{query}/limit:{count}"; // Search with limits
1420
+ ```
1421
+
1422
+ **Time-Based Resources**: Perfect for monitoring and alerting
1423
+
1424
+ ```typescript
1425
+ uriTemplate: "events/since:{timestamp}"; // Events since timestamp
1426
+ uriTemplate: "metrics/aged/gte:{threshold}"; // Metrics past threshold
1427
+ uriTemplate: "logs/errors/last:{duration}"; // Recent errors
1428
+ ```
1429
+
1430
+ > **💡 Pro Tip**: Resources are perfect for monitoring, alerting, and real-time data feeds. They complement tools (one-time actions) by providing continuous data streams that AI assistants can subscribe to.
1431
+
1065
1432
  ### Automatic Console Safety
1066
1433
 
1067
1434
  A major challenge in MCP is preventing `console.log` from corrupting the JSON-RPC communication over `STDOUT`. ArgParser solves this automatically.
@@ -1082,12 +1449,26 @@ my-cli-app --s-build-dxt ./my-dxt-package
1082
1449
  # A default logo will be applied if you don't provide one.
1083
1450
 
1084
1451
  # 2. (Optional) Pack the folder into a .dxt file for distribution
1452
+ # (you can install the unpacked folder) directly in Claude Desktop > Settings > Extensions > Advanced
1085
1453
  npx @anthropic-ai/dxt pack ./my-dxt-package
1086
1454
 
1087
- # 3. (Optional) Sign the DXT package
1455
+ # 3. (Optional) Sign the DXT package - this has not been well tested yet
1088
1456
  npx @anthropic-ai/dxt sign ./my-dxt-package.dxt
1089
1457
 
1090
1458
  # Then drag & drop the .dxt file into Claude Desktop to install it, in the Settings > Extensions screen.
1459
+
1460
+ # **IMPORTANT**:
1461
+ # If you use ML models or packages that include binaries such as Sqlite3 or sharp, etc...
1462
+ # You need to bundle the node_modules folder with your DXT package
1463
+ # In order to do this, you need to use the following flag:
1464
+ # First hard-install all the packages
1465
+ rm -rf node_moduels
1466
+ pnpm install --prod --linker hoisted
1467
+ # Then bundle with node_modules
1468
+ mycli --s-build-dxt ./my-dxt-package --s-with-node-modules
1469
+ # then build the dxt bundle
1470
+ npx @anthropic-ai/dxt pack ./my-dxt-package
1471
+ # then upload the dxt bundle to Claude Desktop from the settings > extensions > advanced
1091
1472
  ```
1092
1473
 
1093
1474
  ### Logo Configuration
@@ -1130,6 +1511,62 @@ logo: "https://example.com/logo.png"; // Downloaded automatically
1130
1511
  logo: "https://cdn.example.com/icon.svg";
1131
1512
  ```
1132
1513
 
1514
+ ### Including Additional Files in DXT Packages
1515
+
1516
+ You can include additional files and directories in your DXT package using the `dxt.include` configuration. This is useful for bundling database migrations, configuration files, assets, or any other files your MCP server needs at runtime.
1517
+
1518
+ ```typescript
1519
+ const cli = ArgParser.withMcp({
1520
+ appName: "My CLI",
1521
+ appCommandName: "mycli",
1522
+ mcp: {
1523
+ serverInfo: {
1524
+ name: "my-mcp-server",
1525
+ version: "1.0.0",
1526
+ description: "My CLI as an MCP server",
1527
+ },
1528
+ dxt: {
1529
+ include: [
1530
+ "migrations", // Copy entire migrations folder
1531
+ "config/production.json", // Copy specific file
1532
+ { from: "assets/logo.png", to: "logo.png" }, // Copy and rename file
1533
+ { from: "scripts", to: "bin" }, // Copy folder with new name
1534
+ ],
1535
+ },
1536
+ },
1537
+ });
1538
+ ```
1539
+
1540
+ #### Include Options
1541
+
1542
+ **Simple string paths** - Copy files/directories to the same relative location:
1543
+
1544
+ ```typescript
1545
+ include: [
1546
+ "migrations", // Copies ./migrations/ to dxt/migrations/
1547
+ "config/default.json", // Copies ./config/default.json to dxt/config/default.json
1548
+ ];
1549
+ ```
1550
+
1551
+ **Object mapping** - Copy with custom destination paths:
1552
+
1553
+ ```typescript
1554
+ include: [
1555
+ { from: "config/prod.json", to: "config.json" }, // Rename during copy
1556
+ { from: "database/schema", to: "db/schema" }, // Copy to different path
1557
+ ];
1558
+ ```
1559
+
1560
+ **Path Resolution**: All paths in the `from` field are resolved relative to your project root (where `package.json` and `tsconfig.json` are located).
1561
+
1562
+ **Example Use Cases**:
1563
+
1564
+ - Database migration files for initialization
1565
+ - Configuration templates or defaults
1566
+ - Static assets like images or documents
1567
+ - Scripts or utilities needed at runtime
1568
+ - Documentation or help files
1569
+
1133
1570
  ### How DXT Generation Works
1134
1571
 
1135
1572
  When you run `--s-build-dxt`, ArgParser performs several steps to create a self-contained, autonomous package:
@@ -1138,37 +1575,145 @@ When you run `--s-build-dxt`, ArgParser performs several steps to create a self-
1138
1575
  2. **Manifest Generation**: It creates a `manifest.json` file.
1139
1576
  - Tool flags are converted into a JSON Schema for the `input_schema`.
1140
1577
  - 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.
1141
- 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.
1578
+ 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. If you have properly setup your node_modules (via `pnpm install --prod --node-linker=hoisted`) and pass `--s-with-node-nodules` to the bundling process, the resulting DXT will include all necessary dependencies, this is useful for projects that require native dependencies or have complex dependency trees.
1142
1579
  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`.
1143
1580
 
1581
+ ### DXT Bundling Strategies
1582
+
1583
+ ArgParser offers two approaches for handling dependencies in DXT packages, depending on your project's needs.
1584
+
1585
+ #### Standard Approach (Recommended for Most Projects)
1586
+
1587
+ ```bash
1588
+ # For pure JavaScript/TypeScript projects
1589
+ your-cli --s-build-dxt
1590
+ ```
1591
+
1592
+ - **Best for**: Pure JS/TS projects without native dependencies
1593
+ - **Bundle size**: Small (5-10MB typical)
1594
+ - **Build time**: Fast
1595
+ - **Dependencies**: Bundled automatically by TSDown
1596
+
1597
+ #### Native Dependencies Approach
1598
+
1599
+ ```bash
1600
+ # For projects with native binaries (ONNX, Sharp, SQLite, etc.)
1601
+ rm -rf node_modules
1602
+ pnpm install --prod --node-linker=hoisted
1603
+ your-cli --s-build-dxt --s-with-node-modules
1604
+ ```
1605
+
1606
+ - **Best for**: Projects using ONNX Runtime, Sharp, Canvas, SQLite, or other packages with `.node` binaries
1607
+ - **Bundle size**: Larger (50-200MB typical)
1608
+ - **Build time**: Longer (copies entire node_modules)
1609
+ - **Dependencies**: Complete autonomy - no installation needed by Claude
1610
+
1611
+ **When to use `--s-with-node-modules`:**
1612
+
1613
+ - ✅ Your project uses machine learning packages (ONNX Runtime, TensorFlow bindings)
1614
+ - ✅ You need image processing (Sharp, Canvas)
1615
+ - ✅ You use database packages with native binaries (better-sqlite3, sqlite3)
1616
+ - ✅ You want guaranteed compatibility without runtime installation
1617
+ - ✅ Bundle size is acceptable for your use case
1618
+
1619
+ **Required preparation steps:**
1620
+
1621
+ 1. `rm -rf node_modules` - Clean slate for proper structure
1622
+ 2. `pnpm install --prod --node-linker=hoisted` - Creates flat, symlink-free structure
1623
+ 3. Add `--s-with-node-modules` flag to your build command
1624
+
1625
+ The system automatically validates your setup and provides guidance if issues are detected.
1626
+
1627
+ ### Typical Errors
1628
+
1629
+ **Failed to run in Claude Desktop**:
1630
+
1631
+ Claude Desktop is pretty finicky (as of Claude 0.12.28), and the built-in Node.js does not work with extensions built with `--s-with-node-modules` and installed via ArgParser (and I have no idea why because there's no debug info).
1632
+ To resolve this, simply go to `Claude Desktop > Settings > Extensions > Advanced Settings` and turn **OFF** `Use Built-in Node.js for MCP`.
1633
+
1634
+ Note that there are _many_ reasons for extensions not to work, if it does not work with Built-in or System Node.js, then something in your app is wrong. Feel free to join Alcyone Labs' discord for support: [Alcyone Labs' Discord](https://discord.gg/rRHhpz5nS5)
1635
+
1636
+ **Failed to attach to MCP when downloading external assets**
1637
+
1638
+ Sometimes, the MCP client needs to install external files, for example an ML model from HuggingFace or some task that takes more than 10 seconds to run. While it's working, Claude Desktop will display a `Cannot attach to MCP`, simply ignore it, Claude Desktop runs a ping every X seconds, and when it is running a long-running task, the ping will fail, but the task itself will still finish correctly.
1639
+
1640
+ **Failed to generate DXT package**:
1641
+
1642
+ If you encounter the following error running a command such as:
1643
+
1644
+ ```bash
1645
+ rm -rf node_modules
1646
+ pnpm install --prod --node-linker=hoisted
1647
+ bun src/index.ts --s-build-dxt ./dxt --s-with-node-modules
1648
+
1649
+ -- Error generating DXT package: TSDown DXT build failed: EEXIST: file already exists, mkdir
1650
+ ```
1651
+
1652
+ Then run:
1653
+
1654
+ ```bash
1655
+ rm -rf ./dxt
1656
+ bun src/index.ts --s-build-dxt ./dxt --s-with-node-modules
1657
+ ```
1658
+
1659
+ And it should work. TSDown is tasked to clean the outputDir first, but it won't if some files have been manually changed.
1660
+
1144
1661
  ---
1145
1662
 
1146
1663
  ## System Flags & Configuration
1147
1664
 
1148
1665
  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.
1149
1666
 
1150
- | Flag | Description |
1151
- | --------------------------- | --------------------------------------------------------------------------------------------------- |
1152
- | **MCP & DXT** | |
1153
- | `--s-mcp-serve` | Starts the application in MCP server mode, exposing all tools. |
1154
- | `--s-build-dxt [dir]` | Generates a complete, autonomous DXT package for Claude Desktop in the specified directory. |
1155
- | `--s-mcp-transport <type>` | Overrides the MCP transport (`stdio`, `sse`, `streamable-http`). |
1156
- | `--s-mcp-transports <json>` | Overrides transports with a JSON array for multi-transport setups. |
1157
- | `--s-mcp-port <number>` | Sets the port for HTTP-based transports (`sse`, `streamable-http`). |
1158
- | `--s-mcp-host <string>` | Sets the host address for HTTP-based transports. |
1159
- | `--s-mcp-log-path <path>` | Sets the file path for MCP server logs (default: `./logs/mcp.log`). Overrides programmatic setting. |
1160
- | **Configuration** | |
1161
- | `--s-with-env <file>` | Loads configuration from a file (`.env`, `.json`, `.yaml`, `.toml`). CLI args take precedence. |
1162
- | `--s-save-to-env <file>` | Saves the current arguments to a configuration file, perfect for templates. |
1163
- | **Debugging** | |
1164
- | `--s-debug` | Prints a detailed, step-by-step log of the argument parsing process. |
1165
- | `--s-debug-print` | Exports the entire parser configuration to a JSON file for inspection. |
1166
- | `--s-enable-fuzzy` | Enables fuzzy testing mode—a dry run that parses args but skips handler execution. |
1667
+ | Flag | Description |
1668
+ | --------------------------- | -------------------------------------------------------------------------------------------------------------- |
1669
+ | **MCP & DXT** | |
1670
+ | `--s-mcp-serve` | Starts the application in MCP server mode, exposing all tools. |
1671
+ | `--s-build-dxt [dir]` | Generates a complete, autonomous DXT package for Claude Desktop in the specified directory. |
1672
+ | `--s-with-node-modules` | Use with `--s-build-dxt`. Includes complete node_modules in DXT package for projects with native dependencies. |
1673
+ | `--s-mcp-transport <type>` | Overrides the MCP transport (`stdio`, `sse`, `streamable-http`). |
1674
+ | `--s-mcp-transports <json>` | Overrides transports with a JSON array for multi-transport setups. |
1675
+ | `--s-mcp-port <number>` | Sets the port for HTTP-based transports (`sse`, `streamable-http`). |
1676
+ | `--s-mcp-host <string>` | Sets the host address for HTTP-based transports. |
1677
+ | `--s-mcp-log-path <path>` | Sets the file path for MCP server logs (default: `./logs/mcp.log`). Overrides programmatic setting. |
1678
+ | **Configuration** | |
1679
+ | `--s-with-env <file>` | Loads configuration from a file (`.env`, `.json`, `.yaml`, `.toml`). CLI args take precedence. |
1680
+ | `--s-save-to-env <file>` | Saves the current arguments to a configuration file, perfect for templates. |
1681
+ | **Debugging** | |
1682
+ | `--s-debug` | Prints a detailed, step-by-step log of the argument parsing process. |
1683
+ | `--s-debug-print` | Exports the entire parser configuration to a JSON file for inspection. |
1684
+ | `--s-enable-fuzzy` | Enables fuzzy testing mode—a dry run that parses args but skips handler execution. |
1167
1685
 
1168
1686
  ---
1169
1687
 
1170
1688
  ## Changelog
1171
1689
 
1690
+ ### v2.4.0
1691
+
1692
+ **Feat**
1693
+
1694
+ - MCP client now supports initialization during the client 'initialize' call, which allows to do certain things such as establishing database connection or even running migrations
1695
+ - MCP client now sanitizes the method names to ensure spec-compliants MCP behavior, names that collision will be logged
1696
+ - There were some use-cases where the DXT bundling failed, this new release addresses all of them, namely:
1697
+ 1. Output structure will match that of the input so relative files (for example DB migrations) will work
1698
+ 2.
1699
+ - DXT bundling now supports including resources via options: `{dxt: {include: ['TSDown blob-like paths']}`
1700
+ - Logger was improved to support log level via `options:{ log: {} }` so you can set it to level: 'debug' and the MCP log will contain 100% of the console output, logPath setting was not impacted
1701
+
1702
+ **Fixes and Changes**
1703
+
1704
+ - Zod has been upgraded to V4 and no issue was identified (but @modelcontextprotocol/sdk had to be upgraded to V4 as well, which was more challenging).
1705
+
1706
+ ### v2.3.0
1707
+
1708
+ The DXT bundling is working pretty well now, and we have had a lot of success building, bundling and running various extensions. If you see issues, feel free to open an Issue on GitHub with details, or ask about it on [Alcyone Labs' Discord](https://discord.gg/rRHhpz5nS5)
1709
+
1710
+ Make sure to clearly identify if you need to include the node_modules or not. In doubt, include them using `--s-with-node-modules`
1711
+
1712
+ **Feat**
1713
+
1714
+ - **New `--s-with-node-modules` flag**: Create fully autonomous DXT packages that include complete native dependencies. Perfect for projects using ONNX Runtime, Sharp, SQLite, or other packages with `.node` binaries. Use `rm -rf ./node_modules && pnpm install --prod --node-linker=hoisted` followed by `my-cli --s-build-dxt ./dxt --s-with-node-modules` to create self-contained packages that work without Claude needing to install dependencies.
1715
+ Note that when bundling with node_modules, it's likely that the built-in Node.js will not work with that extension, so go to `Claude Desktop > Settings > Extensions > Advanced Settings` and turn **OFF** `Use Built-in Node.js for MCP`.
1716
+
1172
1717
  ### v2.2.1
1173
1718
 
1174
1719
  **Feat**
@@ -1241,11 +1786,11 @@ ArgParser includes built-in `--s-*` flags for development, debugging, and config
1241
1786
  - [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)
1242
1787
  - [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)
1243
1788
  - [x] Add support for async type function to enable more flexibility
1789
+ - [x] Upgrade to Zod/V4 (V4 does not support functions well, this will take more time, not a priority)
1244
1790
  - [ ] Add System flags to args.systemArgs
1245
1791
  - [ ] Improve flag options collision prevention
1246
1792
  - [ ] Add support for locales / translations
1247
1793
  - [ ] (potentially) add support for fully typed parsed output, this has proven very challenging
1248
- - [ ] Upgrade to Zod/V4 (V4 does not support functions well, this will take more time, not a priority)
1249
1794
 
1250
1795
  ### (known) Bugs / DX improvement points
1251
1796