@agiflowai/one-mcp 0.2.7 → 0.3.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 +34 -0
- package/dist/cli.cjs +474 -11
- package/dist/cli.mjs +475 -12
- package/dist/{http-B4NAfsQl.cjs → http-BYBRKvD4.cjs} +12 -1
- package/dist/{http-DSkkpGJU.mjs → http-Bi2N9PUM.mjs} +12 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +4 -0
- package/dist/index.d.mts +4 -0
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -128,6 +128,12 @@ mcpServers:
|
|
|
128
128
|
command: node
|
|
129
129
|
args: ["server.js"]
|
|
130
130
|
disabled: true
|
|
131
|
+
|
|
132
|
+
# Custom timeout for slow servers
|
|
133
|
+
slow-server:
|
|
134
|
+
command: npx
|
|
135
|
+
args: ["-y", "@heavy/mcp-package"]
|
|
136
|
+
timeout: 60000 # 60 seconds (default: 30000)
|
|
131
137
|
```
|
|
132
138
|
|
|
133
139
|
### Environment Variables
|
|
@@ -414,6 +420,9 @@ npx @agiflowai/one-mcp mcp-serve --config ./mcp-config.yaml --type http --port 3
|
|
|
414
420
|
# Initialize config file
|
|
415
421
|
npx @agiflowai/one-mcp init --output mcp-config.yaml
|
|
416
422
|
|
|
423
|
+
# Pre-download packages for faster startup
|
|
424
|
+
npx @agiflowai/one-mcp prefetch --config ./mcp-config.yaml
|
|
425
|
+
|
|
417
426
|
# List all tools from configured servers
|
|
418
427
|
npx @agiflowai/one-mcp list-tools --config ./mcp-config.yaml
|
|
419
428
|
|
|
@@ -424,6 +433,31 @@ npx @agiflowai/one-mcp describe-tools --config ./mcp-config.yaml --tools read_fi
|
|
|
424
433
|
npx @agiflowai/one-mcp use-tool --config ./mcp-config.yaml --tool-name read_file --args '{"path": "/tmp/test.txt"}'
|
|
425
434
|
```
|
|
426
435
|
|
|
436
|
+
### Prefetch Command
|
|
437
|
+
|
|
438
|
+
Pre-download packages used by MCP servers (npx, pnpx, uvx, uv) to speed up initial connections:
|
|
439
|
+
|
|
440
|
+
```bash
|
|
441
|
+
# Prefetch all packages
|
|
442
|
+
npx @agiflowai/one-mcp prefetch --config ./mcp-config.yaml
|
|
443
|
+
|
|
444
|
+
# Dry run - see what would be prefetched
|
|
445
|
+
npx @agiflowai/one-mcp prefetch --config ./mcp-config.yaml --dry-run
|
|
446
|
+
|
|
447
|
+
# Run prefetch in parallel (faster)
|
|
448
|
+
npx @agiflowai/one-mcp prefetch --config ./mcp-config.yaml --parallel
|
|
449
|
+
|
|
450
|
+
# Filter by package manager
|
|
451
|
+
npx @agiflowai/one-mcp prefetch --config ./mcp-config.yaml --filter npx
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
| Option | Description |
|
|
455
|
+
|--------|-------------|
|
|
456
|
+
| `-c, --config` | Path to config file |
|
|
457
|
+
| `-p, --parallel` | Run prefetch commands in parallel |
|
|
458
|
+
| `-d, --dry-run` | Show what would be prefetched without executing |
|
|
459
|
+
| `-f, --filter` | Filter by package manager: `npx`, `pnpx`, `uvx`, or `uv` |
|
|
460
|
+
|
|
427
461
|
### Server Options
|
|
428
462
|
|
|
429
463
|
| Option | Description | Default |
|
package/dist/cli.cjs
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const require_http = require('./http-
|
|
2
|
+
const require_http = require('./http-BYBRKvD4.cjs');
|
|
3
3
|
let node_fs_promises = require("node:fs/promises");
|
|
4
4
|
let node_path = require("node:path");
|
|
5
5
|
let liquidjs = require("liquidjs");
|
|
6
6
|
let commander = require("commander");
|
|
7
7
|
let __agiflowai_aicode_utils = require("@agiflowai/aicode-utils");
|
|
8
|
+
let node_child_process = require("node:child_process");
|
|
8
9
|
|
|
9
10
|
//#region src/types/index.ts
|
|
10
11
|
/**
|
|
@@ -546,9 +547,462 @@ const initCommand = new commander.Command("init").description("Initialize MCP co
|
|
|
546
547
|
}
|
|
547
548
|
});
|
|
548
549
|
|
|
550
|
+
//#endregion
|
|
551
|
+
//#region src/services/PrefetchService/constants.ts
|
|
552
|
+
/**
|
|
553
|
+
* PrefetchService Constants
|
|
554
|
+
*
|
|
555
|
+
* Constants for package manager commands and process configuration.
|
|
556
|
+
*/
|
|
557
|
+
/** Transport type for stdio-based MCP servers */
|
|
558
|
+
const TRANSPORT_STDIO = "stdio";
|
|
559
|
+
/** npx command name */
|
|
560
|
+
const COMMAND_NPX = "npx";
|
|
561
|
+
/** npm command name */
|
|
562
|
+
const COMMAND_NPM = "npm";
|
|
563
|
+
/** pnpx command name (pnpm's npx equivalent) */
|
|
564
|
+
const COMMAND_PNPX = "pnpx";
|
|
565
|
+
/** pnpm command name */
|
|
566
|
+
const COMMAND_PNPM = "pnpm";
|
|
567
|
+
/** uvx command name */
|
|
568
|
+
const COMMAND_UVX = "uvx";
|
|
569
|
+
/** uv command name */
|
|
570
|
+
const COMMAND_UV = "uv";
|
|
571
|
+
/** Path suffix for npx command */
|
|
572
|
+
const COMMAND_NPX_SUFFIX = "/npx";
|
|
573
|
+
/** Path suffix for pnpx command */
|
|
574
|
+
const COMMAND_PNPX_SUFFIX = "/pnpx";
|
|
575
|
+
/** Path suffix for uvx command */
|
|
576
|
+
const COMMAND_UVX_SUFFIX = "/uvx";
|
|
577
|
+
/** Path suffix for uv command */
|
|
578
|
+
const COMMAND_UV_SUFFIX = "/uv";
|
|
579
|
+
/** Run subcommand for uv */
|
|
580
|
+
const ARG_RUN = "run";
|
|
581
|
+
/** Tool subcommand for uv */
|
|
582
|
+
const ARG_TOOL = "tool";
|
|
583
|
+
/** Install subcommand for uv tool and npm/pnpm */
|
|
584
|
+
const ARG_INSTALL = "install";
|
|
585
|
+
/** Add subcommand for pnpm */
|
|
586
|
+
const ARG_ADD = "add";
|
|
587
|
+
/** Global flag for npm/pnpm install */
|
|
588
|
+
const ARG_GLOBAL = "-g";
|
|
589
|
+
/** Flag prefix for command arguments */
|
|
590
|
+
const FLAG_PREFIX = "-";
|
|
591
|
+
/** npx --package flag (long form) */
|
|
592
|
+
const FLAG_PACKAGE_LONG = "--package";
|
|
593
|
+
/** npx -p flag (short form) */
|
|
594
|
+
const FLAG_PACKAGE_SHORT = "-p";
|
|
595
|
+
/** Equals delimiter used in flag=value patterns */
|
|
596
|
+
const EQUALS_DELIMITER = "=";
|
|
597
|
+
/**
|
|
598
|
+
* Regex pattern for valid package names (npm, pnpm, uvx, uv)
|
|
599
|
+
* Allows: @scope/package-name@version, package-name, package_name
|
|
600
|
+
* Prevents shell metacharacters that could enable command injection
|
|
601
|
+
* @example
|
|
602
|
+
* // Valid: '@scope/package@1.0.0', 'my-package', 'my_package', '@org/pkg'
|
|
603
|
+
* // Invalid: 'pkg; rm -rf /', 'pkg$(cmd)', 'pkg`whoami`', 'pkg|cat /etc/passwd'
|
|
604
|
+
*/
|
|
605
|
+
const VALID_PACKAGE_NAME_PATTERN = /^(@[a-zA-Z0-9_-]+\/)?[a-zA-Z0-9._-]+(@[a-zA-Z0-9._-]+)?$/;
|
|
606
|
+
/** Windows platform identifier */
|
|
607
|
+
const PLATFORM_WIN32 = "win32";
|
|
608
|
+
/** Success exit code */
|
|
609
|
+
const EXIT_CODE_SUCCESS = 0;
|
|
610
|
+
/** Stdio option to ignore stream */
|
|
611
|
+
const STDIO_IGNORE = "ignore";
|
|
612
|
+
/** Stdio option to pipe stream */
|
|
613
|
+
const STDIO_PIPE = "pipe";
|
|
614
|
+
|
|
615
|
+
//#endregion
|
|
616
|
+
//#region src/services/PrefetchService/PrefetchService.ts
|
|
617
|
+
/**
|
|
618
|
+
* PrefetchService
|
|
619
|
+
*
|
|
620
|
+
* DESIGN PATTERNS:
|
|
621
|
+
* - Service pattern for business logic encapsulation
|
|
622
|
+
* - Single responsibility principle
|
|
623
|
+
*
|
|
624
|
+
* CODING STANDARDS:
|
|
625
|
+
* - Use async/await for asynchronous operations
|
|
626
|
+
* - Throw descriptive errors for error cases
|
|
627
|
+
* - Keep methods focused and well-named
|
|
628
|
+
* - Document complex logic with comments
|
|
629
|
+
*
|
|
630
|
+
* AVOID:
|
|
631
|
+
* - Mixing concerns (keep focused on single domain)
|
|
632
|
+
* - Direct tool implementation (services should be tool-agnostic)
|
|
633
|
+
*/
|
|
634
|
+
/**
|
|
635
|
+
* Type guard to check if a config object is an McpStdioConfig
|
|
636
|
+
* @param config - Config object to check
|
|
637
|
+
* @returns True if config has required McpStdioConfig properties
|
|
638
|
+
*/
|
|
639
|
+
function isMcpStdioConfig(config) {
|
|
640
|
+
return typeof config === "object" && config !== null && "command" in config;
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* PrefetchService handles pre-downloading packages used by MCP servers.
|
|
644
|
+
* Supports npx (Node.js), uvx (Python/uv), and uv run commands.
|
|
645
|
+
*
|
|
646
|
+
* @example
|
|
647
|
+
* ```typescript
|
|
648
|
+
* const service = new PrefetchService({
|
|
649
|
+
* mcpConfig: await configFetcher.fetchConfiguration(),
|
|
650
|
+
* parallel: true,
|
|
651
|
+
* });
|
|
652
|
+
* const packages = service.extractPackages();
|
|
653
|
+
* const summary = await service.prefetch();
|
|
654
|
+
* ```
|
|
655
|
+
*/
|
|
656
|
+
var PrefetchService = class {
|
|
657
|
+
config;
|
|
658
|
+
/**
|
|
659
|
+
* Creates a new PrefetchService instance
|
|
660
|
+
* @param config - Service configuration options
|
|
661
|
+
*/
|
|
662
|
+
constructor(config) {
|
|
663
|
+
this.config = config;
|
|
664
|
+
}
|
|
665
|
+
/**
|
|
666
|
+
* Extract all prefetchable packages from the MCP configuration
|
|
667
|
+
* @returns Array of package info objects
|
|
668
|
+
*/
|
|
669
|
+
extractPackages() {
|
|
670
|
+
const packages = [];
|
|
671
|
+
const { mcpConfig, filter } = this.config;
|
|
672
|
+
for (const [serverName, serverConfig] of Object.entries(mcpConfig.mcpServers)) {
|
|
673
|
+
if (serverConfig.disabled) continue;
|
|
674
|
+
if (serverConfig.transport !== TRANSPORT_STDIO) continue;
|
|
675
|
+
if (!isMcpStdioConfig(serverConfig.config)) continue;
|
|
676
|
+
const packageInfo = this.extractPackageInfo(serverName, serverConfig.config);
|
|
677
|
+
if (packageInfo) {
|
|
678
|
+
if (filter && packageInfo.packageManager !== filter) continue;
|
|
679
|
+
packages.push(packageInfo);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
return packages;
|
|
683
|
+
}
|
|
684
|
+
/**
|
|
685
|
+
* Prefetch all packages from the configuration
|
|
686
|
+
* @returns Summary of prefetch results
|
|
687
|
+
* @throws Error if prefetch operation fails unexpectedly
|
|
688
|
+
*/
|
|
689
|
+
async prefetch() {
|
|
690
|
+
try {
|
|
691
|
+
const packages = this.extractPackages();
|
|
692
|
+
const results = [];
|
|
693
|
+
if (packages.length === 0) return {
|
|
694
|
+
totalPackages: 0,
|
|
695
|
+
successful: 0,
|
|
696
|
+
failed: 0,
|
|
697
|
+
results: []
|
|
698
|
+
};
|
|
699
|
+
if (this.config.parallel) {
|
|
700
|
+
const promises = packages.map(async (pkg) => this.prefetchPackage(pkg));
|
|
701
|
+
results.push(...await Promise.all(promises));
|
|
702
|
+
} else for (const pkg of packages) {
|
|
703
|
+
const result = await this.prefetchPackage(pkg);
|
|
704
|
+
results.push(result);
|
|
705
|
+
}
|
|
706
|
+
const successful = results.filter((r) => r.success).length;
|
|
707
|
+
const failed = results.filter((r) => !r.success).length;
|
|
708
|
+
return {
|
|
709
|
+
totalPackages: packages.length,
|
|
710
|
+
successful,
|
|
711
|
+
failed,
|
|
712
|
+
results
|
|
713
|
+
};
|
|
714
|
+
} catch (error) {
|
|
715
|
+
throw new Error(`Failed to prefetch packages: ${error instanceof Error ? error.message : String(error)}`);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Prefetch a single package
|
|
720
|
+
* @param pkg - Package info to prefetch
|
|
721
|
+
* @returns Result of the prefetch operation
|
|
722
|
+
*/
|
|
723
|
+
async prefetchPackage(pkg) {
|
|
724
|
+
try {
|
|
725
|
+
const [command, ...args] = pkg.fullCommand;
|
|
726
|
+
const result = await this.runCommand(command, args);
|
|
727
|
+
return {
|
|
728
|
+
package: pkg,
|
|
729
|
+
success: result.success,
|
|
730
|
+
output: result.output
|
|
731
|
+
};
|
|
732
|
+
} catch (error) {
|
|
733
|
+
return {
|
|
734
|
+
package: pkg,
|
|
735
|
+
success: false,
|
|
736
|
+
output: error instanceof Error ? error.message : String(error)
|
|
737
|
+
};
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
/**
|
|
741
|
+
* Validate package name to prevent command injection
|
|
742
|
+
* @param packageName - Package name to validate
|
|
743
|
+
* @returns True if package name is safe, false otherwise
|
|
744
|
+
* @remarks Rejects package names containing shell metacharacters
|
|
745
|
+
* @example
|
|
746
|
+
* isValidPackageName('@scope/package') // true
|
|
747
|
+
* isValidPackageName('my-package@1.0.0') // true
|
|
748
|
+
* isValidPackageName('pkg; rm -rf /') // false (shell injection)
|
|
749
|
+
* isValidPackageName('pkg$(whoami)') // false (command substitution)
|
|
750
|
+
*/
|
|
751
|
+
isValidPackageName(packageName) {
|
|
752
|
+
return VALID_PACKAGE_NAME_PATTERN.test(packageName);
|
|
753
|
+
}
|
|
754
|
+
/**
|
|
755
|
+
* Extract package info from a server's stdio config
|
|
756
|
+
* @param serverName - Name of the MCP server
|
|
757
|
+
* @param config - Stdio configuration for the server
|
|
758
|
+
* @returns Package info if extractable, null otherwise
|
|
759
|
+
*/
|
|
760
|
+
extractPackageInfo(serverName, config) {
|
|
761
|
+
const command = config.command.toLowerCase();
|
|
762
|
+
const args = config.args || [];
|
|
763
|
+
if (command === COMMAND_NPX || command.endsWith(COMMAND_NPX_SUFFIX)) {
|
|
764
|
+
const packageName = this.extractNpxPackage(args);
|
|
765
|
+
if (packageName && this.isValidPackageName(packageName)) return {
|
|
766
|
+
serverName,
|
|
767
|
+
packageManager: COMMAND_NPX,
|
|
768
|
+
packageName,
|
|
769
|
+
fullCommand: [
|
|
770
|
+
COMMAND_NPM,
|
|
771
|
+
ARG_INSTALL,
|
|
772
|
+
ARG_GLOBAL,
|
|
773
|
+
packageName
|
|
774
|
+
]
|
|
775
|
+
};
|
|
776
|
+
}
|
|
777
|
+
if (command === COMMAND_PNPX || command.endsWith(COMMAND_PNPX_SUFFIX)) {
|
|
778
|
+
const packageName = this.extractNpxPackage(args);
|
|
779
|
+
if (packageName && this.isValidPackageName(packageName)) return {
|
|
780
|
+
serverName,
|
|
781
|
+
packageManager: COMMAND_PNPX,
|
|
782
|
+
packageName,
|
|
783
|
+
fullCommand: [
|
|
784
|
+
COMMAND_PNPM,
|
|
785
|
+
ARG_ADD,
|
|
786
|
+
ARG_GLOBAL,
|
|
787
|
+
packageName
|
|
788
|
+
]
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
if (command === COMMAND_UVX || command.endsWith(COMMAND_UVX_SUFFIX)) {
|
|
792
|
+
const packageName = this.extractUvxPackage(args);
|
|
793
|
+
if (packageName && this.isValidPackageName(packageName)) return {
|
|
794
|
+
serverName,
|
|
795
|
+
packageManager: COMMAND_UVX,
|
|
796
|
+
packageName,
|
|
797
|
+
fullCommand: [COMMAND_UVX, packageName]
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
if ((command === COMMAND_UV || command.endsWith(COMMAND_UV_SUFFIX)) && args.includes(ARG_RUN)) {
|
|
801
|
+
const packageName = this.extractUvRunPackage(args);
|
|
802
|
+
if (packageName && this.isValidPackageName(packageName)) return {
|
|
803
|
+
serverName,
|
|
804
|
+
packageManager: COMMAND_UV,
|
|
805
|
+
packageName,
|
|
806
|
+
fullCommand: [
|
|
807
|
+
COMMAND_UV,
|
|
808
|
+
ARG_TOOL,
|
|
809
|
+
ARG_INSTALL,
|
|
810
|
+
packageName
|
|
811
|
+
]
|
|
812
|
+
};
|
|
813
|
+
}
|
|
814
|
+
return null;
|
|
815
|
+
}
|
|
816
|
+
/**
|
|
817
|
+
* Extract package name from npx command args
|
|
818
|
+
* @param args - Command arguments
|
|
819
|
+
* @returns Package name or null
|
|
820
|
+
* @remarks Handles --package=value, --package value, -p value patterns.
|
|
821
|
+
* Falls back to first non-flag argument if no --package/-p flag found.
|
|
822
|
+
* Returns null if flag has no value or is followed by another flag.
|
|
823
|
+
* When multiple --package flags exist, returns the first valid one.
|
|
824
|
+
* @example
|
|
825
|
+
* extractNpxPackage(['--package=@scope/pkg']) // returns '@scope/pkg'
|
|
826
|
+
* extractNpxPackage(['--package', 'pkg-name']) // returns 'pkg-name'
|
|
827
|
+
* extractNpxPackage(['-p', 'pkg']) // returns 'pkg'
|
|
828
|
+
* extractNpxPackage(['-y', 'pkg-name', '--flag']) // returns 'pkg-name' (fallback)
|
|
829
|
+
* extractNpxPackage(['--package=']) // returns null (empty value)
|
|
830
|
+
*/
|
|
831
|
+
extractNpxPackage(args) {
|
|
832
|
+
for (let i = 0; i < args.length; i++) {
|
|
833
|
+
const arg = args[i];
|
|
834
|
+
if (arg.startsWith(FLAG_PACKAGE_LONG + EQUALS_DELIMITER)) return arg.slice(FLAG_PACKAGE_LONG.length + EQUALS_DELIMITER.length) || null;
|
|
835
|
+
if (arg === FLAG_PACKAGE_LONG && i + 1 < args.length) {
|
|
836
|
+
const nextArg = args[i + 1];
|
|
837
|
+
if (!nextArg.startsWith(FLAG_PREFIX)) return nextArg;
|
|
838
|
+
}
|
|
839
|
+
if (arg === FLAG_PACKAGE_SHORT && i + 1 < args.length) {
|
|
840
|
+
const nextArg = args[i + 1];
|
|
841
|
+
if (!nextArg.startsWith(FLAG_PREFIX)) return nextArg;
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
for (const arg of args) {
|
|
845
|
+
if (arg.startsWith(FLAG_PREFIX)) continue;
|
|
846
|
+
return arg;
|
|
847
|
+
}
|
|
848
|
+
return null;
|
|
849
|
+
}
|
|
850
|
+
/**
|
|
851
|
+
* Extract package name from uvx command args
|
|
852
|
+
* @param args - Command arguments
|
|
853
|
+
* @returns Package name or null
|
|
854
|
+
* @remarks Assumes the first non-flag argument is the package name.
|
|
855
|
+
* Handles both single (-) and double (--) dash flags.
|
|
856
|
+
* @example
|
|
857
|
+
* extractUvxPackage(['mcp-server-fetch']) // returns 'mcp-server-fetch'
|
|
858
|
+
* extractUvxPackage(['--quiet', 'pkg-name']) // returns 'pkg-name'
|
|
859
|
+
*/
|
|
860
|
+
extractUvxPackage(args) {
|
|
861
|
+
for (const arg of args) {
|
|
862
|
+
if (arg.startsWith(FLAG_PREFIX)) continue;
|
|
863
|
+
return arg;
|
|
864
|
+
}
|
|
865
|
+
return null;
|
|
866
|
+
}
|
|
867
|
+
/**
|
|
868
|
+
* Extract package name from uv run command args
|
|
869
|
+
* @param args - Command arguments
|
|
870
|
+
* @returns Package name or null
|
|
871
|
+
* @remarks Looks for the first non-flag argument after the 'run' subcommand.
|
|
872
|
+
* Returns null if 'run' is not found in args.
|
|
873
|
+
* @example
|
|
874
|
+
* extractUvRunPackage(['run', 'mcp-server']) // returns 'mcp-server'
|
|
875
|
+
* extractUvRunPackage(['run', '--verbose', 'pkg']) // returns 'pkg'
|
|
876
|
+
* extractUvRunPackage(['install', 'pkg']) // returns null (no 'run')
|
|
877
|
+
*/
|
|
878
|
+
extractUvRunPackage(args) {
|
|
879
|
+
const runIndex = args.indexOf(ARG_RUN);
|
|
880
|
+
if (runIndex === -1) return null;
|
|
881
|
+
for (let i = runIndex + 1; i < args.length; i++) {
|
|
882
|
+
const arg = args[i];
|
|
883
|
+
if (arg.startsWith(FLAG_PREFIX)) continue;
|
|
884
|
+
return arg;
|
|
885
|
+
}
|
|
886
|
+
return null;
|
|
887
|
+
}
|
|
888
|
+
/**
|
|
889
|
+
* Run a shell command and capture output
|
|
890
|
+
* @param command - Command to run
|
|
891
|
+
* @param args - Command arguments
|
|
892
|
+
* @returns Promise with success status and output
|
|
893
|
+
*/
|
|
894
|
+
runCommand(command, args) {
|
|
895
|
+
return new Promise((resolve$1) => {
|
|
896
|
+
const proc = (0, node_child_process.spawn)(command, args, {
|
|
897
|
+
stdio: [
|
|
898
|
+
STDIO_IGNORE,
|
|
899
|
+
STDIO_PIPE,
|
|
900
|
+
STDIO_PIPE
|
|
901
|
+
],
|
|
902
|
+
shell: process.platform === PLATFORM_WIN32
|
|
903
|
+
});
|
|
904
|
+
let stdout = "";
|
|
905
|
+
let stderr = "";
|
|
906
|
+
proc.stdout?.on("data", (data) => {
|
|
907
|
+
stdout += data.toString();
|
|
908
|
+
});
|
|
909
|
+
proc.stderr?.on("data", (data) => {
|
|
910
|
+
stderr += data.toString();
|
|
911
|
+
});
|
|
912
|
+
proc.on("close", (code) => {
|
|
913
|
+
resolve$1({
|
|
914
|
+
success: code === EXIT_CODE_SUCCESS,
|
|
915
|
+
output: stdout || stderr
|
|
916
|
+
});
|
|
917
|
+
});
|
|
918
|
+
proc.on("error", (error) => {
|
|
919
|
+
resolve$1({
|
|
920
|
+
success: false,
|
|
921
|
+
output: error.message
|
|
922
|
+
});
|
|
923
|
+
});
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
};
|
|
927
|
+
|
|
928
|
+
//#endregion
|
|
929
|
+
//#region src/commands/prefetch.ts
|
|
930
|
+
/**
|
|
931
|
+
* Prefetch Command
|
|
932
|
+
*
|
|
933
|
+
* DESIGN PATTERNS:
|
|
934
|
+
* - Command pattern with Commander for CLI argument parsing
|
|
935
|
+
* - Async/await pattern for asynchronous operations
|
|
936
|
+
* - Error handling pattern with try-catch and proper exit codes
|
|
937
|
+
*
|
|
938
|
+
* CODING STANDARDS:
|
|
939
|
+
* - Use async action handlers for asynchronous operations
|
|
940
|
+
* - Provide clear option descriptions and default values
|
|
941
|
+
* - Handle errors gracefully with process.exit()
|
|
942
|
+
* - Log progress and errors to console
|
|
943
|
+
* - Use Commander's .option() and .argument() for inputs
|
|
944
|
+
*
|
|
945
|
+
* AVOID:
|
|
946
|
+
* - Synchronous blocking operations in action handlers
|
|
947
|
+
* - Missing error handling (always use try-catch)
|
|
948
|
+
* - Hardcoded values (use options or environment variables)
|
|
949
|
+
* - Not exiting with appropriate exit codes on errors
|
|
950
|
+
*/
|
|
951
|
+
/**
|
|
952
|
+
* Pre-download packages used by MCP servers (npx, pnpx, uvx, uv)
|
|
953
|
+
*/
|
|
954
|
+
const prefetchCommand = new commander.Command("prefetch").description("Pre-download packages used by MCP servers (npx, pnpx, uvx, uv)").option("-c, --config <path>", "Path to MCP server configuration file").option("-p, --parallel", "Run prefetch commands in parallel", false).option("-d, --dry-run", "Show what would be prefetched without executing", false).option("-f, --filter <type>", "Filter by package manager type: npx, pnpx, uvx, or uv").action(async (options) => {
|
|
955
|
+
try {
|
|
956
|
+
const configFilePath = options.config || require_http.findConfigFile();
|
|
957
|
+
if (!configFilePath) {
|
|
958
|
+
__agiflowai_aicode_utils.print.error("No MCP configuration file found.");
|
|
959
|
+
__agiflowai_aicode_utils.print.info("Use --config <path> to specify a config file, or run \"one-mcp init\" to create one.");
|
|
960
|
+
process.exit(1);
|
|
961
|
+
}
|
|
962
|
+
__agiflowai_aicode_utils.print.info(`Loading configuration from: ${configFilePath}`);
|
|
963
|
+
const prefetchService = new PrefetchService({
|
|
964
|
+
mcpConfig: await new require_http.ConfigFetcherService({
|
|
965
|
+
configFilePath,
|
|
966
|
+
useCache: false
|
|
967
|
+
}).fetchConfiguration(true),
|
|
968
|
+
filter: options.filter,
|
|
969
|
+
parallel: options.parallel
|
|
970
|
+
});
|
|
971
|
+
const packages = prefetchService.extractPackages();
|
|
972
|
+
if (packages.length === 0) {
|
|
973
|
+
__agiflowai_aicode_utils.print.warning("No packages found to prefetch.");
|
|
974
|
+
__agiflowai_aicode_utils.print.info("Prefetch supports: npx, pnpx, uvx, and uv run commands");
|
|
975
|
+
return;
|
|
976
|
+
}
|
|
977
|
+
__agiflowai_aicode_utils.print.info(`Found ${packages.length} package(s) to prefetch:`);
|
|
978
|
+
for (const pkg of packages) __agiflowai_aicode_utils.print.item(`${pkg.serverName}: ${pkg.packageManager} ${pkg.packageName}`);
|
|
979
|
+
if (options.dryRun) {
|
|
980
|
+
__agiflowai_aicode_utils.print.newline();
|
|
981
|
+
__agiflowai_aicode_utils.print.header("Dry run mode - commands that would be executed:");
|
|
982
|
+
for (const pkg of packages) __agiflowai_aicode_utils.print.indent(pkg.fullCommand.join(" "));
|
|
983
|
+
return;
|
|
984
|
+
}
|
|
985
|
+
__agiflowai_aicode_utils.print.newline();
|
|
986
|
+
__agiflowai_aicode_utils.print.info("Prefetching packages...");
|
|
987
|
+
const summary = await prefetchService.prefetch();
|
|
988
|
+
__agiflowai_aicode_utils.print.newline();
|
|
989
|
+
if (summary.failed === 0) __agiflowai_aicode_utils.print.success(`Prefetch complete: ${summary.successful} succeeded, ${summary.failed} failed`);
|
|
990
|
+
else __agiflowai_aicode_utils.print.warning(`Prefetch complete: ${summary.successful} succeeded, ${summary.failed} failed`);
|
|
991
|
+
if (summary.failed > 0) {
|
|
992
|
+
__agiflowai_aicode_utils.print.newline();
|
|
993
|
+
__agiflowai_aicode_utils.print.error("Failed packages:");
|
|
994
|
+
for (const result of summary.results.filter((r) => !r.success)) __agiflowai_aicode_utils.print.item(`${result.package.serverName} (${result.package.packageName}): ${result.output.trim()}`);
|
|
995
|
+
process.exit(1);
|
|
996
|
+
}
|
|
997
|
+
} catch (error) {
|
|
998
|
+
__agiflowai_aicode_utils.print.error("Error executing prefetch:", error instanceof Error ? error.message : String(error));
|
|
999
|
+
process.exit(1);
|
|
1000
|
+
}
|
|
1001
|
+
});
|
|
1002
|
+
|
|
549
1003
|
//#endregion
|
|
550
1004
|
//#region package.json
|
|
551
|
-
var version = "0.2.
|
|
1005
|
+
var version = "0.2.2";
|
|
552
1006
|
|
|
553
1007
|
//#endregion
|
|
554
1008
|
//#region src/cli.ts
|
|
@@ -574,15 +1028,24 @@ var version = "0.2.6";
|
|
|
574
1028
|
* Main entry point
|
|
575
1029
|
*/
|
|
576
1030
|
async function main() {
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
1031
|
+
try {
|
|
1032
|
+
const program = new commander.Command();
|
|
1033
|
+
program.name("one-mcp").description("One MCP server package").version(version);
|
|
1034
|
+
program.addCommand(initCommand);
|
|
1035
|
+
program.addCommand(mcpServeCommand);
|
|
1036
|
+
program.addCommand(listToolsCommand);
|
|
1037
|
+
program.addCommand(describeToolsCommand);
|
|
1038
|
+
program.addCommand(useToolCommand);
|
|
1039
|
+
program.addCommand(prefetchCommand);
|
|
1040
|
+
await program.parseAsync(process.argv);
|
|
1041
|
+
} catch (error) {
|
|
1042
|
+
console.error(`CLI execution failed: ${error instanceof Error ? error.message : error}`);
|
|
1043
|
+
process.exit(1);
|
|
1044
|
+
}
|
|
585
1045
|
}
|
|
586
|
-
main()
|
|
1046
|
+
main().catch((error) => {
|
|
1047
|
+
console.error(`Fatal error: ${error instanceof Error ? error.message : error}`);
|
|
1048
|
+
process.exit(1);
|
|
1049
|
+
});
|
|
587
1050
|
|
|
588
1051
|
//#endregion
|
package/dist/cli.mjs
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as SkillService, c as ConfigFetcherService, i as createServer, n as SseTransportHandler, o as findConfigFile, r as StdioTransportHandler, s as McpClientManagerService, t as HttpTransportHandler } from "./http-
|
|
2
|
+
import { a as SkillService, c as ConfigFetcherService, i as createServer, n as SseTransportHandler, o as findConfigFile, r as StdioTransportHandler, s as McpClientManagerService, t as HttpTransportHandler } from "./http-Bi2N9PUM.mjs";
|
|
3
3
|
import { writeFile } from "node:fs/promises";
|
|
4
4
|
import { resolve } from "node:path";
|
|
5
5
|
import { Liquid } from "liquidjs";
|
|
6
6
|
import { Command } from "commander";
|
|
7
|
-
import { log } from "@agiflowai/aicode-utils";
|
|
7
|
+
import { log, print } from "@agiflowai/aicode-utils";
|
|
8
|
+
import { spawn } from "node:child_process";
|
|
8
9
|
|
|
9
10
|
//#region src/types/index.ts
|
|
10
11
|
/**
|
|
@@ -546,9 +547,462 @@ const initCommand = new Command("init").description("Initialize MCP configuratio
|
|
|
546
547
|
}
|
|
547
548
|
});
|
|
548
549
|
|
|
550
|
+
//#endregion
|
|
551
|
+
//#region src/services/PrefetchService/constants.ts
|
|
552
|
+
/**
|
|
553
|
+
* PrefetchService Constants
|
|
554
|
+
*
|
|
555
|
+
* Constants for package manager commands and process configuration.
|
|
556
|
+
*/
|
|
557
|
+
/** Transport type for stdio-based MCP servers */
|
|
558
|
+
const TRANSPORT_STDIO = "stdio";
|
|
559
|
+
/** npx command name */
|
|
560
|
+
const COMMAND_NPX = "npx";
|
|
561
|
+
/** npm command name */
|
|
562
|
+
const COMMAND_NPM = "npm";
|
|
563
|
+
/** pnpx command name (pnpm's npx equivalent) */
|
|
564
|
+
const COMMAND_PNPX = "pnpx";
|
|
565
|
+
/** pnpm command name */
|
|
566
|
+
const COMMAND_PNPM = "pnpm";
|
|
567
|
+
/** uvx command name */
|
|
568
|
+
const COMMAND_UVX = "uvx";
|
|
569
|
+
/** uv command name */
|
|
570
|
+
const COMMAND_UV = "uv";
|
|
571
|
+
/** Path suffix for npx command */
|
|
572
|
+
const COMMAND_NPX_SUFFIX = "/npx";
|
|
573
|
+
/** Path suffix for pnpx command */
|
|
574
|
+
const COMMAND_PNPX_SUFFIX = "/pnpx";
|
|
575
|
+
/** Path suffix for uvx command */
|
|
576
|
+
const COMMAND_UVX_SUFFIX = "/uvx";
|
|
577
|
+
/** Path suffix for uv command */
|
|
578
|
+
const COMMAND_UV_SUFFIX = "/uv";
|
|
579
|
+
/** Run subcommand for uv */
|
|
580
|
+
const ARG_RUN = "run";
|
|
581
|
+
/** Tool subcommand for uv */
|
|
582
|
+
const ARG_TOOL = "tool";
|
|
583
|
+
/** Install subcommand for uv tool and npm/pnpm */
|
|
584
|
+
const ARG_INSTALL = "install";
|
|
585
|
+
/** Add subcommand for pnpm */
|
|
586
|
+
const ARG_ADD = "add";
|
|
587
|
+
/** Global flag for npm/pnpm install */
|
|
588
|
+
const ARG_GLOBAL = "-g";
|
|
589
|
+
/** Flag prefix for command arguments */
|
|
590
|
+
const FLAG_PREFIX = "-";
|
|
591
|
+
/** npx --package flag (long form) */
|
|
592
|
+
const FLAG_PACKAGE_LONG = "--package";
|
|
593
|
+
/** npx -p flag (short form) */
|
|
594
|
+
const FLAG_PACKAGE_SHORT = "-p";
|
|
595
|
+
/** Equals delimiter used in flag=value patterns */
|
|
596
|
+
const EQUALS_DELIMITER = "=";
|
|
597
|
+
/**
|
|
598
|
+
* Regex pattern for valid package names (npm, pnpm, uvx, uv)
|
|
599
|
+
* Allows: @scope/package-name@version, package-name, package_name
|
|
600
|
+
* Prevents shell metacharacters that could enable command injection
|
|
601
|
+
* @example
|
|
602
|
+
* // Valid: '@scope/package@1.0.0', 'my-package', 'my_package', '@org/pkg'
|
|
603
|
+
* // Invalid: 'pkg; rm -rf /', 'pkg$(cmd)', 'pkg`whoami`', 'pkg|cat /etc/passwd'
|
|
604
|
+
*/
|
|
605
|
+
const VALID_PACKAGE_NAME_PATTERN = /^(@[a-zA-Z0-9_-]+\/)?[a-zA-Z0-9._-]+(@[a-zA-Z0-9._-]+)?$/;
|
|
606
|
+
/** Windows platform identifier */
|
|
607
|
+
const PLATFORM_WIN32 = "win32";
|
|
608
|
+
/** Success exit code */
|
|
609
|
+
const EXIT_CODE_SUCCESS = 0;
|
|
610
|
+
/** Stdio option to ignore stream */
|
|
611
|
+
const STDIO_IGNORE = "ignore";
|
|
612
|
+
/** Stdio option to pipe stream */
|
|
613
|
+
const STDIO_PIPE = "pipe";
|
|
614
|
+
|
|
615
|
+
//#endregion
|
|
616
|
+
//#region src/services/PrefetchService/PrefetchService.ts
|
|
617
|
+
/**
|
|
618
|
+
* PrefetchService
|
|
619
|
+
*
|
|
620
|
+
* DESIGN PATTERNS:
|
|
621
|
+
* - Service pattern for business logic encapsulation
|
|
622
|
+
* - Single responsibility principle
|
|
623
|
+
*
|
|
624
|
+
* CODING STANDARDS:
|
|
625
|
+
* - Use async/await for asynchronous operations
|
|
626
|
+
* - Throw descriptive errors for error cases
|
|
627
|
+
* - Keep methods focused and well-named
|
|
628
|
+
* - Document complex logic with comments
|
|
629
|
+
*
|
|
630
|
+
* AVOID:
|
|
631
|
+
* - Mixing concerns (keep focused on single domain)
|
|
632
|
+
* - Direct tool implementation (services should be tool-agnostic)
|
|
633
|
+
*/
|
|
634
|
+
/**
|
|
635
|
+
* Type guard to check if a config object is an McpStdioConfig
|
|
636
|
+
* @param config - Config object to check
|
|
637
|
+
* @returns True if config has required McpStdioConfig properties
|
|
638
|
+
*/
|
|
639
|
+
function isMcpStdioConfig(config) {
|
|
640
|
+
return typeof config === "object" && config !== null && "command" in config;
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* PrefetchService handles pre-downloading packages used by MCP servers.
|
|
644
|
+
* Supports npx (Node.js), uvx (Python/uv), and uv run commands.
|
|
645
|
+
*
|
|
646
|
+
* @example
|
|
647
|
+
* ```typescript
|
|
648
|
+
* const service = new PrefetchService({
|
|
649
|
+
* mcpConfig: await configFetcher.fetchConfiguration(),
|
|
650
|
+
* parallel: true,
|
|
651
|
+
* });
|
|
652
|
+
* const packages = service.extractPackages();
|
|
653
|
+
* const summary = await service.prefetch();
|
|
654
|
+
* ```
|
|
655
|
+
*/
|
|
656
|
+
var PrefetchService = class {
|
|
657
|
+
config;
|
|
658
|
+
/**
|
|
659
|
+
* Creates a new PrefetchService instance
|
|
660
|
+
* @param config - Service configuration options
|
|
661
|
+
*/
|
|
662
|
+
constructor(config) {
|
|
663
|
+
this.config = config;
|
|
664
|
+
}
|
|
665
|
+
/**
|
|
666
|
+
* Extract all prefetchable packages from the MCP configuration
|
|
667
|
+
* @returns Array of package info objects
|
|
668
|
+
*/
|
|
669
|
+
extractPackages() {
|
|
670
|
+
const packages = [];
|
|
671
|
+
const { mcpConfig, filter } = this.config;
|
|
672
|
+
for (const [serverName, serverConfig] of Object.entries(mcpConfig.mcpServers)) {
|
|
673
|
+
if (serverConfig.disabled) continue;
|
|
674
|
+
if (serverConfig.transport !== TRANSPORT_STDIO) continue;
|
|
675
|
+
if (!isMcpStdioConfig(serverConfig.config)) continue;
|
|
676
|
+
const packageInfo = this.extractPackageInfo(serverName, serverConfig.config);
|
|
677
|
+
if (packageInfo) {
|
|
678
|
+
if (filter && packageInfo.packageManager !== filter) continue;
|
|
679
|
+
packages.push(packageInfo);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
return packages;
|
|
683
|
+
}
|
|
684
|
+
/**
|
|
685
|
+
* Prefetch all packages from the configuration
|
|
686
|
+
* @returns Summary of prefetch results
|
|
687
|
+
* @throws Error if prefetch operation fails unexpectedly
|
|
688
|
+
*/
|
|
689
|
+
async prefetch() {
|
|
690
|
+
try {
|
|
691
|
+
const packages = this.extractPackages();
|
|
692
|
+
const results = [];
|
|
693
|
+
if (packages.length === 0) return {
|
|
694
|
+
totalPackages: 0,
|
|
695
|
+
successful: 0,
|
|
696
|
+
failed: 0,
|
|
697
|
+
results: []
|
|
698
|
+
};
|
|
699
|
+
if (this.config.parallel) {
|
|
700
|
+
const promises = packages.map(async (pkg) => this.prefetchPackage(pkg));
|
|
701
|
+
results.push(...await Promise.all(promises));
|
|
702
|
+
} else for (const pkg of packages) {
|
|
703
|
+
const result = await this.prefetchPackage(pkg);
|
|
704
|
+
results.push(result);
|
|
705
|
+
}
|
|
706
|
+
const successful = results.filter((r) => r.success).length;
|
|
707
|
+
const failed = results.filter((r) => !r.success).length;
|
|
708
|
+
return {
|
|
709
|
+
totalPackages: packages.length,
|
|
710
|
+
successful,
|
|
711
|
+
failed,
|
|
712
|
+
results
|
|
713
|
+
};
|
|
714
|
+
} catch (error) {
|
|
715
|
+
throw new Error(`Failed to prefetch packages: ${error instanceof Error ? error.message : String(error)}`);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Prefetch a single package
|
|
720
|
+
* @param pkg - Package info to prefetch
|
|
721
|
+
* @returns Result of the prefetch operation
|
|
722
|
+
*/
|
|
723
|
+
async prefetchPackage(pkg) {
|
|
724
|
+
try {
|
|
725
|
+
const [command, ...args] = pkg.fullCommand;
|
|
726
|
+
const result = await this.runCommand(command, args);
|
|
727
|
+
return {
|
|
728
|
+
package: pkg,
|
|
729
|
+
success: result.success,
|
|
730
|
+
output: result.output
|
|
731
|
+
};
|
|
732
|
+
} catch (error) {
|
|
733
|
+
return {
|
|
734
|
+
package: pkg,
|
|
735
|
+
success: false,
|
|
736
|
+
output: error instanceof Error ? error.message : String(error)
|
|
737
|
+
};
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
/**
|
|
741
|
+
* Validate package name to prevent command injection
|
|
742
|
+
* @param packageName - Package name to validate
|
|
743
|
+
* @returns True if package name is safe, false otherwise
|
|
744
|
+
* @remarks Rejects package names containing shell metacharacters
|
|
745
|
+
* @example
|
|
746
|
+
* isValidPackageName('@scope/package') // true
|
|
747
|
+
* isValidPackageName('my-package@1.0.0') // true
|
|
748
|
+
* isValidPackageName('pkg; rm -rf /') // false (shell injection)
|
|
749
|
+
* isValidPackageName('pkg$(whoami)') // false (command substitution)
|
|
750
|
+
*/
|
|
751
|
+
isValidPackageName(packageName) {
|
|
752
|
+
return VALID_PACKAGE_NAME_PATTERN.test(packageName);
|
|
753
|
+
}
|
|
754
|
+
/**
|
|
755
|
+
* Extract package info from a server's stdio config
|
|
756
|
+
* @param serverName - Name of the MCP server
|
|
757
|
+
* @param config - Stdio configuration for the server
|
|
758
|
+
* @returns Package info if extractable, null otherwise
|
|
759
|
+
*/
|
|
760
|
+
extractPackageInfo(serverName, config) {
|
|
761
|
+
const command = config.command.toLowerCase();
|
|
762
|
+
const args = config.args || [];
|
|
763
|
+
if (command === COMMAND_NPX || command.endsWith(COMMAND_NPX_SUFFIX)) {
|
|
764
|
+
const packageName = this.extractNpxPackage(args);
|
|
765
|
+
if (packageName && this.isValidPackageName(packageName)) return {
|
|
766
|
+
serverName,
|
|
767
|
+
packageManager: COMMAND_NPX,
|
|
768
|
+
packageName,
|
|
769
|
+
fullCommand: [
|
|
770
|
+
COMMAND_NPM,
|
|
771
|
+
ARG_INSTALL,
|
|
772
|
+
ARG_GLOBAL,
|
|
773
|
+
packageName
|
|
774
|
+
]
|
|
775
|
+
};
|
|
776
|
+
}
|
|
777
|
+
if (command === COMMAND_PNPX || command.endsWith(COMMAND_PNPX_SUFFIX)) {
|
|
778
|
+
const packageName = this.extractNpxPackage(args);
|
|
779
|
+
if (packageName && this.isValidPackageName(packageName)) return {
|
|
780
|
+
serverName,
|
|
781
|
+
packageManager: COMMAND_PNPX,
|
|
782
|
+
packageName,
|
|
783
|
+
fullCommand: [
|
|
784
|
+
COMMAND_PNPM,
|
|
785
|
+
ARG_ADD,
|
|
786
|
+
ARG_GLOBAL,
|
|
787
|
+
packageName
|
|
788
|
+
]
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
if (command === COMMAND_UVX || command.endsWith(COMMAND_UVX_SUFFIX)) {
|
|
792
|
+
const packageName = this.extractUvxPackage(args);
|
|
793
|
+
if (packageName && this.isValidPackageName(packageName)) return {
|
|
794
|
+
serverName,
|
|
795
|
+
packageManager: COMMAND_UVX,
|
|
796
|
+
packageName,
|
|
797
|
+
fullCommand: [COMMAND_UVX, packageName]
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
if ((command === COMMAND_UV || command.endsWith(COMMAND_UV_SUFFIX)) && args.includes(ARG_RUN)) {
|
|
801
|
+
const packageName = this.extractUvRunPackage(args);
|
|
802
|
+
if (packageName && this.isValidPackageName(packageName)) return {
|
|
803
|
+
serverName,
|
|
804
|
+
packageManager: COMMAND_UV,
|
|
805
|
+
packageName,
|
|
806
|
+
fullCommand: [
|
|
807
|
+
COMMAND_UV,
|
|
808
|
+
ARG_TOOL,
|
|
809
|
+
ARG_INSTALL,
|
|
810
|
+
packageName
|
|
811
|
+
]
|
|
812
|
+
};
|
|
813
|
+
}
|
|
814
|
+
return null;
|
|
815
|
+
}
|
|
816
|
+
/**
|
|
817
|
+
* Extract package name from npx command args
|
|
818
|
+
* @param args - Command arguments
|
|
819
|
+
* @returns Package name or null
|
|
820
|
+
* @remarks Handles --package=value, --package value, -p value patterns.
|
|
821
|
+
* Falls back to first non-flag argument if no --package/-p flag found.
|
|
822
|
+
* Returns null if flag has no value or is followed by another flag.
|
|
823
|
+
* When multiple --package flags exist, returns the first valid one.
|
|
824
|
+
* @example
|
|
825
|
+
* extractNpxPackage(['--package=@scope/pkg']) // returns '@scope/pkg'
|
|
826
|
+
* extractNpxPackage(['--package', 'pkg-name']) // returns 'pkg-name'
|
|
827
|
+
* extractNpxPackage(['-p', 'pkg']) // returns 'pkg'
|
|
828
|
+
* extractNpxPackage(['-y', 'pkg-name', '--flag']) // returns 'pkg-name' (fallback)
|
|
829
|
+
* extractNpxPackage(['--package=']) // returns null (empty value)
|
|
830
|
+
*/
|
|
831
|
+
extractNpxPackage(args) {
|
|
832
|
+
for (let i = 0; i < args.length; i++) {
|
|
833
|
+
const arg = args[i];
|
|
834
|
+
if (arg.startsWith(FLAG_PACKAGE_LONG + EQUALS_DELIMITER)) return arg.slice(FLAG_PACKAGE_LONG.length + EQUALS_DELIMITER.length) || null;
|
|
835
|
+
if (arg === FLAG_PACKAGE_LONG && i + 1 < args.length) {
|
|
836
|
+
const nextArg = args[i + 1];
|
|
837
|
+
if (!nextArg.startsWith(FLAG_PREFIX)) return nextArg;
|
|
838
|
+
}
|
|
839
|
+
if (arg === FLAG_PACKAGE_SHORT && i + 1 < args.length) {
|
|
840
|
+
const nextArg = args[i + 1];
|
|
841
|
+
if (!nextArg.startsWith(FLAG_PREFIX)) return nextArg;
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
for (const arg of args) {
|
|
845
|
+
if (arg.startsWith(FLAG_PREFIX)) continue;
|
|
846
|
+
return arg;
|
|
847
|
+
}
|
|
848
|
+
return null;
|
|
849
|
+
}
|
|
850
|
+
/**
|
|
851
|
+
* Extract package name from uvx command args
|
|
852
|
+
* @param args - Command arguments
|
|
853
|
+
* @returns Package name or null
|
|
854
|
+
* @remarks Assumes the first non-flag argument is the package name.
|
|
855
|
+
* Handles both single (-) and double (--) dash flags.
|
|
856
|
+
* @example
|
|
857
|
+
* extractUvxPackage(['mcp-server-fetch']) // returns 'mcp-server-fetch'
|
|
858
|
+
* extractUvxPackage(['--quiet', 'pkg-name']) // returns 'pkg-name'
|
|
859
|
+
*/
|
|
860
|
+
extractUvxPackage(args) {
|
|
861
|
+
for (const arg of args) {
|
|
862
|
+
if (arg.startsWith(FLAG_PREFIX)) continue;
|
|
863
|
+
return arg;
|
|
864
|
+
}
|
|
865
|
+
return null;
|
|
866
|
+
}
|
|
867
|
+
/**
|
|
868
|
+
* Extract package name from uv run command args
|
|
869
|
+
* @param args - Command arguments
|
|
870
|
+
* @returns Package name or null
|
|
871
|
+
* @remarks Looks for the first non-flag argument after the 'run' subcommand.
|
|
872
|
+
* Returns null if 'run' is not found in args.
|
|
873
|
+
* @example
|
|
874
|
+
* extractUvRunPackage(['run', 'mcp-server']) // returns 'mcp-server'
|
|
875
|
+
* extractUvRunPackage(['run', '--verbose', 'pkg']) // returns 'pkg'
|
|
876
|
+
* extractUvRunPackage(['install', 'pkg']) // returns null (no 'run')
|
|
877
|
+
*/
|
|
878
|
+
extractUvRunPackage(args) {
|
|
879
|
+
const runIndex = args.indexOf(ARG_RUN);
|
|
880
|
+
if (runIndex === -1) return null;
|
|
881
|
+
for (let i = runIndex + 1; i < args.length; i++) {
|
|
882
|
+
const arg = args[i];
|
|
883
|
+
if (arg.startsWith(FLAG_PREFIX)) continue;
|
|
884
|
+
return arg;
|
|
885
|
+
}
|
|
886
|
+
return null;
|
|
887
|
+
}
|
|
888
|
+
/**
|
|
889
|
+
* Run a shell command and capture output
|
|
890
|
+
* @param command - Command to run
|
|
891
|
+
* @param args - Command arguments
|
|
892
|
+
* @returns Promise with success status and output
|
|
893
|
+
*/
|
|
894
|
+
runCommand(command, args) {
|
|
895
|
+
return new Promise((resolve$1) => {
|
|
896
|
+
const proc = spawn(command, args, {
|
|
897
|
+
stdio: [
|
|
898
|
+
STDIO_IGNORE,
|
|
899
|
+
STDIO_PIPE,
|
|
900
|
+
STDIO_PIPE
|
|
901
|
+
],
|
|
902
|
+
shell: process.platform === PLATFORM_WIN32
|
|
903
|
+
});
|
|
904
|
+
let stdout = "";
|
|
905
|
+
let stderr = "";
|
|
906
|
+
proc.stdout?.on("data", (data) => {
|
|
907
|
+
stdout += data.toString();
|
|
908
|
+
});
|
|
909
|
+
proc.stderr?.on("data", (data) => {
|
|
910
|
+
stderr += data.toString();
|
|
911
|
+
});
|
|
912
|
+
proc.on("close", (code) => {
|
|
913
|
+
resolve$1({
|
|
914
|
+
success: code === EXIT_CODE_SUCCESS,
|
|
915
|
+
output: stdout || stderr
|
|
916
|
+
});
|
|
917
|
+
});
|
|
918
|
+
proc.on("error", (error) => {
|
|
919
|
+
resolve$1({
|
|
920
|
+
success: false,
|
|
921
|
+
output: error.message
|
|
922
|
+
});
|
|
923
|
+
});
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
};
|
|
927
|
+
|
|
928
|
+
//#endregion
|
|
929
|
+
//#region src/commands/prefetch.ts
|
|
930
|
+
/**
|
|
931
|
+
* Prefetch Command
|
|
932
|
+
*
|
|
933
|
+
* DESIGN PATTERNS:
|
|
934
|
+
* - Command pattern with Commander for CLI argument parsing
|
|
935
|
+
* - Async/await pattern for asynchronous operations
|
|
936
|
+
* - Error handling pattern with try-catch and proper exit codes
|
|
937
|
+
*
|
|
938
|
+
* CODING STANDARDS:
|
|
939
|
+
* - Use async action handlers for asynchronous operations
|
|
940
|
+
* - Provide clear option descriptions and default values
|
|
941
|
+
* - Handle errors gracefully with process.exit()
|
|
942
|
+
* - Log progress and errors to console
|
|
943
|
+
* - Use Commander's .option() and .argument() for inputs
|
|
944
|
+
*
|
|
945
|
+
* AVOID:
|
|
946
|
+
* - Synchronous blocking operations in action handlers
|
|
947
|
+
* - Missing error handling (always use try-catch)
|
|
948
|
+
* - Hardcoded values (use options or environment variables)
|
|
949
|
+
* - Not exiting with appropriate exit codes on errors
|
|
950
|
+
*/
|
|
951
|
+
/**
|
|
952
|
+
* Pre-download packages used by MCP servers (npx, pnpx, uvx, uv)
|
|
953
|
+
*/
|
|
954
|
+
const prefetchCommand = new Command("prefetch").description("Pre-download packages used by MCP servers (npx, pnpx, uvx, uv)").option("-c, --config <path>", "Path to MCP server configuration file").option("-p, --parallel", "Run prefetch commands in parallel", false).option("-d, --dry-run", "Show what would be prefetched without executing", false).option("-f, --filter <type>", "Filter by package manager type: npx, pnpx, uvx, or uv").action(async (options) => {
|
|
955
|
+
try {
|
|
956
|
+
const configFilePath = options.config || findConfigFile();
|
|
957
|
+
if (!configFilePath) {
|
|
958
|
+
print.error("No MCP configuration file found.");
|
|
959
|
+
print.info("Use --config <path> to specify a config file, or run \"one-mcp init\" to create one.");
|
|
960
|
+
process.exit(1);
|
|
961
|
+
}
|
|
962
|
+
print.info(`Loading configuration from: ${configFilePath}`);
|
|
963
|
+
const prefetchService = new PrefetchService({
|
|
964
|
+
mcpConfig: await new ConfigFetcherService({
|
|
965
|
+
configFilePath,
|
|
966
|
+
useCache: false
|
|
967
|
+
}).fetchConfiguration(true),
|
|
968
|
+
filter: options.filter,
|
|
969
|
+
parallel: options.parallel
|
|
970
|
+
});
|
|
971
|
+
const packages = prefetchService.extractPackages();
|
|
972
|
+
if (packages.length === 0) {
|
|
973
|
+
print.warning("No packages found to prefetch.");
|
|
974
|
+
print.info("Prefetch supports: npx, pnpx, uvx, and uv run commands");
|
|
975
|
+
return;
|
|
976
|
+
}
|
|
977
|
+
print.info(`Found ${packages.length} package(s) to prefetch:`);
|
|
978
|
+
for (const pkg of packages) print.item(`${pkg.serverName}: ${pkg.packageManager} ${pkg.packageName}`);
|
|
979
|
+
if (options.dryRun) {
|
|
980
|
+
print.newline();
|
|
981
|
+
print.header("Dry run mode - commands that would be executed:");
|
|
982
|
+
for (const pkg of packages) print.indent(pkg.fullCommand.join(" "));
|
|
983
|
+
return;
|
|
984
|
+
}
|
|
985
|
+
print.newline();
|
|
986
|
+
print.info("Prefetching packages...");
|
|
987
|
+
const summary = await prefetchService.prefetch();
|
|
988
|
+
print.newline();
|
|
989
|
+
if (summary.failed === 0) print.success(`Prefetch complete: ${summary.successful} succeeded, ${summary.failed} failed`);
|
|
990
|
+
else print.warning(`Prefetch complete: ${summary.successful} succeeded, ${summary.failed} failed`);
|
|
991
|
+
if (summary.failed > 0) {
|
|
992
|
+
print.newline();
|
|
993
|
+
print.error("Failed packages:");
|
|
994
|
+
for (const result of summary.results.filter((r) => !r.success)) print.item(`${result.package.serverName} (${result.package.packageName}): ${result.output.trim()}`);
|
|
995
|
+
process.exit(1);
|
|
996
|
+
}
|
|
997
|
+
} catch (error) {
|
|
998
|
+
print.error("Error executing prefetch:", error instanceof Error ? error.message : String(error));
|
|
999
|
+
process.exit(1);
|
|
1000
|
+
}
|
|
1001
|
+
});
|
|
1002
|
+
|
|
549
1003
|
//#endregion
|
|
550
1004
|
//#region package.json
|
|
551
|
-
var version = "0.2.
|
|
1005
|
+
var version = "0.2.2";
|
|
552
1006
|
|
|
553
1007
|
//#endregion
|
|
554
1008
|
//#region src/cli.ts
|
|
@@ -574,16 +1028,25 @@ var version = "0.2.6";
|
|
|
574
1028
|
* Main entry point
|
|
575
1029
|
*/
|
|
576
1030
|
async function main() {
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
1031
|
+
try {
|
|
1032
|
+
const program = new Command();
|
|
1033
|
+
program.name("one-mcp").description("One MCP server package").version(version);
|
|
1034
|
+
program.addCommand(initCommand);
|
|
1035
|
+
program.addCommand(mcpServeCommand);
|
|
1036
|
+
program.addCommand(listToolsCommand);
|
|
1037
|
+
program.addCommand(describeToolsCommand);
|
|
1038
|
+
program.addCommand(useToolCommand);
|
|
1039
|
+
program.addCommand(prefetchCommand);
|
|
1040
|
+
await program.parseAsync(process.argv);
|
|
1041
|
+
} catch (error) {
|
|
1042
|
+
console.error(`CLI execution failed: ${error instanceof Error ? error.message : error}`);
|
|
1043
|
+
process.exit(1);
|
|
1044
|
+
}
|
|
585
1045
|
}
|
|
586
|
-
main()
|
|
1046
|
+
main().catch((error) => {
|
|
1047
|
+
console.error(`Fatal error: ${error instanceof Error ? error.message : error}`);
|
|
1048
|
+
process.exit(1);
|
|
1049
|
+
});
|
|
587
1050
|
|
|
588
1051
|
//#endregion
|
|
589
1052
|
export { };
|
|
@@ -231,6 +231,7 @@ const ClaudeCodeStdioServerSchema = zod.z.object({
|
|
|
231
231
|
env: zod.z.record(zod.z.string(), zod.z.string()).optional(),
|
|
232
232
|
disabled: zod.z.boolean().optional(),
|
|
233
233
|
instruction: zod.z.string().optional(),
|
|
234
|
+
timeout: zod.z.number().positive().optional(),
|
|
234
235
|
config: AdditionalConfigSchema
|
|
235
236
|
});
|
|
236
237
|
const ClaudeCodeHttpServerSchema = zod.z.object({
|
|
@@ -239,6 +240,7 @@ const ClaudeCodeHttpServerSchema = zod.z.object({
|
|
|
239
240
|
type: zod.z.enum(["http", "sse"]).optional(),
|
|
240
241
|
disabled: zod.z.boolean().optional(),
|
|
241
242
|
instruction: zod.z.string().optional(),
|
|
243
|
+
timeout: zod.z.number().positive().optional(),
|
|
242
244
|
config: AdditionalConfigSchema
|
|
243
245
|
});
|
|
244
246
|
const ClaudeCodeServerConfigSchema = zod.z.union([ClaudeCodeStdioServerSchema, ClaudeCodeHttpServerSchema]);
|
|
@@ -309,6 +311,7 @@ const McpServerConfigSchema = zod.z.discriminatedUnion("transport", [
|
|
|
309
311
|
toolBlacklist: zod.z.array(zod.z.string()).optional(),
|
|
310
312
|
omitToolDescription: zod.z.boolean().optional(),
|
|
311
313
|
prompts: zod.z.record(zod.z.string(), InternalPromptConfigSchema).optional(),
|
|
314
|
+
timeout: zod.z.number().positive().optional(),
|
|
312
315
|
transport: zod.z.literal("stdio"),
|
|
313
316
|
config: McpStdioConfigSchema
|
|
314
317
|
}),
|
|
@@ -318,6 +321,7 @@ const McpServerConfigSchema = zod.z.discriminatedUnion("transport", [
|
|
|
318
321
|
toolBlacklist: zod.z.array(zod.z.string()).optional(),
|
|
319
322
|
omitToolDescription: zod.z.boolean().optional(),
|
|
320
323
|
prompts: zod.z.record(zod.z.string(), InternalPromptConfigSchema).optional(),
|
|
324
|
+
timeout: zod.z.number().positive().optional(),
|
|
321
325
|
transport: zod.z.literal("http"),
|
|
322
326
|
config: McpHttpConfigSchema
|
|
323
327
|
}),
|
|
@@ -327,6 +331,7 @@ const McpServerConfigSchema = zod.z.discriminatedUnion("transport", [
|
|
|
327
331
|
toolBlacklist: zod.z.array(zod.z.string()).optional(),
|
|
328
332
|
omitToolDescription: zod.z.boolean().optional(),
|
|
329
333
|
prompts: zod.z.record(zod.z.string(), InternalPromptConfigSchema).optional(),
|
|
334
|
+
timeout: zod.z.number().positive().optional(),
|
|
330
335
|
transport: zod.z.literal("sse"),
|
|
331
336
|
config: McpSseConfigSchema
|
|
332
337
|
})
|
|
@@ -360,6 +365,7 @@ function transformClaudeCodeConfig(claudeConfig) {
|
|
|
360
365
|
toolBlacklist: stdioConfig.config?.toolBlacklist,
|
|
361
366
|
omitToolDescription: stdioConfig.config?.omitToolDescription,
|
|
362
367
|
prompts: stdioConfig.config?.prompts,
|
|
368
|
+
timeout: stdioConfig.timeout,
|
|
363
369
|
transport: "stdio",
|
|
364
370
|
config: {
|
|
365
371
|
command: interpolatedCommand,
|
|
@@ -378,6 +384,7 @@ function transformClaudeCodeConfig(claudeConfig) {
|
|
|
378
384
|
toolBlacklist: httpConfig.config?.toolBlacklist,
|
|
379
385
|
omitToolDescription: httpConfig.config?.omitToolDescription,
|
|
380
386
|
prompts: httpConfig.config?.prompts,
|
|
387
|
+
timeout: httpConfig.timeout,
|
|
381
388
|
transport,
|
|
382
389
|
config: {
|
|
383
390
|
url: interpolatedUrl,
|
|
@@ -836,6 +843,8 @@ var ConfigFetcherService = class {
|
|
|
836
843
|
|
|
837
844
|
//#endregion
|
|
838
845
|
//#region src/services/McpClientManagerService.ts
|
|
846
|
+
/** Default connection timeout in milliseconds (30 seconds) */
|
|
847
|
+
const DEFAULT_CONNECTION_TIMEOUT_MS = 3e4;
|
|
839
848
|
/**
|
|
840
849
|
* MCP Client wrapper for managing individual server connections
|
|
841
850
|
* This is an internal class used by McpClientManagerService
|
|
@@ -941,8 +950,10 @@ var McpClientManagerService = class {
|
|
|
941
950
|
}
|
|
942
951
|
/**
|
|
943
952
|
* Connect to an MCP server based on its configuration with timeout
|
|
953
|
+
* Uses the timeout from server config, falling back to default (30s)
|
|
944
954
|
*/
|
|
945
|
-
async connectToServer(serverName, config
|
|
955
|
+
async connectToServer(serverName, config) {
|
|
956
|
+
const timeoutMs = config.timeout ?? DEFAULT_CONNECTION_TIMEOUT_MS;
|
|
946
957
|
if (this.clients.has(serverName)) throw new Error(`Client for ${serverName} is already connected`);
|
|
947
958
|
const client = new __modelcontextprotocol_sdk_client_index_js.Client({
|
|
948
959
|
name: `@agiflowai/one-mcp-client`,
|
|
@@ -202,6 +202,7 @@ const ClaudeCodeStdioServerSchema = z.object({
|
|
|
202
202
|
env: z.record(z.string(), z.string()).optional(),
|
|
203
203
|
disabled: z.boolean().optional(),
|
|
204
204
|
instruction: z.string().optional(),
|
|
205
|
+
timeout: z.number().positive().optional(),
|
|
205
206
|
config: AdditionalConfigSchema
|
|
206
207
|
});
|
|
207
208
|
const ClaudeCodeHttpServerSchema = z.object({
|
|
@@ -210,6 +211,7 @@ const ClaudeCodeHttpServerSchema = z.object({
|
|
|
210
211
|
type: z.enum(["http", "sse"]).optional(),
|
|
211
212
|
disabled: z.boolean().optional(),
|
|
212
213
|
instruction: z.string().optional(),
|
|
214
|
+
timeout: z.number().positive().optional(),
|
|
213
215
|
config: AdditionalConfigSchema
|
|
214
216
|
});
|
|
215
217
|
const ClaudeCodeServerConfigSchema = z.union([ClaudeCodeStdioServerSchema, ClaudeCodeHttpServerSchema]);
|
|
@@ -280,6 +282,7 @@ const McpServerConfigSchema = z.discriminatedUnion("transport", [
|
|
|
280
282
|
toolBlacklist: z.array(z.string()).optional(),
|
|
281
283
|
omitToolDescription: z.boolean().optional(),
|
|
282
284
|
prompts: z.record(z.string(), InternalPromptConfigSchema).optional(),
|
|
285
|
+
timeout: z.number().positive().optional(),
|
|
283
286
|
transport: z.literal("stdio"),
|
|
284
287
|
config: McpStdioConfigSchema
|
|
285
288
|
}),
|
|
@@ -289,6 +292,7 @@ const McpServerConfigSchema = z.discriminatedUnion("transport", [
|
|
|
289
292
|
toolBlacklist: z.array(z.string()).optional(),
|
|
290
293
|
omitToolDescription: z.boolean().optional(),
|
|
291
294
|
prompts: z.record(z.string(), InternalPromptConfigSchema).optional(),
|
|
295
|
+
timeout: z.number().positive().optional(),
|
|
292
296
|
transport: z.literal("http"),
|
|
293
297
|
config: McpHttpConfigSchema
|
|
294
298
|
}),
|
|
@@ -298,6 +302,7 @@ const McpServerConfigSchema = z.discriminatedUnion("transport", [
|
|
|
298
302
|
toolBlacklist: z.array(z.string()).optional(),
|
|
299
303
|
omitToolDescription: z.boolean().optional(),
|
|
300
304
|
prompts: z.record(z.string(), InternalPromptConfigSchema).optional(),
|
|
305
|
+
timeout: z.number().positive().optional(),
|
|
301
306
|
transport: z.literal("sse"),
|
|
302
307
|
config: McpSseConfigSchema
|
|
303
308
|
})
|
|
@@ -331,6 +336,7 @@ function transformClaudeCodeConfig(claudeConfig) {
|
|
|
331
336
|
toolBlacklist: stdioConfig.config?.toolBlacklist,
|
|
332
337
|
omitToolDescription: stdioConfig.config?.omitToolDescription,
|
|
333
338
|
prompts: stdioConfig.config?.prompts,
|
|
339
|
+
timeout: stdioConfig.timeout,
|
|
334
340
|
transport: "stdio",
|
|
335
341
|
config: {
|
|
336
342
|
command: interpolatedCommand,
|
|
@@ -349,6 +355,7 @@ function transformClaudeCodeConfig(claudeConfig) {
|
|
|
349
355
|
toolBlacklist: httpConfig.config?.toolBlacklist,
|
|
350
356
|
omitToolDescription: httpConfig.config?.omitToolDescription,
|
|
351
357
|
prompts: httpConfig.config?.prompts,
|
|
358
|
+
timeout: httpConfig.timeout,
|
|
352
359
|
transport,
|
|
353
360
|
config: {
|
|
354
361
|
url: interpolatedUrl,
|
|
@@ -807,6 +814,8 @@ var ConfigFetcherService = class {
|
|
|
807
814
|
|
|
808
815
|
//#endregion
|
|
809
816
|
//#region src/services/McpClientManagerService.ts
|
|
817
|
+
/** Default connection timeout in milliseconds (30 seconds) */
|
|
818
|
+
const DEFAULT_CONNECTION_TIMEOUT_MS = 3e4;
|
|
810
819
|
/**
|
|
811
820
|
* MCP Client wrapper for managing individual server connections
|
|
812
821
|
* This is an internal class used by McpClientManagerService
|
|
@@ -912,8 +921,10 @@ var McpClientManagerService = class {
|
|
|
912
921
|
}
|
|
913
922
|
/**
|
|
914
923
|
* Connect to an MCP server based on its configuration with timeout
|
|
924
|
+
* Uses the timeout from server config, falling back to default (30s)
|
|
915
925
|
*/
|
|
916
|
-
async connectToServer(serverName, config
|
|
926
|
+
async connectToServer(serverName, config) {
|
|
927
|
+
const timeoutMs = config.timeout ?? DEFAULT_CONNECTION_TIMEOUT_MS;
|
|
917
928
|
if (this.clients.has(serverName)) throw new Error(`Client for ${serverName} is already connected`);
|
|
918
929
|
const client = new Client({
|
|
919
930
|
name: `@agiflowai/one-mcp-client`,
|
package/dist/index.cjs
CHANGED
package/dist/index.d.cts
CHANGED
|
@@ -133,6 +133,8 @@ type McpServerTransportConfig = McpStdioConfig | McpHttpConfig | McpSseConfig;
|
|
|
133
133
|
* @property prompts - Optional prompts configuration for skill conversion
|
|
134
134
|
* @property transport - The transport type (stdio, http, or sse)
|
|
135
135
|
* @property config - Transport-specific configuration options
|
|
136
|
+
* @property timeout - Optional connection timeout in milliseconds (default: 30000)
|
|
137
|
+
* @property disabled - Whether this server is disabled and should not be started
|
|
136
138
|
*/
|
|
137
139
|
interface McpServerConfig {
|
|
138
140
|
name: string;
|
|
@@ -142,6 +144,8 @@ interface McpServerConfig {
|
|
|
142
144
|
prompts?: Record<string, PromptConfig>;
|
|
143
145
|
transport: McpServerTransportType;
|
|
144
146
|
config: McpServerTransportConfig;
|
|
147
|
+
timeout?: number;
|
|
148
|
+
disabled?: boolean;
|
|
145
149
|
}
|
|
146
150
|
/**
|
|
147
151
|
* Skills configuration
|
package/dist/index.d.mts
CHANGED
|
@@ -133,6 +133,8 @@ type McpServerTransportConfig = McpStdioConfig | McpHttpConfig | McpSseConfig;
|
|
|
133
133
|
* @property prompts - Optional prompts configuration for skill conversion
|
|
134
134
|
* @property transport - The transport type (stdio, http, or sse)
|
|
135
135
|
* @property config - Transport-specific configuration options
|
|
136
|
+
* @property timeout - Optional connection timeout in milliseconds (default: 30000)
|
|
137
|
+
* @property disabled - Whether this server is disabled and should not be started
|
|
136
138
|
*/
|
|
137
139
|
interface McpServerConfig {
|
|
138
140
|
name: string;
|
|
@@ -142,6 +144,8 @@ interface McpServerConfig {
|
|
|
142
144
|
prompts?: Record<string, PromptConfig>;
|
|
143
145
|
transport: McpServerTransportType;
|
|
144
146
|
config: McpServerTransportConfig;
|
|
147
|
+
timeout?: number;
|
|
148
|
+
disabled?: boolean;
|
|
145
149
|
}
|
|
146
150
|
/**
|
|
147
151
|
* Skills configuration
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { i as createServer, n as SseTransportHandler, r as StdioTransportHandler, t as HttpTransportHandler } from "./http-
|
|
1
|
+
import { i as createServer, n as SseTransportHandler, r as StdioTransportHandler, t as HttpTransportHandler } from "./http-Bi2N9PUM.mjs";
|
|
2
2
|
|
|
3
3
|
export { HttpTransportHandler, SseTransportHandler, StdioTransportHandler, createServer };
|