@diegotsi/flint-mcp 1.1.0 → 1.2.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/dist/index.js CHANGED
@@ -275,6 +275,13 @@ function registerGetAnalytics(server2) {
275
275
 
276
276
  // src/tools/getBug.ts
277
277
  import { z as z4 } from "zod";
278
+
279
+ // src/shouldShowFix.ts
280
+ function shouldShowFix(fix) {
281
+ return fix != null && (fix.confidence === "high" || fix.confidence === "medium");
282
+ }
283
+
284
+ // src/tools/getBug.ts
278
285
  function timeAgo(iso) {
279
286
  const diff = Date.now() - new Date(iso).getTime();
280
287
  const mins = Math.floor(diff / 6e4);
@@ -339,7 +346,7 @@ ${r.ai_description}`);
339
346
  ### Root Cause${confStr}
340
347
  ${r.ai_root_cause}`);
341
348
  }
342
- if (fix) {
349
+ if (fix && shouldShowFix(fix)) {
343
350
  const filePath = fix.filePath ?? fix.file_path ?? "unknown";
344
351
  sections.push(
345
352
  `
@@ -617,6 +624,21 @@ function registerSuggestFix(server2) {
617
624
  ]
618
625
  };
619
626
  }
627
+ if (!shouldShowFix(fix)) {
628
+ return {
629
+ content: [
630
+ {
631
+ type: "text",
632
+ text: [
633
+ `## No High-Confidence Fix for Bug #${reportId}`,
634
+ "",
635
+ `The AI fix for this bug is **${fix.confidence ?? "low"} confidence** and has been withheld to avoid sending a misleading suggestion to an agent.`,
636
+ "Investigate manually, or open the bug in the Flint dashboard for full context."
637
+ ].join("\n")
638
+ }
639
+ ]
640
+ };
641
+ }
620
642
  const filePath = fix.file_path ?? fix.filePath ?? "unknown";
621
643
  const explanation = fix.explanation ?? "No explanation provided.";
622
644
  const diff = fix.diff ?? fix.code ?? "";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/tools/chatAboutBug.ts","../src/client.ts","../src/tools/createFixPR.ts","../src/tools/getAnalytics.ts","../src/tools/getBug.ts","../src/tools/listBugs.ts","../src/tools/resolveBug.ts","../src/tools/searchCode.ts","../src/tools/suggestFix.ts","../src/tools/triageBug.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n registerChatAboutBug,\n registerCreateFixPR,\n registerGetAnalytics,\n registerGetBug,\n registerListBugs,\n registerResolveBug,\n registerSearchCode,\n registerSuggestFix,\n registerTriageBug,\n} from \"./tools/index.js\";\n\nconst server = new McpServer({\n name: \"flint\",\n version: \"1.0.0\",\n description:\n \"Flint bug tracking & error monitoring — list bugs, search code, suggest fixes, triage issues directly from your editor.\",\n});\n\nregisterListBugs(server);\nregisterGetBug(server);\nregisterSearchCode(server);\nregisterSuggestFix(server);\nregisterTriageBug(server);\nregisterResolveBug(server);\nregisterCreateFixPR(server);\nregisterGetAnalytics(server);\nregisterChatAboutBug(server);\n\nasync function main() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error(\"Flint MCP Server running on stdio\");\n}\n\nmain().catch((error) => {\n console.error(\"Fatal error in MCP server:\", error);\n process.exit(1);\n});\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiPost, resolveProjectId } from \"../client.js\";\n\nexport function registerChatAboutBug(server: McpServer) {\n server.registerTool(\n \"chat_about_bug\",\n {\n description:\n \"Ask a question about a specific bug report. Uses AI with full context (code, similar bugs, fix history) to answer.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n reportId: z.string().describe(\"The bug report ID\"),\n message: z.string().describe(\"The message/question to ask about this bug\"),\n },\n },\n async ({ projectId: pid, reportId, message }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n let result: any;\n try {\n result = await apiPost(`/api/v1/admin/projects/${projectId}/reports/${reportId}/chat`, { message });\n } catch (err: any) {\n const errorMsg = err.message ?? \"Unknown error\";\n return {\n content: [\n {\n type: \"text\" as const,\n text: [\n `Failed to chat about bug #${reportId}: ${errorMsg}`,\n \"\",\n \"The AI chat feature may not be enabled for this project, or the bug report may not exist.\",\n \"Check the Flint Admin Dashboard for more details.\",\n ].join(\"\\n\"),\n },\n ],\n };\n }\n\n // The chat endpoint may return the response in different formats:\n // - { response: \"...\" } or { text: \"...\" } or { message: \"...\" }\n // - or the result itself could be a string (if the response was plain text parsed as JSON string)\n let responseText: string;\n if (typeof result === \"string\") {\n responseText = result;\n } else if (result?.response) {\n responseText = result.response;\n } else if (result?.text) {\n responseText = result.text;\n } else if (result?.message) {\n responseText = result.message;\n } else if (result?.content) {\n // Handle case where the API returns an array of content blocks (Anthropic-style)\n if (Array.isArray(result.content)) {\n responseText = result.content\n .filter((block: any) => block.type === \"text\")\n .map((block: any) => block.text)\n .join(\"\\n\");\n } else {\n responseText = String(result.content);\n }\n } else {\n responseText = JSON.stringify(result, null, 2);\n }\n\n if (!responseText || responseText === \"null\" || responseText === \"undefined\") {\n responseText = \"No response was generated. The AI may need more context about this bug.\";\n }\n\n return {\n content: [{ type: \"text\" as const, text: responseText }],\n };\n },\n );\n}\n","/**\n * HTTP client for the Flint Admin API.\n * Used by MCP tools instead of direct Prisma access.\n */\n\nconst serverUrl = (process.env.FLINT_SERVER_URL ?? \"http://localhost:3333\").replace(/\\/$/, \"\");\n// FLINT_API_KEY kept as fallback for setups created before the rename\nconst adminKey = process.env.FLINT_ADMIN_KEY ?? process.env.FLINT_API_KEY ?? \"\";\nexport const defaultProjectId = process.env.FLINT_PROJECT_ID ?? \"\";\n\nexport function resolveProjectId(pid?: string): string | null {\n return pid || defaultProjectId || null;\n}\n\nif (!serverUrl) {\n console.error(\"[Flint MCP] FLINT_SERVER_URL is required\");\n process.exit(1);\n}\nif (!adminKey) {\n console.error(\"[Flint MCP] FLINT_ADMIN_KEY is required\");\n process.exit(1);\n}\n\nfunction headers(): Record<string, string> {\n return {\n \"X-Admin-Key\": adminKey,\n \"Content-Type\": \"application/json\",\n };\n}\n\nexport async function apiGet<T = unknown>(path: string): Promise<T> {\n const res = await fetch(`${serverUrl}${path}`, { headers: headers() });\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(`API ${res.status}: ${body.slice(0, 200)}`);\n }\n return res.json() as Promise<T>;\n}\n\nexport async function apiPatch<T = unknown>(path: string, body?: unknown): Promise<T> {\n const res = await fetch(`${serverUrl}${path}`, {\n method: \"PATCH\",\n headers: headers(),\n body: body ? JSON.stringify(body) : undefined,\n });\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n throw new Error(`API ${res.status}: ${text.slice(0, 200)}`);\n }\n return res.json() as Promise<T>;\n}\n\nexport async function apiPost<T = unknown>(path: string, body?: unknown): Promise<T> {\n const res = await fetch(`${serverUrl}${path}`, {\n method: \"POST\",\n headers: headers(),\n body: body ? JSON.stringify(body) : undefined,\n });\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n throw new Error(`API ${res.status}: ${text.slice(0, 200)}`);\n }\n return res.json() as Promise<T>;\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiPost, resolveProjectId } from \"../client.js\";\n\nexport function registerCreateFixPR(server: McpServer) {\n server.registerTool(\n \"create_fix_pr\",\n {\n description:\n \"Create a GitHub Pull Request with the AI-suggested fix for a bug report. Requires the bug to have a suggested fix.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n reportId: z.string().describe(\"The bug report ID\"),\n branch: z.string().optional().describe(\"Branch name (default: fix/<reportId>)\"),\n commitMessage: z.string().optional().describe(\"Custom commit message\"),\n },\n },\n async ({ projectId: pid, reportId, branch, commitMessage }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n const body: Record<string, string> = {};\n if (branch) body.branch = branch;\n if (commitMessage) body.commitMessage = commitMessage;\n\n let result: any;\n try {\n result = await apiPost(\n `/api/v1/admin/projects/${projectId}/reports/${reportId}/create-fix-pr`,\n Object.keys(body).length > 0 ? body : undefined,\n );\n } catch (err: any) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Failed to create fix PR for bug #${reportId}: ${err.message ?? \"Unknown error\"}`,\n },\n ],\n };\n }\n\n const prUrl = result?.pr_url ?? result?.prUrl ?? result?.url ?? null;\n\n const text = prUrl\n ? [\n `## Pull Request Created for Bug #${reportId}`,\n \"\",\n `**PR URL:** ${prUrl}`,\n \"\",\n \"The PR has been created with the AI-suggested fix. Review and merge when ready.\",\n ].join(\"\\n\")\n : [\n `## Fix PR Request Submitted for Bug #${reportId}`,\n \"\",\n \"The request to create a fix PR was accepted.\",\n result?.message\n ? `Server response: ${result.message}`\n : \"Check the Flint Admin Dashboard or your GitHub repository for the PR.\",\n ].join(\"\\n\");\n\n return {\n content: [{ type: \"text\" as const, text }],\n };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiGet, resolveProjectId } from \"../client.js\";\n\nexport function registerGetAnalytics(server: McpServer) {\n server.registerTool(\n \"get_analytics\",\n {\n description:\n \"Get project analytics: total reports, open/critical counts, resolution time, triage rate, top errors, and trends.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n period: z.string().optional().describe(\"Time period: 7d, 30d, or 90d (default 30d)\"),\n },\n },\n async ({ projectId: pid, period }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n const periodStr = period ?? \"30d\";\n\n let data: any;\n try {\n data = await apiGet(`/api/v1/admin/projects/${projectId}/analytics?period=${periodStr}`);\n } catch (err: any) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Failed to fetch analytics for project ${projectId}: ${err.message ?? \"Unknown error\"}`,\n },\n ],\n };\n }\n\n // The analytics endpoint may return data in different shapes.\n // We handle the most common fields gracefully.\n const total = data.total ?? data.totalReports ?? \"—\";\n const open = data.open ?? data.openCount ?? \"—\";\n const inProgress = data.inProgress ?? data.inProgressCount ?? \"—\";\n const resolved = data.resolved ?? data.resolvedCount ?? \"—\";\n const critical = data.critical ?? data.criticalCount ?? \"—\";\n const avgResolution = data.avgResolutionHours ?? data.avgResolution ?? \"—\";\n const triageRate = data.triageRate ?? data.triagedPercent ?? \"—\";\n\n const sections: string[] = [\n `## Analytics (${periodStr})`,\n \"\",\n `**Total:** ${total} reports | **Open:** ${open} | **In Progress:** ${inProgress} | **Critical (P1/P2):** ${critical} | **Resolved:** ${resolved}`,\n `**Avg Resolution:** ${avgResolution}${typeof avgResolution === \"number\" ? \"h\" : \"\"} | **Triage Rate:** ${triageRate}${typeof triageRate === \"number\" ? \"%\" : \"\"}`,\n ];\n\n // Top errors\n const topErrors: any[] = data.topErrors ?? data.errorGroups ?? data.topErrorGroups ?? [];\n if (topErrors.length > 0) {\n sections.push(\"\", \"### Top Errors\");\n topErrors.forEach((e: any, i: number) => {\n const title = e.title ?? e.message ?? \"Unknown error\";\n const events = e.error_count ?? e.errorCount ?? e.count ?? 0;\n const users = e.user_count ?? e.userCount ?? 0;\n sections.push(`${i + 1}. ${title} (${events} events${users ? `, ${users} users` : \"\"})`);\n });\n }\n\n // Trends\n const trends: any[] = data.trends ?? data.dailyCounts ?? [];\n if (trends.length > 0) {\n sections.push(\"\", \"### Trend (daily bug count)\");\n const recent = trends.slice(-7);\n const trendLine = recent\n .map((t: any) => {\n const date = t.date ?? t.day ?? t.label ?? \"?\";\n const count = t.count ?? t.total ?? 0;\n return `${date}: ${count}`;\n })\n .join(\" | \");\n sections.push(trendLine);\n }\n\n return {\n content: [{ type: \"text\" as const, text: sections.join(\"\\n\") }],\n };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiGet, resolveProjectId } from \"../client.js\";\n\nfunction timeAgo(iso: string): string {\n const diff = Date.now() - new Date(iso).getTime();\n const mins = Math.floor(diff / 60_000);\n if (mins < 1) return \"just now\";\n if (mins < 60) return `${mins}m ago`;\n const hours = Math.floor(mins / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n\nexport function registerGetBug(server: McpServer) {\n server.registerTool(\n \"get_bug\",\n {\n description:\n \"Get full details of a bug report including AI analysis, root cause, suggested fix, console errors, network errors, and environment info.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n reportId: z.string().describe(\"Bug report ID\"),\n },\n },\n async ({ projectId: pid, reportId }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n let r: any;\n try {\n r = await apiGet(`/api/v1/admin/projects/${projectId}/reports/${reportId}`);\n } catch {\n return { content: [{ type: \"text\" as const, text: `Bug report \"${reportId}\" not found.` }] };\n }\n\n const meta = r.meta as Record<string, unknown> | null;\n const aiReasoning = r.ai_reasoning as Record<string, unknown> | null;\n const consoleLogs = (meta?.consoleLogs ?? []) as { level: string; args: string }[];\n const networkErrors = (meta?.networkErrors ?? []) as { method: string; url: string; status: number }[];\n const envInfo = meta?.environment as Record<string, unknown> | null;\n const fix = r.fix ?? (r.ai_suggested_fix ? JSON.parse(r.ai_suggested_fix) : null);\n\n const sections: string[] = [];\n\n sections.push(`## Bug #${r.id.slice(-8)} — ${r.ai_title ?? r.title}`);\n sections.push(\n `**Severity:** ${r.severity} | **Status:** ${r.status} | **Assignee:** ${r.assignee ?? \"unassigned\"}`,\n );\n sections.push(\n `**Reporter:** ${r.reporter_name} | **Created:** ${timeAgo(r.created_at)} | **URL:** ${r.url ?? \"N/A\"}`,\n );\n if (r.app_version || r.release) {\n sections.push(`**Version:** ${r.app_version ?? \"N/A\"} | **Release:** ${r.release ?? \"N/A\"}`);\n }\n\n if (r.ai_description) sections.push(`\\n### AI Summary\\n${r.ai_description}`);\n\n if (r.ai_root_cause) {\n const conf = (aiReasoning?.rootCauseConfidence as number) ?? null;\n const confStr = conf !== null ? ` (${conf}% confidence)` : \"\";\n sections.push(`\\n### Root Cause${confStr}\\n${r.ai_root_cause}`);\n }\n\n if (fix) {\n const filePath = fix.filePath ?? fix.file_path ?? \"unknown\";\n sections.push(\n `\\n### Suggested Fix (${fix.confidence ?? \"unknown\"} confidence)\\n**File:** ${filePath}\\n\\n${fix.explanation ?? \"\"}\\n\\n\\`\\`\\`diff\\n${fix.diff ?? \"\"}\\n\\`\\`\\``,\n );\n }\n\n const errors = consoleLogs.filter((e) => e.level === \"error\").slice(-5);\n if (errors.length > 0) {\n sections.push(`\\n### Console Errors (last ${errors.length})\\n${errors.map((e) => `- ${e.args}`).join(\"\\n\")}`);\n }\n\n if (networkErrors.length > 0) {\n sections.push(\n `\\n### Failed Network Requests\\n${networkErrors.map((e) => `- ${e.method} ${e.url} → ${e.status}`).join(\"\\n\")}`,\n );\n }\n\n if (envInfo) {\n sections.push(\n `\\n### Environment\\n${envInfo.browser} | ${envInfo.os} | ${envInfo.viewport} | ${envInfo.timezone}`,\n );\n }\n\n const steps = r.steps_to_reproduce as { action: string; result: string }[] | null;\n if (steps && steps.length > 0) {\n sections.push(\n `\\n### Steps to Reproduce\\n${steps.map((s, i) => `${i + 1}. ${s.action}${s.result ? ` → ${s.result}` : \"\"}`).join(\"\\n\")}`,\n );\n }\n\n if (r.ai_repro_steps) sections.push(`\\n### AI-Generated Repro Steps\\n${r.ai_repro_steps}`);\n\n // Fix patterns (D9)\n if (r.fixPatterns?.length > 0) {\n sections.push(`\\n### How Similar Bugs Were Fixed`);\n for (const fp of r.fixPatterns) {\n sections.push(\n `- **PR #${fp.pr_number}**${fp.author_name ? ` by ${fp.author_name}` : \"\"} — ${fp.bug_title.slice(0, 50)}\\n ${fp.diff_summary.slice(0, 120)}`,\n );\n }\n }\n\n return { content: [{ type: \"text\" as const, text: sections.join(\"\\n\") }] };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiGet, resolveProjectId } from \"../client.js\";\n\nfunction timeAgo(iso: string): string {\n const diff = Date.now() - new Date(iso).getTime();\n const mins = Math.floor(diff / 60_000);\n if (mins < 1) return \"just now\";\n if (mins < 60) return `${mins}m ago`;\n const hours = Math.floor(mins / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n\nexport function registerListBugs(server: McpServer) {\n server.registerTool(\n \"list_bugs\",\n {\n description:\n \"List bug reports for a project with optional filters. Returns a summary table with ID, title, severity, status, assignee, and creation time.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n severity: z.string().optional().describe(\"Filter by severity: P1, P2, P3, P4 (comma-separated)\"),\n status: z\n .string()\n .optional()\n .describe(\"Filter by status: OPEN, IN_PROGRESS, TESTING, RESOLVED (comma-separated). Defaults to OPEN\"),\n assignee: z.string().optional().describe(\"Filter by assignee name\"),\n area: z.string().optional().describe(\"Filter by area: FRONTEND, BACKEND, DESIGN\"),\n q: z.string().optional().describe(\"Search in title, reporter name, URL\"),\n limit: z.number().optional().describe(\"Max results (default 10, max 50)\"),\n },\n },\n async ({ projectId: pid, severity, status, assignee, area, q, limit }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n const params = new URLSearchParams({ page: \"1\", limit: String(Math.min(limit ?? 10, 50)) });\n if (severity) params.set(\"severity\", severity);\n params.set(\"status\", status ?? \"OPEN\");\n if (assignee) params.set(\"assignee\", assignee);\n if (area) params.set(\"area\", area);\n if (q) params.set(\"q\", q);\n\n const data = await apiGet<{ reports: any[]; total: number }>(\n `/api/v1/admin/projects/${projectId}/reports?${params}`,\n );\n\n if (data.reports.length === 0) {\n return { content: [{ type: \"text\" as const, text: \"No bugs found matching the filters.\" }] };\n }\n\n const lines = data.reports.map((r: any) => {\n const title = (r.ai_title ?? r.title).slice(0, 60);\n const assigneeStr = r.assignee ?? \"unassigned\";\n const quality = r.quality_score ? ` Q:${r.quality_score}%` : \"\";\n return `- **${r.severity}** \\`${r.id}\\` ${title} — ${r.status} — ${assigneeStr} — ${timeAgo(r.created_at)}${quality}`;\n });\n\n const text = `## Bug Reports (${data.total} total, showing ${data.reports.length})\\n\\n${lines.join(\"\\n\")}\\n\\nUse \\`get_bug\\` with a report ID for full details.`;\n return { content: [{ type: \"text\" as const, text }] };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiPatch, resolveProjectId } from \"../client.js\";\n\nexport function registerResolveBug(server: McpServer) {\n server.registerTool(\n \"resolve_bug\",\n {\n description: \"Mark a bug report as resolved.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n reportId: z.string().describe(\"The bug report ID\"),\n },\n },\n async ({ projectId: pid, reportId }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n try {\n await apiPatch(`/api/v1/admin/projects/${projectId}/reports/${reportId}/resolve`);\n } catch (err: any) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Failed to resolve bug #${reportId}: ${err.message ?? \"Unknown error\"}`,\n },\n ],\n };\n }\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Bug #${reportId} marked as RESOLVED.`,\n },\n ],\n };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { resolveProjectId } from \"../client.js\";\n\nexport function registerSearchCode(server: McpServer) {\n server.registerTool(\n \"search_code\",\n {\n description:\n \"Search the project's indexed codebase by semantic query. Returns relevant code chunks with file paths and line numbers.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n query: z.string().describe(\"Semantic search query\"),\n limit: z.number().optional().describe(\"Max results to return (default 5)\"),\n },\n },\n async ({ projectId: pid, query, limit }) => {\n const projectId = resolveProjectId(pid) ?? \"unknown\";\n const text = [\n \"## Code Search — Not Available via MCP\",\n \"\",\n \"Semantic code search requires direct access to the vector embedding pipeline (Voyage AI + pgvector), which is not exposed through the HTTP API.\",\n \"\",\n \"**Alternatives:**\",\n `- Use the **Flint Admin Dashboard** → Project → Code Index to search the indexed codebase for project \\`${projectId}\\`.`,\n `- Use \\`chat_about_bug\\` with a specific bug report ID — the AI chat endpoint includes relevant code context automatically.`,\n \"\",\n `Your query was: \"${query}\" (limit: ${limit ?? 5})`,\n ].join(\"\\n\");\n\n return {\n content: [{ type: \"text\" as const, text }],\n };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiGet, resolveProjectId } from \"../client.js\";\n\nexport function registerSuggestFix(server: McpServer) {\n server.registerTool(\n \"suggest_fix\",\n {\n description:\n \"Generate an AI-suggested code fix for a bug report. Uses the project's indexed code and AI analysis to produce a diff.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n reportId: z.string().describe(\"The bug report ID\"),\n },\n },\n async ({ projectId: pid, reportId }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n let report: any;\n try {\n report = await apiGet(`/api/v1/admin/projects/${projectId}/reports/${reportId}`);\n } catch (err: any) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Bug report ${reportId} not found in project ${projectId}. ${err.message ?? \"\"}`,\n },\n ],\n };\n }\n\n const rawFix = report.ai_suggested_fix;\n\n if (!rawFix) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: [\n `## No Fix Available for Bug #${reportId}`,\n \"\",\n \"An AI-suggested fix has not been generated yet for this bug report.\",\n \"The fix is generated automatically during background processing when the bug is first created.\",\n \"\",\n \"**Possible reasons:**\",\n \"- The bug was recently created and background processing hasn't completed yet.\",\n \"- The project's codebase may not be indexed (Code Index is required for fix generation).\",\n \"- The AI analysis did not produce a fix for this particular bug.\",\n \"\",\n \"Check the Flint Admin Dashboard for the latest status.\",\n ].join(\"\\n\"),\n },\n ],\n };\n }\n\n let fix: any;\n try {\n fix = typeof rawFix === \"string\" ? JSON.parse(rawFix) : rawFix;\n } catch {\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Failed to parse the suggested fix data.\",\n },\n ],\n };\n }\n\n const filePath = fix.file_path ?? fix.filePath ?? \"unknown\";\n const explanation = fix.explanation ?? \"No explanation provided.\";\n const diff = fix.diff ?? fix.code ?? \"\";\n const confidence = fix.confidence ?? \"unknown\";\n\n const text = [\n `## Suggested Fix for Bug #${reportId}`,\n \"\",\n `**File:** \\`${filePath}\\``,\n `**Confidence:** ${confidence}`,\n \"\",\n `### Explanation`,\n explanation,\n \"\",\n \"### Diff\",\n \"```diff\",\n diff,\n \"```\",\n ].join(\"\\n\");\n\n return {\n content: [{ type: \"text\" as const, text }],\n };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiPatch, resolveProjectId } from \"../client.js\";\n\nexport function registerTriageBug(server: McpServer) {\n server.registerTool(\n \"triage_bug\",\n {\n description: \"Update triage fields on a bug report: assignee, severity, area, and notes.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n reportId: z.string().describe(\"The bug report ID\"),\n assignee: z.string().optional().describe(\"Assignee name or identifier\"),\n severity: z.string().optional().describe(\"Severity level: P1, P2, P3, or P4\"),\n area: z.string().optional().describe(\"Affected area: FRONTEND, BACKEND, or DESIGN\"),\n notes: z.string().optional().describe(\"Triage notes\"),\n },\n },\n async ({ projectId: pid, reportId, assignee, severity, area, notes }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n const data: Record<string, unknown> = {};\n if (assignee !== undefined) data.assignee = assignee;\n if (severity !== undefined) data.severity = severity;\n if (area !== undefined) data.area = area;\n if (notes !== undefined) data.notes = notes;\n\n if (Object.keys(data).length === 0) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"No triage fields provided. Specify at least one of: assignee, severity, area, notes.\",\n },\n ],\n };\n }\n\n try {\n await apiPatch(`/api/v1/admin/projects/${projectId}/reports/${reportId}/triage`, data);\n } catch (err: any) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Failed to triage bug #${reportId}: ${err.message ?? \"Unknown error\"}`,\n },\n ],\n };\n }\n\n const parts: string[] = [];\n if (assignee !== undefined) parts.push(`Assignee: ${assignee}`);\n if (severity !== undefined) parts.push(`Severity: ${severity}`);\n if (area !== undefined) parts.push(`Area: ${area}`);\n if (notes !== undefined) parts.push(`Notes: ${notes}`);\n\n const text = `Bug #${reportId} triaged: ${parts.join(\", \")}`;\n\n return {\n content: [{ type: \"text\" as const, text }],\n };\n },\n );\n}\n"],"mappings":"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","names":["server","z","server","z","z","server","z","z","server","z","z","timeAgo","server","z","z","server","z","z","server","z","z","server","z","z","server","z"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/tools/chatAboutBug.ts","../src/client.ts","../src/tools/createFixPR.ts","../src/tools/getAnalytics.ts","../src/tools/getBug.ts","../src/shouldShowFix.ts","../src/tools/listBugs.ts","../src/tools/resolveBug.ts","../src/tools/searchCode.ts","../src/tools/suggestFix.ts","../src/tools/triageBug.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n registerChatAboutBug,\n registerCreateFixPR,\n registerGetAnalytics,\n registerGetBug,\n registerListBugs,\n registerResolveBug,\n registerSearchCode,\n registerSuggestFix,\n registerTriageBug,\n} from \"./tools/index.js\";\n\nconst server = new McpServer({\n name: \"flint\",\n version: \"1.0.0\",\n description:\n \"Flint bug tracking & error monitoring — list bugs, search code, suggest fixes, triage issues directly from your editor.\",\n});\n\nregisterListBugs(server);\nregisterGetBug(server);\nregisterSearchCode(server);\nregisterSuggestFix(server);\nregisterTriageBug(server);\nregisterResolveBug(server);\nregisterCreateFixPR(server);\nregisterGetAnalytics(server);\nregisterChatAboutBug(server);\n\nasync function main() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error(\"Flint MCP Server running on stdio\");\n}\n\nmain().catch((error) => {\n console.error(\"Fatal error in MCP server:\", error);\n process.exit(1);\n});\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiPost, resolveProjectId } from \"../client.js\";\n\nexport function registerChatAboutBug(server: McpServer) {\n server.registerTool(\n \"chat_about_bug\",\n {\n description:\n \"Ask a question about a specific bug report. Uses AI with full context (code, similar bugs, fix history) to answer.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n reportId: z.string().describe(\"The bug report ID\"),\n message: z.string().describe(\"The message/question to ask about this bug\"),\n },\n },\n async ({ projectId: pid, reportId, message }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n let result: any;\n try {\n result = await apiPost(`/api/v1/admin/projects/${projectId}/reports/${reportId}/chat`, { message });\n } catch (err: any) {\n const errorMsg = err.message ?? \"Unknown error\";\n return {\n content: [\n {\n type: \"text\" as const,\n text: [\n `Failed to chat about bug #${reportId}: ${errorMsg}`,\n \"\",\n \"The AI chat feature may not be enabled for this project, or the bug report may not exist.\",\n \"Check the Flint Admin Dashboard for more details.\",\n ].join(\"\\n\"),\n },\n ],\n };\n }\n\n // The chat endpoint may return the response in different formats:\n // - { response: \"...\" } or { text: \"...\" } or { message: \"...\" }\n // - or the result itself could be a string (if the response was plain text parsed as JSON string)\n let responseText: string;\n if (typeof result === \"string\") {\n responseText = result;\n } else if (result?.response) {\n responseText = result.response;\n } else if (result?.text) {\n responseText = result.text;\n } else if (result?.message) {\n responseText = result.message;\n } else if (result?.content) {\n // Handle case where the API returns an array of content blocks (Anthropic-style)\n if (Array.isArray(result.content)) {\n responseText = result.content\n .filter((block: any) => block.type === \"text\")\n .map((block: any) => block.text)\n .join(\"\\n\");\n } else {\n responseText = String(result.content);\n }\n } else {\n responseText = JSON.stringify(result, null, 2);\n }\n\n if (!responseText || responseText === \"null\" || responseText === \"undefined\") {\n responseText = \"No response was generated. The AI may need more context about this bug.\";\n }\n\n return {\n content: [{ type: \"text\" as const, text: responseText }],\n };\n },\n );\n}\n","/**\n * HTTP client for the Flint Admin API.\n * Used by MCP tools instead of direct Prisma access.\n */\n\nconst serverUrl = (process.env.FLINT_SERVER_URL ?? \"http://localhost:3333\").replace(/\\/$/, \"\");\n// FLINT_API_KEY kept as fallback for setups created before the rename\nconst adminKey = process.env.FLINT_ADMIN_KEY ?? process.env.FLINT_API_KEY ?? \"\";\nexport const defaultProjectId = process.env.FLINT_PROJECT_ID ?? \"\";\n\nexport function resolveProjectId(pid?: string): string | null {\n return pid || defaultProjectId || null;\n}\n\nif (!serverUrl) {\n console.error(\"[Flint MCP] FLINT_SERVER_URL is required\");\n process.exit(1);\n}\nif (!adminKey) {\n console.error(\"[Flint MCP] FLINT_ADMIN_KEY is required\");\n process.exit(1);\n}\n\nfunction headers(): Record<string, string> {\n return {\n \"X-Admin-Key\": adminKey,\n \"Content-Type\": \"application/json\",\n };\n}\n\nexport async function apiGet<T = unknown>(path: string): Promise<T> {\n const res = await fetch(`${serverUrl}${path}`, { headers: headers() });\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(`API ${res.status}: ${body.slice(0, 200)}`);\n }\n return res.json() as Promise<T>;\n}\n\nexport async function apiPatch<T = unknown>(path: string, body?: unknown): Promise<T> {\n const res = await fetch(`${serverUrl}${path}`, {\n method: \"PATCH\",\n headers: headers(),\n body: body ? JSON.stringify(body) : undefined,\n });\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n throw new Error(`API ${res.status}: ${text.slice(0, 200)}`);\n }\n return res.json() as Promise<T>;\n}\n\nexport async function apiPost<T = unknown>(path: string, body?: unknown): Promise<T> {\n const res = await fetch(`${serverUrl}${path}`, {\n method: \"POST\",\n headers: headers(),\n body: body ? JSON.stringify(body) : undefined,\n });\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n throw new Error(`API ${res.status}: ${text.slice(0, 200)}`);\n }\n return res.json() as Promise<T>;\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiPost, resolveProjectId } from \"../client.js\";\n\nexport function registerCreateFixPR(server: McpServer) {\n server.registerTool(\n \"create_fix_pr\",\n {\n description:\n \"Create a GitHub Pull Request with the AI-suggested fix for a bug report. Requires the bug to have a suggested fix.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n reportId: z.string().describe(\"The bug report ID\"),\n branch: z.string().optional().describe(\"Branch name (default: fix/<reportId>)\"),\n commitMessage: z.string().optional().describe(\"Custom commit message\"),\n },\n },\n async ({ projectId: pid, reportId, branch, commitMessage }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n const body: Record<string, string> = {};\n if (branch) body.branch = branch;\n if (commitMessage) body.commitMessage = commitMessage;\n\n let result: any;\n try {\n result = await apiPost(\n `/api/v1/admin/projects/${projectId}/reports/${reportId}/create-fix-pr`,\n Object.keys(body).length > 0 ? body : undefined,\n );\n } catch (err: any) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Failed to create fix PR for bug #${reportId}: ${err.message ?? \"Unknown error\"}`,\n },\n ],\n };\n }\n\n const prUrl = result?.pr_url ?? result?.prUrl ?? result?.url ?? null;\n\n const text = prUrl\n ? [\n `## Pull Request Created for Bug #${reportId}`,\n \"\",\n `**PR URL:** ${prUrl}`,\n \"\",\n \"The PR has been created with the AI-suggested fix. Review and merge when ready.\",\n ].join(\"\\n\")\n : [\n `## Fix PR Request Submitted for Bug #${reportId}`,\n \"\",\n \"The request to create a fix PR was accepted.\",\n result?.message\n ? `Server response: ${result.message}`\n : \"Check the Flint Admin Dashboard or your GitHub repository for the PR.\",\n ].join(\"\\n\");\n\n return {\n content: [{ type: \"text\" as const, text }],\n };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiGet, resolveProjectId } from \"../client.js\";\n\nexport function registerGetAnalytics(server: McpServer) {\n server.registerTool(\n \"get_analytics\",\n {\n description:\n \"Get project analytics: total reports, open/critical counts, resolution time, triage rate, top errors, and trends.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n period: z.string().optional().describe(\"Time period: 7d, 30d, or 90d (default 30d)\"),\n },\n },\n async ({ projectId: pid, period }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n const periodStr = period ?? \"30d\";\n\n let data: any;\n try {\n data = await apiGet(`/api/v1/admin/projects/${projectId}/analytics?period=${periodStr}`);\n } catch (err: any) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Failed to fetch analytics for project ${projectId}: ${err.message ?? \"Unknown error\"}`,\n },\n ],\n };\n }\n\n // The analytics endpoint may return data in different shapes.\n // We handle the most common fields gracefully.\n const total = data.total ?? data.totalReports ?? \"—\";\n const open = data.open ?? data.openCount ?? \"—\";\n const inProgress = data.inProgress ?? data.inProgressCount ?? \"—\";\n const resolved = data.resolved ?? data.resolvedCount ?? \"—\";\n const critical = data.critical ?? data.criticalCount ?? \"—\";\n const avgResolution = data.avgResolutionHours ?? data.avgResolution ?? \"—\";\n const triageRate = data.triageRate ?? data.triagedPercent ?? \"—\";\n\n const sections: string[] = [\n `## Analytics (${periodStr})`,\n \"\",\n `**Total:** ${total} reports | **Open:** ${open} | **In Progress:** ${inProgress} | **Critical (P1/P2):** ${critical} | **Resolved:** ${resolved}`,\n `**Avg Resolution:** ${avgResolution}${typeof avgResolution === \"number\" ? \"h\" : \"\"} | **Triage Rate:** ${triageRate}${typeof triageRate === \"number\" ? \"%\" : \"\"}`,\n ];\n\n // Top errors\n const topErrors: any[] = data.topErrors ?? data.errorGroups ?? data.topErrorGroups ?? [];\n if (topErrors.length > 0) {\n sections.push(\"\", \"### Top Errors\");\n topErrors.forEach((e: any, i: number) => {\n const title = e.title ?? e.message ?? \"Unknown error\";\n const events = e.error_count ?? e.errorCount ?? e.count ?? 0;\n const users = e.user_count ?? e.userCount ?? 0;\n sections.push(`${i + 1}. ${title} (${events} events${users ? `, ${users} users` : \"\"})`);\n });\n }\n\n // Trends\n const trends: any[] = data.trends ?? data.dailyCounts ?? [];\n if (trends.length > 0) {\n sections.push(\"\", \"### Trend (daily bug count)\");\n const recent = trends.slice(-7);\n const trendLine = recent\n .map((t: any) => {\n const date = t.date ?? t.day ?? t.label ?? \"?\";\n const count = t.count ?? t.total ?? 0;\n return `${date}: ${count}`;\n })\n .join(\" | \");\n sections.push(trendLine);\n }\n\n return {\n content: [{ type: \"text\" as const, text: sections.join(\"\\n\") }],\n };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiGet, resolveProjectId } from \"../client.js\";\nimport { shouldShowFix } from \"../shouldShowFix.js\";\n\nfunction timeAgo(iso: string): string {\n const diff = Date.now() - new Date(iso).getTime();\n const mins = Math.floor(diff / 60_000);\n if (mins < 1) return \"just now\";\n if (mins < 60) return `${mins}m ago`;\n const hours = Math.floor(mins / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n\nexport function registerGetBug(server: McpServer) {\n server.registerTool(\n \"get_bug\",\n {\n description:\n \"Get full details of a bug report including AI analysis, root cause, suggested fix, console errors, network errors, and environment info.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n reportId: z.string().describe(\"Bug report ID\"),\n },\n },\n async ({ projectId: pid, reportId }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n let r: any;\n try {\n r = await apiGet(`/api/v1/admin/projects/${projectId}/reports/${reportId}`);\n } catch {\n return { content: [{ type: \"text\" as const, text: `Bug report \"${reportId}\" not found.` }] };\n }\n\n const meta = r.meta as Record<string, unknown> | null;\n const aiReasoning = r.ai_reasoning as Record<string, unknown> | null;\n const consoleLogs = (meta?.consoleLogs ?? []) as { level: string; args: string }[];\n const networkErrors = (meta?.networkErrors ?? []) as { method: string; url: string; status: number }[];\n const envInfo = meta?.environment as Record<string, unknown> | null;\n const fix = r.fix ?? (r.ai_suggested_fix ? JSON.parse(r.ai_suggested_fix) : null);\n\n const sections: string[] = [];\n\n sections.push(`## Bug #${r.id.slice(-8)} — ${r.ai_title ?? r.title}`);\n sections.push(\n `**Severity:** ${r.severity} | **Status:** ${r.status} | **Assignee:** ${r.assignee ?? \"unassigned\"}`,\n );\n sections.push(\n `**Reporter:** ${r.reporter_name} | **Created:** ${timeAgo(r.created_at)} | **URL:** ${r.url ?? \"N/A\"}`,\n );\n if (r.app_version || r.release) {\n sections.push(`**Version:** ${r.app_version ?? \"N/A\"} | **Release:** ${r.release ?? \"N/A\"}`);\n }\n\n if (r.ai_description) sections.push(`\\n### AI Summary\\n${r.ai_description}`);\n\n if (r.ai_root_cause) {\n const conf = (aiReasoning?.rootCauseConfidence as number) ?? null;\n const confStr = conf !== null ? ` (${conf}% confidence)` : \"\";\n sections.push(`\\n### Root Cause${confStr}\\n${r.ai_root_cause}`);\n }\n\n // Withhold low-signal fixes so they don't mislead the consuming agent.\n if (fix && shouldShowFix(fix)) {\n const filePath = fix.filePath ?? fix.file_path ?? \"unknown\";\n sections.push(\n `\\n### Suggested Fix (${fix.confidence ?? \"unknown\"} confidence)\\n**File:** ${filePath}\\n\\n${fix.explanation ?? \"\"}\\n\\n\\`\\`\\`diff\\n${fix.diff ?? \"\"}\\n\\`\\`\\``,\n );\n }\n\n const errors = consoleLogs.filter((e) => e.level === \"error\").slice(-5);\n if (errors.length > 0) {\n sections.push(`\\n### Console Errors (last ${errors.length})\\n${errors.map((e) => `- ${e.args}`).join(\"\\n\")}`);\n }\n\n if (networkErrors.length > 0) {\n sections.push(\n `\\n### Failed Network Requests\\n${networkErrors.map((e) => `- ${e.method} ${e.url} → ${e.status}`).join(\"\\n\")}`,\n );\n }\n\n if (envInfo) {\n sections.push(\n `\\n### Environment\\n${envInfo.browser} | ${envInfo.os} | ${envInfo.viewport} | ${envInfo.timezone}`,\n );\n }\n\n const steps = r.steps_to_reproduce as { action: string; result: string }[] | null;\n if (steps && steps.length > 0) {\n sections.push(\n `\\n### Steps to Reproduce\\n${steps.map((s, i) => `${i + 1}. ${s.action}${s.result ? ` → ${s.result}` : \"\"}`).join(\"\\n\")}`,\n );\n }\n\n if (r.ai_repro_steps) sections.push(`\\n### AI-Generated Repro Steps\\n${r.ai_repro_steps}`);\n\n // Fix patterns (D9)\n if (r.fixPatterns?.length > 0) {\n sections.push(`\\n### How Similar Bugs Were Fixed`);\n for (const fp of r.fixPatterns) {\n sections.push(\n `- **PR #${fp.pr_number}**${fp.author_name ? ` by ${fp.author_name}` : \"\"} — ${fp.bug_title.slice(0, 50)}\\n ${fp.diff_summary.slice(0, 120)}`,\n );\n }\n }\n\n return { content: [{ type: \"text\" as const, text: sections.join(\"\\n\") }] };\n },\n );\n}\n","// Suppression gate for low-signal AI fixes (M0). Keep in sync with\n// `shouldShowFix` in @flint/types. A suggested fix is only surfaced when the\n// model is reasonably confident — \"low\" and \"speculative\" fixes are withheld so\n// they don't mislead a downstream agent that consumes this MCP.\nexport function shouldShowFix(fix: { confidence?: string | null } | null | undefined): boolean {\n return fix != null && (fix.confidence === \"high\" || fix.confidence === \"medium\");\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiGet, resolveProjectId } from \"../client.js\";\n\nfunction timeAgo(iso: string): string {\n const diff = Date.now() - new Date(iso).getTime();\n const mins = Math.floor(diff / 60_000);\n if (mins < 1) return \"just now\";\n if (mins < 60) return `${mins}m ago`;\n const hours = Math.floor(mins / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n\nexport function registerListBugs(server: McpServer) {\n server.registerTool(\n \"list_bugs\",\n {\n description:\n \"List bug reports for a project with optional filters. Returns a summary table with ID, title, severity, status, assignee, and creation time.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n severity: z.string().optional().describe(\"Filter by severity: P1, P2, P3, P4 (comma-separated)\"),\n status: z\n .string()\n .optional()\n .describe(\"Filter by status: OPEN, IN_PROGRESS, TESTING, RESOLVED (comma-separated). Defaults to OPEN\"),\n assignee: z.string().optional().describe(\"Filter by assignee name\"),\n area: z.string().optional().describe(\"Filter by area: FRONTEND, BACKEND, DESIGN\"),\n q: z.string().optional().describe(\"Search in title, reporter name, URL\"),\n limit: z.number().optional().describe(\"Max results (default 10, max 50)\"),\n },\n },\n async ({ projectId: pid, severity, status, assignee, area, q, limit }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n const params = new URLSearchParams({ page: \"1\", limit: String(Math.min(limit ?? 10, 50)) });\n if (severity) params.set(\"severity\", severity);\n params.set(\"status\", status ?? \"OPEN\");\n if (assignee) params.set(\"assignee\", assignee);\n if (area) params.set(\"area\", area);\n if (q) params.set(\"q\", q);\n\n const data = await apiGet<{ reports: any[]; total: number }>(\n `/api/v1/admin/projects/${projectId}/reports?${params}`,\n );\n\n if (data.reports.length === 0) {\n return { content: [{ type: \"text\" as const, text: \"No bugs found matching the filters.\" }] };\n }\n\n const lines = data.reports.map((r: any) => {\n const title = (r.ai_title ?? r.title).slice(0, 60);\n const assigneeStr = r.assignee ?? \"unassigned\";\n const quality = r.quality_score ? ` Q:${r.quality_score}%` : \"\";\n return `- **${r.severity}** \\`${r.id}\\` ${title} — ${r.status} — ${assigneeStr} — ${timeAgo(r.created_at)}${quality}`;\n });\n\n const text = `## Bug Reports (${data.total} total, showing ${data.reports.length})\\n\\n${lines.join(\"\\n\")}\\n\\nUse \\`get_bug\\` with a report ID for full details.`;\n return { content: [{ type: \"text\" as const, text }] };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiPatch, resolveProjectId } from \"../client.js\";\n\nexport function registerResolveBug(server: McpServer) {\n server.registerTool(\n \"resolve_bug\",\n {\n description: \"Mark a bug report as resolved.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n reportId: z.string().describe(\"The bug report ID\"),\n },\n },\n async ({ projectId: pid, reportId }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n try {\n await apiPatch(`/api/v1/admin/projects/${projectId}/reports/${reportId}/resolve`);\n } catch (err: any) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Failed to resolve bug #${reportId}: ${err.message ?? \"Unknown error\"}`,\n },\n ],\n };\n }\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Bug #${reportId} marked as RESOLVED.`,\n },\n ],\n };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { resolveProjectId } from \"../client.js\";\n\nexport function registerSearchCode(server: McpServer) {\n server.registerTool(\n \"search_code\",\n {\n description:\n \"Search the project's indexed codebase by semantic query. Returns relevant code chunks with file paths and line numbers.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n query: z.string().describe(\"Semantic search query\"),\n limit: z.number().optional().describe(\"Max results to return (default 5)\"),\n },\n },\n async ({ projectId: pid, query, limit }) => {\n const projectId = resolveProjectId(pid) ?? \"unknown\";\n const text = [\n \"## Code Search — Not Available via MCP\",\n \"\",\n \"Semantic code search requires direct access to the vector embedding pipeline (Voyage AI + pgvector), which is not exposed through the HTTP API.\",\n \"\",\n \"**Alternatives:**\",\n `- Use the **Flint Admin Dashboard** → Project → Code Index to search the indexed codebase for project \\`${projectId}\\`.`,\n `- Use \\`chat_about_bug\\` with a specific bug report ID — the AI chat endpoint includes relevant code context automatically.`,\n \"\",\n `Your query was: \"${query}\" (limit: ${limit ?? 5})`,\n ].join(\"\\n\");\n\n return {\n content: [{ type: \"text\" as const, text }],\n };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiGet, resolveProjectId } from \"../client.js\";\nimport { shouldShowFix } from \"../shouldShowFix.js\";\n\nexport function registerSuggestFix(server: McpServer) {\n server.registerTool(\n \"suggest_fix\",\n {\n description:\n \"Generate an AI-suggested code fix for a bug report. Uses the project's indexed code and AI analysis to produce a diff.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n reportId: z.string().describe(\"The bug report ID\"),\n },\n },\n async ({ projectId: pid, reportId }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n let report: any;\n try {\n report = await apiGet(`/api/v1/admin/projects/${projectId}/reports/${reportId}`);\n } catch (err: any) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Bug report ${reportId} not found in project ${projectId}. ${err.message ?? \"\"}`,\n },\n ],\n };\n }\n\n const rawFix = report.ai_suggested_fix;\n\n if (!rawFix) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: [\n `## No Fix Available for Bug #${reportId}`,\n \"\",\n \"An AI-suggested fix has not been generated yet for this bug report.\",\n \"The fix is generated automatically during background processing when the bug is first created.\",\n \"\",\n \"**Possible reasons:**\",\n \"- The bug was recently created and background processing hasn't completed yet.\",\n \"- The project's codebase may not be indexed (Code Index is required for fix generation).\",\n \"- The AI analysis did not produce a fix for this particular bug.\",\n \"\",\n \"Check the Flint Admin Dashboard for the latest status.\",\n ].join(\"\\n\"),\n },\n ],\n };\n }\n\n let fix: any;\n try {\n fix = typeof rawFix === \"string\" ? JSON.parse(rawFix) : rawFix;\n } catch {\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Failed to parse the suggested fix data.\",\n },\n ],\n };\n }\n\n if (!shouldShowFix(fix)) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: [\n `## No High-Confidence Fix for Bug #${reportId}`,\n \"\",\n `The AI fix for this bug is **${fix.confidence ?? \"low\"} confidence** and has been withheld to avoid sending a misleading suggestion to an agent.`,\n \"Investigate manually, or open the bug in the Flint dashboard for full context.\",\n ].join(\"\\n\"),\n },\n ],\n };\n }\n\n const filePath = fix.file_path ?? fix.filePath ?? \"unknown\";\n const explanation = fix.explanation ?? \"No explanation provided.\";\n const diff = fix.diff ?? fix.code ?? \"\";\n const confidence = fix.confidence ?? \"unknown\";\n\n const text = [\n `## Suggested Fix for Bug #${reportId}`,\n \"\",\n `**File:** \\`${filePath}\\``,\n `**Confidence:** ${confidence}`,\n \"\",\n `### Explanation`,\n explanation,\n \"\",\n \"### Diff\",\n \"```diff\",\n diff,\n \"```\",\n ].join(\"\\n\");\n\n return {\n content: [{ type: \"text\" as const, text }],\n };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiPatch, resolveProjectId } from \"../client.js\";\n\nexport function registerTriageBug(server: McpServer) {\n server.registerTool(\n \"triage_bug\",\n {\n description: \"Update triage fields on a bug report: assignee, severity, area, and notes.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n reportId: z.string().describe(\"The bug report ID\"),\n assignee: z.string().optional().describe(\"Assignee name or identifier\"),\n severity: z.string().optional().describe(\"Severity level: P1, P2, P3, or P4\"),\n area: z.string().optional().describe(\"Affected area: FRONTEND, BACKEND, or DESIGN\"),\n notes: z.string().optional().describe(\"Triage notes\"),\n },\n },\n async ({ projectId: pid, reportId, assignee, severity, area, notes }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n const data: Record<string, unknown> = {};\n if (assignee !== undefined) data.assignee = assignee;\n if (severity !== undefined) data.severity = severity;\n if (area !== undefined) data.area = area;\n if (notes !== undefined) data.notes = notes;\n\n if (Object.keys(data).length === 0) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"No triage fields provided. Specify at least one of: assignee, severity, area, notes.\",\n },\n ],\n };\n }\n\n try {\n await apiPatch(`/api/v1/admin/projects/${projectId}/reports/${reportId}/triage`, data);\n } catch (err: any) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Failed to triage bug #${reportId}: ${err.message ?? \"Unknown error\"}`,\n },\n ],\n };\n }\n\n const parts: string[] = [];\n if (assignee !== undefined) parts.push(`Assignee: ${assignee}`);\n if (severity !== undefined) parts.push(`Severity: ${severity}`);\n if (area !== undefined) parts.push(`Area: ${area}`);\n if (notes !== undefined) parts.push(`Notes: ${notes}`);\n\n const text = `Bug #${reportId} triaged: ${parts.join(\", \")}`;\n\n return {\n content: [{ type: \"text\" as const, text }],\n };\n },\n );\n}\n"],"mappings":"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","names":["server","z","server","z","z","server","z","z","server","z","z","timeAgo","server","z","z","server","z","z","server","z","z","server","z","z","server","z"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diegotsi/flint-mcp",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Flint MCP server — list bugs, suggest fixes, triage issues and pull analytics from your editor via the Model Context Protocol.",
5
5
  "type": "module",
6
6
  "bin": {