@debugai/mcp 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 DebugAI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,157 @@
1
+ # @debugai/mcp
2
+
3
+ DebugAI as an MCP server. Your agent hands an error to `debug_error` and gets
4
+ back the root cause plus up to 3 ranked fixes with code patches. Works in
5
+ Claude Desktop, Claude Code, Cursor, Zed, Windsurf, and any other MCP client.
6
+
7
+ Until now this server only shipped inside the
8
+ [DebugAI VS Code extension](https://marketplace.visualstudio.com/items?itemName=debugai.debugai).
9
+ This package is the same server, standalone. No VS Code required.
10
+
11
+ ## Setup
12
+
13
+ 1. Create a free account at [debugai.io](https://debugai.io) (10 debugs/day, no card).
14
+ 2. Copy your API key (`dbg_...`) from [debugai.io/dashboard](https://debugai.io/dashboard).
15
+ 3. Add the server to your MCP client (snippets below). Node 18+ required.
16
+
17
+ ### Claude Code
18
+
19
+ ```bash
20
+ claude mcp add debugai --env DEBUGAI_API_KEY=dbg_your_key_here -- npx -y @debugai/mcp
21
+ ```
22
+
23
+ ### Claude Desktop
24
+
25
+ `claude_desktop_config.json` (Settings, Developer, Edit Config):
26
+
27
+ ```json
28
+ {
29
+ "mcpServers": {
30
+ "debugai": {
31
+ "command": "npx",
32
+ "args": ["-y", "@debugai/mcp"],
33
+ "env": { "DEBUGAI_API_KEY": "dbg_your_key_here" }
34
+ }
35
+ }
36
+ }
37
+ ```
38
+
39
+ ### Cursor
40
+
41
+ `~/.cursor/mcp.json` (or `.cursor/mcp.json` per project):
42
+
43
+ ```json
44
+ {
45
+ "mcpServers": {
46
+ "debugai": {
47
+ "command": "npx",
48
+ "args": ["-y", "@debugai/mcp"],
49
+ "env": { "DEBUGAI_API_KEY": "dbg_your_key_here" }
50
+ }
51
+ }
52
+ }
53
+ ```
54
+
55
+ ### Zed
56
+
57
+ `settings.json`:
58
+
59
+ ```json
60
+ {
61
+ "context_servers": {
62
+ "debugai": {
63
+ "command": {
64
+ "path": "npx",
65
+ "args": ["-y", "@debugai/mcp"],
66
+ "env": { "DEBUGAI_API_KEY": "dbg_your_key_here" }
67
+ }
68
+ }
69
+ }
70
+ }
71
+ ```
72
+
73
+ ### Windsurf
74
+
75
+ `~/.codeium/windsurf/mcp_config.json`:
76
+
77
+ ```json
78
+ {
79
+ "mcpServers": {
80
+ "debugai": {
81
+ "command": "npx",
82
+ "args": ["-y", "@debugai/mcp"],
83
+ "env": { "DEBUGAI_API_KEY": "dbg_your_key_here" }
84
+ }
85
+ }
86
+ }
87
+ ```
88
+
89
+ ### VS Code
90
+
91
+ You don't need this package. The
92
+ [DebugAI extension](https://marketplace.visualstudio.com/items?itemName=debugai.debugai)
93
+ registers the MCP server automatically (VS Code 1.101+) and adds one-click
94
+ fix apply, proactive scan, and codebase indexing on top.
95
+
96
+ ## The tool
97
+
98
+ ### `debug_error`
99
+
100
+ Give it an error, get an analysis.
101
+
102
+ | Input | Required | Description |
103
+ |-------|----------|-------------|
104
+ | `errorText` | yes | Full error message, exception, or stack trace. |
105
+ | `language` | no | `javascript`, `typescript`, `python`, `go`, `rust`, or `auto` (default). |
106
+ | `codeSnippet` | no | Code around the failing line, if the agent has it. |
107
+ | `filePath` | no | Path to the file that threw. |
108
+
109
+ Returns the root cause, up to 3 fixes ranked by confidence (with code
110
+ patches), the detected framework, and whether the answer came from cache.
111
+ Read-only: it never touches your files. Applying a fix is your agent's
112
+ (and your) call.
113
+
114
+ Example, in Claude Code:
115
+
116
+ > Paste a traceback and ask "why is this failing?". Claude calls
117
+ > `debug_error` and gets back something like:
118
+ >
119
+ > **Root cause:** `db.session` is used after the request context closed.
120
+ > **Fix 1 (94% confidence):** move the query inside the request handler...
121
+
122
+ ## Environment variables
123
+
124
+ | Variable | Default | Description |
125
+ |----------|---------|-------------|
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. |
128
+ | `DEBUGAI_TIMEOUT_MS` | `150000` | Per-request deadline. Deep analyses can take 30-90s. |
129
+
130
+ ## Limits and honesty
131
+
132
+ - Free tier: 10 debugs/day. Pro ($12/mo): 1,000/mo soft cap, never hard-blocked at it.
133
+ - When you hit the daily cap the tool says so and stops. It will not silently retry.
134
+ - Simple errors route to a fast model; ugly cross-file ones route to a
135
+ stronger one on paid tiers. The `Model:` badge in each response tells you
136
+ which one answered.
137
+ - Analyses run on DebugAI's servers. The error text and any snippet you pass
138
+ are sent there. Privacy policy: [debugai.io/privacy](https://debugai.io/privacy).
139
+
140
+ ## Troubleshooting
141
+
142
+ - **"authentication failed"**: key missing or wrong. Check the `env` block in
143
+ your client config, restart the client. Keys start with `dbg_`.
144
+ - **Nothing happens on `npx @debugai/mcp`**: correct. It's a stdio server that
145
+ waits for an MCP client to speak first. Run `npx @debugai/mcp --help` to
146
+ verify the install.
147
+ - **Timeouts**: deep analyses can take up to 90s. If your client has its own
148
+ tool timeout, raise it above that.
149
+
150
+ ## Development
151
+
152
+ ```bash
153
+ npm install
154
+ npm test # builds, then runs unit + spawned-process e2e tests
155
+ ```
156
+
157
+ MIT © DebugAI
@@ -0,0 +1,42 @@
1
+ export interface DebugRequest {
2
+ error_message: string;
3
+ code_snippet?: string;
4
+ language?: string;
5
+ file_path?: string;
6
+ project_id?: string;
7
+ framework_hint?: string;
8
+ }
9
+ export interface DebugFix {
10
+ rank: number;
11
+ title: string;
12
+ description: string;
13
+ confidence: number;
14
+ code?: string;
15
+ line_hint?: string;
16
+ }
17
+ export interface DebugResponse {
18
+ root_cause: string;
19
+ fixes: DebugFix[];
20
+ framework_detected?: string;
21
+ model_used?: string;
22
+ cached?: boolean;
23
+ has_project_context?: boolean;
24
+ related_files_count?: number;
25
+ confidence_level?: string;
26
+ pattern_matched?: string;
27
+ remaining_today?: number;
28
+ mock?: boolean;
29
+ }
30
+ export interface BackendConfig {
31
+ apiKey: string;
32
+ apiBase: string;
33
+ version: string;
34
+ /** Whole-request deadline in ms. Claude analysis runs 30-90s; nginx cuts at 120s. */
35
+ timeoutMs?: number;
36
+ }
37
+ export interface BackendError extends Error {
38
+ status: number;
39
+ retryAfterSeconds: number;
40
+ }
41
+ export declare const DEFAULT_TIMEOUT_MS = 150000;
42
+ export declare function callDebugBackend(req: DebugRequest, config: BackendConfig): Promise<DebugResponse>;
@@ -0,0 +1,38 @@
1
+ export const DEFAULT_TIMEOUT_MS = 150_000;
2
+ function makeBackendError(message, status, retryAfterSeconds = 0) {
3
+ return Object.assign(new Error(message), { status, retryAfterSeconds });
4
+ }
5
+ export async function callDebugBackend(req, config) {
6
+ const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
7
+ const controller = new AbortController();
8
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
9
+ let res;
10
+ try {
11
+ res = await fetch(`${config.apiBase}/debug`, {
12
+ method: 'POST',
13
+ headers: {
14
+ 'content-type': 'application/json',
15
+ 'x-api-key': config.apiKey,
16
+ 'user-agent': `debugai-mcp/${config.version}`,
17
+ },
18
+ body: JSON.stringify(req),
19
+ signal: controller.signal,
20
+ });
21
+ }
22
+ catch (err) {
23
+ if (controller.signal.aborted) {
24
+ throw makeBackendError(`DebugAI request timed out after ${Math.round(timeoutMs / 1000)}s`, 504);
25
+ }
26
+ // DNS failure, refused connection, no network — status 0 marks "never reached the API"
27
+ throw makeBackendError(`Could not reach the DebugAI API at ${config.apiBase}: ${err?.message ?? String(err)}`, 0);
28
+ }
29
+ finally {
30
+ clearTimeout(timer);
31
+ }
32
+ if (!res.ok) {
33
+ const text = await res.text().catch(() => '');
34
+ const retryAfter = Number(res.headers.get('retry-after') ?? 0);
35
+ throw makeBackendError(text || res.statusText, res.status, retryAfter);
36
+ }
37
+ return res.json();
38
+ }
@@ -0,0 +1,2 @@
1
+ import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
2
+ export declare function mapBackendErrorToToolResult(err: unknown): CallToolResult;
package/dist/errors.js ADDED
@@ -0,0 +1,119 @@
1
+ const PRICING_URL = 'https://debugai.io/pricing';
2
+ const DASHBOARD_URL = 'https://debugai.io/dashboard';
3
+ function tryParseJson(text) {
4
+ try {
5
+ return JSON.parse(text);
6
+ }
7
+ catch {
8
+ return null;
9
+ }
10
+ }
11
+ export function mapBackendErrorToToolResult(err) {
12
+ const status = err?.status ?? 0;
13
+ const message = err?.message ?? String(err);
14
+ const retry = err?.retryAfterSeconds ?? 60;
15
+ if (status === 401 || status === 403) {
16
+ return {
17
+ isError: true,
18
+ content: [{
19
+ type: 'text',
20
+ text: 'DebugAI authentication failed: API key missing, invalid, or expired. ' +
21
+ `Tell the user to get their API key at ${DASHBOARD_URL} and set it as the ` +
22
+ 'DEBUGAI_API_KEY environment variable in their MCP client config (the "env" block ' +
23
+ 'for the debugai server entry), then restart the MCP client and retry.',
24
+ }],
25
+ structuredContent: {
26
+ error_type: 'auth_failed',
27
+ dashboard_url: DASHBOARD_URL,
28
+ retryable: false,
29
+ },
30
+ };
31
+ }
32
+ // 402 Payment Required — quota exhausted (NOT a transient rate limit).
33
+ // Agents must NOT retry. They must surface the upgrade URL to the user.
34
+ if (status === 402) {
35
+ const body = tryParseJson(message) ?? {};
36
+ const tier = body.tier ?? 'free';
37
+ const limit = body.limit ?? 10;
38
+ const resets = body.resets_at ?? 'midnight UTC';
39
+ const upgrade = body.upgrade_url ?? PRICING_URL;
40
+ return {
41
+ isError: true,
42
+ content: [{
43
+ type: 'text',
44
+ text: `DebugAI ${tier} tier daily quota reached (${limit} debugs/day). ` +
45
+ `Resets at ${resets}. ` +
46
+ `IMPORTANT: This is NOT a transient rate limit — do NOT retry this call. ` +
47
+ `Tell the user to upgrade to Pro for more debugging: ${upgrade}. ` +
48
+ `Pro is $12/month, lifts the daily cap, and gives unlimited sessions (soft cap 1,000/mo).`,
49
+ }],
50
+ structuredContent: {
51
+ error_type: 'quota_exceeded',
52
+ tier,
53
+ daily_limit: limit,
54
+ resets_at: resets,
55
+ upgrade_url: upgrade,
56
+ retryable: false,
57
+ },
58
+ };
59
+ }
60
+ if (status === 429) {
61
+ return {
62
+ isError: true,
63
+ content: [{
64
+ type: 'text',
65
+ text: `DebugAI rate limit hit (transient). Retry after ${retry} seconds. ` +
66
+ `Do NOT retry this call immediately — inform the user and wait for the cooldown. ` +
67
+ `Upgrade for higher limits: ${DASHBOARD_URL}`,
68
+ }],
69
+ structuredContent: {
70
+ error_type: 'rate_limited',
71
+ retry_after_seconds: retry,
72
+ retryable: true,
73
+ },
74
+ };
75
+ }
76
+ if (status === 503 || status === 504) {
77
+ return {
78
+ isError: true,
79
+ content: [{
80
+ type: 'text',
81
+ text: `DebugAI engine temporarily unavailable (HTTP ${status}). ` +
82
+ `Tell the user this is a transient issue and to retry in 30-60 seconds. ` +
83
+ `Check status at https://status.debugai.io if it persists.`,
84
+ }],
85
+ structuredContent: {
86
+ error_type: 'engine_unavailable',
87
+ status,
88
+ retryable: true,
89
+ },
90
+ };
91
+ }
92
+ // status 0 — the request never reached the API (DNS, refused, offline)
93
+ if (status === 0) {
94
+ return {
95
+ isError: true,
96
+ content: [{
97
+ type: 'text',
98
+ text: `${message}. The user may be offline, behind a proxy, or DEBUGAI_API_BASE may be ` +
99
+ `misconfigured. Retry once the network is available.`,
100
+ }],
101
+ structuredContent: {
102
+ error_type: 'network_error',
103
+ retryable: true,
104
+ },
105
+ };
106
+ }
107
+ return {
108
+ isError: true,
109
+ content: [{
110
+ type: 'text',
111
+ text: `DebugAI request failed: ${message}. The user can retry shortly.`,
112
+ }],
113
+ structuredContent: {
114
+ error_type: 'unknown',
115
+ status,
116
+ retryable: true,
117
+ },
118
+ };
119
+ }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync } from 'node:fs';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { dirname, join } from 'node:path';
5
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
6
+ import { createServer } from './server.js';
7
+ import { DEFAULT_TIMEOUT_MS } from './backend.js';
8
+ const DEFAULT_API_BASE = 'https://debugai-mvp-production.up.railway.app/api';
9
+ function packageVersion() {
10
+ try {
11
+ const pkgPath = join(dirname(fileURLToPath(import.meta.url)), '..', 'package.json');
12
+ return JSON.parse(readFileSync(pkgPath, 'utf8')).version;
13
+ }
14
+ catch {
15
+ return '0.0.0';
16
+ }
17
+ }
18
+ const VERSION = packageVersion();
19
+ const HELP = `debugai-mcp v${VERSION} — DebugAI MCP server (stdio)
20
+
21
+ Exposes the debug_error tool to any MCP client: hand it an error or stack
22
+ trace, get root cause + ranked fixes from DebugAI.
23
+
24
+ Usage:
25
+ npx @debugai/mcp # start the server (stdio transport)
26
+ npx @debugai/mcp --version
27
+ npx @debugai/mcp --help
28
+
29
+ Environment:
30
+ DEBUGAI_API_KEY required — your API key (dbg_...) from https://debugai.io/dashboard
31
+ DEBUGAI_API_BASE optional — API base URL (default: DebugAI production)
32
+ DEBUGAI_TIMEOUT_MS optional — per-request deadline in ms (default: ${DEFAULT_TIMEOUT_MS})
33
+
34
+ This is a stdio MCP server: it is meant to be launched BY an MCP client
35
+ (Claude Desktop, Claude Code, Cursor, Zed, ...), not run interactively.
36
+ Config snippets: https://www.npmjs.com/package/@debugai/mcp
37
+ `;
38
+ // stdout carries the MCP protocol — every human-facing line goes to stderr.
39
+ function main() {
40
+ const args = process.argv.slice(2);
41
+ if (args.includes('--version') || args.includes('-v')) {
42
+ process.stdout.write(`${VERSION}\n`);
43
+ return;
44
+ }
45
+ if (args.includes('--help') || args.includes('-h')) {
46
+ process.stdout.write(HELP);
47
+ return;
48
+ }
49
+ if (args.length > 0) {
50
+ console.error(`[debugai-mcp] unknown argument(s): ${args.join(' ')} (see --help)`);
51
+ process.exitCode = 1;
52
+ return;
53
+ }
54
+ const apiKey = (process.env.DEBUGAI_API_KEY ?? '').trim();
55
+ const apiBase = (process.env.DEBUGAI_API_BASE ?? DEFAULT_API_BASE).trim().replace(/\/+$/, '');
56
+ const rawTimeout = Number(process.env.DEBUGAI_TIMEOUT_MS);
57
+ const timeoutMs = Number.isFinite(rawTimeout) && rawTimeout > 0 ? rawTimeout : DEFAULT_TIMEOUT_MS;
58
+ 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.');
61
+ }
62
+ else if (!apiKey.startsWith('dbg_')) {
63
+ console.error('[debugai-mcp] warning: DEBUGAI_API_KEY does not look like a DebugAI key (expected dbg_ prefix).');
64
+ }
65
+ const server = createServer({ apiKey, apiBase, version: VERSION, timeoutMs });
66
+ const shutdown = (signal) => {
67
+ console.error(`[debugai-mcp] received ${signal}, shutting down`);
68
+ void server.close().finally(() => process.exit(0));
69
+ };
70
+ process.on('SIGINT', () => shutdown('SIGINT'));
71
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
72
+ const transport = new StdioServerTransport();
73
+ server.connect(transport).then(() => console.error(`[debugai-mcp] v${VERSION} connected on stdio (api: ${apiBase})`), (err) => {
74
+ console.error('[debugai-mcp] fatal:', err);
75
+ process.exit(1);
76
+ });
77
+ }
78
+ main();
@@ -0,0 +1,3 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { BackendConfig } from './backend.js';
3
+ export declare function createServer(config: BackendConfig): McpServer;
package/dist/server.js ADDED
@@ -0,0 +1,7 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { registerDebugError } from './tools/debugError.js';
3
+ export function createServer(config) {
4
+ const server = new McpServer({ name: 'debugai', version: config.version }, { capabilities: { tools: { listChanged: true } } });
5
+ registerDebugError(server, config);
6
+ return server;
7
+ }
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { BackendConfig, DebugFix } from '../backend.js';
3
+ export declare function formatFix(fix: DebugFix, index: number): string;
4
+ export declare function registerDebugError(server: McpServer, config: BackendConfig): void;
@@ -0,0 +1,99 @@
1
+ import { z } from 'zod';
2
+ import { callDebugBackend } from '../backend.js';
3
+ import { mapBackendErrorToToolResult } from '../errors.js';
4
+ export function formatFix(fix, index) {
5
+ const lines = [
6
+ `\n**Fix ${index} (${fix.confidence}% confidence)** — ${fix.title}`,
7
+ fix.description,
8
+ ];
9
+ if (fix.code) {
10
+ lines.push('```', fix.code, '```');
11
+ }
12
+ if (fix.line_hint) {
13
+ lines.push(`_Location: ${fix.line_hint}_`);
14
+ }
15
+ return lines.join('\n');
16
+ }
17
+ export function registerDebugError(server, config) {
18
+ server.registerTool('debug_error', {
19
+ title: 'Debug Error',
20
+ description: 'Analyze a runtime error, exception, or stack trace and return root cause + ranked fixes. ' +
21
+ 'Use whenever the user pastes an error, asks "why is this failing", "what does this error mean", ' +
22
+ '"debug this stack trace", "fix this exception", "analyze this traceback", or shows a ' +
23
+ 'Traceback / TypeError / ReferenceError / AttributeError. ' +
24
+ 'Works for Python, JavaScript, TypeScript, Go, Rust. ' +
25
+ 'Returns root cause explanation plus up to 3 ranked fixes with code patches.',
26
+ inputSchema: {
27
+ errorText: z
28
+ .string()
29
+ .min(1)
30
+ .describe('The full error message, exception, or stack trace text.'),
31
+ language: z
32
+ .enum(['javascript', 'typescript', 'python', 'go', 'rust', 'auto'])
33
+ .default('auto')
34
+ .describe('Source language. Use "auto" to let DebugAI detect from the error.'),
35
+ codeSnippet: z
36
+ .string()
37
+ .optional()
38
+ .describe('Surrounding code lines near where the error was thrown, if available.'),
39
+ filePath: z
40
+ .string()
41
+ .optional()
42
+ .describe('Absolute or relative path to the file that threw the error, if known.'),
43
+ },
44
+ annotations: {
45
+ readOnlyHint: true,
46
+ title: 'Debug Error',
47
+ },
48
+ }, async ({ errorText, language, codeSnippet, filePath }) => {
49
+ try {
50
+ const result = await callDebugBackend({
51
+ error_message: errorText,
52
+ language: language !== 'auto' ? language : undefined,
53
+ code_snippet: codeSnippet,
54
+ file_path: filePath,
55
+ // framework_hint deliberately omitted: a language ('python') is not a
56
+ // framework ('fastapi'), and sending it bypasses the engine's
57
+ // framework detection — FastAPI/React errors lose their expert hints.
58
+ }, config);
59
+ const sections = ['## Root Cause', result.root_cause ?? '(no root cause returned)'];
60
+ if (result.fixes?.length) {
61
+ sections.push('\n## Fixes');
62
+ result.fixes.forEach((fix, i) => {
63
+ sections.push(formatFix(fix, i + 1));
64
+ });
65
+ }
66
+ const badges = [];
67
+ if (result.model_used) {
68
+ badges.push(`Model: ${result.model_used}`);
69
+ }
70
+ if (result.has_project_context) {
71
+ badges.push('Codebase-aware: yes');
72
+ }
73
+ if (result.cached) {
74
+ badges.push('Cached: yes');
75
+ }
76
+ if (result.framework_detected) {
77
+ badges.push(`Framework: ${result.framework_detected}`);
78
+ }
79
+ if (badges.length) {
80
+ sections.push(`\n---\n_${badges.join(' · ')}_`);
81
+ }
82
+ const text = sections.join('\n');
83
+ return {
84
+ content: [{ type: 'text', text }],
85
+ structuredContent: {
86
+ root_cause: result.root_cause,
87
+ fixes: result.fixes,
88
+ framework_detected: result.framework_detected,
89
+ model_used: result.model_used,
90
+ cached: result.cached ?? false,
91
+ has_project_context: result.has_project_context ?? false,
92
+ },
93
+ };
94
+ }
95
+ catch (err) {
96
+ return mapBackendErrorToToolResult(err);
97
+ }
98
+ });
99
+ }
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@debugai/mcp",
3
+ "version": "1.0.0",
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
+ "license": "MIT",
6
+ "type": "module",
7
+ "bin": {
8
+ "debugai-mcp": "dist/index.js"
9
+ },
10
+ "main": "dist/index.js",
11
+ "types": "dist/index.d.ts",
12
+ "files": [
13
+ "dist",
14
+ "README.md",
15
+ "LICENSE"
16
+ ],
17
+ "engines": {
18
+ "node": ">=18"
19
+ },
20
+ "scripts": {
21
+ "build": "tsc -p tsconfig.json && node -e \"require('fs').chmodSync('dist/index.js', 0o755)\"",
22
+ "pretest": "npm run build",
23
+ "test": "vitest run",
24
+ "prepublishOnly": "npm test"
25
+ },
26
+ "keywords": [
27
+ "mcp",
28
+ "model-context-protocol",
29
+ "debugging",
30
+ "ai",
31
+ "claude",
32
+ "error-analysis",
33
+ "stack-trace",
34
+ "debugai"
35
+ ],
36
+ "homepage": "https://debugai.io",
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "git+https://github.com/1shizaan/debugai-mvp.git",
40
+ "directory": "packages/mcp"
41
+ },
42
+ "publishConfig": {
43
+ "access": "public"
44
+ },
45
+ "dependencies": {
46
+ "@modelcontextprotocol/sdk": "^1.29.0",
47
+ "zod": "^4.4.3"
48
+ },
49
+ "devDependencies": {
50
+ "@types/node": "^20.19.0",
51
+ "typescript": "^5.6.0",
52
+ "vitest": "^3.0.0"
53
+ }
54
+ }