Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions apisix/plugins/mcp-bridge.lua
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,25 @@ local function on_connect(conf, ctx)
local line, _
line, _, stderr_partial = proc:stderr_read_line()
if line then
local ok, err = server.transport:send(
'{"jsonrpc":"2.0","method":"notifications/stderr","params":{"content":"'
.. (stderr_partial and stderr_partial .. line or line) .. '"}}')
local content = stderr_partial and stderr_partial .. line or line
local msg, enc_err = core.json.encode({
jsonrpc = "2.0",
method = "notifications/stderr",
params = {
content = content,
},
})
if not msg then
msg = core.json.encode({
jsonrpc = "2.0",
method = "notifications/stderr",
params = {
content = "failed to encode stderr content: " .. (enc_err or "unknown"),
},
})
end
Comment thread
shreemaan-abhishek marked this conversation as resolved.
Outdated

local ok, err = server.transport:send(msg)
if not ok then
core.log.info("session ", server.session_id,
" exit, failed to send response message: ", err)
Expand Down
37 changes: 37 additions & 0 deletions t/plugin/mcp-bridge.t
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,40 @@ property "command" is required
property "command" validation failed: wrong type: expected string, got number
done
property "args" validation failed: wrong type: expected array, got string



=== TEST 2: stderr content with JSON special characters keeps the notification well-formed
--- config
location /t {
content_by_lua_block {
local core = require("apisix.core")
local pipe = require("ngx.pipe")

-- a subprocess line that contains double quotes, a backslash and the
-- "}}" sequence, all of which break naive string concatenation
local payload = [[Error: invalid input "x\y" }}]]

local proc = assert(pipe.spawn({"sh", "-c", [[printf '%s\n' "$1" 1>&2]], "sh", payload}))
proc:set_timeouts(nil, 1000, 1000)
local line = assert(proc:stderr_read_line())

Comment thread
shreemaan-abhishek marked this conversation as resolved.
Outdated
-- build the notification the same way the plugin does
local msg = core.json.encode({
jsonrpc = "2.0",
method = "notifications/stderr",
params = {
content = line,
},
})
Comment thread
shreemaan-abhishek marked this conversation as resolved.
Outdated

local decoded, err = core.json.decode(msg)
if not decoded then
ngx.say("not valid json: ", err)
return
end
ngx.say("valid json: ", decoded.params.content == payload)
}
}
--- response_body
valid json: true
Loading