Skip to content

Commit f4c8872

Browse files
author
Bruce Hauman
committed
Add :shadow-cljs-repl-message config flag to disable REPL mode status messages
Allows users to suppress the shadow-cljs mode status message prepended to every eval result. When false, also skips the mode detection probe entirely. Configurable via config.edn or CLI option. Defaults to true (existing behavior). Closes #150
1 parent 125f16f commit f4c8872

File tree

7 files changed

+77
-24
lines changed

7 files changed

+77
-24
lines changed

CONFIG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,19 @@ Boolean flag to control bash command execution mode (default: `true`). This sett
9595
- Both modes apply consistent output truncation (8500 chars total, split between stdout/stderr)
9696
- Local execution may be faster for simple commands but requires the MCP server to have necessary tools installed
9797

98+
### `:shadow-cljs-repl-message`
99+
Controls whether the shadow-cljs REPL mode status message is included in eval results (default: `true`). When connected to a shadow-cljs nREPL server, a status message about the current CLJS mode is prepended to every eval result. This helps AI assistants understand the REPL state but can be disabled if you find it unnecessary.
100+
101+
**Available values:**
102+
- `true` (default) - Includes the shadow-cljs mode status message in eval results
103+
- `false` - Disables the message and skips the mode detection probe entirely
104+
105+
**When to use each setting:**
106+
- `true` - Best for most users, especially when the AI assistant needs to understand whether the REPL is in CLJS mode
107+
- `false` - When you manage REPL state yourself (e.g., via CLAUDE.md instructions) and want to reduce noise in eval output
108+
109+
This can also be set via the CLI: `:shadow-cljs-repl-message false`
110+
98111
### `:dispatch-agent-context`
99112
Primes the dispatch agent with details about your code to help it find answers more quickly and accurately.
100113

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,11 @@ When used without `:port`, the MCP server will automatically parse the port from
529529

530530
`:nrepl-env-type :bb`
531531

532+
#### `:shadow-cljs-repl-message`
533+
**Optional** - Controls whether the shadow-cljs REPL mode status message is included in eval results (default: `true`). When connected to a shadow-cljs nREPL, a status message about CLJS mode is prepended to every eval result. Set to `false` to disable this message.
534+
535+
`:shadow-cljs-repl-message false`
536+
532537
#### `:config-profile`
533538
**Optional** - Load a built-in configuration profile that adjusts tool availability and descriptions. Useful for tailoring ClojureMCP to specific use cases.
534539

src/clojure_mcp/config.clj

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,15 @@
268268
false
269269
(boolean value))))
270270

271+
(defn get-shadow-cljs-repl-message
272+
"Returns whether the shadow-cljs REPL mode status message should be
273+
included in eval results. Defaults to true."
274+
[nrepl-client-map]
275+
(let [value (get-config nrepl-client-map :shadow-cljs-repl-message)]
276+
(if (nil? value)
277+
true
278+
(boolean value))))
279+
271280
(defn clojure-env?
272281
"Returns true if the nREPL environment is a Clojure environment."
273282
[nrepl-client-map]

src/clojure_mcp/config/schema.clj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@
265265
[:bash-over-nrepl {:optional true} :boolean]
266266
[:nrepl-env-type {:optional true} [:enum :clj :bb :basilisp :scittle]]
267267
[:start-nrepl-cmd {:optional true} [:sequential NonBlankString]]
268+
[:shadow-cljs-repl-message {:optional true} :boolean]
268269

269270
;; Scratch pad configuration
270271
[:scratch-pad-load {:optional true} :boolean]

src/clojure_mcp/core.clj

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,24 @@
270270
env-type))]
271271
(assoc nrepl-client-map ::config/config (assoc config :nrepl-env-type final-env-type)))))
272272

273+
(def ^:private cli-config-override-keys
274+
"Keys from the startup opts that override config.edn values."
275+
[:shadow-cljs-repl-message])
276+
277+
(defn- apply-cli-config-overrides
278+
"Applies CLI option overrides to the config attached to an nrepl-client-map.
279+
Only overrides keys that are explicitly provided (non-nil) in opts."
280+
[nrepl-client-map opts]
281+
(let [overrides (reduce (fn [m k]
282+
(if (some? (get opts k))
283+
(assoc m k (get opts k))
284+
m))
285+
{}
286+
cli-config-override-keys)]
287+
(if (seq overrides)
288+
(update nrepl-client-map ::config/config merge overrides)
289+
nrepl-client-map)))
290+
273291
(defn create-and-start-nrepl-connection
274292
"Creates an nREPL client map and loads configuration.
275293
@@ -282,7 +300,7 @@
282300
when the first eval-code call is made.
283301
284302
Takes initial-config map with optional :port, :host, :project-dir, :nrepl-env-type,
285-
:config-file, :config-profile.
303+
:config-file, :config-profile, :shadow-cljs-repl-message.
286304
- If :project-dir is provided, uses it directly (no REPL query needed)
287305
- If :project-dir is NOT provided, queries REPL for project directory (requires :port)
288306
- If :config-profile is provided, merges profile overlay on top of base config
@@ -293,24 +311,27 @@
293311
(log/info "Creating nREPL client for port" port)
294312
(log/info "Starting without nREPL connection (project-dir mode)"))
295313
(try
296-
(let [nrepl-client-map (nrepl/create (dissoc initial-config :project-dir :nrepl-env-type :config-profile))
314+
(let [nrepl-client-map (nrepl/create (apply dissoc initial-config
315+
:project-dir :nrepl-env-type :config-profile
316+
cli-config-override-keys))
297317
cli-env-type (:nrepl-env-type initial-config)
298-
_ (log/info "nREPL client map created")]
299-
(if project-dir
300-
;; Project dir provided - load config directly, no REPL query needed
301-
(let [user-dir (.getCanonicalPath (io/file project-dir))
302-
_ (log/info "Working directory set to:" user-dir)
303-
config (load-config-handling-validation-errors config-file user-dir config-profile)
304-
;; Use cli-env-type or config's env-type, default to :clj
305-
final-env-type (or cli-env-type
306-
(:nrepl-env-type config)
307-
:clj)]
308-
(assoc nrepl-client-map ::config/config (assoc config :nrepl-env-type final-env-type)))
309-
;; No project dir - need to query REPL (requires port)
310-
(let [;; Detect environment type (uses describe op, no full init needed)
311-
env-type (nrepl/detect-nrepl-env-type nrepl-client-map)
312-
_ (nrepl/set-port-env-type! nrepl-client-map env-type)]
313-
(fetch-config nrepl-client-map config-file cli-env-type env-type project-dir config-profile))))
318+
_ (log/info "nREPL client map created")
319+
result (if project-dir
320+
;; Project dir provided - load config directly, no REPL query needed
321+
(let [user-dir (.getCanonicalPath (io/file project-dir))
322+
_ (log/info "Working directory set to:" user-dir)
323+
config (load-config-handling-validation-errors config-file user-dir config-profile)
324+
;; Use cli-env-type or config's env-type, default to :clj
325+
final-env-type (or cli-env-type
326+
(:nrepl-env-type config)
327+
:clj)]
328+
(assoc nrepl-client-map ::config/config (assoc config :nrepl-env-type final-env-type)))
329+
;; No project dir - need to query REPL (requires port)
330+
(let [;; Detect environment type (uses describe op, no full init needed)
331+
env-type (nrepl/detect-nrepl-env-type nrepl-client-map)
332+
_ (nrepl/set-port-env-type! nrepl-client-map env-type)]
333+
(fetch-config nrepl-client-map config-file cli-env-type env-type project-dir config-profile)))]
334+
(apply-cli-config-overrides result initial-config))
314335
(catch Exception e
315336
(log/error e "Failed to create nREPL connection")
316337
(throw e))))
@@ -369,9 +390,10 @@
369390
(catch Exception _ false))))
370391
(s/def ::start-nrepl-cmd (s/coll-of string? :kind vector?))
371392
(s/def ::config-profile (s/or :keyword keyword? :symbol symbol? :string string?))
393+
(s/def ::shadow-cljs-repl-message boolean?)
372394
(s/def ::nrepl-args (s/keys :req-un []
373395
:opt-un [::port ::host ::config-file ::project-dir ::nrepl-env-type
374-
::start-nrepl-cmd ::config-profile]))
396+
::start-nrepl-cmd ::config-profile ::shadow-cljs-repl-message]))
375397

376398
(def nrepl-client-atom (atom nil))
377399

src/clojure_mcp/tools/eval/core.clj

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,9 @@
6565
6666
For shadow-cljs, prepends a mode status message."
6767
([outputs] (partition-and-format-outputs outputs nil))
68-
([outputs {:keys [env-type shadow-cljs-mode?] :as _context}]
69-
(let [prefix (when (= env-type :shadow)
68+
([outputs {:keys [env-type shadow-cljs-mode? show-shadow-message?]}]
69+
(let [prefix (when (and (= env-type :shadow)
70+
(not (false? show-shadow-message?)))
7071
[(shadow-cljs-mode-message shadow-cljs-mode?)])
7172
formatted (mapv #(format-eval-outputs % env-type) (partition-outputs outputs))]
7273
(if prefix

src/clojure_mcp/tools/eval/tool.clj

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,16 +92,18 @@ Examples:
9292
(try
9393
(let [client (nrepl/with-port-initialized base-client port)
9494
env-type (nrepl/get-port-env-type client)
95-
;; Check CLJS mode for shadow-cljs
96-
cljs-mode? (when (= env-type :shadow)
95+
show-shadow-msg? (config/get-shadow-cljs-repl-message base-client)
96+
;; Check CLJS mode for shadow-cljs (skip probe if message disabled)
97+
cljs-mode? (when (and (= env-type :shadow) show-shadow-msg?)
9798
(nrepl/shadow-cljs-mode? client session-type))
9899
;; Execute the eval
99100
eval-result (core/evaluate-with-repair client (cond-> inputs
100101
session-type (assoc :session-type session-type)
101102
(nil? timeout_ms) (assoc :timeout_ms timeout)))]
102103
;; Add context to result for formatting
103104
(assoc eval-result :context {:env-type env-type
104-
:shadow-cljs-mode? cljs-mode?}))
105+
:shadow-cljs-mode? cljs-mode?
106+
:show-shadow-message? show-shadow-msg?}))
105107
(catch java.net.ConnectException e
106108
{:outputs [[:err (format "Failed to connect to nREPL server on port %d: %s. Ensure an nREPL server is running on that port."
107109
port (.getMessage e))]]

0 commit comments

Comments
 (0)