-
-
Notifications
You must be signed in to change notification settings - Fork 67
Add :config-profile CLI option for resource-based config overlays #143
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Allow users to apply built-in config profiles from classpath resources via CLI argument. Profiles are deep-merged on top of the base config with highest precedence. Usage: clojure -X:mcp :config-profile :cli-assist Includes cli-assist profile with clojure_edit_agent, list_nrepl_ports, clojure_eval tools enabled and write-file-guard disabled. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
📝 WalkthroughWalkthroughA configuration profile system is introduced, enabling overlay of EDN-based configuration profiles onto base configurations. The system includes a new CLI option, config loading/merging functions, and threaded profile parameter through nREPL initialization. Changes
Sequence DiagramsequenceDiagram
participant CLI as CLI Parser
participant Core as Core Init
participant Config as Config Module
participant Files as Config Files
participant nREPL as nREPL Client
CLI->>CLI: Parse --config-profile option
CLI->>Core: run-prompt with config-profile
Core->>Config: load-config-handling-validation-errors(file, dir, profile)
Config->>Files: Load home config
Files-->>Config: home config
Config->>Files: Load project config
Files-->>Config: project config
Config->>Config: Merge home + project
Config->>Config: load-config-profile(profile)
Files-->>Config: profile config
Config->>Config: apply-config-profile (overlay)
Config-->>Core: Final merged config
Core->>nREPL: Create connection with final config
nREPL-->>Core: nREPL client initialized
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
Pre-merge checks✅ Passed checks (3 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
resources/clojure_mcp/configs/cli-assist.edn (1)
1-6: LGTM — consider adding a brief comment.The profile structure is correct and aligns with the PR objectives. The tool names use the expected underscore convention for MCP tools.
Consider adding a comment at the top explaining the profile's purpose for future maintainers:
💡 Optional: Add documentation comment
+;; CLI-assist profile: Enables tools for command-line agent workflows. +;; Disables write-file-guard to allow unrestricted file writes. {:enable-tools [:clojure_edit_agent :list_nrepl_ports :clojure_eval] :write-file-guard false}src/clojure_mcp/prompt_cli.clj (1)
40-44: Consider extracting the keyword parse function to reduce duplication.The parse-fn logic for converting strings to keywords (lines 41-44) is identical to the model option's parse-fn (lines 29-32). Consider extracting a shared helper.
💡 Optional refactor
;; Define once near the top of cli-options (defn- parse-keyword [s] (if (str/starts-with? s ":") (keyword (subs s 1)) (keyword s))) ;; Then use in both places: ;; :parse-fn parse-keyword
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
resources/clojure_mcp/configs/cli-assist.ednsrc/clojure_mcp/config.cljsrc/clojure_mcp/core.cljsrc/clojure_mcp/prompt_cli.cljtest/clojure_mcp/config/profile_test.clj
🧰 Additional context used
📓 Path-based instructions (2)
**/*.clj
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.clj: Use:requirewith ns aliases in Clojure imports (e.g.,[clojure.string :as string])
Use kebab-case for variable and function names in Clojure
End Clojure predicate functions with?(e.g.,is-top-level-form?)
Usetry/catchwith specific exception handling in Clojure; use atom for tracking errors
Use 2-space indentation in Clojure code and maintain whitespace in edited forms
Align Clojure namespaces with directory structure (e.g.,clojure-mcp.repl-tools)
Include clear tool:descriptionin MCP tools for LLM guidance
Validate inputs and provide helpful error messages in MCP tool implementations
Return structured data with both result and error status in MCP tool responses
Maintain atom-based state for consistent service access in MCP tool implementations
Files:
test/clojure_mcp/config/profile_test.cljsrc/clojure_mcp/config.cljsrc/clojure_mcp/prompt_cli.cljsrc/clojure_mcp/core.clj
**/*test*.clj
📄 CodeRabbit inference engine (CLAUDE.md)
Use
deftestwith descriptive names in Clojure tests; usetestingfor subsections andisfor assertions
Files:
test/clojure_mcp/config/profile_test.clj
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
Repo: bhauman/clojure-mcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T16:18:02.394Z
Learning: Applies to **/*.clj : Include clear tool `:description` in MCP tools for LLM guidance
Learnt from: CR
Repo: bhauman/clojure-mcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T16:18:02.394Z
Learning: Applies to **/*.clj : Align Clojure namespaces with directory structure (e.g., `clojure-mcp.repl-tools`)
📚 Learning: 2026-01-02T16:18:02.394Z
Learnt from: CR
Repo: bhauman/clojure-mcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T16:18:02.394Z
Learning: Applies to **/*.clj : Include clear tool `:description` in MCP tools for LLM guidance
Applied to files:
resources/clojure_mcp/configs/cli-assist.ednsrc/clojure_mcp/config.cljsrc/clojure_mcp/prompt_cli.cljsrc/clojure_mcp/core.clj
📚 Learning: 2026-01-02T16:18:02.394Z
Learnt from: CR
Repo: bhauman/clojure-mcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T16:18:02.394Z
Learning: Applies to **/*.clj : Align Clojure namespaces with directory structure (e.g., `clojure-mcp.repl-tools`)
Applied to files:
resources/clojure_mcp/configs/cli-assist.edntest/clojure_mcp/config/profile_test.cljsrc/clojure_mcp/config.cljsrc/clojure_mcp/core.clj
📚 Learning: 2026-01-02T16:18:02.394Z
Learnt from: CR
Repo: bhauman/clojure-mcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T16:18:02.394Z
Learning: Applies to **/*.clj : Validate inputs and provide helpful error messages in MCP tool implementations
Applied to files:
resources/clojure_mcp/configs/cli-assist.edn
📚 Learning: 2026-01-02T16:18:02.394Z
Learnt from: CR
Repo: bhauman/clojure-mcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T16:18:02.394Z
Learning: Applies to **/*.clj : Maintain atom-based state for consistent service access in MCP tool implementations
Applied to files:
resources/clojure_mcp/configs/cli-assist.edn
📚 Learning: 2026-01-02T16:18:02.394Z
Learnt from: CR
Repo: bhauman/clojure-mcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T16:18:02.394Z
Learning: Prefer REPL-driven development for rapid iteration and feedback in Clojure
Applied to files:
resources/clojure_mcp/configs/cli-assist.edn
📚 Learning: 2026-01-02T16:18:02.394Z
Learnt from: CR
Repo: bhauman/clojure-mcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-02T16:18:02.394Z
Learning: Applies to **/*test*.clj : Use `deftest` with descriptive names in Clojure tests; use `testing` for subsections and `is` for assertions
Applied to files:
test/clojure_mcp/config/profile_test.clj
📚 Learning: 2025-12-27T06:54:07.157Z
Learnt from: nandoolle
Repo: bhauman/clojure-mcp PR: 138
File: src/clojure_mcp/agent/langchain/model.clj:91-97
Timestamp: 2025-12-27T06:54:07.157Z
Learning: When reviewing Clojure code (e.g., in src/clojure_mcp/... ), verify calls to presets/get-preset follow the two arities: [preset-key] and [preset-key overrides]. The 2-arg version should merge the provided overrides map with the preset defaults and return the resulting configuration. Check for correct map merging, preservation of immutability, and validation of overrides keys to ensure predictable configuration outcomes.
Applied to files:
test/clojure_mcp/config/profile_test.cljsrc/clojure_mcp/config.cljsrc/clojure_mcp/prompt_cli.cljsrc/clojure_mcp/core.clj
📚 Learning: 2025-08-18T00:39:24.837Z
Learnt from: hugoduncan
Repo: bhauman/clojure-mcp PR: 86
File: src/clojure_mcp/subprocess.clj:0-0
Timestamp: 2025-08-18T00:39:24.837Z
Learning: In the clojure-mcp project, the user prefers to only parse stdout for nREPL port discovery in the subprocess.clj module, and explicitly does not want to parse stderr for port information.
Applied to files:
src/clojure_mcp/core.clj
🔇 Additional comments (13)
src/clojure_mcp/prompt_cli.clj (2)
229-229: LGTM!The destructuring correctly includes
config-profilealongside other options.
251-255: LGTM!The config profile is correctly passed to
config/load-config, and the logging provides helpful visibility when a profile is applied.test/clojure_mcp/config/profile_test.clj (3)
7-36: LGTM — good coverage of input variants and edge cases.The test correctly validates all input types (keyword, string, symbol) and edge cases (missing profile, nil). The use of
testingblocks with descriptive names follows guidelines.
38-73: LGTM — thorough testing of merge semantics.Good coverage of:
- Profile override behavior
- Preservation of non-overlapping keys
- Nil/missing profile handling
- Deep merge for nested maps
75-85: LGTM!The test validates the cli-assist profile contents match expectations from the PR objectives.
src/clojure_mcp/config.clj (4)
44-52: LGTM!Making
deep-mergepublic enables direct testing. The implementation correctly handles recursive map merging.
54-76: LGTM — good error handling and documentation.The function handles all input types (keyword, symbol, string) and provides helpful warnings when profiles are missing or fail to parse.
Minor note: Line 69 uses
slurpinstead offile-utils/slurp-utf8. This is fine for classpath resources which are typically UTF-8, but consider usingfile-utils/slurp-utf8for consistency with other config loading code (line 26).
78-92: LGTM!The function correctly applies the profile overlay with proper precedence (profile values win).
168-216: LGTM — correct merge precedence and clean implementation.The 3-arity version properly threads the config-profile through the loading process with the documented precedence (profile > project > home).
Note: The profile config is not validated with
validate-configsbefore merging. This may be intentional since profiles are built-in resources (trusted), but consider adding validation if user-defined profiles are supported in the future.src/clojure_mcp/core.clj (4)
236-257: LGTM!The multi-arity implementation correctly forwards
config-profiletoconfig/load-configwhile preserving the existing error handling behavior.
259-271: LGTM!The
fetch-configfunction correctly threadsconfig-profileto the config loading layer.
284-316: LGTM!The function correctly:
- Destructures
config-profilefrom initial-config- Excludes it from
nrepl/createviadissoc- Forwards it to config loading in both project-dir and REPL-query paths
371-374: LGTM!The spec correctly defines
::config-profileaccepting keyword, symbol, or string, and properly includes it as optional in::nrepl-args.
Summary
:config-profileCLI option to load built-in config profiles from classpath resourcescli-assistprofile withclojure_edit_agent,list_nrepl_ports,clojure_evaltools enabled andwrite-file-guarddisabledUsage
Merge precedence (highest to lowest)
:config-profileoverlay (if provided):config-fileor project config (.clojure-mcp/config.edn)~/.clojure-mcp/config.edn)Test plan
load-config-profile(keyword/string/symbol, missing profile, nil)apply-config-profile(merge behavior, nil profile, deep merge)cli-assistprofile contents🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
--config-profileCLI option to apply predefined configuration profiles that customize tooling behaviorTests
✏️ Tip: You can customize this high-level summary in your review settings.