@modelcontextprotocol/inspector 0.16.1 → 0.16.3

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
@@ -166,6 +166,12 @@ If you need to disable authentication (NOT RECOMMENDED), you can set the `DANGER
166
166
  DANGEROUSLY_OMIT_AUTH=true npm start
167
167
  ```
168
168
 
169
+ You can also set the token via the `MCP_PROXY_AUTH_TOKEN` environment variable when starting the server:
170
+
171
+ ```bash
172
+ MCP_PROXY_AUTH_TOKEN=$(openssl rand -hex 32) npm start
173
+ ```
174
+
169
175
  #### Local-only Binding
170
176
 
171
177
  By default, both the MCP Inspector proxy server and client bind only to `localhost` to prevent network access. This ensures they are not accessible from other devices on the network. If you need to bind to all interfaces for development purposes, you can override this with the `HOST` environment variable:
@@ -228,6 +234,78 @@ Example server configuration file:
228
234
  }
229
235
  ```
230
236
 
237
+ #### Transport Types in Config Files
238
+
239
+ The inspector automatically detects the transport type from your config file. You can specify different transport types:
240
+
241
+ **STDIO (default):**
242
+
243
+ ```json
244
+ {
245
+ "mcpServers": {
246
+ "my-stdio-server": {
247
+ "type": "stdio",
248
+ "command": "npx",
249
+ "args": ["@modelcontextprotocol/server-everything"]
250
+ }
251
+ }
252
+ }
253
+ ```
254
+
255
+ **SSE (Server-Sent Events):**
256
+
257
+ ```json
258
+ {
259
+ "mcpServers": {
260
+ "my-sse-server": {
261
+ "type": "sse",
262
+ "url": "http://localhost:3000/sse"
263
+ }
264
+ }
265
+ }
266
+ ```
267
+
268
+ **Streamable HTTP:**
269
+
270
+ ```json
271
+ {
272
+ "mcpServers": {
273
+ "my-http-server": {
274
+ "type": "streamable-http",
275
+ "url": "http://localhost:3000/mcp"
276
+ }
277
+ }
278
+ }
279
+ ```
280
+
281
+ #### Default Server Selection
282
+
283
+ You can launch the inspector without specifying a server name if your config has:
284
+
285
+ 1. **A single server** - automatically selected:
286
+
287
+ ```bash
288
+ # Automatically uses "my-server" if it's the only one
289
+ npx @modelcontextprotocol/inspector --config mcp.json
290
+ ```
291
+
292
+ 2. **A server named "default-server"** - automatically selected:
293
+
294
+ ```json
295
+ {
296
+ "mcpServers": {
297
+ "default-server": {
298
+ "command": "npx",
299
+ "args": ["@modelcontextprotocol/server-everything"]
300
+ },
301
+ "other-server": {
302
+ "command": "node",
303
+ "args": ["other.js"]
304
+ }
305
+ }
306
+ }
307
+ ```
308
+
231
309
  > **Tip:** You can easily generate this configuration format using the **Server Entry** and **Servers File** buttons in the Inspector UI, as described in the Servers File Export section above.
232
310
 
233
311
  You can also set the initial `transport` type, `serverUrl`, `serverCommand`, and `serverArgs` via query params, for example:
@@ -309,7 +387,7 @@ npx @modelcontextprotocol/inspector --cli node build/index.js --method prompts/l
309
387
  npx @modelcontextprotocol/inspector --cli https://my-mcp-server.example.com
310
388
 
311
389
  # Connect to a remote MCP server (with Streamable HTTP transport)
312
- npx @modelcontextprotocol/inspector --cli https://my-mcp-server.example.com --transport http
390
+ npx @modelcontextprotocol/inspector --cli https://my-mcp-server.example.com --transport http --method tools/list
313
391
 
314
392
  # Call a tool on a remote server
315
393
  npx @modelcontextprotocol/inspector --cli https://my-mcp-server.example.com --method tools/call --tool-name remotetool --tool-arg param=value
package/cli/build/cli.js CHANGED
@@ -32,8 +32,26 @@ async function runWebClient(args) {
32
32
  cancelled = true;
33
33
  abort.abort();
34
34
  });
35
+ // Build arguments to pass to start.js
36
+ const startArgs = [];
37
+ // Pass environment variables
38
+ for (const [key, value] of Object.entries(args.envArgs)) {
39
+ startArgs.push("-e", `${key}=${value}`);
40
+ }
41
+ // Pass transport type if specified
42
+ if (args.transport) {
43
+ startArgs.push("--transport", args.transport);
44
+ }
45
+ // Pass server URL if specified
46
+ if (args.serverUrl) {
47
+ startArgs.push("--server-url", args.serverUrl);
48
+ }
49
+ // Pass command and args (using -- to separate them)
50
+ if (args.command) {
51
+ startArgs.push("--", args.command, ...args.args);
52
+ }
35
53
  try {
36
- await spawnPromise("node", [inspectorClientPath], {
54
+ await spawnPromise("node", [inspectorClientPath, ...startArgs], {
37
55
  signal: abort.signal,
38
56
  echoOutput: true,
39
57
  });
@@ -53,7 +71,17 @@ async function runCli(args) {
53
71
  abort.abort();
54
72
  });
55
73
  try {
56
- await spawnPromise("node", [cliPath, args.command, ...args.args], {
74
+ // Build CLI arguments
75
+ const cliArgs = [cliPath];
76
+ // Add transport flag if specified
77
+ if (args.transport && args.transport !== "stdio") {
78
+ // Convert streamable-http back to http for CLI mode
79
+ const cliTransport = args.transport === "streamable-http" ? "http" : args.transport;
80
+ cliArgs.push("--transport", cliTransport);
81
+ }
82
+ // Add command and remaining args
83
+ cliArgs.push(args.command, ...args.args);
84
+ await spawnPromise("node", cliArgs, {
57
85
  env: { ...process.env, ...args.envArgs },
58
86
  signal: abort.signal,
59
87
  echoOutput: true,
@@ -114,38 +142,88 @@ function parseArgs() {
114
142
  .option("-e <env>", "environment variables in KEY=VALUE format", parseKeyValuePair, {})
115
143
  .option("--config <path>", "config file path")
116
144
  .option("--server <n>", "server name from config file")
117
- .option("--cli", "enable CLI mode");
145
+ .option("--cli", "enable CLI mode")
146
+ .option("--transport <type>", "transport type (stdio, sse, http)")
147
+ .option("--server-url <url>", "server URL for SSE/HTTP transport");
118
148
  // Parse only the arguments before --
119
149
  program.parse(preArgs);
120
150
  const options = program.opts();
121
151
  const remainingArgs = program.args;
122
152
  // Add back any arguments that came after --
123
153
  const finalArgs = [...remainingArgs, ...postArgs];
124
- // Validate that config and server are provided together
125
- if ((options.config && !options.server) ||
126
- (!options.config && options.server)) {
127
- throw new Error("Both --config and --server must be provided together. If you specify one, you must specify the other.");
154
+ // Validate config and server options
155
+ if (!options.config && options.server) {
156
+ throw new Error("--server requires --config to be specified");
157
+ }
158
+ // If config is provided without server, try to auto-select
159
+ if (options.config && !options.server) {
160
+ const configContent = fs.readFileSync(path.isAbsolute(options.config)
161
+ ? options.config
162
+ : path.resolve(process.cwd(), options.config), "utf8");
163
+ const parsedConfig = JSON.parse(configContent);
164
+ const servers = Object.keys(parsedConfig.mcpServers || {});
165
+ if (servers.length === 1) {
166
+ // Use the only server if there's just one
167
+ options.server = servers[0];
168
+ }
169
+ else if (servers.length === 0) {
170
+ throw new Error("No servers found in config file");
171
+ }
172
+ else {
173
+ // Multiple servers, require explicit selection
174
+ throw new Error(`Multiple servers found in config file. Please specify one with --server.\nAvailable servers: ${servers.join(", ")}`);
175
+ }
128
176
  }
129
177
  // If config file is specified, load and use the options from the file. We must merge the args
130
178
  // from the command line and the file together, or we will miss the method options (--method,
131
179
  // etc.)
132
180
  if (options.config && options.server) {
133
181
  const config = loadConfigFile(options.config, options.server);
134
- return {
135
- command: config.command,
136
- args: [...(config.args || []), ...finalArgs],
137
- envArgs: { ...(config.env || {}), ...(options.e || {}) },
138
- cli: options.cli || false,
139
- };
182
+ if (config.type === "stdio") {
183
+ return {
184
+ command: config.command,
185
+ args: [...(config.args || []), ...finalArgs],
186
+ envArgs: { ...(config.env || {}), ...(options.e || {}) },
187
+ cli: options.cli || false,
188
+ transport: "stdio",
189
+ };
190
+ }
191
+ else if (config.type === "sse" || config.type === "streamable-http") {
192
+ return {
193
+ command: config.url,
194
+ args: finalArgs,
195
+ envArgs: options.e || {},
196
+ cli: options.cli || false,
197
+ transport: config.type,
198
+ serverUrl: config.url,
199
+ };
200
+ }
201
+ else {
202
+ // Backwards compatibility: if no type field, assume stdio
203
+ return {
204
+ command: config.command || "",
205
+ args: [...(config.args || []), ...finalArgs],
206
+ envArgs: { ...(config.env || {}), ...(options.e || {}) },
207
+ cli: options.cli || false,
208
+ transport: "stdio",
209
+ };
210
+ }
140
211
  }
141
212
  // Otherwise use command line arguments
142
213
  const command = finalArgs[0] || "";
143
214
  const args = finalArgs.slice(1);
215
+ // Map "http" shorthand to "streamable-http"
216
+ let transport = options.transport;
217
+ if (transport === "http") {
218
+ transport = "streamable-http";
219
+ }
144
220
  return {
145
221
  command,
146
222
  args,
147
223
  envArgs: options.e || {},
148
224
  cli: options.cli || false,
225
+ transport: transport,
226
+ serverUrl: options.serverUrl,
149
227
  };
150
228
  }
151
229
  async function main() {
@@ -155,7 +233,7 @@ async function main() {
155
233
  try {
156
234
  const args = parseArgs();
157
235
  if (args.cli) {
158
- runCli(args);
236
+ await runCli(args);
159
237
  }
160
238
  else {
161
239
  await runWebClient(args);
@@ -8,6 +8,11 @@ export const validLogLevels = [
8
8
  export async function connect(client, transport) {
9
9
  try {
10
10
  await client.connect(transport);
11
+ if (client.getServerCapabilities()?.logging) {
12
+ // default logging level is undefined in the spec, but the user of the
13
+ // inspector most likely wants debug.
14
+ await client.setLoggingLevel("debug");
15
+ }
11
16
  }
12
17
  catch (error) {
13
18
  throw new Error(`Failed to connect to MCP server: ${error instanceof Error ? error.message : String(error)}`);
@@ -193,6 +193,8 @@ async function main() {
193
193
  try {
194
194
  const args = parseArgs();
195
195
  await callMethod(args);
196
+ // Explicitly exit to ensure process terminates in CI
197
+ process.exit(0);
196
198
  }
197
199
  catch (error) {
198
200
  handleError(error);
@@ -2,20 +2,6 @@ import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
2
2
  import { getDefaultEnvironment, StdioClientTransport, } from "@modelcontextprotocol/sdk/client/stdio.js";
3
3
  import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
4
4
  import { findActualExecutable } from "spawn-rx";
5
- function createSSETransport(options) {
6
- const baseUrl = new URL(options.url ?? "");
7
- const sseUrl = baseUrl.pathname.endsWith("/sse")
8
- ? baseUrl
9
- : new URL("/sse", baseUrl);
10
- return new SSEClientTransport(sseUrl);
11
- }
12
- function createHTTPTransport(options) {
13
- const baseUrl = new URL(options.url ?? "");
14
- const mcpUrl = baseUrl.pathname.endsWith("/mcp")
15
- ? baseUrl
16
- : new URL("/mcp", baseUrl);
17
- return new StreamableHTTPClientTransport(mcpUrl);
18
- }
19
5
  function createStdioTransport(options) {
20
6
  let args = [];
21
7
  if (options.args !== undefined) {
@@ -46,11 +32,16 @@ export function createTransport(options) {
46
32
  if (transportType === "stdio") {
47
33
  return createStdioTransport(options);
48
34
  }
35
+ // If not STDIO, then it must be either SSE or HTTP.
36
+ if (!options.url) {
37
+ throw new Error("URL must be provided for SSE or HTTP transport types.");
38
+ }
39
+ const url = new URL(options.url);
49
40
  if (transportType === "sse") {
50
- return createSSETransport(options);
41
+ return new SSEClientTransport(url);
51
42
  }
52
43
  if (transportType === "http") {
53
- return createHTTPTransport(options);
44
+ return new StreamableHTTPClientTransport(url);
54
45
  }
55
46
  throw new Error(`Unsupported transport type: ${transportType}`);
56
47
  }
@@ -28,8 +28,15 @@ function getClientUrl(port, authDisabled, sessionToken, serverPort) {
28
28
  }
29
29
 
30
30
  async function startDevServer(serverOptions) {
31
- const { SERVER_PORT, CLIENT_PORT, sessionToken, envVars, abort } =
32
- serverOptions;
31
+ const {
32
+ SERVER_PORT,
33
+ CLIENT_PORT,
34
+ sessionToken,
35
+ envVars,
36
+ abort,
37
+ transport,
38
+ serverUrl,
39
+ } = serverOptions;
33
40
  const serverCommand = "npx";
34
41
  const serverArgs = ["tsx", "watch", "--clear-screen=false", "src/index.ts"];
35
42
  const isWindows = process.platform === "win32";
@@ -40,8 +47,10 @@ async function startDevServer(serverOptions) {
40
47
  ...process.env,
41
48
  SERVER_PORT,
42
49
  CLIENT_PORT,
43
- MCP_PROXY_TOKEN: sessionToken,
50
+ MCP_PROXY_AUTH_TOKEN: sessionToken,
44
51
  MCP_ENV_VARS: JSON.stringify(envVars),
52
+ ...(transport ? { MCP_TRANSPORT: transport } : {}),
53
+ ...(serverUrl ? { MCP_SERVER_URL: serverUrl } : {}),
45
54
  },
46
55
  signal: abort.signal,
47
56
  echoOutput: true,
@@ -78,6 +87,8 @@ async function startProdServer(serverOptions) {
78
87
  abort,
79
88
  command,
80
89
  mcpServerArgs,
90
+ transport,
91
+ serverUrl,
81
92
  } = serverOptions;
82
93
  const inspectorServerPath = resolve(
83
94
  __dirname,
@@ -91,15 +102,19 @@ async function startProdServer(serverOptions) {
91
102
  "node",
92
103
  [
93
104
  inspectorServerPath,
94
- ...(command ? [`--env`, command] : []),
95
- ...(mcpServerArgs ? [`--args=${mcpServerArgs.join(" ")}`] : []),
105
+ ...(command ? [`--command=${command}`] : []),
106
+ ...(mcpServerArgs && mcpServerArgs.length > 0
107
+ ? [`--args=${mcpServerArgs.join(" ")}`]
108
+ : []),
109
+ ...(transport ? [`--transport=${transport}`] : []),
110
+ ...(serverUrl ? [`--server-url=${serverUrl}`] : []),
96
111
  ],
97
112
  {
98
113
  env: {
99
114
  ...process.env,
100
115
  SERVER_PORT,
101
116
  CLIENT_PORT,
102
- MCP_PROXY_TOKEN: sessionToken,
117
+ MCP_PROXY_AUTH_TOKEN: sessionToken,
103
118
  MCP_ENV_VARS: JSON.stringify(envVars),
104
119
  },
105
120
  signal: abort.signal,
@@ -206,6 +221,8 @@ async function main() {
206
221
  let command = null;
207
222
  let parsingFlags = true;
208
223
  let isDev = false;
224
+ let transport = null;
225
+ let serverUrl = null;
209
226
 
210
227
  for (let i = 0; i < args.length; i++) {
211
228
  const arg = args[i];
@@ -220,6 +237,16 @@ async function main() {
220
237
  continue;
221
238
  }
222
239
 
240
+ if (parsingFlags && arg === "--transport" && i + 1 < args.length) {
241
+ transport = args[++i];
242
+ continue;
243
+ }
244
+
245
+ if (parsingFlags && arg === "--server-url" && i + 1 < args.length) {
246
+ serverUrl = args[++i];
247
+ continue;
248
+ }
249
+
223
250
  if (parsingFlags && arg === "-e" && i + 1 < args.length) {
224
251
  const envVar = args[++i];
225
252
  const equalsIndex = envVar.indexOf("=");
@@ -247,8 +274,9 @@ async function main() {
247
274
  : "Starting MCP inspector...",
248
275
  );
249
276
 
250
- // Generate session token for authentication
251
- const sessionToken = randomBytes(32).toString("hex");
277
+ // Use provided token from environment or generate a new one
278
+ const sessionToken =
279
+ process.env.MCP_PROXY_AUTH_TOKEN || randomBytes(32).toString("hex");
252
280
  const authDisabled = !!process.env.DANGEROUSLY_OMIT_AUTH;
253
281
 
254
282
  const abort = new AbortController();
@@ -270,6 +298,8 @@ async function main() {
270
298
  abort,
271
299
  command,
272
300
  mcpServerArgs,
301
+ transport,
302
+ serverUrl,
273
303
  };
274
304
 
275
305
  const result = isDev
@@ -1,4 +1,4 @@
1
- import { u as useToast, r as reactExports, j as jsxRuntimeExports, S as SESSION_KEYS, I as InspectorOAuthClientProvider, a as auth } from "./index-CPgI0-gs.js";
1
+ import { u as useToast, r as reactExports, j as jsxRuntimeExports, S as SESSION_KEYS, I as InspectorOAuthClientProvider, a as auth } from "./index-CHDvjhl9.js";
2
2
  import { p as parseOAuthCallbackParams, g as generateOAuthErrorDescription } from "./oauthUtils-DTcoXpSP.js";
3
3
  const OAuthCallback = ({ onConnect }) => {
4
4
  const { toast } = useToast();
@@ -1,4 +1,4 @@
1
- import { r as reactExports, S as SESSION_KEYS, j as jsxRuntimeExports } from "./index-CPgI0-gs.js";
1
+ import { r as reactExports, S as SESSION_KEYS, j as jsxRuntimeExports } from "./index-CHDvjhl9.js";
2
2
  import { p as parseOAuthCallbackParams, g as generateOAuthErrorDescription } from "./oauthUtils-DTcoXpSP.js";
3
3
  const OAuthDebugCallback = ({ onConnect }) => {
4
4
  reactExports.useEffect(() => {
@@ -56,8 +56,6 @@ pre[class*="language-"] {
56
56
  -moz-tab-size: 4;
57
57
  -o-tab-size: 4;
58
58
  tab-size: 4;
59
-
60
- -webkit-hyphens: none;
61
59
  hyphens: none;
62
60
  }
63
61
 
@@ -757,6 +755,9 @@ video {
757
755
  .collapse {
758
756
  visibility: collapse;
759
757
  }
758
+ .static {
759
+ position: static;
760
+ }
760
761
  .fixed {
761
762
  position: fixed;
762
763
  }
@@ -994,6 +995,9 @@ video {
994
995
  .w-full {
995
996
  width: 100%;
996
997
  }
998
+ .min-w-0 {
999
+ min-width: 0px;
1000
+ }
997
1001
  .min-w-\[8rem\] {
998
1002
  min-width: 8rem;
999
1003
  }
@@ -1171,6 +1175,9 @@ video {
1171
1175
  .border {
1172
1176
  border-width: 1px;
1173
1177
  }
1178
+ .border-2 {
1179
+ border-width: 2px;
1180
+ }
1174
1181
  .border-b {
1175
1182
  border-bottom-width: 1px;
1176
1183
  }
@@ -1191,6 +1198,10 @@ video {
1191
1198
  --tw-border-opacity: 1;
1192
1199
  border-color: rgb(147 197 253 / var(--tw-border-opacity, 1));
1193
1200
  }
1201
+ .border-blue-500 {
1202
+ --tw-border-opacity: 1;
1203
+ border-color: rgb(59 130 246 / var(--tw-border-opacity, 1));
1204
+ }
1194
1205
  .border-border {
1195
1206
  border-color: hsl(var(--border));
1196
1207
  }
@@ -1204,6 +1215,10 @@ video {
1204
1215
  --tw-border-opacity: 1;
1205
1216
  border-color: rgb(229 231 235 / var(--tw-border-opacity, 1));
1206
1217
  }
1218
+ .border-gray-300 {
1219
+ --tw-border-opacity: 1;
1220
+ border-color: rgb(209 213 219 / var(--tw-border-opacity, 1));
1221
+ }
1207
1222
  .border-green-200 {
1208
1223
  --tw-border-opacity: 1;
1209
1224
  border-color: rgb(187 247 208 / var(--tw-border-opacity, 1));
@@ -1226,6 +1241,9 @@ video {
1226
1241
  --tw-border-opacity: 1;
1227
1242
  border-color: rgb(239 68 68 / var(--tw-border-opacity, 1));
1228
1243
  }
1244
+ .border-t-transparent {
1245
+ border-top-color: transparent;
1246
+ }
1229
1247
  .bg-accent {
1230
1248
  background-color: hsl(var(--accent));
1231
1249
  }
@@ -1325,6 +1343,10 @@ video {
1325
1343
  .p-6 {
1326
1344
  padding: 1.5rem;
1327
1345
  }
1346
+ .px-1 {
1347
+ padding-left: 0.25rem;
1348
+ padding-right: 0.25rem;
1349
+ }
1328
1350
  .px-12 {
1329
1351
  padding-left: 3rem;
1330
1352
  padding-right: 3rem;
@@ -1349,6 +1371,10 @@ video {
1349
1371
  padding-top: 0px;
1350
1372
  padding-bottom: 0px;
1351
1373
  }
1374
+ .py-0\.5 {
1375
+ padding-top: 0.125rem;
1376
+ padding-bottom: 0.125rem;
1377
+ }
1352
1378
  .py-1 {
1353
1379
  padding-top: 0.25rem;
1354
1380
  padding-bottom: 0.25rem;
@@ -1424,6 +1450,9 @@ video {
1424
1450
  .leading-none {
1425
1451
  line-height: 1;
1426
1452
  }
1453
+ .leading-relaxed {
1454
+ line-height: 1.625;
1455
+ }
1427
1456
  .tracking-tight {
1428
1457
  letter-spacing: -0.025em;
1429
1458
  }
@@ -1600,9 +1629,7 @@ video {
1600
1629
  filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
1601
1630
  }
1602
1631
  .transition {
1603
- transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter;
1604
1632
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
1605
- transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter;
1606
1633
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
1607
1634
  transition-duration: 150ms;
1608
1635
  }
@@ -1796,6 +1823,11 @@ h1 {
1796
1823
  color: rgb(29 78 216 / var(--tw-text-opacity, 1));
1797
1824
  }
1798
1825
 
1826
+ .hover\:text-blue-800:hover {
1827
+ --tw-text-opacity: 1;
1828
+ color: rgb(30 64 175 / var(--tw-text-opacity, 1));
1829
+ }
1830
+
1799
1831
  .hover\:text-foreground:hover {
1800
1832
  color: hsl(var(--foreground));
1801
1833
  }
@@ -1837,6 +1869,11 @@ h1 {
1837
1869
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
1838
1870
  }
1839
1871
 
1872
+ .focus\:ring-blue-500:focus {
1873
+ --tw-ring-opacity: 1;
1874
+ --tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1));
1875
+ }
1876
+
1840
1877
  .focus\:ring-ring:focus {
1841
1878
  --tw-ring-color: hsl(var(--ring));
1842
1879
  }
@@ -1862,10 +1899,19 @@ h1 {
1862
1899
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
1863
1900
  }
1864
1901
 
1902
+ .focus-visible\:ring-blue-500:focus-visible {
1903
+ --tw-ring-opacity: 1;
1904
+ --tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1));
1905
+ }
1906
+
1865
1907
  .focus-visible\:ring-ring:focus-visible {
1866
1908
  --tw-ring-color: hsl(var(--ring));
1867
1909
  }
1868
1910
 
1911
+ .focus-visible\:ring-offset-1:focus-visible {
1912
+ --tw-ring-offset-width: 1px;
1913
+ }
1914
+
1869
1915
  .focus-visible\:ring-offset-2:focus-visible {
1870
1916
  --tw-ring-offset-width: 2px;
1871
1917
  }
@@ -2139,11 +2185,21 @@ h1 {
2139
2185
  border-color: hsl(var(--destructive));
2140
2186
  }
2141
2187
 
2188
+ .dark\:border-gray-600:is(.dark *) {
2189
+ --tw-border-opacity: 1;
2190
+ border-color: rgb(75 85 99 / var(--tw-border-opacity, 1));
2191
+ }
2192
+
2142
2193
  .dark\:border-gray-800:is(.dark *) {
2143
2194
  --tw-border-opacity: 1;
2144
2195
  border-color: rgb(31 41 55 / var(--tw-border-opacity, 1));
2145
2196
  }
2146
2197
 
2198
+ .dark\:border-red-800:is(.dark *) {
2199
+ --tw-border-opacity: 1;
2200
+ border-color: rgb(153 27 27 / var(--tw-border-opacity, 1));
2201
+ }
2202
+
2147
2203
  .dark\:bg-blue-900:is(.dark *) {
2148
2204
  --tw-bg-opacity: 1;
2149
2205
  background-color: rgb(30 58 138 / var(--tw-bg-opacity, 1));
@@ -2169,6 +2225,10 @@ h1 {
2169
2225
  background-color: rgb(127 29 29 / var(--tw-bg-opacity, 1));
2170
2226
  }
2171
2227
 
2228
+ .dark\:bg-red-900\/20:is(.dark *) {
2229
+ background-color: rgb(127 29 29 / 0.2);
2230
+ }
2231
+
2172
2232
  .dark\:bg-yellow-900:is(.dark *) {
2173
2233
  --tw-bg-opacity: 1;
2174
2234
  background-color: rgb(113 63 18 / var(--tw-bg-opacity, 1));
@@ -2179,6 +2239,11 @@ h1 {
2179
2239
  color: rgb(191 219 254 / var(--tw-text-opacity, 1));
2180
2240
  }
2181
2241
 
2242
+ .dark\:text-blue-400:is(.dark *) {
2243
+ --tw-text-opacity: 1;
2244
+ color: rgb(96 165 250 / var(--tw-text-opacity, 1));
2245
+ }
2246
+
2182
2247
  .dark\:text-gray-100:is(.dark *) {
2183
2248
  --tw-text-opacity: 1;
2184
2249
  color: rgb(243 244 246 / var(--tw-text-opacity, 1));
@@ -2209,6 +2274,11 @@ h1 {
2209
2274
  color: rgb(254 202 202 / var(--tw-text-opacity, 1));
2210
2275
  }
2211
2276
 
2277
+ .dark\:text-red-400:is(.dark *) {
2278
+ --tw-text-opacity: 1;
2279
+ color: rgb(248 113 113 / var(--tw-text-opacity, 1));
2280
+ }
2281
+
2212
2282
  .dark\:text-white:is(.dark *) {
2213
2283
  --tw-text-opacity: 1;
2214
2284
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
@@ -2236,6 +2306,11 @@ h1 {
2236
2306
  background-color: hsl(var(--secondary));
2237
2307
  }
2238
2308
 
2309
+ .dark\:hover\:text-blue-300:hover:is(.dark *) {
2310
+ --tw-text-opacity: 1;
2311
+ color: rgb(147 197 253 / var(--tw-text-opacity, 1));
2312
+ }
2313
+
2239
2314
  .group:hover .dark\:group-hover\:text-gray-100:is(.dark *) {
2240
2315
  --tw-text-opacity: 1;
2241
2316
  color: rgb(243 244 246 / var(--tw-text-opacity, 1));