Commit14d909c6Recorded1 Sep 2026Repositorysigil-mcp

fix(client): parse JSON-RPC responses on current runtime

Changed
 package.sgl                |  2 +-
 src/sigil/mcp/protocol.sgl | 38 ++++++++++++++++++++------------------
 test/test-protocol.sgl     |  7 +++++++
 3 files changed, 28 insertions(+), 19 deletions(-)
Diff
package.sglmodified
@@ -7,7 +7,7 @@
7
8
(package
9
name: "sigil-mcp"
−10
version: "0.17.3"
+10
version: "0.17.4"
11
sigil: "^0.19"
12
description: "Library for building MCP clients and servers in Sigil"
13
url: "https://codeberg.org/sigil/sigil-mcp"
src/sigil/mcp/protocol.sglmodified
@@ -108,30 +108,32 @@
108
(define (parse-message json)
109
(and (dict? json)
110
(equal? (dict-ref json jsonrpc: #f) "2.0")
−111
(let ((method (dict-ref json method: #f))
−112
(has-id? (dict-contains? json id:))
−113
(has-result? (dict-contains? json result:))
−114
(has-error? (dict-contains? json error:))
−115
(params (dict-ref json params: #f)))
+111
(let* ((missing (list 'missing-jsonrpc-field))
+112
(method (dict-ref json method: #f))
+113
(id (dict-ref json id: missing))
+114
(result (dict-ref json result: missing))
+115
(error-value (dict-ref json error: missing))
+116
(has-id? (not (eq? id missing)))
+117
(has-result? (not (eq? result missing)))
+118
(has-error? (not (eq? error-value missing)))
+119
(params (dict-ref json params: #f)))
120
(cond
+121
((and has-id? has-result? (not has-error?))
+122
(make-response id result))
+123
((and has-id? has-error? (dict? error-value))
+124
(and (number? (dict-ref error-value code: #f))
+125
(string? (dict-ref error-value message: #f))
+126
(make-error-response
+127
id
+128
(dict-ref error-value code:)
+129
(dict-ref error-value message:)
+130
(dict-ref error-value data: #f))))
131
((string? method)
132
(if has-id?
−119
(jsonrpc-request id: (dict-ref json id:)
+133
(jsonrpc-request id: id
134
method: method
135
params: params)
136
(jsonrpc-notification method: method params: params)))
−123
((and has-id? has-result? (not has-error?))
−124
(jsonrpc-response id: (dict-ref json id:)
−125
result: (dict-ref json result:)))
−126
((and has-id? has-error? (dict? (dict-ref json error:)))
−127
(let ((error (dict-ref json error:)))
−128
(and (number? (dict-ref error code: #f))
−129
(string? (dict-ref error message: #f))
−130
(jsonrpc-error-response
−131
id: (dict-ref json id:)
−132
code: (dict-ref error code:)
−133
message: (dict-ref error message:)
−134
data: (dict-ref error data: #f)))))
137
(else #f)))))
138
139
;; ============================================================
test/test-protocol.sglmodified
@@ -45,6 +45,13 @@
45
(assert-equal 0 (jsonrpc-response-id msg))
46
(assert-true (dict-ref (jsonrpc-response-result msg) ok:))))
47
+48
(test "successful response preserves a false result"
+49
(let ((msg (parse-message-string
+50
"{\"jsonrpc\":\"2.0\",\"id\":0,\"result\":false}")))
+51
(assert-true (jsonrpc-response? msg))
+52
(assert-equal 0 (jsonrpc-response-id msg))
+53
(assert-false (jsonrpc-response-result msg))))
+54
55
(test "error response"
56
(let ((msg (parse-message-string
57
"{\"jsonrpc\":\"2.0\",\"id\":7,\"error\":{\"code\":-32001,\"message\":\"refused\",\"data\":{\"kind\":\"policy\"}}}")))