cd /news/ai-tools/evaluate-clojure-code-in-the-running… · home topics ai-tools article
[ARTICLE · art-16493] src=gist.github.com pub= topic=ai-tools verified=true sentiment=· neutral

Evaluate Clojure code in the running app (written by Claude)

A developer has created eval-app, a tool that connects to a running Clojure application's nREPL to evaluate code for inspecting app state, querying databases, or debugging issues. The tool accepts Clojure code via stdin and returns pretty-printed results, with configurable host, port, and timeout options.

read5 min publishedMay 27, 2026

| #!/usr/bin/env bb | |

| ;; ============================================================================= | |
| ;; eval-app - Evaluate Clojure code in the running app | |
| ;; ============================================================================= | |
| ;; | |

| ;; This tool connects to the nREPL of the app running evaluates Clojure code. | | | ;; Useful for inspecting app state, querying the database, or debugging issues | |

| ;; in the running system. | |
| ;; | |
| ;; USAGE: | |
| ;; cat <<'EOF' | agent-tools/eval-app | |
| ;; (your-code-here) | |
| ;; EOF | |
| ;; | |
| ;; cat code.clj | agent-tools/eval-app | |
| ;; | |
| ;; OPTIONS: | |
| ;; --host HOST nREPL host (default: localhost) | |
| ;; --port PORT nREPL port (default: 4000) | |
| ;; --timeout MS Timeout in milliseconds (default: 30000) | |
| ;; --help, -h Show help | |
| ;; | |
| ;; EXAMPLES: | |
| ;; | |

| ;; # Get the current database value | |

| ;; cat <<'EOF' | agent-tools/eval-app | |
| ;; (dev/db) | |
| ;; EOF | |
| ;; | |
| ;; # Query an entity | |
| ;; cat <<'EOF' | agent-tools/eval-app | |
| ;; (dev/show-entity 12345) | |
| ;; EOF | |
| ;; | |
| ;; # Check system state | |
| ;; cat <<'EOF' | agent-tools/eval-app | |
| ;; (keys @app.system/state) | |
| ;; EOF | |
| ;; | |
| ;; # Multi-line code | |
| ;; cat <<'EOF' | agent-tools/eval-app | |
| ;; (d/q '[:find ?e :where [?e :user/email]] (dev/db)) | |
| ;; EOF | |
| ;; | |
| ;; OUTPUT: | |

| ;; Returns the result of evaluating the Clojure code, pretty-printed. | |

| ;; Errors are printed to stderr. | |
| ;; | |
| ;; ============================================================================= | |
| (require '[babashka.cli :as cli] | |
| '[clojure.string :as str] | |
| '[bencode.core :as bencode]) | |
| (import '[java.net Socket] | |
| '[java.io PushbackInputStream]) | |
| (def cli-spec | |
| {:host {:desc "nREPL host" | |
| :default "localhost"} | |
| :port {:desc "nREPL port" | |

| :default 4000 | |

| :coerce :int} | |
| :timeout {:desc "Timeout in milliseconds" | |

| :default 30000 | |

| :coerce :int} | |
| :help {:desc "Show help" | |
| :alias :h}}) | |
| (defn print-help [] | |
| (println "eval-app - Evaluate Clojure code in the running app") | |
| (println) | |
| (println "Usage: cat <<'EOF' | agent-tools/eval-app [OPTIONS]") | |
| (println " (your-code-here)") | |
| (println " EOF") | |
| (println) | |
| (println " cat code.clj | agent-tools/eval-app [OPTIONS]") | |
| (println) | |
| (println "Options:") | |
| (println " --host HOST nREPL host (default: localhost)") | |
| (println " --port PORT nREPL port (default: 4000)") | |
| (println " --timeout MS Timeout in milliseconds (default: 30000)") | |
| (println " --help, -h Show this help") | |
| (println) | |
| (println "Examples:") | |
| (println " cat <<'EOF' | agent-tools/eval-app") | |
| (println " (dev/db)") | |
| (println " EOF")) | |
| (defn bytes->str [x] | |
| (if (bytes? x) | |
| (String. ^bytes x "UTF-8") | |
| x)) | |
| (defn parse-response [response] | |
| (into {} | |
| (map (fn [[k v]] | |
| [(keyword (bytes->str k)) | |
| (if (sequential? v) | |
| (mapv bytes->str v) | |
| (bytes->str v))]) | |
| response))) | |
| (defn nrepl-eval [{:keys [host port timeout]} code] | |
| (let [socket (Socket. ^String host ^int port) | |
| _ (.setSoTimeout socket timeout) | |
| out (.getOutputStream socket) | |
| in (PushbackInputStream. (.getInputStream socket)) | |
| session-id (str (random-uuid)) | |

| msg {"op" "eval" | | | "code" code | | | "id" session-id}] | | | (try | |

| (bencode/write-bencode out msg) | |
| (loop [has-error false] | |
| (let [response (parse-response (bencode/read-bencode in))] | |
| (when-let [out-str (:out response)] | |
| (print out-str) | |
| (flush)) | |
| (when-let [err-str (:err response)] | |
| (binding [*out* *err*] | |
| (print err-str) | |
| (flush))) | |
| (when-let [value (:value response)] | |
| (println value)) | |
| (when-let [ex (:ex response)] | |
| (binding [*out* *err*] | |
| (println "Exception:" ex))) | |
| (let [status (set (:status response)) | |
| has-error (or has-error | |
| (contains? status "error") | |
| (contains? status "eval-error"))] | |
| (if (contains? status "done") | |
| (if has-error 1 0) | |
| (recur has-error))))) | |

| (finally | |

| (.close socket))))) | |
| (defn eval-code [opts code] | |

| (try | | | (nrepl-eval opts code) | | | (catch java.net.ConnectException e | |

| (binding [*out* *err*] | |
| (println "Error: Cannot connect to nREPL at" (str (:host opts) ":" (:port opts))) | |
| (println "Make sure the app is running (bin/dev up)")) | |

| 1) | | | (catch java.net.SocketTimeoutException e | |

| (binding [*out* *err*] | |
| (println "Error: nREPL request timed out")) | |

| 1) | | | (catch Exception e | |

| (binding [*out* *err*] | |
| (println "Error:" (.getMessage e))) | |
| 1))) | |
| (let [{:keys [opts]} (cli/parse-args *command-line-args* {:spec cli-spec}) | |
| opts-with-defaults (merge {:host "localhost" :port 4000 :timeout 30000} opts)] | |
| (if (:help opts) | |
| (print-help) | |
| (let [code (slurp *in*)] | |
| (if (str/blank? code) | |
| (do (binding [*out* *err*] | |
| (println "Error: No code provided on stdin") | |
| (println "Usage: cat <<'EOF' | agent-tools/eval-app") | |
| (println " (dev/db)") | |
| (println " EOF") | |
| (println "Run with --help for more information")) | |
| (System/exit 1)) | |
| (System/exit (eval-code opts-with-defaults code)))))) |
── more in #ai-tools 4 stories · sorted by recency
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/evaluate-clojure-cod…] indexed:0 read:5min 2026-05-27 ·