Skip to content

About

Clojure MCP

Resources

Stars

784 stars

Watchers

16 watching

Forks

Latest commit

Β 

History

1,055 Commits

Folders and files

Repository files navigation

Clojure MCP: A Live REPL for Your Coding Agent

ClojureMCP gives coding agents like Claude Code and Codex a persistent connection to your Clojure REPL.

Table of Contents

What is ClojureMCP?

ClojureMCP is an MCP server that connects a coding agent to a running nREPL in your project. With it, the agent can do what Clojure programmers do: explore in the REPL, check its assumptions against the running program, and test changes as it makes them.

  • clojure_eval - evaluates code over a persistent nREPL connection, repairing unbalanced delimiters before evaluating. Works with Clojure, ClojureScript (shadow-cljs, Figwheel), Babashka, Basilisp, and Scittle.
  • list_nrepl_ports - discovers the nREPL servers running on your machine, so the agent can find and switch between REPLs.
  • paren_repair - a safety valve for the rare delimiter tangle that's hard to fix by string editing.

That's the whole recommended setup: the :repl profile. Your agent keeps its own file reading, editing, search and shell tools.

Where the project is headed

ClojureMCP began in 2025 as a complete coding toolkit for Claude Desktop, at a time when LLMs regularly mangled Clojure's parentheses. So it shipped its own structure-aware editors (clojure_edit, clojure_edit_replace_sexp), a collapsed read_file, file and shell tools, sub-agents, prompts and resources.

That has changed. Current frontier models (recent Claude models in particular) edit Clojure reliably with the built-in editors of Claude Code and Codex, and they rarely get into delimiter trouble they can't get out of. The part of ClojureMCP that still matters is the REPL.

So:

  • The :repl profile is the recommended way to use ClojureMCP.
  • The editing tools and the rest of the full toolkit still work and remain available. They're useful if you're building your own harness, or if you're driving a model that does struggle with Clojure edits. But they're in maintenance mode and on a long path to deprecation, unless new, effective LLM editing approaches are discovered that are best delivered through ClojureMCP.

Help and Community Resources

πŸ“‹ Installation

Prerequisites

  • Clojure
  • Java (JDK 17 or later)
  • An nREPL in your project (see doc/nrepl.md), or let ClojureMCP start one with :start-nrepl-cmd or :fallback-nrepl
  • Full toolkit only: ripgrep for better grep and glob_files performance

Install ClojureMCP

Install ClojureMCP using the Clojure tools installer:

clojure -Ttools install-latest :lib io.github.bhauman/clojure-mcp :as mcp

This installs ClojureMCP globally, making clojure -Tmcp start available from any directory.

CLI Agents (recommended)

CLI coding agents (Claude Code, Codex, Gemini CLI) already have excellent file editing, search and shell tools. ClojureMCP adds the one thing they're missing: a live REPL.

Adding ClojureMCP with :repl

Run from your project directory:

# Claude Code
claude mcp add clojure-mcp -- clojure -Tmcp start :config-profile :repl

# OpenAI Codex
codex mcp add clojure-mcp -- clojure -Tmcp start :config-profile :repl

# Google Gemini CLI
gemini mcp add clojure-mcp clojure -Tmcp start :config-profile :repl

By default ClojureMCP connects to the nREPL port in your project's .nrepl-port file. If you don't keep a REPL running, add :fallback-nrepl true to have ClojureMCP start one for you, or :start-nrepl-cmd '["clojure" "-M:nrepl"]' to start your own alias.

Why an MCP tool instead of evaluating via the shell? Agents reach for a first-class REPL tool far more readily than for a shell command, and the connection is persistent: state you build up in the REPL stays there between evaluations. If you'd rather not run an MCP server at all, clojure-mcp-light provides a shell-based nREPL client and a delimiter-repair hook instead.

Working with Multiple REPLs

With list_nrepl_ports, the agent can discover both your Clojure and shadow-cljs REPLs simultaneously. The tool identifies which REPLs are shadow-cljs instances, allowing the agent to evaluate on either REPL using clojure_eval with the appropriate port parameter.

Older CLI profiles

These editing-focused profiles are still shipped. They're mainly useful with models that struggle to edit Clojure.

All three include the :repl tools (clojure_eval, list_nrepl_ports, paren_repair) plus deps_list, deps_grep and deps_read for searching and reading source in dependency jars.

  • :cli-assist - structural editors as a fallback for when the host's Edit tool fails to apply a change. Adds: clojure_edit, clojure_edit_replace_sexp.
  • :cli-assist-agent - like :cli-assist, but the form-level fallback is an LLM sub-agent that applies loosely specified edits (requires an API key). Adds: clojure_edit_agent, clojure_edit_replace_sexp.
  • :cli-assist-full - all Clojure reading and editing routed through ClojureMCP's tools instead of the host's. Adds: read_file, clojure_edit, clojure_edit_replace_sexp.

See doc/full-toolkit.md for more.

Check install by starting the server

From your project directory:

clojure -Tmcp start :config-profile :repl

You should see JSON-RPC output like this:

{"jsonrpc":"2.0","method":"notifications/tools/list_changed"}
{"jsonrpc":"2.0","method":"notifications/tools/list_changed"}
{"jsonrpc":"2.0","method":"notifications/resources/list_changed"}
{"jsonrpc":"2.0","method":"notifications/prompts/list_changed"}

The Full Toolkit (legacy)

Without a :config-profile, ClojureMCP serves its original full toolkit: structure-aware editors, a collapsed file reader, file and shell tools, sub-agents, prompts and resources. It was built to turn Claude Desktop into a Clojure coding assistant, and it's in maintenance mode now (see Where the project is headed).

If you're reaching for Claude Desktop to write Clojure, you'll be better served by Claude Code, Codex or another programming harness with the :repl profile.

Setup for Claude Desktop, the older editing profiles, API keys for the agent tools, the full tool list and file-tool configuration are all in doc/full-toolkit.md.

πŸ”§ Customization

If you're building your own harness, ClojureMCP's tools, prompts and resources can be assembled into a custom MCP server: pick the tools you want, add your own as multimethods or simple maps, and expose your own prompts and resources.

See Creating Your Own Custom MCP Server to get started, and the customization docs for the rest.

CLI options

Values passed to clojure -Tmcp start are EDN values.

:port

Optional - The nREPL server port to connect to. When using :start-nrepl-cmd without :port, the port will be automatically discovered from the command output.

:port 7888

:host

Optional - The nREPL server host. Defaults to localhost if not specified.

:host "localhost" or :host "0.0.0.0"

:not-cwd

Optional - If true, don't use the current working directory as the project directory. Requires :port to be specified. The MCP server will introspect the nREPL connection to discover the project's working directory. Needed for clients that launch the MCP server outside your project directory, such as Claude Desktop.

:not-cwd true

:start-nrepl-cmd

Optional - A command to automatically start an nREPL server if one is not already running. Must be specified as a vector of strings. The MCP server will start this process and manage its lifecycle.

When used without :port, the MCP server will automatically parse the port from the command's output. When used with :port, it will use that fixed port instead.

Important: The nREPL server is started in the current working directory, so launch clojure-mcp from your project directory (where your deps.edn or project.clj is located). CLI agents do this already. For clients that launch servers elsewhere, also pass :project-dir.

:start-nrepl-cmd ["lein" "repl" ":headless"] or :start-nrepl-cmd ["clojure" "-M:nrepl"]

:fallback-nrepl

Optional - When true, ClojureMCP will first try to attach to :port. If nothing is listening there (or :port is omitted entirely), it spawns a local nREPL on an ephemeral port and connects to that. The fallback never squats on your configured :port, so a later editor session can still claim it.

This is intended for users who don't always have an editor-managed nREPL running. Without this flag, ClojureMCP fails to start if it can't reach :port.

The default command is built from clojure-mcp's own nREPL dependency (so no version is hardcoded) and runs through clojure -Sdeps ... -M -m nrepl.cmdline. The user's ~/.clojure/deps.edn is still merged in by the clojure CLI, so libraries you keep globally available (e.g. Criterium) remain on the spawned REPL's classpath.

The spawned process is cleaned up automatically when the MCP server shuts down.

:fallback-nrepl true

:fallback-nrepl-cmd

Optional - Overrides the default fallback command. Must be a vector of strings. Only used when :fallback-nrepl is true. Do not include an explicit port in the command; the launcher needs to parse the discovered port from the process output.

:fallback-nrepl-cmd ["lein" "repl" ":headless"]

:fallback-nrepl-dir

Optional - Working directory for the spawned fallback REPL. Defaults to :project-dir if set, otherwise to $HOME. Useful when you want the fallback REPL to pick up a project's deps.edn automatically.

:fallback-nrepl-dir "/path/to/scratch"

:config-file

Optional - Specify the location of a configuration file. Must be a path to an existing file.

:config-file "/path/to/config.edn"

:project-dir

Optional - Specify the working directory for your codebase. This overrides the automatic introspection of the project directory from the nREPL connection. Must be a path to an existing directory.

:project-dir "/path/to/your/clojure/project"

:nrepl-env-type

Optional - Specify the type of environment that we are connecting to over the nREPL connection. This overrides automatic detection. Valid options are:

  • :clj for Clojure or ClojureScript
  • :bb for Babashka - Native, fast starting Clojure interpreter for scripting
  • :basilisp for Basilisp - A Clojure-compatible Lisp dialect targeting Python 3.9+
  • :scittle for Scittle - Execute ClojureScript directly from browser script tags

:nrepl-env-type :bb

:shadow-cljs-repl-message

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.

:shadow-cljs-repl-message false

:config-profile

Optional - Load a built-in configuration profile that adjusts tool availability and descriptions. Useful for tailoring ClojureMCP to specific use cases.

Available profiles:

  • :repl - Recommended. REPL-only toolset for CLI coding agents (Claude Code, Codex, Gemini CLI): clojure_eval, list_nrepl_ports and paren_repair, with no prompts or resources. The agent uses its own tools for all reading and editing. Uses allowlists, so tools added to ClojureMCP later stay off unless the profile lists them.
  • :cli-assist, :cli-assist-agent, :cli-assist-full - (legacy) Editing-focused profiles; see doc/full-toolkit.md.

:config-profile :repl

:enable-tools

Optional - Allowlist of tool keywords. When provided, replaces any :enable-tools value from config. Only the listed tools will be available.

:enable-tools [:clojure_eval :read_file]

:disable-tools

Optional - Blocklist of tool keywords. When provided, replaces any :disable-tools value from config. The listed tools will be disabled.

:disable-tools [:bash :dispatch_agent]

:add-tools

Optional - Force-enable specific tools after config resolution. Removes tools from the disable list, and adds them to the enable list if one is active. This is useful for selectively re-enabling tools that a config profile disables.

:add-tools [:my_custom_agent]

:remove-tools

Optional - Force-disable specific tools after config resolution. Adds tools to the disable list, and removes them from the enable list if one is active. This is useful for selectively disabling tools without replacing the entire config.

:remove-tools [:clojure_eval]

Tool filtering application order

  1. Config loaded (home + project + profile merge)
  2. :enable-tools/:disable-tools from opts replace config values (if provided)
  3. :remove-tools applied (force-disable)
  4. :add-tools applied (force-enable β€” wins over :remove-tools on overlap)
  5. ENABLE_TOOLS/DISABLE_TOOLS env vars still win over everything

See Component Filtering for details on how enable/disable lists work in config files.

Example Usage

# Recommended for CLI coding agents: REPL tools only
clojure -Tmcp start :config-profile :repl

# REPL only, connecting to a specific port
clojure -Tmcp start :config-profile :repl :port 7888

# REPL only, spawning an nREPL if none is running
clojure -Tmcp start :config-profile :repl :fallback-nrepl true

# REPL only, starting your project's nREPL alias (port is discovered)
clojure -Tmcp start :config-profile :repl :start-nrepl-cmd '["clojure" "-M:nrepl"]'

# Leiningen project
clojure -Tmcp start :config-profile :repl :start-nrepl-cmd '["lein" "repl" ":headless"]'

# Babashka nREPL
clojure -Tmcp start :config-profile :repl :port 1667 :nrepl-env-type :bb

# With custom host and project directory
clojure -Tmcp start :port 7888 :host '"0.0.0.0"' :project-dir '"/path/to/project"'

# Using a custom config file
clojure -Tmcp start :port 7888 :config-file '"/path/to/custom-config.edn"'

# REPL only, plus one of the legacy structural editors
clojure -Tmcp start :config-profile :repl :add-tools '[:clojure_edit]'

# Strictly REPL: drop paren_repair too
clojure -Tmcp start :config-profile :repl :remove-tools '[:paren_repair]'

# Full override β€” only these two tools
clojure -Tmcp start :enable-tools '[:clojure_eval :read_file]'

Note: String values need to be properly quoted for the shell, hence '"value"' syntax for strings.

βš™οΈ Configuration

ClojureMCP reads optional project configuration from a .clojure-mcp/config.edn file in your project's root directory. The :repl profile usually needs none. Most options configure the full toolkit's file, shell and agent tools (see doc/full-toolkit.md).

Configuration File Location

Create a .clojure-mcp/config.edn file in your project root:

your-project/
β”œβ”€β”€ .clojure-mcp/
β”‚   └── config.edn
β”œβ”€β”€ src/
β”œβ”€β”€ deps.edn
└── ...

Configuration Options

All options are documented in CONFIG.md.

πŸ“ License

Eclipse Public License - v 2.0

Copyright (c) 2025 Bruce Hauman

This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0

License Summary

  • βœ… Use freely for personal projects, internal business tools, and development
  • βœ… Modify and distribute - improvements and forks are welcome
  • βœ… Commercial use - businesses can use this commercially without restrictions
  • βœ… Flexible licensing - can be combined with proprietary code
  • πŸ“€ Share improvements - source code must be made available when distributed

About

Clojure MCP

Resources

Stars

784 stars

Watchers

16 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages