11(ns mcp-clj.json-rpc.server
22 " JSON-RPC 2.0 server implementation with EDN/JSON conversion"
3- (:require [aleph.http :as http]
4- [clojure.data.json :as json]
5- [mcp-clj.json-rpc.protocol :as protocol]))
3+ (:require
4+ [mcp-clj.json-rpc.protocol :as protocol])
5+ (:import
6+ [com.sun.net.httpserver HttpServer HttpHandler HttpExchange]
7+ [java.net InetSocketAddress]
8+ [java.io InputStreamReader BufferedReader]
9+ [java.util.concurrent Executors]))
610
7- ; ;; Server creation and lifecycle
11+ (defn- read-request-body
12+ " Read the request body from an HttpExchange"
13+ [^HttpExchange exchange]
14+ (with-open [reader (-> exchange
15+ .getRequestBody
16+ InputStreamReader.
17+ BufferedReader.)]
18+ (let [length (-> exchange .getRequestHeaders (get " Content-length" ) first Integer/parseInt)
19+ chars (char-array length)]
20+ (.read reader chars 0 length)
21+ (String. chars))))
22+
23+ (defn- send-response
24+ " Send a response through the HttpExchange"
25+ [^HttpExchange exchange ^String response]
26+ (let [bytes (.getBytes response)
27+ headers (.getResponseHeaders exchange)]
28+ (.add headers " Content-Type" " application/json" )
29+ (.sendResponseHeaders exchange 200 (count bytes))
30+ (with-open [os (.getResponseBody exchange)]
31+ (.write os bytes)
32+ (.flush os))))
33+
34+ (defn- handle-json-rpc
35+ " Process a single JSON-RPC request and return response"
36+ [handlers request]
37+ (if-let [validation-error (protocol/validate-request request)]
38+ validation-error
39+ (let [{:keys [method params id]} request
40+ handler (get handlers method)]
41+ (if handler
42+ (try
43+ (let [result (handler params)]
44+ (protocol/result-response id result))
45+ (catch Exception e
46+ (protocol/error-response
47+ (get protocol/error-codes :internal-error )
48+ (.getMessage e)
49+ {:id id})))
50+ (protocol/error-response
51+ (get protocol/error-codes :method-not-found )
52+ (str " Method not found: " method)
53+ {:id id})))))
54+
55+ (defn- handle-request
56+ " Handle an incoming HTTP request"
57+ [handlers exchange]
58+ (try
59+ (let [body (read-request-body exchange)
60+ [request parse-error] (protocol/parse-json body)
61+ response (if parse-error
62+ parse-error
63+ (cond
64+ (map? request)
65+ (handle-json-rpc handlers request)
66+
67+ (sequential? request)
68+ (mapv #(handle-json-rpc handlers %) request)
69+
70+ :else
71+ (protocol/error-response
72+ (get protocol/error-codes :invalid-request )
73+ " Invalid request format" )))
74+ [json-response json-error] (protocol/write-json response)]
75+ (if json-error
76+ (send-response exchange
77+ (protocol/write-json
78+ (protocol/error-response
79+ (get protocol/error-codes :internal-error )
80+ " Response encoding error" )))
81+ (send-response exchange json-response)))
82+ (catch Exception e
83+ (send-response exchange
84+ (protocol/write-json
85+ (protocol/error-response
86+ (get protocol/error-codes :internal-error )
87+ " Internal server error" ))))))
888
989(defn create-server
1090 " Create a new JSON-RPC server.
11-
91+
1292 Configuration options:
1393 - :port Required. Port number to listen on
1494 - :handlers Required. Map of method names to handler functions
15-
95+
1696 Returns a map containing:
1797 - :server The server instance
1898 - :stop Function to stop the server
19-
99+
20100 Example:
21101 ```clojure
22102 (create-server
28108 (throw (ex-info " Port is required" {:config config})))
29109 (when-not (map? handlers)
30110 (throw (ex-info " Handlers must be a map" {:config config})))
31-
32- ; ; TODO: Implement server creation
33- )
34111
35- ; ;; Request handling
112+ (let [server (HttpServer/create (InetSocketAddress. port) 0 )
113+ executor (Executors/newFixedThreadPool 10 )
114+ handler (reify HttpHandler
115+ (handle [_ exchange]
116+ (handle-request handlers exchange)))]
36117
37- (defn- handle-request
38- " Handle a single JSON-RPC request.
39- Converts JSON to EDN, dispatches to handler, converts response to JSON."
40- [handlers request]
41- ; ; TODO: Implement request handling
42- )
43-
44- (defn- handle-batch
45- " Handle a batch of JSON-RPC requests."
46- [handlers requests]
47- ; ; TODO: Implement batch handling
48- )
49-
50- ; ;; Handler dispatch
51-
52- (defn- dispatch-request
53- " Dispatch a request to its handler and return the response."
54- [handlers {:keys [method params] :as request}]
55- ; ; TODO: Implement handler dispatch
56- )
118+ (.setExecutor server executor)
119+ (.createContext server " /" handler)
120+ (.start server)
121+
122+ {:server server
123+ :stop #(do (.stop server 1 )
124+ (.shutdown executor))}))
0 commit comments