@smithery/cli 0.0.25 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,12 +1,6 @@
1
- # smithery/cli
1
+ # Smithery CLI ![NPM Version](https://img.shields.io/npm/v/%40smithery%2Fcli)
2
2
 
3
- A lightweight registry and manager for Model Context Protocol (MCP) servers, designed to be client-agnostic.
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,60 @@
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
+ import { VALID_CLIENTS } from "../constants.js";
7
+ export async function inspect(client) {
8
+ try {
9
+ // ensure client is valid
10
+ if (client && !VALID_CLIENTS.includes(client)) {
11
+ console.error(chalk.red(`Invalid client: ${client}\nValid clients are: ${VALID_CLIENTS.join(", ")}`));
12
+ process.exit(1);
13
+ }
14
+ const installedIds = ConfigManager.getInstalledServerIds(client);
15
+ if (installedIds.length === 0) {
16
+ console.log(chalk.yellow("\nNo MCP servers are currently installed."));
17
+ return;
18
+ }
19
+ const config = ConfigManager.readConfig(client);
20
+ while (true) {
21
+ const choices = createListChoices(installedIds.map((id) => ({
22
+ id,
23
+ name: ConfigManager.denormalizeServerId(id),
24
+ isInstalled: true,
25
+ connections: [],
26
+ })), false, true);
27
+ const { selectedId } = await inquirer.prompt([
28
+ {
29
+ type: "list",
30
+ name: "selectedId",
31
+ message: "Select a server to inspect:",
32
+ choices,
33
+ },
34
+ ]);
35
+ if (selectedId === "exit") {
36
+ process.exit(0);
37
+ }
38
+ if (!selectedId) {
39
+ return;
40
+ }
41
+ console.log(chalk.blue("\nConnecting to server..."));
42
+ const connectionConfig = config.mcpServers[selectedId.id];
43
+ if ("command" in connectionConfig) {
44
+ const client = await createServerConnection(selectedId.id, connectionConfig);
45
+ const result = await inspectServer(client);
46
+ if (result === "exit") {
47
+ process.exit(0);
48
+ }
49
+ }
50
+ else {
51
+ throw new Error("Only stdio connections are supported");
52
+ }
53
+ }
54
+ }
55
+ catch (error) {
56
+ console.error(chalk.red("Error during inspection:"));
57
+ console.error(chalk.red(error instanceof Error ? error.message : String(error)));
58
+ process.exit(1);
59
+ }
60
+ }
@@ -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, client);
20
+ console.log(chalk.green(`✓ Successfully installed package '${serverId}' for ${client}`));
21
+ }
@@ -0,0 +1,50 @@
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
+ import { VALID_CLIENTS } from "../constants.js";
9
+ inquirer.registerPrompt("autocomplete", AutocompletePrompt);
10
+ let installedServersCache = null;
11
+ export async function listInstalledServers(client) {
12
+ // ensure client is valid
13
+ if (client && !VALID_CLIENTS.includes(client)) {
14
+ console.error(chalk.red(`Invalid client: ${client}\nValid clients are: ${VALID_CLIENTS.join(", ")}`));
15
+ process.exit(1);
16
+ }
17
+ const installedIds = ConfigManager.getInstalledServerIds(client);
18
+ if (installedIds.length === 0) {
19
+ console.log(chalk.yellow("\nNo MCP servers are currently installed."));
20
+ return;
21
+ }
22
+ const denormalizedIds = installedIds.map((id) => ConfigManager.denormalizeServerId(id));
23
+ if (!installedServersCache ||
24
+ !areArraysEqual(denormalizedIds, installedServersCache.map((server) => server.id))) {
25
+ installedServersCache = await fetchServers(client, denormalizedIds);
26
+ installedServersCache.forEach((server) => {
27
+ server.isInstalled = true;
28
+ });
29
+ }
30
+ printServerListHeader(installedServersCache.length, "installed");
31
+ const prompt = {
32
+ type: "list",
33
+ name: "selectedServer",
34
+ message: "Search and select a server:",
35
+ choices: createListChoices(installedServersCache, false, true),
36
+ };
37
+ const answer = await inquirer.prompt([prompt]);
38
+ if (!answer.selectedServer || answer.selectedServer === "exit") {
39
+ return;
40
+ }
41
+ const action = await displayServerDetails(answer.selectedServer);
42
+ await handleServerAction(answer.selectedServer, action, {
43
+ onUninstall: () => listInstalledServers(client),
44
+ onBack: () => listInstalledServers(client),
45
+ }, true, client);
46
+ }
47
+ function areArraysEqual(arr1, arr2) {
48
+ return (arr1.length === arr2.length &&
49
+ arr1.every((value, index) => value === arr2[index]));
50
+ }
@@ -0,0 +1,44 @@
1
+ import chalk from "chalk";
2
+ import inquirer from "inquirer";
3
+ import { ServerManager } from "../utils/server-manager.js";
4
+ import { VALID_CLIENTS } from "../constants.js";
5
+ const serverManager = new ServerManager();
6
+ export async function uninstall(serverId, client) {
7
+ try {
8
+ // ensure client is valid
9
+ if (client && !VALID_CLIENTS.includes(client)) {
10
+ console.error(chalk.red(`Invalid client: ${client}\nValid clients are: ${VALID_CLIENTS.join(", ")}`));
11
+ process.exit(1);
12
+ }
13
+ // If no server name provided, show error
14
+ if (!serverId) {
15
+ console.error(chalk.red("Error: Server ID is required"));
16
+ console.log("Usage: @smithery/cli uninstall <server-id>");
17
+ process.exit(1);
18
+ }
19
+ // Confirm uninstallation
20
+ const { confirmUninstall } = await inquirer.prompt([
21
+ {
22
+ type: "confirm",
23
+ name: "confirmUninstall",
24
+ message: `Are you sure you want to uninstall ${serverId}?`,
25
+ default: false,
26
+ },
27
+ ]);
28
+ if (!confirmUninstall) {
29
+ console.log("Uninstallation cancelled.");
30
+ return;
31
+ }
32
+ // Perform uninstallation
33
+ await serverManager.uninstallServer(serverId, client);
34
+ console.log(chalk.green(`\nSuccessfully uninstalled ${serverId} for ${client}`));
35
+ if (client === "claude") {
36
+ console.log(chalk.yellow("\nNote: Please restart Claude for the changes to take effect."));
37
+ }
38
+ }
39
+ catch (error) {
40
+ console.error(chalk.red("Failed to uninstall server:"));
41
+ console.error(chalk.red(error instanceof Error ? error.message : String(error)));
42
+ process.exit(1);
43
+ }
44
+ }
@@ -0,0 +1,31 @@
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
+ import { VALID_CLIENTS } from "../constants.js";
6
+ export async function get(serverId, client) {
7
+ try {
8
+ // ensure client is valid
9
+ if (client && !VALID_CLIENTS.includes(client)) {
10
+ console.error(chalk.red(`Invalid client: ${client}\nValid clients are: ${VALID_CLIENTS.join(", ")}`));
11
+ process.exit(1);
12
+ }
13
+ const server = await resolveServer(serverId, client);
14
+ if (!server) {
15
+ console.log(chalk.yellow(`No server found with ID: ${serverId}`));
16
+ return;
17
+ }
18
+ const action = await displayServerDetails(server, false);
19
+ await handleServerAction(server, action, {}, false, client);
20
+ }
21
+ catch (error) {
22
+ console.error(chalk.red("Error loading server:"));
23
+ if (error instanceof Error && error.message.includes("fetch")) {
24
+ console.error(chalk.red("Failed to connect to the registry. Please check your internet connection."));
25
+ }
26
+ else {
27
+ console.error(chalk.red(error instanceof Error ? error.message : String(error)));
28
+ }
29
+ process.exit(1);
30
+ }
31
+ }
@@ -0,0 +1 @@
1
+ export const VALID_CLIENTS = ["claude", "cline"];