mcphosting-cli 0.1.0 → 0.1.1
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/package.json +10 -5
- package/CONTRIBUTING.md +0 -156
- package/src/commands/auth.ts +0 -186
- package/src/commands/connect.ts +0 -172
- package/src/commands/import.ts +0 -213
- package/src/commands/proxy.ts +0 -144
- package/src/commands/search.ts +0 -135
- package/src/commands/servers.ts +0 -131
- package/src/index.ts +0 -130
- package/src/lib/api.ts +0 -137
- package/src/lib/clients.ts +0 -188
- package/src/lib/config.ts +0 -90
- package/src/lib/logger.ts +0 -63
- package/src/types.ts +0 -47
- package/tsconfig.json +0 -26
- package/tsup.config.ts +0 -14
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcphosting-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Connect AI agents to MCP servers. Browse, install, and manage Model Context Protocol servers.",
|
|
5
5
|
"bin": {
|
|
6
|
-
"mcphost": "
|
|
6
|
+
"mcphost": "dist/index.js"
|
|
7
7
|
},
|
|
8
8
|
"main": "./dist/index.cjs",
|
|
9
9
|
"module": "./dist/index.js",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"mcp",
|
|
25
25
|
"model-context-protocol",
|
|
26
26
|
"claude",
|
|
27
|
-
"chatgpt",
|
|
27
|
+
"chatgpt",
|
|
28
28
|
"cursor",
|
|
29
29
|
"ai-agents",
|
|
30
30
|
"mcp-server",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"smithery",
|
|
33
33
|
"github-mcp",
|
|
34
34
|
"slack-mcp",
|
|
35
|
-
"notion-mcp",
|
|
35
|
+
"notion-mcp",
|
|
36
36
|
"stripe-mcp",
|
|
37
37
|
"mcp-marketplace",
|
|
38
38
|
"ai-tools",
|
|
@@ -52,5 +52,10 @@
|
|
|
52
52
|
"@types/node": "^20.11.0",
|
|
53
53
|
"tsup": "^8.0.0",
|
|
54
54
|
"typescript": "^5.3.0"
|
|
55
|
-
}
|
|
55
|
+
},
|
|
56
|
+
"files": [
|
|
57
|
+
"dist",
|
|
58
|
+
"README.md",
|
|
59
|
+
"LICENSE"
|
|
60
|
+
]
|
|
56
61
|
}
|
package/CONTRIBUTING.md
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
# Contributing to MCPHosting CLI
|
|
2
|
-
|
|
3
|
-
We love contributions! Here's how to get started.
|
|
4
|
-
|
|
5
|
-
## Development Setup
|
|
6
|
-
|
|
7
|
-
1. **Clone the repository:**
|
|
8
|
-
```bash
|
|
9
|
-
git clone https://github.com/gorlomi-enzo/mcphosting-cli.git
|
|
10
|
-
cd mcphosting-cli
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
2. **Install dependencies:**
|
|
14
|
-
```bash
|
|
15
|
-
npm install
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
3. **Build and test:**
|
|
19
|
-
```bash
|
|
20
|
-
npm run build
|
|
21
|
-
node dist/index.js --help
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
## Project Structure
|
|
25
|
-
|
|
26
|
-
```
|
|
27
|
-
src/
|
|
28
|
-
├── index.ts # CLI entry point
|
|
29
|
-
├── commands/ # Command implementations
|
|
30
|
-
│ ├── auth.ts # login/logout/whoami
|
|
31
|
-
│ ├── connect.ts # connect/disconnect/list
|
|
32
|
-
│ ├── import.ts # import from other tools
|
|
33
|
-
│ ├── proxy.ts # STDIO MCP proxy
|
|
34
|
-
│ ├── search.ts # search/info marketplace
|
|
35
|
-
│ └── servers.ts # server management (stubs)
|
|
36
|
-
├── lib/ # Shared utilities
|
|
37
|
-
│ ├── api.ts # MCPHosting API client
|
|
38
|
-
│ ├── clients.ts # AI client detection/config
|
|
39
|
-
│ ├── config.ts # Local config management
|
|
40
|
-
│ └── logger.ts # Pretty console output
|
|
41
|
-
└── types.ts # TypeScript definitions
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
## Making Changes
|
|
45
|
-
|
|
46
|
-
1. **Create a feature branch:**
|
|
47
|
-
```bash
|
|
48
|
-
git checkout -b feature/my-feature
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
2. **Make your changes:**
|
|
52
|
-
- Follow the existing code style
|
|
53
|
-
- Add TypeScript types for new code
|
|
54
|
-
- Test your changes with `npm run build && node dist/index.js`
|
|
55
|
-
|
|
56
|
-
3. **Test different scenarios:**
|
|
57
|
-
```bash
|
|
58
|
-
# Test search
|
|
59
|
-
node dist/index.js search github
|
|
60
|
-
|
|
61
|
-
# Test connect (dry run)
|
|
62
|
-
node dist/index.js connect github --client chatgpt
|
|
63
|
-
|
|
64
|
-
# Test help
|
|
65
|
-
node dist/index.js --help
|
|
66
|
-
node dist/index.js connect --help
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
## Adding New Commands
|
|
70
|
-
|
|
71
|
-
1. **Create the command file** in `src/commands/`
|
|
72
|
-
2. **Export a function** that returns a `Command` object
|
|
73
|
-
3. **Import and add** to `src/index.ts`
|
|
74
|
-
|
|
75
|
-
Example:
|
|
76
|
-
```typescript
|
|
77
|
-
// src/commands/example.ts
|
|
78
|
-
import { Command } from 'commander';
|
|
79
|
-
import { Logger } from '../lib/logger.js';
|
|
80
|
-
|
|
81
|
-
export function createExampleCommand(): Command {
|
|
82
|
-
return new Command('example')
|
|
83
|
-
.description('Example command')
|
|
84
|
-
.action(async () => {
|
|
85
|
-
Logger.success('Hello world!');
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// src/index.ts
|
|
90
|
-
import { createExampleCommand } from './commands/example.js';
|
|
91
|
-
program.addCommand(createExampleCommand());
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
## Adding New MCP Servers
|
|
95
|
-
|
|
96
|
-
Static MCP servers are defined in `src/lib/api.ts` in the `getStaticMCPs()` method. Add new entries there for testing until the live API is available.
|
|
97
|
-
|
|
98
|
-
## Code Style
|
|
99
|
-
|
|
100
|
-
- Use TypeScript with strict mode
|
|
101
|
-
- Prefer async/await over Promises
|
|
102
|
-
- Use the Logger class for consistent output
|
|
103
|
-
- Add help text and examples to commands
|
|
104
|
-
- Handle errors gracefully with user-friendly messages
|
|
105
|
-
|
|
106
|
-
## Testing
|
|
107
|
-
|
|
108
|
-
Currently manual testing. Run these scenarios:
|
|
109
|
-
|
|
110
|
-
```bash
|
|
111
|
-
# Core functionality
|
|
112
|
-
npm run build
|
|
113
|
-
node dist/index.js search github
|
|
114
|
-
node dist/index.js info notion
|
|
115
|
-
node dist/index.js list
|
|
116
|
-
node dist/index.js connect github --client chatgpt
|
|
117
|
-
|
|
118
|
-
# Import testing (will show "not found" unless you have Smithery)
|
|
119
|
-
node dist/index.js import --from smithery --dry-run
|
|
120
|
-
|
|
121
|
-
# Help testing
|
|
122
|
-
node dist/index.js --help
|
|
123
|
-
node dist/index.js connect --help
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
## Submitting Changes
|
|
127
|
-
|
|
128
|
-
1. **Commit your changes:**
|
|
129
|
-
```bash
|
|
130
|
-
git add .
|
|
131
|
-
git commit -m "Add: your feature description"
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
2. **Push your branch:**
|
|
135
|
-
```bash
|
|
136
|
-
git push origin feature/my-feature
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
3. **Create a Pull Request** on GitHub
|
|
140
|
-
|
|
141
|
-
## Growth Hacking Features
|
|
142
|
-
|
|
143
|
-
When adding commands, remember to include:
|
|
144
|
-
|
|
145
|
-
- Helpful error messages with next steps
|
|
146
|
-
- Links to GitHub repository in help text
|
|
147
|
-
- Sharing prompts after successful actions
|
|
148
|
-
- SEO-friendly descriptions and keywords
|
|
149
|
-
|
|
150
|
-
## Need Help?
|
|
151
|
-
|
|
152
|
-
- Open an issue on GitHub
|
|
153
|
-
- Check existing issues for similar problems
|
|
154
|
-
- Join our Discord: https://discord.gg/mcphosting
|
|
155
|
-
|
|
156
|
-
Thanks for contributing! 🚀
|
package/src/commands/auth.ts
DELETED
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import { createServer } from 'http';
|
|
3
|
-
import open from 'open';
|
|
4
|
-
import { Config } from '../lib/config.js';
|
|
5
|
-
import { MCPHostingAPI } from '../lib/api.js';
|
|
6
|
-
import { Logger } from '../lib/logger.js';
|
|
7
|
-
|
|
8
|
-
export function createAuthCommands(): Command {
|
|
9
|
-
const auth = new Command('auth');
|
|
10
|
-
|
|
11
|
-
auth
|
|
12
|
-
.command('login')
|
|
13
|
-
.description('Authenticate with MCPHosting')
|
|
14
|
-
.option('--token <token>', 'Provide API token directly')
|
|
15
|
-
.action(async (options) => {
|
|
16
|
-
const config = new Config();
|
|
17
|
-
|
|
18
|
-
if (options.token) {
|
|
19
|
-
// Manual token auth
|
|
20
|
-
config.token = options.token;
|
|
21
|
-
|
|
22
|
-
const api = new MCPHostingAPI(options.token);
|
|
23
|
-
const user = await api.whoami();
|
|
24
|
-
|
|
25
|
-
if (user) {
|
|
26
|
-
config.user = user;
|
|
27
|
-
Logger.success(`Logged in as ${user.email}${user.org ? ` (${user.org})` : ''}`);
|
|
28
|
-
} else {
|
|
29
|
-
Logger.warning('Token saved, but could not verify user info');
|
|
30
|
-
}
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Browser OAuth flow
|
|
35
|
-
const spinner = Logger.spinner('Starting login flow...');
|
|
36
|
-
|
|
37
|
-
let server: any;
|
|
38
|
-
let resolved = false;
|
|
39
|
-
|
|
40
|
-
try {
|
|
41
|
-
const authPromise = new Promise<string>((resolve, reject) => {
|
|
42
|
-
server = createServer((req, res) => {
|
|
43
|
-
if (req.url?.startsWith('/callback')) {
|
|
44
|
-
const url = new URL(req.url, 'http://localhost');
|
|
45
|
-
const token = url.searchParams.get('token');
|
|
46
|
-
|
|
47
|
-
if (token) {
|
|
48
|
-
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
49
|
-
res.end(`
|
|
50
|
-
<html>
|
|
51
|
-
<body style="font-family: system-ui; text-align: center; padding: 50px;">
|
|
52
|
-
<h2>✅ Login Successful!</h2>
|
|
53
|
-
<p>You can now close this window and return to your terminal.</p>
|
|
54
|
-
</body>
|
|
55
|
-
</html>
|
|
56
|
-
`);
|
|
57
|
-
resolve(token);
|
|
58
|
-
} else {
|
|
59
|
-
res.writeHead(400, { 'Content-Type': 'text/html' });
|
|
60
|
-
res.end(`
|
|
61
|
-
<html>
|
|
62
|
-
<body style="font-family: system-ui; text-align: center; padding: 50px;">
|
|
63
|
-
<h2>❌ Login Failed</h2>
|
|
64
|
-
<p>No token received. Please try again.</p>
|
|
65
|
-
</body>
|
|
66
|
-
</html>
|
|
67
|
-
`);
|
|
68
|
-
reject(new Error('No token received'));
|
|
69
|
-
}
|
|
70
|
-
} else {
|
|
71
|
-
res.writeHead(404);
|
|
72
|
-
res.end('Not found');
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
server.listen(0, () => {
|
|
77
|
-
const port = (server.address() as any).port;
|
|
78
|
-
const callbackUrl = `http://localhost:${port}/callback`;
|
|
79
|
-
const authUrl = `https://mcphosting.com/cli/auth?callback=${encodeURIComponent(callbackUrl)}`;
|
|
80
|
-
|
|
81
|
-
setTimeout(() => {
|
|
82
|
-
if (!resolved) {
|
|
83
|
-
reject(new Error('Login timeout - please try again'));
|
|
84
|
-
}
|
|
85
|
-
}, 120000); // 2 minute timeout
|
|
86
|
-
|
|
87
|
-
open(authUrl).catch(() => {
|
|
88
|
-
Logger.warning(`Could not open browser automatically. Please visit: ${authUrl}`);
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
const token = await authPromise;
|
|
94
|
-
resolved = true;
|
|
95
|
-
|
|
96
|
-
spinner.succeed('Login successful!');
|
|
97
|
-
|
|
98
|
-
config.token = token;
|
|
99
|
-
|
|
100
|
-
const api = new MCPHostingAPI(token);
|
|
101
|
-
const user = await api.whoami();
|
|
102
|
-
|
|
103
|
-
if (user) {
|
|
104
|
-
config.user = user;
|
|
105
|
-
Logger.success(`Logged in as ${user.email}${user.org ? ` (${user.org})` : ''}`);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
} catch (error) {
|
|
109
|
-
spinner.fail('Login failed');
|
|
110
|
-
Logger.error(`Login error: ${error}`);
|
|
111
|
-
process.exit(1);
|
|
112
|
-
} finally {
|
|
113
|
-
if (server) {
|
|
114
|
-
server.close();
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
auth
|
|
120
|
-
.command('logout')
|
|
121
|
-
.description('Remove stored authentication')
|
|
122
|
-
.action(() => {
|
|
123
|
-
const config = new Config();
|
|
124
|
-
config.token = undefined;
|
|
125
|
-
config.user = undefined;
|
|
126
|
-
Logger.success('Logged out successfully');
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
auth
|
|
130
|
-
.command('whoami')
|
|
131
|
-
.description('Show current user information')
|
|
132
|
-
.action(async () => {
|
|
133
|
-
const config = new Config();
|
|
134
|
-
const token = config.token;
|
|
135
|
-
|
|
136
|
-
if (!token) {
|
|
137
|
-
Logger.warning('Not logged in. Use `mcphost auth login` to authenticate.');
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
const user = config.user;
|
|
142
|
-
if (user) {
|
|
143
|
-
Logger.info(`Logged in as: ${user.email}${user.org ? ` (${user.org})` : ''}`);
|
|
144
|
-
} else {
|
|
145
|
-
Logger.warning('User info not available. Try logging in again.');
|
|
146
|
-
}
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
return auth;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Legacy commands (backwards compatibility)
|
|
153
|
-
export function createLegacyAuthCommands(): Command[] {
|
|
154
|
-
const config = new Config();
|
|
155
|
-
|
|
156
|
-
const login = new Command('login')
|
|
157
|
-
.description('Authenticate with MCPHosting')
|
|
158
|
-
.option('--token <token>', 'Provide API token directly')
|
|
159
|
-
.action(async (options) => {
|
|
160
|
-
const authCmd = createAuthCommands();
|
|
161
|
-
const loginCmd = authCmd.commands.find(cmd => cmd.name() === 'login');
|
|
162
|
-
if (loginCmd) {
|
|
163
|
-
await loginCmd.action(options);
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
const logout = new Command('logout')
|
|
168
|
-
.description('Remove stored authentication')
|
|
169
|
-
.action(() => {
|
|
170
|
-
config.token = undefined;
|
|
171
|
-
config.user = undefined;
|
|
172
|
-
Logger.success('Logged out successfully');
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
const whoami = new Command('whoami')
|
|
176
|
-
.description('Show current user information')
|
|
177
|
-
.action(async () => {
|
|
178
|
-
const authCmd = createAuthCommands();
|
|
179
|
-
const whoamiCmd = authCmd.commands.find(cmd => cmd.name() === 'whoami');
|
|
180
|
-
if (whoamiCmd) {
|
|
181
|
-
await whoamiCmd.action();
|
|
182
|
-
}
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
return [login, logout, whoami];
|
|
186
|
-
}
|
package/src/commands/connect.ts
DELETED
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import { Config } from '../lib/config.js';
|
|
3
|
-
import { ClientManager } from '../lib/clients.js';
|
|
4
|
-
import { Logger } from '../lib/logger.js';
|
|
5
|
-
import { SupportedClient } from '../types.js';
|
|
6
|
-
import chalk from 'chalk';
|
|
7
|
-
|
|
8
|
-
export function createConnectCommands(): Command {
|
|
9
|
-
const connect = new Command('connect')
|
|
10
|
-
.description('Connect an MCP server to AI clients')
|
|
11
|
-
.argument('<url-or-slug>', 'MCP server URL or slug')
|
|
12
|
-
.option('--client <client>', 'Target specific client (claude, cursor, vscode, openclaw, chatgpt)')
|
|
13
|
-
.option('--name <name>', 'Custom name for the connection')
|
|
14
|
-
.action(async (urlOrSlug: string, options) => {
|
|
15
|
-
const config = new Config();
|
|
16
|
-
const spinner = Logger.spinner('Setting up MCP connection...');
|
|
17
|
-
|
|
18
|
-
try {
|
|
19
|
-
const url = ClientManager.resolveUrl(urlOrSlug);
|
|
20
|
-
const slug = ClientManager.extractSlug(url);
|
|
21
|
-
const name = options.name || slug;
|
|
22
|
-
|
|
23
|
-
// Check if already connected
|
|
24
|
-
const existing = config.findConnection(slug);
|
|
25
|
-
if (existing) {
|
|
26
|
-
spinner.warn(`Already connected to ${slug}`);
|
|
27
|
-
Logger.info(`Use \`mcphost disconnect ${slug}\` to remove first`);
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const clients: string[] = [];
|
|
32
|
-
|
|
33
|
-
if (options.client) {
|
|
34
|
-
// Connect to specific client
|
|
35
|
-
const clientName = options.client as SupportedClient;
|
|
36
|
-
const success = await ClientManager.addToClient(clientName, slug, url);
|
|
37
|
-
|
|
38
|
-
if (success) {
|
|
39
|
-
clients.push(clientName);
|
|
40
|
-
spinner.succeed(`Connected to ${clientName}`);
|
|
41
|
-
} else {
|
|
42
|
-
spinner.fail(`Failed to connect to ${clientName}`);
|
|
43
|
-
process.exit(1);
|
|
44
|
-
}
|
|
45
|
-
} else {
|
|
46
|
-
// Auto-detect and connect to all available clients
|
|
47
|
-
const detectedClients = await ClientManager.detectInstalledClients();
|
|
48
|
-
const availableClients = detectedClients.filter(c => c.exists);
|
|
49
|
-
|
|
50
|
-
if (availableClients.length === 0) {
|
|
51
|
-
spinner.warn('No supported clients found');
|
|
52
|
-
Logger.info('Supported clients: Claude Desktop, Cursor, VS Code, OpenClaw');
|
|
53
|
-
Logger.info('Install a client and try again, or use --client chatgpt for web setup');
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
spinner.text = `Configuring ${availableClients.length} client${availableClients.length > 1 ? 's' : ''}...`;
|
|
58
|
-
|
|
59
|
-
for (const client of availableClients) {
|
|
60
|
-
try {
|
|
61
|
-
const success = await ClientManager.addToClient(
|
|
62
|
-
client.name as SupportedClient,
|
|
63
|
-
slug,
|
|
64
|
-
url
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
-
if (success) {
|
|
68
|
-
clients.push(client.name);
|
|
69
|
-
}
|
|
70
|
-
} catch (error) {
|
|
71
|
-
Logger.warning(`Failed to configure ${client.name}: ${error}`);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
spinner.succeed(`Connected to ${clients.length} client${clients.length > 1 ? 's' : ''}`);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Save connection to config
|
|
79
|
-
config.addConnection({
|
|
80
|
-
slug,
|
|
81
|
-
url,
|
|
82
|
-
clients
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
Logger.success(`🔗 ${name} connected successfully!`);
|
|
86
|
-
Logger.dim(` URL: ${url}`);
|
|
87
|
-
Logger.dim(` Clients: ${clients.join(', ')}`);
|
|
88
|
-
|
|
89
|
-
// Growth hacking: show sharing message after successful connection
|
|
90
|
-
console.log('\n' + chalk.green('🎉 Connected! Share with your team:'));
|
|
91
|
-
console.log(chalk.cyan(`npx @mcphosting/cli connect ${urlOrSlug}`));
|
|
92
|
-
console.log('\n' + chalk.yellow('⭐ Star us: ') + chalk.blue('https://github.com/gorlomi-enzo/mcphosting-cli'));
|
|
93
|
-
console.log('');
|
|
94
|
-
|
|
95
|
-
} catch (error) {
|
|
96
|
-
spinner.fail('Connection failed');
|
|
97
|
-
Logger.error(`Error: ${error}`);
|
|
98
|
-
process.exit(1);
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
return connect;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export function createDisconnectCommand(): Command {
|
|
106
|
-
return new Command('disconnect')
|
|
107
|
-
.description('Disconnect an MCP server')
|
|
108
|
-
.argument('<slug-or-id>', 'MCP server slug or connection ID')
|
|
109
|
-
.action(async (slugOrId: string) => {
|
|
110
|
-
const config = new Config();
|
|
111
|
-
const connection = config.findConnection(slugOrId);
|
|
112
|
-
|
|
113
|
-
if (!connection) {
|
|
114
|
-
Logger.error(`Connection not found: ${slugOrId}`);
|
|
115
|
-
Logger.info('Use `mcphost list` to see active connections');
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const spinner = Logger.spinner(`Disconnecting ${connection.slug}...`);
|
|
120
|
-
|
|
121
|
-
try {
|
|
122
|
-
const removedFrom = await ClientManager.removeFromAllClients(connection.slug);
|
|
123
|
-
config.removeConnection(connection.id);
|
|
124
|
-
|
|
125
|
-
spinner.succeed(`Disconnected ${connection.slug}`);
|
|
126
|
-
|
|
127
|
-
if (removedFrom.length > 0) {
|
|
128
|
-
Logger.info(`Removed from: ${removedFrom.join(', ')}`);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
} catch (error) {
|
|
132
|
-
spinner.fail('Disconnect failed');
|
|
133
|
-
Logger.error(`Error: ${error}`);
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
export function createListCommand(): Command {
|
|
139
|
-
return new Command('list')
|
|
140
|
-
.description('List connected MCP servers')
|
|
141
|
-
.option('--json', 'Output as JSON')
|
|
142
|
-
.action(async (options) => {
|
|
143
|
-
const config = new Config();
|
|
144
|
-
const connections = config.connections;
|
|
145
|
-
|
|
146
|
-
if (connections.length === 0) {
|
|
147
|
-
Logger.info('No MCP connections found');
|
|
148
|
-
Logger.dim('Use `mcphost connect <url>` to add one');
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
if (options.json) {
|
|
153
|
-
Logger.json(connections);
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
Logger.bold(`📋 Connected MCP Servers (${connections.length})`);
|
|
158
|
-
console.log('');
|
|
159
|
-
|
|
160
|
-
const tableData = connections.map(conn => ({
|
|
161
|
-
Slug: conn.slug,
|
|
162
|
-
URL: conn.url.length > 50 ? conn.url.slice(0, 47) + '...' : conn.url,
|
|
163
|
-
Clients: conn.clients.join(', '),
|
|
164
|
-
Added: new Date(conn.addedAt).toLocaleDateString()
|
|
165
|
-
}));
|
|
166
|
-
|
|
167
|
-
Logger.table(tableData);
|
|
168
|
-
|
|
169
|
-
console.log('');
|
|
170
|
-
Logger.dim('Use `mcphost disconnect <slug>` to remove a connection');
|
|
171
|
-
});
|
|
172
|
-
}
|