Are you the author? Sign in to claim
Clojure MCP
ClojureMCP is an MCP server for Clojure!
ClojureMCP is an MCP server that connects an LLM client (like Claude Code or Claude Desktop) to your Clojure project. It provides REPL tools and Clojure-aware editing tools designed to handle Clojure's parentheses and formatting reliably.
Depending on your LLM client, ClojureMCP can either:
clojure -Ttools install-latest ...).If you're using a CLI assistant, you'll usually prefer to keep the CLI's native file editing tools and use ClojureMCP mainly for REPL integration (and as an editing fallback).
If you're using a desktop chat app, you'll typically use the full ClojureMCP toolchain.
grep and glob_files performanceInstall 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 coding assistants (Claude Code, Codex, Gemini CLI) already have great inline-diff editing and shell tools.
Start with clojure-mcp-light - it provides REPL integration and delimiter repair while preserving your CLI's native inline-diff display. This works well for most Clojure development.
Consider adding ClojureMCP with the :cli-assist profile if you want:
Adding ClojureMCP to clojure-mcp-light can provide an enhanced Clojure development experience for CLI assistants.
:cli-assist# Claude Code
claude mcp add clojure-mcp -- clojure -Tmcp start :config-profile :cli-assist
# OpenAI Codex
codex mcp add clojure-mcp -- clojure -Tmcp start :config-profile :cli-assist
# Google Gemini CLI
gemini mcp add clojure-mcp clojure -Tmcp start :config-profile :cli-assist
Prefer clojure-mcp's editing/reading tools? If you let the agent drive and care
less about the native inline diff, swap :cli-assist for :cli-assist-full. It makes
read_file, clojure_edit, clojure_edit_replace_sexp, and paren_repair
first-class (instead of fallbacks) and instructs the assistant to do all
Clojure-file edits through them — which sidesteps the host editor's "file modified
since read" conflict without any permission configuration. (Power users who want a
hard guarantee can additionally add Claude Code permissions.deny rules like
"Edit(/**/*.clj)" so the native editor can't touch Clojure files at all.)
From your project directory:
clojure -Tmcp start :config-profile :cli-assist
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"}
Desktop chat apps (like Claude Desktop) start MCP servers outside your project directory and do not provide built-in coding tools. In this environment, you’ll typically use the full ClojureMCP toolchain and connect it to an nREPL running in your project.
ClojureMCP was initially developed to turn Claude Desktop into a coding assistant similar to Claude Code with tools designed to work effectively with the Clojure programming language.
Start an nREPL server from your project directory. If you don't already have an nREPL alias or configuration, see doc/nrepl.md.
Pick the shell executable that will most likely pick up your environment config:
If you are using Bash find the explicit bash executable path:
$ which bash
/opt/homebrew/bin/bash
If you are using Z Shell find the explicit zsh executable path:
$ which zsh
/bin/zsh
Now we're going to use this explicit shell path in the command
parameter in the Claude Desktop configuration as seen below.
Create or edit ~/Library/Application\ Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"clojure-mcp": {
"command": "/opt/homebrew/bin/bash",
"args": [
"-c",
"clojure -Tmcp start :not-cwd true :port 7888"
]
}
}
}
The :not-cwd true flag tells ClojureMCP not to use the current working directory (which for Claude Desktop is not your project). Instead, it introspects the nREPL connection to discover the project's working directory.
This allows a simple working pattern of starting a REPL on 7888, then starting Claude Desktop and allowing it to detect where you are working.
When you want to switch to a different project you would stop the current REPL running on 7888 and start a nREPL server in the project you want to work in on port 7888.
Start nREPL in your target project:
cd /path/to/your/project
clojure -M:nrepl
Look for: nREPL server started on port 7888...
Restart Claude Desktop (required after configuration changes)
Verify Connection: In Claude Desktop, click the + button in the chat area. You should see "Add from clojure-mcp" in the menu. It's important to note that it may take a few moments for this to show up.
If there was an error please see the Troubleshooting Guide. If it connected, go see the Starting a new conversation in Claude Desktop section.
Code Execution and file creation: off
Code execution and file creation provides tools that compete with ClojureMCP; it's best to turn them off.
Go to settings > Capabilities > Code Execution and file creation and toggle it off.
You may also want to turn Artifacts off as well.
See the Wiki for information on setting up other MCP clients.
Once everything is set up I'd suggest starting a new chat in Claude.
The first thing you are going to want to do is initialize context about the Clojure project in the conversation attached to the nREPL.
In Claude Desktop click the + tools and optionally add
PROJECT_SUMMARY.md - (have the LLM create this) see belowClojure Project Info - which introspects the nREPL connected projectLLM_CODE_STYLE.md - Which is your personal coding style instructions (copy the one in this repo to the root of your project)clojure_repl_system_prompt - instructions on how to code - cribbed a bunch from Claude CodeThen start the chat.
I would start by stating a problem and then chatting with the LLM to interactively design a solution. You can ask Claude to "present a solution for my review".
Iterate on that a bit then have it either:
A. code and validate the idea in the REPL.
Don't underestimate LLMs abilities to use the REPL! Current LLMs are absolutely fantastic at using the Clojure REPL.
B. ask the LLM to make the changes to the source code and then have it validate the code in the REPL after file editing.
C. ask to run the tests. D. ask to commit the changes.
Make a branch and have the LLM commit often so that it doesn't ruin good work by going in a bad direction.
This project includes a workflow for maintaining an LLM-friendly PROJECT_SUMMARY.md that helps assistants quickly understand the codebase structure.
Creating the Summary: To generate or update the PROJECT_SUMMARY.md file, use the MCP prompt in the + > clojure-mcp menu create-update-project-summary. This prompt will:
Using the Summary: When starting a new conversation with an assistant:
Keeping It Updated: At the end of a productive session where new features or components were added:
create-update-project-summary prompt againThis workflow creates a virtuous cycle where each session builds on the accumulated knowledge of previous sessions, making the assistant increasingly effective as your project evolves.
The Clojure MCP server provides a pair of prompts that enable
conversation continuity across chat sessions using the scratch_pad
tool. By default, data is stored in memory only for the current session.
To persist summaries across server restarts, you must enable scratch pad
persistence using the configuration options described in the scratch pad section.
The system uses two complementary prompts:
chat-session-summarize: Creates a summary of the current conversation
chat_session_key parameter (defaults to "chat_session_summary")chat-session-resume: Restores context from a previous conversation
clojure_inspect_project for current project statechat_session_key parameter (defaults to "chat_session_summary")Ending a Session:
chat-session-summarize promptStarting a New Session:
chat-session-resume promptYou can maintain multiple parallel conversation contexts by using custom keys:
# For feature development
chat-session-summarize with key "feature-auth-system"
# For bug fixing
chat-session-summarize with key "debug-memory-leak"
# Resume specific context
chat-session-resume with key "feature-auth-system"
This enables switching between different development contexts while maintaining the full state of each conversation thread.
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.
This is NOT required to use the Clojure MCP server.
IMPORTANT: if you have the following API keys set in your environment, then ClojureMCP will make calls to them when you use the
dispatch_agent,architectandcode_critiquetools. These calls will incur API charges.
There are a few MCP tools provided that are agents unto themselves and they need API keys to function.
To use the agent tools, you'll need API keys from one or more of these providers:
GEMINI_API_KEY - For Google Gemini models
dispatch_agent, architect, code_critiqueOPENAI_API_KEY - For GPT models
dispatch_agent, architect, code_critiqueANTHROPIC_API_KEY - For Claude models
dispatch_agentOption 1: Export in your shell
export ANTHROPIC_API_KEY="your-anthropic-api-key-here"
export OPENAI_API_KEY="your-openai-api-key-here"
export GEMINI_API_KEY="your-gemini-api-key-here"
Option 2: Add to your shell profile (.bashrc, .zshrc, etc.)
# Add these lines to your shell profile
export ANTHROPIC_API_KEY="your-anthropic-api-key-here"
export OPENAI_API_KEY="your-openai-api-key-here"
export GEMINI_API_KEY="your-gemini-api-key-here"
When setting up Claude Desktop, ensure it can access your environment variables by updating your config.
Personally I source them right in bash command:
{
"mcpServers": {
"clojure-mcp": {
"command": "/bin/sh",
"args": [
"-c",
"source ~/.api_credentials.sh && PATH=/your/bin/path:$PATH && clojure -Tmcp start :not-cwd true :port 7888"
]
}
}
}
Note: The agent tools will work with any available API key. You don't need all three - just set up the ones you have access to. The tools will automatically select from available models. For now the ANTHROPIC API is limited to the dispatch_agent.
The default tools included in main.clj are organized by category to support different workflows:
| Tool Name | Description | Example Usage |
|---|---|---|
LS | Returns a recursive tree view of files and directories | Exploring project structure |
read_file | Smart file reader with pattern-based exploration for Clojure files | Reading files with collapsed view, pattern matching |
grep | Fast content search using regular expressions | Finding files containing specific patterns |
glob_files | Pattern-based file finding | Finding files by name patterns like *.clj |
| Tool Name | Description | Example Usage |
|---|---|---|
clojure_eval | Evaluates Clojure code in the current namespace; supports optional port parameter for multi-REPL workflows | Testing expressions, connecting to different REPLs |
list_nrepl_ports | Discovers running nREPL servers on the machine | Finding available REPLs to connect to |
bash | Execute shell commands on the host system | Running tests, git commands, file operations |
| Tool Name | Description | Example Usage |
|---|---|---|
clojure_edit | Structure-aware editing of Clojure forms | Replacing/inserting functions, handling defmethod |
clojure_edit_replace_sexp | Modify expressions within functions | Changing specific s-expressions |
file_edit | Edit files by replacing text strings | parinfer repair after edit if needed |
file_write | Write complete files with safety checks | Creating new files, overwriting with validation |
| Tool Name | Description | Example Usage |
|---|---|---|
dispatch_agent | Launch agents with read-only tools for complex searches | Multi-step file exploration and analysis |
architect | Technical planning and implementation guidance | System design, architecture decisions |
| Tool Name | Description | Example Usage |
|---|---|---|
scratch_pad | Persistent workspace for structured data storage | Task tracking, planning, inter-tool communication with optional file persistence (disabled by default) |
code_critique | Interactive code review and improvement suggestions | Iterative code quality improvement |
read_file)name_pattern to find functions by name, content_pattern to search content"area :rectangle" or vector dispatchesclojure_edit)clojure_eval)bash)dispatch_agent)scratch_pad)set_path, get_path, delete_path for precise data manipulationClojureMCP is designed to be highly customizable. During the alpha phase, creating your own custom MCP server is the primary way to configure the system for your specific needs.
You can customize:
The customization approach is both easy and empowering - you're essentially building your own personalized AI development companion.
📖 Complete Customization Documentation
For a quick start: Creating Your Own Custom MCP Server - This is where most users should begin.
Values passed to clojure -Tmcp start are EDN values.
:portOptional - 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
:hostOptional - The nREPL server host. Defaults to localhost if not specified.
:host "localhost" or :host "0.0.0.0"
:not-cwdOptional - 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.
This is essential for Claude Desktop and other clients that launch the MCP server outside your project directory. By connecting to an nREPL running in your project, ClojureMCP can determine the correct working directory automatically.
:not-cwd true
:start-nrepl-cmdOptional - 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: This option requires launching clojure-mcp from your project directory (where your deps.edn or project.clj is located). The nREPL server will be started in the current working directory. This is particularly useful for Claude Code and other command-line LLM clients where you want automatic nREPL startup without manual process management.
Note for Claude Desktop users: Claude Desktop does not start MCP servers from your project directory, so :start-nrepl-cmd will not work unless you also provide :project-dir as a command line argument pointing to your specific project. For example: :project-dir '"/path/to/your/clojure/project"'. This limitation does not affect Claude Code or other CLI-based tools that you run from your project directory.
:start-nrepl-cmd ["lein" "repl" ":headless"] or :start-nrepl-cmd ["clojure" "-M:nrepl"]
:fallback-nreplOptional - 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 — for example, when launching Claude Desktop without first starting a project REPL, or when working in small projects via Vim. Without this flag, ClojureMCP fails to start if it can't reach :port, which Claude Desktop surfaces as a "Server disconnected" error.
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-cmdOptional - 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-dirOptional - 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-fileOptional - Specify the location of a configuration file. Must be a path to an existing file.
:config-file "/path/to/config.edn"
:project-dirOptional - 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-typeOptional - 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-messageOptional - 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-profileOptional - Load a built-in configuration profile that adjusts tool availability and descriptions. Useful for tailoring ClojureMCP to specific use cases.
Available profiles:
:cli-assist - Minimal toolset for CLI coding assistants (Claude Code, Codex, Gemini CLI). Disables redundant tools and configures clojure_edit as a fallback for when native Edit fails.:cli-assist-full - Like :cli-assist, but promotes clojure-mcp's read_file, clojure_edit, clojure_edit_replace_sexp, and paren_repair to first-class tools (no "fallback" framing) for an agent-driven workflow. Its instructions steer the assistant to route all Clojure-file edits through the clojure tools, which avoids the host editor's "file modified since read" conflict without any host permission setup.:config-profile :cli-assist
:enable-toolsOptional - 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-toolsOptional - 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-toolsOptional - 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-toolsOptional - 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]
:enable-tools/:disable-tools from opts replace config values (if provided):remove-tools applied (force-disable):add-tools applied (force-enable — wins over :remove-tools on overlap)ENABLE_TOOLS/DISABLE_TOOLS env vars still win over everythingSee Component Filtering for details on how enable/disable lists work in config files.
# Basic usage with just port
clojure -Tmcp start :port 7888
# With automatic nREPL server startup and port discovery
# Perfect for CLI assistants - run this from your project directory
clojure -Tmcp start :start-nrepl-cmd '["lein" "repl" ":headless"]'
# For deps.edn projects (from project directory)
clojure -Tmcp start :start-nrepl-cmd '["clojure" "-M:nrepl"]'
# Auto-start with explicit port (uses fixed port, no parsing)
clojure -Tmcp start :port 7888 :start-nrepl-cmd '["clojure" "-M:nrepl"]'
# Attach to port 7888 if available, otherwise spawn a fallback nREPL on
# an ephemeral port. Useful for Claude Desktop when you don't always
# have an editor-managed REPL running.
clojure -Tmcp start :not-cwd true :port 7888 :fallback-nrepl true
# For Claude Desktop: must provide project-dir since it doesn't run from your project
clojure -Tmcp start :start-nrepl-cmd '["lein" "repl" ":headless"]' :project-dir '"/path/to/your/clojure/project"'
# 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"'
# Specifying Babashka environment
clojure -Tmcp start :port 7888 :nrepl-env-type :bb
# Using cli-assist profile for CLI coding assistants
clojure -Tmcp start :config-profile :cli-assist
# Like cli-assist, but clojure-mcp's read/edit tools are first-class (agent-driven workflow)
clojure -Tmcp start :config-profile :cli-assist-full
# cli-assist with a custom agent tool re-enabled
clojure -Tmcp start :config-profile :cli-assist :add-tools '[:my_custom_agent]'
# cli-assist but also remove clojure_eval
clojure -Tmcp start :config-profile :cli-assist :remove-tools '[:clojure_eval]'
# 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.
The Clojure MCP server supports minimal project-specific configuration
through a .clojure-mcp/config.edn file in your project's root
directory. This configuration provides security controls and
customization options for the MCP server.
Create a .clojure-mcp/config.edn file in your project root:
your-project/
├── .clojure-mcp/
│ └── config.edn
├── src/
├── deps.edn
└── ...
Configuration is extensively documented here.
{:allowed-directories ["."
"src"
"test"
"resources"
"dev"
"/absolute/path/to/shared/code"
"../sibling-project"]
:write-file-guard :partial-read
:cljfmt false
:bash-over-nrepl false}
Path Resolution:
"src", "../other-project") are resolved relative to your project root"/home/user/shared") are used as-isSecurity:
Default Behavior:
Note: Configuration is loaded when the MCP server starts. Restart the server (or the Chat Agent) after making configuration changes.
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
Run Claude Code as an MCP server so any agent can delegate coding tasks to it
Browser automation using accessibility snapshots instead of screenshots
Google's universal MCP server supporting PostgreSQL, MySQL, MongoDB, Redis, and 10+ databases
Official GitHub integration for repos, issues, PRs, and CI/CD workflows