@rulecatch/mcp-server 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.
@@ -0,0 +1,10 @@
1
+ /**
2
+ * HTTP client for the Rulecatch MCP API.
3
+ * Reads config from ~/.claude/rulecatch/config.json.
4
+ */
5
+ export declare class ApiClient {
6
+ private apiKey;
7
+ private baseUrl;
8
+ constructor();
9
+ request<T>(path: string, params?: Record<string, string>): Promise<T>;
10
+ }
@@ -0,0 +1,80 @@
1
+ /**
2
+ * HTTP client for the Rulecatch MCP API.
3
+ * Reads config from ~/.claude/rulecatch/config.json.
4
+ */
5
+ import { readFileSync, existsSync } from 'fs';
6
+ import { join } from 'path';
7
+ import { homedir } from 'os';
8
+ const CONFIG_PATH = join(homedir(), '.claude', 'rulecatch', 'config.json');
9
+ const MCP_ENDPOINTS = {
10
+ us: 'https://mcp.rulecatch.ai',
11
+ eu: 'https://mcp-eu.rulecatch.ai',
12
+ };
13
+ function loadConfig() {
14
+ if (!existsSync(CONFIG_PATH)) {
15
+ throw new Error('Rulecatch not configured. Run `npx @rulecatch/ai-pooler init` to set up.');
16
+ }
17
+ const raw = readFileSync(CONFIG_PATH, 'utf-8');
18
+ const config = JSON.parse(raw);
19
+ if (!config.apiKey) {
20
+ throw new Error('API key missing from config. Run `npx @rulecatch/ai-pooler init` to reconfigure.');
21
+ }
22
+ return config;
23
+ }
24
+ function getBaseUrl(config) {
25
+ // Priority: mcpEndpoint > derive from region
26
+ if (config.mcpEndpoint)
27
+ return config.mcpEndpoint;
28
+ return MCP_ENDPOINTS[config.region] || MCP_ENDPOINTS.us;
29
+ }
30
+ export class ApiClient {
31
+ apiKey;
32
+ baseUrl;
33
+ constructor() {
34
+ const config = loadConfig();
35
+ this.apiKey = config.apiKey;
36
+ this.baseUrl = getBaseUrl(config);
37
+ }
38
+ async request(path, params) {
39
+ const url = new URL(`/api/v1/mcp${path}`, this.baseUrl);
40
+ if (params) {
41
+ for (const [key, value] of Object.entries(params)) {
42
+ if (value !== undefined && value !== '') {
43
+ url.searchParams.set(key, value);
44
+ }
45
+ }
46
+ }
47
+ let response;
48
+ try {
49
+ response = await fetch(url.toString(), {
50
+ method: 'GET',
51
+ headers: {
52
+ Authorization: `Bearer ${this.apiKey}`,
53
+ Accept: 'application/json',
54
+ },
55
+ });
56
+ }
57
+ catch (err) {
58
+ throw new Error('Cannot reach Rulecatch API. Check your internet connection.');
59
+ }
60
+ if (response.status === 401) {
61
+ throw new Error('Invalid API key. Run `npx @rulecatch/ai-pooler init` to configure.');
62
+ }
63
+ if (response.status === 403) {
64
+ const body = await response.json().catch(() => ({ error: '' }));
65
+ if (body.requiredPlans) {
66
+ throw new Error(`MCP tools require a Pro or Enterprise plan. Upgrade at dashboard.rulecatch.ai/billing.`);
67
+ }
68
+ throw new Error(body.error || 'Subscription inactive. Visit dashboard.rulecatch.ai/billing.');
69
+ }
70
+ if (response.status === 429) {
71
+ throw new Error('Rate limited. Try again in a moment.');
72
+ }
73
+ if (!response.ok) {
74
+ const body = await response.text().catch(() => '');
75
+ throw new Error(`API error (${response.status}): ${body}`);
76
+ }
77
+ return (await response.json());
78
+ }
79
+ }
80
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAS7B,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;AAE3E,MAAM,aAAa,GAA2B;IAC5C,EAAE,EAAE,0BAA0B;IAC9B,EAAE,EAAE,6BAA6B;CAClC,CAAC;AAEF,SAAS,UAAU;IACjB,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CACb,0EAA0E,CAC3E,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAoB,CAAC;IAElD,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CACb,kFAAkF,CACnF,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,UAAU,CAAC,MAAuB;IACzC,6CAA6C;IAC7C,IAAI,MAAM,CAAC,WAAW;QAAE,OAAO,MAAM,CAAC,WAAW,CAAC;IAClD,OAAO,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,aAAa,CAAC,EAAE,CAAC;AAC1D,CAAC;AAED,MAAM,OAAO,SAAS;IACZ,MAAM,CAAS;IACf,OAAO,CAAS;IAExB;QACE,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,OAAO,CAAI,IAAY,EAAE,MAA+B;QAC5D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,cAAc,IAAI,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAExD,IAAI,MAAM,EAAE,CAAC;YACX,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAClD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;oBACxC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;gBACnC,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,QAAkB,CAAC;QACvB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;gBACrC,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;oBACtC,MAAM,EAAE,kBAAkB;iBAC3B;aACF,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,6DAA6D,CAC9D,CAAC;QACJ,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CACb,oEAAoE,CACrE,CAAC;QACJ,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAiD,CAAC;YAChH,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;gBACvB,MAAM,IAAI,KAAK,CACb,wFAAwF,CACzF,CAAC;YACJ,CAAC;YACD,MAAM,IAAI,KAAK,CACb,IAAI,CAAC,KAAK,IAAI,8DAA8D,CAC7E,CAAC;QACJ,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YACnD,MAAM,IAAI,KAAK,CAAC,cAAc,QAAQ,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;QAC7D,CAAC;QAED,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAM,CAAC;IACtC,CAAC;CACF"}
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Rulecatch MCP Server
4
+ *
5
+ * Runs on the customer's machine via stdio transport.
6
+ * Provides 5 tools for querying violations, rules, and generating fix plans.
7
+ *
8
+ * IMPORTANT: Never write to stdout (console.log) — it corrupts JSON-RPC messages.
9
+ * Use console.error() for logging.
10
+ */
11
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Rulecatch MCP Server
4
+ *
5
+ * Runs on the customer's machine via stdio transport.
6
+ * Provides 5 tools for querying violations, rules, and generating fix plans.
7
+ *
8
+ * IMPORTANT: Never write to stdout (console.log) — it corrupts JSON-RPC messages.
9
+ * Use console.error() for logging.
10
+ */
11
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
12
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
13
+ import { ApiClient } from './api-client.js';
14
+ import { registerTools } from './tools.js';
15
+ async function main() {
16
+ const server = new McpServer({
17
+ name: 'rulecatch',
18
+ version: '1.0.0',
19
+ });
20
+ let client;
21
+ try {
22
+ client = new ApiClient();
23
+ }
24
+ catch (err) {
25
+ console.error(`[Rulecatch MCP] Config error: ${err.message}`);
26
+ process.exit(1);
27
+ }
28
+ registerTools(server, client);
29
+ const transport = new StdioServerTransport();
30
+ await server.connect(transport);
31
+ console.error('[Rulecatch MCP] Server running on stdio');
32
+ }
33
+ main().catch((error) => {
34
+ console.error('[Rulecatch MCP] Fatal error:', error);
35
+ process.exit(1);
36
+ });
37
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,IAAI,MAAiB,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;IAC3B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,iCAAkC,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE9B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,OAAO,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;AAC3D,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;IACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Rulecatch MCP tool definitions and handlers.
3
+ *
4
+ * 6 tools that map 1:1 to MCP API endpoints:
5
+ * - rulecatch_summary
6
+ * - rulecatch_violations
7
+ * - rulecatch_violation_detail
8
+ * - rulecatch_rules
9
+ * - rulecatch_fix_plan
10
+ * - rulecatch_top_rules
11
+ */
12
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
13
+ import { ApiClient } from './api-client.js';
14
+ export declare function registerTools(server: McpServer, client: ApiClient): void;
package/dist/tools.js ADDED
@@ -0,0 +1,394 @@
1
+ /**
2
+ * Rulecatch MCP tool definitions and handlers.
3
+ *
4
+ * 6 tools that map 1:1 to MCP API endpoints:
5
+ * - rulecatch_summary
6
+ * - rulecatch_violations
7
+ * - rulecatch_violation_detail
8
+ * - rulecatch_rules
9
+ * - rulecatch_fix_plan
10
+ * - rulecatch_top_rules
11
+ */
12
+ import { z } from 'zod';
13
+ export function registerTools(server, client) {
14
+ // ── Summary ───────────────────────────────────────────────────────────────
15
+ server.registerTool('rulecatch_summary', {
16
+ description: 'Get a summary of Rulecatch violations and AI coding activity for a time period. Includes top violated rules and category breakdown.',
17
+ inputSchema: {
18
+ period: z
19
+ .string()
20
+ .optional()
21
+ .describe('Time period: today, 3d, 7d, 14d, 30d, this_week, this_month, all. Default: 7d'),
22
+ },
23
+ }, async ({ period }) => {
24
+ try {
25
+ const data = await client.request('/summary', {
26
+ period: period || '7d',
27
+ });
28
+ const v = data.violations;
29
+ const a = data.activity;
30
+ const lines = [
31
+ `Rulecatch Summary (${data.period})`,
32
+ '',
33
+ `Violations: ${v.total} total (${v.errors} errors, ${v.warnings} warnings, ${v.info} info)`,
34
+ `Corrected: ${v.corrected}/${v.total} (${v.correctionRate}%)`,
35
+ `Estimated Loss: $${v.estimatedLoss}`,
36
+ '',
37
+ `Sessions: ${a.sessions}`,
38
+ `Tool Calls: ${a.toolCalls}`,
39
+ `Cost: $${a.totalCost.toFixed(2)}`,
40
+ `Lines: +${a.linesAdded} / -${a.linesRemoved}`,
41
+ ];
42
+ if (data.topRules && data.topRules.length > 0) {
43
+ lines.push('', 'Top Violated Rules:');
44
+ for (const r of data.topRules) {
45
+ lines.push(` ${r.count}x ${r.ruleName} [${r.severity.toUpperCase()}]`);
46
+ }
47
+ }
48
+ if (data.byCategory && data.byCategory.length > 0) {
49
+ lines.push('', 'By Category:');
50
+ for (const c of data.byCategory) {
51
+ lines.push(` ${c.category}: ${c.count} (${c.errors} errors, ${c.warnings} warnings)`);
52
+ }
53
+ }
54
+ const text = lines.join('\n');
55
+ return { content: [{ type: 'text', text }] };
56
+ }
57
+ catch (err) {
58
+ return {
59
+ content: [{ type: 'text', text: `Error: ${err.message}` }],
60
+ isError: true,
61
+ };
62
+ }
63
+ });
64
+ // ── Violations list ───────────────────────────────────────────────────────
65
+ server.registerTool('rulecatch_violations', {
66
+ description: 'List Rulecatch rule violations. Filter by severity, category, session, corrected status, rule name, file path, language, tool, or branch.',
67
+ inputSchema: {
68
+ period: z.string().optional().describe('Time period (default: 7d)'),
69
+ severity: z
70
+ .string()
71
+ .optional()
72
+ .describe('Filter by severity: error, warning, info'),
73
+ category: z
74
+ .string()
75
+ .optional()
76
+ .describe('Filter by rule category: Security, Database Patterns, Coding Standards, Architecture, etc.'),
77
+ sessionId: z
78
+ .string()
79
+ .optional()
80
+ .describe('Filter by AI session ID to see violations from a specific coding session'),
81
+ corrected: z
82
+ .string()
83
+ .optional()
84
+ .describe('Filter by corrected status: true or false'),
85
+ rule: z.string().optional().describe('Filter by rule name'),
86
+ file: z.string().optional().describe('Filter by file path'),
87
+ language: z.string().optional().describe('Filter by programming language'),
88
+ toolName: z.string().optional().describe('Filter by tool name (e.g. Write, Edit)'),
89
+ branch: z.string().optional().describe('Filter by git branch name'),
90
+ limit: z
91
+ .string()
92
+ .optional()
93
+ .describe('Max results (default: 20, max: 50)'),
94
+ },
95
+ }, async ({ period, severity, category, sessionId, corrected, rule, file, language, toolName, branch, limit }) => {
96
+ try {
97
+ const params = {};
98
+ if (period)
99
+ params.period = period;
100
+ if (severity)
101
+ params.severity = severity;
102
+ if (category)
103
+ params.category = category;
104
+ if (sessionId)
105
+ params.sessionId = sessionId;
106
+ if (corrected)
107
+ params.corrected = corrected;
108
+ if (rule)
109
+ params.rule = rule;
110
+ if (file)
111
+ params.file = file;
112
+ if (language)
113
+ params.language = language;
114
+ if (toolName)
115
+ params.toolName = toolName;
116
+ if (branch)
117
+ params.branch = branch;
118
+ if (limit)
119
+ params.limit = limit;
120
+ const data = await client.request('/violations', params);
121
+ if (data.violations.length === 0) {
122
+ return {
123
+ content: [
124
+ {
125
+ type: 'text',
126
+ text: 'No violations found for the given filters.',
127
+ },
128
+ ],
129
+ };
130
+ }
131
+ const lines = data.violations.map((v) => {
132
+ const status = v.corrected ? 'FIXED' : v.severity.toUpperCase();
133
+ return `[${status}] ${v.ruleName} — ${v.file}:${v.line} (${v.id})`;
134
+ });
135
+ const text = [
136
+ `${data.total} violations found (showing ${data.violations.length}):`,
137
+ '',
138
+ ...lines,
139
+ ].join('\n');
140
+ return { content: [{ type: 'text', text }] };
141
+ }
142
+ catch (err) {
143
+ return {
144
+ content: [{ type: 'text', text: `Error: ${err.message}` }],
145
+ isError: true,
146
+ };
147
+ }
148
+ });
149
+ // ── Violation detail ──────────────────────────────────────────────────────
150
+ server.registerTool('rulecatch_violation_detail', {
151
+ description: 'Get full details for a specific violation: file path, line number, rule description, matched conditions, git context. Use this before fixing a violation.',
152
+ inputSchema: {
153
+ id: z.string().describe('Violation ID (from rulecatch_violations or rulecatch_fix_plan)'),
154
+ },
155
+ }, async ({ id }) => {
156
+ try {
157
+ const v = await client.request(`/violations/${id}`);
158
+ const lines = [
159
+ `Rule: ${v.ruleName}`,
160
+ v.ruleDescription ? `Description: ${v.ruleDescription}` : '',
161
+ v.ruleCategory ? `Category: ${v.ruleCategory}` : '',
162
+ `Severity: ${v.severity}`,
163
+ v.fixTimeMinutes ? `Est. Fix Time: ${v.fixTimeMinutes} min` : '',
164
+ '',
165
+ `File: ${v.file}:${v.line}`,
166
+ v.language ? `Language: ${v.language}` : '',
167
+ v.toolName ? `Tool: ${v.toolName}` : '',
168
+ `Corrected: ${v.corrected}`,
169
+ '',
170
+ ];
171
+ if (v.fixGuide) {
172
+ lines.push('Fix Guide:');
173
+ lines.push(` ${v.fixGuide}`);
174
+ lines.push('');
175
+ }
176
+ if (v.wrongExample) {
177
+ lines.push('Wrong:');
178
+ lines.push(v.wrongExample);
179
+ lines.push('');
180
+ }
181
+ if (v.correctExample) {
182
+ lines.push('Correct:');
183
+ lines.push(v.correctExample);
184
+ lines.push('');
185
+ }
186
+ if (v.matchedConditions && v.matchedConditions.length > 0) {
187
+ lines.push('Matched Conditions:');
188
+ for (const c of v.matchedConditions) {
189
+ lines.push(` - ${c.field} ${c.operator} "${c.value}"`);
190
+ }
191
+ lines.push('');
192
+ }
193
+ if (v.gitBranch || v.gitCommit || v.gitRepo) {
194
+ lines.push('Git Context:');
195
+ if (v.gitRepo)
196
+ lines.push(` Repo: ${v.gitRepo}`);
197
+ if (v.gitBranch)
198
+ lines.push(` Branch: ${v.gitBranch}`);
199
+ if (v.gitCommit)
200
+ lines.push(` Commit: ${v.gitCommit}`);
201
+ }
202
+ const text = lines.filter(Boolean).join('\n');
203
+ return { content: [{ type: 'text', text }] };
204
+ }
205
+ catch (err) {
206
+ return {
207
+ content: [{ type: 'text', text: `Error: ${err.message}` }],
208
+ isError: true,
209
+ };
210
+ }
211
+ });
212
+ // ── Rules list ────────────────────────────────────────────────────────────
213
+ server.registerTool('rulecatch_rules', {
214
+ description: 'List all active Rulecatch rules with their conditions, severity, and descriptions.',
215
+ inputSchema: {},
216
+ }, async () => {
217
+ try {
218
+ const data = await client.request('/rules');
219
+ if (data.rules.length === 0) {
220
+ return {
221
+ content: [
222
+ {
223
+ type: 'text',
224
+ text: 'No rules configured. Add rules in the Rulecatch dashboard.',
225
+ },
226
+ ],
227
+ };
228
+ }
229
+ const lines = data.rules.map((r) => {
230
+ const status = r.enabled ? r.severity.toUpperCase() : 'DISABLED';
231
+ let line = `[${status}] ${r.name}`;
232
+ if (r.description)
233
+ line += ` — ${r.description}`;
234
+ if (r.conditions && r.conditions.length > 0) {
235
+ const condStr = r.conditions
236
+ .map((c) => `${c.field} ${c.operator} "${c.value}"`)
237
+ .join(', ');
238
+ line += `\n Conditions: ${condStr}`;
239
+ }
240
+ return line;
241
+ });
242
+ const text = [`${data.rules.length} rules:`, '', ...lines].join('\n');
243
+ return { content: [{ type: 'text', text }] };
244
+ }
245
+ catch (err) {
246
+ return {
247
+ content: [{ type: 'text', text: `Error: ${err.message}` }],
248
+ isError: true,
249
+ };
250
+ }
251
+ });
252
+ // ── Fix plan ──────────────────────────────────────────────────────────────
253
+ server.registerTool('rulecatch_fix_plan', {
254
+ description: 'Get a file-by-file plan of uncorrected violations to fix. Groups by file with line numbers, rule descriptions, and conditions. Filter by session to fix violations from a specific coding session.',
255
+ inputSchema: {
256
+ period: z.string().optional().describe('Time period (default: 7d)'),
257
+ severity: z
258
+ .string()
259
+ .optional()
260
+ .describe('Filter severity: error, warning, info. Default: error + warning'),
261
+ sessionId: z
262
+ .string()
263
+ .optional()
264
+ .describe('Filter by AI session ID to fix violations from a specific coding session'),
265
+ category: z
266
+ .string()
267
+ .optional()
268
+ .describe('Filter by rule category: Security, Database Patterns, etc.'),
269
+ },
270
+ }, async ({ period, severity, sessionId, category }) => {
271
+ try {
272
+ const params = {};
273
+ if (period)
274
+ params.period = period;
275
+ if (severity)
276
+ params.severity = severity;
277
+ if (sessionId)
278
+ params.sessionId = sessionId;
279
+ if (category)
280
+ params.category = category;
281
+ const data = await client.request('/fix-plan', params);
282
+ if (data.files.length === 0) {
283
+ return {
284
+ content: [
285
+ {
286
+ type: 'text',
287
+ text: 'No uncorrected violations found. Everything looks clean!',
288
+ },
289
+ ],
290
+ };
291
+ }
292
+ const lines = [
293
+ `Fix Plan: ${data.totalUncorrected} uncorrected violations across ${data.files.length} files`,
294
+ `Estimated fix time: ${data.estimatedFixTime} minutes (~$${data.estimatedCost} cost)`,
295
+ '',
296
+ ];
297
+ for (const f of data.files) {
298
+ lines.push(`--- ${f.file} (${f.violationCount} violations, worst: ${f.worstSeverity}) ---`);
299
+ for (const v of f.violations) {
300
+ lines.push(` Line ${v.line}: [${v.severity.toUpperCase()}] ${v.ruleName}`);
301
+ if (v.ruleDescription) {
302
+ lines.push(` ${v.ruleDescription}`);
303
+ }
304
+ if (v.fixGuide) {
305
+ lines.push(` Fix: ${v.fixGuide}`);
306
+ }
307
+ if (v.wrongExample) {
308
+ lines.push(` Wrong: ${v.wrongExample}`);
309
+ }
310
+ if (v.correctExample) {
311
+ lines.push(` Correct: ${v.correctExample}`);
312
+ }
313
+ if (v.matchedConditions && v.matchedConditions.length > 0) {
314
+ for (const c of v.matchedConditions) {
315
+ lines.push(` → ${c.field} ${c.operator} "${c.value}"`);
316
+ }
317
+ }
318
+ }
319
+ lines.push('');
320
+ }
321
+ const text = lines.join('\n');
322
+ return { content: [{ type: 'text', text }] };
323
+ }
324
+ catch (err) {
325
+ return {
326
+ content: [{ type: 'text', text: `Error: ${err.message}` }],
327
+ isError: true,
328
+ };
329
+ }
330
+ });
331
+ // ── Top Rules ─────────────────────────────────────────────────────────────
332
+ server.registerTool('rulecatch_top_rules', {
333
+ description: 'Get the most frequently violated rules, ranked by count. Shows which rules are broken most often, with correction rates and category breakdown.',
334
+ inputSchema: {
335
+ period: z.string().optional().describe('Time period (default: 7d)'),
336
+ severity: z
337
+ .string()
338
+ .optional()
339
+ .describe('Filter by severity: error, warning, info'),
340
+ category: z
341
+ .string()
342
+ .optional()
343
+ .describe('Filter by rule category: Security, Database Patterns, etc.'),
344
+ limit: z
345
+ .string()
346
+ .optional()
347
+ .describe('Max rules to return (default: 10, max: 25)'),
348
+ },
349
+ }, async ({ period, severity, category, limit }) => {
350
+ try {
351
+ const params = {};
352
+ if (period)
353
+ params.period = period;
354
+ if (severity)
355
+ params.severity = severity;
356
+ if (category)
357
+ params.category = category;
358
+ if (limit)
359
+ params.limit = limit;
360
+ const data = await client.request('/top-rules', params);
361
+ if (data.rules.length === 0) {
362
+ return {
363
+ content: [
364
+ {
365
+ type: 'text',
366
+ text: 'No violations found for the given filters.',
367
+ },
368
+ ],
369
+ };
370
+ }
371
+ const lines = [
372
+ `Top Violated Rules (${data.period}) — ${data.totalViolations} total violations:`,
373
+ '',
374
+ ];
375
+ for (let i = 0; i < data.rules.length; i++) {
376
+ const r = data.rules[i];
377
+ lines.push(`${i + 1}. ${r.ruleName} — ${r.count} violations (${r.percentOfTotal}% of total)`);
378
+ lines.push(` [${r.severity.toUpperCase()}] ${r.category} | Corrected: ${r.correctionRate}%`);
379
+ if (r.description) {
380
+ lines.push(` ${r.description}`);
381
+ }
382
+ lines.push('');
383
+ }
384
+ return { content: [{ type: 'text', text: lines.join('\n') }] };
385
+ }
386
+ catch (err) {
387
+ return {
388
+ content: [{ type: 'text', text: `Error: ${err.message}` }],
389
+ isError: true,
390
+ };
391
+ }
392
+ });
393
+ }
394
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Response types from the MCP API service.
3
+ */
4
+ export interface SummaryTopRule {
5
+ ruleName: string;
6
+ count: number;
7
+ severity: string;
8
+ }
9
+ export interface SummaryCategoryBreakdown {
10
+ category: string;
11
+ count: number;
12
+ errors: number;
13
+ warnings: number;
14
+ }
15
+ export interface SummaryResponse {
16
+ violations: {
17
+ total: number;
18
+ corrected: number;
19
+ correctionRate: number;
20
+ errors: number;
21
+ warnings: number;
22
+ info: number;
23
+ estimatedLoss: number;
24
+ };
25
+ activity: {
26
+ sessions: number;
27
+ toolCalls: number;
28
+ totalCost: number;
29
+ linesAdded: number;
30
+ linesRemoved: number;
31
+ };
32
+ topRules: SummaryTopRule[];
33
+ byCategory: SummaryCategoryBreakdown[];
34
+ period: string;
35
+ }
36
+ export interface TopRuleItem {
37
+ ruleName: string;
38
+ count: number;
39
+ correctedCount: number;
40
+ correctionRate: number;
41
+ percentOfTotal: number;
42
+ severity: string;
43
+ category: string;
44
+ description?: string;
45
+ lastSeen: string;
46
+ }
47
+ export interface TopRulesResponse {
48
+ rules: TopRuleItem[];
49
+ totalViolations: number;
50
+ period: string;
51
+ }
52
+ export interface ViolationListItem {
53
+ id: string;
54
+ ruleName: string;
55
+ ruleDescription?: string;
56
+ severity: string;
57
+ file: string;
58
+ line: number;
59
+ toolName?: string;
60
+ gitBranch?: string;
61
+ corrected: boolean;
62
+ fixTimeMinutes?: number;
63
+ timestamp: string;
64
+ }
65
+ export interface ViolationsResponse {
66
+ violations: ViolationListItem[];
67
+ total: number;
68
+ }
69
+ export interface ViolationDetailResponse {
70
+ id: string;
71
+ ruleName: string;
72
+ ruleDescription?: string;
73
+ ruleCategory?: string;
74
+ ruleSource?: string;
75
+ severity: string;
76
+ fixTimeMinutes?: number;
77
+ file: string;
78
+ line: number;
79
+ language?: string;
80
+ toolName?: string;
81
+ matchedConditions?: Array<{
82
+ field: string;
83
+ operator: string;
84
+ value: string;
85
+ }>;
86
+ corrected: boolean;
87
+ gitUsername?: string;
88
+ gitEmail?: string;
89
+ gitRepo?: string;
90
+ gitBranch?: string;
91
+ gitCommit?: string;
92
+ fixGuide?: string;
93
+ wrongExample?: string;
94
+ correctExample?: string;
95
+ timestamp: string;
96
+ sessionId?: string;
97
+ eventId?: string;
98
+ }
99
+ export interface RuleItem {
100
+ id: string;
101
+ name: string;
102
+ description?: string;
103
+ category?: string;
104
+ severity: string;
105
+ enabled: boolean;
106
+ fixTimeMinutes?: number;
107
+ conditions?: Array<{
108
+ field: string;
109
+ operator: string;
110
+ value: string;
111
+ }>;
112
+ }
113
+ export interface RulesResponse {
114
+ rules: RuleItem[];
115
+ }
116
+ export interface FixPlanFile {
117
+ file: string;
118
+ violationCount: number;
119
+ worstSeverity: string;
120
+ violations: Array<{
121
+ id: string;
122
+ ruleName: string;
123
+ ruleDescription?: string;
124
+ severity: string;
125
+ line: number;
126
+ fixTimeMinutes?: number;
127
+ matchedConditions?: Array<{
128
+ field: string;
129
+ operator: string;
130
+ value: string;
131
+ }>;
132
+ fixGuide?: string;
133
+ wrongExample?: string;
134
+ correctExample?: string;
135
+ }>;
136
+ }
137
+ export interface FixPlanResponse {
138
+ totalUncorrected: number;
139
+ estimatedFixTime: number;
140
+ estimatedCost: number;
141
+ files: FixPlanFile[];
142
+ }
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Response types from the MCP API service.
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "@rulecatch/mcp-server",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "description": "Rulecatch MCP server - query violations and rules from Claude Code",
6
+ "bin": {
7
+ "rulecatch-mcp": "./dist/index.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc && chmod 755 dist/index.js",
11
+ "dev": "tsx src/index.ts",
12
+ "test": "vitest",
13
+ "test:run": "vitest run"
14
+ },
15
+ "files": ["dist"],
16
+ "dependencies": {
17
+ "@modelcontextprotocol/sdk": "^1.2.0",
18
+ "zod": "^3.22.0"
19
+ },
20
+ "devDependencies": {
21
+ "typescript": "^5.0.0",
22
+ "tsx": "^4.0.0",
23
+ "@types/node": "^20.0.0",
24
+ "vitest": "^1.0.0"
25
+ }
26
+ }