|
| 1 | +^{:kindly/hide-code true |
| 2 | + :clay {:title "Connecting Clojure-MCP to Alternative LLM APIs" |
| 3 | + :quarto {:author [:mattb :annieliu] |
| 4 | + :type :post |
| 5 | + :date "2026-02-17" |
| 6 | + :category :clojure |
| 7 | + :tags [:clojuremcp :deepseek :llmapi]}}} |
| 8 | + |
| 9 | +(ns clojuremcp.llmapi |
| 10 | + (:require [scicloj.kindly.v4.kind :as kind])) |
| 11 | + |
| 12 | +;; --- |
| 13 | + |
| 14 | +;; ## Introduction |
| 15 | + |
| 16 | +;; [Clojure-mcp](https://github.com/bhauman/clojure-mcp), created by Bruce Hauman, connects LLMs to a Clojure nREPL via the Model Context Protocol (MCP). It provides specialised tools — such as `clojure_eval` — that let an LLM evaluate code, inspect results, and iteratively refine its output through a tight feedback loop with a live REPL. |
| 17 | + |
| 18 | +;; The standard setup path uses Claude Desktop or Claude Code, both of which have first-class MCP support. But what if you're in a region where Claude applications are unavailable, or you simply prefer a different model? This post walks through an alternative: connecting clojure-mcp to the DeepSeek API via [Cline](https://github.com/cline/cline) and [clojure-mcp-examples](https://github.com/stoating/clojure-mcp-examples). |
| 19 | + |
| 20 | +;; While we use DeepSeek as the example, the same approach works with other API providers that Cline supports — including OpenRouter, Qwen, and Groq. For users who prefer to keep everything local, Cline also supports models running via Ollama or LM Studio, so the entire chain can run on your own machine. |
| 21 | + |
| 22 | +;; ## Architecture Overview |
| 23 | + |
| 24 | +;; The connection chain looks like this: |
| 25 | + |
| 26 | +;; ``` |
| 27 | +;; LLM API (e.g. DeepSeek) ↔ Cline ↔ mcp-proxy (stdio↔HTTP/SSE bridge) ↔ clojure-mcp (stdio) ↔ nREPL |
| 28 | +;; ``` |
| 29 | + |
| 30 | +;; Each component plays a distinct role: |
| 31 | + |
| 32 | +;; | Component | Role | |
| 33 | +;; |-----------|------| |
| 34 | +;; | **nREPL** | The Clojure REPL where code actually executes | |
| 35 | +;; | **clojure-mcp** | Wraps nREPL and exposes MCP-standardised tools (e.g. `clojure_eval`) via stdio | |
| 36 | +;; | **[mcp-proxy](https://github.com/sparfenyuk/mcp-proxy)** | A Python-based transport bridge that converts stdio ↔ HTTP/SSE (port 7080) | |
| 37 | +;; | **Podman container** | Runs mcp-proxy and clojure-mcp together in an isolated environment | |
| 38 | +;; | **Nix/devenv** | Ensures a reproducible environment with all dependencies version-pinned | |
| 39 | +;; | **Cline** | A VS Code extension that bridges the user, the LLM API, and any MCP servers | |
| 40 | +;; | **LLM (DeepSeek)** | The reasoning engine that decides when and how to call tools | |
| 41 | + |
| 42 | +;; **Why do we need mcp-proxy?** The core clojure-mcp server communicates via stdio — it doesn't expose a network endpoint. For Cline (or any third-party client) to reach it, [mcp-proxy](https://github.com/sparfenyuk/mcp-proxy) translates between stdio and HTTP/SSE, making the server accessible over the network on port 7080. |
| 43 | + |
| 44 | +;; **Why a container?** The Podman container packages the proxy and clojure-mcp together, providing isolation from the host system and making the environment portable. Podman is similar to Docker but runs rootless by default with no central daemon. |
| 45 | + |
| 46 | +;; **Why Nix/devenv?** Nix and devenv declaratively provision all dependencies — Podman, Clojure, mcp-proxy, etc. — in a version-pinned, reproducible way. The environment will be identical whether you're on Linux, macOS, or WSL. |
| 47 | + |
| 48 | +;; **Why Cline rather than VS Code's built-in Copilot?** Cline is an open-source AI coding agent that makes it straightforward to connect to a wide range of API providers. VS Code's Copilot can also connect to alternative APIs, but the setup is more involved and requires additional extensions. Cline gives you a simple dropdown to switch between models and providers. |
| 49 | + |
| 50 | +;; ## How It Works at Runtime |
| 51 | + |
| 52 | +;; Once everything is connected, a typical interaction proceeds as follows: |
| 53 | + |
| 54 | +;; 1. You enter a prompt in Cline (e.g. "Write and test a Clojure function that reverses a string"). |
| 55 | +;; 2. Cline sends the prompt to the DeepSeek API. |
| 56 | +;; 3. DeepSeek reasons about the task and may decide to call a tool. It returns a tool-call request (e.g. `clojure_eval`) in its response. |
| 57 | +;; 4. Cline intercepts the tool call and translates it into an MCP request, forwarding it over HTTP/SSE to mcp-proxy → clojure-mcp → nREPL. |
| 58 | +;; 5. The REPL executes the code and returns the result back through the chain. |
| 59 | +;; 6. Cline feeds the tool result back to DeepSeek. |
| 60 | +;; 7. DeepSeek continues reasoning — possibly making further tool calls — until it produces a final response. |
| 61 | +;; 8. Cline displays the final answer, along with token usage and approximate cost. |
| 62 | + |
| 63 | +;; This agentic loop lets the LLM iteratively write, test, and refine Clojure code with real REPL feedback. |
| 64 | + |
| 65 | +;; ## Setup |
| 66 | + |
| 67 | +;; The setup uses [clojure-mcp-examples](https://github.com/stoating/clojure-mcp-examples) by Stoating (Zachary Slade), which provides containerised environments for running clojure-mcp with mcp-proxy. (The project supports four different architectural patterns and multiple simultaneous clients — see its README for the full picture. Here we use just what we need for the Cline/DeepSeek path.) |
| 68 | + |
| 69 | +;; ### Step 1: Clone and install Nix |
| 70 | + |
| 71 | +;; > ``` |
| 72 | +;; > git clone https://github.com/stoating/clojure-mcp-examples.git && cd clojure-mcp-examples && ./bootstrap/01-install-nix.sh |
| 73 | +;; > ``` |
| 74 | +;; > **Important:** Close your terminal and open a new one after this step. |
| 75 | + |
| 76 | +;; ### Step 2: Install devenv and enter the development shell |
| 77 | + |
| 78 | +;; > ``` |
| 79 | +;; > ./bootstrap/02-install-devenv.sh && devenv shell |
| 80 | +;; > ``` |
| 81 | +;; > This installs devenv and enters the development shell with all dependencies (Podman, Clojure, mcp-proxy, etc.) available. |
| 82 | + |
| 83 | +;; ### Step 3: Start the container |
| 84 | + |
| 85 | +;; > ``` |
| 86 | +;; > start |
| 87 | +;; > ``` |
| 88 | +;; > This brings up the containers. The MCP server will be available at `http://localhost:7080/sse`. |
| 89 | + |
| 90 | +;; (There is no need to run `bridge` or `claude-std`, as those generate configurations for Claude Desktop/Code, which we are not using here.) |
| 91 | + |
| 92 | +;; ### Step 4: Install and configure Cline |
| 93 | + |
| 94 | +;; With the container running, open VS Code and install the [Cline](https://github.com/cline/cline) extension. In Cline's settings, under **API Provider**, select DeepSeek, enter your API key (obtainable from the [DeepSeek dashboard](https://platform.deepseek.com/)), and choose your preferred model. (See Cline's [model selection guide](https://docs.cline.bot/getting-started/selecting-your-model) for details.) The finished settings should resemble this: |
| 95 | + |
| 96 | +^{:kindly/hide-code true} |
| 97 | +(defn display [image] |
| 98 | + (kind/hiccup |
| 99 | + [:section |
| 100 | + [:img {:src image |
| 101 | + :style {:display "block" |
| 102 | + :margin "0 auto" |
| 103 | + :max-width "60%" |
| 104 | + :border-radius "6px"}}]])) |
| 105 | + |
| 106 | +^{:kindly/hide-code true} |
| 107 | +(display "./figures/deepseek.png") |
| 108 | + |
| 109 | +;; ### Step 5: Connect Cline to the MCP server |
| 110 | + |
| 111 | +;; In Cline's top navigation bar, click the MCP Servers icon, then **Remote Servers**. Add a new server with the SSE endpoint URL: |
| 112 | + |
| 113 | +;; > ``` |
| 114 | +;; > http://localhost:7080/sse |
| 115 | +;; > ``` |
| 116 | + |
| 117 | +;; Enter a name for the server (e.g. "clojure-mcp") and select **SSE (Legacy)** for Transport Type. Select **Add Server**. Once connected, Cline should show the server as active, and you can browse the available tools and resources in **Configure**: |
| 118 | + |
| 119 | +^{:kindly/hide-code true} |
| 120 | +(display "./figures/clj-config.png") |
| 121 | + |
| 122 | +;; For more advanced MCP server configuration options in Cline, see [Cline's MCP documentation](https://docs.cline.bot/mcp/configuring-mcp-servers). |
| 123 | + |
| 124 | +;; ### Step 6: Grant permissions |
| 125 | + |
| 126 | +;; In the bar above Cline's prompt input, grant Cline permission to use the MCP servers. You can set read, write, and execute permissions here. The setup is now complete. |
| 127 | + |
| 128 | +^{:kindly/hide-code true} |
| 129 | +(display "./figures/cline-tools.png") |
| 130 | + |
| 131 | +;; ## Wrapping Up |
| 132 | + |
| 133 | +;; With this setup, Cline acts as the bridge between any LLM API and clojure-mcp. It translates the LLM's tool-call responses into MCP requests, forwards them to the containerised clojure-mcp server, and feeds the REPL output back to the model. Cline also displays token usage and cached tokens per prompt, with rough cost estimates based on the provider's rates. |
| 134 | + |
| 135 | +;; The same approach works beyond DeepSeek — configure a different API key and model in Cline's settings and the rest of the chain stays the same. For fully local setups, Cline's support for Ollama and LM Studio means the entire chain can run on your machine with no external API calls. |
| 136 | + |
| 137 | +;; ### Related approaches |
| 138 | + |
| 139 | +;; This is not the only way to connect clojure-mcp to alternative LLMs. For Emacs users, [gptel](https://github.com/karthink/gptel?tab=readme-ov-file#model-context-protocol-mcp-integration) provides MCP integration with support for multiple model backends — see [this walkthrough](https://yannesposito.com/posts/0029-ai-assistants-in-doom-emacs-31-on-macos-with-clojure-mcp-server/index.html) for an implementation using clojure-mcp. This suits users who prefer editor-integrated setups with high customisability, though it requires more familiarity with Emacs configuration. |
| 140 | + |
| 141 | +;; Separately, users of Claude Code or other CLI assistants may want to look at [clojure-mcp-light](https://github.com/bhauman/clojure-mcp-light), also by Bruce Hauman. It is not an MCP server, but provides CLI tools (REPL evaluation, delimiter repair) that create a clojure-mcp-like development experience without requiring MCP infrastructure. |
| 142 | + |
| 143 | +;; ### Thanks to: |
| 144 | +;; - [Daniel Slutsky](https://bsky.app/profile/daslu.bsky.social) for comments on an earlier draft |
| 145 | +;; - https://github.com/bhauman/clojure-mcp |
| 146 | +;; - https://github.com/stoating/clojure-mcp-examples |
| 147 | +;; - https://github.com/sparfenyuk/mcp-proxy |
| 148 | +;; - https://github.com/cline/cline |
0 commit comments