Recent Posts
Archives

Posts Tagged ‘reClojure2025’

PostHeaderIcon [reClojure2025] Writing Model Context Protocol (MCP) Servers in Clojure

Lecturer

Vedang Manerikar is the founder of Unravel.tech and a veteran software architect with over 15 years of experience in the Clojure ecosystem. Previously serving as the Head of Backend Engineering at Helpshift, Vedang has managed large-scale distributed systems and led complex technical migrations. At Unravel.tech, his work focuses on the intersection of Clojure and Artificial Intelligence, specifically building “Agentic Systems” and implementing Generative AI (GenAI) and Large Language Model (LLM) solutions. He is the author of mcp-cljc-sdk, a cross-platform Clojure SDK for the Model Context Protocol.

Abstract

The rapid advancement of Artificial Intelligence has created a need for standardized communication between AI agents and external systems. The Model Context Protocol (MCP), introduced by Anthropic, has emerged as a solution to the integration problem, providing a common interface for agents to interact with diverse data sources and tools. This article explores the architecture of MCP and argues that Clojure is uniquely positioned as an ideal language for implementing MCP servers. We analyze the protocol’s similarity to the Language Server Protocol (LSP), examine real-world applications in browser automation and communication platforms, and discuss how Clojure’s REPL-driven development and data-centric philosophy streamline the creation of powerful, composable AI workflows.

The Model Context Protocol: A New Standard for AI UX

At its core, MCP is an open standard designed to enable AI applications—such as Claude Desktop or Cursor—to access the external world in a structured manner. While one might ask why standard HTTP interfaces are insufficient, the answer lies in the integration problem. Without a standard, every AI agent would need a custom integration for every service (PostgreSQL, Google Drive, GitHub, etc.). MCP solves this by acting as a “USB port” for AI; developers write a server for their service once, and it becomes immediately accessible to any MCP-compliant agent.
Vedang describes MCP not just as a data access layer, but as a “baseline AI UX.” It defines how an agent discovers tools, reads resources, and follows prompts. This standardization allows for the creation of sophisticated workflows where an agent can, for example, use a Playwright MCP server to browse Hacker News, a WhatsApp MCP server to read messages, and a local filesystem server to summarize information and save it to a document. By providing a consistent interface, MCP shifts the focus from integration plumbing to the design of the agent’s behavior and user experience.

Clojure as the Premier Language for MCP

Clojure’s technical characteristics align remarkably well with the requirements of building MCP servers. The protocol is heavily reliant on JSON-RPC and the exchange of structured data, which plays directly into Clojure’s “data-as-code” philosophy. Vedang highlights several key reasons why Clojure developers are particularly well-prepared for the LLM world:
1. REPL-Driven Development: MCP servers often act as intermediaries between non-deterministic LLMs and deterministic systems. The ability to interactively test and refine server responses in a live REPL mirrors the iterative nature of working with AI.
2. Data Transformation: Clojure’s rich library for manipulating maps and vectors makes it trivial to transform complex API responses into the simplified “Context” required by LLMs.
3. Cross-Platform Capability: With the mcp-cljc-sdk, developers can write server logic once and deploy it on both the JVM (using clojure.main or GraalVM native images) and Node.js (via ClojureScript), providing flexibility in how the server is hosted and consumed.

Code Sample: Defining a Simple MCP Tool

(defmethod handle-request "tools/call" [request]
  (let [{:keys [name arguments]} (:params request)]
    (case name
      "get-weather" (let [city (:city arguments)]
                      {:content [{:type "text"
                                  :text (str "The weather in " city " is sunny.")}]})
      {:error "Tool not found"})))

Practical Applications and Agentic Workflows

The power of MCP is best demonstrated through real-world “Agentic” use cases. Vedang shares examples of servers he has developed to automate complex tasks. One such server integrates with WhatsApp, allowing an AI agent to scan chat groups for business leads. Instead of a human manually reading hundreds of messages, the agent uses the MCP server to fetch the latest messages, identifies intent, and provides a summarized report of actionable items.
Another significant application is in browser automation. Using an MCP server for Playwright, an AI can navigate the web as a user would—logging into sites, extracting data from dynamically rendered pages, and performing actions. This allows for prompts like “Find me a hotel within walking distance of the reClojure conference,” where the agent autonomously searches maps, checks availability, and compares prices. These examples illustrate how MCP enables the transition from simple chatbots to true “agents” capable of multi-step reasoning and interaction with the physical or digital world.

The Future of Content-Centric AI

Looking ahead, the evolution of MCP suggests a shift toward a “content-is-king” paradigm. Current AI interactions are often limited by the UX of the chat box. However, with MCP, the focus can move toward the actual content being produced or modified—whether that is a codebase, a spreadsheet, or a document. Vedang envisions a future where multiple coding agents can work in parallel on the same repository, coordinated through a “better Git” or similar bidi-rectinal communication protocols enabled by MCP.
By standardizing the way agents interact with our tools, MCP paves the way for a new generation of software that is designed from the ground up to be AI-enhanced. For the Clojure community, this represents a significant opportunity to lead the development of the “AI UX” by building robust, composable servers that unlock the full potential of Large Language Models.

Links:

PostHeaderIcon [reClojure2025] UI, Pure and Simple

Lecturer

Christian Johansen is a highly experienced software developer at the Norwegian Food Safety Authority, where he specializes in architecting robust systems using Clojure and Datomic. With a professional career spanning two decades, Christian has dedicated the last ten years to full-time Clojure development. His expertise is deeply rooted in web technologies, encompassing the entire delivery pipeline from infrastructure configuration and data modeling to sophisticated frontend implementation. Beyond his primary role, he is a prolific contributor to the Clojure ecosystem, maintaining various open-source libraries and frequently sharing insights through conference presentations, educational courses, and a collaborative professional blog.

Abstract

Modern frontend development is often plagued by the complexities of shared mutable state and pervasive side effects, which complicate testing and maintenance. This article examines the philosophical and technical foundations of achieving a truly functional user interface. By revisiting the original promise of React—that UI is a function of state—and refining it through the lens of Clojure’s immutability, we introduce a paradigm known as top-down rendering. Central to this discussion is Replicant, a small, dependency-free Clojure rendering library designed to treat UI as pure, deterministic data. We analyze the methodology of building modular UIs that decouple rendering from state management, utilize data-driven event handlers, and leverage declarative animations to create simpler, more testable applications.

Historical Context and the Pursuit of Purity

The evolution of modern web development reached a significant milestone in 2013 with the introduction of React. The framework proposed a revolutionary conceptual model: the user interface should be viewed as a pure function of application state. In this ideal scenario, developers would write code as if the entire UI were rendered from scratch with every update, leaving the heavy lifting of DOM manipulation to the framework. However, while React transformed the industry’s mental model, it did not fully deliver on the promise of functional purity. In practice, React applications often allow mutable state to proliferate throughout the component tree, leading to the very “side-effect-ridden” complexity it sought to solve.
The ClojureScript community recognized this gap early on. Developers sought a more rigorous adherence to functional principles. One notable advancement was the library Quiescent, which introduced the constraint of “top-down rendering.” In this model, components are prohibited from maintaining their own internal state or triggering their own re-renders. Instead, the entire UI is a literal projection of a central, immutable data structure. This approach aligns perfectly with Clojure’s core strengths, providing a foundation for UIs that are stateless, deterministic, and built entirely on data.

Methodology: Rendering with Replicant

Replicant serves as a realization of this top-down philosophy. It is a minimalist virtual DOM library that operates on Hiccup, a domain-specific language in Clojure that represents HTML structures as standard data vectors and maps. The core methodology involves creating pure functions that transform domain data into Hiccup data. Because these functions are pure, they are inherently predictable and easy to test in isolation.
To illustrate this, consider the rendering of a task card in a Kanban application. The developer defines a function that takes a task map and returns a Hiccup representation. Replicant’s render function then takes this data and a target DOM element to perform the initial mount. When the application state changes, the process is repeated: the pure function generates new Hiccup data, and Replicant calculates the minimal set of DOM mutations required to transition the view. This “diffing” process ensures efficiency without requiring the developer to manage state transitions manually.

Code Sample: Pure Hiccup Transformation

(defn render-task [task tags-lookup]
  [:div.task-card
   [:h3 (:task/title task)]
   [:div.tags
    (map (fn [tag-id]
           (let [tag (get tags-lookup tag-id)]
             [:span {:class (str "tag-" (:tag/color tag))}
              (:tag/label tag)]))
         (:task/tags task))]])

Advanced UI Patterns: Events and Animations

Beyond static rendering, the “pure and simple” approach extends to interactivity. In traditional frameworks, event handlers are often opaque functions that execute side effects directly. Replicant encourages data-driven event handlers. Instead of passing a callback function to an onClick attribute, the developer can pass a data structure—a vector or a map—representing the intent of the event. A central coordinator then interprets this data to update the global state. This decoupling makes the UI’s behavior as inspectable and testable as its appearance.
The same principle applies to complex UI requirements like animations and timed effects. By treating time and transitions as part of the data flow, developers can create declarative animations. These are not imperative commands to “fade in an element” but rather state-based descriptions of how an element should appear at a given point in the application lifecycle. This approach dramatically simplifies the creation of interactive features like drag-and-drop or live data streaming, as the UI remains a consistent reflection of the underlying store regardless of where the data originates.

Consequential Benefits and Conclusion

Adopting a stateless, data-centric approach to UI development yields significant benefits for software quality. Because the UI is composed of pure functions, it is highly modular and testable. Tools like Portfolio (similar to Storybook for ClojureScript) allow developers to render “scenes” in isolation by passing mock domain data to their rendering functions. This facilitates rapid prototyping and visual regression testing without the need to navigate through a live, stateful application.
Ultimately, the shift toward pure and simple UIs represents a move away from the “nashing of teeth” associated with shared mutable state. By leveraging Clojure’s immutable data structures and Replicant’s minimalist rendering engine, developers can build systems that are not only more robust and maintainable but also more enjoyable to create. The decoupling of rendering from state management allows for a degree of architectural clarity that is often missing in contemporary frontend development.

Links: