crucible-mcp 1.0.1__tar.gz → 1.1.0__tar.gz

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 (85) hide show
  1. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/PKG-INFO +6 -3
  2. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/README.md +5 -2
  3. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/pyproject.toml +1 -1
  4. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/server.py +72 -1
  5. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible_mcp.egg-info/PKG-INFO +6 -3
  6. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/setup.cfg +0 -0
  7. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/__init__.py +0 -0
  8. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/cli.py +0 -0
  9. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/domain/__init__.py +0 -0
  10. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/domain/detection.py +0 -0
  11. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/enforcement/__init__.py +0 -0
  12. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/enforcement/assertions.py +0 -0
  13. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/enforcement/budget.py +0 -0
  14. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/enforcement/bundled/error-handling.yaml +0 -0
  15. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/enforcement/bundled/security.yaml +0 -0
  16. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/enforcement/bundled/smart-contract.yaml +0 -0
  17. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/enforcement/compliance.py +0 -0
  18. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/enforcement/models.py +0 -0
  19. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/enforcement/patterns.py +0 -0
  20. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/errors.py +0 -0
  21. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/hooks/__init__.py +0 -0
  22. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/hooks/claudecode.py +0 -0
  23. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/hooks/precommit.py +0 -0
  24. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/knowledge/__init__.py +0 -0
  25. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/knowledge/loader.py +0 -0
  26. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/knowledge/principles/API_DESIGN.md +0 -0
  27. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/knowledge/principles/COMMITS.md +0 -0
  28. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/knowledge/principles/DATABASE.md +0 -0
  29. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/knowledge/principles/DOCUMENTATION.md +0 -0
  30. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/knowledge/principles/ERROR_HANDLING.md +0 -0
  31. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/knowledge/principles/FP.md +0 -0
  32. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/knowledge/principles/GITIGNORE.md +0 -0
  33. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/knowledge/principles/OBSERVABILITY.md +0 -0
  34. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/knowledge/principles/PRECOMMIT.md +0 -0
  35. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/knowledge/principles/SECURITY.md +0 -0
  36. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/knowledge/principles/SMART_CONTRACT.md +0 -0
  37. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/knowledge/principles/SYSTEM_DESIGN.md +0 -0
  38. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/knowledge/principles/TESTING.md +0 -0
  39. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/knowledge/principles/TYPE_SAFETY.md +0 -0
  40. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/models.py +0 -0
  41. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/review/__init__.py +0 -0
  42. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/review/core.py +0 -0
  43. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/skills/__init__.py +0 -0
  44. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/skills/accessibility-engineer/SKILL.md +0 -0
  45. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/skills/backend-engineer/SKILL.md +0 -0
  46. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/skills/customer-success/SKILL.md +0 -0
  47. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/skills/data-engineer/SKILL.md +0 -0
  48. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/skills/devops-engineer/SKILL.md +0 -0
  49. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/skills/fde-engineer/SKILL.md +0 -0
  50. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/skills/formal-verification/SKILL.md +0 -0
  51. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/skills/gas-optimizer/SKILL.md +0 -0
  52. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/skills/incident-responder/SKILL.md +0 -0
  53. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/skills/loader.py +0 -0
  54. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/skills/mev-researcher/SKILL.md +0 -0
  55. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/skills/mobile-engineer/SKILL.md +0 -0
  56. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/skills/performance-engineer/SKILL.md +0 -0
  57. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/skills/product-engineer/SKILL.md +0 -0
  58. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/skills/protocol-architect/SKILL.md +0 -0
  59. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/skills/security-engineer/SKILL.md +0 -0
  60. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/skills/tech-lead/SKILL.md +0 -0
  61. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/skills/uiux-engineer/SKILL.md +0 -0
  62. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/skills/web3-engineer/SKILL.md +0 -0
  63. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/synthesis/__init__.py +0 -0
  64. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/tools/__init__.py +0 -0
  65. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/tools/delegation.py +0 -0
  66. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible/tools/git.py +0 -0
  67. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible_mcp.egg-info/SOURCES.txt +0 -0
  68. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible_mcp.egg-info/dependency_links.txt +0 -0
  69. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible_mcp.egg-info/entry_points.txt +0 -0
  70. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible_mcp.egg-info/requires.txt +0 -0
  71. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/src/crucible_mcp.egg-info/top_level.txt +0 -0
  72. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/tests/test_cli.py +0 -0
  73. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/tests/test_compliance.py +0 -0
  74. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/tests/test_detection.py +0 -0
  75. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/tests/test_enforcement.py +0 -0
  76. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/tests/test_full_review.py +0 -0
  77. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/tests/test_git.py +0 -0
  78. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/tests/test_hooks_cli.py +0 -0
  79. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/tests/test_integration.py +0 -0
  80. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/tests/test_knowledge.py +0 -0
  81. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/tests/test_precommit.py +0 -0
  82. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/tests/test_server.py +0 -0
  83. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/tests/test_skills.py +0 -0
  84. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/tests/test_skills_loader.py +0 -0
  85. {crucible_mcp-1.0.1 → crucible_mcp-1.1.0}/tests/test_tools.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crucible-mcp
3
- Version: 1.0.1
3
+ Version: 1.1.0
4
4
  Summary: Code review MCP server for Claude. Not affiliated with Atlassian.
5
5
  Author: be.nvy
6
6
  License-Expression: MIT
@@ -109,13 +109,16 @@ Add to Claude Code (`.mcp.json`):
109
109
 
110
110
  | Tool | Purpose |
111
111
  |------|---------|
112
+ | `get_assertions()` | **Session start:** Load enforced patterns into context |
113
+ | `get_principles(topic)` | **Session start:** Load engineering knowledge by topic |
114
+ | `load_knowledge(files)` | **Session start:** Load specific knowledge files |
112
115
  | `review(path)` | Full review: analysis + skills + knowledge + assertions |
113
116
  | `review(mode='staged')` | Review git changes with enforcement |
114
- | `load_knowledge(files)` | Load specific knowledge files |
115
- | `get_principles(topic)` | Load engineering knowledge by topic |
116
117
  | `delegate_*` | Direct tool access (semgrep, ruff, slither, bandit) |
117
118
  | `check_tools()` | Show installed analysis tools |
118
119
 
120
+ **Tip:** Call `get_assertions()` at the start of a session so Claude knows what patterns to avoid *before* writing code.
121
+
119
122
  ## CLI
120
123
 
121
124
  ```bash
@@ -91,13 +91,16 @@ Add to Claude Code (`.mcp.json`):
91
91
 
92
92
  | Tool | Purpose |
93
93
  |------|---------|
94
+ | `get_assertions()` | **Session start:** Load enforced patterns into context |
95
+ | `get_principles(topic)` | **Session start:** Load engineering knowledge by topic |
96
+ | `load_knowledge(files)` | **Session start:** Load specific knowledge files |
94
97
  | `review(path)` | Full review: analysis + skills + knowledge + assertions |
95
98
  | `review(mode='staged')` | Review git changes with enforcement |
96
- | `load_knowledge(files)` | Load specific knowledge files |
97
- | `get_principles(topic)` | Load engineering knowledge by topic |
98
99
  | `delegate_*` | Direct tool access (semgrep, ruff, slither, bandit) |
99
100
  | `check_tools()` | Show installed analysis tools |
100
101
 
102
+ **Tip:** Call `get_assertions()` at the start of a session so Claude knows what patterns to avoid *before* writing code.
103
+
101
104
  ## CLI
102
105
 
103
106
  ```bash
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "crucible-mcp"
3
- version = "1.0.1"
3
+ version = "1.1.0"
4
4
  description = "Code review MCP server for Claude. Not affiliated with Atlassian."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -7,6 +7,7 @@ from mcp.server import Server
7
7
  from mcp.server.stdio import stdio_server
8
8
  from mcp.types import TextContent, Tool
9
9
 
10
+ from crucible.enforcement.assertions import load_assertions
10
11
  from crucible.knowledge.loader import (
11
12
  get_custom_knowledge_files,
12
13
  load_all_knowledge,
@@ -314,6 +315,20 @@ async def list_tools() -> list[Tool]:
314
315
  },
315
316
  },
316
317
  ),
318
+ Tool(
319
+ name="get_assertions",
320
+ description="Load active enforcement assertions for this project. Call at session start to understand what code patterns are enforced. Returns all pattern and LLM assertions that will be checked during reviews.",
321
+ inputSchema={
322
+ "type": "object",
323
+ "properties": {
324
+ "include_compliance": {
325
+ "type": "boolean",
326
+ "description": "Include LLM compliance assertion details (default: true)",
327
+ "default": True,
328
+ },
329
+ },
330
+ },
331
+ ),
317
332
  ]
318
333
 
319
334
 
@@ -715,6 +730,61 @@ def _handle_load_knowledge(arguments: dict[str, Any]) -> list[TextContent]:
715
730
  return [TextContent(type="text", text="\n".join(output_parts))]
716
731
 
717
732
 
733
+ def _handle_get_assertions(arguments: dict[str, Any]) -> list[TextContent]:
734
+ """Handle get_assertions tool - load active enforcement rules."""
735
+ include_compliance = arguments.get("include_compliance", True)
736
+
737
+ assertions, load_errors = load_assertions()
738
+
739
+ if not assertions and not load_errors:
740
+ return [TextContent(type="text", text="No assertions found. Add assertion files to .crucible/assertions/ or use bundled assertions.")]
741
+
742
+ parts: list[str] = ["# Active Enforcement Assertions\n"]
743
+ parts.append("These patterns are enforced during code review. Avoid these in your code.\n")
744
+
745
+ if load_errors:
746
+ parts.append("## Load Errors\n")
747
+ for error in load_errors:
748
+ parts.append(f"- {error}")
749
+ parts.append("")
750
+
751
+ # Group by source file / category
752
+ pattern_assertions = [a for a in assertions if a.type.value == "pattern"]
753
+ llm_assertions = [a for a in assertions if a.type.value == "llm"]
754
+
755
+ if pattern_assertions:
756
+ parts.append("## Pattern Assertions (fast, always run)\n")
757
+ parts.append("| ID | Message | Severity | Languages |")
758
+ parts.append("|---|---|---|---|")
759
+ for a in pattern_assertions:
760
+ langs = ", ".join(a.languages) if a.languages else "all"
761
+ parts.append(f"| `{a.id}` | {a.message} | {a.severity} | {langs} |")
762
+ parts.append("")
763
+
764
+ if llm_assertions and include_compliance:
765
+ parts.append("## LLM Compliance Assertions (semantic, budget-controlled)\n")
766
+ parts.append("| ID | Message | Severity | Model |")
767
+ parts.append("|---|---|---|---|")
768
+ for a in llm_assertions:
769
+ model = a.model or "sonnet"
770
+ parts.append(f"| `{a.id}` | {a.message} | {a.severity} | {model} |")
771
+ parts.append("")
772
+
773
+ # Show compliance requirements for LLM assertions
774
+ parts.append("### Compliance Requirements\n")
775
+ for a in llm_assertions:
776
+ parts.append(f"**{a.id}:**")
777
+ if a.compliance:
778
+ parts.append(f"```\n{a.compliance.strip()}\n```")
779
+ parts.append("")
780
+
781
+ # Summary
782
+ parts.append("---\n")
783
+ parts.append(f"**Total:** {len(pattern_assertions)} pattern + {len(llm_assertions)} LLM assertions")
784
+
785
+ return [TextContent(type="text", text="\n".join(parts))]
786
+
787
+
718
788
  def _handle_delegate_semgrep(arguments: dict[str, Any]) -> list[TextContent]:
719
789
  """Handle delegate_semgrep tool."""
720
790
  path = arguments.get("path", "")
@@ -1241,7 +1311,8 @@ async def call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent]:
1241
1311
  "quick_review": _handle_quick_review,
1242
1312
  "full_review": _handle_full_review,
1243
1313
  "review_changes": _handle_review_changes,
1244
- # Other tools
1314
+ # Context injection tools (call at session start)
1315
+ "get_assertions": _handle_get_assertions,
1245
1316
  "get_principles": _handle_get_principles,
1246
1317
  "load_knowledge": _handle_load_knowledge,
1247
1318
  "delegate_semgrep": _handle_delegate_semgrep,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crucible-mcp
3
- Version: 1.0.1
3
+ Version: 1.1.0
4
4
  Summary: Code review MCP server for Claude. Not affiliated with Atlassian.
5
5
  Author: be.nvy
6
6
  License-Expression: MIT
@@ -109,13 +109,16 @@ Add to Claude Code (`.mcp.json`):
109
109
 
110
110
  | Tool | Purpose |
111
111
  |------|---------|
112
+ | `get_assertions()` | **Session start:** Load enforced patterns into context |
113
+ | `get_principles(topic)` | **Session start:** Load engineering knowledge by topic |
114
+ | `load_knowledge(files)` | **Session start:** Load specific knowledge files |
112
115
  | `review(path)` | Full review: analysis + skills + knowledge + assertions |
113
116
  | `review(mode='staged')` | Review git changes with enforcement |
114
- | `load_knowledge(files)` | Load specific knowledge files |
115
- | `get_principles(topic)` | Load engineering knowledge by topic |
116
117
  | `delegate_*` | Direct tool access (semgrep, ruff, slither, bandit) |
117
118
  | `check_tools()` | Show installed analysis tools |
118
119
 
120
+ **Tip:** Call `get_assertions()` at the start of a session so Claude knows what patterns to avoid *before* writing code.
121
+
119
122
  ## CLI
120
123
 
121
124
  ```bash
File without changes