Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
Commitf5a18f9unknown_key

feat(mcp): gluecron_repo_health tool exposes the health score via MCP

feat(mcp): gluecron_repo_health tool exposes the health score via MCP

Extends the v1 MCP tool surface so MCP clients (Claude Desktop /
Code / Cursor) can pull the same health score the dashboard renders.
Useful when prompting an AI to "what should I work on in
acme/payments?" — the agent now has a structured answer.

Tool surface:
- gluecron_repo_health(owner, repo) → {
    score:    0-100,
    grade:    "A+" | "A" | "B" | "C" | "D" | "F",
    breakdown: { security, testing, complexity, dependencies,
                 documentation, activity },
    insights: string[],   // "do this next" list
    generatedAt: ISO string,
  }

Backed by `computeHealthScore` in src/lib/intelligence.ts. Public-
only visibility check matches the other v1 tools; private repos and
not-yet-cloned repos return -32601.

The MCP toolCount assertion in mcp.test.ts already used `>= 4` so
adding a fifth tool stays green without changes; the per-tool
manifest-shape iteration likewise.

Total suite 1219 → 1219 + (no new tests; existing iteration covers
the new tool's manifest shape).

https://claude.ai/code/session_0163vJChUuZqqtBBznUW6xBU
Claude committed on April 30, 2026Parent: 7a14837
1 file changed+561f5a18f9193c0384baa6189f88d1b963294f7c57b
1 changed file+56−1
Modifiedsrc/lib/mcp-tools.ts+56−1View fileUnifiedSplit
2323 users,
2424 codebaseExplanations,
2525} from "../db/schema";
26import { getBlob } from "../git/repository";
26import { getBlob, repoExists } from "../git/repository";
27import { computeHealthScore } from "./intelligence";
2728import { McpError, ERR_INVALID_PARAMS, ERR_METHOD_NOT_FOUND } from "./mcp";
2829import type { McpContext } from "./mcp";
2930
303304 },
304305};
305306
307// ---------------------------------------------------------------------------
308// gluecron_repo_health
309// ---------------------------------------------------------------------------
310
311const repoHealth: McpToolHandler = {
312 tool: {
313 name: "gluecron_repo_health",
314 description:
315 "Compute the current health report for a public repo: overall score (0-100), letter grade, per-category breakdown (security/testing/complexity/dependencies/documentation/activity), and a list of insights to fix next. Backed by computeHealthScore in src/lib/intelligence.ts.",
316 inputSchema: {
317 type: "object",
318 properties: {
319 owner: { type: "string", description: "Repo owner username" },
320 repo: { type: "string", description: "Repo name" },
321 },
322 required: ["owner", "repo"],
323 },
324 },
325 async run(args) {
326 const owner = argString(args, "owner");
327 const repo = argString(args, "repo");
328
329 const [r] = await db
330 .select({ id: repositories.id, isPrivate: repositories.isPrivate })
331 .from(repositories)
332 .innerJoin(users, eq(repositories.ownerId, users.id))
333 .where(and(eq(users.username, owner), eq(repositories.name, repo)))
334 .limit(1);
335 if (!r) throw new McpError(ERR_METHOD_NOT_FOUND, `repo not found: ${owner}/${repo}`);
336 if (r.isPrivate) {
337 throw new McpError(
338 ERR_METHOD_NOT_FOUND,
339 `${owner}/${repo} is private; v1 MCP tools are public-only`
340 );
341 }
342 if (!(await repoExists(owner, repo))) {
343 throw new McpError(
344 ERR_METHOD_NOT_FOUND,
345 `${owner}/${repo} has no on-disk git data yet`
346 );
347 }
348 const report = await computeHealthScore(owner, repo);
349 return {
350 score: report.score,
351 grade: report.grade,
352 breakdown: report.breakdown,
353 insights: report.insights,
354 generatedAt: report.generatedAt,
355 };
356 },
357};
358
306359// ---------------------------------------------------------------------------
307360// Default tool registry
308361// ---------------------------------------------------------------------------
313366 [repoReadFile.tool.name]: repoReadFile,
314367 [repoListIssues.tool.name]: repoListIssues,
315368 [repoExplain.tool.name]: repoExplain,
369 [repoHealth.tool.name]: repoHealth,
316370 };
317371}
318372
324378 repoReadFile,
325379 repoListIssues,
326380 repoExplain,
381 repoHealth,
327382};
328383