rebar-mcp 2.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 (248) hide show
  1. package/.claude/agents/template-writer.md +43 -0
  2. package/.claude/agents/test-runner.md +47 -0
  3. package/.claude/mcp.json +9 -0
  4. package/.claude/settings.json +29 -0
  5. package/.claude/skills/ /SKILL.md +21 -0
  6. package/.claude/skills/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/SKILL.md +21 -0
  7. package/.claude/skills/bmmibwetxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
  8. package/.claude/skills/bmmibwjgvxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
  9. package/.claude/skills/bmmibwsesxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
  10. package/.claude/skills/bmmibwxufxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
  11. package/.claude/skills/bmmibx3r9xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
  12. package/.claude/skills/bmmji0lrkxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
  13. package/.claude/skills/bmmjiniphxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
  14. package/.claude/skills/bmmjio86zxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
  15. package/.claude/skills/bmmjiolfbxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
  16. package/.claude/skills/bmmjit1lvxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
  17. package/.claude/skills/bmmjita1qxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
  18. package/.claude/skills/bnd-mmibweu3/SKILL.md +21 -0
  19. package/.claude/skills/bnd-mmibwjh4/SKILL.md +21 -0
  20. package/.claude/skills/bnd-mmibwsey/SKILL.md +21 -0
  21. package/.claude/skills/bnd-mmibwxup/SKILL.md +21 -0
  22. package/.claude/skills/bnd-mmibx3rg/SKILL.md +21 -0
  23. package/.claude/skills/bnd-mmji0lrp/SKILL.md +21 -0
  24. package/.claude/skills/bnd-mmjinipm/SKILL.md +21 -0
  25. package/.claude/skills/bnd-mmjio875/SKILL.md +21 -0
  26. package/.claude/skills/bnd-mmjiolfg/SKILL.md +21 -0
  27. package/.claude/skills/bnd-mmjit1m3/SKILL.md +21 -0
  28. package/.claude/skills/bnd-mmjita1x/SKILL.md +21 -0
  29. package/.claude/skills/coercion-test/SKILL.md +50 -0
  30. package/.claude/skills/large-skill/SKILL.md +21 -0
  31. package/.claude/skills/long-desc-skill/SKILL.md +21 -0
  32. package/.claude/skills/mcp-dev/SKILL.md +61 -0
  33. package/.claude/skills/nl-mmibweus/SKILL.md +25 -0
  34. package/.claude/skills/nl-mmibwjhf/SKILL.md +25 -0
  35. package/.claude/skills/nl-mmibwsf7/SKILL.md +25 -0
  36. package/.claude/skills/nl-mmibwxvq/SKILL.md +25 -0
  37. package/.claude/skills/nl-mmibx3rt/SKILL.md +25 -0
  38. package/.claude/skills/nl-mmji0lrz/SKILL.md +25 -0
  39. package/.claude/skills/nl-mmjinipx/SKILL.md +25 -0
  40. package/.claude/skills/nl-mmjio87f/SKILL.md +25 -0
  41. package/.claude/skills/nl-mmjiolfs/SKILL.md +25 -0
  42. package/.claude/skills/nl-mmjit1mc/SKILL.md +25 -0
  43. package/.claude/skills/nl-mmjita26/SKILL.md +25 -0
  44. package/.claude/skills/rapid-1/SKILL.md +21 -0
  45. package/.claude/skills/rapid-2/SKILL.md +21 -0
  46. package/.claude/skills/rapid-3/SKILL.md +21 -0
  47. package/.claude/skills/rapid-4/SKILL.md +21 -0
  48. package/.claude/skills/rapid-5/SKILL.md +21 -0
  49. package/.claude/skills/test/", /"malicious/": /"true/SKILL.md" +69 -0
  50. package/.claude/skills/test-emoji-/360/237/230/200-skill/SKILL.md +69 -0
  51. package/.claude/skills/test-skill/SKILL.md +69 -0
  52. package/.claude/skills/test; rm -rf /; skill/SKILL.md +69 -0
  53. package/.claude/skills/test<script>alert(1)</script>skill/SKILL.md +69 -0
  54. package/.claudeignore +5 -0
  55. package/.mcp.json +3 -0
  56. package/CHANGELOG.md +29 -0
  57. package/CLAUDE.md +76 -0
  58. package/LICENSE +21 -0
  59. package/README.md +149 -0
  60. package/ROADMAP.md +526 -0
  61. package/ccboot-PRD-v1.0.docx.md +732 -0
  62. package/ccboot-v1.2.0-enforcement-spec.md +1272 -0
  63. package/dist/cli.d.ts +3 -0
  64. package/dist/cli.d.ts.map +1 -0
  65. package/dist/cli.js +674 -0
  66. package/dist/cli.js.map +1 -0
  67. package/dist/constants.d.ts +25 -0
  68. package/dist/constants.d.ts.map +1 -0
  69. package/dist/constants.js +118 -0
  70. package/dist/constants.js.map +1 -0
  71. package/dist/index.d.ts +3 -0
  72. package/dist/index.d.ts.map +1 -0
  73. package/dist/index.js +47 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/schemas/common.d.ts +62 -0
  76. package/dist/schemas/common.d.ts.map +1 -0
  77. package/dist/schemas/common.js +15 -0
  78. package/dist/schemas/common.js.map +1 -0
  79. package/dist/schemas/scaffolding.d.ts +277 -0
  80. package/dist/schemas/scaffolding.d.ts.map +1 -0
  81. package/dist/schemas/scaffolding.js +133 -0
  82. package/dist/schemas/scaffolding.js.map +1 -0
  83. package/dist/services/claudemd-generator.d.ts +16 -0
  84. package/dist/services/claudemd-generator.d.ts.map +1 -0
  85. package/dist/services/claudemd-generator.js +426 -0
  86. package/dist/services/claudemd-generator.js.map +1 -0
  87. package/dist/services/codex-generator.d.ts +6 -0
  88. package/dist/services/codex-generator.d.ts.map +1 -0
  89. package/dist/services/codex-generator.js +35 -0
  90. package/dist/services/codex-generator.js.map +1 -0
  91. package/dist/services/cursor-generator.d.ts +15 -0
  92. package/dist/services/cursor-generator.d.ts.map +1 -0
  93. package/dist/services/cursor-generator.js +134 -0
  94. package/dist/services/cursor-generator.js.map +1 -0
  95. package/dist/services/file-ops.d.ts +48 -0
  96. package/dist/services/file-ops.d.ts.map +1 -0
  97. package/dist/services/file-ops.js +153 -0
  98. package/dist/services/file-ops.js.map +1 -0
  99. package/dist/services/output-formatter.d.ts +57 -0
  100. package/dist/services/output-formatter.d.ts.map +1 -0
  101. package/dist/services/output-formatter.js +88 -0
  102. package/dist/services/output-formatter.js.map +1 -0
  103. package/dist/services/platform-detect.d.ts +14 -0
  104. package/dist/services/platform-detect.d.ts.map +1 -0
  105. package/dist/services/platform-detect.js +63 -0
  106. package/dist/services/platform-detect.js.map +1 -0
  107. package/dist/services/project-analyzer.d.ts +71 -0
  108. package/dist/services/project-analyzer.d.ts.map +1 -0
  109. package/dist/services/project-analyzer.js +595 -0
  110. package/dist/services/project-analyzer.js.map +1 -0
  111. package/dist/services/rules-engine.d.ts +41 -0
  112. package/dist/services/rules-engine.d.ts.map +1 -0
  113. package/dist/services/rules-engine.js +304 -0
  114. package/dist/services/rules-engine.js.map +1 -0
  115. package/dist/services/strictness.d.ts +37 -0
  116. package/dist/services/strictness.d.ts.map +1 -0
  117. package/dist/services/strictness.js +182 -0
  118. package/dist/services/strictness.js.map +1 -0
  119. package/dist/services/template-engine.d.ts +16 -0
  120. package/dist/services/template-engine.d.ts.map +1 -0
  121. package/dist/services/template-engine.js +85 -0
  122. package/dist/services/template-engine.js.map +1 -0
  123. package/dist/services/validation.d.ts +41 -0
  124. package/dist/services/validation.d.ts.map +1 -0
  125. package/dist/services/validation.js +104 -0
  126. package/dist/services/validation.js.map +1 -0
  127. package/dist/services/windsurf-generator.d.ts +15 -0
  128. package/dist/services/windsurf-generator.d.ts.map +1 -0
  129. package/dist/services/windsurf-generator.js +127 -0
  130. package/dist/services/windsurf-generator.js.map +1 -0
  131. package/dist/tests/enforcement.test.d.ts +2 -0
  132. package/dist/tests/enforcement.test.d.ts.map +1 -0
  133. package/dist/tests/enforcement.test.js +541 -0
  134. package/dist/tests/enforcement.test.js.map +1 -0
  135. package/dist/tests/enterprise.test.d.ts +2 -0
  136. package/dist/tests/enterprise.test.d.ts.map +1 -0
  137. package/dist/tests/enterprise.test.js +353 -0
  138. package/dist/tests/enterprise.test.js.map +1 -0
  139. package/dist/tests/fuzzing.test.d.ts +2 -0
  140. package/dist/tests/fuzzing.test.d.ts.map +1 -0
  141. package/dist/tests/fuzzing.test.js +596 -0
  142. package/dist/tests/fuzzing.test.js.map +1 -0
  143. package/dist/tests/knowledge.test.d.ts +2 -0
  144. package/dist/tests/knowledge.test.d.ts.map +1 -0
  145. package/dist/tests/knowledge.test.js +292 -0
  146. package/dist/tests/knowledge.test.js.map +1 -0
  147. package/dist/tests/management.test.d.ts +2 -0
  148. package/dist/tests/management.test.d.ts.map +1 -0
  149. package/dist/tests/management.test.js +338 -0
  150. package/dist/tests/management.test.js.map +1 -0
  151. package/dist/tests/scaffolding.test.d.ts +2 -0
  152. package/dist/tests/scaffolding.test.d.ts.map +1 -0
  153. package/dist/tests/scaffolding.test.js +419 -0
  154. package/dist/tests/scaffolding.test.js.map +1 -0
  155. package/dist/tests/test-utils.d.ts +76 -0
  156. package/dist/tests/test-utils.d.ts.map +1 -0
  157. package/dist/tests/test-utils.js +171 -0
  158. package/dist/tests/test-utils.js.map +1 -0
  159. package/dist/tests/tool-harness.d.ts +18 -0
  160. package/dist/tests/tool-harness.d.ts.map +1 -0
  161. package/dist/tests/tool-harness.js +51 -0
  162. package/dist/tests/tool-harness.js.map +1 -0
  163. package/dist/tools/enterprise.d.ts +8 -0
  164. package/dist/tools/enterprise.d.ts.map +1 -0
  165. package/dist/tools/enterprise.js +571 -0
  166. package/dist/tools/enterprise.js.map +1 -0
  167. package/dist/tools/knowledge.d.ts +7 -0
  168. package/dist/tools/knowledge.d.ts.map +1 -0
  169. package/dist/tools/knowledge.js +120 -0
  170. package/dist/tools/knowledge.js.map +1 -0
  171. package/dist/tools/management.d.ts +10 -0
  172. package/dist/tools/management.d.ts.map +1 -0
  173. package/dist/tools/management.js +1541 -0
  174. package/dist/tools/management.js.map +1 -0
  175. package/dist/tools/scaffolding.d.ts +8 -0
  176. package/dist/tools/scaffolding.d.ts.map +1 -0
  177. package/dist/tools/scaffolding.js +736 -0
  178. package/dist/tools/scaffolding.js.map +1 -0
  179. package/dist/types.d.ts +54 -0
  180. package/dist/types.d.ts.map +1 -0
  181. package/dist/types.js +5 -0
  182. package/dist/types.js.map +1 -0
  183. package/landing/app/layout.tsx +30 -0
  184. package/landing/app/page.tsx +944 -0
  185. package/landing/next-env.d.ts +6 -0
  186. package/landing/next.config.js +6 -0
  187. package/landing/package-lock.json +896 -0
  188. package/landing/package.json +20 -0
  189. package/landing/tsconfig.json +40 -0
  190. package/package.json +49 -0
  191. package/rebar-v2.0.0-platform-spec.md +1567 -0
  192. package/server.json +20 -0
  193. package/src/cli.ts +735 -0
  194. package/src/constants.ts +131 -0
  195. package/src/index.ts +54 -0
  196. package/src/schemas/common.ts +22 -0
  197. package/src/schemas/scaffolding.ts +161 -0
  198. package/src/services/claudemd-generator.ts +481 -0
  199. package/src/services/codex-generator.ts +44 -0
  200. package/src/services/cursor-generator.ts +153 -0
  201. package/src/services/file-ops.ts +172 -0
  202. package/src/services/platform-detect.ts +80 -0
  203. package/src/services/project-analyzer.ts +690 -0
  204. package/src/services/rules-engine.ts +353 -0
  205. package/src/services/strictness.ts +202 -0
  206. package/src/services/template-engine.ts +119 -0
  207. package/src/services/validation.ts +138 -0
  208. package/src/services/windsurf-generator.ts +145 -0
  209. package/src/tests/enforcement.test.ts +794 -0
  210. package/src/tests/enterprise.test.ts +483 -0
  211. package/src/tests/fuzzing.test.ts +690 -0
  212. package/src/tests/knowledge.test.ts +371 -0
  213. package/src/tests/management.test.ts +451 -0
  214. package/src/tests/scaffolding.test.ts +575 -0
  215. package/src/tests/test-utils.ts +206 -0
  216. package/src/tests/tool-harness.ts +70 -0
  217. package/src/tools/enterprise.ts +666 -0
  218. package/src/tools/knowledge.ts +162 -0
  219. package/src/tools/management.ts +1706 -0
  220. package/src/tools/scaffolding.ts +909 -0
  221. package/src/types.ts +93 -0
  222. package/supabase/.temp/cli-latest +1 -0
  223. package/supabase/.temp/gotrue-version +1 -0
  224. package/supabase/.temp/pooler-url +1 -0
  225. package/supabase/.temp/postgres-version +1 -0
  226. package/supabase/.temp/project-ref +1 -0
  227. package/supabase/.temp/rest-version +1 -0
  228. package/supabase/.temp/storage-migration +1 -0
  229. package/supabase/.temp/storage-version +1 -0
  230. package/templates/agents/explore.md +41 -0
  231. package/templates/agents/plan.md +73 -0
  232. package/templates/agents/security-auditor.md +77 -0
  233. package/templates/agents/test-runner.md +60 -0
  234. package/templates/claudemd/fastapi.md +49 -0
  235. package/templates/claudemd/monorepo.md +48 -0
  236. package/templates/claudemd/nextjs.md +52 -0
  237. package/templates/claudemd/react-spa.md +50 -0
  238. package/templates/claudemd/springboot.md +50 -0
  239. package/templates/hooks/danger-blocker.json +11 -0
  240. package/templates/hooks/format-on-write.json +17 -0
  241. package/templates/hooks/lint-on-write.json +16 -0
  242. package/templates/hooks/secret-detector.json +11 -0
  243. package/templates/skills/code-review.md +68 -0
  244. package/templates/skills/documentation.md +62 -0
  245. package/templates/skills/performance-audit.md +80 -0
  246. package/templates/skills/security-scan.md +66 -0
  247. package/templates/skills/test-writer.md +56 -0
  248. package/tsconfig.json +19 -0
@@ -0,0 +1,666 @@
1
+ /**
2
+ * Tier 3: Enterprise and Compliance Tools
3
+ * rebar_apply_compliance, rebar_create_ci_workflow,
4
+ * rebar_create_security_hook, rebar_generate_mcp_config
5
+ */
6
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
7
+ import * as path from "node:path";
8
+ import {
9
+ ApplyComplianceInputSchema,
10
+ CreateCIWorkflowInputSchema,
11
+ CreateSecurityHookInputSchema,
12
+ GenerateMCPConfigInputSchema,
13
+ } from "../schemas/scaffolding.js";
14
+ import {
15
+ resolveProjectPath,
16
+ sanitizePath,
17
+ atomicWrite,
18
+ ensureDir,
19
+ readFileSafe,
20
+ safeWriteFile,
21
+ } from "../services/file-ops.js";
22
+ import {
23
+ DANGEROUS_COMMANDS_STANDARD,
24
+ DANGEROUS_COMMANDS_STRICT,
25
+ DANGEROUS_COMMANDS_PARANOID,
26
+ SECRET_PATTERNS,
27
+ } from "../constants.js";
28
+ import type { ToolResult } from "../types.js";
29
+
30
+ function makeResult(text: string, isError = false): ToolResult {
31
+ return {
32
+ content: [{ type: "text", text }],
33
+ ...(isError ? { isError: true } : {}),
34
+ };
35
+ }
36
+
37
+ export function registerEnterpriseTools(server: McpServer): void {
38
+ // ─── rebar_apply_compliance ──────────────────────────────────────
39
+ server.registerTool(
40
+ "rebar_apply_compliance",
41
+ {
42
+ title: "Apply Compliance Pack",
43
+ description:
44
+ "[Rebar] Applies a compliance template pack to the project — generates hooks for audit logging, " +
45
+ "skills for compliance-aware code review, and CLAUDE.md sections with regulatory requirements.\n\n" +
46
+ "Supported standards:\n" +
47
+ "• hipaa: PHI handling, audit logging, encryption requirements, data classification\n" +
48
+ "• soc2: Access controls, audit trails, change management, encryption\n" +
49
+ "• pci-dss: Card number blocking, tokenization requirements, OWASP checks\n" +
50
+ "• sox: Financial calculation review, audit trails, separation of duties\n\n" +
51
+ "Scope options:\n" +
52
+ "• full: Hooks + skills + CLAUDE.md section\n" +
53
+ "• hooks_only: Just audit/blocking hooks\n" +
54
+ "• skills_only: Just compliance review skills\n\n" +
55
+ "Examples:\n" +
56
+ " rebar_apply_compliance({ project_path: '.', standard: 'hipaa', scope: 'full' })\n" +
57
+ " rebar_apply_compliance({ project_path: '.', standard: 'soc2', scope: 'hooks_only' })\n\n" +
58
+ "Idempotent: Safe to run multiple times — won't duplicate hooks.",
59
+ inputSchema: ApplyComplianceInputSchema,
60
+ annotations: {
61
+ readOnlyHint: false,
62
+ destructiveHint: false,
63
+ idempotentHint: true,
64
+ openWorldHint: false,
65
+ },
66
+ },
67
+ async (args) => {
68
+ const { project_path, standard, scope } = args;
69
+ const absPath = resolveProjectPath(project_path);
70
+ const generated: string[] = [];
71
+
72
+ try {
73
+ const complianceConfig = getComplianceConfig(standard);
74
+
75
+ // Generate hooks
76
+ if (scope === "full" || scope === "hooks_only") {
77
+ const settingsPath = sanitizePath(absPath, ".claude/settings.json");
78
+ let settings: Record<string, unknown> = {};
79
+ const existing = await readFileSafe(settingsPath);
80
+ if (existing) {
81
+ settings = JSON.parse(existing) as Record<string, unknown>;
82
+ }
83
+
84
+ if (!settings.hooks) settings.hooks = {};
85
+ const hooks = settings.hooks as Record<string, unknown[]>;
86
+
87
+ for (const hook of complianceConfig.hooks) {
88
+ const eventKey = hook.event as string;
89
+ if (!hooks[eventKey]) hooks[eventKey] = [];
90
+ const eventHooks = hooks[eventKey] as Record<string, unknown>[];
91
+ const exists = eventHooks.some((h) => h.command === hook.command);
92
+ if (!exists) {
93
+ eventHooks.push(hook);
94
+ }
95
+ }
96
+
97
+ await ensureDir(path.dirname(settingsPath));
98
+ await atomicWrite(settingsPath, JSON.stringify(settings, null, 2));
99
+ generated.push(`✓ Added ${complianceConfig.hooks.length} compliance hook(s) to settings.json`);
100
+ }
101
+
102
+ // Generate skills
103
+ if (scope === "full" || scope === "skills_only") {
104
+ for (const skill of complianceConfig.skills) {
105
+ const skillDir = sanitizePath(absPath, `.claude/skills/${skill.name}`);
106
+ await ensureDir(skillDir);
107
+ const skillPath = path.join(skillDir, "SKILL.md");
108
+ const result = await safeWriteFile(skillPath, skill.content, true);
109
+ generated.push(`✓ ${result.message}`);
110
+ }
111
+ }
112
+
113
+ // Append to CLAUDE.md
114
+ if (scope === "full") {
115
+ const claudemdPath = sanitizePath(absPath, "CLAUDE.md");
116
+ const existingMd = await readFileSafe(claudemdPath);
117
+ const section = complianceConfig.claudemdSection;
118
+ if (existingMd && !existingMd.includes(section.substring(0, 50))) {
119
+ await atomicWrite(claudemdPath, existingMd + "\n\n" + section);
120
+ generated.push("✓ Added compliance section to CLAUDE.md");
121
+ } else if (!existingMd) {
122
+ await atomicWrite(claudemdPath, `# Project\n\n${section}`);
123
+ generated.push("✓ Created CLAUDE.md with compliance section");
124
+ } else {
125
+ generated.push("• CLAUDE.md already contains compliance section");
126
+ }
127
+ }
128
+
129
+ return makeResult(
130
+ `Compliance pack applied: ${standard.toUpperCase()}\n` +
131
+ `Scope: ${scope}\n\n` +
132
+ generated.join("\n") +
133
+ `\n\nReview the generated artifacts and customize as needed.`
134
+ );
135
+ } catch (err: unknown) {
136
+ const message = err instanceof Error ? err.message : String(err);
137
+ return makeResult(`Failed to apply compliance pack: ${message}`, true);
138
+ }
139
+ }
140
+ );
141
+
142
+ // ─── rebar_create_ci_workflow ────────────────────────────────────
143
+ server.registerTool(
144
+ "rebar_create_ci_workflow",
145
+ {
146
+ title: "Create CI Workflow",
147
+ description:
148
+ "[Rebar] Generates a GitHub Actions workflow that enables Claude Code to review pull requests. " +
149
+ "Creates a .github/workflows/claude-review.yml file that triggers on PRs and @claude mentions.\n\n" +
150
+ "Review focus options:\n" +
151
+ "• security: OWASP vulnerabilities, auth issues, data exposure\n" +
152
+ "• performance: N+1 queries, memory leaks, bundle size\n" +
153
+ "• style: Code conventions, naming, organization\n" +
154
+ "• all: Comprehensive review covering all areas\n\n" +
155
+ "Examples:\n" +
156
+ " rebar_create_ci_workflow({ repo_path: '.', review_focus: 'all', branch_pattern: 'main' })\n" +
157
+ " rebar_create_ci_workflow({ repo_path: '.', review_focus: 'security', branch_pattern: 'develop' })\n\n" +
158
+ "Requires: ANTHROPIC_API_KEY in repository secrets.\n" +
159
+ "Idempotent: Updates existing workflow if present.",
160
+ inputSchema: CreateCIWorkflowInputSchema,
161
+ annotations: {
162
+ readOnlyHint: false,
163
+ destructiveHint: false,
164
+ idempotentHint: true,
165
+ openWorldHint: false,
166
+ },
167
+ },
168
+ async (args) => {
169
+ const { repo_path, review_focus, branch_pattern } = args;
170
+ const absPath = resolveProjectPath(repo_path);
171
+ const workflowDir = sanitizePath(absPath, ".github/workflows");
172
+ const workflowPath = path.join(workflowDir, "claude-review.yml");
173
+
174
+ try {
175
+ await ensureDir(workflowDir);
176
+
177
+ const focusInstructions = getReviewFocusInstructions(review_focus);
178
+
179
+ const workflow = `name: Claude Code Review
180
+
181
+ on:
182
+ pull_request:
183
+ branches: [${branch_pattern}]
184
+ issue_comment:
185
+ types: [created]
186
+
187
+ permissions:
188
+ contents: read
189
+ pull-requests: write
190
+ issues: write
191
+
192
+ jobs:
193
+ claude-review:
194
+ if: |
195
+ (github.event_name == 'pull_request') ||
196
+ (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude'))
197
+ runs-on: ubuntu-latest
198
+ steps:
199
+ - uses: actions/checkout@v4
200
+ with:
201
+ fetch-depth: 0
202
+
203
+ - name: Claude Code Review
204
+ uses: anthropics/claude-code-action@v1
205
+ with:
206
+ anthropic_api_key: \${{ secrets.ANTHROPIC_API_KEY }}
207
+ review_focus: "${review_focus}"
208
+ custom_instructions: |
209
+ ${focusInstructions}
210
+ `;
211
+
212
+ const result = await safeWriteFile(workflowPath, workflow, true);
213
+
214
+ return makeResult(
215
+ `CI workflow created!\n\n` +
216
+ `Location: ${workflowPath}\n` +
217
+ `Review focus: ${review_focus}\n` +
218
+ `Branch pattern: ${branch_pattern}\n\n` +
219
+ `${result.message}\n\n` +
220
+ `Next steps:\n` +
221
+ `1. Add ANTHROPIC_API_KEY to your repository secrets\n` +
222
+ `2. Push the workflow file to your repository\n` +
223
+ `3. Create a PR to trigger the review`
224
+ );
225
+ } catch (err: unknown) {
226
+ const message = err instanceof Error ? err.message : String(err);
227
+ return makeResult(`Failed to create CI workflow: ${message}`, true);
228
+ }
229
+ }
230
+ );
231
+
232
+ // ─── rebar_create_security_hook ──────────────────────────────────
233
+ server.registerTool(
234
+ "rebar_create_security_hook",
235
+ {
236
+ title: "Create Security Hooks",
237
+ description:
238
+ "[Rebar] Generates a comprehensive security hook system that blocks dangerous commands and detects secret leaks " +
239
+ "before they happen. Creates a blocker script and hooks it into Claude Code's PreToolCall lifecycle.\n\n" +
240
+ "Strictness levels:\n" +
241
+ "• standard: Blocks rm -rf, force push, DROP TABLE, TRUNCATE (8 patterns)\n" +
242
+ "• strict: + git reset --hard, chmod 777, curl|sh, wget|sh (13 patterns)\n" +
243
+ "• paranoid: + eval(), exec(), sudo, su, pkill, killall (19 patterns)\n\n" +
244
+ "Also detects secret patterns: AWS keys, API keys, GitHub tokens, private keys.\n\n" +
245
+ "Examples:\n" +
246
+ " rebar_create_security_hook({ project_path: '.', strictness: 'standard' })\n" +
247
+ " rebar_create_security_hook({ project_path: '.', strictness: 'paranoid' })\n\n" +
248
+ "Idempotent: Updates existing security hook if present.",
249
+ inputSchema: CreateSecurityHookInputSchema,
250
+ annotations: {
251
+ readOnlyHint: false,
252
+ destructiveHint: false,
253
+ idempotentHint: true,
254
+ openWorldHint: false,
255
+ },
256
+ },
257
+ async (args) => {
258
+ const { project_path, strictness } = args;
259
+ const absPath = resolveProjectPath(project_path);
260
+
261
+ try {
262
+ // Get the appropriate command list
263
+ let commands: string[];
264
+ switch (strictness) {
265
+ case "paranoid":
266
+ commands = DANGEROUS_COMMANDS_PARANOID;
267
+ break;
268
+ case "strict":
269
+ commands = DANGEROUS_COMMANDS_STRICT;
270
+ break;
271
+ default:
272
+ commands = DANGEROUS_COMMANDS_STANDARD;
273
+ }
274
+
275
+ // Create the blocker script
276
+ const scriptsDir = sanitizePath(absPath, ".claude/scripts");
277
+ await ensureDir(scriptsDir);
278
+
279
+ const patterns = commands.map((c) => ` "${c.replace(/"/g, '\\"')}"`).join("\n");
280
+ const secretPatterns = SECRET_PATTERNS.map((p) => ` "${p}"`).join("\n");
281
+
282
+ const blockerScript = `#!/usr/bin/env bash
283
+ # Security hook: blocks dangerous commands
284
+ # Strictness level: ${strictness}
285
+ # Generated by rebar-mcp
286
+
287
+ COMMAND="$TOOL_INPUT_COMMAND"
288
+
289
+ # Dangerous command patterns
290
+ DANGEROUS_PATTERNS=(
291
+ ${patterns}
292
+ )
293
+
294
+ for pattern in "\${DANGEROUS_PATTERNS[@]}"; do
295
+ if echo "$COMMAND" | grep -qiF "$pattern"; then
296
+ echo "BLOCKED: Command contains dangerous pattern: $pattern" >&2
297
+ echo "If you need to run this command, do it manually outside Claude Code." >&2
298
+ exit 1
299
+ fi
300
+ done
301
+
302
+ # Secret leak detection
303
+ SECRET_PATTERNS=(
304
+ ${secretPatterns}
305
+ )
306
+
307
+ for pattern in "\${SECRET_PATTERNS[@]}"; do
308
+ if echo "$COMMAND" | grep -qE "$pattern"; then
309
+ echo "BLOCKED: Command may expose secrets matching pattern: $pattern" >&2
310
+ exit 1
311
+ fi
312
+ done
313
+
314
+ exit 0
315
+ `;
316
+
317
+ const scriptPath = path.join(scriptsDir, "security-blocker.sh");
318
+ await atomicWrite(scriptPath, blockerScript);
319
+ // Make executable
320
+ const { chmod } = await import("node:fs/promises");
321
+ await chmod(scriptPath, 0o755);
322
+
323
+ // Add hook to settings.json
324
+ const settingsPath = sanitizePath(absPath, ".claude/settings.json");
325
+ let settings: Record<string, unknown> = {};
326
+ const existing = await readFileSafe(settingsPath);
327
+ if (existing) {
328
+ settings = JSON.parse(existing) as Record<string, unknown>;
329
+ }
330
+
331
+ if (!settings.hooks) settings.hooks = {};
332
+ const hooks = settings.hooks as Record<string, unknown[]>;
333
+ if (!hooks.PreToolCall) hooks.PreToolCall = [];
334
+
335
+ const hookEntry = {
336
+ description: `Security blocker (${strictness})`,
337
+ matcher: "Bash",
338
+ command: scriptPath,
339
+ exit_behavior: "block",
340
+ };
341
+
342
+ const eventHooks = hooks.PreToolCall as Record<string, unknown>[];
343
+ const existingIdx = eventHooks.findIndex(
344
+ (h) => (h.description as string)?.startsWith("Security blocker")
345
+ );
346
+ if (existingIdx >= 0) {
347
+ eventHooks[existingIdx] = hookEntry;
348
+ } else {
349
+ eventHooks.push(hookEntry);
350
+ }
351
+
352
+ // Also add deny rules to permissions
353
+ if (!settings.permissions) settings.permissions = {};
354
+ const perms = settings.permissions as Record<string, unknown>;
355
+ if (!perms.deny) perms.deny = [];
356
+ const denyList = perms.deny as string[];
357
+ const denyRules = [
358
+ "Bash(rm -rf *)",
359
+ "Read(./.env)",
360
+ "Read(./.env.*)",
361
+ ];
362
+ for (const rule of denyRules) {
363
+ if (!denyList.includes(rule)) {
364
+ denyList.push(rule);
365
+ }
366
+ }
367
+
368
+ await ensureDir(path.dirname(settingsPath));
369
+ await atomicWrite(settingsPath, JSON.stringify(settings, null, 2));
370
+
371
+ return makeResult(
372
+ `Security hooks installed!\n\n` +
373
+ `Strictness: ${strictness}\n` +
374
+ `Blocked patterns: ${commands.length} dangerous commands\n` +
375
+ `Secret patterns: ${SECRET_PATTERNS.length} leak detectors\n\n` +
376
+ `Generated files:\n` +
377
+ ` ✓ ${scriptPath} — Blocker script\n` +
378
+ ` ✓ ${settingsPath} — Hook configuration\n\n` +
379
+ `The following will be blocked:\n` +
380
+ commands.map((c) => ` • ${c}`).join("\n")
381
+ );
382
+ } catch (err: unknown) {
383
+ const message = err instanceof Error ? err.message : String(err);
384
+ return makeResult(`Failed to create security hooks: ${message}`, true);
385
+ }
386
+ }
387
+ );
388
+
389
+ // ─── rebar_generate_mcp_config ───────────────────────────────────
390
+ server.registerTool(
391
+ "rebar_generate_mcp_config",
392
+ {
393
+ title: "Generate MCP Config",
394
+ description:
395
+ "[Rebar] Creates a .mcp.json file with pre-configured MCP server entries for your services. " +
396
+ "Each entry includes the correct npx command and environment variable placeholders.\n\n" +
397
+ "Supported services: github, sentry, postgres, slack, linear, jira, datadog, pagerduty, vercel, supabase\n\n" +
398
+ "Scope:\n" +
399
+ "• project: Creates .mcp.json in project root (team-shared)\n" +
400
+ "• user: Creates in ~/.claude/.mcp.json (personal)\n\n" +
401
+ "Examples:\n" +
402
+ " rebar_generate_mcp_config({ project_path: '.', services: ['github', 'slack'], scope: 'project' })\n" +
403
+ " rebar_generate_mcp_config({ project_path: '.', services: ['github', 'sentry', 'postgres'], scope: 'project' })\n\n" +
404
+ "Returns: Config file location, list of configured services, next steps.",
405
+ inputSchema: GenerateMCPConfigInputSchema,
406
+ annotations: {
407
+ readOnlyHint: false,
408
+ destructiveHint: false,
409
+ idempotentHint: true,
410
+ openWorldHint: false,
411
+ },
412
+ },
413
+ async (args) => {
414
+ const { project_path, services, scope } = args;
415
+ const absPath = resolveProjectPath(project_path);
416
+
417
+ try {
418
+ const mcpServers: Record<string, unknown> = {};
419
+
420
+ for (const service of services) {
421
+ mcpServers[service] = getMCPServiceConfig(service);
422
+ }
423
+
424
+ const config = { mcpServers };
425
+ const configContent = JSON.stringify(config, null, 2);
426
+
427
+ let configPath: string;
428
+ if (scope === "project") {
429
+ configPath = sanitizePath(absPath, ".mcp.json");
430
+ } else {
431
+ const homeDir = process.env.HOME || process.env.USERPROFILE || "~";
432
+ configPath = path.join(homeDir, ".claude", ".mcp.json");
433
+ }
434
+
435
+ const result = await safeWriteFile(configPath, configContent, true);
436
+
437
+ const serviceList = services
438
+ .map((s) => ` • ${s}`)
439
+ .join("\n");
440
+
441
+ return makeResult(
442
+ `MCP configuration generated!\n\n` +
443
+ `Location: ${configPath}\n` +
444
+ `Scope: ${scope}\n\n` +
445
+ `Configured services:\n${serviceList}\n\n` +
446
+ `${result.message}\n\n` +
447
+ `Next steps:\n` +
448
+ `1. Fill in API keys and tokens in the configuration\n` +
449
+ `2. Run 'claude mcp list' to verify the servers are registered\n` +
450
+ `3. Restart Claude Code to load the new MCP servers`
451
+ );
452
+ } catch (err: unknown) {
453
+ const message = err instanceof Error ? err.message : String(err);
454
+ return makeResult(`Failed to generate MCP config: ${message}`, true);
455
+ }
456
+ }
457
+ );
458
+ }
459
+
460
+ // ─── Helper Functions ─────────────────────────────────────────────────
461
+
462
+ function getComplianceConfig(standard: string): {
463
+ hooks: Array<Record<string, unknown>>;
464
+ skills: Array<{ name: string; content: string }>;
465
+ claudemdSection: string;
466
+ } {
467
+ switch (standard) {
468
+ case "hipaa":
469
+ return {
470
+ hooks: [
471
+ {
472
+ event: "PreToolCall",
473
+ matcher: "Bash",
474
+ description: "HIPAA: Audit logging for all commands",
475
+ command: 'echo "[$(date -u)] HIPAA_AUDIT: $TOOL_INPUT_COMMAND" >> .claude/audit.log',
476
+ exit_behavior: "notify",
477
+ },
478
+ {
479
+ event: "PreToolCall",
480
+ matcher: "Write|Edit",
481
+ description: "HIPAA: Check for PHI in written files",
482
+ command: 'if grep -qiE "(SSN|social.security|patient.id|medical.record|health.insurance)" "$TOOL_INPUT_FILE_PATH" 2>/dev/null; then echo "WARNING: Possible PHI detected in file" >&2; fi',
483
+ exit_behavior: "notify",
484
+ },
485
+ ],
486
+ skills: [
487
+ {
488
+ name: "phi-handler",
489
+ content:
490
+ "---\nname: phi-handler\ndescription: Ensures Protected Health Information (PHI) is handled according to HIPAA requirements\ninvocation: auto\ncontext: inline\n---\n\n# PHI Handler\n\nWhen working with code that handles health data:\n\n1. Never log PHI to console or debug output\n2. Ensure PHI is encrypted at rest and in transit\n3. Apply minimum necessary access principle\n4. Add audit trail for all PHI access\n5. Use de-identification where possible\n",
491
+ },
492
+ ],
493
+ claudemdSection:
494
+ "## HIPAA Compliance\n\n" +
495
+ "This project handles Protected Health Information (PHI).\n\n" +
496
+ "### Requirements\n" +
497
+ "- All PHI must be encrypted at rest (AES-256) and in transit (TLS 1.2+)\n" +
498
+ "- Access to PHI requires authentication and authorization\n" +
499
+ "- All PHI access must be logged for audit purposes\n" +
500
+ "- Data retention policies must be enforced\n" +
501
+ "- Never log PHI in application logs, console output, or error messages\n" +
502
+ "- Use de-identified data for development and testing\n\n" +
503
+ "### Data Classification\n" +
504
+ "- **PHI**: Patient names, SSN, medical records, insurance IDs, dates of service\n" +
505
+ "- **ePHI**: Electronic PHI stored or transmitted digitally\n" +
506
+ "- **De-identified**: Data with all 18 HIPAA identifiers removed\n",
507
+ };
508
+
509
+ case "soc2":
510
+ return {
511
+ hooks: [
512
+ {
513
+ event: "PreToolCall",
514
+ matcher: "Bash",
515
+ description: "SOC2: Audit logging",
516
+ command: 'echo "[$(date -u)] SOC2_AUDIT: $TOOL_INPUT_COMMAND" >> .claude/audit.log',
517
+ exit_behavior: "notify",
518
+ },
519
+ ],
520
+ skills: [
521
+ {
522
+ name: "access-control-review",
523
+ content:
524
+ "---\nname: access-control-review\ndescription: Reviews code for proper access control implementation per SOC2 requirements\ninvocation: auto\ncontext: fork\n---\n\n# Access Control Review\n\nVerify that code changes implement proper access controls:\n\n1. Authentication is required for all protected endpoints\n2. Authorization checks match the principle of least privilege\n3. Session management follows security best practices\n4. API keys and tokens are properly scoped\n",
525
+ },
526
+ ],
527
+ claudemdSection:
528
+ "## SOC2 Compliance\n\n" +
529
+ "This project follows SOC2 Trust Service Criteria.\n\n" +
530
+ "### Security Controls\n" +
531
+ "- All changes require code review\n" +
532
+ "- Access follows principle of least privilege\n" +
533
+ "- Audit logging enabled for all state-changing operations\n" +
534
+ "- Encryption required for sensitive data\n" +
535
+ "- Regular dependency vulnerability scanning\n",
536
+ };
537
+
538
+ case "pci-dss":
539
+ return {
540
+ hooks: [
541
+ {
542
+ event: "PreToolCall",
543
+ matcher: "Bash|Write|Edit",
544
+ description: "PCI-DSS: Block card number patterns in code",
545
+ command: 'if echo "$TOOL_INPUT" | grep -qE "\\b[0-9]{4}[- ]?[0-9]{4}[- ]?[0-9]{4}[- ]?[0-9]{4}\\b"; then echo "BLOCKED: Possible card number detected" >&2; exit 1; fi',
546
+ exit_behavior: "block",
547
+ },
548
+ ],
549
+ skills: [],
550
+ claudemdSection:
551
+ "## PCI-DSS Compliance\n\n" +
552
+ "This project handles payment card data.\n\n" +
553
+ "### Requirements\n" +
554
+ "- Never store full card numbers in code, logs, or comments\n" +
555
+ "- Use tokenization for card data references\n" +
556
+ "- All cardholder data must be encrypted\n" +
557
+ "- Follow secure coding guidelines (OWASP)\n",
558
+ };
559
+
560
+ case "sox":
561
+ return {
562
+ hooks: [
563
+ {
564
+ event: "PreToolCall",
565
+ matcher: "Bash",
566
+ description: "SOX: Audit logging for financial systems",
567
+ command: 'echo "[$(date -u)] SOX_AUDIT: $TOOL_INPUT_COMMAND" >> .claude/audit.log',
568
+ exit_behavior: "notify",
569
+ },
570
+ ],
571
+ skills: [],
572
+ claudemdSection:
573
+ "## SOX Compliance\n\n" +
574
+ "This project is subject to Sarbanes-Oxley requirements.\n\n" +
575
+ "### Requirements\n" +
576
+ "- All changes to financial calculations require dual review\n" +
577
+ "- Audit trail for all data modifications\n" +
578
+ "- Separation of duties in deployment pipeline\n" +
579
+ "- Change management documentation required\n",
580
+ };
581
+
582
+ default:
583
+ return { hooks: [], skills: [], claudemdSection: "" };
584
+ }
585
+ }
586
+
587
+ function getReviewFocusInstructions(focus: string): string {
588
+ switch (focus) {
589
+ case "security":
590
+ return "Focus on security vulnerabilities: injection attacks, auth issues, data exposure, OWASP Top 10.";
591
+ case "performance":
592
+ return "Focus on performance issues: N+1 queries, memory leaks, unnecessary re-renders, bundle size.";
593
+ case "style":
594
+ return "Focus on code style: naming conventions, code organization, readability, documentation.";
595
+ default:
596
+ return "Review for security, performance, code quality, and correctness.";
597
+ }
598
+ }
599
+
600
+ function getMCPServiceConfig(service: string): Record<string, unknown> {
601
+ const configs: Record<string, Record<string, unknown>> = {
602
+ github: {
603
+ command: "npx",
604
+ args: ["-y", "@modelcontextprotocol/server-github"],
605
+ env: { GITHUB_PERSONAL_ACCESS_TOKEN: "<your-github-token>" },
606
+ },
607
+ sentry: {
608
+ command: "npx",
609
+ args: ["-y", "@modelcontextprotocol/server-sentry"],
610
+ env: { SENTRY_AUTH_TOKEN: "<your-sentry-token>" },
611
+ },
612
+ postgres: {
613
+ command: "npx",
614
+ args: ["-y", "@modelcontextprotocol/server-postgres"],
615
+ env: { POSTGRES_CONNECTION_STRING: "<your-postgres-url>" },
616
+ },
617
+ slack: {
618
+ command: "npx",
619
+ args: ["-y", "@modelcontextprotocol/server-slack"],
620
+ env: { SLACK_BOT_TOKEN: "<your-slack-token>" },
621
+ },
622
+ linear: {
623
+ command: "npx",
624
+ args: ["-y", "@modelcontextprotocol/server-linear"],
625
+ env: { LINEAR_API_KEY: "<your-linear-key>" },
626
+ },
627
+ jira: {
628
+ command: "npx",
629
+ args: ["-y", "@modelcontextprotocol/server-jira"],
630
+ env: {
631
+ JIRA_URL: "<your-jira-url>",
632
+ JIRA_API_TOKEN: "<your-jira-token>",
633
+ JIRA_EMAIL: "<your-email>",
634
+ },
635
+ },
636
+ datadog: {
637
+ command: "npx",
638
+ args: ["-y", "@modelcontextprotocol/server-datadog"],
639
+ env: {
640
+ DD_API_KEY: "<your-datadog-api-key>",
641
+ DD_APP_KEY: "<your-datadog-app-key>",
642
+ },
643
+ },
644
+ pagerduty: {
645
+ command: "npx",
646
+ args: ["-y", "@modelcontextprotocol/server-pagerduty"],
647
+ env: { PAGERDUTY_API_KEY: "<your-pagerduty-key>" },
648
+ },
649
+ vercel: {
650
+ command: "npx",
651
+ args: ["-y", "@vercel/mcp"],
652
+ env: { VERCEL_TOKEN: "<your-vercel-token>" },
653
+ },
654
+ supabase: {
655
+ command: "npx",
656
+ args: ["-y", "@supabase/mcp-server"],
657
+ env: { SUPABASE_ACCESS_TOKEN: "<your-supabase-token>" },
658
+ },
659
+ };
660
+
661
+ return configs[service] || {
662
+ command: "npx",
663
+ args: ["-y", `@modelcontextprotocol/server-${service}`],
664
+ env: {},
665
+ };
666
+ }