@modelcontextprotocol/inspector-cli 0.16.5 → 0.16.6
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/build/cli.js +34 -3
- package/build/client/prompts.js +16 -1
- package/build/client/tools.js +12 -2
- package/build/index.js +32 -4
- package/build/transport.js +16 -2
- package/build/utils/awaitable-log.js +7 -0
- package/package.json +6 -3
package/build/cli.js
CHANGED
|
@@ -54,6 +54,10 @@ async function runWebClient(args) {
|
|
|
54
54
|
await spawnPromise("node", [inspectorClientPath, ...startArgs], {
|
|
55
55
|
signal: abort.signal,
|
|
56
56
|
echoOutput: true,
|
|
57
|
+
// pipe the stdout through here, prevents issues with buffering and
|
|
58
|
+
// dropping the end of console.out after 8192 chars due to node
|
|
59
|
+
// closing the stdout pipe before the output has finished flushing
|
|
60
|
+
stdio: "inherit",
|
|
57
61
|
});
|
|
58
62
|
}
|
|
59
63
|
catch (e) {
|
|
@@ -73,18 +77,28 @@ async function runCli(args) {
|
|
|
73
77
|
try {
|
|
74
78
|
// Build CLI arguments
|
|
75
79
|
const cliArgs = [cliPath];
|
|
80
|
+
// Add target URL/command first
|
|
81
|
+
cliArgs.push(args.command, ...args.args);
|
|
76
82
|
// Add transport flag if specified
|
|
77
83
|
if (args.transport && args.transport !== "stdio") {
|
|
78
84
|
// Convert streamable-http back to http for CLI mode
|
|
79
85
|
const cliTransport = args.transport === "streamable-http" ? "http" : args.transport;
|
|
80
86
|
cliArgs.push("--transport", cliTransport);
|
|
81
87
|
}
|
|
82
|
-
// Add
|
|
83
|
-
|
|
88
|
+
// Add headers if specified
|
|
89
|
+
if (args.headers) {
|
|
90
|
+
for (const [key, value] of Object.entries(args.headers)) {
|
|
91
|
+
cliArgs.push("--header", `${key}: ${value}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
84
94
|
await spawnPromise("node", cliArgs, {
|
|
85
95
|
env: { ...process.env, ...args.envArgs },
|
|
86
96
|
signal: abort.signal,
|
|
87
97
|
echoOutput: true,
|
|
98
|
+
// pipe the stdout through here, prevents issues with buffering and
|
|
99
|
+
// dropping the end of console.out after 8192 chars due to node
|
|
100
|
+
// closing the stdout pipe before the output has finished flushing
|
|
101
|
+
stdio: "inherit",
|
|
88
102
|
});
|
|
89
103
|
}
|
|
90
104
|
catch (e) {
|
|
@@ -126,6 +140,18 @@ function parseKeyValuePair(value, previous = {}) {
|
|
|
126
140
|
}
|
|
127
141
|
return { ...previous, [key]: val };
|
|
128
142
|
}
|
|
143
|
+
function parseHeaderPair(value, previous = {}) {
|
|
144
|
+
const colonIndex = value.indexOf(":");
|
|
145
|
+
if (colonIndex === -1) {
|
|
146
|
+
throw new Error(`Invalid header format: ${value}. Use "HeaderName: Value" format.`);
|
|
147
|
+
}
|
|
148
|
+
const key = value.slice(0, colonIndex).trim();
|
|
149
|
+
const val = value.slice(colonIndex + 1).trim();
|
|
150
|
+
if (key === "" || val === "") {
|
|
151
|
+
throw new Error(`Invalid header format: ${value}. Use "HeaderName: Value" format.`);
|
|
152
|
+
}
|
|
153
|
+
return { ...previous, [key]: val };
|
|
154
|
+
}
|
|
129
155
|
function parseArgs() {
|
|
130
156
|
const program = new Command();
|
|
131
157
|
const argSeparatorIndex = process.argv.indexOf("--");
|
|
@@ -144,7 +170,8 @@ function parseArgs() {
|
|
|
144
170
|
.option("--server <n>", "server name from config file")
|
|
145
171
|
.option("--cli", "enable CLI mode")
|
|
146
172
|
.option("--transport <type>", "transport type (stdio, sse, http)")
|
|
147
|
-
.option("--server-url <url>", "server URL for SSE/HTTP transport")
|
|
173
|
+
.option("--server-url <url>", "server URL for SSE/HTTP transport")
|
|
174
|
+
.option("--header <headers...>", 'HTTP headers as "HeaderName: Value" pairs (for HTTP/SSE transports)', parseHeaderPair, {});
|
|
148
175
|
// Parse only the arguments before --
|
|
149
176
|
program.parse(preArgs);
|
|
150
177
|
const options = program.opts();
|
|
@@ -186,6 +213,7 @@ function parseArgs() {
|
|
|
186
213
|
envArgs: { ...(config.env || {}), ...(options.e || {}) },
|
|
187
214
|
cli: options.cli || false,
|
|
188
215
|
transport: "stdio",
|
|
216
|
+
headers: options.header,
|
|
189
217
|
};
|
|
190
218
|
}
|
|
191
219
|
else if (config.type === "sse" || config.type === "streamable-http") {
|
|
@@ -196,6 +224,7 @@ function parseArgs() {
|
|
|
196
224
|
cli: options.cli || false,
|
|
197
225
|
transport: config.type,
|
|
198
226
|
serverUrl: config.url,
|
|
227
|
+
headers: options.header,
|
|
199
228
|
};
|
|
200
229
|
}
|
|
201
230
|
else {
|
|
@@ -206,6 +235,7 @@ function parseArgs() {
|
|
|
206
235
|
envArgs: { ...(config.env || {}), ...(options.e || {}) },
|
|
207
236
|
cli: options.cli || false,
|
|
208
237
|
transport: "stdio",
|
|
238
|
+
headers: options.header,
|
|
209
239
|
};
|
|
210
240
|
}
|
|
211
241
|
}
|
|
@@ -224,6 +254,7 @@ function parseArgs() {
|
|
|
224
254
|
cli: options.cli || false,
|
|
225
255
|
transport: transport,
|
|
226
256
|
serverUrl: options.serverUrl,
|
|
257
|
+
headers: options.header,
|
|
227
258
|
};
|
|
228
259
|
}
|
|
229
260
|
async function main() {
|
package/build/client/prompts.js
CHANGED
|
@@ -11,9 +11,24 @@ export async function listPrompts(client) {
|
|
|
11
11
|
// Get a prompt
|
|
12
12
|
export async function getPrompt(client, name, args) {
|
|
13
13
|
try {
|
|
14
|
+
// Convert all arguments to strings for prompt arguments
|
|
15
|
+
const stringArgs = {};
|
|
16
|
+
if (args) {
|
|
17
|
+
for (const [key, value] of Object.entries(args)) {
|
|
18
|
+
if (typeof value === "string") {
|
|
19
|
+
stringArgs[key] = value;
|
|
20
|
+
}
|
|
21
|
+
else if (value === null || value === undefined) {
|
|
22
|
+
stringArgs[key] = String(value);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
stringArgs[key] = JSON.stringify(value);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
14
29
|
const response = await client.getPrompt({
|
|
15
30
|
name,
|
|
16
|
-
arguments:
|
|
31
|
+
arguments: stringArgs,
|
|
17
32
|
});
|
|
18
33
|
return response;
|
|
19
34
|
}
|
package/build/client/tools.js
CHANGED
|
@@ -49,8 +49,18 @@ export async function callTool(client, name, args) {
|
|
|
49
49
|
const tool = tools.find((t) => t.name === name);
|
|
50
50
|
let convertedArgs = args;
|
|
51
51
|
if (tool) {
|
|
52
|
-
// Convert parameters based on the tool's schema
|
|
53
|
-
|
|
52
|
+
// Convert parameters based on the tool's schema, but only for string values
|
|
53
|
+
// since we now accept pre-parsed values from the CLI
|
|
54
|
+
const stringArgs = {};
|
|
55
|
+
for (const [key, value] of Object.entries(args)) {
|
|
56
|
+
if (typeof value === "string") {
|
|
57
|
+
stringArgs[key] = value;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (Object.keys(stringArgs).length > 0) {
|
|
61
|
+
const convertedStringArgs = convertParameters(tool, stringArgs);
|
|
62
|
+
convertedArgs = { ...args, ...convertedStringArgs };
|
|
63
|
+
}
|
|
54
64
|
}
|
|
55
65
|
const response = await client.callTool({
|
|
56
66
|
name: name,
|
package/build/index.js
CHANGED
|
@@ -4,7 +4,8 @@ import { Command } from "commander";
|
|
|
4
4
|
import { callTool, connect, disconnect, getPrompt, listPrompts, listResources, listResourceTemplates, listTools, readResource, setLoggingLevel, validLogLevels, } from "./client/index.js";
|
|
5
5
|
import { handleError } from "./error-handler.js";
|
|
6
6
|
import { createTransport } from "./transport.js";
|
|
7
|
-
|
|
7
|
+
import { awaitableLog } from "./utils/awaitable-log.js";
|
|
8
|
+
function createTransportOptions(target, transport, headers) {
|
|
8
9
|
if (target.length === 0) {
|
|
9
10
|
throw new Error("Target is required. Specify a URL or a command to execute.");
|
|
10
11
|
}
|
|
@@ -46,10 +47,11 @@ function createTransportOptions(target, transport) {
|
|
|
46
47
|
command: isUrl ? undefined : command,
|
|
47
48
|
args: isUrl ? undefined : commandArgs,
|
|
48
49
|
url: isUrl ? command : undefined,
|
|
50
|
+
headers,
|
|
49
51
|
};
|
|
50
52
|
}
|
|
51
53
|
async function callMethod(args) {
|
|
52
|
-
const transportOptions = createTransportOptions(args.target, args.transport);
|
|
54
|
+
const transportOptions = createTransportOptions(args.target, args.transport, args.headers);
|
|
53
55
|
const transport = createTransport(transportOptions);
|
|
54
56
|
const client = new Client({
|
|
55
57
|
name: "inspector-cli",
|
|
@@ -101,7 +103,7 @@ async function callMethod(args) {
|
|
|
101
103
|
else {
|
|
102
104
|
throw new Error(`Unsupported method: ${args.method}. Supported methods include: tools/list, tools/call, resources/list, resources/read, resources/templates/list, prompts/list, prompts/get, logging/setLevel`);
|
|
103
105
|
}
|
|
104
|
-
|
|
106
|
+
await awaitableLog(JSON.stringify(result, null, 2));
|
|
105
107
|
}
|
|
106
108
|
finally {
|
|
107
109
|
try {
|
|
@@ -119,6 +121,27 @@ function parseKeyValuePair(value, previous = {}) {
|
|
|
119
121
|
if (val === undefined || val === "") {
|
|
120
122
|
throw new Error(`Invalid parameter format: ${value}. Use key=value format.`);
|
|
121
123
|
}
|
|
124
|
+
// Try to parse as JSON first
|
|
125
|
+
let parsedValue;
|
|
126
|
+
try {
|
|
127
|
+
parsedValue = JSON.parse(val);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
// If JSON parsing fails, keep as string
|
|
131
|
+
parsedValue = val;
|
|
132
|
+
}
|
|
133
|
+
return { ...previous, [key]: parsedValue };
|
|
134
|
+
}
|
|
135
|
+
function parseHeaderPair(value, previous = {}) {
|
|
136
|
+
const colonIndex = value.indexOf(":");
|
|
137
|
+
if (colonIndex === -1) {
|
|
138
|
+
throw new Error(`Invalid header format: ${value}. Use "HeaderName: Value" format.`);
|
|
139
|
+
}
|
|
140
|
+
const key = value.slice(0, colonIndex).trim();
|
|
141
|
+
const val = value.slice(colonIndex + 1).trim();
|
|
142
|
+
if (key === "" || val === "") {
|
|
143
|
+
throw new Error(`Invalid header format: ${value}. Use "HeaderName: Value" format.`);
|
|
144
|
+
}
|
|
122
145
|
return { ...previous, [key]: val };
|
|
123
146
|
}
|
|
124
147
|
function parseArgs() {
|
|
@@ -171,7 +194,11 @@ function parseArgs() {
|
|
|
171
194
|
throw new Error(`Invalid transport type: ${value}. Valid types are: ${validTransports.join(", ")}`);
|
|
172
195
|
}
|
|
173
196
|
return value;
|
|
174
|
-
})
|
|
197
|
+
})
|
|
198
|
+
//
|
|
199
|
+
// HTTP headers
|
|
200
|
+
//
|
|
201
|
+
.option("--header <headers...>", 'HTTP headers as "HeaderName: Value" pairs (for HTTP/SSE transports)', parseHeaderPair, {});
|
|
175
202
|
// Parse only the arguments before --
|
|
176
203
|
program.parse(preArgs);
|
|
177
204
|
const options = program.opts();
|
|
@@ -184,6 +211,7 @@ function parseArgs() {
|
|
|
184
211
|
return {
|
|
185
212
|
target: finalArgs,
|
|
186
213
|
...options,
|
|
214
|
+
headers: options.header, // commander.js uses 'header' field, map to 'headers'
|
|
187
215
|
};
|
|
188
216
|
}
|
|
189
217
|
async function main() {
|
package/build/transport.js
CHANGED
|
@@ -38,10 +38,24 @@ export function createTransport(options) {
|
|
|
38
38
|
}
|
|
39
39
|
const url = new URL(options.url);
|
|
40
40
|
if (transportType === "sse") {
|
|
41
|
-
|
|
41
|
+
const transportOptions = options.headers
|
|
42
|
+
? {
|
|
43
|
+
requestInit: {
|
|
44
|
+
headers: options.headers,
|
|
45
|
+
},
|
|
46
|
+
}
|
|
47
|
+
: undefined;
|
|
48
|
+
return new SSEClientTransport(url, transportOptions);
|
|
42
49
|
}
|
|
43
50
|
if (transportType === "http") {
|
|
44
|
-
|
|
51
|
+
const transportOptions = options.headers
|
|
52
|
+
? {
|
|
53
|
+
requestInit: {
|
|
54
|
+
headers: options.headers,
|
|
55
|
+
},
|
|
56
|
+
}
|
|
57
|
+
: undefined;
|
|
58
|
+
return new StreamableHTTPClientTransport(url, transportOptions);
|
|
45
59
|
}
|
|
46
60
|
throw new Error(`Unsupported transport type: ${transportType}`);
|
|
47
61
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@modelcontextprotocol/inspector-cli",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.6",
|
|
4
4
|
"description": "CLI for the Model Context Protocol inspector",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Anthropic, PBC (https://anthropic.com)",
|
|
@@ -17,11 +17,14 @@
|
|
|
17
17
|
"scripts": {
|
|
18
18
|
"build": "tsc",
|
|
19
19
|
"postbuild": "node scripts/make-executable.js",
|
|
20
|
-
"test": "node scripts/cli-tests.js"
|
|
20
|
+
"test": "node scripts/cli-tests.js && node scripts/cli-tool-tests.js && node scripts/cli-header-tests.js",
|
|
21
|
+
"test:cli": "node scripts/cli-tests.js",
|
|
22
|
+
"test:cli-tools": "node scripts/cli-tool-tests.js",
|
|
23
|
+
"test:cli-headers": "node scripts/cli-header-tests.js"
|
|
21
24
|
},
|
|
22
25
|
"devDependencies": {},
|
|
23
26
|
"dependencies": {
|
|
24
|
-
"@modelcontextprotocol/sdk": "^1.17.
|
|
27
|
+
"@modelcontextprotocol/sdk": "^1.17.5",
|
|
25
28
|
"commander": "^13.1.0",
|
|
26
29
|
"spawn-rx": "^5.1.2"
|
|
27
30
|
}
|