@smithery/cli 0.0.25 → 1.0.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/README.md +1 -7
- package/dist/commands/inspect.js +54 -0
- package/dist/commands/install.js +21 -0
- package/dist/commands/installed.js +44 -0
- package/dist/commands/uninstall.js +36 -0
- package/dist/commands/view.js +25 -0
- package/dist/constants.js +1 -0
- package/dist/index.js +3 -3
- package/dist/types/registry.js +29 -0
- package/dist/utils/client-utils.js +93 -0
- package/dist/utils/config-manager.js +115 -0
- package/dist/utils/registry-utils.js +87 -0
- package/dist/utils/runtime-utils.js +141 -0
- package/dist/utils/server-actions.js +43 -0
- package/dist/utils/server-display.js +80 -0
- package/dist/utils/server-inspector.js +124 -0
- package/dist/utils/server-manager.js +37 -0
- package/package.json +5 -22
package/README.md
CHANGED
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
# smithery/cli
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install -g @smithery/cli
|
|
9
|
-
```
|
|
3
|
+
The Smithery registry installer and manager for Model Context Protocol (MCP) servers, designed to be client-agnostic.
|
|
10
4
|
|
|
11
5
|
## Usage
|
|
12
6
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { createServerConnection, inspectServer, } from "../utils/server-inspector.js";
|
|
3
|
+
import { ConfigManager } from "../utils/config-manager.js";
|
|
4
|
+
import { createListChoices } from "../utils/server-display.js";
|
|
5
|
+
import inquirer from "inquirer";
|
|
6
|
+
export async function inspect() {
|
|
7
|
+
try {
|
|
8
|
+
const installedIds = ConfigManager.getInstalledServerIds();
|
|
9
|
+
if (installedIds.length === 0) {
|
|
10
|
+
console.log(chalk.yellow("\nNo MCP servers are currently installed."));
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const config = ConfigManager.readConfig();
|
|
14
|
+
while (true) {
|
|
15
|
+
const choices = createListChoices(installedIds.map((id) => ({
|
|
16
|
+
id,
|
|
17
|
+
name: ConfigManager.denormalizeServerId(id),
|
|
18
|
+
isInstalled: true,
|
|
19
|
+
connections: [],
|
|
20
|
+
})), false, true);
|
|
21
|
+
const { selectedId } = await inquirer.prompt([
|
|
22
|
+
{
|
|
23
|
+
type: "list",
|
|
24
|
+
name: "selectedId",
|
|
25
|
+
message: "Select a server to inspect:",
|
|
26
|
+
choices,
|
|
27
|
+
},
|
|
28
|
+
]);
|
|
29
|
+
if (selectedId === "exit") {
|
|
30
|
+
process.exit(0);
|
|
31
|
+
}
|
|
32
|
+
if (!selectedId) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
console.log(chalk.blue("\nConnecting to server..."));
|
|
36
|
+
const connectionConfig = config.mcpServers[selectedId.id];
|
|
37
|
+
if ("command" in connectionConfig) {
|
|
38
|
+
const client = await createServerConnection(selectedId.id, connectionConfig);
|
|
39
|
+
const result = await inspectServer(client);
|
|
40
|
+
if (result === "exit") {
|
|
41
|
+
process.exit(0);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
throw new Error("Only stdio connections are supported");
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
console.error(chalk.red("Error during inspection:"));
|
|
51
|
+
console.error(chalk.red(error instanceof Error ? error.message : String(error)));
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { ServerManager } from "../utils/server-manager.js";
|
|
3
|
+
import { resolveServer } from "../utils/registry-utils.js";
|
|
4
|
+
import { VALID_CLIENTS } from "../constants.js";
|
|
5
|
+
const serverManager = new ServerManager();
|
|
6
|
+
export async function install(serverId, client) {
|
|
7
|
+
// ensure client is valid
|
|
8
|
+
if (client && !VALID_CLIENTS.includes(client)) {
|
|
9
|
+
console.error(chalk.red(`Invalid client: ${client}\nValid clients are: ${VALID_CLIENTS.join(", ")}`));
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
// get package details and connection template
|
|
13
|
+
const server = await resolveServer(serverId, client);
|
|
14
|
+
if (!server) {
|
|
15
|
+
console.error(chalk.red(`Server '${serverId}' not found in registry`));
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
// install server using the serverManager instance
|
|
19
|
+
await serverManager.installServer(server);
|
|
20
|
+
console.log(chalk.green(`✓ Successfully installed package '${serverId}'`));
|
|
21
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import inquirer from "inquirer";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { fetchServers } from "../utils/registry-utils.js";
|
|
4
|
+
import AutocompletePrompt from "inquirer-autocomplete-prompt";
|
|
5
|
+
import { handleServerAction } from "../utils/server-actions.js";
|
|
6
|
+
import { ConfigManager } from "../utils/config-manager.js";
|
|
7
|
+
import { displayServerDetails, printServerListHeader, createListChoices, } from "../utils/server-display.js";
|
|
8
|
+
inquirer.registerPrompt("autocomplete", AutocompletePrompt);
|
|
9
|
+
let installedServersCache = null;
|
|
10
|
+
export async function listInstalledServers() {
|
|
11
|
+
const installedIds = ConfigManager.getInstalledServerIds();
|
|
12
|
+
if (installedIds.length === 0) {
|
|
13
|
+
console.log(chalk.yellow("\nNo MCP servers are currently installed."));
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const denormalizedIds = installedIds.map((id) => ConfigManager.denormalizeServerId(id));
|
|
17
|
+
if (!installedServersCache ||
|
|
18
|
+
!areArraysEqual(denormalizedIds, installedServersCache.map((server) => server.id))) {
|
|
19
|
+
installedServersCache = await fetchServers(undefined, denormalizedIds);
|
|
20
|
+
installedServersCache.forEach((server) => {
|
|
21
|
+
server.isInstalled = true;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
printServerListHeader(installedServersCache.length, "installed");
|
|
25
|
+
const prompt = {
|
|
26
|
+
type: "list",
|
|
27
|
+
name: "selectedServer",
|
|
28
|
+
message: "Search and select a server:",
|
|
29
|
+
choices: createListChoices(installedServersCache, false, true),
|
|
30
|
+
};
|
|
31
|
+
const answer = await inquirer.prompt([prompt]);
|
|
32
|
+
if (!answer.selectedServer || answer.selectedServer === "exit") {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const action = await displayServerDetails(answer.selectedServer);
|
|
36
|
+
await handleServerAction(answer.selectedServer, action, {
|
|
37
|
+
onUninstall: () => listInstalledServers(),
|
|
38
|
+
onBack: listInstalledServers,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function areArraysEqual(arr1, arr2) {
|
|
42
|
+
return (arr1.length === arr2.length &&
|
|
43
|
+
arr1.every((value, index) => value === arr2[index]));
|
|
44
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import inquirer from "inquirer";
|
|
3
|
+
import { ServerManager } from "../utils/server-manager.js";
|
|
4
|
+
const serverManager = new ServerManager();
|
|
5
|
+
export async function uninstall(serverId) {
|
|
6
|
+
try {
|
|
7
|
+
// If no server name provided, show error
|
|
8
|
+
if (!serverId) {
|
|
9
|
+
console.error(chalk.red("Error: Server ID is required"));
|
|
10
|
+
console.log("Usage: @smithery/cli uninstall <server-id>");
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
// Confirm uninstallation
|
|
14
|
+
const { confirmUninstall } = await inquirer.prompt([
|
|
15
|
+
{
|
|
16
|
+
type: "confirm",
|
|
17
|
+
name: "confirmUninstall",
|
|
18
|
+
message: `Are you sure you want to uninstall ${serverId}?`,
|
|
19
|
+
default: false,
|
|
20
|
+
},
|
|
21
|
+
]);
|
|
22
|
+
if (!confirmUninstall) {
|
|
23
|
+
console.log("Uninstallation cancelled.");
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
// Perform uninstallation
|
|
27
|
+
await serverManager.uninstallServer(serverId);
|
|
28
|
+
console.log(chalk.green(`\nSuccessfully uninstalled ${serverId}`));
|
|
29
|
+
console.log(chalk.yellow("\nNote: Please restart Claude for the changes to take effect."));
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
console.error(chalk.red("Failed to uninstall server:"));
|
|
33
|
+
console.error(chalk.red(error instanceof Error ? error.message : String(error)));
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { resolveServer } from "../utils/registry-utils.js";
|
|
3
|
+
import { handleServerAction } from "../utils/server-actions.js";
|
|
4
|
+
import { displayServerDetails } from "../utils/server-display.js";
|
|
5
|
+
export async function get(serverId) {
|
|
6
|
+
try {
|
|
7
|
+
const server = await resolveServer(serverId);
|
|
8
|
+
if (!server) {
|
|
9
|
+
console.log(chalk.yellow(`No server found with ID: ${serverId}`));
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const action = await displayServerDetails(server, false);
|
|
13
|
+
await handleServerAction(server, action, {});
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
console.error(chalk.red("Error loading server:"));
|
|
17
|
+
if (error instanceof Error && error.message.includes("fetch")) {
|
|
18
|
+
console.error(chalk.red("Failed to connect to the registry. Please check your internet connection."));
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
console.error(chalk.red(error instanceof Error ? error.message : String(error)));
|
|
22
|
+
}
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const VALID_CLIENTS = ["claude"];
|