claude-autopm 1.14.1 → 1.15.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.
@@ -17,6 +17,7 @@ module.exports = {
17
17
  type: 'string',
18
18
  choices: [
19
19
  'list', 'add', 'remove', 'enable', 'disable', 'sync', 'validate', 'info',
20
+ 'search', 'browse', 'install', 'uninstall',
20
21
  'agents', 'agent', 'usage', 'setup', 'check', 'diagnose', 'test', 'tree', 'status'
21
22
  ]
22
23
  })
@@ -39,7 +40,36 @@ module.exports = {
39
40
  type: 'boolean',
40
41
  default: false
41
42
  })
43
+ .option('enable', {
44
+ describe: 'Enable server after installation',
45
+ type: 'boolean',
46
+ default: false
47
+ })
48
+ .option('force', {
49
+ describe: 'Force operation (skip confirmations)',
50
+ type: 'boolean',
51
+ default: false
52
+ })
53
+ .option('keep-package', {
54
+ describe: 'Keep npm package when uninstalling',
55
+ type: 'boolean',
56
+ default: false
57
+ })
58
+ .option('official', {
59
+ describe: 'Show only official @modelcontextprotocol servers',
60
+ type: 'boolean',
61
+ default: false
62
+ })
63
+ .option('category', {
64
+ describe: 'Filter by category',
65
+ type: 'string'
66
+ })
42
67
  .example('autopm mcp list', 'List all available MCP servers')
68
+ .example('autopm mcp search filesystem', 'Search npm for MCP servers')
69
+ .example('autopm mcp browse --official', 'Browse official MCP servers')
70
+ .example('autopm mcp install @modelcontextprotocol/server-filesystem', 'Install MCP server from npm')
71
+ .example('autopm mcp install @upstash/context7-mcp --enable', 'Install and enable immediately')
72
+ .example('autopm mcp uninstall filesystem', 'Uninstall MCP server')
43
73
  .example('autopm mcp enable context7-docs', 'Enable context7 documentation server')
44
74
  .example('autopm mcp agents', 'List all agents using MCP')
45
75
  .example('autopm mcp agent react-frontend-engineer', 'Show MCP config for specific agent')
@@ -107,6 +137,35 @@ module.exports = {
107
137
  handler.info(argv.name || argv.server);
108
138
  break;
109
139
 
140
+ // Discovery and installation commands
141
+ case 'search':
142
+ if (!argv.name) {
143
+ console.error('❌ Please specify a search query: autopm mcp search <query>');
144
+ process.exit(1);
145
+ }
146
+ await handler.search(argv.name, argv);
147
+ break;
148
+
149
+ case 'browse':
150
+ await handler.browse(argv);
151
+ break;
152
+
153
+ case 'install':
154
+ if (!argv.name) {
155
+ console.error('❌ Please specify a package name: autopm mcp install <package>');
156
+ process.exit(1);
157
+ }
158
+ await handler.installFromNpm(argv.name, argv);
159
+ break;
160
+
161
+ case 'uninstall':
162
+ if (!argv.name && !argv.server) {
163
+ console.error('❌ Please specify a server name: autopm mcp uninstall <server-name>');
164
+ process.exit(1);
165
+ }
166
+ await handler.uninstallServer(argv.name || argv.server, argv);
167
+ break;
168
+
110
169
  // Agent analysis commands
111
170
  case 'agents':
112
171
  handler.mcpAgents(argv.byServer ? { groupBy: 'server' } : {});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-autopm",
3
- "version": "1.14.1",
3
+ "version": "1.15.0",
4
4
  "description": "Autonomous Project Management Framework for Claude Code - Advanced AI-powered development automation",
5
5
  "main": "bin/autopm.js",
6
6
  "bin": {
@@ -555,6 +555,349 @@ This server can be integrated with various agents and context pools.
555
555
  console.log(`📝 TODO: Remove ${name} from registry`);
556
556
  }
557
557
 
558
+ // ==========================================
559
+ // DISCOVERY & INSTALLATION
560
+ // ==========================================
561
+
562
+ /**
563
+ * Search npm registry for MCP servers
564
+ * @param {string} query - Search query
565
+ * @param {Object} options - Search options
566
+ */
567
+ async search(query, options = {}) {
568
+ console.log(`🔍 Searching npm for "${query}"...\n`);
569
+
570
+ try {
571
+ const { execSync } = require('child_process');
572
+
573
+ // Build npm search command
574
+ let searchQuery = query;
575
+ if (options.official) {
576
+ searchQuery = `@modelcontextprotocol ${query}`;
577
+ }
578
+
579
+ // Search npm
580
+ const searchResults = execSync(`npm search ${searchQuery} --json`, {
581
+ encoding: 'utf8',
582
+ stdio: ['pipe', 'pipe', 'ignore']
583
+ });
584
+
585
+ const packages = JSON.parse(searchResults);
586
+
587
+ // Filter for MCP-related packages
588
+ const mcpPackages = packages.filter(pkg => {
589
+ const name = pkg.name.toLowerCase();
590
+ const desc = (pkg.description || '').toLowerCase();
591
+ return name.includes('mcp') || name.includes('context') ||
592
+ desc.includes('mcp') || desc.includes('model context protocol');
593
+ });
594
+
595
+ if (mcpPackages.length === 0) {
596
+ console.log('❌ No MCP servers found matching your query');
597
+ console.log('\n💡 Try:');
598
+ console.log(' - Broader search terms');
599
+ console.log(' - Use --official to search @modelcontextprotocol packages');
600
+ console.log(' - Visit: https://www.npmjs.com/search?q=@modelcontextprotocol');
601
+ return;
602
+ }
603
+
604
+ console.log(`📦 Found ${mcpPackages.length} MCP server(s):\n`);
605
+
606
+ mcpPackages.forEach((pkg, index) => {
607
+ console.log(`${index + 1}. ${pkg.name}`);
608
+ console.log(` Version: ${pkg.version}`);
609
+ if (pkg.description) {
610
+ console.log(` Description: ${pkg.description}`);
611
+ }
612
+ console.log(` Downloads: ${this._formatDownloads(pkg)}`);
613
+ console.log();
614
+ });
615
+
616
+ console.log('💡 To install a server:');
617
+ console.log(` autopm mcp install <package-name>`);
618
+ console.log('\n📚 More info: https://registry.modelcontextprotocol.io');
619
+
620
+ } catch (error) {
621
+ console.error('❌ Search failed:', error.message);
622
+ console.log('\n💡 Try using npm directly: npm search mcp');
623
+ }
624
+ }
625
+
626
+ /**
627
+ * Browse popular/official MCP servers
628
+ * @param {Object} options - Browse options
629
+ */
630
+ async browse(options = {}) {
631
+ console.log('🌟 Popular MCP Servers\n');
632
+
633
+ const officialServers = [
634
+ {
635
+ name: '@modelcontextprotocol/server-filesystem',
636
+ description: 'MCP server for filesystem access',
637
+ category: 'codebase'
638
+ },
639
+ {
640
+ name: '@modelcontextprotocol/server-memory',
641
+ description: 'Knowledge graph memory for Claude',
642
+ category: 'database'
643
+ },
644
+ {
645
+ name: '@modelcontextprotocol/server-sequential-thinking',
646
+ description: 'Structured problem-solving server',
647
+ category: 'utility'
648
+ },
649
+ {
650
+ name: '@upstash/context7-mcp',
651
+ description: 'Context7 documentation and codebase server',
652
+ category: 'documentation'
653
+ },
654
+ {
655
+ name: '@playwright/mcp',
656
+ description: 'Browser automation and E2E testing',
657
+ category: 'testing'
658
+ }
659
+ ];
660
+
661
+ let servers = options.official ? officialServers.filter(s => s.name.startsWith('@modelcontextprotocol')) : officialServers;
662
+
663
+ if (options.category) {
664
+ servers = servers.filter(s => s.category === options.category);
665
+ }
666
+
667
+ if (servers.length === 0) {
668
+ console.log('❌ No servers found matching your filters');
669
+ return;
670
+ }
671
+
672
+ servers.forEach((server, index) => {
673
+ console.log(`${index + 1}. ${server.name}`);
674
+ console.log(` Category: ${server.category}`);
675
+ console.log(` Description: ${server.description}`);
676
+ console.log();
677
+ });
678
+
679
+ console.log('💡 To install a server:');
680
+ console.log(' autopm mcp install <package-name> --enable');
681
+ console.log('\n💡 To search for more:');
682
+ console.log(' autopm mcp search <query>');
683
+ console.log('\n📚 Full registry: https://registry.modelcontextprotocol.io');
684
+ }
685
+
686
+ /**
687
+ * Install MCP server from npm
688
+ * @param {string} packageName - NPM package name
689
+ * @param {Object} options - Installation options
690
+ */
691
+ async installFromNpm(packageName, options = {}) {
692
+ console.log(`📦 Installing MCP server: ${packageName}\n`);
693
+
694
+ try {
695
+ const { execSync } = require('child_process');
696
+
697
+ // Step 1: Fetch package info
698
+ console.log('1️⃣ Fetching package info from npm...');
699
+ const packageInfo = execSync(`npm view ${packageName} --json`, {
700
+ encoding: 'utf8'
701
+ });
702
+ const pkg = JSON.parse(packageInfo);
703
+ console.log(` ✅ Found: ${pkg.name}@${pkg.version}`);
704
+
705
+ // Step 2: Install npm package
706
+ console.log('\n2️⃣ Installing npm package...');
707
+ execSync(`npm install -g ${packageName}`, {
708
+ encoding: 'utf8',
709
+ stdio: 'inherit'
710
+ });
711
+ console.log(' ✅ Installed successfully');
712
+
713
+ // Step 3: Create server definition
714
+ console.log('\n3️⃣ Creating server definition...');
715
+ const serverName = this._extractServerName(packageName);
716
+ const serverPath = path.join(this.mcpDir, `${serverName}.md`);
717
+
718
+ // Ensure mcp directory exists
719
+ if (!fs.existsSync(this.mcpDir)) {
720
+ fs.mkdirSync(this.mcpDir, { recursive: true });
721
+ }
722
+
723
+ // Create .md file
724
+ const serverContent = this._generateServerDefinition(pkg, packageName);
725
+ fs.writeFileSync(serverPath, serverContent, 'utf8');
726
+ console.log(` ✅ Created: .claude/mcp/${serverName}.md`);
727
+
728
+ // Step 4: Enable if requested
729
+ if (options.enable) {
730
+ console.log('\n4️⃣ Enabling server...');
731
+ this.enable(serverName);
732
+ console.log(' ✅ Enabled in config.json');
733
+
734
+ console.log('\n5️⃣ Syncing configuration...');
735
+ this.sync();
736
+ console.log(' ✅ Updated: .claude/mcp-servers.json');
737
+ }
738
+
739
+ console.log(`\n🎉 MCP server '${serverName}' ready to use!`);
740
+ console.log('\n📝 Next steps:');
741
+ if (!options.enable) {
742
+ console.log(` 1. Enable: autopm mcp enable ${serverName}`);
743
+ console.log(' 2. Sync: autopm mcp sync');
744
+ }
745
+ console.log(` 3. Configure environment: nano .claude/.env`);
746
+ console.log(` 4. Test connection: autopm mcp test ${serverName}`);
747
+
748
+ } catch (error) {
749
+ console.error('❌ Installation failed:', error.message);
750
+ console.log('\n💡 Troubleshooting:');
751
+ console.log(' - Check package name is correct');
752
+ console.log(' - Try: npm install -g ' + packageName);
753
+ console.log(' - Visit: https://www.npmjs.com/package/' + packageName);
754
+ process.exit(1);
755
+ }
756
+ }
757
+
758
+ /**
759
+ * Uninstall MCP server
760
+ * @param {string} serverName - Server name
761
+ * @param {Object} options - Uninstallation options
762
+ */
763
+ async uninstallServer(serverName, options = {}) {
764
+ console.log(`🗑️ Uninstalling MCP server '${serverName}'...\n`);
765
+
766
+ const serverPath = path.join(this.mcpDir, `${serverName}.md`);
767
+
768
+ if (!fs.existsSync(serverPath)) {
769
+ console.error(`❌ Server '${serverName}' not found`);
770
+ console.log('\n💡 List available servers: autopm mcp list');
771
+ process.exit(1);
772
+ }
773
+
774
+ try {
775
+ // Step 1: Check status
776
+ console.log('1️⃣ Checking server status...');
777
+ const config = this.loadConfig();
778
+ const isActive = (config.mcp?.activeServers || []).includes(serverName);
779
+ if (isActive) {
780
+ console.log(' ⚠️ Server is currently enabled');
781
+ } else {
782
+ console.log(' ✅ Server is not active');
783
+ }
784
+
785
+ // Step 2: Disable if active
786
+ if (isActive && !options.force) {
787
+ console.log('\n2️⃣ Disabling server...');
788
+ this.disable(serverName);
789
+ console.log(' ✅ Disabled in config.json');
790
+ }
791
+
792
+ // Step 3: Remove definition
793
+ console.log('\n3️⃣ Removing server definition...');
794
+ fs.unlinkSync(serverPath);
795
+ console.log(` ✅ Deleted: .claude/mcp/${serverName}.md`);
796
+
797
+ // Step 4: Uninstall npm package (unless --keep-package)
798
+ if (!options.keepPackage) {
799
+ console.log('\n4️⃣ Uninstalling npm package...');
800
+ try {
801
+ const { execSync } = require('child_process');
802
+ // Try to find package name from .md file (but it's deleted, so we'll guess)
803
+ execSync(`npm uninstall -g @modelcontextprotocol/server-${serverName}`, {
804
+ stdio: 'ignore'
805
+ });
806
+ console.log(' ✅ Uninstalled npm package');
807
+ } catch (error) {
808
+ console.log(' ⚠️ Could not uninstall npm package automatically');
809
+ console.log(' 💡 Try: npm uninstall -g <package-name>');
810
+ }
811
+ } else {
812
+ console.log('\n4️⃣ Keeping npm package (--keep-package)');
813
+ }
814
+
815
+ // Step 5: Clean up config
816
+ console.log('\n5️⃣ Cleaning up configuration...');
817
+ this.sync();
818
+ console.log(' ✅ Updated: .claude/mcp-servers.json');
819
+
820
+ console.log(`\n✨ Server '${serverName}' completely removed`);
821
+
822
+ } catch (error) {
823
+ console.error('❌ Uninstallation failed:', error.message);
824
+ process.exit(1);
825
+ }
826
+ }
827
+
828
+ // Helper methods for discovery/installation
829
+
830
+ _formatDownloads(pkg) {
831
+ // npm search doesn't always include download counts
832
+ return pkg.date ? `Last publish: ${pkg.date}` : 'N/A';
833
+ }
834
+
835
+ _extractServerName(packageName) {
836
+ // Extract server name from package
837
+ // @modelcontextprotocol/server-filesystem -> filesystem
838
+ // @upstash/context7-mcp -> context7-mcp
839
+ const parts = packageName.split('/');
840
+ const name = parts[parts.length - 1];
841
+ return name.replace('server-', '').replace('-mcp', '');
842
+ }
843
+
844
+ _generateServerDefinition(pkg, packageName) {
845
+ const serverName = this._extractServerName(packageName);
846
+ const category = this._guessCategory(pkg);
847
+
848
+ return `---
849
+ name: ${serverName}
850
+ command: npx
851
+ args: ["${packageName}"]
852
+ description: ${pkg.description || 'MCP server'}
853
+ category: ${category}
854
+ status: active
855
+ version: ${pkg.version}
856
+ installed: ${new Date().toISOString()}
857
+ ---
858
+
859
+ # ${pkg.name}
860
+
861
+ ## Description
862
+ ${pkg.description || 'MCP server'}
863
+
864
+ ## Installation
865
+ This server was automatically installed via:
866
+ \`\`\`bash
867
+ autopm mcp install ${packageName}
868
+ \`\`\`
869
+
870
+ ## Configuration
871
+ Configure environment variables in \`.claude/.env\` if needed.
872
+
873
+ ## Usage
874
+ Enable this server:
875
+ \`\`\`bash
876
+ autopm mcp enable ${serverName}
877
+ autopm mcp sync
878
+ \`\`\`
879
+
880
+ ## Links
881
+ - NPM: https://www.npmjs.com/package/${packageName}
882
+ ${pkg.homepage ? `- Homepage: ${pkg.homepage}` : ''}
883
+ ${pkg.repository?.url ? `- Repository: ${pkg.repository.url}` : ''}
884
+ `;
885
+ }
886
+
887
+ _guessCategory(pkg) {
888
+ const name = (pkg.name || '').toLowerCase();
889
+ const desc = (pkg.description || '').toLowerCase();
890
+ const text = name + ' ' + desc;
891
+
892
+ if (text.includes('filesystem') || text.includes('file')) return 'codebase';
893
+ if (text.includes('doc') || text.includes('context7')) return 'documentation';
894
+ if (text.includes('test') || text.includes('playwright')) return 'testing';
895
+ if (text.includes('database') || text.includes('sql') || text.includes('memory')) return 'database';
896
+ if (text.includes('github') || text.includes('git')) return 'integration';
897
+
898
+ return 'utility';
899
+ }
900
+
558
901
  // ==========================================
559
902
  // EXTENDED FEATURES: Agent Analysis
560
903
  // ==========================================