@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 +2 -8
- package/dist/commands/inspect.js +60 -0
- package/dist/commands/install.js +21 -0
- package/dist/commands/installed.js +50 -0
- package/dist/commands/uninstall.js +44 -0
- package/dist/commands/view.js +31 -0
- package/dist/constants.js +1 -0
- package/dist/index.js +60 -56
- package/dist/types/registry.js +29 -0
- package/dist/utils/client-utils.js +93 -0
- package/dist/utils/config-manager.js +118 -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
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
2
|
+
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
3
|
+
import inquirer from "inquirer";
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
export async function createServerConnection(id, config) {
|
|
6
|
+
// console.log('Creating server connection with config:', JSON.stringify(config, null, 2));
|
|
7
|
+
if (!config) {
|
|
8
|
+
throw new Error(`No connection configuration found for server ${id}`);
|
|
9
|
+
}
|
|
10
|
+
const transport = new StdioClientTransport({
|
|
11
|
+
command: process.platform === "win32" ? "npx.cmd" : "/usr/local/bin/npx",
|
|
12
|
+
args: config.args || [],
|
|
13
|
+
env: {
|
|
14
|
+
...process.env,
|
|
15
|
+
...(config.env || {}),
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
const client = new Client({ name: "mcp-cli", version: "1.0.0" }, { capabilities: {} });
|
|
19
|
+
await client.connect(transport);
|
|
20
|
+
return client;
|
|
21
|
+
}
|
|
22
|
+
export async function listServerPrimitives(client) {
|
|
23
|
+
const capabilities = client.getServerCapabilities() || {};
|
|
24
|
+
const primitives = [];
|
|
25
|
+
const promises = [];
|
|
26
|
+
if (capabilities.resources) {
|
|
27
|
+
promises.push(client.listResources().then(({ resources }) => {
|
|
28
|
+
resources.forEach((item) => primitives.push({ type: "resource", value: item }));
|
|
29
|
+
}));
|
|
30
|
+
}
|
|
31
|
+
if (capabilities.tools) {
|
|
32
|
+
promises.push(client.listTools().then(({ tools }) => {
|
|
33
|
+
tools.forEach((item) => primitives.push({ type: "tool", value: item }));
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
36
|
+
if (capabilities.prompts) {
|
|
37
|
+
promises.push(client.listPrompts().then(({ prompts }) => {
|
|
38
|
+
prompts.forEach((item) => primitives.push({ type: "prompt", value: item }));
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
await Promise.all(promises);
|
|
42
|
+
return primitives;
|
|
43
|
+
}
|
|
44
|
+
export async function selectPrimitive(primitives) {
|
|
45
|
+
const truncateDescription = (desc, maxLength = 100) => {
|
|
46
|
+
if (!desc)
|
|
47
|
+
return "No description";
|
|
48
|
+
return desc.length > maxLength ? `${desc.slice(0, maxLength)}...` : desc;
|
|
49
|
+
};
|
|
50
|
+
const choices = [
|
|
51
|
+
...primitives.map((p) => ({
|
|
52
|
+
name: `${chalk.green(`${p.type}(${p.value.name})`)} - ${chalk.gray(truncateDescription(p.value.description || ""))}`,
|
|
53
|
+
value: p,
|
|
54
|
+
description: p.value.description,
|
|
55
|
+
})),
|
|
56
|
+
new inquirer.Separator(),
|
|
57
|
+
{
|
|
58
|
+
name: chalk.yellow("↩ Back"),
|
|
59
|
+
value: "back",
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: chalk.red("✖ Exit"),
|
|
63
|
+
value: "exit",
|
|
64
|
+
},
|
|
65
|
+
];
|
|
66
|
+
const { selected } = await inquirer.prompt([
|
|
67
|
+
{
|
|
68
|
+
type: "list",
|
|
69
|
+
name: "selected",
|
|
70
|
+
message: "Pick a primitive",
|
|
71
|
+
choices,
|
|
72
|
+
pageSize: 10,
|
|
73
|
+
},
|
|
74
|
+
]);
|
|
75
|
+
return selected;
|
|
76
|
+
}
|
|
77
|
+
export async function inspectServer(client) {
|
|
78
|
+
const primitives = await listServerPrimitives(client);
|
|
79
|
+
while (true) {
|
|
80
|
+
const selected = await selectPrimitive(primitives);
|
|
81
|
+
if (selected === "back") {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
if (selected === "exit") {
|
|
85
|
+
return "exit";
|
|
86
|
+
}
|
|
87
|
+
// Pretty print the specification with colors
|
|
88
|
+
const spec = {
|
|
89
|
+
type: selected.type,
|
|
90
|
+
value: {
|
|
91
|
+
name: selected.value.name,
|
|
92
|
+
description: selected.value.description,
|
|
93
|
+
...(selected.type === "tool" && {
|
|
94
|
+
inputSchema: (await client.listTools({ name: selected.value.name }))
|
|
95
|
+
?.tools?.[0]?.inputSchema,
|
|
96
|
+
}),
|
|
97
|
+
...(selected.value.uri && { uri: selected.value.uri }),
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
console.log("\n", chalk.cyan(JSON.stringify(spec, null, 2)
|
|
101
|
+
.replace(/"(\w+)":/g, (match) => chalk.green(match))
|
|
102
|
+
.replace(/"([^"]+)"(?=,|\n|\})/g, (match) => chalk.yellow(match))));
|
|
103
|
+
const { action } = await inquirer.prompt([
|
|
104
|
+
{
|
|
105
|
+
type: "list",
|
|
106
|
+
name: "action",
|
|
107
|
+
message: "What would you like to do?",
|
|
108
|
+
choices: [
|
|
109
|
+
{
|
|
110
|
+
name: chalk.yellow("↩ Back to primitives"),
|
|
111
|
+
value: "back",
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: chalk.red("✖ Exit"),
|
|
115
|
+
value: "exit",
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
},
|
|
119
|
+
]);
|
|
120
|
+
if (action === "exit") {
|
|
121
|
+
return "exit";
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ConfigManager } from "./config-manager.js";
|
|
2
|
+
import { getServerConfiguration } from "./registry-utils.js";
|
|
3
|
+
import { promptForRestart } from "./client-utils.js";
|
|
4
|
+
import { collectConfigValues } from "./runtime-utils.js";
|
|
5
|
+
export class ServerManager {
|
|
6
|
+
constructor(configManager = ConfigManager) {
|
|
7
|
+
this.configManager = configManager;
|
|
8
|
+
}
|
|
9
|
+
validateConnection(server) {
|
|
10
|
+
const connection = server.connections?.[0];
|
|
11
|
+
if (!connection) {
|
|
12
|
+
throw new Error("No connection configuration found");
|
|
13
|
+
}
|
|
14
|
+
return connection;
|
|
15
|
+
}
|
|
16
|
+
async installServer(server, client) {
|
|
17
|
+
const connection = this.validateConnection(server);
|
|
18
|
+
const values = await collectConfigValues(connection);
|
|
19
|
+
const serverConfig = await getServerConfiguration(server.id, values, connection.type);
|
|
20
|
+
if (!serverConfig) {
|
|
21
|
+
throw new Error(`Unable to fetch server configuration for server ${server.id}`);
|
|
22
|
+
}
|
|
23
|
+
await this.configManager.installServer(server.id, serverConfig, client);
|
|
24
|
+
await promptForRestart(client);
|
|
25
|
+
}
|
|
26
|
+
async uninstallServer(serverId, client) {
|
|
27
|
+
try {
|
|
28
|
+
await this.configManager.uninstallServer(serverId, client);
|
|
29
|
+
console.log(`\nUninstalled ${serverId}`);
|
|
30
|
+
await promptForRestart(client);
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
console.error("Failed to uninstall server:", error);
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
package/package.json
CHANGED
|
@@ -1,56 +1,39 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smithery/cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"type": "commonjs",
|
|
5
5
|
"private": false,
|
|
6
6
|
"homepage": "https://smithery.ai/",
|
|
7
|
-
"description": "A NPX command to install and list Model Context Protocols",
|
|
7
|
+
"description": "A NPX command to install and list Model Context Protocols from Smithery",
|
|
8
8
|
"main": "dist/index.js",
|
|
9
9
|
"scripts": {
|
|
10
|
-
"build": "node build.mjs && chmod +x dist/index.js",
|
|
10
|
+
"build": "tsc && node build.mjs && chmod +x dist/index.js",
|
|
11
11
|
"start": "node dist/index.js",
|
|
12
12
|
"test:list": "node --loader ts-node/esm src/index.ts list",
|
|
13
13
|
"test:install": "node --loader ts-node/esm src/index.ts install",
|
|
14
14
|
"test:installed": "node --loader ts-node/esm src/index.ts installed",
|
|
15
15
|
"extract": "node --loader ts-node/esm src/extractors/modelcontextprotocol-extractor.ts",
|
|
16
16
|
"test:uninstall": "node --loader ts-node/esm src/index.ts uninstall",
|
|
17
|
-
"version:patch": "npm version patch",
|
|
18
|
-
"version:minor": "npm version minor",
|
|
19
|
-
"version:major": "npm version major",
|
|
20
|
-
"publish:npm": "npm run build && npm publish --access public",
|
|
21
|
-
"pr-check": "node src/scripts/pr-check.js",
|
|
22
|
-
"test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --config jest.config.mjs --watch",
|
|
23
|
-
"test:coverage": "NODE_OPTIONS=--experimental-vm-modules jest --config jest.config.mjs --coverage",
|
|
24
17
|
"prepare": "npm run build",
|
|
25
|
-
"
|
|
26
|
-
"format": "npx @biomejs/biome format --write"
|
|
18
|
+
"check": "npx @biomejs/biome check --write --unsafe"
|
|
27
19
|
},
|
|
28
20
|
"bin": {
|
|
29
21
|
"cli": "dist/index.js"
|
|
30
22
|
},
|
|
31
23
|
"dependencies": {
|
|
32
|
-
"@iarna/toml": "^2.2.5",
|
|
33
24
|
"@modelcontextprotocol/sdk": "^1.0.3",
|
|
34
|
-
"@types/iarna__toml": "^2.0.5",
|
|
35
25
|
"chalk": "^4.1.2",
|
|
36
|
-
"cli-table3": "^0.6.5",
|
|
37
|
-
"fuzzy": "^0.1.3",
|
|
38
26
|
"inquirer": "^8.2.4",
|
|
39
|
-
"inquirer-autocomplete-prompt": "^2.0.0"
|
|
40
|
-
"open": "^10.1.0",
|
|
41
|
-
"string-width": "^4.2.3"
|
|
27
|
+
"inquirer-autocomplete-prompt": "^2.0.0"
|
|
42
28
|
},
|
|
43
29
|
"devDependencies": {
|
|
44
30
|
"@biomejs/biome": "^1.5.3",
|
|
45
31
|
"@types/inquirer": "^8.2.4",
|
|
46
32
|
"@types/inquirer-autocomplete-prompt": "^3.0.3",
|
|
47
|
-
"@types/jest": "^29.5.14",
|
|
48
33
|
"@types/json-schema": "^7.0.15",
|
|
49
34
|
"@types/node": "^14.0.0",
|
|
50
35
|
"dotenv": "^16.4.7",
|
|
51
36
|
"esbuild": "^0.24.0",
|
|
52
|
-
"jest": "^29.7.0",
|
|
53
|
-
"ts-jest": "^29.2.5",
|
|
54
37
|
"ts-node": "^10.9.1",
|
|
55
38
|
"tsx": "^4.19.2",
|
|
56
39
|
"typescript": "^5.0.0"
|