@evantahler/mcpx 0.18.3 → 0.18.5
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 +63 -63
- package/src/cli.ts +46 -54
- package/src/client/browser.ts +15 -15
- package/src/client/debug-fetch.ts +53 -56
- package/src/client/elicitation.ts +279 -291
- package/src/client/http.ts +1 -1
- package/src/client/manager.ts +481 -514
- package/src/client/oauth.ts +272 -282
- package/src/client/sse.ts +1 -1
- package/src/client/stdio.ts +7 -7
- package/src/client/trace.ts +146 -152
- package/src/client/transport-options.ts +20 -20
- package/src/commands/add.ts +160 -165
- package/src/commands/allow.ts +141 -142
- package/src/commands/auth.ts +86 -90
- package/src/commands/check-update.ts +49 -53
- package/src/commands/deny.ts +114 -117
- package/src/commands/exec.ts +218 -222
- package/src/commands/index.ts +41 -41
- package/src/commands/info.ts +48 -50
- package/src/commands/list.ts +49 -49
- package/src/commands/ping.ts +47 -50
- package/src/commands/prompt.ts +40 -50
- package/src/commands/remove.ts +54 -56
- package/src/commands/resource.ts +31 -36
- package/src/commands/search.ts +35 -39
- package/src/commands/servers.ts +44 -48
- package/src/commands/skill.ts +89 -95
- package/src/commands/task.ts +50 -60
- package/src/commands/upgrade.ts +191 -208
- package/src/commands/with-command.ts +27 -29
- package/src/config/env.ts +26 -28
- package/src/config/loader.ts +99 -102
- package/src/config/schemas.ts +78 -87
- package/src/constants.ts +17 -17
- package/src/context.ts +51 -51
- package/src/lib/client-settings.ts +127 -140
- package/src/lib/input.ts +23 -26
- package/src/output/format-output.ts +12 -16
- package/src/output/format-table.ts +39 -42
- package/src/output/formatter.ts +790 -814
- package/src/output/logger.ts +140 -152
- package/src/sdk.ts +283 -291
- package/src/search/index.ts +50 -54
- package/src/search/indexer.ts +65 -65
- package/src/search/keyword.ts +54 -54
- package/src/search/semantic.ts +39 -39
- package/src/search/staleness.ts +3 -3
- package/src/search/types.ts +4 -4
- package/src/update/background.ts +51 -51
- package/src/update/cache.ts +21 -21
- package/src/update/checker.ts +81 -86
- package/src/validation/schema.ts +52 -58
package/src/output/logger.ts
CHANGED
|
@@ -1,172 +1,160 @@
|
|
|
1
|
+
import { dim, red, yellow } from "ansis";
|
|
1
2
|
import { createSpinner } from "nanospinner";
|
|
2
|
-
import { dim, yellow, red } from "ansis";
|
|
3
3
|
import type { FormatOptions } from "./formatter.ts";
|
|
4
4
|
|
|
5
5
|
/** MCP log levels ordered by severity (RFC 5424) */
|
|
6
|
-
const LOG_LEVELS = [
|
|
7
|
-
"debug",
|
|
8
|
-
"info",
|
|
9
|
-
"notice",
|
|
10
|
-
"warning",
|
|
11
|
-
"error",
|
|
12
|
-
"critical",
|
|
13
|
-
"alert",
|
|
14
|
-
"emergency",
|
|
15
|
-
] as const;
|
|
6
|
+
const LOG_LEVELS = ["debug", "info", "notice", "warning", "error", "critical", "alert", "emergency"] as const;
|
|
16
7
|
|
|
17
8
|
type LogLevel = (typeof LOG_LEVELS)[number];
|
|
18
9
|
|
|
19
10
|
function logLevelIndex(level: string): number {
|
|
20
|
-
|
|
21
|
-
|
|
11
|
+
const idx = LOG_LEVELS.indexOf(level as LogLevel);
|
|
12
|
+
return idx === -1 ? 0 : idx;
|
|
22
13
|
}
|
|
23
14
|
|
|
24
15
|
function colorForLevel(level: string): (s: string) => string {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
16
|
+
switch (level) {
|
|
17
|
+
case "debug":
|
|
18
|
+
return dim;
|
|
19
|
+
case "warning":
|
|
20
|
+
return yellow;
|
|
21
|
+
case "error":
|
|
22
|
+
case "critical":
|
|
23
|
+
case "alert":
|
|
24
|
+
case "emergency":
|
|
25
|
+
return red;
|
|
26
|
+
default:
|
|
27
|
+
return (s: string) => s;
|
|
28
|
+
}
|
|
38
29
|
}
|
|
39
30
|
|
|
40
31
|
export interface Spinner {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
32
|
+
update(text: string): void;
|
|
33
|
+
success(text?: string): void;
|
|
34
|
+
error(text?: string): void;
|
|
35
|
+
stop(): void;
|
|
45
36
|
}
|
|
46
37
|
|
|
47
38
|
class Logger {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
},
|
|
168
|
-
};
|
|
169
|
-
}
|
|
39
|
+
private static instance: Logger;
|
|
40
|
+
private activeSpinner: ReturnType<typeof createSpinner> | null = null;
|
|
41
|
+
private formatOptions: FormatOptions = {};
|
|
42
|
+
|
|
43
|
+
private constructor() {}
|
|
44
|
+
|
|
45
|
+
static getInstance(): Logger {
|
|
46
|
+
if (!Logger.instance) {
|
|
47
|
+
Logger.instance = new Logger();
|
|
48
|
+
}
|
|
49
|
+
return Logger.instance;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Set format options (called once during context setup) */
|
|
53
|
+
configure(options: FormatOptions): void {
|
|
54
|
+
this.formatOptions = options;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Whether interactive output is suppressed (JSON mode or non-TTY stderr) */
|
|
58
|
+
private isSilent(): boolean {
|
|
59
|
+
return !!this.formatOptions.json || !(process.stderr.isTTY ?? false);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Write a line to stderr, pausing any active spinner around the write */
|
|
63
|
+
private writeStderr(msg: string): void {
|
|
64
|
+
if (this.activeSpinner) {
|
|
65
|
+
this.activeSpinner.clear();
|
|
66
|
+
process.stderr.write(`${msg}\n`);
|
|
67
|
+
this.activeSpinner.render();
|
|
68
|
+
} else {
|
|
69
|
+
process.stderr.write(`${msg}\n`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Info-level message (dim text on stderr). Suppressed in JSON/non-TTY mode. */
|
|
74
|
+
info(msg: string): void {
|
|
75
|
+
if (this.isSilent()) return;
|
|
76
|
+
this.writeStderr(dim(msg));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Warning message (yellow text on stderr). Suppressed in JSON/non-TTY mode. */
|
|
80
|
+
warn(msg: string): void {
|
|
81
|
+
if (this.isSilent()) return;
|
|
82
|
+
this.writeStderr(yellow(msg));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Error message (red text on stderr). Always writes. */
|
|
86
|
+
error(msg: string): void {
|
|
87
|
+
this.writeStderr(red(msg));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Debug/verbose message (dim text on stderr). Only when verbose is enabled. */
|
|
91
|
+
debug(msg: string): void {
|
|
92
|
+
if (!this.formatOptions.verbose || this.isSilent()) return;
|
|
93
|
+
this.writeStderr(dim(msg));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Write a raw string to stderr. Spinner-aware but no formatting or newline added. */
|
|
97
|
+
writeRaw(msg: string): void {
|
|
98
|
+
if (this.activeSpinner) {
|
|
99
|
+
this.activeSpinner.clear();
|
|
100
|
+
process.stderr.write(msg);
|
|
101
|
+
this.activeSpinner.render();
|
|
102
|
+
} else {
|
|
103
|
+
process.stderr.write(msg);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Display a structured server log message. Suppressed if below configured log level. */
|
|
108
|
+
logServerMessage(serverName: string, params: { level: string; logger?: string; data: unknown }): void {
|
|
109
|
+
const minLevel = this.formatOptions.logLevel ?? "warning";
|
|
110
|
+
if (logLevelIndex(params.level) < logLevelIndex(minLevel)) return;
|
|
111
|
+
|
|
112
|
+
if (this.formatOptions.json) {
|
|
113
|
+
// JSON mode: structured object to stderr
|
|
114
|
+
const obj = { server: serverName, ...params };
|
|
115
|
+
process.stderr.write(`${JSON.stringify(obj)}\n`);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (!(process.stderr.isTTY ?? false)) return;
|
|
120
|
+
|
|
121
|
+
const prefix = params.logger ? `[${serverName}/${params.logger}]` : `[${serverName}]`;
|
|
122
|
+
const dataStr = typeof params.data === "string" ? params.data : JSON.stringify(params.data);
|
|
123
|
+
const line = `${prefix} ${params.level}: ${dataStr}`;
|
|
124
|
+
const color = colorForLevel(params.level);
|
|
125
|
+
this.writeStderr(color(line));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** Start a spinner. Returns the Spinner interface. */
|
|
129
|
+
startSpinner(text: string, options?: FormatOptions): Spinner {
|
|
130
|
+
const opts = options ?? this.formatOptions;
|
|
131
|
+
|
|
132
|
+
// No spinner in JSON/piped/verbose mode — verbose writeRaw output conflicts with spinner rendering
|
|
133
|
+
if (opts.json || opts.verbose || !(process.stderr.isTTY ?? false)) {
|
|
134
|
+
return { update() {}, success() {}, error() {}, stop() {} };
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const spinner = createSpinner(text, { stream: process.stderr }).start();
|
|
138
|
+
this.activeSpinner = spinner;
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
update: (text: string) => {
|
|
142
|
+
spinner.update({ text });
|
|
143
|
+
},
|
|
144
|
+
success: (text?: string) => {
|
|
145
|
+
spinner.success({ text });
|
|
146
|
+
this.activeSpinner = null;
|
|
147
|
+
},
|
|
148
|
+
error: (text?: string) => {
|
|
149
|
+
spinner.error({ text });
|
|
150
|
+
this.activeSpinner = null;
|
|
151
|
+
},
|
|
152
|
+
stop: () => {
|
|
153
|
+
spinner.stop();
|
|
154
|
+
this.activeSpinner = null;
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
}
|
|
170
158
|
}
|
|
171
159
|
|
|
172
160
|
/** The singleton logger instance */
|