@debugai/mcp 1.0.0 → 1.1.0

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
@@ -14,6 +14,19 @@ This package is the same server, standalone. No VS Code required.
14
14
  2. Copy your API key (`dbg_...`) from [debugai.io/dashboard](https://debugai.io/dashboard).
15
15
  3. Add the server to your MCP client (snippets below). Node 18+ required.
16
16
 
17
+ ### Set the key once for every client (optional)
18
+
19
+ Instead of repeating the key in each client's `env` block, write it to
20
+ `~/.debugai/config.json`:
21
+
22
+ ```json
23
+ { "api_key": "dbg_your_key_here" }
24
+ ```
25
+
26
+ Every MCP client launching `npx -y @debugai/mcp` picks it up — you can then
27
+ drop the `env` block from the snippets below entirely. An explicit
28
+ `DEBUGAI_API_KEY` env var still wins over the file.
29
+
17
30
  ### Claude Code
18
31
 
19
32
  ```bash
@@ -123,9 +136,10 @@ Example, in Claude Code:
123
136
 
124
137
  | Variable | Default | Description |
125
138
  |----------|---------|-------------|
126
- | `DEBUGAI_API_KEY` | (none) | Your API key. Required for real analyses. |
127
- | `DEBUGAI_API_BASE` | DebugAI production | Override for self-hosted or staging setups. |
139
+ | `DEBUGAI_API_KEY` | (none) | Your API key. Falls back to `api_key` in the config file. |
140
+ | `DEBUGAI_API_BASE` | DebugAI production | Override for self-hosted or staging setups. Falls back to `api_base` in the config file. |
128
141
  | `DEBUGAI_TIMEOUT_MS` | `150000` | Per-request deadline. Deep analyses can take 30-90s. |
142
+ | `DEBUGAI_CONFIG_PATH` | `~/.debugai/config.json` | Alternate config file location. Rarely needed. |
129
143
 
130
144
  ## Limits and honesty
131
145
 
@@ -140,7 +154,8 @@ Example, in Claude Code:
140
154
  ## Troubleshooting
141
155
 
142
156
  - **"authentication failed"**: key missing or wrong. Check the `env` block in
143
- your client config, restart the client. Keys start with `dbg_`.
157
+ your client config or `~/.debugai/config.json`, restart the client. Keys
158
+ start with `dbg_`.
144
159
  - **Nothing happens on `npx @debugai/mcp`**: correct. It's a stdio server that
145
160
  waits for an MCP client to speak first. Run `npx @debugai/mcp --help` to
146
161
  verify the install.
@@ -0,0 +1,13 @@
1
+ export interface FileConfig {
2
+ apiKey?: string;
3
+ apiBase?: string;
4
+ }
5
+ export interface ResolvedSettings {
6
+ apiKey: string;
7
+ apiBase: string;
8
+ /** Where the key came from — used only for the startup log line. */
9
+ keySource: 'env' | 'file' | 'none';
10
+ }
11
+ export declare function configPath(env?: NodeJS.ProcessEnv): string;
12
+ export declare function loadFileConfig(env?: NodeJS.ProcessEnv, warn?: (msg: string) => void): FileConfig;
13
+ export declare function resolveSettings(defaultApiBase: string, env?: NodeJS.ProcessEnv, warn?: (msg: string) => void): ResolvedSettings;
package/dist/config.js ADDED
@@ -0,0 +1,48 @@
1
+ // Optional on-disk config so a user can set their key once instead of
2
+ // repeating it in every MCP client's env block:
3
+ //
4
+ // ~/.debugai/config.json { "api_key": "dbg_...", "api_base": "..." }
5
+ //
6
+ // Environment variables always win over the file. DEBUGAI_CONFIG_PATH
7
+ // overrides the file location (tests point it at a temp dir; users normally
8
+ // never set it).
9
+ import { readFileSync } from 'node:fs';
10
+ import { homedir } from 'node:os';
11
+ import { join } from 'node:path';
12
+ export function configPath(env = process.env) {
13
+ const override = (env.DEBUGAI_CONFIG_PATH ?? '').trim();
14
+ return override || join(homedir(), '.debugai', 'config.json');
15
+ }
16
+ export function loadFileConfig(env = process.env, warn = (msg) => console.error(msg)) {
17
+ const path = configPath(env);
18
+ let raw;
19
+ try {
20
+ raw = readFileSync(path, 'utf8');
21
+ }
22
+ catch {
23
+ return {}; // no config file is the normal case — stay silent
24
+ }
25
+ try {
26
+ const parsed = JSON.parse(raw);
27
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
28
+ warn(`[debugai-mcp] ignoring ${path}: expected a JSON object`);
29
+ return {};
30
+ }
31
+ const record = parsed;
32
+ const str = (v) => typeof v === 'string' && v.trim() !== '' ? v.trim() : undefined;
33
+ return { apiKey: str(record.api_key), apiBase: str(record.api_base) };
34
+ }
35
+ catch {
36
+ warn(`[debugai-mcp] ignoring ${path}: malformed JSON`);
37
+ return {};
38
+ }
39
+ }
40
+ export function resolveSettings(defaultApiBase, env = process.env, warn = (msg) => console.error(msg)) {
41
+ const file = loadFileConfig(env, warn);
42
+ const envKey = (env.DEBUGAI_API_KEY ?? '').trim();
43
+ const apiKey = envKey || file.apiKey || '';
44
+ const keySource = envKey ? 'env' : file.apiKey ? 'file' : 'none';
45
+ const envBase = (env.DEBUGAI_API_BASE ?? '').trim();
46
+ const apiBase = (envBase || file.apiBase || defaultApiBase).replace(/\/+$/, '');
47
+ return { apiKey, apiBase, keySource };
48
+ }
package/dist/index.js CHANGED
@@ -5,6 +5,7 @@ import { dirname, join } from 'node:path';
5
5
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
6
6
  import { createServer } from './server.js';
7
7
  import { DEFAULT_TIMEOUT_MS } from './backend.js';
8
+ import { configPath, resolveSettings } from './config.js';
8
9
  const DEFAULT_API_BASE = 'https://debugai-mvp-production.up.railway.app/api';
9
10
  function packageVersion() {
10
11
  try {
@@ -27,10 +28,14 @@ Usage:
27
28
  npx @debugai/mcp --help
28
29
 
29
30
  Environment:
30
- DEBUGAI_API_KEY required — your API key (dbg_...) from https://debugai.io/dashboard
31
+ DEBUGAI_API_KEY your API key (dbg_...) from https://debugai.io/dashboard
31
32
  DEBUGAI_API_BASE optional — API base URL (default: DebugAI production)
32
33
  DEBUGAI_TIMEOUT_MS optional — per-request deadline in ms (default: ${DEFAULT_TIMEOUT_MS})
33
34
 
35
+ Config file (set the key once, every MCP client picks it up):
36
+ ~/.debugai/config.json {"api_key": "dbg_..."}
37
+ Env vars win over the file. api_base is also accepted.
38
+
34
39
  This is a stdio MCP server: it is meant to be launched BY an MCP client
35
40
  (Claude Desktop, Claude Code, Cursor, Zed, ...), not run interactively.
36
41
  Config snippets: https://www.npmjs.com/package/@debugai/mcp
@@ -51,13 +56,13 @@ function main() {
51
56
  process.exitCode = 1;
52
57
  return;
53
58
  }
54
- const apiKey = (process.env.DEBUGAI_API_KEY ?? '').trim();
55
- const apiBase = (process.env.DEBUGAI_API_BASE ?? DEFAULT_API_BASE).trim().replace(/\/+$/, '');
59
+ const { apiKey, apiBase, keySource } = resolveSettings(DEFAULT_API_BASE);
56
60
  const rawTimeout = Number(process.env.DEBUGAI_TIMEOUT_MS);
57
61
  const timeoutMs = Number.isFinite(rawTimeout) && rawTimeout > 0 ? rawTimeout : DEFAULT_TIMEOUT_MS;
58
62
  if (!apiKey) {
59
- console.error('[debugai-mcp] DEBUGAI_API_KEY not set — tools will return auth errors. ' +
60
- 'Get a key at https://debugai.io/dashboard and add it to the "env" block of your MCP client config.');
63
+ console.error('[debugai-mcp] no API key found — tools will return auth errors. ' +
64
+ 'Get a key at https://debugai.io/dashboard, then either set DEBUGAI_API_KEY in your ' +
65
+ `MCP client config or write it once to ${configPath()} as {"api_key": "dbg_..."}.`);
61
66
  }
62
67
  else if (!apiKey.startsWith('dbg_')) {
63
68
  console.error('[debugai-mcp] warning: DEBUGAI_API_KEY does not look like a DebugAI key (expected dbg_ prefix).');
@@ -70,7 +75,7 @@ function main() {
70
75
  process.on('SIGINT', () => shutdown('SIGINT'));
71
76
  process.on('SIGTERM', () => shutdown('SIGTERM'));
72
77
  const transport = new StdioServerTransport();
73
- server.connect(transport).then(() => console.error(`[debugai-mcp] v${VERSION} connected on stdio (api: ${apiBase})`), (err) => {
78
+ server.connect(transport).then(() => console.error(`[debugai-mcp] v${VERSION} connected on stdio (api: ${apiBase}, key: ${keySource})`), (err) => {
74
79
  console.error('[debugai-mcp] fatal:', err);
75
80
  process.exit(1);
76
81
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@debugai/mcp",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "DebugAI MCP server — hand any error to DebugAI from Claude Desktop, Claude Code, Cursor, Zed, or any MCP client and get root cause + ranked fixes.",
5
5
  "license": "MIT",
6
6
  "type": "module",