projectpulse-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.
Files changed (68) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +73 -0
  3. package/bin/projectpulse-mcp.js +2 -0
  4. package/dist/github/client.d.ts +3 -0
  5. package/dist/github/client.d.ts.map +1 -0
  6. package/dist/github/client.js +10 -0
  7. package/dist/github/client.js.map +1 -0
  8. package/dist/index.d.ts +2 -0
  9. package/dist/index.d.ts.map +1 -0
  10. package/dist/index.js +29 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/scoring/health-score.d.ts +16 -0
  13. package/dist/scoring/health-score.d.ts.map +1 -0
  14. package/dist/scoring/health-score.js +80 -0
  15. package/dist/scoring/health-score.js.map +1 -0
  16. package/dist/scoring/health-score.test.d.ts +2 -0
  17. package/dist/scoring/health-score.test.d.ts.map +1 -0
  18. package/dist/scoring/health-score.test.js +209 -0
  19. package/dist/scoring/health-score.test.js.map +1 -0
  20. package/dist/tools/analyze-code-scanning.d.ts +12 -0
  21. package/dist/tools/analyze-code-scanning.d.ts.map +1 -0
  22. package/dist/tools/analyze-code-scanning.js +44 -0
  23. package/dist/tools/analyze-code-scanning.js.map +1 -0
  24. package/dist/tools/analyze-code-scanning.test.d.ts +2 -0
  25. package/dist/tools/analyze-code-scanning.test.d.ts.map +1 -0
  26. package/dist/tools/analyze-code-scanning.test.js +62 -0
  27. package/dist/tools/analyze-code-scanning.test.js.map +1 -0
  28. package/dist/tools/analyze-dependencies.d.ts +13 -0
  29. package/dist/tools/analyze-dependencies.d.ts.map +1 -0
  30. package/dist/tools/analyze-dependencies.js +31 -0
  31. package/dist/tools/analyze-dependencies.js.map +1 -0
  32. package/dist/tools/analyze-dependencies.test.d.ts +2 -0
  33. package/dist/tools/analyze-dependencies.test.d.ts.map +1 -0
  34. package/dist/tools/analyze-dependencies.test.js +65 -0
  35. package/dist/tools/analyze-dependencies.test.js.map +1 -0
  36. package/dist/tools/check-ci-status.d.ts +13 -0
  37. package/dist/tools/check-ci-status.d.ts.map +1 -0
  38. package/dist/tools/check-ci-status.js +32 -0
  39. package/dist/tools/check-ci-status.js.map +1 -0
  40. package/dist/tools/check-ci-status.test.d.ts +2 -0
  41. package/dist/tools/check-ci-status.test.d.ts.map +1 -0
  42. package/dist/tools/check-ci-status.test.js +90 -0
  43. package/dist/tools/check-ci-status.test.js.map +1 -0
  44. package/dist/tools/get-health-score.d.ts +12 -0
  45. package/dist/tools/get-health-score.d.ts.map +1 -0
  46. package/dist/tools/get-health-score.js +47 -0
  47. package/dist/tools/get-health-score.js.map +1 -0
  48. package/dist/tools/get-health-score.test.d.ts +2 -0
  49. package/dist/tools/get-health-score.test.d.ts.map +1 -0
  50. package/dist/tools/get-health-score.test.js +93 -0
  51. package/dist/tools/get-health-score.test.js.map +1 -0
  52. package/dist/tools/get-repo-health.d.ts +12 -0
  53. package/dist/tools/get-repo-health.d.ts.map +1 -0
  54. package/dist/tools/get-repo-health.js +49 -0
  55. package/dist/tools/get-repo-health.js.map +1 -0
  56. package/dist/tools/get-repo-health.test.d.ts +2 -0
  57. package/dist/tools/get-repo-health.test.d.ts.map +1 -0
  58. package/dist/tools/get-repo-health.test.js +80 -0
  59. package/dist/tools/get-repo-health.test.js.map +1 -0
  60. package/dist/types/health.d.ts +16 -0
  61. package/dist/types/health.d.ts.map +1 -0
  62. package/dist/types/health.js +2 -0
  63. package/dist/types/health.js.map +1 -0
  64. package/dist/vitest.config.d.ts +3 -0
  65. package/dist/vitest.config.d.ts.map +1 -0
  66. package/dist/vitest.config.js +7 -0
  67. package/dist/vitest.config.js.map +1 -0
  68. package/package.json +41 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze-code-scanning.test.js","sourceRoot":"","sources":["../../src/tools/analyze-code-scanning.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAExE,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;AAE/B,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;IACxC,UAAU,CAAC,GAAG,EAAE;QACZ,EAAE,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAChD,MAAM,UAAU,GAAG;YACf;gBACI,IAAI,EAAE,EAAE,EAAE,EAAE,kBAAkB,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE;gBACjF,KAAK,EAAE,MAAM;gBACb,oBAAoB,EAAE,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE;gBACzE,QAAQ,EAAE,uDAAuD;aACpE;SACJ,CAAC;QAEF,MAAM,cAAc,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;QAEvE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC;YAClC,YAAY,EAAE,EAAE,iBAAiB,EAAE,cAAc,EAAE;SAC/C,CAAC,CAAC;QAEV,MAAM,MAAM,GAAG,MAAM,0BAA0B,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QAEjF,MAAM,CAAC,cAAc,CAAC,CAAC,oBAAoB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QAE7E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAE5C,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACtD,MAAM,CAAC,UAAU,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAC1B,OAAO,EAAE,kBAAkB;YAC3B,QAAQ,EAAE,OAAO;YACjB,gBAAgB,EAAE,eAAe;YACjC,KAAK,EAAE,MAAM;YACb,yBAAyB,EAAE,WAAW;YACtC,+BAA+B,EAAE,EAAE;YACnC,QAAQ,EAAE,uDAAuD;SACpE,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,aAAa,GAAG,IAAI,KAAK,CAAC,WAAW,CAAQ,CAAC;QACpD,aAAa,CAAC,MAAM,GAAG,GAAG,CAAC;QAE3B,MAAM,cAAc,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC;QAEhE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC;YAClC,YAAY,EAAE,EAAE,iBAAiB,EAAE,cAAc,EAAE;SAC/C,CAAC,CAAC;QAEV,MAAM,MAAM,GAAG,MAAM,0BAA0B,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QAEjF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;IACrF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QACzD,MAAM,WAAW,GAAG,IAAI,KAAK,CAAC,cAAc,CAAQ,CAAC;QACrD,WAAW,CAAC,MAAM,GAAG,GAAG,CAAC;QAEzB,MAAM,cAAc,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;QAE9D,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC;YAClC,YAAY,EAAE,EAAE,iBAAiB,EAAE,cAAc,EAAE;SAC/C,CAAC,CAAC;QAEV,MAAM,MAAM,CAAC,0BAA0B,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;aACpE,OAAO;aACP,OAAO,CAAC,cAAc,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function executeAnalyzeDependencies({ owner, repo, severity }: {
3
+ owner: string;
4
+ repo: string;
5
+ severity?: string;
6
+ }): Promise<{
7
+ content: {
8
+ type: "text";
9
+ text: string;
10
+ }[];
11
+ }>;
12
+ export declare function registerAnalyzeDependencies(server: McpServer): void;
13
+ //# sourceMappingURL=analyze-dependencies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze-dependencies.d.ts","sourceRoot":"","sources":["../../src/tools/analyze-dependencies.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AASpE,wBAAsB,0BAA0B,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE;;;;;GAkB7H;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CASnE"}
@@ -0,0 +1,31 @@
1
+ import { z } from "zod";
2
+ import { getOctokit } from "../github/client.js";
3
+ const inputSchema = z.object({
4
+ owner: z.string().describe("GitHub repository owner"),
5
+ repo: z.string().describe("GitHub repository name"),
6
+ severity: z.enum(["critical", "high", "medium", "low"]).optional()
7
+ });
8
+ export async function executeAnalyzeDependencies({ owner, repo, severity }) {
9
+ const { data } = await getOctokit().dependabot.listAlertsForRepo({ owner, repo });
10
+ const result = data.map((alert) => ({
11
+ summary: alert.security_advisory.summary,
12
+ severity: alert.security_advisory.severity,
13
+ package_name: alert.dependency.package?.name,
14
+ state: alert.state,
15
+ html_url: alert.html_url
16
+ }));
17
+ const filtered = severity ? result.filter((alert) => alert.severity === severity) : result;
18
+ return {
19
+ content: [{
20
+ type: "text",
21
+ text: JSON.stringify(filtered, null, 2)
22
+ }]
23
+ };
24
+ }
25
+ export function registerAnalyzeDependencies(server) {
26
+ server.registerTool("analyze_dependencies", {
27
+ description: "Get Dependabot alerts for a GitHub repository",
28
+ inputSchema
29
+ }, executeAnalyzeDependencies);
30
+ }
31
+ //# sourceMappingURL=analyze-dependencies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze-dependencies.js","sourceRoot":"","sources":["../../src/tools/analyze-dependencies.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IACzB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;IACrD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;IACnD,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE;CACrE,CAAC,CAAC;AAEH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAsD;IAC1H,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAClF,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAChC,OAAO,EAAE,KAAK,CAAC,iBAAiB,CAAC,OAAO;QACxC,QAAQ,EAAE,KAAK,CAAC,iBAAiB,CAAC,QAAQ;QAC1C,YAAY,EAAE,KAAK,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI;QAC5C,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,QAAQ,EAAE,KAAK,CAAC,QAAQ;KAC3B,CAAC,CAAC,CAAC;IAEJ,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAE3F,OAAO;QACH,OAAO,EAAE,CAAC;gBACN,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;aAC1C,CAAC;KACL,CAAC;AACN,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,MAAiB;IACzD,MAAM,CAAC,YAAY,CACf,sBAAsB,EACtB;QACI,WAAW,EAAE,+CAA+C;QAC5D,WAAW;KACd,EACD,0BAA0B,CAC7B,CAAC;AACN,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=analyze-dependencies.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze-dependencies.test.d.ts","sourceRoot":"","sources":["../../src/tools/analyze-dependencies.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,65 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { getOctokit } from '../github/client.js';
3
+ import { executeAnalyzeDependencies } from './analyze-dependencies.js';
4
+ vi.mock('../github/client.js');
5
+ describe('executeAnalyzeDependencies', () => {
6
+ beforeEach(() => {
7
+ vi.resetAllMocks();
8
+ });
9
+ const mockAlerts = [
10
+ {
11
+ security_advisory: { summary: 'Critical bug', severity: 'critical' },
12
+ dependency: { package: { name: 'lodash' } },
13
+ state: 'open',
14
+ html_url: 'https://github.com/advisory/1'
15
+ },
16
+ {
17
+ security_advisory: { summary: 'High bug', severity: 'high' },
18
+ dependency: { package: { name: 'express' } },
19
+ state: 'fixed',
20
+ html_url: 'https://github.com/advisory/2'
21
+ },
22
+ {
23
+ security_advisory: { summary: 'Another High bug', severity: 'high' },
24
+ dependency: { package: { name: 'react' } },
25
+ state: 'open',
26
+ html_url: 'https://github.com/advisory/3'
27
+ }
28
+ ];
29
+ it('should return all dependencies if no severity is provided', async () => {
30
+ const mockListAlerts = vi.fn().mockResolvedValue({ data: mockAlerts });
31
+ vi.mocked(getOctokit).mockReturnValue({
32
+ dependabot: { listAlertsForRepo: mockListAlerts }
33
+ });
34
+ const result = await executeAnalyzeDependencies({ owner: 'test', repo: 'repo' });
35
+ expect(mockListAlerts).toHaveBeenCalledWith({ owner: 'test', repo: 'repo' });
36
+ expect(result.content).toHaveLength(1);
37
+ expect(result.content[0].type).toBe('text');
38
+ const parsedText = JSON.parse(result.content[0].text);
39
+ expect(parsedText).toHaveLength(3);
40
+ expect(parsedText[0].severity).toBe('critical');
41
+ expect(parsedText[1].severity).toBe('high');
42
+ expect(parsedText[2].severity).toBe('high');
43
+ });
44
+ it('should return filtered dependencies if severity is provided', async () => {
45
+ const mockListAlerts = vi.fn().mockResolvedValue({ data: mockAlerts });
46
+ vi.mocked(getOctokit).mockReturnValue({
47
+ dependabot: { listAlertsForRepo: mockListAlerts }
48
+ });
49
+ const result = await executeAnalyzeDependencies({ owner: 'test', repo: 'repo', severity: 'high' });
50
+ const parsedText = JSON.parse(result.content[0].text);
51
+ expect(parsedText).toHaveLength(2);
52
+ expect(parsedText[0].package_name).toBe('express');
53
+ expect(parsedText[1].package_name).toBe('react');
54
+ });
55
+ it('should throw an error if API fails', async () => {
56
+ const mockListAlerts = vi.fn().mockRejectedValue(new Error('API Error'));
57
+ vi.mocked(getOctokit).mockReturnValue({
58
+ dependabot: { listAlertsForRepo: mockListAlerts }
59
+ });
60
+ await expect(executeAnalyzeDependencies({ owner: 'test', repo: 'repo' }))
61
+ .rejects
62
+ .toThrow('API Error');
63
+ });
64
+ });
65
+ //# sourceMappingURL=analyze-dependencies.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze-dependencies.test.js","sourceRoot":"","sources":["../../src/tools/analyze-dependencies.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function executeCheckCiStatus({ owner, repo, limit }: {
3
+ owner: string;
4
+ repo: string;
5
+ limit: number;
6
+ }): Promise<{
7
+ content: {
8
+ type: "text";
9
+ text: string;
10
+ }[];
11
+ }>;
12
+ export declare function registerCheckCiStatus(server: McpServer): void;
13
+ //# sourceMappingURL=check-ci-status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-ci-status.d.ts","sourceRoot":"","sources":["../../src/tools/check-ci-status.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AASpE,wBAAsB,oBAAoB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;;;;;GAkBhH;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAS7D"}
@@ -0,0 +1,32 @@
1
+ import { z } from "zod";
2
+ import { getOctokit } from "../github/client.js";
3
+ const inputSchema = z.object({
4
+ owner: z.string().describe("GitHub repository owner"),
5
+ repo: z.string().describe("GitHub repository name"),
6
+ limit: z.number().min(1).max(30).default(10).describe("Number of runs to return"),
7
+ });
8
+ export async function executeCheckCiStatus({ owner, repo, limit }) {
9
+ const { data } = await getOctokit().actions.listWorkflowRunsForRepo({ owner, repo, per_page: limit });
10
+ const result = data.workflow_runs.map((run) => ({
11
+ name: run.name,
12
+ status: run.status,
13
+ conclusion: run.conclusion,
14
+ head_branch: run.head_branch,
15
+ created_at: run.created_at,
16
+ updated_at: run.updated_at,
17
+ html_url: run.html_url,
18
+ }));
19
+ return {
20
+ content: [{
21
+ type: "text",
22
+ text: JSON.stringify(result, null, 2),
23
+ }],
24
+ };
25
+ }
26
+ export function registerCheckCiStatus(server) {
27
+ server.registerTool("check_ci_status", {
28
+ description: "Get recent CI/CD workflow runs for a GitHub repository",
29
+ inputSchema,
30
+ }, executeCheckCiStatus);
31
+ }
32
+ //# sourceMappingURL=check-ci-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-ci-status.js","sourceRoot":"","sources":["../../src/tools/check-ci-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IACzB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;IACrD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;IACnD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,0BAA0B,CAAC;CACpF,CAAC,CAAC;AAEH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAkD;IAC7G,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC,OAAO,CAAC,uBAAuB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IACtG,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC5C,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,QAAQ,EAAE,GAAG,CAAC,QAAQ;KACzB,CAAC,CAAC,CAAC;IAEJ,OAAO;QACH,OAAO,EAAE,CAAC;gBACN,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;aACxC,CAAC;KACL,CAAC;AACN,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,MAAiB;IACnD,MAAM,CAAC,YAAY,CACf,iBAAiB,EACjB;QACI,WAAW,EAAE,wDAAwD;QACrE,WAAW;KACd,EACD,oBAAoB,CACvB,CAAC;AACN,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=check-ci-status.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-ci-status.test.d.ts","sourceRoot":"","sources":["../../src/tools/check-ci-status.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,90 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { getOctokit } from '../github/client.js';
3
+ import { executeCheckCiStatus } from './check-ci-status.js';
4
+ vi.mock('../github/client.js');
5
+ describe('executeCheckCiStatus', () => {
6
+ beforeEach(() => {
7
+ vi.resetAllMocks();
8
+ });
9
+ it('should return recent workflow runs', async () => {
10
+ const mockListRuns = vi.fn().mockResolvedValue({
11
+ data: {
12
+ workflow_runs: [
13
+ {
14
+ name: 'CI',
15
+ status: 'completed',
16
+ conclusion: 'success',
17
+ head_branch: 'main',
18
+ created_at: '2023-10-01T00:00:00Z',
19
+ updated_at: '2023-10-01T00:05:00Z',
20
+ html_url: 'https://github.com/test/repo/actions/runs/1',
21
+ id: 123
22
+ },
23
+ {
24
+ name: 'CI',
25
+ status: 'completed',
26
+ conclusion: 'failure',
27
+ head_branch: 'feature-branch',
28
+ created_at: '2023-10-02T00:00:00Z',
29
+ updated_at: '2023-10-02T00:05:00Z',
30
+ html_url: 'https://github.com/test/repo/actions/runs/2',
31
+ id: 124
32
+ }
33
+ ]
34
+ }
35
+ });
36
+ vi.mocked(getOctokit).mockReturnValue({
37
+ actions: { listWorkflowRunsForRepo: mockListRuns }
38
+ });
39
+ const result = await executeCheckCiStatus({ owner: 'test', repo: 'repo', limit: 10 });
40
+ expect(mockListRuns).toHaveBeenCalledWith({ owner: 'test', repo: 'repo', per_page: 10 });
41
+ expect(result.content).toHaveLength(1);
42
+ expect(result.content[0].type).toBe('text');
43
+ const parsedText = JSON.parse(result.content[0].text);
44
+ expect(parsedText).toEqual([
45
+ {
46
+ name: 'CI',
47
+ status: 'completed',
48
+ conclusion: 'success',
49
+ head_branch: 'main',
50
+ created_at: '2023-10-01T00:00:00Z',
51
+ updated_at: '2023-10-01T00:05:00Z',
52
+ html_url: 'https://github.com/test/repo/actions/runs/1'
53
+ },
54
+ {
55
+ name: 'CI',
56
+ status: 'completed',
57
+ conclusion: 'failure',
58
+ head_branch: 'feature-branch',
59
+ created_at: '2023-10-02T00:00:00Z',
60
+ updated_at: '2023-10-02T00:05:00Z',
61
+ html_url: 'https://github.com/test/repo/actions/runs/2'
62
+ }
63
+ ]);
64
+ });
65
+ it('should handle empty workflow runs', async () => {
66
+ const mockListRuns = vi.fn().mockResolvedValue({
67
+ data: {
68
+ workflow_runs: []
69
+ }
70
+ });
71
+ vi.mocked(getOctokit).mockReturnValue({
72
+ actions: { listWorkflowRunsForRepo: mockListRuns }
73
+ });
74
+ const result = await executeCheckCiStatus({ owner: 'test', repo: 'empty-repo', limit: 5 });
75
+ expect(mockListRuns).toHaveBeenCalledWith({ owner: 'test', repo: 'empty-repo', per_page: 5 });
76
+ const parsedText = JSON.parse(result.content[0].text);
77
+ expect(parsedText).toEqual([]);
78
+ });
79
+ it('should throw error if API fails', async () => {
80
+ const error = new Error('API Error');
81
+ const mockListRuns = vi.fn().mockRejectedValue(error);
82
+ vi.mocked(getOctokit).mockReturnValue({
83
+ actions: { listWorkflowRunsForRepo: mockListRuns }
84
+ });
85
+ await expect(executeCheckCiStatus({ owner: 'test', repo: 'error-repo', limit: 10 }))
86
+ .rejects
87
+ .toThrow('API Error');
88
+ });
89
+ });
90
+ //# sourceMappingURL=check-ci-status.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-ci-status.test.js","sourceRoot":"","sources":["../../src/tools/check-ci-status.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function executeGetHealthScore({ owner, repo }: {
3
+ owner: string;
4
+ repo: string;
5
+ }): Promise<{
6
+ content: {
7
+ type: "text";
8
+ text: string;
9
+ }[];
10
+ }>;
11
+ export declare function registerGetHealthScore(server: McpServer): void;
12
+ //# sourceMappingURL=get-health-score.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-health-score.d.ts","sourceRoot":"","sources":["../../src/tools/get-health-score.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAgBpE,wBAAsB,qBAAqB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;;;;;GAuC3F;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAS9D"}
@@ -0,0 +1,47 @@
1
+ import { z } from "zod";
2
+ import { getOctokit } from "../github/client.js";
3
+ import { calculateCiScore, calculateFreshnessScore, calculateSecurityScore, calculateCommunityScore, calculateMaintenanceScore, calculateHealthScore, } from "../scoring/health-score.js";
4
+ const inputSchema = z.object({
5
+ owner: z.string().describe("GitHub repository owner"),
6
+ repo: z.string().describe("GitHub repository name"),
7
+ });
8
+ export async function executeGetHealthScore({ owner, repo }) {
9
+ const octokit = getOctokit();
10
+ const [repoData, runsData] = await Promise.all([
11
+ octokit.repos.get({ owner, repo }),
12
+ octokit.actions.listWorkflowRunsForRepo({ owner, repo, per_page: 10 }),
13
+ ]);
14
+ let alertCounts = { critical: 0, high: 0, medium: 0, low: 0 };
15
+ try {
16
+ const { data: alerts } = await octokit.dependabot.listAlertsForRepo({ owner, repo });
17
+ for (const alert of alerts) {
18
+ const sev = alert.security_advisory.severity;
19
+ if (sev in alertCounts)
20
+ alertCounts[sev]++;
21
+ }
22
+ }
23
+ catch {
24
+ // Dependabot not enabled or no access — keep zeros
25
+ }
26
+ const categories = {
27
+ ci: calculateCiScore(runsData.data.workflow_runs),
28
+ freshness: calculateFreshnessScore(repoData.data.pushed_at ?? new Date().toISOString()),
29
+ security: calculateSecurityScore(alertCounts),
30
+ community: calculateCommunityScore(repoData.data.open_issues_count, repoData.data.forks_count),
31
+ maintenance: calculateMaintenanceScore(repoData.data.license !== null, repoData.data.description !== null, repoData.data.archived),
32
+ };
33
+ const report = calculateHealthScore(`${owner}/${repo}`, categories);
34
+ return {
35
+ content: [{
36
+ type: "text",
37
+ text: JSON.stringify(report, null, 2),
38
+ }],
39
+ };
40
+ }
41
+ export function registerGetHealthScore(server) {
42
+ server.registerTool("get_health_score", {
43
+ description: "Calculate a 0-100 health score for a GitHub repository with grade (A-F), category breakdown, and improvement suggestions",
44
+ inputSchema,
45
+ }, executeGetHealthScore);
46
+ }
47
+ //# sourceMappingURL=get-health-score.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-health-score.js","sourceRoot":"","sources":["../../src/tools/get-health-score.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EACH,gBAAgB,EAChB,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,EACvB,yBAAyB,EACzB,oBAAoB,GACvB,MAAM,4BAA4B,CAAC;AAEpC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IACzB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;IACrD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;CACtD,CAAC,CAAC;AAEH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAmC;IACxF,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAE7B,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC3C,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QAClC,OAAO,CAAC,OAAO,CAAC,uBAAuB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;KACzE,CAAC,CAAC;IAEH,IAAI,WAAW,GAAG,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;IAC9D,IAAI,CAAC;QACD,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACrF,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,KAAK,CAAC,iBAAiB,CAAC,QAAoC,CAAC;YACzE,IAAI,GAAG,IAAI,WAAW;gBAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACL,mDAAmD;IACvD,CAAC;IAED,MAAM,UAAU,GAAG;QACf,EAAE,EAAE,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAoB,CAAC;QACxD,SAAS,EAAE,uBAAuB,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACvF,QAAQ,EAAE,sBAAsB,CAAC,WAAW,CAAC;QAC7C,SAAS,EAAE,uBAAuB,CAAC,QAAQ,CAAC,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC;QAC9F,WAAW,EAAE,yBAAyB,CAClC,QAAQ,CAAC,IAAI,CAAC,OAAO,KAAK,IAAI,EAC9B,QAAQ,CAAC,IAAI,CAAC,WAAW,KAAK,IAAI,EAClC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CACzB;KACJ,CAAC;IAEF,MAAM,MAAM,GAAG,oBAAoB,CAAC,GAAG,KAAK,IAAI,IAAI,EAAE,EAAE,UAAU,CAAC,CAAC;IAEpE,OAAO;QACH,OAAO,EAAE,CAAC;gBACN,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;aACxC,CAAC;KACL,CAAC;AACN,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,MAAiB;IACpD,MAAM,CAAC,YAAY,CACf,kBAAkB,EAClB;QACI,WAAW,EAAE,0HAA0H;QACvI,WAAW;KACd,EACD,qBAAqB,CACxB,CAAC;AACN,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=get-health-score.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-health-score.test.d.ts","sourceRoot":"","sources":["../../src/tools/get-health-score.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,93 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { getOctokit } from '../github/client.js';
3
+ import { executeGetHealthScore } from './get-health-score.js';
4
+ vi.mock('../github/client.js');
5
+ describe('executeGetHealthScore', () => {
6
+ beforeEach(() => {
7
+ vi.resetAllMocks();
8
+ });
9
+ it('should calculate health score successfully with dependabot alerts', async () => {
10
+ const mockReposGet = vi.fn().mockResolvedValue({
11
+ data: {
12
+ pushed_at: '2023-10-01T00:00:00Z',
13
+ open_issues_count: 5,
14
+ forks_count: 10,
15
+ license: { spdx_id: 'MIT' },
16
+ description: 'test repo',
17
+ archived: false
18
+ }
19
+ });
20
+ const mockListRuns = vi.fn().mockResolvedValue({
21
+ data: {
22
+ workflow_runs: [{ conclusion: 'success' }]
23
+ }
24
+ });
25
+ const mockListAlerts = vi.fn().mockResolvedValue({
26
+ data: [
27
+ { security_advisory: { severity: 'critical' } },
28
+ { security_advisory: { severity: 'high' } }
29
+ ]
30
+ });
31
+ vi.mocked(getOctokit).mockReturnValue({
32
+ repos: { get: mockReposGet },
33
+ actions: { listWorkflowRunsForRepo: mockListRuns },
34
+ dependabot: { listAlertsForRepo: mockListAlerts }
35
+ });
36
+ const result = await executeGetHealthScore({ owner: 'test', repo: 'repo' });
37
+ expect(mockReposGet).toHaveBeenCalledWith({ owner: 'test', repo: 'repo' });
38
+ expect(mockListRuns).toHaveBeenCalledWith({ owner: 'test', repo: 'repo', per_page: 10 });
39
+ expect(mockListAlerts).toHaveBeenCalledWith({ owner: 'test', repo: 'repo' });
40
+ expect(result.content).toHaveLength(1);
41
+ expect(result.content[0].type).toBe('text');
42
+ const parsedText = JSON.parse(result.content[0].text);
43
+ expect(parsedText.repo).toBe('test/repo');
44
+ expect(parsedText.score).toBeTypeOf('number');
45
+ expect(parsedText.grade).toBeTypeOf('string');
46
+ // Ensure dependabot parsing worked:
47
+ expect(parsedText.breakdown.security.detail).toContain('1 critical');
48
+ expect(parsedText.breakdown.security.detail).toContain('1 high');
49
+ });
50
+ it('should calculate health score successfully even if dependabot fails', async () => {
51
+ const mockReposGet = vi.fn().mockResolvedValue({
52
+ data: {
53
+ pushed_at: '2023-10-01T00:00:00Z',
54
+ open_issues_count: 5,
55
+ forks_count: 10,
56
+ license: { spdx_id: 'MIT' },
57
+ description: 'test repo',
58
+ archived: false
59
+ }
60
+ });
61
+ const mockListRuns = vi.fn().mockResolvedValue({
62
+ data: {
63
+ workflow_runs: [{ conclusion: 'success' }]
64
+ }
65
+ });
66
+ // Simulating 404 or disabled dependabot
67
+ const mockListAlerts = vi.fn().mockRejectedValue(new Error('Not Found'));
68
+ vi.mocked(getOctokit).mockReturnValue({
69
+ repos: { get: mockReposGet },
70
+ actions: { listWorkflowRunsForRepo: mockListRuns },
71
+ dependabot: { listAlertsForRepo: mockListAlerts }
72
+ });
73
+ const result = await executeGetHealthScore({ owner: 'test', repo: 'repo' });
74
+ const parsedText = JSON.parse(result.content[0].text);
75
+ expect(parsedText.repo).toBe('test/repo');
76
+ // If dependabot fails, it should assume 0 alerts
77
+ expect(parsedText.breakdown.security.detail).toContain('0 critical');
78
+ expect(parsedText.breakdown.security.detail).toContain('0 high');
79
+ });
80
+ it('should fail if repos.get fails', async () => {
81
+ const mockReposGet = vi.fn().mockRejectedValue(new Error('API Error'));
82
+ const mockListRuns = vi.fn().mockResolvedValue({ data: { workflow_runs: [] } });
83
+ vi.mocked(getOctokit).mockReturnValue({
84
+ repos: { get: mockReposGet },
85
+ actions: { listWorkflowRunsForRepo: mockListRuns },
86
+ dependabot: { listAlertsForRepo: vi.fn() }
87
+ });
88
+ await expect(executeGetHealthScore({ owner: 'test', repo: 'error-repo' }))
89
+ .rejects
90
+ .toThrow('API Error');
91
+ });
92
+ });
93
+ //# sourceMappingURL=get-health-score.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-health-score.test.js","sourceRoot":"","sources":["../../src/tools/get-health-score.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;AAE/B,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACnC,UAAU,CAAC,GAAG,EAAE;QACZ,EAAE,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;QAC/E,MAAM,YAAY,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;YAC3C,IAAI,EAAE;gBACF,SAAS,EAAE,sBAAsB;gBACjC,iBAAiB,EAAE,CAAC;gBACpB,WAAW,EAAE,EAAE;gBACf,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;gBAC3B,WAAW,EAAE,WAAW;gBACxB,QAAQ,EAAE,KAAK;aAClB;SACJ,CAAC,CAAC;QAEH,MAAM,YAAY,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;YAC3C,IAAI,EAAE;gBACF,aAAa,EAAE,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;aAC7C;SACJ,CAAC,CAAC;QAEH,MAAM,cAAc,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;YAC7C,IAAI,EAAE;gBACF,EAAE,iBAAiB,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE;gBAC/C,EAAE,iBAAiB,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;aAC9C;SACJ,CAAC,CAAC;QAEH,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC;YAClC,KAAK,EAAE,EAAE,GAAG,EAAE,YAAY,EAAE;YAC5B,OAAO,EAAE,EAAE,uBAAuB,EAAE,YAAY,EAAE;YAClD,UAAU,EAAE,EAAE,iBAAiB,EAAE,cAAc,EAAE;SAC7C,CAAC,CAAC;QAEV,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QAE5E,MAAM,CAAC,YAAY,CAAC,CAAC,oBAAoB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QAC3E,MAAM,CAAC,YAAY,CAAC,CAAC,oBAAoB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;QACzF,MAAM,CAAC,cAAc,CAAC,CAAC,oBAAoB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QAE7E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAE5C,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACtD,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC1C,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC9C,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC9C,oCAAoC;QACpC,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACrE,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE,KAAK,IAAI,EAAE;QACjF,MAAM,YAAY,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;YAC3C,IAAI,EAAE;gBACF,SAAS,EAAE,sBAAsB;gBACjC,iBAAiB,EAAE,CAAC;gBACpB,WAAW,EAAE,EAAE;gBACf,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;gBAC3B,WAAW,EAAE,WAAW;gBACxB,QAAQ,EAAE,KAAK;aAClB;SACJ,CAAC,CAAC;QAEH,MAAM,YAAY,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;YAC3C,IAAI,EAAE;gBACF,aAAa,EAAE,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;aAC7C;SACJ,CAAC,CAAC;QAEH,wCAAwC;QACxC,MAAM,cAAc,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;QAEzE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC;YAClC,KAAK,EAAE,EAAE,GAAG,EAAE,YAAY,EAAE;YAC5B,OAAO,EAAE,EAAE,uBAAuB,EAAE,YAAY,EAAE;YAClD,UAAU,EAAE,EAAE,iBAAiB,EAAE,cAAc,EAAE;SAC7C,CAAC,CAAC;QAEV,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QAE5E,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACtD,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC1C,iDAAiD;QACjD,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACrE,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC5C,MAAM,YAAY,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;QACvE,MAAM,YAAY,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QAEhF,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC;YAClC,KAAK,EAAE,EAAE,GAAG,EAAE,YAAY,EAAE;YAC5B,OAAO,EAAE,EAAE,uBAAuB,EAAE,YAAY,EAAE;YAClD,UAAU,EAAE,EAAE,iBAAiB,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE;SACtC,CAAC,CAAC;QAEV,MAAM,MAAM,CAAC,qBAAqB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;aACrE,OAAO;aACP,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function executeGetRepoHealth({ owner, repo }: {
3
+ owner: string;
4
+ repo: string;
5
+ }): Promise<{
6
+ content: {
7
+ type: "text";
8
+ text: string;
9
+ }[];
10
+ }>;
11
+ export declare function registerGetRepoHealth(server: McpServer): void;
12
+ //# sourceMappingURL=get-repo-health.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-repo-health.d.ts","sourceRoot":"","sources":["../../src/tools/get-repo-health.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQpE,wBAAsB,oBAAoB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;;;;;GAkC1F;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAS7D"}
@@ -0,0 +1,49 @@
1
+ import { z } from "zod";
2
+ import { getOctokit } from "../github/client.js";
3
+ const inputSchema = z.object({
4
+ owner: z.string().describe("GitHub repository owner"),
5
+ repo: z.string().describe("GitHub repository name")
6
+ });
7
+ export async function executeGetRepoHealth({ owner, repo }) {
8
+ try {
9
+ const { data } = await getOctokit().repos.get({ owner, repo });
10
+ return {
11
+ content: [{
12
+ type: "text",
13
+ text: JSON.stringify({
14
+ full_name: data.full_name,
15
+ description: data.description,
16
+ stargazers_count: data.stargazers_count,
17
+ open_issues_count: data.open_issues_count,
18
+ language: data.language,
19
+ license: data.license ? data.license.spdx_id : null,
20
+ pushed_at: data.pushed_at,
21
+ default_branch: data.default_branch,
22
+ archived: data.archived,
23
+ forks_count: data.forks_count
24
+ }, null, 2),
25
+ }]
26
+ };
27
+ }
28
+ catch (error) {
29
+ if (error.status === 404) {
30
+ return {
31
+ content: [{
32
+ type: "text",
33
+ text: JSON.stringify({
34
+ error: "Repository not found",
35
+ details: error.message
36
+ }, null, 2),
37
+ }]
38
+ };
39
+ }
40
+ throw error; //-> will be caught by MCP server
41
+ }
42
+ }
43
+ export function registerGetRepoHealth(server) {
44
+ server.registerTool("get_repo_health", {
45
+ description: "Get health information for a GitHub repository",
46
+ inputSchema
47
+ }, executeGetRepoHealth);
48
+ }
49
+ //# sourceMappingURL=get-repo-health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-repo-health.js","sourceRoot":"","sources":["../../src/tools/get-repo-health.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IACzB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;IACrD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;CACtD,CAAC,CAAC;AAEH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAmC;IACvF,IAAI,CAAC;QACD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/D,OAAO;YACH,OAAO,EAAE,CAAC;oBACN,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACjB,SAAS,EAAE,IAAI,CAAC,SAAS;wBACzB,WAAW,EAAE,IAAI,CAAC,WAAW;wBAC7B,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;wBACvC,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;wBACzC,QAAQ,EAAE,IAAI,CAAC,QAAQ;wBACvB,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;wBACnD,SAAS,EAAE,IAAI,CAAC,SAAS;wBACzB,cAAc,EAAE,IAAI,CAAC,cAAc;wBACnC,QAAQ,EAAE,IAAI,CAAC,QAAQ;wBACvB,WAAW,EAAE,IAAI,CAAC,WAAW;qBAChC,EAAE,IAAI,EAAE,CAAC,CAAC;iBACd,CAAC;SACL,CAAC;IACN,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,IAAK,KAA6B,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAChD,OAAO;gBACH,OAAO,EAAE,CAAC;wBACN,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;4BACjB,KAAK,EAAE,sBAAsB;4BAC7B,OAAO,EAAG,KAAe,CAAC,OAAO;yBACpC,EAAE,IAAI,EAAE,CAAC,CAAC;qBACd,CAAC;aACL,CAAC;QACN,CAAC;QACD,MAAM,KAAK,CAAC,CAAC,iCAAiC;IAClD,CAAC;AACL,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,MAAiB;IACnD,MAAM,CAAC,YAAY,CACf,iBAAiB,EACjB;QACI,WAAW,EAAE,gDAAgD;QAC7D,WAAW;KACd,EACD,oBAAoB,CACvB,CAAC;AACN,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=get-repo-health.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-repo-health.test.d.ts","sourceRoot":"","sources":["../../src/tools/get-repo-health.test.ts"],"names":[],"mappings":""}